/*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson, École Polytechnique de Montréal
+ * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* Patrick Tasse - Initial API and implementation
* Bernd Hufmann - Updated signal handling
* Geneviève Bastien - Move code to provide base classes for time graph view
+ * Marc-Andre Laperle - Add time zone preference
+ * Geneviève Bastien - Add event links between entries
*******************************************************************************/
package org.eclipse.linuxtools.tmf.ui.views.timegraph;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTimestamp;
import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
+import org.eclipse.linuxtools.tmf.ui.TmfUiRefreshHandler;
import org.eclipse.linuxtools.tmf.ui.views.TmfView;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphContentProvider;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
/**
* An abstract view all time graph views can inherit
*
- * This view contains a time graph combo, divided between a treeview on the
- * left, showing entries and a canvas on the right to draw something for these
- * entries.
+ * This view contains either a time graph viewer, or a time graph combo which is
+ * divided between a tree viewer on the left and a time graph viewer on the right.
*
- * @since 3.0
+ * @since 2.1
*/
public abstract class AbstractTimeGraphView extends TmfView {
- private final String[] fColumns;
- private final String[] fFilterColumns;
-
/**
* Redraw state enum
*/
// Fields
// ------------------------------------------------------------------------
- /** The timegraph combo */
- private TimeGraphCombo fTimeGraphCombo;
+ /** The timegraph wrapper */
+ private ITimeGraphWrapper fTimeGraphWrapper;
/** The selected trace */
private ITmfTrace fTrace;
private List<TimeGraphEntry> fEntryList;
/** The trace to entry list hash map */
- private final Map<ITmfTrace, List<TimeGraphEntry>> fEntryListMap = new HashMap<ITmfTrace, List<TimeGraphEntry>>();
+ private final Map<ITmfTrace, List<TimeGraphEntry>> fEntryListMap = new HashMap<>();
- /* The trace to build thread hash map */
- private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<ITmfTrace, BuildThread>();
+ /** The trace to build thread hash map */
+ private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<>();
/** The start time */
private long fStartTime;
/** The previous resource action */
private Action fPreviousResourceAction;
- /** The relative weight of the sash */
- private int[] fWeight = { 1, 1 };
-
/** A comparator class */
private Comparator<ITimeGraphEntry> fEntryComparator = null;
- /** The redraw state used to prevent unnecessary queuing of display runnables */
+ /** The redraw state used to prevent unnecessary queuing of display runnables */
private State fRedrawState = State.IDLE;
/** The redraw synchronization object */
/** The presentation provider for this view */
private final TimeGraphPresentationProvider fPresentation;
- private TreeLabelProvider fLabelProvider = new TreeLabelProvider();
+ /** The tree column label array, or null if combo is not used */
+ private String[] fColumns;
+
+ /** The tree label provider, or null if combo is not used */
+ private TreeLabelProvider fLabelProvider = null;
+
+ /** The relative weight of the sash, ignored if combo is not used */
+ private int[] fWeight = { 1, 1 };
+
+ /** The filter column label array, or null if filter is not used */
+ private String[] fFilterColumns;
+
+ /** The pack done flag */
+ private boolean fPackDone = false;
+
+ /** The filter label provider, or null if filter is not used */
+ private TreeLabelProvider fFilterLabelProvider;
// ------------------------------------------------------------------------
- // Getters and setters
+ // Classes
// ------------------------------------------------------------------------
- /**
- * Getter for the time graph combo
- *
- * @return The Time graph combo
- */
- protected TimeGraphCombo getTimeGraphCombo() {
- return fTimeGraphCombo;
- }
+ private interface ITimeGraphWrapper {
- /**
- * Sets the tree label provider
- *
- * @param tlp
- * The tree label provider
- */
- protected void setTreeLabelProvider(final TreeLabelProvider tlp) {
- fLabelProvider = tlp;
- }
+ void setTimeGraphProvider(TimeGraphPresentationProvider fPresentation);
- /**
- * Sets the relative weight of each part of the time graph combo
- *
- * @param weights
- * The array of relative weights of each part of the combo
- */
- protected void setWeight(final int[] weights) {
- fWeight = weights;
- }
+ TimeGraphViewer getTimeGraphViewer();
- /**
- * Gets the display width
- *
- * @return the display width
- */
- protected int getDisplayWidth() {
- return fDisplayWidth;
- }
+ void addSelectionListener(ITimeGraphSelectionListener iTimeGraphSelectionListener);
- /**
- * Gets the comparator for the entries
- *
- * @return The entry comparator
- */
- protected Comparator<ITimeGraphEntry> getEntryComparator() {
- return fEntryComparator;
- }
+ ISelectionProvider getSelectionProvider();
- /**
- * Sets the comparator class for the entries * Gets the display width
- *
- * @param comparator
- * A comparator object
- */
- protected void setEntryComparator(final Comparator<ITimeGraphEntry> comparator) {
- fEntryComparator = comparator;
- }
+ void setFocus();
- /**
- * Gets the trace displayed in the view
- *
- * @return The trace
- */
- protected ITmfTrace getTrace() {
- return fTrace;
- }
+ boolean isDisposed();
- /**
- * Sets the trace to display
- *
- * @param trace
- * The trace
- */
- protected void setTrace(final ITmfTrace trace) {
- fTrace = trace;
- }
+ void refresh();
- /**
- * Gets the start time
- *
- * @return The start time
- */
- protected long getStartTime() {
- return fStartTime;
- }
+ void setInput(Object input);
- /**
- * Sets the start time
- *
- * @param time
- * The start time
- */
- protected void setStartTime(long time) {
- fStartTime = time;
- }
+ Object getInput();
- /**
- * Gets the end time
- *
- * @return The end time
- */
- protected long getEndTime() {
- return fEndTime;
- }
+ void redraw();
- /**
- * Sets the end time
- *
- * @param time
- * The end time
- */
- protected void setEndTime(long time) {
- fEndTime = time;
- }
+ void update();
- /**
- * Gets the entry list map
- *
- * @return the entry list map
- */
- protected Map<ITmfTrace, List<TimeGraphEntry>> getEntryListMap() {
- return Collections.unmodifiableMap(fEntryListMap);
}
- /**
- * Adds an entry to the entry list
- *
- * @param trace
- * the trace to add
- * @param list
- * The list of time graph entries
- */
- protected void putEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
- synchronized(fEntryListMap) {
- fEntryListMap.put(trace, list);
+ private class TimeGraphViewerWrapper implements ITimeGraphWrapper {
+ private TimeGraphViewer viewer;
+
+ private TimeGraphViewerWrapper(Composite parent, int style) {
+ viewer = new TimeGraphViewer(parent, style);
}
- }
- /**
- * Text for the "next" button
- *
- * @return The "next" button text
- */
- protected String getNextText() {
- return Messages.AbstractTimeGraphtView_NextText;
- }
+ @Override
+ public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) {
+ viewer.setTimeGraphProvider(timeGraphProvider);
+ }
- /**
- * Tooltip for the "next" button
- *
- * @return Tooltip for the "next" button
- */
- protected String getNextTooltip() {
- return Messages.AbstractTimeGraphView_NextTooltip;
- }
+ @Override
+ public TimeGraphViewer getTimeGraphViewer() {
+ return viewer;
+ }
- /**
- * Text for the "Previous" button
- *
- * @return The "Previous" button text
- */
- protected String getPrevText() {
- return Messages.AbstractTimeGraphView_PreviousText;
- }
+ @Override
+ public void addSelectionListener(ITimeGraphSelectionListener listener) {
+ viewer.addSelectionListener(listener);
+ }
- /**
- * Tooltip for the "previous" button
- *
- * @return Tooltip for the "previous" button
- */
- protected String getPrevTooltip() {
- return Messages.AbstractTimeGraphView_PreviousTooltip;
+ @Override
+ public ISelectionProvider getSelectionProvider() {
+ return viewer.getSelectionProvider();
+ }
+
+ @Override
+ public void setFocus() {
+ viewer.setFocus();
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return viewer.getControl().isDisposed();
+ }
+
+ @Override
+ public void setInput(Object input) {
+ viewer.setInput(input);
+ }
+
+ @Override
+ public Object getInput() {
+ return viewer.getInput();
+ }
+
+ @Override
+ public void refresh() {
+ viewer.refresh();
+ }
+
+ @Override
+ public void redraw() {
+ viewer.getControl().redraw();
+ }
+
+ @Override
+ public void update() {
+ viewer.getControl().update();
+ }
}
- // ------------------------------------------------------------------------
- // Classes
- // ------------------------------------------------------------------------
+ private class TimeGraphComboWrapper implements ITimeGraphWrapper {
+ private TimeGraphCombo combo;
+
+ private TimeGraphComboWrapper(Composite parent, int style) {
+ combo = new TimeGraphCombo(parent, style, fWeight);
+ }
+
+ @Override
+ public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) {
+ combo.setTimeGraphProvider(timeGraphProvider);
+ }
+
+ @Override
+ public TimeGraphViewer getTimeGraphViewer() {
+ return combo.getTimeGraphViewer();
+ }
+
+ @Override
+ public void addSelectionListener(ITimeGraphSelectionListener listener) {
+ combo.addSelectionListener(listener);
+ }
+
+ @Override
+ public ISelectionProvider getSelectionProvider() {
+ return combo.getTreeViewer();
+ }
+
+ @Override
+ public void setFocus() {
+ combo.setFocus();
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return combo.isDisposed();
+ }
+
+ @Override
+ public void setInput(Object input) {
+ combo.setInput(input);
+ }
+
+ @Override
+ public Object getInput() {
+ return combo.getInput();
+ }
+
+ @Override
+ public void refresh() {
+ combo.refresh();
+ }
+
+ @Override
+ public void redraw() {
+ combo.redraw();
+ }
+
+ @Override
+ public void update() {
+ combo.update();
+ }
+
+ TimeGraphCombo getTimeGraphCombo() {
+ return combo;
+ }
+
+ TreeViewer getTreeViewer() {
+ return combo.getTreeViewer();
+ }
+
+ IAction getShowFilterAction() {
+ return combo.getShowFilterAction();
+ }
+ }
private class TreeContentProvider implements ITreeContentProvider {
}
@Override
- public Object[] getElements(Object inputElement) {
- return (ITimeGraphEntry[]) inputElement;
+ public ITimeGraphEntry[] getElements(Object inputElement) {
+ if (inputElement != null) {
+ try {
+ return ((List<?>) inputElement).toArray(new ITimeGraphEntry[0]);
+ } catch (ClassCastException e) {
+ }
+ }
+ return new ITimeGraphEntry[0];
}
@Override
}
+ private class TimeGraphContentProvider implements ITimeGraphContentProvider {
+
+ @Override
+ public ITimeGraphEntry[] getElements(Object inputElement) {
+ if (inputElement != null) {
+ try {
+ return ((List<?>) inputElement).toArray(new ITimeGraphEntry[0]);
+ } catch (ClassCastException e) {
+ }
+ }
+ return new ITimeGraphEntry[0];
+ }
+
+ }
+
/**
- * Base class to provide the labels for the left tree view entry. Views
- * extending this class typically need to override the getColumnText method
- * if they have more than one column to display
+ * Base class to provide the labels for the tree viewer. Views extending
+ * this class typically need to override the getColumnText method if they
+ * have more than one column to display
*/
- protected static class TreeLabelProvider implements ITableLabelProvider {
+ protected static class TreeLabelProvider implements ITableLabelProvider, ILabelProvider {
@Override
public void addListener(ILabelProviderListener listener) {
if (columnIndex == 0) {
return entry.getName();
}
- return ""; //$NON-NLS-1$
+ return new String();
+ }
+
+ /**
+ * @since 3.2
+ */
+ @Override
+ public Image getImage(Object element) {
+ return null;
+ }
+
+ /**
+ * @since 3.2
+ */
+ @Override
+ public String getText(Object element) {
+ TimeGraphEntry entry = (TimeGraphEntry) element;
+ return entry.getName();
}
}
private class BuildThread extends Thread {
private final ITmfTrace fBuildTrace;
+ private final ITmfTrace fParentTrace;
private final IProgressMonitor fMonitor;
- public BuildThread(final ITmfTrace trace, final String name) {
+ public BuildThread(final ITmfTrace trace, final ITmfTrace parentTrace, final String name) {
super(name + " build"); //$NON-NLS-1$
fBuildTrace = trace;
+ fParentTrace = parentTrace;
fMonitor = new NullProgressMonitor();
}
@Override
public void run() {
- buildEventList(fBuildTrace, fMonitor);
+ buildEventList(fBuildTrace, fParentTrace, fMonitor);
synchronized (fBuildThreadMap) {
- fBuildThreadMap.remove(this);
+ fBuildThreadMap.remove(fBuildTrace);
}
}
}
for (TimeGraphEntry entry : fZoomEntryList) {
if (fMonitor.isCanceled()) {
- break;
+ return;
}
zoom(entry, fMonitor);
}
+ /* Refresh the arrows when zooming */
+ List<ILinkEvent> events = getLinkList(fZoomStartTime, fZoomEndTime, fResolution, fMonitor);
+ if (events != null) {
+ fTimeGraphWrapper.getTimeGraphViewer().setLinks(events);
+ redraw();
+ }
}
private void zoom(TimeGraphEntry entry, IProgressMonitor monitor) {
}
}
redraw();
- for (TimeGraphEntry child : entry.getChildren()) {
+ for (ITimeGraphEntry child : entry.getChildren()) {
if (fMonitor.isCanceled()) {
return;
}
- zoom(child, monitor);
+ if (child instanceof TimeGraphEntry) {
+ zoom((TimeGraphEntry) child, monitor);
+ }
}
}
// ------------------------------------------------------------------------
/**
- * Constructor
+ * Constructs a time graph view that contains either a time graph viewer or
+ * a time graph combo.
+ *
+ * By default, the view uses a time graph viewer. To use a time graph combo,
+ * the subclass constructor must call {@link #setTreeColumns(String[])} and
+ * {@link #setTreeLabelProvider(TreeLabelProvider)}.
*
* @param id
* The id of the view
- * @param cols
- * The columns to display in the tree view on the left
- * @param filterCols
- * The columns list to filter the view
* @param pres
* The presentation provider
*/
- public AbstractTimeGraphView(String id, String[] cols, String[] filterCols,
- TimeGraphPresentationProvider pres) {
+ public AbstractTimeGraphView(String id, TimeGraphPresentationProvider pres) {
super(id);
- fColumns = cols;
- fFilterColumns = filterCols;
fPresentation = pres;
fDisplayWidth = Display.getDefault().getBounds().width;
}
// ------------------------------------------------------------------------
- // ViewPart
+ // Getters and setters
// ------------------------------------------------------------------------
- @Override
- public void createPartControl(Composite parent) {
- fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE, fWeight);
+ /**
+ * Getter for the time graph combo
+ *
+ * @return The time graph combo, or null if combo is not used
+ */
+ protected TimeGraphCombo getTimeGraphCombo() {
+ if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) {
+ return ((TimeGraphComboWrapper) fTimeGraphWrapper).getTimeGraphCombo();
+ }
+ return null;
+ }
+
+ /**
+ * Getter for the time graph viewer
+ *
+ * @return The time graph viewer
+ */
+ protected TimeGraphViewer getTimeGraphViewer() {
+ return fTimeGraphWrapper.getTimeGraphViewer();
+ }
+
+ /**
+ * Getter for the presentation provider
+ *
+ * @return The time graph presentation provider
+ * @since 3.0
+ */
+ protected ITimeGraphPresentationProvider2 getPresentationProvider() {
+ return fPresentation;
+ }
+
+ /**
+ * Sets the tree column labels.
+ * This should be called from the constructor.
+ *
+ * @param columns
+ * The array of tree column labels
+ */
+ protected void setTreeColumns(final String[] columns) {
+ fColumns = columns;
+ }
+
+ /**
+ * Sets the tree label provider.
+ * This should be called from the constructor.
+ *
+ * @param tlp
+ * The tree label provider
+ */
+ protected void setTreeLabelProvider(final TreeLabelProvider tlp) {
+ fLabelProvider = tlp;
+ }
+
+ /**
+ * Sets the relative weight of each part of the time graph combo.
+ * This should be called from the constructor.
+ *
+ * @param weights
+ * The array (length 2) of relative weights of each part of the combo
+ */
+ protected void setWeight(final int[] weights) {
+ fWeight = weights;
+ }
+
+ /**
+ * Sets the filter column labels.
+ * This should be called from the constructor.
+ *
+ * @param filterColumns
+ * The array of filter column labels
+ */
+ protected void setFilterColumns(final String[] filterColumns) {
+ fFilterColumns = filterColumns;
+ }
+
+ /**
+ * Sets the filter label provider.
+ * This should be called from the constructor.
+ *
+ * @param labelProvider
+ * The filter label provider
+ *
+ * @since 3.0
+ */
+ protected void setFilterLabelProvider(final TreeLabelProvider labelProvider) {
+ fFilterLabelProvider = labelProvider;
+ }
+
+ /**
+ * Gets the display width
+ *
+ * @return the display width
+ */
+ protected int getDisplayWidth() {
+ return fDisplayWidth;
+ }
+
+ /**
+ * Gets the comparator for the entries
+ *
+ * @return The entry comparator
+ */
+ protected Comparator<ITimeGraphEntry> getEntryComparator() {
+ return fEntryComparator;
+ }
+
+ /**
+ * Sets the comparator class for the entries
+ *
+ * @param comparator
+ * A comparator object
+ */
+ protected void setEntryComparator(final Comparator<ITimeGraphEntry> comparator) {
+ fEntryComparator = comparator;
+ }
+
+ /**
+ * Gets the trace displayed in the view
+ *
+ * @return The trace
+ */
+ protected ITmfTrace getTrace() {
+ return fTrace;
+ }
+
+ /**
+ * Gets the start time
+ *
+ * @return The start time
+ */
+ protected long getStartTime() {
+ return fStartTime;
+ }
+
+ /**
+ * Sets the start time
+ *
+ * @param time
+ * The start time
+ */
+ protected void setStartTime(long time) {
+ fStartTime = time;
+ }
+
+ /**
+ * Gets the end time
+ *
+ * @return The end time
+ */
+ protected long getEndTime() {
+ return fEndTime;
+ }
+
+ /**
+ * Sets the end time
+ *
+ * @param time
+ * The end time
+ */
+ protected void setEndTime(long time) {
+ fEndTime = time;
+ }
+
+ /**
+ * Gets the entry list for a trace
+ *
+ * @param trace
+ * the trace
+ *
+ * @return the entry list map
+ * @since 3.0
+ */
+ protected List<TimeGraphEntry> getEntryList(ITmfTrace trace) {
+ synchronized (fEntryListMap) {
+ return fEntryListMap.get(trace);
+ }
+ }
+
+ /**
+ * Adds a trace entry list to the entry list map
+ *
+ * @param trace
+ * the trace to add
+ * @param list
+ * the list of time graph entries
+ */
+ protected void putEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
+ synchronized (fEntryListMap) {
+ fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list));
+ }
+ }
+
+ /**
+ * Adds a list of entries to a trace's entry list
+ *
+ * @param trace
+ * the trace
+ * @param list
+ * the list of time graph entries to add
+ * @since 3.0
+ */
+ protected void addToEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
+ synchronized (fEntryListMap) {
+ List<TimeGraphEntry> entryList = fEntryListMap.get(trace);
+ if (entryList == null) {
+ fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list));
+ } else {
+ entryList.addAll(list);
+ }
+ }
+ }
+
+ /**
+ * Removes a list of entries from a trace's entry list
+ *
+ * @param trace
+ * the trace
+ * @param list
+ * the list of time graph entries to remove
+ * @since 3.0
+ */
+ protected void removeFromEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
+ synchronized (fEntryListMap) {
+ List<TimeGraphEntry> entryList = fEntryListMap.get(trace);
+ if (entryList != null) {
+ entryList.removeAll(list);
+ }
+ }
+ }
- fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider());
+ /**
+ * Text for the "next" button
+ *
+ * @return The "next" button text
+ */
+ protected String getNextText() {
+ return Messages.AbstractTimeGraphtView_NextText;
+ }
- fTimeGraphCombo.setTreeLabelProvider(fLabelProvider);
+ /**
+ * Tooltip for the "next" button
+ *
+ * @return Tooltip for the "next" button
+ */
+ protected String getNextTooltip() {
+ return Messages.AbstractTimeGraphView_NextTooltip;
+ }
- fTimeGraphCombo.setTimeGraphProvider(fPresentation);
+ /**
+ * Text for the "Previous" button
+ *
+ * @return The "Previous" button text
+ */
+ protected String getPrevText() {
+ return Messages.AbstractTimeGraphView_PreviousText;
+ }
- fTimeGraphCombo.setTreeColumns(fColumns);
+ /**
+ * Tooltip for the "previous" button
+ *
+ * @return Tooltip for the "previous" button
+ */
+ protected String getPrevTooltip() {
+ return Messages.AbstractTimeGraphView_PreviousTooltip;
+ }
- fTimeGraphCombo.setFilterContentProvider(new TreeContentProvider());
+ // ------------------------------------------------------------------------
+ // ViewPart
+ // ------------------------------------------------------------------------
- fTimeGraphCombo.setFilterLabelProvider(new TreeLabelProvider());
+ @Override
+ public void createPartControl(Composite parent) {
+ if (fColumns == null || fLabelProvider == null) {
+ fTimeGraphWrapper = new TimeGraphViewerWrapper(parent, SWT.NONE);
+ TimeGraphViewer viewer = fTimeGraphWrapper.getTimeGraphViewer();
+ viewer.setTimeGraphContentProvider(new TimeGraphContentProvider());
+ } else {
+ TimeGraphComboWrapper wrapper = new TimeGraphComboWrapper(parent, SWT.NONE);
+ fTimeGraphWrapper = wrapper;
+ TimeGraphCombo combo = wrapper.getTimeGraphCombo();
+ combo.setTreeContentProvider(new TreeContentProvider());
+ combo.setTreeLabelProvider(fLabelProvider);
+ combo.setTreeColumns(fColumns);
+ combo.setFilterContentProvider(new TreeContentProvider());
+ combo.setFilterLabelProvider(fFilterLabelProvider);
+ combo.setFilterColumns(fFilterColumns);
+ combo.setTimeGraphContentProvider(new TimeGraphContentProvider());
+ }
- fTimeGraphCombo.setFilterColumns(fFilterColumns);
+ fTimeGraphWrapper.setTimeGraphProvider(fPresentation);
- fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
+ fTimeGraphWrapper.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
@Override
public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
final long startTime = event.getStartTime();
final long endTime = event.getEndTime();
- TmfTimeRange range = new TmfTimeRange(new CtfTmfTimestamp(startTime), new CtfTmfTimestamp(endTime));
- TmfTimestamp time = new CtfTmfTimestamp(fTimeGraphCombo.getTimeGraphViewer().getSelectedTime());
- broadcast(new TmfRangeSynchSignal(AbstractTimeGraphView.this, range, time));
+ TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
+ broadcast(new TmfRangeSynchSignal(AbstractTimeGraphView.this, range));
if (fZoomThread != null) {
fZoomThread.cancel();
}
}
});
- fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
+ fTimeGraphWrapper.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
@Override
public void timeSelected(TimeGraphTimeEvent event) {
- long time = event.getTime();
- broadcast(new TmfTimeSynchSignal(AbstractTimeGraphView.this, new CtfTmfTimestamp(time)));
+ TmfNanoTimestamp startTime = new TmfNanoTimestamp(event.getBeginTime());
+ TmfNanoTimestamp endTime = new TmfNanoTimestamp(event.getEndTime());
+ broadcast(new TmfTimeSynchSignal(AbstractTimeGraphView.this, startTime, endTime));
}
});
- fTimeGraphCombo.addSelectionListener(new ITimeGraphSelectionListener() {
- @Override
- public void selectionChanged(TimeGraphSelectionEvent event) {
- // ITimeGraphEntry selection = event.getSelection();
- }
- });
+ fTimeGraphWrapper.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
- fTimeGraphCombo.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
+ IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
+ fTimeGraphWrapper.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager);
// View Action Handling
makeActions();
}
// make selection available to other views
- getSite().setSelectionProvider(fTimeGraphCombo.getTreeViewer());
+ getSite().setSelectionProvider(fTimeGraphWrapper.getSelectionProvider());
}
@Override
public void setFocus() {
- fTimeGraphCombo.setFocus();
+ fTimeGraphWrapper.setFocus();
}
// ------------------------------------------------------------------------
@TmfSignalHandler
public void traceClosed(final TmfTraceClosedSignal signal) {
synchronized (fBuildThreadMap) {
- BuildThread buildThread = fBuildThreadMap.remove(signal.getTrace());
- if (buildThread != null) {
- buildThread.cancel();
+ for (ITmfTrace trace : getTracesToBuild(signal.getTrace())) {
+ BuildThread buildThread = fBuildThreadMap.remove(trace);
+ if (buildThread != null) {
+ buildThread.cancel();
+ }
}
}
synchronized (fEntryListMap) {
}
/**
- * Handler for the synch signal
+ * Handler for the time synch signal
*
* @param signal
* The signal that's received
if (signal.getSource() == this || fTrace == null) {
return;
}
- final long time = signal.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
- if (fTimeGraphCombo.isDisposed()) {
+ if (fTimeGraphWrapper.isDisposed()) {
return;
}
- fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);
- startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
+ if (beginTime == endTime) {
+ fTimeGraphWrapper.getTimeGraphViewer().setSelectedTime(beginTime, true);
+ } else {
+ fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(beginTime, endTime);
+ }
+ startZoomThread(fTimeGraphWrapper.getTimeGraphViewer().getTime0(), fTimeGraphWrapper.getTimeGraphViewer().getTime1());
- synchingToTime(time);
+ synchingToTime(beginTime);
}
});
}
/**
- * Handler for the range sync signal
+ * Handler for the range synch signal
*
* @param signal
* The signal that's received
}
final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
- final long time = signal.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
- if (fTimeGraphCombo.isDisposed()) {
+ if (fTimeGraphWrapper.isDisposed()) {
return;
}
- fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
- fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);
+ fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
startZoomThread(startTime, endTime);
}
});
}
+ /**
+ * @param signal the format of the timestamps was updated.
+ * @since 2.1
+ */
+ @TmfSignalHandler
+ public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal){
+ fTimeGraphWrapper.refresh();
+ }
+
// ------------------------------------------------------------------------
// Internal
// ------------------------------------------------------------------------
synchronized (fEntryListMap) {
fEntryList = fEntryListMap.get(fTrace);
if (fEntryList == null) {
- synchronized (fBuildThreadMap) {
- BuildThread buildThread = new BuildThread(fTrace, this.getName());
- fBuildThreadMap.put(fTrace, buildThread);
- buildThread.start();
- }
+ rebuild();
} else {
fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
}
}
+ /**
+ * Forces a rebuild of the entries list, even if entries already exist for this trace
+ * @since 3.0
+ */
+ protected void rebuild() {
+ setStartTime(Long.MAX_VALUE);
+ setEndTime(Long.MIN_VALUE);
+ synchronized (fBuildThreadMap) {
+ for (ITmfTrace trace : getTracesToBuild(fTrace)) {
+ BuildThread buildThread = new BuildThread(trace, fTrace, getName());
+ fBuildThreadMap.put(trace, buildThread);
+ buildThread.start();
+ }
+ }
+ }
+
/**
* Method called when synching to a given timestamp. Inheriting classes can
* perform actions here to update the view at the given timestamp.
}
+ /**
+ * Return the list of traces whose data or analysis results will be used to
+ * populate the view. By default, if the trace is an experiment, the traces
+ * under it will be returned, otherwise, the trace itself is returned.
+ *
+ * A build thread will be started for each trace returned by this method,
+ * some of which may receive events in live streaming mode.
+ *
+ * @param trace
+ * The trace associated with this view
+ * @return List of traces with data to display
+ * @since 3.0
+ */
+ protected Iterable<ITmfTrace> getTracesToBuild(ITmfTrace trace) {
+ return Arrays.asList(TmfTraceManager.getTraceSet(trace));
+ }
+
/**
* Build the entries list to show in this time graph
*
*
* @param trace
* The trace being built
+ * @param parentTrace
+ * The parent of the trace set, or the trace itself
* @param monitor
* The progress monitor object
+ * @since 3.0
*/
- protected abstract void buildEventList(final ITmfTrace trace, IProgressMonitor monitor);
+ protected abstract void buildEventList(ITmfTrace trace, ITmfTrace parentTrace, IProgressMonitor monitor);
/**
* Gets the list of event for an entry in a given timerange
* The progress monitor object
* @return The list of events for the entry
*/
- protected abstract List<ITimeEvent> getEventList(TimeGraphEntry entry,
+ protected abstract @Nullable List<ITimeEvent> getEventList(TimeGraphEntry entry,
long startTime, long endTime, long resolution,
IProgressMonitor monitor);
+ /**
+ * Gets the list of links (displayed as arrows) for a trace in a given
+ * timerange. Default implementation returns an empty list.
+ *
+ * @param startTime
+ * Start of the time range
+ * @param endTime
+ * End of the time range
+ * @param resolution
+ * The resolution
+ * @param monitor
+ * The progress monitor object
+ * @return The list of link events
+ * @since 2.1
+ */
+ protected List<ILinkEvent> getLinkList(long startTime, long endTime,
+ long resolution, IProgressMonitor monitor) {
+ return new ArrayList<>();
+ }
+
+
/**
* Refresh the display
*/
protected void refresh() {
- Display.getDefault().asyncExec(new Runnable() {
+ TmfUiRefreshHandler.getInstance().queueUpdate(this, new Runnable() {
@Override
public void run() {
- if (fTimeGraphCombo.isDisposed()) {
+ if (fTimeGraphWrapper.isDisposed()) {
return;
}
- ITimeGraphEntry[] entries = null;
+ boolean hasEntries = false;
synchronized (fEntryListMap) {
fEntryList = fEntryListMap.get(fTrace);
if (fEntryList == null) {
- fEntryList = new ArrayList<TimeGraphEntry>();
+ fEntryList = new CopyOnWriteArrayList<>();
+ } else if (fEntryComparator != null) {
+ List<TimeGraphEntry> list = new ArrayList<>(fEntryList);
+ Collections.sort(list, fEntryComparator);
+ fEntryList.clear();
+ fEntryList.addAll(list);
}
- entries = fEntryList.toArray(new ITimeGraphEntry[0]);
+ hasEntries = fEntryList.size() != 0;
}
- if (fEntryComparator != null) {
- Arrays.sort(entries, fEntryComparator);
+ if (fEntryList != fTimeGraphWrapper.getInput()) {
+ fTimeGraphWrapper.setInput(fEntryList);
+ } else {
+ fTimeGraphWrapper.refresh();
}
- fTimeGraphCombo.setInput(entries);
- fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
+ fTimeGraphWrapper.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
- long timestamp = fTrace == null ? 0 : fTraceManager.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
startTime = Math.max(startTime, fStartTime);
endTime = Math.min(endTime, fEndTime);
- fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(timestamp, false);
- fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
+ fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime);
+ fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
- for (TreeColumn column : fTimeGraphCombo.getTreeViewer().getTree().getColumns()) {
- column.pack();
+ if (fTimeGraphWrapper instanceof TimeGraphComboWrapper && !fPackDone) {
+ for (TreeColumn column : ((TimeGraphComboWrapper) fTimeGraphWrapper).getTreeViewer().getTree().getColumns()) {
+ column.pack();
+ }
+ if (hasEntries) {
+ fPackDone = true;
+ }
}
startZoomThread(startTime, endTime);
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
- if (fTimeGraphCombo.isDisposed()) {
+ if (fTimeGraphWrapper.isDisposed()) {
return;
}
- fTimeGraphCombo.redraw();
- fTimeGraphCombo.update();
+ fTimeGraphWrapper.redraw();
+ fTimeGraphWrapper.update();
synchronized (fSyncObj) {
if (fRedrawState == State.PENDING) {
fRedrawState = State.IDLE;
}
private void makeActions() {
- fPreviousResourceAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction();
+ fPreviousResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getPreviousItemAction();
fPreviousResourceAction.setText(getPrevText());
fPreviousResourceAction.setToolTipText(getPrevTooltip());
- fNextResourceAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction();
+ fNextResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getNextItemAction();
fNextResourceAction.setText(getNextText());
fNextResourceAction.setToolTipText(getNextTooltip());
}
fillLocalToolBar(bars.getToolBarManager());
}
- private void fillLocalToolBar(IToolBarManager manager) {
- if (fFilterColumns.length > 0) {
- manager.add(fTimeGraphCombo.getShowFilterAction());
+ /**
+ * Add actions to local tool bar manager
+ *
+ * @param manager the tool bar manager
+ */
+ protected void fillLocalToolBar(IToolBarManager manager) {
+ if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) {
+ if (fFilterColumns != null && fFilterLabelProvider != null && fFilterColumns.length > 0) {
+ manager.add(((TimeGraphComboWrapper) fTimeGraphWrapper).getShowFilterAction());
+ }
}
- manager.add(fTimeGraphCombo.getTimeGraphViewer().getShowLegendAction());
+ manager.add(fTimeGraphWrapper.getTimeGraphViewer().getShowLegendAction());
manager.add(new Separator());
- manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction());
- manager.add(fTimeGraphCombo.getTimeGraphViewer().getPreviousEventAction());
- manager.add(fTimeGraphCombo.getTimeGraphViewer().getNextEventAction());
+ manager.add(fTimeGraphWrapper.getTimeGraphViewer().getResetScaleAction());
+ manager.add(fTimeGraphWrapper.getTimeGraphViewer().getPreviousEventAction());
+ manager.add(fTimeGraphWrapper.getTimeGraphViewer().getNextEventAction());
manager.add(fPreviousResourceAction);
manager.add(fNextResourceAction);
- manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction());
- manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction());
+ manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomInAction());
+ manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomOutAction());
manager.add(new Separator());
}
}