lttng: Remove capital letter in package name
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / TimeGraphViewer.java
CommitLineData
837a2f8c 1/*****************************************************************************
10ad9fa6 2 * Copyright (c) 2007, 2015 Intel Corporation, Ericsson, others
837a2f8c
PT
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Intel Corporation - Initial API and implementation
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation
11 * Alexander N. Alexeev, Intel - Add monitors statistics support
12 * Alvaro Sanchez-Leon - Adapted for TMF
13 * Patrick Tasse - Refactoring
bec1f1ac 14 * Geneviève Bastien - Add event links between entries
837a2f8c
PT
15 *****************************************************************************/
16
2bdf0193 17package org.eclipse.tracecompass.tmf.ui.widgets.timegraph;
837a2f8c
PT
18
19import java.util.ArrayList;
f1fae91f 20import java.util.List;
837a2f8c
PT
21
22import org.eclipse.jface.action.Action;
79ec0b89
PT
23import org.eclipse.jface.action.IAction;
24import org.eclipse.jface.dialogs.IDialogSettings;
f4617471 25import org.eclipse.jface.viewers.AbstractTreeViewer;
837a2f8c 26import org.eclipse.jface.viewers.ISelectionProvider;
6ac5a950 27import org.eclipse.jface.viewers.ViewerFilter;
837a2f8c
PT
28import org.eclipse.swt.SWT;
29import org.eclipse.swt.events.ControlAdapter;
30import org.eclipse.swt.events.ControlEvent;
31import org.eclipse.swt.events.KeyAdapter;
32import org.eclipse.swt.events.KeyEvent;
27df1564 33import org.eclipse.swt.events.MenuDetectListener;
837a2f8c
PT
34import org.eclipse.swt.events.MouseEvent;
35import org.eclipse.swt.events.MouseWheelListener;
36import org.eclipse.swt.events.SelectionAdapter;
37import org.eclipse.swt.events.SelectionEvent;
38import org.eclipse.swt.events.SelectionListener;
39import org.eclipse.swt.graphics.Rectangle;
40import org.eclipse.swt.layout.FillLayout;
41import org.eclipse.swt.layout.GridData;
42import org.eclipse.swt.layout.GridLayout;
43import org.eclipse.swt.widgets.Composite;
44import org.eclipse.swt.widgets.Control;
10ad9fa6 45import org.eclipse.swt.widgets.Display;
b698ec63
PT
46import org.eclipse.swt.widgets.Event;
47import org.eclipse.swt.widgets.Listener;
837a2f8c 48import org.eclipse.swt.widgets.Slider;
2bdf0193
AM
49import org.eclipse.tracecompass.internal.tmf.ui.Activator;
50import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants;
51import org.eclipse.tracecompass.internal.tmf.ui.Messages;
52import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TimeGraphLegend;
53import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
54import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
55import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
56import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider;
57import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeDataProviderCyclesConverter;
58import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme;
59import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
60import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphScale;
61import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphTooltipHandler;
62import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
63import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
837a2f8c
PT
64
65/**
66 * Generic time graph viewer implementation
67 *
837a2f8c
PT
68 * @author Patrick Tasse, and others
69 */
baf92cac 70public class TimeGraphViewer implements ITimeDataProvider, SelectionListener {
837a2f8c 71
ae09c4ad 72 /** Constant indicating that all levels of the time graph should be expanded */
f4617471
PT
73 public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS;
74
f1fae91f
PT
75 private static final int DEFAULT_NAME_WIDTH = 200;
76 private static final int MIN_NAME_WIDTH = 6;
77 private static final int MAX_NAME_WIDTH = 1000;
78 private static final int DEFAULT_HEIGHT = 22;
79 private static final long RECENTERING_MARGIN_FACTOR = 50;
79ec0b89 80 private static final String HIDE_ARROWS_KEY = "hide.arrows"; //$NON-NLS-1$
0fab12b0 81 private static final long DEFAULT_FREQUENCY = 1000000000L;
b698ec63 82 private static final int H_SCROLLBAR_MAX = Integer.MAX_VALUE - 1;
f1fae91f
PT
83
84 private long fMinTimeInterval;
f1fae91f 85 private ITimeGraphEntry fSelectedEntry;
50d36521
PT
86 private long fBeginTime = SWT.DEFAULT; // The user-specified bounds start time
87 private long fEndTime = SWT.DEFAULT; // The user-specified bounds end time
88 private long fTime0 = SWT.DEFAULT; // The current window start time
89 private long fTime1 = SWT.DEFAULT; // The current window end time
90 private long fSelectionBegin = SWT.DEFAULT;
91 private long fSelectionEnd = SWT.DEFAULT;
92 private long fTime0Bound = SWT.DEFAULT; // The bounds start time
93 private long fTime1Bound = SWT.DEFAULT; // The bounds end time
94 private long fTime0ExtSynch = SWT.DEFAULT;
95 private long fTime1ExtSynch = SWT.DEFAULT;
f1fae91f
PT
96 private boolean fTimeRangeFixed;
97 private int fNameWidthPref = DEFAULT_NAME_WIDTH;
98 private int fMinNameWidth = MIN_NAME_WIDTH;
99 private int fNameWidth;
100 private Composite fDataViewer;
101
102 private TimeGraphControl fTimeGraphCtrl;
103 private TimeGraphScale fTimeScaleCtrl;
b698ec63 104 private Slider fHorizontalScrollBar;
f1fae91f
PT
105 private Slider fVerticalScrollBar;
106 private TimeGraphColorScheme fColorScheme;
4c9c0c87
PT
107 private Object fInputElement;
108 private ITimeGraphContentProvider fTimeGraphContentProvider;
837a2f8c 109 private ITimeGraphPresentationProvider fTimeGraphProvider;
0fab12b0
PT
110 private ITimeDataProvider fTimeDataProvider = this;
111 private TimeGraphTooltipHandler fToolTipHandler;
837a2f8c 112
507b1336
AM
113 private List<ITimeGraphSelectionListener> fSelectionListeners = new ArrayList<>();
114 private List<ITimeGraphTimeListener> fTimeListeners = new ArrayList<>();
115 private List<ITimeGraphRangeListener> fRangeListeners = new ArrayList<>();
837a2f8c 116
0fab12b0
PT
117 // Time format, using Epoch reference, Relative time format(default),
118 // Number, or Cycles
f1fae91f 119 private TimeFormat fTimeFormat = TimeFormat.RELATIVE;
0fab12b0
PT
120 // Clock frequency to use for Cycles time format
121 private long fClockFrequency = DEFAULT_FREQUENCY;
f1fae91f
PT
122 private int fBorderWidth = 0;
123 private int fTimeScaleHeight = DEFAULT_HEIGHT;
837a2f8c 124
f1fae91f
PT
125 private Action fResetScaleAction;
126 private Action fShowLegendAction;
127 private Action fNextEventAction;
128 private Action fPrevEventAction;
129 private Action fNextItemAction;
130 private Action fPreviousItemAction;
131 private Action fZoomInAction;
132 private Action fZoomOutAction;
79ec0b89 133 private Action fHideArrowsAction;
086f21ae
PT
134 private Action fFollowArrowFwdAction;
135 private Action fFollowArrowBwdAction;
837a2f8c 136
10ad9fa6
PT
137 private ListenerNotifier fListenerNotifier;
138 private final Object fListenerNotifierLock = new Object();
139
140 private class ListenerNotifier extends Thread {
141 private static final long DELAY = 400L;
142 private static final long POLLING_INTERVAL = 10L;
143 private long fLastUpdateTime = Long.MAX_VALUE;
144 private boolean fSelectionChanged = false;
145 private boolean fTimeRangeUpdated = false;
146 private boolean fTimeSelected = false;
147
148 @Override
149 public void run() {
150 while ((System.currentTimeMillis() - fLastUpdateTime) < DELAY) {
151 try {
152 Thread.sleep(POLLING_INTERVAL);
153 } catch (Exception e) {
154 return;
155 }
156 }
157 synchronized (fListenerNotifierLock) {
158 fListenerNotifier = null;
159 }
160 if (!isInterrupted()) {
161 Display.getDefault().asyncExec(new Runnable() {
162 @Override
163 public void run() {
164 if (fDataViewer.isDisposed()) {
165 return;
166 }
167 if (fSelectionChanged) {
168 fireSelectionChanged(fSelectedEntry);
169 }
170 if (fTimeRangeUpdated) {
171 fireTimeRangeUpdated(fTime0, fTime1);
172 }
173 if (fTimeSelected) {
174 fireTimeSelected(fSelectionBegin, fSelectionEnd);
175 }
176 }
177 });
178 }
179 }
180
181 public void selectionChanged() {
182 fSelectionChanged = true;
183 fLastUpdateTime = System.currentTimeMillis();
184 }
185
186 public void timeRangeUpdated() {
187 fTimeRangeUpdated = true;
188 fLastUpdateTime = System.currentTimeMillis();
189 }
190
191 public void timeSelected() {
192 fTimeSelected = true;
193 fLastUpdateTime = System.currentTimeMillis();
194 }
195 }
196
837a2f8c 197 /**
4c9c0c87
PT
198 * Standard constructor.
199 * <p>
200 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
837a2f8c
PT
201 *
202 * @param parent
203 * The parent UI composite object
204 * @param style
205 * The style to use
206 */
207 public TimeGraphViewer(Composite parent, int style) {
208 createDataViewer(parent, style);
d8a230f8 209 fTimeGraphContentProvider = new TimeGraphContentProvider();
837a2f8c
PT
210 }
211
212 /**
4c9c0c87
PT
213 * Sets the timegraph content provider used by this timegraph viewer.
214 *
215 * @param timeGraphContentProvider
216 * the timegraph content provider
4c9c0c87
PT
217 */
218 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) {
219 fTimeGraphContentProvider = timeGraphContentProvider;
220 }
221
222 /**
223 * Gets the timegraph content provider used by this timegraph viewer.
224 *
225 * @return the timegraph content provider
4c9c0c87
PT
226 */
227 public ITimeGraphContentProvider getTimeGraphContentProvider() {
228 return fTimeGraphContentProvider;
229 }
230
231 /**
232 * Sets the timegraph presentation provider used by this timegraph viewer.
837a2f8c 233 *
79ec0b89
PT
234 * @param timeGraphProvider
235 * the timegraph provider
837a2f8c
PT
236 */
237 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) {
238 fTimeGraphProvider = timeGraphProvider;
f1fae91f 239 fTimeGraphCtrl.setTimeGraphProvider(timeGraphProvider);
0fab12b0
PT
240 fToolTipHandler = new TimeGraphTooltipHandler(fTimeGraphProvider, fTimeDataProvider);
241 fToolTipHandler.activateHoverHelp(fTimeGraphCtrl);
837a2f8c
PT
242 }
243
244 /**
4c9c0c87 245 * Sets or clears the input for this time graph viewer.
837a2f8c 246 *
4c9c0c87 247 * @param inputElement
79ec0b89
PT
248 * The input of this time graph viewer, or <code>null</code> if
249 * none
837a2f8c 250 */
4c9c0c87
PT
251 public void setInput(Object inputElement) {
252 fInputElement = inputElement;
253 ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(inputElement);
41b5c37f 254
f1fae91f 255 if (fTimeGraphCtrl != null) {
4c9c0c87 256 setTimeRange(input);
837a2f8c 257 setTopIndex(0);
50d36521
PT
258 fSelectionBegin = SWT.DEFAULT;
259 fSelectionEnd = SWT.DEFAULT;
f1fae91f 260 fSelectedEntry = null;
4c9c0c87 261 refreshAllData(input);
837a2f8c
PT
262 }
263 }
264
4c9c0c87
PT
265 /**
266 * Gets the input for this time graph viewer.
267 *
268 * @return The input of this time graph viewer, or <code>null</code> if none
4c9c0c87
PT
269 */
270 public Object getInput() {
271 return fInputElement;
272 }
273
bec1f1ac
GB
274 /**
275 * Sets (or clears if null) the list of links to display on this combo
276 *
277 * @param links
278 * the links to display in this time graph combo
bec1f1ac
GB
279 */
280 public void setLinks(List<ILinkEvent> links) {
281 if (fTimeGraphCtrl != null) {
282 fTimeGraphCtrl.refreshArrows(links);
283 }
284 }
285
837a2f8c
PT
286 /**
287 * Refresh the view
288 */
289 public void refresh() {
4c9c0c87
PT
290 ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(fInputElement);
291 setTimeRange(input);
4c9c0c87 292 refreshAllData(input);
837a2f8c
PT
293 }
294
295 /**
296 * Callback for when the control is moved
297 *
298 * @param e
299 * The caller event
300 */
301 public void controlMoved(ControlEvent e) {
302 }
303
304 /**
305 * Callback for when the control is resized
306 *
307 * @param e
308 * The caller event
309 */
310 public void controlResized(ControlEvent e) {
311 resizeControls();
312 }
313
a0a88f65
AM
314 /**
315 * @return The string representing the view type
316 */
837a2f8c
PT
317 protected String getViewTypeStr() {
318 return "viewoption.threads"; //$NON-NLS-1$
319 }
320
a0a88f65 321 int getMarginWidth() {
837a2f8c
PT
322 return 0;
323 }
324
a0a88f65 325 int getMarginHeight() {
837a2f8c
PT
326 return 0;
327 }
328
329 void loadOptions() {
f1fae91f 330 fMinTimeInterval = 1;
50d36521
PT
331 fSelectionBegin = SWT.DEFAULT;
332 fSelectionEnd = SWT.DEFAULT;
f1fae91f
PT
333 fNameWidth = Utils.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
334 fNameWidthPref, fMinNameWidth, MAX_NAME_WIDTH);
837a2f8c
PT
335 }
336
337 void saveOptions() {
f1fae91f 338 Utils.saveIntOption(getPreferenceString("namewidth"), fNameWidth); //$NON-NLS-1$
837a2f8c
PT
339 }
340
a0a88f65
AM
341 /**
342 * Create a data viewer.
343 *
344 * @param parent
345 * Parent composite
346 * @param style
347 * Style to use
348 * @return The new data viewer
349 */
837a2f8c
PT
350 protected Control createDataViewer(Composite parent, int style) {
351 loadOptions();
f1fae91f
PT
352 fColorScheme = new TimeGraphColorScheme();
353 fDataViewer = new Composite(parent, style) {
837a2f8c
PT
354 @Override
355 public void redraw() {
f1fae91f
PT
356 fTimeScaleCtrl.redraw();
357 fTimeGraphCtrl.redraw();
837a2f8c
PT
358 super.redraw();
359 }
360 };
361 GridLayout gl = new GridLayout(2, false);
f1fae91f 362 gl.marginHeight = fBorderWidth;
837a2f8c
PT
363 gl.marginWidth = 0;
364 gl.verticalSpacing = 0;
365 gl.horizontalSpacing = 0;
f1fae91f 366 fDataViewer.setLayout(gl);
837a2f8c 367
f1fae91f 368 fTimeScaleCtrl = new TimeGraphScale(fDataViewer, fColorScheme);
0fab12b0 369 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
f1fae91f
PT
370 fTimeScaleCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
371 fTimeScaleCtrl.setHeight(fTimeScaleHeight);
6b11be52
PT
372 fTimeScaleCtrl.addMouseWheelListener(new MouseWheelListener() {
373 @Override
374 public void mouseScrolled(MouseEvent e) {
375 fTimeGraphCtrl.zoom(e.count > 0);
376 }
377 });
837a2f8c 378
f1fae91f
PT
379 fVerticalScrollBar = new Slider(fDataViewer, SWT.VERTICAL | SWT.NO_FOCUS);
380 fVerticalScrollBar.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false, true, 1, 2));
381 fVerticalScrollBar.addSelectionListener(new SelectionAdapter() {
837a2f8c
PT
382 @Override
383 public void widgetSelected(SelectionEvent e) {
f1fae91f 384 setTopIndex(fVerticalScrollBar.getSelection());
837a2f8c
PT
385 }
386 });
837a2f8c 387
f1fae91f 388 fTimeGraphCtrl = createTimeGraphControl(fDataViewer, fColorScheme);
837a2f8c 389
f1fae91f 390 fTimeGraphCtrl.setTimeProvider(this);
0fcf3b09 391 fTimeGraphCtrl.setTimeGraphScale(fTimeScaleCtrl);
f1fae91f 392 fTimeGraphCtrl.addSelectionListener(this);
b698ec63 393 fTimeGraphCtrl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
f1fae91f 394 fTimeGraphCtrl.addMouseWheelListener(new MouseWheelListener() {
837a2f8c
PT
395 @Override
396 public void mouseScrolled(MouseEvent e) {
397 adjustVerticalScrollBar();
398 }
399 });
f1fae91f 400 fTimeGraphCtrl.addKeyListener(new KeyAdapter() {
837a2f8c
PT
401 @Override
402 public void keyPressed(KeyEvent e) {
dc5ed8a6
XR
403 if (e.character == '+') {
404 zoomIn();
405 } else if (e.character == '-') {
406 zoomOut();
407 }
837a2f8c
PT
408 adjustVerticalScrollBar();
409 }
410 });
411
b698ec63
PT
412 fHorizontalScrollBar = new Slider(fDataViewer, SWT.HORIZONTAL | SWT.NO_FOCUS);
413 fHorizontalScrollBar.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
414 fHorizontalScrollBar.addListener(SWT.MouseWheel, new Listener() {
415 @Override
416 public void handleEvent(Event event) {
417 if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) {
418 getTimeGraphControl().zoom(event.count > 0);
419 } else {
420 getTimeGraphControl().horizontalScroll(event.count > 0);
421 }
422 // don't handle the immediately following SWT.Selection event
423 event.doit = false;
424 }
425 });
426 fHorizontalScrollBar.addListener(SWT.Selection, new Listener() {
427 @Override
428 public void handleEvent(Event event) {
429 int start = fHorizontalScrollBar.getSelection();
430 long time0 = getTime0();
431 long time1 = getTime1();
432 long timeMin = getMinTime();
433 long timeMax = getMaxTime();
434 long delta = timeMax - timeMin;
435
436 long range = time1 - time0;
437 time0 = timeMin + Math.round(delta * ((double) start / H_SCROLLBAR_MAX));
438 time1 = time0 + range;
439
10ad9fa6 440 setStartFinishTimeNotify(time0, time1);
b698ec63
PT
441 }
442 });
443
f1fae91f 444 Composite filler = new Composite(fDataViewer, SWT.NONE);
837a2f8c 445 GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
b698ec63 446 gd.heightHint = fHorizontalScrollBar.getSize().y;
837a2f8c
PT
447 filler.setLayoutData(gd);
448 filler.setLayout(new FillLayout());
449
f1fae91f 450 fTimeGraphCtrl.addControlListener(new ControlAdapter() {
837a2f8c
PT
451 @Override
452 public void controlResized(ControlEvent event) {
453 resizeControls();
454 }
455 });
456 resizeControls();
f1fae91f 457 fDataViewer.update();
b698ec63 458 adjustHorizontalScrollBar();
837a2f8c 459 adjustVerticalScrollBar();
f1fae91f 460 return fDataViewer;
837a2f8c
PT
461 }
462
463 /**
464 * Dispose the view.
465 */
466 public void dispose() {
467 saveOptions();
f1fae91f
PT
468 fTimeGraphCtrl.dispose();
469 fDataViewer.dispose();
470 fColorScheme.dispose();
837a2f8c
PT
471 }
472
96d00a83 473 /**
a0a88f65
AM
474 * Create a new time graph control.
475 *
476 * @param parent
477 * The parent composite
478 * @param colors
479 * The color scheme
480 * @return The new TimeGraphControl
96d00a83 481 */
a0a88f65
AM
482 protected TimeGraphControl createTimeGraphControl(Composite parent,
483 TimeGraphColorScheme colors) {
96d00a83 484 return new TimeGraphControl(parent, colors);
837a2f8c
PT
485 }
486
487 /**
488 * Resize the controls
489 */
490 public void resizeControls() {
f1fae91f 491 Rectangle r = fDataViewer.getClientArea();
837a2f8c
PT
492 if (r.isEmpty()) {
493 return;
494 }
495
496 int width = r.width;
f1fae91f
PT
497 if (fNameWidth > width - fMinNameWidth) {
498 fNameWidth = width - fMinNameWidth;
837a2f8c 499 }
f1fae91f
PT
500 if (fNameWidth < fMinNameWidth) {
501 fNameWidth = fMinNameWidth;
837a2f8c 502 }
b698ec63 503 adjustHorizontalScrollBar();
837a2f8c
PT
504 adjustVerticalScrollBar();
505 }
506
507 /**
50d36521
PT
508 * Recalculate the time bounds based on the time graph entries,
509 * if the user-specified bound is set to SWT.DEFAULT.
837a2f8c 510 *
50d36521
PT
511 * @param entries
512 * The root time graph entries in the model
837a2f8c 513 */
50d36521
PT
514 public void setTimeRange(ITimeGraphEntry entries[]) {
515 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
516 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
517 if (fBeginTime != SWT.DEFAULT && fEndTime != SWT.DEFAULT) {
518 return;
519 }
520 if (entries == null || entries.length == 0) {
521 return;
522 }
523 if (fTime0Bound == SWT.DEFAULT) {
524 fTime0Bound = Long.MAX_VALUE;
525 }
526 if (fTime1Bound == SWT.DEFAULT) {
527 fTime1Bound = Long.MIN_VALUE;
528 }
529 for (ITimeGraphEntry entry : entries) {
530 setTimeRange(entry);
531 }
532 }
533
534 private void setTimeRange(ITimeGraphEntry entry) {
535 if (fBeginTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getStartTime() != SWT.DEFAULT) {
536 fTime0Bound = Math.min(entry.getStartTime(), fTime0Bound);
537 }
538 if (fEndTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getEndTime() != SWT.DEFAULT) {
539 fTime1Bound = Math.max(entry.getEndTime(), fTime1Bound);
540 }
541 if (entry.hasChildren()) {
542 for (ITimeGraphEntry child : entry.getChildren()) {
543 setTimeRange(child);
837a2f8c
PT
544 }
545 }
50d36521 546 }
837a2f8c 547
50d36521
PT
548 /**
549 * Set the time bounds to the provided values.
550 *
551 * @param beginTime
552 * The bounds begin time, or SWT.DEFAULT to use the input bounds
553 * @param endTime
554 * The bounds end time, or SWT.DEFAULT to use the input bounds
555 */
556 public void setTimeBounds(long beginTime, long endTime) {
557 fBeginTime = beginTime;
558 fEndTime = endTime;
559 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
560 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
561 if (fTime0Bound > fTime1Bound) {
562 // only possible if both are not default
563 fBeginTime = endTime;
564 fEndTime = beginTime;
565 fTime0Bound = fBeginTime;
566 fTime1Bound = fEndTime;
837a2f8c 567 }
50d36521 568 adjustHorizontalScrollBar();
837a2f8c
PT
569 }
570
571 /**
50d36521 572 * Recalculate the current time window when bounds have changed.
837a2f8c
PT
573 */
574 public void setTimeBounds() {
f1fae91f
PT
575 if (!fTimeRangeFixed) {
576 fTime0 = fTime0Bound;
577 fTime1 = fTime1Bound;
837a2f8c 578 }
407bfdd5
PT
579 fTime0 = Math.max(fTime0Bound, Math.min(fTime0, fTime1Bound));
580 fTime1 = Math.max(fTime0Bound, Math.min(fTime1, fTime1Bound));
f1fae91f
PT
581 if (fTime1 - fTime0 < fMinTimeInterval) {
582 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
837a2f8c
PT
583 }
584 }
585
837a2f8c
PT
586 /**
587 * @param traces
588 */
589 private void refreshAllData(ITimeGraphEntry[] traces) {
590 setTimeBounds();
0fcf3b09
PT
591 if (fSelectionBegin < fBeginTime) {
592 fSelectionBegin = fBeginTime;
593 } else if (fSelectionBegin > fEndTime) {
594 fSelectionBegin = fEndTime;
595 }
596 if (fSelectionEnd < fBeginTime) {
597 fSelectionEnd = fBeginTime;
598 } else if (fSelectionEnd > fEndTime) {
599 fSelectionEnd = fEndTime;
837a2f8c 600 }
f1fae91f
PT
601 fTimeGraphCtrl.refreshData(traces);
602 fTimeScaleCtrl.redraw();
837a2f8c
PT
603 adjustVerticalScrollBar();
604 }
605
606 /**
607 * Callback for when this view is focused
608 */
609 public void setFocus() {
f1fae91f
PT
610 if (null != fTimeGraphCtrl) {
611 fTimeGraphCtrl.setFocus();
837a2f8c
PT
612 }
613 }
614
615 /**
616 * Get the current focus status of this view.
617 *
618 * @return If the view is currently focused, or not
619 */
620 public boolean isInFocus() {
f1fae91f 621 return fTimeGraphCtrl.isInFocus();
837a2f8c
PT
622 }
623
624 /**
625 * Get the view's current selection
626 *
627 * @return The entry that is selected
628 */
629 public ITimeGraphEntry getSelection() {
f1fae91f 630 return fTimeGraphCtrl.getSelectedTrace();
837a2f8c
PT
631 }
632
633 /**
634 * Get the index of the current selection
635 *
636 * @return The index
637 */
638 public int getSelectionIndex() {
f1fae91f 639 return fTimeGraphCtrl.getSelectedIndex();
837a2f8c
PT
640 }
641
642 @Override
643 public long getTime0() {
f1fae91f 644 return fTime0;
837a2f8c
PT
645 }
646
647 @Override
648 public long getTime1() {
f1fae91f 649 return fTime1;
837a2f8c
PT
650 }
651
652 @Override
653 public long getMinTimeInterval() {
f1fae91f 654 return fMinTimeInterval;
837a2f8c
PT
655 }
656
657 @Override
658 public int getNameSpace() {
f1fae91f 659 return fNameWidth;
837a2f8c
PT
660 }
661
662 @Override
663 public void setNameSpace(int width) {
f1fae91f
PT
664 fNameWidth = width;
665 int w = fTimeGraphCtrl.getClientArea().width;
666 if (fNameWidth > w - MIN_NAME_WIDTH) {
667 fNameWidth = w - MIN_NAME_WIDTH;
837a2f8c 668 }
f1fae91f
PT
669 if (fNameWidth < MIN_NAME_WIDTH) {
670 fNameWidth = MIN_NAME_WIDTH;
837a2f8c 671 }
f1fae91f
PT
672 fTimeGraphCtrl.redraw();
673 fTimeScaleCtrl.redraw();
837a2f8c
PT
674 }
675
676 @Override
677 public int getTimeSpace() {
f1fae91f
PT
678 int w = fTimeGraphCtrl.getClientArea().width;
679 return w - fNameWidth;
837a2f8c
PT
680 }
681
837a2f8c
PT
682 @Override
683 public long getBeginTime() {
f1fae91f 684 return fBeginTime;
837a2f8c
PT
685 }
686
687 @Override
688 public long getEndTime() {
f1fae91f 689 return fEndTime;
837a2f8c
PT
690 }
691
692 @Override
693 public long getMaxTime() {
f1fae91f 694 return fTime1Bound;
837a2f8c
PT
695 }
696
697 @Override
698 public long getMinTime() {
f1fae91f 699 return fTime0Bound;
837a2f8c
PT
700 }
701
0fcf3b09
PT
702 @Override
703 public long getSelectionBegin() {
704 return fSelectionBegin;
705 }
706
0fcf3b09
PT
707 @Override
708 public long getSelectionEnd() {
709 return fSelectionEnd;
710 }
711
837a2f8c
PT
712 @Override
713 public void setStartFinishTimeNotify(long time0, long time1) {
714 setStartFinishTime(time0, time1);
10ad9fa6 715 notifyRangeListeners();
837a2f8c
PT
716 }
717
837a2f8c
PT
718 @Override
719 public void notifyStartFinishTime() {
10ad9fa6 720 notifyRangeListeners();
837a2f8c
PT
721 }
722
837a2f8c
PT
723 @Override
724 public void setStartFinishTime(long time0, long time1) {
f1fae91f
PT
725 fTime0 = time0;
726 if (fTime0 < fTime0Bound) {
727 fTime0 = fTime0Bound;
837a2f8c 728 }
f1fae91f
PT
729 if (fTime0 > fTime1Bound) {
730 fTime0 = fTime1Bound;
837a2f8c 731 }
f1fae91f
PT
732 fTime1 = time1;
733 if (fTime1 < fTime0Bound) {
734 fTime1 = fTime0Bound;
837a2f8c 735 }
f1fae91f
PT
736 if (fTime1 > fTime1Bound) {
737 fTime1 = fTime1Bound;
837a2f8c 738 }
f1fae91f
PT
739 if (fTime1 - fTime0 < fMinTimeInterval) {
740 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
837a2f8c 741 }
f1fae91f 742 fTimeRangeFixed = true;
b698ec63 743 adjustHorizontalScrollBar();
f1fae91f
PT
744 fTimeGraphCtrl.redraw();
745 fTimeScaleCtrl.redraw();
837a2f8c
PT
746 }
747
837a2f8c
PT
748 @Override
749 public void resetStartFinishTime() {
f1fae91f
PT
750 setStartFinishTime(fTime0Bound, fTime1Bound);
751 fTimeRangeFixed = false;
837a2f8c
PT
752 }
753
754 @Override
755 public void setSelectedTimeNotify(long time, boolean ensureVisible) {
756 setSelectedTimeInt(time, ensureVisible, true);
757 }
758
759 @Override
760 public void setSelectedTime(long time, boolean ensureVisible) {
761 setSelectedTimeInt(time, ensureVisible, false);
762 }
763
0fcf3b09
PT
764 @Override
765 public void setSelectionRangeNotify(long beginTime, long endTime) {
766 boolean changed = (beginTime != fSelectionBegin || endTime != fSelectionEnd);
767 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
768 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
769 fTimeGraphCtrl.redraw();
770 fTimeScaleCtrl.redraw();
771 if (changed) {
10ad9fa6 772 notifyTimeListeners();
0fcf3b09
PT
773 }
774 }
775
0fcf3b09
PT
776 @Override
777 public void setSelectionRange(long beginTime, long endTime) {
778 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
779 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
780 fTimeGraphCtrl.redraw();
781 fTimeScaleCtrl.redraw();
782 }
783
837a2f8c 784 private void setSelectedTimeInt(long time, boolean ensureVisible, boolean doNotify) {
f1fae91f
PT
785 long time0 = fTime0;
786 long time1 = fTime1;
837a2f8c 787 if (ensureVisible) {
f1fae91f
PT
788 long timeSpace = (fTime1 - fTime0) / RECENTERING_MARGIN_FACTOR;
789 long timeMid = (fTime1 - fTime0) / 2;
790 if (time < fTime0 + timeSpace) {
791 long dt = fTime0 - time + timeMid;
792 fTime0 -= dt;
793 fTime1 -= dt;
794 } else if (time > fTime1 - timeSpace) {
795 long dt = time - fTime1 + timeMid;
796 fTime0 += dt;
797 fTime1 += dt;
837a2f8c 798 }
f1fae91f
PT
799 if (fTime0 < fTime0Bound) {
800 fTime1 = Math.min(fTime1Bound, fTime1 + (fTime0Bound - fTime0));
801 fTime0 = fTime0Bound;
802 } else if (fTime1 > fTime1Bound) {
803 fTime0 = Math.max(fTime0Bound, fTime0 - (fTime1 - fTime1Bound));
804 fTime1 = fTime1Bound;
837a2f8c
PT
805 }
806 }
f1fae91f
PT
807 if (fTime1 - fTime0 < fMinTimeInterval) {
808 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
837a2f8c 809 }
b698ec63 810 adjustHorizontalScrollBar();
f1fae91f
PT
811 fTimeGraphCtrl.redraw();
812 fTimeScaleCtrl.redraw();
837a2f8c 813
0fcf3b09
PT
814 boolean notifySelectedTime = (time != fSelectionBegin || time != fSelectionEnd);
815 fSelectionBegin = time;
816 fSelectionEnd = time;
837a2f8c 817
f1fae91f 818 if (doNotify && ((time0 != fTime0) || (time1 != fTime1))) {
10ad9fa6 819 notifyRangeListeners();
837a2f8c
PT
820 }
821
822 if (doNotify && notifySelectedTime) {
10ad9fa6 823 notifyTimeListeners();
837a2f8c
PT
824 }
825 }
826
827 @Override
828 public void widgetDefaultSelected(SelectionEvent e) {
f1fae91f
PT
829 if (fSelectedEntry != getSelection()) {
830 fSelectedEntry = getSelection();
10ad9fa6 831 notifySelectionListeners();
837a2f8c
PT
832 }
833 }
834
835 @Override
836 public void widgetSelected(SelectionEvent e) {
f1fae91f
PT
837 if (fSelectedEntry != getSelection()) {
838 fSelectedEntry = getSelection();
10ad9fa6 839 notifySelectionListeners();
837a2f8c
PT
840 }
841 }
842
843 /**
844 * Callback for when the next event is selected
845 */
846 public void selectNextEvent() {
f1fae91f 847 fTimeGraphCtrl.selectNextEvent();
837a2f8c
PT
848 adjustVerticalScrollBar();
849 }
850
851 /**
852 * Callback for when the previous event is selected
853 */
854 public void selectPrevEvent() {
f1fae91f 855 fTimeGraphCtrl.selectPrevEvent();
837a2f8c
PT
856 adjustVerticalScrollBar();
857 }
858
859 /**
860 * Callback for when the next item is selected
861 */
862 public void selectNextItem() {
f1fae91f 863 fTimeGraphCtrl.selectNextTrace();
837a2f8c
PT
864 adjustVerticalScrollBar();
865 }
866
867 /**
868 * Callback for when the previous item is selected
869 */
870 public void selectPrevItem() {
f1fae91f 871 fTimeGraphCtrl.selectPrevTrace();
837a2f8c
PT
872 adjustVerticalScrollBar();
873 }
874
875 /**
876 * Callback for the show legend action
877 */
878 public void showLegend() {
f1fae91f 879 if (fDataViewer == null || fDataViewer.isDisposed()) {
837a2f8c
PT
880 return;
881 }
882
f1fae91f 883 TimeGraphLegend.open(fDataViewer.getShell(), fTimeGraphProvider);
837a2f8c
PT
884 }
885
886 /**
887 * Callback for the Zoom In action
888 */
889 public void zoomIn() {
f1fae91f 890 fTimeGraphCtrl.zoomIn();
837a2f8c
PT
891 }
892
893 /**
894 * Callback for the Zoom Out action
895 */
896 public void zoomOut() {
f1fae91f 897 fTimeGraphCtrl.zoomOut();
837a2f8c
PT
898 }
899
900 private String getPreferenceString(String string) {
901 return getViewTypeStr() + "." + string; //$NON-NLS-1$
902 }
903
904 /**
905 * Add a selection listener
906 *
907 * @param listener
908 * The listener to add
909 */
910 public void addSelectionListener(ITimeGraphSelectionListener listener) {
911 fSelectionListeners.add(listener);
912 }
913
914 /**
915 * Remove a selection listener
916 *
917 * @param listener
918 * The listener to remove
919 */
920 public void removeSelectionListener(ITimeGraphSelectionListener listener) {
921 fSelectionListeners.remove(listener);
922 }
923
10ad9fa6
PT
924 private void notifySelectionListeners() {
925 synchronized (fListenerNotifierLock) {
926 if (fListenerNotifier == null) {
927 fListenerNotifier = new ListenerNotifier();
928 fListenerNotifier.start();
929 }
930 fListenerNotifier.selectionChanged();
931 }
932 }
933
934 private void fireSelectionChanged(ITimeGraphEntry selection) {
837a2f8c
PT
935 TimeGraphSelectionEvent event = new TimeGraphSelectionEvent(this, selection);
936
937 for (ITimeGraphSelectionListener listener : fSelectionListeners) {
938 listener.selectionChanged(event);
939 }
940 }
941
942 /**
943 * Add a time listener
944 *
945 * @param listener
946 * The listener to add
947 */
948 public void addTimeListener(ITimeGraphTimeListener listener) {
949 fTimeListeners.add(listener);
950 }
951
952 /**
953 * Remove a time listener
954 *
955 * @param listener
956 * The listener to remove
957 */
958 public void removeTimeListener(ITimeGraphTimeListener listener) {
959 fTimeListeners.remove(listener);
960 }
961
10ad9fa6
PT
962 private void notifyTimeListeners() {
963 synchronized (fListenerNotifierLock) {
964 if (fListenerNotifier == null) {
965 fListenerNotifier = new ListenerNotifier();
966 fListenerNotifier.start();
967 }
968 fListenerNotifier.timeSelected();
969 }
970 }
971
972 private void fireTimeSelected(long startTime, long endTime) {
0fcf3b09 973 TimeGraphTimeEvent event = new TimeGraphTimeEvent(this, startTime, endTime);
837a2f8c
PT
974
975 for (ITimeGraphTimeListener listener : fTimeListeners) {
976 listener.timeSelected(event);
977 }
978 }
979
980 /**
981 * Add a range listener
982 *
983 * @param listener
984 * The listener to add
985 */
986 public void addRangeListener(ITimeGraphRangeListener listener) {
987 fRangeListeners.add(listener);
988 }
989
990 /**
991 * Remove a range listener
992 *
993 * @param listener
994 * The listener to remove
995 */
996 public void removeRangeListener(ITimeGraphRangeListener listener) {
997 fRangeListeners.remove(listener);
998 }
999
10ad9fa6
PT
1000 private void notifyRangeListeners() {
1001 synchronized (fListenerNotifierLock) {
1002 if (fListenerNotifier == null) {
1003 fListenerNotifier = new ListenerNotifier();
1004 fListenerNotifier.start();
1005 }
1006 fListenerNotifier.timeRangeUpdated();
1007 }
1008 }
1009
1010 private void fireTimeRangeUpdated(long startTime, long endTime) {
837a2f8c 1011 // Check if the time has actually changed from last notification
f1fae91f 1012 if (startTime != fTime0ExtSynch || endTime != fTime1ExtSynch) {
837a2f8c
PT
1013 // Notify Time Scale Selection Listeners
1014 TimeGraphRangeUpdateEvent event = new TimeGraphRangeUpdateEvent(this, startTime, endTime);
1015
1016 for (ITimeGraphRangeListener listener : fRangeListeners) {
1017 listener.timeRangeUpdated(event);
1018 }
1019
1020 // update external synch timers
1021 updateExtSynchTimers();
1022 }
1023 }
1024
1025 /**
1026 * Callback to set a selected event in the view
1027 *
1028 * @param event
1029 * The event that was selected
1030 * @param source
1031 * The source of this selection event
1032 */
1033 public void setSelectedEvent(ITimeEvent event, Object source) {
1034 if (event == null || source == this) {
1035 return;
1036 }
f1fae91f
PT
1037 fSelectedEntry = event.getEntry();
1038 fTimeGraphCtrl.selectItem(fSelectedEntry, false);
837a2f8c
PT
1039
1040 setSelectedTimeInt(event.getTime(), true, true);
1041 adjustVerticalScrollBar();
1042 }
1043
1044 /**
1045 * Set the seeked time of a trace
1046 *
1047 * @param trace
1048 * The trace that was seeked
1049 * @param time
1050 * The target time
1051 * @param source
1052 * The source of this seek event
1053 */
1054 public void setSelectedTraceTime(ITimeGraphEntry trace, long time, Object source) {
1055 if (trace == null || source == this) {
1056 return;
1057 }
f1fae91f
PT
1058 fSelectedEntry = trace;
1059 fTimeGraphCtrl.selectItem(trace, false);
837a2f8c
PT
1060
1061 setSelectedTimeInt(time, true, true);
1062 }
1063
1064 /**
1065 * Callback for a trace selection
1066 *
1067 * @param trace
1068 * The trace that was selected
1069 */
1070 public void setSelection(ITimeGraphEntry trace) {
f1fae91f
PT
1071 fSelectedEntry = trace;
1072 fTimeGraphCtrl.selectItem(trace, false);
837a2f8c
PT
1073 adjustVerticalScrollBar();
1074 }
1075
1076 /**
1077 * Callback for a time window selection
1078 *
1079 * @param time0
1080 * Start time of the range
1081 * @param time1
1082 * End time of the range
1083 * @param source
1084 * Source of the event
1085 */
1086 public void setSelectVisTimeWindow(long time0, long time1, Object source) {
1087 if (source == this) {
1088 return;
1089 }
1090
1091 setStartFinishTime(time0, time1);
1092
1093 // update notification time values since we are now in synch with the
1094 // external application
1095 updateExtSynchTimers();
1096 }
1097
1098 /**
1099 * update the cache timers used to identify the need to send a time window
1100 * update to external registered listeners
1101 */
1102 private void updateExtSynchTimers() {
1103 // last time notification cache
f1fae91f
PT
1104 fTime0ExtSynch = fTime0;
1105 fTime1ExtSynch = fTime1;
837a2f8c
PT
1106 }
1107
026664b7
XR
1108 @Override
1109 public TimeFormat getTimeFormat() {
f1fae91f 1110 return fTimeFormat;
837a2f8c
PT
1111 }
1112
026664b7 1113 /**
79ec0b89
PT
1114 * @param tf
1115 * the {@link TimeFormat} used to display timestamps
026664b7
XR
1116 */
1117 public void setTimeFormat(TimeFormat tf) {
f1fae91f 1118 this.fTimeFormat = tf;
0fab12b0
PT
1119 if (tf == TimeFormat.CYCLES) {
1120 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1121 } else {
1122 fTimeDataProvider = this;
1123 }
1124 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1125 if (fToolTipHandler != null) {
1126 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1127 }
1128 }
1129
1130 /**
1131 * Sets the clock frequency. Used when the time format is set to CYCLES.
1132 *
1133 * @param clockFrequency
1134 * the clock frequency in Hz
0fab12b0
PT
1135 */
1136 public void setClockFrequency(long clockFrequency) {
1137 fClockFrequency = clockFrequency;
1138 if (fTimeFormat == TimeFormat.CYCLES) {
1139 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1140 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1141 if (fToolTipHandler != null) {
1142 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1143 }
1144 }
837a2f8c
PT
1145 }
1146
1147 /**
1148 * Retrieve the border width
1149 *
1150 * @return The width
1151 */
1152 public int getBorderWidth() {
f1fae91f 1153 return fBorderWidth;
837a2f8c
PT
1154 }
1155
1156 /**
1157 * Set the border width
1158 *
1159 * @param borderWidth
1160 * The width
1161 */
1162 public void setBorderWidth(int borderWidth) {
1163 if (borderWidth > -1) {
f1fae91f 1164 this.fBorderWidth = borderWidth;
79ec0b89 1165 GridLayout gl = (GridLayout) fDataViewer.getLayout();
837a2f8c
PT
1166 gl.marginHeight = borderWidth;
1167 }
1168 }
1169
1170 /**
1171 * Retrieve the height of the header
1172 *
1173 * @return The height
1174 */
1175 public int getHeaderHeight() {
f1fae91f 1176 return fTimeScaleHeight;
837a2f8c
PT
1177 }
1178
1179 /**
1180 * Set the height of the header
1181 *
1182 * @param headerHeight
1183 * The height to set
1184 */
1185 public void setHeaderHeight(int headerHeight) {
1186 if (headerHeight > -1) {
f1fae91f
PT
1187 this.fTimeScaleHeight = headerHeight;
1188 fTimeScaleCtrl.setHeight(headerHeight);
837a2f8c
PT
1189 }
1190 }
1191
1192 /**
1193 * Retrieve the height of an item row
1194 *
1195 * @return The height
1196 */
1197 public int getItemHeight() {
f1fae91f
PT
1198 if (fTimeGraphCtrl != null) {
1199 return fTimeGraphCtrl.getItemHeight();
837a2f8c
PT
1200 }
1201 return 0;
1202 }
1203
1204 /**
1205 * Set the height of an item row
1206 *
1207 * @param rowHeight
1208 * The height to set
1209 */
1210 public void setItemHeight(int rowHeight) {
f1fae91f
PT
1211 if (fTimeGraphCtrl != null) {
1212 fTimeGraphCtrl.setItemHeight(rowHeight);
837a2f8c
PT
1213 }
1214 }
1215
1216 /**
1217 * Set the minimum item width
1218 *
1219 * @param width
1220 * The min width
1221 */
1222 public void setMinimumItemWidth(int width) {
f1fae91f
PT
1223 if (fTimeGraphCtrl != null) {
1224 fTimeGraphCtrl.setMinimumItemWidth(width);
837a2f8c
PT
1225 }
1226 }
1227
1228 /**
1229 * Set the width for the name column
1230 *
79ec0b89
PT
1231 * @param width
1232 * The width
837a2f8c
PT
1233 */
1234 public void setNameWidthPref(int width) {
f1fae91f 1235 fNameWidthPref = width;
837a2f8c 1236 if (width == 0) {
f1fae91f
PT
1237 fMinNameWidth = 0;
1238 fNameWidth = 0;
837a2f8c
PT
1239 }
1240 }
1241
1242 /**
1243 * Retrieve the configure width for the name column
1244 *
1245 * @param width
1246 * Unused?
1247 * @return The width
1248 */
1249 public int getNameWidthPref(int width) {
f1fae91f 1250 return fNameWidthPref;
837a2f8c
PT
1251 }
1252
1253 /**
1254 * Returns the primary control associated with this viewer.
1255 *
1256 * @return the SWT control which displays this viewer's content
1257 */
1258 public Control getControl() {
f1fae91f 1259 return fDataViewer;
837a2f8c
PT
1260 }
1261
1262 /**
1263 * Returns the time graph control associated with this viewer.
1264 *
1265 * @return the time graph control
1266 */
3e9a3685 1267 public TimeGraphControl getTimeGraphControl() {
f1fae91f 1268 return fTimeGraphCtrl;
837a2f8c
PT
1269 }
1270
1271 /**
1272 * Returns the time graph scale associated with this viewer.
1273 *
1274 * @return the time graph scale
1275 */
3e9a3685 1276 public TimeGraphScale getTimeGraphScale() {
f1fae91f 1277 return fTimeScaleCtrl;
837a2f8c
PT
1278 }
1279
713a70ae
PT
1280 /**
1281 * Return the x coordinate corresponding to a time
1282 *
79ec0b89
PT
1283 * @param time
1284 * the time
713a70ae 1285 * @return the x coordinate corresponding to the time
713a70ae
PT
1286 */
1287 public int getXForTime(long time) {
f1fae91f 1288 return fTimeGraphCtrl.getXForTime(time);
713a70ae
PT
1289 }
1290
1291 /**
1292 * Return the time corresponding to an x coordinate
1293 *
79ec0b89
PT
1294 * @param x
1295 * the x coordinate
713a70ae 1296 * @return the time corresponding to the x coordinate
713a70ae
PT
1297 */
1298 public long getTimeAtX(int x) {
f1fae91f 1299 return fTimeGraphCtrl.getTimeAtX(x);
713a70ae
PT
1300 }
1301
837a2f8c
PT
1302 /**
1303 * Get the selection provider
1304 *
1305 * @return the selection provider
1306 */
1307 public ISelectionProvider getSelectionProvider() {
f1fae91f 1308 return fTimeGraphCtrl;
837a2f8c
PT
1309 }
1310
1311 /**
1312 * Wait for the cursor
1313 *
1314 * @param waitInd
1315 * Wait indefinitely?
1316 */
1317 public void waitCursor(boolean waitInd) {
f1fae91f 1318 fTimeGraphCtrl.waitCursor(waitInd);
837a2f8c
PT
1319 }
1320
1321 /**
1322 * Get the horizontal scroll bar object
1323 *
1324 * @return The scroll bar
1325 */
b698ec63
PT
1326 public Slider getHorizontalBar() {
1327 return fHorizontalScrollBar;
837a2f8c
PT
1328 }
1329
1330 /**
1331 * Get the vertical scroll bar object
1332 *
1333 * @return The scroll bar
1334 */
1335 public Slider getVerticalBar() {
f1fae91f 1336 return fVerticalScrollBar;
837a2f8c
PT
1337 }
1338
1339 /**
1340 * Set the given index as the top one
1341 *
1342 * @param index
1343 * The index that will go to the top
1344 */
1345 public void setTopIndex(int index) {
f1fae91f 1346 fTimeGraphCtrl.setTopIndex(index);
837a2f8c
PT
1347 adjustVerticalScrollBar();
1348 }
1349
1350 /**
1351 * Retrieve the current top index
1352 *
1353 * @return The top index
1354 */
1355 public int getTopIndex() {
f1fae91f 1356 return fTimeGraphCtrl.getTopIndex();
837a2f8c
PT
1357 }
1358
f4617471
PT
1359 /**
1360 * Sets the auto-expand level to be used when the input of the viewer is set
1361 * using {@link #setInput(Object)}. The value 0 means that there is no
1362 * auto-expand; 1 means that top-level elements are expanded, but not their
1363 * children; 2 means that top-level elements are expanded, and their
1364 * children, but not grand-children; and so on.
1365 * <p>
1366 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1367 * </p>
1368 * @param level
1369 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1370 * levels of the tree
f4617471
PT
1371 */
1372 public void setAutoExpandLevel(int level) {
1373 fTimeGraphCtrl.setAutoExpandLevel(level);
1374 }
1375
1376 /**
1377 * Returns the auto-expand level.
1378 *
1379 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1380 * the tree are expanded automatically
1381 * @see #setAutoExpandLevel
f4617471
PT
1382 */
1383 public int getAutoExpandLevel() {
1384 return fTimeGraphCtrl.getAutoExpandLevel();
1385 }
1386
837a2f8c
PT
1387 /**
1388 * Set the expanded state of an entry
1389 *
1390 * @param entry
1391 * The entry to expand/collapse
1392 * @param expanded
1393 * True for expanded, false for collapsed
1394 */
1395 public void setExpandedState(ITimeGraphEntry entry, boolean expanded) {
f1fae91f 1396 fTimeGraphCtrl.setExpandedState(entry, expanded);
837a2f8c
PT
1397 adjustVerticalScrollBar();
1398 }
1399
1400 /**
1401 * Collapses all nodes of the viewer's tree, starting with the root.
837a2f8c
PT
1402 */
1403 public void collapseAll() {
f1fae91f 1404 fTimeGraphCtrl.collapseAll();
837a2f8c
PT
1405 adjustVerticalScrollBar();
1406 }
1407
1408 /**
1409 * Expands all nodes of the viewer's tree, starting with the root.
837a2f8c
PT
1410 */
1411 public void expandAll() {
f1fae91f 1412 fTimeGraphCtrl.expandAll();
837a2f8c
PT
1413 adjustVerticalScrollBar();
1414 }
1415
1416 /**
1417 * Get the number of sub-elements when expanded
1418 *
1419 * @return The element count
1420 */
1421 public int getExpandedElementCount() {
f1fae91f 1422 return fTimeGraphCtrl.getExpandedElementCount();
837a2f8c
PT
1423 }
1424
1425 /**
1426 * Get the sub-elements
1427 *
1428 * @return The array of entries that are below this one
1429 */
1430 public ITimeGraphEntry[] getExpandedElements() {
f1fae91f 1431 return fTimeGraphCtrl.getExpandedElements();
837a2f8c
PT
1432 }
1433
1434 /**
1435 * Add a tree listener
1436 *
1437 * @param listener
1438 * The listener to add
1439 */
1440 public void addTreeListener(ITimeGraphTreeListener listener) {
f1fae91f 1441 fTimeGraphCtrl.addTreeListener(listener);
837a2f8c
PT
1442 }
1443
1444 /**
1445 * Remove a tree listener
1446 *
1447 * @param listener
1448 * The listener to remove
1449 */
1450 public void removeTreeListener(ITimeGraphTreeListener listener) {
f1fae91f 1451 fTimeGraphCtrl.removeTreeListener(listener);
837a2f8c
PT
1452 }
1453
1454 /**
1455 * Get the reset scale action.
1456 *
1457 * @return The Action object
1458 */
1459 public Action getResetScaleAction() {
f1fae91f 1460 if (fResetScaleAction == null) {
837a2f8c 1461 // resetScale
f1fae91f 1462 fResetScaleAction = new Action() {
837a2f8c
PT
1463 @Override
1464 public void run() {
1465 resetStartFinishTime();
894d6929 1466 notifyStartFinishTime();
837a2f8c
PT
1467 }
1468 };
f1fae91f
PT
1469 fResetScaleAction.setText(Messages.TmfTimeGraphViewer_ResetScaleActionNameText);
1470 fResetScaleAction.setToolTipText(Messages.TmfTimeGraphViewer_ResetScaleActionToolTipText);
1471 fResetScaleAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU));
837a2f8c 1472 }
f1fae91f 1473 return fResetScaleAction;
837a2f8c
PT
1474 }
1475
1476 /**
1477 * Get the show legend action.
1478 *
1479 * @return The Action object
1480 */
1481 public Action getShowLegendAction() {
f1fae91f 1482 if (fShowLegendAction == null) {
837a2f8c 1483 // showLegend
f1fae91f 1484 fShowLegendAction = new Action() {
837a2f8c
PT
1485 @Override
1486 public void run() {
1487 showLegend();
1488 }
1489 };
f1fae91f
PT
1490 fShowLegendAction.setText(Messages.TmfTimeGraphViewer_LegendActionNameText);
1491 fShowLegendAction.setToolTipText(Messages.TmfTimeGraphViewer_LegendActionToolTipText);
1492 fShowLegendAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LEGEND));
837a2f8c
PT
1493 }
1494
f1fae91f 1495 return fShowLegendAction;
837a2f8c
PT
1496 }
1497
1498 /**
1499 * Get the the next event action.
1500 *
1501 * @return The action object
1502 */
1503 public Action getNextEventAction() {
f1fae91f
PT
1504 if (fNextEventAction == null) {
1505 fNextEventAction = new Action() {
837a2f8c
PT
1506 @Override
1507 public void run() {
1508 selectNextEvent();
1509 }
1510 };
1511
f1fae91f
PT
1512 fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText);
1513 fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText);
1514 fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT));
837a2f8c
PT
1515 }
1516
f1fae91f 1517 return fNextEventAction;
837a2f8c
PT
1518 }
1519
1520 /**
1521 * Get the previous event action.
1522 *
1523 * @return The Action object
1524 */
1525 public Action getPreviousEventAction() {
f1fae91f
PT
1526 if (fPrevEventAction == null) {
1527 fPrevEventAction = new Action() {
837a2f8c
PT
1528 @Override
1529 public void run() {
1530 selectPrevEvent();
1531 }
1532 };
1533
f1fae91f
PT
1534 fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText);
1535 fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText);
1536 fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT));
837a2f8c
PT
1537 }
1538
f1fae91f 1539 return fPrevEventAction;
837a2f8c
PT
1540 }
1541
1542 /**
1543 * Get the next item action.
1544 *
1545 * @return The Action object
1546 */
1547 public Action getNextItemAction() {
f1fae91f 1548 if (fNextItemAction == null) {
837a2f8c 1549
f1fae91f 1550 fNextItemAction = new Action() {
837a2f8c
PT
1551 @Override
1552 public void run() {
1553 selectNextItem();
1554 }
1555 };
f1fae91f
PT
1556 fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText);
1557 fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText);
1558 fNextItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_ITEM));
837a2f8c 1559 }
f1fae91f 1560 return fNextItemAction;
837a2f8c
PT
1561 }
1562
1563 /**
1564 * Get the previous item action.
1565 *
1566 * @return The Action object
1567 */
1568 public Action getPreviousItemAction() {
f1fae91f 1569 if (fPreviousItemAction == null) {
837a2f8c 1570
f1fae91f 1571 fPreviousItemAction = new Action() {
837a2f8c
PT
1572 @Override
1573 public void run() {
1574 selectPrevItem();
1575 }
1576 };
f1fae91f
PT
1577 fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText);
1578 fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText);
1579 fPreviousItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_ITEM));
837a2f8c 1580 }
f1fae91f 1581 return fPreviousItemAction;
837a2f8c
PT
1582 }
1583
1584 /**
1585 * Get the zoom in action
1586 *
1587 * @return The Action object
1588 */
1589 public Action getZoomInAction() {
f1fae91f
PT
1590 if (fZoomInAction == null) {
1591 fZoomInAction = new Action() {
837a2f8c
PT
1592 @Override
1593 public void run() {
1594 zoomIn();
1595 }
1596 };
f1fae91f
PT
1597 fZoomInAction.setText(Messages.TmfTimeGraphViewer_ZoomInActionNameText);
1598 fZoomInAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomInActionToolTipText);
1599 fZoomInAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU));
837a2f8c 1600 }
f1fae91f 1601 return fZoomInAction;
837a2f8c
PT
1602 }
1603
1604 /**
1605 * Get the zoom out action
1606 *
1607 * @return The Action object
1608 */
1609 public Action getZoomOutAction() {
f1fae91f
PT
1610 if (fZoomOutAction == null) {
1611 fZoomOutAction = new Action() {
837a2f8c
PT
1612 @Override
1613 public void run() {
1614 zoomOut();
1615 }
1616 };
f1fae91f
PT
1617 fZoomOutAction.setText(Messages.TmfTimeGraphViewer_ZoomOutActionNameText);
1618 fZoomOutAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomOutActionToolTipText);
1619 fZoomOutAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU));
837a2f8c 1620 }
f1fae91f 1621 return fZoomOutAction;
837a2f8c
PT
1622 }
1623
79ec0b89
PT
1624 /**
1625 * Get the hide arrows action
1626 *
1627 * @param dialogSettings
1628 * The dialog settings section where the state should be stored,
1629 * or null
1630 *
1631 * @return The Action object
79ec0b89
PT
1632 */
1633 public Action getHideArrowsAction(final IDialogSettings dialogSettings) {
1634 if (fHideArrowsAction == null) {
1635 fHideArrowsAction = new Action(Messages.TmfTimeGraphViewer_HideArrowsActionNameText, IAction.AS_CHECK_BOX) {
1636 @Override
1637 public void run() {
1638 boolean hideArrows = fHideArrowsAction.isChecked();
1639 fTimeGraphCtrl.hideArrows(hideArrows);
1640 refresh();
1641 if (dialogSettings != null) {
1642 dialogSettings.put(HIDE_ARROWS_KEY, hideArrows);
1643 }
086f21ae
PT
1644 if (fFollowArrowFwdAction != null) {
1645 fFollowArrowFwdAction.setEnabled(!hideArrows);
1646 }
1647 if (fFollowArrowBwdAction != null) {
1648 fFollowArrowBwdAction.setEnabled(!hideArrows);
1649 }
79ec0b89
PT
1650 }
1651 };
1652 fHideArrowsAction.setToolTipText(Messages.TmfTimeGraphViewer_HideArrowsActionToolTipText);
1653 fHideArrowsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HIDE_ARROWS));
1654 if (dialogSettings != null) {
1655 boolean hideArrows = dialogSettings.getBoolean(HIDE_ARROWS_KEY);
1656 fTimeGraphCtrl.hideArrows(hideArrows);
1657 fHideArrowsAction.setChecked(hideArrows);
086f21ae
PT
1658 if (fFollowArrowFwdAction != null) {
1659 fFollowArrowFwdAction.setEnabled(!hideArrows);
1660 }
1661 if (fFollowArrowBwdAction != null) {
1662 fFollowArrowBwdAction.setEnabled(!hideArrows);
1663 }
79ec0b89
PT
1664 }
1665 }
1666 return fHideArrowsAction;
1667 }
837a2f8c 1668
086f21ae
PT
1669 /**
1670 * Get the follow arrow forward action.
1671 *
1672 * @return The Action object
086f21ae
PT
1673 */
1674 public Action getFollowArrowFwdAction() {
1675 if (fFollowArrowFwdAction == null) {
1676 fFollowArrowFwdAction = new Action() {
1677 @Override
1678 public void run() {
1679 fTimeGraphCtrl.followArrowFwd();
1680 adjustVerticalScrollBar();
1681 }
1682 };
1683 fFollowArrowFwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionNameText);
1684 fFollowArrowFwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText);
1685 fFollowArrowFwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_FORWARD));
1686 if (fHideArrowsAction != null) {
1687 fFollowArrowFwdAction.setEnabled(!fHideArrowsAction.isChecked());
1688 }
1689 }
1690 return fFollowArrowFwdAction;
1691 }
1692
1693 /**
1694 * Get the follow arrow backward action.
1695 *
1696 * @return The Action object
086f21ae
PT
1697 */
1698 public Action getFollowArrowBwdAction() {
1699 if (fFollowArrowBwdAction == null) {
1700 fFollowArrowBwdAction = new Action() {
1701 @Override
1702 public void run() {
1703 fTimeGraphCtrl.followArrowBwd();
1704 adjustVerticalScrollBar();
1705 }
1706 };
1707 fFollowArrowBwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionNameText);
1708 fFollowArrowBwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText);
1709 fFollowArrowBwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_BACKWARD));
1710 if (fHideArrowsAction != null) {
1711 fFollowArrowBwdAction.setEnabled(!fHideArrowsAction.isChecked());
1712 }
1713 }
1714 return fFollowArrowBwdAction;
1715 }
1716
b698ec63
PT
1717 private void adjustHorizontalScrollBar() {
1718 long time0 = getTime0();
1719 long time1 = getTime1();
1720 long timeMin = getMinTime();
1721 long timeMax = getMaxTime();
1722 long delta = timeMax - timeMin;
1723 int timePos = 0;
1724 int thumb = H_SCROLLBAR_MAX;
1725 if (delta != 0) {
1726 // Thumb size (page size)
1727 thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta)));
1728 // At the beginning of visible window
1729 timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta));
1730 }
1731 fHorizontalScrollBar.setValues(timePos, 0, H_SCROLLBAR_MAX, thumb, Math.max(1, thumb / 2), Math.max(2, thumb));
1732 }
1733
837a2f8c 1734 private void adjustVerticalScrollBar() {
f1fae91f
PT
1735 int topIndex = fTimeGraphCtrl.getTopIndex();
1736 int countPerPage = fTimeGraphCtrl.countPerPage();
1737 int expandedElementCount = fTimeGraphCtrl.getExpandedElementCount();
837a2f8c 1738 if (topIndex + countPerPage > expandedElementCount) {
f1fae91f 1739 fTimeGraphCtrl.setTopIndex(Math.max(0, expandedElementCount - countPerPage));
837a2f8c
PT
1740 }
1741
f1fae91f 1742 int selection = fTimeGraphCtrl.getTopIndex();
837a2f8c
PT
1743 int min = 0;
1744 int max = Math.max(1, expandedElementCount - 1);
1745 int thumb = Math.min(max, Math.max(1, countPerPage - 1));
1746 int increment = 1;
1747 int pageIncrement = Math.max(1, countPerPage);
f1fae91f 1748 fVerticalScrollBar.setValues(selection, min, max, thumb, increment, pageIncrement);
837a2f8c
PT
1749 }
1750
27df1564 1751 /**
79ec0b89
PT
1752 * @param listener
1753 * a {@link MenuDetectListener}
2bdf0193 1754 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
1755 */
1756 public void addTimeGraphEntryMenuListener(MenuDetectListener listener) {
f1fae91f 1757 fTimeGraphCtrl.addTimeGraphEntryMenuListener(listener);
27df1564
XR
1758 }
1759
1760 /**
79ec0b89
PT
1761 * @param listener
1762 * a {@link MenuDetectListener}
2bdf0193 1763 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
1764 */
1765 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) {
f1fae91f 1766 fTimeGraphCtrl.removeTimeGraphEntryMenuListener(listener);
27df1564
XR
1767 }
1768
1769 /**
79ec0b89
PT
1770 * @param listener
1771 * a {@link MenuDetectListener}
2bdf0193 1772 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
1773 */
1774 public void addTimeEventMenuListener(MenuDetectListener listener) {
f1fae91f 1775 fTimeGraphCtrl.addTimeEventMenuListener(listener);
27df1564
XR
1776 }
1777
1778 /**
79ec0b89
PT
1779 * @param listener
1780 * a {@link MenuDetectListener}
2bdf0193 1781 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
1782 */
1783 public void removeTimeEventMenuListener(MenuDetectListener listener) {
f1fae91f 1784 fTimeGraphCtrl.removeTimeEventMenuListener(listener);
27df1564
XR
1785 }
1786
6ac5a950 1787 /**
79ec0b89
PT
1788 * @param filter
1789 * The filter object to be attached to the view
6ac5a950
AM
1790 */
1791 public void addFilter(ViewerFilter filter) {
f1fae91f 1792 fTimeGraphCtrl.addFilter(filter);
6ac5a950
AM
1793 refresh();
1794 }
837a2f8c 1795
6ac5a950 1796 /**
79ec0b89
PT
1797 * @param filter
1798 * The filter object to be attached to the view
6ac5a950
AM
1799 */
1800 public void removeFilter(ViewerFilter filter) {
f1fae91f 1801 fTimeGraphCtrl.removeFilter(filter);
6ac5a950
AM
1802 refresh();
1803 }
837a2f8c
PT
1804
1805}
This page took 0.181705 seconds and 5 git commands to generate.