1 /*****************************************************************************
2 * Copyright (c) 2007, 2014 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
.linuxtools
.tmf
.ui
.widgets
.timegraph
;
19 import java
.util
.ArrayList
;
20 import java
.util
.List
;
22 import org
.eclipse
.jface
.action
.Action
;
23 import org
.eclipse
.jface
.action
.IAction
;
24 import org
.eclipse
.jface
.dialogs
.IDialogSettings
;
25 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
26 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
27 import org
.eclipse
.jface
.viewers
.ViewerFilter
;
28 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
29 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.ITmfImageConstants
;
30 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Messages
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.dialogs
.TimeGraphLegend
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
33 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
34 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
35 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.ITimeDataProvider
;
36 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphColorScheme
;
37 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphControl
;
38 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphScale
;
39 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.TimeGraphTooltipHandler
;
40 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
41 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
42 import org
.eclipse
.swt
.SWT
;
43 import org
.eclipse
.swt
.events
.ControlAdapter
;
44 import org
.eclipse
.swt
.events
.ControlEvent
;
45 import org
.eclipse
.swt
.events
.KeyAdapter
;
46 import org
.eclipse
.swt
.events
.KeyEvent
;
47 import org
.eclipse
.swt
.events
.MenuDetectListener
;
48 import org
.eclipse
.swt
.events
.MouseEvent
;
49 import org
.eclipse
.swt
.events
.MouseWheelListener
;
50 import org
.eclipse
.swt
.events
.SelectionAdapter
;
51 import org
.eclipse
.swt
.events
.SelectionEvent
;
52 import org
.eclipse
.swt
.events
.SelectionListener
;
53 import org
.eclipse
.swt
.graphics
.Rectangle
;
54 import org
.eclipse
.swt
.layout
.FillLayout
;
55 import org
.eclipse
.swt
.layout
.GridData
;
56 import org
.eclipse
.swt
.layout
.GridLayout
;
57 import org
.eclipse
.swt
.widgets
.Composite
;
58 import org
.eclipse
.swt
.widgets
.Control
;
59 import org
.eclipse
.swt
.widgets
.ScrollBar
;
60 import org
.eclipse
.swt
.widgets
.Slider
;
63 * Generic time graph viewer implementation
66 * @author Patrick Tasse, and others
68 public class TimeGraphViewer
implements ITimeDataProvider
, SelectionListener
{
70 /** Constant indicating that all levels of the time graph should be expanded
72 public static final int ALL_LEVELS
= AbstractTreeViewer
.ALL_LEVELS
;
74 private static final int DEFAULT_NAME_WIDTH
= 200;
75 private static final int MIN_NAME_WIDTH
= 6;
76 private static final int MAX_NAME_WIDTH
= 1000;
77 private static final int DEFAULT_HEIGHT
= 22;
78 private static final long RECENTERING_MARGIN_FACTOR
= 50;
79 private static final String HIDE_ARROWS_KEY
= "hide.arrows"; //$NON-NLS-1$
81 private long fMinTimeInterval
;
82 private ITimeGraphEntry fSelectedEntry
;
83 private long fBeginTime
;
84 private long fEndTime
;
87 private long fSelectionBegin
= 0;
88 private long fSelectionEnd
= 0;
89 private long fTime0Bound
;
90 private long fTime1Bound
;
91 private long fTime0ExtSynch
= 0;
92 private long fTime1ExtSynch
= 0;
93 private boolean fTimeRangeFixed
;
94 private int fNameWidthPref
= DEFAULT_NAME_WIDTH
;
95 private int fMinNameWidth
= MIN_NAME_WIDTH
;
96 private int fNameWidth
;
97 private Composite fDataViewer
;
99 private TimeGraphControl fTimeGraphCtrl
;
100 private TimeGraphScale fTimeScaleCtrl
;
101 private Slider fVerticalScrollBar
;
102 private TimeGraphColorScheme fColorScheme
;
103 private Object fInputElement
;
104 private ITimeGraphContentProvider fTimeGraphContentProvider
;
105 private ITimeGraphPresentationProvider fTimeGraphProvider
;
107 private List
<ITimeGraphSelectionListener
> fSelectionListeners
= new ArrayList
<>();
108 private List
<ITimeGraphTimeListener
> fTimeListeners
= new ArrayList
<>();
109 private List
<ITimeGraphRangeListener
> fRangeListeners
= new ArrayList
<>();
111 // Time format, using Epoch reference, Relative time format(default) or
113 private TimeFormat fTimeFormat
= TimeFormat
.RELATIVE
;
114 private int fBorderWidth
= 0;
115 private int fTimeScaleHeight
= DEFAULT_HEIGHT
;
117 private Action fResetScaleAction
;
118 private Action fShowLegendAction
;
119 private Action fNextEventAction
;
120 private Action fPrevEventAction
;
121 private Action fNextItemAction
;
122 private Action fPreviousItemAction
;
123 private Action fZoomInAction
;
124 private Action fZoomOutAction
;
125 private Action fHideArrowsAction
;
126 private Action fFollowArrowFwdAction
;
127 private Action fFollowArrowBwdAction
;
130 * Standard constructor.
132 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
135 * The parent UI composite object
139 public TimeGraphViewer(Composite parent
, int style
) {
140 createDataViewer(parent
, style
);
141 fTimeGraphContentProvider
= new ITimeGraphContentProvider() {
143 public ITimeGraphEntry
[] getElements(Object inputElement
) {
144 if (inputElement
instanceof ITimeGraphEntry
[]) {
145 return (ITimeGraphEntry
[]) inputElement
;
147 return new ITimeGraphEntry
[0];
153 * Sets the timegraph content provider used by this timegraph viewer.
155 * @param timeGraphContentProvider
156 * the timegraph content provider
160 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
) {
161 fTimeGraphContentProvider
= timeGraphContentProvider
;
165 * Gets the timegraph content provider used by this timegraph viewer.
167 * @return the timegraph content provider
171 public ITimeGraphContentProvider
getTimeGraphContentProvider() {
172 return fTimeGraphContentProvider
;
176 * Sets the timegraph presentation provider used by this timegraph viewer.
178 * @param timeGraphProvider
179 * the timegraph provider
181 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider
) {
182 fTimeGraphProvider
= timeGraphProvider
;
183 fTimeGraphCtrl
.setTimeGraphProvider(timeGraphProvider
);
184 TimeGraphTooltipHandler toolTipHandler
= new TimeGraphTooltipHandler(fTimeGraphProvider
, this);
185 toolTipHandler
.activateHoverHelp(fTimeGraphCtrl
);
189 * Sets or clears the input for this time graph viewer.
191 * @param inputElement
192 * The input of this time graph viewer, or <code>null</code> if
197 public void setInput(Object inputElement
) {
198 fInputElement
= inputElement
;
199 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(inputElement
);
201 if (fTimeGraphCtrl
!= null) {
203 fVerticalScrollBar
.setEnabled(true);
207 fSelectedEntry
= null;
208 refreshAllData(input
);
213 * Gets the input for this time graph viewer.
215 * @return The input of this time graph viewer, or <code>null</code> if none
219 public Object
getInput() {
220 return fInputElement
;
224 * Sets (or clears if null) the list of links to display on this combo
227 * the links to display in this time graph combo
230 public void setLinks(List
<ILinkEvent
> links
) {
231 if (fTimeGraphCtrl
!= null) {
232 fTimeGraphCtrl
.refreshArrows(links
);
239 public void refresh() {
240 ITimeGraphEntry
[] input
= fTimeGraphContentProvider
.getElements(fInputElement
);
242 fVerticalScrollBar
.setEnabled(true);
243 refreshAllData(input
);
247 * Callback for when the control is moved
252 public void controlMoved(ControlEvent e
) {
256 * Callback for when the control is resized
261 public void controlResized(ControlEvent e
) {
266 * Handler for when the model is updated. Called from the display order in
270 * The traces in the model
275 * @param updateTimeBounds
276 * Should we updated the time bounds too
278 public void modelUpdate(ITimeGraphEntry
[] traces
, long start
,
279 long end
, boolean updateTimeBounds
) {
280 if (null != fTimeGraphCtrl
) {
281 updateInternalData(traces
, start
, end
);
282 if (updateTimeBounds
) {
283 fTimeRangeFixed
= true;
284 // set window to match limits
285 setStartFinishTime(fTime0Bound
, fTime1Bound
);
287 fTimeGraphCtrl
.redraw();
288 fTimeScaleCtrl
.redraw();
294 * @return The string representing the view type
296 protected String
getViewTypeStr() {
297 return "viewoption.threads"; //$NON-NLS-1$
300 int getMarginWidth() {
304 int getMarginHeight() {
309 fMinTimeInterval
= 1;
310 fSelectionBegin
= -1;
312 fNameWidth
= Utils
.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
313 fNameWidthPref
, fMinNameWidth
, MAX_NAME_WIDTH
);
317 Utils
.saveIntOption(getPreferenceString("namewidth"), fNameWidth
); //$NON-NLS-1$
321 * Create a data viewer.
327 * @return The new data viewer
329 protected Control
createDataViewer(Composite parent
, int style
) {
331 fColorScheme
= new TimeGraphColorScheme();
332 fDataViewer
= new Composite(parent
, style
) {
334 public void redraw() {
335 fTimeScaleCtrl
.redraw();
336 fTimeGraphCtrl
.redraw();
340 GridLayout gl
= new GridLayout(2, false);
341 gl
.marginHeight
= fBorderWidth
;
343 gl
.verticalSpacing
= 0;
344 gl
.horizontalSpacing
= 0;
345 fDataViewer
.setLayout(gl
);
347 fTimeScaleCtrl
= new TimeGraphScale(fDataViewer
, fColorScheme
);
348 fTimeScaleCtrl
.setTimeProvider(this);
349 fTimeScaleCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.DEFAULT
, true, false));
350 fTimeScaleCtrl
.setHeight(fTimeScaleHeight
);
352 fVerticalScrollBar
= new Slider(fDataViewer
, SWT
.VERTICAL
| SWT
.NO_FOCUS
);
353 fVerticalScrollBar
.setLayoutData(new GridData(SWT
.DEFAULT
, SWT
.FILL
, false, true, 1, 2));
354 fVerticalScrollBar
.addSelectionListener(new SelectionAdapter() {
356 public void widgetSelected(SelectionEvent e
) {
357 setTopIndex(fVerticalScrollBar
.getSelection());
360 fVerticalScrollBar
.setEnabled(false);
362 fTimeGraphCtrl
= createTimeGraphControl(fDataViewer
, fColorScheme
);
364 fTimeGraphCtrl
.setTimeProvider(this);
365 fTimeGraphCtrl
.setTimeGraphScale(fTimeScaleCtrl
);
366 fTimeGraphCtrl
.addSelectionListener(this);
367 fTimeGraphCtrl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true, 1, 2));
368 fTimeGraphCtrl
.addMouseWheelListener(new MouseWheelListener() {
370 public void mouseScrolled(MouseEvent e
) {
371 adjustVerticalScrollBar();
374 fTimeGraphCtrl
.addKeyListener(new KeyAdapter() {
376 public void keyPressed(KeyEvent e
) {
377 if (e
.character
== '+') {
379 } else if (e
.character
== '-') {
382 adjustVerticalScrollBar();
386 Composite filler
= new Composite(fDataViewer
, SWT
.NONE
);
387 GridData gd
= new GridData(SWT
.DEFAULT
, SWT
.DEFAULT
, false, false);
388 gd
.heightHint
= fTimeGraphCtrl
.getHorizontalBar().getSize().y
;
389 filler
.setLayoutData(gd
);
390 filler
.setLayout(new FillLayout());
392 fTimeGraphCtrl
.addControlListener(new ControlAdapter() {
394 public void controlResized(ControlEvent event
) {
399 fDataViewer
.update();
400 adjustVerticalScrollBar();
407 public void dispose() {
409 fTimeGraphCtrl
.dispose();
410 fDataViewer
.dispose();
411 fColorScheme
.dispose();
415 * Create a new time graph control.
418 * The parent composite
421 * @return The new TimeGraphControl
424 protected TimeGraphControl
createTimeGraphControl(Composite parent
,
425 TimeGraphColorScheme colors
) {
426 return new TimeGraphControl(parent
, colors
);
430 * Resize the controls
432 public void resizeControls() {
433 Rectangle r
= fDataViewer
.getClientArea();
439 if (fNameWidth
> width
- fMinNameWidth
) {
440 fNameWidth
= width
- fMinNameWidth
;
442 if (fNameWidth
< fMinNameWidth
) {
443 fNameWidth
= fMinNameWidth
;
445 adjustVerticalScrollBar();
449 * Try to set most convenient time range for display.
452 * The traces in the model
454 public void setTimeRange(ITimeGraphEntry traces
[]) {
457 for (int i
= 0; i
< traces
.length
; i
++) {
458 ITimeGraphEntry entry
= traces
[i
];
459 if (entry
.getEndTime() >= entry
.getStartTime() && entry
.getEndTime() > 0) {
460 if (fBeginTime
< 0 || entry
.getStartTime() < fBeginTime
) {
461 fBeginTime
= entry
.getStartTime();
463 if (entry
.getEndTime() > fEndTime
) {
464 fEndTime
= entry
.getEndTime();
469 if (fBeginTime
< 0) {
475 * Recalculate the time bounds
477 public void setTimeBounds() {
478 fTime0Bound
= fBeginTime
;
479 if (fTime0Bound
< 0) {
482 fTime1Bound
= fEndTime
;
483 if (!fTimeRangeFixed
) {
484 fTime0
= fTime0Bound
;
485 fTime1
= fTime1Bound
;
487 fTime0
= Math
.max(fTime0Bound
, Math
.min(fTime0
, fTime1Bound
));
488 fTime1
= Math
.max(fTime0Bound
, Math
.min(fTime1
, fTime1Bound
));
489 if (fTime1
- fTime0
< fMinTimeInterval
) {
490 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
499 void updateInternalData(ITimeGraphEntry
[] traces
, long start
, long end
) {
500 ITimeGraphEntry
[] realTraces
= traces
;
502 if (null == realTraces
) {
503 realTraces
= new ITimeGraphEntry
[0];
505 if ((start
== 0 && end
== 0) || start
< 0 || end
< 0) {
506 // Start and end time are unspecified and need to be determined from
507 // individual processes
508 setTimeRange(realTraces
);
514 refreshAllData(realTraces
);
520 private void refreshAllData(ITimeGraphEntry
[] traces
) {
522 if (fSelectionBegin
< fBeginTime
) {
523 fSelectionBegin
= fBeginTime
;
524 } else if (fSelectionBegin
> fEndTime
) {
525 fSelectionBegin
= fEndTime
;
527 if (fSelectionEnd
< fBeginTime
) {
528 fSelectionEnd
= fBeginTime
;
529 } else if (fSelectionEnd
> fEndTime
) {
530 fSelectionEnd
= fEndTime
;
532 fTimeGraphCtrl
.refreshData(traces
);
533 fTimeScaleCtrl
.redraw();
534 adjustVerticalScrollBar();
538 * Callback for when this view is focused
540 public void setFocus() {
541 if (null != fTimeGraphCtrl
) {
542 fTimeGraphCtrl
.setFocus();
547 * Get the current focus status of this view.
549 * @return If the view is currently focused, or not
551 public boolean isInFocus() {
552 return fTimeGraphCtrl
.isInFocus();
556 * Get the view's current selection
558 * @return The entry that is selected
560 public ITimeGraphEntry
getSelection() {
561 return fTimeGraphCtrl
.getSelectedTrace();
565 * Get the index of the current selection
569 public int getSelectionIndex() {
570 return fTimeGraphCtrl
.getSelectedIndex();
574 public long getTime0() {
579 public long getTime1() {
584 public long getMinTimeInterval() {
585 return fMinTimeInterval
;
589 public int getNameSpace() {
594 public void setNameSpace(int width
) {
596 int w
= fTimeGraphCtrl
.getClientArea().width
;
597 if (fNameWidth
> w
- MIN_NAME_WIDTH
) {
598 fNameWidth
= w
- MIN_NAME_WIDTH
;
600 if (fNameWidth
< MIN_NAME_WIDTH
) {
601 fNameWidth
= MIN_NAME_WIDTH
;
603 fTimeGraphCtrl
.adjustScrolls();
604 fTimeGraphCtrl
.redraw();
605 fTimeScaleCtrl
.redraw();
609 public int getTimeSpace() {
610 int w
= fTimeGraphCtrl
.getClientArea().width
;
611 return w
- fNameWidth
;
615 public long getBeginTime() {
620 public long getEndTime() {
625 public long getMaxTime() {
630 public long getMinTime() {
638 public long getSelectionBegin() {
639 return fSelectionBegin
;
646 public long getSelectionEnd() {
647 return fSelectionEnd
;
651 public void setStartFinishTimeNotify(long time0
, long time1
) {
652 setStartFinishTime(time0
, time1
);
653 notifyRangeListeners(time0
, time1
);
657 public void notifyStartFinishTime() {
658 notifyRangeListeners(fTime0
, fTime1
);
662 public void setStartFinishTime(long time0
, long time1
) {
664 if (fTime0
< fTime0Bound
) {
665 fTime0
= fTime0Bound
;
667 if (fTime0
> fTime1Bound
) {
668 fTime0
= fTime1Bound
;
671 if (fTime1
< fTime0Bound
) {
672 fTime1
= fTime0Bound
;
674 if (fTime1
> fTime1Bound
) {
675 fTime1
= fTime1Bound
;
677 if (fTime1
- fTime0
< fMinTimeInterval
) {
678 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
680 fTimeRangeFixed
= true;
681 fTimeGraphCtrl
.adjustScrolls();
682 fTimeGraphCtrl
.redraw();
683 fTimeScaleCtrl
.redraw();
687 * Set the time bounds to the provided values
690 * The start time of the window
694 public void setTimeBounds(long beginTime
, long endTime
) {
695 if (endTime
>= beginTime
) {
696 fBeginTime
= beginTime
;
698 fTime0Bound
= beginTime
;
699 fTime1Bound
= endTime
;
706 fTimeGraphCtrl
.adjustScrolls();
710 public void resetStartFinishTime() {
711 setStartFinishTime(fTime0Bound
, fTime1Bound
);
712 fTimeRangeFixed
= false;
716 public void setSelectedTimeNotify(long time
, boolean ensureVisible
) {
717 setSelectedTimeInt(time
, ensureVisible
, true);
721 public void setSelectedTime(long time
, boolean ensureVisible
) {
722 setSelectedTimeInt(time
, ensureVisible
, false);
729 public void setSelectionRangeNotify(long beginTime
, long endTime
) {
730 boolean changed
= (beginTime
!= fSelectionBegin
|| endTime
!= fSelectionEnd
);
731 fSelectionBegin
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, beginTime
));
732 fSelectionEnd
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, endTime
));
733 fTimeGraphCtrl
.redraw();
734 fTimeScaleCtrl
.redraw();
736 notifyTimeListeners(fSelectionBegin
, fSelectionEnd
);
744 public void setSelectionRange(long beginTime
, long endTime
) {
745 fSelectionBegin
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, beginTime
));
746 fSelectionEnd
= Math
.max(fTime0Bound
, Math
.min(fTime1Bound
, endTime
));
747 fTimeGraphCtrl
.redraw();
748 fTimeScaleCtrl
.redraw();
751 private void setSelectedTimeInt(long time
, boolean ensureVisible
, boolean doNotify
) {
755 long timeSpace
= (fTime1
- fTime0
) / RECENTERING_MARGIN_FACTOR
;
756 long timeMid
= (fTime1
- fTime0
) / 2;
757 if (time
< fTime0
+ timeSpace
) {
758 long dt
= fTime0
- time
+ timeMid
;
761 } else if (time
> fTime1
- timeSpace
) {
762 long dt
= time
- fTime1
+ timeMid
;
766 if (fTime0
< fTime0Bound
) {
767 fTime1
= Math
.min(fTime1Bound
, fTime1
+ (fTime0Bound
- fTime0
));
768 fTime0
= fTime0Bound
;
769 } else if (fTime1
> fTime1Bound
) {
770 fTime0
= Math
.max(fTime0Bound
, fTime0
- (fTime1
- fTime1Bound
));
771 fTime1
= fTime1Bound
;
774 if (fTime1
- fTime0
< fMinTimeInterval
) {
775 fTime1
= Math
.min(fTime1Bound
, fTime0
+ fMinTimeInterval
);
777 fTimeGraphCtrl
.adjustScrolls();
778 fTimeGraphCtrl
.redraw();
779 fTimeScaleCtrl
.redraw();
781 boolean notifySelectedTime
= (time
!= fSelectionBegin
|| time
!= fSelectionEnd
);
782 fSelectionBegin
= time
;
783 fSelectionEnd
= time
;
785 if (doNotify
&& ((time0
!= fTime0
) || (time1
!= fTime1
))) {
786 notifyRangeListeners(fTime0
, fTime1
);
789 if (doNotify
&& notifySelectedTime
) {
790 notifyTimeListeners(fSelectionBegin
, fSelectionEnd
);
795 public void widgetDefaultSelected(SelectionEvent e
) {
796 if (fSelectedEntry
!= getSelection()) {
797 fSelectedEntry
= getSelection();
798 notifySelectionListeners(fSelectedEntry
);
803 public void widgetSelected(SelectionEvent e
) {
804 if (fSelectedEntry
!= getSelection()) {
805 fSelectedEntry
= getSelection();
806 notifySelectionListeners(fSelectedEntry
);
811 * Callback for when the next event is selected
813 public void selectNextEvent() {
814 fTimeGraphCtrl
.selectNextEvent();
815 adjustVerticalScrollBar();
819 * Callback for when the previous event is selected
821 public void selectPrevEvent() {
822 fTimeGraphCtrl
.selectPrevEvent();
823 adjustVerticalScrollBar();
827 * Callback for when the next item is selected
829 public void selectNextItem() {
830 fTimeGraphCtrl
.selectNextTrace();
831 adjustVerticalScrollBar();
835 * Callback for when the previous item is selected
837 public void selectPrevItem() {
838 fTimeGraphCtrl
.selectPrevTrace();
839 adjustVerticalScrollBar();
843 * Callback for the show legend action
845 public void showLegend() {
846 if (fDataViewer
== null || fDataViewer
.isDisposed()) {
850 TimeGraphLegend
.open(fDataViewer
.getShell(), fTimeGraphProvider
);
854 * Callback for the Zoom In action
856 public void zoomIn() {
857 fTimeGraphCtrl
.zoomIn();
861 * Callback for the Zoom Out action
863 public void zoomOut() {
864 fTimeGraphCtrl
.zoomOut();
867 private String
getPreferenceString(String string
) {
868 return getViewTypeStr() + "." + string
; //$NON-NLS-1$
872 * Add a selection listener
875 * The listener to add
877 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
878 fSelectionListeners
.add(listener
);
882 * Remove a selection listener
885 * The listener to remove
887 public void removeSelectionListener(ITimeGraphSelectionListener listener
) {
888 fSelectionListeners
.remove(listener
);
891 private void notifySelectionListeners(ITimeGraphEntry selection
) {
892 TimeGraphSelectionEvent event
= new TimeGraphSelectionEvent(this, selection
);
894 for (ITimeGraphSelectionListener listener
: fSelectionListeners
) {
895 listener
.selectionChanged(event
);
900 * Add a time listener
903 * The listener to add
905 public void addTimeListener(ITimeGraphTimeListener listener
) {
906 fTimeListeners
.add(listener
);
910 * Remove a time listener
913 * The listener to remove
915 public void removeTimeListener(ITimeGraphTimeListener listener
) {
916 fTimeListeners
.remove(listener
);
919 private void notifyTimeListeners(long startTime
, long endTime
) {
920 TimeGraphTimeEvent event
= new TimeGraphTimeEvent(this, startTime
, endTime
);
922 for (ITimeGraphTimeListener listener
: fTimeListeners
) {
923 listener
.timeSelected(event
);
928 * Add a range listener
931 * The listener to add
933 public void addRangeListener(ITimeGraphRangeListener listener
) {
934 fRangeListeners
.add(listener
);
938 * Remove a range listener
941 * The listener to remove
943 public void removeRangeListener(ITimeGraphRangeListener listener
) {
944 fRangeListeners
.remove(listener
);
947 private void notifyRangeListeners(long startTime
, long endTime
) {
948 // Check if the time has actually changed from last notification
949 if (startTime
!= fTime0ExtSynch
|| endTime
!= fTime1ExtSynch
) {
950 // Notify Time Scale Selection Listeners
951 TimeGraphRangeUpdateEvent event
= new TimeGraphRangeUpdateEvent(this, startTime
, endTime
);
953 for (ITimeGraphRangeListener listener
: fRangeListeners
) {
954 listener
.timeRangeUpdated(event
);
957 // update external synch timers
958 updateExtSynchTimers();
963 * Callback to set a selected event in the view
966 * The event that was selected
968 * The source of this selection event
970 public void setSelectedEvent(ITimeEvent event
, Object source
) {
971 if (event
== null || source
== this) {
974 fSelectedEntry
= event
.getEntry();
975 fTimeGraphCtrl
.selectItem(fSelectedEntry
, false);
977 setSelectedTimeInt(event
.getTime(), true, true);
978 adjustVerticalScrollBar();
982 * Set the seeked time of a trace
985 * The trace that was seeked
989 * The source of this seek event
991 public void setSelectedTraceTime(ITimeGraphEntry trace
, long time
, Object source
) {
992 if (trace
== null || source
== this) {
995 fSelectedEntry
= trace
;
996 fTimeGraphCtrl
.selectItem(trace
, false);
998 setSelectedTimeInt(time
, true, true);
1002 * Callback for a trace selection
1005 * The trace that was selected
1007 public void setSelection(ITimeGraphEntry trace
) {
1008 fSelectedEntry
= trace
;
1009 fTimeGraphCtrl
.selectItem(trace
, false);
1010 adjustVerticalScrollBar();
1014 * Callback for a time window selection
1017 * Start time of the range
1019 * End time of the range
1021 * Source of the event
1023 public void setSelectVisTimeWindow(long time0
, long time1
, Object source
) {
1024 if (source
== this) {
1028 setStartFinishTime(time0
, time1
);
1030 // update notification time values since we are now in synch with the
1031 // external application
1032 updateExtSynchTimers();
1036 * update the cache timers used to identify the need to send a time window
1037 * update to external registered listeners
1039 private void updateExtSynchTimers() {
1040 // last time notification cache
1041 fTime0ExtSynch
= fTime0
;
1042 fTime1ExtSynch
= fTime1
;
1049 public TimeFormat
getTimeFormat() {
1055 * the {@link TimeFormat} used to display timestamps
1058 public void setTimeFormat(TimeFormat tf
) {
1059 this.fTimeFormat
= tf
;
1063 * Retrieve the border width
1067 public int getBorderWidth() {
1068 return fBorderWidth
;
1072 * Set the border width
1074 * @param borderWidth
1077 public void setBorderWidth(int borderWidth
) {
1078 if (borderWidth
> -1) {
1079 this.fBorderWidth
= borderWidth
;
1080 GridLayout gl
= (GridLayout
) fDataViewer
.getLayout();
1081 gl
.marginHeight
= borderWidth
;
1086 * Retrieve the height of the header
1088 * @return The height
1090 public int getHeaderHeight() {
1091 return fTimeScaleHeight
;
1095 * Set the height of the header
1097 * @param headerHeight
1100 public void setHeaderHeight(int headerHeight
) {
1101 if (headerHeight
> -1) {
1102 this.fTimeScaleHeight
= headerHeight
;
1103 fTimeScaleCtrl
.setHeight(headerHeight
);
1108 * Retrieve the height of an item row
1110 * @return The height
1112 public int getItemHeight() {
1113 if (fTimeGraphCtrl
!= null) {
1114 return fTimeGraphCtrl
.getItemHeight();
1120 * Set the height of an item row
1125 public void setItemHeight(int rowHeight
) {
1126 if (fTimeGraphCtrl
!= null) {
1127 fTimeGraphCtrl
.setItemHeight(rowHeight
);
1132 * Set the minimum item width
1137 public void setMinimumItemWidth(int width
) {
1138 if (fTimeGraphCtrl
!= null) {
1139 fTimeGraphCtrl
.setMinimumItemWidth(width
);
1144 * Set the width for the name column
1149 public void setNameWidthPref(int width
) {
1150 fNameWidthPref
= width
;
1158 * Retrieve the configure width for the name column
1164 public int getNameWidthPref(int width
) {
1165 return fNameWidthPref
;
1169 * Returns the primary control associated with this viewer.
1171 * @return the SWT control which displays this viewer's content
1173 public Control
getControl() {
1178 * Returns the time graph control associated with this viewer.
1180 * @return the time graph control
1183 public TimeGraphControl
getTimeGraphControl() {
1184 return fTimeGraphCtrl
;
1188 * Returns the time graph scale associated with this viewer.
1190 * @return the time graph scale
1193 public TimeGraphScale
getTimeGraphScale() {
1194 return fTimeScaleCtrl
;
1198 * Return the x coordinate corresponding to a time
1202 * @return the x coordinate corresponding to the time
1206 public int getXForTime(long time
) {
1207 return fTimeGraphCtrl
.getXForTime(time
);
1211 * Return the time corresponding to an x coordinate
1215 * @return the time corresponding to the x coordinate
1219 public long getTimeAtX(int x
) {
1220 return fTimeGraphCtrl
.getTimeAtX(x
);
1224 * Get the selection provider
1226 * @return the selection provider
1228 public ISelectionProvider
getSelectionProvider() {
1229 return fTimeGraphCtrl
;
1233 * Wait for the cursor
1236 * Wait indefinitely?
1238 public void waitCursor(boolean waitInd
) {
1239 fTimeGraphCtrl
.waitCursor(waitInd
);
1243 * Get the horizontal scroll bar object
1245 * @return The scroll bar
1247 public ScrollBar
getHorizontalBar() {
1248 return fTimeGraphCtrl
.getHorizontalBar();
1252 * Get the vertical scroll bar object
1254 * @return The scroll bar
1256 public Slider
getVerticalBar() {
1257 return fVerticalScrollBar
;
1261 * Set the given index as the top one
1264 * The index that will go to the top
1266 public void setTopIndex(int index
) {
1267 fTimeGraphCtrl
.setTopIndex(index
);
1268 adjustVerticalScrollBar();
1272 * Retrieve the current top index
1274 * @return The top index
1276 public int getTopIndex() {
1277 return fTimeGraphCtrl
.getTopIndex();
1281 * Sets the auto-expand level to be used when the input of the viewer is set
1282 * using {@link #setInput(Object)}. The value 0 means that there is no
1283 * auto-expand; 1 means that top-level elements are expanded, but not their
1284 * children; 2 means that top-level elements are expanded, and their
1285 * children, but not grand-children; and so on.
1287 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1290 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1291 * levels of the tree
1294 public void setAutoExpandLevel(int level
) {
1295 fTimeGraphCtrl
.setAutoExpandLevel(level
);
1299 * Returns the auto-expand level.
1301 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1302 * the tree are expanded automatically
1303 * @see #setAutoExpandLevel
1306 public int getAutoExpandLevel() {
1307 return fTimeGraphCtrl
.getAutoExpandLevel();
1311 * Set the expanded state of an entry
1314 * The entry to expand/collapse
1316 * True for expanded, false for collapsed
1318 public void setExpandedState(ITimeGraphEntry entry
, boolean expanded
) {
1319 fTimeGraphCtrl
.setExpandedState(entry
, expanded
);
1320 adjustVerticalScrollBar();
1324 * Collapses all nodes of the viewer's tree, starting with the root.
1328 public void collapseAll() {
1329 fTimeGraphCtrl
.collapseAll();
1330 adjustVerticalScrollBar();
1334 * Expands all nodes of the viewer's tree, starting with the root.
1338 public void expandAll() {
1339 fTimeGraphCtrl
.expandAll();
1340 adjustVerticalScrollBar();
1344 * Get the number of sub-elements when expanded
1346 * @return The element count
1348 public int getExpandedElementCount() {
1349 return fTimeGraphCtrl
.getExpandedElementCount();
1353 * Get the sub-elements
1355 * @return The array of entries that are below this one
1357 public ITimeGraphEntry
[] getExpandedElements() {
1358 return fTimeGraphCtrl
.getExpandedElements();
1362 * Add a tree listener
1365 * The listener to add
1367 public void addTreeListener(ITimeGraphTreeListener listener
) {
1368 fTimeGraphCtrl
.addTreeListener(listener
);
1372 * Remove a tree listener
1375 * The listener to remove
1377 public void removeTreeListener(ITimeGraphTreeListener listener
) {
1378 fTimeGraphCtrl
.removeTreeListener(listener
);
1382 * Get the reset scale action.
1384 * @return The Action object
1386 public Action
getResetScaleAction() {
1387 if (fResetScaleAction
== null) {
1389 fResetScaleAction
= new Action() {
1392 resetStartFinishTime();
1393 notifyStartFinishTime();
1396 fResetScaleAction
.setText(Messages
.TmfTimeGraphViewer_ResetScaleActionNameText
);
1397 fResetScaleAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ResetScaleActionToolTipText
);
1398 fResetScaleAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HOME_MENU
));
1400 return fResetScaleAction
;
1404 * Get the show legend action.
1406 * @return The Action object
1408 public Action
getShowLegendAction() {
1409 if (fShowLegendAction
== null) {
1411 fShowLegendAction
= new Action() {
1417 fShowLegendAction
.setText(Messages
.TmfTimeGraphViewer_LegendActionNameText
);
1418 fShowLegendAction
.setToolTipText(Messages
.TmfTimeGraphViewer_LegendActionToolTipText
);
1419 fShowLegendAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_LEGEND
));
1422 return fShowLegendAction
;
1426 * Get the the next event action.
1428 * @return The action object
1430 public Action
getNextEventAction() {
1431 if (fNextEventAction
== null) {
1432 fNextEventAction
= new Action() {
1439 fNextEventAction
.setText(Messages
.TmfTimeGraphViewer_NextEventActionNameText
);
1440 fNextEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextEventActionToolTipText
);
1441 fNextEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_EVENT
));
1444 return fNextEventAction
;
1448 * Get the previous event action.
1450 * @return The Action object
1452 public Action
getPreviousEventAction() {
1453 if (fPrevEventAction
== null) {
1454 fPrevEventAction
= new Action() {
1461 fPrevEventAction
.setText(Messages
.TmfTimeGraphViewer_PreviousEventActionNameText
);
1462 fPrevEventAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousEventActionToolTipText
);
1463 fPrevEventAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_EVENT
));
1466 return fPrevEventAction
;
1470 * Get the next item action.
1472 * @return The Action object
1474 public Action
getNextItemAction() {
1475 if (fNextItemAction
== null) {
1477 fNextItemAction
= new Action() {
1483 fNextItemAction
.setText(Messages
.TmfTimeGraphViewer_NextItemActionNameText
);
1484 fNextItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_NextItemActionToolTipText
);
1485 fNextItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_NEXT_ITEM
));
1487 return fNextItemAction
;
1491 * Get the previous item action.
1493 * @return The Action object
1495 public Action
getPreviousItemAction() {
1496 if (fPreviousItemAction
== null) {
1498 fPreviousItemAction
= new Action() {
1504 fPreviousItemAction
.setText(Messages
.TmfTimeGraphViewer_PreviousItemActionNameText
);
1505 fPreviousItemAction
.setToolTipText(Messages
.TmfTimeGraphViewer_PreviousItemActionToolTipText
);
1506 fPreviousItemAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_PREV_ITEM
));
1508 return fPreviousItemAction
;
1512 * Get the zoom in action
1514 * @return The Action object
1516 public Action
getZoomInAction() {
1517 if (fZoomInAction
== null) {
1518 fZoomInAction
= new Action() {
1524 fZoomInAction
.setText(Messages
.TmfTimeGraphViewer_ZoomInActionNameText
);
1525 fZoomInAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomInActionToolTipText
);
1526 fZoomInAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_IN_MENU
));
1528 return fZoomInAction
;
1532 * Get the zoom out action
1534 * @return The Action object
1536 public Action
getZoomOutAction() {
1537 if (fZoomOutAction
== null) {
1538 fZoomOutAction
= new Action() {
1544 fZoomOutAction
.setText(Messages
.TmfTimeGraphViewer_ZoomOutActionNameText
);
1545 fZoomOutAction
.setToolTipText(Messages
.TmfTimeGraphViewer_ZoomOutActionToolTipText
);
1546 fZoomOutAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_ZOOM_OUT_MENU
));
1548 return fZoomOutAction
;
1552 * Get the hide arrows action
1554 * @param dialogSettings
1555 * The dialog settings section where the state should be stored,
1558 * @return The Action object
1562 public Action
getHideArrowsAction(final IDialogSettings dialogSettings
) {
1563 if (fHideArrowsAction
== null) {
1564 fHideArrowsAction
= new Action(Messages
.TmfTimeGraphViewer_HideArrowsActionNameText
, IAction
.AS_CHECK_BOX
) {
1567 boolean hideArrows
= fHideArrowsAction
.isChecked();
1568 fTimeGraphCtrl
.hideArrows(hideArrows
);
1570 if (dialogSettings
!= null) {
1571 dialogSettings
.put(HIDE_ARROWS_KEY
, hideArrows
);
1573 if (fFollowArrowFwdAction
!= null) {
1574 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
1576 if (fFollowArrowBwdAction
!= null) {
1577 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
1581 fHideArrowsAction
.setToolTipText(Messages
.TmfTimeGraphViewer_HideArrowsActionToolTipText
);
1582 fHideArrowsAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_HIDE_ARROWS
));
1583 if (dialogSettings
!= null) {
1584 boolean hideArrows
= dialogSettings
.getBoolean(HIDE_ARROWS_KEY
);
1585 fTimeGraphCtrl
.hideArrows(hideArrows
);
1586 fHideArrowsAction
.setChecked(hideArrows
);
1587 if (fFollowArrowFwdAction
!= null) {
1588 fFollowArrowFwdAction
.setEnabled(!hideArrows
);
1590 if (fFollowArrowBwdAction
!= null) {
1591 fFollowArrowBwdAction
.setEnabled(!hideArrows
);
1595 return fHideArrowsAction
;
1599 * Get the follow arrow forward action.
1601 * @return The Action object
1605 public Action
getFollowArrowFwdAction() {
1606 if (fFollowArrowFwdAction
== null) {
1607 fFollowArrowFwdAction
= new Action() {
1610 fTimeGraphCtrl
.followArrowFwd();
1611 adjustVerticalScrollBar();
1614 fFollowArrowFwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionNameText
);
1615 fFollowArrowFwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText
);
1616 fFollowArrowFwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_FORWARD
));
1617 if (fHideArrowsAction
!= null) {
1618 fFollowArrowFwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
1621 return fFollowArrowFwdAction
;
1625 * Get the follow arrow backward action.
1627 * @return The Action object
1631 public Action
getFollowArrowBwdAction() {
1632 if (fFollowArrowBwdAction
== null) {
1633 fFollowArrowBwdAction
= new Action() {
1636 fTimeGraphCtrl
.followArrowBwd();
1637 adjustVerticalScrollBar();
1640 fFollowArrowBwdAction
.setText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionNameText
);
1641 fFollowArrowBwdAction
.setToolTipText(Messages
.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText
);
1642 fFollowArrowBwdAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_FOLLOW_ARROW_BACKWARD
));
1643 if (fHideArrowsAction
!= null) {
1644 fFollowArrowBwdAction
.setEnabled(!fHideArrowsAction
.isChecked());
1647 return fFollowArrowBwdAction
;
1650 private void adjustVerticalScrollBar() {
1651 int topIndex
= fTimeGraphCtrl
.getTopIndex();
1652 int countPerPage
= fTimeGraphCtrl
.countPerPage();
1653 int expandedElementCount
= fTimeGraphCtrl
.getExpandedElementCount();
1654 if (topIndex
+ countPerPage
> expandedElementCount
) {
1655 fTimeGraphCtrl
.setTopIndex(Math
.max(0, expandedElementCount
- countPerPage
));
1658 int selection
= fTimeGraphCtrl
.getTopIndex();
1660 int max
= Math
.max(1, expandedElementCount
- 1);
1661 int thumb
= Math
.min(max
, Math
.max(1, countPerPage
- 1));
1663 int pageIncrement
= Math
.max(1, countPerPage
);
1664 fVerticalScrollBar
.setValues(selection
, min
, max
, thumb
, increment
, pageIncrement
);
1669 * a {@link MenuDetectListener}
1670 * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
1673 public void addTimeGraphEntryMenuListener(MenuDetectListener listener
) {
1674 fTimeGraphCtrl
.addTimeGraphEntryMenuListener(listener
);
1679 * a {@link MenuDetectListener}
1680 * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
1683 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener
) {
1684 fTimeGraphCtrl
.removeTimeGraphEntryMenuListener(listener
);
1689 * a {@link MenuDetectListener}
1690 * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
1693 public void addTimeEventMenuListener(MenuDetectListener listener
) {
1694 fTimeGraphCtrl
.addTimeEventMenuListener(listener
);
1699 * a {@link MenuDetectListener}
1700 * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
1703 public void removeTimeEventMenuListener(MenuDetectListener listener
) {
1704 fTimeGraphCtrl
.removeTimeEventMenuListener(listener
);
1709 * The filter object to be attached to the view
1712 public void addFilter(ViewerFilter filter
) {
1713 fTimeGraphCtrl
.addFilter(filter
);
1719 * The filter object to be attached to the view
1722 public void removeFilter(ViewerFilter filter
) {
1723 fTimeGraphCtrl
.removeFilter(filter
);