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