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