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