1 /*******************************************************************************
2 * Copyright (c) 2012, 2014 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
;
26 import java
.util
.concurrent
.CopyOnWriteArrayList
;
28 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
29 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
30 import org
.eclipse
.jface
.action
.Action
;
31 import org
.eclipse
.jface
.action
.IAction
;
32 import org
.eclipse
.jface
.action
.IStatusLineManager
;
33 import org
.eclipse
.jface
.action
.IToolBarManager
;
34 import org
.eclipse
.jface
.action
.Separator
;
35 import org
.eclipse
.jface
.viewers
.ILabelProviderListener
;
36 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
37 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
38 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
39 import org
.eclipse
.jface
.viewers
.TreeViewer
;
40 import org
.eclipse
.jface
.viewers
.Viewer
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfRangeSynchSignal
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimeSynchSignal
;
44 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimestampFormatUpdateSignal
;
45 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceClosedSignal
;
46 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
47 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
48 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
49 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfNanoTimestamp
;
50 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimeRange
;
51 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
52 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTraceManager
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.TmfView
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphContentProvider
;
55 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphRangeListener
;
56 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphSelectionListener
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphTimeListener
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphCombo
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphPresentationProvider
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphRangeUpdateEvent
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphSelectionEvent
;
62 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphTimeEvent
;
63 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.TimeGraphViewer
;
64 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ILinkEvent
;
65 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
66 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
67 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.TimeGraphEntry
;
68 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
69 import org
.eclipse
.swt
.SWT
;
70 import org
.eclipse
.swt
.graphics
.Image
;
71 import org
.eclipse
.swt
.widgets
.Composite
;
72 import org
.eclipse
.swt
.widgets
.Display
;
73 import org
.eclipse
.swt
.widgets
.TreeColumn
;
74 import org
.eclipse
.ui
.IActionBars
;
77 * An abstract view all time graph views can inherit
79 * This view contains either a time graph viewer, or a time graph combo which is
80 * divided between a tree viewer on the left and a time graph viewer on the right.
84 public abstract class AbstractTimeGraphView
extends TmfView
{
93 // ------------------------------------------------------------------------
95 // ------------------------------------------------------------------------
97 /** The timegraph wrapper */
98 private ITimeGraphWrapper fTimeGraphWrapper
;
100 /** The selected trace */
101 private ITmfTrace fTrace
;
103 /** The timegraph entry list */
104 private List
<TimeGraphEntry
> fEntryList
;
106 /** The trace to entry list hash map */
107 private final Map
<ITmfTrace
, List
<TimeGraphEntry
>> fEntryListMap
= new HashMap
<>();
109 /** The trace to build thread hash map */
110 private final Map
<ITmfTrace
, BuildThread
> fBuildThreadMap
= new HashMap
<>();
112 /** The start time */
113 private long fStartTime
;
116 private long fEndTime
;
118 /** The display width */
119 private final int fDisplayWidth
;
121 /** The zoom thread */
122 private ZoomThread fZoomThread
;
124 /** The next resource action */
125 private Action fNextResourceAction
;
127 /** The previous resource action */
128 private Action fPreviousResourceAction
;
130 /** A comparator class */
131 private Comparator
<ITimeGraphEntry
> fEntryComparator
= null;
133 /** The redraw state used to prevent unnecessary queuing of display runnables */
134 private State fRedrawState
= State
.IDLE
;
136 /** The redraw synchronization object */
137 private final Object fSyncObj
= new Object();
139 /** The presentation provider for this view */
140 private final TimeGraphPresentationProvider fPresentation
;
142 /** The tree column label array, or null if combo is not used */
143 private String
[] fColumns
;
145 /** The tree label provider, or null if combo is not used */
146 private TreeLabelProvider fLabelProvider
= null;
148 /** The relative weight of the sash, ignored if combo is not used */
149 private int[] fWeight
= { 1, 1 };
151 /** The filter column label array, or null if filter is not used */
152 private String
[] fFilterColumns
;
154 /** The pack done flag */
155 private boolean fPackDone
= false;
157 /** The filter label provider, or null if filter is not used */
158 private TreeLabelProvider fFilterLabelProvider
;
160 // ------------------------------------------------------------------------
162 // ------------------------------------------------------------------------
164 private interface ITimeGraphWrapper
{
166 void setTimeGraphProvider(TimeGraphPresentationProvider fPresentation
);
168 TimeGraphViewer
getTimeGraphViewer();
170 void addSelectionListener(ITimeGraphSelectionListener iTimeGraphSelectionListener
);
172 ISelectionProvider
getSelectionProvider();
176 boolean isDisposed();
180 void setInput(Object input
);
190 private class TimeGraphViewerWrapper
implements ITimeGraphWrapper
{
191 private TimeGraphViewer viewer
;
193 private TimeGraphViewerWrapper(Composite parent
, int style
) {
194 viewer
= new TimeGraphViewer(parent
, style
);
198 public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider
) {
199 viewer
.setTimeGraphProvider(timeGraphProvider
);
203 public TimeGraphViewer
getTimeGraphViewer() {
208 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
209 viewer
.addSelectionListener(listener
);
213 public ISelectionProvider
getSelectionProvider() {
214 return viewer
.getSelectionProvider();
218 public void setFocus() {
223 public boolean isDisposed() {
224 return viewer
.getControl().isDisposed();
228 public void setInput(Object input
) {
229 viewer
.setInput(input
);
233 public Object
getInput() {
234 return viewer
.getInput();
238 public void refresh() {
243 public void redraw() {
244 viewer
.getControl().redraw();
248 public void update() {
249 viewer
.getControl().update();
253 private class TimeGraphComboWrapper
implements ITimeGraphWrapper
{
254 private TimeGraphCombo combo
;
256 private TimeGraphComboWrapper(Composite parent
, int style
) {
257 combo
= new TimeGraphCombo(parent
, style
, fWeight
);
261 public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider
) {
262 combo
.setTimeGraphProvider(timeGraphProvider
);
266 public TimeGraphViewer
getTimeGraphViewer() {
267 return combo
.getTimeGraphViewer();
271 public void addSelectionListener(ITimeGraphSelectionListener listener
) {
272 combo
.addSelectionListener(listener
);
276 public ISelectionProvider
getSelectionProvider() {
277 return combo
.getTreeViewer();
281 public void setFocus() {
286 public boolean isDisposed() {
287 return combo
.isDisposed();
291 public void setInput(Object input
) {
292 combo
.setInput(input
);
296 public Object
getInput() {
297 return combo
.getInput();
301 public void refresh() {
306 public void redraw() {
311 public void update() {
315 TimeGraphCombo
getTimeGraphCombo() {
319 TreeViewer
getTreeViewer() {
320 return combo
.getTreeViewer();
323 IAction
getShowFilterAction() {
324 return combo
.getShowFilterAction();
328 private class TreeContentProvider
implements ITreeContentProvider
{
331 public void dispose() {
335 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
339 public ITimeGraphEntry
[] getElements(Object inputElement
) {
340 if (inputElement
!= null) {
342 return ((List
<?
>) inputElement
).toArray(new ITimeGraphEntry
[0]);
343 } catch (ClassCastException e
) {
346 return new ITimeGraphEntry
[0];
350 public Object
[] getChildren(Object parentElement
) {
351 ITimeGraphEntry entry
= (ITimeGraphEntry
) parentElement
;
352 List
<?
extends ITimeGraphEntry
> children
= entry
.getChildren();
353 return children
.toArray(new ITimeGraphEntry
[children
.size()]);
357 public Object
getParent(Object element
) {
358 ITimeGraphEntry entry
= (ITimeGraphEntry
) element
;
359 return entry
.getParent();
363 public boolean hasChildren(Object element
) {
364 ITimeGraphEntry entry
= (ITimeGraphEntry
) element
;
365 return entry
.hasChildren();
370 private class TimeGraphContentProvider
implements ITimeGraphContentProvider
{
373 public ITimeGraphEntry
[] getElements(Object inputElement
) {
374 if (inputElement
!= null) {
376 return ((List
<?
>) inputElement
).toArray(new ITimeGraphEntry
[0]);
377 } catch (ClassCastException e
) {
380 return new ITimeGraphEntry
[0];
386 * Base class to provide the labels for the tree viewer. Views extending
387 * this class typically need to override the getColumnText method if they
388 * have more than one column to display
390 protected static class TreeLabelProvider
implements ITableLabelProvider
{
393 public void addListener(ILabelProviderListener listener
) {
397 public void dispose() {
401 public boolean isLabelProperty(Object element
, String property
) {
406 public void removeListener(ILabelProviderListener listener
) {
410 public Image
getColumnImage(Object element
, int columnIndex
) {
415 public String
getColumnText(Object element
, int columnIndex
) {
416 TimeGraphEntry entry
= (TimeGraphEntry
) element
;
417 if (columnIndex
== 0) {
418 return entry
.getName();
425 private class BuildThread
extends Thread
{
426 private final ITmfTrace fBuildTrace
;
427 private final ITmfTrace fParentTrace
;
428 private final IProgressMonitor fMonitor
;
430 public BuildThread(final ITmfTrace trace
, final ITmfTrace parentTrace
, final String name
) {
431 super(name
+ " build"); //$NON-NLS-1$
433 fParentTrace
= parentTrace
;
434 fMonitor
= new NullProgressMonitor();
439 buildEventList(fBuildTrace
, fParentTrace
, fMonitor
);
440 synchronized (fBuildThreadMap
) {
441 fBuildThreadMap
.remove(fBuildTrace
);
445 public void cancel() {
446 fMonitor
.setCanceled(true);
450 private class ZoomThread
extends Thread
{
451 private final List
<TimeGraphEntry
> fZoomEntryList
;
452 private final long fZoomStartTime
;
453 private final long fZoomEndTime
;
454 private final long fResolution
;
455 private final IProgressMonitor fMonitor
;
457 public ZoomThread(List
<TimeGraphEntry
> entryList
, long startTime
, long endTime
, String name
) {
458 super(name
+ " zoom"); //$NON-NLS-1$
459 fZoomEntryList
= entryList
;
460 fZoomStartTime
= startTime
;
461 fZoomEndTime
= endTime
;
462 fResolution
= Math
.max(1, (fZoomEndTime
- fZoomStartTime
) / fDisplayWidth
);
463 fMonitor
= new NullProgressMonitor();
468 if (fZoomEntryList
== null) {
471 for (TimeGraphEntry entry
: fZoomEntryList
) {
472 if (fMonitor
.isCanceled()) {
475 zoom(entry
, fMonitor
);
477 /* Refresh the arrows when zooming */
478 List
<ILinkEvent
> events
= getLinkList(fZoomStartTime
, fZoomEndTime
, fResolution
, fMonitor
);
479 if (events
!= null) {
480 fTimeGraphWrapper
.getTimeGraphViewer().setLinks(events
);
485 private void zoom(TimeGraphEntry entry
, IProgressMonitor monitor
) {
486 if (fZoomStartTime
<= fStartTime
&& fZoomEndTime
>= fEndTime
) {
487 entry
.setZoomedEventList(null);
489 List
<ITimeEvent
> zoomedEventList
= getEventList(entry
, fZoomStartTime
, fZoomEndTime
, fResolution
, monitor
);
490 if (zoomedEventList
!= null) {
491 entry
.setZoomedEventList(zoomedEventList
);
495 for (TimeGraphEntry child
: entry
.getChildren()) {
496 if (fMonitor
.isCanceled()) {
499 zoom(child
, monitor
);
503 public void cancel() {
504 fMonitor
.setCanceled(true);
508 // ------------------------------------------------------------------------
510 // ------------------------------------------------------------------------
513 * Constructs a time graph view that contains either a time graph viewer or
514 * a time graph combo.
516 * By default, the view uses a time graph viewer. To use a time graph combo,
517 * the subclass constructor must call {@link #setTreeColumns(String[])} and
518 * {@link #setTreeLabelProvider(TreeLabelProvider)}.
523 * The presentation provider
525 public AbstractTimeGraphView(String id
, TimeGraphPresentationProvider pres
) {
527 fPresentation
= pres
;
528 fDisplayWidth
= Display
.getDefault().getBounds().width
;
531 // ------------------------------------------------------------------------
532 // Getters and setters
533 // ------------------------------------------------------------------------
536 * Getter for the time graph combo
538 * @return The time graph combo, or null if combo is not used
540 protected TimeGraphCombo
getTimeGraphCombo() {
541 if (fTimeGraphWrapper
instanceof TimeGraphComboWrapper
) {
542 return ((TimeGraphComboWrapper
) fTimeGraphWrapper
).getTimeGraphCombo();
548 * Getter for the time graph viewer
550 * @return The time graph viewer
552 protected TimeGraphViewer
getTimeGraphViewer() {
553 return fTimeGraphWrapper
.getTimeGraphViewer();
557 * Sets the tree column labels.
558 * This should be called from the constructor.
561 * The array of tree column labels
563 protected void setTreeColumns(final String
[] columns
) {
568 * Sets the tree label provider.
569 * This should be called from the constructor.
572 * The tree label provider
574 protected void setTreeLabelProvider(final TreeLabelProvider tlp
) {
575 fLabelProvider
= tlp
;
579 * Sets the relative weight of each part of the time graph combo.
580 * This should be called from the constructor.
583 * The array (length 2) of relative weights of each part of the combo
585 protected void setWeight(final int[] weights
) {
590 * Sets the filter column labels.
591 * This should be called from the constructor.
593 * @param filterColumns
594 * The array of filter column labels
596 protected void setFilterColumns(final String
[] filterColumns
) {
597 fFilterColumns
= filterColumns
;
601 * Sets the filter label provider.
602 * This should be called from the constructor.
604 * @param labelProvider
605 * The filter label provider
609 protected void setFilterLabelProvider(final TreeLabelProvider labelProvider
) {
610 fFilterLabelProvider
= labelProvider
;
614 * Gets the display width
616 * @return the display width
618 protected int getDisplayWidth() {
619 return fDisplayWidth
;
623 * Gets the comparator for the entries
625 * @return The entry comparator
627 protected Comparator
<ITimeGraphEntry
> getEntryComparator() {
628 return fEntryComparator
;
632 * Sets the comparator class for the entries
635 * A comparator object
637 protected void setEntryComparator(final Comparator
<ITimeGraphEntry
> comparator
) {
638 fEntryComparator
= comparator
;
642 * Gets the trace displayed in the view
646 protected ITmfTrace
getTrace() {
651 * Gets the start time
653 * @return The start time
655 protected long getStartTime() {
660 * Sets the start time
665 protected void setStartTime(long time
) {
672 * @return The end time
674 protected long getEndTime() {
684 protected void setEndTime(long time
) {
689 * Gets the entry list for a trace
694 * @return the entry list map
697 protected List
<TimeGraphEntry
> getEntryList(ITmfTrace trace
) {
698 synchronized (fEntryListMap
) {
699 return fEntryListMap
.get(trace
);
704 * Adds a trace entry list to the entry list map
709 * the list of time graph entries
711 protected void putEntryList(ITmfTrace trace
, List
<TimeGraphEntry
> list
) {
712 synchronized (fEntryListMap
) {
713 fEntryListMap
.put(trace
, new CopyOnWriteArrayList
<>(list
));
718 * Adds a list of entries to a trace's entry list
723 * the list of time graph entries to add
726 protected void addToEntryList(ITmfTrace trace
, List
<TimeGraphEntry
> list
) {
727 synchronized (fEntryListMap
) {
728 List
<TimeGraphEntry
> entryList
= fEntryListMap
.get(trace
);
729 if (entryList
== null) {
730 fEntryListMap
.put(trace
, new CopyOnWriteArrayList
<>(list
));
732 entryList
.addAll(list
);
738 * Removes a list of entries from a trace's entry list
743 * the list of time graph entries to remove
746 protected void removeFromEntryList(ITmfTrace trace
, List
<TimeGraphEntry
> list
) {
747 synchronized (fEntryListMap
) {
748 List
<TimeGraphEntry
> entryList
= fEntryListMap
.get(trace
);
749 if (entryList
!= null) {
750 entryList
.removeAll(list
);
756 * Text for the "next" button
758 * @return The "next" button text
760 protected String
getNextText() {
761 return Messages
.AbstractTimeGraphtView_NextText
;
765 * Tooltip for the "next" button
767 * @return Tooltip for the "next" button
769 protected String
getNextTooltip() {
770 return Messages
.AbstractTimeGraphView_NextTooltip
;
774 * Text for the "Previous" button
776 * @return The "Previous" button text
778 protected String
getPrevText() {
779 return Messages
.AbstractTimeGraphView_PreviousText
;
783 * Tooltip for the "previous" button
785 * @return Tooltip for the "previous" button
787 protected String
getPrevTooltip() {
788 return Messages
.AbstractTimeGraphView_PreviousTooltip
;
791 // ------------------------------------------------------------------------
793 // ------------------------------------------------------------------------
796 public void createPartControl(Composite parent
) {
797 if (fColumns
== null || fLabelProvider
== null) {
798 fTimeGraphWrapper
= new TimeGraphViewerWrapper(parent
, SWT
.NONE
);
799 TimeGraphViewer viewer
= fTimeGraphWrapper
.getTimeGraphViewer();
800 viewer
.setTimeGraphContentProvider(new TimeGraphContentProvider());
802 TimeGraphComboWrapper wrapper
= new TimeGraphComboWrapper(parent
, SWT
.NONE
);
803 fTimeGraphWrapper
= wrapper
;
804 TimeGraphCombo combo
= wrapper
.getTimeGraphCombo();
805 combo
.setTreeContentProvider(new TreeContentProvider());
806 combo
.setTreeLabelProvider(fLabelProvider
);
807 combo
.setTreeColumns(fColumns
);
808 combo
.setFilterContentProvider(new TreeContentProvider());
809 combo
.setFilterLabelProvider(fFilterLabelProvider
);
810 combo
.setFilterColumns(fFilterColumns
);
811 combo
.setTimeGraphContentProvider(new TimeGraphContentProvider());
814 fTimeGraphWrapper
.setTimeGraphProvider(fPresentation
);
816 fTimeGraphWrapper
.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
818 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event
) {
819 final long startTime
= event
.getStartTime();
820 final long endTime
= event
.getEndTime();
821 TmfTimeRange range
= new TmfTimeRange(new TmfNanoTimestamp(startTime
), new TmfNanoTimestamp(endTime
));
822 broadcast(new TmfRangeSynchSignal(AbstractTimeGraphView
.this, range
));
823 if (fZoomThread
!= null) {
824 fZoomThread
.cancel();
826 startZoomThread(startTime
, endTime
);
830 fTimeGraphWrapper
.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
832 public void timeSelected(TimeGraphTimeEvent event
) {
833 TmfNanoTimestamp startTime
= new TmfNanoTimestamp(event
.getBeginTime());
834 TmfNanoTimestamp endTime
= new TmfNanoTimestamp(event
.getEndTime());
835 broadcast(new TmfTimeSynchSignal(AbstractTimeGraphView
.this, startTime
, endTime
));
839 fTimeGraphWrapper
.addSelectionListener(new ITimeGraphSelectionListener() {
841 public void selectionChanged(TimeGraphSelectionEvent event
) {
842 // ITimeGraphEntry selection = event.getSelection();
846 fTimeGraphWrapper
.getTimeGraphViewer().setTimeFormat(TimeFormat
.CALENDAR
);
848 IStatusLineManager statusLineManager
= getViewSite().getActionBars().getStatusLineManager();
849 fTimeGraphWrapper
.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager
);
851 // View Action Handling
853 contributeToActionBars();
855 ITmfTrace trace
= getActiveTrace();
857 traceSelected(new TmfTraceSelectedSignal(this, trace
));
860 // make selection available to other views
861 getSite().setSelectionProvider(fTimeGraphWrapper
.getSelectionProvider());
865 public void setFocus() {
866 fTimeGraphWrapper
.setFocus();
869 // ------------------------------------------------------------------------
871 // ------------------------------------------------------------------------
874 * Handler for the trace opened signal.
877 * The incoming signal
881 public void traceOpened(TmfTraceOpenedSignal signal
) {
882 fTrace
= signal
.getTrace();
887 * Handler for the trace selected signal
890 * The incoming signal
893 public void traceSelected(final TmfTraceSelectedSignal signal
) {
894 if (signal
.getTrace() == fTrace
) {
897 fTrace
= signal
.getTrace();
903 * Trace is closed: clear the data structures and the view
906 * the signal received
909 public void traceClosed(final TmfTraceClosedSignal signal
) {
910 synchronized (fBuildThreadMap
) {
911 for (ITmfTrace trace
: getTracesToBuild(signal
.getTrace())) {
912 BuildThread buildThread
= fBuildThreadMap
.remove(trace
);
913 if (buildThread
!= null) {
914 buildThread
.cancel();
918 synchronized (fEntryListMap
) {
919 fEntryListMap
.remove(signal
.getTrace());
921 if (signal
.getTrace() == fTrace
) {
925 if (fZoomThread
!= null) {
926 fZoomThread
.cancel();
933 * Handler for the time synch signal
936 * The signal that's received
939 public void synchToTime(final TmfTimeSynchSignal signal
) {
940 if (signal
.getSource() == this || fTrace
== null) {
943 final long beginTime
= signal
.getBeginTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
944 final long endTime
= signal
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
946 Display
.getDefault().asyncExec(new Runnable() {
949 if (fTimeGraphWrapper
.isDisposed()) {
952 if (beginTime
== endTime
) {
953 fTimeGraphWrapper
.getTimeGraphViewer().setSelectedTime(beginTime
, true);
955 fTimeGraphWrapper
.getTimeGraphViewer().setSelectionRange(beginTime
, endTime
);
957 startZoomThread(fTimeGraphWrapper
.getTimeGraphViewer().getTime0(), fTimeGraphWrapper
.getTimeGraphViewer().getTime1());
959 synchingToTime(beginTime
);
965 * Handler for the range synch signal
968 * The signal that's received
971 public void synchToRange(final TmfRangeSynchSignal signal
) {
972 if (signal
.getSource() == this || fTrace
== null) {
975 if (signal
.getCurrentRange().getIntersection(fTrace
.getTimeRange()) == null) {
978 final long startTime
= signal
.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
979 final long endTime
= signal
.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
980 Display
.getDefault().asyncExec(new Runnable() {
983 if (fTimeGraphWrapper
.isDisposed()) {
986 fTimeGraphWrapper
.getTimeGraphViewer().setStartFinishTime(startTime
, endTime
);
987 startZoomThread(startTime
, endTime
);
993 * @param signal the format of the timestamps was updated.
997 public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal
){
998 fTimeGraphWrapper
.refresh();
1001 // ------------------------------------------------------------------------
1003 // ------------------------------------------------------------------------
1005 private void loadTrace() {
1006 synchronized (fEntryListMap
) {
1007 fEntryList
= fEntryListMap
.get(fTrace
);
1008 if (fEntryList
== null) {
1009 setStartTime(Long
.MAX_VALUE
);
1010 setEndTime(Long
.MIN_VALUE
);
1011 synchronized (fBuildThreadMap
) {
1012 for (ITmfTrace trace
: getTracesToBuild(fTrace
)) {
1013 BuildThread buildThread
= new BuildThread(trace
, fTrace
, getName());
1014 fBuildThreadMap
.put(trace
, buildThread
);
1015 buildThread
.start();
1019 fStartTime
= fTrace
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1020 fEndTime
= fTrace
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1027 * Method called when synching to a given timestamp. Inheriting classes can
1028 * perform actions here to update the view at the given timestamp.
1031 * The currently selected time
1033 protected void synchingToTime(long time
) {
1038 * Return the list of traces whose data or analysis results will be used to
1039 * populate the view. By default, if the trace is an experiment, the traces
1040 * under it will be returned, otherwise, the trace itself is returned.
1042 * A build thread will be started for each trace returned by this method,
1043 * some of which may receive events in live streaming mode.
1046 * The trace associated with this view
1047 * @return List of traces with data to display
1050 protected Iterable
<ITmfTrace
> getTracesToBuild(ITmfTrace trace
) {
1051 return Arrays
.asList(TmfTraceManager
.getTraceSet(trace
));
1055 * Build the entries list to show in this time graph
1057 * Called from the BuildThread
1060 * The trace being built
1061 * @param parentTrace
1062 * The parent of the trace set, or the trace itself
1064 * The progress monitor object
1067 protected abstract void buildEventList(ITmfTrace trace
, ITmfTrace parentTrace
, IProgressMonitor monitor
);
1070 * Gets the list of event for an entry in a given timerange
1073 * The entry to get events for
1075 * Start of the time range
1077 * End of the time range
1081 * The progress monitor object
1082 * @return The list of events for the entry
1084 protected abstract List
<ITimeEvent
> getEventList(TimeGraphEntry entry
,
1085 long startTime
, long endTime
, long resolution
,
1086 IProgressMonitor monitor
);
1089 * Gets the list of links (displayed as arrows) for a trace in a given
1090 * timerange. Default implementation returns an empty list.
1093 * Start of the time range
1095 * End of the time range
1099 * The progress monitor object
1100 * @return The list of link events
1103 protected List
<ILinkEvent
> getLinkList(long startTime
, long endTime
,
1104 long resolution
, IProgressMonitor monitor
) {
1105 return new ArrayList
<>();
1110 * Refresh the display
1112 protected void refresh() {
1113 Display
.getDefault().asyncExec(new Runnable() {
1116 if (fTimeGraphWrapper
.isDisposed()) {
1119 boolean hasEntries
= false;
1120 synchronized (fEntryListMap
) {
1121 fEntryList
= fEntryListMap
.get(fTrace
);
1122 if (fEntryList
== null) {
1123 fEntryList
= new CopyOnWriteArrayList
<>();
1124 } else if (fEntryComparator
!= null) {
1125 List
<TimeGraphEntry
> list
= new ArrayList
<>(fEntryList
);
1126 Collections
.sort(list
, fEntryComparator
);
1128 fEntryList
.addAll(list
);
1130 hasEntries
= fEntryList
.size() != 0;
1132 if (fEntryList
!= fTimeGraphWrapper
.getInput()) {
1133 fTimeGraphWrapper
.setInput(fEntryList
);
1135 fTimeGraphWrapper
.refresh();
1137 fTimeGraphWrapper
.getTimeGraphViewer().setTimeBounds(fStartTime
, fEndTime
);
1139 long selectionBeginTime
= fTrace
== null ?
0 : fTraceManager
.getSelectionBeginTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1140 long selectionEndTime
= fTrace
== null ?
0 : fTraceManager
.getSelectionEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1141 long startTime
= fTrace
== null ?
0 : fTraceManager
.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1142 long endTime
= fTrace
== null ?
0 : fTraceManager
.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
1143 startTime
= Math
.max(startTime
, fStartTime
);
1144 endTime
= Math
.min(endTime
, fEndTime
);
1145 fTimeGraphWrapper
.getTimeGraphViewer().setSelectionRange(selectionBeginTime
, selectionEndTime
);
1146 fTimeGraphWrapper
.getTimeGraphViewer().setStartFinishTime(startTime
, endTime
);
1148 if (fTimeGraphWrapper
instanceof TimeGraphComboWrapper
&& !fPackDone
) {
1149 for (TreeColumn column
: ((TimeGraphComboWrapper
) fTimeGraphWrapper
).getTreeViewer().getTree().getColumns()) {
1157 startZoomThread(startTime
, endTime
);
1165 protected void redraw() {
1166 synchronized (fSyncObj
) {
1167 if (fRedrawState
== State
.IDLE
) {
1168 fRedrawState
= State
.BUSY
;
1170 fRedrawState
= State
.PENDING
;
1174 Display
.getDefault().asyncExec(new Runnable() {
1177 if (fTimeGraphWrapper
.isDisposed()) {
1180 fTimeGraphWrapper
.redraw();
1181 fTimeGraphWrapper
.update();
1182 synchronized (fSyncObj
) {
1183 if (fRedrawState
== State
.PENDING
) {
1184 fRedrawState
= State
.IDLE
;
1187 fRedrawState
= State
.IDLE
;
1194 private void startZoomThread(long startTime
, long endTime
) {
1195 if (fZoomThread
!= null) {
1196 fZoomThread
.cancel();
1198 fZoomThread
= new ZoomThread(fEntryList
, startTime
, endTime
, getName());
1199 fZoomThread
.start();
1202 private void makeActions() {
1203 fPreviousResourceAction
= fTimeGraphWrapper
.getTimeGraphViewer().getPreviousItemAction();
1204 fPreviousResourceAction
.setText(getPrevText());
1205 fPreviousResourceAction
.setToolTipText(getPrevTooltip());
1206 fNextResourceAction
= fTimeGraphWrapper
.getTimeGraphViewer().getNextItemAction();
1207 fNextResourceAction
.setText(getNextText());
1208 fNextResourceAction
.setToolTipText(getNextTooltip());
1211 private void contributeToActionBars() {
1212 IActionBars bars
= getViewSite().getActionBars();
1213 fillLocalToolBar(bars
.getToolBarManager());
1217 * Add actions to local tool bar manager
1219 * @param manager the tool bar manager
1221 protected void fillLocalToolBar(IToolBarManager manager
) {
1222 if (fTimeGraphWrapper
instanceof TimeGraphComboWrapper
) {
1223 if (fFilterColumns
!= null && fFilterLabelProvider
!= null && fFilterColumns
.length
> 0) {
1224 manager
.add(((TimeGraphComboWrapper
) fTimeGraphWrapper
).getShowFilterAction());
1227 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getShowLegendAction());
1228 manager
.add(new Separator());
1229 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getResetScaleAction());
1230 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getPreviousEventAction());
1231 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getNextEventAction());
1232 manager
.add(fPreviousResourceAction
);
1233 manager
.add(fNextResourceAction
);
1234 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getZoomInAction());
1235 manager
.add(fTimeGraphWrapper
.getTimeGraphViewer().getZoomOutAction());
1236 manager
.add(new Separator());