1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 Ericsson, École Polytechnique de Montréal
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Patrick Tasse - Initial API and implementation
11 * Bernd Hufmann - Updated signal handling
12 * Geneviève Bastien - Move code to provide base classes for time graph view
13 * Marc-Andre Laperle - Add time zone preference
14 * Geneviève Bastien - Add event links between entries
15 *******************************************************************************/
17 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.timegraph
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Arrays
;
21 import java
.util
.Collections
;
22 import java
.util
.Comparator
;
23 import java
.util
.HashMap
;
24 import java
.util
.List
;
27 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
28 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
29 import org
.eclipse
.jface
.action
.Action
;
30 import org
.eclipse
.jface
.action
.IAction
;
31 import org
.eclipse
.jface
.action
.IStatusLineManager
;
32 import org
.eclipse
.jface
.action
.IToolBarManager
;
33 import org
.eclipse
.jface
.action
.Separator
;
34 import org
.eclipse
.jface
.viewers
.ILabelProviderListener
;
35 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
36 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
37 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
38 import org
.eclipse
.jface
.viewers
.TreeViewer
;
39 import org
.eclipse
.jface
.viewers
.Viewer
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfRangeSynchSignal
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimeSynchSignal
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimestampFormatUpdateSignal
;
44 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceClosedSignal
;
45 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
46 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
47 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
48 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfNanoTimestamp
;
49 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimeRange
;
50 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
51 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.TmfView
;
52 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphRangeListener
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphSelectionListener
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphTimeListener
;
55 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphCombo
;
56 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphPresentationProvider
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphRangeUpdateEvent
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphSelectionEvent
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphTimeEvent
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphViewer
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
62 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
63 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
64 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.TimeGraphEntry
;
65 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
66 import org
.eclipse
.swt
.SWT
;
67 import org
.eclipse
.swt
.graphics
.Image
;
68 import org
.eclipse
.swt
.widgets
.Composite
;
69 import org
.eclipse
.swt
.widgets
.Display
;
70 import org
.eclipse
.swt
.widgets
.TreeColumn
;
71 import org
.eclipse
.ui
.IActionBars
;
74 * An abstract view all time graph views can inherit
76 * This view contains either a time graph viewer, or a time graph combo which is
77 * divided between a tree viewer on the left and a time graph viewer on the right.
81 public abstract class AbstractTimeGraphView
extends TmfView
{
90 // ------------------------------------------------------------------------
92 // ------------------------------------------------------------------------
94 /** The timegraph wrapper */
95 private ITimeGraphWrapper fTimeGraphWrapper
;
97 /** The selected trace */
98 private ITmfTrace fTrace
;
100 /** The timegraph entry list */
101 private List
<TimeGraphEntry
> fEntryList
;
103 /** The trace to entry list hash map */
104 private final Map
<ITmfTrace
, List
<TimeGraphEntry
>> fEntryListMap
= new HashMap
<ITmfTrace
, List
<TimeGraphEntry
>>();
106 /* The trace to build thread hash map */
107 private final Map
<ITmfTrace
, BuildThread
> fBuildThreadMap
= new HashMap
<ITmfTrace
, BuildThread
>();
109 /** The start time */
110 private long fStartTime
;
113 private long fEndTime
;
115 /** The display width */
116 private final int fDisplayWidth
;
118 /** The zoom thread */
119 private ZoomThread fZoomThread
;
121 /** The next resource action */
122 private Action fNextResourceAction
;
124 /** The previous resource action */
125 private Action fPreviousResourceAction
;
127 /** A comparator class */
128 private Comparator
<ITimeGraphEntry
> fEntryComparator
= null;
130 /** The redraw state used to prevent unnecessary queuing of display runnables */
131 private State fRedrawState
= State
.IDLE
;
133 /** The redraw synchronization object */
134 private final Object fSyncObj
= new Object();
136 /** The presentation provider for this view */
137 private final TimeGraphPresentationProvider fPresentation
;
139 /** The tree column label array, or null if combo is not used */
140 private String
[] fColumns
;
142 /** The tree label provider, or null if combo is not used */
143 private TreeLabelProvider fLabelProvider
= null;
145 /** The relative weight of the sash, ignored if combo is not used */
146 private int[] fWeight
= { 1, 1 };
148 /** The filter column label array, or null if filter is not used */
149 private String
[] fFilterColumns
;
151 // ------------------------------------------------------------------------
153 // ------------------------------------------------------------------------
155 private interface ITimeGraphWrapper
{
157 void setTimeGraphProvider(TimeGraphPresentationProvider fPresentation
);
159 TimeGraphViewer
getTimeGraphViewer();
161 void addSelectionListener(ITimeGraphSelectionListener iTimeGraphSelectionListener
);
163 ISelectionProvider
getSelectionProvider();
167 boolean isDisposed();
171 void setInput(ITimeGraphEntry
[] entries
);
179 private class TimeGraphViewerWrapper
implements ITimeGraphWrapper
{
180 private TimeGraphViewer viewer
;
182 private TimeGraphViewerWrapper(Composite parent
, int style
) {
183 viewer
= new TimeGraphViewer(parent
, style
);
187 public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider
) {
188 viewer
.setTimeGraphProvider(timeGraphProvider
);
192 public TimeGraphViewer
getTimeGraphViewer() {
197 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
198 viewer
.addSelectionListener(listener
);
202 public ISelectionProvider
getSelectionProvider() {
203 return viewer
.getSelectionProvider();
207 public void setFocus() {
212 public boolean isDisposed() {
213 return viewer
.getControl().isDisposed();
217 public void setInput(ITimeGraphEntry
[] input
) {
218 viewer
.setInput(input
);
222 public void refresh() {
227 public void redraw() {
228 viewer
.getControl().redraw();
232 public void update() {
233 viewer
.getControl().update();
237 private class TimeGraphComboWrapper
implements ITimeGraphWrapper
{
238 private TimeGraphCombo combo
;
240 private TimeGraphComboWrapper(Composite parent
, int style
) {
241 combo
= new TimeGraphCombo(parent
, style
, fWeight
);
245 public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider
) {
246 combo
.setTimeGraphProvider(timeGraphProvider
);
250 public TimeGraphViewer
getTimeGraphViewer() {
251 return combo
.getTimeGraphViewer();
255 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
256 combo
.addSelectionListener(listener
);
260 public ISelectionProvider
getSelectionProvider() {
261 return combo
.getTreeViewer();
265 public void setFocus() {
270 public boolean isDisposed() {
271 return combo
.isDisposed();
275 public void setInput(ITimeGraphEntry
[] input
) {
276 combo
.setInput(input
);
280 public void refresh() {
285 public void redraw() {
290 public void update() {
294 TimeGraphCombo
getTimeGraphCombo() {
298 TreeViewer
getTreeViewer() {
299 return combo
.getTreeViewer();
302 IAction
getShowFilterAction() {
303 return combo
.getShowFilterAction();
307 private class TreeContentProvider
implements ITreeContentProvider
{
310 public void dispose() {
314 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
318 public Object
[] getElements(Object inputElement
) {
319 return (ITimeGraphEntry
[]) inputElement
;
323 public Object
[] getChildren(Object parentElement
) {
324 ITimeGraphEntry entry
= (ITimeGraphEntry
) parentElement
;
325 List
<?
extends ITimeGraphEntry
> children
= entry
.getChildren();
326 return children
.toArray(new ITimeGraphEntry
[children
.size()]);
330 public Object
getParent(Object element
) {
331 ITimeGraphEntry entry
= (ITimeGraphEntry
) element
;
332 return entry
.getParent();
336 public boolean hasChildren(Object element
) {
337 ITimeGraphEntry entry
= (ITimeGraphEntry
) element
;
338 return entry
.hasChildren();
344 * Base class to provide the labels for the tree viewer. Views extending
345 * this class typically need to override the getColumnText method if they
346 * have more than one column to display
348 protected static class TreeLabelProvider
implements ITableLabelProvider
{
351 public void addListener(ILabelProviderListener listener
) {
355 public void dispose() {
359 public boolean isLabelProperty(Object element
, String property
) {
364 public void removeListener(ILabelProviderListener listener
) {
368 public Image
getColumnImage(Object element
, int columnIndex
) {
373 public String
getColumnText(Object element
, int columnIndex
) {
374 TimeGraphEntry entry
= (TimeGraphEntry
) element
;
375 if (columnIndex
== 0) {
376 return entry
.getName();
383 private class BuildThread
extends Thread
{
384 private final ITmfTrace fBuildTrace
;
385 private final IProgressMonitor fMonitor
;
387 public BuildThread(final ITmfTrace trace
, final String name
) {
388 super(name
+ " build"); //$NON-NLS-1$
390 fMonitor
= new NullProgressMonitor();
395 buildEventList(fBuildTrace
, fMonitor
);
396 synchronized (fBuildThreadMap
) {
397 fBuildThreadMap
.remove(this);
401 public void cancel() {
402 fMonitor
.setCanceled(true);
406 private class ZoomThread
extends Thread
{
407 private final List
<TimeGraphEntry
> fZoomEntryList
;
408 private final long fZoomStartTime
;
409 private final long fZoomEndTime
;
410 private final long fResolution
;
411 private final IProgressMonitor fMonitor
;
413 public ZoomThread(List
<TimeGraphEntry
> entryList
, long startTime
, long endTime
, String name
) {
414 super(name
+ " zoom"); //$NON-NLS-1$
415 fZoomEntryList
= entryList
;
416 fZoomStartTime
= startTime
;
417 fZoomEndTime
= endTime
;
418 fResolution
= Math
.max(1, (fZoomEndTime
- fZoomStartTime
) / fDisplayWidth
);
419 fMonitor
= new NullProgressMonitor();
424 if (fZoomEntryList
== null) {
427 for (TimeGraphEntry entry
: fZoomEntryList
) {
428 if (fMonitor
.isCanceled()) {
431 zoom(entry
, fMonitor
);
433 /* Refresh the arrows when zooming */
434 List
<ILinkEvent
> events
= getLinkList(fZoomStartTime
, fZoomEndTime
, fResolution
, fMonitor
);
435 if (events
!= null) {
436 fTimeGraphWrapper
.getTimeGraphViewer().setLinks(events
);
441 private void zoom(TimeGraphEntry entry
, IProgressMonitor monitor
) {
442 if (fZoomStartTime
<= fStartTime
&& fZoomEndTime
>= fEndTime
) {
443 entry
.setZoomedEventList(null);
445 List
<ITimeEvent
> zoomedEventList
= getEventList(entry
, fZoomStartTime
, fZoomEndTime
, fResolution
, monitor
);
446 if (zoomedEventList
!= null) {
447 entry
.setZoomedEventList(zoomedEventList
);
451 for (TimeGraphEntry child
: entry
.getChildren()) {
452 if (fMonitor
.isCanceled()) {
455 zoom(child
, monitor
);
459 public void cancel() {
460 fMonitor
.setCanceled(true);
464 // ------------------------------------------------------------------------
466 // ------------------------------------------------------------------------
469 * Constructs a time graph view that contains either a time graph viewer or
470 * a time graph combo.
472 * By default, the view uses a time graph viewer. To use a time graph combo,
473 * the subclass constructor must call {@link #setTreeColumns(String[])} and
474 * {@link #setTreeLabelProvider(TreeLabelProvider)}.
479 * The presentation provider
481 public AbstractTimeGraphView(String id
, TimeGraphPresentationProvider pres
) {
483 fPresentation
= pres
;
484 fDisplayWidth
= Display
.getDefault().getBounds().width
;
487 // ------------------------------------------------------------------------
488 // Getters and setters
489 // ------------------------------------------------------------------------
492 * Getter for the time graph combo
494 * @return The time graph combo, or null if combo is not used
496 protected TimeGraphCombo
getTimeGraphCombo() {
497 if (fTimeGraphWrapper
instanceof TimeGraphComboWrapper
) {
498 return ((TimeGraphComboWrapper
) fTimeGraphWrapper
).getTimeGraphCombo();
504 * Getter for the time graph viewer
506 * @return The time graph viewer
508 protected TimeGraphViewer
getTimeGraphViewer() {
509 return fTimeGraphWrapper
.getTimeGraphViewer();
513 * Sets the tree column labels.
514 * This should be called from the constructor.
517 * The array of tree column labels
519 protected void setTreeColumns(final String
[] columns
) {
524 * Sets the tree label provider.
525 * This should be called from the constructor.
528 * The tree label provider
530 protected void setTreeLabelProvider(final TreeLabelProvider tlp
) {
531 fLabelProvider
= tlp
;
535 * Sets the relative weight of each part of the time graph combo.
536 * This should be called from the constructor.
539 * The array (length 2) of relative weights of each part of the combo
541 protected void setWeight(final int[] weights
) {
546 * Sets the filter column labels.
547 * This should be called from the constructor.
549 * @param filterColumns
550 * The array of filter column labels
552 protected void setFilterColumns(final String
[] filterColumns
) {
553 fFilterColumns
= filterColumns
;
557 * Gets the display width
559 * @return the display width
561 protected int getDisplayWidth() {
562 return fDisplayWidth
;
566 * Gets the comparator for the entries
568 * @return The entry comparator
570 protected Comparator
<ITimeGraphEntry
> getEntryComparator() {
571 return fEntryComparator
;
575 * Sets the comparator class for the entries
578 * A comparator object
580 protected void setEntryComparator(final Comparator
<ITimeGraphEntry
> comparator
) {
581 fEntryComparator
= comparator
;
585 * Gets the trace displayed in the view
589 protected ITmfTrace
getTrace() {
594 * Gets the start time
596 * @return The start time
598 protected long getStartTime() {
603 * Sets the start time
608 protected void setStartTime(long time
) {
615 * @return The end time
617 protected long getEndTime() {
627 protected void setEndTime(long time
) {
632 * Gets the entry list map
634 * @return the entry list map
636 protected Map
<ITmfTrace
, List
<TimeGraphEntry
>> getEntryListMap() {
637 return Collections
.unmodifiableMap(fEntryListMap
);
641 * Adds an entry to the entry list
646 * The list of time graph entries
648 protected void putEntryList(ITmfTrace trace
, List
<TimeGraphEntry
> list
) {
649 synchronized(fEntryListMap
) {
650 fEntryListMap
.put(trace
, list
);
655 * Text for the "next" button
657 * @return The "next" button text
659 protected String
getNextText() {
660 return Messages
.AbstractTimeGraphtView_NextText
;
664 * Tooltip for the "next" button
666 * @return Tooltip for the "next" button
668 protected String
getNextTooltip() {
669 return Messages
.AbstractTimeGraphView_NextTooltip
;
673 * Text for the "Previous" button
675 * @return The "Previous" button text
677 protected String
getPrevText() {
678 return Messages
.AbstractTimeGraphView_PreviousText
;
682 * Tooltip for the "previous" button
684 * @return Tooltip for the "previous" button
686 protected String
getPrevTooltip() {
687 return Messages
.AbstractTimeGraphView_PreviousTooltip
;
690 // ------------------------------------------------------------------------
692 // ------------------------------------------------------------------------
695 public void createPartControl(Composite parent
) {
696 if (fColumns
== null || fLabelProvider
== null) {
697 fTimeGraphWrapper
= new TimeGraphViewerWrapper(parent
, SWT
.NONE
);
699 TimeGraphComboWrapper wrapper
= new TimeGraphComboWrapper(parent
, SWT
.NONE
);
700 fTimeGraphWrapper
= wrapper
;
701 TimeGraphCombo combo
= wrapper
.getTimeGraphCombo();
702 combo
.setTreeContentProvider(new TreeContentProvider());
703 combo
.setTreeLabelProvider(fLabelProvider
);
704 combo
.setTreeColumns(fColumns
);
705 combo
.setFilterContentProvider(new TreeContentProvider());
706 combo
.setFilterLabelProvider(new TreeLabelProvider());
707 combo
.setFilterColumns(fFilterColumns
);
710 fTimeGraphWrapper
.setTimeGraphProvider(fPresentation
);
712 fTimeGraphWrapper
.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
714 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event
) {
715 final long startTime
= event
.getStartTime();
716 final long endTime
= event
.getEndTime();
717 TmfTimeRange range
= new TmfTimeRange(new TmfNanoTimestamp(startTime
), new TmfNanoTimestamp(endTime
));
718 broadcast(new TmfRangeSynchSignal(AbstractTimeGraphView
.this, range
));
719 if (fZoomThread
!= null) {
720 fZoomThread
.cancel();
722 startZoomThread(startTime
, endTime
);
726 fTimeGraphWrapper
.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
728 public void timeSelected(TimeGraphTimeEvent event
) {
729 TmfNanoTimestamp startTime
= new TmfNanoTimestamp(event
.getBeginTime());
730 TmfNanoTimestamp endTime
= new TmfNanoTimestamp(event
.getEndTime());
731 broadcast(new TmfTimeSynchSignal(AbstractTimeGraphView
.this, startTime
, endTime
));
735 fTimeGraphWrapper
.addSelectionListener(new ITimeGraphSelectionListener() {
737 public void selectionChanged(TimeGraphSelectionEvent event
) {
738 // ITimeGraphEntry selection = event.getSelection();
742 fTimeGraphWrapper
.getTimeGraphViewer().setTimeFormat(TimeFormat
.CALENDAR
);
744 IStatusLineManager statusLineManager
= getViewSite().getActionBars().getStatusLineManager();
745 fTimeGraphWrapper
.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager
);
747 // View Action Handling
749 contributeToActionBars();
751 ITmfTrace trace
= getActiveTrace();
753 traceSelected(new TmfTraceSelectedSignal(this, trace
));
756 // make selection available to other views
757 getSite().setSelectionProvider(fTimeGraphWrapper
.getSelectionProvider());
761 public void setFocus() {
762 fTimeGraphWrapper
.setFocus();
765 // ------------------------------------------------------------------------
767 // ------------------------------------------------------------------------
770 * Handler for the trace opened signal.
773 * The incoming signal
777 public void traceOpened(TmfTraceOpenedSignal signal
) {
778 fTrace
= signal
.getTrace();
783 * Handler for the trace selected signal
786 * The incoming signal
789 public void traceSelected(final TmfTraceSelectedSignal signal
) {
790 if (signal
.getTrace() == fTrace
) {
793 fTrace
= signal
.getTrace();
799 * Trace is closed: clear the data structures and the view
802 * the signal received
805 public void traceClosed(final TmfTraceClosedSignal signal
) {
806 synchronized (fBuildThreadMap
) {
807 BuildThread buildThread
= fBuildThreadMap
.remove(signal
.getTrace());
808 if (buildThread
!= null) {
809 buildThread
.cancel();
812 synchronized (fEntryListMap
) {
813 fEntryListMap
.remove(signal
.getTrace());
815 if (signal
.getTrace() == fTrace
) {
819 if (fZoomThread
!= null) {
820 fZoomThread
.cancel();
827 * Handler for the time synch signal
830 * The signal that's received
833 public void synchToTime(final TmfTimeSynchSignal signal
) {
834 if (signal
.getSource() == this || fTrace
== null) {
837 final long beginTime
= signal
.getBeginTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
838 final long endTime
= signal
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
840 Display
.getDefault().asyncExec(new Runnable() {
843 if (fTimeGraphWrapper
.isDisposed()) {
846 if (beginTime
== endTime
) {
847 fTimeGraphWrapper
.getTimeGraphViewer().setSelectedTime(beginTime
, true);
849 fTimeGraphWrapper
.getTimeGraphViewer().setSelectionRange(beginTime
, endTime
);
851 startZoomThread(fTimeGraphWrapper
.getTimeGraphViewer().getTime0(), fTimeGraphWrapper
.getTimeGraphViewer().getTime1());
853 synchingToTime(beginTime
);
859 * Handler for the range synch signal
862 * The signal that's received
865 public void synchToRange(final TmfRangeSynchSignal signal
) {
866 if (signal
.getSource() == this || fTrace
== null) {
869 if (signal
.getCurrentRange().getIntersection(fTrace
.getTimeRange()) == null) {
872 final long startTime
= signal
.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
873 final long endTime
= signal
.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
874 Display
.getDefault().asyncExec(new Runnable() {
877 if (fTimeGraphWrapper
.isDisposed()) {
880 fTimeGraphWrapper
.getTimeGraphViewer().setStartFinishTime(startTime
, endTime
);
881 startZoomThread(startTime
, endTime
);
887 * @param signal the format of the timestamps was updated.
891 public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal
){
892 fTimeGraphWrapper
.refresh();
895 // ------------------------------------------------------------------------
897 // ------------------------------------------------------------------------
899 private void loadTrace() {
900 synchronized (fEntryListMap
) {
901 fEntryList
= fEntryListMap
.get(fTrace
);
902 if (fEntryList
== null) {
903 synchronized (fBuildThreadMap
) {
904 BuildThread buildThread
= new BuildThread(fTrace
, getName());
905 fBuildThreadMap
.put(fTrace
, buildThread
);
909 fStartTime
= fTrace
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
910 fEndTime
= fTrace
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
917 * Method called when synching to a given timestamp. Inheriting classes can
918 * perform actions here to update the view at the given timestamp.
921 * The currently selected time
923 protected void synchingToTime(long time
) {
928 * Build the entries list to show in this time graph
930 * Called from the BuildThread
933 * The trace being built
935 * The progress monitor object
937 protected abstract void buildEventList(final ITmfTrace trace
, IProgressMonitor monitor
);
940 * Gets the list of event for an entry in a given timerange
943 * The entry to get events for
945 * Start of the time range
947 * End of the time range
951 * The progress monitor object
952 * @return The list of events for the entry
954 protected abstract List
<ITimeEvent
> getEventList(TimeGraphEntry entry
,
955 long startTime
, long endTime
, long resolution
,
956 IProgressMonitor monitor
);
959 * Gets the list of links (displayed as arrows) for a trace in a given
960 * timerange. Default implementation returns an empty list.
963 * Start of the time range
965 * End of the time range
969 * The progress monitor object
970 * @return The list of link events
973 protected List
<ILinkEvent
> getLinkList(long startTime
, long endTime
,
974 long resolution
, IProgressMonitor monitor
) {
975 return new ArrayList
<ILinkEvent
>();
980 * Refresh the display
982 protected void refresh() {
983 Display
.getDefault().asyncExec(new Runnable() {
986 if (fTimeGraphWrapper
.isDisposed()) {
989 ITimeGraphEntry
[] entries
= null;
990 synchronized (fEntryListMap
) {
991 fEntryList
= fEntryListMap
.get(fTrace
);
992 if (fEntryList
== null) {
993 fEntryList
= new ArrayList
<TimeGraphEntry
>();
995 entries
= fEntryList
.toArray(new ITimeGraphEntry
[0]);
997 if (fEntryComparator
!= null) {
998 Arrays
.sort(entries
, fEntryComparator
);
1000 fTimeGraphWrapper
.setInput(entries
);
1001 fTimeGraphWrapper
.getTimeGraphViewer().setTimeBounds(fStartTime
, fEndTime
);
1003 long selectionBeginTime
= fTrace
== null ?
0 : fTraceManager
.getSelectionBeginTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1004 long selectionEndTime
= fTrace
== null ?
0 : fTraceManager
.getSelectionEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1005 long startTime
= fTrace
== null ?
0 : fTraceManager
.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1006 long endTime
= fTrace
== null ?
0 : fTraceManager
.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1007 startTime
= Math
.max(startTime
, fStartTime
);
1008 endTime
= Math
.min(endTime
, fEndTime
);
1009 fTimeGraphWrapper
.getTimeGraphViewer().setSelectionRange(selectionBeginTime
, selectionEndTime
);
1010 fTimeGraphWrapper
.getTimeGraphViewer().setStartFinishTime(startTime
, endTime
);
1012 if (fTimeGraphWrapper
instanceof TimeGraphComboWrapper
) {
1013 for (TreeColumn column
: ((TimeGraphComboWrapper
) fTimeGraphWrapper
).getTreeViewer().getTree().getColumns()) {
1018 startZoomThread(startTime
, endTime
);
1026 protected void redraw() {
1027 synchronized (fSyncObj
) {
1028 if (fRedrawState
== State
.IDLE
) {
1029 fRedrawState
= State
.BUSY
;
1031 fRedrawState
= State
.PENDING
;
1035 Display
.getDefault().asyncExec(new Runnable() {
1038 if (fTimeGraphWrapper
.isDisposed()) {
1041 fTimeGraphWrapper
.redraw();
1042 fTimeGraphWrapper
.update();
1043 synchronized (fSyncObj
) {
1044 if (fRedrawState
== State
.PENDING
) {
1045 fRedrawState
= State
.IDLE
;
1048 fRedrawState
= State
.IDLE
;
1055 private void startZoomThread(long startTime
, long endTime
) {
1056 if (fZoomThread
!= null) {
1057 fZoomThread
.cancel();
1059 fZoomThread
= new ZoomThread(fEntryList
, startTime
, endTime
, getName());
1060 fZoomThread
.start();
1063 private void makeActions() {
1064 fPreviousResourceAction
= fTimeGraphWrapper
.getTimeGraphViewer().getPreviousItemAction();
1065 fPreviousResourceAction
.setText(getPrevText());
1066 fPreviousResourceAction
.setToolTipText(getPrevTooltip());
1067 fNextResourceAction
= fTimeGraphWrapper
.getTimeGraphViewer().getNextItemAction();
1068 fNextResourceAction
.setText(getNextText());
1069 fNextResourceAction
.setToolTipText(getNextTooltip());
1072 private void contributeToActionBars() {
1073 IActionBars bars
= getViewSite().getActionBars();
1074 fillLocalToolBar(bars
.getToolBarManager());
1078 * Add actions to local tool bar manager
1080 * @param manager the tool bar manager
1082 protected void fillLocalToolBar(IToolBarManager manager
) {
1083 if (fTimeGraphWrapper
instanceof TimeGraphComboWrapper
) {
1084 if (fFilterColumns
.length
> 0) {
1085 manager
.add(((TimeGraphComboWrapper
) fTimeGraphWrapper
).getShowFilterAction());
1088 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getShowLegendAction());
1089 manager
.add(new Separator());
1090 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getResetScaleAction());
1091 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getPreviousEventAction());
1092 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getNextEventAction());
1093 manager
.add(fPreviousResourceAction
);
1094 manager
.add(fNextResourceAction
);
1095 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getZoomInAction());
1096 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getZoomOutAction());
1097 manager
.add(new Separator());