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
.DisposeEvent
;
46 import org
.eclipse
.swt
.events
.DisposeListener
;
47 import org
.eclipse
.swt
.events
.KeyAdapter
;
48 import org
.eclipse
.swt
.events
.KeyEvent
;
49 import org
.eclipse
.swt
.events
.MenuDetectListener
;
50 import org
.eclipse
.swt
.events
.MouseEvent
;
51 import org
.eclipse
.swt
.events
.MouseWheelListener
;
52 import org
.eclipse
.swt
.events
.SelectionAdapter
;
53 import org
.eclipse
.swt
.events
.SelectionEvent
;
54 import org
.eclipse
.swt
.events
.SelectionListener
;
55 import org
.eclipse
.swt
.graphics
.Point
;
56 import org
.eclipse
.swt
.graphics
.RGBA
;
57 import org
.eclipse
.swt
.graphics
.Rectangle
;
58 import org
.eclipse
.swt
.layout
.FillLayout
;
59 import org
.eclipse
.swt
.layout
.GridData
;
60 import org
.eclipse
.swt
.layout
.GridLayout
;
61 import org
.eclipse
.swt
.widgets
.Composite
;
62 import org
.eclipse
.swt
.widgets
.Control
;
63 import org
.eclipse
.swt
.widgets
.Display
;
64 import org
.eclipse
.swt
.widgets
.Event
;
65 import org
.eclipse
.swt
.widgets
.Listener
;
66 import org
.eclipse
.swt
.widgets
.Menu
;
67 import org
.eclipse
.swt
.widgets
.Slider
;
68 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
69 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.ITmfImageConstants
;
70 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Messages
;
71 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.dialogs
.AddBookmarkDialog
;
72 import org
.eclipse
.tracecompass
.tmf
.ui
.signal
.TmfTimeViewAlignmentInfo
;
73 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.ITmfTimeAligned
;
74 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.ShowFilterDialogAction
;
75 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.TimeGraphLegend
;
76 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
77 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.IMarkerEvent
;
78 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
79 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
80 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.MarkerEvent
;
81 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.IMarkerAxisListener
;
82 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.ITimeDataProvider
;
83 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeDataProviderCyclesConverter
;
84 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphColorScheme
;
85 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphControl
;
86 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphMarkerAxis
;
87 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphScale
;
88 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphTooltipHandler
;
89 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
90 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
91 import org
.eclipse
.ui
.PlatformUI
;
94 * Generic time graph viewer implementation
96 * @author Patrick Tasse, and others
98 public class TimeGraphViewer
implements ITimeDataProvider
, IMarkerAxisListener
, SelectionListener
{
100 /** Constant indicating that all levels of the time graph should be expanded */
101 public static final int ALL_LEVELS
= AbstractTreeViewer
.ALL_LEVELS
;
103 private static final int DEFAULT_NAME_WIDTH
= 200;
104 private static final int MIN_NAME_WIDTH
= 6;
105 private static final int MAX_NAME_WIDTH
= 1000;
106 private static final int DEFAULT_HEIGHT
= 22;
107 private static final String HIDE_ARROWS_KEY
= "hide.arrows"; //$NON-NLS-1$
108 private static final long DEFAULT_FREQUENCY
= 1000000000L;
109 private static final int H_SCROLLBAR_MAX
= Integer
.MAX_VALUE
- 1;
111 private static final ImageDescriptor ADD_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ADD_BOOKMARK
);
112 private static final ImageDescriptor NEXT_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_BOOKMARK
);
113 private static final ImageDescriptor PREVIOUS_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREVIOUS_BOOKMARK
);
114 private static final ImageDescriptor REMOVE_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_REMOVE_BOOKMARK
);
116 private long fMinTimeInterval
;
117 private ITimeGraphEntry fSelectedEntry
;
118 private long fBeginTime
= SWT
.DEFAULT
; // The user-specified bounds start time
119 private long fEndTime
= SWT
.DEFAULT
; // The user-specified bounds end time
120 private long fTime0
= SWT
.DEFAULT
; // The current window start time
121 private long fTime1
= SWT
.DEFAULT
; // The current window end time
122 private long fSelectionBegin
= SWT
.DEFAULT
;
123 private long fSelectionEnd
= SWT
.DEFAULT
;
124 private long fTime0Bound
= SWT
.DEFAULT
; // The bounds start time
125 private long fTime1Bound
= SWT
.DEFAULT
; // The bounds end time
126 private long fTime0ExtSynch
= SWT
.DEFAULT
;
127 private long fTime1ExtSynch
= SWT
.DEFAULT
;
128 private boolean fTimeRangeFixed
;
129 private int fNameWidthPref
= DEFAULT_NAME_WIDTH
;
130 private int fMinNameWidth
= MIN_NAME_WIDTH
;
131 private int fNameWidth
;
132 private Composite fDataViewer
;
134 private TimeGraphControl fTimeGraphCtrl
;
135 private TimeGraphScale fTimeScaleCtrl
;
136 private TimeGraphMarkerAxis fMarkerAxisCtrl
;
137 private Slider fHorizontalScrollBar
;
138 private Slider fVerticalScrollBar
;
139 private @NonNull TimeGraphColorScheme fColorScheme
= new TimeGraphColorScheme();
140 private Object fInputElement
;
141 private ITimeGraphContentProvider fTimeGraphContentProvider
;
142 private ITimeGraphPresentationProvider fTimeGraphProvider
;
143 private @NonNull ITimeDataProvider fTimeDataProvider
= this;
144 private TimeGraphTooltipHandler fToolTipHandler
;
146 private List
<ITimeGraphSelectionListener
> fSelectionListeners
= new ArrayList
<>();
147 private List
<ITimeGraphTimeListener
> fTimeListeners
= new ArrayList
<>();
148 private List
<ITimeGraphRangeListener
> fRangeListeners
= new ArrayList
<>();
149 private List
<ITimeGraphBookmarkListener
> fBookmarkListeners
= new ArrayList
<>();
151 // Time format, using Epoch reference, Relative time format(default),
153 private TimeFormat fTimeFormat
= TimeFormat
.RELATIVE
;
154 // Clock frequency to use for Cycles time format
155 private long fClockFrequency
= DEFAULT_FREQUENCY
;
156 private int fBorderWidth
= 0;
157 private int fTimeScaleHeight
= DEFAULT_HEIGHT
;
159 private Action fResetScaleAction
;
160 private Action fShowLegendAction
;
161 private Action fNextEventAction
;
162 private Action fPrevEventAction
;
163 private Action fNextItemAction
;
164 private Action fPreviousItemAction
;
165 private Action fZoomInAction
;
166 private Action fZoomOutAction
;
167 private Action fHideArrowsAction
;
168 private Action fFollowArrowFwdAction
;
169 private Action fFollowArrowBwdAction
;
170 private ShowFilterDialogAction fShowFilterDialogAction
;
171 private Action fToggleBookmarkAction
;
172 private Action fNextMarkerAction
;
173 private Action fPreviousMarkerAction
;
174 private MenuManager fMarkersMenu
;
176 /** The list of bookmarks */
177 private final List
<IMarkerEvent
> fBookmarks
= new ArrayList
<>();
179 /** The list of marker categories */
180 private final List
<String
> fMarkerCategories
= new ArrayList
<>();
182 /** The set of hidden marker categories */
183 private final Set
<String
> fHiddenMarkerCategories
= new HashSet
<>();
185 /** The set of skipped marker categories */
186 private final Set
<String
> fSkippedMarkerCategories
= new HashSet
<>();
188 /** The list of markers */
189 private final List
<IMarkerEvent
> fMarkers
= new ArrayList
<>();
191 private ListenerNotifier fListenerNotifier
;
193 private Composite fTimeAlignedComposite
;
195 private class ListenerNotifier
extends Thread
{
196 private static final long DELAY
= 400L;
197 private static final long POLLING_INTERVAL
= 10L;
198 private long fLastUpdateTime
= Long
.MAX_VALUE
;
199 private boolean fSelectionChanged
= false;
200 private boolean fTimeRangeUpdated
= false;
201 private boolean fTimeSelected
= false;
205 while ((System
.currentTimeMillis() - fLastUpdateTime
) < DELAY
) {
207 Thread
.sleep(POLLING_INTERVAL
);
208 } catch (Exception e
) {
212 Display
.getDefault().asyncExec(new Runnable() {
215 if (fListenerNotifier
!= ListenerNotifier
.this) {
218 fListenerNotifier
= null;
219 if (ListenerNotifier
.this.isInterrupted() || fDataViewer
.isDisposed()) {
222 if (fSelectionChanged
) {
223 fireSelectionChanged(fSelectedEntry
);
225 if (fTimeRangeUpdated
) {
226 fireTimeRangeUpdated(fTime0
, fTime1
);
229 fireTimeSelected(fSelectionBegin
, fSelectionEnd
);
235 public void selectionChanged() {
236 fSelectionChanged
= true;
237 fLastUpdateTime
= System
.currentTimeMillis();
240 public void timeRangeUpdated() {
241 fTimeRangeUpdated
= true;
242 fLastUpdateTime
= System
.currentTimeMillis();
245 public void timeSelected() {
246 fTimeSelected
= true;
247 fLastUpdateTime
= System
.currentTimeMillis();
250 public boolean hasSelectionChanged() {
251 return fSelectionChanged
;
254 public boolean hasTimeRangeUpdated() {
255 return fTimeRangeUpdated
;
258 public boolean hasTimeSelected() {
259 return fTimeSelected
;
263 private final static class MarkerComparator
implements Comparator
<IMarkerEvent
> {
265 public int compare(IMarkerEvent o1
, IMarkerEvent o2
) {
266 int res
= Long
.compare(o1
.getTime(), o2
.getTime());
270 return Long
.compare(o1
.getDuration(), o2
.getDuration());
275 * Standard constructor.
277 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
280 * The parent UI composite object
284 public TimeGraphViewer(Composite parent
, int style
) {
285 createDataViewer(parent
, style
);
286 fTimeGraphContentProvider
= new TimeGraphContentProvider();
290 * Sets the timegraph content provider used by this timegraph viewer.
292 * @param timeGraphContentProvider
293 * the timegraph content provider
295 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
) {
296 fTimeGraphContentProvider
= timeGraphContentProvider
;
300 * Gets the timegraph content provider used by this timegraph viewer.
302 * @return the timegraph content provider
304 public ITimeGraphContentProvider
getTimeGraphContentProvider() {
305 return fTimeGraphContentProvider
;
309 * Sets the timegraph presentation provider used by this timegraph viewer.
311 * @param timeGraphProvider
312 * the timegraph provider
314 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider
) {
315 fTimeGraphProvider
= timeGraphProvider
;
316 fTimeGraphCtrl
.setTimeGraphProvider(timeGraphProvider
);
317 fToolTipHandler
= new TimeGraphTooltipHandler(fTimeGraphProvider
, fTimeDataProvider
);
318 fToolTipHandler
.activateHoverHelp(fTimeGraphCtrl
);
322 * Sets the tree columns for this time graph combo's filter dialog.
324 * @param columnNames the tree column names
327 public void setFilterColumns(String
[] columnNames
) {
328 getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames
);
332 * Sets the tree content provider used by the filter dialog
334 * @param contentProvider the tree content provider
337 public void setFilterContentProvider(ITreeContentProvider contentProvider
) {
338 getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider
);
342 * Sets the tree label provider used by the filter dialog
344 * @param labelProvider the tree label provider
347 public void setFilterLabelProvider(ITableLabelProvider labelProvider
) {
348 getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider
);
352 * Sets or clears the input for this time graph viewer.
354 * @param inputElement
355 * The input of this time graph viewer, or <code>null</code> if
358 public void setInput(Object inputElement
) {
359 fInputElement
= inputElement
;
360 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(inputElement
);
361 fListenerNotifier
= null;
362 if (fTimeGraphCtrl
!= null) {
365 fSelectionBegin
= SWT
.DEFAULT
;
366 fSelectionEnd
= SWT
.DEFAULT
;
367 updateMarkerActions();
368 fSelectedEntry
= null;
369 refreshAllData(input
);
374 * Gets the input for this time graph viewer.
376 * @return The input of this time graph viewer, or <code>null</code> if none
378 public Object
getInput() {
379 return fInputElement
;
383 * Sets (or clears if null) the list of links to display on this combo
386 * the links to display in this time graph combo
388 public void setLinks(List
<ILinkEvent
> links
) {
389 if (fTimeGraphCtrl
!= null) {
390 fTimeGraphCtrl
.refreshArrows(links
);
397 public void refresh() {
398 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(fInputElement
);
400 refreshAllData(input
);
404 * Callback for when the control is moved
409 public void controlMoved(ControlEvent e
) {
413 * Callback for when the control is resized
418 public void controlResized(ControlEvent e
) {
423 * @return The string representing the view type
425 protected String
getViewTypeStr() {
426 return "viewoption.threads"; //$NON-NLS-1$
429 int getMarginWidth() {
433 int getMarginHeight() {
438 fMinTimeInterval
= 1;
439 fSelectionBegin
= SWT
.DEFAULT
;
440 fSelectionEnd
= SWT
.DEFAULT
;
441 fNameWidth
= Utils
.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
442 fNameWidthPref
, fMinNameWidth
, MAX_NAME_WIDTH
);
446 Utils
.saveIntOption(getPreferenceString("namewidth"), fNameWidth
); //$NON-NLS-1$
450 * Create a data viewer.
456 * @return The new data viewer
458 protected Control
createDataViewer(Composite parent
, int style
) {
460 fDataViewer
= new Composite(parent
, style
) {
462 public void redraw() {
463 fTimeScaleCtrl
.redraw();
464 fTimeGraphCtrl
.redraw();
465 fMarkerAxisCtrl
.redraw();
469 fDataViewer
.addDisposeListener(new DisposeListener() {
471 public void widgetDisposed(DisposeEvent e
) {
472 if (fMarkersMenu
!= null) {
473 fMarkersMenu
.dispose();
477 GridLayout gl
= new GridLayout(2, false);
478 gl
.marginHeight
= fBorderWidth
;
480 gl
.verticalSpacing
= 0;
481 gl
.horizontalSpacing
= 0;
482 fDataViewer
.setLayout(gl
);
484 fTimeAlignedComposite
= new Composite(fDataViewer
, style
) {
486 public void redraw() {
487 fDataViewer
.redraw();
491 GridLayout gl2
= new GridLayout(1, false);
492 gl2
.marginHeight
= fBorderWidth
;
494 gl2
.verticalSpacing
= 0;
495 gl2
.horizontalSpacing
= 0;
496 fTimeAlignedComposite
.setLayout(gl2
);
497 fTimeAlignedComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
499 fTimeScaleCtrl
= new TimeGraphScale(fTimeAlignedComposite
, fColorScheme
);
500 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
501 fTimeScaleCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
502 fTimeScaleCtrl
.setHeight(fTimeScaleHeight
);
503 fTimeScaleCtrl
.addMouseWheelListener(new MouseWheelListener() {
505 public void mouseScrolled(MouseEvent e
) {
509 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
510 fTimeGraphCtrl
.zoom(e
.count
> 0);
512 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
517 fTimeGraphCtrl
= createTimeGraphControl(fTimeAlignedComposite
, fColorScheme
);
519 fTimeGraphCtrl
.setTimeProvider(this);
520 fTimeGraphCtrl
.setTimeGraphScale(fTimeScaleCtrl
);
521 fTimeGraphCtrl
.addSelectionListener(this);
522 fTimeGraphCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
523 fTimeGraphCtrl
.addMouseWheelListener(new MouseWheelListener() {
525 public void mouseScrolled(MouseEvent e
) {
530 * On some platforms the mouse scroll event is sent to the
531 * control that has focus even if it is not under the cursor.
532 * Handle the event only if not over the time graph control.
534 Point ctrlParentCoords
= fTimeAlignedComposite
.toControl(fTimeGraphCtrl
.toDisplay(e
.x
, e
.y
));
535 Point scrollBarParentCoords
= fDataViewer
.toControl(fTimeGraphCtrl
.toDisplay(e
.x
, e
.y
));
536 if (fTimeGraphCtrl
.getBounds().contains(ctrlParentCoords
)) {
537 /* the time graph control handles the event */
538 adjustVerticalScrollBar();
539 } else if (fTimeScaleCtrl
.getBounds().contains(ctrlParentCoords
)
540 || fMarkerAxisCtrl
.getBounds().contains(ctrlParentCoords
)
541 || fHorizontalScrollBar
.getBounds().contains(scrollBarParentCoords
)) {
542 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
543 fTimeGraphCtrl
.zoom(e
.count
> 0);
545 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
548 /* over the vertical scroll bar or outside of the viewer */
549 setTopIndex(getTopIndex() - e
.count
);
553 fTimeGraphCtrl
.addKeyListener(new KeyAdapter() {
555 public void keyPressed(KeyEvent e
) {
556 if ((e
.character
== '+' || e
.character
== '=') && ((e
.stateMask
& SWT
.CTRL
) == 0)) {
558 } else if (e
.character
== '-' && ((e
.stateMask
& SWT
.CTRL
) == 0)) {
560 } else if (e
.keyCode
== '.') {
561 boolean extend
= (e
.stateMask
& SWT
.SHIFT
) != 0;
563 extendToNextMarker();
567 } else if (e
.keyCode
== ',') {
568 boolean extend
= (e
.stateMask
& SWT
.SHIFT
) != 0;
570 extendToPrevMarker();
575 adjustVerticalScrollBar();
579 fMarkerAxisCtrl
= createTimeGraphMarkerAxis(fTimeAlignedComposite
, fColorScheme
, this);
580 fMarkerAxisCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
581 fMarkerAxisCtrl
.addMarkerAxisListener(this);
582 fMarkerAxisCtrl
.addMouseWheelListener(new MouseWheelListener() {
584 public void mouseScrolled(MouseEvent e
) {
588 if ((e
.stateMask
& SWT
.CTRL
) != 0) {
589 fTimeGraphCtrl
.zoom(e
.count
> 0);
591 fTimeGraphCtrl
.horizontalScroll(e
.count
> 0);
596 fVerticalScrollBar
= new Slider(fDataViewer
, SWT
.VERTICAL
| SWT
.NO_FOCUS
);
597 fVerticalScrollBar
.setLayoutData(new GridData(SWT
.DEFAULT
, SWT
.FILL
, false, true, 1, 1));
598 fVerticalScrollBar
.addSelectionListener(new SelectionAdapter() {
600 public void widgetSelected(SelectionEvent e
) {
601 setTopIndex(fVerticalScrollBar
.getSelection());
605 fHorizontalScrollBar
= new Slider(fDataViewer
, SWT
.HORIZONTAL
| SWT
.NO_FOCUS
);
606 fHorizontalScrollBar
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
607 fHorizontalScrollBar
.addListener(SWT
.MouseWheel
, new Listener() {
609 public void handleEvent(Event event
) {
610 // don't handle the immediately following SWT.Selection event
612 if (event
.count
== 0) {
615 if ((event
.stateMask
& SWT
.CTRL
) != 0) {
616 fTimeGraphCtrl
.zoom(event
.count
> 0);
618 fTimeGraphCtrl
.horizontalScroll(event
.count
> 0);
622 fHorizontalScrollBar
.addListener(SWT
.Selection
, new Listener() {
624 public void handleEvent(Event event
) {
625 int start
= fHorizontalScrollBar
.getSelection();
626 long time0
= getTime0();
627 long time1
= getTime1();
628 long timeMin
= getMinTime();
629 long timeMax
= getMaxTime();
630 long delta
= timeMax
- timeMin
;
632 long range
= time1
- time0
;
633 time0
= timeMin
+ Math
.round(delta
* ((double) start
/ H_SCROLLBAR_MAX
));
634 time1
= time0
+ range
;
636 setStartFinishTimeNotify(time0
, time1
);
640 Composite filler
= new Composite(fDataViewer
, SWT
.NONE
);
641 GridData gd
= new GridData(SWT
.DEFAULT
, SWT
.DEFAULT
, false, false);
642 gd
.heightHint
= fHorizontalScrollBar
.getSize().y
;
643 filler
.setLayoutData(gd
);
644 filler
.setLayout(new FillLayout());
646 fTimeGraphCtrl
.addControlListener(new ControlAdapter() {
648 public void controlResized(ControlEvent event
) {
653 fDataViewer
.update();
654 adjustHorizontalScrollBar();
655 adjustVerticalScrollBar();
662 public void dispose() {
664 fTimeGraphCtrl
.dispose();
665 fDataViewer
.dispose();
666 fColorScheme
.dispose();
670 * Create a new time graph control.
673 * The parent composite
676 * @return The new TimeGraphControl
678 protected TimeGraphControl
createTimeGraphControl(Composite parent
,
679 TimeGraphColorScheme colors
) {
680 return new TimeGraphControl(parent
, colors
);
684 * Create a new time graph marker axis.
687 * The parent composite object
689 * The color scheme to use
690 * @param timeProvider
691 * The time data provider
692 * @return The new TimeGraphMarkerAxis
695 protected TimeGraphMarkerAxis
createTimeGraphMarkerAxis(Composite parent
,
696 @NonNull TimeGraphColorScheme colorScheme
, @NonNull ITimeDataProvider timeProvider
) {
697 return new TimeGraphMarkerAxis(parent
, colorScheme
, timeProvider
);
701 * Resize the controls
703 public void resizeControls() {
704 Rectangle r
= fDataViewer
.getClientArea();
710 if (fNameWidth
> width
- fMinNameWidth
) {
711 fNameWidth
= width
- fMinNameWidth
;
713 if (fNameWidth
< fMinNameWidth
) {
714 fNameWidth
= fMinNameWidth
;
716 adjustHorizontalScrollBar();
717 adjustVerticalScrollBar();
721 * Recalculate the time bounds based on the time graph entries,
722 * if the user-specified bound is set to SWT.DEFAULT.
725 * The root time graph entries in the model
727 public void setTimeRange(ITimeGraphEntry entries
[]) {
728 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
729 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
730 if (fBeginTime
!= SWT
.DEFAULT
&& fEndTime
!= SWT
.DEFAULT
) {
733 if (entries
== null || entries
.length
== 0) {
736 if (fTime0Bound
== SWT
.DEFAULT
) {
737 fTime0Bound
= Long
.MAX_VALUE
;
739 if (fTime1Bound
== SWT
.DEFAULT
) {
740 fTime1Bound
= Long
.MIN_VALUE
;
742 for (ITimeGraphEntry entry
: entries
) {
747 private void setTimeRange(ITimeGraphEntry entry
) {
748 if (fBeginTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getStartTime() != SWT
.DEFAULT
) {
749 fTime0Bound
= Math
.min(entry
.getStartTime(), fTime0Bound
);
751 if (fEndTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getEndTime() != SWT
.DEFAULT
) {
752 fTime1Bound
= Math
.max(entry
.getEndTime(), fTime1Bound
);
754 if (entry
.hasChildren()) {
755 for (ITimeGraphEntry child
: entry
.getChildren()) {
762 * Set the time bounds to the provided values.
765 * The bounds begin time, or SWT.DEFAULT to use the input bounds
767 * The bounds end time, or SWT.DEFAULT to use the input bounds
769 public void setTimeBounds(long beginTime
, long endTime
) {
770 fBeginTime
= beginTime
;
772 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
773 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
774 if (fTime0Bound
> fTime1Bound
) {
775 // only possible if both are not default
776 fBeginTime
= endTime
;
777 fEndTime
= beginTime
;
778 fTime0Bound
= fBeginTime
;
779 fTime1Bound
= fEndTime
;
781 adjustHorizontalScrollBar();
785 * Recalculate the current time window when bounds have changed.
787 public void setTimeBounds() {
788 if (!fTimeRangeFixed
) {
789 fTime0
= fTime0Bound
;
790 fTime1
= fTime1Bound
;
792 fTime0
= Math
.max(fTime0Bound
, Math
.min(fTime0
, fTime1Bound
));
793 fTime1
= Math
.max(fTime0Bound
, Math
.min(fTime1
, fTime1Bound
));
794 if (fTime1
- fTime0
< fMinTimeInterval
) {
795 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
802 private void refreshAllData(ITimeGraphEntry
[] traces
) {
804 if (fSelectionBegin
< fBeginTime
) {
805 fSelectionBegin
= fBeginTime
;
806 } else if (fSelectionBegin
> fEndTime
) {
807 fSelectionBegin
= fEndTime
;
809 if (fSelectionEnd
< fBeginTime
) {
810 fSelectionEnd
= fBeginTime
;
811 } else if (fSelectionEnd
> fEndTime
) {
812 fSelectionEnd
= fEndTime
;
814 fTimeGraphCtrl
.refreshData(traces
);
815 fTimeScaleCtrl
.redraw();
816 fMarkerAxisCtrl
.redraw();
817 updateMarkerActions();
818 adjustVerticalScrollBar();
822 * Callback for when this view is focused
824 public void setFocus() {
825 if (null != fTimeGraphCtrl
) {
826 fTimeGraphCtrl
.setFocus();
831 * Get the current focus status of this view.
833 * @return If the view is currently focused, or not
835 public boolean isInFocus() {
836 return fTimeGraphCtrl
.isInFocus();
840 * Get the view's current selection
842 * @return The entry that is selected
844 public ITimeGraphEntry
getSelection() {
845 return fTimeGraphCtrl
.getSelectedTrace();
849 * Get the index of the current selection
853 public int getSelectionIndex() {
854 return fTimeGraphCtrl
.getSelectedIndex();
858 public long getTime0() {
863 public long getTime1() {
868 public long getMinTimeInterval() {
869 return fMinTimeInterval
;
873 public int getNameSpace() {
878 public void setNameSpace(int width
) {
880 int w
= fTimeGraphCtrl
.getClientArea().width
;
881 if (fNameWidth
> w
- MIN_NAME_WIDTH
) {
882 fNameWidth
= w
- MIN_NAME_WIDTH
;
884 if (fNameWidth
< MIN_NAME_WIDTH
) {
885 fNameWidth
= MIN_NAME_WIDTH
;
887 fTimeGraphCtrl
.redraw();
888 fTimeScaleCtrl
.redraw();
889 fMarkerAxisCtrl
.redraw();
890 /* force update the controls to keep them aligned */
891 fTimeScaleCtrl
.update();
892 fMarkerAxisCtrl
.update();
893 fTimeGraphCtrl
.update();
897 public int getTimeSpace() {
898 int w
= fTimeGraphCtrl
.getClientArea().width
;
899 return w
- fNameWidth
;
903 public long getBeginTime() {
908 public long getEndTime() {
913 public long getMaxTime() {
918 public long getMinTime() {
923 public long getSelectionBegin() {
924 return fSelectionBegin
;
928 public long getSelectionEnd() {
929 return fSelectionEnd
;
933 public void setStartFinishTimeNotify(long time0
, long time1
) {
934 setStartFinishTimeInt(time0
, time1
);
935 notifyRangeListeners();
939 public void notifyStartFinishTime() {
940 notifyRangeListeners();
944 public void setStartFinishTime(long time0
, long time1
) {
945 /* if there is a pending time range, ignore this one */
946 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeRangeUpdated()) {
949 setStartFinishTimeInt(time0
, time1
);
950 updateExtSynchValues();
953 private void setStartFinishTimeInt(long time0
, long time1
) {
955 if (fTime0
< fTime0Bound
) {
956 fTime0
= fTime0Bound
;
958 if (fTime0
> fTime1Bound
) {
959 fTime0
= fTime1Bound
;
962 if (fTime1
< fTime0Bound
) {
963 fTime1
= fTime0Bound
;
965 if (fTime1
> fTime1Bound
) {
966 fTime1
= fTime1Bound
;
968 if (fTime1
- fTime0
< fMinTimeInterval
) {
969 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
971 fTimeRangeFixed
= true;
972 adjustHorizontalScrollBar();
973 fTimeGraphCtrl
.redraw();
974 fTimeScaleCtrl
.redraw();
975 fMarkerAxisCtrl
.redraw();
976 /* force update the controls to keep them aligned */
977 fTimeScaleCtrl
.update();
978 fMarkerAxisCtrl
.update();
979 fTimeGraphCtrl
.update();
983 public void resetStartFinishTime() {
984 setStartFinishTimeNotify(fTime0Bound
, fTime1Bound
);
985 fTimeRangeFixed
= false;
989 public void setSelectedTimeNotify(long time
, boolean ensureVisible
) {
990 setSelectedTimeInt(time
, ensureVisible
, true);
994 public void setSelectedTime(long time
, boolean ensureVisible
) {
995 /* if there is a pending time selection, ignore this one */
996 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
999 setSelectedTimeInt(time
, ensureVisible
, false);
1002 private void setSelectedTimeInt(long time
, boolean ensureVisible
, boolean doNotify
) {
1003 setSelectionRangeInt(time
, time
, ensureVisible
, doNotify
);
1010 public void setSelectionRangeNotify(long beginTime
, long endTime
, boolean ensureVisible
) {
1011 setSelectionRangeInt(beginTime
, endTime
, ensureVisible
, true);
1018 public void setSelectionRange(long beginTime
, long endTime
, boolean ensureVisible
) {
1019 /* if there is a pending time selection, ignore this one */
1020 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
1023 setSelectionRangeInt(beginTime
, endTime
, ensureVisible
, false);
1026 private void setSelectionRangeInt(long beginTime
, long endTime
, boolean ensureVisible
, boolean doNotify
) {
1027 long time0
= fTime0
;
1028 long time1
= fTime1
;
1029 long selectionBegin
= fSelectionBegin
;
1030 long selectionEnd
= fSelectionEnd
;
1031 fSelectionBegin
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, beginTime
));
1032 fSelectionEnd
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, endTime
));
1033 boolean changed
= (selectionBegin
!= fSelectionBegin
|| selectionEnd
!= fSelectionEnd
);
1035 if (ensureVisible
) {
1036 ensureVisible(selectionBegin
!= fSelectionBegin ? fSelectionBegin
: fSelectionEnd
);
1039 fTimeGraphCtrl
.redraw();
1040 fTimeScaleCtrl
.redraw();
1041 fMarkerAxisCtrl
.redraw();
1042 updateMarkerActions();
1044 if ((time0
!= fTime0
) || (time1
!= fTime1
)) {
1045 notifyRangeListeners();
1048 if (doNotify
&& changed
) {
1049 notifyTimeListeners();
1053 private void ensureVisible(long time
) {
1054 long timeMid
= (fTime1
- fTime0
) / 2;
1055 if (time
< fTime0
) {
1056 long dt
= fTime0
- time
+ timeMid
;
1059 } else if (time
> fTime1
) {
1060 long dt
= time
- fTime1
+ timeMid
;
1064 if (fTime0
< fTime0Bound
) {
1065 fTime1
= Math
.min(fTime1Bound
, fTime1
+ (fTime0Bound
- fTime0
));
1066 fTime0
= fTime0Bound
;
1067 } else if (fTime1
> fTime1Bound
) {
1068 fTime0
= Math
.max(fTime0Bound
, fTime0
- (fTime1
- fTime1Bound
));
1069 fTime1
= fTime1Bound
;
1071 if (fTime1
- fTime0
< fMinTimeInterval
) {
1072 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
1074 adjustHorizontalScrollBar();
1078 public void widgetDefaultSelected(SelectionEvent e
) {
1079 if (fSelectedEntry
!= getSelection()) {
1080 fSelectedEntry
= getSelection();
1081 notifySelectionListeners();
1086 public void widgetSelected(SelectionEvent e
) {
1087 if (fSelectedEntry
!= getSelection()) {
1088 fSelectedEntry
= getSelection();
1089 notifySelectionListeners();
1094 * Callback for when the next event is selected
1097 * true to extend selection range, false for single selection
1100 public void selectNextEvent(boolean extend
) {
1101 fTimeGraphCtrl
.selectNextEvent(extend
);
1102 adjustVerticalScrollBar();
1106 * Callback for when the previous event is selected
1109 * true to extend selection range, false for single selection
1112 public void selectPrevEvent(boolean extend
) {
1113 fTimeGraphCtrl
.selectPrevEvent(extend
);
1114 adjustVerticalScrollBar();
1118 * Callback for when the next item is selected
1120 public void selectNextItem() {
1121 fTimeGraphCtrl
.selectNextTrace();
1122 adjustVerticalScrollBar();
1126 * Callback for when the previous item is selected
1128 public void selectPrevItem() {
1129 fTimeGraphCtrl
.selectPrevTrace();
1130 adjustVerticalScrollBar();
1134 * Callback for the show legend action
1136 public void showLegend() {
1137 if (fDataViewer
== null || fDataViewer
.isDisposed()) {
1141 TimeGraphLegend
.open(fDataViewer
.getShell(), fTimeGraphProvider
);
1145 * Callback for the Zoom In action
1147 public void zoomIn() {
1148 fTimeGraphCtrl
.zoomIn();
1152 * Callback for the Zoom Out action
1154 public void zoomOut() {
1155 fTimeGraphCtrl
.zoomOut();
1158 private String
getPreferenceString(String string
) {
1159 return getViewTypeStr() + "." + string
; //$NON-NLS-1$
1163 * Add a selection listener
1166 * The listener to add
1168 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
1169 fSelectionListeners
.add(listener
);
1173 * Remove a selection listener
1176 * The listener to remove
1178 public void removeSelectionListener(ITimeGraphSelectionListener listener
) {
1179 fSelectionListeners
.remove(listener
);
1182 private void notifySelectionListeners() {
1183 if (fListenerNotifier
== null) {
1184 fListenerNotifier
= new ListenerNotifier();
1185 fListenerNotifier
.start();
1187 fListenerNotifier
.selectionChanged();
1190 private void fireSelectionChanged(ITimeGraphEntry selection
) {
1191 TimeGraphSelectionEvent event
= new TimeGraphSelectionEvent(this, selection
);
1193 for (ITimeGraphSelectionListener listener
: fSelectionListeners
) {
1194 listener
.selectionChanged(event
);
1199 * Add a time listener
1202 * The listener to add
1204 public void addTimeListener(ITimeGraphTimeListener listener
) {
1205 fTimeListeners
.add(listener
);
1209 * Remove a time listener
1212 * The listener to remove
1214 public void removeTimeListener(ITimeGraphTimeListener listener
) {
1215 fTimeListeners
.remove(listener
);
1218 private void notifyTimeListeners() {
1219 if (fListenerNotifier
== null) {
1220 fListenerNotifier
= new ListenerNotifier();
1221 fListenerNotifier
.start();
1223 fListenerNotifier
.timeSelected();
1226 private void fireTimeSelected(long startTime
, long endTime
) {
1227 TimeGraphTimeEvent event
= new TimeGraphTimeEvent(this, startTime
, endTime
);
1229 for (ITimeGraphTimeListener listener
: fTimeListeners
) {
1230 listener
.timeSelected(event
);
1235 * Add a range listener
1238 * The listener to add
1240 public void addRangeListener(ITimeGraphRangeListener listener
) {
1241 fRangeListeners
.add(listener
);
1245 * Remove a range listener
1248 * The listener to remove
1250 public void removeRangeListener(ITimeGraphRangeListener listener
) {
1251 fRangeListeners
.remove(listener
);
1254 private void notifyRangeListeners() {
1255 if (fListenerNotifier
== null) {
1256 fListenerNotifier
= new ListenerNotifier();
1257 fListenerNotifier
.start();
1259 fListenerNotifier
.timeRangeUpdated();
1262 private void fireTimeRangeUpdated(long startTime
, long endTime
) {
1263 // Check if the time has actually changed from last notification
1264 if (startTime
!= fTime0ExtSynch
|| endTime
!= fTime1ExtSynch
) {
1265 // Notify Time Scale Selection Listeners
1266 TimeGraphRangeUpdateEvent event
= new TimeGraphRangeUpdateEvent(this, startTime
, endTime
);
1268 for (ITimeGraphRangeListener listener
: fRangeListeners
) {
1269 listener
.timeRangeUpdated(event
);
1272 // update external synch values
1273 updateExtSynchValues();
1278 * Add a bookmark listener
1281 * The listener to add
1284 public void addBookmarkListener(ITimeGraphBookmarkListener listener
) {
1285 fBookmarkListeners
.add(listener
);
1289 * Remove a bookmark listener
1292 * The listener to remove
1295 public void removeBookmarkListener(ITimeGraphBookmarkListener listener
) {
1296 fBookmarkListeners
.remove(listener
);
1299 private void fireBookmarkAdded(IMarkerEvent bookmark
) {
1300 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1302 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1303 listener
.bookmarkAdded(event
);
1307 private void fireBookmarkRemoved(IMarkerEvent bookmark
) {
1308 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1310 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1311 listener
.bookmarkRemoved(event
);
1316 * Set the bookmarks list.
1319 * The bookmarks list, or null
1322 public void setBookmarks(List
<IMarkerEvent
> bookmarks
) {
1324 if (bookmarks
!= null) {
1325 fBookmarks
.addAll(bookmarks
);
1328 updateMarkerActions();
1332 * Get the bookmarks list.
1334 * @return The bookmarks list
1337 public List
<IMarkerEvent
> getBookmarks() {
1338 return Collections
.unmodifiableList(fBookmarks
);
1342 * Set the list of marker categories.
1345 * The list of marker categories, or null
1348 public void setMarkerCategories(List
<String
> categories
) {
1349 fMarkerCategories
.clear();
1350 if (categories
!= null) {
1351 fMarkerCategories
.addAll(categories
);
1353 fMarkerCategories
.add(IMarkerEvent
.BOOKMARKS
);
1354 fMarkerAxisCtrl
.setMarkerCategories(fMarkerCategories
);
1361 public void setMarkerCategoryVisible(String category
, boolean visible
) {
1362 boolean changed
= false;
1364 changed
= fHiddenMarkerCategories
.remove(category
);
1366 changed
= fHiddenMarkerCategories
.add(category
);
1370 updateMarkerActions();
1371 getControl().redraw();
1376 * Set the markers list.
1379 * The markers list, or null
1382 public void setMarkers(List
<IMarkerEvent
> markers
) {
1384 if (markers
!= null) {
1385 fMarkers
.addAll(markers
);
1388 updateMarkerActions();
1392 * Get the markers list.
1394 * @return The markers list, or null
1397 public List
<IMarkerEvent
> getMarkers() {
1398 return Collections
.unmodifiableList(fMarkers
);
1402 * Callback to set a selected event in the view
1405 * The event that was selected
1407 * The source of this selection event
1409 public void setSelectedEvent(ITimeEvent event
, Object source
) {
1410 if (event
== null || source
== this) {
1413 fSelectedEntry
= event
.getEntry();
1414 fTimeGraphCtrl
.selectItem(fSelectedEntry
, false);
1416 setSelectedTimeInt(event
.getTime(), true, true);
1417 adjustVerticalScrollBar();
1421 * Set the seeked time of a trace
1424 * The trace that was seeked
1428 * The source of this seek event
1430 public void setSelectedTraceTime(ITimeGraphEntry trace
, long time
, Object source
) {
1431 if (trace
== null || source
== this) {
1434 fSelectedEntry
= trace
;
1435 fTimeGraphCtrl
.selectItem(trace
, false);
1437 setSelectedTimeInt(time
, true, true);
1441 * Callback for a trace selection
1444 * The trace that was selected
1446 public void setSelection(ITimeGraphEntry trace
) {
1447 /* if there is a pending selection, ignore this one */
1448 if (fListenerNotifier
!= null && fListenerNotifier
.hasSelectionChanged()) {
1451 fSelectedEntry
= trace
;
1452 fTimeGraphCtrl
.selectItem(trace
, false);
1453 adjustVerticalScrollBar();
1457 * Callback for a time window selection
1460 * Start time of the range
1462 * End time of the range
1464 * Source of the event
1466 public void setSelectVisTimeWindow(long time0
, long time1
, Object source
) {
1467 if (source
== this) {
1471 setStartFinishTimeInt(time0
, time1
);
1473 // update notification time values since we are now in synch with the
1474 // external application
1475 updateExtSynchValues();
1479 * update the cache values used to identify the need to send a time window
1480 * update to external registered listeners
1482 private void updateExtSynchValues() {
1483 // last time notification cache
1484 fTime0ExtSynch
= fTime0
;
1485 fTime1ExtSynch
= fTime1
;
1489 public TimeFormat
getTimeFormat() {
1495 * the {@link TimeFormat} used to display timestamps
1497 public void setTimeFormat(TimeFormat tf
) {
1498 this.fTimeFormat
= tf
;
1499 if (tf
== TimeFormat
.CYCLES
) {
1500 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1502 fTimeDataProvider
= this;
1504 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1505 if (fToolTipHandler
!= null) {
1506 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1511 * Sets the clock frequency. Used when the time format is set to CYCLES.
1513 * @param clockFrequency
1514 * the clock frequency in Hz
1516 public void setClockFrequency(long clockFrequency
) {
1517 fClockFrequency
= clockFrequency
;
1518 if (fTimeFormat
== TimeFormat
.CYCLES
) {
1519 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1520 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1521 if (fToolTipHandler
!= null) {
1522 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1528 * Retrieve the border width
1532 public int getBorderWidth() {
1533 return fBorderWidth
;
1537 * Set the border width
1539 * @param borderWidth
1542 public void setBorderWidth(int borderWidth
) {
1543 if (borderWidth
> -1) {
1544 this.fBorderWidth
= borderWidth
;
1545 GridLayout gl
= (GridLayout
) fDataViewer
.getLayout();
1546 gl
.marginHeight
= borderWidth
;
1551 * Retrieve the height of the header
1553 * @return The height
1555 public int getHeaderHeight() {
1556 return fTimeScaleHeight
;
1560 * Set the height of the header
1562 * @param headerHeight
1565 public void setHeaderHeight(int headerHeight
) {
1566 if (headerHeight
> -1) {
1567 this.fTimeScaleHeight
= headerHeight
;
1568 fTimeScaleCtrl
.setHeight(headerHeight
);
1573 * Retrieve the height of an item row
1575 * @return The height
1577 public int getItemHeight() {
1578 if (fTimeGraphCtrl
!= null) {
1579 return fTimeGraphCtrl
.getItemHeight();
1585 * Set the height of an item row
1590 public void setItemHeight(int rowHeight
) {
1591 if (fTimeGraphCtrl
!= null) {
1592 fTimeGraphCtrl
.setItemHeight(rowHeight
);
1597 * Set the minimum item width
1602 public void setMinimumItemWidth(int width
) {
1603 if (fTimeGraphCtrl
!= null) {
1604 fTimeGraphCtrl
.setMinimumItemWidth(width
);
1609 * Set the width for the name column
1614 public void setNameWidthPref(int width
) {
1615 fNameWidthPref
= width
;
1623 * Retrieve the configure width for the name column
1629 public int getNameWidthPref(int width
) {
1630 return fNameWidthPref
;
1634 * Returns the primary control associated with this viewer.
1636 * @return the SWT control which displays this viewer's content
1638 public Control
getControl() {
1643 * Returns the time graph control associated with this viewer.
1645 * @return the time graph control
1647 public TimeGraphControl
getTimeGraphControl() {
1648 return fTimeGraphCtrl
;
1652 * Returns the time graph scale associated with this viewer.
1654 * @return the time graph scale
1656 public TimeGraphScale
getTimeGraphScale() {
1657 return fTimeScaleCtrl
;
1661 * Returns the composite containing all the controls that are time aligned,
1662 * i.e. TimeGraphScale, TimeGraphControl.
1664 * @return the time based composite
1667 public Composite
getTimeAlignedComposite() {
1668 return fTimeAlignedComposite
;
1672 * Return the x coordinate corresponding to a time
1676 * @return the x coordinate corresponding to the time
1678 public int getXForTime(long time
) {
1679 return fTimeGraphCtrl
.getXForTime(time
);
1683 * Return the time corresponding to an x coordinate
1687 * @return the time corresponding to the x coordinate
1689 public long getTimeAtX(int x
) {
1690 return fTimeGraphCtrl
.getTimeAtX(x
);
1694 * Get the selection provider
1696 * @return the selection provider
1698 public ISelectionProvider
getSelectionProvider() {
1699 return fTimeGraphCtrl
;
1703 * Wait for the cursor
1706 * Wait indefinitely?
1708 public void waitCursor(boolean waitInd
) {
1709 fTimeGraphCtrl
.waitCursor(waitInd
);
1713 * Get the horizontal scroll bar object
1715 * @return The scroll bar
1717 public Slider
getHorizontalBar() {
1718 return fHorizontalScrollBar
;
1722 * Get the vertical scroll bar object
1724 * @return The scroll bar
1726 public Slider
getVerticalBar() {
1727 return fVerticalScrollBar
;
1731 * Set the given index as the top one
1734 * The index that will go to the top
1736 public void setTopIndex(int index
) {
1737 fTimeGraphCtrl
.setTopIndex(index
);
1738 adjustVerticalScrollBar();
1742 * Retrieve the current top index
1744 * @return The top index
1746 public int getTopIndex() {
1747 return fTimeGraphCtrl
.getTopIndex();
1751 * Sets the auto-expand level to be used for new entries discovered when
1752 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1753 * means that there is no auto-expand; 1 means that top-level entries are
1754 * expanded, but not their children; 2 means that top-level entries are
1755 * expanded, and their children, but not grand-children; and so on.
1757 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1761 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1762 * levels of the tree
1764 public void setAutoExpandLevel(int level
) {
1765 fTimeGraphCtrl
.setAutoExpandLevel(level
);
1769 * Returns the auto-expand level.
1771 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1772 * the tree are expanded automatically
1773 * @see #setAutoExpandLevel
1775 public int getAutoExpandLevel() {
1776 return fTimeGraphCtrl
.getAutoExpandLevel();
1780 * Get the expanded state of an entry.
1784 * @return true if the entry is expanded, false if collapsed
1787 public boolean getExpandedState(ITimeGraphEntry entry
) {
1788 return fTimeGraphCtrl
.getExpandedState(entry
);
1792 * Set the expanded state of an entry
1795 * The entry to expand/collapse
1797 * True for expanded, false for collapsed
1799 public void setExpandedState(ITimeGraphEntry entry
, boolean expanded
) {
1800 fTimeGraphCtrl
.setExpandedState(entry
, expanded
);
1801 adjustVerticalScrollBar();
1805 * Collapses all nodes of the viewer's tree, starting with the root.
1807 public void collapseAll() {
1808 fTimeGraphCtrl
.collapseAll();
1809 adjustVerticalScrollBar();
1813 * Expands all entries of the viewer's tree, starting with the root.
1815 public void expandAll() {
1816 fTimeGraphCtrl
.expandAll();
1817 adjustVerticalScrollBar();
1821 * Get the number of expanded (visible) time graph entries. This includes
1822 * leafs and does not include filtered-out entries.
1824 * @return The number of expanded (visible) time graph entries
1826 public int getExpandedElementCount() {
1827 return fTimeGraphCtrl
.getExpandedElementCount();
1831 * Get the expanded (visible) time graph entries. This includes leafs and
1832 * does not include filtered-out entries.
1834 * @return The array of expanded (visible) time graph entries
1836 public ITimeGraphEntry
[] getExpandedElements() {
1837 return fTimeGraphCtrl
.getExpandedElements();
1841 * Add a tree listener
1844 * The listener to add
1846 public void addTreeListener(ITimeGraphTreeListener listener
) {
1847 fTimeGraphCtrl
.addTreeListener(listener
);
1851 * Remove a tree listener
1854 * The listener to remove
1856 public void removeTreeListener(ITimeGraphTreeListener listener
) {
1857 fTimeGraphCtrl
.removeTreeListener(listener
);
1861 * Get the reset scale action.
1863 * @return The Action object
1865 public Action
getResetScaleAction() {
1866 if (fResetScaleAction
== null) {
1868 fResetScaleAction
= new Action() {
1871 resetStartFinishTime();
1874 fResetScaleAction
.setText(Messages
.TmfTimeGraphViewer_ResetScaleActionNameText
);
1875 fResetScaleAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ResetScaleActionToolTipText
);
1876 fResetScaleAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HOME_MENU
));
1878 return fResetScaleAction
;
1882 * Get the show legend action.
1884 * @return The Action object
1886 public Action
getShowLegendAction() {
1887 if (fShowLegendAction
== null) {
1889 fShowLegendAction
= new Action() {
1895 fShowLegendAction
.setText(Messages
.TmfTimeGraphViewer_LegendActionNameText
);
1896 fShowLegendAction
.setToolTipText(Messages
.TmfTimeGraphViewer_LegendActionToolTipText
);
1897 fShowLegendAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_LEGEND
));
1900 return fShowLegendAction
;
1904 * Get the the next event action.
1906 * @return The action object
1908 public Action
getNextEventAction() {
1909 if (fNextEventAction
== null) {
1910 fNextEventAction
= new Action() {
1912 public void runWithEvent(Event event
) {
1913 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
1914 selectNextEvent(extend
);
1918 fNextEventAction
.setText(Messages
.TmfTimeGraphViewer_NextEventActionNameText
);
1919 fNextEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextEventActionToolTipText
);
1920 fNextEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_EVENT
));
1923 return fNextEventAction
;
1927 * Get the previous event action.
1929 * @return The Action object
1931 public Action
getPreviousEventAction() {
1932 if (fPrevEventAction
== null) {
1933 fPrevEventAction
= new Action() {
1935 public void runWithEvent(Event event
) {
1936 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
1937 selectPrevEvent(extend
);
1941 fPrevEventAction
.setText(Messages
.TmfTimeGraphViewer_PreviousEventActionNameText
);
1942 fPrevEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousEventActionToolTipText
);
1943 fPrevEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_EVENT
));
1946 return fPrevEventAction
;
1950 * Get the next item action.
1952 * @return The Action object
1954 public Action
getNextItemAction() {
1955 if (fNextItemAction
== null) {
1957 fNextItemAction
= new Action() {
1963 fNextItemAction
.setText(Messages
.TmfTimeGraphViewer_NextItemActionNameText
);
1964 fNextItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextItemActionToolTipText
);
1965 fNextItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_ITEM
));
1967 return fNextItemAction
;
1971 * Get the previous item action.
1973 * @return The Action object
1975 public Action
getPreviousItemAction() {
1976 if (fPreviousItemAction
== null) {
1978 fPreviousItemAction
= new Action() {
1984 fPreviousItemAction
.setText(Messages
.TmfTimeGraphViewer_PreviousItemActionNameText
);
1985 fPreviousItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousItemActionToolTipText
);
1986 fPreviousItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_ITEM
));
1988 return fPreviousItemAction
;
1992 * Get the zoom in action
1994 * @return The Action object
1996 public Action
getZoomInAction() {
1997 if (fZoomInAction
== null) {
1998 fZoomInAction
= new Action() {
2004 fZoomInAction
.setText(Messages
.TmfTimeGraphViewer_ZoomInActionNameText
);
2005 fZoomInAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomInActionToolTipText
);
2006 fZoomInAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_IN_MENU
));
2008 return fZoomInAction
;
2012 * Get the zoom out action
2014 * @return The Action object
2016 public Action
getZoomOutAction() {
2017 if (fZoomOutAction
== null) {
2018 fZoomOutAction
= new Action() {
2024 fZoomOutAction
.setText(Messages
.TmfTimeGraphViewer_ZoomOutActionNameText
);
2025 fZoomOutAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomOutActionToolTipText
);
2026 fZoomOutAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_OUT_MENU
));
2028 return fZoomOutAction
;
2032 * Get the hide arrows action
2034 * @param dialogSettings
2035 * The dialog settings section where the state should be stored,
2038 * @return The Action object
2040 public Action
getHideArrowsAction(final IDialogSettings dialogSettings
) {
2041 if (fHideArrowsAction
== null) {
2042 fHideArrowsAction
= new Action(Messages
.TmfTimeGraphViewer_HideArrowsActionNameText
, IAction
.AS_CHECK_BOX
) {
2045 boolean hideArrows
= fHideArrowsAction
.isChecked();
2046 fTimeGraphCtrl
.hideArrows(hideArrows
);
2048 if (dialogSettings
!= null) {
2049 dialogSettings
.put(HIDE_ARROWS_KEY
, hideArrows
);
2051 if (fFollowArrowFwdAction
!= null) {
2052 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
2054 if (fFollowArrowBwdAction
!= null) {
2055 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
2059 fHideArrowsAction
.setToolTipText(Messages
.TmfTimeGraphViewer_HideArrowsActionToolTipText
);
2060 fHideArrowsAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HIDE_ARROWS
));
2061 if (dialogSettings
!= null) {
2062 boolean hideArrows
= dialogSettings
.getBoolean(HIDE_ARROWS_KEY
);
2063 fTimeGraphCtrl
.hideArrows(hideArrows
);
2064 fHideArrowsAction
.setChecked(hideArrows
);
2065 if (fFollowArrowFwdAction
!= null) {
2066 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
2068 if (fFollowArrowBwdAction
!= null) {
2069 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
2073 return fHideArrowsAction
;
2077 * Get the follow arrow forward action.
2079 * @return The Action object
2081 public Action
getFollowArrowFwdAction() {
2082 if (fFollowArrowFwdAction
== null) {
2083 fFollowArrowFwdAction
= new Action() {
2085 public void runWithEvent(Event event
) {
2086 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2087 fTimeGraphCtrl
.followArrowFwd(extend
);
2088 adjustVerticalScrollBar();
2091 fFollowArrowFwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionNameText
);
2092 fFollowArrowFwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText
);
2093 fFollowArrowFwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_FORWARD
));
2094 if (fHideArrowsAction
!= null) {
2095 fFollowArrowFwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2098 return fFollowArrowFwdAction
;
2102 * Get the follow arrow backward action.
2104 * @return The Action object
2106 public Action
getFollowArrowBwdAction() {
2107 if (fFollowArrowBwdAction
== null) {
2108 fFollowArrowBwdAction
= new Action() {
2110 public void runWithEvent(Event event
) {
2111 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2112 fTimeGraphCtrl
.followArrowBwd(extend
);
2113 adjustVerticalScrollBar();
2116 fFollowArrowBwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionNameText
);
2117 fFollowArrowBwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText
);
2118 fFollowArrowBwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_BACKWARD
));
2119 if (fHideArrowsAction
!= null) {
2120 fFollowArrowBwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2123 return fFollowArrowBwdAction
;
2127 * Get the show filter dialog action.
2129 * @return The Action object
2132 public ShowFilterDialogAction
getShowFilterDialogAction() {
2133 if (fShowFilterDialogAction
== null) {
2134 fShowFilterDialogAction
= new ShowFilterDialogAction(this);
2136 return fShowFilterDialogAction
;
2140 * Get the toggle bookmark action.
2142 * @return The Action object
2145 public Action
getToggleBookmarkAction() {
2146 if (fToggleBookmarkAction
== null) {
2147 fToggleBookmarkAction
= new Action() {
2149 public void runWithEvent(Event event
) {
2150 IMarkerEvent selectedBookmark
= getBookmarkAtSelection();
2151 if (selectedBookmark
== null) {
2152 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2153 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2154 final AddBookmarkDialog dialog
= new AddBookmarkDialog(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell(), null);
2155 if (dialog
.open() == Window
.OK
) {
2156 final String label
= dialog
.getValue();
2157 final RGBA rgba
= dialog
.getColorValue();
2158 IMarkerEvent bookmark
= new MarkerEvent(null, time
, duration
, IMarkerEvent
.BOOKMARKS
, rgba
, label
, true);
2159 fBookmarks
.add(bookmark
);
2161 updateMarkerActions();
2162 getControl().redraw();
2163 fireBookmarkAdded(bookmark
);
2166 fBookmarks
.remove(selectedBookmark
);
2168 updateMarkerActions();
2169 getControl().redraw();
2170 fireBookmarkRemoved(selectedBookmark
);
2174 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2175 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2176 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2178 return fToggleBookmarkAction
;
2182 * Get the next marker action.
2184 * @return The Action object
2187 public Action
getNextMarkerAction() {
2188 if (fNextMarkerAction
== null) {
2189 fNextMarkerAction
= new Action(Messages
.TmfTimeGraphViewer_NextMarkerActionText
, IAction
.AS_DROP_DOWN_MENU
) {
2191 public void runWithEvent(Event event
) {
2192 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2194 extendToNextMarker();
2200 fNextMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextMarkerActionText
);
2201 fNextMarkerAction
.setImageDescriptor(NEXT_BOOKMARK
);
2202 fNextMarkerAction
.setMenuCreator(new IMenuCreator () {
2205 public void dispose() {
2213 public Menu
getMenu(Control parent
) {
2217 menu
= new Menu(parent
);
2218 for (String category
: fMarkerCategories
) {
2219 final Action action
= new Action(category
, IAction
.AS_CHECK_BOX
) {
2221 public void runWithEvent(Event event
) {
2223 fSkippedMarkerCategories
.remove(getText());
2225 fSkippedMarkerCategories
.add(getText());
2227 updateMarkerActions();
2230 action
.setEnabled(!fHiddenMarkerCategories
.contains(category
));
2231 action
.setChecked(action
.isEnabled() && !fSkippedMarkerCategories
.contains(category
));
2232 new ActionContributionItem(action
).fill(menu
, -1);
2238 public Menu
getMenu(Menu parent
) {
2243 return fNextMarkerAction
;
2247 * Get the previous marker action.
2249 * @return The Action object
2252 public Action
getPreviousMarkerAction() {
2253 if (fPreviousMarkerAction
== null) {
2254 fPreviousMarkerAction
= new Action() {
2256 public void runWithEvent(Event event
) {
2257 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
2259 extendToPrevMarker();
2265 fPreviousMarkerAction
.setText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2266 fPreviousMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2267 fPreviousMarkerAction
.setImageDescriptor(PREVIOUS_BOOKMARK
);
2269 return fPreviousMarkerAction
;
2273 * Get the show markers menu.
2275 * @return The menu manager object
2278 public MenuManager
getMarkersMenu() {
2279 if (fMarkersMenu
== null) {
2280 fMarkersMenu
= new MenuManager(Messages
.TmfTimeGraphViewer_ShowMarkersMenuText
);
2281 fMarkersMenu
.setRemoveAllWhenShown(true);
2282 fMarkersMenu
.addMenuListener(new IMenuListener() {
2284 public void menuAboutToShow(IMenuManager manager
) {
2285 for (String category
: fMarkerCategories
) {
2286 final Action action
= new Action(category
, IAction
.AS_CHECK_BOX
) {
2288 public void runWithEvent(Event event
) {
2289 setMarkerCategoryVisible(getText(), isChecked());
2292 action
.setChecked(!fHiddenMarkerCategories
.contains(category
));
2293 manager
.add(action
);
2298 return fMarkersMenu
;
2302 * Select the next marker that begins at or after the current selection
2303 * begin time. Markers that begin at the same time are ordered by end time.
2305 private void selectNextMarker() {
2306 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2307 if (markers
== null) {
2310 for (IMarkerEvent marker
: markers
) {
2311 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2312 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2313 if ((marker
.getTime() > time
||
2314 (marker
.getTime() == time
&& marker
.getDuration() > duration
))
2315 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2316 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration(), false);
2317 ensureVisible(marker
.getTime());
2318 notifyRangeListeners();
2319 fTimeGraphCtrl
.updateStatusLine();
2326 * Select the previous marker that begins at or before the current selection
2327 * begin time. Markers that begin at the same time are ordered by end time.
2329 private void selectPrevMarker() {
2330 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2331 if (markers
== null) {
2334 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2335 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2336 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2337 IMarkerEvent marker
= markers
.get(i
);
2338 if ((marker
.getTime() < time
||
2339 (marker
.getTime() == time
&& marker
.getDuration() < duration
))
2340 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2341 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration(), false);
2342 ensureVisible(marker
.getTime());
2343 notifyRangeListeners();
2344 fTimeGraphCtrl
.updateStatusLine();
2351 * Extend the selection to the closest next marker end time.
2353 private void extendToNextMarker() {
2354 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2355 if (markers
== null) {
2358 IMarkerEvent nextMarker
= null;
2359 for (IMarkerEvent marker
: markers
) {
2360 if (marker
.getTime() + marker
.getDuration() > fSelectionEnd
2361 && !fSkippedMarkerCategories
.contains(marker
.getCategory())
2362 && (nextMarker
== null || marker
.getTime() + marker
.getDuration() < nextMarker
.getTime() + nextMarker
.getDuration())) {
2363 nextMarker
= marker
;
2366 if (nextMarker
!= null) {
2367 setSelectionRangeNotify(fSelectionBegin
, nextMarker
.getTime() + nextMarker
.getDuration(), true);
2368 fTimeGraphCtrl
.updateStatusLine();
2373 * Extend the selection to the closest previous marker start time.
2375 private void extendToPrevMarker() {
2376 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2377 if (markers
== null) {
2380 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2381 IMarkerEvent marker
= markers
.get(i
);
2382 if (marker
.getTime() < fSelectionEnd
2383 && !fSkippedMarkerCategories
.contains(marker
.getCategory())) {
2384 setSelectionRangeNotify(fSelectionBegin
, marker
.getTime(), true);
2385 fTimeGraphCtrl
.updateStatusLine();
2391 private IMarkerEvent
getBookmarkAtSelection() {
2392 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2393 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2394 for (IMarkerEvent bookmark
: fBookmarks
) {
2395 if (bookmark
.getTime() == time
&& bookmark
.getDuration() == duration
) {
2402 private void updateMarkerActions() {
2403 boolean enabled
= fTime0Bound
!= SWT
.DEFAULT
|| fTime1Bound
!= SWT
.DEFAULT
;
2404 if (fToggleBookmarkAction
!= null) {
2405 if (getBookmarkAtSelection() != null) {
2406 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2407 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2408 fToggleBookmarkAction
.setImageDescriptor(REMOVE_BOOKMARK
);
2410 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2411 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2412 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2414 fToggleBookmarkAction
.setEnabled(enabled
);
2416 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2417 if (markers
== null) {
2418 markers
= Collections
.emptyList();
2420 if (fPreviousMarkerAction
!= null) {
2421 fPreviousMarkerAction
.setEnabled(enabled
&& !markers
.isEmpty());
2423 if (fNextMarkerAction
!= null) {
2424 fNextMarkerAction
.setEnabled(enabled
&& !markers
.isEmpty());
2428 private void updateMarkerList() {
2429 List
<IMarkerEvent
> markers
= new ArrayList
<>();
2430 for (IMarkerEvent marker
: fMarkers
) {
2431 if (!fHiddenMarkerCategories
.contains(marker
.getCategory())) {
2432 markers
.add(marker
);
2435 if (!fHiddenMarkerCategories
.contains(IMarkerEvent
.BOOKMARKS
)) {
2436 markers
.addAll(fBookmarks
);
2438 Collections
.sort(markers
, new MarkerComparator());
2439 fTimeGraphCtrl
.setMarkers(markers
);
2440 fMarkerAxisCtrl
.setMarkers(markers
);
2443 private void adjustHorizontalScrollBar() {
2444 long time0
= getTime0();
2445 long time1
= getTime1();
2446 long timeMin
= getMinTime();
2447 long timeMax
= getMaxTime();
2448 long delta
= timeMax
- timeMin
;
2450 int thumb
= H_SCROLLBAR_MAX
;
2452 // Thumb size (page size)
2453 thumb
= Math
.max(1, (int) (H_SCROLLBAR_MAX
* ((double) (time1
- time0
) / delta
)));
2454 // At the beginning of visible window
2455 timePos
= (int) (H_SCROLLBAR_MAX
* ((double) (time0
- timeMin
) / delta
));
2457 fHorizontalScrollBar
.setValues(timePos
, 0, H_SCROLLBAR_MAX
, thumb
, Math
.max(1, thumb
/ 2), Math
.max(2, thumb
));
2460 private void adjustVerticalScrollBar() {
2461 int topIndex
= fTimeGraphCtrl
.getTopIndex();
2462 int countPerPage
= fTimeGraphCtrl
.countPerPage();
2463 int expandedElementCount
= fTimeGraphCtrl
.getExpandedElementCount();
2464 if (topIndex
+ countPerPage
> expandedElementCount
) {
2465 fTimeGraphCtrl
.setTopIndex(Math
.max(0, expandedElementCount
- countPerPage
));
2468 int selection
= fTimeGraphCtrl
.getTopIndex();
2470 int max
= Math
.max(1, expandedElementCount
- 1);
2471 int thumb
= Math
.min(max
, Math
.max(1, countPerPage
- 1));
2473 int pageIncrement
= Math
.max(1, countPerPage
);
2474 fVerticalScrollBar
.setValues(selection
, min
, max
, thumb
, increment
, pageIncrement
);
2479 * a {@link MenuDetectListener}
2480 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2482 public void addTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2483 fTimeGraphCtrl
.addTimeGraphEntryMenuListener(listener
);
2488 * a {@link MenuDetectListener}
2489 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2491 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2492 fTimeGraphCtrl
.removeTimeGraphEntryMenuListener(listener
);
2497 * a {@link MenuDetectListener}
2498 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2500 public void addTimeEventMenuListener(MenuDetectListener listener
) {
2501 fTimeGraphCtrl
.addTimeEventMenuListener(listener
);
2506 * a {@link MenuDetectListener}
2507 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2509 public void removeTimeEventMenuListener(MenuDetectListener listener
) {
2510 fTimeGraphCtrl
.removeTimeEventMenuListener(listener
);
2515 * The filter object to be attached to the view
2517 public void addFilter(@NonNull ViewerFilter filter
) {
2518 fTimeGraphCtrl
.addFilter(filter
);
2524 * The filter object to be attached to the view
2526 public void removeFilter(@NonNull ViewerFilter filter
) {
2527 fTimeGraphCtrl
.removeFilter(filter
);
2532 * Returns this viewer's filters.
2534 * @return an array of viewer filters
2537 public @NonNull ViewerFilter
[] getFilters() {
2538 return fTimeGraphCtrl
.getFilters();
2542 * Sets the filters, replacing any previous filters, and triggers
2543 * refiltering of the elements.
2546 * an array of viewer filters, or null
2549 public void setFilters(@NonNull ViewerFilter
[] filters
) {
2550 fTimeGraphCtrl
.setFilters(filters
);
2555 * Return the time alignment information
2557 * @return the time alignment information
2559 * @see ITmfTimeAligned
2563 public TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo() {
2564 return fTimeGraphCtrl
.getTimeViewAlignmentInfo();
2568 * Return the available width for the time-axis.
2570 * @see ITmfTimeAligned
2572 * @param requestedOffset
2573 * the requested offset
2574 * @return the available width for the time-axis
2578 public int getAvailableWidth(int requestedOffset
) {
2579 int totalWidth
= fTimeAlignedComposite
.getSize().x
;
2580 return Math
.min(totalWidth
, Math
.max(0, totalWidth
- requestedOffset
));
2584 * Perform the alignment operation.
2587 * the alignment offset
2589 * the alignment width
2591 * @see ITmfTimeAligned
2595 public void performAlign(int offset
, int width
) {
2596 fTimeGraphCtrl
.performAlign(offset
);
2597 int alignmentWidth
= width
;
2598 int size
= fTimeAlignedComposite
.getSize().x
;
2599 GridLayout layout
= (GridLayout
) fTimeAlignedComposite
.getLayout();
2600 int marginSize
= size
- alignmentWidth
- offset
;
2601 layout
.marginRight
= Math
.max(0, marginSize
);
2602 fTimeAlignedComposite
.layout();