1 /*****************************************************************************
2 * Copyright (c) 2007, 2017 Intel Corporation, Ericsson, others
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
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
14 * Geneviève Bastien - Add event links between entries
15 *****************************************************************************/
17 package org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Arrays
;
21 import java
.util
.Collections
;
22 import java
.util
.Comparator
;
23 import java
.util
.HashSet
;
24 import java
.util
.List
;
27 import org
.eclipse
.jdt
.annotation
.NonNull
;
28 import org
.eclipse
.jface
.action
.Action
;
29 import org
.eclipse
.jface
.action
.ActionContributionItem
;
30 import org
.eclipse
.jface
.action
.IAction
;
31 import org
.eclipse
.jface
.action
.IMenuCreator
;
32 import org
.eclipse
.jface
.action
.IMenuListener
;
33 import org
.eclipse
.jface
.action
.IMenuManager
;
34 import org
.eclipse
.jface
.action
.MenuManager
;
35 import org
.eclipse
.jface
.dialogs
.IDialogSettings
;
36 import org
.eclipse
.jface
.resource
.ImageDescriptor
;
37 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
38 import org
.eclipse
.jface
.viewers
.ISelection
;
39 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
40 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
41 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
42 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
43 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
44 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
45 import org
.eclipse
.jface
.viewers
.Viewer
;
46 import org
.eclipse
.jface
.viewers
.ViewerFilter
;
47 import org
.eclipse
.jface
.window
.Window
;
48 import org
.eclipse
.swt
.SWT
;
49 import org
.eclipse
.swt
.events
.ControlAdapter
;
50 import org
.eclipse
.swt
.events
.ControlEvent
;
51 import org
.eclipse
.swt
.events
.KeyAdapter
;
52 import org
.eclipse
.swt
.events
.KeyEvent
;
53 import org
.eclipse
.swt
.events
.MenuDetectListener
;
54 import org
.eclipse
.swt
.events
.MouseEvent
;
55 import org
.eclipse
.swt
.events
.MouseWheelListener
;
56 import org
.eclipse
.swt
.events
.PaintEvent
;
57 import org
.eclipse
.swt
.events
.PaintListener
;
58 import org
.eclipse
.swt
.events
.SelectionAdapter
;
59 import org
.eclipse
.swt
.events
.SelectionEvent
;
60 import org
.eclipse
.swt
.events
.SelectionListener
;
61 import org
.eclipse
.swt
.graphics
.Point
;
62 import org
.eclipse
.swt
.graphics
.RGBA
;
63 import org
.eclipse
.swt
.graphics
.Rectangle
;
64 import org
.eclipse
.swt
.layout
.FillLayout
;
65 import org
.eclipse
.swt
.layout
.GridData
;
66 import org
.eclipse
.swt
.layout
.GridLayout
;
67 import org
.eclipse
.swt
.widgets
.Composite
;
68 import org
.eclipse
.swt
.widgets
.Control
;
69 import org
.eclipse
.swt
.widgets
.Display
;
70 import org
.eclipse
.swt
.widgets
.Event
;
71 import org
.eclipse
.swt
.widgets
.Listener
;
72 import org
.eclipse
.swt
.widgets
.Menu
;
73 import org
.eclipse
.swt
.widgets
.Slider
;
74 import org
.eclipse
.swt
.widgets
.Tree
;
75 import org
.eclipse
.swt
.widgets
.TreeColumn
;
76 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
77 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.ITmfImageConstants
;
78 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Messages
;
79 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.dialogs
.AddBookmarkDialog
;
80 import org
.eclipse
.tracecompass
.tmf
.ui
.signal
.TmfTimeViewAlignmentInfo
;
81 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.ITmfTimeAligned
;
82 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.ShowFilterDialogAction
;
83 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.TimeGraphLegend
;
84 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
85 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.IMarkerEvent
;
86 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
87 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
88 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.MarkerEvent
;
89 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.IMarkerAxisListener
;
90 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.ITimeDataProvider
;
91 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeDataProviderCyclesConverter
;
92 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphColorScheme
;
93 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphControl
;
94 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphMarkerAxis
;
95 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphScale
;
96 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphTooltipHandler
;
97 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
98 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
99 import org
.eclipse
.ui
.PlatformUI
;
102 * Generic time graph viewer implementation
104 * @author Patrick Tasse, and others
106 public class TimeGraphViewer
extends Viewer
implements ITimeDataProvider
, IMarkerAxisListener
, SelectionListener
{
108 /** Constant indicating that all levels of the time graph should be expanded */
109 public static final int ALL_LEVELS
= AbstractTreeViewer
.ALL_LEVELS
;
111 private static final int DEFAULT_NAME_WIDTH
= 200;
112 private static final int MIN_NAME_WIDTH
= 3;
113 private static final int MAX_NAME_WIDTH
= 1000;
114 private static final int DEFAULT_HEIGHT
= 22;
115 private static final String HIDE_ARROWS_KEY
= "hide.arrows"; //$NON-NLS-1$
116 private static final long DEFAULT_FREQUENCY
= 1000000000L;
117 private static final int H_SCROLLBAR_MAX
= Integer
.MAX_VALUE
- 1;
119 private static final ImageDescriptor ADD_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ADD_BOOKMARK
);
120 private static final ImageDescriptor NEXT_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_BOOKMARK
);
121 private static final ImageDescriptor PREVIOUS_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREVIOUS_BOOKMARK
);
122 private static final ImageDescriptor REMOVE_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_REMOVE_BOOKMARK
);
124 private long fMinTimeInterval
;
125 private ITimeGraphEntry fSelectedEntry
;
126 private long fBeginTime
= SWT
.DEFAULT
; // The user-specified bounds start time
127 private long fEndTime
= SWT
.DEFAULT
; // The user-specified bounds end time
128 private long fTime0
= SWT
.DEFAULT
; // The current window start time
129 private long fTime1
= SWT
.DEFAULT
; // The current window end time
130 private long fSelectionBegin
= SWT
.DEFAULT
;
131 private long fSelectionEnd
= SWT
.DEFAULT
;
132 private long fTime0Bound
= SWT
.DEFAULT
; // The bounds start time
133 private long fTime1Bound
= SWT
.DEFAULT
; // The bounds end time
134 private long fTime0ExtSynch
= SWT
.DEFAULT
;
135 private long fTime1ExtSynch
= SWT
.DEFAULT
;
136 private boolean fTimeRangeFixed
;
137 private int fNameWidthPref
= DEFAULT_NAME_WIDTH
;
138 private int fMinNameWidth
= MIN_NAME_WIDTH
;
139 private int fNameWidth
;
140 private int[] fWeights
;
141 private Composite fDataViewer
;
143 private TimeGraphControl fTimeGraphCtrl
;
145 private TimeGraphScale fTimeScaleCtrl
;
146 private TimeGraphMarkerAxis fMarkerAxisCtrl
;
147 private Slider fHorizontalScrollBar
;
148 private Slider fVerticalScrollBar
;
149 private @NonNull TimeGraphColorScheme fColorScheme
= new TimeGraphColorScheme();
150 private Object fInputElement
;
151 private ITimeGraphContentProvider fTimeGraphContentProvider
;
152 private ITimeGraphPresentationProvider fTimeGraphProvider
;
153 private ITableLabelProvider fLabelProvider
;
154 private @NonNull ITimeDataProvider fTimeDataProvider
= this;
155 private TimeGraphTooltipHandler fToolTipHandler
;
157 private List
<ITimeGraphSelectionListener
> fSelectionListeners
= new ArrayList
<>();
158 private List
<ITimeGraphTimeListener
> fTimeListeners
= new ArrayList
<>();
159 private List
<ITimeGraphRangeListener
> fRangeListeners
= new ArrayList
<>();
160 private List
<ITimeGraphBookmarkListener
> fBookmarkListeners
= new ArrayList
<>();
162 // Time format, using Epoch reference, Relative time format(default),
164 private TimeFormat fTimeFormat
= TimeFormat
.RELATIVE
;
165 // Clock frequency to use for Cycles time format
166 private long fClockFrequency
= DEFAULT_FREQUENCY
;
167 private int fBorderWidth
= 0;
168 private int fTimeScaleHeight
= DEFAULT_HEIGHT
;
170 private Action fResetScaleAction
;
171 private Action fShowLegendAction
;
172 private Action fNextEventAction
;
173 private Action fPrevEventAction
;
174 private Action fNextItemAction
;
175 private Action fPreviousItemAction
;
176 private Action fZoomInAction
;
177 private Action fZoomOutAction
;
178 private Action fHideArrowsAction
;
179 private Action fFollowArrowFwdAction
;
180 private Action fFollowArrowBwdAction
;
181 private ShowFilterDialogAction fShowFilterDialogAction
;
182 private Action fToggleBookmarkAction
;
183 private Action fNextMarkerAction
;
184 private Action fPreviousMarkerAction
;
185 private MenuManager fMarkersMenu
;
187 /** The list of bookmarks */
188 private final List
<IMarkerEvent
> fBookmarks
= new ArrayList
<>();
190 /** The list of marker categories */
191 private final List
<String
> fMarkerCategories
= new ArrayList
<>();
193 /** The set of hidden marker categories */
194 private final Set
<String
> fHiddenMarkerCategories
= new HashSet
<>();
196 /** The set of skipped marker categories */
197 private final Set
<String
> fSkippedMarkerCategories
= new HashSet
<>();
199 /** The list of markers */
200 private final List
<IMarkerEvent
> fMarkers
= new ArrayList
<>();
202 private ListenerNotifier fListenerNotifier
;
204 private Composite fTimeAlignedComposite
;
206 private class ListenerNotifier
extends Thread
{
207 private static final long DELAY
= 400L;
208 private static final long POLLING_INTERVAL
= 10L;
209 private long fLastUpdateTime
= Long
.MAX_VALUE
;
210 private boolean fSelectionChanged
= false;
211 private boolean fTimeRangeUpdated
= false;
212 private boolean fTimeSelected
= false;
216 while ((System
.currentTimeMillis() - fLastUpdateTime
) < DELAY
) {
218 Thread
.sleep(POLLING_INTERVAL
);
219 } catch (Exception e
) {
223 Display
.getDefault().asyncExec(new Runnable() {
226 if (fListenerNotifier
!= ListenerNotifier
.this) {
229 fListenerNotifier
= null;
230 if (ListenerNotifier
.this.isInterrupted() || fDataViewer
.isDisposed()) {
233 if (fSelectionChanged
) {
234 fireSelectionChanged(fSelectedEntry
);
236 if (fTimeRangeUpdated
) {
237 fireTimeRangeUpdated(fTime0
, fTime1
);
240 fireTimeSelected(fSelectionBegin
, fSelectionEnd
);
246 public void selectionChanged() {
247 fSelectionChanged
= true;
248 fLastUpdateTime
= System
.currentTimeMillis();
251 public void timeRangeUpdated() {
252 fTimeRangeUpdated
= true;
253 fLastUpdateTime
= System
.currentTimeMillis();
256 public void timeSelected() {
257 fTimeSelected
= true;
258 fLastUpdateTime
= System
.currentTimeMillis();
261 public boolean hasSelectionChanged() {
262 return fSelectionChanged
;
265 public boolean hasTimeRangeUpdated() {
266 return fTimeRangeUpdated
;
269 public boolean hasTimeSelected() {
270 return fTimeSelected
;
274 private final static class MarkerComparator
implements Comparator
<IMarkerEvent
> {
276 public int compare(IMarkerEvent o1
, IMarkerEvent o2
) {
277 int res
= Long
.compare(o1
.getTime(), o2
.getTime());
281 return Long
.compare(o1
.getDuration(), o2
.getDuration());
286 * Standard constructor.
288 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
291 * The parent UI composite object
295 public TimeGraphViewer(Composite parent
, int style
) {
296 createDataViewer(parent
, style
);
297 fTimeGraphContentProvider
= new TimeGraphContentProvider();
301 * Sets the timegraph content provider used by this timegraph viewer.
303 * @param timeGraphContentProvider
304 * the timegraph content provider
306 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
) {
307 fTimeGraphContentProvider
= timeGraphContentProvider
;
311 * Gets the timegraph content provider used by this timegraph viewer.
313 * @return the timegraph content provider
315 public ITimeGraphContentProvider
getTimeGraphContentProvider() {
316 return fTimeGraphContentProvider
;
320 * Sets the timegraph presentation provider used by this timegraph viewer.
322 * @param timeGraphProvider
323 * the timegraph provider
325 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider
) {
326 fTimeGraphProvider
= timeGraphProvider
;
327 fTimeGraphCtrl
.setTimeGraphProvider(timeGraphProvider
);
328 fToolTipHandler
= new TimeGraphTooltipHandler(fTimeGraphProvider
, fTimeDataProvider
);
329 fToolTipHandler
.activateHoverHelp(fTimeGraphCtrl
);
333 * Sets the tree label provider used for the name space
335 * @param labelProvider the tree label provider
338 public void setTimeGraphLabelProvider(ITableLabelProvider labelProvider
) {
339 fLabelProvider
= labelProvider
;
340 if (fTimeGraphCtrl
!= null) {
341 fTimeGraphCtrl
.setLabelProvider(labelProvider
);
346 * Sets the tree columns for this time graph combo's filter dialog.
348 * @param columnNames the tree column names
351 public void setFilterColumns(String
[] columnNames
) {
352 getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames
);
356 * Sets the tree content provider used by the filter dialog
358 * @param contentProvider the tree content provider
361 public void setFilterContentProvider(ITreeContentProvider contentProvider
) {
362 getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider
);
366 * Sets the tree label provider used by the filter dialog
368 * @param labelProvider the tree label provider
371 public void setFilterLabelProvider(ITableLabelProvider labelProvider
) {
372 getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider
);
376 public void setInput(Object inputElement
) {
377 Object oldInput
= fInputElement
;
378 fTimeGraphContentProvider
.inputChanged(this, oldInput
, inputElement
);
379 fInputElement
= inputElement
;
380 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(inputElement
);
381 fListenerNotifier
= null;
382 if (fTimeGraphCtrl
!= null) {
385 fSelectionBegin
= SWT
.DEFAULT
;
386 fSelectionEnd
= SWT
.DEFAULT
;
387 updateMarkerActions();
388 fSelectedEntry
= null;
389 refreshAllData(input
);
394 public Object
getInput() {
395 return fInputElement
;
399 * Sets (or clears if null) the list of links to display on this combo
402 * the links to display in this time graph combo
404 public void setLinks(List
<ILinkEvent
> links
) {
405 if (fTimeGraphCtrl
!= null) {
406 fTimeGraphCtrl
.refreshArrows(links
);
411 public void refresh() {
412 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(fInputElement
);
414 refreshAllData(input
);
418 * Callback for when the control is moved
423 public void controlMoved(ControlEvent e
) {
427 * Callback for when the control is resized
432 public void controlResized(ControlEvent e
) {
437 * @return The string representing the view type
439 protected String
getViewTypeStr() {
440 return "viewoption.threads"; //$NON-NLS-1$
443 int getMarginWidth() {
447 int getMarginHeight() {
452 fMinTimeInterval
= 1;
453 fSelectionBegin
= SWT
.DEFAULT
;
454 fSelectionEnd
= SWT
.DEFAULT
;
455 fNameWidth
= Utils
.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
456 fNameWidthPref
, fMinNameWidth
, MAX_NAME_WIDTH
);
460 Utils
.saveIntOption(getPreferenceString("namewidth"), fNameWidth
); //$NON-NLS-1$
464 * Create a data viewer.
470 * @return The new data viewer
472 protected Control
createDataViewer(Composite parent
, int style
) {
474 fDataViewer
= new Composite(parent
, style
) {
476 public void redraw() {
478 fTimeScaleCtrl
.redraw();
479 fTimeGraphCtrl
.redraw();
480 fMarkerAxisCtrl
.redraw();
484 fDataViewer
.addDisposeListener((e
) -> {
485 if (fMarkersMenu
!= null) {
486 fMarkersMenu
.dispose();
489 GridLayout gl
= new GridLayout(2, false);
490 gl
.marginHeight
= fBorderWidth
;
492 gl
.verticalSpacing
= 0;
493 gl
.horizontalSpacing
= 0;
494 fDataViewer
.setLayout(gl
);
496 fTimeAlignedComposite
= new Composite(fDataViewer
, style
) {
498 public void redraw() {
499 fDataViewer
.redraw();
503 GridLayout gl2
= new GridLayout(2, false);
504 gl2
.marginHeight
= fBorderWidth
;
506 gl2
.verticalSpacing
= 0;
507 gl2
.horizontalSpacing
= 0;
508 fTimeAlignedComposite
.setLayout(gl2
);
509 fTimeAlignedComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
511 fTree
= new Tree(fTimeAlignedComposite
, SWT
.NO_SCROLL
);
512 GridData gd
= new GridData(SWT
.FILL
, SWT
.FILL
, false, false);
513 gd
.widthHint
= fNameWidth
;
514 fTree
.setLayoutData(gd
);
515 fTree
.setHeaderVisible(true);
516 // add a default column
517 TreeColumn column
= new TreeColumn(fTree
, SWT
.LEFT
);
518 column
.setResizable(false);
521 * Bug in Linux. The tree header height is 0 in constructor, so we need
522 * to reset it later when the control is painted. This work around used
523 * to be done on control resized but the header height was not
524 * initialized on the initial resize on GTK3.
526 fTree
.addPaintListener(new PaintListener() {
528 public void paintControl(PaintEvent e
) {
529 int headerHeight
= fTree
.getHeaderHeight();
530 if (headerHeight
> 0) {
531 fTree
.removePaintListener(this);
532 setHeaderHeight(headerHeight
);
537 fTimeScaleCtrl
= new TimeGraphScale(fTimeAlignedComposite
, fColorScheme
);
538 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
539 fTimeScaleCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
540 fTimeScaleCtrl
.setHeight(fTimeScaleHeight
);
541 fTimeScaleCtrl
.addMouseWheelListener(new MouseWheelListener() {
543 public void mouseScrolled(MouseEvent e
) {
547 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
548 fTimeGraphCtrl
.zoom(e
.count
> 0);
550 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
555 fTimeGraphCtrl
= createTimeGraphControl(fTimeAlignedComposite
, fColorScheme
);
557 fTimeGraphCtrl
.setTimeProvider(this);
558 fTimeGraphCtrl
.setLabelProvider(fLabelProvider
);
559 fTimeGraphCtrl
.setTree(fTree
);
560 fTimeGraphCtrl
.setTimeGraphScale(fTimeScaleCtrl
);
561 fTimeGraphCtrl
.addSelectionListener(this);
562 fTimeGraphCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true, 2, 1));
563 fTimeGraphCtrl
.addMouseWheelListener(new MouseWheelListener() {
565 public void mouseScrolled(MouseEvent e
) {
570 * On some platforms the mouse scroll event is sent to the
571 * control that has focus even if it is not under the cursor.
572 * Handle the event only if not over the time graph control.
574 Point ctrlParentCoords
= fTimeAlignedComposite
.toControl(fTimeGraphCtrl
.toDisplay(e
.x
, e
.y
));
575 Point scrollBarParentCoords
= fDataViewer
.toControl(fTimeGraphCtrl
.toDisplay(e
.x
, e
.y
));
576 if (fTimeGraphCtrl
.getBounds().contains(ctrlParentCoords
)) {
577 /* the time graph control handles the event */
578 adjustVerticalScrollBar();
579 } else if (fTimeScaleCtrl
.getBounds().contains(ctrlParentCoords
)
580 || fMarkerAxisCtrl
.getBounds().contains(ctrlParentCoords
)
581 || fHorizontalScrollBar
.getBounds().contains(scrollBarParentCoords
)) {
582 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
583 fTimeGraphCtrl
.zoom(e
.count
> 0);
585 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
588 /* over the vertical scroll bar or outside of the viewer */
589 setTopIndex(getTopIndex() - e
.count
);
593 fTimeGraphCtrl
.addKeyListener(new KeyAdapter() {
595 public void keyPressed(KeyEvent e
) {
596 if (e
.keyCode
== '.') {
597 boolean extend
= (e
.stateMask
& SWT
.SHIFT
) != 0;
599 extendToNextMarker();
603 } else if (e
.keyCode
== ',') {
604 boolean extend
= (e
.stateMask
& SWT
.SHIFT
) != 0;
606 extendToPrevMarker();
611 adjustVerticalScrollBar();
615 fMarkerAxisCtrl
= createTimeGraphMarkerAxis(fTimeAlignedComposite
, fColorScheme
, this);
616 fMarkerAxisCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false, 2, 1));
617 fMarkerAxisCtrl
.addMarkerAxisListener(this);
618 fMarkerAxisCtrl
.addMouseWheelListener(new MouseWheelListener() {
620 public void mouseScrolled(MouseEvent e
) {
624 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
625 fTimeGraphCtrl
.zoom(e
.count
> 0);
627 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
632 fVerticalScrollBar
= new Slider(fDataViewer
, SWT
.VERTICAL
| SWT
.NO_FOCUS
);
633 fVerticalScrollBar
.setLayoutData(new GridData(SWT
.DEFAULT
, SWT
.FILL
, false, true, 1, 1));
634 fVerticalScrollBar
.addSelectionListener(new SelectionAdapter() {
636 public void widgetSelected(SelectionEvent e
) {
637 setTopIndex(fVerticalScrollBar
.getSelection());
641 fHorizontalScrollBar
= new Slider(fDataViewer
, SWT
.HORIZONTAL
| SWT
.NO_FOCUS
);
642 fHorizontalScrollBar
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
643 fHorizontalScrollBar
.addListener(SWT
.MouseWheel
, new Listener() {
645 public void handleEvent(Event event
) {
646 // don't handle the immediately following SWT.Selection event
648 if (event
.count
== 0) {
651 if ((event
.stateMask
& SWT
.CTRL
) != 0) {
652 fTimeGraphCtrl
.zoom(event
.count
> 0);
654 fTimeGraphCtrl
.horizontalScroll(event
.count
> 0);
658 fHorizontalScrollBar
.addListener(SWT
.Selection
, new Listener() {
660 public void handleEvent(Event event
) {
661 int start
= fHorizontalScrollBar
.getSelection();
662 long time0
= getTime0();
663 long time1
= getTime1();
664 long timeMin
= getMinTime();
665 long timeMax
= getMaxTime();
666 long delta
= timeMax
- timeMin
;
668 long range
= time1
- time0
;
669 time0
= timeMin
+ Math
.round(delta
* ((double) start
/ H_SCROLLBAR_MAX
));
670 time1
= time0
+ range
;
672 setStartFinishTimeNotify(time0
, time1
);
676 Composite filler
= new Composite(fDataViewer
, SWT
.NONE
);
677 gd
= new GridData(SWT
.DEFAULT
, SWT
.DEFAULT
, false, false);
678 gd
.heightHint
= fHorizontalScrollBar
.getSize().y
;
679 filler
.setLayoutData(gd
);
680 filler
.setLayout(new FillLayout());
682 fTimeGraphCtrl
.addControlListener(new ControlAdapter() {
684 public void controlResized(ControlEvent event
) {
689 fDataViewer
.update();
690 adjustHorizontalScrollBar();
691 adjustVerticalScrollBar();
693 fDataViewer
.addDisposeListener((e
) -> {
695 fColorScheme
.dispose();
702 * Dispose the time graph viewer.
704 public void dispose() {
705 fDataViewer
.dispose();
709 * Create a new time graph control.
712 * The parent composite
715 * @return The new TimeGraphControl
717 protected TimeGraphControl
createTimeGraphControl(Composite parent
,
718 TimeGraphColorScheme colors
) {
719 return new TimeGraphControl(parent
, colors
);
723 * Create a new time graph marker axis.
726 * The parent composite object
728 * The color scheme to use
729 * @param timeProvider
730 * The time data provider
731 * @return The new TimeGraphMarkerAxis
734 protected TimeGraphMarkerAxis
createTimeGraphMarkerAxis(Composite parent
,
735 @NonNull TimeGraphColorScheme colorScheme
, @NonNull ITimeDataProvider timeProvider
) {
736 return new TimeGraphMarkerAxis(parent
, colorScheme
, timeProvider
);
740 * Resize the controls
742 public void resizeControls() {
743 Rectangle r
= fDataViewer
.getClientArea();
748 if (fWeights
!= null) {
749 setWeights(fWeights
);
753 if (fNameWidth
> width
- fMinNameWidth
) {
754 fNameWidth
= width
- fMinNameWidth
;
756 if (fNameWidth
< fMinNameWidth
) {
757 fNameWidth
= fMinNameWidth
;
759 GridData gd
= (GridData
) fTree
.getLayoutData();
760 gd
.widthHint
= fNameWidth
;
761 if (fTree
.getColumnCount() == 1) {
762 fTree
.getColumn(0).setWidth(fNameWidth
);
764 adjustHorizontalScrollBar();
765 adjustVerticalScrollBar();
769 * Recalculate the time bounds based on the time graph entries,
770 * if the user-specified bound is set to SWT.DEFAULT.
773 * The root time graph entries in the model
775 public void setTimeRange(ITimeGraphEntry entries
[]) {
776 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
777 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
778 if (fBeginTime
!= SWT
.DEFAULT
&& fEndTime
!= SWT
.DEFAULT
) {
781 if (entries
== null || entries
.length
== 0) {
784 if (fTime0Bound
== SWT
.DEFAULT
) {
785 fTime0Bound
= Long
.MAX_VALUE
;
787 if (fTime1Bound
== SWT
.DEFAULT
) {
788 fTime1Bound
= Long
.MIN_VALUE
;
790 for (ITimeGraphEntry entry
: entries
) {
793 if (fTime0Bound
> fTime1Bound
) {
794 fTime0Bound
= SWT
.DEFAULT
;
795 fTime1Bound
= SWT
.DEFAULT
;
799 private void setTimeRange(ITimeGraphEntry entry
) {
800 if (fBeginTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getStartTime() != SWT
.DEFAULT
) {
801 fTime0Bound
= Math
.min(entry
.getStartTime(), fTime0Bound
);
803 if (fEndTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getEndTime() != SWT
.DEFAULT
) {
804 fTime1Bound
= Math
.max(entry
.getEndTime(), fTime1Bound
);
806 if (entry
.hasChildren()) {
807 for (ITimeGraphEntry child
: entry
.getChildren()) {
814 * Set the time bounds to the provided values.
817 * The bounds begin time, or SWT.DEFAULT to use the input bounds
819 * The bounds end time, or SWT.DEFAULT to use the input bounds
821 public void setTimeBounds(long beginTime
, long endTime
) {
822 fBeginTime
= beginTime
;
824 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
825 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
826 if (fTime0Bound
> fTime1Bound
) {
827 // only possible if both are not default
828 fBeginTime
= endTime
;
829 fEndTime
= beginTime
;
830 fTime0Bound
= fBeginTime
;
831 fTime1Bound
= fEndTime
;
833 adjustHorizontalScrollBar();
837 * Recalculate the current time window when bounds have changed.
839 public void setTimeBounds() {
840 if (!fTimeRangeFixed
) {
841 fTime0
= fTime0Bound
;
842 fTime1
= fTime1Bound
;
844 fTime0
= Math
.max(fTime0Bound
, Math
.min(fTime0
, fTime1Bound
));
845 fTime1
= Math
.max(fTime0Bound
, Math
.min(fTime1
, fTime1Bound
));
846 if (fTime1
- fTime0
< fMinTimeInterval
) {
847 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
854 private void refreshAllData(ITimeGraphEntry
[] traces
) {
856 if (fSelectionBegin
< fBeginTime
) {
857 fSelectionBegin
= fBeginTime
;
858 } else if (fSelectionBegin
> fEndTime
) {
859 fSelectionBegin
= fEndTime
;
861 if (fSelectionEnd
< fBeginTime
) {
862 fSelectionEnd
= fBeginTime
;
863 } else if (fSelectionEnd
> fEndTime
) {
864 fSelectionEnd
= fEndTime
;
866 fTimeGraphCtrl
.refreshData(traces
);
867 fTimeScaleCtrl
.redraw();
868 fMarkerAxisCtrl
.redraw();
869 updateMarkerActions();
870 adjustVerticalScrollBar();
874 * Callback for when this view is focused
876 public void setFocus() {
877 if (null != fTimeGraphCtrl
) {
878 fTimeGraphCtrl
.setFocus();
883 * Get the current focus status of this view.
885 * @return If the view is currently focused, or not
887 public boolean isInFocus() {
888 return fTimeGraphCtrl
.isInFocus();
892 * Get the view's current selection
894 * @return The entry that is selected
897 public ITimeGraphEntry
getSelection() {
898 return fTimeGraphCtrl
.getSelectedTrace();
902 * Get the index of the current selection
906 public int getSelectionIndex() {
907 return fTimeGraphCtrl
.getSelectedIndex();
911 public long getTime0() {
916 public long getTime1() {
921 public long getMinTimeInterval() {
922 return fMinTimeInterval
;
926 * Sets the relative horizontal weight of each part of the time graph
927 * viewer. The first number is the name space weight, and the second number
928 * is the time space weight.
931 * The array of relative weights of each part of the viewer
934 public void setWeights(final int[] weights
) {
935 if (weights
.length
!= 2) {
938 int width
= fTimeAlignedComposite
.getSize().x
;
940 /* the weigths will be applied when the control is resized */
941 fWeights
= Arrays
.copyOf(weights
, weights
.length
);
944 setNameSpace(width
* weights
[0] / (weights
[0] + weights
[1]));
948 public int getNameSpace() {
953 public void setNameSpace(int width
) {
955 int w
= fTimeGraphCtrl
.getClientArea().width
;
956 if (fNameWidth
> w
- MIN_NAME_WIDTH
) {
957 fNameWidth
= w
- MIN_NAME_WIDTH
;
959 if (fNameWidth
< MIN_NAME_WIDTH
) {
960 fNameWidth
= MIN_NAME_WIDTH
;
962 GridData gd
= (GridData
) fTree
.getLayoutData();
963 gd
.widthHint
= fNameWidth
;
964 if (fTree
.getColumnCount() == 1) {
965 fTree
.getColumn(0).setWidth(fNameWidth
);
967 fTimeAlignedComposite
.layout();
969 fTimeGraphCtrl
.redraw();
970 fTimeScaleCtrl
.redraw();
971 fMarkerAxisCtrl
.redraw();
975 public int getTimeSpace() {
976 int w
= fTimeGraphCtrl
.getClientArea().width
;
977 return w
- fNameWidth
;
981 public long getBeginTime() {
986 public long getEndTime() {
991 public long getMaxTime() {
996 public long getMinTime() {
1001 public long getSelectionBegin() {
1002 return fSelectionBegin
;
1006 public long getSelectionEnd() {
1007 return fSelectionEnd
;
1011 public void setStartFinishTimeNotify(long time0
, long time1
) {
1012 setStartFinishTimeInt(time0
, time1
);
1013 notifyRangeListeners();
1017 public void notifyStartFinishTime() {
1018 notifyRangeListeners();
1022 public void setStartFinishTime(long time0
, long time1
) {
1023 /* if there is a pending time range, ignore this one */
1024 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeRangeUpdated()) {
1027 setStartFinishTimeInt(time0
, time1
);
1028 updateExtSynchValues();
1031 private void setStartFinishTimeInt(long time0
, long time1
) {
1033 if (fTime0
< fTime0Bound
) {
1034 fTime0
= fTime0Bound
;
1036 if (fTime0
> fTime1Bound
) {
1037 fTime0
= fTime1Bound
;
1040 if (fTime1
< fTime0Bound
) {
1041 fTime1
= fTime0Bound
;
1043 if (fTime1
> fTime1Bound
) {
1044 fTime1
= fTime1Bound
;
1046 if (fTime1
- fTime0
< fMinTimeInterval
) {
1047 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
1049 fTimeRangeFixed
= true;
1050 adjustHorizontalScrollBar();
1051 fTimeGraphCtrl
.redraw();
1052 fTimeScaleCtrl
.redraw();
1053 fMarkerAxisCtrl
.redraw();
1057 public void resetStartFinishTime() {
1058 setStartFinishTimeNotify(fTime0Bound
, fTime1Bound
);
1059 fTimeRangeFixed
= false;
1066 public void resetStartFinishTime(boolean notify
) {
1068 setStartFinishTimeNotify(fTime0Bound
, fTime1Bound
);
1070 setStartFinishTime(fTime0Bound
, fTime1Bound
);
1072 fTimeRangeFixed
= false;
1076 public void setSelectedTimeNotify(long time
, boolean ensureVisible
) {
1077 setSelectedTimeInt(time
, ensureVisible
, true);
1081 public void setSelectedTime(long time
, boolean ensureVisible
) {
1082 /* if there is a pending time selection, ignore this one */
1083 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
1086 setSelectedTimeInt(time
, ensureVisible
, false);
1089 private void setSelectedTimeInt(long time
, boolean ensureVisible
, boolean doNotify
) {
1090 setSelectionRangeInt(time
, time
, ensureVisible
, doNotify
);
1097 public void setSelectionRangeNotify(long beginTime
, long endTime
, boolean ensureVisible
) {
1098 setSelectionRangeInt(beginTime
, endTime
, ensureVisible
, true);
1105 public void setSelectionRange(long beginTime
, long endTime
, boolean ensureVisible
) {
1106 /* if there is a pending time selection, ignore this one */
1107 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
1110 setSelectionRangeInt(beginTime
, endTime
, ensureVisible
, false);
1113 private void setSelectionRangeInt(long beginTime
, long endTime
, boolean ensureVisible
, boolean doNotify
) {
1114 long time0
= fTime0
;
1115 long time1
= fTime1
;
1116 long selectionBegin
= fSelectionBegin
;
1117 long selectionEnd
= fSelectionEnd
;
1118 fSelectionBegin
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, beginTime
));
1119 fSelectionEnd
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, endTime
));
1120 boolean changed
= (selectionBegin
!= fSelectionBegin
|| selectionEnd
!= fSelectionEnd
);
1122 if (ensureVisible
) {
1123 ensureVisible(selectionBegin
!= fSelectionBegin ? fSelectionBegin
: fSelectionEnd
);
1126 fTimeGraphCtrl
.redraw();
1127 fTimeScaleCtrl
.redraw();
1128 fMarkerAxisCtrl
.redraw();
1129 updateMarkerActions();
1131 if ((time0
!= fTime0
) || (time1
!= fTime1
)) {
1132 notifyRangeListeners();
1135 if (doNotify
&& changed
) {
1136 notifyTimeListeners();
1140 private void ensureVisible(long time
) {
1141 long timeMid
= (fTime1
- fTime0
) / 2;
1142 if (time
< fTime0
) {
1143 long dt
= fTime0
- time
+ timeMid
;
1146 } else if (time
> fTime1
) {
1147 long dt
= time
- fTime1
+ timeMid
;
1151 if (fTime0
< fTime0Bound
) {
1152 fTime1
= Math
.min(fTime1Bound
, fTime1
+ (fTime0Bound
- fTime0
));
1153 fTime0
= fTime0Bound
;
1154 } else if (fTime1
> fTime1Bound
) {
1155 fTime0
= Math
.max(fTime0Bound
, fTime0
- (fTime1
- fTime1Bound
));
1156 fTime1
= fTime1Bound
;
1158 if (fTime1
- fTime0
< fMinTimeInterval
) {
1159 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
1161 adjustHorizontalScrollBar();
1165 public void widgetDefaultSelected(SelectionEvent e
) {
1166 if (fSelectedEntry
!= getSelection()) {
1167 fSelectedEntry
= getSelection();
1168 notifySelectionListeners();
1173 public void widgetSelected(SelectionEvent e
) {
1174 if (fSelectedEntry
!= getSelection()) {
1175 fSelectedEntry
= getSelection();
1176 notifySelectionListeners();
1181 * Callback for when the next event is selected
1184 * true to extend selection range, false for single selection
1187 public void selectNextEvent(boolean extend
) {
1188 fTimeGraphCtrl
.selectNextEvent(extend
);
1189 adjustVerticalScrollBar();
1193 * Callback for when the previous event is selected
1196 * true to extend selection range, false for single selection
1199 public void selectPrevEvent(boolean extend
) {
1200 fTimeGraphCtrl
.selectPrevEvent(extend
);
1201 adjustVerticalScrollBar();
1205 * Callback for when the next item is selected
1207 public void selectNextItem() {
1208 fTimeGraphCtrl
.selectNextTrace();
1209 adjustVerticalScrollBar();
1213 * Callback for when the previous item is selected
1215 public void selectPrevItem() {
1216 fTimeGraphCtrl
.selectPrevTrace();
1217 adjustVerticalScrollBar();
1221 * Callback for the show legend action
1223 public void showLegend() {
1224 if (fDataViewer
== null || fDataViewer
.isDisposed()) {
1228 TimeGraphLegend
.open(fDataViewer
.getShell(), fTimeGraphProvider
);
1232 * Callback for the Zoom In action
1234 public void zoomIn() {
1235 fTimeGraphCtrl
.zoomIn();
1239 * Callback for the Zoom Out action
1241 public void zoomOut() {
1242 fTimeGraphCtrl
.zoomOut();
1245 private String
getPreferenceString(String string
) {
1246 return getViewTypeStr() + "." + string
; //$NON-NLS-1$
1250 * Add a selection listener
1253 * The listener to add
1255 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
1256 fSelectionListeners
.add(listener
);
1260 * Remove a selection listener
1263 * The listener to remove
1265 public void removeSelectionListener(ITimeGraphSelectionListener listener
) {
1266 fSelectionListeners
.remove(listener
);
1269 private void notifySelectionListeners() {
1270 if (fListenerNotifier
== null) {
1271 fListenerNotifier
= new ListenerNotifier();
1272 fListenerNotifier
.start();
1274 fListenerNotifier
.selectionChanged();
1277 private void fireSelectionChanged(ITimeGraphEntry selection
) {
1278 TimeGraphSelectionEvent event
= new TimeGraphSelectionEvent(this, selection
);
1280 for (ITimeGraphSelectionListener listener
: fSelectionListeners
) {
1281 listener
.selectionChanged(event
);
1284 ISelection structuredSelection
= (selection
== null) ? StructuredSelection
.EMPTY
: new StructuredSelection(selection
);
1285 fireSelectionChanged(new SelectionChangedEvent(this, structuredSelection
));
1289 * Add a time listener
1292 * The listener to add
1294 public void addTimeListener(ITimeGraphTimeListener listener
) {
1295 fTimeListeners
.add(listener
);
1299 * Remove a time listener
1302 * The listener to remove
1304 public void removeTimeListener(ITimeGraphTimeListener listener
) {
1305 fTimeListeners
.remove(listener
);
1308 private void notifyTimeListeners() {
1309 if (fListenerNotifier
== null) {
1310 fListenerNotifier
= new ListenerNotifier();
1311 fListenerNotifier
.start();
1313 fListenerNotifier
.timeSelected();
1316 private void fireTimeSelected(long startTime
, long endTime
) {
1317 TimeGraphTimeEvent event
= new TimeGraphTimeEvent(this, startTime
, endTime
);
1319 for (ITimeGraphTimeListener listener
: fTimeListeners
) {
1320 listener
.timeSelected(event
);
1325 * Add a range listener
1328 * The listener to add
1330 public void addRangeListener(ITimeGraphRangeListener listener
) {
1331 fRangeListeners
.add(listener
);
1335 * Remove a range listener
1338 * The listener to remove
1340 public void removeRangeListener(ITimeGraphRangeListener listener
) {
1341 fRangeListeners
.remove(listener
);
1344 private void notifyRangeListeners() {
1345 if (fListenerNotifier
== null) {
1346 fListenerNotifier
= new ListenerNotifier();
1347 fListenerNotifier
.start();
1349 fListenerNotifier
.timeRangeUpdated();
1352 private void fireTimeRangeUpdated(long startTime
, long endTime
) {
1353 // Check if the time has actually changed from last notification
1354 if (startTime
!= fTime0ExtSynch
|| endTime
!= fTime1ExtSynch
) {
1355 // Notify Time Scale Selection Listeners
1356 TimeGraphRangeUpdateEvent event
= new TimeGraphRangeUpdateEvent(this, startTime
, endTime
);
1358 for (ITimeGraphRangeListener listener
: fRangeListeners
) {
1359 listener
.timeRangeUpdated(event
);
1362 // update external synch values
1363 updateExtSynchValues();
1368 * Add a bookmark listener
1371 * The listener to add
1374 public void addBookmarkListener(ITimeGraphBookmarkListener listener
) {
1375 fBookmarkListeners
.add(listener
);
1379 * Remove a bookmark listener
1382 * The listener to remove
1385 public void removeBookmarkListener(ITimeGraphBookmarkListener listener
) {
1386 fBookmarkListeners
.remove(listener
);
1389 private void fireBookmarkAdded(IMarkerEvent bookmark
) {
1390 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1392 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1393 listener
.bookmarkAdded(event
);
1397 private void fireBookmarkRemoved(IMarkerEvent bookmark
) {
1398 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1400 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1401 listener
.bookmarkRemoved(event
);
1406 * Set the bookmarks list.
1409 * The bookmarks list, or null
1412 public void setBookmarks(List
<IMarkerEvent
> bookmarks
) {
1414 if (bookmarks
!= null) {
1415 fBookmarks
.addAll(bookmarks
);
1418 updateMarkerActions();
1422 * Get the bookmarks list.
1424 * @return The bookmarks list
1427 public List
<IMarkerEvent
> getBookmarks() {
1428 return Collections
.unmodifiableList(fBookmarks
);
1432 * Set the list of marker categories.
1435 * The list of marker categories, or null
1438 public void setMarkerCategories(List
<String
> categories
) {
1439 fMarkerCategories
.clear();
1440 if (categories
!= null) {
1441 fMarkerCategories
.addAll(categories
);
1443 fMarkerCategories
.add(IMarkerEvent
.BOOKMARKS
);
1444 fMarkerAxisCtrl
.setMarkerCategories(fMarkerCategories
);
1451 public void setMarkerCategoryVisible(String category
, boolean visible
) {
1452 boolean changed
= false;
1454 changed
= fHiddenMarkerCategories
.remove(category
);
1456 changed
= fHiddenMarkerCategories
.add(category
);
1460 updateMarkerActions();
1461 getControl().redraw();
1466 * Set the markers list.
1469 * The markers list, or null
1472 public void setMarkers(List
<IMarkerEvent
> markers
) {
1474 if (markers
!= null) {
1475 fMarkers
.addAll(markers
);
1478 updateMarkerActions();
1482 * Get the markers list.
1484 * @return The markers list, or null
1487 public List
<IMarkerEvent
> getMarkers() {
1488 return Collections
.unmodifiableList(fMarkers
);
1492 * Callback to set a selected event in the view
1495 * The event that was selected
1497 * The source of this selection event
1499 public void setSelectedEvent(ITimeEvent event
, Object source
) {
1500 if (event
== null || source
== this) {
1503 fSelectedEntry
= event
.getEntry();
1504 fTimeGraphCtrl
.selectItem(fSelectedEntry
, false);
1506 setSelectedTimeInt(event
.getTime(), true, true);
1507 adjustVerticalScrollBar();
1511 * Set the seeked time of a trace
1514 * The trace that was seeked
1518 * The source of this seek event
1520 public void setSelectedTraceTime(ITimeGraphEntry trace
, long time
, Object source
) {
1521 if (trace
== null || source
== this) {
1524 fSelectedEntry
= trace
;
1525 fTimeGraphCtrl
.selectItem(trace
, false);
1527 setSelectedTimeInt(time
, true, true);
1531 * Sets a new selection for this viewer and makes it visible.
1534 * The entry to select
1535 * @deprecated Use {@link #setSelection(ISelection, boolean)} instead.
1538 public void setSelection(ITimeGraphEntry entry
) {
1539 setSelection(entry
, true);
1543 public void setSelection(ISelection selection
, boolean reveal
) {
1544 /* if there is a pending selection, ignore this one */
1545 if (fListenerNotifier
!= null && fListenerNotifier
.hasSelectionChanged()) {
1548 Object element
= selection
;
1549 if (selection
instanceof IStructuredSelection
) {
1550 element
= ((IStructuredSelection
) selection
).getFirstElement();
1552 if (!(element
instanceof ITimeGraphEntry
)) {
1555 ITimeGraphEntry entry
= (ITimeGraphEntry
) element
;
1556 fSelectedEntry
= entry
;
1557 fTimeGraphCtrl
.selectItem(entry
, false, reveal
);
1558 adjustVerticalScrollBar();
1562 * Callback for a time window selection
1565 * Start time of the range
1567 * End time of the range
1569 * Source of the event
1571 public void setSelectVisTimeWindow(long time0
, long time1
, Object source
) {
1572 if (source
== this) {
1576 setStartFinishTimeInt(time0
, time1
);
1578 // update notification time values since we are now in synch with the
1579 // external application
1580 updateExtSynchValues();
1584 * update the cache values used to identify the need to send a time window
1585 * update to external registered listeners
1587 private void updateExtSynchValues() {
1588 // last time notification cache
1589 fTime0ExtSynch
= fTime0
;
1590 fTime1ExtSynch
= fTime1
;
1594 public TimeFormat
getTimeFormat() {
1600 * the {@link TimeFormat} used to display timestamps
1602 public void setTimeFormat(TimeFormat tf
) {
1603 this.fTimeFormat
= tf
;
1604 if (tf
== TimeFormat
.CYCLES
) {
1605 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1607 fTimeDataProvider
= this;
1609 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1610 if (fToolTipHandler
!= null) {
1611 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1616 * Sets the clock frequency. Used when the time format is set to CYCLES.
1618 * @param clockFrequency
1619 * the clock frequency in Hz
1621 public void setClockFrequency(long clockFrequency
) {
1622 fClockFrequency
= clockFrequency
;
1623 if (fTimeFormat
== TimeFormat
.CYCLES
) {
1624 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1625 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1626 if (fToolTipHandler
!= null) {
1627 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1633 * Retrieve the border width
1637 public int getBorderWidth() {
1638 return fBorderWidth
;
1642 * Set the border width
1644 * @param borderWidth
1647 public void setBorderWidth(int borderWidth
) {
1648 if (borderWidth
> -1) {
1649 this.fBorderWidth
= borderWidth
;
1650 GridLayout gl
= (GridLayout
) fDataViewer
.getLayout();
1651 gl
.marginHeight
= borderWidth
;
1656 * Retrieve the height of the header
1658 * @return The height
1660 public int getHeaderHeight() {
1661 return fTimeScaleHeight
;
1665 * Set the height of the header
1667 * @param headerHeight
1670 public void setHeaderHeight(int headerHeight
) {
1671 if (headerHeight
> -1) {
1672 this.fTimeScaleHeight
= headerHeight
;
1673 fTimeScaleCtrl
.setHeight(headerHeight
);
1678 * Retrieve the height of an item row
1680 * @return The height
1682 public int getItemHeight() {
1683 if (fTimeGraphCtrl
!= null) {
1684 return fTimeGraphCtrl
.getItemHeight();
1690 * Set the height of an item row
1695 public void setItemHeight(int rowHeight
) {
1696 if (fTimeGraphCtrl
!= null) {
1697 fTimeGraphCtrl
.setItemHeight(rowHeight
);
1702 * Set the minimum item width
1707 public void setMinimumItemWidth(int width
) {
1708 if (fTimeGraphCtrl
!= null) {
1709 fTimeGraphCtrl
.setMinimumItemWidth(width
);
1714 * Set the width for the name column
1719 public void setNameWidthPref(int width
) {
1720 fNameWidthPref
= width
;
1728 * Retrieve the configure width for the name column
1734 public int getNameWidthPref(int width
) {
1735 return fNameWidthPref
;
1739 public Control
getControl() {
1744 * Returns the time graph control associated with this viewer.
1746 * @return the time graph control
1748 public TimeGraphControl
getTimeGraphControl() {
1749 return fTimeGraphCtrl
;
1753 * Returns the tree control associated with this viewer. The tree is only
1754 * used for column handling of the name space and contains no tree items.
1756 * @return the tree control
1759 public Tree
getTree() {
1764 * Sets the columns for this time graph viewer's name space.
1766 * @param columnNames
1770 public void setColumns(String
[] columnNames
) {
1771 fTimeGraphCtrl
.setColumns(columnNames
);
1775 * Returns the time graph scale associated with this viewer.
1777 * @return the time graph scale
1779 public TimeGraphScale
getTimeGraphScale() {
1780 return fTimeScaleCtrl
;
1784 * Returns the composite containing all the controls that are time aligned,
1785 * i.e. TimeGraphScale, TimeGraphControl.
1787 * @return the time based composite
1790 public Composite
getTimeAlignedComposite() {
1791 return fTimeAlignedComposite
;
1795 * Return the x coordinate corresponding to a time
1799 * @return the x coordinate corresponding to the time
1801 public int getXForTime(long time
) {
1802 return fTimeGraphCtrl
.getXForTime(time
);
1806 * Return the time corresponding to an x coordinate
1810 * @return the time corresponding to the x coordinate
1812 public long getTimeAtX(int x
) {
1813 return fTimeGraphCtrl
.getTimeAtX(x
);
1817 * Get the selection provider
1819 * @return the selection provider
1821 public ISelectionProvider
getSelectionProvider() {
1822 return fTimeGraphCtrl
;
1826 * Wait for the cursor
1829 * Wait indefinitely?
1831 public void waitCursor(boolean waitInd
) {
1832 fTimeGraphCtrl
.waitCursor(waitInd
);
1836 * Get the horizontal scroll bar object
1838 * @return The scroll bar
1840 public Slider
getHorizontalBar() {
1841 return fHorizontalScrollBar
;
1845 * Get the vertical scroll bar object
1847 * @return The scroll bar
1849 public Slider
getVerticalBar() {
1850 return fVerticalScrollBar
;
1854 * Set the given index as the top one
1857 * The index that will go to the top
1859 public void setTopIndex(int index
) {
1860 fTimeGraphCtrl
.setTopIndex(index
);
1861 adjustVerticalScrollBar();
1865 * Retrieve the current top index
1867 * @return The top index
1869 public int getTopIndex() {
1870 return fTimeGraphCtrl
.getTopIndex();
1874 * Sets the auto-expand level to be used for new entries discovered when
1875 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1876 * means that there is no auto-expand; 1 means that top-level entries are
1877 * expanded, but not their children; 2 means that top-level entries are
1878 * expanded, and their children, but not grand-children; and so on.
1880 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1884 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1885 * levels of the tree
1887 public void setAutoExpandLevel(int level
) {
1888 fTimeGraphCtrl
.setAutoExpandLevel(level
);
1892 * Returns the auto-expand level.
1894 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1895 * the tree are expanded automatically
1896 * @see #setAutoExpandLevel
1898 public int getAutoExpandLevel() {
1899 return fTimeGraphCtrl
.getAutoExpandLevel();
1903 * Get the expanded state of an entry.
1907 * @return true if the entry is expanded, false if collapsed
1910 public boolean getExpandedState(ITimeGraphEntry entry
) {
1911 return fTimeGraphCtrl
.getExpandedState(entry
);
1915 * Set the expanded state of an entry
1918 * The entry to expand/collapse
1920 * True for expanded, false for collapsed
1922 public void setExpandedState(ITimeGraphEntry entry
, boolean expanded
) {
1923 fTimeGraphCtrl
.setExpandedState(entry
, expanded
);
1924 adjustVerticalScrollBar();
1928 * Collapses all nodes of the viewer's tree, starting with the root.
1930 public void collapseAll() {
1931 fTimeGraphCtrl
.collapseAll();
1932 adjustVerticalScrollBar();
1936 * Expands all entries of the viewer's tree, starting with the root.
1938 public void expandAll() {
1939 fTimeGraphCtrl
.expandAll();
1940 adjustVerticalScrollBar();
1944 * Select an entry and reveal it
1947 * The entry to select
1950 public void selectAndReveal(@NonNull ITimeGraphEntry entry
) {
1951 final ITimeGraphEntry parent
= entry
.getParent();
1952 if (parent
!= null) {
1953 fTimeGraphCtrl
.setExpandedState(parent
, true);
1955 fSelectedEntry
= entry
;
1956 fTimeGraphCtrl
.selectItem(entry
, false);
1957 adjustVerticalScrollBar();
1961 * Get the number of expanded (visible) time graph entries. This includes
1962 * leafs and does not include filtered-out entries.
1964 * @return The number of expanded (visible) time graph entries
1966 public int getExpandedElementCount() {
1967 return fTimeGraphCtrl
.getExpandedElementCount();
1971 * Get the expanded (visible) time graph entries. This includes leafs and
1972 * does not include filtered-out entries.
1974 * @return The array of expanded (visible) time graph entries
1976 public ITimeGraphEntry
[] getExpandedElements() {
1977 return fTimeGraphCtrl
.getExpandedElements();
1981 * Add a tree listener
1984 * The listener to add
1986 public void addTreeListener(ITimeGraphTreeListener listener
) {
1987 fTimeGraphCtrl
.addTreeListener(listener
);
1991 * Remove a tree listener
1994 * The listener to remove
1996 public void removeTreeListener(ITimeGraphTreeListener listener
) {
1997 fTimeGraphCtrl
.removeTreeListener(listener
);
2001 * Get the reset scale action.
2003 * @return The Action object
2005 public Action
getResetScaleAction() {
2006 if (fResetScaleAction
== null) {
2008 fResetScaleAction
= new Action() {
2011 resetStartFinishTime();
2014 fResetScaleAction
.setText(Messages
.TmfTimeGraphViewer_ResetScaleActionNameText
);
2015 fResetScaleAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ResetScaleActionToolTipText
);
2016 fResetScaleAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HOME_MENU
));
2018 return fResetScaleAction
;
2022 * Get the show legend action.
2024 * @return The Action object
2026 public Action
getShowLegendAction() {
2027 if (fShowLegendAction
== null) {
2029 fShowLegendAction
= new Action() {
2035 fShowLegendAction
.setText(Messages
.TmfTimeGraphViewer_LegendActionNameText
);
2036 fShowLegendAction
.setToolTipText(Messages
.TmfTimeGraphViewer_LegendActionToolTipText
);
2037 fShowLegendAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_LEGEND
));
2040 return fShowLegendAction
;
2044 * Get the the next event action.
2046 * @return The action object
2048 public Action
getNextEventAction() {
2049 if (fNextEventAction
== null) {
2050 fNextEventAction
= new Action() {
2052 public void runWithEvent(Event event
) {
2053 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2054 selectNextEvent(extend
);
2058 fNextEventAction
.setText(Messages
.TmfTimeGraphViewer_NextStateChangeActionNameText
);
2059 fNextEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextStateChangeActionToolTipText
);
2060 fNextEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_STATE_CHANGE
));
2063 return fNextEventAction
;
2067 * Get the previous event action.
2069 * @return The Action object
2071 public Action
getPreviousEventAction() {
2072 if (fPrevEventAction
== null) {
2073 fPrevEventAction
= new Action() {
2075 public void runWithEvent(Event event
) {
2076 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2077 selectPrevEvent(extend
);
2081 fPrevEventAction
.setText(Messages
.TmfTimeGraphViewer_PreviousStateChangeActionNameText
);
2082 fPrevEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousStateChangeActionToolTipText
);
2083 fPrevEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_STATE_CHANGE
));
2086 return fPrevEventAction
;
2090 * Get the next item action.
2092 * @return The Action object
2094 public Action
getNextItemAction() {
2095 if (fNextItemAction
== null) {
2097 fNextItemAction
= new Action() {
2103 fNextItemAction
.setText(Messages
.TmfTimeGraphViewer_NextItemActionNameText
);
2104 fNextItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextItemActionToolTipText
);
2105 fNextItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_ITEM
));
2107 return fNextItemAction
;
2111 * Get the previous item action.
2113 * @return The Action object
2115 public Action
getPreviousItemAction() {
2116 if (fPreviousItemAction
== null) {
2118 fPreviousItemAction
= new Action() {
2124 fPreviousItemAction
.setText(Messages
.TmfTimeGraphViewer_PreviousItemActionNameText
);
2125 fPreviousItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousItemActionToolTipText
);
2126 fPreviousItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_ITEM
));
2128 return fPreviousItemAction
;
2132 * Get the zoom in action
2134 * @return The Action object
2136 public Action
getZoomInAction() {
2137 if (fZoomInAction
== null) {
2138 fZoomInAction
= new Action() {
2144 fZoomInAction
.setText(Messages
.TmfTimeGraphViewer_ZoomInActionNameText
);
2145 fZoomInAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomInActionToolTipText
);
2146 fZoomInAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_IN_MENU
));
2148 return fZoomInAction
;
2152 * Get the zoom out action
2154 * @return The Action object
2156 public Action
getZoomOutAction() {
2157 if (fZoomOutAction
== null) {
2158 fZoomOutAction
= new Action() {
2164 fZoomOutAction
.setText(Messages
.TmfTimeGraphViewer_ZoomOutActionNameText
);
2165 fZoomOutAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomOutActionToolTipText
);
2166 fZoomOutAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_OUT_MENU
));
2168 return fZoomOutAction
;
2172 * Get the hide arrows action
2174 * @param dialogSettings
2175 * The dialog settings section where the state should be stored,
2178 * @return The Action object
2180 public Action
getHideArrowsAction(final IDialogSettings dialogSettings
) {
2181 if (fHideArrowsAction
== null) {
2182 fHideArrowsAction
= new Action(Messages
.TmfTimeGraphViewer_HideArrowsActionNameText
, IAction
.AS_CHECK_BOX
) {
2185 boolean hideArrows
= fHideArrowsAction
.isChecked();
2186 fTimeGraphCtrl
.hideArrows(hideArrows
);
2188 if (dialogSettings
!= null) {
2189 dialogSettings
.put(HIDE_ARROWS_KEY
, hideArrows
);
2191 if (fFollowArrowFwdAction
!= null) {
2192 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
2194 if (fFollowArrowBwdAction
!= null) {
2195 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
2199 fHideArrowsAction
.setToolTipText(Messages
.TmfTimeGraphViewer_HideArrowsActionToolTipText
);
2200 fHideArrowsAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HIDE_ARROWS
));
2201 if (dialogSettings
!= null) {
2202 boolean hideArrows
= dialogSettings
.getBoolean(HIDE_ARROWS_KEY
);
2203 fTimeGraphCtrl
.hideArrows(hideArrows
);
2204 fHideArrowsAction
.setChecked(hideArrows
);
2205 if (fFollowArrowFwdAction
!= null) {
2206 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
2208 if (fFollowArrowBwdAction
!= null) {
2209 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
2213 return fHideArrowsAction
;
2217 * Get the follow arrow forward action.
2219 * @return The Action object
2221 public Action
getFollowArrowFwdAction() {
2222 if (fFollowArrowFwdAction
== null) {
2223 fFollowArrowFwdAction
= new Action() {
2225 public void runWithEvent(Event event
) {
2226 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2227 fTimeGraphCtrl
.followArrowFwd(extend
);
2228 adjustVerticalScrollBar();
2231 fFollowArrowFwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionNameText
);
2232 fFollowArrowFwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText
);
2233 fFollowArrowFwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_FORWARD
));
2234 if (fHideArrowsAction
!= null) {
2235 fFollowArrowFwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2238 return fFollowArrowFwdAction
;
2242 * Get the follow arrow backward action.
2244 * @return The Action object
2246 public Action
getFollowArrowBwdAction() {
2247 if (fFollowArrowBwdAction
== null) {
2248 fFollowArrowBwdAction
= new Action() {
2250 public void runWithEvent(Event event
) {
2251 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2252 fTimeGraphCtrl
.followArrowBwd(extend
);
2253 adjustVerticalScrollBar();
2256 fFollowArrowBwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionNameText
);
2257 fFollowArrowBwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText
);
2258 fFollowArrowBwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_BACKWARD
));
2259 if (fHideArrowsAction
!= null) {
2260 fFollowArrowBwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2263 return fFollowArrowBwdAction
;
2267 * Get the show filter dialog action.
2269 * @return The Action object
2272 public ShowFilterDialogAction
getShowFilterDialogAction() {
2273 if (fShowFilterDialogAction
== null) {
2274 fShowFilterDialogAction
= new ShowFilterDialogAction(this);
2276 return fShowFilterDialogAction
;
2280 * Get the toggle bookmark action.
2282 * @return The Action object
2285 public Action
getToggleBookmarkAction() {
2286 if (fToggleBookmarkAction
== null) {
2287 fToggleBookmarkAction
= new Action() {
2289 public void runWithEvent(Event event
) {
2290 IMarkerEvent selectedBookmark
= getBookmarkAtSelection();
2291 if (selectedBookmark
== null) {
2292 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2293 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2294 final AddBookmarkDialog dialog
= new AddBookmarkDialog(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell(), null);
2295 if (dialog
.open() == Window
.OK
) {
2296 final String label
= dialog
.getValue();
2297 final RGBA rgba
= dialog
.getColorValue();
2298 IMarkerEvent bookmark
= new MarkerEvent(null, time
, duration
, IMarkerEvent
.BOOKMARKS
, rgba
, label
, true);
2299 fBookmarks
.add(bookmark
);
2301 updateMarkerActions();
2302 getControl().redraw();
2303 fireBookmarkAdded(bookmark
);
2306 fBookmarks
.remove(selectedBookmark
);
2308 updateMarkerActions();
2309 getControl().redraw();
2310 fireBookmarkRemoved(selectedBookmark
);
2314 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2315 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2316 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2318 return fToggleBookmarkAction
;
2322 * Get the next marker action.
2324 * @return The Action object
2327 public Action
getNextMarkerAction() {
2328 if (fNextMarkerAction
== null) {
2329 fNextMarkerAction
= new Action(Messages
.TmfTimeGraphViewer_NextMarkerActionText
, IAction
.AS_DROP_DOWN_MENU
) {
2331 public void runWithEvent(Event event
) {
2332 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2334 extendToNextMarker();
2340 fNextMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextMarkerActionText
);
2341 fNextMarkerAction
.setImageDescriptor(NEXT_BOOKMARK
);
2342 fNextMarkerAction
.setMenuCreator(new IMenuCreator () {
2345 public void dispose() {
2353 public Menu
getMenu(Control parent
) {
2357 menu
= new Menu(parent
);
2358 for (String category
: fMarkerCategories
) {
2359 final Action action
= new Action(category
, IAction
.AS_CHECK_BOX
) {
2361 public void runWithEvent(Event event
) {
2363 fSkippedMarkerCategories
.remove(getText());
2365 fSkippedMarkerCategories
.add(getText());
2367 updateMarkerActions();
2370 action
.setEnabled(!fHiddenMarkerCategories
.contains(category
));
2371 action
.setChecked(action
.isEnabled() && !fSkippedMarkerCategories
.contains(category
));
2372 new ActionContributionItem(action
).fill(menu
, -1);
2378 public Menu
getMenu(Menu parent
) {
2383 return fNextMarkerAction
;
2387 * Get the previous marker action.
2389 * @return The Action object
2392 public Action
getPreviousMarkerAction() {
2393 if (fPreviousMarkerAction
== null) {
2394 fPreviousMarkerAction
= new Action() {
2396 public void runWithEvent(Event event
) {
2397 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2399 extendToPrevMarker();
2405 fPreviousMarkerAction
.setText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2406 fPreviousMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2407 fPreviousMarkerAction
.setImageDescriptor(PREVIOUS_BOOKMARK
);
2409 return fPreviousMarkerAction
;
2413 * Get the show markers menu.
2415 * @return The menu manager object
2418 public MenuManager
getMarkersMenu() {
2419 if (fMarkersMenu
== null) {
2420 fMarkersMenu
= new MenuManager(Messages
.TmfTimeGraphViewer_ShowMarkersMenuText
);
2421 fMarkersMenu
.setRemoveAllWhenShown(true);
2422 fMarkersMenu
.addMenuListener(new IMenuListener() {
2424 public void menuAboutToShow(IMenuManager manager
) {
2425 for (String category
: fMarkerCategories
) {
2426 final Action action
= new Action(category
, IAction
.AS_CHECK_BOX
) {
2428 public void runWithEvent(Event event
) {
2429 setMarkerCategoryVisible(getText(), isChecked());
2432 action
.setChecked(!fHiddenMarkerCategories
.contains(category
));
2433 manager
.add(action
);
2438 return fMarkersMenu
;
2442 * Select the next marker that begins at or after the current selection
2443 * begin time. Markers that begin at the same time are ordered by end time.
2445 private void selectNextMarker() {
2446 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2447 if (markers
== null) {
2450 for (IMarkerEvent marker
: markers
) {
2451 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2452 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2453 if ((marker
.getTime() > time
||
2454 (marker
.getTime() == time
&& marker
.getDuration() > duration
))
2455 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2456 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration(), false);
2457 ensureVisible(marker
.getTime());
2458 notifyRangeListeners();
2459 fTimeGraphCtrl
.updateStatusLine();
2466 * Select the previous marker that begins at or before the current selection
2467 * begin time. Markers that begin at the same time are ordered by end time.
2469 private void selectPrevMarker() {
2470 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2471 if (markers
== null) {
2474 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2475 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2476 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2477 IMarkerEvent marker
= markers
.get(i
);
2478 if ((marker
.getTime() < time
||
2479 (marker
.getTime() == time
&& marker
.getDuration() < duration
))
2480 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2481 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration(), false);
2482 ensureVisible(marker
.getTime());
2483 notifyRangeListeners();
2484 fTimeGraphCtrl
.updateStatusLine();
2491 * Extend the selection to the closest next marker end time.
2493 private void extendToNextMarker() {
2494 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2495 if (markers
== null) {
2498 IMarkerEvent nextMarker
= null;
2499 for (IMarkerEvent marker
: markers
) {
2500 if (marker
.getTime() + marker
.getDuration() > fSelectionEnd
2501 && !fSkippedMarkerCategories
.contains(marker
.getCategory())
2502 && (nextMarker
== null || marker
.getTime() + marker
.getDuration() < nextMarker
.getTime() + nextMarker
.getDuration())) {
2503 nextMarker
= marker
;
2506 if (nextMarker
!= null) {
2507 setSelectionRangeNotify(fSelectionBegin
, nextMarker
.getTime() + nextMarker
.getDuration(), true);
2508 fTimeGraphCtrl
.updateStatusLine();
2513 * Extend the selection to the closest previous marker start time.
2515 private void extendToPrevMarker() {
2516 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2517 if (markers
== null) {
2520 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2521 IMarkerEvent marker
= markers
.get(i
);
2522 if (marker
.getTime() < fSelectionEnd
2523 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2524 setSelectionRangeNotify(fSelectionBegin
, marker
.getTime(), true);
2525 fTimeGraphCtrl
.updateStatusLine();
2531 private IMarkerEvent
getBookmarkAtSelection() {
2532 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2533 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2534 for (IMarkerEvent bookmark
: fBookmarks
) {
2535 if (bookmark
.getTime() == time
&& bookmark
.getDuration() == duration
) {
2542 private void updateMarkerActions() {
2543 boolean enabled
= fTime0Bound
!= SWT
.DEFAULT
|| fTime1Bound
!= SWT
.DEFAULT
;
2544 if (fToggleBookmarkAction
!= null) {
2545 if (getBookmarkAtSelection() != null) {
2546 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2547 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2548 fToggleBookmarkAction
.setImageDescriptor(REMOVE_BOOKMARK
);
2550 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2551 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2552 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2554 fToggleBookmarkAction
.setEnabled(enabled
);
2556 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2557 if (markers
== null) {
2558 markers
= Collections
.emptyList();
2560 if (fPreviousMarkerAction
!= null) {
2561 fPreviousMarkerAction
.setEnabled(enabled
&& !markers
.isEmpty());
2563 if (fNextMarkerAction
!= null) {
2564 fNextMarkerAction
.setEnabled(enabled
&& !markers
.isEmpty());
2568 private void updateMarkerList() {
2569 List
<IMarkerEvent
> markers
= new ArrayList
<>();
2570 for (IMarkerEvent marker
: fMarkers
) {
2571 if (!fHiddenMarkerCategories
.contains(marker
.getCategory())) {
2572 markers
.add(marker
);
2575 if (!fHiddenMarkerCategories
.contains(IMarkerEvent
.BOOKMARKS
)) {
2576 markers
.addAll(fBookmarks
);
2578 Collections
.sort(markers
, new MarkerComparator());
2579 fTimeGraphCtrl
.setMarkers(markers
);
2580 fMarkerAxisCtrl
.setMarkers(markers
);
2583 private void adjustHorizontalScrollBar() {
2584 long time0
= getTime0();
2585 long time1
= getTime1();
2586 long timeMin
= getMinTime();
2587 long timeMax
= getMaxTime();
2588 long delta
= timeMax
- timeMin
;
2590 int thumb
= H_SCROLLBAR_MAX
;
2592 // Thumb size (page size)
2593 thumb
= Math
.max(1, (int) (H_SCROLLBAR_MAX
* ((double) (time1
- time0
) / delta
)));
2594 // At the beginning of visible window
2595 timePos
= (int) (H_SCROLLBAR_MAX
* ((double) (time0
- timeMin
) / delta
));
2597 fHorizontalScrollBar
.setValues(timePos
, 0, H_SCROLLBAR_MAX
, thumb
, Math
.max(1, thumb
/ 2), Math
.max(2, thumb
));
2600 private void adjustVerticalScrollBar() {
2601 int topIndex
= fTimeGraphCtrl
.getTopIndex();
2602 int countPerPage
= fTimeGraphCtrl
.countPerPage();
2603 int expandedElementCount
= fTimeGraphCtrl
.getExpandedElementCount();
2604 if (topIndex
+ countPerPage
> expandedElementCount
) {
2605 fTimeGraphCtrl
.setTopIndex(Math
.max(0, expandedElementCount
- countPerPage
));
2608 int selection
= fTimeGraphCtrl
.getTopIndex();
2610 int max
= Math
.max(1, expandedElementCount
- 1);
2611 int thumb
= Math
.min(max
, Math
.max(1, countPerPage
- 1));
2613 int pageIncrement
= Math
.max(1, countPerPage
);
2614 fVerticalScrollBar
.setValues(selection
, min
, max
, thumb
, increment
, pageIncrement
);
2619 * a {@link MenuDetectListener}
2620 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2622 public void addTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2623 fTimeGraphCtrl
.addTimeGraphEntryMenuListener(listener
);
2628 * a {@link MenuDetectListener}
2629 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2631 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2632 fTimeGraphCtrl
.removeTimeGraphEntryMenuListener(listener
);
2637 * a {@link MenuDetectListener}
2638 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2640 public void addTimeEventMenuListener(MenuDetectListener listener
) {
2641 fTimeGraphCtrl
.addTimeEventMenuListener(listener
);
2646 * a {@link MenuDetectListener}
2647 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2649 public void removeTimeEventMenuListener(MenuDetectListener listener
) {
2650 fTimeGraphCtrl
.removeTimeEventMenuListener(listener
);
2655 * The filter object to be attached to the view
2657 public void addFilter(@NonNull ViewerFilter filter
) {
2658 fTimeGraphCtrl
.addFilter(filter
);
2664 * The filter object to be attached to the view
2666 public void removeFilter(@NonNull ViewerFilter filter
) {
2667 fTimeGraphCtrl
.removeFilter(filter
);
2672 * Returns this viewer's filters.
2674 * @return an array of viewer filters
2677 public @NonNull ViewerFilter
[] getFilters() {
2678 return fTimeGraphCtrl
.getFilters();
2682 * Sets the filters, replacing any previous filters, and triggers
2683 * refiltering of the elements.
2686 * an array of viewer filters, or null
2689 public void setFilters(@NonNull ViewerFilter
[] filters
) {
2690 fTimeGraphCtrl
.setFilters(filters
);
2695 * Return the time alignment information
2697 * @return the time alignment information
2699 * @see ITmfTimeAligned
2703 public TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo() {
2704 return fTimeGraphCtrl
.getTimeViewAlignmentInfo();
2708 * Return the available width for the time-axis.
2710 * @see ITmfTimeAligned
2712 * @param requestedOffset
2713 * the requested offset
2714 * @return the available width for the time-axis
2718 public int getAvailableWidth(int requestedOffset
) {
2719 int totalWidth
= fTimeAlignedComposite
.getSize().x
;
2720 return Math
.min(totalWidth
, Math
.max(0, totalWidth
- requestedOffset
));
2724 * Perform the alignment operation.
2727 * the alignment offset
2729 * the alignment width
2731 * @see ITmfTimeAligned
2735 public void performAlign(int offset
, int width
) {
2736 fTimeGraphCtrl
.performAlign(offset
);
2737 int alignmentWidth
= width
;
2738 int size
= fTimeAlignedComposite
.getSize().x
;
2739 GridLayout layout
= (GridLayout
) fTimeAlignedComposite
.getLayout();
2740 int marginSize
= size
- alignmentWidth
- offset
;
2741 layout
.marginRight
= Math
.max(0, marginSize
);
2742 fTimeAlignedComposite
.layout();