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