Commit | Line | Data |
---|---|---|
6e512b93 | 1 | /******************************************************************************* |
c8422608 | 2 | * Copyright (c) 2009, 2013 Ericsson |
1b055dfa | 3 | * |
6e512b93 ASL |
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 | |
1b055dfa | 8 | * |
6e512b93 | 9 | * Contributors: |
b59134e1 | 10 | * William Bourque - Initial API and implementation |
c392540b | 11 | * Yuriy Vashchuk - GUI reorganisation, simplification and some related code improvements. |
1b055dfa | 12 | * Yuriy Vashchuk - Histograms optimisation. |
c392540b FC |
13 | * Yuriy Vashchuk - Histogram Canvas Heritage correction |
14 | * Francois Chouinard - Cleanup and refactoring | |
e0752744 | 15 | * Francois Chouinard - Moved from LTTng to TMF |
65cdf787 | 16 | * Patrick Tasse - Update for mouse wheel zoom |
6e512b93 | 17 | *******************************************************************************/ |
3e9fdb8b | 18 | |
e0752744 | 19 | package org.eclipse.linuxtools.tmf.ui.views.histogram; |
6e512b93 | 20 | |
95aa81ef JCK |
21 | import org.eclipse.jface.action.Action; |
22 | import org.eclipse.jface.action.IAction; | |
23 | import org.eclipse.jface.action.Separator; | |
24 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; | |
25 | import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; | |
2740e05c | 26 | import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; |
fd3f1eff | 27 | import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; |
6c13869b FC |
28 | import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; |
29 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; | |
38df2c82 | 30 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalThrottler; |
6c13869b | 31 | import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; |
faa38350 PT |
32 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; |
33 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; | |
34 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; | |
35 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; | |
36 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; | |
3bd46eef AM |
37 | import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; |
38 | import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; | |
39 | import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; | |
faa38350 | 40 | import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; |
b59134e1 WB |
41 | import org.eclipse.linuxtools.tmf.ui.views.TmfView; |
42 | import org.eclipse.swt.SWT; | |
720d67cb PT |
43 | import org.eclipse.swt.events.MouseAdapter; |
44 | import org.eclipse.swt.events.MouseEvent; | |
65cdf787 | 45 | import org.eclipse.swt.events.MouseWheelListener; |
720d67cb PT |
46 | import org.eclipse.swt.events.PaintEvent; |
47 | import org.eclipse.swt.events.PaintListener; | |
48 | import org.eclipse.swt.graphics.Image; | |
49 | import org.eclipse.swt.graphics.Rectangle; | |
b59134e1 | 50 | import org.eclipse.swt.layout.GridData; |
252ae4bd | 51 | import org.eclipse.swt.layout.GridLayout; |
6e512b93 | 52 | import org.eclipse.swt.widgets.Composite; |
80c930fa | 53 | import org.eclipse.swt.widgets.Display; |
720d67cb | 54 | import org.eclipse.swt.widgets.Label; |
95aa81ef | 55 | import org.eclipse.ui.IActionBars; |
6e512b93 | 56 | |
544fe9b7 | 57 | /** |
faa38350 | 58 | * The purpose of this view is to provide graphical time distribution statistics about the trace events. |
544fe9b7 | 59 | * <p> |
c392540b FC |
60 | * The view is composed of two histograms and two controls: |
61 | * <ul> | |
faa38350 | 62 | * <li>an event distribution histogram for the whole trace; |
c392540b FC |
63 | * <li>an event distribution histogram for current time window (window span); |
64 | * <li>the timestamp of the currently selected event; | |
65 | * <li>the window span (size of the time window of the smaller histogram). | |
66 | * </ul> | |
67 | * The histograms x-axis show their respective time range. | |
abbdd66a | 68 | * |
f8177ba2 | 69 | * @version 2.0 |
2af7df97 | 70 | * @author Francois Chouinard |
544fe9b7 | 71 | */ |
c392540b FC |
72 | public class HistogramView extends TmfView { |
73 | ||
74 | // ------------------------------------------------------------------------ | |
75 | // Constants | |
76 | // ------------------------------------------------------------------------ | |
77 | ||
b544077e BH |
78 | /** |
79 | * The view ID as defined in plugin.xml | |
80 | */ | |
e0752744 | 81 | public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$ |
c392540b | 82 | |
720d67cb PT |
83 | private static final Image LINK_IMG = Activator.getDefault().getImageFromPath("/icons/etool16/link.gif"); //$NON-NLS-1$ |
84 | ||
c392540b FC |
85 | // ------------------------------------------------------------------------ |
86 | // Attributes | |
87 | // ------------------------------------------------------------------------ | |
88 | ||
89 | // Parent widget | |
90 | private Composite fParent; | |
91 | ||
faa38350 PT |
92 | // The current trace |
93 | private ITmfTrace fTrace; | |
c392540b | 94 | |
f8177ba2 | 95 | // Current timestamp/time window - everything in the TIME_SCALE |
faa38350 PT |
96 | private long fTraceStartTime; |
97 | private long fTraceEndTime; | |
c392540b FC |
98 | private long fWindowStartTime; |
99 | private long fWindowEndTime; | |
d7ee91bb | 100 | private long fWindowSpan; |
0fcf3b09 PT |
101 | private long fSelectionBeginTime; |
102 | private long fSelectionEndTime; | |
c392540b FC |
103 | |
104 | // Time controls | |
720d67cb PT |
105 | private HistogramTextControl fSelectionStartControl; |
106 | private HistogramTextControl fSelectionEndControl; | |
c392540b FC |
107 | private HistogramTextControl fTimeSpanControl; |
108 | ||
720d67cb PT |
109 | // Link |
110 | private Label fLinkButton; | |
111 | private boolean fLinkState; | |
112 | ||
c392540b FC |
113 | // Histogram/request for the full trace range |
114 | private static FullTraceHistogram fFullTraceHistogram; | |
115 | private HistogramRequest fFullTraceRequest; | |
116 | ||
117 | // Histogram/request for the selected time range | |
118 | private static TimeRangeHistogram fTimeRangeHistogram; | |
119 | private HistogramRequest fTimeRangeRequest; | |
120 | ||
38df2c82 AM |
121 | // Throttlers for the time sync and time-range sync signals |
122 | private final TmfSignalThrottler fTimeSyncThrottle; | |
123 | private final TmfSignalThrottler fTimeRangeSyncThrottle; | |
124 | ||
95aa81ef JCK |
125 | // Action for toggle showing the lost events |
126 | private Action hideLostEventsAction; | |
127 | ||
c392540b FC |
128 | // ------------------------------------------------------------------------ |
129 | // Constructor | |
130 | // ------------------------------------------------------------------------ | |
131 | ||
b544077e BH |
132 | /** |
133 | * Default constructor | |
134 | */ | |
c392540b FC |
135 | public HistogramView() { |
136 | super(ID); | |
38df2c82 AM |
137 | fTimeSyncThrottle = new TmfSignalThrottler(this, 200); |
138 | fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200); | |
c392540b FC |
139 | } |
140 | ||
6a13fa07 | 141 | @Override |
c392540b | 142 | public void dispose() { |
1b055dfa | 143 | if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { |
4dc47e28 FC |
144 | fTimeRangeRequest.cancel(); |
145 | } | |
1b055dfa | 146 | if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { |
4dc47e28 FC |
147 | fFullTraceRequest.cancel(); |
148 | } | |
6a13fa07 FC |
149 | fFullTraceHistogram.dispose(); |
150 | fTimeRangeHistogram.dispose(); | |
720d67cb PT |
151 | fSelectionStartControl.dispose(); |
152 | fSelectionEndControl.dispose(); | |
f8177ba2 | 153 | fTimeSpanControl.dispose(); |
4dc47e28 | 154 | super.dispose(); |
c392540b FC |
155 | } |
156 | ||
157 | // ------------------------------------------------------------------------ | |
158 | // TmfView | |
159 | // ------------------------------------------------------------------------ | |
160 | ||
161 | @Override | |
c392540b FC |
162 | public void createPartControl(Composite parent) { |
163 | ||
164 | fParent = parent; | |
165 | ||
166 | // Control labels | |
720d67cb PT |
167 | final String selectionStartLabel = Messages.HistogramView_selectionStartLabel; |
168 | final String selectionEndLabel = Messages.HistogramView_selectionEndLabel; | |
c392540b FC |
169 | final String windowSpanLabel = Messages.HistogramView_windowSpanLabel; |
170 | ||
171 | // -------------------------------------------------------------------- | |
172 | // Set the HistogramView layout | |
173 | // -------------------------------------------------------------------- | |
174 | ||
175 | Composite viewComposite = new Composite(fParent, SWT.FILL); | |
176 | GridLayout gridLayout = new GridLayout(); | |
177 | gridLayout.numColumns = 2; | |
178 | gridLayout.horizontalSpacing = 5; | |
179 | gridLayout.verticalSpacing = 0; | |
180 | gridLayout.marginHeight = 0; | |
181 | gridLayout.marginWidth = 0; | |
182 | viewComposite.setLayout(gridLayout); | |
183 | ||
c392540b FC |
184 | // -------------------------------------------------------------------- |
185 | // Time controls | |
186 | // -------------------------------------------------------------------- | |
187 | ||
720d67cb | 188 | Composite controlsComposite = new Composite(viewComposite, SWT.NONE); |
c392540b FC |
189 | gridLayout = new GridLayout(); |
190 | gridLayout.numColumns = 2; | |
191 | gridLayout.marginHeight = 0; | |
192 | gridLayout.marginWidth = 0; | |
193 | gridLayout.horizontalSpacing = 5; | |
720d67cb | 194 | gridLayout.verticalSpacing = 1; |
f8177ba2 | 195 | gridLayout.makeColumnsEqualWidth = false; |
c392540b | 196 | controlsComposite.setLayout(gridLayout); |
720d67cb PT |
197 | GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false); |
198 | controlsComposite.setLayoutData(gridData); | |
199 | ||
200 | Composite selectionGroup = new Composite(controlsComposite, SWT.BORDER); | |
201 | gridLayout = new GridLayout(); | |
202 | gridLayout.marginHeight = 0; | |
203 | gridLayout.marginWidth = 0; | |
204 | gridLayout.horizontalSpacing = 0; | |
205 | gridLayout.verticalSpacing = 0; | |
206 | selectionGroup.setLayout(gridLayout); | |
c392540b | 207 | |
720d67cb | 208 | // Selection start control |
c392540b | 209 | gridData = new GridData(); |
720d67cb PT |
210 | gridData.horizontalAlignment = SWT.FILL; |
211 | gridData.verticalAlignment = SWT.CENTER; | |
212 | fSelectionStartControl = new HistogramSelectionStartControl(this, selectionGroup, selectionStartLabel, 0L); | |
213 | fSelectionStartControl.setLayoutData(gridData); | |
214 | fSelectionStartControl.setValue(Long.MIN_VALUE); | |
215 | ||
216 | // Selection end control | |
217 | gridData = new GridData(); | |
218 | gridData.horizontalAlignment = SWT.FILL; | |
c392540b | 219 | gridData.verticalAlignment = SWT.CENTER; |
720d67cb PT |
220 | fSelectionEndControl = new HistogramSelectionEndControl(this, selectionGroup, selectionEndLabel, 0L); |
221 | fSelectionEndControl.setLayoutData(gridData); | |
222 | fSelectionEndControl.setValue(Long.MIN_VALUE); | |
223 | ||
224 | // Link button | |
225 | gridData = new GridData(); | |
226 | fLinkButton = new Label(controlsComposite, SWT.NONE); | |
227 | fLinkButton.setImage(LINK_IMG); | |
228 | fLinkButton.setLayoutData(gridData); | |
229 | addLinkButtonListeners(); | |
c392540b FC |
230 | |
231 | // Window span time control | |
232 | gridData = new GridData(); | |
720d67cb | 233 | gridData.horizontalAlignment = SWT.FILL; |
c392540b | 234 | gridData.verticalAlignment = SWT.CENTER; |
f8177ba2 | 235 | fTimeSpanControl = new HistogramTimeRangeControl(this, controlsComposite, windowSpanLabel, 0L); |
c392540b | 236 | fTimeSpanControl.setLayoutData(gridData); |
da7bdcbc | 237 | fTimeSpanControl.setValue(Long.MIN_VALUE); |
c392540b FC |
238 | |
239 | // -------------------------------------------------------------------- | |
240 | // Time range histogram | |
241 | // -------------------------------------------------------------------- | |
242 | ||
720d67cb | 243 | Composite timeRangeComposite = new Composite(viewComposite, SWT.NONE); |
c392540b FC |
244 | gridLayout = new GridLayout(); |
245 | gridLayout.numColumns = 1; | |
246 | gridLayout.marginHeight = 0; | |
247 | gridLayout.marginWidth = 0; | |
248 | gridLayout.marginTop = 5; | |
249 | gridLayout.horizontalSpacing = 0; | |
250 | gridLayout.verticalSpacing = 0; | |
251 | gridLayout.marginLeft = 5; | |
252 | gridLayout.marginRight = 5; | |
253 | timeRangeComposite.setLayout(gridLayout); | |
254 | ||
255 | // Use remaining horizontal space | |
256 | gridData = new GridData(); | |
257 | gridData.horizontalAlignment = SWT.FILL; | |
258 | gridData.verticalAlignment = SWT.FILL; | |
259 | gridData.grabExcessHorizontalSpace = true; | |
3a790c10 | 260 | gridData.grabExcessVerticalSpace = true; |
c392540b FC |
261 | timeRangeComposite.setLayoutData(gridData); |
262 | ||
263 | // Histogram | |
264 | fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite); | |
265 | ||
266 | // -------------------------------------------------------------------- | |
267 | // Full range histogram | |
268 | // -------------------------------------------------------------------- | |
269 | ||
270 | Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL); | |
271 | gridLayout = new GridLayout(); | |
272 | gridLayout.numColumns = 1; | |
273 | gridLayout.marginHeight = 0; | |
274 | gridLayout.marginWidth = 0; | |
275 | gridLayout.marginTop = 5; | |
276 | gridLayout.horizontalSpacing = 0; | |
277 | gridLayout.verticalSpacing = 0; | |
278 | gridLayout.marginLeft = 5; | |
279 | gridLayout.marginRight = 5; | |
280 | fullRangeComposite.setLayout(gridLayout); | |
281 | ||
282 | // Use remaining horizontal space | |
283 | gridData = new GridData(); | |
284 | gridData.horizontalAlignment = SWT.FILL; | |
285 | gridData.verticalAlignment = SWT.FILL; | |
286 | gridData.horizontalSpan = 2; | |
287 | gridData.grabExcessHorizontalSpace = true; | |
3a790c10 | 288 | gridData.grabExcessVerticalSpace = true; |
c392540b FC |
289 | fullRangeComposite.setLayoutData(gridData); |
290 | ||
291 | // Histogram | |
292 | fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite); | |
293 | ||
65cdf787 PT |
294 | // Add mouse wheel listener to time span control |
295 | MouseWheelListener listener = fFullTraceHistogram.getZoom(); | |
296 | fTimeSpanControl.addMouseWheelListener(listener); | |
297 | ||
95aa81ef JCK |
298 | |
299 | // View Action Handling | |
300 | contributeToActionBars(); | |
301 | ||
3ac5721a AM |
302 | ITmfTrace trace = getActiveTrace(); |
303 | if (trace != null) { | |
304 | traceSelected(new TmfTraceSelectedSignal(this, trace)); | |
1b055dfa | 305 | } |
ecfd1d41 | 306 | } |
c392540b FC |
307 | |
308 | @Override | |
c392540b | 309 | public void setFocus() { |
faa38350 | 310 | fFullTraceHistogram.fCanvas.setFocus(); |
833a21aa | 311 | } |
c392540b | 312 | |
f8177ba2 FC |
313 | void refresh() { |
314 | fParent.layout(true); | |
315 | } | |
316 | ||
c392540b FC |
317 | // ------------------------------------------------------------------------ |
318 | // Accessors | |
319 | // ------------------------------------------------------------------------ | |
320 | ||
faa38350 PT |
321 | /** |
322 | * Returns the current trace handled by the view | |
323 | * | |
324 | * @return the current trace | |
325 | * @since 2.0 | |
326 | */ | |
327 | public ITmfTrace getTrace() { | |
328 | return fTrace; | |
329 | } | |
330 | ||
b544077e BH |
331 | /** |
332 | * Returns the time range of the current selected window (base on default time scale). | |
abbdd66a | 333 | * |
b544077e | 334 | * @return the time range of current selected window. |
3bd46eef | 335 | * @since 2.0 |
b544077e | 336 | */ |
c392540b | 337 | public TmfTimeRange getTimeRange() { |
f8177ba2 FC |
338 | return new TmfTimeRange( |
339 | new TmfTimestamp(fWindowStartTime, ITmfTimestamp.NANOSECOND_SCALE), | |
340 | new TmfTimestamp(fWindowEndTime, ITmfTimestamp.NANOSECOND_SCALE)); | |
c392540b FC |
341 | } |
342 | ||
95aa81ef JCK |
343 | /** |
344 | * get the show lost events action | |
345 | * | |
346 | * @return The action object | |
46a59db7 | 347 | * @since 2.2 |
95aa81ef JCK |
348 | */ |
349 | public Action getShowLostEventsAction() { | |
350 | if (hideLostEventsAction == null) { | |
351 | /* show lost events */ | |
352 | hideLostEventsAction = new Action(Messages.HistogramView_hideLostEvents, IAction.AS_CHECK_BOX) { | |
353 | @Override | |
354 | public void run() { | |
355 | HistogramScaledData.hideLostEvents = hideLostEventsAction.isChecked(); | |
356 | long maxNbEvents = HistogramScaledData.hideLostEvents ? fFullTraceHistogram.fScaledData.fMaxValue : fFullTraceHistogram.fScaledData.fMaxCombinedValue; | |
357 | fFullTraceHistogram.getMaxNbEventsText().setText(Long.toString(maxNbEvents)); | |
358 | fFullTraceHistogram.getMaxNbEventsText().getParent().layout(); | |
359 | fFullTraceHistogram.fCanvas.redraw(); | |
360 | maxNbEvents = HistogramScaledData.hideLostEvents ? fTimeRangeHistogram.fScaledData.fMaxValue : fTimeRangeHistogram.fScaledData.fMaxCombinedValue; | |
361 | fTimeRangeHistogram.getMaxNbEventsText().setText(Long.toString(maxNbEvents)); | |
362 | fTimeRangeHistogram.getMaxNbEventsText().getParent().layout(); | |
363 | fTimeRangeHistogram.fCanvas.redraw(); | |
364 | } | |
365 | }; | |
366 | hideLostEventsAction.setText(Messages.HistogramView_hideLostEvents); | |
367 | hideLostEventsAction.setToolTipText(Messages.HistogramView_hideLostEvents); | |
368 | hideLostEventsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LOST_EVENTS)); | |
369 | } | |
370 | return hideLostEventsAction; | |
371 | } | |
372 | ||
c392540b FC |
373 | // ------------------------------------------------------------------------ |
374 | // Operations | |
375 | // ------------------------------------------------------------------------ | |
376 | ||
b544077e | 377 | /** |
0fcf3b09 PT |
378 | * Broadcast TmfSignal about new current selection time range. |
379 | * @param beginTime the begin time of current selection. | |
380 | * @param endTime the end time of current selection. | |
b544077e | 381 | */ |
0fcf3b09 PT |
382 | void updateSelectionTime(long beginTime, long endTime) { |
383 | updateDisplayedSelectionTime(beginTime, endTime); | |
384 | TmfTimestamp beginTs = new TmfTimestamp(beginTime, ITmfTimestamp.NANOSECOND_SCALE); | |
385 | TmfTimestamp endTs = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE); | |
386 | TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, beginTs, endTs); | |
387 | fTimeSyncThrottle.queue(signal); | |
c392540b FC |
388 | } |
389 | ||
720d67cb PT |
390 | /** |
391 | * Get selection begin time | |
392 | * @return the begin time of current selection | |
393 | */ | |
394 | long getSelectionBegin() { | |
395 | return fSelectionBeginTime; | |
396 | } | |
397 | ||
398 | /** | |
399 | * Get selection end time | |
400 | * @return the end time of current selection | |
401 | */ | |
402 | long getSelectionEnd() { | |
403 | return fSelectionEndTime; | |
404 | } | |
405 | ||
406 | /** | |
407 | * Get the link state | |
408 | * @return true if begin and end selection time should be linked | |
409 | */ | |
410 | boolean getLinkState() { | |
411 | return fLinkState; | |
412 | } | |
413 | ||
b544077e | 414 | /** |
0fcf3b09 | 415 | * Broadcast TmfSignal about new selection time range. |
b544077e BH |
416 | * @param startTime the new start time |
417 | * @param endTime the new end time | |
418 | */ | |
f8177ba2 | 419 | void updateTimeRange(long startTime, long endTime) { |
faa38350 | 420 | if (fTrace != null) { |
c392540b | 421 | // Build the new time range; keep the current time |
f8177ba2 FC |
422 | TmfTimeRange timeRange = new TmfTimeRange( |
423 | new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE), | |
424 | new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE)); | |
c392540b FC |
425 | fTimeSpanControl.setValue(endTime - startTime); |
426 | ||
38df2c82 AM |
427 | updateDisplayedTimeRange(startTime, endTime); |
428 | ||
c392540b | 429 | // Send the FW signal |
0fcf3b09 | 430 | TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange); |
38df2c82 | 431 | fTimeRangeSyncThrottle.queue(signal); |
c392540b FC |
432 | } |
433 | } | |
434 | ||
b544077e BH |
435 | /** |
436 | * Broadcast TmfSignal about new selected time range. | |
437 | * @param newDuration new duration (relative to current start time) | |
438 | */ | |
c392540b | 439 | public synchronized void updateTimeRange(long newDuration) { |
faa38350 | 440 | if (fTrace != null) { |
6a13fa07 | 441 | long delta = newDuration - fWindowSpan; |
1c6a842a | 442 | long newStartTime = fWindowStartTime - (delta / 2); |
6a13fa07 | 443 | setNewRange(newStartTime, newDuration); |
c392540b FC |
444 | } |
445 | } | |
446 | ||
447 | private void setNewRange(long startTime, long duration) { | |
41b5c37f AM |
448 | long realStart = startTime; |
449 | ||
450 | if (realStart < fTraceStartTime) { | |
451 | realStart = fTraceStartTime; | |
1b055dfa | 452 | } |
c392540b | 453 | |
41b5c37f | 454 | long endTime = realStart + duration; |
faa38350 PT |
455 | if (endTime > fTraceEndTime) { |
456 | endTime = fTraceEndTime; | |
1c6a842a | 457 | if ((endTime - duration) > fTraceStartTime) { |
41b5c37f | 458 | realStart = endTime - duration; |
1b055dfa | 459 | } else { |
41b5c37f | 460 | realStart = fTraceStartTime; |
6a13fa07 | 461 | } |
c392540b | 462 | } |
41b5c37f | 463 | updateTimeRange(realStart, endTime); |
833a21aa | 464 | } |
c392540b FC |
465 | |
466 | // ------------------------------------------------------------------------ | |
467 | // Signal handlers | |
468 | // ------------------------------------------------------------------------ | |
469 | ||
b544077e | 470 | /** |
faa38350 | 471 | * Handles trace opened signal. Loads histogram if new trace time range is not |
b544077e | 472 | * equal <code>TmfTimeRange.NULL_RANGE</code> |
fec1ac0b | 473 | * @param signal the trace opened signal |
faa38350 | 474 | * @since 2.0 |
b544077e | 475 | */ |
1406f802 | 476 | @TmfSignalHandler |
faa38350 | 477 | public void traceOpened(TmfTraceOpenedSignal signal) { |
c392540b | 478 | assert (signal != null); |
faa38350 PT |
479 | fTrace = signal.getTrace(); |
480 | loadTrace(); | |
ecfd1d41 | 481 | } |
550d787e | 482 | |
faa38350 PT |
483 | /** |
484 | * Handles trace selected signal. Loads histogram if new trace time range is not | |
485 | * equal <code>TmfTimeRange.NULL_RANGE</code> | |
486 | * @param signal the trace selected signal | |
487 | * @since 2.0 | |
488 | */ | |
489 | @TmfSignalHandler | |
490 | public void traceSelected(TmfTraceSelectedSignal signal) { | |
491 | assert (signal != null); | |
492 | if (fTrace != signal.getTrace()) { | |
493 | fTrace = signal.getTrace(); | |
494 | loadTrace(); | |
495 | } | |
496 | } | |
497 | ||
498 | private void loadTrace() { | |
c392540b FC |
499 | initializeHistograms(); |
500 | fParent.redraw(); | |
550d787e FC |
501 | } |
502 | ||
ea279a69 | 503 | /** |
faa38350 PT |
504 | * Handles trace closed signal. Clears the view and data model and cancels requests. |
505 | * @param signal the trace closed signal | |
ea279a69 FC |
506 | * @since 2.0 |
507 | */ | |
508 | @TmfSignalHandler | |
faa38350 PT |
509 | public void traceClosed(TmfTraceClosedSignal signal) { |
510 | ||
511 | if (signal.getTrace() != fTrace) { | |
512 | return; | |
513 | } | |
ea279a69 FC |
514 | |
515 | // Kill any running request | |
516 | if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { | |
517 | fTimeRangeRequest.cancel(); | |
518 | } | |
519 | if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { | |
520 | fFullTraceRequest.cancel(); | |
521 | } | |
522 | ||
523 | // Initialize the internal data | |
faa38350 PT |
524 | fTrace = null; |
525 | fTraceStartTime = 0L; | |
526 | fTraceEndTime = 0L; | |
f8177ba2 FC |
527 | fWindowStartTime = 0L; |
528 | fWindowEndTime = 0L; | |
d7ee91bb | 529 | fWindowSpan = 0L; |
0fcf3b09 PT |
530 | fSelectionBeginTime = 0L; |
531 | fSelectionEndTime = 0L; | |
ea279a69 FC |
532 | |
533 | // Clear the UI widgets | |
534 | fFullTraceHistogram.clear(); | |
535 | fTimeRangeHistogram.clear(); | |
720d67cb PT |
536 | fSelectionStartControl.setValue(Long.MIN_VALUE); |
537 | fSelectionEndControl.setValue(Long.MIN_VALUE); | |
f8177ba2 | 538 | |
da7bdcbc | 539 | fTimeSpanControl.setValue(Long.MIN_VALUE); |
ea279a69 FC |
540 | } |
541 | ||
b544077e | 542 | /** |
faa38350 | 543 | * Handles trace range updated signal. Extends histogram according to the new time range. If a |
b544077e BH |
544 | * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range |
545 | * will be issued. | |
abbdd66a | 546 | * |
faa38350 PT |
547 | * @param signal the trace range updated signal |
548 | * @since 2.0 | |
b544077e | 549 | */ |
74237cc3 | 550 | @TmfSignalHandler |
faa38350 | 551 | public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { |
74237cc3 | 552 | |
faa38350 | 553 | if (signal.getTrace() != fTrace) { |
09d11238 PT |
554 | return; |
555 | } | |
556 | ||
74237cc3 FC |
557 | TmfTimeRange fullRange = signal.getRange(); |
558 | ||
faa38350 PT |
559 | fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); |
560 | fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
74237cc3 | 561 | |
faa38350 PT |
562 | fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
563 | fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); | |
74237cc3 | 564 | |
74237cc3 FC |
565 | sendFullRangeRequest(fullRange); |
566 | } | |
c392540b | 567 | |
b544077e | 568 | /** |
faa38350 PT |
569 | * Handles the trace updated signal. Used to update time limits (start and end time) |
570 | * @param signal the trace updated signal | |
571 | * @since 2.0 | |
b544077e | 572 | */ |
a28d503d | 573 | @TmfSignalHandler |
faa38350 PT |
574 | public void traceUpdated(TmfTraceUpdatedSignal signal) { |
575 | if (signal.getTrace() != fTrace) { | |
a28d503d PT |
576 | return; |
577 | } | |
faa38350 PT |
578 | TmfTimeRange fullRange = signal.getTrace().getTimeRange(); |
579 | fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
580 | fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
a28d503d | 581 | |
faa38350 PT |
582 | fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
583 | fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); | |
584 | ||
585 | if ((fFullTraceRequest != null) && fFullTraceRequest.getRange().getEndTime().compareTo(signal.getRange().getEndTime()) < 0) { | |
586 | sendFullRangeRequest(fullRange); | |
587 | } | |
588 | } | |
a28d503d | 589 | |
b544077e BH |
590 | /** |
591 | * Handles the current time updated signal. Sets the current time in the time range | |
592 | * histogram as well as the full histogram. | |
abbdd66a | 593 | * |
b544077e BH |
594 | * @param signal the signal to process |
595 | */ | |
c392540b | 596 | @TmfSignalHandler |
80c930fa PT |
597 | public void currentTimeUpdated(final TmfTimeSynchSignal signal) { |
598 | if (Display.getCurrent() == null) { | |
599 | // Make sure the signal is handled in the UI thread | |
600 | Display.getDefault().asyncExec(new Runnable() { | |
601 | @Override | |
602 | public void run() { | |
603 | if (fParent.isDisposed()) { | |
604 | return; | |
605 | } | |
606 | currentTimeUpdated(signal); | |
607 | } | |
608 | }); | |
609 | return; | |
610 | } | |
c392540b | 611 | |
0fcf3b09 PT |
612 | // Update the selected time range |
613 | ITmfTimestamp beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); | |
614 | ITmfTimestamp endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); | |
615 | updateDisplayedSelectionTime(beginTime.getValue(), endTime.getValue()); | |
ecfd1d41 | 616 | } |
f05aabed | 617 | |
b544077e BH |
618 | /** |
619 | * Updates the current time range in the time range histogram and full range histogram. | |
620 | * @param signal the signal to process | |
621 | */ | |
c392540b | 622 | @TmfSignalHandler |
80c930fa PT |
623 | public void timeRangeUpdated(final TmfRangeSynchSignal signal) { |
624 | if (Display.getCurrent() == null) { | |
625 | // Make sure the signal is handled in the UI thread | |
626 | Display.getDefault().asyncExec(new Runnable() { | |
627 | @Override | |
628 | public void run() { | |
629 | if (fParent.isDisposed()) { | |
630 | return; | |
631 | } | |
632 | timeRangeUpdated(signal); | |
633 | } | |
634 | }); | |
635 | return; | |
636 | } | |
c392540b | 637 | |
faa38350 | 638 | if (fTrace != null) { |
1c6a842a PT |
639 | // Validate the time range |
640 | TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange()); | |
641 | if (range == null) { | |
642 | return; | |
643 | } | |
644 | ||
38df2c82 AM |
645 | updateDisplayedTimeRange( |
646 | range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(), | |
647 | range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); | |
c392540b | 648 | |
38df2c82 | 649 | // Send the event request to populate the small histogram |
c392540b | 650 | sendTimeRangeRequest(fWindowStartTime, fWindowEndTime); |
f8177ba2 | 651 | |
c392540b FC |
652 | fTimeSpanControl.setValue(fWindowSpan); |
653 | } | |
b59134e1 | 654 | } |
c392540b FC |
655 | |
656 | // ------------------------------------------------------------------------ | |
657 | // Helper functions | |
658 | // ------------------------------------------------------------------------ | |
659 | ||
660 | private void initializeHistograms() { | |
faa38350 | 661 | TmfTimeRange fullRange = updateTraceTimeRange(); |
0fcf3b09 PT |
662 | long selectionBeginTime = fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); |
663 | long selectionEndTime = fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
248af329 AM |
664 | long startTime = fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); |
665 | long duration = fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue() - startTime; | |
74237cc3 | 666 | |
faa38350 PT |
667 | if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { |
668 | fTimeRangeRequest.cancel(); | |
669 | } | |
74237cc3 | 670 | fTimeRangeHistogram.clear(); |
faa38350 | 671 | fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
d7ee91bb | 672 | fTimeRangeHistogram.setTimeRange(startTime, duration); |
0fcf3b09 | 673 | fTimeRangeHistogram.setSelection(selectionBeginTime, selectionEndTime); |
c392540b | 674 | |
faa38350 PT |
675 | if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { |
676 | fFullTraceRequest.cancel(); | |
677 | } | |
74237cc3 | 678 | fFullTraceHistogram.clear(); |
faa38350 | 679 | fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
d7ee91bb | 680 | fFullTraceHistogram.setTimeRange(startTime, duration); |
0fcf3b09 | 681 | fFullTraceHistogram.setSelection(selectionBeginTime, selectionEndTime); |
c392540b | 682 | |
d7ee91bb PT |
683 | fWindowStartTime = startTime; |
684 | fWindowSpan = duration; | |
685 | fWindowEndTime = startTime + duration; | |
6a13fa07 | 686 | |
0fcf3b09 PT |
687 | fSelectionBeginTime = selectionBeginTime; |
688 | fSelectionEndTime = selectionEndTime; | |
720d67cb PT |
689 | fSelectionStartControl.setValue(fSelectionBeginTime); |
690 | fSelectionEndControl.setValue(fSelectionEndTime); | |
f8177ba2 | 691 | |
d7ee91bb | 692 | fTimeSpanControl.setValue(duration); |
6a13fa07 | 693 | |
2af7df97 | 694 | if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) { |
d7ee91bb | 695 | sendTimeRangeRequest(startTime, startTime + duration); |
2af7df97 FC |
696 | sendFullRangeRequest(fullRange); |
697 | } | |
74237cc3 FC |
698 | } |
699 | ||
0fcf3b09 PT |
700 | private void updateDisplayedSelectionTime(long beginTime, long endTime) { |
701 | fSelectionBeginTime = beginTime; | |
702 | fSelectionEndTime = endTime; | |
38df2c82 | 703 | |
0fcf3b09 PT |
704 | fFullTraceHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime); |
705 | fTimeRangeHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime); | |
720d67cb PT |
706 | fSelectionStartControl.setValue(fSelectionBeginTime); |
707 | fSelectionEndControl.setValue(fSelectionEndTime); | |
38df2c82 AM |
708 | } |
709 | ||
710 | private void updateDisplayedTimeRange(long start, long end) { | |
711 | fWindowStartTime = start; | |
712 | fWindowEndTime = end; | |
713 | fWindowSpan = fWindowEndTime - fWindowStartTime; | |
714 | fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan); | |
715 | } | |
716 | ||
faa38350 PT |
717 | private TmfTimeRange updateTraceTimeRange() { |
718 | fTraceStartTime = 0L; | |
719 | fTraceEndTime = 0L; | |
74237cc3 | 720 | |
faa38350 | 721 | TmfTimeRange timeRange = fTrace.getTimeRange(); |
c6023803 | 722 | if (!timeRange.equals(TmfTimeRange.NULL_RANGE)) { |
faa38350 PT |
723 | fTraceStartTime = timeRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); |
724 | fTraceEndTime = timeRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
74237cc3 FC |
725 | } |
726 | return timeRange; | |
b59134e1 | 727 | } |
c392540b FC |
728 | |
729 | private void sendTimeRangeRequest(long startTime, long endTime) { | |
1b055dfa | 730 | if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { |
c392540b | 731 | fTimeRangeRequest.cancel(); |
088c1d4e | 732 | } |
f8177ba2 FC |
733 | TmfTimestamp startTS = new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE); |
734 | TmfTimestamp endTS = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE); | |
c392540b FC |
735 | TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS); |
736 | ||
737 | fTimeRangeHistogram.clear(); | |
15844a4e | 738 | fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
c392540b | 739 | fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime); |
4cf201de | 740 | |
faa38350 | 741 | int cacheSize = fTrace.getCacheSize(); |
2740e05c AM |
742 | fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(), |
743 | timeRange, 0, ITmfEventRequest.ALL_DATA, cacheSize, ExecutionType.FOREGROUND, false); | |
faa38350 | 744 | fTrace.sendRequest(fTimeRangeRequest); |
088c1d4e | 745 | } |
c392540b | 746 | |
74237cc3 | 747 | private void sendFullRangeRequest(TmfTimeRange fullRange) { |
1b055dfa | 748 | if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { |
c392540b FC |
749 | fFullTraceRequest.cancel(); |
750 | } | |
faa38350 | 751 | int cacheSize = fTrace.getCacheSize(); |
2740e05c AM |
752 | fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(), |
753 | fullRange, | |
754 | (int) fFullTraceHistogram.fDataModel.getNbEvents(), | |
755 | ITmfEventRequest.ALL_DATA, | |
756 | cacheSize, | |
757 | ExecutionType.BACKGROUND, true); | |
faa38350 | 758 | fTrace.sendRequest(fFullTraceRequest); |
ed4b3b9f | 759 | } |
c392540b | 760 | |
95aa81ef JCK |
761 | private void contributeToActionBars() { |
762 | IActionBars bars = getViewSite().getActionBars(); | |
763 | bars.getToolBarManager().add(getShowLostEventsAction()); | |
764 | bars.getToolBarManager().add(new Separator()); | |
765 | } | |
766 | ||
720d67cb PT |
767 | private void addLinkButtonListeners() { |
768 | fLinkButton.addMouseListener(new MouseAdapter() { | |
769 | @Override | |
770 | public void mouseDown(MouseEvent e) { | |
771 | fSelectionEndControl.setEnabled(fLinkState); | |
772 | fLinkState = !fLinkState; | |
773 | fLinkButton.redraw(); | |
774 | } | |
775 | }); | |
776 | ||
777 | fLinkButton.addPaintListener(new PaintListener() { | |
778 | @Override | |
779 | public void paintControl(PaintEvent e) { | |
780 | if (fLinkState) { | |
781 | Rectangle r = fLinkButton.getBounds(); | |
782 | r.x = -1; | |
783 | r.y = -1; | |
784 | e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); | |
785 | e.gc.drawRectangle(r); | |
786 | r.x = 0; | |
787 | r.y = 0; | |
788 | e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY)); | |
789 | e.gc.drawRectangle(r); | |
790 | } | |
791 | } | |
792 | }); | |
793 | } | |
6e512b93 | 794 | } |