TimeGraphViewer is a TmfViewer
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / TimeGraphViewer.java
CommitLineData
837a2f8c 1/*****************************************************************************
8910dea2 2 * Copyright (c) 2007, 2016 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;
1d012443
PT
20import java.util.Collections;
21import java.util.Comparator;
91512088 22import java.util.HashSet;
f1fae91f 23import java.util.List;
91512088 24import java.util.Set;
837a2f8c 25
367e2932 26import org.eclipse.jdt.annotation.NonNull;
837a2f8c 27import org.eclipse.jface.action.Action;
6d5b0ba1 28import org.eclipse.jface.action.ActionContributionItem;
79ec0b89 29import org.eclipse.jface.action.IAction;
6d5b0ba1 30import org.eclipse.jface.action.IMenuCreator;
91512088
PT
31import org.eclipse.jface.action.IMenuListener;
32import org.eclipse.jface.action.IMenuManager;
33import org.eclipse.jface.action.MenuManager;
79ec0b89 34import org.eclipse.jface.dialogs.IDialogSettings;
1d012443 35import org.eclipse.jface.resource.ImageDescriptor;
f4617471 36import org.eclipse.jface.viewers.AbstractTreeViewer;
837a2f8c 37import org.eclipse.jface.viewers.ISelectionProvider;
cfcfd964
PT
38import org.eclipse.jface.viewers.ITableLabelProvider;
39import org.eclipse.jface.viewers.ITreeContentProvider;
6ac5a950 40import org.eclipse.jface.viewers.ViewerFilter;
1d012443 41import org.eclipse.jface.window.Window;
837a2f8c
PT
42import org.eclipse.swt.SWT;
43import org.eclipse.swt.events.ControlAdapter;
44import org.eclipse.swt.events.ControlEvent;
45import org.eclipse.swt.events.KeyAdapter;
46import org.eclipse.swt.events.KeyEvent;
27df1564 47import org.eclipse.swt.events.MenuDetectListener;
837a2f8c
PT
48import org.eclipse.swt.events.MouseEvent;
49import org.eclipse.swt.events.MouseWheelListener;
50import org.eclipse.swt.events.SelectionAdapter;
51import org.eclipse.swt.events.SelectionEvent;
52import org.eclipse.swt.events.SelectionListener;
494c9b22 53import org.eclipse.swt.graphics.Point;
1d012443 54import org.eclipse.swt.graphics.RGBA;
837a2f8c
PT
55import org.eclipse.swt.graphics.Rectangle;
56import org.eclipse.swt.layout.FillLayout;
57import org.eclipse.swt.layout.GridData;
58import org.eclipse.swt.layout.GridLayout;
59import org.eclipse.swt.widgets.Composite;
60import org.eclipse.swt.widgets.Control;
10ad9fa6 61import org.eclipse.swt.widgets.Display;
b698ec63
PT
62import org.eclipse.swt.widgets.Event;
63import org.eclipse.swt.widgets.Listener;
6d5b0ba1 64import org.eclipse.swt.widgets.Menu;
837a2f8c 65import org.eclipse.swt.widgets.Slider;
2bdf0193
AM
66import org.eclipse.tracecompass.internal.tmf.ui.Activator;
67import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants;
68import org.eclipse.tracecompass.internal.tmf.ui.Messages;
1d012443 69import org.eclipse.tracecompass.internal.tmf.ui.dialogs.AddBookmarkDialog;
d2e4afa7 70import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
2802c35e 71import org.eclipse.tracecompass.tmf.ui.viewers.TmfViewer;
d2e4afa7 72import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
cfcfd964 73import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.ShowFilterDialogAction;
2bdf0193
AM
74import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TimeGraphLegend;
75import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
1d012443 76import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
2bdf0193
AM
77import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
78import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
1d012443 79import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.MarkerEvent;
f0a9cee1 80import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.IMarkerAxisListener;
2bdf0193
AM
81import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider;
82import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeDataProviderCyclesConverter;
83import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme;
84import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
dc4fa715 85import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphMarkerAxis;
2bdf0193
AM
86import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphScale;
87import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphTooltipHandler;
88import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
89import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
1d012443 90import org.eclipse.ui.PlatformUI;
837a2f8c
PT
91
92/**
93 * Generic time graph viewer implementation
94 *
837a2f8c
PT
95 * @author Patrick Tasse, and others
96 */
2802c35e 97public class TimeGraphViewer extends TmfViewer implements ITimeDataProvider, IMarkerAxisListener, SelectionListener {
837a2f8c 98
ae09c4ad 99 /** Constant indicating that all levels of the time graph should be expanded */
f4617471
PT
100 public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS;
101
f1fae91f
PT
102 private static final int DEFAULT_NAME_WIDTH = 200;
103 private static final int MIN_NAME_WIDTH = 6;
104 private static final int MAX_NAME_WIDTH = 1000;
105 private static final int DEFAULT_HEIGHT = 22;
79ec0b89 106 private static final String HIDE_ARROWS_KEY = "hide.arrows"; //$NON-NLS-1$
0fab12b0 107 private static final long DEFAULT_FREQUENCY = 1000000000L;
b698ec63 108 private static final int H_SCROLLBAR_MAX = Integer.MAX_VALUE - 1;
f1fae91f 109
27a40314
JCK
110 private static final ImageDescriptor ADD_BOOKMARK = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ADD_BOOKMARK);
111 private static final ImageDescriptor NEXT_BOOKMARK = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_BOOKMARK);
112 private static final ImageDescriptor PREVIOUS_BOOKMARK = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREVIOUS_BOOKMARK);
113 private static final ImageDescriptor REMOVE_BOOKMARK = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_REMOVE_BOOKMARK);
1d012443 114
f1fae91f 115 private long fMinTimeInterval;
f1fae91f 116 private ITimeGraphEntry fSelectedEntry;
50d36521
PT
117 private long fBeginTime = SWT.DEFAULT; // The user-specified bounds start time
118 private long fEndTime = SWT.DEFAULT; // The user-specified bounds end time
119 private long fTime0 = SWT.DEFAULT; // The current window start time
120 private long fTime1 = SWT.DEFAULT; // The current window end time
121 private long fSelectionBegin = SWT.DEFAULT;
122 private long fSelectionEnd = SWT.DEFAULT;
123 private long fTime0Bound = SWT.DEFAULT; // The bounds start time
124 private long fTime1Bound = SWT.DEFAULT; // The bounds end time
125 private long fTime0ExtSynch = SWT.DEFAULT;
126 private long fTime1ExtSynch = SWT.DEFAULT;
f1fae91f
PT
127 private boolean fTimeRangeFixed;
128 private int fNameWidthPref = DEFAULT_NAME_WIDTH;
129 private int fMinNameWidth = MIN_NAME_WIDTH;
130 private int fNameWidth;
131 private Composite fDataViewer;
132
133 private TimeGraphControl fTimeGraphCtrl;
134 private TimeGraphScale fTimeScaleCtrl;
dc4fa715 135 private TimeGraphMarkerAxis fMarkerAxisCtrl;
b698ec63 136 private Slider fHorizontalScrollBar;
f1fae91f 137 private Slider fVerticalScrollBar;
dc4fa715 138 private @NonNull TimeGraphColorScheme fColorScheme = new TimeGraphColorScheme();
4c9c0c87
PT
139 private Object fInputElement;
140 private ITimeGraphContentProvider fTimeGraphContentProvider;
837a2f8c 141 private ITimeGraphPresentationProvider fTimeGraphProvider;
dc4fa715 142 private @NonNull ITimeDataProvider fTimeDataProvider = this;
0fab12b0 143 private TimeGraphTooltipHandler fToolTipHandler;
837a2f8c 144
507b1336
AM
145 private List<ITimeGraphSelectionListener> fSelectionListeners = new ArrayList<>();
146 private List<ITimeGraphTimeListener> fTimeListeners = new ArrayList<>();
147 private List<ITimeGraphRangeListener> fRangeListeners = new ArrayList<>();
1d012443 148 private List<ITimeGraphBookmarkListener> fBookmarkListeners = new ArrayList<>();
837a2f8c 149
0fab12b0
PT
150 // Time format, using Epoch reference, Relative time format(default),
151 // Number, or Cycles
f1fae91f 152 private TimeFormat fTimeFormat = TimeFormat.RELATIVE;
0fab12b0
PT
153 // Clock frequency to use for Cycles time format
154 private long fClockFrequency = DEFAULT_FREQUENCY;
f1fae91f
PT
155 private int fBorderWidth = 0;
156 private int fTimeScaleHeight = DEFAULT_HEIGHT;
837a2f8c 157
f1fae91f
PT
158 private Action fResetScaleAction;
159 private Action fShowLegendAction;
160 private Action fNextEventAction;
161 private Action fPrevEventAction;
162 private Action fNextItemAction;
163 private Action fPreviousItemAction;
164 private Action fZoomInAction;
165 private Action fZoomOutAction;
79ec0b89 166 private Action fHideArrowsAction;
086f21ae
PT
167 private Action fFollowArrowFwdAction;
168 private Action fFollowArrowBwdAction;
cfcfd964 169 private ShowFilterDialogAction fShowFilterDialogAction;
1d012443 170 private Action fToggleBookmarkAction;
f72cd563
PT
171 private Action fNextMarkerAction;
172 private Action fPreviousMarkerAction;
91512088 173 private MenuManager fMarkersMenu;
1d012443
PT
174
175 /** The list of bookmarks */
176 private final List<IMarkerEvent> fBookmarks = new ArrayList<>();
177
91512088
PT
178 /** The list of marker categories */
179 private final List<String> fMarkerCategories = new ArrayList<>();
180
181 /** The set of hidden marker categories */
182 private final Set<String> fHiddenMarkerCategories = new HashSet<>();
183
6d5b0ba1
PT
184 /** The set of skipped marker categories */
185 private final Set<String> fSkippedMarkerCategories = new HashSet<>();
186
f72cd563
PT
187 /** The list of markers */
188 private final List<IMarkerEvent> fMarkers = new ArrayList<>();
189
10ad9fa6 190 private ListenerNotifier fListenerNotifier;
10ad9fa6 191
d2e4afa7
MAL
192 private Composite fTimeAlignedComposite;
193
69401011
JR
194 private final MouseWheelListeners fMouseWheelListeners = new MouseWheelListeners();
195 private final KeyListeners fKeyListeners = new KeyListeners();
196
197 private final class MouseWheelListeners {
198
199 private boolean fZoomEnabled;
200 private boolean fHorizontalScrollEnabled;
201
202 public MouseWheelListeners() {
203 super();
204 fZoomEnabled = true;
205 fHorizontalScrollEnabled = true;
206 }
207
208 public void setZoomEnabled(boolean enabled) {
209 fZoomEnabled = enabled;
210 }
211
212 public void setHorizontalScrollEnabled(boolean enabled) {
213 fHorizontalScrollEnabled = enabled;
214 }
215
216 public final MouseWheelListener fTimeGraphCtrlListener = new MouseWheelListener() {
217 @Override
218 public void mouseScrolled(MouseEvent e) {
219 if (e.count == 0) {
220 return;
221 }
222 /*
223 * On some platforms the mouse scroll event is sent to the
224 * control that has focus even if it is not under the cursor.
225 * Handle the event only if not over the time graph control.
226 */
227 Point ctrlParentCoords = fTimeAlignedComposite.toControl(fTimeGraphCtrl.toDisplay(e.x, e.y));
228 Point scrollBarParentCoords = fDataViewer.toControl(fTimeGraphCtrl.toDisplay(e.x, e.y));
229 if (fTimeGraphCtrl.getBounds().contains(ctrlParentCoords)) {
230 /* the time graph control handles the event */
231 adjustVerticalScrollBar();
232 } else if (fTimeScaleCtrl.getBounds().contains(ctrlParentCoords)
233 || fMarkerAxisCtrl.getBounds().contains(ctrlParentCoords)
234 || fHorizontalScrollBar.getBounds().contains(scrollBarParentCoords)) {
235 if (((e.stateMask & SWT.CTRL) != 0) && fZoomEnabled) {
236 fTimeGraphCtrl.zoom(e.count > 0);
237 } else if (fHorizontalScrollEnabled) {
238 fTimeGraphCtrl.horizontalScroll(e.count > 0);
239 }
240 } else {
241 /* over the vertical scroll bar or outside of the viewer */
242 setTopIndex(getTopIndex() - e.count);
243 }
244 }
245 };
246
247 public final MouseWheelListener fTimeScaleCtrlListener = new MouseWheelListener() {
248 @Override
249 public void mouseScrolled(MouseEvent e) {
250 if (e.count == 0) {
251 return;
252 }
253 if (((e.stateMask & SWT.CTRL) != 0) && fZoomEnabled) {
254 fTimeGraphCtrl.zoom(e.count > 0);
255 } else if (fHorizontalScrollEnabled) {
256 fTimeGraphCtrl.horizontalScroll(e.count > 0);
257 }
258 }
259 };
260
261 public final MouseWheelListener fMarkerAxisCtrlListener = new MouseWheelListener() {
262 @Override
263 public void mouseScrolled(MouseEvent e) {
264 if (e.count == 0) {
265 return;
266 }
267 if (((e.stateMask & SWT.CTRL) != 0) && fZoomEnabled) {
268 fTimeGraphCtrl.zoom(e.count > 0);
269 } else if (fHorizontalScrollEnabled) {
270 fTimeGraphCtrl.horizontalScroll(e.count > 0);
271 }
272 }
273 };
274
275 public final Listener fHorizontalScrollBarListener = new Listener() {
276 @Override
277 public void handleEvent(Event event) {
278 // don't handle the immediately following SWT.Selection event
279 event.doit = false;
280 if (event.count == 0) {
281 return;
282 }
283 if (((event.stateMask & SWT.CTRL) != 0) && fZoomEnabled) {
284 fTimeGraphCtrl.zoom(event.count > 0);
285 } else if (fHorizontalScrollEnabled) {
286 fTimeGraphCtrl.horizontalScroll(event.count > 0);
287 }
288 }
289 };
290 }
291
292 private final class KeyListeners {
293
294 private boolean fExtendToNextMarkerEnabled;
295 private boolean fSelectNextMarkerEnabled;
296 private boolean fExtendToPrevMarkerEnabled;
297 private boolean fSelectPrevMarkerEnabled;
298
299 public KeyListeners() {
300 fExtendToNextMarkerEnabled = true;
301 fSelectNextMarkerEnabled = true;
302 fExtendToPrevMarkerEnabled = true;
303 fSelectPrevMarkerEnabled = true;
304 }
305
306 public void setExtendToNextMarkerEnabled(boolean enabled) {
307 fExtendToNextMarkerEnabled = enabled;
308 }
309
310 public void setExtendToPrevMarkerEnabled(boolean enabled) {
311 fExtendToPrevMarkerEnabled = enabled;
312 }
313
314 public void setSelectNextMarkerEnabled(boolean enabled) {
315 fSelectNextMarkerEnabled = enabled;
316 }
317
318 public void setSelectPrevMarkerEnabled(boolean enabled) {
319 fSelectPrevMarkerEnabled = enabled;
320 }
321
322 public void setAllEnabled(boolean enabled) {
323 setExtendToNextMarkerEnabled(enabled);
324 setSelectNextMarkerEnabled(enabled);
325 setExtendToPrevMarkerEnabled(enabled);
326 setSelectPrevMarkerEnabled(enabled);
327 }
328
329 public final KeyAdapter fTimeGraphCtrlKeyListener = new KeyAdapter() {
330 @Override
331 public void keyPressed(KeyEvent e) {
332 boolean validEvent = false;
333 if (e.keyCode == '.') {
334 boolean extend = (e.stateMask & SWT.SHIFT) != 0;
335 if (extend && fExtendToNextMarkerEnabled) {
336 extendToNextMarker();
337 validEvent = true;
338 } else if (fSelectNextMarkerEnabled) {
339 selectNextMarker();
340 validEvent = true;
341 }
342 } else if (e.keyCode == ',') {
343 boolean extend = (e.stateMask & SWT.SHIFT) != 0;
344 if (extend && fExtendToPrevMarkerEnabled) {
345 extendToPrevMarker();
346 validEvent = true;
347 } else if (fSelectPrevMarkerEnabled) {
348 selectPrevMarker();
349 validEvent = true;
350 }
351 }
352 if (validEvent) {
353 adjustVerticalScrollBar();
354 }
355 }
356 };
357 }
358
10ad9fa6
PT
359 private class ListenerNotifier extends Thread {
360 private static final long DELAY = 400L;
361 private static final long POLLING_INTERVAL = 10L;
362 private long fLastUpdateTime = Long.MAX_VALUE;
363 private boolean fSelectionChanged = false;
364 private boolean fTimeRangeUpdated = false;
365 private boolean fTimeSelected = false;
366
367 @Override
368 public void run() {
369 while ((System.currentTimeMillis() - fLastUpdateTime) < DELAY) {
370 try {
371 Thread.sleep(POLLING_INTERVAL);
372 } catch (Exception e) {
373 return;
374 }
375 }
88de10c6
PT
376 Display.getDefault().asyncExec(new Runnable() {
377 @Override
378 public void run() {
379 if (fListenerNotifier != ListenerNotifier.this) {
380 return;
3ad34c5d 381 }
88de10c6
PT
382 fListenerNotifier = null;
383 if (ListenerNotifier.this.isInterrupted() || fDataViewer.isDisposed()) {
384 return;
385 }
386 if (fSelectionChanged) {
387 fireSelectionChanged(fSelectedEntry);
388 }
389 if (fTimeRangeUpdated) {
390 fireTimeRangeUpdated(fTime0, fTime1);
391 }
392 if (fTimeSelected) {
393 fireTimeSelected(fSelectionBegin, fSelectionEnd);
394 }
395 }
396 });
10ad9fa6
PT
397 }
398
399 public void selectionChanged() {
400 fSelectionChanged = true;
401 fLastUpdateTime = System.currentTimeMillis();
402 }
403
404 public void timeRangeUpdated() {
405 fTimeRangeUpdated = true;
406 fLastUpdateTime = System.currentTimeMillis();
407 }
408
409 public void timeSelected() {
410 fTimeSelected = true;
411 fLastUpdateTime = System.currentTimeMillis();
412 }
88de10c6
PT
413
414 public boolean hasSelectionChanged() {
415 return fSelectionChanged;
416 }
417
418 public boolean hasTimeRangeUpdated() {
419 return fTimeRangeUpdated;
420 }
421
422 public boolean hasTimeSelected() {
423 return fTimeSelected;
424 }
10ad9fa6
PT
425 }
426
f72cd563 427 private final static class MarkerComparator implements Comparator<IMarkerEvent> {
1d012443
PT
428 @Override
429 public int compare(IMarkerEvent o1, IMarkerEvent o2) {
430 int res = Long.compare(o1.getTime(), o2.getTime());
431 if (res != 0) {
432 return res;
433 }
434 return Long.compare(o1.getDuration(), o2.getDuration());
435 }
436 }
437
837a2f8c 438 /**
4c9c0c87
PT
439 * Standard constructor.
440 * <p>
441 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
837a2f8c
PT
442 *
443 * @param parent
444 * The parent UI composite object
445 * @param style
446 * The style to use
447 */
448 public TimeGraphViewer(Composite parent, int style) {
449 createDataViewer(parent, style);
d8a230f8 450 fTimeGraphContentProvider = new TimeGraphContentProvider();
837a2f8c
PT
451 }
452
453 /**
4c9c0c87
PT
454 * Sets the timegraph content provider used by this timegraph viewer.
455 *
456 * @param timeGraphContentProvider
457 * the timegraph content provider
4c9c0c87
PT
458 */
459 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) {
460 fTimeGraphContentProvider = timeGraphContentProvider;
461 }
462
463 /**
464 * Gets the timegraph content provider used by this timegraph viewer.
465 *
466 * @return the timegraph content provider
4c9c0c87
PT
467 */
468 public ITimeGraphContentProvider getTimeGraphContentProvider() {
469 return fTimeGraphContentProvider;
470 }
471
472 /**
473 * Sets the timegraph presentation provider used by this timegraph viewer.
837a2f8c 474 *
79ec0b89
PT
475 * @param timeGraphProvider
476 * the timegraph provider
837a2f8c
PT
477 */
478 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) {
479 fTimeGraphProvider = timeGraphProvider;
f1fae91f 480 fTimeGraphCtrl.setTimeGraphProvider(timeGraphProvider);
0fab12b0
PT
481 fToolTipHandler = new TimeGraphTooltipHandler(fTimeGraphProvider, fTimeDataProvider);
482 fToolTipHandler.activateHoverHelp(fTimeGraphCtrl);
837a2f8c
PT
483 }
484
cfcfd964
PT
485 /**
486 * Sets the tree columns for this time graph combo's filter dialog.
487 *
488 * @param columnNames the tree column names
066b02aa 489 * @since 1.2
cfcfd964
PT
490 */
491 public void setFilterColumns(String[] columnNames) {
492 getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames);
493 }
494
495 /**
496 * Sets the tree content provider used by the filter dialog
497 *
498 * @param contentProvider the tree content provider
066b02aa 499 * @since 1.2
cfcfd964
PT
500 */
501 public void setFilterContentProvider(ITreeContentProvider contentProvider) {
502 getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider);
503 }
504
505 /**
506 * Sets the tree label provider used by the filter dialog
507 *
508 * @param labelProvider the tree label provider
066b02aa 509 * @since 1.2
cfcfd964
PT
510 */
511 public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
512 getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider);
513 }
514
837a2f8c 515 /**
4c9c0c87 516 * Sets or clears the input for this time graph viewer.
837a2f8c 517 *
4c9c0c87 518 * @param inputElement
79ec0b89
PT
519 * The input of this time graph viewer, or <code>null</code> if
520 * none
837a2f8c 521 */
4c9c0c87
PT
522 public void setInput(Object inputElement) {
523 fInputElement = inputElement;
524 ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(inputElement);
88de10c6 525 fListenerNotifier = null;
f1fae91f 526 if (fTimeGraphCtrl != null) {
4c9c0c87 527 setTimeRange(input);
837a2f8c 528 setTopIndex(0);
50d36521
PT
529 fSelectionBegin = SWT.DEFAULT;
530 fSelectionEnd = SWT.DEFAULT;
f72cd563 531 updateMarkerActions();
f1fae91f 532 fSelectedEntry = null;
4c9c0c87 533 refreshAllData(input);
837a2f8c
PT
534 }
535 }
536
4c9c0c87
PT
537 /**
538 * Gets the input for this time graph viewer.
539 *
540 * @return The input of this time graph viewer, or <code>null</code> if none
4c9c0c87
PT
541 */
542 public Object getInput() {
543 return fInputElement;
544 }
545
bec1f1ac
GB
546 /**
547 * Sets (or clears if null) the list of links to display on this combo
548 *
549 * @param links
550 * the links to display in this time graph combo
bec1f1ac
GB
551 */
552 public void setLinks(List<ILinkEvent> links) {
553 if (fTimeGraphCtrl != null) {
554 fTimeGraphCtrl.refreshArrows(links);
555 }
556 }
557
837a2f8c
PT
558 /**
559 * Refresh the view
560 */
2802c35e 561 @Override
837a2f8c 562 public void refresh() {
4c9c0c87
PT
563 ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(fInputElement);
564 setTimeRange(input);
4c9c0c87 565 refreshAllData(input);
837a2f8c
PT
566 }
567
568 /**
569 * Callback for when the control is moved
570 *
571 * @param e
572 * The caller event
573 */
574 public void controlMoved(ControlEvent e) {
575 }
576
577 /**
578 * Callback for when the control is resized
579 *
580 * @param e
581 * The caller event
582 */
583 public void controlResized(ControlEvent e) {
584 resizeControls();
585 }
586
a0a88f65
AM
587 /**
588 * @return The string representing the view type
589 */
837a2f8c
PT
590 protected String getViewTypeStr() {
591 return "viewoption.threads"; //$NON-NLS-1$
592 }
593
a0a88f65 594 int getMarginWidth() {
837a2f8c
PT
595 return 0;
596 }
597
a0a88f65 598 int getMarginHeight() {
837a2f8c
PT
599 return 0;
600 }
601
602 void loadOptions() {
f1fae91f 603 fMinTimeInterval = 1;
50d36521
PT
604 fSelectionBegin = SWT.DEFAULT;
605 fSelectionEnd = SWT.DEFAULT;
f1fae91f
PT
606 fNameWidth = Utils.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
607 fNameWidthPref, fMinNameWidth, MAX_NAME_WIDTH);
837a2f8c
PT
608 }
609
610 void saveOptions() {
f1fae91f 611 Utils.saveIntOption(getPreferenceString("namewidth"), fNameWidth); //$NON-NLS-1$
837a2f8c
PT
612 }
613
a0a88f65
AM
614 /**
615 * Create a data viewer.
616 *
617 * @param parent
618 * Parent composite
619 * @param style
620 * Style to use
621 * @return The new data viewer
622 */
837a2f8c
PT
623 protected Control createDataViewer(Composite parent, int style) {
624 loadOptions();
f1fae91f 625 fDataViewer = new Composite(parent, style) {
837a2f8c
PT
626 @Override
627 public void redraw() {
f1fae91f
PT
628 fTimeScaleCtrl.redraw();
629 fTimeGraphCtrl.redraw();
dc4fa715 630 fMarkerAxisCtrl.redraw();
837a2f8c
PT
631 super.redraw();
632 }
633 };
25033fef
PT
634 fDataViewer.addDisposeListener((e) -> {
635 if (fMarkersMenu != null) {
636 fMarkersMenu.dispose();
1d012443
PT
637 }
638 });
837a2f8c 639 GridLayout gl = new GridLayout(2, false);
f1fae91f 640 gl.marginHeight = fBorderWidth;
837a2f8c
PT
641 gl.marginWidth = 0;
642 gl.verticalSpacing = 0;
643 gl.horizontalSpacing = 0;
f1fae91f 644 fDataViewer.setLayout(gl);
837a2f8c 645
d2e4afa7
MAL
646 fTimeAlignedComposite = new Composite(fDataViewer, style) {
647 @Override
648 public void redraw() {
649 fDataViewer.redraw();
650 super.redraw();
651 }
652 };
653 GridLayout gl2 = new GridLayout(1, false);
654 gl2.marginHeight = fBorderWidth;
655 gl2.marginWidth = 0;
656 gl2.verticalSpacing = 0;
657 gl2.horizontalSpacing = 0;
658 fTimeAlignedComposite.setLayout(gl2);
659 fTimeAlignedComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
660
661 fTimeScaleCtrl = new TimeGraphScale(fTimeAlignedComposite, fColorScheme);
0fab12b0 662 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
f1fae91f
PT
663 fTimeScaleCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
664 fTimeScaleCtrl.setHeight(fTimeScaleHeight);
69401011 665 fTimeScaleCtrl.addMouseWheelListener(fMouseWheelListeners.fTimeScaleCtrlListener);
837a2f8c 666
d2e4afa7 667 fTimeGraphCtrl = createTimeGraphControl(fTimeAlignedComposite, fColorScheme);
837a2f8c 668
f1fae91f 669 fTimeGraphCtrl.setTimeProvider(this);
0fcf3b09 670 fTimeGraphCtrl.setTimeGraphScale(fTimeScaleCtrl);
f1fae91f 671 fTimeGraphCtrl.addSelectionListener(this);
b698ec63 672 fTimeGraphCtrl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
69401011
JR
673 fTimeGraphCtrl.addMouseWheelListener(fMouseWheelListeners.fTimeGraphCtrlListener);
674 fTimeGraphCtrl.addKeyListener(fKeyListeners.fTimeGraphCtrlKeyListener);
837a2f8c 675
dc4fa715
PT
676 fMarkerAxisCtrl = createTimeGraphMarkerAxis(fTimeAlignedComposite, fColorScheme, this);
677 fMarkerAxisCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
f0a9cee1 678 fMarkerAxisCtrl.addMarkerAxisListener(this);
69401011 679 fMarkerAxisCtrl.addMouseWheelListener(fMouseWheelListeners.fMarkerAxisCtrlListener);
dc4fa715 680
d2e4afa7
MAL
681 fVerticalScrollBar = new Slider(fDataViewer, SWT.VERTICAL | SWT.NO_FOCUS);
682 fVerticalScrollBar.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false, true, 1, 1));
683 fVerticalScrollBar.addSelectionListener(new SelectionAdapter() {
684 @Override
685 public void widgetSelected(SelectionEvent e) {
686 setTopIndex(fVerticalScrollBar.getSelection());
687 }
688 });
689
b698ec63
PT
690 fHorizontalScrollBar = new Slider(fDataViewer, SWT.HORIZONTAL | SWT.NO_FOCUS);
691 fHorizontalScrollBar.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
69401011 692 fHorizontalScrollBar.addListener(SWT.MouseWheel, fMouseWheelListeners.fHorizontalScrollBarListener);
b698ec63
PT
693 fHorizontalScrollBar.addListener(SWT.Selection, new Listener() {
694 @Override
695 public void handleEvent(Event event) {
696 int start = fHorizontalScrollBar.getSelection();
697 long time0 = getTime0();
698 long time1 = getTime1();
699 long timeMin = getMinTime();
700 long timeMax = getMaxTime();
701 long delta = timeMax - timeMin;
702
703 long range = time1 - time0;
704 time0 = timeMin + Math.round(delta * ((double) start / H_SCROLLBAR_MAX));
705 time1 = time0 + range;
706
10ad9fa6 707 setStartFinishTimeNotify(time0, time1);
b698ec63
PT
708 }
709 });
710
f1fae91f 711 Composite filler = new Composite(fDataViewer, SWT.NONE);
837a2f8c 712 GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
b698ec63 713 gd.heightHint = fHorizontalScrollBar.getSize().y;
837a2f8c
PT
714 filler.setLayoutData(gd);
715 filler.setLayout(new FillLayout());
716
f1fae91f 717 fTimeGraphCtrl.addControlListener(new ControlAdapter() {
837a2f8c
PT
718 @Override
719 public void controlResized(ControlEvent event) {
720 resizeControls();
721 }
722 });
723 resizeControls();
f1fae91f 724 fDataViewer.update();
b698ec63 725 adjustHorizontalScrollBar();
837a2f8c 726 adjustVerticalScrollBar();
25033fef
PT
727
728 fDataViewer.addDisposeListener((e) -> {
729 saveOptions();
730 fColorScheme.dispose();
731 });
732
f1fae91f 733 return fDataViewer;
837a2f8c
PT
734 }
735
736 /**
25033fef 737 * Dispose the time graph viewer.
837a2f8c 738 */
2802c35e 739 @Override
837a2f8c 740 public void dispose() {
f1fae91f 741 fDataViewer.dispose();
837a2f8c
PT
742 }
743
96d00a83 744 /**
a0a88f65
AM
745 * Create a new time graph control.
746 *
747 * @param parent
748 * The parent composite
749 * @param colors
750 * The color scheme
751 * @return The new TimeGraphControl
96d00a83 752 */
a0a88f65
AM
753 protected TimeGraphControl createTimeGraphControl(Composite parent,
754 TimeGraphColorScheme colors) {
96d00a83 755 return new TimeGraphControl(parent, colors);
837a2f8c
PT
756 }
757
dc4fa715
PT
758 /**
759 * Create a new time graph marker axis.
760 *
761 * @param parent
762 * The parent composite object
763 * @param colorScheme
764 * The color scheme to use
765 * @param timeProvider
766 * The time data provider
767 * @return The new TimeGraphMarkerAxis
768 * @since 2.0
769 */
770 protected TimeGraphMarkerAxis createTimeGraphMarkerAxis(Composite parent,
771 @NonNull TimeGraphColorScheme colorScheme, @NonNull ITimeDataProvider timeProvider) {
772 return new TimeGraphMarkerAxis(parent, colorScheme, timeProvider);
773 }
774
837a2f8c
PT
775 /**
776 * Resize the controls
777 */
778 public void resizeControls() {
f1fae91f 779 Rectangle r = fDataViewer.getClientArea();
837a2f8c
PT
780 if (r.isEmpty()) {
781 return;
782 }
783
784 int width = r.width;
f1fae91f
PT
785 if (fNameWidth > width - fMinNameWidth) {
786 fNameWidth = width - fMinNameWidth;
837a2f8c 787 }
f1fae91f
PT
788 if (fNameWidth < fMinNameWidth) {
789 fNameWidth = fMinNameWidth;
837a2f8c 790 }
b698ec63 791 adjustHorizontalScrollBar();
837a2f8c
PT
792 adjustVerticalScrollBar();
793 }
794
795 /**
50d36521
PT
796 * Recalculate the time bounds based on the time graph entries,
797 * if the user-specified bound is set to SWT.DEFAULT.
837a2f8c 798 *
50d36521
PT
799 * @param entries
800 * The root time graph entries in the model
837a2f8c 801 */
50d36521
PT
802 public void setTimeRange(ITimeGraphEntry entries[]) {
803 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
804 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
805 if (fBeginTime != SWT.DEFAULT && fEndTime != SWT.DEFAULT) {
806 return;
807 }
808 if (entries == null || entries.length == 0) {
809 return;
810 }
811 if (fTime0Bound == SWT.DEFAULT) {
812 fTime0Bound = Long.MAX_VALUE;
813 }
814 if (fTime1Bound == SWT.DEFAULT) {
815 fTime1Bound = Long.MIN_VALUE;
816 }
817 for (ITimeGraphEntry entry : entries) {
818 setTimeRange(entry);
819 }
f778786a
PT
820 if (fTime0Bound > fTime1Bound) {
821 fTime0Bound = SWT.DEFAULT;
822 fTime1Bound = SWT.DEFAULT;
823 }
50d36521
PT
824 }
825
826 private void setTimeRange(ITimeGraphEntry entry) {
827 if (fBeginTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getStartTime() != SWT.DEFAULT) {
828 fTime0Bound = Math.min(entry.getStartTime(), fTime0Bound);
829 }
830 if (fEndTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getEndTime() != SWT.DEFAULT) {
831 fTime1Bound = Math.max(entry.getEndTime(), fTime1Bound);
832 }
833 if (entry.hasChildren()) {
834 for (ITimeGraphEntry child : entry.getChildren()) {
835 setTimeRange(child);
837a2f8c
PT
836 }
837 }
50d36521 838 }
837a2f8c 839
50d36521
PT
840 /**
841 * Set the time bounds to the provided values.
842 *
843 * @param beginTime
844 * The bounds begin time, or SWT.DEFAULT to use the input bounds
845 * @param endTime
846 * The bounds end time, or SWT.DEFAULT to use the input bounds
847 */
848 public void setTimeBounds(long beginTime, long endTime) {
849 fBeginTime = beginTime;
850 fEndTime = endTime;
851 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
852 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
853 if (fTime0Bound > fTime1Bound) {
854 // only possible if both are not default
855 fBeginTime = endTime;
856 fEndTime = beginTime;
857 fTime0Bound = fBeginTime;
858 fTime1Bound = fEndTime;
837a2f8c 859 }
50d36521 860 adjustHorizontalScrollBar();
837a2f8c
PT
861 }
862
863 /**
50d36521 864 * Recalculate the current time window when bounds have changed.
837a2f8c
PT
865 */
866 public void setTimeBounds() {
f1fae91f
PT
867 if (!fTimeRangeFixed) {
868 fTime0 = fTime0Bound;
869 fTime1 = fTime1Bound;
837a2f8c 870 }
407bfdd5
PT
871 fTime0 = Math.max(fTime0Bound, Math.min(fTime0, fTime1Bound));
872 fTime1 = Math.max(fTime0Bound, Math.min(fTime1, fTime1Bound));
f1fae91f
PT
873 if (fTime1 - fTime0 < fMinTimeInterval) {
874 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
837a2f8c
PT
875 }
876 }
877
837a2f8c
PT
878 /**
879 * @param traces
880 */
881 private void refreshAllData(ITimeGraphEntry[] traces) {
882 setTimeBounds();
0fcf3b09
PT
883 if (fSelectionBegin < fBeginTime) {
884 fSelectionBegin = fBeginTime;
885 } else if (fSelectionBegin > fEndTime) {
886 fSelectionBegin = fEndTime;
887 }
888 if (fSelectionEnd < fBeginTime) {
889 fSelectionEnd = fBeginTime;
890 } else if (fSelectionEnd > fEndTime) {
891 fSelectionEnd = fEndTime;
837a2f8c 892 }
f1fae91f
PT
893 fTimeGraphCtrl.refreshData(traces);
894 fTimeScaleCtrl.redraw();
dc4fa715 895 fMarkerAxisCtrl.redraw();
f72cd563 896 updateMarkerActions();
837a2f8c
PT
897 adjustVerticalScrollBar();
898 }
899
900 /**
901 * Callback for when this view is focused
902 */
903 public void setFocus() {
f1fae91f
PT
904 if (null != fTimeGraphCtrl) {
905 fTimeGraphCtrl.setFocus();
837a2f8c
PT
906 }
907 }
908
909 /**
910 * Get the current focus status of this view.
911 *
912 * @return If the view is currently focused, or not
913 */
914 public boolean isInFocus() {
f1fae91f 915 return fTimeGraphCtrl.isInFocus();
837a2f8c
PT
916 }
917
918 /**
919 * Get the view's current selection
920 *
921 * @return The entry that is selected
922 */
923 public ITimeGraphEntry getSelection() {
f1fae91f 924 return fTimeGraphCtrl.getSelectedTrace();
837a2f8c
PT
925 }
926
927 /**
928 * Get the index of the current selection
929 *
930 * @return The index
931 */
932 public int getSelectionIndex() {
f1fae91f 933 return fTimeGraphCtrl.getSelectedIndex();
837a2f8c
PT
934 }
935
936 @Override
937 public long getTime0() {
f1fae91f 938 return fTime0;
837a2f8c
PT
939 }
940
941 @Override
942 public long getTime1() {
f1fae91f 943 return fTime1;
837a2f8c
PT
944 }
945
946 @Override
947 public long getMinTimeInterval() {
f1fae91f 948 return fMinTimeInterval;
837a2f8c
PT
949 }
950
951 @Override
952 public int getNameSpace() {
f1fae91f 953 return fNameWidth;
837a2f8c
PT
954 }
955
956 @Override
957 public void setNameSpace(int width) {
f1fae91f
PT
958 fNameWidth = width;
959 int w = fTimeGraphCtrl.getClientArea().width;
960 if (fNameWidth > w - MIN_NAME_WIDTH) {
961 fNameWidth = w - MIN_NAME_WIDTH;
837a2f8c 962 }
f1fae91f
PT
963 if (fNameWidth < MIN_NAME_WIDTH) {
964 fNameWidth = MIN_NAME_WIDTH;
837a2f8c 965 }
f1fae91f
PT
966 fTimeGraphCtrl.redraw();
967 fTimeScaleCtrl.redraw();
dc4fa715
PT
968 fMarkerAxisCtrl.redraw();
969 /* force update the controls to keep them aligned */
970 fTimeScaleCtrl.update();
971 fMarkerAxisCtrl.update();
972 fTimeGraphCtrl.update();
837a2f8c
PT
973 }
974
975 @Override
976 public int getTimeSpace() {
f1fae91f
PT
977 int w = fTimeGraphCtrl.getClientArea().width;
978 return w - fNameWidth;
837a2f8c
PT
979 }
980
837a2f8c
PT
981 @Override
982 public long getBeginTime() {
f1fae91f 983 return fBeginTime;
837a2f8c
PT
984 }
985
986 @Override
987 public long getEndTime() {
f1fae91f 988 return fEndTime;
837a2f8c
PT
989 }
990
991 @Override
992 public long getMaxTime() {
f1fae91f 993 return fTime1Bound;
837a2f8c
PT
994 }
995
996 @Override
997 public long getMinTime() {
f1fae91f 998 return fTime0Bound;
837a2f8c
PT
999 }
1000
0fcf3b09
PT
1001 @Override
1002 public long getSelectionBegin() {
1003 return fSelectionBegin;
1004 }
1005
0fcf3b09
PT
1006 @Override
1007 public long getSelectionEnd() {
1008 return fSelectionEnd;
1009 }
1010
837a2f8c
PT
1011 @Override
1012 public void setStartFinishTimeNotify(long time0, long time1) {
88de10c6 1013 setStartFinishTimeInt(time0, time1);
10ad9fa6 1014 notifyRangeListeners();
837a2f8c
PT
1015 }
1016
837a2f8c
PT
1017 @Override
1018 public void notifyStartFinishTime() {
10ad9fa6 1019 notifyRangeListeners();
837a2f8c
PT
1020 }
1021
837a2f8c
PT
1022 @Override
1023 public void setStartFinishTime(long time0, long time1) {
88de10c6
PT
1024 /* if there is a pending time range, ignore this one */
1025 if (fListenerNotifier != null && fListenerNotifier.hasTimeRangeUpdated()) {
1026 return;
1027 }
1028 setStartFinishTimeInt(time0, time1);
45f63682 1029 updateExtSynchValues();
88de10c6
PT
1030 }
1031
1032 private void setStartFinishTimeInt(long time0, long time1) {
f1fae91f
PT
1033 fTime0 = time0;
1034 if (fTime0 < fTime0Bound) {
1035 fTime0 = fTime0Bound;
837a2f8c 1036 }
f1fae91f
PT
1037 if (fTime0 > fTime1Bound) {
1038 fTime0 = fTime1Bound;
837a2f8c 1039 }
f1fae91f
PT
1040 fTime1 = time1;
1041 if (fTime1 < fTime0Bound) {
1042 fTime1 = fTime0Bound;
837a2f8c 1043 }
f1fae91f
PT
1044 if (fTime1 > fTime1Bound) {
1045 fTime1 = fTime1Bound;
837a2f8c 1046 }
f1fae91f
PT
1047 if (fTime1 - fTime0 < fMinTimeInterval) {
1048 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
837a2f8c 1049 }
f1fae91f 1050 fTimeRangeFixed = true;
b698ec63 1051 adjustHorizontalScrollBar();
f1fae91f
PT
1052 fTimeGraphCtrl.redraw();
1053 fTimeScaleCtrl.redraw();
dc4fa715
PT
1054 fMarkerAxisCtrl.redraw();
1055 /* force update the controls to keep them aligned */
1056 fTimeScaleCtrl.update();
1057 fMarkerAxisCtrl.update();
1058 fTimeGraphCtrl.update();
837a2f8c
PT
1059 }
1060
837a2f8c
PT
1061 @Override
1062 public void resetStartFinishTime() {
88de10c6 1063 setStartFinishTimeNotify(fTime0Bound, fTime1Bound);
f1fae91f 1064 fTimeRangeFixed = false;
7255573c
PT
1065 }
1066
1067 /**
1068 * @since 2.0
1069 */
1070 @Override
1071 public void resetStartFinishTime(boolean notify) {
1072 if (notify) {
1073 setStartFinishTimeNotify(fTime0Bound, fTime1Bound);
1074 } else {
1075 setStartFinishTime(fTime0Bound, fTime1Bound);
1076 }
1077 fTimeRangeFixed = false;
837a2f8c
PT
1078 }
1079
1080 @Override
1081 public void setSelectedTimeNotify(long time, boolean ensureVisible) {
1082 setSelectedTimeInt(time, ensureVisible, true);
1083 }
1084
1085 @Override
1086 public void setSelectedTime(long time, boolean ensureVisible) {
88de10c6
PT
1087 /* if there is a pending time selection, ignore this one */
1088 if (fListenerNotifier != null && fListenerNotifier.hasTimeSelected()) {
1089 return;
1090 }
837a2f8c
PT
1091 setSelectedTimeInt(time, ensureVisible, false);
1092 }
1093
84c8aef7
PT
1094 private void setSelectedTimeInt(long time, boolean ensureVisible, boolean doNotify) {
1095 setSelectionRangeInt(time, time, ensureVisible, doNotify);
1096 }
1097
1098 /**
066b02aa 1099 * @since 1.2
84c8aef7 1100 */
0fcf3b09 1101 @Override
84c8aef7
PT
1102 public void setSelectionRangeNotify(long beginTime, long endTime, boolean ensureVisible) {
1103 setSelectionRangeInt(beginTime, endTime, ensureVisible, true);
0fcf3b09
PT
1104 }
1105
84c8aef7 1106 /**
066b02aa 1107 * @since 1.2
84c8aef7 1108 */
0fcf3b09 1109 @Override
84c8aef7 1110 public void setSelectionRange(long beginTime, long endTime, boolean ensureVisible) {
88de10c6
PT
1111 /* if there is a pending time selection, ignore this one */
1112 if (fListenerNotifier != null && fListenerNotifier.hasTimeSelected()) {
1113 return;
1114 }
84c8aef7 1115 setSelectionRangeInt(beginTime, endTime, ensureVisible, false);
0fcf3b09
PT
1116 }
1117
84c8aef7 1118 private void setSelectionRangeInt(long beginTime, long endTime, boolean ensureVisible, boolean doNotify) {
f1fae91f
PT
1119 long time0 = fTime0;
1120 long time1 = fTime1;
84c8aef7
PT
1121 long selectionBegin = fSelectionBegin;
1122 long selectionEnd = fSelectionEnd;
1123 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
1124 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
1125 boolean changed = (selectionBegin != fSelectionBegin || selectionEnd != fSelectionEnd);
1126
837a2f8c 1127 if (ensureVisible) {
84c8aef7 1128 ensureVisible(selectionBegin != fSelectionBegin ? fSelectionBegin : fSelectionEnd);
837a2f8c 1129 }
84c8aef7 1130
f1fae91f
PT
1131 fTimeGraphCtrl.redraw();
1132 fTimeScaleCtrl.redraw();
dc4fa715 1133 fMarkerAxisCtrl.redraw();
f72cd563 1134 updateMarkerActions();
837a2f8c 1135
37e1a265 1136 if ((time0 != fTime0) || (time1 != fTime1)) {
10ad9fa6 1137 notifyRangeListeners();
837a2f8c
PT
1138 }
1139
84c8aef7 1140 if (doNotify && changed) {
10ad9fa6 1141 notifyTimeListeners();
837a2f8c
PT
1142 }
1143 }
1144
33fa1fc7
PT
1145 private void ensureVisible(long time) {
1146 long timeMid = (fTime1 - fTime0) / 2;
1147 if (time < fTime0) {
1148 long dt = fTime0 - time + timeMid;
1149 fTime0 -= dt;
1150 fTime1 -= dt;
1151 } else if (time > fTime1) {
1152 long dt = time - fTime1 + timeMid;
1153 fTime0 += dt;
1154 fTime1 += dt;
1155 }
1156 if (fTime0 < fTime0Bound) {
1157 fTime1 = Math.min(fTime1Bound, fTime1 + (fTime0Bound - fTime0));
1158 fTime0 = fTime0Bound;
1159 } else if (fTime1 > fTime1Bound) {
1160 fTime0 = Math.max(fTime0Bound, fTime0 - (fTime1 - fTime1Bound));
1161 fTime1 = fTime1Bound;
1162 }
1163 if (fTime1 - fTime0 < fMinTimeInterval) {
1164 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
1165 }
1166 adjustHorizontalScrollBar();
1167 }
1168
837a2f8c
PT
1169 @Override
1170 public void widgetDefaultSelected(SelectionEvent e) {
f1fae91f
PT
1171 if (fSelectedEntry != getSelection()) {
1172 fSelectedEntry = getSelection();
10ad9fa6 1173 notifySelectionListeners();
837a2f8c
PT
1174 }
1175 }
1176
1177 @Override
1178 public void widgetSelected(SelectionEvent e) {
f1fae91f
PT
1179 if (fSelectedEntry != getSelection()) {
1180 fSelectedEntry = getSelection();
10ad9fa6 1181 notifySelectionListeners();
837a2f8c
PT
1182 }
1183 }
1184
1185 /**
1186 * Callback for when the next event is selected
33fa1fc7
PT
1187 *
1188 * @param extend
1189 * true to extend selection range, false for single selection
1190 * @since 1.0
837a2f8c 1191 */
33fa1fc7
PT
1192 public void selectNextEvent(boolean extend) {
1193 fTimeGraphCtrl.selectNextEvent(extend);
837a2f8c
PT
1194 adjustVerticalScrollBar();
1195 }
1196
1197 /**
1198 * Callback for when the previous event is selected
33fa1fc7
PT
1199 *
1200 * @param extend
1201 * true to extend selection range, false for single selection
1202 * @since 1.0
837a2f8c 1203 */
33fa1fc7
PT
1204 public void selectPrevEvent(boolean extend) {
1205 fTimeGraphCtrl.selectPrevEvent(extend);
837a2f8c
PT
1206 adjustVerticalScrollBar();
1207 }
1208
1209 /**
1210 * Callback for when the next item is selected
1211 */
1212 public void selectNextItem() {
f1fae91f 1213 fTimeGraphCtrl.selectNextTrace();
837a2f8c
PT
1214 adjustVerticalScrollBar();
1215 }
1216
1217 /**
1218 * Callback for when the previous item is selected
1219 */
1220 public void selectPrevItem() {
f1fae91f 1221 fTimeGraphCtrl.selectPrevTrace();
837a2f8c
PT
1222 adjustVerticalScrollBar();
1223 }
1224
1225 /**
1226 * Callback for the show legend action
1227 */
1228 public void showLegend() {
f1fae91f 1229 if (fDataViewer == null || fDataViewer.isDisposed()) {
837a2f8c
PT
1230 return;
1231 }
1232
f1fae91f 1233 TimeGraphLegend.open(fDataViewer.getShell(), fTimeGraphProvider);
837a2f8c
PT
1234 }
1235
1236 /**
1237 * Callback for the Zoom In action
1238 */
1239 public void zoomIn() {
f1fae91f 1240 fTimeGraphCtrl.zoomIn();
837a2f8c
PT
1241 }
1242
1243 /**
1244 * Callback for the Zoom Out action
1245 */
1246 public void zoomOut() {
f1fae91f 1247 fTimeGraphCtrl.zoomOut();
837a2f8c
PT
1248 }
1249
1250 private String getPreferenceString(String string) {
1251 return getViewTypeStr() + "." + string; //$NON-NLS-1$
1252 }
1253
1254 /**
1255 * Add a selection listener
1256 *
1257 * @param listener
1258 * The listener to add
1259 */
1260 public void addSelectionListener(ITimeGraphSelectionListener listener) {
1261 fSelectionListeners.add(listener);
1262 }
1263
1264 /**
1265 * Remove a selection listener
1266 *
1267 * @param listener
1268 * The listener to remove
1269 */
1270 public void removeSelectionListener(ITimeGraphSelectionListener listener) {
1271 fSelectionListeners.remove(listener);
1272 }
1273
10ad9fa6 1274 private void notifySelectionListeners() {
88de10c6
PT
1275 if (fListenerNotifier == null) {
1276 fListenerNotifier = new ListenerNotifier();
1277 fListenerNotifier.start();
10ad9fa6 1278 }
88de10c6 1279 fListenerNotifier.selectionChanged();
10ad9fa6
PT
1280 }
1281
1282 private void fireSelectionChanged(ITimeGraphEntry selection) {
837a2f8c
PT
1283 TimeGraphSelectionEvent event = new TimeGraphSelectionEvent(this, selection);
1284
1285 for (ITimeGraphSelectionListener listener : fSelectionListeners) {
1286 listener.selectionChanged(event);
1287 }
1288 }
1289
1290 /**
1291 * Add a time listener
1292 *
1293 * @param listener
1294 * The listener to add
1295 */
1296 public void addTimeListener(ITimeGraphTimeListener listener) {
1297 fTimeListeners.add(listener);
1298 }
1299
1300 /**
1301 * Remove a time listener
1302 *
1303 * @param listener
1304 * The listener to remove
1305 */
1306 public void removeTimeListener(ITimeGraphTimeListener listener) {
1307 fTimeListeners.remove(listener);
1308 }
1309
10ad9fa6 1310 private void notifyTimeListeners() {
88de10c6
PT
1311 if (fListenerNotifier == null) {
1312 fListenerNotifier = new ListenerNotifier();
1313 fListenerNotifier.start();
10ad9fa6 1314 }
88de10c6 1315 fListenerNotifier.timeSelected();
10ad9fa6
PT
1316 }
1317
1318 private void fireTimeSelected(long startTime, long endTime) {
0fcf3b09 1319 TimeGraphTimeEvent event = new TimeGraphTimeEvent(this, startTime, endTime);
837a2f8c
PT
1320
1321 for (ITimeGraphTimeListener listener : fTimeListeners) {
1322 listener.timeSelected(event);
1323 }
1324 }
1325
1326 /**
1327 * Add a range listener
1328 *
1329 * @param listener
1330 * The listener to add
1331 */
1332 public void addRangeListener(ITimeGraphRangeListener listener) {
1333 fRangeListeners.add(listener);
1334 }
1335
1336 /**
1337 * Remove a range listener
1338 *
1339 * @param listener
1340 * The listener to remove
1341 */
1342 public void removeRangeListener(ITimeGraphRangeListener listener) {
1343 fRangeListeners.remove(listener);
1344 }
1345
10ad9fa6 1346 private void notifyRangeListeners() {
88de10c6
PT
1347 if (fListenerNotifier == null) {
1348 fListenerNotifier = new ListenerNotifier();
1349 fListenerNotifier.start();
10ad9fa6 1350 }
88de10c6 1351 fListenerNotifier.timeRangeUpdated();
10ad9fa6
PT
1352 }
1353
1354 private void fireTimeRangeUpdated(long startTime, long endTime) {
837a2f8c 1355 // Check if the time has actually changed from last notification
f1fae91f 1356 if (startTime != fTime0ExtSynch || endTime != fTime1ExtSynch) {
837a2f8c
PT
1357 // Notify Time Scale Selection Listeners
1358 TimeGraphRangeUpdateEvent event = new TimeGraphRangeUpdateEvent(this, startTime, endTime);
1359
1360 for (ITimeGraphRangeListener listener : fRangeListeners) {
1361 listener.timeRangeUpdated(event);
1362 }
1363
45f63682
PT
1364 // update external synch values
1365 updateExtSynchValues();
837a2f8c
PT
1366 }
1367 }
1368
1d012443
PT
1369 /**
1370 * Add a bookmark listener
1371 *
1372 * @param listener
1373 * The listener to add
1374 * @since 2.0
1375 */
1376 public void addBookmarkListener(ITimeGraphBookmarkListener listener) {
1377 fBookmarkListeners.add(listener);
1378 }
1379
1380 /**
1381 * Remove a bookmark listener
1382 *
1383 * @param listener
1384 * The listener to remove
1385 * @since 2.0
1386 */
1387 public void removeBookmarkListener(ITimeGraphBookmarkListener listener) {
1388 fBookmarkListeners.remove(listener);
1389 }
1390
1391 private void fireBookmarkAdded(IMarkerEvent bookmark) {
1392 TimeGraphBookmarkEvent event = new TimeGraphBookmarkEvent(this, bookmark);
1393
1394 for (ITimeGraphBookmarkListener listener : fBookmarkListeners) {
1395 listener.bookmarkAdded(event);
1396 }
1397 }
1398
1399 private void fireBookmarkRemoved(IMarkerEvent bookmark) {
1400 TimeGraphBookmarkEvent event = new TimeGraphBookmarkEvent(this, bookmark);
1401
1402 for (ITimeGraphBookmarkListener listener : fBookmarkListeners) {
1403 listener.bookmarkRemoved(event);
1404 }
1405 }
1406
1407 /**
1408 * Set the bookmarks list.
1409 *
1410 * @param bookmarks
1411 * The bookmarks list, or null
1412 * @since 2.0
1413 */
1414 public void setBookmarks(List<IMarkerEvent> bookmarks) {
1d012443
PT
1415 fBookmarks.clear();
1416 if (bookmarks != null) {
1417 fBookmarks.addAll(bookmarks);
1d012443 1418 }
f72cd563
PT
1419 updateMarkerList();
1420 updateMarkerActions();
1d012443
PT
1421 }
1422
1423 /**
1424 * Get the bookmarks list.
1425 *
1426 * @return The bookmarks list
1427 * @since 2.0
1428 */
1429 public List<IMarkerEvent> getBookmarks() {
1430 return Collections.unmodifiableList(fBookmarks);
1431 }
1432
91512088
PT
1433 /**
1434 * Set the list of marker categories.
1435 *
1436 * @param categories
1437 * The list of marker categories, or null
1438 * @since 2.0
1439 */
1440 public void setMarkerCategories(List<String> categories) {
1441 fMarkerCategories.clear();
91512088
PT
1442 if (categories != null) {
1443 fMarkerCategories.addAll(categories);
1444 }
a924e2ed
PT
1445 fMarkerCategories.add(IMarkerEvent.BOOKMARKS);
1446 fMarkerAxisCtrl.setMarkerCategories(fMarkerCategories);
91512088
PT
1447 }
1448
f0a9cee1
PT
1449 /**
1450 * @since 2.0
1451 */
1452 @Override
1453 public void setMarkerCategoryVisible(String category, boolean visible) {
1454 boolean changed = false;
1455 if (visible) {
1456 changed = fHiddenMarkerCategories.remove(category);
1457 } else {
1458 changed = fHiddenMarkerCategories.add(category);
1459 }
1460 if (changed) {
1461 updateMarkerList();
1462 updateMarkerActions();
1463 getControl().redraw();
1464 }
1465 }
1466
f72cd563
PT
1467 /**
1468 * Set the markers list.
1469 *
1470 * @param markers
1471 * The markers list, or null
1472 * @since 2.0
1473 */
1474 public void setMarkers(List<IMarkerEvent> markers) {
1475 fMarkers.clear();
1476 if (markers != null) {
1477 fMarkers.addAll(markers);
1478 }
1479 updateMarkerList();
1480 updateMarkerActions();
1481 }
1482
1483 /**
1484 * Get the markers list.
1485 *
1486 * @return The markers list, or null
1487 * @since 2.0
1488 */
1489 public List<IMarkerEvent> getMarkers() {
1490 return Collections.unmodifiableList(fMarkers);
1491 }
1492
837a2f8c
PT
1493 /**
1494 * Callback to set a selected event in the view
1495 *
1496 * @param event
1497 * The event that was selected
1498 * @param source
1499 * The source of this selection event
1500 */
1501 public void setSelectedEvent(ITimeEvent event, Object source) {
1502 if (event == null || source == this) {
1503 return;
1504 }
f1fae91f
PT
1505 fSelectedEntry = event.getEntry();
1506 fTimeGraphCtrl.selectItem(fSelectedEntry, false);
837a2f8c
PT
1507
1508 setSelectedTimeInt(event.getTime(), true, true);
1509 adjustVerticalScrollBar();
1510 }
1511
1512 /**
1513 * Set the seeked time of a trace
1514 *
1515 * @param trace
1516 * The trace that was seeked
1517 * @param time
1518 * The target time
1519 * @param source
1520 * The source of this seek event
1521 */
1522 public void setSelectedTraceTime(ITimeGraphEntry trace, long time, Object source) {
1523 if (trace == null || source == this) {
1524 return;
1525 }
f1fae91f
PT
1526 fSelectedEntry = trace;
1527 fTimeGraphCtrl.selectItem(trace, false);
837a2f8c
PT
1528
1529 setSelectedTimeInt(time, true, true);
1530 }
1531
1532 /**
1533 * Callback for a trace selection
1534 *
1535 * @param trace
1536 * The trace that was selected
1537 */
1538 public void setSelection(ITimeGraphEntry trace) {
88de10c6
PT
1539 /* if there is a pending selection, ignore this one */
1540 if (fListenerNotifier != null && fListenerNotifier.hasSelectionChanged()) {
1541 return;
1542 }
f1fae91f
PT
1543 fSelectedEntry = trace;
1544 fTimeGraphCtrl.selectItem(trace, false);
837a2f8c
PT
1545 adjustVerticalScrollBar();
1546 }
1547
1548 /**
1549 * Callback for a time window selection
1550 *
1551 * @param time0
1552 * Start time of the range
1553 * @param time1
1554 * End time of the range
1555 * @param source
1556 * Source of the event
1557 */
1558 public void setSelectVisTimeWindow(long time0, long time1, Object source) {
1559 if (source == this) {
1560 return;
1561 }
1562
88de10c6 1563 setStartFinishTimeInt(time0, time1);
837a2f8c
PT
1564
1565 // update notification time values since we are now in synch with the
1566 // external application
45f63682 1567 updateExtSynchValues();
837a2f8c
PT
1568 }
1569
1570 /**
45f63682 1571 * update the cache values used to identify the need to send a time window
837a2f8c
PT
1572 * update to external registered listeners
1573 */
45f63682 1574 private void updateExtSynchValues() {
837a2f8c 1575 // last time notification cache
f1fae91f
PT
1576 fTime0ExtSynch = fTime0;
1577 fTime1ExtSynch = fTime1;
837a2f8c
PT
1578 }
1579
026664b7
XR
1580 @Override
1581 public TimeFormat getTimeFormat() {
f1fae91f 1582 return fTimeFormat;
837a2f8c
PT
1583 }
1584
026664b7 1585 /**
79ec0b89
PT
1586 * @param tf
1587 * the {@link TimeFormat} used to display timestamps
026664b7
XR
1588 */
1589 public void setTimeFormat(TimeFormat tf) {
f1fae91f 1590 this.fTimeFormat = tf;
0fab12b0
PT
1591 if (tf == TimeFormat.CYCLES) {
1592 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1593 } else {
1594 fTimeDataProvider = this;
1595 }
1596 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1597 if (fToolTipHandler != null) {
1598 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1599 }
1600 }
1601
1602 /**
1603 * Sets the clock frequency. Used when the time format is set to CYCLES.
1604 *
1605 * @param clockFrequency
1606 * the clock frequency in Hz
0fab12b0
PT
1607 */
1608 public void setClockFrequency(long clockFrequency) {
1609 fClockFrequency = clockFrequency;
1610 if (fTimeFormat == TimeFormat.CYCLES) {
1611 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1612 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1613 if (fToolTipHandler != null) {
1614 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1615 }
1616 }
837a2f8c
PT
1617 }
1618
1619 /**
1620 * Retrieve the border width
1621 *
1622 * @return The width
1623 */
1624 public int getBorderWidth() {
f1fae91f 1625 return fBorderWidth;
837a2f8c
PT
1626 }
1627
1628 /**
1629 * Set the border width
1630 *
1631 * @param borderWidth
1632 * The width
1633 */
1634 public void setBorderWidth(int borderWidth) {
1635 if (borderWidth > -1) {
f1fae91f 1636 this.fBorderWidth = borderWidth;
79ec0b89 1637 GridLayout gl = (GridLayout) fDataViewer.getLayout();
837a2f8c
PT
1638 gl.marginHeight = borderWidth;
1639 }
1640 }
1641
1642 /**
1643 * Retrieve the height of the header
1644 *
1645 * @return The height
1646 */
1647 public int getHeaderHeight() {
f1fae91f 1648 return fTimeScaleHeight;
837a2f8c
PT
1649 }
1650
1651 /**
1652 * Set the height of the header
1653 *
1654 * @param headerHeight
1655 * The height to set
1656 */
1657 public void setHeaderHeight(int headerHeight) {
1658 if (headerHeight > -1) {
f1fae91f
PT
1659 this.fTimeScaleHeight = headerHeight;
1660 fTimeScaleCtrl.setHeight(headerHeight);
837a2f8c
PT
1661 }
1662 }
1663
1664 /**
1665 * Retrieve the height of an item row
1666 *
1667 * @return The height
1668 */
1669 public int getItemHeight() {
f1fae91f
PT
1670 if (fTimeGraphCtrl != null) {
1671 return fTimeGraphCtrl.getItemHeight();
837a2f8c
PT
1672 }
1673 return 0;
1674 }
1675
1676 /**
1677 * Set the height of an item row
1678 *
1679 * @param rowHeight
1680 * The height to set
1681 */
1682 public void setItemHeight(int rowHeight) {
f1fae91f
PT
1683 if (fTimeGraphCtrl != null) {
1684 fTimeGraphCtrl.setItemHeight(rowHeight);
837a2f8c
PT
1685 }
1686 }
1687
1688 /**
1689 * Set the minimum item width
1690 *
1691 * @param width
1692 * The min width
1693 */
1694 public void setMinimumItemWidth(int width) {
f1fae91f
PT
1695 if (fTimeGraphCtrl != null) {
1696 fTimeGraphCtrl.setMinimumItemWidth(width);
837a2f8c
PT
1697 }
1698 }
1699
1700 /**
1701 * Set the width for the name column
1702 *
79ec0b89
PT
1703 * @param width
1704 * The width
837a2f8c
PT
1705 */
1706 public void setNameWidthPref(int width) {
f1fae91f 1707 fNameWidthPref = width;
837a2f8c 1708 if (width == 0) {
f1fae91f
PT
1709 fMinNameWidth = 0;
1710 fNameWidth = 0;
837a2f8c
PT
1711 }
1712 }
1713
1714 /**
1715 * Retrieve the configure width for the name column
1716 *
1717 * @param width
1718 * Unused?
1719 * @return The width
1720 */
1721 public int getNameWidthPref(int width) {
f1fae91f 1722 return fNameWidthPref;
837a2f8c
PT
1723 }
1724
1725 /**
1726 * Returns the primary control associated with this viewer.
1727 *
1728 * @return the SWT control which displays this viewer's content
1729 */
2802c35e 1730 @Override
837a2f8c 1731 public Control getControl() {
f1fae91f 1732 return fDataViewer;
837a2f8c
PT
1733 }
1734
1735 /**
1736 * Returns the time graph control associated with this viewer.
1737 *
1738 * @return the time graph control
1739 */
3e9a3685 1740 public TimeGraphControl getTimeGraphControl() {
f1fae91f 1741 return fTimeGraphCtrl;
837a2f8c
PT
1742 }
1743
1744 /**
1745 * Returns the time graph scale associated with this viewer.
1746 *
1747 * @return the time graph scale
1748 */
3e9a3685 1749 public TimeGraphScale getTimeGraphScale() {
f1fae91f 1750 return fTimeScaleCtrl;
837a2f8c
PT
1751 }
1752
d2e4afa7
MAL
1753 /**
1754 * Returns the composite containing all the controls that are time aligned,
1755 * i.e. TimeGraphScale, TimeGraphControl.
1756 *
1757 * @return the time based composite
1758 * @since 1.0
1759 */
1760 public Composite getTimeAlignedComposite() {
1761 return fTimeAlignedComposite;
1762 }
1763
713a70ae
PT
1764 /**
1765 * Return the x coordinate corresponding to a time
1766 *
79ec0b89
PT
1767 * @param time
1768 * the time
713a70ae 1769 * @return the x coordinate corresponding to the time
713a70ae
PT
1770 */
1771 public int getXForTime(long time) {
f1fae91f 1772 return fTimeGraphCtrl.getXForTime(time);
713a70ae
PT
1773 }
1774
1775 /**
1776 * Return the time corresponding to an x coordinate
1777 *
79ec0b89
PT
1778 * @param x
1779 * the x coordinate
713a70ae 1780 * @return the time corresponding to the x coordinate
713a70ae
PT
1781 */
1782 public long getTimeAtX(int x) {
f1fae91f 1783 return fTimeGraphCtrl.getTimeAtX(x);
713a70ae
PT
1784 }
1785
837a2f8c
PT
1786 /**
1787 * Get the selection provider
1788 *
1789 * @return the selection provider
1790 */
1791 public ISelectionProvider getSelectionProvider() {
f1fae91f 1792 return fTimeGraphCtrl;
837a2f8c
PT
1793 }
1794
1795 /**
1796 * Wait for the cursor
1797 *
1798 * @param waitInd
1799 * Wait indefinitely?
1800 */
1801 public void waitCursor(boolean waitInd) {
f1fae91f 1802 fTimeGraphCtrl.waitCursor(waitInd);
837a2f8c
PT
1803 }
1804
1805 /**
1806 * Get the horizontal scroll bar object
1807 *
1808 * @return The scroll bar
1809 */
b698ec63
PT
1810 public Slider getHorizontalBar() {
1811 return fHorizontalScrollBar;
837a2f8c
PT
1812 }
1813
1814 /**
1815 * Get the vertical scroll bar object
1816 *
1817 * @return The scroll bar
1818 */
1819 public Slider getVerticalBar() {
f1fae91f 1820 return fVerticalScrollBar;
837a2f8c
PT
1821 }
1822
1823 /**
1824 * Set the given index as the top one
1825 *
1826 * @param index
1827 * The index that will go to the top
1828 */
1829 public void setTopIndex(int index) {
f1fae91f 1830 fTimeGraphCtrl.setTopIndex(index);
837a2f8c
PT
1831 adjustVerticalScrollBar();
1832 }
1833
1834 /**
1835 * Retrieve the current top index
1836 *
1837 * @return The top index
1838 */
1839 public int getTopIndex() {
f1fae91f 1840 return fTimeGraphCtrl.getTopIndex();
837a2f8c
PT
1841 }
1842
f4617471 1843 /**
df0e3d5f
PT
1844 * Sets the auto-expand level to be used for new entries discovered when
1845 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1846 * means that there is no auto-expand; 1 means that top-level entries are
1847 * expanded, but not their children; 2 means that top-level entries are
1848 * expanded, and their children, but not grand-children; and so on.
f4617471
PT
1849 * <p>
1850 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1851 * </p>
df0e3d5f 1852 *
f4617471
PT
1853 * @param level
1854 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1855 * levels of the tree
f4617471
PT
1856 */
1857 public void setAutoExpandLevel(int level) {
1858 fTimeGraphCtrl.setAutoExpandLevel(level);
1859 }
1860
1861 /**
1862 * Returns the auto-expand level.
1863 *
1864 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1865 * the tree are expanded automatically
1866 * @see #setAutoExpandLevel
f4617471
PT
1867 */
1868 public int getAutoExpandLevel() {
1869 return fTimeGraphCtrl.getAutoExpandLevel();
1870 }
1871
df0e3d5f
PT
1872 /**
1873 * Get the expanded state of an entry.
1874 *
1875 * @param entry
1876 * The entry
1877 * @return true if the entry is expanded, false if collapsed
0336f981 1878 * @since 1.1
df0e3d5f
PT
1879 */
1880 public boolean getExpandedState(ITimeGraphEntry entry) {
1881 return fTimeGraphCtrl.getExpandedState(entry);
1882 }
1883
837a2f8c
PT
1884 /**
1885 * Set the expanded state of an entry
1886 *
1887 * @param entry
1888 * The entry to expand/collapse
1889 * @param expanded
1890 * True for expanded, false for collapsed
1891 */
1892 public void setExpandedState(ITimeGraphEntry entry, boolean expanded) {
f1fae91f 1893 fTimeGraphCtrl.setExpandedState(entry, expanded);
837a2f8c
PT
1894 adjustVerticalScrollBar();
1895 }
1896
1897 /**
1898 * Collapses all nodes of the viewer's tree, starting with the root.
837a2f8c
PT
1899 */
1900 public void collapseAll() {
f1fae91f 1901 fTimeGraphCtrl.collapseAll();
837a2f8c
PT
1902 adjustVerticalScrollBar();
1903 }
1904
1905 /**
df0e3d5f 1906 * Expands all entries of the viewer's tree, starting with the root.
837a2f8c
PT
1907 */
1908 public void expandAll() {
f1fae91f 1909 fTimeGraphCtrl.expandAll();
837a2f8c
PT
1910 adjustVerticalScrollBar();
1911 }
1912
36299425
JCK
1913 /**
1914 * Select an entry and reveal it
1915 *
1916 * @param entry
1917 * The entry to select
1918 * @since 2.0
1919 */
1920 public void selectAndReveal(@NonNull ITimeGraphEntry entry) {
1921 final ITimeGraphEntry parent = entry.getParent();
1922 if (parent != null) {
1923 fTimeGraphCtrl.setExpandedState(parent, true);
1924 }
1e691cca
JCK
1925 fSelectedEntry = entry;
1926 fTimeGraphCtrl.selectItem(entry, false);
36299425
JCK
1927 adjustVerticalScrollBar();
1928 }
1929
837a2f8c 1930 /**
df0e3d5f
PT
1931 * Get the number of expanded (visible) time graph entries. This includes
1932 * leafs and does not include filtered-out entries.
837a2f8c 1933 *
df0e3d5f 1934 * @return The number of expanded (visible) time graph entries
837a2f8c
PT
1935 */
1936 public int getExpandedElementCount() {
f1fae91f 1937 return fTimeGraphCtrl.getExpandedElementCount();
837a2f8c
PT
1938 }
1939
1940 /**
df0e3d5f
PT
1941 * Get the expanded (visible) time graph entries. This includes leafs and
1942 * does not include filtered-out entries.
837a2f8c 1943 *
df0e3d5f 1944 * @return The array of expanded (visible) time graph entries
837a2f8c
PT
1945 */
1946 public ITimeGraphEntry[] getExpandedElements() {
f1fae91f 1947 return fTimeGraphCtrl.getExpandedElements();
837a2f8c
PT
1948 }
1949
1950 /**
1951 * Add a tree listener
1952 *
1953 * @param listener
1954 * The listener to add
1955 */
1956 public void addTreeListener(ITimeGraphTreeListener listener) {
f1fae91f 1957 fTimeGraphCtrl.addTreeListener(listener);
837a2f8c
PT
1958 }
1959
1960 /**
1961 * Remove a tree listener
1962 *
1963 * @param listener
1964 * The listener to remove
1965 */
1966 public void removeTreeListener(ITimeGraphTreeListener listener) {
f1fae91f 1967 fTimeGraphCtrl.removeTreeListener(listener);
837a2f8c
PT
1968 }
1969
1970 /**
1971 * Get the reset scale action.
1972 *
1973 * @return The Action object
1974 */
1975 public Action getResetScaleAction() {
f1fae91f 1976 if (fResetScaleAction == null) {
837a2f8c 1977 // resetScale
f1fae91f 1978 fResetScaleAction = new Action() {
837a2f8c
PT
1979 @Override
1980 public void run() {
1981 resetStartFinishTime();
1982 }
1983 };
f1fae91f
PT
1984 fResetScaleAction.setText(Messages.TmfTimeGraphViewer_ResetScaleActionNameText);
1985 fResetScaleAction.setToolTipText(Messages.TmfTimeGraphViewer_ResetScaleActionToolTipText);
1986 fResetScaleAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU));
837a2f8c 1987 }
f1fae91f 1988 return fResetScaleAction;
837a2f8c
PT
1989 }
1990
1991 /**
1992 * Get the show legend action.
1993 *
1994 * @return The Action object
1995 */
1996 public Action getShowLegendAction() {
f1fae91f 1997 if (fShowLegendAction == null) {
837a2f8c 1998 // showLegend
f1fae91f 1999 fShowLegendAction = new Action() {
837a2f8c
PT
2000 @Override
2001 public void run() {
2002 showLegend();
2003 }
2004 };
f1fae91f
PT
2005 fShowLegendAction.setText(Messages.TmfTimeGraphViewer_LegendActionNameText);
2006 fShowLegendAction.setToolTipText(Messages.TmfTimeGraphViewer_LegendActionToolTipText);
2007 fShowLegendAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LEGEND));
837a2f8c
PT
2008 }
2009
f1fae91f 2010 return fShowLegendAction;
837a2f8c
PT
2011 }
2012
2013 /**
2014 * Get the the next event action.
2015 *
2016 * @return The action object
2017 */
2018 public Action getNextEventAction() {
f1fae91f
PT
2019 if (fNextEventAction == null) {
2020 fNextEventAction = new Action() {
837a2f8c 2021 @Override
33fa1fc7
PT
2022 public void runWithEvent(Event event) {
2023 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
2024 selectNextEvent(extend);
837a2f8c
PT
2025 }
2026 };
2027
d33eb610
AM
2028 fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextStateChangeActionNameText);
2029 fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextStateChangeActionToolTipText);
2030 fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_STATE_CHANGE));
837a2f8c
PT
2031 }
2032
f1fae91f 2033 return fNextEventAction;
837a2f8c
PT
2034 }
2035
2036 /**
2037 * Get the previous event action.
2038 *
2039 * @return The Action object
2040 */
2041 public Action getPreviousEventAction() {
f1fae91f
PT
2042 if (fPrevEventAction == null) {
2043 fPrevEventAction = new Action() {
837a2f8c 2044 @Override
33fa1fc7
PT
2045 public void runWithEvent(Event event) {
2046 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
2047 selectPrevEvent(extend);
837a2f8c
PT
2048 }
2049 };
2050
d33eb610
AM
2051 fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousStateChangeActionNameText);
2052 fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousStateChangeActionToolTipText);
2053 fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_STATE_CHANGE));
837a2f8c
PT
2054 }
2055
f1fae91f 2056 return fPrevEventAction;
837a2f8c
PT
2057 }
2058
2059 /**
2060 * Get the next item action.
2061 *
2062 * @return The Action object
2063 */
2064 public Action getNextItemAction() {
f1fae91f 2065 if (fNextItemAction == null) {
837a2f8c 2066
f1fae91f 2067 fNextItemAction = new Action() {
837a2f8c
PT
2068 @Override
2069 public void run() {
2070 selectNextItem();
2071 }
2072 };
f1fae91f
PT
2073 fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText);
2074 fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText);
2075 fNextItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_ITEM));
837a2f8c 2076 }
f1fae91f 2077 return fNextItemAction;
837a2f8c
PT
2078 }
2079
2080 /**
2081 * Get the previous item action.
2082 *
2083 * @return The Action object
2084 */
2085 public Action getPreviousItemAction() {
f1fae91f 2086 if (fPreviousItemAction == null) {
837a2f8c 2087
f1fae91f 2088 fPreviousItemAction = new Action() {
837a2f8c
PT
2089 @Override
2090 public void run() {
2091 selectPrevItem();
2092 }
2093 };
f1fae91f
PT
2094 fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText);
2095 fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText);
2096 fPreviousItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_ITEM));
837a2f8c 2097 }
f1fae91f 2098 return fPreviousItemAction;
837a2f8c
PT
2099 }
2100
2101 /**
2102 * Get the zoom in action
2103 *
2104 * @return The Action object
2105 */
2106 public Action getZoomInAction() {
f1fae91f
PT
2107 if (fZoomInAction == null) {
2108 fZoomInAction = new Action() {
837a2f8c
PT
2109 @Override
2110 public void run() {
2111 zoomIn();
2112 }
2113 };
f1fae91f
PT
2114 fZoomInAction.setText(Messages.TmfTimeGraphViewer_ZoomInActionNameText);
2115 fZoomInAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomInActionToolTipText);
2116 fZoomInAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU));
837a2f8c 2117 }
f1fae91f 2118 return fZoomInAction;
837a2f8c
PT
2119 }
2120
2121 /**
2122 * Get the zoom out action
2123 *
2124 * @return The Action object
2125 */
2126 public Action getZoomOutAction() {
f1fae91f
PT
2127 if (fZoomOutAction == null) {
2128 fZoomOutAction = new Action() {
837a2f8c
PT
2129 @Override
2130 public void run() {
2131 zoomOut();
2132 }
2133 };
f1fae91f
PT
2134 fZoomOutAction.setText(Messages.TmfTimeGraphViewer_ZoomOutActionNameText);
2135 fZoomOutAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomOutActionToolTipText);
2136 fZoomOutAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU));
837a2f8c 2137 }
f1fae91f 2138 return fZoomOutAction;
837a2f8c
PT
2139 }
2140
79ec0b89
PT
2141 /**
2142 * Get the hide arrows action
2143 *
2144 * @param dialogSettings
2145 * The dialog settings section where the state should be stored,
2146 * or null
2147 *
2148 * @return The Action object
79ec0b89
PT
2149 */
2150 public Action getHideArrowsAction(final IDialogSettings dialogSettings) {
2151 if (fHideArrowsAction == null) {
2152 fHideArrowsAction = new Action(Messages.TmfTimeGraphViewer_HideArrowsActionNameText, IAction.AS_CHECK_BOX) {
2153 @Override
2154 public void run() {
2155 boolean hideArrows = fHideArrowsAction.isChecked();
2156 fTimeGraphCtrl.hideArrows(hideArrows);
2157 refresh();
2158 if (dialogSettings != null) {
2159 dialogSettings.put(HIDE_ARROWS_KEY, hideArrows);
2160 }
086f21ae
PT
2161 if (fFollowArrowFwdAction != null) {
2162 fFollowArrowFwdAction.setEnabled(!hideArrows);
2163 }
2164 if (fFollowArrowBwdAction != null) {
2165 fFollowArrowBwdAction.setEnabled(!hideArrows);
2166 }
79ec0b89
PT
2167 }
2168 };
2169 fHideArrowsAction.setToolTipText(Messages.TmfTimeGraphViewer_HideArrowsActionToolTipText);
2170 fHideArrowsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HIDE_ARROWS));
2171 if (dialogSettings != null) {
2172 boolean hideArrows = dialogSettings.getBoolean(HIDE_ARROWS_KEY);
2173 fTimeGraphCtrl.hideArrows(hideArrows);
2174 fHideArrowsAction.setChecked(hideArrows);
086f21ae
PT
2175 if (fFollowArrowFwdAction != null) {
2176 fFollowArrowFwdAction.setEnabled(!hideArrows);
2177 }
2178 if (fFollowArrowBwdAction != null) {
2179 fFollowArrowBwdAction.setEnabled(!hideArrows);
2180 }
79ec0b89
PT
2181 }
2182 }
2183 return fHideArrowsAction;
2184 }
837a2f8c 2185
086f21ae
PT
2186 /**
2187 * Get the follow arrow forward action.
2188 *
2189 * @return The Action object
086f21ae
PT
2190 */
2191 public Action getFollowArrowFwdAction() {
2192 if (fFollowArrowFwdAction == null) {
2193 fFollowArrowFwdAction = new Action() {
2194 @Override
33fa1fc7
PT
2195 public void runWithEvent(Event event) {
2196 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
2197 fTimeGraphCtrl.followArrowFwd(extend);
086f21ae
PT
2198 adjustVerticalScrollBar();
2199 }
2200 };
2201 fFollowArrowFwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionNameText);
2202 fFollowArrowFwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText);
2203 fFollowArrowFwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_FORWARD));
2204 if (fHideArrowsAction != null) {
2205 fFollowArrowFwdAction.setEnabled(!fHideArrowsAction.isChecked());
2206 }
2207 }
2208 return fFollowArrowFwdAction;
2209 }
2210
2211 /**
2212 * Get the follow arrow backward action.
2213 *
2214 * @return The Action object
086f21ae
PT
2215 */
2216 public Action getFollowArrowBwdAction() {
2217 if (fFollowArrowBwdAction == null) {
2218 fFollowArrowBwdAction = new Action() {
2219 @Override
33fa1fc7
PT
2220 public void runWithEvent(Event event) {
2221 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
2222 fTimeGraphCtrl.followArrowBwd(extend);
086f21ae
PT
2223 adjustVerticalScrollBar();
2224 }
2225 };
2226 fFollowArrowBwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionNameText);
2227 fFollowArrowBwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText);
2228 fFollowArrowBwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_BACKWARD));
2229 if (fHideArrowsAction != null) {
2230 fFollowArrowBwdAction.setEnabled(!fHideArrowsAction.isChecked());
2231 }
2232 }
2233 return fFollowArrowBwdAction;
2234 }
2235
cfcfd964
PT
2236 /**
2237 * Get the show filter dialog action.
2238 *
2239 * @return The Action object
066b02aa 2240 * @since 1.2
cfcfd964
PT
2241 */
2242 public ShowFilterDialogAction getShowFilterDialogAction() {
2243 if (fShowFilterDialogAction == null) {
2244 fShowFilterDialogAction = new ShowFilterDialogAction(this);
2245 }
2246 return fShowFilterDialogAction;
2247 }
2248
1d012443
PT
2249 /**
2250 * Get the toggle bookmark action.
2251 *
2252 * @return The Action object
2253 * @since 2.0
2254 */
2255 public Action getToggleBookmarkAction() {
2256 if (fToggleBookmarkAction == null) {
2257 fToggleBookmarkAction = new Action() {
2258 @Override
2259 public void runWithEvent(Event event) {
2260 IMarkerEvent selectedBookmark = getBookmarkAtSelection();
2261 if (selectedBookmark == null) {
2262 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2263 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
7697e148 2264 final AddBookmarkDialog dialog = new AddBookmarkDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), null);
1d012443
PT
2265 if (dialog.open() == Window.OK) {
2266 final String label = dialog.getValue();
2267 final RGBA rgba = dialog.getColorValue();
8910dea2 2268 IMarkerEvent bookmark = new MarkerEvent(null, time, duration, IMarkerEvent.BOOKMARKS, rgba, label, true);
1d012443 2269 fBookmarks.add(bookmark);
f72cd563 2270 updateMarkerList();
91512088 2271 updateMarkerActions();
1d012443
PT
2272 getControl().redraw();
2273 fireBookmarkAdded(bookmark);
2274 }
2275 } else {
1d012443 2276 fBookmarks.remove(selectedBookmark);
f72cd563 2277 updateMarkerList();
91512088 2278 updateMarkerActions();
1d012443
PT
2279 getControl().redraw();
2280 fireBookmarkRemoved(selectedBookmark);
2281 }
1d012443
PT
2282 }
2283 };
2284 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2285 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2286 fToggleBookmarkAction.setImageDescriptor(ADD_BOOKMARK);
2287 }
2288 return fToggleBookmarkAction;
2289 }
2290
2291 /**
f72cd563 2292 * Get the next marker action.
1d012443
PT
2293 *
2294 * @return The Action object
2295 * @since 2.0
2296 */
f72cd563
PT
2297 public Action getNextMarkerAction() {
2298 if (fNextMarkerAction == null) {
6d5b0ba1 2299 fNextMarkerAction = new Action(Messages.TmfTimeGraphViewer_NextMarkerActionText, IAction.AS_DROP_DOWN_MENU) {
1d012443
PT
2300 @Override
2301 public void runWithEvent(Event event) {
4aa2593c
PT
2302 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
2303 if (extend) {
2304 extendToNextMarker();
2305 } else {
2306 selectNextMarker();
1d012443
PT
2307 }
2308 }
2309 };
f72cd563
PT
2310 fNextMarkerAction.setToolTipText(Messages.TmfTimeGraphViewer_NextMarkerActionText);
2311 fNextMarkerAction.setImageDescriptor(NEXT_BOOKMARK);
6d5b0ba1
PT
2312 fNextMarkerAction.setMenuCreator(new IMenuCreator () {
2313 Menu menu = null;
2314 @Override
2315 public void dispose() {
2316 if (menu != null) {
2317 menu.dispose();
2318 menu = null;
2319 }
2320 }
2321
2322 @Override
2323 public Menu getMenu(Control parent) {
2324 if (menu != null) {
2325 menu.dispose();
2326 }
2327 menu = new Menu(parent);
2328 for (String category : fMarkerCategories) {
2329 final Action action = new Action(category, IAction.AS_CHECK_BOX) {
2330 @Override
2331 public void runWithEvent(Event event) {
2332 if (isChecked()) {
2333 fSkippedMarkerCategories.remove(getText());
2334 } else {
2335 fSkippedMarkerCategories.add(getText());
2336 }
2337 updateMarkerActions();
2338 }
2339 };
2340 action.setEnabled(!fHiddenMarkerCategories.contains(category));
2341 action.setChecked(action.isEnabled() && !fSkippedMarkerCategories.contains(category));
2342 new ActionContributionItem(action).fill(menu, -1);
2343 }
2344 return menu;
2345 }
2346
2347 @Override
2348 public Menu getMenu(Menu parent) {
2349 return null;
2350 }
2351 });
1d012443 2352 }
f72cd563 2353 return fNextMarkerAction;
1d012443
PT
2354 }
2355
2356 /**
f72cd563 2357 * Get the previous marker action.
1d012443
PT
2358 *
2359 * @return The Action object
2360 * @since 2.0
2361 */
f72cd563
PT
2362 public Action getPreviousMarkerAction() {
2363 if (fPreviousMarkerAction == null) {
2364 fPreviousMarkerAction = new Action() {
1d012443
PT
2365 @Override
2366 public void runWithEvent(Event event) {
4aa2593c
PT
2367 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
2368 if (extend) {
2369 extendToPrevMarker();
2370 } else {
2371 selectPrevMarker();
1d012443
PT
2372 }
2373 }
2374 };
f72cd563
PT
2375 fPreviousMarkerAction.setText(Messages.TmfTimeGraphViewer_PreviousMarkerActionText);
2376 fPreviousMarkerAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousMarkerActionText);
2377 fPreviousMarkerAction.setImageDescriptor(PREVIOUS_BOOKMARK);
1d012443 2378 }
f72cd563 2379 return fPreviousMarkerAction;
1d012443
PT
2380 }
2381
91512088
PT
2382 /**
2383 * Get the show markers menu.
2384 *
2385 * @return The menu manager object
2386 * @since 2.0
2387 */
2388 public MenuManager getMarkersMenu() {
2389 if (fMarkersMenu == null) {
2390 fMarkersMenu = new MenuManager(Messages.TmfTimeGraphViewer_ShowMarkersMenuText);
2391 fMarkersMenu.setRemoveAllWhenShown(true);
2392 fMarkersMenu.addMenuListener(new IMenuListener() {
2393 @Override
2394 public void menuAboutToShow(IMenuManager manager) {
2395 for (String category : fMarkerCategories) {
2396 final Action action = new Action(category, IAction.AS_CHECK_BOX) {
2397 @Override
2398 public void runWithEvent(Event event) {
f0a9cee1 2399 setMarkerCategoryVisible(getText(), isChecked());
91512088
PT
2400 }
2401 };
2402 action.setChecked(!fHiddenMarkerCategories.contains(category));
2403 manager.add(action);
2404 }
2405 }
2406 });
2407 }
2408 return fMarkersMenu;
2409 }
2410
4aa2593c
PT
2411 /**
2412 * Select the next marker that begins at or after the current selection
2413 * begin time. Markers that begin at the same time are ordered by end time.
2414 */
2415 private void selectNextMarker() {
2416 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2417 if (markers == null) {
2418 return;
2419 }
2420 for (IMarkerEvent marker : markers) {
2421 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2422 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2423 if ((marker.getTime() > time ||
2424 (marker.getTime() == time && marker.getDuration() > duration))
2425 && !fSkippedMarkerCategories.contains(marker.getCategory())) {
d5997aaf
PT
2426 setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration(), false);
2427 ensureVisible(marker.getTime());
2428 notifyRangeListeners();
4aa2593c
PT
2429 fTimeGraphCtrl.updateStatusLine();
2430 return;
2431 }
2432 }
2433 }
2434
2435 /**
2436 * Select the previous marker that begins at or before the current selection
2437 * begin time. Markers that begin at the same time are ordered by end time.
2438 */
2439 private void selectPrevMarker() {
2440 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2441 if (markers == null) {
2442 return;
2443 }
2444 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2445 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2446 for (int i = markers.size() - 1; i >= 0; i--) {
2447 IMarkerEvent marker = markers.get(i);
2448 if ((marker.getTime() < time ||
2449 (marker.getTime() == time && marker.getDuration() < duration))
2450 && !fSkippedMarkerCategories.contains(marker.getCategory())) {
d5997aaf
PT
2451 setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration(), false);
2452 ensureVisible(marker.getTime());
2453 notifyRangeListeners();
4aa2593c
PT
2454 fTimeGraphCtrl.updateStatusLine();
2455 return;
2456 }
2457 }
2458 }
2459
2460 /**
2461 * Extend the selection to the closest next marker end time.
2462 */
2463 private void extendToNextMarker() {
2464 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2465 if (markers == null) {
2466 return;
2467 }
2468 IMarkerEvent nextMarker = null;
2469 for (IMarkerEvent marker : markers) {
2470 if (marker.getTime() + marker.getDuration() > fSelectionEnd
2471 && !fSkippedMarkerCategories.contains(marker.getCategory())
2472 && (nextMarker == null || marker.getTime() + marker.getDuration() < nextMarker.getTime() + nextMarker.getDuration())) {
2473 nextMarker = marker;
2474 }
2475 }
2476 if (nextMarker != null) {
84c8aef7 2477 setSelectionRangeNotify(fSelectionBegin, nextMarker.getTime() + nextMarker.getDuration(), true);
4aa2593c
PT
2478 fTimeGraphCtrl.updateStatusLine();
2479 }
2480 }
2481
2482 /**
2483 * Extend the selection to the closest previous marker start time.
2484 */
2485 private void extendToPrevMarker() {
2486 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2487 if (markers == null) {
2488 return;
2489 }
2490 for (int i = markers.size() - 1; i >= 0; i--) {
2491 IMarkerEvent marker = markers.get(i);
2492 if (marker.getTime() < fSelectionEnd
2493 && !fSkippedMarkerCategories.contains(marker.getCategory())) {
84c8aef7 2494 setSelectionRangeNotify(fSelectionBegin, marker.getTime(), true);
4aa2593c
PT
2495 fTimeGraphCtrl.updateStatusLine();
2496 return;
2497 }
2498 }
2499 }
2500
1d012443
PT
2501 private IMarkerEvent getBookmarkAtSelection() {
2502 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2503 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2504 for (IMarkerEvent bookmark : fBookmarks) {
2505 if (bookmark.getTime() == time && bookmark.getDuration() == duration) {
2506 return bookmark;
2507 }
2508 }
2509 return null;
2510 }
2511
f72cd563 2512 private void updateMarkerActions() {
6d5b0ba1 2513 boolean enabled = fTime0Bound != SWT.DEFAULT || fTime1Bound != SWT.DEFAULT;
1d012443
PT
2514 if (fToggleBookmarkAction != null) {
2515 if (getBookmarkAtSelection() != null) {
2516 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionRemoveText);
2517 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionRemoveText);
2518 fToggleBookmarkAction.setImageDescriptor(REMOVE_BOOKMARK);
2519 } else {
2520 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2521 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2522 fToggleBookmarkAction.setImageDescriptor(ADD_BOOKMARK);
2523 }
6d5b0ba1 2524 fToggleBookmarkAction.setEnabled(enabled);
1d012443 2525 }
f72cd563
PT
2526 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2527 if (markers == null) {
2528 markers = Collections.emptyList();
2529 }
2530 if (fPreviousMarkerAction != null) {
6d5b0ba1 2531 fPreviousMarkerAction.setEnabled(enabled && !markers.isEmpty());
1d012443 2532 }
f72cd563 2533 if (fNextMarkerAction != null) {
6d5b0ba1 2534 fNextMarkerAction.setEnabled(enabled && !markers.isEmpty());
1d012443
PT
2535 }
2536 }
2537
f72cd563 2538 private void updateMarkerList() {
91512088
PT
2539 List<IMarkerEvent> markers = new ArrayList<>();
2540 for (IMarkerEvent marker : fMarkers) {
2541 if (!fHiddenMarkerCategories.contains(marker.getCategory())) {
2542 markers.add(marker);
2543 }
2544 }
2545 if (!fHiddenMarkerCategories.contains(IMarkerEvent.BOOKMARKS)) {
2546 markers.addAll(fBookmarks);
2547 }
f72cd563 2548 Collections.sort(markers, new MarkerComparator());
dc4fa715
PT
2549 fTimeGraphCtrl.setMarkers(markers);
2550 fMarkerAxisCtrl.setMarkers(markers);
f72cd563
PT
2551 }
2552
b698ec63
PT
2553 private void adjustHorizontalScrollBar() {
2554 long time0 = getTime0();
2555 long time1 = getTime1();
2556 long timeMin = getMinTime();
2557 long timeMax = getMaxTime();
2558 long delta = timeMax - timeMin;
2559 int timePos = 0;
2560 int thumb = H_SCROLLBAR_MAX;
2561 if (delta != 0) {
2562 // Thumb size (page size)
2563 thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta)));
2564 // At the beginning of visible window
2565 timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta));
2566 }
2567 fHorizontalScrollBar.setValues(timePos, 0, H_SCROLLBAR_MAX, thumb, Math.max(1, thumb / 2), Math.max(2, thumb));
2568 }
2569
837a2f8c 2570 private void adjustVerticalScrollBar() {
f1fae91f
PT
2571 int topIndex = fTimeGraphCtrl.getTopIndex();
2572 int countPerPage = fTimeGraphCtrl.countPerPage();
2573 int expandedElementCount = fTimeGraphCtrl.getExpandedElementCount();
837a2f8c 2574 if (topIndex + countPerPage > expandedElementCount) {
f1fae91f 2575 fTimeGraphCtrl.setTopIndex(Math.max(0, expandedElementCount - countPerPage));
837a2f8c
PT
2576 }
2577
f1fae91f 2578 int selection = fTimeGraphCtrl.getTopIndex();
837a2f8c
PT
2579 int min = 0;
2580 int max = Math.max(1, expandedElementCount - 1);
2581 int thumb = Math.min(max, Math.max(1, countPerPage - 1));
2582 int increment = 1;
2583 int pageIncrement = Math.max(1, countPerPage);
f1fae91f 2584 fVerticalScrollBar.setValues(selection, min, max, thumb, increment, pageIncrement);
837a2f8c
PT
2585 }
2586
27df1564 2587 /**
79ec0b89
PT
2588 * @param listener
2589 * a {@link MenuDetectListener}
2bdf0193 2590 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
2591 */
2592 public void addTimeGraphEntryMenuListener(MenuDetectListener listener) {
f1fae91f 2593 fTimeGraphCtrl.addTimeGraphEntryMenuListener(listener);
27df1564
XR
2594 }
2595
2596 /**
79ec0b89
PT
2597 * @param listener
2598 * a {@link MenuDetectListener}
2bdf0193 2599 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
2600 */
2601 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) {
f1fae91f 2602 fTimeGraphCtrl.removeTimeGraphEntryMenuListener(listener);
27df1564
XR
2603 }
2604
2605 /**
79ec0b89
PT
2606 * @param listener
2607 * a {@link MenuDetectListener}
2bdf0193 2608 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
2609 */
2610 public void addTimeEventMenuListener(MenuDetectListener listener) {
f1fae91f 2611 fTimeGraphCtrl.addTimeEventMenuListener(listener);
27df1564
XR
2612 }
2613
2614 /**
79ec0b89
PT
2615 * @param listener
2616 * a {@link MenuDetectListener}
2bdf0193 2617 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
2618 */
2619 public void removeTimeEventMenuListener(MenuDetectListener listener) {
f1fae91f 2620 fTimeGraphCtrl.removeTimeEventMenuListener(listener);
27df1564
XR
2621 }
2622
6ac5a950 2623 /**
79ec0b89
PT
2624 * @param filter
2625 * The filter object to be attached to the view
6ac5a950 2626 */
367e2932 2627 public void addFilter(@NonNull ViewerFilter filter) {
f1fae91f 2628 fTimeGraphCtrl.addFilter(filter);
6ac5a950
AM
2629 refresh();
2630 }
837a2f8c 2631
6ac5a950 2632 /**
79ec0b89
PT
2633 * @param filter
2634 * The filter object to be attached to the view
6ac5a950 2635 */
367e2932 2636 public void removeFilter(@NonNull ViewerFilter filter) {
f1fae91f 2637 fTimeGraphCtrl.removeFilter(filter);
6ac5a950
AM
2638 refresh();
2639 }
837a2f8c 2640
4923d7b9
PT
2641 /**
2642 * Returns this viewer's filters.
2643 *
2644 * @return an array of viewer filters
066b02aa 2645 * @since 1.2
4923d7b9 2646 */
367e2932 2647 public @NonNull ViewerFilter[] getFilters() {
4923d7b9
PT
2648 return fTimeGraphCtrl.getFilters();
2649 }
2650
2651 /**
2652 * Sets the filters, replacing any previous filters, and triggers
2653 * refiltering of the elements.
2654 *
2655 * @param filters
2656 * an array of viewer filters, or null
066b02aa 2657 * @since 1.2
4923d7b9 2658 */
367e2932 2659 public void setFilters(@NonNull ViewerFilter[] filters) {
4923d7b9
PT
2660 fTimeGraphCtrl.setFilters(filters);
2661 refresh();
2662 }
2663
d2e4afa7
MAL
2664 /**
2665 * Return the time alignment information
2666 *
2667 * @return the time alignment information
2668 *
2669 * @see ITmfTimeAligned
2670 *
2671 * @since 1.0
2672 */
2673 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
2674 return fTimeGraphCtrl.getTimeViewAlignmentInfo();
2675 }
2676
2677 /**
2678 * Return the available width for the time-axis.
2679 *
2680 * @see ITmfTimeAligned
2681 *
2682 * @param requestedOffset
2683 * the requested offset
2684 * @return the available width for the time-axis
2685 *
2686 * @since 1.0
2687 */
2688 public int getAvailableWidth(int requestedOffset) {
921ae867
MAL
2689 int totalWidth = fTimeAlignedComposite.getSize().x;
2690 return Math.min(totalWidth, Math.max(0, totalWidth - requestedOffset));
d2e4afa7
MAL
2691 }
2692
2693 /**
2694 * Perform the alignment operation.
2695 *
2696 * @param offset
2697 * the alignment offset
2698 * @param width
2699 * the alignment width
2700 *
2701 * @see ITmfTimeAligned
2702 *
2703 * @since 1.0
2704 */
2705 public void performAlign(int offset, int width) {
2706 fTimeGraphCtrl.performAlign(offset);
2707 int alignmentWidth = width;
2708 int size = fTimeAlignedComposite.getSize().x;
2709 GridLayout layout = (GridLayout) fTimeAlignedComposite.getLayout();
2710 int marginSize = size - alignmentWidth - offset;
2711 layout.marginRight = Math.max(0, marginSize);
2712 fTimeAlignedComposite.layout();
2713 }
2714
837a2f8c 2715}
This page took 0.266205 seconds and 5 git commands to generate.