Commit | Line | Data |
---|---|---|
6e512b93 | 1 | /******************************************************************************* |
ed902a2b | 2 | * Copyright (c) 2009, 2015 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 |
2fc582d2 | 17 | * Xavier Raynaud - Support multi-trace coloring |
6e512b93 | 18 | *******************************************************************************/ |
3e9fdb8b | 19 | |
2bdf0193 | 20 | package org.eclipse.tracecompass.tmf.ui.views.histogram; |
6e512b93 | 21 | |
c14c0757 GB |
22 | import java.util.Collection; |
23 | ||
dab5f596 | 24 | import org.eclipse.jdt.annotation.NonNull; |
95aa81ef JCK |
25 | import org.eclipse.jface.action.Action; |
26 | import org.eclipse.jface.action.IAction; | |
27 | import org.eclipse.jface.action.Separator; | |
b59134e1 | 28 | import org.eclipse.swt.SWT; |
2fc582d2 | 29 | import org.eclipse.swt.custom.CLabel; |
f7d9ea05 BH |
30 | import org.eclipse.swt.custom.SashForm; |
31 | import org.eclipse.swt.custom.ScrolledComposite; | |
720d67cb PT |
32 | import org.eclipse.swt.events.MouseAdapter; |
33 | import org.eclipse.swt.events.MouseEvent; | |
65cdf787 | 34 | import org.eclipse.swt.events.MouseWheelListener; |
720d67cb PT |
35 | import org.eclipse.swt.events.PaintEvent; |
36 | import org.eclipse.swt.events.PaintListener; | |
2fc582d2 | 37 | import org.eclipse.swt.graphics.GC; |
720d67cb | 38 | import org.eclipse.swt.graphics.Image; |
f7d9ea05 | 39 | import org.eclipse.swt.graphics.Point; |
720d67cb | 40 | import org.eclipse.swt.graphics.Rectangle; |
b59134e1 | 41 | import org.eclipse.swt.layout.GridData; |
252ae4bd | 42 | import org.eclipse.swt.layout.GridLayout; |
2fc582d2 | 43 | import org.eclipse.swt.layout.RowLayout; |
6e512b93 | 44 | import org.eclipse.swt.widgets.Composite; |
2fc582d2 | 45 | import org.eclipse.swt.widgets.Control; |
80c930fa | 46 | import org.eclipse.swt.widgets.Display; |
e8c79054 | 47 | import org.eclipse.swt.widgets.Event; |
720d67cb | 48 | import org.eclipse.swt.widgets.Label; |
e8c79054 BH |
49 | import org.eclipse.swt.widgets.Listener; |
50 | import org.eclipse.swt.widgets.Sash; | |
2bdf0193 AM |
51 | import org.eclipse.tracecompass.internal.tmf.ui.Activator; |
52 | import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; | |
53 | import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; | |
54 | import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; | |
e8c79054 | 55 | import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal; |
2bdf0193 | 56 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; |
e8c79054 | 57 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; |
2bdf0193 | 58 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalThrottler; |
2bdf0193 AM |
59 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; |
60 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; | |
61 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; | |
62 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; | |
63 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal; | |
e8c79054 | 64 | import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal; |
2bdf0193 AM |
65 | import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; |
66 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; | |
67 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; | |
68 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
21852dfa | 69 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext; |
2bdf0193 | 70 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; |
e8c79054 BH |
71 | import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo; |
72 | import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal; | |
73 | import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned; | |
2bdf0193 | 74 | import org.eclipse.tracecompass.tmf.ui.views.TmfView; |
95aa81ef | 75 | import org.eclipse.ui.IActionBars; |
6e512b93 | 76 | |
544fe9b7 | 77 | /** |
faa38350 | 78 | * The purpose of this view is to provide graphical time distribution statistics about the trace events. |
544fe9b7 | 79 | * <p> |
c392540b FC |
80 | * The view is composed of two histograms and two controls: |
81 | * <ul> | |
faa38350 | 82 | * <li>an event distribution histogram for the whole trace; |
c392540b FC |
83 | * <li>an event distribution histogram for current time window (window span); |
84 | * <li>the timestamp of the currently selected event; | |
85 | * <li>the window span (size of the time window of the smaller histogram). | |
86 | * </ul> | |
87 | * The histograms x-axis show their respective time range. | |
abbdd66a | 88 | * |
f8177ba2 | 89 | * @version 2.0 |
2af7df97 | 90 | * @author Francois Chouinard |
544fe9b7 | 91 | */ |
e8c79054 | 92 | public class HistogramView extends TmfView implements ITmfTimeAligned { |
c392540b FC |
93 | |
94 | // ------------------------------------------------------------------------ | |
95 | // Constants | |
96 | // ------------------------------------------------------------------------ | |
97 | ||
b544077e BH |
98 | /** |
99 | * The view ID as defined in plugin.xml | |
100 | */ | |
dab5f596 | 101 | public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$ |
c392540b | 102 | |
d2e4afa7 | 103 | private static final Image LINK_IMG = Activator.getDefault().getImageFromPath(ITmfImageConstants.IMG_UI_LINK); |
720d67cb | 104 | |
f7d9ea05 BH |
105 | private static final int[] DEFAULT_WEIGHTS = {1, 3}; |
106 | ||
c392540b FC |
107 | // ------------------------------------------------------------------------ |
108 | // Attributes | |
109 | // ------------------------------------------------------------------------ | |
110 | ||
faa38350 PT |
111 | // The current trace |
112 | private ITmfTrace fTrace; | |
c392540b | 113 | |
f8177ba2 | 114 | // Current timestamp/time window - everything in the TIME_SCALE |
faa38350 PT |
115 | private long fTraceStartTime; |
116 | private long fTraceEndTime; | |
c392540b FC |
117 | private long fWindowStartTime; |
118 | private long fWindowEndTime; | |
d7ee91bb | 119 | private long fWindowSpan; |
0fcf3b09 PT |
120 | private long fSelectionBeginTime; |
121 | private long fSelectionEndTime; | |
c392540b | 122 | |
e8c79054 BH |
123 | // SashForm |
124 | private SashForm fSashForm; | |
f7d9ea05 BH |
125 | private ScrolledComposite fScrollComposite; |
126 | private Composite fTimeControlsComposite; | |
e8c79054 BH |
127 | private Composite fTimeRangeComposite; |
128 | private Listener fSashDragListener; | |
f7d9ea05 | 129 | |
c392540b | 130 | // Time controls |
720d67cb PT |
131 | private HistogramTextControl fSelectionStartControl; |
132 | private HistogramTextControl fSelectionEndControl; | |
c392540b FC |
133 | private HistogramTextControl fTimeSpanControl; |
134 | ||
720d67cb PT |
135 | // Link |
136 | private Label fLinkButton; | |
137 | private boolean fLinkState; | |
138 | ||
c392540b FC |
139 | // Histogram/request for the full trace range |
140 | private static FullTraceHistogram fFullTraceHistogram; | |
141 | private HistogramRequest fFullTraceRequest; | |
142 | ||
143 | // Histogram/request for the selected time range | |
144 | private static TimeRangeHistogram fTimeRangeHistogram; | |
145 | private HistogramRequest fTimeRangeRequest; | |
146 | ||
2fc582d2 XR |
147 | // Legend area |
148 | private Composite fLegendArea; | |
149 | private Image[] fLegendImages; | |
150 | ||
38df2c82 AM |
151 | // Throttlers for the time sync and time-range sync signals |
152 | private final TmfSignalThrottler fTimeSyncThrottle; | |
153 | private final TmfSignalThrottler fTimeRangeSyncThrottle; | |
154 | ||
95aa81ef JCK |
155 | // Action for toggle showing the lost events |
156 | private Action hideLostEventsAction; | |
2fc582d2 XR |
157 | // Action for toggle showing the traces |
158 | private Action showTraceAction; | |
95aa81ef | 159 | |
c392540b FC |
160 | // ------------------------------------------------------------------------ |
161 | // Constructor | |
162 | // ------------------------------------------------------------------------ | |
163 | ||
b544077e BH |
164 | /** |
165 | * Default constructor | |
166 | */ | |
c392540b FC |
167 | public HistogramView() { |
168 | super(ID); | |
38df2c82 AM |
169 | fTimeSyncThrottle = new TmfSignalThrottler(this, 200); |
170 | fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200); | |
c392540b FC |
171 | } |
172 | ||
6a13fa07 | 173 | @Override |
c392540b | 174 | public void dispose() { |
1b055dfa | 175 | if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { |
4dc47e28 FC |
176 | fTimeRangeRequest.cancel(); |
177 | } | |
1b055dfa | 178 | if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { |
4dc47e28 FC |
179 | fFullTraceRequest.cancel(); |
180 | } | |
6a13fa07 FC |
181 | fFullTraceHistogram.dispose(); |
182 | fTimeRangeHistogram.dispose(); | |
720d67cb PT |
183 | fSelectionStartControl.dispose(); |
184 | fSelectionEndControl.dispose(); | |
f8177ba2 | 185 | fTimeSpanControl.dispose(); |
03ec1f6a MAL |
186 | disposeLegendImages(); |
187 | ||
4dc47e28 | 188 | super.dispose(); |
c392540b FC |
189 | } |
190 | ||
03ec1f6a MAL |
191 | private void disposeLegendImages() { |
192 | if (fLegendImages != null) { | |
193 | for (Image i: fLegendImages) { | |
194 | i.dispose(); | |
195 | } | |
196 | } | |
197 | fLegendImages = null; | |
198 | } | |
199 | ||
c392540b FC |
200 | // ------------------------------------------------------------------------ |
201 | // TmfView | |
202 | // ------------------------------------------------------------------------ | |
203 | ||
204 | @Override | |
c392540b | 205 | public void createPartControl(Composite parent) { |
e8c79054 | 206 | super.createPartControl(parent); |
c392540b FC |
207 | |
208 | // Control labels | |
720d67cb PT |
209 | final String selectionStartLabel = Messages.HistogramView_selectionStartLabel; |
210 | final String selectionEndLabel = Messages.HistogramView_selectionEndLabel; | |
c392540b FC |
211 | final String windowSpanLabel = Messages.HistogramView_windowSpanLabel; |
212 | ||
213 | // -------------------------------------------------------------------- | |
214 | // Set the HistogramView layout | |
215 | // -------------------------------------------------------------------- | |
e8c79054 | 216 | Composite viewComposite = new Composite(getParentComposite(), SWT.FILL); |
f7d9ea05 | 217 | GridLayout gridLayout = new GridLayout(1, false); |
c392540b FC |
218 | gridLayout.verticalSpacing = 0; |
219 | gridLayout.marginHeight = 0; | |
220 | gridLayout.marginWidth = 0; | |
221 | viewComposite.setLayout(gridLayout); | |
222 | ||
f7d9ea05 BH |
223 | // -------------------------------------------------------------------- |
224 | // Add a sash for time controls and time range histogram | |
225 | // -------------------------------------------------------------------- | |
e8c79054 BH |
226 | |
227 | /* | |
228 | * The ScrolledComposite preferred size can be larger than its visible | |
229 | * width. This affects the preferred width of the SashForm. Set the | |
230 | * preferred width to 1 to prevent it from affecting the preferred width | |
231 | * of the view composite. | |
232 | */ | |
233 | fSashForm = new SashForm(viewComposite, SWT.NONE) { | |
234 | @Override | |
235 | public Point computeSize(int wHint, int hHint) { | |
236 | Point computedSize = super.computeSize(wHint, hHint); | |
237 | if (wHint == SWT.DEFAULT) { | |
238 | return new Point(1, computedSize.y); | |
239 | } | |
240 | return computedSize; | |
241 | } | |
242 | @Override | |
243 | public Point computeSize(int wHint, int hHint, boolean changed) { | |
244 | Point computedSize = super.computeSize(wHint, hHint, changed); | |
245 | if (wHint == SWT.DEFAULT) { | |
246 | return new Point(1, computedSize.y); | |
247 | } | |
248 | return computedSize; | |
249 | } | |
250 | }; | |
f7d9ea05 | 251 | GridData gridData = new GridData(GridData.FILL, GridData.FILL, false, true); |
e8c79054 | 252 | fSashForm.setLayoutData(gridData); |
f7d9ea05 | 253 | |
c392540b FC |
254 | // -------------------------------------------------------------------- |
255 | // Time controls | |
256 | // -------------------------------------------------------------------- | |
e8c79054 | 257 | fScrollComposite = new PackedScrolledComposite(fSashForm, SWT.H_SCROLL | SWT.V_SCROLL); |
f7d9ea05 BH |
258 | fTimeControlsComposite = new Composite(fScrollComposite, SWT.NONE); |
259 | fScrollComposite.setContent(fTimeControlsComposite); | |
260 | gridLayout = new GridLayout(1, false); | |
261 | gridLayout.marginHeight = 0; | |
262 | gridLayout.marginWidth = 0; | |
263 | fScrollComposite.setLayout(gridLayout); | |
264 | fScrollComposite.setExpandHorizontal(true); | |
265 | fScrollComposite.setExpandVertical(true); | |
c392540b | 266 | |
f7d9ea05 BH |
267 | gridLayout = new GridLayout(1, false); |
268 | gridLayout.marginHeight = 0; | |
269 | gridLayout.marginWidth = 0; | |
270 | fTimeControlsComposite.setLayout(gridLayout); | |
271 | gridData = new GridData(GridData.FILL, GridData.CENTER, false, true); | |
272 | fTimeControlsComposite.setLayoutData(gridData); | |
273 | ||
274 | Composite innerComp = new Composite(fTimeControlsComposite, SWT.NONE); | |
275 | ||
276 | gridLayout = new GridLayout(2, false); | |
277 | innerComp.setLayout(gridLayout); | |
c392540b FC |
278 | gridLayout.marginHeight = 0; |
279 | gridLayout.marginWidth = 0; | |
280 | gridLayout.horizontalSpacing = 5; | |
720d67cb | 281 | gridLayout.verticalSpacing = 1; |
f7d9ea05 BH |
282 | gridData = new GridData(GridData.FILL, GridData.CENTER, false, true); |
283 | innerComp.setLayoutData(gridData); | |
720d67cb | 284 | |
f7d9ea05 BH |
285 | Composite selectionGroup = new Composite(innerComp, SWT.BORDER); |
286 | gridLayout = new GridLayout(1, false); | |
720d67cb PT |
287 | gridLayout.marginHeight = 0; |
288 | gridLayout.marginWidth = 0; | |
720d67cb | 289 | selectionGroup.setLayout(gridLayout); |
f7d9ea05 BH |
290 | gridData = new GridData(GridData.BEGINNING, GridData.CENTER, false, false); |
291 | selectionGroup.setLayoutData(gridData); | |
c392540b | 292 | |
720d67cb | 293 | // Selection start control |
f7d9ea05 | 294 | gridData = new GridData(GridData.FILL, GridData.CENTER, false, false); |
720d67cb PT |
295 | fSelectionStartControl = new HistogramSelectionStartControl(this, selectionGroup, selectionStartLabel, 0L); |
296 | fSelectionStartControl.setLayoutData(gridData); | |
297 | fSelectionStartControl.setValue(Long.MIN_VALUE); | |
298 | ||
299 | // Selection end control | |
f7d9ea05 | 300 | gridData = new GridData(GridData.FILL, GridData.CENTER, false, false); |
720d67cb PT |
301 | fSelectionEndControl = new HistogramSelectionEndControl(this, selectionGroup, selectionEndLabel, 0L); |
302 | fSelectionEndControl.setLayoutData(gridData); | |
303 | fSelectionEndControl.setValue(Long.MIN_VALUE); | |
304 | ||
305 | // Link button | |
f7d9ea05 BH |
306 | gridData = new GridData(GridData.BEGINNING, GridData.CENTER, false, false); |
307 | fLinkButton = new Label(innerComp, SWT.NONE); | |
720d67cb PT |
308 | fLinkButton.setImage(LINK_IMG); |
309 | fLinkButton.setLayoutData(gridData); | |
310 | addLinkButtonListeners(); | |
c392540b FC |
311 | |
312 | // Window span time control | |
f7d9ea05 BH |
313 | gridData = new GridData(GridData.FILL, GridData.CENTER, false, false); |
314 | fTimeSpanControl = new HistogramTimeRangeControl(this, innerComp, windowSpanLabel, 0L); | |
c392540b | 315 | fTimeSpanControl.setLayoutData(gridData); |
da7bdcbc | 316 | fTimeSpanControl.setValue(Long.MIN_VALUE); |
c392540b FC |
317 | |
318 | // -------------------------------------------------------------------- | |
319 | // Time range histogram | |
320 | // -------------------------------------------------------------------- | |
e8c79054 | 321 | fTimeRangeComposite = new Composite(fSashForm, SWT.NONE); |
f7d9ea05 BH |
322 | gridLayout = new GridLayout(1, true); |
323 | gridLayout.marginTop = 0; | |
e8c79054 BH |
324 | gridLayout.marginWidth = 0; |
325 | fTimeRangeComposite.setLayout(gridLayout); | |
c392540b FC |
326 | |
327 | // Use remaining horizontal space | |
f7d9ea05 | 328 | gridData = new GridData(GridData.FILL, GridData.FILL, true, true); |
e8c79054 | 329 | fTimeRangeComposite.setLayoutData(gridData); |
c392540b FC |
330 | |
331 | // Histogram | |
e8c79054 | 332 | fTimeRangeHistogram = new TimeRangeHistogram(this, fTimeRangeComposite, true); |
c392540b FC |
333 | |
334 | // -------------------------------------------------------------------- | |
335 | // Full range histogram | |
336 | // -------------------------------------------------------------------- | |
f7d9ea05 BH |
337 | final Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL); |
338 | gridLayout = new GridLayout(1, true); | |
c392540b FC |
339 | fullRangeComposite.setLayout(gridLayout); |
340 | ||
341 | // Use remaining horizontal space | |
f7d9ea05 | 342 | gridData = new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1); |
c392540b FC |
343 | fullRangeComposite.setLayoutData(gridData); |
344 | ||
345 | // Histogram | |
346 | fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite); | |
347 | ||
2fc582d2 XR |
348 | fLegendArea = new Composite(viewComposite, SWT.FILL); |
349 | fLegendArea.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false, 2, 1)); | |
350 | fLegendArea.setLayout(new RowLayout()); | |
351 | ||
65cdf787 PT |
352 | // Add mouse wheel listener to time span control |
353 | MouseWheelListener listener = fFullTraceHistogram.getZoom(); | |
354 | fTimeSpanControl.addMouseWheelListener(listener); | |
355 | ||
95aa81ef JCK |
356 | // View Action Handling |
357 | contributeToActionBars(); | |
358 | ||
21852dfa | 359 | ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); |
3ac5721a AM |
360 | if (trace != null) { |
361 | traceSelected(new TmfTraceSelectedSignal(this, trace)); | |
1b055dfa | 362 | } |
f7d9ea05 | 363 | |
e8c79054 BH |
364 | fSashForm.setVisible(true); |
365 | fSashForm.setWeights(DEFAULT_WEIGHTS); | |
366 | ||
367 | fTimeControlsComposite.addPaintListener(new PaintListener() { | |
368 | @Override | |
369 | public void paintControl(PaintEvent e) { | |
370 | // Sashes in a SashForm are being created on layout so add the | |
371 | // drag listener here | |
372 | if (fSashDragListener == null) { | |
373 | for (Control control : fSashForm.getChildren()) { | |
374 | if (control instanceof Sash) { | |
375 | fSashDragListener = new Listener() { | |
376 | @Override | |
377 | public void handleEvent(Event event) { | |
378 | TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(fSashForm, getTimeViewAlignmentInfo())); | |
379 | } | |
380 | }; | |
381 | control.removePaintListener(this); | |
382 | control.addListener(SWT.Selection, fSashDragListener); | |
383 | // There should be only one sash | |
384 | break; | |
385 | } | |
386 | } | |
387 | } | |
388 | } | |
389 | }); | |
ecfd1d41 | 390 | } |
c392540b FC |
391 | |
392 | @Override | |
c392540b | 393 | public void setFocus() { |
faa38350 | 394 | fFullTraceHistogram.fCanvas.setFocus(); |
833a21aa | 395 | } |
c392540b | 396 | |
f8177ba2 | 397 | void refresh() { |
e8c79054 BH |
398 | getParentComposite().layout(true); |
399 | } | |
400 | ||
401 | /** | |
402 | * @since 1.0 | |
403 | */ | |
404 | @Override | |
405 | public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() { | |
406 | if (fSashForm == null) { | |
407 | return null; | |
408 | } | |
409 | return new TmfTimeViewAlignmentInfo(fSashForm.getShell(), fSashForm.toDisplay(0, 0), getTimeAxisOffset()); | |
410 | } | |
411 | ||
412 | private int getTimeAxisOffset() { | |
413 | int[] weights = fSashForm.getWeights(); | |
414 | int width = (int) (((float) weights[0] / (weights[0] + weights[1])) * fSashForm.getBounds().width); | |
415 | int curTimeAxisOffset = width + fSashForm.getSashWidth() + fTimeRangeHistogram.getPointAreaOffset(); | |
416 | return curTimeAxisOffset; | |
417 | } | |
418 | ||
419 | /** | |
420 | * @since 1.0 | |
421 | */ | |
422 | @Override | |
423 | public int getAvailableWidth(int requestedOffset) { | |
424 | int pointAreaWidth = fTimeRangeHistogram.getPointAreaWidth(); | |
425 | int curTimeAxisOffset = getTimeAxisOffset(); | |
426 | if (pointAreaWidth <= 0) { | |
427 | pointAreaWidth = fSashForm.getBounds().width - curTimeAxisOffset; | |
428 | } | |
429 | // TODO this is just an approximation that assumes that the end will be at the same position but that can change for a different data range/scaling | |
430 | int endOffset = curTimeAxisOffset + pointAreaWidth; | |
431 | GridLayout layout = (GridLayout) fTimeRangeComposite.getLayout(); | |
432 | int endOffsetWithoutMargin = endOffset + layout.marginRight; | |
433 | int availableWidth = endOffsetWithoutMargin - requestedOffset; | |
434 | availableWidth = Math.min(fSashForm.getBounds().width, Math.max(0, availableWidth)); | |
435 | ||
436 | return availableWidth; | |
437 | } | |
438 | ||
439 | /** | |
440 | * @since 1.0 | |
441 | */ | |
442 | @Override | |
443 | public void performAlign(int offset, int width) { | |
e8c79054 | 444 | int total = fSashForm.getBounds().width; |
c34ab48a PT |
445 | int plotAreaOffset = fTimeRangeHistogram.getPointAreaOffset(); |
446 | int width1 = Math.max(0, offset - plotAreaOffset - fSashForm.getSashWidth()); | |
447 | int width2 = Math.max(0, total - width1 - fSashForm.getSashWidth()); | |
e8c79054 BH |
448 | fSashForm.setWeights(new int[] { width1, width2 }); |
449 | fSashForm.layout(); | |
450 | ||
451 | // calculate right margin | |
452 | GridLayout layout = (GridLayout) fTimeRangeComposite.getLayout(); | |
453 | int timeBasedControlsWidth = fTimeRangeComposite.getSize().x; | |
454 | int marginSize = timeBasedControlsWidth - width - plotAreaOffset; | |
455 | layout.marginRight = Math.max(0, marginSize); | |
456 | fTimeRangeComposite.layout(); | |
f8177ba2 FC |
457 | } |
458 | ||
c392540b FC |
459 | // ------------------------------------------------------------------------ |
460 | // Accessors | |
461 | // ------------------------------------------------------------------------ | |
462 | ||
faa38350 PT |
463 | /** |
464 | * Returns the current trace handled by the view | |
465 | * | |
466 | * @return the current trace | |
faa38350 PT |
467 | */ |
468 | public ITmfTrace getTrace() { | |
469 | return fTrace; | |
470 | } | |
471 | ||
b544077e BH |
472 | /** |
473 | * Returns the time range of the current selected window (base on default time scale). | |
abbdd66a | 474 | * |
b544077e BH |
475 | * @return the time range of current selected window. |
476 | */ | |
c392540b | 477 | public TmfTimeRange getTimeRange() { |
f8177ba2 FC |
478 | return new TmfTimeRange( |
479 | new TmfTimestamp(fWindowStartTime, ITmfTimestamp.NANOSECOND_SCALE), | |
480 | new TmfTimestamp(fWindowEndTime, ITmfTimestamp.NANOSECOND_SCALE)); | |
c392540b FC |
481 | } |
482 | ||
95aa81ef JCK |
483 | /** |
484 | * get the show lost events action | |
485 | * | |
486 | * @return The action object | |
95aa81ef JCK |
487 | */ |
488 | public Action getShowLostEventsAction() { | |
489 | if (hideLostEventsAction == null) { | |
490 | /* show lost events */ | |
491 | hideLostEventsAction = new Action(Messages.HistogramView_hideLostEvents, IAction.AS_CHECK_BOX) { | |
492 | @Override | |
493 | public void run() { | |
494 | HistogramScaledData.hideLostEvents = hideLostEventsAction.isChecked(); | |
495 | long maxNbEvents = HistogramScaledData.hideLostEvents ? fFullTraceHistogram.fScaledData.fMaxValue : fFullTraceHistogram.fScaledData.fMaxCombinedValue; | |
3311a6ca | 496 | fFullTraceHistogram.setMaxNbEvents(maxNbEvents); |
95aa81ef | 497 | maxNbEvents = HistogramScaledData.hideLostEvents ? fTimeRangeHistogram.fScaledData.fMaxValue : fTimeRangeHistogram.fScaledData.fMaxCombinedValue; |
3311a6ca | 498 | fTimeRangeHistogram.setMaxNbEvents(maxNbEvents); |
95aa81ef JCK |
499 | } |
500 | }; | |
501 | hideLostEventsAction.setText(Messages.HistogramView_hideLostEvents); | |
502 | hideLostEventsAction.setToolTipText(Messages.HistogramView_hideLostEvents); | |
503 | hideLostEventsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LOST_EVENTS)); | |
504 | } | |
505 | return hideLostEventsAction; | |
506 | } | |
507 | ||
2fc582d2 XR |
508 | /** |
509 | * get the show trace action | |
510 | * | |
511 | * @return The action object | |
2fc582d2 XR |
512 | */ |
513 | public Action getShowTraceAction() { | |
514 | if (showTraceAction == null) { | |
515 | /* show lost events */ | |
516 | showTraceAction = new Action(Messages.HistogramView_showTraces, IAction.AS_CHECK_BOX) { | |
517 | @Override | |
518 | public void run() { | |
519 | Histogram.showTraces = showTraceAction.isChecked(); | |
520 | fFullTraceHistogram.fCanvas.redraw(); | |
521 | fTimeRangeHistogram.fCanvas.redraw(); | |
522 | updateLegendArea(); | |
523 | } | |
524 | }; | |
525 | showTraceAction.setChecked(true); | |
526 | showTraceAction.setText(Messages.HistogramView_showTraces); | |
527 | showTraceAction.setToolTipText(Messages.HistogramView_showTraces); | |
528 | showTraceAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_HIST_TRACES)); | |
529 | } | |
530 | return showTraceAction; | |
531 | } | |
532 | ||
c392540b FC |
533 | // ------------------------------------------------------------------------ |
534 | // Operations | |
535 | // ------------------------------------------------------------------------ | |
536 | ||
b544077e | 537 | /** |
0fcf3b09 PT |
538 | * Broadcast TmfSignal about new current selection time range. |
539 | * @param beginTime the begin time of current selection. | |
540 | * @param endTime the end time of current selection. | |
b544077e | 541 | */ |
0fcf3b09 PT |
542 | void updateSelectionTime(long beginTime, long endTime) { |
543 | updateDisplayedSelectionTime(beginTime, endTime); | |
544 | TmfTimestamp beginTs = new TmfTimestamp(beginTime, ITmfTimestamp.NANOSECOND_SCALE); | |
545 | TmfTimestamp endTs = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE); | |
97c71024 | 546 | TmfSelectionRangeUpdatedSignal signal = new TmfSelectionRangeUpdatedSignal(this, beginTs, endTs); |
0fcf3b09 | 547 | fTimeSyncThrottle.queue(signal); |
c392540b FC |
548 | } |
549 | ||
720d67cb PT |
550 | /** |
551 | * Get selection begin time | |
552 | * @return the begin time of current selection | |
553 | */ | |
554 | long getSelectionBegin() { | |
555 | return fSelectionBeginTime; | |
556 | } | |
557 | ||
558 | /** | |
559 | * Get selection end time | |
560 | * @return the end time of current selection | |
561 | */ | |
562 | long getSelectionEnd() { | |
563 | return fSelectionEndTime; | |
564 | } | |
565 | ||
566 | /** | |
567 | * Get the link state | |
568 | * @return true if begin and end selection time should be linked | |
569 | */ | |
570 | boolean getLinkState() { | |
571 | return fLinkState; | |
572 | } | |
573 | ||
b544077e | 574 | /** |
0fcf3b09 | 575 | * Broadcast TmfSignal about new selection time range. |
b544077e BH |
576 | * @param startTime the new start time |
577 | * @param endTime the new end time | |
578 | */ | |
f8177ba2 | 579 | void updateTimeRange(long startTime, long endTime) { |
faa38350 | 580 | if (fTrace != null) { |
c392540b | 581 | // Build the new time range; keep the current time |
f8177ba2 FC |
582 | TmfTimeRange timeRange = new TmfTimeRange( |
583 | new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE), | |
584 | new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE)); | |
c392540b FC |
585 | fTimeSpanControl.setValue(endTime - startTime); |
586 | ||
38df2c82 AM |
587 | updateDisplayedTimeRange(startTime, endTime); |
588 | ||
c392540b | 589 | // Send the FW signal |
97c71024 | 590 | TmfWindowRangeUpdatedSignal signal = new TmfWindowRangeUpdatedSignal(this, timeRange); |
38df2c82 | 591 | fTimeRangeSyncThrottle.queue(signal); |
c392540b FC |
592 | } |
593 | } | |
594 | ||
b544077e BH |
595 | /** |
596 | * Broadcast TmfSignal about new selected time range. | |
597 | * @param newDuration new duration (relative to current start time) | |
598 | */ | |
c392540b | 599 | public synchronized void updateTimeRange(long newDuration) { |
faa38350 | 600 | if (fTrace != null) { |
6a13fa07 | 601 | long delta = newDuration - fWindowSpan; |
1c6a842a | 602 | long newStartTime = fWindowStartTime - (delta / 2); |
6a13fa07 | 603 | setNewRange(newStartTime, newDuration); |
c392540b FC |
604 | } |
605 | } | |
606 | ||
607 | private void setNewRange(long startTime, long duration) { | |
41b5c37f AM |
608 | long realStart = startTime; |
609 | ||
610 | if (realStart < fTraceStartTime) { | |
611 | realStart = fTraceStartTime; | |
1b055dfa | 612 | } |
c392540b | 613 | |
41b5c37f | 614 | long endTime = realStart + duration; |
faa38350 PT |
615 | if (endTime > fTraceEndTime) { |
616 | endTime = fTraceEndTime; | |
1c6a842a | 617 | if ((endTime - duration) > fTraceStartTime) { |
41b5c37f | 618 | realStart = endTime - duration; |
1b055dfa | 619 | } else { |
41b5c37f | 620 | realStart = fTraceStartTime; |
6a13fa07 | 621 | } |
c392540b | 622 | } |
41b5c37f | 623 | updateTimeRange(realStart, endTime); |
833a21aa | 624 | } |
c392540b FC |
625 | |
626 | // ------------------------------------------------------------------------ | |
627 | // Signal handlers | |
628 | // ------------------------------------------------------------------------ | |
629 | ||
b544077e | 630 | /** |
faa38350 | 631 | * Handles trace opened signal. Loads histogram if new trace time range is not |
b544077e | 632 | * equal <code>TmfTimeRange.NULL_RANGE</code> |
fec1ac0b | 633 | * @param signal the trace opened signal |
b544077e | 634 | */ |
1406f802 | 635 | @TmfSignalHandler |
faa38350 | 636 | public void traceOpened(TmfTraceOpenedSignal signal) { |
c392540b | 637 | assert (signal != null); |
faa38350 PT |
638 | fTrace = signal.getTrace(); |
639 | loadTrace(); | |
ecfd1d41 | 640 | } |
550d787e | 641 | |
faa38350 PT |
642 | /** |
643 | * Handles trace selected signal. Loads histogram if new trace time range is not | |
644 | * equal <code>TmfTimeRange.NULL_RANGE</code> | |
645 | * @param signal the trace selected signal | |
faa38350 PT |
646 | */ |
647 | @TmfSignalHandler | |
648 | public void traceSelected(TmfTraceSelectedSignal signal) { | |
649 | assert (signal != null); | |
650 | if (fTrace != signal.getTrace()) { | |
651 | fTrace = signal.getTrace(); | |
652 | loadTrace(); | |
653 | } | |
654 | } | |
655 | ||
656 | private void loadTrace() { | |
c392540b | 657 | initializeHistograms(); |
e8c79054 | 658 | getParentComposite().redraw(); |
550d787e FC |
659 | } |
660 | ||
ea279a69 | 661 | /** |
faa38350 PT |
662 | * Handles trace closed signal. Clears the view and data model and cancels requests. |
663 | * @param signal the trace closed signal | |
ea279a69 FC |
664 | */ |
665 | @TmfSignalHandler | |
faa38350 PT |
666 | public void traceClosed(TmfTraceClosedSignal signal) { |
667 | ||
668 | if (signal.getTrace() != fTrace) { | |
669 | return; | |
670 | } | |
ea279a69 FC |
671 | |
672 | // Kill any running request | |
673 | if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { | |
674 | fTimeRangeRequest.cancel(); | |
675 | } | |
676 | if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { | |
677 | fFullTraceRequest.cancel(); | |
678 | } | |
679 | ||
680 | // Initialize the internal data | |
faa38350 PT |
681 | fTrace = null; |
682 | fTraceStartTime = 0L; | |
683 | fTraceEndTime = 0L; | |
f8177ba2 FC |
684 | fWindowStartTime = 0L; |
685 | fWindowEndTime = 0L; | |
d7ee91bb | 686 | fWindowSpan = 0L; |
0fcf3b09 PT |
687 | fSelectionBeginTime = 0L; |
688 | fSelectionEndTime = 0L; | |
ea279a69 FC |
689 | |
690 | // Clear the UI widgets | |
691 | fFullTraceHistogram.clear(); | |
692 | fTimeRangeHistogram.clear(); | |
720d67cb PT |
693 | fSelectionStartControl.setValue(Long.MIN_VALUE); |
694 | fSelectionEndControl.setValue(Long.MIN_VALUE); | |
f8177ba2 | 695 | |
da7bdcbc | 696 | fTimeSpanControl.setValue(Long.MIN_VALUE); |
2fc582d2 XR |
697 | |
698 | for (Control c: fLegendArea.getChildren()) { | |
699 | c.dispose(); | |
700 | } | |
03ec1f6a | 701 | disposeLegendImages(); |
2fc582d2 XR |
702 | fLegendArea.layout(); |
703 | fLegendArea.getParent().layout(); | |
ea279a69 FC |
704 | } |
705 | ||
b544077e | 706 | /** |
faa38350 | 707 | * Handles trace range updated signal. Extends histogram according to the new time range. If a |
b544077e BH |
708 | * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range |
709 | * will be issued. | |
abbdd66a | 710 | * |
faa38350 | 711 | * @param signal the trace range updated signal |
b544077e | 712 | */ |
74237cc3 | 713 | @TmfSignalHandler |
faa38350 | 714 | public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { |
74237cc3 | 715 | |
faa38350 | 716 | if (signal.getTrace() != fTrace) { |
09d11238 PT |
717 | return; |
718 | } | |
719 | ||
74237cc3 FC |
720 | TmfTimeRange fullRange = signal.getRange(); |
721 | ||
faa38350 PT |
722 | fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); |
723 | fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
74237cc3 | 724 | |
faa38350 PT |
725 | fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
726 | fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); | |
74237cc3 | 727 | |
74237cc3 FC |
728 | sendFullRangeRequest(fullRange); |
729 | } | |
c392540b | 730 | |
b544077e | 731 | /** |
faa38350 PT |
732 | * Handles the trace updated signal. Used to update time limits (start and end time) |
733 | * @param signal the trace updated signal | |
b544077e | 734 | */ |
a28d503d | 735 | @TmfSignalHandler |
faa38350 PT |
736 | public void traceUpdated(TmfTraceUpdatedSignal signal) { |
737 | if (signal.getTrace() != fTrace) { | |
a28d503d PT |
738 | return; |
739 | } | |
faa38350 PT |
740 | TmfTimeRange fullRange = signal.getTrace().getTimeRange(); |
741 | fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
742 | fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
a28d503d | 743 | |
faa38350 PT |
744 | fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
745 | fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); | |
746 | ||
747 | if ((fFullTraceRequest != null) && fFullTraceRequest.getRange().getEndTime().compareTo(signal.getRange().getEndTime()) < 0) { | |
748 | sendFullRangeRequest(fullRange); | |
749 | } | |
750 | } | |
a28d503d | 751 | |
b544077e | 752 | /** |
97c71024 AM |
753 | * Handles the selection range updated signal. Sets the current time |
754 | * selection in the time range histogram as well as the full histogram. | |
abbdd66a | 755 | * |
97c71024 AM |
756 | * @param signal |
757 | * the signal to process | |
758 | * @since 1.0 | |
b544077e | 759 | */ |
c392540b | 760 | @TmfSignalHandler |
97c71024 | 761 | public void selectionRangeUpdated(final TmfSelectionRangeUpdatedSignal signal) { |
80c930fa PT |
762 | if (Display.getCurrent() == null) { |
763 | // Make sure the signal is handled in the UI thread | |
764 | Display.getDefault().asyncExec(new Runnable() { | |
765 | @Override | |
766 | public void run() { | |
e8c79054 | 767 | if (getParentComposite().isDisposed()) { |
80c930fa PT |
768 | return; |
769 | } | |
97c71024 | 770 | selectionRangeUpdated(signal); |
80c930fa PT |
771 | } |
772 | }); | |
773 | return; | |
774 | } | |
c392540b | 775 | |
0fcf3b09 PT |
776 | // Update the selected time range |
777 | ITmfTimestamp beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); | |
778 | ITmfTimestamp endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); | |
779 | updateDisplayedSelectionTime(beginTime.getValue(), endTime.getValue()); | |
ecfd1d41 | 780 | } |
f05aabed | 781 | |
b544077e | 782 | /** |
97c71024 AM |
783 | * Updates the current window time range in the time range histogram and |
784 | * full range histogram. | |
785 | * | |
786 | * @param signal | |
787 | * the signal to process | |
788 | * @since 1.0 | |
b544077e | 789 | */ |
c392540b | 790 | @TmfSignalHandler |
97c71024 | 791 | public void windowRangeUpdated(final TmfWindowRangeUpdatedSignal signal) { |
80c930fa PT |
792 | if (Display.getCurrent() == null) { |
793 | // Make sure the signal is handled in the UI thread | |
794 | Display.getDefault().asyncExec(new Runnable() { | |
795 | @Override | |
796 | public void run() { | |
e8c79054 | 797 | if (getParentComposite().isDisposed()) { |
80c930fa PT |
798 | return; |
799 | } | |
97c71024 | 800 | windowRangeUpdated(signal); |
80c930fa PT |
801 | } |
802 | }); | |
803 | return; | |
804 | } | |
c392540b | 805 | |
faa38350 | 806 | if (fTrace != null) { |
1c6a842a PT |
807 | // Validate the time range |
808 | TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange()); | |
809 | if (range == null) { | |
810 | return; | |
811 | } | |
812 | ||
38df2c82 AM |
813 | updateDisplayedTimeRange( |
814 | range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(), | |
815 | range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); | |
c392540b | 816 | |
38df2c82 | 817 | // Send the event request to populate the small histogram |
c392540b | 818 | sendTimeRangeRequest(fWindowStartTime, fWindowEndTime); |
f8177ba2 | 819 | |
c392540b FC |
820 | fTimeSpanControl.setValue(fWindowSpan); |
821 | } | |
b59134e1 | 822 | } |
c392540b FC |
823 | |
824 | // ------------------------------------------------------------------------ | |
825 | // Helper functions | |
826 | // ------------------------------------------------------------------------ | |
827 | ||
828 | private void initializeHistograms() { | |
faa38350 | 829 | TmfTimeRange fullRange = updateTraceTimeRange(); |
21852dfa AM |
830 | |
831 | TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext(); | |
832 | long selectionBeginTime = ctx.getSelectionRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
833 | long selectionEndTime = ctx.getSelectionRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
834 | long startTime = ctx.getWindowRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
835 | long duration = ctx.getWindowRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue() - startTime; | |
74237cc3 | 836 | |
faa38350 PT |
837 | if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { |
838 | fTimeRangeRequest.cancel(); | |
839 | } | |
74237cc3 | 840 | fTimeRangeHistogram.clear(); |
faa38350 | 841 | fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
d7ee91bb | 842 | fTimeRangeHistogram.setTimeRange(startTime, duration); |
0fcf3b09 | 843 | fTimeRangeHistogram.setSelection(selectionBeginTime, selectionEndTime); |
2fc582d2 | 844 | fTimeRangeHistogram.fDataModel.setTrace(fTrace); |
c392540b | 845 | |
faa38350 PT |
846 | if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { |
847 | fFullTraceRequest.cancel(); | |
848 | } | |
74237cc3 | 849 | fFullTraceHistogram.clear(); |
faa38350 | 850 | fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
d7ee91bb | 851 | fFullTraceHistogram.setTimeRange(startTime, duration); |
0fcf3b09 | 852 | fFullTraceHistogram.setSelection(selectionBeginTime, selectionEndTime); |
2fc582d2 | 853 | fFullTraceHistogram.fDataModel.setTrace(fTrace); |
c392540b | 854 | |
d7ee91bb PT |
855 | fWindowStartTime = startTime; |
856 | fWindowSpan = duration; | |
857 | fWindowEndTime = startTime + duration; | |
6a13fa07 | 858 | |
0fcf3b09 PT |
859 | fSelectionBeginTime = selectionBeginTime; |
860 | fSelectionEndTime = selectionEndTime; | |
720d67cb PT |
861 | fSelectionStartControl.setValue(fSelectionBeginTime); |
862 | fSelectionEndControl.setValue(fSelectionEndTime); | |
f8177ba2 | 863 | |
f7d9ea05 BH |
864 | // make sure that the scrollbar is setup properly |
865 | fScrollComposite.setMinSize(fTimeControlsComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); | |
d7ee91bb | 866 | fTimeSpanControl.setValue(duration); |
6a13fa07 | 867 | |
c14c0757 GB |
868 | Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace); |
869 | if (!traces.isEmpty()) { | |
870 | this.showTraceAction.setEnabled(traces.size() < fFullTraceHistogram.getMaxNbTraces()); | |
2fc582d2 XR |
871 | } |
872 | updateLegendArea(); | |
873 | ||
2af7df97 | 874 | if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) { |
d7ee91bb | 875 | sendTimeRangeRequest(startTime, startTime + duration); |
2af7df97 FC |
876 | sendFullRangeRequest(fullRange); |
877 | } | |
74237cc3 FC |
878 | } |
879 | ||
2fc582d2 XR |
880 | private void updateLegendArea() { |
881 | for (Control c: fLegendArea.getChildren()) { | |
882 | c.dispose(); | |
883 | } | |
03ec1f6a | 884 | disposeLegendImages(); |
2fc582d2 | 885 | if (fFullTraceHistogram.showTraces()) { |
c14c0757 GB |
886 | Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace); |
887 | fLegendImages = new Image[traces.size()]; | |
2fc582d2 XR |
888 | int traceIndex = 0; |
889 | for (ITmfTrace trace : traces) { | |
890 | fLegendImages[traceIndex] = new Image(fLegendArea.getDisplay(), 16, 16); | |
891 | GC gc = new GC(fLegendImages[traceIndex]); | |
892 | gc.setBackground(fFullTraceHistogram.getTraceColor(traceIndex)); | |
893 | gc.fillRectangle(0, 0, 15, 15); | |
894 | gc.setForeground(fLegendArea.getDisplay().getSystemColor(SWT.COLOR_BLACK)); | |
895 | gc.drawRectangle(0, 0, 15, 15); | |
896 | gc.dispose(); | |
897 | ||
898 | CLabel label = new CLabel(fLegendArea, SWT.NONE); | |
899 | label.setText(trace.getName()); | |
900 | label.setImage(fLegendImages[traceIndex]); | |
901 | traceIndex++; | |
902 | } | |
903 | } | |
904 | fLegendArea.layout(); | |
905 | fLegendArea.getParent().layout(); | |
906 | } | |
907 | ||
0fcf3b09 PT |
908 | private void updateDisplayedSelectionTime(long beginTime, long endTime) { |
909 | fSelectionBeginTime = beginTime; | |
910 | fSelectionEndTime = endTime; | |
38df2c82 | 911 | |
0fcf3b09 PT |
912 | fFullTraceHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime); |
913 | fTimeRangeHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime); | |
720d67cb PT |
914 | fSelectionStartControl.setValue(fSelectionBeginTime); |
915 | fSelectionEndControl.setValue(fSelectionEndTime); | |
38df2c82 AM |
916 | } |
917 | ||
918 | private void updateDisplayedTimeRange(long start, long end) { | |
919 | fWindowStartTime = start; | |
920 | fWindowEndTime = end; | |
921 | fWindowSpan = fWindowEndTime - fWindowStartTime; | |
922 | fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan); | |
923 | } | |
924 | ||
faa38350 PT |
925 | private TmfTimeRange updateTraceTimeRange() { |
926 | fTraceStartTime = 0L; | |
927 | fTraceEndTime = 0L; | |
74237cc3 | 928 | |
faa38350 | 929 | TmfTimeRange timeRange = fTrace.getTimeRange(); |
c6023803 | 930 | if (!timeRange.equals(TmfTimeRange.NULL_RANGE)) { |
faa38350 PT |
931 | fTraceStartTime = timeRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); |
932 | fTraceEndTime = timeRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); | |
74237cc3 FC |
933 | } |
934 | return timeRange; | |
b59134e1 | 935 | } |
c392540b FC |
936 | |
937 | private void sendTimeRangeRequest(long startTime, long endTime) { | |
1b055dfa | 938 | if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) { |
c392540b | 939 | fTimeRangeRequest.cancel(); |
088c1d4e | 940 | } |
f8177ba2 FC |
941 | TmfTimestamp startTS = new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE); |
942 | TmfTimestamp endTS = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE); | |
c392540b FC |
943 | TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS); |
944 | ||
945 | fTimeRangeHistogram.clear(); | |
15844a4e | 946 | fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime); |
c392540b | 947 | fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime); |
4cf201de | 948 | |
faa38350 | 949 | int cacheSize = fTrace.getCacheSize(); |
2740e05c AM |
950 | fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(), |
951 | timeRange, 0, ITmfEventRequest.ALL_DATA, cacheSize, ExecutionType.FOREGROUND, false); | |
faa38350 | 952 | fTrace.sendRequest(fTimeRangeRequest); |
088c1d4e | 953 | } |
c392540b | 954 | |
74237cc3 | 955 | private void sendFullRangeRequest(TmfTimeRange fullRange) { |
1b055dfa | 956 | if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) { |
c392540b FC |
957 | fFullTraceRequest.cancel(); |
958 | } | |
faa38350 | 959 | int cacheSize = fTrace.getCacheSize(); |
2740e05c AM |
960 | fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(), |
961 | fullRange, | |
962 | (int) fFullTraceHistogram.fDataModel.getNbEvents(), | |
963 | ITmfEventRequest.ALL_DATA, | |
964 | cacheSize, | |
965 | ExecutionType.BACKGROUND, true); | |
faa38350 | 966 | fTrace.sendRequest(fFullTraceRequest); |
ed4b3b9f | 967 | } |
c392540b | 968 | |
95aa81ef JCK |
969 | private void contributeToActionBars() { |
970 | IActionBars bars = getViewSite().getActionBars(); | |
971 | bars.getToolBarManager().add(getShowLostEventsAction()); | |
2fc582d2 | 972 | bars.getToolBarManager().add(getShowTraceAction()); |
95aa81ef JCK |
973 | bars.getToolBarManager().add(new Separator()); |
974 | } | |
975 | ||
720d67cb PT |
976 | private void addLinkButtonListeners() { |
977 | fLinkButton.addMouseListener(new MouseAdapter() { | |
978 | @Override | |
979 | public void mouseDown(MouseEvent e) { | |
980 | fSelectionEndControl.setEnabled(fLinkState); | |
981 | fLinkState = !fLinkState; | |
982 | fLinkButton.redraw(); | |
983 | } | |
984 | }); | |
985 | ||
986 | fLinkButton.addPaintListener(new PaintListener() { | |
987 | @Override | |
988 | public void paintControl(PaintEvent e) { | |
989 | if (fLinkState) { | |
990 | Rectangle r = fLinkButton.getBounds(); | |
991 | r.x = -1; | |
992 | r.y = -1; | |
993 | e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); | |
994 | e.gc.drawRectangle(r); | |
995 | r.x = 0; | |
996 | r.y = 0; | |
997 | e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY)); | |
998 | e.gc.drawRectangle(r); | |
999 | } | |
1000 | } | |
1001 | }); | |
1002 | } | |
f7d9ea05 BH |
1003 | |
1004 | private static class PackedScrolledComposite extends ScrolledComposite { | |
1005 | Point fScrollBarSize; // Size of OS-specific scrollbar | |
1006 | ||
1007 | public PackedScrolledComposite(Composite parent, int style) { | |
1008 | super(parent, style); | |
1009 | Composite composite = new Composite(parent, SWT.H_SCROLL | SWT.V_SCROLL); | |
1010 | composite.setSize(1, 1); | |
1011 | fScrollBarSize = composite.computeSize(0, 0); | |
1012 | composite.dispose(); | |
1013 | } | |
1014 | ||
1015 | @Override | |
1016 | public Point computeSize(int wHint, int hHint, boolean changed) { | |
1017 | Point point = super.computeSize(wHint, hHint, changed); | |
1018 | // Remove scrollbar size if applicable | |
1019 | point.x += ((getStyle() & SWT.V_SCROLL) != 0) ? -fScrollBarSize.x : 0; | |
1020 | point.y += ((getStyle() & SWT.H_SCROLL) != 0) ? -fScrollBarSize.y : 0; | |
1021 | return point; | |
1022 | } | |
1023 | } | |
6e512b93 | 1024 | } |