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