ctf: Fix CtfTmfLostEvent time range does not use timestamp transform
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / timegraph / AbstractTimeGraphView.java
index 7358c9f89103ac815ef85f78e2dbcdf935e62653..68e98e42636b83c307cd8bd1171edf312572d255 100644 (file)
 
 package org.eclipse.tracecompass.tmf.ui.views.timegraph;
 
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
-
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IStatusLineManager;
 import org.eclipse.jface.action.IToolBarManager;
 import org.eclipse.jface.action.Separator;
@@ -38,12 +54,18 @@ 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.ViewerFilter;
+import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.tracecompass.internal.tmf.ui.Activator;
+import org.eclipse.tracecompass.tmf.core.resources.ITmfMarker;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
@@ -55,17 +77,20 @@ import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceAdapterManager;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler;
 import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
 import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
 import org.eclipse.tracecompass.tmf.ui.views.TmfView;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphBookmarkListener;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphContentProvider;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphBookmarkEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphCombo;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphContentProvider;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
@@ -73,8 +98,11 @@ import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEve
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphViewer;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEventSource;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.MarkerEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
 import org.eclipse.ui.IActionBars;
@@ -85,11 +113,13 @@ import org.eclipse.ui.IActionBars;
  * 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.
  */
-public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeAligned {
+public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeAligned, IResourceChangeListener {
 
     /** Constant indicating that all levels of the time graph should be expanded */
     protected static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS;
 
+    private static final Pattern RGBA_PATTERN = Pattern.compile("RGBA \\{(\\d+), (\\d+), (\\d+), (\\d+)\\}"); //$NON-NLS-1$
+
     /**
      * Redraw state enum
      */
@@ -107,20 +137,29 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
     /** The selected trace */
     private ITmfTrace fTrace;
 
+    /** The selected trace editor file*/
+    private IFile fEditorFile;
+
     /** The timegraph entry list */
     private List<TimeGraphEntry> fEntryList;
 
     /** The trace to entry list hash map */
     private final Map<ITmfTrace, List<TimeGraphEntry>> fEntryListMap = new HashMap<>();
 
+    /** The trace to filters hash map */
+    private final Map<ITmfTrace, ViewerFilter[]> fFiltersMap = new HashMap<>();
+
+    /** The trace to marker event sources hash map */
+    private final Map<ITmfTrace, List<IMarkerEventSource>> fMarkerEventSourcesMap = new HashMap<>();
+
     /** The trace to build thread hash map */
     private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<>();
 
     /** The start time */
-    private long fStartTime;
+    private long fStartTime = SWT.DEFAULT;
 
     /** The end time */
-    private long fEndTime;
+    private long fEndTime = SWT.DEFAULT;
 
     /** The display width */
     private final int fDisplayWidth;
@@ -169,17 +208,22 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
 
     private int fAutoExpandLevel = ALL_LEVELS;
 
+    /** The list of color resources created by this view */
+    private final List<Color> fColors = new ArrayList<>();
+
     // ------------------------------------------------------------------------
     // Classes
     // ------------------------------------------------------------------------
 
     private interface ITimeGraphWrapper {
 
-        void setTimeGraphProvider(TimeGraphPresentationProvider fPresentation);
+        void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider);
+
+        void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider);
 
         TimeGraphViewer getTimeGraphViewer();
 
-        void addSelectionListener(ITimeGraphSelectionListener iTimeGraphSelectionListener);
+        void addSelectionListener(ITimeGraphSelectionListener listener);
 
         ISelectionProvider getSelectionProvider();
 
@@ -193,12 +237,24 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
 
         Object getInput();
 
+        void setFilters(ViewerFilter[] filters);
+
+        ViewerFilter[] getFilters();
+
         void redraw();
 
         void update();
 
         void setAutoExpandLevel(int level);
 
+        void setFilterColumns(String[] columnNames);
+
+        void setFilterContentProvider(ITreeContentProvider contentProvider);
+
+        void setFilterLabelProvider(ITableLabelProvider labelProvider);
+
+        IAction getShowFilterDialogAction();
+
         void performAlign(int offset, int width);
 
         TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo();
@@ -214,8 +270,13 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
         }
 
         @Override
-        public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) {
-            viewer.setTimeGraphProvider(timeGraphProvider);
+        public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) {
+            viewer.setTimeGraphContentProvider(timeGraphContentProvider);
+        }
+
+        @Override
+        public void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider) {
+            viewer.setTimeGraphProvider(timeGraphPresentationProvider);
         }
 
         @Override
@@ -253,6 +314,36 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
             return viewer.getInput();
         }
 
+        @Override
+        public void setFilterColumns(String[] columnNames) {
+            viewer.setFilterColumns(columnNames);
+        }
+
+        @Override
+        public void setFilterContentProvider(ITreeContentProvider contentProvider) {
+            viewer.setFilterContentProvider(contentProvider);
+        }
+
+        @Override
+        public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
+            viewer.setFilterLabelProvider(labelProvider);
+        }
+
+        @Override
+        public void setFilters(ViewerFilter[] filters) {
+            viewer.setFilters(filters);
+        }
+
+        @Override
+        public ViewerFilter[] getFilters() {
+            return viewer.getFilters();
+        }
+
+        @Override
+        public IAction getShowFilterDialogAction() {
+            return viewer.getShowFilterDialogAction();
+        }
+
         @Override
         public void refresh() {
             viewer.refresh();
@@ -297,8 +388,13 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
         }
 
         @Override
-        public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) {
-            combo.setTimeGraphProvider(timeGraphProvider);
+        public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) {
+            combo.setTimeGraphContentProvider(timeGraphContentProvider);
+        }
+
+        @Override
+        public void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider) {
+            combo.setTimeGraphProvider(timeGraphPresentationProvider);
         }
 
         @Override
@@ -336,6 +432,36 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
             return combo.getInput();
         }
 
+        @Override
+        public void setFilterColumns(String[] columnNames) {
+            combo.setFilterColumns(columnNames);
+        }
+
+        @Override
+        public void setFilterContentProvider(ITreeContentProvider contentProvider) {
+            combo.setFilterContentProvider(contentProvider);
+        }
+
+        @Override
+        public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
+            combo.setFilterLabelProvider(labelProvider);
+        }
+
+        @Override
+        public void setFilters(ViewerFilter[] filters) {
+            combo.setFilters(filters);
+        }
+
+        @Override
+        public ViewerFilter[] getFilters() {
+            return combo.getFilters();
+        }
+
+        @Override
+        public IAction getShowFilterDialogAction() {
+            return combo.getShowFilterDialogAction();
+        }
+
         @Override
         public void refresh() {
             combo.refresh();
@@ -364,10 +490,6 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
             return combo.getTreeViewer();
         }
 
-        IAction getShowFilterAction() {
-            return combo.getShowFilterAction();
-        }
-
         @Override
         public void performAlign(int offset, int width) {
             combo.performAlign(offset, width);
@@ -549,6 +671,12 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
                 fTimeGraphWrapper.getTimeGraphViewer().setLinks(events);
                 redraw();
             }
+            /* Refresh the view-specific markers when zooming */
+            List<IMarkerEvent> markers = new ArrayList<>(getViewMarkerList(getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor()));
+            /* Refresh the trace-specific markers when zooming */
+            markers.addAll(getTraceMarkerList(getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor()));
+            fTimeGraphWrapper.getTimeGraphViewer().setMarkers(markers);
+            redraw();
         }
 
         private void zoom(@NonNull TimeGraphEntry entry, @NonNull IProgressMonitor monitor) {
@@ -903,8 +1031,6 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
         super.createPartControl(parent);
         if (fColumns == null || fLabelProvider == null) {
             fTimeGraphWrapper = new TimeGraphViewerWrapper(parent, SWT.NONE);
-            TimeGraphViewer viewer = fTimeGraphWrapper.getTimeGraphViewer();
-            viewer.setTimeGraphContentProvider(fTimeGraphContentProvider);
         } else {
             TimeGraphComboWrapper wrapper = new TimeGraphComboWrapper(parent, SWT.NONE);
             fTimeGraphWrapper = wrapper;
@@ -912,13 +1038,13 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
             combo.setTreeContentProvider(fTimeGraphContentProvider);
             combo.setTreeLabelProvider(fLabelProvider);
             combo.setTreeColumns(fColumns);
-            combo.setFilterContentProvider(fTimeGraphContentProvider);
-            combo.setFilterLabelProvider(fFilterLabelProvider);
-            combo.setFilterColumns(fFilterColumns);
-            combo.setTimeGraphContentProvider(fTimeGraphContentProvider);
         }
+        fTimeGraphWrapper.setTimeGraphContentProvider(fTimeGraphContentProvider);
+        fTimeGraphWrapper.setFilterContentProvider(fTimeGraphContentProvider);
+        fTimeGraphWrapper.setFilterLabelProvider(fFilterLabelProvider);
+        fTimeGraphWrapper.setFilterColumns(fFilterColumns);
 
-        fTimeGraphWrapper.setTimeGraphProvider(fPresentation);
+        fTimeGraphWrapper.setTimeGraphPresentationProvider(fPresentation);
         fTimeGraphWrapper.setAutoExpandLevel(fAutoExpandLevel);
 
         fTimeGraphWrapper.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
@@ -941,6 +1067,56 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
             }
         });
 
+        fTimeGraphWrapper.getTimeGraphViewer().addBookmarkListener(new ITimeGraphBookmarkListener() {
+            @Override
+            public void bookmarkAdded(final TimeGraphBookmarkEvent event) {
+                try {
+                    ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
+                        @Override
+                        public void run(IProgressMonitor monitor) throws CoreException {
+                            IMarkerEvent bookmark = event.getBookmark();
+                            IMarker marker = fEditorFile.createMarker(IMarker.BOOKMARK);
+                            marker.setAttribute(IMarker.MESSAGE, bookmark.getLabel());
+                            marker.setAttribute(ITmfMarker.MARKER_TIME, Long.toString(bookmark.getTime()));
+                            if (bookmark.getDuration() > 0) {
+                                marker.setAttribute(ITmfMarker.MARKER_DURATION, Long.toString(bookmark.getDuration()));
+                                marker.setAttribute(IMarker.LOCATION,
+                                        NLS.bind(org.eclipse.tracecompass.internal.tmf.ui.Messages.TmfMarker_LocationTimeRange,
+                                                new TmfNanoTimestamp(bookmark.getTime()),
+                                                new TmfNanoTimestamp(bookmark.getTime() + bookmark.getDuration())));
+                            } else {
+                                marker.setAttribute(IMarker.LOCATION,
+                                        NLS.bind(org.eclipse.tracecompass.internal.tmf.ui.Messages.TmfMarker_LocationTime,
+                                                new TmfNanoTimestamp(bookmark.getTime())));
+                            }
+                            marker.setAttribute(ITmfMarker.MARKER_COLOR, bookmark.getColor().getRGBA().toString());
+                        }
+                    }, null);
+                } catch (CoreException e) {
+                    Activator.getDefault().logError(e.getMessage());
+                }
+            }
+
+            @Override
+            public void bookmarkRemoved(TimeGraphBookmarkEvent event) {
+                try {
+                    IMarkerEvent bookmark = event.getBookmark();
+                    IMarker[] markers = fEditorFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO);
+                    for (IMarker marker : markers) {
+                        if (bookmark.getLabel().equals(marker.getAttribute(IMarker.MESSAGE)) &&
+                                Long.toString(bookmark.getTime()).equals(marker.getAttribute(ITmfMarker.MARKER_TIME, (String) null)) &&
+                                Long.toString(bookmark.getDuration()).equals(marker.getAttribute(ITmfMarker.MARKER_DURATION, Long.toString(0))) &&
+                                bookmark.getColor().getRGBA().toString().equals(marker.getAttribute(ITmfMarker.MARKER_COLOR))) {
+                            marker.delete();
+                            break;
+                        }
+                    }
+                } catch (CoreException e) {
+                    Activator.getDefault().logError(e.getMessage());
+                }
+            }
+        });
+
         fTimeGraphWrapper.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
 
         IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
@@ -957,6 +1133,8 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
 
         // make selection available to other views
         getSite().setSelectionProvider(fTimeGraphWrapper.getSelectionProvider());
+
+        ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
     }
 
     @Override
@@ -964,6 +1142,65 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
         fTimeGraphWrapper.setFocus();
     }
 
+    @Override
+    public void dispose() {
+        super.dispose();
+        ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+    }
+
+    /**
+     * @since 2.0
+     */
+    @Override
+    public void resourceChanged(final IResourceChangeEvent event) {
+        for (final IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) {
+            if (delta.getResource().equals(fEditorFile)) {
+                fTimeGraphWrapper.getTimeGraphViewer().setBookmarks(refreshBookmarks(fEditorFile));
+                redraw();
+                return;
+            }
+        }
+    }
+
+    private List<IMarkerEvent> refreshBookmarks(final IFile editorFile) {
+        List<IMarkerEvent> bookmarks = new ArrayList<>();
+        for (Color color : fColors) {
+            color.dispose();
+        }
+        fColors.clear();
+        if (editorFile == null || !editorFile.exists()) {
+            return bookmarks;
+        }
+        try {
+            IMarker[] markers = editorFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO);
+            for (IMarker marker : markers) {
+                String label = marker.getAttribute(IMarker.MESSAGE, (String) null);
+                String time = marker.getAttribute(ITmfMarker.MARKER_TIME, (String) null);
+                String duration = marker.getAttribute(ITmfMarker.MARKER_DURATION, Long.toString(0));
+                String rgba = marker.getAttribute(ITmfMarker.MARKER_COLOR, (String) null);
+                if (label != null && time != null && rgba != null) {
+                    Matcher matcher = RGBA_PATTERN.matcher(rgba);
+                    if (matcher.matches()) {
+                        try {
+                            int red = Integer.valueOf(matcher.group(1));
+                            int green = Integer.valueOf(matcher.group(2));
+                            int blue = Integer.valueOf(matcher.group(3));
+                            int alpha = Integer.valueOf(matcher.group(4));
+                            Color color = new Color(Display.getDefault(), red, green, blue, alpha);
+                            fColors.add(color);
+                            bookmarks.add(new MarkerEvent(null, Long.valueOf(time), Long.valueOf(duration), IMarkerEvent.BOOKMARKS, color, label, true));
+                        } catch (NumberFormatException e) {
+                            Activator.getDefault().logError(e.getMessage());
+                        }
+                    }
+                }
+            }
+        } catch (CoreException e) {
+            Activator.getDefault().logError(e.getMessage());
+        }
+        return bookmarks;
+    }
+
     // ------------------------------------------------------------------------
     // Signal handlers
     // ------------------------------------------------------------------------
@@ -976,8 +1213,7 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
      */
     @TmfSignalHandler
     public void traceOpened(TmfTraceOpenedSignal signal) {
-        fTrace = signal.getTrace();
-        loadTrace();
+        loadTrace(signal.getTrace());
     }
 
     /**
@@ -991,8 +1227,7 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
         if (signal.getTrace() == fTrace) {
             return;
         }
-        fTrace = signal.getTrace();
-        loadTrace();
+        loadTrace(signal.getTrace());
     }
 
     /**
@@ -1009,15 +1244,18 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
                 if (buildThread != null) {
                     buildThread.cancel();
                 }
+                fMarkerEventSourcesMap.remove(trace);
             }
         }
         synchronized (fEntryListMap) {
             fEntryListMap.remove(signal.getTrace());
         }
+        fFiltersMap.remove(signal.getTrace());
         if (signal.getTrace() == fTrace) {
             fTrace = null;
-            fStartTime = 0;
-            fEndTime = 0;
+            fEditorFile = null;
+            fStartTime = SWT.DEFAULT;
+            fEndTime = SWT.DEFAULT;
             if (fZoomThread != null) {
                 fZoomThread.cancel();
                 fZoomThread = null;
@@ -1050,11 +1288,9 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
                 if (beginTime == endTime) {
                     fTimeGraphWrapper.getTimeGraphViewer().setSelectedTime(beginTime, true);
                 } else {
-                    fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(beginTime, endTime);
+                    fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(beginTime, endTime, true);
                 }
-                startZoomThread(fTimeGraphWrapper.getTimeGraphViewer().getTime0(), fTimeGraphWrapper.getTimeGraphViewer().getTime1());
-
-                synchingToTime(beginTime);
+                synchingToTime(fTimeGraphWrapper.getTimeGraphViewer().getTime0());
             }
         });
     }
@@ -1100,11 +1336,17 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
     // Internal
     // ------------------------------------------------------------------------
 
-    private void loadTrace() {
+    private void loadTrace(final ITmfTrace trace) {
         if (fZoomThread != null) {
             fZoomThread.cancel();
             fZoomThread = null;
         }
+        if (fTrace != null) {
+            /* save the filters of the previous trace */
+            fFiltersMap.put(fTrace, fTimeGraphWrapper.getFilters());
+        }
+        fTrace = trace;
+        fEditorFile = TmfTraceManager.getInstance().getTraceEditorFile(trace);
         synchronized (fEntryListMap) {
             fEntryList = fEntryListMap.get(fTrace);
             if (fEntryList == null) {
@@ -1133,6 +1375,7 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
                 if (trace == null) {
                     break;
                 }
+                fMarkerEventSourcesMap.put(trace, TmfTraceAdapterManager.getAdapters(trace, IMarkerEventSource.class));
                 BuildThread buildThread = new BuildThread(trace, viewTrace, getName());
                 fBuildThreadMap.put(trace, buildThread);
                 buildThread.start();
@@ -1196,7 +1439,7 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
      *            The progress monitor object
      * @return The list of events for the entry
      */
-    protected abstract @Nullable List<ITimeEvent> getEventList(@NonNull TimeGraphEntry entry,
+    protected abstract @Nullable List<@NonNull ITimeEvent> getEventList(@NonNull TimeGraphEntry entry,
             long startTime, long endTime, long resolution,
             @NonNull IProgressMonitor monitor);
 
@@ -1214,11 +1457,99 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
      *            The progress monitor object
      * @return The list of link events
      */
-    protected @Nullable List<ILinkEvent> getLinkList(long startTime, long endTime,
+    protected @Nullable List<@NonNull ILinkEvent> getLinkList(long startTime, long endTime,
+            long resolution, @NonNull IProgressMonitor monitor) {
+        return new ArrayList<>();
+    }
+
+    /**
+     * Gets the list of view-specific marker categories. Default implementation
+     * returns an empty list.
+     *
+     * @return The list of marker categories
+     * @since 2.0
+     */
+    protected @NonNull List<String> getViewMarkerCategories() {
+        return new ArrayList<>();
+    }
+
+    /**
+     * Gets the list of view-specific markers for a trace in a given time range.
+     * 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 marker events
+     * @since 2.0
+     */
+    protected @NonNull List<IMarkerEvent> getViewMarkerList(long startTime, long endTime,
             long resolution, @NonNull IProgressMonitor monitor) {
         return new ArrayList<>();
     }
 
+    /**
+     * Gets the list of trace-specific markers for a trace in a given time range.
+     *
+     * @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 marker events
+     * @since 2.0
+     */
+    protected @NonNull List<IMarkerEvent> getTraceMarkerList(long startTime, long endTime,
+            long resolution, @NonNull IProgressMonitor monitor) {
+        List<IMarkerEvent> markers = new ArrayList<>();
+        for (IMarkerEventSource markerEventSource : getMarkerEventSources(getTrace())) {
+            for (String category : markerEventSource.getMarkerCategories()) {
+                if (monitor.isCanceled()) {
+                    break;
+                }
+                markers.addAll(markerEventSource.getMarkerList(checkNotNull(category), startTime, endTime, resolution, monitor));
+            }
+        }
+        return markers;
+    }
+
+    /**
+     * Get the list of current marker categories.
+     *
+     * @return The list of marker categories
+     * @since 2.0
+     */
+    private @NonNull List<String> getMarkerCategories() {
+        Set<String> categories = new HashSet<>(getViewMarkerCategories());
+        for (IMarkerEventSource markerEventSource : getMarkerEventSources(fTrace)) {
+            categories.addAll(markerEventSource.getMarkerCategories());
+        }
+        return new ArrayList<>(categories);
+    }
+
+    /**
+     * Gets the list of marker event sources for a given trace.
+     *
+     * @param trace
+     *            The trace
+     * @return The list of marker event sources
+     * @since 2.0
+     */
+    private @NonNull List<IMarkerEventSource> getMarkerEventSources(ITmfTrace trace) {
+        List<IMarkerEventSource> markerEventSources = fMarkerEventSourcesMap.get(trace);
+        if (markerEventSources == null) {
+            markerEventSources = checkNotNull(Collections.<IMarkerEventSource>emptyList());
+        }
+        return markerEventSources;
+    }
 
     /**
      * Refresh the display
@@ -1246,20 +1577,27 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
                 }
                 if (fEntryList != fTimeGraphWrapper.getInput()) {
                     fTimeGraphWrapper.setInput(fEntryList);
+                    /* restore the previously saved filters, if any */
+                    fTimeGraphWrapper.setFilters(fFiltersMap.get(fTrace));
                     fTimeGraphWrapper.getTimeGraphViewer().setLinks(null);
+                    fTimeGraphWrapper.getTimeGraphViewer().setBookmarks(refreshBookmarks(fEditorFile));
+                    fTimeGraphWrapper.getTimeGraphViewer().setMarkerCategories(getMarkerCategories());
+                    fTimeGraphWrapper.getTimeGraphViewer().setMarkers(null);
                 } else {
                     fTimeGraphWrapper.refresh();
                 }
-                fTimeGraphWrapper.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
+                long startBound = (fStartTime == Long.MAX_VALUE ? SWT.DEFAULT : fStartTime);
+                long endBound = (fEndTime == Long.MIN_VALUE ? SWT.DEFAULT : fEndTime);
+                fTimeGraphWrapper.getTimeGraphViewer().setTimeBounds(startBound, endBound);
 
                 TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
-                long selectionBeginTime = fTrace == null ? 0 : ctx.getSelectionRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                long selectionEndTime = fTrace == null ? 0 : ctx.getSelectionRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                long startTime = fTrace == null ? 0 : ctx.getWindowRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                long endTime = fTrace == null ? 0 : ctx.getWindowRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                startTime = Math.max(startTime, fStartTime);
-                endTime = Math.min(endTime, fEndTime);
-                fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime);
+                long selectionBeginTime = fTrace == null ? SWT.DEFAULT : ctx.getSelectionRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+                long selectionEndTime = fTrace == null ? SWT.DEFAULT : ctx.getSelectionRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+                long startTime = fTrace == null ? SWT.DEFAULT : ctx.getWindowRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+                long endTime = fTrace == null ? SWT.DEFAULT : ctx.getWindowRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+                startTime = (fStartTime == Long.MAX_VALUE ? SWT.DEFAULT : Math.max(startTime, fStartTime));
+                endTime = (fEndTime == Long.MIN_VALUE ? SWT.DEFAULT : Math.min(endTime, fEndTime));
+                fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime, false);
                 fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
 
                 if (fTimeGraphWrapper instanceof TimeGraphComboWrapper && !fPackDone) {
@@ -1359,6 +1697,7 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
     private void contributeToActionBars() {
         IActionBars bars = getViewSite().getActionBars();
         fillLocalToolBar(bars.getToolBarManager());
+        fillLocalMenu(bars.getMenuManager());
     }
 
     /**
@@ -1367,16 +1706,19 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
      * @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());
-            }
+        if (fFilterColumns != null && fFilterLabelProvider != null && fFilterColumns.length > 0) {
+            manager.add(fTimeGraphWrapper.getShowFilterDialogAction());
         }
         manager.add(fTimeGraphWrapper.getTimeGraphViewer().getShowLegendAction());
         manager.add(new Separator());
         manager.add(fTimeGraphWrapper.getTimeGraphViewer().getResetScaleAction());
         manager.add(fTimeGraphWrapper.getTimeGraphViewer().getPreviousEventAction());
         manager.add(fTimeGraphWrapper.getTimeGraphViewer().getNextEventAction());
+        manager.add(new Separator());
+        manager.add(fTimeGraphWrapper.getTimeGraphViewer().getToggleBookmarkAction());
+        manager.add(fTimeGraphWrapper.getTimeGraphViewer().getPreviousMarkerAction());
+        manager.add(fTimeGraphWrapper.getTimeGraphViewer().getNextMarkerAction());
+        manager.add(new Separator());
         manager.add(fPreviousResourceAction);
         manager.add(fNextResourceAction);
         manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomInAction());
@@ -1384,6 +1726,16 @@ public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeA
         manager.add(new Separator());
     }
 
+    /**
+     * Add actions to local menu manager
+     *
+     * @param manager the tool bar manager
+     * @since 2.0
+     */
+    protected void fillLocalMenu(IMenuManager manager) {
+        manager.add(fTimeGraphWrapper.getTimeGraphViewer().getMarkersMenu());
+    }
+
     /**
      * @since 1.0
      */
This page took 0.035409 seconds and 5 git commands to generate.