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