1 /*****************************************************************************
2 * Copyright (c) 2007, 2016 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
.Collections
;
21 import java
.util
.Comparator
;
22 import java
.util
.HashSet
;
23 import java
.util
.List
;
26 import org
.eclipse
.jdt
.annotation
.NonNull
;
27 import org
.eclipse
.jface
.action
.Action
;
28 import org
.eclipse
.jface
.action
.ActionContributionItem
;
29 import org
.eclipse
.jface
.action
.IAction
;
30 import org
.eclipse
.jface
.action
.IMenuCreator
;
31 import org
.eclipse
.jface
.action
.IMenuListener
;
32 import org
.eclipse
.jface
.action
.IMenuManager
;
33 import org
.eclipse
.jface
.action
.MenuManager
;
34 import org
.eclipse
.jface
.dialogs
.IDialogSettings
;
35 import org
.eclipse
.jface
.resource
.ImageDescriptor
;
36 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
37 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
38 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
39 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
40 import org
.eclipse
.jface
.viewers
.ViewerFilter
;
41 import org
.eclipse
.jface
.window
.Window
;
42 import org
.eclipse
.swt
.SWT
;
43 import org
.eclipse
.swt
.events
.ControlAdapter
;
44 import org
.eclipse
.swt
.events
.ControlEvent
;
45 import org
.eclipse
.swt
.events
.KeyAdapter
;
46 import org
.eclipse
.swt
.events
.KeyEvent
;
47 import org
.eclipse
.swt
.events
.MenuDetectListener
;
48 import org
.eclipse
.swt
.events
.MouseEvent
;
49 import org
.eclipse
.swt
.events
.MouseWheelListener
;
50 import org
.eclipse
.swt
.events
.SelectionAdapter
;
51 import org
.eclipse
.swt
.events
.SelectionEvent
;
52 import org
.eclipse
.swt
.events
.SelectionListener
;
53 import org
.eclipse
.swt
.graphics
.Point
;
54 import org
.eclipse
.swt
.graphics
.RGBA
;
55 import org
.eclipse
.swt
.graphics
.Rectangle
;
56 import org
.eclipse
.swt
.layout
.FillLayout
;
57 import org
.eclipse
.swt
.layout
.GridData
;
58 import org
.eclipse
.swt
.layout
.GridLayout
;
59 import org
.eclipse
.swt
.widgets
.Composite
;
60 import org
.eclipse
.swt
.widgets
.Control
;
61 import org
.eclipse
.swt
.widgets
.Display
;
62 import org
.eclipse
.swt
.widgets
.Event
;
63 import org
.eclipse
.swt
.widgets
.Listener
;
64 import org
.eclipse
.swt
.widgets
.Menu
;
65 import org
.eclipse
.swt
.widgets
.Slider
;
66 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
67 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.ITmfImageConstants
;
68 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Messages
;
69 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.dialogs
.AddBookmarkDialog
;
70 import org
.eclipse
.tracecompass
.tmf
.ui
.signal
.TmfTimeViewAlignmentInfo
;
71 import org
.eclipse
.tracecompass
.tmf
.ui
.viewers
.TmfViewer
;
72 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.ITmfTimeAligned
;
73 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.ShowFilterDialogAction
;
74 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.TimeGraphLegend
;
75 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
76 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.IMarkerEvent
;
77 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
78 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
79 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.MarkerEvent
;
80 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.IMarkerAxisListener
;
81 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.ITimeDataProvider
;
82 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeDataProviderCyclesConverter
;
83 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphColorScheme
;
84 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphControl
;
85 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphMarkerAxis
;
86 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphScale
;
87 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphTooltipHandler
;
88 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
89 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
90 import org
.eclipse
.ui
.PlatformUI
;
93 * Generic time graph viewer implementation
95 * @author Patrick Tasse, and others
97 public class TimeGraphViewer
extends TmfViewer
implements ITimeDataProvider
, IMarkerAxisListener
, SelectionListener
{
99 /** Constant indicating that all levels of the time graph should be expanded */
100 public static final int ALL_LEVELS
= AbstractTreeViewer
.ALL_LEVELS
;
102 private static final int DEFAULT_NAME_WIDTH
= 200;
103 private static final int MIN_NAME_WIDTH
= 6;
104 private static final int MAX_NAME_WIDTH
= 1000;
105 private static final int DEFAULT_HEIGHT
= 22;
106 private static final String HIDE_ARROWS_KEY
= "hide.arrows"; //$NON-NLS-1$
107 private static final long DEFAULT_FREQUENCY
= 1000000000L;
108 private static final int H_SCROLLBAR_MAX
= Integer
.MAX_VALUE
- 1;
110 private static final ImageDescriptor ADD_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ADD_BOOKMARK
);
111 private static final ImageDescriptor NEXT_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_BOOKMARK
);
112 private static final ImageDescriptor PREVIOUS_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREVIOUS_BOOKMARK
);
113 private static final ImageDescriptor REMOVE_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_REMOVE_BOOKMARK
);
115 private long fMinTimeInterval
;
116 private ITimeGraphEntry fSelectedEntry
;
117 private long fBeginTime
= SWT
.DEFAULT
; // The user-specified bounds start time
118 private long fEndTime
= SWT
.DEFAULT
; // The user-specified bounds end time
119 private long fTime0
= SWT
.DEFAULT
; // The current window start time
120 private long fTime1
= SWT
.DEFAULT
; // The current window end time
121 private long fSelectionBegin
= SWT
.DEFAULT
;
122 private long fSelectionEnd
= SWT
.DEFAULT
;
123 private long fTime0Bound
= SWT
.DEFAULT
; // The bounds start time
124 private long fTime1Bound
= SWT
.DEFAULT
; // The bounds end time
125 private long fTime0ExtSynch
= SWT
.DEFAULT
;
126 private long fTime1ExtSynch
= SWT
.DEFAULT
;
127 private boolean fTimeRangeFixed
;
128 private int fNameWidthPref
= DEFAULT_NAME_WIDTH
;
129 private int fMinNameWidth
= MIN_NAME_WIDTH
;
130 private int fNameWidth
;
131 private Composite fDataViewer
;
133 private TimeGraphControl fTimeGraphCtrl
;
134 private TimeGraphScale fTimeScaleCtrl
;
135 private TimeGraphMarkerAxis fMarkerAxisCtrl
;
136 private Slider fHorizontalScrollBar
;
137 private Slider fVerticalScrollBar
;
138 private @NonNull TimeGraphColorScheme fColorScheme
= new TimeGraphColorScheme();
139 private Object fInputElement
;
140 private ITimeGraphContentProvider fTimeGraphContentProvider
;
141 private ITimeGraphPresentationProvider fTimeGraphProvider
;
142 private @NonNull ITimeDataProvider fTimeDataProvider
= this;
143 private TimeGraphTooltipHandler fToolTipHandler
;
145 private List
<ITimeGraphSelectionListener
> fSelectionListeners
= new ArrayList
<>();
146 private List
<ITimeGraphTimeListener
> fTimeListeners
= new ArrayList
<>();
147 private List
<ITimeGraphRangeListener
> fRangeListeners
= new ArrayList
<>();
148 private List
<ITimeGraphBookmarkListener
> fBookmarkListeners
= new ArrayList
<>();
150 // Time format, using Epoch reference, Relative time format(default),
152 private TimeFormat fTimeFormat
= TimeFormat
.RELATIVE
;
153 // Clock frequency to use for Cycles time format
154 private long fClockFrequency
= DEFAULT_FREQUENCY
;
155 private int fBorderWidth
= 0;
156 private int fTimeScaleHeight
= DEFAULT_HEIGHT
;
158 private Action fResetScaleAction
;
159 private Action fShowLegendAction
;
160 private Action fNextEventAction
;
161 private Action fPrevEventAction
;
162 private Action fNextItemAction
;
163 private Action fPreviousItemAction
;
164 private Action fZoomInAction
;
165 private Action fZoomOutAction
;
166 private Action fHideArrowsAction
;
167 private Action fFollowArrowFwdAction
;
168 private Action fFollowArrowBwdAction
;
169 private ShowFilterDialogAction fShowFilterDialogAction
;
170 private Action fToggleBookmarkAction
;
171 private Action fNextMarkerAction
;
172 private Action fPreviousMarkerAction
;
173 private MenuManager fMarkersMenu
;
175 /** Pin related state */
176 private boolean fMarkersUpdateEnabled
= true;
177 private boolean fShowMarkerActionsEnabled
= true;
179 /** The list of bookmarks */
180 private final List
<IMarkerEvent
> fCurrentBookmark
= new ArrayList
<>();
181 private final List
<IMarkerEvent
> fSyncedBookmark
= new ArrayList
<>();
183 /** The list of marker categories */
184 private final List
<String
> fMarkerCategories
= new ArrayList
<>();
186 /** The set of hidden marker categories */
187 private final Set
<String
> fHiddenMarkerCategories
= new HashSet
<>();
189 /** The set of skipped marker categories */
190 private final Set
<String
> fSkippedMarkerCategories
= new HashSet
<>();
192 /** The list of markers */
193 private final List
<IMarkerEvent
> fMarkers
= new ArrayList
<>();
195 private ListenerNotifier fListenerNotifier
;
197 private Composite fTimeAlignedComposite
;
199 private final MouseWheelListeners fMouseWheelListeners
= new MouseWheelListeners();
200 private final KeyListeners fKeyListeners
= new KeyListeners();
202 private final class MouseWheelListeners
{
204 private boolean fZoomEnabled
;
205 private boolean fHorizontalScrollEnabled
;
207 public MouseWheelListeners() {
210 fHorizontalScrollEnabled
= true;
213 public void setZoomEnabled(boolean enabled
) {
214 fZoomEnabled
= enabled
;
217 public void setHorizontalScrollEnabled(boolean enabled
) {
218 fHorizontalScrollEnabled
= enabled
;
221 public final MouseWheelListener fTimeGraphCtrlListener
= new MouseWheelListener() {
223 public void mouseScrolled(MouseEvent e
) {
228 * On some platforms the mouse scroll event is sent to the
229 * control that has focus even if it is not under the cursor.
230 * Handle the event only if not over the time graph control.
232 Point ctrlParentCoords
= fTimeAlignedComposite
.toControl(fTimeGraphCtrl
.toDisplay(e
.x
, e
.y
));
233 Point scrollBarParentCoords
= fDataViewer
.toControl(fTimeGraphCtrl
.toDisplay(e
.x
, e
.y
));
234 if (fTimeGraphCtrl
.getBounds().contains(ctrlParentCoords
)) {
235 /* the time graph control handles the event */
236 adjustVerticalScrollBar();
237 } else if (fTimeScaleCtrl
.getBounds().contains(ctrlParentCoords
)
238 || fMarkerAxisCtrl
.getBounds().contains(ctrlParentCoords
)
239 || fHorizontalScrollBar
.getBounds().contains(scrollBarParentCoords
)) {
240 if (((e
.stateMask
& SWT
.CTRL
) != 0) && fZoomEnabled
) {
241 fTimeGraphCtrl
.zoom(e
.count
> 0);
242 } else if (fHorizontalScrollEnabled
) {
243 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
246 /* over the vertical scroll bar or outside of the viewer */
247 setTopIndex(getTopIndex() - e
.count
);
252 public final MouseWheelListener fTimeScaleCtrlListener
= new MouseWheelListener() {
254 public void mouseScrolled(MouseEvent e
) {
258 if (((e
.stateMask
& SWT
.CTRL
) != 0) && fZoomEnabled
) {
259 fTimeGraphCtrl
.zoom(e
.count
> 0);
260 } else if (fHorizontalScrollEnabled
) {
261 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
266 public final MouseWheelListener fMarkerAxisCtrlListener
= new MouseWheelListener() {
268 public void mouseScrolled(MouseEvent e
) {
272 if (((e
.stateMask
& SWT
.CTRL
) != 0) && fZoomEnabled
) {
273 fTimeGraphCtrl
.zoom(e
.count
> 0);
274 } else if (fHorizontalScrollEnabled
) {
275 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
280 public final Listener fHorizontalScrollBarListener
= new Listener() {
282 public void handleEvent(Event event
) {
283 // don't handle the immediately following SWT.Selection event
285 if (event
.count
== 0) {
288 if (((event
.stateMask
& SWT
.CTRL
) != 0) && fZoomEnabled
) {
289 fTimeGraphCtrl
.zoom(event
.count
> 0);
290 } else if (fHorizontalScrollEnabled
) {
291 fTimeGraphCtrl
.horizontalScroll(event
.count
> 0);
297 private final class KeyListeners
{
299 private boolean fExtendToNextMarkerEnabled
;
300 private boolean fSelectNextMarkerEnabled
;
301 private boolean fExtendToPrevMarkerEnabled
;
302 private boolean fSelectPrevMarkerEnabled
;
304 public KeyListeners() {
305 fExtendToNextMarkerEnabled
= true;
306 fSelectNextMarkerEnabled
= true;
307 fExtendToPrevMarkerEnabled
= true;
308 fSelectPrevMarkerEnabled
= true;
311 public void setExtendToNextMarkerEnabled(boolean enabled
) {
312 fExtendToNextMarkerEnabled
= enabled
;
315 public void setExtendToPrevMarkerEnabled(boolean enabled
) {
316 fExtendToPrevMarkerEnabled
= enabled
;
319 public void setSelectNextMarkerEnabled(boolean enabled
) {
320 fSelectNextMarkerEnabled
= enabled
;
323 public void setSelectPrevMarkerEnabled(boolean enabled
) {
324 fSelectPrevMarkerEnabled
= enabled
;
327 public void setAllEnabled(boolean enabled
) {
328 setExtendToNextMarkerEnabled(enabled
);
329 setSelectNextMarkerEnabled(enabled
);
330 setExtendToPrevMarkerEnabled(enabled
);
331 setSelectPrevMarkerEnabled(enabled
);
334 public final KeyAdapter fTimeGraphCtrlKeyListener
= new KeyAdapter() {
336 public void keyPressed(KeyEvent e
) {
337 boolean validEvent
= false;
338 if (e
.keyCode
== '.') {
339 boolean extend
= (e
.stateMask
& SWT
.SHIFT
) != 0;
340 if (extend
&& fExtendToNextMarkerEnabled
) {
341 extendToNextMarker();
343 } else if (fSelectNextMarkerEnabled
) {
347 } else if (e
.keyCode
== ',') {
348 boolean extend
= (e
.stateMask
& SWT
.SHIFT
) != 0;
349 if (extend
&& fExtendToPrevMarkerEnabled
) {
350 extendToPrevMarker();
352 } else if (fSelectPrevMarkerEnabled
) {
358 adjustVerticalScrollBar();
364 private class ListenerNotifier
extends Thread
{
365 private static final long DELAY
= 400L;
366 private static final long POLLING_INTERVAL
= 10L;
367 private long fLastUpdateTime
= Long
.MAX_VALUE
;
368 private boolean fSelectionChanged
= false;
369 private boolean fTimeRangeUpdated
= false;
370 private boolean fTimeSelected
= false;
374 while ((System
.currentTimeMillis() - fLastUpdateTime
) < DELAY
) {
376 Thread
.sleep(POLLING_INTERVAL
);
377 } catch (Exception e
) {
381 Display
.getDefault().asyncExec(new Runnable() {
384 if (fListenerNotifier
!= ListenerNotifier
.this) {
387 fListenerNotifier
= null;
388 if (ListenerNotifier
.this.isInterrupted() || fDataViewer
.isDisposed()) {
391 if (fSelectionChanged
) {
392 fireSelectionChanged(fSelectedEntry
);
394 if (fTimeRangeUpdated
) {
395 fireTimeRangeUpdated(fTime0
, fTime1
);
398 fireTimeSelected(fSelectionBegin
, fSelectionEnd
);
404 public void selectionChanged() {
405 fSelectionChanged
= true;
406 fLastUpdateTime
= System
.currentTimeMillis();
409 public void timeRangeUpdated() {
410 fTimeRangeUpdated
= true;
411 fLastUpdateTime
= System
.currentTimeMillis();
414 public void timeSelected() {
415 fTimeSelected
= true;
416 fLastUpdateTime
= System
.currentTimeMillis();
419 public boolean hasSelectionChanged() {
420 return fSelectionChanged
;
423 public boolean hasTimeRangeUpdated() {
424 return fTimeRangeUpdated
;
427 public boolean hasTimeSelected() {
428 return fTimeSelected
;
432 private final static class MarkerComparator
implements Comparator
<IMarkerEvent
> {
434 public int compare(IMarkerEvent o1
, IMarkerEvent o2
) {
435 int res
= Long
.compare(o1
.getTime(), o2
.getTime());
439 return Long
.compare(o1
.getDuration(), o2
.getDuration());
444 * Standard constructor.
446 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
449 * The parent UI composite object
453 public TimeGraphViewer(Composite parent
, int style
) {
454 createDataViewer(parent
, style
);
455 fTimeGraphContentProvider
= new TimeGraphContentProvider();
459 * Sets the timegraph content provider used by this timegraph viewer.
461 * @param timeGraphContentProvider
462 * the timegraph content provider
464 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
) {
465 fTimeGraphContentProvider
= timeGraphContentProvider
;
469 * Gets the timegraph content provider used by this timegraph viewer.
471 * @return the timegraph content provider
473 public ITimeGraphContentProvider
getTimeGraphContentProvider() {
474 return fTimeGraphContentProvider
;
478 * Sets the timegraph presentation provider used by this timegraph viewer.
480 * @param timeGraphProvider
481 * the timegraph provider
483 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider
) {
484 fTimeGraphProvider
= timeGraphProvider
;
485 fTimeGraphCtrl
.setTimeGraphProvider(timeGraphProvider
);
486 fToolTipHandler
= new TimeGraphTooltipHandler(fTimeGraphProvider
, fTimeDataProvider
);
487 fToolTipHandler
.activateHoverHelp(fTimeGraphCtrl
);
491 * Sets the tree columns for this time graph combo's filter dialog.
493 * @param columnNames the tree column names
496 public void setFilterColumns(String
[] columnNames
) {
497 getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames
);
501 * Sets the tree content provider used by the filter dialog
503 * @param contentProvider the tree content provider
506 public void setFilterContentProvider(ITreeContentProvider contentProvider
) {
507 getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider
);
511 * Sets the tree label provider used by the filter dialog
513 * @param labelProvider the tree label provider
516 public void setFilterLabelProvider(ITableLabelProvider labelProvider
) {
517 getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider
);
521 * Sets or clears the input for this time graph viewer.
523 * @param inputElement
524 * The input of this time graph viewer, or <code>null</code> if
527 public void setInput(Object inputElement
) {
528 fInputElement
= inputElement
;
529 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(inputElement
);
530 fListenerNotifier
= null;
531 if (fTimeGraphCtrl
!= null) {
534 fSelectionBegin
= SWT
.DEFAULT
;
535 fSelectionEnd
= SWT
.DEFAULT
;
536 updateMarkerActions();
537 fSelectedEntry
= null;
538 refreshAllData(input
);
543 * Gets the input for this time graph viewer.
545 * @return The input of this time graph viewer, or <code>null</code> if none
547 public Object
getInput() {
548 return fInputElement
;
552 * Sets (or clears if null) the list of links to display on this combo
555 * the links to display in this time graph combo
557 public void setLinks(List
<ILinkEvent
> links
) {
558 if (fTimeGraphCtrl
!= null) {
559 fTimeGraphCtrl
.refreshArrows(links
);
567 public void refresh() {
568 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(fInputElement
);
570 refreshAllData(input
);
574 * Callback for when the control is moved
579 public void controlMoved(ControlEvent e
) {
583 * Callback for when the control is resized
588 public void controlResized(ControlEvent e
) {
593 * @return The string representing the view type
595 protected String
getViewTypeStr() {
596 return "viewoption.threads"; //$NON-NLS-1$
599 int getMarginWidth() {
603 int getMarginHeight() {
608 fMinTimeInterval
= 1;
609 fSelectionBegin
= SWT
.DEFAULT
;
610 fSelectionEnd
= SWT
.DEFAULT
;
611 fNameWidth
= Utils
.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
612 fNameWidthPref
, fMinNameWidth
, MAX_NAME_WIDTH
);
616 Utils
.saveIntOption(getPreferenceString("namewidth"), fNameWidth
); //$NON-NLS-1$
620 * Create a data viewer.
626 * @return The new data viewer
628 protected Control
createDataViewer(Composite parent
, int style
) {
630 fDataViewer
= new Composite(parent
, style
) {
632 public void redraw() {
633 fTimeScaleCtrl
.redraw();
634 fTimeGraphCtrl
.redraw();
635 fMarkerAxisCtrl
.redraw();
639 fDataViewer
.addDisposeListener((e
) -> {
640 if (fMarkersMenu
!= null) {
641 fMarkersMenu
.dispose();
644 GridLayout gl
= new GridLayout(2, false);
645 gl
.marginHeight
= fBorderWidth
;
647 gl
.verticalSpacing
= 0;
648 gl
.horizontalSpacing
= 0;
649 fDataViewer
.setLayout(gl
);
651 fTimeAlignedComposite
= new Composite(fDataViewer
, style
) {
653 public void redraw() {
654 fDataViewer
.redraw();
658 GridLayout gl2
= new GridLayout(1, false);
659 gl2
.marginHeight
= fBorderWidth
;
661 gl2
.verticalSpacing
= 0;
662 gl2
.horizontalSpacing
= 0;
663 fTimeAlignedComposite
.setLayout(gl2
);
664 fTimeAlignedComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
666 fTimeScaleCtrl
= new TimeGraphScale(fTimeAlignedComposite
, fColorScheme
);
667 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
668 fTimeScaleCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
669 fTimeScaleCtrl
.setHeight(fTimeScaleHeight
);
670 fTimeScaleCtrl
.addMouseWheelListener(fMouseWheelListeners
.fTimeScaleCtrlListener
);
672 fTimeGraphCtrl
= createTimeGraphControl(fTimeAlignedComposite
, fColorScheme
);
674 fTimeGraphCtrl
.setTimeProvider(this);
675 fTimeGraphCtrl
.setTimeGraphScale(fTimeScaleCtrl
);
676 fTimeGraphCtrl
.addSelectionListener(this);
677 fTimeGraphCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
678 fTimeGraphCtrl
.addMouseWheelListener(fMouseWheelListeners
.fTimeGraphCtrlListener
);
679 fTimeGraphCtrl
.addKeyListener(fKeyListeners
.fTimeGraphCtrlKeyListener
);
681 fMarkerAxisCtrl
= createTimeGraphMarkerAxis(fTimeAlignedComposite
, fColorScheme
, this);
682 fMarkerAxisCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
683 fMarkerAxisCtrl
.addMarkerAxisListener(this);
684 fMarkerAxisCtrl
.addMouseWheelListener(fMouseWheelListeners
.fMarkerAxisCtrlListener
);
686 fVerticalScrollBar
= new Slider(fDataViewer
, SWT
.VERTICAL
| SWT
.NO_FOCUS
);
687 fVerticalScrollBar
.setLayoutData(new GridData(SWT
.DEFAULT
, SWT
.FILL
, false, true, 1, 1));
688 fVerticalScrollBar
.addSelectionListener(new SelectionAdapter() {
690 public void widgetSelected(SelectionEvent e
) {
691 setTopIndex(fVerticalScrollBar
.getSelection());
695 fHorizontalScrollBar
= new Slider(fDataViewer
, SWT
.HORIZONTAL
| SWT
.NO_FOCUS
);
696 fHorizontalScrollBar
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
697 fHorizontalScrollBar
.addListener(SWT
.MouseWheel
, fMouseWheelListeners
.fHorizontalScrollBarListener
);
698 fHorizontalScrollBar
.addListener(SWT
.Selection
, new Listener() {
700 public void handleEvent(Event event
) {
701 int start
= fHorizontalScrollBar
.getSelection();
702 long time0
= getTime0();
703 long time1
= getTime1();
704 long timeMin
= getMinTime();
705 long timeMax
= getMaxTime();
706 long delta
= timeMax
- timeMin
;
708 long range
= time1
- time0
;
709 time0
= timeMin
+ Math
.round(delta
* ((double) start
/ H_SCROLLBAR_MAX
));
710 time1
= time0
+ range
;
712 setStartFinishTimeNotify(time0
, time1
);
716 Composite filler
= new Composite(fDataViewer
, SWT
.NONE
);
717 GridData gd
= new GridData(SWT
.DEFAULT
, SWT
.DEFAULT
, false, false);
718 gd
.heightHint
= fHorizontalScrollBar
.getSize().y
;
719 filler
.setLayoutData(gd
);
720 filler
.setLayout(new FillLayout());
722 fTimeGraphCtrl
.addControlListener(new ControlAdapter() {
724 public void controlResized(ControlEvent event
) {
729 fDataViewer
.update();
730 adjustHorizontalScrollBar();
731 adjustVerticalScrollBar();
733 fDataViewer
.addDisposeListener((e
) -> {
735 fColorScheme
.dispose();
742 * Dispose the time graph viewer.
745 public void dispose() {
746 fDataViewer
.dispose();
750 * Create a new time graph control.
753 * The parent composite
756 * @return The new TimeGraphControl
758 protected TimeGraphControl
createTimeGraphControl(Composite parent
,
759 TimeGraphColorScheme colors
) {
760 return new TimeGraphControl(parent
, colors
);
764 * Create a new time graph marker axis.
767 * The parent composite object
769 * The color scheme to use
770 * @param timeProvider
771 * The time data provider
772 * @return The new TimeGraphMarkerAxis
775 protected TimeGraphMarkerAxis
createTimeGraphMarkerAxis(Composite parent
,
776 @NonNull TimeGraphColorScheme colorScheme
, @NonNull ITimeDataProvider timeProvider
) {
777 return new TimeGraphMarkerAxis(parent
, colorScheme
, timeProvider
);
781 * Resize the controls
783 public void resizeControls() {
784 Rectangle r
= fDataViewer
.getClientArea();
790 if (fNameWidth
> width
- fMinNameWidth
) {
791 fNameWidth
= width
- fMinNameWidth
;
793 if (fNameWidth
< fMinNameWidth
) {
794 fNameWidth
= fMinNameWidth
;
796 adjustHorizontalScrollBar();
797 adjustVerticalScrollBar();
801 * Recalculate the time bounds based on the time graph entries,
802 * if the user-specified bound is set to SWT.DEFAULT.
805 * The root time graph entries in the model
807 public void setTimeRange(ITimeGraphEntry entries
[]) {
808 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
809 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
810 if (fBeginTime
!= SWT
.DEFAULT
&& fEndTime
!= SWT
.DEFAULT
) {
813 if (entries
== null || entries
.length
== 0) {
816 if (fTime0Bound
== SWT
.DEFAULT
) {
817 fTime0Bound
= Long
.MAX_VALUE
;
819 if (fTime1Bound
== SWT
.DEFAULT
) {
820 fTime1Bound
= Long
.MIN_VALUE
;
822 for (ITimeGraphEntry entry
: entries
) {
825 if (fTime0Bound
> fTime1Bound
) {
826 fTime0Bound
= SWT
.DEFAULT
;
827 fTime1Bound
= SWT
.DEFAULT
;
831 private void setTimeRange(ITimeGraphEntry entry
) {
832 if (fBeginTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getStartTime() != SWT
.DEFAULT
) {
833 fTime0Bound
= Math
.min(entry
.getStartTime(), fTime0Bound
);
835 if (fEndTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getEndTime() != SWT
.DEFAULT
) {
836 fTime1Bound
= Math
.max(entry
.getEndTime(), fTime1Bound
);
838 if (entry
.hasChildren()) {
839 for (ITimeGraphEntry child
: entry
.getChildren()) {
846 * Set the time bounds to the provided values.
849 * The bounds begin time, or SWT.DEFAULT to use the input bounds
851 * The bounds end time, or SWT.DEFAULT to use the input bounds
853 public void setTimeBounds(long beginTime
, long endTime
) {
854 fBeginTime
= beginTime
;
856 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
857 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
858 if (fTime0Bound
> fTime1Bound
) {
859 // only possible if both are not default
860 fBeginTime
= endTime
;
861 fEndTime
= beginTime
;
862 fTime0Bound
= fBeginTime
;
863 fTime1Bound
= fEndTime
;
865 adjustHorizontalScrollBar();
869 * Recalculate the current time window when bounds have changed.
871 public void setTimeBounds() {
872 if (!fTimeRangeFixed
) {
873 fTime0
= fTime0Bound
;
874 fTime1
= fTime1Bound
;
876 fTime0
= Math
.max(fTime0Bound
, Math
.min(fTime0
, fTime1Bound
));
877 fTime1
= Math
.max(fTime0Bound
, Math
.min(fTime1
, fTime1Bound
));
878 if (fTime1
- fTime0
< fMinTimeInterval
) {
879 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
886 private void refreshAllData(ITimeGraphEntry
[] traces
) {
888 if (fSelectionBegin
< fBeginTime
) {
889 fSelectionBegin
= fBeginTime
;
890 } else if (fSelectionBegin
> fEndTime
) {
891 fSelectionBegin
= fEndTime
;
893 if (fSelectionEnd
< fBeginTime
) {
894 fSelectionEnd
= fBeginTime
;
895 } else if (fSelectionEnd
> fEndTime
) {
896 fSelectionEnd
= fEndTime
;
898 fTimeGraphCtrl
.refreshData(traces
);
899 fTimeScaleCtrl
.redraw();
900 fMarkerAxisCtrl
.redraw();
901 updateMarkerActions();
902 adjustVerticalScrollBar();
906 * Callback for when this view is focused
908 public void setFocus() {
909 if (null != fTimeGraphCtrl
) {
910 fTimeGraphCtrl
.setFocus();
915 * Get the current focus status of this view.
917 * @return If the view is currently focused, or not
919 public boolean isInFocus() {
920 return fTimeGraphCtrl
.isInFocus();
924 * Get the view's current selection
926 * @return The entry that is selected
928 public ITimeGraphEntry
getSelection() {
929 return fTimeGraphCtrl
.getSelectedTrace();
933 * Get the index of the current selection
937 public int getSelectionIndex() {
938 return fTimeGraphCtrl
.getSelectedIndex();
942 public long getTime0() {
947 public long getTime1() {
952 public long getMinTimeInterval() {
953 return fMinTimeInterval
;
957 public int getNameSpace() {
962 public void setNameSpace(int width
) {
964 int w
= fTimeGraphCtrl
.getClientArea().width
;
965 if (fNameWidth
> w
- MIN_NAME_WIDTH
) {
966 fNameWidth
= w
- MIN_NAME_WIDTH
;
968 if (fNameWidth
< MIN_NAME_WIDTH
) {
969 fNameWidth
= MIN_NAME_WIDTH
;
971 fTimeGraphCtrl
.redraw();
972 fTimeScaleCtrl
.redraw();
973 fMarkerAxisCtrl
.redraw();
974 /* force update the controls to keep them aligned */
975 fTimeScaleCtrl
.update();
976 fMarkerAxisCtrl
.update();
977 fTimeGraphCtrl
.update();
981 public int getTimeSpace() {
982 int w
= fTimeGraphCtrl
.getClientArea().width
;
983 return w
- fNameWidth
;
987 public long getBeginTime() {
992 public long getEndTime() {
997 public long getMaxTime() {
1002 public long getMinTime() {
1007 public long getSelectionBegin() {
1008 return fSelectionBegin
;
1012 public long getSelectionEnd() {
1013 return fSelectionEnd
;
1017 public void setStartFinishTimeNotify(long time0
, long time1
) {
1018 setStartFinishTimeInt(time0
, time1
);
1019 notifyRangeListeners();
1023 public void notifyStartFinishTime() {
1024 notifyRangeListeners();
1028 public void setStartFinishTime(long time0
, long time1
) {
1029 /* if there is a pending time range, ignore this one */
1030 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeRangeUpdated()) {
1033 setStartFinishTimeInt(time0
, time1
);
1034 updateExtSynchValues();
1037 private void setStartFinishTimeInt(long time0
, long time1
) {
1039 if (fTime0
< fTime0Bound
) {
1040 fTime0
= fTime0Bound
;
1042 if (fTime0
> fTime1Bound
) {
1043 fTime0
= fTime1Bound
;
1046 if (fTime1
< fTime0Bound
) {
1047 fTime1
= fTime0Bound
;
1049 if (fTime1
> fTime1Bound
) {
1050 fTime1
= fTime1Bound
;
1052 if (fTime1
- fTime0
< fMinTimeInterval
) {
1053 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
1055 fTimeRangeFixed
= true;
1056 adjustHorizontalScrollBar();
1057 fTimeGraphCtrl
.redraw();
1058 fTimeScaleCtrl
.redraw();
1059 fMarkerAxisCtrl
.redraw();
1060 /* force update the controls to keep them aligned */
1061 fTimeScaleCtrl
.update();
1062 fMarkerAxisCtrl
.update();
1063 fTimeGraphCtrl
.update();
1067 public void resetStartFinishTime() {
1068 setStartFinishTimeNotify(fTime0Bound
, fTime1Bound
);
1069 fTimeRangeFixed
= false;
1076 public void resetStartFinishTime(boolean notify
) {
1078 setStartFinishTimeNotify(fTime0Bound
, fTime1Bound
);
1080 setStartFinishTime(fTime0Bound
, fTime1Bound
);
1082 fTimeRangeFixed
= false;
1086 public void setSelectedTimeNotify(long time
, boolean ensureVisible
) {
1087 setSelectedTimeInt(time
, ensureVisible
, true);
1091 public void setSelectedTime(long time
, boolean ensureVisible
) {
1092 /* if there is a pending time selection, ignore this one */
1093 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
1096 setSelectedTimeInt(time
, ensureVisible
, false);
1099 private void setSelectedTimeInt(long time
, boolean ensureVisible
, boolean doNotify
) {
1100 setSelectionRangeInt(time
, time
, ensureVisible
, doNotify
);
1107 public void setSelectionRangeNotify(long beginTime
, long endTime
, boolean ensureVisible
) {
1108 setSelectionRangeInt(beginTime
, endTime
, ensureVisible
, true);
1115 public void setSelectionRange(long beginTime
, long endTime
, boolean ensureVisible
) {
1116 /* if there is a pending time selection, ignore this one */
1117 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
1120 setSelectionRangeInt(beginTime
, endTime
, ensureVisible
, false);
1123 private void setSelectionRangeInt(long beginTime
, long endTime
, boolean ensureVisible
, boolean doNotify
) {
1124 long time0
= fTime0
;
1125 long time1
= fTime1
;
1126 long selectionBegin
= fSelectionBegin
;
1127 long selectionEnd
= fSelectionEnd
;
1128 fSelectionBegin
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, beginTime
));
1129 fSelectionEnd
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, endTime
));
1130 boolean changed
= (selectionBegin
!= fSelectionBegin
|| selectionEnd
!= fSelectionEnd
);
1132 if (ensureVisible
) {
1133 ensureVisible(selectionBegin
!= fSelectionBegin ? fSelectionBegin
: fSelectionEnd
);
1136 fTimeGraphCtrl
.redraw();
1137 fTimeScaleCtrl
.redraw();
1138 fMarkerAxisCtrl
.redraw();
1139 updateMarkerActions();
1141 if ((time0
!= fTime0
) || (time1
!= fTime1
)) {
1142 notifyRangeListeners();
1145 if (doNotify
&& changed
) {
1146 notifyTimeListeners();
1150 private void ensureVisible(long time
) {
1151 long timeMid
= (fTime1
- fTime0
) / 2;
1152 if (time
< fTime0
) {
1153 long dt
= fTime0
- time
+ timeMid
;
1156 } else if (time
> fTime1
) {
1157 long dt
= time
- fTime1
+ timeMid
;
1161 if (fTime0
< fTime0Bound
) {
1162 fTime1
= Math
.min(fTime1Bound
, fTime1
+ (fTime0Bound
- fTime0
));
1163 fTime0
= fTime0Bound
;
1164 } else if (fTime1
> fTime1Bound
) {
1165 fTime0
= Math
.max(fTime0Bound
, fTime0
- (fTime1
- fTime1Bound
));
1166 fTime1
= fTime1Bound
;
1168 if (fTime1
- fTime0
< fMinTimeInterval
) {
1169 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
1171 adjustHorizontalScrollBar();
1175 public void widgetDefaultSelected(SelectionEvent e
) {
1176 if (fSelectedEntry
!= getSelection()) {
1177 fSelectedEntry
= getSelection();
1178 notifySelectionListeners();
1183 public void widgetSelected(SelectionEvent e
) {
1184 if (fSelectedEntry
!= getSelection()) {
1185 fSelectedEntry
= getSelection();
1186 notifySelectionListeners();
1191 * Callback for when the next event is selected
1194 * true to extend selection range, false for single selection
1197 public void selectNextEvent(boolean extend
) {
1198 fTimeGraphCtrl
.selectNextEvent(extend
);
1199 adjustVerticalScrollBar();
1203 * Callback for when the previous event is selected
1206 * true to extend selection range, false for single selection
1209 public void selectPrevEvent(boolean extend
) {
1210 fTimeGraphCtrl
.selectPrevEvent(extend
);
1211 adjustVerticalScrollBar();
1215 * Callback for when the next item is selected
1217 public void selectNextItem() {
1218 fTimeGraphCtrl
.selectNextTrace();
1219 adjustVerticalScrollBar();
1223 * Callback for when the previous item is selected
1225 public void selectPrevItem() {
1226 fTimeGraphCtrl
.selectPrevTrace();
1227 adjustVerticalScrollBar();
1231 * Callback for the show legend action
1233 public void showLegend() {
1234 if (fDataViewer
== null || fDataViewer
.isDisposed()) {
1238 TimeGraphLegend
.open(fDataViewer
.getShell(), fTimeGraphProvider
);
1242 * Callback for the Zoom In action
1244 public void zoomIn() {
1245 fTimeGraphCtrl
.zoomIn();
1249 * Callback for the Zoom Out action
1251 public void zoomOut() {
1252 fTimeGraphCtrl
.zoomOut();
1255 private String
getPreferenceString(String string
) {
1256 return getViewTypeStr() + "." + string
; //$NON-NLS-1$
1260 * Add a selection listener
1263 * The listener to add
1265 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
1266 fSelectionListeners
.add(listener
);
1270 * Remove a selection listener
1273 * The listener to remove
1275 public void removeSelectionListener(ITimeGraphSelectionListener listener
) {
1276 fSelectionListeners
.remove(listener
);
1279 private void notifySelectionListeners() {
1280 if (fListenerNotifier
== null) {
1281 fListenerNotifier
= new ListenerNotifier();
1282 fListenerNotifier
.start();
1284 fListenerNotifier
.selectionChanged();
1287 private void fireSelectionChanged(ITimeGraphEntry selection
) {
1288 TimeGraphSelectionEvent event
= new TimeGraphSelectionEvent(this, selection
);
1290 for (ITimeGraphSelectionListener listener
: fSelectionListeners
) {
1291 listener
.selectionChanged(event
);
1296 * Add a time listener
1299 * The listener to add
1301 public void addTimeListener(ITimeGraphTimeListener listener
) {
1302 fTimeListeners
.add(listener
);
1306 * Remove a time listener
1309 * The listener to remove
1311 public void removeTimeListener(ITimeGraphTimeListener listener
) {
1312 fTimeListeners
.remove(listener
);
1315 private void notifyTimeListeners() {
1316 if (fListenerNotifier
== null) {
1317 fListenerNotifier
= new ListenerNotifier();
1318 fListenerNotifier
.start();
1320 fListenerNotifier
.timeSelected();
1323 private void fireTimeSelected(long startTime
, long endTime
) {
1324 TimeGraphTimeEvent event
= new TimeGraphTimeEvent(this, startTime
, endTime
);
1326 for (ITimeGraphTimeListener listener
: fTimeListeners
) {
1327 listener
.timeSelected(event
);
1332 * Add a range listener
1335 * The listener to add
1337 public void addRangeListener(ITimeGraphRangeListener listener
) {
1338 fRangeListeners
.add(listener
);
1342 * Remove a range listener
1345 * The listener to remove
1347 public void removeRangeListener(ITimeGraphRangeListener listener
) {
1348 fRangeListeners
.remove(listener
);
1351 private void notifyRangeListeners() {
1352 if (fListenerNotifier
== null) {
1353 fListenerNotifier
= new ListenerNotifier();
1354 fListenerNotifier
.start();
1356 fListenerNotifier
.timeRangeUpdated();
1359 private void fireTimeRangeUpdated(long startTime
, long endTime
) {
1360 // Check if the time has actually changed from last notification
1361 if (startTime
!= fTime0ExtSynch
|| endTime
!= fTime1ExtSynch
) {
1362 // Notify Time Scale Selection Listeners
1363 TimeGraphRangeUpdateEvent event
= new TimeGraphRangeUpdateEvent(this, startTime
, endTime
);
1365 for (ITimeGraphRangeListener listener
: fRangeListeners
) {
1366 listener
.timeRangeUpdated(event
);
1369 // update external synch values
1370 updateExtSynchValues();
1375 * Add a bookmark listener
1378 * The listener to add
1381 public void addBookmarkListener(ITimeGraphBookmarkListener listener
) {
1382 fBookmarkListeners
.add(listener
);
1386 * Remove a bookmark listener
1389 * The listener to remove
1392 public void removeBookmarkListener(ITimeGraphBookmarkListener listener
) {
1393 fBookmarkListeners
.remove(listener
);
1396 private void fireBookmarkAdded(IMarkerEvent bookmark
) {
1397 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1399 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1400 listener
.bookmarkAdded(event
);
1404 private void fireBookmarkRemoved(IMarkerEvent bookmark
) {
1405 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1407 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1408 listener
.bookmarkRemoved(event
);
1413 * Set the bookmarks list.
1416 * The bookmarks list, or null
1419 public void setBookmarks(List
<IMarkerEvent
> bookmarks
) {
1421 fSyncedBookmark
.clear();
1423 if (bookmarks
!= null) {
1424 fSyncedBookmark
.addAll(bookmarks
);
1427 if (fMarkersUpdateEnabled
) {
1428 fCurrentBookmark
.clear();
1429 fCurrentBookmark
.addAll(fSyncedBookmark
);
1432 updateMarkerActions();
1436 * Get the bookmarks list.
1438 * @return The bookmarks list
1441 public List
<IMarkerEvent
> getBookmarks() {
1442 return Collections
.unmodifiableList(fCurrentBookmark
);
1446 * Set the list of marker categories.
1449 * The list of marker categories, or null
1452 public void setMarkerCategories(List
<String
> categories
) {
1453 fMarkerCategories
.clear();
1454 if (categories
!= null) {
1455 fMarkerCategories
.addAll(categories
);
1457 fMarkerCategories
.add(IMarkerEvent
.BOOKMARKS
);
1458 fMarkerAxisCtrl
.setMarkerCategories(fMarkerCategories
);
1465 public void setMarkerCategoryVisible(String category
, boolean visible
) {
1466 boolean changed
= false;
1468 changed
= fHiddenMarkerCategories
.remove(category
);
1470 changed
= fHiddenMarkerCategories
.add(category
);
1474 updateMarkerActions();
1475 getControl().redraw();
1480 * Set the markers list.
1483 * The markers list, or null
1486 public void setMarkers(List
<IMarkerEvent
> markers
) {
1488 if (markers
!= null) {
1489 fMarkers
.addAll(markers
);
1492 updateMarkerActions();
1496 * Get the markers list.
1498 * @return The markers list, or null
1501 public List
<IMarkerEvent
> getMarkers() {
1502 return Collections
.unmodifiableList(fMarkers
);
1506 * Callback to set a selected event in the view
1509 * The event that was selected
1511 * The source of this selection event
1513 public void setSelectedEvent(ITimeEvent event
, Object source
) {
1514 if (event
== null || source
== this) {
1517 fSelectedEntry
= event
.getEntry();
1518 fTimeGraphCtrl
.selectItem(fSelectedEntry
, false);
1520 setSelectedTimeInt(event
.getTime(), true, true);
1521 adjustVerticalScrollBar();
1525 * Set the seeked time of a trace
1528 * The trace that was seeked
1532 * The source of this seek event
1534 public void setSelectedTraceTime(ITimeGraphEntry trace
, long time
, Object source
) {
1535 if (trace
== null || source
== this) {
1538 fSelectedEntry
= trace
;
1539 fTimeGraphCtrl
.selectItem(trace
, false);
1541 setSelectedTimeInt(time
, true, true);
1545 * Callback for a trace selection
1548 * The trace that was selected
1550 public void setSelection(ITimeGraphEntry trace
) {
1551 /* if there is a pending selection, ignore this one */
1552 if (fListenerNotifier
!= null && fListenerNotifier
.hasSelectionChanged()) {
1555 fSelectedEntry
= trace
;
1556 fTimeGraphCtrl
.selectItem(trace
, false);
1557 adjustVerticalScrollBar();
1561 * Callback for a time window selection
1564 * Start time of the range
1566 * End time of the range
1568 * Source of the event
1570 public void setSelectVisTimeWindow(long time0
, long time1
, Object source
) {
1571 if (source
== this) {
1575 setStartFinishTimeInt(time0
, time1
);
1577 // update notification time values since we are now in synch with the
1578 // external application
1579 updateExtSynchValues();
1583 * update the cache values used to identify the need to send a time window
1584 * update to external registered listeners
1586 private void updateExtSynchValues() {
1587 // last time notification cache
1588 fTime0ExtSynch
= fTime0
;
1589 fTime1ExtSynch
= fTime1
;
1593 public TimeFormat
getTimeFormat() {
1599 * the {@link TimeFormat} used to display timestamps
1601 public void setTimeFormat(TimeFormat tf
) {
1602 this.fTimeFormat
= tf
;
1603 if (tf
== TimeFormat
.CYCLES
) {
1604 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1606 fTimeDataProvider
= this;
1608 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1609 if (fToolTipHandler
!= null) {
1610 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1615 * Sets the clock frequency. Used when the time format is set to CYCLES.
1617 * @param clockFrequency
1618 * the clock frequency in Hz
1620 public void setClockFrequency(long clockFrequency
) {
1621 fClockFrequency
= clockFrequency
;
1622 if (fTimeFormat
== TimeFormat
.CYCLES
) {
1623 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1624 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1625 if (fToolTipHandler
!= null) {
1626 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1632 * Retrieve the border width
1636 public int getBorderWidth() {
1637 return fBorderWidth
;
1641 * Set the border width
1643 * @param borderWidth
1646 public void setBorderWidth(int borderWidth
) {
1647 if (borderWidth
> -1) {
1648 this.fBorderWidth
= borderWidth
;
1649 GridLayout gl
= (GridLayout
) fDataViewer
.getLayout();
1650 gl
.marginHeight
= borderWidth
;
1655 * Retrieve the height of the header
1657 * @return The height
1659 public int getHeaderHeight() {
1660 return fTimeScaleHeight
;
1664 * Set the height of the header
1666 * @param headerHeight
1669 public void setHeaderHeight(int headerHeight
) {
1670 if (headerHeight
> -1) {
1671 this.fTimeScaleHeight
= headerHeight
;
1672 fTimeScaleCtrl
.setHeight(headerHeight
);
1677 * Retrieve the height of an item row
1679 * @return The height
1681 public int getItemHeight() {
1682 if (fTimeGraphCtrl
!= null) {
1683 return fTimeGraphCtrl
.getItemHeight();
1689 * Set the height of an item row
1694 public void setItemHeight(int rowHeight
) {
1695 if (fTimeGraphCtrl
!= null) {
1696 fTimeGraphCtrl
.setItemHeight(rowHeight
);
1701 * Set the minimum item width
1706 public void setMinimumItemWidth(int width
) {
1707 if (fTimeGraphCtrl
!= null) {
1708 fTimeGraphCtrl
.setMinimumItemWidth(width
);
1713 * Set the width for the name column
1718 public void setNameWidthPref(int width
) {
1719 fNameWidthPref
= width
;
1727 * Retrieve the configure width for the name column
1733 public int getNameWidthPref(int width
) {
1734 return fNameWidthPref
;
1738 * Returns the primary control associated with this viewer.
1740 * @return the SWT control which displays this viewer's content
1743 public Control
getControl() {
1748 * Returns the time graph control associated with this viewer.
1750 * @return the time graph control
1752 public TimeGraphControl
getTimeGraphControl() {
1753 return fTimeGraphCtrl
;
1757 * Returns the time graph scale associated with this viewer.
1759 * @return the time graph scale
1761 public TimeGraphScale
getTimeGraphScale() {
1762 return fTimeScaleCtrl
;
1766 * Returns the composite containing all the controls that are time aligned,
1767 * i.e. TimeGraphScale, TimeGraphControl.
1769 * @return the time based composite
1772 public Composite
getTimeAlignedComposite() {
1773 return fTimeAlignedComposite
;
1777 * Return the x coordinate corresponding to a time
1781 * @return the x coordinate corresponding to the time
1783 public int getXForTime(long time
) {
1784 return fTimeGraphCtrl
.getXForTime(time
);
1788 * Return the time corresponding to an x coordinate
1792 * @return the time corresponding to the x coordinate
1794 public long getTimeAtX(int x
) {
1795 return fTimeGraphCtrl
.getTimeAtX(x
);
1799 * Get the selection provider
1801 * @return the selection provider
1803 public ISelectionProvider
getSelectionProvider() {
1804 return fTimeGraphCtrl
;
1808 * Wait for the cursor
1811 * Wait indefinitely?
1813 public void waitCursor(boolean waitInd
) {
1814 fTimeGraphCtrl
.waitCursor(waitInd
);
1818 * Get the horizontal scroll bar object
1820 * @return The scroll bar
1822 public Slider
getHorizontalBar() {
1823 return fHorizontalScrollBar
;
1827 * Get the vertical scroll bar object
1829 * @return The scroll bar
1831 public Slider
getVerticalBar() {
1832 return fVerticalScrollBar
;
1836 * Set the given index as the top one
1839 * The index that will go to the top
1841 public void setTopIndex(int index
) {
1842 fTimeGraphCtrl
.setTopIndex(index
);
1843 adjustVerticalScrollBar();
1847 * Retrieve the current top index
1849 * @return The top index
1851 public int getTopIndex() {
1852 return fTimeGraphCtrl
.getTopIndex();
1856 * Sets the auto-expand level to be used for new entries discovered when
1857 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1858 * means that there is no auto-expand; 1 means that top-level entries are
1859 * expanded, but not their children; 2 means that top-level entries are
1860 * expanded, and their children, but not grand-children; and so on.
1862 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1866 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1867 * levels of the tree
1869 public void setAutoExpandLevel(int level
) {
1870 fTimeGraphCtrl
.setAutoExpandLevel(level
);
1874 * Returns the auto-expand level.
1876 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1877 * the tree are expanded automatically
1878 * @see #setAutoExpandLevel
1880 public int getAutoExpandLevel() {
1881 return fTimeGraphCtrl
.getAutoExpandLevel();
1885 * Get the expanded state of an entry.
1889 * @return true if the entry is expanded, false if collapsed
1892 public boolean getExpandedState(ITimeGraphEntry entry
) {
1893 return fTimeGraphCtrl
.getExpandedState(entry
);
1897 * Set the expanded state of an entry
1900 * The entry to expand/collapse
1902 * True for expanded, false for collapsed
1904 public void setExpandedState(ITimeGraphEntry entry
, boolean expanded
) {
1905 fTimeGraphCtrl
.setExpandedState(entry
, expanded
);
1906 adjustVerticalScrollBar();
1910 * Collapses all nodes of the viewer's tree, starting with the root.
1912 public void collapseAll() {
1913 fTimeGraphCtrl
.collapseAll();
1914 adjustVerticalScrollBar();
1918 * Expands all entries of the viewer's tree, starting with the root.
1920 public void expandAll() {
1921 fTimeGraphCtrl
.expandAll();
1922 adjustVerticalScrollBar();
1926 * Select an entry and reveal it
1929 * The entry to select
1932 public void selectAndReveal(@NonNull ITimeGraphEntry entry
) {
1933 final ITimeGraphEntry parent
= entry
.getParent();
1934 if (parent
!= null) {
1935 fTimeGraphCtrl
.setExpandedState(parent
, true);
1937 fSelectedEntry
= entry
;
1938 fTimeGraphCtrl
.selectItem(entry
, false);
1939 adjustVerticalScrollBar();
1943 * Get the number of expanded (visible) time graph entries. This includes
1944 * leafs and does not include filtered-out entries.
1946 * @return The number of expanded (visible) time graph entries
1948 public int getExpandedElementCount() {
1949 return fTimeGraphCtrl
.getExpandedElementCount();
1953 * Get the expanded (visible) time graph entries. This includes leafs and
1954 * does not include filtered-out entries.
1956 * @return The array of expanded (visible) time graph entries
1958 public ITimeGraphEntry
[] getExpandedElements() {
1959 return fTimeGraphCtrl
.getExpandedElements();
1963 * Add a tree listener
1966 * The listener to add
1968 public void addTreeListener(ITimeGraphTreeListener listener
) {
1969 fTimeGraphCtrl
.addTreeListener(listener
);
1973 * Remove a tree listener
1976 * The listener to remove
1978 public void removeTreeListener(ITimeGraphTreeListener listener
) {
1979 fTimeGraphCtrl
.removeTreeListener(listener
);
1983 * Get the reset scale action.
1985 * @return The Action object
1987 public Action
getResetScaleAction() {
1988 if (fResetScaleAction
== null) {
1990 fResetScaleAction
= new Action() {
1993 resetStartFinishTime();
1996 fResetScaleAction
.setText(Messages
.TmfTimeGraphViewer_ResetScaleActionNameText
);
1997 fResetScaleAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ResetScaleActionToolTipText
);
1998 fResetScaleAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HOME_MENU
));
2000 return fResetScaleAction
;
2004 * Get the show legend action.
2006 * @return The Action object
2008 public Action
getShowLegendAction() {
2009 if (fShowLegendAction
== null) {
2011 fShowLegendAction
= new Action() {
2017 fShowLegendAction
.setText(Messages
.TmfTimeGraphViewer_LegendActionNameText
);
2018 fShowLegendAction
.setToolTipText(Messages
.TmfTimeGraphViewer_LegendActionToolTipText
);
2019 fShowLegendAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_LEGEND
));
2022 return fShowLegendAction
;
2026 * Get the the next event action.
2028 * @return The action object
2030 public Action
getNextEventAction() {
2031 if (fNextEventAction
== null) {
2032 fNextEventAction
= new Action() {
2034 public void runWithEvent(Event event
) {
2035 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2036 selectNextEvent(extend
);
2040 fNextEventAction
.setText(Messages
.TmfTimeGraphViewer_NextStateChangeActionNameText
);
2041 fNextEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextStateChangeActionToolTipText
);
2042 fNextEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_STATE_CHANGE
));
2045 return fNextEventAction
;
2049 * Get the previous event action.
2051 * @return The Action object
2053 public Action
getPreviousEventAction() {
2054 if (fPrevEventAction
== null) {
2055 fPrevEventAction
= new Action() {
2057 public void runWithEvent(Event event
) {
2058 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2059 selectPrevEvent(extend
);
2063 fPrevEventAction
.setText(Messages
.TmfTimeGraphViewer_PreviousStateChangeActionNameText
);
2064 fPrevEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousStateChangeActionToolTipText
);
2065 fPrevEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_STATE_CHANGE
));
2068 return fPrevEventAction
;
2072 * Get the next item action.
2074 * @return The Action object
2076 public Action
getNextItemAction() {
2077 if (fNextItemAction
== null) {
2079 fNextItemAction
= new Action() {
2085 fNextItemAction
.setText(Messages
.TmfTimeGraphViewer_NextItemActionNameText
);
2086 fNextItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextItemActionToolTipText
);
2087 fNextItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_ITEM
));
2089 return fNextItemAction
;
2093 * Get the previous item action.
2095 * @return The Action object
2097 public Action
getPreviousItemAction() {
2098 if (fPreviousItemAction
== null) {
2100 fPreviousItemAction
= new Action() {
2106 fPreviousItemAction
.setText(Messages
.TmfTimeGraphViewer_PreviousItemActionNameText
);
2107 fPreviousItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousItemActionToolTipText
);
2108 fPreviousItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_ITEM
));
2110 return fPreviousItemAction
;
2114 * Get the zoom in action
2116 * @return The Action object
2118 public Action
getZoomInAction() {
2119 if (fZoomInAction
== null) {
2120 fZoomInAction
= new Action() {
2126 fZoomInAction
.setText(Messages
.TmfTimeGraphViewer_ZoomInActionNameText
);
2127 fZoomInAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomInActionToolTipText
);
2128 fZoomInAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_IN_MENU
));
2130 return fZoomInAction
;
2134 * Get the zoom out action
2136 * @return The Action object
2138 public Action
getZoomOutAction() {
2139 if (fZoomOutAction
== null) {
2140 fZoomOutAction
= new Action() {
2146 fZoomOutAction
.setText(Messages
.TmfTimeGraphViewer_ZoomOutActionNameText
);
2147 fZoomOutAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomOutActionToolTipText
);
2148 fZoomOutAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_OUT_MENU
));
2150 return fZoomOutAction
;
2154 * Get the hide arrows action
2156 * @param dialogSettings
2157 * The dialog settings section where the state should be stored,
2160 * @return The Action object
2162 public Action
getHideArrowsAction(final IDialogSettings dialogSettings
) {
2163 if (fHideArrowsAction
== null) {
2164 fHideArrowsAction
= new Action(Messages
.TmfTimeGraphViewer_HideArrowsActionNameText
, IAction
.AS_CHECK_BOX
) {
2167 boolean hideArrows
= fHideArrowsAction
.isChecked();
2168 fTimeGraphCtrl
.hideArrows(hideArrows
);
2170 if (dialogSettings
!= null) {
2171 dialogSettings
.put(HIDE_ARROWS_KEY
, hideArrows
);
2173 if (fFollowArrowFwdAction
!= null) {
2174 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
2176 if (fFollowArrowBwdAction
!= null) {
2177 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
2181 fHideArrowsAction
.setToolTipText(Messages
.TmfTimeGraphViewer_HideArrowsActionToolTipText
);
2182 fHideArrowsAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HIDE_ARROWS
));
2183 if (dialogSettings
!= null) {
2184 boolean hideArrows
= dialogSettings
.getBoolean(HIDE_ARROWS_KEY
);
2185 fTimeGraphCtrl
.hideArrows(hideArrows
);
2186 fHideArrowsAction
.setChecked(hideArrows
);
2187 if (fFollowArrowFwdAction
!= null) {
2188 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
2190 if (fFollowArrowBwdAction
!= null) {
2191 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
2195 return fHideArrowsAction
;
2199 * Get the follow arrow forward action.
2201 * @return The Action object
2203 public Action
getFollowArrowFwdAction() {
2204 if (fFollowArrowFwdAction
== null) {
2205 fFollowArrowFwdAction
= new Action() {
2207 public void runWithEvent(Event event
) {
2208 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2209 fTimeGraphCtrl
.followArrowFwd(extend
);
2210 adjustVerticalScrollBar();
2213 fFollowArrowFwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionNameText
);
2214 fFollowArrowFwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText
);
2215 fFollowArrowFwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_FORWARD
));
2216 if (fHideArrowsAction
!= null) {
2217 fFollowArrowFwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2220 return fFollowArrowFwdAction
;
2224 * Get the follow arrow backward action.
2226 * @return The Action object
2228 public Action
getFollowArrowBwdAction() {
2229 if (fFollowArrowBwdAction
== null) {
2230 fFollowArrowBwdAction
= new Action() {
2232 public void runWithEvent(Event event
) {
2233 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2234 fTimeGraphCtrl
.followArrowBwd(extend
);
2235 adjustVerticalScrollBar();
2238 fFollowArrowBwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionNameText
);
2239 fFollowArrowBwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText
);
2240 fFollowArrowBwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_BACKWARD
));
2241 if (fHideArrowsAction
!= null) {
2242 fFollowArrowBwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2245 return fFollowArrowBwdAction
;
2249 * Get the show filter dialog action.
2251 * @return The Action object
2254 public ShowFilterDialogAction
getShowFilterDialogAction() {
2255 if (fShowFilterDialogAction
== null) {
2256 fShowFilterDialogAction
= new ShowFilterDialogAction(this);
2258 return fShowFilterDialogAction
;
2262 * Get the toggle bookmark action.
2264 * @return The Action object
2267 public Action
getToggleBookmarkAction() {
2268 if (fToggleBookmarkAction
== null) {
2269 fToggleBookmarkAction
= new Action() {
2271 public void runWithEvent(Event event
) {
2272 IMarkerEvent selectedBookmark
= getBookmarkAtSelection();
2273 if (selectedBookmark
== null) {
2274 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2275 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2276 final AddBookmarkDialog dialog
= new AddBookmarkDialog(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell(), null);
2277 if (dialog
.open() == Window
.OK
) {
2278 final String label
= dialog
.getValue();
2279 final RGBA rgba
= dialog
.getColorValue();
2280 IMarkerEvent bookmark
= new MarkerEvent(null, time
, duration
, IMarkerEvent
.BOOKMARKS
, rgba
, label
, true);
2281 fCurrentBookmark
.add(bookmark
);
2283 updateMarkerActions();
2284 getControl().redraw();
2285 fireBookmarkAdded(bookmark
);
2288 fCurrentBookmark
.remove(selectedBookmark
);
2290 updateMarkerActions();
2291 getControl().redraw();
2292 fireBookmarkRemoved(selectedBookmark
);
2296 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2297 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2298 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2300 return fToggleBookmarkAction
;
2304 * Get the next marker action.
2306 * @return The Action object
2309 public Action
getNextMarkerAction() {
2310 if (fNextMarkerAction
== null) {
2311 fNextMarkerAction
= new Action(Messages
.TmfTimeGraphViewer_NextMarkerActionText
, IAction
.AS_DROP_DOWN_MENU
) {
2313 public void runWithEvent(Event event
) {
2314 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2316 extendToNextMarker();
2322 fNextMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextMarkerActionText
);
2323 fNextMarkerAction
.setImageDescriptor(NEXT_BOOKMARK
);
2324 fNextMarkerAction
.setMenuCreator(new IMenuCreator () {
2327 public void dispose() {
2335 public Menu
getMenu(Control parent
) {
2339 menu
= new Menu(parent
);
2340 for (String category
: fMarkerCategories
) {
2341 final Action action
= new Action(category
, IAction
.AS_CHECK_BOX
) {
2343 public void runWithEvent(Event event
) {
2345 fSkippedMarkerCategories
.remove(getText());
2347 fSkippedMarkerCategories
.add(getText());
2349 updateMarkerActions();
2352 action
.setEnabled(!fHiddenMarkerCategories
.contains(category
));
2353 action
.setChecked(action
.isEnabled() && !fSkippedMarkerCategories
.contains(category
));
2354 new ActionContributionItem(action
).fill(menu
, -1);
2360 public Menu
getMenu(Menu parent
) {
2365 return fNextMarkerAction
;
2369 * Get the previous marker action.
2371 * @return The Action object
2374 public Action
getPreviousMarkerAction() {
2375 if (fPreviousMarkerAction
== null) {
2376 fPreviousMarkerAction
= new Action() {
2378 public void runWithEvent(Event event
) {
2379 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2381 extendToPrevMarker();
2387 fPreviousMarkerAction
.setText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2388 fPreviousMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2389 fPreviousMarkerAction
.setImageDescriptor(PREVIOUS_BOOKMARK
);
2391 return fPreviousMarkerAction
;
2395 * Get the show markers menu.
2397 * @return The menu manager object
2400 public MenuManager
getMarkersMenu() {
2401 if (fMarkersMenu
== null) {
2402 fMarkersMenu
= new MenuManager(Messages
.TmfTimeGraphViewer_ShowMarkersMenuText
);
2403 fMarkersMenu
.setRemoveAllWhenShown(true);
2404 fMarkersMenu
.addMenuListener(new IMenuListener() {
2406 public void menuAboutToShow(IMenuManager manager
) {
2407 for (String category
: fMarkerCategories
) {
2408 final Action action
= new Action(category
, IAction
.AS_CHECK_BOX
) {
2410 public void runWithEvent(Event event
) {
2411 setMarkerCategoryVisible(getText(), isChecked());
2414 action
.setChecked(!fHiddenMarkerCategories
.contains(category
));
2415 manager
.add(action
);
2420 return fMarkersMenu
;
2424 * Select the next marker that begins at or after the current selection
2425 * begin time. Markers that begin at the same time are ordered by end time.
2427 private void selectNextMarker() {
2428 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2429 if (markers
== null) {
2432 for (IMarkerEvent marker
: markers
) {
2433 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2434 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2435 if ((marker
.getTime() > time
||
2436 (marker
.getTime() == time
&& marker
.getDuration() > duration
))
2437 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2438 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration(), false);
2439 ensureVisible(marker
.getTime());
2440 notifyRangeListeners();
2441 fTimeGraphCtrl
.updateStatusLine();
2448 * Select the previous marker that begins at or before the current selection
2449 * begin time. Markers that begin at the same time are ordered by end time.
2451 private void selectPrevMarker() {
2452 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2453 if (markers
== null) {
2456 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2457 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2458 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2459 IMarkerEvent marker
= markers
.get(i
);
2460 if ((marker
.getTime() < time
||
2461 (marker
.getTime() == time
&& marker
.getDuration() < duration
))
2462 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2463 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration(), false);
2464 ensureVisible(marker
.getTime());
2465 notifyRangeListeners();
2466 fTimeGraphCtrl
.updateStatusLine();
2473 * Extend the selection to the closest next marker end time.
2475 private void extendToNextMarker() {
2476 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2477 if (markers
== null) {
2480 IMarkerEvent nextMarker
= null;
2481 for (IMarkerEvent marker
: markers
) {
2482 if (marker
.getTime() + marker
.getDuration() > fSelectionEnd
2483 && !fSkippedMarkerCategories
.contains(marker
.getCategory())
2484 && (nextMarker
== null || marker
.getTime() + marker
.getDuration() < nextMarker
.getTime() + nextMarker
.getDuration())) {
2485 nextMarker
= marker
;
2488 if (nextMarker
!= null) {
2489 setSelectionRangeNotify(fSelectionBegin
, nextMarker
.getTime() + nextMarker
.getDuration(), true);
2490 fTimeGraphCtrl
.updateStatusLine();
2495 * Extend the selection to the closest previous marker start time.
2497 private void extendToPrevMarker() {
2498 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2499 if (markers
== null) {
2502 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2503 IMarkerEvent marker
= markers
.get(i
);
2504 if (marker
.getTime() < fSelectionEnd
2505 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2506 setSelectionRangeNotify(fSelectionBegin
, marker
.getTime(), true);
2507 fTimeGraphCtrl
.updateStatusLine();
2513 private IMarkerEvent
getBookmarkAtSelection() {
2514 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2515 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2516 for (IMarkerEvent bookmark
: fCurrentBookmark
) {
2517 if (bookmark
.getTime() == time
&& bookmark
.getDuration() == duration
) {
2524 private void updateMarkerActions() {
2525 boolean enabled
= (fTime0Bound
!= SWT
.DEFAULT
|| fTime1Bound
!= SWT
.DEFAULT
) && fShowMarkerActionsEnabled
;
2526 if (fToggleBookmarkAction
!= null) {
2527 if (getBookmarkAtSelection() != null) {
2528 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2529 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2530 fToggleBookmarkAction
.setImageDescriptor(REMOVE_BOOKMARK
);
2532 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2533 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2534 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2536 fToggleBookmarkAction
.setEnabled(enabled
);
2538 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2539 if (markers
== null) {
2540 markers
= Collections
.emptyList();
2542 if (fPreviousMarkerAction
!= null) {
2543 fPreviousMarkerAction
.setEnabled(enabled
&& !markers
.isEmpty());
2545 if (fNextMarkerAction
!= null) {
2546 fNextMarkerAction
.setEnabled(enabled
&& !markers
.isEmpty());
2550 private void updateMarkerList() {
2551 List
<IMarkerEvent
> markers
= new ArrayList
<>();
2552 for (IMarkerEvent marker
: fMarkers
) {
2553 if (!fHiddenMarkerCategories
.contains(marker
.getCategory())) {
2554 markers
.add(marker
);
2557 if (!fHiddenMarkerCategories
.contains(IMarkerEvent
.BOOKMARKS
)) {
2558 markers
.addAll(fCurrentBookmark
);
2560 Collections
.sort(markers
, new MarkerComparator());
2561 fTimeGraphCtrl
.setMarkers(markers
);
2562 fMarkerAxisCtrl
.setMarkers(markers
);
2565 private void adjustHorizontalScrollBar() {
2566 long time0
= getTime0();
2567 long time1
= getTime1();
2568 long timeMin
= getMinTime();
2569 long timeMax
= getMaxTime();
2570 long delta
= timeMax
- timeMin
;
2572 int thumb
= H_SCROLLBAR_MAX
;
2574 // Thumb size (page size)
2575 thumb
= Math
.max(1, (int) (H_SCROLLBAR_MAX
* ((double) (time1
- time0
) / delta
)));
2576 // At the beginning of visible window
2577 timePos
= (int) (H_SCROLLBAR_MAX
* ((double) (time0
- timeMin
) / delta
));
2579 fHorizontalScrollBar
.setValues(timePos
, 0, H_SCROLLBAR_MAX
, thumb
, Math
.max(1, thumb
/ 2), Math
.max(2, thumb
));
2582 private void adjustVerticalScrollBar() {
2583 int topIndex
= fTimeGraphCtrl
.getTopIndex();
2584 int countPerPage
= fTimeGraphCtrl
.countPerPage();
2585 int expandedElementCount
= fTimeGraphCtrl
.getExpandedElementCount();
2586 if (topIndex
+ countPerPage
> expandedElementCount
) {
2587 fTimeGraphCtrl
.setTopIndex(Math
.max(0, expandedElementCount
- countPerPage
));
2590 int selection
= fTimeGraphCtrl
.getTopIndex();
2592 int max
= Math
.max(1, expandedElementCount
- 1);
2593 int thumb
= Math
.min(max
, Math
.max(1, countPerPage
- 1));
2595 int pageIncrement
= Math
.max(1, countPerPage
);
2596 fVerticalScrollBar
.setValues(selection
, min
, max
, thumb
, increment
, pageIncrement
);
2601 * a {@link MenuDetectListener}
2602 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2604 public void addTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2605 fTimeGraphCtrl
.addTimeGraphEntryMenuListener(listener
);
2610 * a {@link MenuDetectListener}
2611 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2613 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2614 fTimeGraphCtrl
.removeTimeGraphEntryMenuListener(listener
);
2619 * a {@link MenuDetectListener}
2620 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2622 public void addTimeEventMenuListener(MenuDetectListener listener
) {
2623 fTimeGraphCtrl
.addTimeEventMenuListener(listener
);
2628 * a {@link MenuDetectListener}
2629 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2631 public void removeTimeEventMenuListener(MenuDetectListener listener
) {
2632 fTimeGraphCtrl
.removeTimeEventMenuListener(listener
);
2637 * The filter object to be attached to the view
2639 public void addFilter(@NonNull ViewerFilter filter
) {
2640 fTimeGraphCtrl
.addFilter(filter
);
2646 * The filter object to be attached to the view
2648 public void removeFilter(@NonNull ViewerFilter filter
) {
2649 fTimeGraphCtrl
.removeFilter(filter
);
2654 * Returns this viewer's filters.
2656 * @return an array of viewer filters
2659 public @NonNull ViewerFilter
[] getFilters() {
2660 return fTimeGraphCtrl
.getFilters();
2664 * Sets the filters, replacing any previous filters, and triggers
2665 * refiltering of the elements.
2668 * an array of viewer filters, or null
2671 public void setFilters(@NonNull ViewerFilter
[] filters
) {
2672 fTimeGraphCtrl
.setFilters(filters
);
2677 * Return the time alignment information
2679 * @return the time alignment information
2681 * @see ITmfTimeAligned
2685 public TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo() {
2686 return fTimeGraphCtrl
.getTimeViewAlignmentInfo();
2690 * Return the available width for the time-axis.
2692 * @see ITmfTimeAligned
2694 * @param requestedOffset
2695 * the requested offset
2696 * @return the available width for the time-axis
2700 public int getAvailableWidth(int requestedOffset
) {
2701 int totalWidth
= fTimeAlignedComposite
.getSize().x
;
2702 return Math
.min(totalWidth
, Math
.max(0, totalWidth
- requestedOffset
));
2706 * Perform the alignment operation.
2709 * the alignment offset
2711 * the alignment width
2713 * @see ITmfTimeAligned
2717 public void performAlign(int offset
, int width
) {
2718 fTimeGraphCtrl
.performAlign(offset
);
2719 int alignmentWidth
= width
;
2720 int size
= fTimeAlignedComposite
.getSize().x
;
2721 GridLayout layout
= (GridLayout
) fTimeAlignedComposite
.getLayout();
2722 int marginSize
= size
- alignmentWidth
- offset
;
2723 layout
.marginRight
= Math
.max(0, marginSize
);
2724 fTimeAlignedComposite
.layout();
2728 public synchronized void setPinned(boolean pinned
) {
2729 super.setPinned(pinned
);
2730 boolean enabled
= !pinned
;
2732 fTimeGraphCtrl
.setPinned(pinned
);
2733 fTimeScaleCtrl
.setPinned(pinned
);
2734 fMarkerAxisCtrl
.setPinned(pinned
);
2736 fHorizontalScrollBar
.setEnabled(enabled
);
2737 fHorizontalScrollBar
.setVisible(enabled
);
2739 fMouseWheelListeners
.setHorizontalScrollEnabled(enabled
);
2740 fMouseWheelListeners
.setZoomEnabled(enabled
);
2742 fKeyListeners
.setAllEnabled(enabled
);
2744 fMarkersMenu
.setVisible(enabled
);
2747 fCurrentBookmark
.clear();
2748 fCurrentBookmark
.addAll(fSyncedBookmark
);
2751 if (fResetScaleAction
!= null) {
2752 fResetScaleAction
.setEnabled(enabled
);
2754 if (fShowLegendAction
!= null) {
2755 fShowLegendAction
.setEnabled(enabled
);
2757 if (fNextEventAction
!= null) {
2758 fNextEventAction
.setEnabled(enabled
);
2760 if (fPrevEventAction
!= null) {
2761 fPrevEventAction
.setEnabled(enabled
);
2763 if (fNextItemAction
!= null) {
2764 fNextItemAction
.setEnabled(enabled
);
2766 if (fPreviousItemAction
!= null) {
2767 fPreviousItemAction
.setEnabled(enabled
);
2769 if (fZoomInAction
!= null) {
2770 fZoomInAction
.setEnabled(enabled
);
2772 if (fZoomOutAction
!= null) {
2773 fZoomOutAction
.setEnabled(enabled
);
2775 if (fHideArrowsAction
!= null) {
2776 fHideArrowsAction
.setEnabled(enabled
);
2778 if (fFollowArrowFwdAction
!= null) {
2779 fFollowArrowFwdAction
.setEnabled(enabled
);
2781 if (fFollowArrowBwdAction
!= null) {
2782 fFollowArrowBwdAction
.setEnabled(enabled
);
2784 if (fShowFilterDialogAction
!= null) {
2785 fShowFilterDialogAction
.setEnabled(enabled
);
2787 if (fToggleBookmarkAction
!= null) {
2788 fToggleBookmarkAction
.setEnabled(enabled
);
2791 fShowMarkerActionsEnabled
= enabled
;
2792 fMarkersUpdateEnabled
= enabled
;
2793 updateMarkerActions();