Remove all existing @since annotations
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / histogram / HistogramView.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 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 * 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 *******************************************************************************/
19
20 package org.eclipse.tracecompass.tmf.ui.views.histogram;
21
22 import java.util.Collection;
23
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.TmfTraceManager;
63 import org.eclipse.tracecompass.tmf.ui.views.TmfView;
64 import org.eclipse.ui.IActionBars;
65
66 /**
67 * The purpose of this view is to provide graphical time distribution statistics about the trace events.
68 * <p>
69 * The view is composed of two histograms and two controls:
70 * <ul>
71 * <li>an event distribution histogram for the whole trace;
72 * <li>an event distribution histogram for current time window (window span);
73 * <li>the timestamp of the currently selected event;
74 * <li>the window span (size of the time window of the smaller histogram).
75 * </ul>
76 * The histograms x-axis show their respective time range.
77 *
78 * @version 2.0
79 * @author Francois Chouinard
80 */
81 public class HistogramView extends TmfView {
82
83 // ------------------------------------------------------------------------
84 // Constants
85 // ------------------------------------------------------------------------
86
87 /**
88 * The view ID as defined in plugin.xml
89 */
90 public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$
91
92 private static final Image LINK_IMG = Activator.getDefault().getImageFromPath("/icons/etool16/link.gif"); //$NON-NLS-1$
93
94 // ------------------------------------------------------------------------
95 // Attributes
96 // ------------------------------------------------------------------------
97
98 // Parent widget
99 private Composite fParent;
100
101 // The current trace
102 private ITmfTrace fTrace;
103
104 // Current timestamp/time window - everything in the TIME_SCALE
105 private long fTraceStartTime;
106 private long fTraceEndTime;
107 private long fWindowStartTime;
108 private long fWindowEndTime;
109 private long fWindowSpan;
110 private long fSelectionBeginTime;
111 private long fSelectionEndTime;
112
113 // Time controls
114 private HistogramTextControl fSelectionStartControl;
115 private HistogramTextControl fSelectionEndControl;
116 private HistogramTextControl fTimeSpanControl;
117
118 // Link
119 private Label fLinkButton;
120 private boolean fLinkState;
121
122 // Histogram/request for the full trace range
123 private static FullTraceHistogram fFullTraceHistogram;
124 private HistogramRequest fFullTraceRequest;
125
126 // Histogram/request for the selected time range
127 private static TimeRangeHistogram fTimeRangeHistogram;
128 private HistogramRequest fTimeRangeRequest;
129
130 // Legend area
131 private Composite fLegendArea;
132 private Image[] fLegendImages;
133
134 // Throttlers for the time sync and time-range sync signals
135 private final TmfSignalThrottler fTimeSyncThrottle;
136 private final TmfSignalThrottler fTimeRangeSyncThrottle;
137
138 // Action for toggle showing the lost events
139 private Action hideLostEventsAction;
140 // Action for toggle showing the traces
141 private Action showTraceAction;
142
143 // ------------------------------------------------------------------------
144 // Constructor
145 // ------------------------------------------------------------------------
146
147 /**
148 * Default constructor
149 */
150 public HistogramView() {
151 super(ID);
152 fTimeSyncThrottle = new TmfSignalThrottler(this, 200);
153 fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200);
154 }
155
156 @Override
157 public void dispose() {
158 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
159 fTimeRangeRequest.cancel();
160 }
161 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
162 fFullTraceRequest.cancel();
163 }
164 fFullTraceHistogram.dispose();
165 fTimeRangeHistogram.dispose();
166 fSelectionStartControl.dispose();
167 fSelectionEndControl.dispose();
168 fTimeSpanControl.dispose();
169 disposeLegendImages();
170
171 super.dispose();
172 }
173
174 private void disposeLegendImages() {
175 if (fLegendImages != null) {
176 for (Image i: fLegendImages) {
177 i.dispose();
178 }
179 }
180 fLegendImages = null;
181 }
182
183 // ------------------------------------------------------------------------
184 // TmfView
185 // ------------------------------------------------------------------------
186
187 @Override
188 public void createPartControl(Composite parent) {
189
190 fParent = parent;
191
192 // Control labels
193 final String selectionStartLabel = Messages.HistogramView_selectionStartLabel;
194 final String selectionEndLabel = Messages.HistogramView_selectionEndLabel;
195 final String windowSpanLabel = Messages.HistogramView_windowSpanLabel;
196
197 // --------------------------------------------------------------------
198 // Set the HistogramView layout
199 // --------------------------------------------------------------------
200
201 Composite viewComposite = new Composite(fParent, SWT.FILL);
202 GridLayout gridLayout = new GridLayout();
203 gridLayout.numColumns = 2;
204 gridLayout.horizontalSpacing = 5;
205 gridLayout.verticalSpacing = 0;
206 gridLayout.marginHeight = 0;
207 gridLayout.marginWidth = 0;
208 viewComposite.setLayout(gridLayout);
209
210 // --------------------------------------------------------------------
211 // Time controls
212 // --------------------------------------------------------------------
213
214 Composite controlsComposite = new Composite(viewComposite, SWT.NONE);
215 gridLayout = new GridLayout();
216 gridLayout.numColumns = 2;
217 gridLayout.marginHeight = 0;
218 gridLayout.marginWidth = 0;
219 gridLayout.horizontalSpacing = 5;
220 gridLayout.verticalSpacing = 1;
221 gridLayout.makeColumnsEqualWidth = false;
222 controlsComposite.setLayout(gridLayout);
223 GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false);
224 controlsComposite.setLayoutData(gridData);
225
226 Composite selectionGroup = new Composite(controlsComposite, SWT.BORDER);
227 gridLayout = new GridLayout();
228 gridLayout.marginHeight = 0;
229 gridLayout.marginWidth = 0;
230 gridLayout.horizontalSpacing = 0;
231 gridLayout.verticalSpacing = 0;
232 selectionGroup.setLayout(gridLayout);
233
234 // Selection start control
235 gridData = new GridData();
236 gridData.horizontalAlignment = SWT.FILL;
237 gridData.verticalAlignment = SWT.CENTER;
238 fSelectionStartControl = new HistogramSelectionStartControl(this, selectionGroup, selectionStartLabel, 0L);
239 fSelectionStartControl.setLayoutData(gridData);
240 fSelectionStartControl.setValue(Long.MIN_VALUE);
241
242 // Selection end control
243 gridData = new GridData();
244 gridData.horizontalAlignment = SWT.FILL;
245 gridData.verticalAlignment = SWT.CENTER;
246 fSelectionEndControl = new HistogramSelectionEndControl(this, selectionGroup, selectionEndLabel, 0L);
247 fSelectionEndControl.setLayoutData(gridData);
248 fSelectionEndControl.setValue(Long.MIN_VALUE);
249
250 // Link button
251 gridData = new GridData();
252 fLinkButton = new Label(controlsComposite, SWT.NONE);
253 fLinkButton.setImage(LINK_IMG);
254 fLinkButton.setLayoutData(gridData);
255 addLinkButtonListeners();
256
257 // Window span time control
258 gridData = new GridData();
259 gridData.horizontalAlignment = SWT.FILL;
260 gridData.verticalAlignment = SWT.CENTER;
261 fTimeSpanControl = new HistogramTimeRangeControl(this, controlsComposite, windowSpanLabel, 0L);
262 fTimeSpanControl.setLayoutData(gridData);
263 fTimeSpanControl.setValue(Long.MIN_VALUE);
264
265 // --------------------------------------------------------------------
266 // Time range histogram
267 // --------------------------------------------------------------------
268
269 Composite timeRangeComposite = new Composite(viewComposite, SWT.NONE);
270 gridLayout = new GridLayout();
271 gridLayout.numColumns = 1;
272 gridLayout.marginHeight = 0;
273 gridLayout.marginWidth = 0;
274 gridLayout.marginTop = 5;
275 gridLayout.horizontalSpacing = 0;
276 gridLayout.verticalSpacing = 0;
277 gridLayout.marginLeft = 5;
278 gridLayout.marginRight = 5;
279 timeRangeComposite.setLayout(gridLayout);
280
281 // Use remaining horizontal space
282 gridData = new GridData();
283 gridData.horizontalAlignment = SWT.FILL;
284 gridData.verticalAlignment = SWT.FILL;
285 gridData.grabExcessHorizontalSpace = true;
286 gridData.grabExcessVerticalSpace = true;
287 timeRangeComposite.setLayoutData(gridData);
288
289 // Histogram
290 fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite);
291
292 // --------------------------------------------------------------------
293 // Full range histogram
294 // --------------------------------------------------------------------
295
296 Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL);
297 gridLayout = new GridLayout();
298 gridLayout.numColumns = 1;
299 gridLayout.marginHeight = 0;
300 gridLayout.marginWidth = 0;
301 gridLayout.marginTop = 5;
302 gridLayout.horizontalSpacing = 0;
303 gridLayout.verticalSpacing = 0;
304 gridLayout.marginLeft = 5;
305 gridLayout.marginRight = 5;
306 fullRangeComposite.setLayout(gridLayout);
307
308 // Use remaining horizontal space
309 gridData = new GridData();
310 gridData.horizontalAlignment = SWT.FILL;
311 gridData.verticalAlignment = SWT.FILL;
312 gridData.horizontalSpan = 2;
313 gridData.grabExcessHorizontalSpace = true;
314 gridData.grabExcessVerticalSpace = true;
315 fullRangeComposite.setLayoutData(gridData);
316
317 // Histogram
318 fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite);
319
320 fLegendArea = new Composite(viewComposite, SWT.FILL);
321 fLegendArea.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false, 2, 1));
322 fLegendArea.setLayout(new RowLayout());
323
324 // Add mouse wheel listener to time span control
325 MouseWheelListener listener = fFullTraceHistogram.getZoom();
326 fTimeSpanControl.addMouseWheelListener(listener);
327
328
329 // View Action Handling
330 contributeToActionBars();
331
332 ITmfTrace trace = getActiveTrace();
333 if (trace != null) {
334 traceSelected(new TmfTraceSelectedSignal(this, trace));
335 }
336 }
337
338 @Override
339 public void setFocus() {
340 fFullTraceHistogram.fCanvas.setFocus();
341 }
342
343 void refresh() {
344 fParent.layout(true);
345 }
346
347 // ------------------------------------------------------------------------
348 // Accessors
349 // ------------------------------------------------------------------------
350
351 /**
352 * Returns the current trace handled by the view
353 *
354 * @return the current trace
355 */
356 public ITmfTrace getTrace() {
357 return fTrace;
358 }
359
360 /**
361 * Returns the time range of the current selected window (base on default time scale).
362 *
363 * @return the time range of current selected window.
364 */
365 public TmfTimeRange getTimeRange() {
366 return new TmfTimeRange(
367 new TmfTimestamp(fWindowStartTime, ITmfTimestamp.NANOSECOND_SCALE),
368 new TmfTimestamp(fWindowEndTime, ITmfTimestamp.NANOSECOND_SCALE));
369 }
370
371 /**
372 * get the show lost events action
373 *
374 * @return The action object
375 */
376 public Action getShowLostEventsAction() {
377 if (hideLostEventsAction == null) {
378 /* show lost events */
379 hideLostEventsAction = new Action(Messages.HistogramView_hideLostEvents, IAction.AS_CHECK_BOX) {
380 @Override
381 public void run() {
382 HistogramScaledData.hideLostEvents = hideLostEventsAction.isChecked();
383 long maxNbEvents = HistogramScaledData.hideLostEvents ? fFullTraceHistogram.fScaledData.fMaxValue : fFullTraceHistogram.fScaledData.fMaxCombinedValue;
384 fFullTraceHistogram.setMaxNbEvents(maxNbEvents);
385 maxNbEvents = HistogramScaledData.hideLostEvents ? fTimeRangeHistogram.fScaledData.fMaxValue : fTimeRangeHistogram.fScaledData.fMaxCombinedValue;
386 fTimeRangeHistogram.setMaxNbEvents(maxNbEvents);
387 }
388 };
389 hideLostEventsAction.setText(Messages.HistogramView_hideLostEvents);
390 hideLostEventsAction.setToolTipText(Messages.HistogramView_hideLostEvents);
391 hideLostEventsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LOST_EVENTS));
392 }
393 return hideLostEventsAction;
394 }
395
396 /**
397 * get the show trace action
398 *
399 * @return The action object
400 */
401 public Action getShowTraceAction() {
402 if (showTraceAction == null) {
403 /* show lost events */
404 showTraceAction = new Action(Messages.HistogramView_showTraces, IAction.AS_CHECK_BOX) {
405 @Override
406 public void run() {
407 Histogram.showTraces = showTraceAction.isChecked();
408 fFullTraceHistogram.fCanvas.redraw();
409 fTimeRangeHistogram.fCanvas.redraw();
410 updateLegendArea();
411 }
412 };
413 showTraceAction.setChecked(true);
414 showTraceAction.setText(Messages.HistogramView_showTraces);
415 showTraceAction.setToolTipText(Messages.HistogramView_showTraces);
416 showTraceAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_HIST_TRACES));
417 }
418 return showTraceAction;
419 }
420
421 // ------------------------------------------------------------------------
422 // Operations
423 // ------------------------------------------------------------------------
424
425 /**
426 * Broadcast TmfSignal about new current selection time range.
427 * @param beginTime the begin time of current selection.
428 * @param endTime the end time of current selection.
429 */
430 void updateSelectionTime(long beginTime, long endTime) {
431 updateDisplayedSelectionTime(beginTime, endTime);
432 TmfTimestamp beginTs = new TmfTimestamp(beginTime, ITmfTimestamp.NANOSECOND_SCALE);
433 TmfTimestamp endTs = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE);
434 TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, beginTs, endTs);
435 fTimeSyncThrottle.queue(signal);
436 }
437
438 /**
439 * Get selection begin time
440 * @return the begin time of current selection
441 */
442 long getSelectionBegin() {
443 return fSelectionBeginTime;
444 }
445
446 /**
447 * Get selection end time
448 * @return the end time of current selection
449 */
450 long getSelectionEnd() {
451 return fSelectionEndTime;
452 }
453
454 /**
455 * Get the link state
456 * @return true if begin and end selection time should be linked
457 */
458 boolean getLinkState() {
459 return fLinkState;
460 }
461
462 /**
463 * Broadcast TmfSignal about new selection time range.
464 * @param startTime the new start time
465 * @param endTime the new end time
466 */
467 void updateTimeRange(long startTime, long endTime) {
468 if (fTrace != null) {
469 // Build the new time range; keep the current time
470 TmfTimeRange timeRange = new TmfTimeRange(
471 new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE),
472 new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE));
473 fTimeSpanControl.setValue(endTime - startTime);
474
475 updateDisplayedTimeRange(startTime, endTime);
476
477 // Send the FW signal
478 TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange);
479 fTimeRangeSyncThrottle.queue(signal);
480 }
481 }
482
483 /**
484 * Broadcast TmfSignal about new selected time range.
485 * @param newDuration new duration (relative to current start time)
486 */
487 public synchronized void updateTimeRange(long newDuration) {
488 if (fTrace != null) {
489 long delta = newDuration - fWindowSpan;
490 long newStartTime = fWindowStartTime - (delta / 2);
491 setNewRange(newStartTime, newDuration);
492 }
493 }
494
495 private void setNewRange(long startTime, long duration) {
496 long realStart = startTime;
497
498 if (realStart < fTraceStartTime) {
499 realStart = fTraceStartTime;
500 }
501
502 long endTime = realStart + duration;
503 if (endTime > fTraceEndTime) {
504 endTime = fTraceEndTime;
505 if ((endTime - duration) > fTraceStartTime) {
506 realStart = endTime - duration;
507 } else {
508 realStart = fTraceStartTime;
509 }
510 }
511 updateTimeRange(realStart, endTime);
512 }
513
514 // ------------------------------------------------------------------------
515 // Signal handlers
516 // ------------------------------------------------------------------------
517
518 /**
519 * Handles trace opened signal. Loads histogram if new trace time range is not
520 * equal <code>TmfTimeRange.NULL_RANGE</code>
521 * @param signal the trace opened signal
522 */
523 @TmfSignalHandler
524 public void traceOpened(TmfTraceOpenedSignal signal) {
525 assert (signal != null);
526 fTrace = signal.getTrace();
527 loadTrace();
528 }
529
530 /**
531 * Handles trace selected signal. Loads histogram if new trace time range is not
532 * equal <code>TmfTimeRange.NULL_RANGE</code>
533 * @param signal the trace selected signal
534 */
535 @TmfSignalHandler
536 public void traceSelected(TmfTraceSelectedSignal signal) {
537 assert (signal != null);
538 if (fTrace != signal.getTrace()) {
539 fTrace = signal.getTrace();
540 loadTrace();
541 }
542 }
543
544 private void loadTrace() {
545 initializeHistograms();
546 fParent.redraw();
547 }
548
549 /**
550 * Handles trace closed signal. Clears the view and data model and cancels requests.
551 * @param signal the trace closed signal
552 */
553 @TmfSignalHandler
554 public void traceClosed(TmfTraceClosedSignal signal) {
555
556 if (signal.getTrace() != fTrace) {
557 return;
558 }
559
560 // Kill any running request
561 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
562 fTimeRangeRequest.cancel();
563 }
564 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
565 fFullTraceRequest.cancel();
566 }
567
568 // Initialize the internal data
569 fTrace = null;
570 fTraceStartTime = 0L;
571 fTraceEndTime = 0L;
572 fWindowStartTime = 0L;
573 fWindowEndTime = 0L;
574 fWindowSpan = 0L;
575 fSelectionBeginTime = 0L;
576 fSelectionEndTime = 0L;
577
578 // Clear the UI widgets
579 fFullTraceHistogram.clear();
580 fTimeRangeHistogram.clear();
581 fSelectionStartControl.setValue(Long.MIN_VALUE);
582 fSelectionEndControl.setValue(Long.MIN_VALUE);
583
584 fTimeSpanControl.setValue(Long.MIN_VALUE);
585
586 for (Control c: fLegendArea.getChildren()) {
587 c.dispose();
588 }
589 disposeLegendImages();
590 fLegendArea.layout();
591 fLegendArea.getParent().layout();
592 }
593
594 /**
595 * Handles trace range updated signal. Extends histogram according to the new time range. If a
596 * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range
597 * will be issued.
598 *
599 * @param signal the trace range updated signal
600 */
601 @TmfSignalHandler
602 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
603
604 if (signal.getTrace() != fTrace) {
605 return;
606 }
607
608 TmfTimeRange fullRange = signal.getRange();
609
610 fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
611 fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
612
613 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
614 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
615
616 sendFullRangeRequest(fullRange);
617 }
618
619 /**
620 * Handles the trace updated signal. Used to update time limits (start and end time)
621 * @param signal the trace updated signal
622 */
623 @TmfSignalHandler
624 public void traceUpdated(TmfTraceUpdatedSignal signal) {
625 if (signal.getTrace() != fTrace) {
626 return;
627 }
628 TmfTimeRange fullRange = signal.getTrace().getTimeRange();
629 fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
630 fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
631
632 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
633 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
634
635 if ((fFullTraceRequest != null) && fFullTraceRequest.getRange().getEndTime().compareTo(signal.getRange().getEndTime()) < 0) {
636 sendFullRangeRequest(fullRange);
637 }
638 }
639
640 /**
641 * Handles the current time updated signal. Sets the current time in the time range
642 * histogram as well as the full histogram.
643 *
644 * @param signal the signal to process
645 */
646 @TmfSignalHandler
647 public void currentTimeUpdated(final TmfTimeSynchSignal signal) {
648 if (Display.getCurrent() == null) {
649 // Make sure the signal is handled in the UI thread
650 Display.getDefault().asyncExec(new Runnable() {
651 @Override
652 public void run() {
653 if (fParent.isDisposed()) {
654 return;
655 }
656 currentTimeUpdated(signal);
657 }
658 });
659 return;
660 }
661
662 // Update the selected time range
663 ITmfTimestamp beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE);
664 ITmfTimestamp endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE);
665 updateDisplayedSelectionTime(beginTime.getValue(), endTime.getValue());
666 }
667
668 /**
669 * Updates the current time range in the time range histogram and full range histogram.
670 * @param signal the signal to process
671 */
672 @TmfSignalHandler
673 public void timeRangeUpdated(final TmfRangeSynchSignal signal) {
674 if (Display.getCurrent() == null) {
675 // Make sure the signal is handled in the UI thread
676 Display.getDefault().asyncExec(new Runnable() {
677 @Override
678 public void run() {
679 if (fParent.isDisposed()) {
680 return;
681 }
682 timeRangeUpdated(signal);
683 }
684 });
685 return;
686 }
687
688 if (fTrace != null) {
689 // Validate the time range
690 TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange());
691 if (range == null) {
692 return;
693 }
694
695 updateDisplayedTimeRange(
696 range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(),
697 range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue());
698
699 // Send the event request to populate the small histogram
700 sendTimeRangeRequest(fWindowStartTime, fWindowEndTime);
701
702 fTimeSpanControl.setValue(fWindowSpan);
703 }
704 }
705
706 // ------------------------------------------------------------------------
707 // Helper functions
708 // ------------------------------------------------------------------------
709
710 private void initializeHistograms() {
711 TmfTimeRange fullRange = updateTraceTimeRange();
712 long selectionBeginTime = fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
713 long selectionEndTime = fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
714 long startTime = fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
715 long duration = fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue() - startTime;
716
717 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
718 fTimeRangeRequest.cancel();
719 }
720 fTimeRangeHistogram.clear();
721 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
722 fTimeRangeHistogram.setTimeRange(startTime, duration);
723 fTimeRangeHistogram.setSelection(selectionBeginTime, selectionEndTime);
724 fTimeRangeHistogram.fDataModel.setTrace(fTrace);
725
726 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
727 fFullTraceRequest.cancel();
728 }
729 fFullTraceHistogram.clear();
730 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
731 fFullTraceHistogram.setTimeRange(startTime, duration);
732 fFullTraceHistogram.setSelection(selectionBeginTime, selectionEndTime);
733 fFullTraceHistogram.fDataModel.setTrace(fTrace);
734
735 fWindowStartTime = startTime;
736 fWindowSpan = duration;
737 fWindowEndTime = startTime + duration;
738
739 fSelectionBeginTime = selectionBeginTime;
740 fSelectionEndTime = selectionEndTime;
741 fSelectionStartControl.setValue(fSelectionBeginTime);
742 fSelectionEndControl.setValue(fSelectionEndTime);
743
744 fTimeSpanControl.setValue(duration);
745
746 Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace);
747 if (!traces.isEmpty()) {
748 this.showTraceAction.setEnabled(traces.size() < fFullTraceHistogram.getMaxNbTraces());
749 }
750 updateLegendArea();
751
752 if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) {
753 sendTimeRangeRequest(startTime, startTime + duration);
754 sendFullRangeRequest(fullRange);
755 }
756 }
757
758 private void updateLegendArea() {
759 for (Control c: fLegendArea.getChildren()) {
760 c.dispose();
761 }
762 disposeLegendImages();
763 if (fFullTraceHistogram.showTraces()) {
764 Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace);
765 fLegendImages = new Image[traces.size()];
766 int traceIndex = 0;
767 for (ITmfTrace trace : traces) {
768 fLegendImages[traceIndex] = new Image(fLegendArea.getDisplay(), 16, 16);
769 GC gc = new GC(fLegendImages[traceIndex]);
770 gc.setBackground(fFullTraceHistogram.getTraceColor(traceIndex));
771 gc.fillRectangle(0, 0, 15, 15);
772 gc.setForeground(fLegendArea.getDisplay().getSystemColor(SWT.COLOR_BLACK));
773 gc.drawRectangle(0, 0, 15, 15);
774 gc.dispose();
775
776 CLabel label = new CLabel(fLegendArea, SWT.NONE);
777 label.setText(trace.getName());
778 label.setImage(fLegendImages[traceIndex]);
779 traceIndex++;
780 }
781 }
782 fLegendArea.layout();
783 fLegendArea.getParent().layout();
784 }
785
786 private void updateDisplayedSelectionTime(long beginTime, long endTime) {
787 fSelectionBeginTime = beginTime;
788 fSelectionEndTime = endTime;
789
790 fFullTraceHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime);
791 fTimeRangeHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime);
792 fSelectionStartControl.setValue(fSelectionBeginTime);
793 fSelectionEndControl.setValue(fSelectionEndTime);
794 }
795
796 private void updateDisplayedTimeRange(long start, long end) {
797 fWindowStartTime = start;
798 fWindowEndTime = end;
799 fWindowSpan = fWindowEndTime - fWindowStartTime;
800 fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan);
801 }
802
803 private TmfTimeRange updateTraceTimeRange() {
804 fTraceStartTime = 0L;
805 fTraceEndTime = 0L;
806
807 TmfTimeRange timeRange = fTrace.getTimeRange();
808 if (!timeRange.equals(TmfTimeRange.NULL_RANGE)) {
809 fTraceStartTime = timeRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
810 fTraceEndTime = timeRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
811 }
812 return timeRange;
813 }
814
815 private void sendTimeRangeRequest(long startTime, long endTime) {
816 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
817 fTimeRangeRequest.cancel();
818 }
819 TmfTimestamp startTS = new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE);
820 TmfTimestamp endTS = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE);
821 TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS);
822
823 fTimeRangeHistogram.clear();
824 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
825 fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
826
827 int cacheSize = fTrace.getCacheSize();
828 fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(),
829 timeRange, 0, ITmfEventRequest.ALL_DATA, cacheSize, ExecutionType.FOREGROUND, false);
830 fTrace.sendRequest(fTimeRangeRequest);
831 }
832
833 private void sendFullRangeRequest(TmfTimeRange fullRange) {
834 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
835 fFullTraceRequest.cancel();
836 }
837 int cacheSize = fTrace.getCacheSize();
838 fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(),
839 fullRange,
840 (int) fFullTraceHistogram.fDataModel.getNbEvents(),
841 ITmfEventRequest.ALL_DATA,
842 cacheSize,
843 ExecutionType.BACKGROUND, true);
844 fTrace.sendRequest(fFullTraceRequest);
845 }
846
847 private void contributeToActionBars() {
848 IActionBars bars = getViewSite().getActionBars();
849 bars.getToolBarManager().add(getShowLostEventsAction());
850 bars.getToolBarManager().add(getShowTraceAction());
851 bars.getToolBarManager().add(new Separator());
852 }
853
854 private void addLinkButtonListeners() {
855 fLinkButton.addMouseListener(new MouseAdapter() {
856 @Override
857 public void mouseDown(MouseEvent e) {
858 fSelectionEndControl.setEnabled(fLinkState);
859 fLinkState = !fLinkState;
860 fLinkButton.redraw();
861 }
862 });
863
864 fLinkButton.addPaintListener(new PaintListener() {
865 @Override
866 public void paintControl(PaintEvent e) {
867 if (fLinkState) {
868 Rectangle r = fLinkButton.getBounds();
869 r.x = -1;
870 r.y = -1;
871 e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
872 e.gc.drawRectangle(r);
873 r.x = 0;
874 r.y = 0;
875 e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY));
876 e.gc.drawRectangle(r);
877 }
878 }
879 });
880 }
881 }
This page took 0.050782 seconds and 5 git commands to generate.