Updated fix for bug 371528: Updates for bookmarks, editor for experiments, accelerato...
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / views / histogram / HistogramView.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2011 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 *******************************************************************************/
16
17 package org.eclipse.linuxtools.lttng.ui.views.histogram;
18
19 import org.eclipse.linuxtools.lttng.core.event.LttngEvent;
20 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
21 import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
22 import org.eclipse.linuxtools.tmf.core.experiment.TmfExperiment;
23 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
24 import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
25 import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
26 import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
27 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
28 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
29 import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
30 import org.eclipse.linuxtools.tmf.ui.views.TmfView;
31 import org.eclipse.swt.SWT;
32 import org.eclipse.swt.layout.GridData;
33 import org.eclipse.swt.layout.GridLayout;
34 import org.eclipse.swt.widgets.Composite;
35
36 /**
37 * <b><u>HistogramView</u></b>
38 * <p>
39 * The purpose of this view is to provide graphical time distribution statistics about the experiment/trace events.
40 * <p>
41 * The view is composed of two histograms and two controls:
42 * <ul>
43 * <li>an event distribution histogram for the whole experiment;
44 * <li>an event distribution histogram for current time window (window span);
45 * <li>the timestamp of the currently selected event;
46 * <li>the window span (size of the time window of the smaller histogram).
47 * </ul>
48 * The histograms x-axis show their respective time range.
49 */
50 public class HistogramView extends TmfView {
51
52 // ------------------------------------------------------------------------
53 // Constants
54 // ------------------------------------------------------------------------
55
56 // The view ID as defined in plugin.xml
57 public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.histogram"; //$NON-NLS-1$
58
59 // The initial window span (in nanoseconds)
60 public static long INITIAL_WINDOW_SPAN = (1L * 100 * 1000 * 1000); // .1sec
61
62 // Time scale
63 private final byte TIME_SCALE = Histogram.TIME_SCALE;
64
65 // ------------------------------------------------------------------------
66 // Attributes
67 // ------------------------------------------------------------------------
68
69 // Parent widget
70 private Composite fParent;
71
72 // The current experiment
73 private TmfExperiment<LttngEvent> fCurrentExperiment;
74
75 // Current timestamp/time window
76 private long fExperimentStartTime;
77 private long fExperimentEndTime;
78 private long fWindowStartTime;
79 private long fWindowEndTime;
80 private long fWindowSpan = INITIAL_WINDOW_SPAN;
81 private long fCurrentTimestamp;
82
83 // Time controls
84 private HistogramTextControl fCurrentEventTimeControl;
85 private HistogramTextControl fTimeSpanControl;
86
87 // Histogram/request for the full trace range
88 private static FullTraceHistogram fFullTraceHistogram;
89 private HistogramRequest fFullTraceRequest;
90
91 // Histogram/request for the selected time range
92 private static TimeRangeHistogram fTimeRangeHistogram;
93 private HistogramRequest fTimeRangeRequest;
94
95 // ------------------------------------------------------------------------
96 // Constructor
97 // ------------------------------------------------------------------------
98
99 public HistogramView() {
100 super(ID);
101 }
102
103 @Override
104 public void dispose() {
105 if (fTimeRangeRequest != null && !fTimeRangeRequest.isCompleted()) {
106 fTimeRangeRequest.cancel();
107 }
108 if (fFullTraceRequest != null && !fFullTraceRequest.isCompleted()) {
109 fFullTraceRequest.cancel();
110 }
111 fFullTraceHistogram.dispose();
112 fTimeRangeHistogram.dispose();
113 super.dispose();
114 }
115
116 // ------------------------------------------------------------------------
117 // TmfView
118 // ------------------------------------------------------------------------
119
120 @Override
121 @SuppressWarnings("unchecked")
122 public void createPartControl(Composite parent) {
123
124 fParent = parent;
125
126 // Control labels
127 final String currentEventLabel = Messages.HistogramView_currentEventLabel;
128 final String windowSpanLabel = Messages.HistogramView_windowSpanLabel;
129
130 // --------------------------------------------------------------------
131 // Set the HistogramView layout
132 // --------------------------------------------------------------------
133
134 Composite viewComposite = new Composite(fParent, SWT.FILL);
135 GridLayout gridLayout = new GridLayout();
136 gridLayout.numColumns = 2;
137 gridLayout.horizontalSpacing = 5;
138 gridLayout.verticalSpacing = 0;
139 gridLayout.marginHeight = 0;
140 gridLayout.marginWidth = 0;
141 viewComposite.setLayout(gridLayout);
142
143 // Use all available space
144 GridData gridData = new GridData();
145 gridData.horizontalAlignment = SWT.FILL;
146 gridData.verticalAlignment = SWT.FILL;
147 gridData.grabExcessHorizontalSpace = true;
148 viewComposite.setLayoutData(gridData);
149
150 // --------------------------------------------------------------------
151 // Time controls
152 // --------------------------------------------------------------------
153
154 Composite controlsComposite = new Composite(viewComposite, SWT.FILL);
155 gridLayout = new GridLayout();
156 gridLayout.numColumns = 2;
157 gridLayout.marginHeight = 0;
158 gridLayout.marginWidth = 0;
159 gridLayout.horizontalSpacing = 5;
160 gridLayout.verticalSpacing = 0;
161 gridLayout.makeColumnsEqualWidth = true;
162 gridLayout.marginLeft = 5;
163 gridLayout.marginRight = 5;
164 controlsComposite.setLayout(gridLayout);
165
166 // Current event time control
167 gridData = new GridData();
168 gridData.horizontalAlignment = SWT.CENTER;
169 gridData.verticalAlignment = SWT.CENTER;
170 fCurrentEventTimeControl = new HistogramCurrentTimeControl(this, controlsComposite, SWT.BORDER, SWT.BORDER,
171 currentEventLabel, HistogramUtils.nanosecondsToString(0L));
172 fCurrentEventTimeControl.setLayoutData(gridData);
173
174 // Window span time control
175 gridData = new GridData();
176 gridData.horizontalAlignment = SWT.CENTER;
177 gridData.verticalAlignment = SWT.CENTER;
178 fTimeSpanControl = new HistogramTimeRangeControl(this, controlsComposite, SWT.BORDER, SWT.BORDER,
179 windowSpanLabel, HistogramUtils.nanosecondsToString(0L));
180 fTimeSpanControl.setLayoutData(gridData);
181
182 // --------------------------------------------------------------------
183 // Time range histogram
184 // --------------------------------------------------------------------
185
186 Composite timeRangeComposite = new Composite(viewComposite, SWT.FILL);
187 gridLayout = new GridLayout();
188 gridLayout.numColumns = 1;
189 gridLayout.marginHeight = 0;
190 gridLayout.marginWidth = 0;
191 gridLayout.marginTop = 5;
192 gridLayout.horizontalSpacing = 0;
193 gridLayout.verticalSpacing = 0;
194 gridLayout.marginLeft = 5;
195 gridLayout.marginRight = 5;
196 timeRangeComposite.setLayout(gridLayout);
197
198 // Use remaining horizontal space
199 gridData = new GridData();
200 gridData.horizontalAlignment = SWT.FILL;
201 gridData.verticalAlignment = SWT.FILL;
202 gridData.grabExcessHorizontalSpace = true;
203 timeRangeComposite.setLayoutData(gridData);
204
205 // Histogram
206 fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite);
207
208 // --------------------------------------------------------------------
209 // Full range histogram
210 // --------------------------------------------------------------------
211
212 Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL);
213 gridLayout = new GridLayout();
214 gridLayout.numColumns = 1;
215 gridLayout.marginHeight = 0;
216 gridLayout.marginWidth = 0;
217 gridLayout.marginTop = 5;
218 gridLayout.horizontalSpacing = 0;
219 gridLayout.verticalSpacing = 0;
220 gridLayout.marginLeft = 5;
221 gridLayout.marginRight = 5;
222 fullRangeComposite.setLayout(gridLayout);
223
224 // Use remaining horizontal space
225 gridData = new GridData();
226 gridData.horizontalAlignment = SWT.FILL;
227 gridData.verticalAlignment = SWT.FILL;
228 gridData.horizontalSpan = 2;
229 gridData.grabExcessHorizontalSpace = true;
230 fullRangeComposite.setLayoutData(gridData);
231
232 // Histogram
233 fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite);
234
235 // Load the experiment if present
236 fCurrentExperiment = (TmfExperiment<LttngEvent>) TmfExperiment.getCurrentExperiment();
237 if (fCurrentExperiment != null)
238 loadExperiment();
239 }
240
241 @Override
242 @SuppressWarnings("unchecked")
243 public void setFocus() {
244 TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) TmfExperiment.getCurrentExperiment();
245 if ((experiment != null) && (experiment != fCurrentExperiment)) {
246 fCurrentExperiment = experiment;
247 initializeHistograms();
248 }
249 fParent.redraw();
250 }
251
252 // ------------------------------------------------------------------------
253 // Accessors
254 // ------------------------------------------------------------------------
255
256 public TmfTimeRange getTimeRange() {
257 return new TmfTimeRange(new TmfTimestamp(fWindowStartTime, TIME_SCALE), new TmfTimestamp(fWindowEndTime,
258 TIME_SCALE));
259 }
260
261 // ------------------------------------------------------------------------
262 // Operations
263 // ------------------------------------------------------------------------
264
265 public void updateCurrentEventTime(long newTime) {
266 if (fCurrentExperiment != null) {
267 TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(newTime, TIME_SCALE), TmfTimestamp.BigCrunch);
268 HistogramRequest request = new HistogramRequest(fTimeRangeHistogram.getDataModel(), timeRange, 0, 1, ExecutionType.FOREGROUND) {
269 @Override
270 public void handleData(LttngEvent event) {
271 if (event != null) {
272 TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, event.getTimestamp());
273 TmfSignalManager.dispatchSignal(signal);
274 }
275 }
276 };
277 fCurrentExperiment.sendRequest(request);
278 }
279 }
280
281 public void updateTimeRange(long startTime, long endTime) {
282 if (fCurrentExperiment != null) {
283 // Build the new time range; keep the current time
284 TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(startTime, TIME_SCALE), new TmfTimestamp(
285 endTime, TIME_SCALE));
286 TmfTimestamp currentTime = new TmfTimestamp(fCurrentTimestamp, TIME_SCALE);
287
288 fTimeSpanControl.setValue(endTime - startTime);
289
290 // Send the FW signal
291 TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange, currentTime);
292 TmfSignalManager.dispatchSignal(signal);
293 }
294 }
295
296 public synchronized void updateTimeRange(long newDuration) {
297 if (fCurrentExperiment != null) {
298 long delta = newDuration - fWindowSpan;
299 long newStartTime = fWindowStartTime + delta / 2;
300 setNewRange(newStartTime, newDuration);
301 }
302 }
303
304 private void setNewRange(long startTime, long duration) {
305 if (startTime < fExperimentStartTime)
306 startTime = fExperimentStartTime;
307
308 long endTime = startTime + duration;
309 if (endTime > fExperimentEndTime) {
310 endTime = fExperimentEndTime;
311 if (endTime - duration > fExperimentStartTime)
312 startTime = endTime - duration;
313 else {
314 startTime = fExperimentStartTime;
315 }
316 }
317 updateTimeRange(startTime, endTime);
318 }
319
320 // ------------------------------------------------------------------------
321 // Signal handlers
322 // ------------------------------------------------------------------------
323
324 @TmfSignalHandler
325 @SuppressWarnings("unchecked")
326 public void experimentSelected(TmfExperimentSelectedSignal<LttngEvent> signal) {
327 assert (signal != null);
328 fCurrentExperiment = (TmfExperiment<LttngEvent>) signal.getExperiment();
329 loadExperiment();
330 }
331
332 private void loadExperiment() {
333 initializeHistograms();
334 fParent.redraw();
335 }
336
337 @TmfSignalHandler
338 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
339
340 if (signal.getExperiment() != fCurrentExperiment) {
341 return;
342 }
343
344 boolean drawTimeRangeHistogram = fExperimentStartTime == 0;
345 TmfTimeRange fullRange = signal.getRange();
346
347 fExperimentStartTime = fullRange.getStartTime().getValue();
348 fExperimentEndTime = fullRange.getEndTime().getValue();
349
350 fFullTraceHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
351 fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
352
353 if (drawTimeRangeHistogram) {
354 fCurrentTimestamp = fExperimentStartTime;
355 fCurrentEventTimeControl.setValue(fCurrentTimestamp);
356 fFullTraceHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
357 fTimeRangeHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
358 sendTimeRangeRequest(fExperimentStartTime, fExperimentStartTime + INITIAL_WINDOW_SPAN);
359 }
360
361 sendFullRangeRequest(fullRange);
362 }
363
364 @TmfSignalHandler
365 public void currentTimeUpdated(TmfTimeSynchSignal signal) {
366 // Because this can't happen :-)
367 assert (signal != null);
368
369 // Update the selected event time
370 TmfTimestamp currentTime = signal.getCurrentTime();
371 fCurrentTimestamp = currentTime.getValue();
372
373 // Notify the relevant widgets
374 fFullTraceHistogram.setCurrentEvent(fCurrentTimestamp);
375 fTimeRangeHistogram.setCurrentEvent(fCurrentTimestamp);
376 fCurrentEventTimeControl.setValue(fCurrentTimestamp);
377 }
378
379 @TmfSignalHandler
380 public void timeRangeUpdated(TmfRangeSynchSignal signal) {
381 // Because this can't happen :-)
382 assert (signal != null);
383
384 if (fCurrentExperiment != null) {
385 // Update the time range
386 fWindowStartTime = signal.getCurrentRange().getStartTime().getValue();
387 fWindowEndTime = signal.getCurrentRange().getEndTime().getValue();
388 fWindowSpan = fWindowEndTime - fWindowStartTime;
389
390 // Notify the relevant widgets
391 sendTimeRangeRequest(fWindowStartTime, fWindowEndTime);
392 fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan);
393 fTimeSpanControl.setValue(fWindowSpan);
394 }
395 }
396
397 // ------------------------------------------------------------------------
398 // Helper functions
399 // ------------------------------------------------------------------------
400
401 private void initializeHistograms() {
402 TmfTimeRange fullRange = updateExperimentTimeRange(fCurrentExperiment);
403
404 fTimeRangeHistogram.clear();
405 fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
406 fTimeRangeHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
407 fTimeRangeHistogram.setCurrentEvent(fExperimentStartTime);
408
409 fFullTraceHistogram.clear();
410 fFullTraceHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
411 fFullTraceHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
412 fFullTraceHistogram.setCurrentEvent(fExperimentStartTime);
413
414 fWindowStartTime = fExperimentStartTime;
415 fWindowSpan = INITIAL_WINDOW_SPAN;
416 fWindowEndTime = fWindowStartTime + fWindowSpan;
417
418 fCurrentEventTimeControl.setValue(fExperimentStartTime);
419 fTimeSpanControl.setValue(fWindowSpan);
420
421 sendTimeRangeRequest(fExperimentStartTime, fExperimentStartTime + fWindowSpan);
422 sendFullRangeRequest(fullRange);
423 }
424
425 private TmfTimeRange updateExperimentTimeRange(TmfExperiment<LttngEvent> experiment) {
426 fExperimentStartTime = 0;
427 fExperimentEndTime = 0;
428 fCurrentTimestamp = 0;
429
430 TmfTimeRange timeRange = fCurrentExperiment.getTimeRange();
431 if (timeRange != TmfTimeRange.Null) {
432 fExperimentStartTime = timeRange.getStartTime().getValue();
433 fExperimentEndTime = timeRange.getEndTime().getValue();
434 fCurrentTimestamp = fExperimentStartTime;
435 }
436 return timeRange;
437 }
438
439 private void sendTimeRangeRequest(long startTime, long endTime) {
440 if (fTimeRangeRequest != null && !fTimeRangeRequest.isCompleted()) {
441 fTimeRangeRequest.cancel();
442 }
443 TmfTimestamp startTS = new TmfTimestamp(startTime, TIME_SCALE);
444 TmfTimestamp endTS = new TmfTimestamp(endTime, TIME_SCALE);
445 TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS);
446
447 fTimeRangeHistogram.clear();
448 fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
449 fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(), timeRange, ExecutionType.FOREGROUND);
450 fCurrentExperiment.sendRequest(fTimeRangeRequest);
451 }
452
453 private void sendFullRangeRequest(TmfTimeRange fullRange) {
454 if (fFullTraceRequest != null && !fFullTraceRequest.isCompleted()) {
455 fFullTraceRequest.cancel();
456 }
457 fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(), fullRange, (int) fFullTraceHistogram.fDataModel.getNbEvents(),
458 ExecutionType.BACKGROUND);
459 fCurrentExperiment.sendRequest(fFullTraceRequest);
460 }
461
462 }
This page took 0.040883 seconds and 5 git commands to generate.