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