Build documentation index
[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.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;
66
67 /**
68 * The purpose of this view is to provide graphical time distribution statistics about the trace events.
69 * <p>
70 * The view is composed of two histograms and two controls:
71 * <ul>
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).
76 * </ul>
77 * The histograms x-axis show their respective time range.
78 *
79 * @version 2.0
80 * @author Francois Chouinard
81 */
82 public class HistogramView extends TmfView {
83
84 // ------------------------------------------------------------------------
85 // Constants
86 // ------------------------------------------------------------------------
87
88 /**
89 * The view ID as defined in plugin.xml
90 */
91 public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$
92
93 private static final Image LINK_IMG = Activator.getDefault().getImageFromPath("/icons/etool16/link.gif"); //$NON-NLS-1$
94
95 // ------------------------------------------------------------------------
96 // Attributes
97 // ------------------------------------------------------------------------
98
99 // Parent widget
100 private Composite fParent;
101
102 // The current trace
103 private ITmfTrace fTrace;
104
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;
113
114 // Time controls
115 private HistogramTextControl fSelectionStartControl;
116 private HistogramTextControl fSelectionEndControl;
117 private HistogramTextControl fTimeSpanControl;
118
119 // Link
120 private Label fLinkButton;
121 private boolean fLinkState;
122
123 // Histogram/request for the full trace range
124 private static FullTraceHistogram fFullTraceHistogram;
125 private HistogramRequest fFullTraceRequest;
126
127 // Histogram/request for the selected time range
128 private static TimeRangeHistogram fTimeRangeHistogram;
129 private HistogramRequest fTimeRangeRequest;
130
131 // Legend area
132 private Composite fLegendArea;
133 private Image[] fLegendImages;
134
135 // Throttlers for the time sync and time-range sync signals
136 private final TmfSignalThrottler fTimeSyncThrottle;
137 private final TmfSignalThrottler fTimeRangeSyncThrottle;
138
139 // Action for toggle showing the lost events
140 private Action hideLostEventsAction;
141 // Action for toggle showing the traces
142 private Action showTraceAction;
143
144 // ------------------------------------------------------------------------
145 // Constructor
146 // ------------------------------------------------------------------------
147
148 /**
149 * Default constructor
150 */
151 public HistogramView() {
152 super(ID);
153 fTimeSyncThrottle = new TmfSignalThrottler(this, 200);
154 fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200);
155 }
156
157 @Override
158 public void dispose() {
159 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
160 fTimeRangeRequest.cancel();
161 }
162 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
163 fFullTraceRequest.cancel();
164 }
165 fFullTraceHistogram.dispose();
166 fTimeRangeHistogram.dispose();
167 fSelectionStartControl.dispose();
168 fSelectionEndControl.dispose();
169 fTimeSpanControl.dispose();
170 disposeLegendImages();
171
172 super.dispose();
173 }
174
175 private void disposeLegendImages() {
176 if (fLegendImages != null) {
177 for (Image i: fLegendImages) {
178 i.dispose();
179 }
180 }
181 fLegendImages = null;
182 }
183
184 // ------------------------------------------------------------------------
185 // TmfView
186 // ------------------------------------------------------------------------
187
188 @Override
189 public void createPartControl(Composite parent) {
190
191 fParent = parent;
192
193 // Control labels
194 final String selectionStartLabel = Messages.HistogramView_selectionStartLabel;
195 final String selectionEndLabel = Messages.HistogramView_selectionEndLabel;
196 final String windowSpanLabel = Messages.HistogramView_windowSpanLabel;
197
198 // --------------------------------------------------------------------
199 // Set the HistogramView layout
200 // --------------------------------------------------------------------
201
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);
210
211 // --------------------------------------------------------------------
212 // Time controls
213 // --------------------------------------------------------------------
214
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);
226
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);
234
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);
242
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);
250
251 // Link button
252 gridData = new GridData();
253 fLinkButton = new Label(controlsComposite, SWT.NONE);
254 fLinkButton.setImage(LINK_IMG);
255 fLinkButton.setLayoutData(gridData);
256 addLinkButtonListeners();
257
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);
265
266 // --------------------------------------------------------------------
267 // Time range histogram
268 // --------------------------------------------------------------------
269
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);
281
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);
289
290 // Histogram
291 fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite);
292
293 // --------------------------------------------------------------------
294 // Full range histogram
295 // --------------------------------------------------------------------
296
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);
308
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);
317
318 // Histogram
319 fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite);
320
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());
324
325 // Add mouse wheel listener to time span control
326 MouseWheelListener listener = fFullTraceHistogram.getZoom();
327 fTimeSpanControl.addMouseWheelListener(listener);
328
329
330 // View Action Handling
331 contributeToActionBars();
332
333 ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
334 if (trace != null) {
335 traceSelected(new TmfTraceSelectedSignal(this, trace));
336 }
337 }
338
339 @Override
340 public void setFocus() {
341 fFullTraceHistogram.fCanvas.setFocus();
342 }
343
344 void refresh() {
345 fParent.layout(true);
346 }
347
348 // ------------------------------------------------------------------------
349 // Accessors
350 // ------------------------------------------------------------------------
351
352 /**
353 * Returns the current trace handled by the view
354 *
355 * @return the current trace
356 */
357 public ITmfTrace getTrace() {
358 return fTrace;
359 }
360
361 /**
362 * Returns the time range of the current selected window (base on default time scale).
363 *
364 * @return the time range of current selected window.
365 */
366 public TmfTimeRange getTimeRange() {
367 return new TmfTimeRange(
368 new TmfTimestamp(fWindowStartTime, ITmfTimestamp.NANOSECOND_SCALE),
369 new TmfTimestamp(fWindowEndTime, ITmfTimestamp.NANOSECOND_SCALE));
370 }
371
372 /**
373 * get the show lost events action
374 *
375 * @return The action object
376 */
377 public Action getShowLostEventsAction() {
378 if (hideLostEventsAction == null) {
379 /* show lost events */
380 hideLostEventsAction = new Action(Messages.HistogramView_hideLostEvents, IAction.AS_CHECK_BOX) {
381 @Override
382 public void run() {
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);
388 }
389 };
390 hideLostEventsAction.setText(Messages.HistogramView_hideLostEvents);
391 hideLostEventsAction.setToolTipText(Messages.HistogramView_hideLostEvents);
392 hideLostEventsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LOST_EVENTS));
393 }
394 return hideLostEventsAction;
395 }
396
397 /**
398 * get the show trace action
399 *
400 * @return The action object
401 */
402 public Action getShowTraceAction() {
403 if (showTraceAction == null) {
404 /* show lost events */
405 showTraceAction = new Action(Messages.HistogramView_showTraces, IAction.AS_CHECK_BOX) {
406 @Override
407 public void run() {
408 Histogram.showTraces = showTraceAction.isChecked();
409 fFullTraceHistogram.fCanvas.redraw();
410 fTimeRangeHistogram.fCanvas.redraw();
411 updateLegendArea();
412 }
413 };
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));
418 }
419 return showTraceAction;
420 }
421
422 // ------------------------------------------------------------------------
423 // Operations
424 // ------------------------------------------------------------------------
425
426 /**
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.
430 */
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);
437 }
438
439 /**
440 * Get selection begin time
441 * @return the begin time of current selection
442 */
443 long getSelectionBegin() {
444 return fSelectionBeginTime;
445 }
446
447 /**
448 * Get selection end time
449 * @return the end time of current selection
450 */
451 long getSelectionEnd() {
452 return fSelectionEndTime;
453 }
454
455 /**
456 * Get the link state
457 * @return true if begin and end selection time should be linked
458 */
459 boolean getLinkState() {
460 return fLinkState;
461 }
462
463 /**
464 * Broadcast TmfSignal about new selection time range.
465 * @param startTime the new start time
466 * @param endTime the new end time
467 */
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);
475
476 updateDisplayedTimeRange(startTime, endTime);
477
478 // Send the FW signal
479 TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange);
480 fTimeRangeSyncThrottle.queue(signal);
481 }
482 }
483
484 /**
485 * Broadcast TmfSignal about new selected time range.
486 * @param newDuration new duration (relative to current start time)
487 */
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);
493 }
494 }
495
496 private void setNewRange(long startTime, long duration) {
497 long realStart = startTime;
498
499 if (realStart < fTraceStartTime) {
500 realStart = fTraceStartTime;
501 }
502
503 long endTime = realStart + duration;
504 if (endTime > fTraceEndTime) {
505 endTime = fTraceEndTime;
506 if ((endTime - duration) > fTraceStartTime) {
507 realStart = endTime - duration;
508 } else {
509 realStart = fTraceStartTime;
510 }
511 }
512 updateTimeRange(realStart, endTime);
513 }
514
515 // ------------------------------------------------------------------------
516 // Signal handlers
517 // ------------------------------------------------------------------------
518
519 /**
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
523 */
524 @TmfSignalHandler
525 public void traceOpened(TmfTraceOpenedSignal signal) {
526 assert (signal != null);
527 fTrace = signal.getTrace();
528 loadTrace();
529 }
530
531 /**
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
535 */
536 @TmfSignalHandler
537 public void traceSelected(TmfTraceSelectedSignal signal) {
538 assert (signal != null);
539 if (fTrace != signal.getTrace()) {
540 fTrace = signal.getTrace();
541 loadTrace();
542 }
543 }
544
545 private void loadTrace() {
546 initializeHistograms();
547 fParent.redraw();
548 }
549
550 /**
551 * Handles trace closed signal. Clears the view and data model and cancels requests.
552 * @param signal the trace closed signal
553 */
554 @TmfSignalHandler
555 public void traceClosed(TmfTraceClosedSignal signal) {
556
557 if (signal.getTrace() != fTrace) {
558 return;
559 }
560
561 // Kill any running request
562 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
563 fTimeRangeRequest.cancel();
564 }
565 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
566 fFullTraceRequest.cancel();
567 }
568
569 // Initialize the internal data
570 fTrace = null;
571 fTraceStartTime = 0L;
572 fTraceEndTime = 0L;
573 fWindowStartTime = 0L;
574 fWindowEndTime = 0L;
575 fWindowSpan = 0L;
576 fSelectionBeginTime = 0L;
577 fSelectionEndTime = 0L;
578
579 // Clear the UI widgets
580 fFullTraceHistogram.clear();
581 fTimeRangeHistogram.clear();
582 fSelectionStartControl.setValue(Long.MIN_VALUE);
583 fSelectionEndControl.setValue(Long.MIN_VALUE);
584
585 fTimeSpanControl.setValue(Long.MIN_VALUE);
586
587 for (Control c: fLegendArea.getChildren()) {
588 c.dispose();
589 }
590 disposeLegendImages();
591 fLegendArea.layout();
592 fLegendArea.getParent().layout();
593 }
594
595 /**
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
598 * will be issued.
599 *
600 * @param signal the trace range updated signal
601 */
602 @TmfSignalHandler
603 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
604
605 if (signal.getTrace() != fTrace) {
606 return;
607 }
608
609 TmfTimeRange fullRange = signal.getRange();
610
611 fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
612 fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
613
614 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
615 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
616
617 sendFullRangeRequest(fullRange);
618 }
619
620 /**
621 * Handles the trace updated signal. Used to update time limits (start and end time)
622 * @param signal the trace updated signal
623 */
624 @TmfSignalHandler
625 public void traceUpdated(TmfTraceUpdatedSignal signal) {
626 if (signal.getTrace() != fTrace) {
627 return;
628 }
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();
632
633 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
634 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
635
636 if ((fFullTraceRequest != null) && fFullTraceRequest.getRange().getEndTime().compareTo(signal.getRange().getEndTime()) < 0) {
637 sendFullRangeRequest(fullRange);
638 }
639 }
640
641 /**
642 * Handles the current time updated signal. Sets the current time in the time range
643 * histogram as well as the full histogram.
644 *
645 * @param signal the signal to process
646 */
647 @TmfSignalHandler
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() {
652 @Override
653 public void run() {
654 if (fParent.isDisposed()) {
655 return;
656 }
657 currentTimeUpdated(signal);
658 }
659 });
660 return;
661 }
662
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());
667 }
668
669 /**
670 * Updates the current time range in the time range histogram and full range histogram.
671 * @param signal the signal to process
672 */
673 @TmfSignalHandler
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() {
678 @Override
679 public void run() {
680 if (fParent.isDisposed()) {
681 return;
682 }
683 timeRangeUpdated(signal);
684 }
685 });
686 return;
687 }
688
689 if (fTrace != null) {
690 // Validate the time range
691 TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange());
692 if (range == null) {
693 return;
694 }
695
696 updateDisplayedTimeRange(
697 range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(),
698 range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue());
699
700 // Send the event request to populate the small histogram
701 sendTimeRangeRequest(fWindowStartTime, fWindowEndTime);
702
703 fTimeSpanControl.setValue(fWindowSpan);
704 }
705 }
706
707 // ------------------------------------------------------------------------
708 // Helper functions
709 // ------------------------------------------------------------------------
710
711 private void initializeHistograms() {
712 TmfTimeRange fullRange = updateTraceTimeRange();
713
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;
719
720 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
721 fTimeRangeRequest.cancel();
722 }
723 fTimeRangeHistogram.clear();
724 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
725 fTimeRangeHistogram.setTimeRange(startTime, duration);
726 fTimeRangeHistogram.setSelection(selectionBeginTime, selectionEndTime);
727 fTimeRangeHistogram.fDataModel.setTrace(fTrace);
728
729 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
730 fFullTraceRequest.cancel();
731 }
732 fFullTraceHistogram.clear();
733 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
734 fFullTraceHistogram.setTimeRange(startTime, duration);
735 fFullTraceHistogram.setSelection(selectionBeginTime, selectionEndTime);
736 fFullTraceHistogram.fDataModel.setTrace(fTrace);
737
738 fWindowStartTime = startTime;
739 fWindowSpan = duration;
740 fWindowEndTime = startTime + duration;
741
742 fSelectionBeginTime = selectionBeginTime;
743 fSelectionEndTime = selectionEndTime;
744 fSelectionStartControl.setValue(fSelectionBeginTime);
745 fSelectionEndControl.setValue(fSelectionEndTime);
746
747 fTimeSpanControl.setValue(duration);
748
749 Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace);
750 if (!traces.isEmpty()) {
751 this.showTraceAction.setEnabled(traces.size() < fFullTraceHistogram.getMaxNbTraces());
752 }
753 updateLegendArea();
754
755 if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) {
756 sendTimeRangeRequest(startTime, startTime + duration);
757 sendFullRangeRequest(fullRange);
758 }
759 }
760
761 private void updateLegendArea() {
762 for (Control c: fLegendArea.getChildren()) {
763 c.dispose();
764 }
765 disposeLegendImages();
766 if (fFullTraceHistogram.showTraces()) {
767 Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace);
768 fLegendImages = new Image[traces.size()];
769 int traceIndex = 0;
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);
777 gc.dispose();
778
779 CLabel label = new CLabel(fLegendArea, SWT.NONE);
780 label.setText(trace.getName());
781 label.setImage(fLegendImages[traceIndex]);
782 traceIndex++;
783 }
784 }
785 fLegendArea.layout();
786 fLegendArea.getParent().layout();
787 }
788
789 private void updateDisplayedSelectionTime(long beginTime, long endTime) {
790 fSelectionBeginTime = beginTime;
791 fSelectionEndTime = endTime;
792
793 fFullTraceHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime);
794 fTimeRangeHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime);
795 fSelectionStartControl.setValue(fSelectionBeginTime);
796 fSelectionEndControl.setValue(fSelectionEndTime);
797 }
798
799 private void updateDisplayedTimeRange(long start, long end) {
800 fWindowStartTime = start;
801 fWindowEndTime = end;
802 fWindowSpan = fWindowEndTime - fWindowStartTime;
803 fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan);
804 }
805
806 private TmfTimeRange updateTraceTimeRange() {
807 fTraceStartTime = 0L;
808 fTraceEndTime = 0L;
809
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();
814 }
815 return timeRange;
816 }
817
818 private void sendTimeRangeRequest(long startTime, long endTime) {
819 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
820 fTimeRangeRequest.cancel();
821 }
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);
825
826 fTimeRangeHistogram.clear();
827 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
828 fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
829
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);
834 }
835
836 private void sendFullRangeRequest(TmfTimeRange fullRange) {
837 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
838 fFullTraceRequest.cancel();
839 }
840 int cacheSize = fTrace.getCacheSize();
841 fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(),
842 fullRange,
843 (int) fFullTraceHistogram.fDataModel.getNbEvents(),
844 ITmfEventRequest.ALL_DATA,
845 cacheSize,
846 ExecutionType.BACKGROUND, true);
847 fTrace.sendRequest(fFullTraceRequest);
848 }
849
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());
855 }
856
857 private void addLinkButtonListeners() {
858 fLinkButton.addMouseListener(new MouseAdapter() {
859 @Override
860 public void mouseDown(MouseEvent e) {
861 fSelectionEndControl.setEnabled(fLinkState);
862 fLinkState = !fLinkState;
863 fLinkButton.redraw();
864 }
865 });
866
867 fLinkButton.addPaintListener(new PaintListener() {
868 @Override
869 public void paintControl(PaintEvent e) {
870 if (fLinkState) {
871 Rectangle r = fLinkButton.getBounds();
872 r.x = -1;
873 r.y = -1;
874 e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
875 e.gc.drawRectangle(r);
876 r.x = 0;
877 r.y = 0;
878 e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY));
879 e.gc.drawRectangle(r);
880 }
881 }
882 });
883 }
884 }
This page took 0.109585 seconds and 5 git commands to generate.