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