1 /*******************************************************************************
2 * Copyright (c) 2012, 2015 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
.tracecompass
.tmf
.ui
.views
.timegraph
;
19 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
21 import java
.util
.ArrayList
;
22 import java
.util
.Collections
;
23 import java
.util
.Comparator
;
24 import java
.util
.HashMap
;
25 import java
.util
.HashSet
;
26 import java
.util
.List
;
29 import java
.util
.concurrent
.CopyOnWriteArrayList
;
30 import java
.util
.regex
.Matcher
;
31 import java
.util
.regex
.Pattern
;
33 import org
.eclipse
.core
.resources
.IFile
;
34 import org
.eclipse
.core
.resources
.IMarker
;
35 import org
.eclipse
.core
.resources
.IMarkerDelta
;
36 import org
.eclipse
.core
.resources
.IResource
;
37 import org
.eclipse
.core
.resources
.IResourceChangeEvent
;
38 import org
.eclipse
.core
.resources
.IResourceChangeListener
;
39 import org
.eclipse
.core
.resources
.IWorkspaceRunnable
;
40 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
41 import org
.eclipse
.core
.runtime
.CoreException
;
42 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
43 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
44 import org
.eclipse
.jdt
.annotation
.NonNull
;
45 import org
.eclipse
.jdt
.annotation
.Nullable
;
46 import org
.eclipse
.jface
.action
.Action
;
47 import org
.eclipse
.jface
.action
.IAction
;
48 import org
.eclipse
.jface
.action
.IMenuManager
;
49 import org
.eclipse
.jface
.action
.IStatusLineManager
;
50 import org
.eclipse
.jface
.action
.IToolBarManager
;
51 import org
.eclipse
.jface
.action
.Separator
;
52 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
53 import org
.eclipse
.jface
.viewers
.ILabelProvider
;
54 import org
.eclipse
.jface
.viewers
.ILabelProviderListener
;
55 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
56 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
57 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
58 import org
.eclipse
.jface
.viewers
.TreeViewer
;
59 import org
.eclipse
.jface
.viewers
.ViewerFilter
;
60 import org
.eclipse
.osgi
.util
.NLS
;
61 import org
.eclipse
.swt
.SWT
;
62 import org
.eclipse
.swt
.graphics
.Color
;
63 import org
.eclipse
.swt
.graphics
.Image
;
64 import org
.eclipse
.swt
.widgets
.Composite
;
65 import org
.eclipse
.swt
.widgets
.Display
;
66 import org
.eclipse
.swt
.widgets
.TreeColumn
;
67 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
68 import org
.eclipse
.tracecompass
.tmf
.core
.resources
.ITmfMarker
;
69 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSelectionRangeUpdatedSignal
;
70 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalHandler
;
71 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTimestampFormatUpdateSignal
;
72 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceClosedSignal
;
73 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
74 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
75 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfWindowRangeUpdatedSignal
;
76 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
77 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfNanoTimestamp
;
78 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
79 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
80 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceAdapterManager
;
81 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceContext
;
82 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
83 import org
.eclipse
.tracecompass
.tmf
.ui
.TmfUiRefreshHandler
;
84 import org
.eclipse
.tracecompass
.tmf
.ui
.signal
.TmfTimeViewAlignmentInfo
;
85 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.ITmfTimeAligned
;
86 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.TmfView
;
87 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphBookmarkListener
;
88 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphContentProvider
;
89 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphPresentationProvider2
;
90 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphRangeListener
;
91 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphSelectionListener
;
92 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphTimeListener
;
93 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphBookmarkEvent
;
94 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphCombo
;
95 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphContentProvider
;
96 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphPresentationProvider
;
97 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphRangeUpdateEvent
;
98 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphTimeEvent
;
99 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphViewer
;
100 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
101 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.IMarkerEvent
;
102 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.IMarkerEventSource
;
103 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
104 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
105 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.MarkerEvent
;
106 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.TimeGraphEntry
;
107 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
108 import org
.eclipse
.ui
.IActionBars
;
111 * An abstract view all time graph views can inherit
113 * This view contains either a time graph viewer, or a time graph combo which is
114 * divided between a tree viewer on the left and a time graph viewer on the right.
116 public abstract class AbstractTimeGraphView
extends TmfView
implements ITmfTimeAligned
, IResourceChangeListener
{
118 /** Constant indicating that all levels of the time graph should be expanded */
119 protected static final int ALL_LEVELS
= AbstractTreeViewer
.ALL_LEVELS
;
121 private static final Pattern RGBA_PATTERN
= Pattern
.compile("RGBA \\{(\\d+), (\\d+), (\\d+), (\\d+)\\}"); //$NON-NLS-1$
130 // ------------------------------------------------------------------------
132 // ------------------------------------------------------------------------
134 /** The timegraph wrapper */
135 private ITimeGraphWrapper fTimeGraphWrapper
;
137 /** The selected trace */
138 private ITmfTrace fTrace
;
140 /** The selected trace editor file*/
141 private IFile fEditorFile
;
143 /** The timegraph entry list */
144 private List
<TimeGraphEntry
> fEntryList
;
146 /** The trace to entry list hash map */
147 private final Map
<ITmfTrace
, List
<TimeGraphEntry
>> fEntryListMap
= new HashMap
<>();
149 /** The trace to filters hash map */
150 private final Map
<ITmfTrace
, ViewerFilter
[]> fFiltersMap
= new HashMap
<>();
152 /** The trace to marker event sources hash map */
153 private final Map
<ITmfTrace
, List
<IMarkerEventSource
>> fMarkerEventSourcesMap
= new HashMap
<>();
155 /** The trace to build thread hash map */
156 private final Map
<ITmfTrace
, BuildThread
> fBuildThreadMap
= new HashMap
<>();
158 /** The start time */
159 private long fStartTime
= SWT
.DEFAULT
;
162 private long fEndTime
= SWT
.DEFAULT
;
164 /** The display width */
165 private final int fDisplayWidth
;
167 /** The zoom thread */
168 private ZoomThread fZoomThread
;
170 /** The next resource action */
171 private Action fNextResourceAction
;
173 /** The previous resource action */
174 private Action fPreviousResourceAction
;
176 /** A comparator class */
177 private Comparator
<ITimeGraphEntry
> fEntryComparator
= null;
179 /** The redraw state used to prevent unnecessary queuing of display runnables */
180 private State fRedrawState
= State
.IDLE
;
182 /** The redraw synchronization object */
183 private final Object fSyncObj
= new Object();
185 /** The presentation provider for this view */
186 private final TimeGraphPresentationProvider fPresentation
;
188 /** The tree column label array, or null if combo is not used */
189 private String
[] fColumns
;
191 /** The tree label provider, or null if combo is not used */
192 private TreeLabelProvider fLabelProvider
= null;
194 /** The time graph content provider */
195 private @NonNull ITimeGraphContentProvider fTimeGraphContentProvider
= new TimeGraphContentProvider();
197 /** The relative weight of the sash, ignored if combo is not used */
198 private int[] fWeight
= { 1, 3 };
200 /** The filter column label array, or null if filter is not used */
201 private String
[] fFilterColumns
;
203 /** The pack done flag */
204 private boolean fPackDone
= false;
206 /** The filter content provider, or null if filter is not used */
207 private ITreeContentProvider fFilterContentProvider
;
209 /** The filter label provider, or null if filter is not used */
210 private TreeLabelProvider fFilterLabelProvider
;
212 private int fAutoExpandLevel
= ALL_LEVELS
;
214 /** The list of color resources created by this view */
215 private final List
<Color
> fColors
= new ArrayList
<>();
217 // ------------------------------------------------------------------------
219 // ------------------------------------------------------------------------
221 private interface ITimeGraphWrapper
{
223 void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
);
225 void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider
);
227 TimeGraphViewer
getTimeGraphViewer();
229 void addSelectionListener(ITimeGraphSelectionListener listener
);
231 ISelectionProvider
getSelectionProvider();
235 boolean isDisposed();
239 void setInput(Object input
);
243 void setFilters(ViewerFilter
[] filters
);
245 ViewerFilter
[] getFilters();
251 void setAutoExpandLevel(int level
);
253 void setFilterColumns(String
[] columnNames
);
255 void setFilterContentProvider(ITreeContentProvider contentProvider
);
257 void setFilterLabelProvider(ITableLabelProvider labelProvider
);
259 IAction
getShowFilterDialogAction();
261 void performAlign(int offset
, int width
);
263 TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo();
265 int getAvailableWidth(int requestedOffset
);
268 private class TimeGraphViewerWrapper
implements ITimeGraphWrapper
{
269 private TimeGraphViewer viewer
;
271 private TimeGraphViewerWrapper(Composite parent
, int style
) {
272 viewer
= new TimeGraphViewer(parent
, style
);
276 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
) {
277 viewer
.setTimeGraphContentProvider(timeGraphContentProvider
);
281 public void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider
) {
282 viewer
.setTimeGraphProvider(timeGraphPresentationProvider
);
286 public TimeGraphViewer
getTimeGraphViewer() {
291 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
292 viewer
.addSelectionListener(listener
);
296 public ISelectionProvider
getSelectionProvider() {
297 return viewer
.getSelectionProvider();
301 public void setFocus() {
306 public boolean isDisposed() {
307 return viewer
.getControl().isDisposed();
311 public void setInput(Object input
) {
312 viewer
.setInput(input
);
316 public Object
getInput() {
317 return viewer
.getInput();
321 public void setFilterColumns(String
[] columnNames
) {
322 viewer
.setFilterColumns(columnNames
);
326 public void setFilterContentProvider(ITreeContentProvider contentProvider
) {
327 viewer
.setFilterContentProvider(contentProvider
);
331 public void setFilterLabelProvider(ITableLabelProvider labelProvider
) {
332 viewer
.setFilterLabelProvider(labelProvider
);
336 public void setFilters(ViewerFilter
[] filters
) {
337 viewer
.setFilters(filters
);
341 public ViewerFilter
[] getFilters() {
342 return viewer
.getFilters();
346 public IAction
getShowFilterDialogAction() {
347 return viewer
.getShowFilterDialogAction();
351 public void refresh() {
356 public void redraw() {
357 viewer
.getControl().redraw();
361 public void update() {
362 viewer
.getControl().update();
366 public void setAutoExpandLevel(int level
) {
367 viewer
.setAutoExpandLevel(level
);
371 public void performAlign(int offset
, int width
) {
372 viewer
.performAlign(offset
, width
);
376 public TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo() {
377 return viewer
.getTimeViewAlignmentInfo();
381 public int getAvailableWidth(int requestedOffset
) {
382 return viewer
.getAvailableWidth(requestedOffset
);
386 private class TimeGraphComboWrapper
implements ITimeGraphWrapper
{
387 private TimeGraphCombo combo
;
389 private TimeGraphComboWrapper(Composite parent
, int style
) {
390 combo
= new TimeGraphCombo(parent
, style
, fWeight
);
394 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider
) {
395 combo
.setTimeGraphContentProvider(timeGraphContentProvider
);
399 public void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider
) {
400 combo
.setTimeGraphProvider(timeGraphPresentationProvider
);
404 public TimeGraphViewer
getTimeGraphViewer() {
405 return combo
.getTimeGraphViewer();
409 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
410 combo
.addSelectionListener(listener
);
414 public ISelectionProvider
getSelectionProvider() {
415 return combo
.getTreeViewer();
419 public void setFocus() {
424 public boolean isDisposed() {
425 return combo
.isDisposed();
429 public void setInput(Object input
) {
430 combo
.setInput(input
);
434 public Object
getInput() {
435 return combo
.getInput();
439 public void setFilterColumns(String
[] columnNames
) {
440 combo
.setFilterColumns(columnNames
);
444 public void setFilterContentProvider(ITreeContentProvider contentProvider
) {
445 combo
.setFilterContentProvider(contentProvider
);
449 public void setFilterLabelProvider(ITableLabelProvider labelProvider
) {
450 combo
.setFilterLabelProvider(labelProvider
);
454 public void setFilters(ViewerFilter
[] filters
) {
455 combo
.setFilters(filters
);
459 public ViewerFilter
[] getFilters() {
460 return combo
.getFilters();
464 public IAction
getShowFilterDialogAction() {
465 return combo
.getShowFilterDialogAction();
469 public void refresh() {
474 public void redraw() {
479 public void update() {
484 public void setAutoExpandLevel(int level
) {
485 combo
.setAutoExpandLevel(level
);
488 TimeGraphCombo
getTimeGraphCombo() {
492 TreeViewer
getTreeViewer() {
493 return combo
.getTreeViewer();
497 public void performAlign(int offset
, int width
) {
498 combo
.performAlign(offset
, width
);
502 public TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo() {
503 return combo
.getTimeViewAlignmentInfo();
507 public int getAvailableWidth(int requestedOffset
) {
508 return combo
.getAvailableWidth(requestedOffset
);
513 * Base class to provide the labels for the tree viewer. Views extending
514 * this class typically need to override the getColumnText method if they
515 * have more than one column to display
517 protected static class TreeLabelProvider
implements ITableLabelProvider
, ILabelProvider
{
520 public void addListener(ILabelProviderListener listener
) {
524 public void dispose() {
528 public boolean isLabelProperty(Object element
, String property
) {
533 public void removeListener(ILabelProviderListener listener
) {
537 public Image
getColumnImage(Object element
, int columnIndex
) {
542 public String
getColumnText(Object element
, int columnIndex
) {
543 TimeGraphEntry entry
= (TimeGraphEntry
) element
;
544 if (columnIndex
== 0) {
545 return entry
.getName();
551 public Image
getImage(Object element
) {
556 public String
getText(Object element
) {
557 TimeGraphEntry entry
= (TimeGraphEntry
) element
;
558 return entry
.getName();
563 private class BuildThread
extends Thread
{
564 private final @NonNull ITmfTrace fBuildTrace
;
565 private final @NonNull ITmfTrace fParentTrace
;
566 private final @NonNull IProgressMonitor fMonitor
;
568 public BuildThread(final @NonNull ITmfTrace trace
, final @NonNull ITmfTrace parentTrace
, final String name
) {
569 super(name
+ " build"); //$NON-NLS-1$
571 fParentTrace
= parentTrace
;
572 fMonitor
= new NullProgressMonitor();
577 buildEventList(fBuildTrace
, fParentTrace
, fMonitor
);
578 synchronized (fBuildThreadMap
) {
579 fBuildThreadMap
.remove(fBuildTrace
);
583 public void cancel() {
584 fMonitor
.setCanceled(true);
592 protected abstract class ZoomThread
extends Thread
{
593 private final long fZoomStartTime
;
594 private final long fZoomEndTime
;
595 private final long fResolution
;
596 private final @NonNull IProgressMonitor fMonitor
;
608 public ZoomThread(long startTime
, long endTime
, long resolution
) {
609 super(AbstractTimeGraphView
.this.getName() + " zoom"); //$NON-NLS-1$
610 fZoomStartTime
= startTime
;
611 fZoomEndTime
= endTime
;
612 fResolution
= resolution
;
613 fMonitor
= new NullProgressMonitor();
617 * @return the zoom start time
619 public long getZoomStartTime() {
620 return fZoomStartTime
;
624 * @return the zoom end time
626 public long getZoomEndTime() {
631 * @return the resolution
633 public long getResolution() {
638 * @return the monitor
640 public @NonNull IProgressMonitor
getMonitor() {
645 * Cancel the zoom thread
647 public void cancel() {
648 fMonitor
.setCanceled(true);
652 private class ZoomThreadByEntry
extends ZoomThread
{
653 private final @NonNull List
<TimeGraphEntry
> fZoomEntryList
;
655 public ZoomThreadByEntry(@NonNull List
<TimeGraphEntry
> entryList
, long startTime
, long endTime
, long resolution
) {
656 super(startTime
, endTime
, resolution
);
657 fZoomEntryList
= entryList
;
662 for (TimeGraphEntry entry
: fZoomEntryList
) {
663 if (getMonitor().isCanceled()) {
669 zoom(entry
, getMonitor());
671 /* Refresh the arrows when zooming */
672 List
<ILinkEvent
> events
= getLinkList(getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor());
673 if (events
!= null) {
674 fTimeGraphWrapper
.getTimeGraphViewer().setLinks(events
);
677 /* Refresh the view-specific markers when zooming */
678 List
<IMarkerEvent
> markers
= new ArrayList
<>(getViewMarkerList(getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor()));
679 /* Refresh the trace-specific markers when zooming */
680 markers
.addAll(getTraceMarkerList(getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor()));
681 fTimeGraphWrapper
.getTimeGraphViewer().setMarkers(markers
);
685 private void zoom(@NonNull TimeGraphEntry entry
, @NonNull IProgressMonitor monitor
) {
686 if (getZoomStartTime() <= fStartTime
&& getZoomEndTime() >= fEndTime
) {
687 entry
.setZoomedEventList(null);
689 List
<ITimeEvent
> zoomedEventList
= getEventList(entry
, getZoomStartTime(), getZoomEndTime(), getResolution(), monitor
);
690 if (zoomedEventList
!= null) {
691 entry
.setZoomedEventList(zoomedEventList
);
695 for (ITimeGraphEntry child
: entry
.getChildren()) {
696 if (monitor
.isCanceled()) {
699 if (child
instanceof TimeGraphEntry
) {
700 zoom((TimeGraphEntry
) child
, monitor
);
707 // ------------------------------------------------------------------------
709 // ------------------------------------------------------------------------
712 * Constructs a time graph view that contains either a time graph viewer or
713 * a time graph combo.
715 * By default, the view uses a time graph viewer. To use a time graph combo,
716 * the subclass constructor must call {@link #setTreeColumns(String[])} and
717 * {@link #setTreeLabelProvider(TreeLabelProvider)}.
722 * The presentation provider
724 public AbstractTimeGraphView(String id
, TimeGraphPresentationProvider pres
) {
726 fPresentation
= pres
;
727 fDisplayWidth
= Display
.getDefault().getBounds().width
;
730 // ------------------------------------------------------------------------
731 // Getters and setters
732 // ------------------------------------------------------------------------
735 * Getter for the time graph combo
737 * @return The time graph combo, or null if combo is not used
739 protected TimeGraphCombo
getTimeGraphCombo() {
740 if (fTimeGraphWrapper
instanceof TimeGraphComboWrapper
) {
741 return ((TimeGraphComboWrapper
) fTimeGraphWrapper
).getTimeGraphCombo();
747 * Getter for the time graph viewer
749 * @return The time graph viewer
751 protected TimeGraphViewer
getTimeGraphViewer() {
752 return fTimeGraphWrapper
.getTimeGraphViewer();
756 * Getter for the presentation provider
758 * @return The time graph presentation provider
760 protected ITimeGraphPresentationProvider2
getPresentationProvider() {
761 return fPresentation
;
765 * Sets the tree column labels.
767 * This should be called from the constructor.
770 * The array of tree column labels
772 protected void setTreeColumns(final String
[] columns
) {
773 checkPartNotCreated();
778 * Sets the tree label provider.
780 * This should be called from the constructor.
783 * The tree label provider
785 protected void setTreeLabelProvider(final TreeLabelProvider tlp
) {
786 checkPartNotCreated();
787 fLabelProvider
= tlp
;
791 * Sets the time graph content provider.
793 * This should be called from the constructor.
796 * The time graph content provider
799 protected void setTimeGraphContentProvider(final @NonNull ITimeGraphContentProvider tgcp
) {
800 checkPartNotCreated();
801 fTimeGraphContentProvider
= tgcp
;
805 * Sets the relative weight of each part of the time graph combo.
807 * This should be called from the constructor.
810 * The array (length 2) of relative weights of each part of the combo
812 protected void setWeight(final int[] weights
) {
813 checkPartNotCreated();
818 * Sets the filter column labels.
820 * This should be called from the constructor.
822 * @param filterColumns
823 * The array of filter column labels
825 protected void setFilterColumns(final String
[] filterColumns
) {
826 checkPartNotCreated();
827 fFilterColumns
= filterColumns
;
831 * Sets the filter content provider.
833 * This should be called from the constructor.
835 * @param contentProvider
836 * The filter content provider
839 protected void setFilterContentProvider(final ITreeContentProvider contentProvider
) {
840 checkPartNotCreated();
841 fFilterContentProvider
= contentProvider
;
845 * Sets the filter label provider.
847 * This should be called from the constructor.
849 * @param labelProvider
850 * The filter label provider
852 protected void setFilterLabelProvider(final TreeLabelProvider labelProvider
) {
853 checkPartNotCreated();
854 fFilterLabelProvider
= labelProvider
;
857 private void checkPartNotCreated() {
858 if (getParentComposite() != null) {
859 throw new IllegalStateException("This method must be called before createPartControl."); //$NON-NLS-1$
864 * Gets the display width
866 * @return the display width
868 protected int getDisplayWidth() {
869 return fDisplayWidth
;
873 * Gets the comparator for the entries
875 * @return The entry comparator
877 protected Comparator
<ITimeGraphEntry
> getEntryComparator() {
878 return fEntryComparator
;
882 * Sets the comparator class for the entries.
884 * This comparator will apply recursively to entries that implement
885 * {@link TimeGraphEntry#sortChildren(Comparator)}.
888 * A comparator object
890 protected void setEntryComparator(final Comparator
<ITimeGraphEntry
> comparator
) {
891 fEntryComparator
= comparator
;
895 * Gets the trace displayed in the view
899 protected ITmfTrace
getTrace() {
904 * Gets the start time
906 * @return The start time
908 protected long getStartTime() {
913 * Sets the start time
918 protected void setStartTime(long time
) {
925 * @return The end time
927 protected long getEndTime() {
937 protected void setEndTime(long time
) {
942 * Sets the auto-expand level to be used for the input of the view. The
943 * value 0 means that there is no auto-expand; 1 means that top-level
944 * elements are expanded, but not their children; 2 means that top-level
945 * elements are expanded, and their children, but not grand-children; and so
948 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
952 * non-negative level, or <code>ALL_LEVELS</code> to expand all
955 protected void setAutoExpandLevel(int level
) {
956 fAutoExpandLevel
= level
;
957 ITimeGraphWrapper tgWrapper
= fTimeGraphWrapper
;
958 if (tgWrapper
!= null) {
959 tgWrapper
.setAutoExpandLevel(level
);
964 * Gets the entry list for a trace
969 * @return the entry list map
971 protected List
<TimeGraphEntry
> getEntryList(ITmfTrace trace
) {
972 synchronized (fEntryListMap
) {
973 return fEntryListMap
.get(trace
);
978 * Adds a trace entry list to the entry list map
983 * the list of time graph entries
985 protected void putEntryList(ITmfTrace trace
, List
<TimeGraphEntry
> list
) {
986 synchronized (fEntryListMap
) {
987 fEntryListMap
.put(trace
, new CopyOnWriteArrayList
<>(list
));
992 * Adds a list of entries to a trace's entry list
997 * the list of time graph entries to add
999 protected void addToEntryList(ITmfTrace trace
, List
<TimeGraphEntry
> list
) {
1000 synchronized (fEntryListMap
) {
1001 List
<TimeGraphEntry
> entryList
= fEntryListMap
.get(trace
);
1002 if (entryList
== null) {
1003 fEntryListMap
.put(trace
, new CopyOnWriteArrayList
<>(list
));
1005 entryList
.addAll(list
);
1011 * Removes a list of entries from a trace's entry list
1016 * the list of time graph entries to remove
1018 protected void removeFromEntryList(ITmfTrace trace
, List
<TimeGraphEntry
> list
) {
1019 synchronized (fEntryListMap
) {
1020 List
<TimeGraphEntry
> entryList
= fEntryListMap
.get(trace
);
1021 if (entryList
!= null) {
1022 entryList
.removeAll(list
);
1028 * Text for the "next" button
1030 * @return The "next" button text
1032 protected String
getNextText() {
1033 return Messages
.AbstractTimeGraphtView_NextText
;
1037 * Tooltip for the "next" button
1039 * @return Tooltip for the "next" button
1041 protected String
getNextTooltip() {
1042 return Messages
.AbstractTimeGraphView_NextTooltip
;
1046 * Text for the "Previous" button
1048 * @return The "Previous" button text
1050 protected String
getPrevText() {
1051 return Messages
.AbstractTimeGraphView_PreviousText
;
1055 * Tooltip for the "previous" button
1057 * @return Tooltip for the "previous" button
1059 protected String
getPrevTooltip() {
1060 return Messages
.AbstractTimeGraphView_PreviousTooltip
;
1063 // ------------------------------------------------------------------------
1065 // ------------------------------------------------------------------------
1068 public void createPartControl(Composite parent
) {
1069 super.createPartControl(parent
);
1070 if (fColumns
== null || fLabelProvider
== null) {
1071 fTimeGraphWrapper
= new TimeGraphViewerWrapper(parent
, SWT
.NONE
);
1073 TimeGraphComboWrapper wrapper
= new TimeGraphComboWrapper(parent
, SWT
.NONE
);
1074 fTimeGraphWrapper
= wrapper
;
1075 TimeGraphCombo combo
= wrapper
.getTimeGraphCombo();
1076 combo
.setTreeContentProvider(fTimeGraphContentProvider
);
1077 combo
.setTreeLabelProvider(fLabelProvider
);
1078 combo
.setTreeColumns(fColumns
);
1080 fTimeGraphWrapper
.setTimeGraphContentProvider(fTimeGraphContentProvider
);
1081 fTimeGraphWrapper
.setFilterContentProvider(fFilterContentProvider
!= null ? fFilterContentProvider
: fTimeGraphContentProvider
);
1082 fTimeGraphWrapper
.setFilterLabelProvider(fFilterLabelProvider
);
1083 fTimeGraphWrapper
.setFilterColumns(fFilterColumns
);
1085 fTimeGraphWrapper
.setTimeGraphPresentationProvider(fPresentation
);
1086 fTimeGraphWrapper
.setAutoExpandLevel(fAutoExpandLevel
);
1088 fTimeGraphWrapper
.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
1090 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event
) {
1091 final long startTime
= event
.getStartTime();
1092 final long endTime
= event
.getEndTime();
1093 TmfTimeRange range
= new TmfTimeRange(new TmfNanoTimestamp(startTime
), new TmfNanoTimestamp(endTime
));
1094 broadcast(new TmfWindowRangeUpdatedSignal(AbstractTimeGraphView
.this, range
));
1095 startZoomThread(startTime
, endTime
);
1099 fTimeGraphWrapper
.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
1101 public void timeSelected(TimeGraphTimeEvent event
) {
1102 TmfNanoTimestamp startTime
= new TmfNanoTimestamp(event
.getBeginTime());
1103 TmfNanoTimestamp endTime
= new TmfNanoTimestamp(event
.getEndTime());
1104 broadcast(new TmfSelectionRangeUpdatedSignal(AbstractTimeGraphView
.this, startTime
, endTime
));
1108 fTimeGraphWrapper
.getTimeGraphViewer().addBookmarkListener(new ITimeGraphBookmarkListener() {
1110 public void bookmarkAdded(final TimeGraphBookmarkEvent event
) {
1112 ResourcesPlugin
.getWorkspace().run(new IWorkspaceRunnable() {
1114 public void run(IProgressMonitor monitor
) throws CoreException
{
1115 IMarkerEvent bookmark
= event
.getBookmark();
1116 IMarker marker
= fEditorFile
.createMarker(IMarker
.BOOKMARK
);
1117 marker
.setAttribute(IMarker
.MESSAGE
, bookmark
.getLabel());
1118 marker
.setAttribute(ITmfMarker
.MARKER_TIME
, Long
.toString(bookmark
.getTime()));
1119 if (bookmark
.getDuration() > 0) {
1120 marker
.setAttribute(ITmfMarker
.MARKER_DURATION
, Long
.toString(bookmark
.getDuration()));
1121 marker
.setAttribute(IMarker
.LOCATION
,
1122 NLS
.bind(org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Messages
.TmfMarker_LocationTimeRange
,
1123 new TmfNanoTimestamp(bookmark
.getTime()),
1124 new TmfNanoTimestamp(bookmark
.getTime() + bookmark
.getDuration())));
1126 marker
.setAttribute(IMarker
.LOCATION
,
1127 NLS
.bind(org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Messages
.TmfMarker_LocationTime
,
1128 new TmfNanoTimestamp(bookmark
.getTime())));
1130 marker
.setAttribute(ITmfMarker
.MARKER_COLOR
, bookmark
.getColor().getRGBA().toString());
1133 } catch (CoreException e
) {
1134 Activator
.getDefault().logError(e
.getMessage());
1139 public void bookmarkRemoved(TimeGraphBookmarkEvent event
) {
1141 IMarkerEvent bookmark
= event
.getBookmark();
1142 IMarker
[] markers
= fEditorFile
.findMarkers(IMarker
.BOOKMARK
, false, IResource
.DEPTH_ZERO
);
1143 for (IMarker marker
: markers
) {
1144 if (bookmark
.getLabel().equals(marker
.getAttribute(IMarker
.MESSAGE
)) &&
1145 Long
.toString(bookmark
.getTime()).equals(marker
.getAttribute(ITmfMarker
.MARKER_TIME
, (String
) null)) &&
1146 Long
.toString(bookmark
.getDuration()).equals(marker
.getAttribute(ITmfMarker
.MARKER_DURATION
, Long
.toString(0))) &&
1147 bookmark
.getColor().getRGBA().toString().equals(marker
.getAttribute(ITmfMarker
.MARKER_COLOR
))) {
1152 } catch (CoreException e
) {
1153 Activator
.getDefault().logError(e
.getMessage());
1158 fTimeGraphWrapper
.getTimeGraphViewer().setTimeFormat(TimeFormat
.CALENDAR
);
1160 IStatusLineManager statusLineManager
= getViewSite().getActionBars().getStatusLineManager();
1161 fTimeGraphWrapper
.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager
);
1163 // View Action Handling
1165 contributeToActionBars();
1167 ITmfTrace trace
= TmfTraceManager
.getInstance().getActiveTrace();
1168 if (trace
!= null) {
1169 traceSelected(new TmfTraceSelectedSignal(this, trace
));
1172 // make selection available to other views
1173 getSite().setSelectionProvider(fTimeGraphWrapper
.getSelectionProvider());
1175 ResourcesPlugin
.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent
.POST_CHANGE
);
1179 public void setFocus() {
1180 fTimeGraphWrapper
.setFocus();
1184 public void dispose() {
1186 ResourcesPlugin
.getWorkspace().removeResourceChangeListener(this);
1193 public void resourceChanged(final IResourceChangeEvent event
) {
1194 for (final IMarkerDelta delta
: event
.findMarkerDeltas(IMarker
.BOOKMARK
, false)) {
1195 if (delta
.getResource().equals(fEditorFile
)) {
1196 fTimeGraphWrapper
.getTimeGraphViewer().setBookmarks(refreshBookmarks(fEditorFile
));
1203 private List
<IMarkerEvent
> refreshBookmarks(final IFile editorFile
) {
1204 List
<IMarkerEvent
> bookmarks
= new ArrayList
<>();
1205 for (Color color
: fColors
) {
1209 if (editorFile
== null || !editorFile
.exists()) {
1213 IMarker
[] markers
= editorFile
.findMarkers(IMarker
.BOOKMARK
, false, IResource
.DEPTH_ZERO
);
1214 for (IMarker marker
: markers
) {
1215 String label
= marker
.getAttribute(IMarker
.MESSAGE
, (String
) null);
1216 String time
= marker
.getAttribute(ITmfMarker
.MARKER_TIME
, (String
) null);
1217 String duration
= marker
.getAttribute(ITmfMarker
.MARKER_DURATION
, Long
.toString(0));
1218 String rgba
= marker
.getAttribute(ITmfMarker
.MARKER_COLOR
, (String
) null);
1219 if (label
!= null && time
!= null && rgba
!= null) {
1220 Matcher matcher
= RGBA_PATTERN
.matcher(rgba
);
1221 if (matcher
.matches()) {
1223 int red
= Integer
.valueOf(matcher
.group(1));
1224 int green
= Integer
.valueOf(matcher
.group(2));
1225 int blue
= Integer
.valueOf(matcher
.group(3));
1226 int alpha
= Integer
.valueOf(matcher
.group(4));
1227 Color color
= new Color(Display
.getDefault(), red
, green
, blue
, alpha
);
1229 bookmarks
.add(new MarkerEvent(null, Long
.valueOf(time
), Long
.valueOf(duration
), IMarkerEvent
.BOOKMARKS
, color
, label
, true));
1230 } catch (NumberFormatException e
) {
1231 Activator
.getDefault().logError(e
.getMessage());
1236 } catch (CoreException e
) {
1237 Activator
.getDefault().logError(e
.getMessage());
1242 // ------------------------------------------------------------------------
1244 // ------------------------------------------------------------------------
1247 * Handler for the trace opened signal.
1250 * The incoming signal
1253 public void traceOpened(TmfTraceOpenedSignal signal
) {
1254 loadTrace(signal
.getTrace());
1258 * Handler for the trace selected signal
1261 * The incoming signal
1264 public void traceSelected(final TmfTraceSelectedSignal signal
) {
1265 if (signal
.getTrace() == fTrace
) {
1268 loadTrace(signal
.getTrace());
1272 * Trace is closed: clear the data structures and the view
1275 * the signal received
1278 public void traceClosed(final TmfTraceClosedSignal signal
) {
1279 synchronized (fBuildThreadMap
) {
1280 for (ITmfTrace trace
: getTracesToBuild(signal
.getTrace())) {
1281 BuildThread buildThread
= fBuildThreadMap
.remove(trace
);
1282 if (buildThread
!= null) {
1283 buildThread
.cancel();
1287 fMarkerEventSourcesMap
.remove(signal
.getTrace());
1288 synchronized (fEntryListMap
) {
1289 fEntryListMap
.remove(signal
.getTrace());
1291 fFiltersMap
.remove(signal
.getTrace());
1292 if (signal
.getTrace() == fTrace
) {
1295 fStartTime
= SWT
.DEFAULT
;
1296 fEndTime
= SWT
.DEFAULT
;
1297 if (fZoomThread
!= null) {
1298 fZoomThread
.cancel();
1306 * Handler for the selection range signal.
1309 * The signal that's received
1313 public void selectionRangeUpdated(final TmfSelectionRangeUpdatedSignal signal
) {
1314 if (signal
.getSource() == this || fTrace
== null) {
1317 final long beginTime
= signal
.getBeginTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1318 final long endTime
= signal
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1320 Display
.getDefault().asyncExec(new Runnable() {
1323 if (fTimeGraphWrapper
.isDisposed()) {
1326 if (beginTime
== endTime
) {
1327 fTimeGraphWrapper
.getTimeGraphViewer().setSelectedTime(beginTime
, true);
1329 fTimeGraphWrapper
.getTimeGraphViewer().setSelectionRange(beginTime
, endTime
, true);
1331 synchingToTime(fTimeGraphWrapper
.getTimeGraphViewer().getSelectionBegin());
1337 * Handler for the window range signal.
1340 * The signal that's received
1344 public void windowRangeUpdated(final TmfWindowRangeUpdatedSignal signal
) {
1345 if (signal
.getSource() == this || fTrace
== null) {
1348 if (signal
.getCurrentRange().getIntersection(fTrace
.getTimeRange()) == null) {
1351 final long startTime
= signal
.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1352 final long endTime
= signal
.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1353 Display
.getDefault().asyncExec(new Runnable() {
1356 if (fTimeGraphWrapper
.isDisposed()) {
1359 fTimeGraphWrapper
.getTimeGraphViewer().setStartFinishTime(startTime
, endTime
);
1360 startZoomThread(startTime
, endTime
);
1366 * @param signal the format of the timestamps was updated.
1369 public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal
){
1370 fTimeGraphWrapper
.refresh();
1373 // ------------------------------------------------------------------------
1375 // ------------------------------------------------------------------------
1377 private void loadTrace(final ITmfTrace trace
) {
1378 if (fZoomThread
!= null) {
1379 fZoomThread
.cancel();
1382 if (fTrace
!= null) {
1383 /* save the filters of the previous trace */
1384 fFiltersMap
.put(fTrace
, fTimeGraphWrapper
.getFilters());
1387 fEditorFile
= TmfTraceManager
.getInstance().getTraceEditorFile(trace
);
1388 synchronized (fEntryListMap
) {
1389 fEntryList
= fEntryListMap
.get(fTrace
);
1390 if (fEntryList
== null) {
1393 fStartTime
= fTrace
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1394 fEndTime
= fTrace
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1401 * Forces a rebuild of the entries list, even if entries already exist for this trace
1403 protected void rebuild() {
1404 setStartTime(Long
.MAX_VALUE
);
1405 setEndTime(Long
.MIN_VALUE
);
1407 ITmfTrace viewTrace
= fTrace
;
1408 if (viewTrace
== null) {
1411 List
<IMarkerEventSource
> markerEventSources
= new ArrayList
<>();
1412 synchronized (fBuildThreadMap
) {
1413 for (ITmfTrace trace
: getTracesToBuild(viewTrace
)) {
1414 if (trace
== null) {
1417 markerEventSources
.addAll(TmfTraceAdapterManager
.getAdapters(trace
, IMarkerEventSource
.class));
1418 BuildThread buildThread
= new BuildThread(trace
, viewTrace
, getName());
1419 fBuildThreadMap
.put(trace
, buildThread
);
1420 buildThread
.start();
1423 fMarkerEventSourcesMap
.put(viewTrace
, markerEventSources
);
1427 * Method called when synching to a given timestamp. Inheriting classes can
1428 * perform actions here to update the view at the given timestamp.
1431 * The currently selected time
1433 protected void synchingToTime(long time
) {
1438 * Return the list of traces whose data or analysis results will be used to
1439 * populate the view. By default, if the trace is an experiment, the traces
1440 * under it will be returned, otherwise, the trace itself is returned.
1442 * A build thread will be started for each trace returned by this method,
1443 * some of which may receive events in live streaming mode.
1446 * The trace associated with this view
1447 * @return List of traces with data to display
1449 protected @NonNull Iterable
<ITmfTrace
> getTracesToBuild(@NonNull ITmfTrace trace
) {
1450 return TmfTraceManager
.getTraceSet(trace
);
1454 * Build the entries list to show in this time graph
1456 * Called from the BuildThread
1459 * The trace being built
1460 * @param parentTrace
1461 * The parent of the trace set, or the trace itself
1463 * The progress monitor object
1465 protected abstract void buildEventList(@NonNull ITmfTrace trace
, @NonNull ITmfTrace parentTrace
, @NonNull IProgressMonitor monitor
);
1468 * Gets the list of event for an entry in a given timerange
1471 * The entry to get events for
1473 * Start of the time range
1475 * End of the time range
1479 * The progress monitor object
1480 * @return The list of events for the entry
1482 protected abstract @Nullable List
<@NonNull ITimeEvent
> getEventList(@NonNull TimeGraphEntry entry
,
1483 long startTime
, long endTime
, long resolution
,
1484 @NonNull IProgressMonitor monitor
);
1487 * Gets the list of links (displayed as arrows) for a trace in a given
1488 * timerange. Default implementation returns an empty list.
1491 * Start of the time range
1493 * End of the time range
1497 * The progress monitor object
1498 * @return The list of link events
1500 protected @Nullable List
<@NonNull ILinkEvent
> getLinkList(long startTime
, long endTime
,
1501 long resolution
, @NonNull IProgressMonitor monitor
) {
1502 return new ArrayList
<>();
1506 * Gets the list of view-specific marker categories. Default implementation
1507 * returns an empty list.
1509 * @return The list of marker categories
1512 protected @NonNull List
<String
> getViewMarkerCategories() {
1513 return new ArrayList
<>();
1517 * Gets the list of view-specific markers for a trace in a given time range.
1518 * Default implementation returns an empty list.
1521 * Start of the time range
1523 * End of the time range
1527 * The progress monitor object
1528 * @return The list of marker events
1531 protected @NonNull List
<IMarkerEvent
> getViewMarkerList(long startTime
, long endTime
,
1532 long resolution
, @NonNull IProgressMonitor monitor
) {
1533 return new ArrayList
<>();
1537 * Gets the list of trace-specific markers for a trace in a given time range.
1540 * Start of the time range
1542 * End of the time range
1546 * The progress monitor object
1547 * @return The list of marker events
1550 protected @NonNull List
<IMarkerEvent
> getTraceMarkerList(long startTime
, long endTime
,
1551 long resolution
, @NonNull IProgressMonitor monitor
) {
1552 List
<IMarkerEvent
> markers
= new ArrayList
<>();
1553 for (IMarkerEventSource markerEventSource
: getMarkerEventSources(fTrace
)) {
1554 for (String category
: markerEventSource
.getMarkerCategories()) {
1555 if (monitor
.isCanceled()) {
1558 markers
.addAll(markerEventSource
.getMarkerList(checkNotNull(category
), startTime
, endTime
, resolution
, monitor
));
1565 * Get the list of current marker categories.
1567 * @return The list of marker categories
1570 private @NonNull List
<String
> getMarkerCategories() {
1571 Set
<String
> categories
= new HashSet
<>(getViewMarkerCategories());
1572 for (IMarkerEventSource markerEventSource
: getMarkerEventSources(fTrace
)) {
1573 categories
.addAll(markerEventSource
.getMarkerCategories());
1575 return new ArrayList
<>(categories
);
1579 * Gets the list of marker event sources for a given trace.
1583 * @return The list of marker event sources
1586 private @NonNull List
<IMarkerEventSource
> getMarkerEventSources(ITmfTrace trace
) {
1587 List
<IMarkerEventSource
> markerEventSources
= fMarkerEventSourcesMap
.get(trace
);
1588 if (markerEventSources
== null) {
1589 markerEventSources
= checkNotNull(Collections
.<IMarkerEventSource
>emptyList());
1591 return markerEventSources
;
1595 * Refresh the display
1597 protected void refresh() {
1598 final boolean zoomThread
= Thread
.currentThread() instanceof ZoomThread
;
1599 TmfUiRefreshHandler
.getInstance().queueUpdate(this, new Runnable() {
1602 if (fTimeGraphWrapper
.isDisposed()) {
1605 boolean hasEntries
= false;
1606 synchronized (fEntryListMap
) {
1607 fEntryList
= fEntryListMap
.get(fTrace
);
1608 if (fEntryList
== null) {
1609 fEntryList
= new CopyOnWriteArrayList
<>();
1610 } else if (fEntryComparator
!= null) {
1611 List
<TimeGraphEntry
> list
= new ArrayList
<>(fEntryList
);
1612 Collections
.sort(list
, fEntryComparator
);
1613 for (ITimeGraphEntry entry
: list
) {
1614 sortChildren(entry
, fEntryComparator
);
1617 fEntryList
.addAll(list
);
1619 hasEntries
= !fEntryList
.isEmpty();
1621 boolean inputChanged
= fEntryList
!= fTimeGraphWrapper
.getInput();
1623 fTimeGraphWrapper
.setInput(fEntryList
);
1624 /* restore the previously saved filters, if any */
1625 fTimeGraphWrapper
.setFilters(fFiltersMap
.get(fTrace
));
1626 fTimeGraphWrapper
.getTimeGraphViewer().setLinks(null);
1627 fTimeGraphWrapper
.getTimeGraphViewer().setBookmarks(refreshBookmarks(fEditorFile
));
1628 fTimeGraphWrapper
.getTimeGraphViewer().setMarkerCategories(getMarkerCategories());
1629 fTimeGraphWrapper
.getTimeGraphViewer().setMarkers(null);
1631 fTimeGraphWrapper
.refresh();
1633 long startBound
= (fStartTime
== Long
.MAX_VALUE ? SWT
.DEFAULT
: fStartTime
);
1634 long endBound
= (fEndTime
== Long
.MIN_VALUE ? SWT
.DEFAULT
: fEndTime
);
1635 fTimeGraphWrapper
.getTimeGraphViewer().setTimeBounds(startBound
, endBound
);
1637 TmfTraceContext ctx
= TmfTraceManager
.getInstance().getCurrentTraceContext();
1638 long selectionBeginTime
= fTrace
== null ? SWT
.DEFAULT
: ctx
.getSelectionRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1639 long selectionEndTime
= fTrace
== null ? SWT
.DEFAULT
: ctx
.getSelectionRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1640 long startTime
= fTrace
== null ? SWT
.DEFAULT
: ctx
.getWindowRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1641 long endTime
= fTrace
== null ? SWT
.DEFAULT
: ctx
.getWindowRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1642 startTime
= (fStartTime
== Long
.MAX_VALUE ? SWT
.DEFAULT
: Math
.max(startTime
, fStartTime
));
1643 endTime
= (fEndTime
== Long
.MIN_VALUE ? SWT
.DEFAULT
: Math
.min(endTime
, fEndTime
));
1644 fTimeGraphWrapper
.getTimeGraphViewer().setSelectionRange(selectionBeginTime
, selectionEndTime
, false);
1645 fTimeGraphWrapper
.getTimeGraphViewer().setStartFinishTime(startTime
, endTime
);
1647 if (inputChanged
&& selectionBeginTime
!= SWT
.DEFAULT
) {
1648 synchingToTime(selectionBeginTime
);
1651 if (fTimeGraphWrapper
instanceof TimeGraphComboWrapper
&& !fPackDone
) {
1652 for (TreeColumn column
: ((TimeGraphComboWrapper
) fTimeGraphWrapper
).getTreeViewer().getTree().getColumns()) {
1661 startZoomThread(startTime
, endTime
);
1670 protected void redraw() {
1671 synchronized (fSyncObj
) {
1672 if (fRedrawState
== State
.IDLE
) {
1673 fRedrawState
= State
.BUSY
;
1675 fRedrawState
= State
.PENDING
;
1679 Display
.getDefault().asyncExec(new Runnable() {
1682 if (fTimeGraphWrapper
.isDisposed()) {
1685 fTimeGraphWrapper
.redraw();
1686 fTimeGraphWrapper
.update();
1687 synchronized (fSyncObj
) {
1688 if (fRedrawState
== State
.PENDING
) {
1689 fRedrawState
= State
.IDLE
;
1692 fRedrawState
= State
.IDLE
;
1699 private static void sortChildren(ITimeGraphEntry entry
, Comparator
<ITimeGraphEntry
> comparator
) {
1700 if (entry
instanceof TimeGraphEntry
) {
1701 ((TimeGraphEntry
) entry
).sortChildren(comparator
);
1703 for (ITimeGraphEntry child
: entry
.getChildren()) {
1704 sortChildren(child
, comparator
);
1709 * Start or restart the zoom thread.
1712 * the zoom start time
1717 protected void startZoomThread(long startTime
, long endTime
) {
1718 boolean restart
= false;
1719 if (fZoomThread
!= null) {
1720 fZoomThread
.cancel();
1721 if (fZoomThread
.fZoomStartTime
== startTime
&& fZoomThread
.fZoomEndTime
== endTime
) {
1725 long resolution
= Math
.max(1, (endTime
- startTime
) / fDisplayWidth
);
1726 fZoomThread
= createZoomThread(startTime
, endTime
, resolution
, restart
);
1727 if (fZoomThread
!= null) {
1728 fZoomThread
.start();
1733 * Create a zoom thread.
1736 * the zoom start time
1742 * true if restarting zoom for the same time range
1743 * @return a zoom thread
1746 protected @Nullable ZoomThread
createZoomThread(long startTime
, long endTime
, long resolution
, boolean restart
) {
1747 final List
<TimeGraphEntry
> entryList
= fEntryList
;
1748 if (entryList
== null) {
1751 return new ZoomThreadByEntry(entryList
, startTime
, endTime
, resolution
);
1754 private void makeActions() {
1755 fPreviousResourceAction
= fTimeGraphWrapper
.getTimeGraphViewer().getPreviousItemAction();
1756 fPreviousResourceAction
.setText(getPrevText());
1757 fPreviousResourceAction
.setToolTipText(getPrevTooltip());
1758 fNextResourceAction
= fTimeGraphWrapper
.getTimeGraphViewer().getNextItemAction();
1759 fNextResourceAction
.setText(getNextText());
1760 fNextResourceAction
.setToolTipText(getNextTooltip());
1763 private void contributeToActionBars() {
1764 IActionBars bars
= getViewSite().getActionBars();
1765 fillLocalToolBar(bars
.getToolBarManager());
1766 fillLocalMenu(bars
.getMenuManager());
1770 * Add actions to local tool bar manager
1772 * @param manager the tool bar manager
1774 protected void fillLocalToolBar(IToolBarManager manager
) {
1775 if (fFilterColumns
!= null && fFilterLabelProvider
!= null && fFilterColumns
.length
> 0) {
1776 manager
.add(fTimeGraphWrapper
.getShowFilterDialogAction());
1778 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getShowLegendAction());
1779 manager
.add(new Separator());
1780 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getResetScaleAction());
1781 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getPreviousEventAction());
1782 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getNextEventAction());
1783 manager
.add(new Separator());
1784 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getToggleBookmarkAction());
1785 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getPreviousMarkerAction());
1786 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getNextMarkerAction());
1787 manager
.add(new Separator());
1788 manager
.add(fPreviousResourceAction
);
1789 manager
.add(fNextResourceAction
);
1790 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getZoomInAction());
1791 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getZoomOutAction());
1792 manager
.add(new Separator());
1796 * Add actions to local menu manager
1798 * @param manager the tool bar manager
1801 protected void fillLocalMenu(IMenuManager manager
) {
1802 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getMarkersMenu());
1809 public TmfTimeViewAlignmentInfo
getTimeViewAlignmentInfo() {
1810 if (fTimeGraphWrapper
== null) {
1813 return fTimeGraphWrapper
.getTimeViewAlignmentInfo();
1820 public int getAvailableWidth(int requestedOffset
) {
1821 if (fTimeGraphWrapper
== null) {
1824 return fTimeGraphWrapper
.getAvailableWidth(requestedOffset
);
1831 public void performAlign(int offset
, int width
) {
1832 if (fTimeGraphWrapper
!= null) {
1833 fTimeGraphWrapper
.performAlign(offset
, width
);