2010-10-27 Francois Chouinard <fchouinard@gmail.com> Contribution for Bug316467
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / views / histogram / HistogramView.java
CommitLineData
6e512b93
ASL
1/*******************************************************************************
2 * Copyright (c) 2009 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:
b59134e1 10 * William Bourque - Initial API and implementation
3e9fdb8b
FC
11 *
12 * Modifications:
13 * 2010-06-10 Yuriy Vashchuk - GUI reorganisation, simplification and some
14 * related code improvements.
f05aabed
FC
15 * 2010-06-20 Yuriy Vashchuk - Histograms optimisation.
16 * 2010-07-16 Yuriy Vashchuk - Histogram Canvas Heritage correction
6e512b93 17 *******************************************************************************/
3e9fdb8b 18
6e512b93
ASL
19package org.eclipse.linuxtools.lttng.ui.views.histogram;
20
b59134e1
WB
21import org.eclipse.linuxtools.lttng.event.LttngEvent;
22import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
23import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
833a21aa 24import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
b59134e1 25import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
550d787e
FC
26import org.eclipse.linuxtools.tmf.request.ITmfDataRequest;
27import org.eclipse.linuxtools.tmf.request.ITmfDataRequest.ExecutionType;
ff4ed569 28import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal;
ed4b3b9f 29import org.eclipse.linuxtools.tmf.signal.TmfRangeSynchSignal;
b59134e1
WB
30import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
31import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;
550d787e 32import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
b59134e1
WB
33import org.eclipse.linuxtools.tmf.ui.views.TmfView;
34import org.eclipse.swt.SWT;
7ef9ae3f
WB
35import org.eclipse.swt.events.ControlEvent;
36import org.eclipse.swt.events.ControlListener;
6cf16d22 37import org.eclipse.swt.graphics.Font;
833a21aa 38import org.eclipse.swt.graphics.FontData;
b59134e1 39import org.eclipse.swt.layout.GridData;
252ae4bd 40import org.eclipse.swt.layout.GridLayout;
6e512b93 41import org.eclipse.swt.widgets.Composite;
833a21aa 42import org.eclipse.swt.widgets.Text;
6e512b93 43
544fe9b7
WB
44/**
45 * <b><u>HistogramView</u></b>
46 * <p>
47 * View that contain an visual approach to the window that control the request.
48 * This is intended to replace the TimeFrameView
49 * <p>
1a971e96 50 * This view is composed of 2 canvas, one for the whole experiment and one for the selected window in the experiment.
544fe9b7
WB
51 * It also contain a certain number of controls to print or change informations about the experiment.
52 */
7ef9ae3f 53public class HistogramView extends TmfView implements ControlListener {
544fe9b7
WB
54
55 // *** TODO ***
56 // Here is what's left to do in this view
57 //
3e9fdb8b 58 // 1- Make sure the interval time is small enough on very big trace (bug 311930)
1155ca9f
WB
59 // The interval time of the content is dynamically assigned from the screen width and trace duration.
60 // However, on very big trace (more than 1 hour), we could end up with time interval that are > 1 seconds,
61 // which is not very precise.
62 // An algorithm need to be implemented to make sure we "increase" the number of interval in the content if
63 // their precision is getting too bad.
64 //
65 // 2- Make sure all control are thread safe (bug 309348)
544fe9b7
WB
66 // Right now, all the basic controls (i.e. Text and Label) are sensible to "Thread Access Exception" if
67 // updated from different threads; we need to carefully decide when/where to redraw them.
68 // This is a real problem since there is a lot of thread going on in this view.
69 // All basic control should be subclassed to offer "Asynchronous" functions.
1155ca9f
WB
70 //
71 // 3- Implement a "preferences view" for the HistogramView (bug 311935)
3e9fdb8b 72 // There is a lot of adjustable preferences in the view, however there is no way to adjust them right now
1155ca9f
WB
73 // at run time. There should be a view of some kind of "menu" to allow the user to change them while executing.
74 // Most of the pertinent values are in HistogramConstant.java or in this file.
544fe9b7 75
62d1696a 76 public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.histogram";
b59134e1 77
7c1540ab
WB
78 // "Minimum" screen width size. On smaller screen, we will apply several space saving technique
79 private static final int SCREEN_SMALL_IF_SMALLER_THAN = 1600;
80
3e9fdb8b
FC
81/*
82 // 2010-06-20 Yuriy: We will use the dynamic height.
83 // Size of the "full trace" canvas
833a21aa 84 private static final int FULL_TRACE_CANVAS_HEIGHT = 25;
3e9fdb8b 85*/
833a21aa 86 private static final int FULL_TRACE_BAR_WIDTH = 1;
7ef9ae3f 87 private static final double FULL_TRACE_DIFFERENCE_TO_AVERAGE = 1.5;
833a21aa 88
544fe9b7 89 // Size of the "Selected Window" canvas
3e9fdb8b
FC
90/*
91 // 2010-06-20 Yuriy
544fe9b7 92 private static final int SELECTED_WINDOW_CANVAS_WIDTH = 300;
7ef9ae3f 93 private static final int SMALL_SELECTED_WINDOW_CANVAS_WIDTH = 200;
544fe9b7 94 private static final int SELECTED_WINDOW_CANVAS_HEIGHT = 60;
3e9fdb8b 95*/
833a21aa
WB
96 private static final int SELECTED_WINDOW_BAR_WIDTH = 1;
97 private static final double SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE = 10.0;
98
3e9fdb8b 99 // For the two "events" label (Max and Min number of events in the selection), we force a width
833a21aa 100 // This will prevent the control from moving horizontally if the number of events in the selection varies
3fda53ab 101 private static final int NB_EVENTS_FIXED_WIDTH = 50;
833a21aa 102
833a21aa
WB
103 // The "small font" height used to display time will be "default font" minus this constant
104 private static final int SMALL_FONT_MODIFIER = 2;
7c1540ab 105 private static final int VERY_SMALL_FONT_MODIFIER = 4;
ecfd1d41
WB
106
107 // *** TODO ***
108 // This need to be changed as soon the framework implement a "window"
f6b14ce2
FC
109// private static long DEFAULT_WINDOW_SIZE = (10L * 100 * 1000 * 1000); // 1sec
110 private static long DEFAULT_WINDOW_SIZE = (1L * 100 * 1000 * 1000); // .1sec
ecfd1d41 111
544fe9b7 112 // The last experiment received/used by the view
ecfd1d41 113 private TmfExperiment<LttngEvent> lastUsedExperiment = null;
b59134e1 114
7c1540ab
WB
115 // Parent of the view
116 private Composite parent = null;
117
544fe9b7 118 // Request and canvas for the "full trace" part
b59134e1 119 private HistogramRequest dataBackgroundFullRequest = null;
f05aabed 120 private static ParentHistogramCanvas fullExperimentCanvas = null;
b59134e1 121
544fe9b7 122 // Request and canvas for the "selected window"
ecfd1d41 123 private HistogramRequest selectedWindowRequest = null;
f05aabed 124 private static ChildrenHistogramCanvas selectedWindowCanvas = null;
b59134e1 125
544fe9b7
WB
126 // Content of the timeTextGroup
127 // Since the user can modify them with erroneous value,
128 // we will keep track of the value internally
1406f802 129 private long currentEventTime = 0L;
7c1540ab 130
544fe9b7
WB
131 // *** All the UI control below
132 //
133 // NOTE : All textboxes will be READ_ONLY.
134 // So the user will be able to select/copy the value in them but not to change it
833a21aa
WB
135 private Text txtExperimentStartTime = null;
136 private Text txtExperimentStopTime = null;
137
138 private Text txtWindowStartTime = null;
139 private Text txtWindowStopTime = null;
7c1540ab
WB
140 private Text txtWindowMaxNbEvents = null;
141 private Text txtWindowMinNbEvents = null;
833a21aa 142
3e9fdb8b 143 // We move the time label to header from TimeTextGroup.java
1a971e96
FC
144// protected static final String NANOSEC_LABEL = "(sec)";
145// private static final String WINDOW_TIMERANGE_LABEL_TEXT = "Window Timerange, " + NANOSEC_LABEL;
146// private static final String WINDOW_CURRENT_TIME_LABEL_TEXT = "Cursor Centered on, " + NANOSEC_LABEL;
147// private static final String EVENT_CURRENT_TIME_LABEL_TEXT = "Current Event Time, " + NANOSEC_LABEL;
148 private static final String WINDOW_TIMESPAN_LABEL_TEXT = "Window Span (sec)";
149 private static final String WINDOW_CENTER_TIME_LABEL_TEXT = "Window Center (sec)";
150 private static final String CURRENT_EVENT_TIME_LABEL_TEXT = "Current Event (sec)";
151 private TimeTextGroup ntgWindowTimeSpan = null;
152 private TimeTextGroup ntgWindowCenterTime = null;
088c1d4e
WB
153 private TimeTextGroup ntgCurrentEventTime = null;
154
544fe9b7 155 /**
1a971e96 156 * Default constructor of the view
544fe9b7 157 */
6e512b93 158 public HistogramView() {
b59134e1 159 super(ID);
6e512b93 160 }
b59134e1 161
544fe9b7
WB
162 /**
163 * Create the UI controls of this view
164 *
165 * @param parent The composite parent of this view
166 */
6e512b93 167 @Override
7c1540ab
WB
168 public void createPartControl(Composite newParent) {
169 // Save the parent
170 parent = newParent;
b59134e1 171
833a21aa 172 // Default font
6cf16d22 173 Font font = parent.getFont();
833a21aa 174 FontData tmpFontData = font.getFontData()[0];
833a21aa
WB
175
176
7c1540ab
WB
177 Font smallFont = null;
178 int nbEventWidth = -1;
7ef9ae3f 179 int selectedCanvasWidth = -1;
7c1540ab
WB
180 boolean doesTimeTextGroupNeedAdjustment = false;
181
182 // Calculate if we need "small screen" fixes
183 if ( parent.getDisplay().getBounds().width < SCREEN_SMALL_IF_SMALLER_THAN ) {
3e9fdb8b 184
1a971e96 185 // A lot smaller font for timestamp
7c1540ab
WB
186 smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight() - VERY_SMALL_FONT_MODIFIER, tmpFontData.getStyle());
187
3e9fdb8b
FC
188/*
189 // 2010-06-20 Yuriy
7ef9ae3f
WB
190 // Smaller selection window canvas
191 selectedCanvasWidth = SMALL_SELECTED_WINDOW_CANVAS_WIDTH;
3e9fdb8b 192*/
7c1540ab
WB
193 // Smaller event number text field
194 nbEventWidth = NB_EVENTS_FIXED_WIDTH/2;
195
196 // Tell the text group to ajust
197 doesTimeTextGroupNeedAdjustment = true;
3e9fdb8b
FC
198
199 } else {
200
7c1540ab
WB
201 // Slightly smaller font for timestamp
202 smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight() - SMALL_FONT_MODIFIER, tmpFontData.getStyle());
203 // Usual size for selected window and event number text field
204 nbEventWidth = NB_EVENTS_FIXED_WIDTH;
3e9fdb8b
FC
205/*
206 // 2010-06-20 Yuriy
7c1540ab 207 selectedCanvasWidth = SELECTED_WINDOW_CANVAS_WIDTH;
3e9fdb8b 208*/
7c1540ab
WB
209 // No ajustement needed by the text group
210 doesTimeTextGroupNeedAdjustment = false;
3e9fdb8b 211
7c1540ab 212 }
3e9fdb8b 213
7c1540ab 214
3e9fdb8b 215 /////////////////////////////////////////////////////////////////////////////////////
833a21aa
WB
216 // Layout for the whole view, other elements will be in a child composite of this one
217 // Contains :
218 // Composite layoutSelectionWindow
219 // Composite layoutTimesSpinner
220 // Composite layoutExperimentHistogram
3e9fdb8b
FC
221 /////////////////////////////////////////////////////////////////////////////////////
222 Composite layoutFullView = new Composite(parent, SWT.FILL);
833a21aa
WB
223 GridLayout gridFullView = new GridLayout();
224 gridFullView.numColumns = 2;
544fe9b7
WB
225 gridFullView.horizontalSpacing = 0;
226 gridFullView.verticalSpacing = 0;
833a21aa
WB
227 gridFullView.marginHeight = 0;
228 gridFullView.marginWidth = 0;
229 layoutFullView.setLayout(gridFullView);
3e9fdb8b 230
833a21aa 231
3e9fdb8b 232 /////////////////////////////////////////////////////////////////////////////////////
1a971e96 233 // Layout that contain the time spinners
833a21aa 234 // Contains :
1a971e96
FC
235 // NanosecTextGroup ntgCurrentEventTime
236 // NanosecTextGroup ntgTimeRangeWindow
237 // NanosecTextGroup ntgCurrentWindowTime
3e9fdb8b 238 /////////////////////////////////////////////////////////////////////////////////////
1a971e96 239 Composite layoutTimeSpinners = new Composite(layoutFullView, SWT.NONE);
833a21aa 240 GridLayout gridTimesSpinner = new GridLayout();
544fe9b7 241 gridTimesSpinner.numColumns = 3;
833a21aa
WB
242 gridTimesSpinner.marginHeight = 0;
243 gridTimesSpinner.marginWidth = 0;
1a971e96 244 gridTimesSpinner.horizontalSpacing = 5;
544fe9b7 245 gridTimesSpinner.verticalSpacing = 0;
1a971e96
FC
246 gridTimesSpinner.makeColumnsEqualWidth = true;
247 gridTimesSpinner.marginLeft = 5;
248 gridTimesSpinner.marginRight = 5;
249 layoutTimeSpinners.setLayout(gridTimesSpinner);
833a21aa 250
3e9fdb8b
FC
251 GridData gridDataCurrentEvent = new GridData();
252 gridDataCurrentEvent.horizontalAlignment = SWT.LEFT;
253 gridDataCurrentEvent.verticalAlignment = SWT.CENTER;
1a971e96 254 ntgCurrentEventTime = new TimeTextGroup(this, layoutTimeSpinners, SWT.BORDER, SWT.BORDER, CURRENT_EVENT_TIME_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment);
3e9fdb8b 255 ntgCurrentEventTime.setLayoutData(gridDataCurrentEvent);
833a21aa 256
1a971e96
FC
257 GridData gridDataTimeSpan = new GridData();
258 gridDataTimeSpan.horizontalAlignment = SWT.CENTER;
259 gridDataTimeSpan.verticalAlignment = SWT.CENTER;
260 ntgWindowTimeSpan = new TimeTextGroup(this, layoutTimeSpinners, SWT.BORDER, SWT.BORDER, WINDOW_TIMESPAN_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment);
261 ntgWindowTimeSpan.setLayoutData(gridDataTimeSpan);
3e9fdb8b 262
1a971e96
FC
263 GridData gridDataWindowCenter = new GridData();
264 gridDataWindowCenter.horizontalAlignment = SWT.RIGHT;
265 gridDataWindowCenter.verticalAlignment = SWT.CENTER;
266 ntgWindowCenterTime = new TimeTextGroup(this, layoutTimeSpinners, SWT.BORDER, SWT.BORDER, WINDOW_CENTER_TIME_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment);
267 ntgWindowCenterTime.setLayoutData(gridDataWindowCenter);
833a21aa
WB
268
269
3e9fdb8b
FC
270 /////////////////////////////////////////////////////////////////////////////////////
271 // Layout that contain the SelectionWindow
272 // Contains :
273 // Label txtWindowStartTime
274 // Label txtWindowStopTime
275 // Label txtWindowMaxNbEvents
276 // Label txtWindowMinNbEvents
277 // ChildrenHistogramCanvas selectedWindowCanvas
278 /////////////////////////////////////////////////////////////////////////////////////
279 Composite layoutSelectionWindow = new Composite(layoutFullView, SWT.FILL);
280 GridLayout gridSelectionWindow = new GridLayout();
281 gridSelectionWindow.numColumns = 3;
282 gridSelectionWindow.marginHeight = 0;
1a971e96
FC
283 gridSelectionWindow.marginWidth = 2;
284 gridSelectionWindow.marginTop = 5;
3e9fdb8b
FC
285 gridSelectionWindow.horizontalSpacing = 0;
286 gridSelectionWindow.verticalSpacing = 0;
287 layoutSelectionWindow.setLayout(gridSelectionWindow);
288
289 GridData gridDataSelectionWindow = new GridData();
290 gridDataSelectionWindow.horizontalAlignment = SWT.FILL;
291 gridDataSelectionWindow.verticalAlignment = SWT.FILL;
292 layoutSelectionWindow.setLayoutData(gridDataSelectionWindow);
833a21aa 293
3e9fdb8b
FC
294 GridData gridDataSelectionWindowCanvas = new GridData();
295 gridDataSelectionWindowCanvas.horizontalSpan = 2;
296 gridDataSelectionWindowCanvas.verticalSpan = 2;
297 gridDataSelectionWindowCanvas.horizontalAlignment = SWT.FILL;
298 gridDataSelectionWindowCanvas.grabExcessHorizontalSpace = true;
299 gridDataSelectionWindowCanvas.verticalAlignment = SWT.FILL;
300/*
301 // 2010-06-20 Yuriy
833a21aa
WB
302 gridDataSelectionWindowCanvas.heightHint = SELECTED_WINDOW_CANVAS_HEIGHT;
303 gridDataSelectionWindowCanvas.minimumHeight = SELECTED_WINDOW_CANVAS_HEIGHT;
3e9fdb8b 304*/
7c1540ab
WB
305 gridDataSelectionWindowCanvas.widthHint = selectedCanvasWidth;
306 gridDataSelectionWindowCanvas.minimumWidth = selectedCanvasWidth;
833a21aa
WB
307 selectedWindowCanvas = new ChildrenHistogramCanvas(this, layoutSelectionWindow, SWT.BORDER);
308 selectedWindowCanvas.setLayoutData(gridDataSelectionWindowCanvas);
309
3e9fdb8b
FC
310 GridData gridDataWindowMaxEvents = new GridData();
311 gridDataWindowMaxEvents.horizontalAlignment = SWT.RIGHT;
312 gridDataWindowMaxEvents.verticalAlignment = SWT.TOP;
833a21aa 313 // Force a width, to avoid the control to enlarge if the number of events change
7c1540ab
WB
314 gridDataWindowMaxEvents.minimumWidth = nbEventWidth;
315 txtWindowMaxNbEvents = new Text(layoutSelectionWindow, SWT.READ_ONLY);
316 txtWindowMaxNbEvents.setFont(smallFont);
317 txtWindowMaxNbEvents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
318 txtWindowMaxNbEvents.setEditable(false);
3e9fdb8b 319 txtWindowMaxNbEvents.setText("0");
7c1540ab 320 txtWindowMaxNbEvents.setLayoutData(gridDataWindowMaxEvents);
833a21aa 321
3e9fdb8b
FC
322 GridData gridDataWindowMinEvents = new GridData();
323 gridDataWindowMinEvents.horizontalAlignment = SWT.RIGHT;
324 gridDataWindowMinEvents.verticalAlignment = SWT.BOTTOM;
833a21aa 325 // Force a width, to avoid the control to enlarge if the number of events change
7c1540ab
WB
326 gridDataWindowMinEvents.minimumWidth = nbEventWidth;
327 txtWindowMinNbEvents = new Text(layoutSelectionWindow, SWT.READ_ONLY);
328 txtWindowMinNbEvents.setFont(smallFont);
329 txtWindowMinNbEvents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
330 txtWindowMinNbEvents.setEditable(false);
3e9fdb8b 331 txtWindowMinNbEvents.setText("0");
7c1540ab 332 txtWindowMinNbEvents.setLayoutData(gridDataWindowMinEvents);
833a21aa 333
3e9fdb8b
FC
334 GridData gridDataWindowStart = new GridData();
335 gridDataWindowStart.horizontalAlignment = SWT.LEFT;
336 gridDataWindowStart.verticalAlignment = SWT.BOTTOM;
833a21aa
WB
337 txtWindowStartTime = new Text(layoutSelectionWindow, SWT.READ_ONLY);
338 txtWindowStartTime.setFont(smallFont);
339 txtWindowStartTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
340 txtWindowStartTime.setEditable(false);
3e9fdb8b 341 txtWindowStartTime.setText("0.000000000");
833a21aa
WB
342 txtWindowStartTime.setLayoutData(gridDataWindowStart);
343
3e9fdb8b
FC
344 GridData gridDataWindowStop = new GridData();
345 gridDataWindowStop.horizontalAlignment = SWT.RIGHT;
346 gridDataWindowStop.verticalAlignment = SWT.BOTTOM;
833a21aa
WB
347 txtWindowStopTime = new Text(layoutSelectionWindow, SWT.READ_ONLY);
348 txtWindowStopTime.setFont(smallFont);
349 txtWindowStopTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
350 txtWindowStopTime.setEditable(false);
3e9fdb8b 351 txtWindowStopTime.setText("0.000000000");
833a21aa
WB
352 txtWindowStopTime.setLayoutData(gridDataWindowStop);
353
3e9fdb8b
FC
354
355/*
356 // 2010-06-10 Yuriy: NOT NEEDED AFTER GUI IMPROVEMENTS. WORK FINE WITOUT THIS HACK
7ef9ae3f
WB
357 // *** HACK ***
358 // To align properly AND to make sure the canvas size is fixed, we NEED to make sure all "section" of the
359 // gridlayout are taken (and if possible of a fixed size).
360 // However, SWT is VERY VERY DUMB and won't consider griddata that contain no control.
361 // Since there will be missing a section, the SelectedWindowCanvas + NbEventsText will take 3 spaces, but
362 // startTimeText + stopTimeText will take only 2 (as if empty the other griddata of 1 will get ignored).
363 // StopTime will then take over the missing space; I want to align "stopTime" right on the end of canvas, so
364 // the added space to stop time would make it being aligned improperly
365 // So I NEED the empty griddata to be considered!
366 // Visually :
367 // |---------------|---------------|-----------|
368 // |SelectionCanvas SelectionCanvas|NbEventText|
369 // |SelectionCanvas SelectionCanvas|NbEventText|
370 // |---------------|---------------|-----------|
371 // |StartTime | StopTime| ??? |
372 // |---------------|---------------|-----------|
373 //
374 // So since SWT will only consider griddata with control,
375 // I need to create a totally useless control in the ??? section.
1155ca9f 376 // That's ugly, useless and it is generally a bad practice.
7ef9ae3f
WB
377 //
378 // *** SUB-HACK ***
379 // Other interesting fact about SWT : the way it draws (Fill/Expand control in grid) will change if
1406f802 380 // the control is a Text or a Label.
7ef9ae3f
WB
381 // A Label here will be "pushed" by startTime/stopTime Text and won't fill the full space as NbEventText.
382 // A Text here will NOT be "pushed" and would give a nice visual output.
383 // (NB : No, I am NOT kidding, try it for yourself!)
384 //
385 // Soooooo I guess I will use a Text here. Way to go SWT!
1155ca9f
WB
386 // Downside is that disabled textbox has a slightly different color (even if you force it yourself) so if I want
387 // to make the text "invisible", I have to keep it enabled (but read only), so it can be clicked on.
7ef9ae3f
WB
388 //
389 // Label uselessControlToByPassSWTStupidBug = new Label(layoutSelectionWindow, SWT.BORDER); // WON'T align correctly!!!
3e9fdb8b
FC
390 //GridData gridDataSpacer = new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1);
391 GridData gridDataSpacer = new GridData();
392 gridDataWindowStop.horizontalAlignment = SWT.FILL;
393 gridDataWindowStop.verticalAlignment = SWT.TOP;
394 gridDataSpacer.minimumWidth = nbEventWidth;
7ef9ae3f
WB
395 Text uselessControlToByPassSWTStupidBug = new Text(layoutSelectionWindow, SWT.READ_ONLY); // WILL align correctly!!!
396 uselessControlToByPassSWTStupidBug.setEditable(false);
397 uselessControlToByPassSWTStupidBug.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
398 uselessControlToByPassSWTStupidBug.setLayoutData(gridDataSpacer);
3e9fdb8b 399*/
7ef9ae3f
WB
400
401
3e9fdb8b
FC
402 /////////////////////////////////////////////////////////////////////////////////////
403 // Layout that contain the complete experiment histogram and related controls.
404 // Contains :
405 // ParentHistogramCanvas fullExperimentCanvas
406 // Text txtExperimentStartTime
407 // Text txtExperimentStopTime
408 /////////////////////////////////////////////////////////////////////////////////////
409 Composite layoutExperimentHistogram = new Composite(layoutFullView, SWT.FILL);
7ef9ae3f 410
3e9fdb8b
FC
411 GridLayout gridExperimentHistogram = new GridLayout();
412 gridExperimentHistogram.numColumns = 2;
413 gridExperimentHistogram.marginHeight = 0;
414 gridExperimentHistogram.marginWidth = 0;
415 gridExperimentHistogram.horizontalSpacing = 0;
416 gridExperimentHistogram.verticalSpacing = 0;
1a971e96
FC
417 gridExperimentHistogram.marginLeft = 5;
418 gridExperimentHistogram.marginRight = 5;
3e9fdb8b 419 layoutExperimentHistogram.setLayout(gridExperimentHistogram);
833a21aa 420
3e9fdb8b
FC
421/*
422 // 2010-06-10 Yuriy: NOT NEEDED AFTER GUI IMPROVEMENTS
423 GridData gridDataExperimentHistogram = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
424 layoutExperimentHistogram.setLayoutData(gridDataExperimentHistogram);
425*/
833a21aa 426
544fe9b7 427 // *** Everything related to the experiment canvas is below
3e9fdb8b
FC
428 GridData gridDataExperimentCanvas = new GridData();
429 gridDataExperimentCanvas.horizontalSpan = 2;
430 gridDataExperimentCanvas.horizontalAlignment = SWT.FILL;
431 gridDataExperimentCanvas.grabExcessHorizontalSpace = true;
432 gridDataExperimentCanvas.verticalAlignment = SWT.FILL;
433 gridDataExperimentCanvas.grabExcessVerticalSpace = true;
434/*
435 // 2010-06-20 Yuriy: We use the dynamic height.
833a21aa
WB
436 gridDataExperimentCanvas.heightHint = FULL_TRACE_CANVAS_HEIGHT;
437 gridDataExperimentCanvas.minimumHeight = FULL_TRACE_CANVAS_HEIGHT;
3e9fdb8b 438*/
544fe9b7
WB
439 fullExperimentCanvas = new ParentHistogramCanvas(this, layoutExperimentHistogram, SWT.BORDER);
440 fullExperimentCanvas.setLayoutData(gridDataExperimentCanvas);
3e9fdb8b 441 layoutExperimentHistogram.setLayoutData(gridDataExperimentCanvas);
833a21aa 442
3e9fdb8b
FC
443 GridData gridDataExperimentStart = new GridData();
444 gridDataExperimentStart.horizontalAlignment = SWT.LEFT;
445 gridDataExperimentStart.verticalAlignment = SWT.BOTTOM;
833a21aa
WB
446 txtExperimentStartTime = new Text(layoutExperimentHistogram, SWT.READ_ONLY);
447 txtExperimentStartTime.setFont(smallFont);
3e9fdb8b 448 txtExperimentStartTime.setText("0.000000000");
833a21aa
WB
449 txtExperimentStartTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
450 txtExperimentStartTime.setEditable(false);
451 txtExperimentStartTime.setLayoutData(gridDataExperimentStart);
452
3e9fdb8b
FC
453 GridData gridDataExperimentStop = new GridData();
454 gridDataExperimentStop.horizontalAlignment = SWT.RIGHT;
455 gridDataExperimentStop.verticalAlignment = SWT.BOTTOM;
833a21aa
WB
456 txtExperimentStopTime = new Text(layoutExperimentHistogram, SWT.READ_ONLY);
457 txtExperimentStopTime.setFont(smallFont);
3e9fdb8b 458 txtExperimentStopTime.setText("0.000000000");
833a21aa
WB
459 txtExperimentStopTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
460 txtExperimentStopTime.setEditable(false);
461 txtExperimentStopTime.setLayoutData(gridDataExperimentStop);
6e512b93 462 }
b59134e1 463
544fe9b7
WB
464 // *** FIXME ***
465 // This is mainly used because of a because in the "experimentSelected()" notification, we shouldn't need this
466 /**
467 * Method called when the view receive the focus.<p>
468 * If ExperimentSelected didn't send us a request yet, get the current Experiment and fire requests
469 */
b59134e1 470 @SuppressWarnings("unchecked")
6e512b93
ASL
471 @Override
472 public void setFocus() {
544fe9b7 473 // WARNING : This does not seem to be thread safe
b59134e1
WB
474 TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)TmfExperiment.getCurrentExperiment();
475
476 if ( (dataBackgroundFullRequest == null) && (tmpExperiment != null) ) {
ecfd1d41 477 createCanvasAndRequests(tmpExperiment);
b59134e1 478 }
7ef9ae3f
WB
479
480 // Call a redraw for everything
481 parent.redraw();
6e512b93 482 }
b59134e1 483
544fe9b7
WB
484 /**
485 * Method called when the user select (double-click on) an experiment.<p>
486 * We will create the needed canvas and fire the requests.
487 *
488 * @param signal Signal received from the framework. Contain the experiment.
489 */
b59134e1
WB
490 @SuppressWarnings("unchecked")
491 @TmfSignalHandler
492 public void experimentSelected(TmfExperimentSelectedSignal<LttngEvent> signal) {
ecfd1d41
WB
493 TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)signal.getExperiment();
494 createCanvasAndRequests(tmpExperiment);
495 }
496
3e9fdb8b 497
088c1d4e
WB
498 // *** VERIFY ***
499 // Not sure what this should do since I don't know when it will be called
500 // Let's do the same thing as experimentSelected for now
501 //
544fe9b7
WB
502 /**
503 * Method called when an experiment is updated (??).<p>
7c1540ab 504 * ...for now, do nothing, as udating an experiment running in the background might cause crash
544fe9b7
WB
505 *
506 * @param signal Signal received from the framework. Contain the experiment.
507 */
3e9fdb8b
FC
508/*
509 @SuppressWarnings("unchecked")
088c1d4e 510 @TmfSignalHandler
833a21aa 511 public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
3e9fdb8b
FC
512
513 TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)signal.getExperiment();
514
515 // Make sure the UI object are sane
516 resetControlsContent();
517
518 // Redraw the canvas right away to have something "clean" as soon as we can
519 fullExperimentCanvas.redraw();
520 selectedWindowCanvas.redraw();
521
522 // Recreate the request
523 createCanvasAndRequests(tmpExperiment);
833a21aa 524 }
3e9fdb8b 525*/
833a21aa 526
544fe9b7 527 /**
1a971e96 528 * Method called when synchronization is active and that the user select an event.
544fe9b7
WB
529 * We update the current event timeTextGroup and move the selected window if needed.
530 *
531 * @param signal Signal received from the framework. Contain the event.
532 */
833a21aa
WB
533 @TmfSignalHandler
534 public void currentTimeUpdated(TmfTimeSynchSignal signal) {
544fe9b7 535 // In case we received our own signal
3e9fdb8b 536 if ( (signal != null) && (signal.getSource() != this) ) {
833a21aa 537 TmfTimestamp currentTime = signal.getCurrentTime();
833a21aa 538
544fe9b7 539 // Update the current event controls
088c1d4e
WB
540 currentEventTime = currentTime.getValue();
541 updateSelectedEventTime();
542
544fe9b7
WB
543 // If the given event is outside the selection window, recenter the window
544 if ( isGivenTimestampInSelectedWindow( currentEventTime ) == false) {
1406f802 545 fullExperimentCanvas.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(currentEventTime) );
544fe9b7 546 // Notify control that the window changed
833a21aa 547 windowChangedNotification();
1406f802
WB
548 // Send a broadcast to the framework about the window change
549 sendTmfRangeSynchSignalBroadcast();
833a21aa 550 }
833a21aa
WB
551 }
552 }
553
1406f802
WB
554 @TmfSignalHandler
555 public void synchToTimeRange(TmfRangeSynchSignal signal) {
c1c69938 556 if ( (signal != null) ) {
1406f802
WB
557 if ( lastUsedExperiment != null ) {
558 long currentTime = signal.getCurrentTime().getValue();
559 long windowStart = signal.getCurrentRange().getStartTime().getValue();
560 long windowEnd = signal.getCurrentRange().getEndTime().getValue();
561 long windowTimeWidth = (windowEnd - windowStart);
562
563 // Recenter the window
1406f802 564 fullExperimentCanvas.setSelectedWindowSize(windowTimeWidth);
f05aabed 565 fullExperimentCanvas.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(windowStart + (windowTimeWidth/2)) );
1406f802
WB
566
567 // *** HACK ***
568 // Views could send us incorrect current event value (event outside the current window)
569 // Here we make sure the value is sane, otherwise, we force it as the left border of the window
570 if ( isGivenTimestampInSelectedWindow( currentTime ) == false ) {
571 currentTime = windowStart;
572 }
573 currentEventTime = currentTime;
574
575 // Notify control that the window changed
576 windowChangedNotification();
577
16511734 578 // Make sure we redraw the change
1406f802 579 fullExperimentCanvas.redraw();
1406f802
WB
580 }
581 }
582 }
583
584
544fe9b7
WB
585 /*
586 * Create the canvas needed and issue the requests
587 *
588 * @param newExperiment Experiment we will use for the request
589 */
590 private void createCanvasAndRequests(TmfExperiment<LttngEvent> newExperiment) {
16511734 591 // Save the experiment we are about to use
3cd34850
WB
592 lastUsedExperiment = newExperiment;
593
550d787e
FC
594// // Create a copy of the trace that will be use only by the full experiment request
595// TmfExperiment<LttngEvent> experimentCopy = newExperiment.createTraceCopy();
c1877796 596
3fda53ab
WB
597 // Create the content for the full experiment.
598 // This NEED to be created first, as we use it in the selectedWindowCanvas
3e9fdb8b
FC
599 fullExperimentCanvas.createNewHistogramContent(
600 fullExperimentCanvas.getSize().x,
601 FULL_TRACE_BAR_WIDTH,
602/*
603 // 2010-06-20 Yuriy: We will use the dynamic height.
604 FULL_TRACE_CANVAS_HEIGHT
605*/
606 fullExperimentCanvas.getSize().y / 2,
607 FULL_TRACE_DIFFERENCE_TO_AVERAGE
f05aabed 608 );
550d787e
FC
609
610 TmfTimeRange timeRange = getExperimentTimeRange(newExperiment);
f05aabed
FC
611
612 // We will take the half of the full experiment length in case of bigger window size than the full experiment length
613 if(timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() > DEFAULT_WINDOW_SIZE ) {
614 fullExperimentCanvas.createNewSelectedWindow(
615 timeRange.getStartTime().getValue(),
616 DEFAULT_WINDOW_SIZE
617 );
618 } else {
619 fullExperimentCanvas.createNewSelectedWindow(
620 timeRange.getStartTime().getValue(),
621 (timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() ) / 2
622 );
623 }
624
550d787e
FC
625 currentEventTime = timeRange.getStartTime().getValue();
626
627 // Set the window of the fullTrace canvas visible.
7c1540ab 628 fullExperimentCanvas.getCurrentWindow().setSelectedWindowVisible(true);
550d787e 629 fullExperimentCanvas.getHistogramContent().resetTable(timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue());
f05aabed 630
7c1540ab 631 // Create the content for the selected window.
f05aabed
FC
632 selectedWindowCanvas.createNewHistogramContent(
633 selectedWindowCanvas.getSize().x,
634 SELECTED_WINDOW_BAR_WIDTH,
635 selectedWindowCanvas.getSize().y,
636 SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE
637 );
1155ca9f 638 selectedWindowCanvas.getHistogramContent().resetTable(fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition(), fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition());
6cf16d22 639
1406f802 640 // Make sure the UI object are sane
544fe9b7 641 resetControlsContent();
833a21aa 642
6cf16d22
WB
643 // Redraw the canvas right away to have something "clean" as soon as we can
644 if ( dataBackgroundFullRequest != null ) {
544fe9b7 645 fullExperimentCanvas.redraw();
6cf16d22
WB
646 selectedWindowCanvas.redraw();
647 }
544fe9b7
WB
648 // Nullify the (possible) old request to be sure we start we something clean
649 // Note : this is very important for the order of the request below,
650 // see "TODO" in performSelectedWindowEventsRequest
651 dataBackgroundFullRequest = null;
652 selectedWindowRequest = null;
ecfd1d41 653
544fe9b7
WB
654 // Perform both request.
655 // Order is important here, the small/synchronous request for the selection window should go first
ecfd1d41 656 performSelectedWindowEventsRequest(newExperiment);
550d787e 657 performAllTraceEventsRequest(newExperiment);
ecfd1d41 658 }
550d787e
FC
659
660 // Before completing its indexing, the experiment doesn't know start/end time.
661 // However, LTTng individual traces have this knowledge so we should ask them
662 // directly.
663 private TmfTimeRange getExperimentTimeRange(TmfExperiment<LttngEvent> experiment) {
664 // Before completing its indexing, the experiment doesn't know start/end time.
665 // However, LTTng individual traces have this knowledge so we should ask them
666 // directly.
667 TmfTimestamp startTime = TmfTimestamp.BigCrunch;
668 TmfTimestamp endTime = TmfTimestamp.BigBang;
669 for (ITmfTrace trace : experiment.getTraces()) {
c1c69938 670 TmfTimestamp traceStartTime = trace.getStartTime();
550d787e
FC
671 if (traceStartTime.compareTo(startTime, true) < 0)
672 startTime = traceStartTime;
673 TmfTimestamp traceEndTime = trace.getEndTime();
674 if (traceEndTime.compareTo(endTime, true) > 0)
675 endTime = traceEndTime;
676 }
677 TmfTimeRange tmpRange = new TmfTimeRange(startTime, endTime);
678 return tmpRange;
679 }
680
544fe9b7
WB
681 /**
682 * Perform a new request for the Selection window.<p>
683 * This assume the full experiment canvas has correct information about the selected window;
684 * we need the fullExperimentCanvas' HistogramContent to be created and a selection window to be set.
685 *
686 * @param experiment The experiment we will select from
687 */
ecfd1d41 688 public void performSelectedWindowEventsRequest(TmfExperiment<LttngEvent> experiment) {
252ae4bd 689
3e9fdb8b
FC
690 if(fullExperimentCanvas != null) {
691 HistogramSelectedWindow curSelectedWindow = fullExperimentCanvas.getCurrentWindow();
692
f05aabed
FC
693 TmfTimeRange timeRange = getExperimentTimeRange(experiment);
694
3e9fdb8b
FC
695 // If no selection window exists, we will try to create one;
696 // however this will most likely fail as the content is probably not created either
697 if ( curSelectedWindow == null ) {
f05aabed
FC
698 // We will take the half of the full experiment length in case of bigger window size than the full experiment length
699 if(timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() > DEFAULT_WINDOW_SIZE ) {
700 fullExperimentCanvas.createNewSelectedWindow(
701 timeRange.getStartTime().getValue(),
702 DEFAULT_WINDOW_SIZE
703 );
704 } else {
705 fullExperimentCanvas.createNewSelectedWindow(
706 timeRange.getStartTime().getValue(),
707 (timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() ) / 2
708 );
709 }
3e9fdb8b
FC
710 curSelectedWindow = fullExperimentCanvas.getCurrentWindow();
711 }
712
713 // The request will go from the Left timestamp of the window to the Right timestamp
714 // This assume that out-of-bound value are handled by the SelectionWindow itself
715 LttngTimestamp ts1 = new LttngTimestamp( curSelectedWindow.getTimestampOfLeftPosition() );
716 LttngTimestamp ts2 = new LttngTimestamp( curSelectedWindow.getTimestampOfRightPosition() );
717 TmfTimeRange tmpRange = new TmfTimeRange(ts1, ts2);
718
719 // Set a (dynamic) time interval
720 long intervalTime = ( (ts2.getValue() - ts1.getValue()) / selectedWindowCanvas.getHistogramContent().getNbElement() );
721
1a971e96 722 selectedWindowRequest = performRequest(experiment, selectedWindowCanvas, tmpRange, intervalTime, ExecutionType.FOREGROUND);
3e9fdb8b 723 selectedWindowCanvas.redrawAsynchronously();
ecfd1d41
WB
724 }
725
ecfd1d41
WB
726 }
727
544fe9b7
WB
728 /**
729 * Perform a new request for the full experiment.<p>
730 * NOTE : this is very long, we need to implement a way to run this in parallel (see TODO)
731 *
732 * @param experiment The experiment we will select from
733 */
ecfd1d41 734 public void performAllTraceEventsRequest(TmfExperiment<LttngEvent> experiment) {
b59134e1
WB
735 // Create a new time range from "start" to "end"
736 // That way, we will get "everything" in the trace
550d787e
FC
737// LttngTimestamp ts1 = new LttngTimestamp( experiment.getStartTime() );
738// LttngTimestamp ts2 = new LttngTimestamp( experiment.getEndTime() );
739// TmfTimeRange tmpRange = new TmfTimeRange(ts1, ts2);
740
741 TmfTimeRange tmpRange = getExperimentTimeRange(experiment);
742 TmfTimestamp startTime = tmpRange.getStartTime();
743 TmfTimestamp endTime = tmpRange.getEndTime();
b59134e1 744
ecfd1d41 745 // Set a (dynamic) time interval
550d787e 746 long intervalTime = ( (endTime.getValue() - startTime.getValue()) / fullExperimentCanvas.getHistogramContent().getNbElement() );
b59134e1 747
544fe9b7
WB
748 // *** VERIFY ***
749 // This would enable "fixed interval" instead of dynamic one.
750 // ... we don't need it, do we?
751 //
752 // long intervalTime = ((long)(0.001 * (double)1000000000));
753
754 // *** TODO ***
755 // It would be interesting if there was a way to tell the framework to run the request "in parallel" here.
756 // Mean a completetly independant copy of the Expereiment would be done and we would proceed on that.
757 //
f6b14ce2 758 dataBackgroundFullRequest = performRequest(experiment, fullExperimentCanvas, tmpRange, intervalTime, ExecutionType.BACKGROUND);
f05aabed
FC
759
760
761 fullExperimentCanvas.getCurrentWindow().setWindowXPositionLeft(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition()));
762 fullExperimentCanvas.getCurrentWindow().setWindowXPositionCenter(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition()));
763 fullExperimentCanvas.getCurrentWindow().setWindowXPositionRight(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition()));
764
544fe9b7 765 fullExperimentCanvas.redrawAsynchronously();
b59134e1
WB
766 }
767
768 // *** VERIFY ***
544fe9b7
WB
769 // This function is synchronized, is it a good idea?
770 // Tis is done to make sure requests arrive somewhat in order,
771 // this is especially important when request are issued from different thread.
772 /**
773 * Create a new request from the given data and send it to the framework.<p>
774 * The request will be queued and processed later.
775 *
776 * @param experiment The experiment we will process the request on
777 * @param targetCanvas The canvas that will received the result
778 * @param newRange The range of the request
779 * @param newInterval The interval of time we use to store the result into the HistogramContent
780 */
550d787e 781 private synchronized HistogramRequest performRequest(TmfExperiment<LttngEvent> experiment, HistogramCanvas targetCanvas, TmfTimeRange newRange, long newInterval, ITmfDataRequest.ExecutionType execType) {
b59134e1
WB
782 HistogramRequest returnedRequest = null;
783
ecfd1d41
WB
784 // *** FIXME ***
785 // EVIL BUG!
1406f802 786 // We use int.MAX_VALUE because we want every events BUT we don't know the number inside the range.
ecfd1d41
WB
787 // HOWEVER, this would cause the request to run forever (or until it reach the end of trace).
788 // Seeting an EndTime does not seems to stop the request
550d787e 789 returnedRequest = new HistogramRequest(newRange, Integer.MAX_VALUE, targetCanvas, newInterval, execType );
544fe9b7
WB
790
791 // Send the request to the framework : it will be queued and processed later
b59134e1
WB
792 experiment.sendRequest(returnedRequest);
793
794 return returnedRequest;
795 }
088c1d4e 796
544fe9b7
WB
797 /**
798 * Function used to warn that the selection window changed.<p>
799 * This might be called because the window moved or because its size changed.<p>
800 *
801 * We will update the different control related to the selection window.
802 */
ecfd1d41 803 public void windowChangedNotification() {
833a21aa 804
ecfd1d41 805 if ( lastUsedExperiment != null ) {
544fe9b7 806 // If a request is ongoing, try to stop it
1a971e96 807 if (selectedWindowRequest != null && !selectedWindowRequest.isCompleted()) {
6cf16d22
WB
808 selectedWindowRequest.cancel();
809 }
833a21aa 810
3e9fdb8b 811 if(fullExperimentCanvas != null) {
3e9fdb8b
FC
812 // If the current event time is outside the new window, change the current event
813 // The new current event will be the one closest to the LEFT side of the new window
814 if ( isGivenTimestampInSelectedWindow(currentEventTime) == false ) {
815 currentEventChangeNotification( fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition() );
816 }
817 }
088c1d4e 818
544fe9b7 819 // Perform a new request to read data about the new window
ecfd1d41
WB
820 performSelectedWindowEventsRequest(lastUsedExperiment);
821 }
822 }
823
544fe9b7
WB
824 /**
825 * Function used to tell that the current event changed.<p>
826 * This might be called because the user changed the current event or
827 * because the last current event is now outside the selection window.<p>
828 *
829 * We update the related control and send a signal to notify other views of the new current event.
830 *
831 * @param newCurrentEventTime
832 */
1406f802
WB
833 public void currentEventChangeNotification(long newCurrentEventTime) {
834
088c1d4e
WB
835 // Notify other views in the framework
836 if (currentEventTime != newCurrentEventTime) {
837 currentEventTime = newCurrentEventTime;
838
544fe9b7 839 // Update the UI control
088c1d4e 840 updateSelectedEventTime();
088c1d4e
WB
841 }
842 }
843
1406f802
WB
844 public void sendTmfTimeSynchSignalBroadcast() {
845
846// System.out.println("sendTmfTimeSynchSignalBroadcast " + System.currentTimeMillis());
847
848 // Send a signal to the framework
849 LttngTimestamp tmpTimestamp = new LttngTimestamp(currentEventTime);
850 broadcast(new TmfTimeSynchSignal(this, tmpTimestamp));
851 }
852
ed4b3b9f
WB
853 /**
854 * Function used to tell that the timerange (window) changed.<p>
855 * This will most likely be called if the time window is resized.
856 *
857 * We send a signal to notify other views of the new timerange.
858 */
1406f802
WB
859 public void sendTmfRangeSynchSignalBroadcast() {
860
9b635e61
FC
861 if (TmfExperiment.getCurrentExperiment() == null)
862 return;
863
3e9fdb8b 864 long startTime = fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition();
1406f802
WB
865 if ( startTime < fullExperimentCanvas.getHistogramContent().getStartTime() ) {
866 startTime = fullExperimentCanvas.getHistogramContent().getStartTime();
867 }
868 LttngTimestamp tmpStartTime = new LttngTimestamp(startTime);
869
3e9fdb8b 870 long endTime = fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition();
1406f802
WB
871 if ( endTime > fullExperimentCanvas.getHistogramContent().getEndTime() ) {
872 endTime = fullExperimentCanvas.getHistogramContent().getEndTime();
873 }
874 LttngTimestamp tmpEndTime = new LttngTimestamp(endTime);
1406f802 875
ed4b3b9f
WB
876 TmfTimeRange tmpTimeRange = new TmfTimeRange(tmpStartTime, tmpEndTime);
877 LttngTimestamp tmpEventTime = new LttngTimestamp(currentEventTime);
1406f802 878
ed4b3b9f
WB
879 // Send a signal to the framework
880 broadcast(new TmfRangeSynchSignal(this, tmpTimeRange, tmpEventTime));
881 }
882
544fe9b7
WB
883 /**
884 * Function that will be called when one of the time text group value is changed.<p>
885 * Since we don't (and can't unless we subclass them) know which one, we check them all.
886 */
088c1d4e
WB
887 public void timeTextGroupChangeNotification() {
888
3e9fdb8b
FC
889 if(ntgCurrentEventTime != null) {
890 // If the user changed the current event time, call the notification
891 long newCurrentTime = ntgCurrentEventTime.getValue();
892 if ( newCurrentTime != currentEventTime ) {
893 currentEventChangeNotification( newCurrentTime );
894 // Send a broadcast to the framework about the window change
895 sendTmfTimeSynchSignalBroadcast();
896 }
897 }
088c1d4e 898
1a971e96 899 if(ntgWindowCenterTime != null && fullExperimentCanvas != null) {
3e9fdb8b 900 // If the user changed the selected window time, recenter the window and call the notification
1a971e96 901 long newSelectedWindowTime = ntgWindowCenterTime.getValue();
f05aabed
FC
902 if ( newSelectedWindowTime != fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition() ) {
903 fullExperimentCanvas.setWindowCenterPosition(newSelectedWindowTime);
3e9fdb8b
FC
904 // Send a broadcast to the framework about the window change
905 sendTmfRangeSynchSignalBroadcast();
906 }
088c1d4e
WB
907 }
908
1a971e96 909 if(ntgWindowTimeSpan != null && fullExperimentCanvas != null) {
3e9fdb8b 910 // If the user changed the selected window size, resize the window and call the notification
1a971e96 911 long newSelectedWindowTimeRange = ntgWindowTimeSpan.getValue();
f05aabed
FC
912 if ( newSelectedWindowTimeRange != fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth() ) {
913 fullExperimentCanvas.resizeWindowByAbsoluteTime(newSelectedWindowTimeRange);
3e9fdb8b
FC
914 // Send a broadcast to the framework about the window change
915 sendTmfRangeSynchSignalBroadcast();
916 }
088c1d4e
WB
917 }
918
919 }
920
544fe9b7
WB
921 /**
922 * Getter for the last used experiment.<p>
923 * This might be different than the current experiment or even null.
924 *
925 * @return the last experiment we used in this view
926 */
ecfd1d41
WB
927 public TmfExperiment<LttngEvent> getLastUsedExperiment() {
928 return lastUsedExperiment;
929 }
930
544fe9b7
WB
931 /**
932 * Check if a given timestamp is inside the selection window.<p>
933 * This assume fullExperimentCanvas contain a valid HistogramContent
934 *
935 * @param timestamp the timestamp to check
936 *
937 * @return if the time is inside the selection window or not
938 */
1406f802 939 public boolean isGivenTimestampInSelectedWindow(long timestamp) {
088c1d4e
WB
940 boolean returnedValue = true;
941
544fe9b7 942 // If the content is not set correctly, this will return weird (or even null) result
1155ca9f
WB
943 if ( (timestamp < fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition() ) ||
944 (timestamp > fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition() ) )
088c1d4e
WB
945 {
946 returnedValue = false;
947 }
948
949 return returnedValue;
950 }
951
544fe9b7
WB
952 /**
953 * Reset the content of all Controls.<p>
954 * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
955 */
956 public void resetControlsContent() {
833a21aa
WB
957
958 TmfExperiment<LttngEvent> tmpExperiment = getLastUsedExperiment();
959
544fe9b7 960 // Use the previous Start and End time, or default if they are not available
833a21aa
WB
961 String startTime = null;
962 String stopTime = null;
963 if ( tmpExperiment != null ) {
964 startTime = HistogramConstant.formatNanoSecondsTime( tmpExperiment.getStartTime().getValue() );
965 stopTime = HistogramConstant.formatNanoSecondsTime( tmpExperiment.getEndTime().getValue() );
6cf16d22 966 }
833a21aa
WB
967 else {
968 startTime = HistogramConstant.formatNanoSecondsTime( 0L );
969 stopTime = HistogramConstant.formatNanoSecondsTime( 0L );
970 }
971
972 txtExperimentStartTime.setText( startTime );
973 txtExperimentStopTime.setText( stopTime );
974 txtExperimentStartTime.getParent().layout();
975
7c1540ab
WB
976 txtWindowMaxNbEvents.setText("" + 0);
977 txtWindowMinNbEvents.setText("" + 0);
833a21aa
WB
978 txtWindowStartTime.setText( HistogramConstant.formatNanoSecondsTime( 0L ) );
979 txtWindowStopTime.setText( HistogramConstant.formatNanoSecondsTime( 0L ) );
980 txtWindowStartTime.getParent().layout();
378e7718 981
1a971e96
FC
982 ntgWindowCenterTime.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) );
983 ntgWindowTimeSpan.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) );
16511734
WB
984
985 // Using "startTime" here can avoid an useless TmfTimeSynchSignal here
986 // However it look ugly to have only this time
833a21aa 987 ntgCurrentEventTime.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) );
378e7718
WB
988 }
989
544fe9b7
WB
990 /**
991 * Update the content of the controls related to the full experiment canvas<p>
992 * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
993 */
994 public void updateFullExperimentInformation() {
378e7718 995
3e9fdb8b
FC
996 if(fullExperimentCanvas != null) {
997 String startTime = HistogramConstant.formatNanoSecondsTime( fullExperimentCanvas.getHistogramContent().getStartTime() );
998 String stopTime = HistogramConstant.formatNanoSecondsTime( fullExperimentCanvas.getHistogramContent().getEndTime() );
999
1000 txtExperimentStartTime.setText( startTime );
1001 txtExperimentStopTime.setText( stopTime );
1002 }
833a21aa
WB
1003
1004 // Take one of the parent and call its layout to update control size
1005 // Since both control have the same parent, only one call is needed
1006 txtExperimentStartTime.getParent().layout();
1007
1008 // Update the selected window, just in case
1009 // This should give a better user experience and it is low cost
1010 updateSelectedWindowInformation();
378e7718
WB
1011 }
1012
544fe9b7
WB
1013 /**
1014 * Update the content of the controls related to the selection window canvas<p>
1015 * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
1016 */
378e7718 1017 public void updateSelectedWindowInformation() {
833a21aa
WB
1018 // Update the timestamp as well
1019 updateSelectedWindowTimestamp();
1020
3e9fdb8b
FC
1021 if(selectedWindowCanvas != null) {
1022 txtWindowMaxNbEvents.setText( Long.toString(selectedWindowCanvas.getHistogramContent().getHeighestEventCount()) );
1023 txtWindowMinNbEvents.setText(Long.toString(0));
1024 }
833a21aa
WB
1025
1026 // Refresh the layout
7c1540ab 1027 txtWindowMaxNbEvents.getParent().layout();
ecfd1d41 1028 }
6cf16d22 1029
544fe9b7
WB
1030 /**
1031 * Update the content of the controls related to the timestamp of the selection window<p>
1032 * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
1033 */
833a21aa 1034 public void updateSelectedWindowTimestamp() {
833a21aa 1035
3e9fdb8b
FC
1036 if(selectedWindowCanvas != null) {
1037 String startTime = HistogramConstant.formatNanoSecondsTime( selectedWindowCanvas.getHistogramContent().getStartTime() );
1038 String stopTime = HistogramConstant.formatNanoSecondsTime( selectedWindowCanvas.getHistogramContent().getEndTime() );
1039 txtWindowStartTime.setText( startTime );
1040 txtWindowStopTime.setText( stopTime );
1041 }
833a21aa 1042
3e9fdb8b 1043 if(fullExperimentCanvas != null) {
1a971e96
FC
1044 ntgWindowCenterTime.setValue( fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition() );
1045 ntgWindowTimeSpan.setValue( fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth() );
3e9fdb8b
FC
1046
1047 // If the current event time is outside the selection window, recenter our window
1048 if ( isGivenTimestampInSelectedWindow(ntgCurrentEventTime.getValue()) == false ) {
1049 currentEventChangeNotification( fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition() );
1050 }
088c1d4e
WB
1051 }
1052
833a21aa
WB
1053 // Take one control in each group to call to refresh the layout
1054 // Since both control have the same parent, only one call is needed
1055 txtWindowStartTime.getParent().layout();
1a971e96 1056 ntgWindowCenterTime.getParent().layout();
833a21aa 1057 }
378e7718 1058
544fe9b7
WB
1059 /**
1060 * Update the controls related current event.<p>
1061 * The call here SHOULD be thread safe and can be call from any threads.
1062 */
088c1d4e
WB
1063 public void updateSelectedEventTime() {
1064 ntgCurrentEventTime.setValueAsynchronously(currentEventTime);
1a971e96 1065// sendTmfTimeSynchSignalBroadcast();
544fe9b7
WB
1066 // Tell the selection canvas which event is currently selected
1067 // This give a nice graphic output
088c1d4e
WB
1068 selectedWindowCanvas.getHistogramContent().setSelectedEventTimeInWindow(currentEventTime);
1069 selectedWindowCanvas.redrawAsynchronously();
1070 }
1071
7ef9ae3f
WB
1072 /**
1073 * Method called when the view is moved.<p>
1074 *
1075 * Just redraw everything...
1076 *
1a971e96 1077 * @param event The control event generated by the move.
7ef9ae3f 1078 */
d4011df2 1079 @Override
7ef9ae3f
WB
1080 public void controlMoved(ControlEvent event) {
1081 parent.redraw();
1082 }
1083
1084 /**
1085 * Method called when the view is resized.<p>
1086 *
1087 * We will make sure that the size didn't change more than the content size.<p>
1088 * Otherwise we need to perform a new request for the full experiment because we are missing data).
1089 *
1090 * @param event The control event generated by the resize.
1091 */
d4011df2 1092 @Override
7ef9ae3f
WB
1093 public void controlResized(ControlEvent event) {
1094
1095 // Ouch! The screen enlarged (screen resolution changed?) so far that we miss content to fill the space.
7ef9ae3f
WB
1096 if ( parent.getDisplay().getBounds().width > fullExperimentCanvas.getHistogramContent().getNbElement() ) {
1097 if ( lastUsedExperiment != null ) {
1406f802 1098 createCanvasAndRequests(lastUsedExperiment);
7ef9ae3f
WB
1099 }
1100 }
1101
1102 }
f05aabed
FC
1103
1104 /*
1105 * Getter of FullExperimentCanvas
1106 *
1107 * @return FullExperimentCanvas object
1108 */
1109 public static ParentHistogramCanvas getFullExperimentCanvas() {
1110 return fullExperimentCanvas;
1111 }
1112
1113 /*
1114 * Getter of SelectedWindowCanvas
1115 *
1116 * @return SelectedWindowCanvas object
1117 */
1118 public static ChildrenHistogramCanvas getSelectedWindowCanvas() {
1119 return selectedWindowCanvas;
1120 }
1121
1122
1123 /*
1124 * Getter of DEFAULT_WINDOW_SIZE
1125 *
1126 * @return DEFAULT_WINDOW_SIZE value
1127 */
1128 public static long getDEFAULT_WINDOW_SIZE() {
1129 return DEFAULT_WINDOW_SIZE;
1130 }
1131
1132 /**
1133 * Getter for dataBackgroundFullRequest variable
1134 * @return the dataBackgroundFullRequest instance
1135 */
1136 public HistogramRequest getDataBackgroundFullRequest() {
1137 return dataBackgroundFullRequest;
1138 }
1139
1140 /**
1141 * Getter for selectedWindowRequest variable
1142 * @return the selectedWindowRequest instance
1143 */
1144 public HistogramRequest getSelectedWindowRequest() {
1145 return selectedWindowRequest;
1146 }
1147
6e512b93 1148}
This page took 0.093292 seconds and 5 git commands to generate.