1 /*****************************************************************************
2 * Copyright (c) 2007, 2015 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
.List
;
24 import org
.eclipse
.jface
.action
.Action
;
25 import org
.eclipse
.jface
.action
.IAction
;
26 import org
.eclipse
.jface
.dialogs
.IDialogSettings
;
27 import org
.eclipse
.jface
.resource
.ImageDescriptor
;
28 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
29 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
30 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
31 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
32 import org
.eclipse
.jface
.viewers
.ViewerFilter
;
33 import org
.eclipse
.jface
.window
.Window
;
34 import org
.eclipse
.swt
.SWT
;
35 import org
.eclipse
.swt
.events
.ControlAdapter
;
36 import org
.eclipse
.swt
.events
.ControlEvent
;
37 import org
.eclipse
.swt
.events
.DisposeEvent
;
38 import org
.eclipse
.swt
.events
.DisposeListener
;
39 import org
.eclipse
.swt
.events
.KeyAdapter
;
40 import org
.eclipse
.swt
.events
.KeyEvent
;
41 import org
.eclipse
.swt
.events
.MenuDetectListener
;
42 import org
.eclipse
.swt
.events
.MouseEvent
;
43 import org
.eclipse
.swt
.events
.MouseWheelListener
;
44 import org
.eclipse
.swt
.events
.SelectionAdapter
;
45 import org
.eclipse
.swt
.events
.SelectionEvent
;
46 import org
.eclipse
.swt
.events
.SelectionListener
;
47 import org
.eclipse
.swt
.graphics
.Color
;
48 import org
.eclipse
.swt
.graphics
.RGBA
;
49 import org
.eclipse
.swt
.graphics
.Rectangle
;
50 import org
.eclipse
.swt
.layout
.FillLayout
;
51 import org
.eclipse
.swt
.layout
.GridData
;
52 import org
.eclipse
.swt
.layout
.GridLayout
;
53 import org
.eclipse
.swt
.widgets
.Composite
;
54 import org
.eclipse
.swt
.widgets
.Control
;
55 import org
.eclipse
.swt
.widgets
.Display
;
56 import org
.eclipse
.swt
.widgets
.Event
;
57 import org
.eclipse
.swt
.widgets
.Listener
;
58 import org
.eclipse
.swt
.widgets
.Slider
;
59 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
60 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.ITmfImageConstants
;
61 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Messages
;
62 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.dialogs
.AddBookmarkDialog
;
63 import org
.eclipse
.tracecompass
.tmf
.ui
.signal
.TmfTimeViewAlignmentInfo
;
64 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.ITmfTimeAligned
;
65 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.ShowFilterDialogAction
;
66 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
.TimeGraphLegend
;
67 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
68 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.IMarkerEvent
;
69 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
70 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
71 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.MarkerEvent
;
72 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.ITimeDataProvider
;
73 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeDataProviderCyclesConverter
;
74 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphColorScheme
;
75 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphControl
;
76 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphScale
;
77 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphTooltipHandler
;
78 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
79 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
80 import org
.eclipse
.ui
.PlatformUI
;
83 * Generic time graph viewer implementation
85 * @author Patrick Tasse, and others
87 public class TimeGraphViewer
implements ITimeDataProvider
, SelectionListener
{
89 /** Constant indicating that all levels of the time graph should be expanded */
90 public static final int ALL_LEVELS
= AbstractTreeViewer
.ALL_LEVELS
;
92 private static final int DEFAULT_NAME_WIDTH
= 200;
93 private static final int MIN_NAME_WIDTH
= 6;
94 private static final int MAX_NAME_WIDTH
= 1000;
95 private static final int DEFAULT_HEIGHT
= 22;
96 private static final String HIDE_ARROWS_KEY
= "hide.arrows"; //$NON-NLS-1$
97 private static final long DEFAULT_FREQUENCY
= 1000000000L;
98 private static final int H_SCROLLBAR_MAX
= Integer
.MAX_VALUE
- 1;
100 private static ImageDescriptor ADD_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ADD_BOOKMARK
);
101 private static ImageDescriptor NEXT_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_BOOKMARK
);
102 private static ImageDescriptor PREVIOUS_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREVIOUS_BOOKMARK
);
103 private static ImageDescriptor REMOVE_BOOKMARK
= Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_REMOVE_BOOKMARK
);
105 private long fMinTimeInterval
;
106 private ITimeGraphEntry fSelectedEntry
;
107 private long fBeginTime
= SWT
.DEFAULT
; // The user-specified bounds start time
108 private long fEndTime
= SWT
.DEFAULT
; // The user-specified bounds end time
109 private long fTime0
= SWT
.DEFAULT
; // The current window start time
110 private long fTime1
= SWT
.DEFAULT
; // The current window end time
111 private long fSelectionBegin
= SWT
.DEFAULT
;
112 private long fSelectionEnd
= SWT
.DEFAULT
;
113 private long fTime0Bound
= SWT
.DEFAULT
; // The bounds start time
114 private long fTime1Bound
= SWT
.DEFAULT
; // The bounds end time
115 private long fTime0ExtSynch
= SWT
.DEFAULT
;
116 private long fTime1ExtSynch
= SWT
.DEFAULT
;
117 private boolean fTimeRangeFixed
;
118 private int fNameWidthPref
= DEFAULT_NAME_WIDTH
;
119 private int fMinNameWidth
= MIN_NAME_WIDTH
;
120 private int fNameWidth
;
121 private Composite fDataViewer
;
123 private TimeGraphControl fTimeGraphCtrl
;
124 private TimeGraphScale fTimeScaleCtrl
;
125 private Slider fHorizontalScrollBar
;
126 private Slider fVerticalScrollBar
;
127 private TimeGraphColorScheme fColorScheme
;
128 private Object fInputElement
;
129 private ITimeGraphContentProvider fTimeGraphContentProvider
;
130 private ITimeGraphPresentationProvider fTimeGraphProvider
;
131 private ITimeDataProvider fTimeDataProvider
= this;
132 private TimeGraphTooltipHandler fToolTipHandler
;
134 private List
<ITimeGraphSelectionListener
> fSelectionListeners
= new ArrayList
<>();
135 private List
<ITimeGraphTimeListener
> fTimeListeners
= new ArrayList
<>();
136 private List
<ITimeGraphRangeListener
> fRangeListeners
= new ArrayList
<>();
137 private List
<ITimeGraphBookmarkListener
> fBookmarkListeners
= new ArrayList
<>();
139 // Time format, using Epoch reference, Relative time format(default),
141 private TimeFormat fTimeFormat
= TimeFormat
.RELATIVE
;
142 // Clock frequency to use for Cycles time format
143 private long fClockFrequency
= DEFAULT_FREQUENCY
;
144 private int fBorderWidth
= 0;
145 private int fTimeScaleHeight
= DEFAULT_HEIGHT
;
147 private Action fResetScaleAction
;
148 private Action fShowLegendAction
;
149 private Action fNextEventAction
;
150 private Action fPrevEventAction
;
151 private Action fNextItemAction
;
152 private Action fPreviousItemAction
;
153 private Action fZoomInAction
;
154 private Action fZoomOutAction
;
155 private Action fHideArrowsAction
;
156 private Action fFollowArrowFwdAction
;
157 private Action fFollowArrowBwdAction
;
158 private ShowFilterDialogAction fShowFilterDialogAction
;
159 private Action fToggleBookmarkAction
;
160 private Action fNextMarkerAction
;
161 private Action fPreviousMarkerAction
;
163 /** The list of bookmarks */
164 private final List
<IMarkerEvent
> fBookmarks
= new ArrayList
<>();
166 /** The list of markers */
167 private final List
<IMarkerEvent
> fMarkers
= new ArrayList
<>();
169 /** The list of color resources created by this viewer */
170 private final List
<Color
> fColors
= new ArrayList
<>();
172 private ListenerNotifier fListenerNotifier
;
174 private Composite fTimeAlignedComposite
;
176 private class ListenerNotifier
extends Thread
{
177 private static final long DELAY
= 400L;
178 private static final long POLLING_INTERVAL
= 10L;
179 private long fLastUpdateTime
= Long
.MAX_VALUE
;
180 private boolean fSelectionChanged
= false;
181 private boolean fTimeRangeUpdated
= false;
182 private boolean fTimeSelected
= false;
186 while ((System
.currentTimeMillis() - fLastUpdateTime
) < DELAY
) {
188 Thread
.sleep(POLLING_INTERVAL
);
189 } catch (Exception e
) {
193 Display
.getDefault().asyncExec(new Runnable() {
196 if (fListenerNotifier
!= ListenerNotifier
.this) {
199 fListenerNotifier
= null;
200 if (ListenerNotifier
.this.isInterrupted() || fDataViewer
.isDisposed()) {
203 if (fSelectionChanged
) {
204 fireSelectionChanged(fSelectedEntry
);
206 if (fTimeRangeUpdated
) {
207 fireTimeRangeUpdated(fTime0
, fTime1
);
210 fireTimeSelected(fSelectionBegin
, fSelectionEnd
);
216 public void selectionChanged() {
217 fSelectionChanged
= true;
218 fLastUpdateTime
= System
.currentTimeMillis();
221 public void timeRangeUpdated() {
222 fTimeRangeUpdated
= true;
223 fLastUpdateTime
= System
.currentTimeMillis();
226 public void timeSelected() {
227 fTimeSelected
= true;
228 fLastUpdateTime
= System
.currentTimeMillis();
231 public boolean hasSelectionChanged() {
232 return fSelectionChanged
;
235 public boolean hasTimeRangeUpdated() {
236 return fTimeRangeUpdated
;
239 public boolean hasTimeSelected() {
240 return fTimeSelected
;
244 private final static class MarkerComparator
implements Comparator
<IMarkerEvent
> {
246 public int compare(IMarkerEvent o1
, IMarkerEvent o2
) {
247 int res
= Long
.compare(o1
.getTime(), o2
.getTime());
251 return Long
.compare(o1
.getDuration(), o2
.getDuration());
256 * Standard constructor.
258 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
261 * The parent UI composite object
265 public TimeGraphViewer(Composite parent
, int style
) {
266 createDataViewer(parent
, style
);
267 fTimeGraphContentProvider
= new TimeGraphContentProvider();
271 * Sets the timegraph content provider used by this timegraph viewer.
273 * @param timeGraphContentProvider
274 * the timegraph content provider
276 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
) {
277 fTimeGraphContentProvider
= timeGraphContentProvider
;
281 * Gets the timegraph content provider used by this timegraph viewer.
283 * @return the timegraph content provider
285 public ITimeGraphContentProvider
getTimeGraphContentProvider() {
286 return fTimeGraphContentProvider
;
290 * Sets the timegraph presentation provider used by this timegraph viewer.
292 * @param timeGraphProvider
293 * the timegraph provider
295 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider
) {
296 fTimeGraphProvider
= timeGraphProvider
;
297 fTimeGraphCtrl
.setTimeGraphProvider(timeGraphProvider
);
298 fToolTipHandler
= new TimeGraphTooltipHandler(fTimeGraphProvider
, fTimeDataProvider
);
299 fToolTipHandler
.activateHoverHelp(fTimeGraphCtrl
);
303 * Sets the tree columns for this time graph combo's filter dialog.
305 * @param columnNames the tree column names
308 public void setFilterColumns(String
[] columnNames
) {
309 getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames
);
313 * Sets the tree content provider used by the filter dialog
315 * @param contentProvider the tree content provider
318 public void setFilterContentProvider(ITreeContentProvider contentProvider
) {
319 getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider
);
323 * Sets the tree label provider used by the filter dialog
325 * @param labelProvider the tree label provider
328 public void setFilterLabelProvider(ITableLabelProvider labelProvider
) {
329 getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider
);
333 * Sets or clears the input for this time graph viewer.
335 * @param inputElement
336 * The input of this time graph viewer, or <code>null</code> if
339 public void setInput(Object inputElement
) {
340 fInputElement
= inputElement
;
341 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(inputElement
);
342 fListenerNotifier
= null;
343 if (fTimeGraphCtrl
!= null) {
346 fSelectionBegin
= SWT
.DEFAULT
;
347 fSelectionEnd
= SWT
.DEFAULT
;
348 updateMarkerActions();
349 fSelectedEntry
= null;
350 refreshAllData(input
);
355 * Gets the input for this time graph viewer.
357 * @return The input of this time graph viewer, or <code>null</code> if none
359 public Object
getInput() {
360 return fInputElement
;
364 * Sets (or clears if null) the list of links to display on this combo
367 * the links to display in this time graph combo
369 public void setLinks(List
<ILinkEvent
> links
) {
370 if (fTimeGraphCtrl
!= null) {
371 fTimeGraphCtrl
.refreshArrows(links
);
378 public void refresh() {
379 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(fInputElement
);
381 refreshAllData(input
);
385 * Callback for when the control is moved
390 public void controlMoved(ControlEvent e
) {
394 * Callback for when the control is resized
399 public void controlResized(ControlEvent e
) {
404 * @return The string representing the view type
406 protected String
getViewTypeStr() {
407 return "viewoption.threads"; //$NON-NLS-1$
410 int getMarginWidth() {
414 int getMarginHeight() {
419 fMinTimeInterval
= 1;
420 fSelectionBegin
= SWT
.DEFAULT
;
421 fSelectionEnd
= SWT
.DEFAULT
;
422 fNameWidth
= Utils
.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
423 fNameWidthPref
, fMinNameWidth
, MAX_NAME_WIDTH
);
427 Utils
.saveIntOption(getPreferenceString("namewidth"), fNameWidth
); //$NON-NLS-1$
431 * Create a data viewer.
437 * @return The new data viewer
439 protected Control
createDataViewer(Composite parent
, int style
) {
441 fColorScheme
= new TimeGraphColorScheme();
442 fDataViewer
= new Composite(parent
, style
) {
444 public void redraw() {
445 fTimeScaleCtrl
.redraw();
446 fTimeGraphCtrl
.redraw();
450 fDataViewer
.addDisposeListener(new DisposeListener() {
452 public void widgetDisposed(DisposeEvent e
) {
453 for (Color color
: fColors
) {
458 GridLayout gl
= new GridLayout(2, false);
459 gl
.marginHeight
= fBorderWidth
;
461 gl
.verticalSpacing
= 0;
462 gl
.horizontalSpacing
= 0;
463 fDataViewer
.setLayout(gl
);
465 fTimeAlignedComposite
= new Composite(fDataViewer
, style
) {
467 public void redraw() {
468 fDataViewer
.redraw();
472 GridLayout gl2
= new GridLayout(1, false);
473 gl2
.marginHeight
= fBorderWidth
;
475 gl2
.verticalSpacing
= 0;
476 gl2
.horizontalSpacing
= 0;
477 fTimeAlignedComposite
.setLayout(gl2
);
478 fTimeAlignedComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
480 fTimeScaleCtrl
= new TimeGraphScale(fTimeAlignedComposite
, fColorScheme
);
481 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
482 fTimeScaleCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
483 fTimeScaleCtrl
.setHeight(fTimeScaleHeight
);
484 fTimeScaleCtrl
.addMouseWheelListener(new MouseWheelListener() {
486 public void mouseScrolled(MouseEvent e
) {
487 fTimeGraphCtrl
.zoom(e
.count
> 0);
491 fTimeGraphCtrl
= createTimeGraphControl(fTimeAlignedComposite
, fColorScheme
);
493 fTimeGraphCtrl
.setTimeProvider(this);
494 fTimeGraphCtrl
.setTimeGraphScale(fTimeScaleCtrl
);
495 fTimeGraphCtrl
.addSelectionListener(this);
496 fTimeGraphCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
497 fTimeGraphCtrl
.addMouseWheelListener(new MouseWheelListener() {
499 public void mouseScrolled(MouseEvent e
) {
500 adjustVerticalScrollBar();
503 fTimeGraphCtrl
.addKeyListener(new KeyAdapter() {
505 public void keyPressed(KeyEvent e
) {
506 if (e
.character
== '+') {
508 } else if (e
.character
== '-') {
511 adjustVerticalScrollBar();
515 fVerticalScrollBar
= new Slider(fDataViewer
, SWT
.VERTICAL
| SWT
.NO_FOCUS
);
516 fVerticalScrollBar
.setLayoutData(new GridData(SWT
.DEFAULT
, SWT
.FILL
, false, true, 1, 1));
517 fVerticalScrollBar
.addSelectionListener(new SelectionAdapter() {
519 public void widgetSelected(SelectionEvent e
) {
520 setTopIndex(fVerticalScrollBar
.getSelection());
524 fHorizontalScrollBar
= new Slider(fDataViewer
, SWT
.HORIZONTAL
| SWT
.NO_FOCUS
);
525 fHorizontalScrollBar
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
526 fHorizontalScrollBar
.addListener(SWT
.MouseWheel
, new Listener() {
528 public void handleEvent(Event event
) {
529 if ((event
.stateMask
& SWT
.MODIFIER_MASK
) == SWT
.CTRL
) {
530 getTimeGraphControl().zoom(event
.count
> 0);
532 getTimeGraphControl().horizontalScroll(event
.count
> 0);
534 // don't handle the immediately following SWT.Selection event
538 fHorizontalScrollBar
.addListener(SWT
.Selection
, new Listener() {
540 public void handleEvent(Event event
) {
541 int start
= fHorizontalScrollBar
.getSelection();
542 long time0
= getTime0();
543 long time1
= getTime1();
544 long timeMin
= getMinTime();
545 long timeMax
= getMaxTime();
546 long delta
= timeMax
- timeMin
;
548 long range
= time1
- time0
;
549 time0
= timeMin
+ Math
.round(delta
* ((double) start
/ H_SCROLLBAR_MAX
));
550 time1
= time0
+ range
;
552 setStartFinishTimeNotify(time0
, time1
);
556 Composite filler
= new Composite(fDataViewer
, SWT
.NONE
);
557 GridData gd
= new GridData(SWT
.DEFAULT
, SWT
.DEFAULT
, false, false);
558 gd
.heightHint
= fHorizontalScrollBar
.getSize().y
;
559 filler
.setLayoutData(gd
);
560 filler
.setLayout(new FillLayout());
562 fTimeGraphCtrl
.addControlListener(new ControlAdapter() {
564 public void controlResized(ControlEvent event
) {
569 fDataViewer
.update();
570 adjustHorizontalScrollBar();
571 adjustVerticalScrollBar();
578 public void dispose() {
580 fTimeGraphCtrl
.dispose();
581 fDataViewer
.dispose();
582 fColorScheme
.dispose();
586 * Create a new time graph control.
589 * The parent composite
592 * @return The new TimeGraphControl
594 protected TimeGraphControl
createTimeGraphControl(Composite parent
,
595 TimeGraphColorScheme colors
) {
596 return new TimeGraphControl(parent
, colors
);
600 * Resize the controls
602 public void resizeControls() {
603 Rectangle r
= fDataViewer
.getClientArea();
609 if (fNameWidth
> width
- fMinNameWidth
) {
610 fNameWidth
= width
- fMinNameWidth
;
612 if (fNameWidth
< fMinNameWidth
) {
613 fNameWidth
= fMinNameWidth
;
615 adjustHorizontalScrollBar();
616 adjustVerticalScrollBar();
620 * Recalculate the time bounds based on the time graph entries,
621 * if the user-specified bound is set to SWT.DEFAULT.
624 * The root time graph entries in the model
626 public void setTimeRange(ITimeGraphEntry entries
[]) {
627 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
628 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
629 if (fBeginTime
!= SWT
.DEFAULT
&& fEndTime
!= SWT
.DEFAULT
) {
632 if (entries
== null || entries
.length
== 0) {
635 if (fTime0Bound
== SWT
.DEFAULT
) {
636 fTime0Bound
= Long
.MAX_VALUE
;
638 if (fTime1Bound
== SWT
.DEFAULT
) {
639 fTime1Bound
= Long
.MIN_VALUE
;
641 for (ITimeGraphEntry entry
: entries
) {
646 private void setTimeRange(ITimeGraphEntry entry
) {
647 if (fBeginTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getStartTime() != SWT
.DEFAULT
) {
648 fTime0Bound
= Math
.min(entry
.getStartTime(), fTime0Bound
);
650 if (fEndTime
== SWT
.DEFAULT
&& entry
.hasTimeEvents() && entry
.getEndTime() != SWT
.DEFAULT
) {
651 fTime1Bound
= Math
.max(entry
.getEndTime(), fTime1Bound
);
653 if (entry
.hasChildren()) {
654 for (ITimeGraphEntry child
: entry
.getChildren()) {
661 * Set the time bounds to the provided values.
664 * The bounds begin time, or SWT.DEFAULT to use the input bounds
666 * The bounds end time, or SWT.DEFAULT to use the input bounds
668 public void setTimeBounds(long beginTime
, long endTime
) {
669 fBeginTime
= beginTime
;
671 fTime0Bound
= (fBeginTime
!= SWT
.DEFAULT ? fBeginTime
: fEndTime
);
672 fTime1Bound
= (fEndTime
!= SWT
.DEFAULT ? fEndTime
: fBeginTime
);
673 if (fTime0Bound
> fTime1Bound
) {
674 // only possible if both are not default
675 fBeginTime
= endTime
;
676 fEndTime
= beginTime
;
677 fTime0Bound
= fBeginTime
;
678 fTime1Bound
= fEndTime
;
680 adjustHorizontalScrollBar();
684 * Recalculate the current time window when bounds have changed.
686 public void setTimeBounds() {
687 if (!fTimeRangeFixed
) {
688 fTime0
= fTime0Bound
;
689 fTime1
= fTime1Bound
;
691 fTime0
= Math
.max(fTime0Bound
, Math
.min(fTime0
, fTime1Bound
));
692 fTime1
= Math
.max(fTime0Bound
, Math
.min(fTime1
, fTime1Bound
));
693 if (fTime1
- fTime0
< fMinTimeInterval
) {
694 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
701 private void refreshAllData(ITimeGraphEntry
[] traces
) {
703 if (fSelectionBegin
< fBeginTime
) {
704 fSelectionBegin
= fBeginTime
;
705 } else if (fSelectionBegin
> fEndTime
) {
706 fSelectionBegin
= fEndTime
;
708 if (fSelectionEnd
< fBeginTime
) {
709 fSelectionEnd
= fBeginTime
;
710 } else if (fSelectionEnd
> fEndTime
) {
711 fSelectionEnd
= fEndTime
;
713 fTimeGraphCtrl
.refreshData(traces
);
714 fTimeScaleCtrl
.redraw();
715 updateMarkerActions();
716 adjustVerticalScrollBar();
720 * Callback for when this view is focused
722 public void setFocus() {
723 if (null != fTimeGraphCtrl
) {
724 fTimeGraphCtrl
.setFocus();
729 * Get the current focus status of this view.
731 * @return If the view is currently focused, or not
733 public boolean isInFocus() {
734 return fTimeGraphCtrl
.isInFocus();
738 * Get the view's current selection
740 * @return The entry that is selected
742 public ITimeGraphEntry
getSelection() {
743 return fTimeGraphCtrl
.getSelectedTrace();
747 * Get the index of the current selection
751 public int getSelectionIndex() {
752 return fTimeGraphCtrl
.getSelectedIndex();
756 public long getTime0() {
761 public long getTime1() {
766 public long getMinTimeInterval() {
767 return fMinTimeInterval
;
771 public int getNameSpace() {
776 public void setNameSpace(int width
) {
778 int w
= fTimeGraphCtrl
.getClientArea().width
;
779 if (fNameWidth
> w
- MIN_NAME_WIDTH
) {
780 fNameWidth
= w
- MIN_NAME_WIDTH
;
782 if (fNameWidth
< MIN_NAME_WIDTH
) {
783 fNameWidth
= MIN_NAME_WIDTH
;
785 fTimeGraphCtrl
.redraw();
786 fTimeScaleCtrl
.redraw();
790 public int getTimeSpace() {
791 int w
= fTimeGraphCtrl
.getClientArea().width
;
792 return w
- fNameWidth
;
796 public long getBeginTime() {
801 public long getEndTime() {
806 public long getMaxTime() {
811 public long getMinTime() {
816 public long getSelectionBegin() {
817 return fSelectionBegin
;
821 public long getSelectionEnd() {
822 return fSelectionEnd
;
826 public void setStartFinishTimeNotify(long time0
, long time1
) {
827 setStartFinishTimeInt(time0
, time1
);
828 notifyRangeListeners();
832 public void notifyStartFinishTime() {
833 notifyRangeListeners();
837 public void setStartFinishTime(long time0
, long time1
) {
838 /* if there is a pending time range, ignore this one */
839 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeRangeUpdated()) {
842 setStartFinishTimeInt(time0
, time1
);
843 updateExtSynchValues();
846 private void setStartFinishTimeInt(long time0
, long time1
) {
848 if (fTime0
< fTime0Bound
) {
849 fTime0
= fTime0Bound
;
851 if (fTime0
> fTime1Bound
) {
852 fTime0
= fTime1Bound
;
855 if (fTime1
< fTime0Bound
) {
856 fTime1
= fTime0Bound
;
858 if (fTime1
> fTime1Bound
) {
859 fTime1
= fTime1Bound
;
861 if (fTime1
- fTime0
< fMinTimeInterval
) {
862 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
864 fTimeRangeFixed
= true;
865 adjustHorizontalScrollBar();
866 fTimeGraphCtrl
.redraw();
867 fTimeScaleCtrl
.redraw();
871 public void resetStartFinishTime() {
872 setStartFinishTimeNotify(fTime0Bound
, fTime1Bound
);
873 fTimeRangeFixed
= false;
877 public void setSelectedTimeNotify(long time
, boolean ensureVisible
) {
878 setSelectedTimeInt(time
, ensureVisible
, true);
882 public void setSelectedTime(long time
, boolean ensureVisible
) {
883 /* if there is a pending time selection, ignore this one */
884 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
887 setSelectedTimeInt(time
, ensureVisible
, false);
891 public void setSelectionRangeNotify(long beginTime
, long endTime
) {
894 long selectionBegin
= fSelectionBegin
;
895 long selectionEnd
= fSelectionEnd
;
896 fSelectionBegin
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, beginTime
));
897 fSelectionEnd
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, endTime
));
898 boolean changed
= (selectionBegin
!= fSelectionBegin
|| selectionEnd
!= fSelectionEnd
);
899 ensureVisible(fSelectionEnd
);
900 fTimeGraphCtrl
.redraw();
901 fTimeScaleCtrl
.redraw();
902 updateMarkerActions();
903 if ((time0
!= fTime0
) || (time1
!= fTime1
)) {
904 notifyRangeListeners();
907 notifyTimeListeners();
912 public void setSelectionRange(long beginTime
, long endTime
) {
913 /* if there is a pending time selection, ignore this one */
914 if (fListenerNotifier
!= null && fListenerNotifier
.hasTimeSelected()) {
917 fSelectionBegin
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, beginTime
));
918 fSelectionEnd
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, endTime
));
919 fTimeGraphCtrl
.redraw();
920 fTimeScaleCtrl
.redraw();
921 updateMarkerActions();
924 private void setSelectedTimeInt(long time
, boolean ensureVisible
, boolean doNotify
) {
925 long selection
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, time
));
929 ensureVisible(selection
);
931 fTimeGraphCtrl
.redraw();
932 fTimeScaleCtrl
.redraw();
934 boolean notifySelectedTime
= (selection
!= fSelectionBegin
|| selection
!= fSelectionEnd
);
935 fSelectionBegin
= selection
;
936 fSelectionEnd
= selection
;
937 updateMarkerActions();
939 if ((time0
!= fTime0
) || (time1
!= fTime1
)) {
940 notifyRangeListeners();
943 if (doNotify
&& notifySelectedTime
) {
944 notifyTimeListeners();
948 private void ensureVisible(long time
) {
949 long timeMid
= (fTime1
- fTime0
) / 2;
951 long dt
= fTime0
- time
+ timeMid
;
954 } else if (time
> fTime1
) {
955 long dt
= time
- fTime1
+ timeMid
;
959 if (fTime0
< fTime0Bound
) {
960 fTime1
= Math
.min(fTime1Bound
, fTime1
+ (fTime0Bound
- fTime0
));
961 fTime0
= fTime0Bound
;
962 } else if (fTime1
> fTime1Bound
) {
963 fTime0
= Math
.max(fTime0Bound
, fTime0
- (fTime1
- fTime1Bound
));
964 fTime1
= fTime1Bound
;
966 if (fTime1
- fTime0
< fMinTimeInterval
) {
967 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
969 adjustHorizontalScrollBar();
973 public void widgetDefaultSelected(SelectionEvent e
) {
974 if (fSelectedEntry
!= getSelection()) {
975 fSelectedEntry
= getSelection();
976 notifySelectionListeners();
981 public void widgetSelected(SelectionEvent e
) {
982 if (fSelectedEntry
!= getSelection()) {
983 fSelectedEntry
= getSelection();
984 notifySelectionListeners();
989 * Callback for when the next event is selected
992 * true to extend selection range, false for single selection
995 public void selectNextEvent(boolean extend
) {
996 fTimeGraphCtrl
.selectNextEvent(extend
);
997 adjustVerticalScrollBar();
1001 * Callback for when the previous event is selected
1004 * true to extend selection range, false for single selection
1007 public void selectPrevEvent(boolean extend
) {
1008 fTimeGraphCtrl
.selectPrevEvent(extend
);
1009 adjustVerticalScrollBar();
1013 * Callback for when the next item is selected
1015 public void selectNextItem() {
1016 fTimeGraphCtrl
.selectNextTrace();
1017 adjustVerticalScrollBar();
1021 * Callback for when the previous item is selected
1023 public void selectPrevItem() {
1024 fTimeGraphCtrl
.selectPrevTrace();
1025 adjustVerticalScrollBar();
1029 * Callback for the show legend action
1031 public void showLegend() {
1032 if (fDataViewer
== null || fDataViewer
.isDisposed()) {
1036 TimeGraphLegend
.open(fDataViewer
.getShell(), fTimeGraphProvider
);
1040 * Callback for the Zoom In action
1042 public void zoomIn() {
1043 fTimeGraphCtrl
.zoomIn();
1047 * Callback for the Zoom Out action
1049 public void zoomOut() {
1050 fTimeGraphCtrl
.zoomOut();
1053 private String
getPreferenceString(String string
) {
1054 return getViewTypeStr() + "." + string
; //$NON-NLS-1$
1058 * Add a selection listener
1061 * The listener to add
1063 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
1064 fSelectionListeners
.add(listener
);
1068 * Remove a selection listener
1071 * The listener to remove
1073 public void removeSelectionListener(ITimeGraphSelectionListener listener
) {
1074 fSelectionListeners
.remove(listener
);
1077 private void notifySelectionListeners() {
1078 if (fListenerNotifier
== null) {
1079 fListenerNotifier
= new ListenerNotifier();
1080 fListenerNotifier
.start();
1082 fListenerNotifier
.selectionChanged();
1085 private void fireSelectionChanged(ITimeGraphEntry selection
) {
1086 TimeGraphSelectionEvent event
= new TimeGraphSelectionEvent(this, selection
);
1088 for (ITimeGraphSelectionListener listener
: fSelectionListeners
) {
1089 listener
.selectionChanged(event
);
1094 * Add a time listener
1097 * The listener to add
1099 public void addTimeListener(ITimeGraphTimeListener listener
) {
1100 fTimeListeners
.add(listener
);
1104 * Remove a time listener
1107 * The listener to remove
1109 public void removeTimeListener(ITimeGraphTimeListener listener
) {
1110 fTimeListeners
.remove(listener
);
1113 private void notifyTimeListeners() {
1114 if (fListenerNotifier
== null) {
1115 fListenerNotifier
= new ListenerNotifier();
1116 fListenerNotifier
.start();
1118 fListenerNotifier
.timeSelected();
1121 private void fireTimeSelected(long startTime
, long endTime
) {
1122 TimeGraphTimeEvent event
= new TimeGraphTimeEvent(this, startTime
, endTime
);
1124 for (ITimeGraphTimeListener listener
: fTimeListeners
) {
1125 listener
.timeSelected(event
);
1130 * Add a range listener
1133 * The listener to add
1135 public void addRangeListener(ITimeGraphRangeListener listener
) {
1136 fRangeListeners
.add(listener
);
1140 * Remove a range listener
1143 * The listener to remove
1145 public void removeRangeListener(ITimeGraphRangeListener listener
) {
1146 fRangeListeners
.remove(listener
);
1149 private void notifyRangeListeners() {
1150 if (fListenerNotifier
== null) {
1151 fListenerNotifier
= new ListenerNotifier();
1152 fListenerNotifier
.start();
1154 fListenerNotifier
.timeRangeUpdated();
1157 private void fireTimeRangeUpdated(long startTime
, long endTime
) {
1158 // Check if the time has actually changed from last notification
1159 if (startTime
!= fTime0ExtSynch
|| endTime
!= fTime1ExtSynch
) {
1160 // Notify Time Scale Selection Listeners
1161 TimeGraphRangeUpdateEvent event
= new TimeGraphRangeUpdateEvent(this, startTime
, endTime
);
1163 for (ITimeGraphRangeListener listener
: fRangeListeners
) {
1164 listener
.timeRangeUpdated(event
);
1167 // update external synch values
1168 updateExtSynchValues();
1173 * Add a bookmark listener
1176 * The listener to add
1179 public void addBookmarkListener(ITimeGraphBookmarkListener listener
) {
1180 fBookmarkListeners
.add(listener
);
1184 * Remove a bookmark listener
1187 * The listener to remove
1190 public void removeBookmarkListener(ITimeGraphBookmarkListener listener
) {
1191 fBookmarkListeners
.remove(listener
);
1194 private void fireBookmarkAdded(IMarkerEvent bookmark
) {
1195 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1197 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1198 listener
.bookmarkAdded(event
);
1202 private void fireBookmarkRemoved(IMarkerEvent bookmark
) {
1203 TimeGraphBookmarkEvent event
= new TimeGraphBookmarkEvent(this, bookmark
);
1205 for (ITimeGraphBookmarkListener listener
: fBookmarkListeners
) {
1206 listener
.bookmarkRemoved(event
);
1211 * Set the bookmarks list.
1214 * The bookmarks list, or null
1217 public void setBookmarks(List
<IMarkerEvent
> bookmarks
) {
1218 for (IMarkerEvent bookmark
: fBookmarks
) {
1219 checkDisposeColor(bookmark
.getColor());
1222 if (bookmarks
!= null) {
1223 fBookmarks
.addAll(bookmarks
);
1226 updateMarkerActions();
1230 * Get the bookmarks list.
1232 * @return The bookmarks list
1235 public List
<IMarkerEvent
> getBookmarks() {
1236 return Collections
.unmodifiableList(fBookmarks
);
1240 * Set the markers list.
1243 * The markers list, or null
1246 public void setMarkers(List
<IMarkerEvent
> markers
) {
1248 if (markers
!= null) {
1249 fMarkers
.addAll(markers
);
1252 updateMarkerActions();
1256 * Get the markers list.
1258 * @return The markers list, or null
1261 public List
<IMarkerEvent
> getMarkers() {
1262 return Collections
.unmodifiableList(fMarkers
);
1266 * Dispose the color resource if and only if it was created by this viewer.
1271 private void checkDisposeColor(Color color
) {
1272 for (int i
= 0; i
< fColors
.size(); i
++) {
1273 /* check for identity, not equality */
1274 if (fColors
.get(i
) == color
) {
1283 * Callback to set a selected event in the view
1286 * The event that was selected
1288 * The source of this selection event
1290 public void setSelectedEvent(ITimeEvent event
, Object source
) {
1291 if (event
== null || source
== this) {
1294 fSelectedEntry
= event
.getEntry();
1295 fTimeGraphCtrl
.selectItem(fSelectedEntry
, false);
1297 setSelectedTimeInt(event
.getTime(), true, true);
1298 adjustVerticalScrollBar();
1302 * Set the seeked time of a trace
1305 * The trace that was seeked
1309 * The source of this seek event
1311 public void setSelectedTraceTime(ITimeGraphEntry trace
, long time
, Object source
) {
1312 if (trace
== null || source
== this) {
1315 fSelectedEntry
= trace
;
1316 fTimeGraphCtrl
.selectItem(trace
, false);
1318 setSelectedTimeInt(time
, true, true);
1322 * Callback for a trace selection
1325 * The trace that was selected
1327 public void setSelection(ITimeGraphEntry trace
) {
1328 /* if there is a pending selection, ignore this one */
1329 if (fListenerNotifier
!= null && fListenerNotifier
.hasSelectionChanged()) {
1332 fSelectedEntry
= trace
;
1333 fTimeGraphCtrl
.selectItem(trace
, false);
1334 adjustVerticalScrollBar();
1338 * Callback for a time window selection
1341 * Start time of the range
1343 * End time of the range
1345 * Source of the event
1347 public void setSelectVisTimeWindow(long time0
, long time1
, Object source
) {
1348 if (source
== this) {
1352 setStartFinishTimeInt(time0
, time1
);
1354 // update notification time values since we are now in synch with the
1355 // external application
1356 updateExtSynchValues();
1360 * update the cache values used to identify the need to send a time window
1361 * update to external registered listeners
1363 private void updateExtSynchValues() {
1364 // last time notification cache
1365 fTime0ExtSynch
= fTime0
;
1366 fTime1ExtSynch
= fTime1
;
1370 public TimeFormat
getTimeFormat() {
1376 * the {@link TimeFormat} used to display timestamps
1378 public void setTimeFormat(TimeFormat tf
) {
1379 this.fTimeFormat
= tf
;
1380 if (tf
== TimeFormat
.CYCLES
) {
1381 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1383 fTimeDataProvider
= this;
1385 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1386 if (fToolTipHandler
!= null) {
1387 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1392 * Sets the clock frequency. Used when the time format is set to CYCLES.
1394 * @param clockFrequency
1395 * the clock frequency in Hz
1397 public void setClockFrequency(long clockFrequency
) {
1398 fClockFrequency
= clockFrequency
;
1399 if (fTimeFormat
== TimeFormat
.CYCLES
) {
1400 fTimeDataProvider
= new TimeDataProviderCyclesConverter(this, fClockFrequency
);
1401 fTimeScaleCtrl
.setTimeProvider(fTimeDataProvider
);
1402 if (fToolTipHandler
!= null) {
1403 fToolTipHandler
.setTimeProvider(fTimeDataProvider
);
1409 * Retrieve the border width
1413 public int getBorderWidth() {
1414 return fBorderWidth
;
1418 * Set the border width
1420 * @param borderWidth
1423 public void setBorderWidth(int borderWidth
) {
1424 if (borderWidth
> -1) {
1425 this.fBorderWidth
= borderWidth
;
1426 GridLayout gl
= (GridLayout
) fDataViewer
.getLayout();
1427 gl
.marginHeight
= borderWidth
;
1432 * Retrieve the height of the header
1434 * @return The height
1436 public int getHeaderHeight() {
1437 return fTimeScaleHeight
;
1441 * Set the height of the header
1443 * @param headerHeight
1446 public void setHeaderHeight(int headerHeight
) {
1447 if (headerHeight
> -1) {
1448 this.fTimeScaleHeight
= headerHeight
;
1449 fTimeScaleCtrl
.setHeight(headerHeight
);
1454 * Retrieve the height of an item row
1456 * @return The height
1458 public int getItemHeight() {
1459 if (fTimeGraphCtrl
!= null) {
1460 return fTimeGraphCtrl
.getItemHeight();
1466 * Set the height of an item row
1471 public void setItemHeight(int rowHeight
) {
1472 if (fTimeGraphCtrl
!= null) {
1473 fTimeGraphCtrl
.setItemHeight(rowHeight
);
1478 * Set the minimum item width
1483 public void setMinimumItemWidth(int width
) {
1484 if (fTimeGraphCtrl
!= null) {
1485 fTimeGraphCtrl
.setMinimumItemWidth(width
);
1490 * Set the width for the name column
1495 public void setNameWidthPref(int width
) {
1496 fNameWidthPref
= width
;
1504 * Retrieve the configure width for the name column
1510 public int getNameWidthPref(int width
) {
1511 return fNameWidthPref
;
1515 * Returns the primary control associated with this viewer.
1517 * @return the SWT control which displays this viewer's content
1519 public Control
getControl() {
1524 * Returns the time graph control associated with this viewer.
1526 * @return the time graph control
1528 public TimeGraphControl
getTimeGraphControl() {
1529 return fTimeGraphCtrl
;
1533 * Returns the time graph scale associated with this viewer.
1535 * @return the time graph scale
1537 public TimeGraphScale
getTimeGraphScale() {
1538 return fTimeScaleCtrl
;
1542 * Returns the composite containing all the controls that are time aligned,
1543 * i.e. TimeGraphScale, TimeGraphControl.
1545 * @return the time based composite
1548 public Composite
getTimeAlignedComposite() {
1549 return fTimeAlignedComposite
;
1553 * Return the x coordinate corresponding to a time
1557 * @return the x coordinate corresponding to the time
1559 public int getXForTime(long time
) {
1560 return fTimeGraphCtrl
.getXForTime(time
);
1564 * Return the time corresponding to an x coordinate
1568 * @return the time corresponding to the x coordinate
1570 public long getTimeAtX(int x
) {
1571 return fTimeGraphCtrl
.getTimeAtX(x
);
1575 * Get the selection provider
1577 * @return the selection provider
1579 public ISelectionProvider
getSelectionProvider() {
1580 return fTimeGraphCtrl
;
1584 * Wait for the cursor
1587 * Wait indefinitely?
1589 public void waitCursor(boolean waitInd
) {
1590 fTimeGraphCtrl
.waitCursor(waitInd
);
1594 * Get the horizontal scroll bar object
1596 * @return The scroll bar
1598 public Slider
getHorizontalBar() {
1599 return fHorizontalScrollBar
;
1603 * Get the vertical scroll bar object
1605 * @return The scroll bar
1607 public Slider
getVerticalBar() {
1608 return fVerticalScrollBar
;
1612 * Set the given index as the top one
1615 * The index that will go to the top
1617 public void setTopIndex(int index
) {
1618 fTimeGraphCtrl
.setTopIndex(index
);
1619 adjustVerticalScrollBar();
1623 * Retrieve the current top index
1625 * @return The top index
1627 public int getTopIndex() {
1628 return fTimeGraphCtrl
.getTopIndex();
1632 * Sets the auto-expand level to be used for new entries discovered when
1633 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1634 * means that there is no auto-expand; 1 means that top-level entries are
1635 * expanded, but not their children; 2 means that top-level entries are
1636 * expanded, and their children, but not grand-children; and so on.
1638 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1642 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1643 * levels of the tree
1645 public void setAutoExpandLevel(int level
) {
1646 fTimeGraphCtrl
.setAutoExpandLevel(level
);
1650 * Returns the auto-expand level.
1652 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1653 * the tree are expanded automatically
1654 * @see #setAutoExpandLevel
1656 public int getAutoExpandLevel() {
1657 return fTimeGraphCtrl
.getAutoExpandLevel();
1661 * Get the expanded state of an entry.
1665 * @return true if the entry is expanded, false if collapsed
1668 public boolean getExpandedState(ITimeGraphEntry entry
) {
1669 return fTimeGraphCtrl
.getExpandedState(entry
);
1673 * Set the expanded state of an entry
1676 * The entry to expand/collapse
1678 * True for expanded, false for collapsed
1680 public void setExpandedState(ITimeGraphEntry entry
, boolean expanded
) {
1681 fTimeGraphCtrl
.setExpandedState(entry
, expanded
);
1682 adjustVerticalScrollBar();
1686 * Collapses all nodes of the viewer's tree, starting with the root.
1688 public void collapseAll() {
1689 fTimeGraphCtrl
.collapseAll();
1690 adjustVerticalScrollBar();
1694 * Expands all entries of the viewer's tree, starting with the root.
1696 public void expandAll() {
1697 fTimeGraphCtrl
.expandAll();
1698 adjustVerticalScrollBar();
1702 * Get the number of expanded (visible) time graph entries. This includes
1703 * leafs and does not include filtered-out entries.
1705 * @return The number of expanded (visible) time graph entries
1707 public int getExpandedElementCount() {
1708 return fTimeGraphCtrl
.getExpandedElementCount();
1712 * Get the expanded (visible) time graph entries. This includes leafs and
1713 * does not include filtered-out entries.
1715 * @return The array of expanded (visible) time graph entries
1717 public ITimeGraphEntry
[] getExpandedElements() {
1718 return fTimeGraphCtrl
.getExpandedElements();
1722 * Add a tree listener
1725 * The listener to add
1727 public void addTreeListener(ITimeGraphTreeListener listener
) {
1728 fTimeGraphCtrl
.addTreeListener(listener
);
1732 * Remove a tree listener
1735 * The listener to remove
1737 public void removeTreeListener(ITimeGraphTreeListener listener
) {
1738 fTimeGraphCtrl
.removeTreeListener(listener
);
1742 * Get the reset scale action.
1744 * @return The Action object
1746 public Action
getResetScaleAction() {
1747 if (fResetScaleAction
== null) {
1749 fResetScaleAction
= new Action() {
1752 resetStartFinishTime();
1755 fResetScaleAction
.setText(Messages
.TmfTimeGraphViewer_ResetScaleActionNameText
);
1756 fResetScaleAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ResetScaleActionToolTipText
);
1757 fResetScaleAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HOME_MENU
));
1759 return fResetScaleAction
;
1763 * Get the show legend action.
1765 * @return The Action object
1767 public Action
getShowLegendAction() {
1768 if (fShowLegendAction
== null) {
1770 fShowLegendAction
= new Action() {
1776 fShowLegendAction
.setText(Messages
.TmfTimeGraphViewer_LegendActionNameText
);
1777 fShowLegendAction
.setToolTipText(Messages
.TmfTimeGraphViewer_LegendActionToolTipText
);
1778 fShowLegendAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_LEGEND
));
1781 return fShowLegendAction
;
1785 * Get the the next event action.
1787 * @return The action object
1789 public Action
getNextEventAction() {
1790 if (fNextEventAction
== null) {
1791 fNextEventAction
= new Action() {
1793 public void runWithEvent(Event event
) {
1794 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
1795 selectNextEvent(extend
);
1799 fNextEventAction
.setText(Messages
.TmfTimeGraphViewer_NextEventActionNameText
);
1800 fNextEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextEventActionToolTipText
);
1801 fNextEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_EVENT
));
1804 return fNextEventAction
;
1808 * Get the previous event action.
1810 * @return The Action object
1812 public Action
getPreviousEventAction() {
1813 if (fPrevEventAction
== null) {
1814 fPrevEventAction
= new Action() {
1816 public void runWithEvent(Event event
) {
1817 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
1818 selectPrevEvent(extend
);
1822 fPrevEventAction
.setText(Messages
.TmfTimeGraphViewer_PreviousEventActionNameText
);
1823 fPrevEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousEventActionToolTipText
);
1824 fPrevEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_EVENT
));
1827 return fPrevEventAction
;
1831 * Get the next item action.
1833 * @return The Action object
1835 public Action
getNextItemAction() {
1836 if (fNextItemAction
== null) {
1838 fNextItemAction
= new Action() {
1844 fNextItemAction
.setText(Messages
.TmfTimeGraphViewer_NextItemActionNameText
);
1845 fNextItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextItemActionToolTipText
);
1846 fNextItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_ITEM
));
1848 return fNextItemAction
;
1852 * Get the previous item action.
1854 * @return The Action object
1856 public Action
getPreviousItemAction() {
1857 if (fPreviousItemAction
== null) {
1859 fPreviousItemAction
= new Action() {
1865 fPreviousItemAction
.setText(Messages
.TmfTimeGraphViewer_PreviousItemActionNameText
);
1866 fPreviousItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousItemActionToolTipText
);
1867 fPreviousItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_ITEM
));
1869 return fPreviousItemAction
;
1873 * Get the zoom in action
1875 * @return The Action object
1877 public Action
getZoomInAction() {
1878 if (fZoomInAction
== null) {
1879 fZoomInAction
= new Action() {
1885 fZoomInAction
.setText(Messages
.TmfTimeGraphViewer_ZoomInActionNameText
);
1886 fZoomInAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomInActionToolTipText
);
1887 fZoomInAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_IN_MENU
));
1889 return fZoomInAction
;
1893 * Get the zoom out action
1895 * @return The Action object
1897 public Action
getZoomOutAction() {
1898 if (fZoomOutAction
== null) {
1899 fZoomOutAction
= new Action() {
1905 fZoomOutAction
.setText(Messages
.TmfTimeGraphViewer_ZoomOutActionNameText
);
1906 fZoomOutAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomOutActionToolTipText
);
1907 fZoomOutAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_OUT_MENU
));
1909 return fZoomOutAction
;
1913 * Get the hide arrows action
1915 * @param dialogSettings
1916 * The dialog settings section where the state should be stored,
1919 * @return The Action object
1921 public Action
getHideArrowsAction(final IDialogSettings dialogSettings
) {
1922 if (fHideArrowsAction
== null) {
1923 fHideArrowsAction
= new Action(Messages
.TmfTimeGraphViewer_HideArrowsActionNameText
, IAction
.AS_CHECK_BOX
) {
1926 boolean hideArrows
= fHideArrowsAction
.isChecked();
1927 fTimeGraphCtrl
.hideArrows(hideArrows
);
1929 if (dialogSettings
!= null) {
1930 dialogSettings
.put(HIDE_ARROWS_KEY
, hideArrows
);
1932 if (fFollowArrowFwdAction
!= null) {
1933 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
1935 if (fFollowArrowBwdAction
!= null) {
1936 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
1940 fHideArrowsAction
.setToolTipText(Messages
.TmfTimeGraphViewer_HideArrowsActionToolTipText
);
1941 fHideArrowsAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HIDE_ARROWS
));
1942 if (dialogSettings
!= null) {
1943 boolean hideArrows
= dialogSettings
.getBoolean(HIDE_ARROWS_KEY
);
1944 fTimeGraphCtrl
.hideArrows(hideArrows
);
1945 fHideArrowsAction
.setChecked(hideArrows
);
1946 if (fFollowArrowFwdAction
!= null) {
1947 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
1949 if (fFollowArrowBwdAction
!= null) {
1950 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
1954 return fHideArrowsAction
;
1958 * Get the follow arrow forward action.
1960 * @return The Action object
1962 public Action
getFollowArrowFwdAction() {
1963 if (fFollowArrowFwdAction
== null) {
1964 fFollowArrowFwdAction
= new Action() {
1966 public void runWithEvent(Event event
) {
1967 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
1968 fTimeGraphCtrl
.followArrowFwd(extend
);
1969 adjustVerticalScrollBar();
1972 fFollowArrowFwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionNameText
);
1973 fFollowArrowFwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText
);
1974 fFollowArrowFwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_FORWARD
));
1975 if (fHideArrowsAction
!= null) {
1976 fFollowArrowFwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
1979 return fFollowArrowFwdAction
;
1983 * Get the follow arrow backward action.
1985 * @return The Action object
1987 public Action
getFollowArrowBwdAction() {
1988 if (fFollowArrowBwdAction
== null) {
1989 fFollowArrowBwdAction
= new Action() {
1991 public void runWithEvent(Event event
) {
1992 boolean extend
= (event
.stateMask
& SWT
.SHIFT
) != 0;
1993 fTimeGraphCtrl
.followArrowBwd(extend
);
1994 adjustVerticalScrollBar();
1997 fFollowArrowBwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionNameText
);
1998 fFollowArrowBwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText
);
1999 fFollowArrowBwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_BACKWARD
));
2000 if (fHideArrowsAction
!= null) {
2001 fFollowArrowBwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
2004 return fFollowArrowBwdAction
;
2008 * Get the show filter dialog action.
2010 * @return The Action object
2013 public ShowFilterDialogAction
getShowFilterDialogAction() {
2014 if (fShowFilterDialogAction
== null) {
2015 fShowFilterDialogAction
= new ShowFilterDialogAction(this);
2017 return fShowFilterDialogAction
;
2021 * Get the toggle bookmark action.
2023 * @return The Action object
2026 public Action
getToggleBookmarkAction() {
2027 if (fToggleBookmarkAction
== null) {
2028 fToggleBookmarkAction
= new Action() {
2030 public void runWithEvent(Event event
) {
2031 IMarkerEvent selectedBookmark
= getBookmarkAtSelection();
2032 if (selectedBookmark
== null) {
2033 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2034 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2035 final AddBookmarkDialog dialog
= new AddBookmarkDialog(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell(), null);
2036 if (dialog
.open() == Window
.OK
) {
2037 final String label
= dialog
.getValue();
2038 final RGBA rgba
= dialog
.getColorValue();
2039 Color color
= new Color(Display
.getDefault(), rgba
.rgb
.red
, rgba
.rgb
.green
, rgba
.rgb
.blue
, rgba
.alpha
);
2041 IMarkerEvent bookmark
= new MarkerEvent(null, time
, duration
, IMarkerEvent
.BOOKMARK
, color
, label
, true);
2042 fBookmarks
.add(bookmark
);
2044 getControl().redraw();
2045 fireBookmarkAdded(bookmark
);
2048 checkDisposeColor(selectedBookmark
.getColor());
2049 fBookmarks
.remove(selectedBookmark
);
2051 getControl().redraw();
2052 fireBookmarkRemoved(selectedBookmark
);
2054 updateMarkerActions();
2057 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2058 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2059 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2061 return fToggleBookmarkAction
;
2065 * Get the next marker action.
2067 * @return The Action object
2070 public Action
getNextMarkerAction() {
2071 if (fNextMarkerAction
== null) {
2072 fNextMarkerAction
= new Action() {
2074 public void runWithEvent(Event event
) {
2075 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2076 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2077 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2078 if (markers
== null) {
2081 for (IMarkerEvent marker
: markers
) {
2082 if (marker
.getTime() > time
||
2083 (marker
.getTime() == time
&& marker
.getDuration() > duration
)) {
2084 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration());
2090 fNextMarkerAction
.setText(Messages
.TmfTimeGraphViewer_NextMarkerActionText
);
2091 fNextMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextMarkerActionText
);
2092 fNextMarkerAction
.setImageDescriptor(NEXT_BOOKMARK
);
2094 return fNextMarkerAction
;
2098 * Get the previous marker action.
2100 * @return The Action object
2103 public Action
getPreviousMarkerAction() {
2104 if (fPreviousMarkerAction
== null) {
2105 fPreviousMarkerAction
= new Action() {
2107 public void runWithEvent(Event event
) {
2108 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2109 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2110 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2111 if (markers
== null) {
2114 for (int i
= markers
.size() - 1; i
>= 0; i
--) {
2115 IMarkerEvent marker
= markers
.get(i
);
2116 if (marker
.getTime() < time
||
2117 (marker
.getTime() == time
&& marker
.getDuration() < duration
)) {
2118 setSelectionRangeNotify(marker
.getTime(), marker
.getTime() + marker
.getDuration());
2124 fPreviousMarkerAction
.setText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2125 fPreviousMarkerAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousMarkerActionText
);
2126 fPreviousMarkerAction
.setImageDescriptor(PREVIOUS_BOOKMARK
);
2128 return fPreviousMarkerAction
;
2131 private IMarkerEvent
getBookmarkAtSelection() {
2132 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2133 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2134 for (IMarkerEvent bookmark
: fBookmarks
) {
2135 if (bookmark
.getTime() == time
&& bookmark
.getDuration() == duration
) {
2142 private void updateMarkerActions() {
2143 if (fToggleBookmarkAction
!= null) {
2144 if (getBookmarkAtSelection() != null) {
2145 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2146 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionRemoveText
);
2147 fToggleBookmarkAction
.setImageDescriptor(REMOVE_BOOKMARK
);
2149 fToggleBookmarkAction
.setText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2150 fToggleBookmarkAction
.setToolTipText(Messages
.TmfTimeGraphViewer_BookmarkActionAddText
);
2151 fToggleBookmarkAction
.setImageDescriptor(ADD_BOOKMARK
);
2154 final long time
= Math
.min(fSelectionBegin
, fSelectionEnd
);
2155 final long duration
= Math
.max(fSelectionBegin
, fSelectionEnd
) - time
;
2156 List
<IMarkerEvent
> markers
= getTimeGraphControl().getMarkers();
2157 if (markers
== null) {
2158 markers
= Collections
.emptyList();
2160 if (fPreviousMarkerAction
!= null) {
2161 fPreviousMarkerAction
.setEnabled(!markers
.isEmpty() &&
2162 (time
> markers
.get(0).getTime() || (time
== markers
.get(0).getTime() && duration
> markers
.get(0).getDuration())));
2164 if (fNextMarkerAction
!= null) {
2165 int last
= markers
.size() - 1;
2166 fNextMarkerAction
.setEnabled(!markers
.isEmpty() &&
2167 (time
< markers
.get(last
).getTime() || (time
== markers
.get(last
).getTime() && duration
< markers
.get(last
).getDuration())));
2171 private void updateMarkerList() {
2172 List
<IMarkerEvent
> markers
= new ArrayList
<>(fMarkers
);
2173 markers
.addAll(fBookmarks
);
2174 Collections
.sort(markers
, new MarkerComparator());
2175 getTimeGraphControl().setMarkers(markers
);
2178 private void adjustHorizontalScrollBar() {
2179 long time0
= getTime0();
2180 long time1
= getTime1();
2181 long timeMin
= getMinTime();
2182 long timeMax
= getMaxTime();
2183 long delta
= timeMax
- timeMin
;
2185 int thumb
= H_SCROLLBAR_MAX
;
2187 // Thumb size (page size)
2188 thumb
= Math
.max(1, (int) (H_SCROLLBAR_MAX
* ((double) (time1
- time0
) / delta
)));
2189 // At the beginning of visible window
2190 timePos
= (int) (H_SCROLLBAR_MAX
* ((double) (time0
- timeMin
) / delta
));
2192 fHorizontalScrollBar
.setValues(timePos
, 0, H_SCROLLBAR_MAX
, thumb
, Math
.max(1, thumb
/ 2), Math
.max(2, thumb
));
2195 private void adjustVerticalScrollBar() {
2196 int topIndex
= fTimeGraphCtrl
.getTopIndex();
2197 int countPerPage
= fTimeGraphCtrl
.countPerPage();
2198 int expandedElementCount
= fTimeGraphCtrl
.getExpandedElementCount();
2199 if (topIndex
+ countPerPage
> expandedElementCount
) {
2200 fTimeGraphCtrl
.setTopIndex(Math
.max(0, expandedElementCount
- countPerPage
));
2203 int selection
= fTimeGraphCtrl
.getTopIndex();
2205 int max
= Math
.max(1, expandedElementCount
- 1);
2206 int thumb
= Math
.min(max
, Math
.max(1, countPerPage
- 1));
2208 int pageIncrement
= Math
.max(1, countPerPage
);
2209 fVerticalScrollBar
.setValues(selection
, min
, max
, thumb
, increment
, pageIncrement
);
2214 * a {@link MenuDetectListener}
2215 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2217 public void addTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2218 fTimeGraphCtrl
.addTimeGraphEntryMenuListener(listener
);
2223 * a {@link MenuDetectListener}
2224 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2226 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener
) {
2227 fTimeGraphCtrl
.removeTimeGraphEntryMenuListener(listener
);
2232 * a {@link MenuDetectListener}
2233 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2235 public void addTimeEventMenuListener(MenuDetectListener listener
) {
2236 fTimeGraphCtrl
.addTimeEventMenuListener(listener
);
2241 * a {@link MenuDetectListener}
2242 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2244 public void removeTimeEventMenuListener(MenuDetectListener listener
) {
2245 fTimeGraphCtrl
.removeTimeEventMenuListener(listener
);
2250 * The filter object to be attached to the view
2252 public void addFilter(ViewerFilter filter
) {
2253 fTimeGraphCtrl
.addFilter(filter
);
2259 * The filter object to be attached to the view
2261 public void removeFilter(ViewerFilter filter
) {
2262 fTimeGraphCtrl
.removeFilter(filter
);
2267 * Returns this viewer's filters.
2269 * @return an array of viewer filters
2272 public ViewerFilter
[] getFilters() {
2273 return fTimeGraphCtrl
.getFilters();
2277 * Sets the filters, replacing any previous filters, and triggers
2278 * refiltering of the elements.
2281 * an array of viewer filters, or null
2284 public void setFilters(ViewerFilter
[] filters
) {
2285 fTimeGraphCtrl
.setFilters(filters
);
2290 * Return the time alignment information
2292 * @return the time alignment information
2294 * @see ITmfTimeAligned
2298 public TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo() {
2299 return fTimeGraphCtrl
.getTimeViewAlignmentInfo();
2303 * Return the available width for the time-axis.
2305 * @see ITmfTimeAligned
2307 * @param requestedOffset
2308 * the requested offset
2309 * @return the available width for the time-axis
2313 public int getAvailableWidth(int requestedOffset
) {
2314 int totalWidth
= fTimeAlignedComposite
.getSize().x
;
2315 return Math
.min(totalWidth
, Math
.max(0, totalWidth
- requestedOffset
));
2319 * Perform the alignment operation.
2322 * the alignment offset
2324 * the alignment width
2326 * @see ITmfTimeAligned
2330 public void performAlign(int offset
, int width
) {
2331 fTimeGraphCtrl
.performAlign(offset
);
2332 int alignmentWidth
= width
;
2333 int size
= fTimeAlignedComposite
.getSize().x
;
2334 GridLayout layout
= (GridLayout
) fTimeAlignedComposite
.getLayout();
2335 int marginSize
= size
- alignmentWidth
- offset
;
2336 layout
.marginRight
= Math
.max(0, marginSize
);
2337 fTimeAlignedComposite
.layout();