analysis: Fix missing setItemCount in AbstractSegmentStoreTableViewer
[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();
531 }
837a2f8c
PT
532 adjustVerticalScrollBar();
533 }
534 });
535
d2e4afa7
MAL
536 fVerticalScrollBar = new Slider(fDataViewer, SWT.VERTICAL | SWT.NO_FOCUS);
537 fVerticalScrollBar.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false, true, 1, 1));
538 fVerticalScrollBar.addSelectionListener(new SelectionAdapter() {
539 @Override
540 public void widgetSelected(SelectionEvent e) {
541 setTopIndex(fVerticalScrollBar.getSelection());
542 }
543 });
544
b698ec63
PT
545 fHorizontalScrollBar = new Slider(fDataViewer, SWT.HORIZONTAL | SWT.NO_FOCUS);
546 fHorizontalScrollBar.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
547 fHorizontalScrollBar.addListener(SWT.MouseWheel, new Listener() {
548 @Override
549 public void handleEvent(Event event) {
550 if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) {
551 getTimeGraphControl().zoom(event.count > 0);
552 } else {
553 getTimeGraphControl().horizontalScroll(event.count > 0);
554 }
555 // don't handle the immediately following SWT.Selection event
556 event.doit = false;
557 }
558 });
559 fHorizontalScrollBar.addListener(SWT.Selection, new Listener() {
560 @Override
561 public void handleEvent(Event event) {
562 int start = fHorizontalScrollBar.getSelection();
563 long time0 = getTime0();
564 long time1 = getTime1();
565 long timeMin = getMinTime();
566 long timeMax = getMaxTime();
567 long delta = timeMax - timeMin;
568
569 long range = time1 - time0;
570 time0 = timeMin + Math.round(delta * ((double) start / H_SCROLLBAR_MAX));
571 time1 = time0 + range;
572
10ad9fa6 573 setStartFinishTimeNotify(time0, time1);
b698ec63
PT
574 }
575 });
576
f1fae91f 577 Composite filler = new Composite(fDataViewer, SWT.NONE);
837a2f8c 578 GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
b698ec63 579 gd.heightHint = fHorizontalScrollBar.getSize().y;
837a2f8c
PT
580 filler.setLayoutData(gd);
581 filler.setLayout(new FillLayout());
582
f1fae91f 583 fTimeGraphCtrl.addControlListener(new ControlAdapter() {
837a2f8c
PT
584 @Override
585 public void controlResized(ControlEvent event) {
586 resizeControls();
587 }
588 });
589 resizeControls();
f1fae91f 590 fDataViewer.update();
b698ec63 591 adjustHorizontalScrollBar();
837a2f8c 592 adjustVerticalScrollBar();
f1fae91f 593 return fDataViewer;
837a2f8c
PT
594 }
595
596 /**
597 * Dispose the view.
598 */
599 public void dispose() {
600 saveOptions();
f1fae91f
PT
601 fTimeGraphCtrl.dispose();
602 fDataViewer.dispose();
603 fColorScheme.dispose();
837a2f8c
PT
604 }
605
96d00a83 606 /**
a0a88f65
AM
607 * Create a new time graph control.
608 *
609 * @param parent
610 * The parent composite
611 * @param colors
612 * The color scheme
613 * @return The new TimeGraphControl
96d00a83 614 */
a0a88f65
AM
615 protected TimeGraphControl createTimeGraphControl(Composite parent,
616 TimeGraphColorScheme colors) {
96d00a83 617 return new TimeGraphControl(parent, colors);
837a2f8c
PT
618 }
619
620 /**
621 * Resize the controls
622 */
623 public void resizeControls() {
f1fae91f 624 Rectangle r = fDataViewer.getClientArea();
837a2f8c
PT
625 if (r.isEmpty()) {
626 return;
627 }
628
629 int width = r.width;
f1fae91f
PT
630 if (fNameWidth > width - fMinNameWidth) {
631 fNameWidth = width - fMinNameWidth;
837a2f8c 632 }
f1fae91f
PT
633 if (fNameWidth < fMinNameWidth) {
634 fNameWidth = fMinNameWidth;
837a2f8c 635 }
b698ec63 636 adjustHorizontalScrollBar();
837a2f8c
PT
637 adjustVerticalScrollBar();
638 }
639
640 /**
50d36521
PT
641 * Recalculate the time bounds based on the time graph entries,
642 * if the user-specified bound is set to SWT.DEFAULT.
837a2f8c 643 *
50d36521
PT
644 * @param entries
645 * The root time graph entries in the model
837a2f8c 646 */
50d36521
PT
647 public void setTimeRange(ITimeGraphEntry entries[]) {
648 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
649 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
650 if (fBeginTime != SWT.DEFAULT && fEndTime != SWT.DEFAULT) {
651 return;
652 }
653 if (entries == null || entries.length == 0) {
654 return;
655 }
656 if (fTime0Bound == SWT.DEFAULT) {
657 fTime0Bound = Long.MAX_VALUE;
658 }
659 if (fTime1Bound == SWT.DEFAULT) {
660 fTime1Bound = Long.MIN_VALUE;
661 }
662 for (ITimeGraphEntry entry : entries) {
663 setTimeRange(entry);
664 }
665 }
666
667 private void setTimeRange(ITimeGraphEntry entry) {
668 if (fBeginTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getStartTime() != SWT.DEFAULT) {
669 fTime0Bound = Math.min(entry.getStartTime(), fTime0Bound);
670 }
671 if (fEndTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getEndTime() != SWT.DEFAULT) {
672 fTime1Bound = Math.max(entry.getEndTime(), fTime1Bound);
673 }
674 if (entry.hasChildren()) {
675 for (ITimeGraphEntry child : entry.getChildren()) {
676 setTimeRange(child);
837a2f8c
PT
677 }
678 }
50d36521 679 }
837a2f8c 680
50d36521
PT
681 /**
682 * Set the time bounds to the provided values.
683 *
684 * @param beginTime
685 * The bounds begin time, or SWT.DEFAULT to use the input bounds
686 * @param endTime
687 * The bounds end time, or SWT.DEFAULT to use the input bounds
688 */
689 public void setTimeBounds(long beginTime, long endTime) {
690 fBeginTime = beginTime;
691 fEndTime = endTime;
692 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
693 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
694 if (fTime0Bound > fTime1Bound) {
695 // only possible if both are not default
696 fBeginTime = endTime;
697 fEndTime = beginTime;
698 fTime0Bound = fBeginTime;
699 fTime1Bound = fEndTime;
837a2f8c 700 }
50d36521 701 adjustHorizontalScrollBar();
837a2f8c
PT
702 }
703
704 /**
50d36521 705 * Recalculate the current time window when bounds have changed.
837a2f8c
PT
706 */
707 public void setTimeBounds() {
f1fae91f
PT
708 if (!fTimeRangeFixed) {
709 fTime0 = fTime0Bound;
710 fTime1 = fTime1Bound;
837a2f8c 711 }
407bfdd5
PT
712 fTime0 = Math.max(fTime0Bound, Math.min(fTime0, fTime1Bound));
713 fTime1 = Math.max(fTime0Bound, Math.min(fTime1, fTime1Bound));
f1fae91f
PT
714 if (fTime1 - fTime0 < fMinTimeInterval) {
715 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
837a2f8c
PT
716 }
717 }
718
837a2f8c
PT
719 /**
720 * @param traces
721 */
722 private void refreshAllData(ITimeGraphEntry[] traces) {
723 setTimeBounds();
0fcf3b09
PT
724 if (fSelectionBegin < fBeginTime) {
725 fSelectionBegin = fBeginTime;
726 } else if (fSelectionBegin > fEndTime) {
727 fSelectionBegin = fEndTime;
728 }
729 if (fSelectionEnd < fBeginTime) {
730 fSelectionEnd = fBeginTime;
731 } else if (fSelectionEnd > fEndTime) {
732 fSelectionEnd = fEndTime;
837a2f8c 733 }
f1fae91f
PT
734 fTimeGraphCtrl.refreshData(traces);
735 fTimeScaleCtrl.redraw();
f72cd563 736 updateMarkerActions();
837a2f8c
PT
737 adjustVerticalScrollBar();
738 }
739
740 /**
741 * Callback for when this view is focused
742 */
743 public void setFocus() {
f1fae91f
PT
744 if (null != fTimeGraphCtrl) {
745 fTimeGraphCtrl.setFocus();
837a2f8c
PT
746 }
747 }
748
749 /**
750 * Get the current focus status of this view.
751 *
752 * @return If the view is currently focused, or not
753 */
754 public boolean isInFocus() {
f1fae91f 755 return fTimeGraphCtrl.isInFocus();
837a2f8c
PT
756 }
757
758 /**
759 * Get the view's current selection
760 *
761 * @return The entry that is selected
762 */
763 public ITimeGraphEntry getSelection() {
f1fae91f 764 return fTimeGraphCtrl.getSelectedTrace();
837a2f8c
PT
765 }
766
767 /**
768 * Get the index of the current selection
769 *
770 * @return The index
771 */
772 public int getSelectionIndex() {
f1fae91f 773 return fTimeGraphCtrl.getSelectedIndex();
837a2f8c
PT
774 }
775
776 @Override
777 public long getTime0() {
f1fae91f 778 return fTime0;
837a2f8c
PT
779 }
780
781 @Override
782 public long getTime1() {
f1fae91f 783 return fTime1;
837a2f8c
PT
784 }
785
786 @Override
787 public long getMinTimeInterval() {
f1fae91f 788 return fMinTimeInterval;
837a2f8c
PT
789 }
790
791 @Override
792 public int getNameSpace() {
f1fae91f 793 return fNameWidth;
837a2f8c
PT
794 }
795
796 @Override
797 public void setNameSpace(int width) {
f1fae91f
PT
798 fNameWidth = width;
799 int w = fTimeGraphCtrl.getClientArea().width;
800 if (fNameWidth > w - MIN_NAME_WIDTH) {
801 fNameWidth = w - MIN_NAME_WIDTH;
837a2f8c 802 }
f1fae91f
PT
803 if (fNameWidth < MIN_NAME_WIDTH) {
804 fNameWidth = MIN_NAME_WIDTH;
837a2f8c 805 }
f1fae91f
PT
806 fTimeGraphCtrl.redraw();
807 fTimeScaleCtrl.redraw();
837a2f8c
PT
808 }
809
810 @Override
811 public int getTimeSpace() {
f1fae91f
PT
812 int w = fTimeGraphCtrl.getClientArea().width;
813 return w - fNameWidth;
837a2f8c
PT
814 }
815
837a2f8c
PT
816 @Override
817 public long getBeginTime() {
f1fae91f 818 return fBeginTime;
837a2f8c
PT
819 }
820
821 @Override
822 public long getEndTime() {
f1fae91f 823 return fEndTime;
837a2f8c
PT
824 }
825
826 @Override
827 public long getMaxTime() {
f1fae91f 828 return fTime1Bound;
837a2f8c
PT
829 }
830
831 @Override
832 public long getMinTime() {
f1fae91f 833 return fTime0Bound;
837a2f8c
PT
834 }
835
0fcf3b09
PT
836 @Override
837 public long getSelectionBegin() {
838 return fSelectionBegin;
839 }
840
0fcf3b09
PT
841 @Override
842 public long getSelectionEnd() {
843 return fSelectionEnd;
844 }
845
837a2f8c
PT
846 @Override
847 public void setStartFinishTimeNotify(long time0, long time1) {
88de10c6 848 setStartFinishTimeInt(time0, time1);
10ad9fa6 849 notifyRangeListeners();
837a2f8c
PT
850 }
851
837a2f8c
PT
852 @Override
853 public void notifyStartFinishTime() {
10ad9fa6 854 notifyRangeListeners();
837a2f8c
PT
855 }
856
837a2f8c
PT
857 @Override
858 public void setStartFinishTime(long time0, long time1) {
88de10c6
PT
859 /* if there is a pending time range, ignore this one */
860 if (fListenerNotifier != null && fListenerNotifier.hasTimeRangeUpdated()) {
861 return;
862 }
863 setStartFinishTimeInt(time0, time1);
45f63682 864 updateExtSynchValues();
88de10c6
PT
865 }
866
867 private void setStartFinishTimeInt(long time0, long time1) {
f1fae91f
PT
868 fTime0 = time0;
869 if (fTime0 < fTime0Bound) {
870 fTime0 = fTime0Bound;
837a2f8c 871 }
f1fae91f
PT
872 if (fTime0 > fTime1Bound) {
873 fTime0 = fTime1Bound;
837a2f8c 874 }
f1fae91f
PT
875 fTime1 = time1;
876 if (fTime1 < fTime0Bound) {
877 fTime1 = fTime0Bound;
837a2f8c 878 }
f1fae91f
PT
879 if (fTime1 > fTime1Bound) {
880 fTime1 = fTime1Bound;
837a2f8c 881 }
f1fae91f
PT
882 if (fTime1 - fTime0 < fMinTimeInterval) {
883 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
837a2f8c 884 }
f1fae91f 885 fTimeRangeFixed = true;
b698ec63 886 adjustHorizontalScrollBar();
f1fae91f
PT
887 fTimeGraphCtrl.redraw();
888 fTimeScaleCtrl.redraw();
837a2f8c
PT
889 }
890
837a2f8c
PT
891 @Override
892 public void resetStartFinishTime() {
88de10c6 893 setStartFinishTimeNotify(fTime0Bound, fTime1Bound);
f1fae91f 894 fTimeRangeFixed = false;
837a2f8c
PT
895 }
896
897 @Override
898 public void setSelectedTimeNotify(long time, boolean ensureVisible) {
899 setSelectedTimeInt(time, ensureVisible, true);
900 }
901
902 @Override
903 public void setSelectedTime(long time, boolean ensureVisible) {
88de10c6
PT
904 /* if there is a pending time selection, ignore this one */
905 if (fListenerNotifier != null && fListenerNotifier.hasTimeSelected()) {
906 return;
907 }
837a2f8c
PT
908 setSelectedTimeInt(time, ensureVisible, false);
909 }
910
0fcf3b09
PT
911 @Override
912 public void setSelectionRangeNotify(long beginTime, long endTime) {
33fa1fc7
PT
913 long time0 = fTime0;
914 long time1 = fTime1;
c534b0a5
PT
915 long selectionBegin = fSelectionBegin;
916 long selectionEnd = fSelectionEnd;
0fcf3b09
PT
917 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
918 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
c534b0a5 919 boolean changed = (selectionBegin != fSelectionBegin || selectionEnd != fSelectionEnd);
33fa1fc7 920 ensureVisible(fSelectionEnd);
0fcf3b09
PT
921 fTimeGraphCtrl.redraw();
922 fTimeScaleCtrl.redraw();
f72cd563 923 updateMarkerActions();
33fa1fc7
PT
924 if ((time0 != fTime0) || (time1 != fTime1)) {
925 notifyRangeListeners();
926 }
0fcf3b09 927 if (changed) {
10ad9fa6 928 notifyTimeListeners();
0fcf3b09
PT
929 }
930 }
931
0fcf3b09
PT
932 @Override
933 public void setSelectionRange(long beginTime, long endTime) {
88de10c6
PT
934 /* if there is a pending time selection, ignore this one */
935 if (fListenerNotifier != null && fListenerNotifier.hasTimeSelected()) {
936 return;
937 }
0fcf3b09
PT
938 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
939 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
940 fTimeGraphCtrl.redraw();
941 fTimeScaleCtrl.redraw();
f72cd563 942 updateMarkerActions();
0fcf3b09
PT
943 }
944
837a2f8c 945 private void setSelectedTimeInt(long time, boolean ensureVisible, boolean doNotify) {
c534b0a5 946 long selection = Math.max(fTime0Bound, Math.min(fTime1Bound, time));
f1fae91f
PT
947 long time0 = fTime0;
948 long time1 = fTime1;
837a2f8c 949 if (ensureVisible) {
c534b0a5 950 ensureVisible(selection);
837a2f8c 951 }
f1fae91f
PT
952 fTimeGraphCtrl.redraw();
953 fTimeScaleCtrl.redraw();
837a2f8c 954
c534b0a5
PT
955 boolean notifySelectedTime = (selection != fSelectionBegin || selection != fSelectionEnd);
956 fSelectionBegin = selection;
957 fSelectionEnd = selection;
f72cd563 958 updateMarkerActions();
837a2f8c 959
37e1a265 960 if ((time0 != fTime0) || (time1 != fTime1)) {
10ad9fa6 961 notifyRangeListeners();
837a2f8c
PT
962 }
963
964 if (doNotify && notifySelectedTime) {
10ad9fa6 965 notifyTimeListeners();
837a2f8c
PT
966 }
967 }
968
33fa1fc7
PT
969 private void ensureVisible(long time) {
970 long timeMid = (fTime1 - fTime0) / 2;
971 if (time < fTime0) {
972 long dt = fTime0 - time + timeMid;
973 fTime0 -= dt;
974 fTime1 -= dt;
975 } else if (time > fTime1) {
976 long dt = time - fTime1 + timeMid;
977 fTime0 += dt;
978 fTime1 += dt;
979 }
980 if (fTime0 < fTime0Bound) {
981 fTime1 = Math.min(fTime1Bound, fTime1 + (fTime0Bound - fTime0));
982 fTime0 = fTime0Bound;
983 } else if (fTime1 > fTime1Bound) {
984 fTime0 = Math.max(fTime0Bound, fTime0 - (fTime1 - fTime1Bound));
985 fTime1 = fTime1Bound;
986 }
987 if (fTime1 - fTime0 < fMinTimeInterval) {
988 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
989 }
990 adjustHorizontalScrollBar();
991 }
992
837a2f8c
PT
993 @Override
994 public void widgetDefaultSelected(SelectionEvent e) {
f1fae91f
PT
995 if (fSelectedEntry != getSelection()) {
996 fSelectedEntry = getSelection();
10ad9fa6 997 notifySelectionListeners();
837a2f8c
PT
998 }
999 }
1000
1001 @Override
1002 public void widgetSelected(SelectionEvent e) {
f1fae91f
PT
1003 if (fSelectedEntry != getSelection()) {
1004 fSelectedEntry = getSelection();
10ad9fa6 1005 notifySelectionListeners();
837a2f8c
PT
1006 }
1007 }
1008
1009 /**
1010 * Callback for when the next event is selected
33fa1fc7
PT
1011 *
1012 * @param extend
1013 * true to extend selection range, false for single selection
1014 * @since 1.0
837a2f8c 1015 */
33fa1fc7
PT
1016 public void selectNextEvent(boolean extend) {
1017 fTimeGraphCtrl.selectNextEvent(extend);
837a2f8c
PT
1018 adjustVerticalScrollBar();
1019 }
1020
1021 /**
1022 * Callback for when the previous event is selected
33fa1fc7
PT
1023 *
1024 * @param extend
1025 * true to extend selection range, false for single selection
1026 * @since 1.0
837a2f8c 1027 */
33fa1fc7
PT
1028 public void selectPrevEvent(boolean extend) {
1029 fTimeGraphCtrl.selectPrevEvent(extend);
837a2f8c
PT
1030 adjustVerticalScrollBar();
1031 }
1032
1033 /**
1034 * Callback for when the next item is selected
1035 */
1036 public void selectNextItem() {
f1fae91f 1037 fTimeGraphCtrl.selectNextTrace();
837a2f8c
PT
1038 adjustVerticalScrollBar();
1039 }
1040
1041 /**
1042 * Callback for when the previous item is selected
1043 */
1044 public void selectPrevItem() {
f1fae91f 1045 fTimeGraphCtrl.selectPrevTrace();
837a2f8c
PT
1046 adjustVerticalScrollBar();
1047 }
1048
1049 /**
1050 * Callback for the show legend action
1051 */
1052 public void showLegend() {
f1fae91f 1053 if (fDataViewer == null || fDataViewer.isDisposed()) {
837a2f8c
PT
1054 return;
1055 }
1056
f1fae91f 1057 TimeGraphLegend.open(fDataViewer.getShell(), fTimeGraphProvider);
837a2f8c
PT
1058 }
1059
1060 /**
1061 * Callback for the Zoom In action
1062 */
1063 public void zoomIn() {
f1fae91f 1064 fTimeGraphCtrl.zoomIn();
837a2f8c
PT
1065 }
1066
1067 /**
1068 * Callback for the Zoom Out action
1069 */
1070 public void zoomOut() {
f1fae91f 1071 fTimeGraphCtrl.zoomOut();
837a2f8c
PT
1072 }
1073
1074 private String getPreferenceString(String string) {
1075 return getViewTypeStr() + "." + string; //$NON-NLS-1$
1076 }
1077
1078 /**
1079 * Add a selection listener
1080 *
1081 * @param listener
1082 * The listener to add
1083 */
1084 public void addSelectionListener(ITimeGraphSelectionListener listener) {
1085 fSelectionListeners.add(listener);
1086 }
1087
1088 /**
1089 * Remove a selection listener
1090 *
1091 * @param listener
1092 * The listener to remove
1093 */
1094 public void removeSelectionListener(ITimeGraphSelectionListener listener) {
1095 fSelectionListeners.remove(listener);
1096 }
1097
10ad9fa6 1098 private void notifySelectionListeners() {
88de10c6
PT
1099 if (fListenerNotifier == null) {
1100 fListenerNotifier = new ListenerNotifier();
1101 fListenerNotifier.start();
10ad9fa6 1102 }
88de10c6 1103 fListenerNotifier.selectionChanged();
10ad9fa6
PT
1104 }
1105
1106 private void fireSelectionChanged(ITimeGraphEntry selection) {
837a2f8c
PT
1107 TimeGraphSelectionEvent event = new TimeGraphSelectionEvent(this, selection);
1108
1109 for (ITimeGraphSelectionListener listener : fSelectionListeners) {
1110 listener.selectionChanged(event);
1111 }
1112 }
1113
1114 /**
1115 * Add a time listener
1116 *
1117 * @param listener
1118 * The listener to add
1119 */
1120 public void addTimeListener(ITimeGraphTimeListener listener) {
1121 fTimeListeners.add(listener);
1122 }
1123
1124 /**
1125 * Remove a time listener
1126 *
1127 * @param listener
1128 * The listener to remove
1129 */
1130 public void removeTimeListener(ITimeGraphTimeListener listener) {
1131 fTimeListeners.remove(listener);
1132 }
1133
10ad9fa6 1134 private void notifyTimeListeners() {
88de10c6
PT
1135 if (fListenerNotifier == null) {
1136 fListenerNotifier = new ListenerNotifier();
1137 fListenerNotifier.start();
10ad9fa6 1138 }
88de10c6 1139 fListenerNotifier.timeSelected();
10ad9fa6
PT
1140 }
1141
1142 private void fireTimeSelected(long startTime, long endTime) {
0fcf3b09 1143 TimeGraphTimeEvent event = new TimeGraphTimeEvent(this, startTime, endTime);
837a2f8c
PT
1144
1145 for (ITimeGraphTimeListener listener : fTimeListeners) {
1146 listener.timeSelected(event);
1147 }
1148 }
1149
1150 /**
1151 * Add a range listener
1152 *
1153 * @param listener
1154 * The listener to add
1155 */
1156 public void addRangeListener(ITimeGraphRangeListener listener) {
1157 fRangeListeners.add(listener);
1158 }
1159
1160 /**
1161 * Remove a range listener
1162 *
1163 * @param listener
1164 * The listener to remove
1165 */
1166 public void removeRangeListener(ITimeGraphRangeListener listener) {
1167 fRangeListeners.remove(listener);
1168 }
1169
10ad9fa6 1170 private void notifyRangeListeners() {
88de10c6
PT
1171 if (fListenerNotifier == null) {
1172 fListenerNotifier = new ListenerNotifier();
1173 fListenerNotifier.start();
10ad9fa6 1174 }
88de10c6 1175 fListenerNotifier.timeRangeUpdated();
10ad9fa6
PT
1176 }
1177
1178 private void fireTimeRangeUpdated(long startTime, long endTime) {
837a2f8c 1179 // Check if the time has actually changed from last notification
f1fae91f 1180 if (startTime != fTime0ExtSynch || endTime != fTime1ExtSynch) {
837a2f8c
PT
1181 // Notify Time Scale Selection Listeners
1182 TimeGraphRangeUpdateEvent event = new TimeGraphRangeUpdateEvent(this, startTime, endTime);
1183
1184 for (ITimeGraphRangeListener listener : fRangeListeners) {
1185 listener.timeRangeUpdated(event);
1186 }
1187
45f63682
PT
1188 // update external synch values
1189 updateExtSynchValues();
837a2f8c
PT
1190 }
1191 }
1192
1d012443
PT
1193 /**
1194 * Add a bookmark listener
1195 *
1196 * @param listener
1197 * The listener to add
1198 * @since 2.0
1199 */
1200 public void addBookmarkListener(ITimeGraphBookmarkListener listener) {
1201 fBookmarkListeners.add(listener);
1202 }
1203
1204 /**
1205 * Remove a bookmark listener
1206 *
1207 * @param listener
1208 * The listener to remove
1209 * @since 2.0
1210 */
1211 public void removeBookmarkListener(ITimeGraphBookmarkListener listener) {
1212 fBookmarkListeners.remove(listener);
1213 }
1214
1215 private void fireBookmarkAdded(IMarkerEvent bookmark) {
1216 TimeGraphBookmarkEvent event = new TimeGraphBookmarkEvent(this, bookmark);
1217
1218 for (ITimeGraphBookmarkListener listener : fBookmarkListeners) {
1219 listener.bookmarkAdded(event);
1220 }
1221 }
1222
1223 private void fireBookmarkRemoved(IMarkerEvent bookmark) {
1224 TimeGraphBookmarkEvent event = new TimeGraphBookmarkEvent(this, bookmark);
1225
1226 for (ITimeGraphBookmarkListener listener : fBookmarkListeners) {
1227 listener.bookmarkRemoved(event);
1228 }
1229 }
1230
1231 /**
1232 * Set the bookmarks list.
1233 *
1234 * @param bookmarks
1235 * The bookmarks list, or null
1236 * @since 2.0
1237 */
1238 public void setBookmarks(List<IMarkerEvent> bookmarks) {
1239 for (IMarkerEvent bookmark : fBookmarks) {
1240 checkDisposeColor(bookmark.getColor());
1241 }
1242 fBookmarks.clear();
1243 if (bookmarks != null) {
1244 fBookmarks.addAll(bookmarks);
1d012443 1245 }
f72cd563
PT
1246 updateMarkerList();
1247 updateMarkerActions();
1d012443
PT
1248 }
1249
1250 /**
1251 * Get the bookmarks list.
1252 *
1253 * @return The bookmarks list
1254 * @since 2.0
1255 */
1256 public List<IMarkerEvent> getBookmarks() {
1257 return Collections.unmodifiableList(fBookmarks);
1258 }
1259
91512088
PT
1260 /**
1261 * Set the list of marker categories.
1262 *
1263 * @param categories
1264 * The list of marker categories, or null
1265 * @since 2.0
1266 */
1267 public void setMarkerCategories(List<String> categories) {
1268 fMarkerCategories.clear();
1269 fMarkerCategories.add(IMarkerEvent.BOOKMARKS);
1270 if (categories != null) {
1271 fMarkerCategories.addAll(categories);
1272 }
1273 Collections.sort(fMarkerCategories);
1274 }
1275
f72cd563
PT
1276 /**
1277 * Set the markers list.
1278 *
1279 * @param markers
1280 * The markers list, or null
1281 * @since 2.0
1282 */
1283 public void setMarkers(List<IMarkerEvent> markers) {
1284 fMarkers.clear();
1285 if (markers != null) {
1286 fMarkers.addAll(markers);
1287 }
1288 updateMarkerList();
1289 updateMarkerActions();
1290 }
1291
1292 /**
1293 * Get the markers list.
1294 *
1295 * @return The markers list, or null
1296 * @since 2.0
1297 */
1298 public List<IMarkerEvent> getMarkers() {
1299 return Collections.unmodifiableList(fMarkers);
1300 }
1301
1d012443
PT
1302 /**
1303 * Dispose the color resource if and only if it was created by this viewer.
1304 *
1305 * @param color
1306 * the color
1307 */
1308 private void checkDisposeColor(Color color) {
1309 for (int i = 0; i < fColors.size(); i++) {
1310 /* check for identity, not equality */
1311 if (fColors.get(i) == color) {
1312 color.dispose();
1313 fColors.remove(i);
1314 break;
1315 }
1316 }
1317 }
1318
837a2f8c
PT
1319 /**
1320 * Callback to set a selected event in the view
1321 *
1322 * @param event
1323 * The event that was selected
1324 * @param source
1325 * The source of this selection event
1326 */
1327 public void setSelectedEvent(ITimeEvent event, Object source) {
1328 if (event == null || source == this) {
1329 return;
1330 }
f1fae91f
PT
1331 fSelectedEntry = event.getEntry();
1332 fTimeGraphCtrl.selectItem(fSelectedEntry, false);
837a2f8c
PT
1333
1334 setSelectedTimeInt(event.getTime(), true, true);
1335 adjustVerticalScrollBar();
1336 }
1337
1338 /**
1339 * Set the seeked time of a trace
1340 *
1341 * @param trace
1342 * The trace that was seeked
1343 * @param time
1344 * The target time
1345 * @param source
1346 * The source of this seek event
1347 */
1348 public void setSelectedTraceTime(ITimeGraphEntry trace, long time, Object source) {
1349 if (trace == null || source == this) {
1350 return;
1351 }
f1fae91f
PT
1352 fSelectedEntry = trace;
1353 fTimeGraphCtrl.selectItem(trace, false);
837a2f8c
PT
1354
1355 setSelectedTimeInt(time, true, true);
1356 }
1357
1358 /**
1359 * Callback for a trace selection
1360 *
1361 * @param trace
1362 * The trace that was selected
1363 */
1364 public void setSelection(ITimeGraphEntry trace) {
88de10c6
PT
1365 /* if there is a pending selection, ignore this one */
1366 if (fListenerNotifier != null && fListenerNotifier.hasSelectionChanged()) {
1367 return;
1368 }
f1fae91f
PT
1369 fSelectedEntry = trace;
1370 fTimeGraphCtrl.selectItem(trace, false);
837a2f8c
PT
1371 adjustVerticalScrollBar();
1372 }
1373
1374 /**
1375 * Callback for a time window selection
1376 *
1377 * @param time0
1378 * Start time of the range
1379 * @param time1
1380 * End time of the range
1381 * @param source
1382 * Source of the event
1383 */
1384 public void setSelectVisTimeWindow(long time0, long time1, Object source) {
1385 if (source == this) {
1386 return;
1387 }
1388
88de10c6 1389 setStartFinishTimeInt(time0, time1);
837a2f8c
PT
1390
1391 // update notification time values since we are now in synch with the
1392 // external application
45f63682 1393 updateExtSynchValues();
837a2f8c
PT
1394 }
1395
1396 /**
45f63682 1397 * update the cache values used to identify the need to send a time window
837a2f8c
PT
1398 * update to external registered listeners
1399 */
45f63682 1400 private void updateExtSynchValues() {
837a2f8c 1401 // last time notification cache
f1fae91f
PT
1402 fTime0ExtSynch = fTime0;
1403 fTime1ExtSynch = fTime1;
837a2f8c
PT
1404 }
1405
026664b7
XR
1406 @Override
1407 public TimeFormat getTimeFormat() {
f1fae91f 1408 return fTimeFormat;
837a2f8c
PT
1409 }
1410
026664b7 1411 /**
79ec0b89
PT
1412 * @param tf
1413 * the {@link TimeFormat} used to display timestamps
026664b7
XR
1414 */
1415 public void setTimeFormat(TimeFormat tf) {
f1fae91f 1416 this.fTimeFormat = tf;
0fab12b0
PT
1417 if (tf == TimeFormat.CYCLES) {
1418 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1419 } else {
1420 fTimeDataProvider = this;
1421 }
1422 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1423 if (fToolTipHandler != null) {
1424 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1425 }
1426 }
1427
1428 /**
1429 * Sets the clock frequency. Used when the time format is set to CYCLES.
1430 *
1431 * @param clockFrequency
1432 * the clock frequency in Hz
0fab12b0
PT
1433 */
1434 public void setClockFrequency(long clockFrequency) {
1435 fClockFrequency = clockFrequency;
1436 if (fTimeFormat == TimeFormat.CYCLES) {
1437 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1438 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1439 if (fToolTipHandler != null) {
1440 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1441 }
1442 }
837a2f8c
PT
1443 }
1444
1445 /**
1446 * Retrieve the border width
1447 *
1448 * @return The width
1449 */
1450 public int getBorderWidth() {
f1fae91f 1451 return fBorderWidth;
837a2f8c
PT
1452 }
1453
1454 /**
1455 * Set the border width
1456 *
1457 * @param borderWidth
1458 * The width
1459 */
1460 public void setBorderWidth(int borderWidth) {
1461 if (borderWidth > -1) {
f1fae91f 1462 this.fBorderWidth = borderWidth;
79ec0b89 1463 GridLayout gl = (GridLayout) fDataViewer.getLayout();
837a2f8c
PT
1464 gl.marginHeight = borderWidth;
1465 }
1466 }
1467
1468 /**
1469 * Retrieve the height of the header
1470 *
1471 * @return The height
1472 */
1473 public int getHeaderHeight() {
f1fae91f 1474 return fTimeScaleHeight;
837a2f8c
PT
1475 }
1476
1477 /**
1478 * Set the height of the header
1479 *
1480 * @param headerHeight
1481 * The height to set
1482 */
1483 public void setHeaderHeight(int headerHeight) {
1484 if (headerHeight > -1) {
f1fae91f
PT
1485 this.fTimeScaleHeight = headerHeight;
1486 fTimeScaleCtrl.setHeight(headerHeight);
837a2f8c
PT
1487 }
1488 }
1489
1490 /**
1491 * Retrieve the height of an item row
1492 *
1493 * @return The height
1494 */
1495 public int getItemHeight() {
f1fae91f
PT
1496 if (fTimeGraphCtrl != null) {
1497 return fTimeGraphCtrl.getItemHeight();
837a2f8c
PT
1498 }
1499 return 0;
1500 }
1501
1502 /**
1503 * Set the height of an item row
1504 *
1505 * @param rowHeight
1506 * The height to set
1507 */
1508 public void setItemHeight(int rowHeight) {
f1fae91f
PT
1509 if (fTimeGraphCtrl != null) {
1510 fTimeGraphCtrl.setItemHeight(rowHeight);
837a2f8c
PT
1511 }
1512 }
1513
1514 /**
1515 * Set the minimum item width
1516 *
1517 * @param width
1518 * The min width
1519 */
1520 public void setMinimumItemWidth(int width) {
f1fae91f
PT
1521 if (fTimeGraphCtrl != null) {
1522 fTimeGraphCtrl.setMinimumItemWidth(width);
837a2f8c
PT
1523 }
1524 }
1525
1526 /**
1527 * Set the width for the name column
1528 *
79ec0b89
PT
1529 * @param width
1530 * The width
837a2f8c
PT
1531 */
1532 public void setNameWidthPref(int width) {
f1fae91f 1533 fNameWidthPref = width;
837a2f8c 1534 if (width == 0) {
f1fae91f
PT
1535 fMinNameWidth = 0;
1536 fNameWidth = 0;
837a2f8c
PT
1537 }
1538 }
1539
1540 /**
1541 * Retrieve the configure width for the name column
1542 *
1543 * @param width
1544 * Unused?
1545 * @return The width
1546 */
1547 public int getNameWidthPref(int width) {
f1fae91f 1548 return fNameWidthPref;
837a2f8c
PT
1549 }
1550
1551 /**
1552 * Returns the primary control associated with this viewer.
1553 *
1554 * @return the SWT control which displays this viewer's content
1555 */
1556 public Control getControl() {
f1fae91f 1557 return fDataViewer;
837a2f8c
PT
1558 }
1559
1560 /**
1561 * Returns the time graph control associated with this viewer.
1562 *
1563 * @return the time graph control
1564 */
3e9a3685 1565 public TimeGraphControl getTimeGraphControl() {
f1fae91f 1566 return fTimeGraphCtrl;
837a2f8c
PT
1567 }
1568
1569 /**
1570 * Returns the time graph scale associated with this viewer.
1571 *
1572 * @return the time graph scale
1573 */
3e9a3685 1574 public TimeGraphScale getTimeGraphScale() {
f1fae91f 1575 return fTimeScaleCtrl;
837a2f8c
PT
1576 }
1577
d2e4afa7
MAL
1578 /**
1579 * Returns the composite containing all the controls that are time aligned,
1580 * i.e. TimeGraphScale, TimeGraphControl.
1581 *
1582 * @return the time based composite
1583 * @since 1.0
1584 */
1585 public Composite getTimeAlignedComposite() {
1586 return fTimeAlignedComposite;
1587 }
1588
713a70ae
PT
1589 /**
1590 * Return the x coordinate corresponding to a time
1591 *
79ec0b89
PT
1592 * @param time
1593 * the time
713a70ae 1594 * @return the x coordinate corresponding to the time
713a70ae
PT
1595 */
1596 public int getXForTime(long time) {
f1fae91f 1597 return fTimeGraphCtrl.getXForTime(time);
713a70ae
PT
1598 }
1599
1600 /**
1601 * Return the time corresponding to an x coordinate
1602 *
79ec0b89
PT
1603 * @param x
1604 * the x coordinate
713a70ae 1605 * @return the time corresponding to the x coordinate
713a70ae
PT
1606 */
1607 public long getTimeAtX(int x) {
f1fae91f 1608 return fTimeGraphCtrl.getTimeAtX(x);
713a70ae
PT
1609 }
1610
837a2f8c
PT
1611 /**
1612 * Get the selection provider
1613 *
1614 * @return the selection provider
1615 */
1616 public ISelectionProvider getSelectionProvider() {
f1fae91f 1617 return fTimeGraphCtrl;
837a2f8c
PT
1618 }
1619
1620 /**
1621 * Wait for the cursor
1622 *
1623 * @param waitInd
1624 * Wait indefinitely?
1625 */
1626 public void waitCursor(boolean waitInd) {
f1fae91f 1627 fTimeGraphCtrl.waitCursor(waitInd);
837a2f8c
PT
1628 }
1629
1630 /**
1631 * Get the horizontal scroll bar object
1632 *
1633 * @return The scroll bar
1634 */
b698ec63
PT
1635 public Slider getHorizontalBar() {
1636 return fHorizontalScrollBar;
837a2f8c
PT
1637 }
1638
1639 /**
1640 * Get the vertical scroll bar object
1641 *
1642 * @return The scroll bar
1643 */
1644 public Slider getVerticalBar() {
f1fae91f 1645 return fVerticalScrollBar;
837a2f8c
PT
1646 }
1647
1648 /**
1649 * Set the given index as the top one
1650 *
1651 * @param index
1652 * The index that will go to the top
1653 */
1654 public void setTopIndex(int index) {
f1fae91f 1655 fTimeGraphCtrl.setTopIndex(index);
837a2f8c
PT
1656 adjustVerticalScrollBar();
1657 }
1658
1659 /**
1660 * Retrieve the current top index
1661 *
1662 * @return The top index
1663 */
1664 public int getTopIndex() {
f1fae91f 1665 return fTimeGraphCtrl.getTopIndex();
837a2f8c
PT
1666 }
1667
f4617471 1668 /**
df0e3d5f
PT
1669 * Sets the auto-expand level to be used for new entries discovered when
1670 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1671 * means that there is no auto-expand; 1 means that top-level entries are
1672 * expanded, but not their children; 2 means that top-level entries are
1673 * expanded, and their children, but not grand-children; and so on.
f4617471
PT
1674 * <p>
1675 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1676 * </p>
df0e3d5f 1677 *
f4617471
PT
1678 * @param level
1679 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1680 * levels of the tree
f4617471
PT
1681 */
1682 public void setAutoExpandLevel(int level) {
1683 fTimeGraphCtrl.setAutoExpandLevel(level);
1684 }
1685
1686 /**
1687 * Returns the auto-expand level.
1688 *
1689 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1690 * the tree are expanded automatically
1691 * @see #setAutoExpandLevel
f4617471
PT
1692 */
1693 public int getAutoExpandLevel() {
1694 return fTimeGraphCtrl.getAutoExpandLevel();
1695 }
1696
df0e3d5f
PT
1697 /**
1698 * Get the expanded state of an entry.
1699 *
1700 * @param entry
1701 * The entry
1702 * @return true if the entry is expanded, false if collapsed
0336f981 1703 * @since 1.1
df0e3d5f
PT
1704 */
1705 public boolean getExpandedState(ITimeGraphEntry entry) {
1706 return fTimeGraphCtrl.getExpandedState(entry);
1707 }
1708
837a2f8c
PT
1709 /**
1710 * Set the expanded state of an entry
1711 *
1712 * @param entry
1713 * The entry to expand/collapse
1714 * @param expanded
1715 * True for expanded, false for collapsed
1716 */
1717 public void setExpandedState(ITimeGraphEntry entry, boolean expanded) {
f1fae91f 1718 fTimeGraphCtrl.setExpandedState(entry, expanded);
837a2f8c
PT
1719 adjustVerticalScrollBar();
1720 }
1721
1722 /**
1723 * Collapses all nodes of the viewer's tree, starting with the root.
837a2f8c
PT
1724 */
1725 public void collapseAll() {
f1fae91f 1726 fTimeGraphCtrl.collapseAll();
837a2f8c
PT
1727 adjustVerticalScrollBar();
1728 }
1729
1730 /**
df0e3d5f 1731 * Expands all entries of the viewer's tree, starting with the root.
837a2f8c
PT
1732 */
1733 public void expandAll() {
f1fae91f 1734 fTimeGraphCtrl.expandAll();
837a2f8c
PT
1735 adjustVerticalScrollBar();
1736 }
1737
1738 /**
df0e3d5f
PT
1739 * Get the number of expanded (visible) time graph entries. This includes
1740 * leafs and does not include filtered-out entries.
837a2f8c 1741 *
df0e3d5f 1742 * @return The number of expanded (visible) time graph entries
837a2f8c
PT
1743 */
1744 public int getExpandedElementCount() {
f1fae91f 1745 return fTimeGraphCtrl.getExpandedElementCount();
837a2f8c
PT
1746 }
1747
1748 /**
df0e3d5f
PT
1749 * Get the expanded (visible) time graph entries. This includes leafs and
1750 * does not include filtered-out entries.
837a2f8c 1751 *
df0e3d5f 1752 * @return The array of expanded (visible) time graph entries
837a2f8c
PT
1753 */
1754 public ITimeGraphEntry[] getExpandedElements() {
f1fae91f 1755 return fTimeGraphCtrl.getExpandedElements();
837a2f8c
PT
1756 }
1757
1758 /**
1759 * Add a tree listener
1760 *
1761 * @param listener
1762 * The listener to add
1763 */
1764 public void addTreeListener(ITimeGraphTreeListener listener) {
f1fae91f 1765 fTimeGraphCtrl.addTreeListener(listener);
837a2f8c
PT
1766 }
1767
1768 /**
1769 * Remove a tree listener
1770 *
1771 * @param listener
1772 * The listener to remove
1773 */
1774 public void removeTreeListener(ITimeGraphTreeListener listener) {
f1fae91f 1775 fTimeGraphCtrl.removeTreeListener(listener);
837a2f8c
PT
1776 }
1777
1778 /**
1779 * Get the reset scale action.
1780 *
1781 * @return The Action object
1782 */
1783 public Action getResetScaleAction() {
f1fae91f 1784 if (fResetScaleAction == null) {
837a2f8c 1785 // resetScale
f1fae91f 1786 fResetScaleAction = new Action() {
837a2f8c
PT
1787 @Override
1788 public void run() {
1789 resetStartFinishTime();
1790 }
1791 };
f1fae91f
PT
1792 fResetScaleAction.setText(Messages.TmfTimeGraphViewer_ResetScaleActionNameText);
1793 fResetScaleAction.setToolTipText(Messages.TmfTimeGraphViewer_ResetScaleActionToolTipText);
1794 fResetScaleAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU));
837a2f8c 1795 }
f1fae91f 1796 return fResetScaleAction;
837a2f8c
PT
1797 }
1798
1799 /**
1800 * Get the show legend action.
1801 *
1802 * @return The Action object
1803 */
1804 public Action getShowLegendAction() {
f1fae91f 1805 if (fShowLegendAction == null) {
837a2f8c 1806 // showLegend
f1fae91f 1807 fShowLegendAction = new Action() {
837a2f8c
PT
1808 @Override
1809 public void run() {
1810 showLegend();
1811 }
1812 };
f1fae91f
PT
1813 fShowLegendAction.setText(Messages.TmfTimeGraphViewer_LegendActionNameText);
1814 fShowLegendAction.setToolTipText(Messages.TmfTimeGraphViewer_LegendActionToolTipText);
1815 fShowLegendAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LEGEND));
837a2f8c
PT
1816 }
1817
f1fae91f 1818 return fShowLegendAction;
837a2f8c
PT
1819 }
1820
1821 /**
1822 * Get the the next event action.
1823 *
1824 * @return The action object
1825 */
1826 public Action getNextEventAction() {
f1fae91f
PT
1827 if (fNextEventAction == null) {
1828 fNextEventAction = new Action() {
837a2f8c 1829 @Override
33fa1fc7
PT
1830 public void runWithEvent(Event event) {
1831 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1832 selectNextEvent(extend);
837a2f8c
PT
1833 }
1834 };
1835
f1fae91f
PT
1836 fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText);
1837 fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText);
1838 fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT));
837a2f8c
PT
1839 }
1840
f1fae91f 1841 return fNextEventAction;
837a2f8c
PT
1842 }
1843
1844 /**
1845 * Get the previous event action.
1846 *
1847 * @return The Action object
1848 */
1849 public Action getPreviousEventAction() {
f1fae91f
PT
1850 if (fPrevEventAction == null) {
1851 fPrevEventAction = new Action() {
837a2f8c 1852 @Override
33fa1fc7
PT
1853 public void runWithEvent(Event event) {
1854 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1855 selectPrevEvent(extend);
837a2f8c
PT
1856 }
1857 };
1858
f1fae91f
PT
1859 fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText);
1860 fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText);
1861 fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT));
837a2f8c
PT
1862 }
1863
f1fae91f 1864 return fPrevEventAction;
837a2f8c
PT
1865 }
1866
1867 /**
1868 * Get the next item action.
1869 *
1870 * @return The Action object
1871 */
1872 public Action getNextItemAction() {
f1fae91f 1873 if (fNextItemAction == null) {
837a2f8c 1874
f1fae91f 1875 fNextItemAction = new Action() {
837a2f8c
PT
1876 @Override
1877 public void run() {
1878 selectNextItem();
1879 }
1880 };
f1fae91f
PT
1881 fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText);
1882 fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText);
1883 fNextItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_ITEM));
837a2f8c 1884 }
f1fae91f 1885 return fNextItemAction;
837a2f8c
PT
1886 }
1887
1888 /**
1889 * Get the previous item action.
1890 *
1891 * @return The Action object
1892 */
1893 public Action getPreviousItemAction() {
f1fae91f 1894 if (fPreviousItemAction == null) {
837a2f8c 1895
f1fae91f 1896 fPreviousItemAction = new Action() {
837a2f8c
PT
1897 @Override
1898 public void run() {
1899 selectPrevItem();
1900 }
1901 };
f1fae91f
PT
1902 fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText);
1903 fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText);
1904 fPreviousItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_ITEM));
837a2f8c 1905 }
f1fae91f 1906 return fPreviousItemAction;
837a2f8c
PT
1907 }
1908
1909 /**
1910 * Get the zoom in action
1911 *
1912 * @return The Action object
1913 */
1914 public Action getZoomInAction() {
f1fae91f
PT
1915 if (fZoomInAction == null) {
1916 fZoomInAction = new Action() {
837a2f8c
PT
1917 @Override
1918 public void run() {
1919 zoomIn();
1920 }
1921 };
f1fae91f
PT
1922 fZoomInAction.setText(Messages.TmfTimeGraphViewer_ZoomInActionNameText);
1923 fZoomInAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomInActionToolTipText);
1924 fZoomInAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU));
837a2f8c 1925 }
f1fae91f 1926 return fZoomInAction;
837a2f8c
PT
1927 }
1928
1929 /**
1930 * Get the zoom out action
1931 *
1932 * @return The Action object
1933 */
1934 public Action getZoomOutAction() {
f1fae91f
PT
1935 if (fZoomOutAction == null) {
1936 fZoomOutAction = new Action() {
837a2f8c
PT
1937 @Override
1938 public void run() {
1939 zoomOut();
1940 }
1941 };
f1fae91f
PT
1942 fZoomOutAction.setText(Messages.TmfTimeGraphViewer_ZoomOutActionNameText);
1943 fZoomOutAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomOutActionToolTipText);
1944 fZoomOutAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU));
837a2f8c 1945 }
f1fae91f 1946 return fZoomOutAction;
837a2f8c
PT
1947 }
1948
79ec0b89
PT
1949 /**
1950 * Get the hide arrows action
1951 *
1952 * @param dialogSettings
1953 * The dialog settings section where the state should be stored,
1954 * or null
1955 *
1956 * @return The Action object
79ec0b89
PT
1957 */
1958 public Action getHideArrowsAction(final IDialogSettings dialogSettings) {
1959 if (fHideArrowsAction == null) {
1960 fHideArrowsAction = new Action(Messages.TmfTimeGraphViewer_HideArrowsActionNameText, IAction.AS_CHECK_BOX) {
1961 @Override
1962 public void run() {
1963 boolean hideArrows = fHideArrowsAction.isChecked();
1964 fTimeGraphCtrl.hideArrows(hideArrows);
1965 refresh();
1966 if (dialogSettings != null) {
1967 dialogSettings.put(HIDE_ARROWS_KEY, hideArrows);
1968 }
086f21ae
PT
1969 if (fFollowArrowFwdAction != null) {
1970 fFollowArrowFwdAction.setEnabled(!hideArrows);
1971 }
1972 if (fFollowArrowBwdAction != null) {
1973 fFollowArrowBwdAction.setEnabled(!hideArrows);
1974 }
79ec0b89
PT
1975 }
1976 };
1977 fHideArrowsAction.setToolTipText(Messages.TmfTimeGraphViewer_HideArrowsActionToolTipText);
1978 fHideArrowsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HIDE_ARROWS));
1979 if (dialogSettings != null) {
1980 boolean hideArrows = dialogSettings.getBoolean(HIDE_ARROWS_KEY);
1981 fTimeGraphCtrl.hideArrows(hideArrows);
1982 fHideArrowsAction.setChecked(hideArrows);
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 return fHideArrowsAction;
1992 }
837a2f8c 1993
086f21ae
PT
1994 /**
1995 * Get the follow arrow forward action.
1996 *
1997 * @return The Action object
086f21ae
PT
1998 */
1999 public Action getFollowArrowFwdAction() {
2000 if (fFollowArrowFwdAction == null) {
2001 fFollowArrowFwdAction = new Action() {
2002 @Override
33fa1fc7
PT
2003 public void runWithEvent(Event event) {
2004 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
2005 fTimeGraphCtrl.followArrowFwd(extend);
086f21ae
PT
2006 adjustVerticalScrollBar();
2007 }
2008 };
2009 fFollowArrowFwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionNameText);
2010 fFollowArrowFwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText);
2011 fFollowArrowFwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_FORWARD));
2012 if (fHideArrowsAction != null) {
2013 fFollowArrowFwdAction.setEnabled(!fHideArrowsAction.isChecked());
2014 }
2015 }
2016 return fFollowArrowFwdAction;
2017 }
2018
2019 /**
2020 * Get the follow arrow backward action.
2021 *
2022 * @return The Action object
086f21ae
PT
2023 */
2024 public Action getFollowArrowBwdAction() {
2025 if (fFollowArrowBwdAction == null) {
2026 fFollowArrowBwdAction = new Action() {
2027 @Override
33fa1fc7
PT
2028 public void runWithEvent(Event event) {
2029 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
2030 fTimeGraphCtrl.followArrowBwd(extend);
086f21ae
PT
2031 adjustVerticalScrollBar();
2032 }
2033 };
2034 fFollowArrowBwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionNameText);
2035 fFollowArrowBwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText);
2036 fFollowArrowBwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_BACKWARD));
2037 if (fHideArrowsAction != null) {
2038 fFollowArrowBwdAction.setEnabled(!fHideArrowsAction.isChecked());
2039 }
2040 }
2041 return fFollowArrowBwdAction;
2042 }
2043
cfcfd964
PT
2044 /**
2045 * Get the show filter dialog action.
2046 *
2047 * @return The Action object
2048 * @since 2.0
2049 */
2050 public ShowFilterDialogAction getShowFilterDialogAction() {
2051 if (fShowFilterDialogAction == null) {
2052 fShowFilterDialogAction = new ShowFilterDialogAction(this);
2053 }
2054 return fShowFilterDialogAction;
2055 }
2056
1d012443
PT
2057 /**
2058 * Get the toggle bookmark action.
2059 *
2060 * @return The Action object
2061 * @since 2.0
2062 */
2063 public Action getToggleBookmarkAction() {
2064 if (fToggleBookmarkAction == null) {
2065 fToggleBookmarkAction = new Action() {
2066 @Override
2067 public void runWithEvent(Event event) {
2068 IMarkerEvent selectedBookmark = getBookmarkAtSelection();
2069 if (selectedBookmark == null) {
2070 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2071 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
7697e148 2072 final AddBookmarkDialog dialog = new AddBookmarkDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), null);
1d012443
PT
2073 if (dialog.open() == Window.OK) {
2074 final String label = dialog.getValue();
2075 final RGBA rgba = dialog.getColorValue();
2076 Color color = new Color(Display.getDefault(), rgba.rgb.red, rgba.rgb.green, rgba.rgb.blue, rgba.alpha);
2077 fColors.add(color);
91512088 2078 IMarkerEvent bookmark = new MarkerEvent(null, time, duration, IMarkerEvent.BOOKMARKS, color, label, true);
1d012443 2079 fBookmarks.add(bookmark);
f72cd563 2080 updateMarkerList();
91512088 2081 updateMarkerActions();
1d012443
PT
2082 getControl().redraw();
2083 fireBookmarkAdded(bookmark);
2084 }
2085 } else {
2086 checkDisposeColor(selectedBookmark.getColor());
2087 fBookmarks.remove(selectedBookmark);
f72cd563 2088 updateMarkerList();
91512088 2089 updateMarkerActions();
1d012443
PT
2090 getControl().redraw();
2091 fireBookmarkRemoved(selectedBookmark);
2092 }
1d012443
PT
2093 }
2094 };
2095 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2096 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2097 fToggleBookmarkAction.setImageDescriptor(ADD_BOOKMARK);
2098 }
2099 return fToggleBookmarkAction;
2100 }
2101
2102 /**
f72cd563 2103 * Get the next marker action.
1d012443
PT
2104 *
2105 * @return The Action object
2106 * @since 2.0
2107 */
f72cd563
PT
2108 public Action getNextMarkerAction() {
2109 if (fNextMarkerAction == null) {
6d5b0ba1 2110 fNextMarkerAction = new Action(Messages.TmfTimeGraphViewer_NextMarkerActionText, IAction.AS_DROP_DOWN_MENU) {
1d012443
PT
2111 @Override
2112 public void runWithEvent(Event event) {
2113 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2114 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
f72cd563
PT
2115 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2116 if (markers == null) {
2117 return;
2118 }
2119 for (IMarkerEvent marker : markers) {
6d5b0ba1
PT
2120 if ((marker.getTime() > time ||
2121 (marker.getTime() == time && marker.getDuration() > duration))
2122 && !fSkippedMarkerCategories.contains(marker.getCategory())) {
f72cd563 2123 setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration());
1d012443
PT
2124 return;
2125 }
2126 }
2127 }
2128 };
f72cd563
PT
2129 fNextMarkerAction.setToolTipText(Messages.TmfTimeGraphViewer_NextMarkerActionText);
2130 fNextMarkerAction.setImageDescriptor(NEXT_BOOKMARK);
6d5b0ba1
PT
2131 fNextMarkerAction.setMenuCreator(new IMenuCreator () {
2132 Menu menu = null;
2133 @Override
2134 public void dispose() {
2135 if (menu != null) {
2136 menu.dispose();
2137 menu = null;
2138 }
2139 }
2140
2141 @Override
2142 public Menu getMenu(Control parent) {
2143 if (menu != null) {
2144 menu.dispose();
2145 }
2146 menu = new Menu(parent);
2147 for (String category : fMarkerCategories) {
2148 final Action action = new Action(category, IAction.AS_CHECK_BOX) {
2149 @Override
2150 public void runWithEvent(Event event) {
2151 if (isChecked()) {
2152 fSkippedMarkerCategories.remove(getText());
2153 } else {
2154 fSkippedMarkerCategories.add(getText());
2155 }
2156 updateMarkerActions();
2157 }
2158 };
2159 action.setEnabled(!fHiddenMarkerCategories.contains(category));
2160 action.setChecked(action.isEnabled() && !fSkippedMarkerCategories.contains(category));
2161 new ActionContributionItem(action).fill(menu, -1);
2162 }
2163 return menu;
2164 }
2165
2166 @Override
2167 public Menu getMenu(Menu parent) {
2168 return null;
2169 }
2170 });
1d012443 2171 }
f72cd563 2172 return fNextMarkerAction;
1d012443
PT
2173 }
2174
2175 /**
f72cd563 2176 * Get the previous marker action.
1d012443
PT
2177 *
2178 * @return The Action object
2179 * @since 2.0
2180 */
f72cd563
PT
2181 public Action getPreviousMarkerAction() {
2182 if (fPreviousMarkerAction == null) {
2183 fPreviousMarkerAction = new Action() {
1d012443
PT
2184 @Override
2185 public void runWithEvent(Event event) {
2186 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2187 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
f72cd563
PT
2188 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2189 if (markers == null) {
2190 return;
2191 }
2192 for (int i = markers.size() - 1; i >= 0; i--) {
2193 IMarkerEvent marker = markers.get(i);
6d5b0ba1
PT
2194 if ((marker.getTime() < time ||
2195 (marker.getTime() == time && marker.getDuration() < duration))
2196 && !fSkippedMarkerCategories.contains(marker.getCategory())) {
f72cd563 2197 setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration());
1d012443
PT
2198 return;
2199 }
2200 }
2201 }
2202 };
f72cd563
PT
2203 fPreviousMarkerAction.setText(Messages.TmfTimeGraphViewer_PreviousMarkerActionText);
2204 fPreviousMarkerAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousMarkerActionText);
2205 fPreviousMarkerAction.setImageDescriptor(PREVIOUS_BOOKMARK);
1d012443 2206 }
f72cd563 2207 return fPreviousMarkerAction;
1d012443
PT
2208 }
2209
91512088
PT
2210 /**
2211 * Get the show markers menu.
2212 *
2213 * @return The menu manager object
2214 * @since 2.0
2215 */
2216 public MenuManager getMarkersMenu() {
2217 if (fMarkersMenu == null) {
2218 fMarkersMenu = new MenuManager(Messages.TmfTimeGraphViewer_ShowMarkersMenuText);
2219 fMarkersMenu.setRemoveAllWhenShown(true);
2220 fMarkersMenu.addMenuListener(new IMenuListener() {
2221 @Override
2222 public void menuAboutToShow(IMenuManager manager) {
2223 for (String category : fMarkerCategories) {
2224 final Action action = new Action(category, IAction.AS_CHECK_BOX) {
2225 @Override
2226 public void runWithEvent(Event event) {
2227 if (isChecked()) {
2228 fHiddenMarkerCategories.remove(getText());
2229 } else {
2230 fHiddenMarkerCategories.add(getText());
2231 }
2232 updateMarkerList();
2233 updateMarkerActions();
2234 getControl().redraw();
2235 }
2236 };
2237 action.setChecked(!fHiddenMarkerCategories.contains(category));
2238 manager.add(action);
2239 }
2240 }
2241 });
2242 }
2243 return fMarkersMenu;
2244 }
2245
1d012443
PT
2246 private IMarkerEvent getBookmarkAtSelection() {
2247 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2248 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2249 for (IMarkerEvent bookmark : fBookmarks) {
2250 if (bookmark.getTime() == time && bookmark.getDuration() == duration) {
2251 return bookmark;
2252 }
2253 }
2254 return null;
2255 }
2256
f72cd563 2257 private void updateMarkerActions() {
6d5b0ba1 2258 boolean enabled = fTime0Bound != SWT.DEFAULT || fTime1Bound != SWT.DEFAULT;
1d012443
PT
2259 if (fToggleBookmarkAction != null) {
2260 if (getBookmarkAtSelection() != null) {
2261 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionRemoveText);
2262 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionRemoveText);
2263 fToggleBookmarkAction.setImageDescriptor(REMOVE_BOOKMARK);
2264 } else {
2265 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2266 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2267 fToggleBookmarkAction.setImageDescriptor(ADD_BOOKMARK);
2268 }
6d5b0ba1 2269 fToggleBookmarkAction.setEnabled(enabled);
1d012443 2270 }
f72cd563
PT
2271 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2272 if (markers == null) {
2273 markers = Collections.emptyList();
2274 }
2275 if (fPreviousMarkerAction != null) {
6d5b0ba1 2276 fPreviousMarkerAction.setEnabled(enabled && !markers.isEmpty());
1d012443 2277 }
f72cd563 2278 if (fNextMarkerAction != null) {
6d5b0ba1 2279 fNextMarkerAction.setEnabled(enabled && !markers.isEmpty());
1d012443
PT
2280 }
2281 }
2282
f72cd563 2283 private void updateMarkerList() {
91512088
PT
2284 List<IMarkerEvent> markers = new ArrayList<>();
2285 for (IMarkerEvent marker : fMarkers) {
2286 if (!fHiddenMarkerCategories.contains(marker.getCategory())) {
2287 markers.add(marker);
2288 }
2289 }
2290 if (!fHiddenMarkerCategories.contains(IMarkerEvent.BOOKMARKS)) {
2291 markers.addAll(fBookmarks);
2292 }
f72cd563
PT
2293 Collections.sort(markers, new MarkerComparator());
2294 getTimeGraphControl().setMarkers(markers);
2295 }
2296
b698ec63
PT
2297 private void adjustHorizontalScrollBar() {
2298 long time0 = getTime0();
2299 long time1 = getTime1();
2300 long timeMin = getMinTime();
2301 long timeMax = getMaxTime();
2302 long delta = timeMax - timeMin;
2303 int timePos = 0;
2304 int thumb = H_SCROLLBAR_MAX;
2305 if (delta != 0) {
2306 // Thumb size (page size)
2307 thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta)));
2308 // At the beginning of visible window
2309 timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta));
2310 }
2311 fHorizontalScrollBar.setValues(timePos, 0, H_SCROLLBAR_MAX, thumb, Math.max(1, thumb / 2), Math.max(2, thumb));
2312 }
2313
837a2f8c 2314 private void adjustVerticalScrollBar() {
f1fae91f
PT
2315 int topIndex = fTimeGraphCtrl.getTopIndex();
2316 int countPerPage = fTimeGraphCtrl.countPerPage();
2317 int expandedElementCount = fTimeGraphCtrl.getExpandedElementCount();
837a2f8c 2318 if (topIndex + countPerPage > expandedElementCount) {
f1fae91f 2319 fTimeGraphCtrl.setTopIndex(Math.max(0, expandedElementCount - countPerPage));
837a2f8c
PT
2320 }
2321
f1fae91f 2322 int selection = fTimeGraphCtrl.getTopIndex();
837a2f8c
PT
2323 int min = 0;
2324 int max = Math.max(1, expandedElementCount - 1);
2325 int thumb = Math.min(max, Math.max(1, countPerPage - 1));
2326 int increment = 1;
2327 int pageIncrement = Math.max(1, countPerPage);
f1fae91f 2328 fVerticalScrollBar.setValues(selection, min, max, thumb, increment, pageIncrement);
837a2f8c
PT
2329 }
2330
27df1564 2331 /**
79ec0b89
PT
2332 * @param listener
2333 * a {@link MenuDetectListener}
2bdf0193 2334 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
2335 */
2336 public void addTimeGraphEntryMenuListener(MenuDetectListener listener) {
f1fae91f 2337 fTimeGraphCtrl.addTimeGraphEntryMenuListener(listener);
27df1564
XR
2338 }
2339
2340 /**
79ec0b89
PT
2341 * @param listener
2342 * a {@link MenuDetectListener}
2bdf0193 2343 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
2344 */
2345 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) {
f1fae91f 2346 fTimeGraphCtrl.removeTimeGraphEntryMenuListener(listener);
27df1564
XR
2347 }
2348
2349 /**
79ec0b89
PT
2350 * @param listener
2351 * a {@link MenuDetectListener}
2bdf0193 2352 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
2353 */
2354 public void addTimeEventMenuListener(MenuDetectListener listener) {
f1fae91f 2355 fTimeGraphCtrl.addTimeEventMenuListener(listener);
27df1564
XR
2356 }
2357
2358 /**
79ec0b89
PT
2359 * @param listener
2360 * a {@link MenuDetectListener}
2bdf0193 2361 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
27df1564
XR
2362 */
2363 public void removeTimeEventMenuListener(MenuDetectListener listener) {
f1fae91f 2364 fTimeGraphCtrl.removeTimeEventMenuListener(listener);
27df1564
XR
2365 }
2366
6ac5a950 2367 /**
79ec0b89
PT
2368 * @param filter
2369 * The filter object to be attached to the view
6ac5a950
AM
2370 */
2371 public void addFilter(ViewerFilter filter) {
f1fae91f 2372 fTimeGraphCtrl.addFilter(filter);
6ac5a950
AM
2373 refresh();
2374 }
837a2f8c 2375
6ac5a950 2376 /**
79ec0b89
PT
2377 * @param filter
2378 * The filter object to be attached to the view
6ac5a950
AM
2379 */
2380 public void removeFilter(ViewerFilter filter) {
f1fae91f 2381 fTimeGraphCtrl.removeFilter(filter);
6ac5a950
AM
2382 refresh();
2383 }
837a2f8c 2384
4923d7b9
PT
2385 /**
2386 * Returns this viewer's filters.
2387 *
2388 * @return an array of viewer filters
2389 * @since 2.0
2390 */
2391 public ViewerFilter[] getFilters() {
2392 return fTimeGraphCtrl.getFilters();
2393 }
2394
2395 /**
2396 * Sets the filters, replacing any previous filters, and triggers
2397 * refiltering of the elements.
2398 *
2399 * @param filters
2400 * an array of viewer filters, or null
2401 * @since 2.0
2402 */
2403 public void setFilters(ViewerFilter[] filters) {
2404 fTimeGraphCtrl.setFilters(filters);
2405 refresh();
2406 }
2407
d2e4afa7
MAL
2408 /**
2409 * Return the time alignment information
2410 *
2411 * @return the time alignment information
2412 *
2413 * @see ITmfTimeAligned
2414 *
2415 * @since 1.0
2416 */
2417 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
2418 return fTimeGraphCtrl.getTimeViewAlignmentInfo();
2419 }
2420
2421 /**
2422 * Return the available width for the time-axis.
2423 *
2424 * @see ITmfTimeAligned
2425 *
2426 * @param requestedOffset
2427 * the requested offset
2428 * @return the available width for the time-axis
2429 *
2430 * @since 1.0
2431 */
2432 public int getAvailableWidth(int requestedOffset) {
921ae867
MAL
2433 int totalWidth = fTimeAlignedComposite.getSize().x;
2434 return Math.min(totalWidth, Math.max(0, totalWidth - requestedOffset));
d2e4afa7
MAL
2435 }
2436
2437 /**
2438 * Perform the alignment operation.
2439 *
2440 * @param offset
2441 * the alignment offset
2442 * @param width
2443 * the alignment width
2444 *
2445 * @see ITmfTimeAligned
2446 *
2447 * @since 1.0
2448 */
2449 public void performAlign(int offset, int width) {
2450 fTimeGraphCtrl.performAlign(offset);
2451 int alignmentWidth = width;
2452 int size = fTimeAlignedComposite.getSize().x;
2453 GridLayout layout = (GridLayout) fTimeAlignedComposite.getLayout();
2454 int marginSize = size - alignmentWidth - offset;
2455 layout.marginRight = Math.max(0, marginSize);
2456 fTimeAlignedComposite.layout();
2457 }
2458
837a2f8c 2459}
This page took 0.203833 seconds and 5 git commands to generate.