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