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
.views
.ITmfTimeAligned
;
72 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.ShowFilterDialogAction
;
73 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.TimeGraphLegend
;
74 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
75 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.IMarkerEvent
;
76 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
77 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
78 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.MarkerEvent
;
79 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.IMarkerAxisListener
;
80 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.ITimeDataProvider
;
81 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeDataProviderCyclesConverter
;
82 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphColorScheme
;
83 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphControl
;
84 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphMarkerAxis
;
85 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphScale
;
86 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphTooltipHandler
;
87 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
88 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
89 import org
.eclipse
.ui
.PlatformUI
;
92 * Generic time graph viewer implementation
94 * @author Patrick Tasse, and others
96 public class TimeGraphViewer
implements ITimeDataProvider
, IMarkerAxisListener
, SelectionListener
{
98 /** Constant indicating that all levels of the time graph should be expanded */
99 public static final int ALL_LEVELS
= AbstractTreeViewer
.ALL_LEVELS
;
101 private static final int DEFAULT_NAME_WIDTH
= 200;
102 private static final int MIN_NAME_WIDTH
= 6;
103 private static final int MAX_NAME_WIDTH
= 1000;
104 private static final int DEFAULT_HEIGHT
= 22;
105 private static final String HIDE_ARROWS_KEY
= "hide.arrows"; //$NON-NLS-1$
106 private static final long DEFAULT_FREQUENCY
= 1000000000L;
107 private static final int H_SCROLLBAR_MAX
= Integer
.MAX_VALUE
- 1;
109 private static final ImageDescriptor ADD_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ADD_BOOKMARK
);
110 private static final ImageDescriptor NEXT_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_BOOKMARK
);
111 private static final ImageDescriptor PREVIOUS_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREVIOUS_BOOKMARK
);
112 private static final ImageDescriptor REMOVE_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_REMOVE_BOOKMARK
);
114 private long fMinTimeInterval
;
115 private ITimeGraphEntry fSelectedEntry
;
116 private long fBeginTime
= SWT
.DEFAULT
; // The user-specified bounds start time
117 private long fEndTime
= SWT
.DEFAULT
; // The user-specified bounds end time
118 private long fTime0
= SWT
.DEFAULT
; // The current window start time
119 private long fTime1
= SWT
.DEFAULT
; // The current window end time
120 private long fSelectionBegin
= SWT
.DEFAULT
;
121 private long fSelectionEnd
= SWT
.DEFAULT
;
122 private long fTime0Bound
= SWT
.DEFAULT
; // The bounds start time
123 private long fTime1Bound
= SWT
.DEFAULT
; // The bounds end time
124 private long fTime0ExtSynch
= SWT
.DEFAULT
;
125 private long fTime1ExtSynch
= SWT
.DEFAULT
;
126 private boolean fTimeRangeFixed
;
127 private int fNameWidthPref
= DEFAULT_NAME_WIDTH
;
128 private int fMinNameWidth
= MIN_NAME_WIDTH
;
129 private int fNameWidth
;
130 private Composite fDataViewer
;
132 private TimeGraphControl fTimeGraphCtrl
;
133 private TimeGraphScale fTimeScaleCtrl
;
134 private TimeGraphMarkerAxis fMarkerAxisCtrl
;
135 private Slider fHorizontalScrollBar
;
136 private Slider fVerticalScrollBar
;
137 private @NonNull TimeGraphColorScheme fColorScheme
= new TimeGraphColorScheme();
138 private Object fInputElement
;
139 private ITimeGraphContentProvider fTimeGraphContentProvider
;
140 private ITimeGraphPresentationProvider fTimeGraphProvider
;
141 private @NonNull ITimeDataProvider fTimeDataProvider
= this;
142 private TimeGraphTooltipHandler fToolTipHandler
;
144 private List
<ITimeGraphSelectionListener
> fSelectionListeners
= new ArrayList
<>();
145 private List
<ITimeGraphTimeListener
> fTimeListeners
= new ArrayList
<>();
146 private List
<ITimeGraphRangeListener
> fRangeListeners
= new ArrayList
<>();
147 private List
<ITimeGraphBookmarkListener
> fBookmarkListeners
= new ArrayList
<>();
149 // Time format, using Epoch reference, Relative time format(default),
151 private TimeFormat fTimeFormat
= TimeFormat
.RELATIVE
;
152 // Clock frequency to use for Cycles time format
153 private long fClockFrequency
= DEFAULT_FREQUENCY
;
154 private int fBorderWidth
= 0;
155 private int fTimeScaleHeight
= DEFAULT_HEIGHT
;
157 private Action fResetScaleAction
;
158 private Action fShowLegendAction
;
159 private Action fNextEventAction
;
160 private Action fPrevEventAction
;
161 private Action fNextItemAction
;
162 private Action fPreviousItemAction
;
163 private Action fZoomInAction
;
164 private Action fZoomOutAction
;
165 private Action fHideArrowsAction
;
166 private Action fFollowArrowFwdAction
;
167 private Action fFollowArrowBwdAction
;
168 private ShowFilterDialogAction fShowFilterDialogAction
;
169 private Action fToggleBookmarkAction
;
170 private Action fNextMarkerAction
;
171 private Action fPreviousMarkerAction
;
172 private MenuManager fMarkersMenu
;
174 /** The list of bookmarks */
175 private final List
<IMarkerEvent
> fBookmarks
= new ArrayList
<>();
177 /** The list of marker categories */
178 private final List
<String
> fMarkerCategories
= new ArrayList
<>();
180 /** The set of hidden marker categories */
181 private final Set
<String
> fHiddenMarkerCategories
= new HashSet
<>();
183 /** The set of skipped marker categories */
184 private final Set
<String
> fSkippedMarkerCategories
= new HashSet
<>();
186 /** The list of markers */
187 private final List
<IMarkerEvent
> fMarkers
= new ArrayList
<>();
189 private ListenerNotifier fListenerNotifier
;
191 private Composite fTimeAlignedComposite
;
193 private class ListenerNotifier
extends Thread
{
194 private static final long DELAY
= 400L;
195 private static final long POLLING_INTERVAL
= 10L;
196 private long fLastUpdateTime
= Long
.MAX_VALUE
;
197 private boolean fSelectionChanged
= false;
198 private boolean fTimeRangeUpdated
= false;
199 private boolean fTimeSelected
= false;
203 while ((System
.currentTimeMillis() - fLastUpdateTime
) < DELAY
) {
205 Thread
.sleep(POLLING_INTERVAL
);
206 } catch (Exception e
) {
210 Display
.getDefault().asyncExec(new Runnable() {
213 if (fListenerNotifier
!= ListenerNotifier
.this) {
216 fListenerNotifier
= null;
217 if (ListenerNotifier
.this.isInterrupted() || fDataViewer
.isDisposed()) {
220 if (fSelectionChanged
) {
221 fireSelectionChanged(fSelectedEntry
);
223 if (fTimeRangeUpdated
) {
224 fireTimeRangeUpdated(fTime0
, fTime1
);
227 fireTimeSelected(fSelectionBegin
, fSelectionEnd
);
233 public void selectionChanged() {
234 fSelectionChanged
= true;
235 fLastUpdateTime
= System
.currentTimeMillis();
238 public void timeRangeUpdated() {
239 fTimeRangeUpdated
= true;
240 fLastUpdateTime
= System
.currentTimeMillis();
243 public void timeSelected() {
244 fTimeSelected
= true;
245 fLastUpdateTime
= System
.currentTimeMillis();
248 public boolean hasSelectionChanged() {
249 return fSelectionChanged
;
252 public boolean hasTimeRangeUpdated() {
253 return fTimeRangeUpdated
;
256 public boolean hasTimeSelected() {
257 return fTimeSelected
;
261 private final static class MarkerComparator
implements Comparator
<IMarkerEvent
> {
263 public int compare(IMarkerEvent o1
, IMarkerEvent o2
) {
264 int res
= Long
.compare(o1
.getTime(), o2
.getTime());
268 return Long
.compare(o1
.getDuration(), o2
.getDuration());
273 * Standard constructor.
275 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
278 * The parent UI composite object
282 public TimeGraphViewer(Composite parent
, int style
) {
283 createDataViewer(parent
, style
);
284 fTimeGraphContentProvider
= new TimeGraphContentProvider();
288 * Sets the timegraph content provider used by this timegraph viewer.
290 * @param timeGraphContentProvider
291 * the timegraph content provider
293 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
) {
294 fTimeGraphContentProvider
= timeGraphContentProvider
;
298 * Gets the timegraph content provider used by this timegraph viewer.
300 * @return the timegraph content provider
302 public ITimeGraphContentProvider
getTimeGraphContentProvider() {
303 return fTimeGraphContentProvider
;
307 * Sets the timegraph presentation provider used by this timegraph viewer.
309 * @param timeGraphProvider
310 * the timegraph provider
312 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider
) {
313 fTimeGraphProvider
= timeGraphProvider
;
314 fTimeGraphCtrl
.setTimeGraphProvider(timeGraphProvider
);
315 fToolTipHandler
= new TimeGraphTooltipHandler(fTimeGraphProvider
, fTimeDataProvider
);
316 fToolTipHandler
.activateHoverHelp(fTimeGraphCtrl
);
320 * Sets the tree columns for this time graph combo's filter dialog.
322 * @param columnNames the tree column names
325 public void setFilterColumns(String
[] columnNames
) {
326 getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames
);
330 * Sets the tree content provider used by the filter dialog
332 * @param contentProvider the tree content provider
335 public void setFilterContentProvider(ITreeContentProvider contentProvider
) {
336 getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider
);
340 * Sets the tree label provider used by the filter dialog
342 * @param labelProvider the tree label provider
345 public void setFilterLabelProvider(ITableLabelProvider labelProvider
) {
346 getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider
);
350 * Sets or clears the input for this time graph viewer.
352 * @param inputElement
353 * The input of this time graph viewer, or <code>null</code> if
356 public void setInput(Object inputElement
) {
357 fInputElement
= inputElement
;
358 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(inputElement
);
359 fListenerNotifier
= null;
360 if (fTimeGraphCtrl
!= null) {
363 fSelectionBegin
= SWT
.DEFAULT
;
364 fSelectionEnd
= SWT
.DEFAULT
;
365 updateMarkerActions();
366 fSelectedEntry
= null;
367 refreshAllData(input
);
372 * Gets the input for this time graph viewer.
374 * @return The input of this time graph viewer, or <code>null</code> if none
376 public Object
getInput() {
377 return fInputElement
;
381 * Sets (or clears if null) the list of links to display on this combo
384 * the links to display in this time graph combo
386 public void setLinks(List
<ILinkEvent
> links
) {
387 if (fTimeGraphCtrl
!= null) {
388 fTimeGraphCtrl
.refreshArrows(links
);
395 public void refresh() {
396 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(fInputElement
);
398 refreshAllData(input
);
402 * Callback for when the control is moved
407 public void controlMoved(ControlEvent e
) {
411 * Callback for when the control is resized
416 public void controlResized(ControlEvent e
) {
421 * @return The string representing the view type
423 protected String
getViewTypeStr() {
424 return "viewoption.threads"; //$NON-NLS-1$
427 int getMarginWidth() {
431 int getMarginHeight() {
436 fMinTimeInterval
= 1;
437 fSelectionBegin
= SWT
.DEFAULT
;
438 fSelectionEnd
= SWT
.DEFAULT
;
439 fNameWidth
= Utils
.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
440 fNameWidthPref
, fMinNameWidth
, MAX_NAME_WIDTH
);
444 Utils
.saveIntOption(getPreferenceString("namewidth"), fNameWidth
); //$NON-NLS-1$
448 * Create a data viewer.
454 * @return The new data viewer
456 protected Control
createDataViewer(Composite parent
, int style
) {
458 fDataViewer
= new Composite(parent
, style
) {
460 public void redraw() {
461 fTimeScaleCtrl
.redraw();
462 fTimeGraphCtrl
.redraw();
463 fMarkerAxisCtrl
.redraw();
467 fDataViewer
.addDisposeListener((e
) -> {
468 if (fMarkersMenu
!= null) {
469 fMarkersMenu
.dispose();
472 GridLayout gl
= new GridLayout(2, false);
473 gl
.marginHeight
= fBorderWidth
;
475 gl
.verticalSpacing
= 0;
476 gl
.horizontalSpacing
= 0;
477 fDataViewer
.setLayout(gl
);
479 fTimeAlignedComposite
= new Composite(fDataViewer
, style
) {
481 public void redraw() {
482 fDataViewer
.redraw();
486 GridLayout gl2
= new GridLayout(1, false);
487 gl2
.marginHeight
= fBorderWidth
;
489 gl2
.verticalSpacing
= 0;
490 gl2
.horizontalSpacing
= 0;
491 fTimeAlignedComposite
.setLayout(gl2
);
492 fTimeAlignedComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
494 fTimeScaleCtrl
= new TimeGraphScale(fTimeAlignedComposite
, fColorScheme
);
495 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
496 fTimeScaleCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
497 fTimeScaleCtrl
.setHeight(fTimeScaleHeight
);
498 fTimeScaleCtrl
.addMouseWheelListener(new MouseWheelListener() {
500 public void mouseScrolled(MouseEvent e
) {
504 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
505 fTimeGraphCtrl
.zoom(e
.count
> 0);
507 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
512 fTimeGraphCtrl
= createTimeGraphControl(fTimeAlignedComposite
, fColorScheme
);
514 fTimeGraphCtrl
.setTimeProvider(this);
515 fTimeGraphCtrl
.setTimeGraphScale(fTimeScaleCtrl
);
516 fTimeGraphCtrl
.addSelectionListener(this);
517 fTimeGraphCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
518 fTimeGraphCtrl
.addMouseWheelListener(new MouseWheelListener() {
520 public void mouseScrolled(MouseEvent e
) {
525 * On some platforms the mouse scroll event is sent to the
526 * control that has focus even if it is not under the cursor.
527 * Handle the event only if not over the time graph control.
529 Point ctrlParentCoords
= fTimeAlignedComposite
.toControl(fTimeGraphCtrl
.toDisplay(e
.x
, e
.y
));
530 Point scrollBarParentCoords
= fDataViewer
.toControl(fTimeGraphCtrl
.toDisplay(e
.x
, e
.y
));
531 if (fTimeGraphCtrl
.getBounds().contains(ctrlParentCoords
)) {
532 /* the time graph control handles the event */
533 adjustVerticalScrollBar();
534 } else if (fTimeScaleCtrl
.getBounds().contains(ctrlParentCoords
)
535 || fMarkerAxisCtrl
.getBounds().contains(ctrlParentCoords
)
536 || fHorizontalScrollBar
.getBounds().contains(scrollBarParentCoords
)) {
537 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
538 fTimeGraphCtrl
.zoom(e
.count
> 0);
540 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
543 /* over the vertical scroll bar or outside of the viewer */
544 setTopIndex(getTopIndex() - e
.count
);
548 fTimeGraphCtrl
.addKeyListener(new KeyAdapter() {
550 public void keyPressed(KeyEvent e
) {
551 if (e
.keyCode
== '.') {
552 boolean extend
= (e
.stateMask
& SWT
.SHIFT
) != 0;
554 extendToNextMarker();
558 } else if (e
.keyCode
== ',') {
559 boolean extend
= (e
.stateMask
& SWT
.SHIFT
) != 0;
561 extendToPrevMarker();
566 adjustVerticalScrollBar();
570 fMarkerAxisCtrl
= createTimeGraphMarkerAxis(fTimeAlignedComposite
, fColorScheme
, this);
571 fMarkerAxisCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
572 fMarkerAxisCtrl
.addMarkerAxisListener(this);
573 fMarkerAxisCtrl
.addMouseWheelListener(new MouseWheelListener() {
575 public void mouseScrolled(MouseEvent e
) {
579 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
580 fTimeGraphCtrl
.zoom(e
.count
> 0);
582 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
587 fVerticalScrollBar
= new Slider(fDataViewer
, SWT
.VERTICAL
| SWT
.NO_FOCUS
);
588 fVerticalScrollBar
.setLayoutData(new GridData(SWT
.DEFAULT
, SWT
.FILL
, false, true, 1, 1));
589 fVerticalScrollBar
.addSelectionListener(new SelectionAdapter() {
591 public void widgetSelected(SelectionEvent e
) {
592 setTopIndex(fVerticalScrollBar
.getSelection());
596 fHorizontalScrollBar
= new Slider(fDataViewer
, SWT
.HORIZONTAL
| SWT
.NO_FOCUS
);
597 fHorizontalScrollBar
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
598 fHorizontalScrollBar
.addListener(SWT
.MouseWheel
, new Listener() {
600 public void handleEvent(Event event
) {
601 // don't handle the immediately following SWT.Selection event
603 if (event
.count
== 0) {
606 if ((event
.stateMask
& SWT
.CTRL
) != 0) {
607 fTimeGraphCtrl
.zoom(event
.count
> 0);
609 fTimeGraphCtrl
.horizontalScroll(event
.count
> 0);
613 fHorizontalScrollBar
.addListener(SWT
.Selection
, new Listener() {
615 public void handleEvent(Event event
) {
616 int start
= fHorizontalScrollBar
.getSelection();
617 long time0
= getTime0();
618 long time1
= getTime1();
619 long timeMin
= getMinTime();
620 long timeMax
= getMaxTime();
621 long delta
= timeMax
- timeMin
;
623 long range
= time1
- time0
;
624 time0
= timeMin
+ Math
.round(delta
* ((double) start
/ H_SCROLLBAR_MAX
));
625 time1
= time0
+ range
;
627 setStartFinishTimeNotify(time0
, time1
);
631 Composite filler
= new Composite(fDataViewer
, SWT
.NONE
);
632 GridData gd
= new GridData(SWT
.DEFAULT
, SWT
.DEFAULT
, false, false);
633 gd
.heightHint
= fHorizontalScrollBar
.getSize().y
;
634 filler
.setLayoutData(gd
);
635 filler
.setLayout(new FillLayout());
637 fTimeGraphCtrl
.addControlListener(new ControlAdapter() {
639 public void controlResized(ControlEvent event
) {
644 fDataViewer
.update();
645 adjustHorizontalScrollBar();
646 adjustVerticalScrollBar();
648 fDataViewer
.addDisposeListener((e
) -> {
650 fColorScheme
.dispose();
657 * Dispose the time graph viewer.
659 public void dispose() {
660 fDataViewer
.dispose();
664 * Create a new time graph control.
667 * The parent composite
670 * @return The new TimeGraphControl
672 protected TimeGraphControl
createTimeGraphControl(Composite parent
,
673 TimeGraphColorScheme colors
) {
674 return new TimeGraphControl(parent
, colors
);
678 * Create a new time graph marker axis.
681 * The parent composite object
683 * The color scheme to use
684 * @param timeProvider
685 * The time data provider
686 * @return The new TimeGraphMarkerAxis
689 protected TimeGraphMarkerAxis
createTimeGraphMarkerAxis(Composite parent
,
690 @NonNull TimeGraphColorScheme colorScheme
, @NonNull ITimeDataProvider timeProvider
) {
691 return new TimeGraphMarkerAxis(parent
, colorScheme
, timeProvider
);
695 * Resize the controls
697 public void resizeControls() {
698 Rectangle r
= fDataViewer
.getClientArea();
704 if (fNameWidth
> width
- fMinNameWidth
) {
705 fNameWidth
= width
- fMinNameWidth
;
707 if (fNameWidth
< fMinNameWidth
) {
708 fNameWidth
= fMinNameWidth
;
710 adjustHorizontalScrollBar();
711 adjustVerticalScrollBar();
715 * Recalculate the time bounds based on the time graph entries,
716 * if the user-specified bound is set to SWT.DEFAULT.
719 * The root time graph entries in the model
721 public void setTimeRange(ITimeGraphEntry entries
[]) {
722 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
723 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
724 if (fBeginTime
!= SWT
.DEFAULT
&& fEndTime
!= SWT
.DEFAULT
) {
727 if (entries
== null || entries
.length
== 0) {
730 if (fTime0Bound
== SWT
.DEFAULT
) {
731 fTime0Bound
= Long
.MAX_VALUE
;
733 if (fTime1Bound
== SWT
.DEFAULT
) {
734 fTime1Bound
= Long
.MIN_VALUE
;
736 for (ITimeGraphEntry entry
: entries
) {
741 private void setTimeRange(ITimeGraphEntry entry
) {
742 if (fBeginTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getStartTime() != SWT
.DEFAULT
) {
743 fTime0Bound
= Math
.min(entry
.getStartTime(), fTime0Bound
);
745 if (fEndTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getEndTime() != SWT
.DEFAULT
) {
746 fTime1Bound
= Math
.max(entry
.getEndTime(), fTime1Bound
);
748 if (entry
.hasChildren()) {
749 for (ITimeGraphEntry child
: entry
.getChildren()) {
756 * Set the time bounds to the provided values.
759 * The bounds begin time, or SWT.DEFAULT to use the input bounds
761 * The bounds end time, or SWT.DEFAULT to use the input bounds
763 public void setTimeBounds(long beginTime
, long endTime
) {
764 fBeginTime
= beginTime
;
766 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
767 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
768 if (fTime0Bound
> fTime1Bound
) {
769 // only possible if both are not default
770 fBeginTime
= endTime
;
771 fEndTime
= beginTime
;
772 fTime0Bound
= fBeginTime
;
773 fTime1Bound
= fEndTime
;
775 adjustHorizontalScrollBar();
779 * Recalculate the current time window when bounds have changed.
781 public void setTimeBounds() {
782 if (!fTimeRangeFixed
) {
783 fTime0
= fTime0Bound
;
784 fTime1
= fTime1Bound
;
786 fTime0
= Math
.max(fTime0Bound
, Math
.min(fTime0
, fTime1Bound
));
787 fTime1
= Math
.max(fTime0Bound
, Math
.min(fTime1
, fTime1Bound
));
788 if (fTime1
- fTime0
< fMinTimeInterval
) {
789 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
796 private void refreshAllData(ITimeGraphEntry
[] traces
) {
798 if (fSelectionBegin
< fBeginTime
) {
799 fSelectionBegin
= fBeginTime
;
800 } else if (fSelectionBegin
> fEndTime
) {
801 fSelectionBegin
= fEndTime
;
803 if (fSelectionEnd
< fBeginTime
) {
804 fSelectionEnd
= fBeginTime
;
805 } else if (fSelectionEnd
> fEndTime
) {
806 fSelectionEnd
= fEndTime
;
808 fTimeGraphCtrl
.refreshData(traces
);
809 fTimeScaleCtrl
.redraw();
810 fMarkerAxisCtrl
.redraw();
811 updateMarkerActions();
812 adjustVerticalScrollBar();
816 * Callback for when this view is focused
818 public void setFocus() {
819 if (null != fTimeGraphCtrl
) {
820 fTimeGraphCtrl
.setFocus();
825 * Get the current focus status of this view.
827 * @return If the view is currently focused, or not
829 public boolean isInFocus() {
830 return fTimeGraphCtrl
.isInFocus();
834 * Get the view's current selection
836 * @return The entry that is selected
838 public ITimeGraphEntry
getSelection() {
839 return fTimeGraphCtrl
.getSelectedTrace();
843 * Get the index of the current selection
847 public int getSelectionIndex() {
848 return fTimeGraphCtrl
.getSelectedIndex();
852 public long getTime0() {
857 public long getTime1() {
862 public long getMinTimeInterval() {
863 return fMinTimeInterval
;
867 public int getNameSpace() {
872 public void setNameSpace(int width
) {
874 int w
= fTimeGraphCtrl
.getClientArea().width
;
875 if (fNameWidth
> w
- MIN_NAME_WIDTH
) {
876 fNameWidth
= w
- MIN_NAME_WIDTH
;
878 if (fNameWidth
< MIN_NAME_WIDTH
) {
879 fNameWidth
= MIN_NAME_WIDTH
;
881 fTimeGraphCtrl
.redraw();
882 fTimeScaleCtrl
.redraw();
883 fMarkerAxisCtrl
.redraw();
884 /* force update the controls to keep them aligned */
885 fTimeScaleCtrl
.update();
886 fMarkerAxisCtrl
.update();
887 fTimeGraphCtrl
.update();
891 public int getTimeSpace() {
892 int w
= fTimeGraphCtrl
.getClientArea().width
;
893 return w
- fNameWidth
;
897 public long getBeginTime() {
902 public long getEndTime() {
907 public long getMaxTime() {
912 public long getMinTime() {
917 public long getSelectionBegin() {
918 return fSelectionBegin
;
922 public long getSelectionEnd() {
923 return fSelectionEnd
;
927 public void setStartFinishTimeNotify(long time0
, long time1
) {
928 setStartFinishTimeInt(time0
, time1
);
929 notifyRangeListeners();
933 public void notifyStartFinishTime() {
934 notifyRangeListeners();
938 public void setStartFinishTime(long time0
, long time1
) {
939 /* if there is a pending time range, ignore this one */
940 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeRangeUpdated()) {
943 setStartFinishTimeInt(time0
, time1
);
944 updateExtSynchValues();
947 private void setStartFinishTimeInt(long time0
, long time1
) {
949 if (fTime0
< fTime0Bound
) {
950 fTime0
= fTime0Bound
;
952 if (fTime0
> fTime1Bound
) {
953 fTime0
= fTime1Bound
;
956 if (fTime1
< fTime0Bound
) {
957 fTime1
= fTime0Bound
;
959 if (fTime1
> fTime1Bound
) {
960 fTime1
= fTime1Bound
;
962 if (fTime1
- fTime0
< fMinTimeInterval
) {
963 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
965 fTimeRangeFixed
= true;
966 adjustHorizontalScrollBar();
967 fTimeGraphCtrl
.redraw();
968 fTimeScaleCtrl
.redraw();
969 fMarkerAxisCtrl
.redraw();
970 /* force update the controls to keep them aligned */
971 fTimeScaleCtrl
.update();
972 fMarkerAxisCtrl
.update();
973 fTimeGraphCtrl
.update();
977 public void resetStartFinishTime() {
978 setStartFinishTimeNotify(fTime0Bound
, fTime1Bound
);
979 fTimeRangeFixed
= false;
986 public void resetStartFinishTime(boolean notify
) {
988 setStartFinishTimeNotify(fTime0Bound
, fTime1Bound
);
990 setStartFinishTime(fTime0Bound
, fTime1Bound
);
992 fTimeRangeFixed
= false;
996 public void setSelectedTimeNotify(long time
, boolean ensureVisible
) {
997 setSelectedTimeInt(time
, ensureVisible
, true);
1001 public void setSelectedTime(long time
, boolean ensureVisible
) {
1002 /* if there is a pending time selection, ignore this one */
1003 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
1006 setSelectedTimeInt(time
, ensureVisible
, false);
1009 private void setSelectedTimeInt(long time
, boolean ensureVisible
, boolean doNotify
) {
1010 setSelectionRangeInt(time
, time
, ensureVisible
, doNotify
);
1017 public void setSelectionRangeNotify(long beginTime
, long endTime
, boolean ensureVisible
) {
1018 setSelectionRangeInt(beginTime
, endTime
, ensureVisible
, true);
1025 public void setSelectionRange(long beginTime
, long endTime
, boolean ensureVisible
) {
1026 /* if there is a pending time selection, ignore this one */
1027 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
1030 setSelectionRangeInt(beginTime
, endTime
, ensureVisible
, false);
1033 private void setSelectionRangeInt(long beginTime
, long endTime
, boolean ensureVisible
, boolean doNotify
) {
1034 long time0
= fTime0
;
1035 long time1
= fTime1
;
1036 long selectionBegin
= fSelectionBegin
;
1037 long selectionEnd
= fSelectionEnd
;
1038 fSelectionBegin
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, beginTime
));
1039 fSelectionEnd
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, endTime
));
1040 boolean changed
= (selectionBegin
!= fSelectionBegin
|| selectionEnd
!= fSelectionEnd
);
1042 if (ensureVisible
) {
1043 ensureVisible(selectionBegin
!= fSelectionBegin ? fSelectionBegin
: fSelectionEnd
);
1046 fTimeGraphCtrl
.redraw();
1047 fTimeScaleCtrl
.redraw();
1048 fMarkerAxisCtrl
.redraw();
1049 updateMarkerActions();
1051 if ((time0
!= fTime0
) || (time1
!= fTime1
)) {
1052 notifyRangeListeners();
1055 if (doNotify
&& changed
) {
1056 notifyTimeListeners();
1060 private void ensureVisible(long time
) {
1061 long timeMid
= (fTime1
- fTime0
) / 2;
1062 if (time
< fTime0
) {
1063 long dt
= fTime0
- time
+ timeMid
;
1066 } else if (time
> fTime1
) {
1067 long dt
= time
- fTime1
+ timeMid
;
1071 if (fTime0
< fTime0Bound
) {
1072 fTime1
= Math
.min(fTime1Bound
, fTime1
+ (fTime0Bound
- fTime0
));
1073 fTime0
= fTime0Bound
;
1074 } else if (fTime1
> fTime1Bound
) {
1075 fTime0
= Math
.max(fTime0Bound
, fTime0
- (fTime1
- fTime1Bound
));
1076 fTime1
= fTime1Bound
;
1078 if (fTime1
- fTime0
< fMinTimeInterval
) {
1079 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
1081 adjustHorizontalScrollBar();
1085 public void widgetDefaultSelected(SelectionEvent e
) {
1086 if (fSelectedEntry
!= getSelection()) {
1087 fSelectedEntry
= getSelection();
1088 notifySelectionListeners();
1093 public void widgetSelected(SelectionEvent e
) {
1094 if (fSelectedEntry
!= getSelection()) {
1095 fSelectedEntry
= getSelection();
1096 notifySelectionListeners();
1101 * Callback for when the next event is selected
1104 * true to extend selection range, false for single selection
1107 public void selectNextEvent(boolean extend
) {
1108 fTimeGraphCtrl
.selectNextEvent(extend
);
1109 adjustVerticalScrollBar();
1113 * Callback for when the previous event is selected
1116 * true to extend selection range, false for single selection
1119 public void selectPrevEvent(boolean extend
) {
1120 fTimeGraphCtrl
.selectPrevEvent(extend
);
1121 adjustVerticalScrollBar();
1125 * Callback for when the next item is selected
1127 public void selectNextItem() {
1128 fTimeGraphCtrl
.selectNextTrace();
1129 adjustVerticalScrollBar();
1133 * Callback for when the previous item is selected
1135 public void selectPrevItem() {
1136 fTimeGraphCtrl
.selectPrevTrace();
1137 adjustVerticalScrollBar();
1141 * Callback for the show legend action
1143 public void showLegend() {
1144 if (fDataViewer
== null || fDataViewer
.isDisposed()) {
1148 TimeGraphLegend
.open(fDataViewer
.getShell(), fTimeGraphProvider
);
1152 * Callback for the Zoom In action
1154 public void zoomIn() {
1155 fTimeGraphCtrl
.zoomIn();
1159 * Callback for the Zoom Out action
1161 public void zoomOut() {
1162 fTimeGraphCtrl
.zoomOut();
1165 private String
getPreferenceString(String string
) {
1166 return getViewTypeStr() + "." + string
; //$NON-NLS-1$
1170 * Add a selection listener
1173 * The listener to add
1175 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
1176 fSelectionListeners
.add(listener
);
1180 * Remove a selection listener
1183 * The listener to remove
1185 public void removeSelectionListener(ITimeGraphSelectionListener listener
) {
1186 fSelectionListeners
.remove(listener
);
1189 private void notifySelectionListeners() {
1190 if (fListenerNotifier
== null) {
1191 fListenerNotifier
= new ListenerNotifier();
1192 fListenerNotifier
.start();
1194 fListenerNotifier
.selectionChanged();
1197 private void fireSelectionChanged(ITimeGraphEntry selection
) {
1198 TimeGraphSelectionEvent event
= new TimeGraphSelectionEvent(this, selection
);
1200 for (ITimeGraphSelectionListener listener
: fSelectionListeners
) {
1201 listener
.selectionChanged(event
);
1206 * Add a time listener
1209 * The listener to add
1211 public void addTimeListener(ITimeGraphTimeListener listener
) {
1212 fTimeListeners
.add(listener
);
1216 * Remove a time listener
1219 * The listener to remove
1221 public void removeTimeListener(ITimeGraphTimeListener listener
) {
1222 fTimeListeners
.remove(listener
);
1225 private void notifyTimeListeners() {
1226 if (fListenerNotifier
== null) {
1227 fListenerNotifier
= new ListenerNotifier();
1228 fListenerNotifier
.start();
1230 fListenerNotifier
.timeSelected();
1233 private void fireTimeSelected(long startTime
, long endTime
) {
1234 TimeGraphTimeEvent event
= new TimeGraphTimeEvent(this, startTime
, endTime
);
1236 for (ITimeGraphTimeListener listener
: fTimeListeners
) {
1237 listener
.timeSelected(event
);
1242 * Add a range listener
1245 * The listener to add
1247 public void addRangeListener(ITimeGraphRangeListener listener
) {
1248 fRangeListeners
.add(listener
);
1252 * Remove a range listener
1255 * The listener to remove
1257 public void removeRangeListener(ITimeGraphRangeListener listener
) {
1258 fRangeListeners
.remove(listener
);
1261 private void notifyRangeListeners() {
1262 if (fListenerNotifier
== null) {
1263 fListenerNotifier
= new ListenerNotifier();
1264 fListenerNotifier
.start();
1266 fListenerNotifier
.timeRangeUpdated();
1269 private void fireTimeRangeUpdated(long startTime
, long endTime
) {
1270 // Check if the time has actually changed from last notification
1271 if (startTime
!= fTime0ExtSynch
|| endTime
!= fTime1ExtSynch
) {
1272 // Notify Time Scale Selection Listeners
1273 TimeGraphRangeUpdateEvent event
= new TimeGraphRangeUpdateEvent(this, startTime
, endTime
);
1275 for (ITimeGraphRangeListener listener
: fRangeListeners
) {
1276 listener
.timeRangeUpdated(event
);
1279 // update external synch values
1280 updateExtSynchValues();
1285 * Add a bookmark listener
1288 * The listener to add
1291 public void addBookmarkListener(ITimeGraphBookmarkListener listener
) {
1292 fBookmarkListeners
.add(listener
);
1296 * Remove a bookmark listener
1299 * The listener to remove
1302 public void removeBookmarkListener(ITimeGraphBookmarkListener listener
) {
1303 fBookmarkListeners
.remove(listener
);
1306 private void fireBookmarkAdded(IMarkerEvent bookmark
) {
1307 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1309 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1310 listener
.bookmarkAdded(event
);
1314 private void fireBookmarkRemoved(IMarkerEvent bookmark
) {
1315 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1317 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1318 listener
.bookmarkRemoved(event
);
1323 * Set the bookmarks list.
1326 * The bookmarks list, or null
1329 public void setBookmarks(List
<IMarkerEvent
> bookmarks
) {
1331 if (bookmarks
!= null) {
1332 fBookmarks
.addAll(bookmarks
);
1335 updateMarkerActions();
1339 * Get the bookmarks list.
1341 * @return The bookmarks list
1344 public List
<IMarkerEvent
> getBookmarks() {
1345 return Collections
.unmodifiableList(fBookmarks
);
1349 * Set the list of marker categories.
1352 * The list of marker categories, or null
1355 public void setMarkerCategories(List
<String
> categories
) {
1356 fMarkerCategories
.clear();
1357 if (categories
!= null) {
1358 fMarkerCategories
.addAll(categories
);
1360 fMarkerCategories
.add(IMarkerEvent
.BOOKMARKS
);
1361 fMarkerAxisCtrl
.setMarkerCategories(fMarkerCategories
);
1368 public void setMarkerCategoryVisible(String category
, boolean visible
) {
1369 boolean changed
= false;
1371 changed
= fHiddenMarkerCategories
.remove(category
);
1373 changed
= fHiddenMarkerCategories
.add(category
);
1377 updateMarkerActions();
1378 getControl().redraw();
1383 * Set the markers list.
1386 * The markers list, or null
1389 public void setMarkers(List
<IMarkerEvent
> markers
) {
1391 if (markers
!= null) {
1392 fMarkers
.addAll(markers
);
1395 updateMarkerActions();
1399 * Get the markers list.
1401 * @return The markers list, or null
1404 public List
<IMarkerEvent
> getMarkers() {
1405 return Collections
.unmodifiableList(fMarkers
);
1409 * Callback to set a selected event in the view
1412 * The event that was selected
1414 * The source of this selection event
1416 public void setSelectedEvent(ITimeEvent event
, Object source
) {
1417 if (event
== null || source
== this) {
1420 fSelectedEntry
= event
.getEntry();
1421 fTimeGraphCtrl
.selectItem(fSelectedEntry
, false);
1423 setSelectedTimeInt(event
.getTime(), true, true);
1424 adjustVerticalScrollBar();
1428 * Set the seeked time of a trace
1431 * The trace that was seeked
1435 * The source of this seek event
1437 public void setSelectedTraceTime(ITimeGraphEntry trace
, long time
, Object source
) {
1438 if (trace
== null || source
== this) {
1441 fSelectedEntry
= trace
;
1442 fTimeGraphCtrl
.selectItem(trace
, false);
1444 setSelectedTimeInt(time
, true, true);
1448 * Callback for a trace selection
1451 * The trace that was selected
1453 public void setSelection(ITimeGraphEntry trace
) {
1454 /* if there is a pending selection, ignore this one */
1455 if (fListenerNotifier
!= null && fListenerNotifier
.hasSelectionChanged()) {
1458 fSelectedEntry
= trace
;
1459 fTimeGraphCtrl
.selectItem(trace
, false);
1460 adjustVerticalScrollBar();
1464 * Callback for a time window selection
1467 * Start time of the range
1469 * End time of the range
1471 * Source of the event
1473 public void setSelectVisTimeWindow(long time0
, long time1
, Object source
) {
1474 if (source
== this) {
1478 setStartFinishTimeInt(time0
, time1
);
1480 // update notification time values since we are now in synch with the
1481 // external application
1482 updateExtSynchValues();
1486 * update the cache values used to identify the need to send a time window
1487 * update to external registered listeners
1489 private void updateExtSynchValues() {
1490 // last time notification cache
1491 fTime0ExtSynch
= fTime0
;
1492 fTime1ExtSynch
= fTime1
;
1496 public TimeFormat
getTimeFormat() {
1502 * the {@link TimeFormat} used to display timestamps
1504 public void setTimeFormat(TimeFormat tf
) {
1505 this.fTimeFormat
= tf
;
1506 if (tf
== TimeFormat
.CYCLES
) {
1507 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1509 fTimeDataProvider
= this;
1511 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1512 if (fToolTipHandler
!= null) {
1513 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1518 * Sets the clock frequency. Used when the time format is set to CYCLES.
1520 * @param clockFrequency
1521 * the clock frequency in Hz
1523 public void setClockFrequency(long clockFrequency
) {
1524 fClockFrequency
= clockFrequency
;
1525 if (fTimeFormat
== TimeFormat
.CYCLES
) {
1526 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1527 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1528 if (fToolTipHandler
!= null) {
1529 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1535 * Retrieve the border width
1539 public int getBorderWidth() {
1540 return fBorderWidth
;
1544 * Set the border width
1546 * @param borderWidth
1549 public void setBorderWidth(int borderWidth
) {
1550 if (borderWidth
> -1) {
1551 this.fBorderWidth
= borderWidth
;
1552 GridLayout gl
= (GridLayout
) fDataViewer
.getLayout();
1553 gl
.marginHeight
= borderWidth
;
1558 * Retrieve the height of the header
1560 * @return The height
1562 public int getHeaderHeight() {
1563 return fTimeScaleHeight
;
1567 * Set the height of the header
1569 * @param headerHeight
1572 public void setHeaderHeight(int headerHeight
) {
1573 if (headerHeight
> -1) {
1574 this.fTimeScaleHeight
= headerHeight
;
1575 fTimeScaleCtrl
.setHeight(headerHeight
);
1580 * Retrieve the height of an item row
1582 * @return The height
1584 public int getItemHeight() {
1585 if (fTimeGraphCtrl
!= null) {
1586 return fTimeGraphCtrl
.getItemHeight();
1592 * Set the height of an item row
1597 public void setItemHeight(int rowHeight
) {
1598 if (fTimeGraphCtrl
!= null) {
1599 fTimeGraphCtrl
.setItemHeight(rowHeight
);
1604 * Set the minimum item width
1609 public void setMinimumItemWidth(int width
) {
1610 if (fTimeGraphCtrl
!= null) {
1611 fTimeGraphCtrl
.setMinimumItemWidth(width
);
1616 * Set the width for the name column
1621 public void setNameWidthPref(int width
) {
1622 fNameWidthPref
= width
;
1630 * Retrieve the configure width for the name column
1636 public int getNameWidthPref(int width
) {
1637 return fNameWidthPref
;
1641 * Returns the primary control associated with this viewer.
1643 * @return the SWT control which displays this viewer's content
1645 public Control
getControl() {
1650 * Returns the time graph control associated with this viewer.
1652 * @return the time graph control
1654 public TimeGraphControl
getTimeGraphControl() {
1655 return fTimeGraphCtrl
;
1659 * Returns the time graph scale associated with this viewer.
1661 * @return the time graph scale
1663 public TimeGraphScale
getTimeGraphScale() {
1664 return fTimeScaleCtrl
;
1668 * Returns the composite containing all the controls that are time aligned,
1669 * i.e. TimeGraphScale, TimeGraphControl.
1671 * @return the time based composite
1674 public Composite
getTimeAlignedComposite() {
1675 return fTimeAlignedComposite
;
1679 * Return the x coordinate corresponding to a time
1683 * @return the x coordinate corresponding to the time
1685 public int getXForTime(long time
) {
1686 return fTimeGraphCtrl
.getXForTime(time
);
1690 * Return the time corresponding to an x coordinate
1694 * @return the time corresponding to the x coordinate
1696 public long getTimeAtX(int x
) {
1697 return fTimeGraphCtrl
.getTimeAtX(x
);
1701 * Get the selection provider
1703 * @return the selection provider
1705 public ISelectionProvider
getSelectionProvider() {
1706 return fTimeGraphCtrl
;
1710 * Wait for the cursor
1713 * Wait indefinitely?
1715 public void waitCursor(boolean waitInd
) {
1716 fTimeGraphCtrl
.waitCursor(waitInd
);
1720 * Get the horizontal scroll bar object
1722 * @return The scroll bar
1724 public Slider
getHorizontalBar() {
1725 return fHorizontalScrollBar
;
1729 * Get the vertical scroll bar object
1731 * @return The scroll bar
1733 public Slider
getVerticalBar() {
1734 return fVerticalScrollBar
;
1738 * Set the given index as the top one
1741 * The index that will go to the top
1743 public void setTopIndex(int index
) {
1744 fTimeGraphCtrl
.setTopIndex(index
);
1745 adjustVerticalScrollBar();
1749 * Retrieve the current top index
1751 * @return The top index
1753 public int getTopIndex() {
1754 return fTimeGraphCtrl
.getTopIndex();
1758 * Sets the auto-expand level to be used for new entries discovered when
1759 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1760 * means that there is no auto-expand; 1 means that top-level entries are
1761 * expanded, but not their children; 2 means that top-level entries are
1762 * expanded, and their children, but not grand-children; and so on.
1764 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1768 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1769 * levels of the tree
1771 public void setAutoExpandLevel(int level
) {
1772 fTimeGraphCtrl
.setAutoExpandLevel(level
);
1776 * Returns the auto-expand level.
1778 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1779 * the tree are expanded automatically
1780 * @see #setAutoExpandLevel
1782 public int getAutoExpandLevel() {
1783 return fTimeGraphCtrl
.getAutoExpandLevel();
1787 * Get the expanded state of an entry.
1791 * @return true if the entry is expanded, false if collapsed
1794 public boolean getExpandedState(ITimeGraphEntry entry
) {
1795 return fTimeGraphCtrl
.getExpandedState(entry
);
1799 * Set the expanded state of an entry
1802 * The entry to expand/collapse
1804 * True for expanded, false for collapsed
1806 public void setExpandedState(ITimeGraphEntry entry
, boolean expanded
) {
1807 fTimeGraphCtrl
.setExpandedState(entry
, expanded
);
1808 adjustVerticalScrollBar();
1812 * Collapses all nodes of the viewer's tree, starting with the root.
1814 public void collapseAll() {
1815 fTimeGraphCtrl
.collapseAll();
1816 adjustVerticalScrollBar();
1820 * Expands all entries of the viewer's tree, starting with the root.
1822 public void expandAll() {
1823 fTimeGraphCtrl
.expandAll();
1824 adjustVerticalScrollBar();
1828 * Select an entry and reveal it
1831 * The entry to select
1834 public void selectAndReveal(@NonNull ITimeGraphEntry entry
) {
1835 final ITimeGraphEntry parent
= entry
.getParent();
1836 if (parent
!= null) {
1837 fTimeGraphCtrl
.setExpandedState(parent
, true);
1839 fSelectedEntry
= entry
;
1840 fTimeGraphCtrl
.selectItem(entry
, false);
1841 adjustVerticalScrollBar();
1845 * Get the number of expanded (visible) time graph entries. This includes
1846 * leafs and does not include filtered-out entries.
1848 * @return The number of expanded (visible) time graph entries
1850 public int getExpandedElementCount() {
1851 return fTimeGraphCtrl
.getExpandedElementCount();
1855 * Get the expanded (visible) time graph entries. This includes leafs and
1856 * does not include filtered-out entries.
1858 * @return The array of expanded (visible) time graph entries
1860 public ITimeGraphEntry
[] getExpandedElements() {
1861 return fTimeGraphCtrl
.getExpandedElements();
1865 * Add a tree listener
1868 * The listener to add
1870 public void addTreeListener(ITimeGraphTreeListener listener
) {
1871 fTimeGraphCtrl
.addTreeListener(listener
);
1875 * Remove a tree listener
1878 * The listener to remove
1880 public void removeTreeListener(ITimeGraphTreeListener listener
) {
1881 fTimeGraphCtrl
.removeTreeListener(listener
);
1885 * Get the reset scale action.
1887 * @return The Action object
1889 public Action
getResetScaleAction() {
1890 if (fResetScaleAction
== null) {
1892 fResetScaleAction
= new Action() {
1895 resetStartFinishTime();
1898 fResetScaleAction
.setText(Messages
.TmfTimeGraphViewer_ResetScaleActionNameText
);
1899 fResetScaleAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ResetScaleActionToolTipText
);
1900 fResetScaleAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HOME_MENU
));
1902 return fResetScaleAction
;
1906 * Get the show legend action.
1908 * @return The Action object
1910 public Action
getShowLegendAction() {
1911 if (fShowLegendAction
== null) {
1913 fShowLegendAction
= new Action() {
1919 fShowLegendAction
.setText(Messages
.TmfTimeGraphViewer_LegendActionNameText
);
1920 fShowLegendAction
.setToolTipText(Messages
.TmfTimeGraphViewer_LegendActionToolTipText
);
1921 fShowLegendAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_LEGEND
));
1924 return fShowLegendAction
;
1928 * Get the the next event action.
1930 * @return The action object
1932 public Action
getNextEventAction() {
1933 if (fNextEventAction
== null) {
1934 fNextEventAction
= new Action() {
1936 public void runWithEvent(Event event
) {
1937 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
1938 selectNextEvent(extend
);
1942 fNextEventAction
.setText(Messages
.TmfTimeGraphViewer_NextEventActionNameText
);
1943 fNextEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextEventActionToolTipText
);
1944 fNextEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_EVENT
));
1947 return fNextEventAction
;
1951 * Get the previous event action.
1953 * @return The Action object
1955 public Action
getPreviousEventAction() {
1956 if (fPrevEventAction
== null) {
1957 fPrevEventAction
= new Action() {
1959 public void runWithEvent(Event event
) {
1960 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
1961 selectPrevEvent(extend
);
1965 fPrevEventAction
.setText(Messages
.TmfTimeGraphViewer_PreviousEventActionNameText
);
1966 fPrevEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousEventActionToolTipText
);
1967 fPrevEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_EVENT
));
1970 return fPrevEventAction
;
1974 * Get the next item action.
1976 * @return The Action object
1978 public Action
getNextItemAction() {
1979 if (fNextItemAction
== null) {
1981 fNextItemAction
= new Action() {
1987 fNextItemAction
.setText(Messages
.TmfTimeGraphViewer_NextItemActionNameText
);
1988 fNextItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextItemActionToolTipText
);
1989 fNextItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_ITEM
));
1991 return fNextItemAction
;
1995 * Get the previous item action.
1997 * @return The Action object
1999 public Action
getPreviousItemAction() {
2000 if (fPreviousItemAction
== null) {
2002 fPreviousItemAction
= new Action() {
2008 fPreviousItemAction
.setText(Messages
.TmfTimeGraphViewer_PreviousItemActionNameText
);
2009 fPreviousItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousItemActionToolTipText
);
2010 fPreviousItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_ITEM
));
2012 return fPreviousItemAction
;
2016 * Get the zoom in action
2018 * @return The Action object
2020 public Action
getZoomInAction() {
2021 if (fZoomInAction
== null) {
2022 fZoomInAction
= new Action() {
2028 fZoomInAction
.setText(Messages
.TmfTimeGraphViewer_ZoomInActionNameText
);
2029 fZoomInAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomInActionToolTipText
);
2030 fZoomInAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_IN_MENU
));
2032 return fZoomInAction
;
2036 * Get the zoom out action
2038 * @return The Action object
2040 public Action
getZoomOutAction() {
2041 if (fZoomOutAction
== null) {
2042 fZoomOutAction
= new Action() {
2048 fZoomOutAction
.setText(Messages
.TmfTimeGraphViewer_ZoomOutActionNameText
);
2049 fZoomOutAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomOutActionToolTipText
);
2050 fZoomOutAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_OUT_MENU
));
2052 return fZoomOutAction
;
2056 * Get the hide arrows action
2058 * @param dialogSettings
2059 * The dialog settings section where the state should be stored,
2062 * @return The Action object
2064 public Action
getHideArrowsAction(final IDialogSettings dialogSettings
) {
2065 if (fHideArrowsAction
== null) {
2066 fHideArrowsAction
= new Action(Messages
.TmfTimeGraphViewer_HideArrowsActionNameText
, IAction
.AS_CHECK_BOX
) {
2069 boolean hideArrows
= fHideArrowsAction
.isChecked();
2070 fTimeGraphCtrl
.hideArrows(hideArrows
);
2072 if (dialogSettings
!= null) {
2073 dialogSettings
.put(HIDE_ARROWS_KEY
, hideArrows
);
2075 if (fFollowArrowFwdAction
!= null) {
2076 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
2078 if (fFollowArrowBwdAction
!= null) {
2079 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
2083 fHideArrowsAction
.setToolTipText(Messages
.TmfTimeGraphViewer_HideArrowsActionToolTipText
);
2084 fHideArrowsAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HIDE_ARROWS
));
2085 if (dialogSettings
!= null) {
2086 boolean hideArrows
= dialogSettings
.getBoolean(HIDE_ARROWS_KEY
);
2087 fTimeGraphCtrl
.hideArrows(hideArrows
);
2088 fHideArrowsAction
.setChecked(hideArrows
);
2089 if (fFollowArrowFwdAction
!= null) {
2090 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
2092 if (fFollowArrowBwdAction
!= null) {
2093 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
2097 return fHideArrowsAction
;
2101 * Get the follow arrow forward action.
2103 * @return The Action object
2105 public Action
getFollowArrowFwdAction() {
2106 if (fFollowArrowFwdAction
== null) {
2107 fFollowArrowFwdAction
= new Action() {
2109 public void runWithEvent(Event event
) {
2110 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2111 fTimeGraphCtrl
.followArrowFwd(extend
);
2112 adjustVerticalScrollBar();
2115 fFollowArrowFwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionNameText
);
2116 fFollowArrowFwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText
);
2117 fFollowArrowFwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_FORWARD
));
2118 if (fHideArrowsAction
!= null) {
2119 fFollowArrowFwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2122 return fFollowArrowFwdAction
;
2126 * Get the follow arrow backward action.
2128 * @return The Action object
2130 public Action
getFollowArrowBwdAction() {
2131 if (fFollowArrowBwdAction
== null) {
2132 fFollowArrowBwdAction
= new Action() {
2134 public void runWithEvent(Event event
) {
2135 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2136 fTimeGraphCtrl
.followArrowBwd(extend
);
2137 adjustVerticalScrollBar();
2140 fFollowArrowBwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionNameText
);
2141 fFollowArrowBwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText
);
2142 fFollowArrowBwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_BACKWARD
));
2143 if (fHideArrowsAction
!= null) {
2144 fFollowArrowBwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2147 return fFollowArrowBwdAction
;
2151 * Get the show filter dialog action.
2153 * @return The Action object
2156 public ShowFilterDialogAction
getShowFilterDialogAction() {
2157 if (fShowFilterDialogAction
== null) {
2158 fShowFilterDialogAction
= new ShowFilterDialogAction(this);
2160 return fShowFilterDialogAction
;
2164 * Get the toggle bookmark action.
2166 * @return The Action object
2169 public Action
getToggleBookmarkAction() {
2170 if (fToggleBookmarkAction
== null) {
2171 fToggleBookmarkAction
= new Action() {
2173 public void runWithEvent(Event event
) {
2174 IMarkerEvent selectedBookmark
= getBookmarkAtSelection();
2175 if (selectedBookmark
== null) {
2176 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2177 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2178 final AddBookmarkDialog dialog
= new AddBookmarkDialog(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell(), null);
2179 if (dialog
.open() == Window
.OK
) {
2180 final String label
= dialog
.getValue();
2181 final RGBA rgba
= dialog
.getColorValue();
2182 IMarkerEvent bookmark
= new MarkerEvent(null, time
, duration
, IMarkerEvent
.BOOKMARKS
, rgba
, label
, true);
2183 fBookmarks
.add(bookmark
);
2185 updateMarkerActions();
2186 getControl().redraw();
2187 fireBookmarkAdded(bookmark
);
2190 fBookmarks
.remove(selectedBookmark
);
2192 updateMarkerActions();
2193 getControl().redraw();
2194 fireBookmarkRemoved(selectedBookmark
);
2198 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2199 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2200 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2202 return fToggleBookmarkAction
;
2206 * Get the next marker action.
2208 * @return The Action object
2211 public Action
getNextMarkerAction() {
2212 if (fNextMarkerAction
== null) {
2213 fNextMarkerAction
= new Action(Messages
.TmfTimeGraphViewer_NextMarkerActionText
, IAction
.AS_DROP_DOWN_MENU
) {
2215 public void runWithEvent(Event event
) {
2216 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2218 extendToNextMarker();
2224 fNextMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextMarkerActionText
);
2225 fNextMarkerAction
.setImageDescriptor(NEXT_BOOKMARK
);
2226 fNextMarkerAction
.setMenuCreator(new IMenuCreator () {
2229 public void dispose() {
2237 public Menu
getMenu(Control parent
) {
2241 menu
= new Menu(parent
);
2242 for (String category
: fMarkerCategories
) {
2243 final Action action
= new Action(category
, IAction
.AS_CHECK_BOX
) {
2245 public void runWithEvent(Event event
) {
2247 fSkippedMarkerCategories
.remove(getText());
2249 fSkippedMarkerCategories
.add(getText());
2251 updateMarkerActions();
2254 action
.setEnabled(!fHiddenMarkerCategories
.contains(category
));
2255 action
.setChecked(action
.isEnabled() && !fSkippedMarkerCategories
.contains(category
));
2256 new ActionContributionItem(action
).fill(menu
, -1);
2262 public Menu
getMenu(Menu parent
) {
2267 return fNextMarkerAction
;
2271 * Get the previous marker action.
2273 * @return The Action object
2276 public Action
getPreviousMarkerAction() {
2277 if (fPreviousMarkerAction
== null) {
2278 fPreviousMarkerAction
= new Action() {
2280 public void runWithEvent(Event event
) {
2281 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2283 extendToPrevMarker();
2289 fPreviousMarkerAction
.setText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2290 fPreviousMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2291 fPreviousMarkerAction
.setImageDescriptor(PREVIOUS_BOOKMARK
);
2293 return fPreviousMarkerAction
;
2297 * Get the show markers menu.
2299 * @return The menu manager object
2302 public MenuManager
getMarkersMenu() {
2303 if (fMarkersMenu
== null) {
2304 fMarkersMenu
= new MenuManager(Messages
.TmfTimeGraphViewer_ShowMarkersMenuText
);
2305 fMarkersMenu
.setRemoveAllWhenShown(true);
2306 fMarkersMenu
.addMenuListener(new IMenuListener() {
2308 public void menuAboutToShow(IMenuManager manager
) {
2309 for (String category
: fMarkerCategories
) {
2310 final Action action
= new Action(category
, IAction
.AS_CHECK_BOX
) {
2312 public void runWithEvent(Event event
) {
2313 setMarkerCategoryVisible(getText(), isChecked());
2316 action
.setChecked(!fHiddenMarkerCategories
.contains(category
));
2317 manager
.add(action
);
2322 return fMarkersMenu
;
2326 * Select the next marker that begins at or after the current selection
2327 * begin time. Markers that begin at the same time are ordered by end time.
2329 private void selectNextMarker() {
2330 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2331 if (markers
== null) {
2334 for (IMarkerEvent marker
: markers
) {
2335 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2336 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2337 if ((marker
.getTime() > time
||
2338 (marker
.getTime() == time
&& marker
.getDuration() > duration
))
2339 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2340 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration(), false);
2341 ensureVisible(marker
.getTime());
2342 notifyRangeListeners();
2343 fTimeGraphCtrl
.updateStatusLine();
2350 * Select the previous marker that begins at or before the current selection
2351 * begin time. Markers that begin at the same time are ordered by end time.
2353 private void selectPrevMarker() {
2354 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2355 if (markers
== null) {
2358 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2359 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2360 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2361 IMarkerEvent marker
= markers
.get(i
);
2362 if ((marker
.getTime() < time
||
2363 (marker
.getTime() == time
&& marker
.getDuration() < duration
))
2364 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2365 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration(), false);
2366 ensureVisible(marker
.getTime());
2367 notifyRangeListeners();
2368 fTimeGraphCtrl
.updateStatusLine();
2375 * Extend the selection to the closest next marker end time.
2377 private void extendToNextMarker() {
2378 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2379 if (markers
== null) {
2382 IMarkerEvent nextMarker
= null;
2383 for (IMarkerEvent marker
: markers
) {
2384 if (marker
.getTime() + marker
.getDuration() > fSelectionEnd
2385 && !fSkippedMarkerCategories
.contains(marker
.getCategory())
2386 && (nextMarker
== null || marker
.getTime() + marker
.getDuration() < nextMarker
.getTime() + nextMarker
.getDuration())) {
2387 nextMarker
= marker
;
2390 if (nextMarker
!= null) {
2391 setSelectionRangeNotify(fSelectionBegin
, nextMarker
.getTime() + nextMarker
.getDuration(), true);
2392 fTimeGraphCtrl
.updateStatusLine();
2397 * Extend the selection to the closest previous marker start time.
2399 private void extendToPrevMarker() {
2400 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2401 if (markers
== null) {
2404 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2405 IMarkerEvent marker
= markers
.get(i
);
2406 if (marker
.getTime() < fSelectionEnd
2407 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2408 setSelectionRangeNotify(fSelectionBegin
, marker
.getTime(), true);
2409 fTimeGraphCtrl
.updateStatusLine();
2415 private IMarkerEvent
getBookmarkAtSelection() {
2416 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2417 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2418 for (IMarkerEvent bookmark
: fBookmarks
) {
2419 if (bookmark
.getTime() == time
&& bookmark
.getDuration() == duration
) {
2426 private void updateMarkerActions() {
2427 boolean enabled
= fTime0Bound
!= SWT
.DEFAULT
|| fTime1Bound
!= SWT
.DEFAULT
;
2428 if (fToggleBookmarkAction
!= null) {
2429 if (getBookmarkAtSelection() != null) {
2430 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2431 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2432 fToggleBookmarkAction
.setImageDescriptor(REMOVE_BOOKMARK
);
2434 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2435 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2436 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2438 fToggleBookmarkAction
.setEnabled(enabled
);
2440 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2441 if (markers
== null) {
2442 markers
= Collections
.emptyList();
2444 if (fPreviousMarkerAction
!= null) {
2445 fPreviousMarkerAction
.setEnabled(enabled
&& !markers
.isEmpty());
2447 if (fNextMarkerAction
!= null) {
2448 fNextMarkerAction
.setEnabled(enabled
&& !markers
.isEmpty());
2452 private void updateMarkerList() {
2453 List
<IMarkerEvent
> markers
= new ArrayList
<>();
2454 for (IMarkerEvent marker
: fMarkers
) {
2455 if (!fHiddenMarkerCategories
.contains(marker
.getCategory())) {
2456 markers
.add(marker
);
2459 if (!fHiddenMarkerCategories
.contains(IMarkerEvent
.BOOKMARKS
)) {
2460 markers
.addAll(fBookmarks
);
2462 Collections
.sort(markers
, new MarkerComparator());
2463 fTimeGraphCtrl
.setMarkers(markers
);
2464 fMarkerAxisCtrl
.setMarkers(markers
);
2467 private void adjustHorizontalScrollBar() {
2468 long time0
= getTime0();
2469 long time1
= getTime1();
2470 long timeMin
= getMinTime();
2471 long timeMax
= getMaxTime();
2472 long delta
= timeMax
- timeMin
;
2474 int thumb
= H_SCROLLBAR_MAX
;
2476 // Thumb size (page size)
2477 thumb
= Math
.max(1, (int) (H_SCROLLBAR_MAX
* ((double) (time1
- time0
) / delta
)));
2478 // At the beginning of visible window
2479 timePos
= (int) (H_SCROLLBAR_MAX
* ((double) (time0
- timeMin
) / delta
));
2481 fHorizontalScrollBar
.setValues(timePos
, 0, H_SCROLLBAR_MAX
, thumb
, Math
.max(1, thumb
/ 2), Math
.max(2, thumb
));
2484 private void adjustVerticalScrollBar() {
2485 int topIndex
= fTimeGraphCtrl
.getTopIndex();
2486 int countPerPage
= fTimeGraphCtrl
.countPerPage();
2487 int expandedElementCount
= fTimeGraphCtrl
.getExpandedElementCount();
2488 if (topIndex
+ countPerPage
> expandedElementCount
) {
2489 fTimeGraphCtrl
.setTopIndex(Math
.max(0, expandedElementCount
- countPerPage
));
2492 int selection
= fTimeGraphCtrl
.getTopIndex();
2494 int max
= Math
.max(1, expandedElementCount
- 1);
2495 int thumb
= Math
.min(max
, Math
.max(1, countPerPage
- 1));
2497 int pageIncrement
= Math
.max(1, countPerPage
);
2498 fVerticalScrollBar
.setValues(selection
, min
, max
, thumb
, increment
, pageIncrement
);
2503 * a {@link MenuDetectListener}
2504 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2506 public void addTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2507 fTimeGraphCtrl
.addTimeGraphEntryMenuListener(listener
);
2512 * a {@link MenuDetectListener}
2513 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2515 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2516 fTimeGraphCtrl
.removeTimeGraphEntryMenuListener(listener
);
2521 * a {@link MenuDetectListener}
2522 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2524 public void addTimeEventMenuListener(MenuDetectListener listener
) {
2525 fTimeGraphCtrl
.addTimeEventMenuListener(listener
);
2530 * a {@link MenuDetectListener}
2531 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2533 public void removeTimeEventMenuListener(MenuDetectListener listener
) {
2534 fTimeGraphCtrl
.removeTimeEventMenuListener(listener
);
2539 * The filter object to be attached to the view
2541 public void addFilter(@NonNull ViewerFilter filter
) {
2542 fTimeGraphCtrl
.addFilter(filter
);
2548 * The filter object to be attached to the view
2550 public void removeFilter(@NonNull ViewerFilter filter
) {
2551 fTimeGraphCtrl
.removeFilter(filter
);
2556 * Returns this viewer's filters.
2558 * @return an array of viewer filters
2561 public @NonNull ViewerFilter
[] getFilters() {
2562 return fTimeGraphCtrl
.getFilters();
2566 * Sets the filters, replacing any previous filters, and triggers
2567 * refiltering of the elements.
2570 * an array of viewer filters, or null
2573 public void setFilters(@NonNull ViewerFilter
[] filters
) {
2574 fTimeGraphCtrl
.setFilters(filters
);
2579 * Return the time alignment information
2581 * @return the time alignment information
2583 * @see ITmfTimeAligned
2587 public TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo() {
2588 return fTimeGraphCtrl
.getTimeViewAlignmentInfo();
2592 * Return the available width for the time-axis.
2594 * @see ITmfTimeAligned
2596 * @param requestedOffset
2597 * the requested offset
2598 * @return the available width for the time-axis
2602 public int getAvailableWidth(int requestedOffset
) {
2603 int totalWidth
= fTimeAlignedComposite
.getSize().x
;
2604 return Math
.min(totalWidth
, Math
.max(0, totalWidth
- requestedOffset
));
2608 * Perform the alignment operation.
2611 * the alignment offset
2613 * the alignment width
2615 * @see ITmfTimeAligned
2619 public void performAlign(int offset
, int width
) {
2620 fTimeGraphCtrl
.performAlign(offset
);
2621 int alignmentWidth
= width
;
2622 int size
= fTimeAlignedComposite
.getSize().x
;
2623 GridLayout layout
= (GridLayout
) fTimeAlignedComposite
.getLayout();
2624 int marginSize
= size
- alignmentWidth
- offset
;
2625 layout
.marginRight
= Math
.max(0, marginSize
);
2626 fTimeAlignedComposite
.layout();