TMF: Consolidate some view code into the AbstractTimeGraphView
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Wed, 1 May 2013 18:34:21 +0000 (14:34 -0400)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Tue, 2 Jul 2013 14:34:51 +0000 (10:34 -0400)
This new view is a base view for all views using the TimeGraphCombo widget.
As a first step, the lttng2 kernel Control flow view and Resources view have
been modified to extend this abstract view.

Mostly all of the interface management code (build thread, zoom thread, signal
handling, etc) is in the base class.  Final views need only implement to code
to fill the entries' list and events.

This patch includes:
- The abstract view class that all new time graph views may extend.  The default
  weight of each sash can be set in the child view.
- A TimeGraphEntry class that can be used as is if the view does not require
  extra data of its entries
- Modification of the TimeEvent class to add a value to it.
- Added a ITimeGraphDrawingHelper interface to pass to the presentation
  providers to help them get the information they need to know where to draw
  some things (see ResourcesPresentationProvider)

It is a first step before adding new features to the time graph views.  Some
more abstraction may need to be done as well as other reorganizing of the
code.

Also updated for the 2.1 API, added a ITimeGraphPresentationProvider2 interface
to avoid API breakage.

Change-Id: I73c9f1b4bf8ec265f1b02804fa7f819bd2b8dd7a
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/12423
Tested-by: Hudson CI
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
IP-Clean: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
IP-Clean: Alexandre Montplaisir <alexmonthy@voxpopuli.im>

20 files changed:
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEntry.java
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEvent.java [deleted file]
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowPresentationProvider.java
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEntry.java
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEvent.java [deleted file]
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesPresentationProvider.java
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesView.java
org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/Messages.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/messages.properties [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphPresentationProvider.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeEvent.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java

index 2cd832138d034e3ecdc22c068616713c85bf4685..d12a8630913fd1853507f8292cecd6d0fd9a3477 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
+ * Copyright (c) 2012, 2013 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
@@ -8,39 +8,27 @@
  *
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
+ *   Geneviève Bastien - Move code to provide base classes for time graph view
  *******************************************************************************/
 
 package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
 import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngKernelTrace;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.EventIterator;
-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 entry in the Control Flow view
  */
-public class ControlFlowEntry implements ITimeGraphEntry {
-    private final int fThreadQuark;
-    private final LttngKernelTrace fTrace;
-    private ControlFlowEntry fParent = null;
-    private final ArrayList<ControlFlowEntry> fChildren = new ArrayList<ControlFlowEntry>();
-    private String fName;
+public class ControlFlowEntry extends TimeGraphEntry {
+
     private final int fThreadId;
     private final int fParentThreadId;
-    private long fStartTime = -1;
-    private long fEndTime = -1;
-    private List<ITimeEvent> fEventList = new ArrayList<ITimeEvent>();
-    private List<ITimeEvent> fZoomedEventList = null;
+    private final int fThreadQuark;
 
     /**
      * Constructor
      *
-     * @param threadQuark
+     * @param quark
      *            The attribute quark matching the thread
      * @param trace
      *            The trace on which we are working
@@ -55,85 +43,11 @@ public class ControlFlowEntry implements ITimeGraphEntry {
      * @param endTime
      *            The end time of this process
      */
-    public ControlFlowEntry(int threadQuark, LttngKernelTrace trace, String execName, int threadId, int parentThreadId, long startTime, long endTime) {
-        fThreadQuark = threadQuark;
-        fTrace = trace;
-        fName = execName;
+    public ControlFlowEntry(int quark, LttngKernelTrace trace, String execName, int threadId, int parentThreadId, long startTime, long endTime) {
+        super(quark, trace, execName, startTime, endTime);
         fThreadId = threadId;
         fParentThreadId = parentThreadId;
-        fStartTime = startTime;
-        fEndTime = endTime;
-    }
-
-    @Override
-    public ITimeGraphEntry getParent() {
-        return fParent;
-    }
-
-    @Override
-    public boolean hasChildren() {
-        return fChildren.size() > 0;
-    }
-
-    @Override
-    public List<ControlFlowEntry> getChildren() {
-        return fChildren;
-    }
-
-    @Override
-    public String getName() {
-        return fName;
-    }
-
-    /**
-     * Update the entry name
-     * @param execName the updated entry name
-     */
-    public void setName(String execName) {
-        fName = execName;
-    }
-
-    @Override
-    public long getStartTime() {
-        return fStartTime;
-    }
-
-    @Override
-    public long getEndTime() {
-        return fEndTime;
-    }
-
-    @Override
-    public boolean hasTimeEvents() {
-        return true;
-    }
-
-    @Override
-    public Iterator<ITimeEvent> getTimeEventsIterator() {
-        return new EventIterator(fEventList, fZoomedEventList);
-    }
-
-    @Override
-    public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
-        return new EventIterator(fEventList, fZoomedEventList, startTime, stopTime);
-    }
-
-    /**
-     * Get the quark of the attribute matching this thread's TID
-     *
-     * @return The quark
-     */
-    public int getThreadQuark() {
-        return fThreadQuark;
-    }
-
-    /**
-     * Get the CTF trace object
-     *
-     * @return The trace
-     */
-    public LttngKernelTrace getTrace() {
-        return fTrace;
+        fThreadQuark = quark;
     }
 
     /**
@@ -145,6 +59,11 @@ public class ControlFlowEntry implements ITimeGraphEntry {
         return fThreadId;
     }
 
+    @Override
+    public LttngKernelTrace getTrace() {
+        return (LttngKernelTrace) super.getTrace();
+    }
+
     /**
      * Get this thread's parent TID
      *
@@ -155,54 +74,12 @@ public class ControlFlowEntry implements ITimeGraphEntry {
     }
 
     /**
-     * Add an event to this process's timeline
-     *
-     * @param event
-     *            The time event
-     */
-    public void addEvent(ITimeEvent event) {
-        long start = event.getTime();
-        long end = start + event.getDuration();
-        synchronized (fEventList) {
-            fEventList.add(event);
-            if (fStartTime == -1 || start < fStartTime) {
-                fStartTime = start;
-            }
-            if (fEndTime == -1 || end > fEndTime) {
-                fEndTime = end;
-            }
-        }
-    }
-
-    /**
-     * Set the general event list of this entry
-     *
-     * @param eventList
-     *            The list of time events
-     */
-    public void setEventList(List<ITimeEvent> eventList) {
-        fEventList = eventList;
-    }
-
-    /**
-     * Set the zoomed event list of this entry
+     * Get the quark of the attribute matching this thread's TID
      *
-     * @param eventList
-     *            The list of time events
+     * @return The quark
      */
-    public void setZoomedEventList(List<ITimeEvent> eventList) {
-        fZoomedEventList = eventList;
+    public int getThreadQuark() {
+        return fThreadQuark;
     }
 
-    /**
-     * Add a child entry to this one (to show relationships between processes as
-     * a tree)
-     *
-     * @param child
-     *            The child entry
-     */
-    public void addChild(ControlFlowEntry child) {
-        child.fParent = this;
-        fChildren.add(child);
-    }
 }
diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEvent.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowEvent.java
deleted file mode 100644 (file)
index b84f5dd..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *   Patrick Tasse - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow;
-
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent;
-
-/**
- * Time Event specific to the control flow view
- */
-public class ControlFlowEvent extends TimeEvent {
-
-    private final int fStatus;
-
-    /**
-     * Constructor
-     *
-     * @param entry
-     *            The entry to which this time event is assigned
-     * @param time
-     *            The timestamp of this event
-     * @param duration
-     *            The duration of this event
-     * @param status
-     *            The status assigned to the event
-     */
-    public ControlFlowEvent(ITimeGraphEntry entry, long time, long duration,
-            int status) {
-        super(entry, time, duration);
-        fStatus = status;
-    }
-
-    /**
-     * Get this event's status
-     *
-     * @return The integer matching this status
-     */
-    public int getStatus() {
-        return fStatus;
-    }
-
-    @Override
-    public String toString() {
-        return "ControlFlowEvent start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + " status=" + fStatus; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-    }
-}
index 6ded4d72274121785b7aadd0c50ce03f475516cf..cb148e03d1febdbc998f72f5e9e9572aa23b1dca 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
+ * Copyright (c) 2012, 2013 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
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
+ *   Geneviève Bastien - Move code to provide base classes for time graph view
  *******************************************************************************/
 
 package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow;
@@ -30,6 +31,8 @@ import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.GC;
@@ -42,30 +45,38 @@ import org.eclipse.swt.graphics.Rectangle;
 public class ControlFlowPresentationProvider extends TimeGraphPresentationProvider {
 
     private enum State {
-        UNKNOWN      (new RGB(100, 100, 100)),
-        WAIT_BLOCKED (new RGB(200, 200,   0)),
-        WAIT_FOR_CPU (new RGB(200, 100,   0)),
-        USERMODE     (new RGB(  0, 200,   0)),
-        SYSCALL      (new RGB(  0,   0, 200)),
-        INTERRUPTED  (new RGB(200,   0, 100));
+        UNKNOWN        (new RGB(100, 100, 100)),
+        WAIT_BLOCKED   (new RGB(200, 200, 0)),
+        WAIT_FOR_CPU   (new RGB(200, 100, 0)),
+        USERMODE       (new RGB(0,   200, 0)),
+        SYSCALL        (new RGB(0,     0, 200)),
+        INTERRUPTED    (new RGB(200,   0, 100));
 
         public final RGB rgb;
 
-        private State (RGB rgb) {
+        private State(RGB rgb) {
             this.rgb = rgb;
         }
+
     }
 
-    @Override
-    public String getStateTypeName() {
-        return Messages.ControlFlowView_stateTypeName;
+    /**
+     * Default constructor
+     */
+    public ControlFlowPresentationProvider() {
+        super(Messages.ControlFlowView_stateTypeName);
+    }
+
+    private static State[] getStateValues() {
+        return State.values();
     }
 
     @Override
     public StateItem[] getStateTable() {
-        StateItem[] stateTable = new StateItem[State.values().length];
+        State[] states = getStateValues();
+        StateItem[] stateTable = new StateItem[states.length];
         for (int i = 0; i < stateTable.length; i++) {
-            State state = State.values()[i];
+            State state = states[i];
             stateTable[i] = new StateItem(state.rgb, state.toString());
         }
         return stateTable;
@@ -73,8 +84,8 @@ public class ControlFlowPresentationProvider extends TimeGraphPresentationProvid
 
     @Override
     public int getStateTableIndex(ITimeEvent event) {
-        if (event instanceof ControlFlowEvent) {
-            int status = ((ControlFlowEvent) event).getStatus();
+        if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
+            int status = ((TimeEvent) event).getValue();
             return getMatchingState(status).ordinal();
         }
         return TRANSPARENT;
@@ -82,9 +93,11 @@ public class ControlFlowPresentationProvider extends TimeGraphPresentationProvid
 
     @Override
     public String getEventName(ITimeEvent event) {
-        if (event instanceof ControlFlowEvent) {
-            int status = ((ControlFlowEvent) event).getStatus();
-            return getMatchingState(status).toString();
+        if (event instanceof TimeEvent) {
+            TimeEvent ev = (TimeEvent) event;
+            if (ev.hasValue()) {
+                return getMatchingState(ev.getValue()).toString();
+            }
         }
         return Messages.ControlFlowView_multipleStates;
     }
@@ -109,54 +122,58 @@ public class ControlFlowPresentationProvider extends TimeGraphPresentationProvid
     @Override
     public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event) {
         Map<String, String> retMap = new LinkedHashMap<String, String>();
-        if (event instanceof ControlFlowEvent) {
-            ControlFlowEntry entry = (ControlFlowEntry) event.getEntry();
+
+        if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
+            TimeGraphEntry entry = (TimeGraphEntry) event.getEntry();
             ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
-            int tid = entry.getThreadId();
-
-            try {
-                //Find every CPU first, then get the current thread
-                int cpusQuark = ssq.getQuarkAbsolute(Attributes.CPUS);
-                List<Integer> cpuQuarks = ssq.getSubAttributes(cpusQuark, false);
-                for (Integer cpuQuark : cpuQuarks) {
-                    int currentThreadQuark = ssq.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
-                    ITmfStateInterval interval = ssq.querySingleState(event.getTime(), currentThreadQuark);
-                    if (!interval.getStateValue().isNull()) {
-                        ITmfStateValue state = interval.getStateValue();
-                        int currentThreadId = state.unboxInt();
-                        if (tid == currentThreadId) {
-                            retMap.put(Messages.ControlFlowView_attributeCpuName, ssq.getAttributeName(cpuQuark));
-                            break;
-                        }
-                    }
-                }
+            if (entry instanceof ControlFlowEntry) {
+                ControlFlowEntry entry2 = (ControlFlowEntry) entry;
+                int tid = entry2.getThreadId();
 
-            } catch (AttributeNotFoundException e) {
-                e.printStackTrace();
-            } catch (TimeRangeException e) {
-                e.printStackTrace();
-            } catch (StateValueTypeException e) {
-                e.printStackTrace();
-            } catch (StateSystemDisposedException e) {
-                /* Ignored */
-            }
-            int status = ((ControlFlowEvent) event).getStatus();
-            if (status == StateValues.PROCESS_STATUS_RUN_SYSCALL) {
                 try {
-                    int syscallQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.SYSTEM_CALL);
-                    ITmfStateInterval value = ssq.querySingleState(event.getTime(), syscallQuark);
-                    if (!value.getStateValue().isNull()) {
-                        ITmfStateValue state = value.getStateValue();
-                        retMap.put(Messages.ControlFlowView_attributeSyscallName, state.toString());
+                    // Find every CPU first, then get the current thread
+                    int cpusQuark = ssq.getQuarkAbsolute(Attributes.CPUS);
+                    List<Integer> cpuQuarks = ssq.getSubAttributes(cpusQuark, false);
+                    for (Integer cpuQuark : cpuQuarks) {
+                        int currentThreadQuark = ssq.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
+                        ITmfStateInterval interval = ssq.querySingleState(event.getTime(), currentThreadQuark);
+                        if (!interval.getStateValue().isNull()) {
+                            ITmfStateValue state = interval.getStateValue();
+                            int currentThreadId = state.unboxInt();
+                            if (tid == currentThreadId) {
+                                retMap.put(Messages.ControlFlowView_attributeCpuName, ssq.getAttributeName(cpuQuark));
+                                break;
+                            }
+                        }
                     }
 
                 } catch (AttributeNotFoundException e) {
                     e.printStackTrace();
                 } catch (TimeRangeException e) {
                     e.printStackTrace();
+                } catch (StateValueTypeException e) {
+                    e.printStackTrace();
                 } catch (StateSystemDisposedException e) {
                     /* Ignored */
                 }
+                int status = ((TimeEvent) event).getValue();
+                if (status == StateValues.PROCESS_STATUS_RUN_SYSCALL) {
+                    try {
+                        int syscallQuark = ssq.getQuarkRelative(entry2.getThreadQuark(), Attributes.SYSTEM_CALL);
+                        ITmfStateInterval value = ssq.querySingleState(event.getTime(), syscallQuark);
+                        if (!value.getStateValue().isNull()) {
+                            ITmfStateValue state = value.getStateValue();
+                            retMap.put(Messages.ControlFlowView_attributeSyscallName, state.toString());
+                        }
+
+                    } catch (AttributeNotFoundException e) {
+                        e.printStackTrace();
+                    } catch (TimeRangeException e) {
+                        e.printStackTrace();
+                    } catch (StateSystemDisposedException e) {
+                        /* Ignored */
+                    }
+                }
             }
         }
 
@@ -168,12 +185,13 @@ public class ControlFlowPresentationProvider extends TimeGraphPresentationProvid
         if (bounds.width <= gc.getFontMetrics().getAverageCharWidth()) {
             return;
         }
-        if (!(event instanceof ControlFlowEvent)) {
+        if (!(event instanceof TimeEvent)) {
             return;
         }
         ControlFlowEntry entry = (ControlFlowEntry) event.getEntry();
         ITmfStateSystem ss = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
-        int status = ((ControlFlowEvent) event).getStatus();
+        int status = ((TimeEvent) event).getValue();
+
         if (status != StateValues.PROCESS_STATUS_RUN_SYSCALL) {
             return;
         }
@@ -193,5 +211,4 @@ public class ControlFlowPresentationProvider extends TimeGraphPresentationProvid
             /* Ignored */
         }
     }
-
 }
index e9181da46b3878450460612b5119be5b95f49457..da4666f4b83391bb719f20c5da8815e320dcec6d 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
+ * Copyright (c) 2012, 2013 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
@@ -8,75 +8,42 @@
  *
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
- *   Bernd Hufmann - Updated signal handling
+ *   Geneviève Bastien - Move code to provide base classes for time graph view
  *******************************************************************************/
 
 package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.List;
 
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
 import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Messages;
 import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngKernelTrace;
-import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
 import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
 import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
 import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
 import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
-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.TmfTraceClosedSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
 import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
 import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
-import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
-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.views.TmfView;
-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.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.views.timegraph.AbstractTimeGraphView;
 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.TimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
-import org.eclipse.swt.SWT;
-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.ui.IActionBars;
 
 /**
  * The Control Flow view main object
  *
  */
-public class ControlFlowView extends TmfView {
+public class ControlFlowView extends AbstractTimeGraphView {
 
     // ------------------------------------------------------------------------
     // Constants
@@ -87,13 +54,13 @@ public class ControlFlowView extends TmfView {
      */
     public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.controlflow"; //$NON-NLS-1$
 
-    private static final String PROCESS_COLUMN    = Messages.ControlFlowView_processColumn;
-    private static final String TID_COLUMN        = Messages.ControlFlowView_tidColumn;
-    private static final String PTID_COLUMN       = Messages.ControlFlowView_ptidColumn;
+    private static final String PROCESS_COLUMN = Messages.ControlFlowView_processColumn;
+    private static final String TID_COLUMN = Messages.ControlFlowView_tidColumn;
+    private static final String PTID_COLUMN = Messages.ControlFlowView_ptidColumn;
     private static final String BIRTH_TIME_COLUMN = Messages.ControlFlowView_birthTimeColumn;
-    private static final String TRACE_COLUMN      = Messages.ControlFlowView_traceColumn;
+    private static final String TRACE_COLUMN = Messages.ControlFlowView_traceColumn;
 
-    private final String[] COLUMN_NAMES = new String[] {
+    private static final String[] COLUMN_NAMES = new String[] {
             PROCESS_COLUMN,
             TID_COLUMN,
             PTID_COLUMN,
@@ -101,151 +68,49 @@ public class ControlFlowView extends TmfView {
             TRACE_COLUMN
     };
 
-    private final String[] FILTER_COLUMN_NAMES = new String[] {
+    private static final String[] FILTER_COLUMN_NAMES = new String[] {
             PROCESS_COLUMN,
             TID_COLUMN
     };
 
-    /**
-     * Redraw state enum
-     */
-    private enum State { IDLE, BUSY, PENDING }
-
-    // ------------------------------------------------------------------------
-    // Fields
-    // ------------------------------------------------------------------------
-
-    // The timegraph combo
-    private TimeGraphCombo fTimeGraphCombo;
-
-    // The selected trace
-    private ITmfTrace fTrace;
-
-    // The timegraph entry list
-    private ArrayList<ControlFlowEntry> fEntryList;
-
-    // The trace to entry list hash map
-    final private HashMap<ITmfTrace, ArrayList<ControlFlowEntry>> fEntryListMap = new HashMap<ITmfTrace, ArrayList<ControlFlowEntry>>();
-
-    // The trace to build thread hash map
-    final private HashMap<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<ITmfTrace, BuildThread>();
-
-    // The start time
-    private long fStartTime;
-
-    // The end time
-    private long fEndTime;
-
-    // The display width
-    private final int fDisplayWidth;
-
-    // The zoom thread
-    private ZoomThread fZoomThread;
-
-    // The next resource action
-    private Action fNextResourceAction;
-
-    // The previous resource action
-    private Action fPreviousResourceAction;
-
-    // A comparator class
-    private final ControlFlowEntryComparator fControlFlowEntryComparator = new ControlFlowEntryComparator();
-
-    // The redraw state used to prevent unnecessary queuing of display runnables
-    private State fRedrawState = State.IDLE;
-
-    // The redraw synchronization object
-    final private Object fSyncObj = new Object();
-
     // ------------------------------------------------------------------------
-    // Classes
+    // Constructors
     // ------------------------------------------------------------------------
 
-    private class TreeContentProvider implements ITreeContentProvider {
-
-        @Override
-        public void dispose() {
-        }
-
-        @Override
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-        }
-
-        @Override
-        public Object[] getElements(Object inputElement) {
-            return (ITimeGraphEntry[]) inputElement;
-        }
-
-        @Override
-        public Object[] getChildren(Object parentElement) {
-            ITimeGraphEntry entry = (ITimeGraphEntry) parentElement;
-            List<? extends ITimeGraphEntry> children = entry.getChildren();
-            return children.toArray(new ITimeGraphEntry[children.size()]);
-        }
-
-        @Override
-        public Object getParent(Object element) {
-            ITimeGraphEntry entry = (ITimeGraphEntry) element;
-            return entry.getParent();
-        }
-
-        @Override
-        public boolean hasChildren(Object element) {
-            ITimeGraphEntry entry = (ITimeGraphEntry) element;
-            return entry.hasChildren();
-        }
-
+    /**
+     * Constructor
+     */
+    public ControlFlowView() {
+        super(ID, COLUMN_NAMES, FILTER_COLUMN_NAMES, new ControlFlowPresentationProvider());
+        setTreeLabelProvider(new ControlFlowTreeLabelProvider());
+        setEntryComparator(new ControlFlowEntryComparator());
     }
 
-    private class TreeLabelProvider implements ITableLabelProvider {
-
-        @Override
-        public void addListener(ILabelProviderListener listener) {
-        }
-
-        @Override
-        public void dispose() {
-        }
-
-        @Override
-        public boolean isLabelProperty(Object element, String property) {
-            return false;
-        }
-
-        @Override
-        public void removeListener(ILabelProviderListener listener) {
-        }
+    @Override
+    protected String getNextText() {
+        return Messages.ControlFlowView_nextProcessActionNameText;
+    }
 
-        @Override
-        public Image getColumnImage(Object element, int columnIndex) {
-            return null;
-        }
+    @Override
+    protected String getNextTooltip() {
+        return Messages.ControlFlowView_nextProcessActionToolTipText;
+    }
 
-        @Override
-        public String getColumnText(Object element, int columnIndex) {
-            ControlFlowEntry entry = (ControlFlowEntry) element;
-            if (columnIndex == 0) {
-                return entry.getName();
-            } else if (columnIndex == 1) {
-                return Integer.toString(entry.getThreadId());
-            } else if (columnIndex == 2) {
-                if (entry.getParentThreadId() > 0) {
-                    return Integer.toString(entry.getParentThreadId());
-                }
-            } else if (columnIndex == 3) {
-                return Utils.formatTime(entry.getStartTime(), TimeFormat.CALENDAR, Resolution.NANOSEC);
-            } else if (columnIndex == 4) {
-                return entry.getTrace().getName();
-            }
-            return ""; //$NON-NLS-1$
-        }
+    @Override
+    protected String getPrevText() {
+        return Messages.ControlFlowView_previousProcessActionNameText;
+    }
 
+    @Override
+    protected String getPrevTooltip() {
+        return Messages.ControlFlowView_previousProcessActionToolTipText;
     }
 
     private static class ControlFlowEntryComparator implements Comparator<ITimeGraphEntry> {
 
         @Override
         public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {
+
             int result = 0;
 
             if ((o1 instanceof ControlFlowEntry) && (o2 instanceof ControlFlowEntry)) {
@@ -268,357 +133,50 @@ public class ControlFlowView extends TmfView {
         }
     }
 
-    private class BuildThread extends Thread {
-        private final ITmfTrace fBuildTrace;
-        private final IProgressMonitor fMonitor;
-
-        public BuildThread(ITmfTrace trace) {
-            super("ControlFlowView build"); //$NON-NLS-1$
-            fBuildTrace = trace;
-            fMonitor = new NullProgressMonitor();
-        }
-
-        @Override
-        public void run() {
-            buildEventList(fBuildTrace, fMonitor);
-            synchronized (fBuildThreadMap) {
-                fBuildThreadMap.remove(this);
-            }
-        }
-
-        public void cancel() {
-            fMonitor.setCanceled(true);
-        }
-    }
-
-    private class ZoomThread extends Thread {
-        private final ArrayList<ControlFlowEntry> fZoomEntryList;
-        private final long fZoomStartTime;
-        private final long fZoomEndTime;
-        private final long fResolution;
-        private final IProgressMonitor fMonitor;
-
-        public ZoomThread(ArrayList<ControlFlowEntry> entryList, long startTime, long endTime) {
-            super("ControlFlowView zoom"); //$NON-NLS-1$
-            fZoomEntryList = entryList;
-            fZoomStartTime = startTime;
-            fZoomEndTime = endTime;
-            fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
-            fMonitor = new NullProgressMonitor();
-        }
-
-        @Override
-        public void run() {
-            if (fZoomEntryList == null) {
-                return;
-            }
-            for (ControlFlowEntry entry : fZoomEntryList) {
-                if (fMonitor.isCanceled()) {
-                    break;
-                }
-                zoom(entry, fMonitor);
-            }
-        }
-
-        private void zoom(ControlFlowEntry entry, IProgressMonitor monitor) {
-            if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {
-                entry.setZoomedEventList(null);
-            } else {
-                List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor);
-                if (zoomedEventList != null) {
-                    entry.setZoomedEventList(zoomedEventList);
-                }
-            }
-            redraw();
-            for (ControlFlowEntry child : entry.getChildren()) {
-                if (fMonitor.isCanceled()) {
-                    return;
-                }
-                zoom(child, monitor);
-            }
-        }
-
-        public void cancel() {
-            fMonitor.setCanceled(true);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Constructors
-    // ------------------------------------------------------------------------
-
     /**
-     * Constructor
-     */
-    public ControlFlowView() {
-        super(ID);
-        fDisplayWidth = Display.getDefault().getBounds().width;
-    }
-
-    // ------------------------------------------------------------------------
-    // ViewPart
-    // ------------------------------------------------------------------------
-
-    @Override
-    public void createPartControl(Composite parent) {
-        fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE);
-
-        fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider());
-
-        fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider());
-
-        fTimeGraphCombo.setTimeGraphProvider(new ControlFlowPresentationProvider());
-
-        fTimeGraphCombo.setTreeColumns(COLUMN_NAMES);
-
-        fTimeGraphCombo.setFilterContentProvider(new TreeContentProvider());
-
-        fTimeGraphCombo.setFilterLabelProvider(new TreeLabelProvider());
-
-        fTimeGraphCombo.setFilterColumns(FILTER_COLUMN_NAMES);
-
-        fTimeGraphCombo.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(ControlFlowView.this, range, time));
-                if (fZoomThread != null) {
-                    fZoomThread.cancel();
-                }
-                startZoomThread(startTime, endTime);
-            }
-        });
-
-        fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
-            @Override
-            public void timeSelected(TimeGraphTimeEvent event) {
-                long time = event.getTime();
-                broadcast(new TmfTimeSynchSignal(ControlFlowView.this, new CtfTmfTimestamp(time)));
-            }
-        });
-
-        fTimeGraphCombo.addSelectionListener(new ITimeGraphSelectionListener() {
-            @Override
-            public void selectionChanged(TimeGraphSelectionEvent event) {
-                //ITimeGraphEntry selection = event.getSelection();
-            }
-        });
-
-        fTimeGraphCombo.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
-
-        // View Action Handling
-        makeActions();
-        contributeToActionBars();
-
-        ITmfTrace trace = getActiveTrace();
-        if (trace != null) {
-            traceSelected(new TmfTraceSelectedSignal(this, trace));
-        }
-
-        // make selection available to other views
-        getSite().setSelectionProvider(fTimeGraphCombo.getTreeViewer());
-    }
-
-    @Override
-    public void setFocus() {
-        fTimeGraphCombo.setFocus();
-    }
-
-    // ------------------------------------------------------------------------
-    // Signal handlers
-    // ------------------------------------------------------------------------
-    /**
-     * Handler for the trace opened signal.
-     * @param signal
-     *            The incoming signal
-     * @since 2.0
-     */
-    @TmfSignalHandler
-    public void traceOpened(TmfTraceOpenedSignal signal) {
-        fTrace = signal.getTrace();
-        loadTrace();
-    }
-
-    /**
-     * Handler for the trace selected signal
+     * @author gbastien
      *
-     * @param signal
-     *            The incoming signal
      */
-    @TmfSignalHandler
-    public void traceSelected(final TmfTraceSelectedSignal signal) {
-        if (signal.getTrace() == fTrace) {
-            return;
-        }
-        fTrace = signal.getTrace();
-        loadTrace();
-    }
+    protected static class ControlFlowTreeLabelProvider extends TreeLabelProvider {
 
-    /**
-     * Trace is closed: clear the data structures and the view
-     *
-     * @param signal the signal received
-     */
-    @TmfSignalHandler
-    public void traceClosed(final TmfTraceClosedSignal signal) {
-        synchronized (fBuildThreadMap) {
-            BuildThread buildThread = fBuildThreadMap.remove(signal.getTrace());
-            if (buildThread != null) {
-                buildThread.cancel();
-            }
-        }
-        synchronized (fEntryListMap) {
-            fEntryListMap.remove(signal.getTrace());
-        }
-        if (signal.getTrace() == fTrace) {
-            fTrace = null;
-            fStartTime = 0;
-            fEndTime = 0;
-            if (fZoomThread != null) {
-                fZoomThread.cancel();
-            }
-            refresh();
-        }
-    }
-
-    /**
-     * Handler for the synch signal
-     *
-     * @param signal
-     *            The signal that's received
-     */
-    @TmfSignalHandler
-    public void synchToTime(final TmfTimeSynchSignal signal) {
-        if (signal.getSource() == this || fTrace == null) {
-            return;
-        }
-        final long time = signal.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+        @Override
+        public String getColumnText(Object element, int columnIndex) {
+            ControlFlowEntry entry = (ControlFlowEntry) element;
 
-        int thread = -1;
-        for (ITmfTrace trace : TmfTraceManager.getTraceSet(fTrace)) {
-            if (thread > 0) {
-                break;
-            }
-            if (trace instanceof LttngKernelTrace) {
-                LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) trace;
-                ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
-                if (time >= ssq.getStartTime() && time <= ssq.getCurrentEndTime()) {
-                    List<Integer> currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD);  //$NON-NLS-1$
-                    for (int currentThreadQuark : currentThreadQuarks) {
-                        try {
-                            ITmfStateInterval currentThreadInterval = ssq.querySingleState(time, currentThreadQuark);
-                            int currentThread = currentThreadInterval.getStateValue().unboxInt();
-                            if (currentThread > 0) {
-                                int statusQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThread), Attributes.STATUS);
-                                ITmfStateInterval statusInterval = ssq.querySingleState(time, statusQuark);
-                                if (statusInterval.getStartTime() == time) {
-                                    thread = currentThread;
-                                    break;
-                                }
-                            }
-                        } catch (AttributeNotFoundException e) {
-                            e.printStackTrace();
-                        } catch (TimeRangeException e) {
-                            e.printStackTrace();
-                        } catch (StateValueTypeException e) {
-                            e.printStackTrace();
-                        } catch (StateSystemDisposedException e) {
-                            /* Ignored */
-                        }
-                    }
+            if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_processColumn)) {
+                return entry.getName();
+            } else if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_tidColumn)) {
+                return Integer.toString(entry.getThreadId());
+            } else if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_ptidColumn)) {
+                if (entry.getParentThreadId() > 0) {
+                    return Integer.toString(entry.getParentThreadId());
                 }
+            } else if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_birthTimeColumn)) {
+                return Utils.formatTime(entry.getStartTime(), TimeFormat.CALENDAR, Resolution.NANOSEC);
+            } else if (COLUMN_NAMES[columnIndex].equals(Messages.ControlFlowView_traceColumn)) {
+                return entry.getTrace().getName();
             }
+            return ""; //$NON-NLS-1$
         }
-        final int selectedThread = thread;
-
-        Display.getDefault().asyncExec(new Runnable() {
-            @Override
-            public void run() {
-                if (fTimeGraphCombo.isDisposed()) {
-                    return;
-                }
-                fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);
-                startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
-
-                if (selectedThread > 0) {
-                    for (Object element : fTimeGraphCombo.getTimeGraphViewer().getExpandedElements()) {
-                        if (element instanceof ControlFlowEntry) {
-                            ControlFlowEntry entry = (ControlFlowEntry) element;
-                            if (entry.getThreadId() == selectedThread) {
-                                fTimeGraphCombo.setSelection(entry);
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        });
-    }
 
-    /**
-     * Handler for the range sync signal
-     *
-     * @param signal
-     *            The signal that's received
-     */
-    @TmfSignalHandler
-    public void synchToRange(final TmfRangeSynchSignal signal) {
-        if (signal.getSource() == this || fTrace == null) {
-            return;
-        }
-        if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) {
-            return;
-        }
-        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()) {
-                    return;
-                }
-                fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
-                fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);
-                startZoomThread(startTime, endTime);
-            }
-        });
     }
 
     // ------------------------------------------------------------------------
     // Internal
     // ------------------------------------------------------------------------
 
-    private void loadTrace() {
-        synchronized (fEntryListMap) {
-            fEntryList = fEntryListMap.get(fTrace);
-            if (fEntryList == null) {
-                synchronized (fBuildThreadMap) {
-                    BuildThread buildThread = new BuildThread(fTrace);
-                    fBuildThreadMap.put(fTrace, buildThread);
-                    buildThread.start();
-                }
-            } else {
-                fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                refresh();
-            }
-        }
-    }
+    @Override
+    protected void buildEventList(final ITmfTrace trace, IProgressMonitor monitor) {
+        setStartTime(Long.MAX_VALUE);
+        setEndTime(Long.MIN_VALUE);
 
-    private void buildEventList(final ITmfTrace trace, IProgressMonitor monitor) {
-        fStartTime = Long.MAX_VALUE;
-        fEndTime = Long.MIN_VALUE;
-        ArrayList<ControlFlowEntry> rootList = new ArrayList<ControlFlowEntry>();
-        for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) {
+        ArrayList<TimeGraphEntry> rootList = new ArrayList<TimeGraphEntry>();
+        for (ITmfTrace aTrace : fTraceManager.getActiveTraceSet()) {
             if (monitor.isCanceled()) {
                 return;
             }
             if (aTrace instanceof LttngKernelTrace) {
-                ArrayList<ControlFlowEntry> entryList = new ArrayList<ControlFlowEntry>();
+                ArrayList<TimeGraphEntry> entryList = new ArrayList<TimeGraphEntry>();
                 LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) aTrace;
                 ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
                 if (!ssq.waitUntilBuilt()) {
@@ -626,8 +184,8 @@ public class ControlFlowView extends TmfView {
                 }
                 long start = ssq.getStartTime();
                 long end = ssq.getCurrentEndTime() + 1;
-                fStartTime = Math.min(fStartTime, start);
-                fEndTime = Math.max(fEndTime, end);
+                setStartTime(Math.min(getStartTime(), start));
+                setEndTime(Math.max(getEndTime(), end));
                 List<Integer> threadQuarks = ssq.getQuarks(Attributes.THREADS, "*"); //$NON-NLS-1$
                 for (int threadQuark : threadQuarks) {
                     if (monitor.isCanceled()) {
@@ -651,11 +209,12 @@ public class ControlFlowView extends TmfView {
                             continue;
                         }
                         int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID);
-                        List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end - 1); // use monitor when available in api
+                        List<ITmfStateInterval> execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end - 1);
+                        // use monitor when available in api
                         if (monitor.isCanceled()) {
                             return;
                         }
-                        ControlFlowEntry entry = null;
+                        TimeGraphEntry entry = null;
                         for (ITmfStateInterval execNameInterval : execNameIntervals) {
                             if (monitor.isCanceled()) {
                                 return;
@@ -674,7 +233,8 @@ public class ControlFlowView extends TmfView {
                                     entry = new ControlFlowEntry(threadQuark, ctfKernelTrace, execName, threadId, ppid, startTime, endTime);
                                     entryList.add(entry);
                                 } else {
-                                    // update the name of the entry to the latest execName
+                                    // update the name of the entry to the
+                                    // latest execName
                                     entry.setName(execName);
                                 }
                                 entry.addEvent(new TimeEvent(entry, startTime, endTime - startTime));
@@ -694,15 +254,14 @@ public class ControlFlowView extends TmfView {
                 }
                 buildTree(entryList, rootList);
             }
-            Collections.sort(rootList, fControlFlowEntryComparator);
-            synchronized (fEntryListMap) {
-                fEntryListMap.put(trace, (ArrayList<ControlFlowEntry>) rootList.clone());
-            }
-            if (trace == fTrace) {
+            Collections.sort(rootList, getEntryComparator());
+            putEntryList(trace, (ArrayList<TimeGraphEntry>) rootList.clone());
+
+            if (trace.equals(getTrace())) {
                 refresh();
             }
         }
-        for (ControlFlowEntry entry : rootList) {
+        for (TimeGraphEntry entry : rootList) {
             if (monitor.isCanceled()) {
                 return;
             }
@@ -710,12 +269,14 @@ public class ControlFlowView extends TmfView {
         }
     }
 
-    private static void buildTree(ArrayList<ControlFlowEntry> entryList,
-            ArrayList<ControlFlowEntry> rootList) {
-        for (ControlFlowEntry entry : entryList) {
+    private static void buildTree(ArrayList<TimeGraphEntry> entryList,
+            ArrayList<TimeGraphEntry> rootList) {
+        for (TimeGraphEntry listentry : entryList) {
+            ControlFlowEntry entry = (ControlFlowEntry) listentry;
             boolean root = true;
             if (entry.getParentThreadId() > 0) {
-                for (ControlFlowEntry parent : entryList) {
+                for (TimeGraphEntry parententry : entryList) {
+                    ControlFlowEntry parent = (ControlFlowEntry) parententry;
                     if (parent.getThreadId() == entry.getParentThreadId() &&
                             entry.getStartTime() >= parent.getStartTime() &&
                             entry.getStartTime() <= parent.getEndTime()) {
@@ -731,37 +292,41 @@ public class ControlFlowView extends TmfView {
         }
     }
 
-    private void buildStatusEvents(ITmfTrace trace, ControlFlowEntry entry, IProgressMonitor monitor) {
+    private void buildStatusEvents(ITmfTrace trace, TimeGraphEntry entry, IProgressMonitor monitor) {
         ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
+
         long start = ssq.getStartTime();
         long end = ssq.getCurrentEndTime() + 1;
-        long resolution = Math.max(1, (end - start) / fDisplayWidth);
+        long resolution = Math.max(1, (end - start) / getDisplayWidth());
         List<ITimeEvent> eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution, monitor);
         if (monitor.isCanceled()) {
             return;
         }
         entry.setEventList(eventList);
-        if (trace == fTrace) {
+        if (trace.equals(getTrace())) {
             redraw();
         }
         for (ITimeGraphEntry child : entry.getChildren()) {
             if (monitor.isCanceled()) {
                 return;
             }
-            buildStatusEvents(trace, (ControlFlowEntry) child, monitor);
+            buildStatusEvents(trace, (TimeGraphEntry) child, monitor);
         }
     }
 
-    private static List<ITimeEvent> getEventList(ControlFlowEntry entry,
-            long startTime, long endTime, long resolution,
-            IProgressMonitor monitor) {
+    @Override
+    protected List<ITimeEvent> getEventList(TimeGraphEntry tgentry, long startTime, long endTime, long resolution, IProgressMonitor monitor) {
+        List<ITimeEvent> eventList = null;
+        if (!(tgentry instanceof ControlFlowEntry)) {
+            return eventList;
+        }
+        ControlFlowEntry entry = (ControlFlowEntry) tgentry;
         final long realStart = Math.max(startTime, entry.getStartTime());
         final long realEnd = Math.min(endTime, entry.getEndTime());
         if (realEnd <= realStart) {
             return null;
         }
         ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
-        List<ITimeEvent> eventList = null;
         try {
             int statusQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.STATUS);
             List<ITmfStateInterval> statusIntervals = ssq.queryHistoryRange(statusQuark, realStart, realEnd - 1, resolution, monitor);
@@ -782,7 +347,7 @@ public class ControlFlowView extends TmfView {
                 if (lastEndTime != time && lastEndTime != -1) {
                     eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
                 }
-                eventList.add(new ControlFlowEvent(entry, time, duration, status));
+                eventList.add(new TimeEvent(entry, time, duration, status));
                 lastEndTime = time + duration;
             }
         } catch (AttributeNotFoundException e) {
@@ -795,104 +360,68 @@ public class ControlFlowView extends TmfView {
         return eventList;
     }
 
-    private void refresh() {
-        Display.getDefault().asyncExec(new Runnable() {
-            @Override
-            public void run() {
-                if (fTimeGraphCombo.isDisposed()) {
-                    return;
-                }
-                ITimeGraphEntry[] entries = null;
-                synchronized (fEntryListMap) {
-                    fEntryList = fEntryListMap.get(fTrace);
-                    if (fEntryList == null) {
-                        fEntryList = new ArrayList<ControlFlowEntry>();
+    /**
+     * Returns a value corresponding to the selected entry.
+     *
+     * Used in conjunction with selectEntry to change the selected entry. If one
+     * of these methods is overridden in child class, then both should be.
+     *
+     * @param time
+     *            The currently selected time
+     * @return a value identifying the entry
+     */
+    private int getSelectionValue(long time) {
+        int thread = -1;
+        for (ITmfTrace trace : fTraceManager.getActiveTraceSet()) {
+            if (thread > 0) {
+                break;
+            }
+            if (trace instanceof LttngKernelTrace) {
+                LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) trace;
+                ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
+                if (time >= ssq.getStartTime() && time <= ssq.getCurrentEndTime()) {
+                    List<Integer> currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$
+                    for (int currentThreadQuark : currentThreadQuarks) {
+                        try {
+                            ITmfStateInterval currentThreadInterval = ssq.querySingleState(time, currentThreadQuark);
+                            int currentThread = currentThreadInterval.getStateValue().unboxInt();
+                            if (currentThread > 0) {
+                                int statusQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThread), Attributes.STATUS);
+                                ITmfStateInterval statusInterval = ssq.querySingleState(time, statusQuark);
+                                if (statusInterval.getStartTime() == time) {
+                                    thread = currentThread;
+                                    break;
+                                }
+                            }
+                        } catch (AttributeNotFoundException e) {
+                            e.printStackTrace();
+                        } catch (TimeRangeException e) {
+                            e.printStackTrace();
+                        } catch (StateValueTypeException e) {
+                            e.printStackTrace();
+                        } catch (StateSystemDisposedException e) {
+                            /* Ignored */
+                        }
                     }
-                    entries = fEntryList.toArray(new ITimeGraphEntry[0]);
                 }
-                Arrays.sort(entries, fControlFlowEntryComparator);
-                fTimeGraphCombo.setInput(entries);
-                fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
-
-                long timestamp = fTrace == null ? 0 : fTraceManager.getCurrentTime().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);
-
-                for (TreeColumn column : fTimeGraphCombo.getTreeViewer().getTree().getColumns()) {
-                    column.pack();
-                }
-
-                startZoomThread(startTime, endTime);
             }
-        });
+        }
+        return thread;
     }
 
-    private void redraw() {
-        synchronized (fSyncObj) {
-            if (fRedrawState == State.IDLE) {
-                fRedrawState = State.BUSY;
-            } else {
-                fRedrawState = State.PENDING;
-                return;
-            }
-        }
-        Display.getDefault().asyncExec(new Runnable() {
-            @Override
-            public void run() {
-                if (fTimeGraphCombo.isDisposed()) {
-                    return;
-                }
-                fTimeGraphCombo.redraw();
-                fTimeGraphCombo.update();
-                synchronized (fSyncObj) {
-                    if (fRedrawState == State.PENDING) {
-                        fRedrawState = State.IDLE;
-                        redraw();
-                    } else {
-                        fRedrawState = State.IDLE;
+    @Override
+    protected void synchingToTime(long time) {
+        int selected = getSelectionValue(time);
+        if (selected > 0) {
+            for (Object element : getTimeGraphCombo().getTimeGraphViewer().getExpandedElements()) {
+                if (element instanceof ControlFlowEntry) {
+                    ControlFlowEntry entry = (ControlFlowEntry) element;
+                    if (entry.getThreadId() == selected) {
+                        getTimeGraphCombo().setSelection(entry);
+                        break;
                     }
                 }
             }
-        });
-    }
-
-    private void startZoomThread(long startTime, long endTime) {
-        if (fZoomThread != null) {
-            fZoomThread.cancel();
         }
-        fZoomThread = new ZoomThread(fEntryList, startTime, endTime);
-        fZoomThread.start();
-    }
-
-    private void makeActions() {
-        fPreviousResourceAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction();
-        fPreviousResourceAction.setText(Messages.ControlFlowView_previousProcessActionNameText);
-        fPreviousResourceAction.setToolTipText(Messages.ControlFlowView_previousProcessActionToolTipText);
-        fNextResourceAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction();
-        fNextResourceAction.setText(Messages.ControlFlowView_nextProcessActionNameText);
-        fNextResourceAction.setToolTipText(Messages.ControlFlowView_nextProcessActionToolTipText);
-    }
-
-    private void contributeToActionBars() {
-        IActionBars bars = getViewSite().getActionBars();
-        fillLocalToolBar(bars.getToolBarManager());
-    }
-
-    private void fillLocalToolBar(IToolBarManager manager) {
-        manager.add(fTimeGraphCombo.getShowFilterAction());
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getShowLegendAction());
-        manager.add(new Separator());
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction());
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getPreviousEventAction());
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getNextEventAction());
-        manager.add(fPreviousResourceAction);
-        manager.add(fNextResourceAction);
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction());
-        manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction());
-        manager.add(new Separator());
     }
 }
index 5b12b8661c0077fcc1ff0c1a5984d9e794821278..34d43c4185c81234394814e2ad54f6355ad0e1c0 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
+ * Copyright (c) 2012, 2013 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
@@ -8,25 +8,20 @@
  *
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
+ *   Geneviève Bastien - Move code to provide base classes for time graph view
  *******************************************************************************/
 
 package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.resources;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
 import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngKernelTrace;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.EventIterator;
-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 entry, or row, in the resource view
  *
  * @author Patrick Tasse
  */
-public class ResourcesEntry implements ITimeGraphEntry {
+public class ResourcesEntry extends TimeGraphEntry {
 
     /** Type of resource */
     public static enum Type {
@@ -37,113 +32,88 @@ public class ResourcesEntry implements ITimeGraphEntry {
         /** Entries for IRQs */
         IRQ,
         /** Entries for Soft IRQ */
-        SOFT_IRQ }
+        SOFT_IRQ
+    }
 
-    private final int fQuark;
-    private final LttngKernelTrace fTrace;
-    private ITimeGraphEntry fParent = null;
-    private final List<ITimeGraphEntry> children = null;
-    private final String fName;
-    private final Type fType;
     private final int fId;
-    private long fStartTime;
-    private long fEndTime;
-    private List<ITimeEvent> fEventList = new ArrayList<ITimeEvent>();
-    private List<ITimeEvent> fZoomedEventList = null;
+    private final Type fType;
+    private final int fQuark;
 
     /**
-     * Standard constructor
+     * Constructor
      *
      * @param quark
-     *            The quark of the state system attribute whose state is shown
-     *            on this row
+     *            The attribute quark matching the entry
      * @param trace
-     *            The trace that this view is talking about
+     *            The trace on which we are working
+     * @param name
+     *            The exec_name of this entry
+     * @param startTime
+     *            The start time of this entry lifetime
+     * @param endTime
+     *            The end time of this entry
      * @param type
-     *            Type of entry, see the Type enum
+     *            The type of this entry
      * @param id
-     *            The integer id associated with this entry or row
+     *            The id of this entry
      */
-    public ResourcesEntry(int quark, LttngKernelTrace trace, Type type, int id) {
-        fQuark = quark;
-        fTrace = trace;
-        fType = type;
+    public ResourcesEntry(int quark, LttngKernelTrace trace, String name, long startTime, long endTime, Type type, int id) {
+        super(quark, trace, name, startTime, endTime);
         fId = id;
-        fName = type.toString() + ' ' + Integer.toString(id);
-    }
-
-    @Override
-    public ITimeGraphEntry getParent() {
-        return fParent;
-    }
-
-    @Override
-    public boolean hasChildren() {
-        return children != null && children.size() > 0;
-    }
-
-    @Override
-    public List<ITimeGraphEntry> getChildren() {
-        return children;
-    }
-
-    @Override
-    public String getName() {
-        return fName;
-    }
-
-    @Override
-    public long getStartTime() {
-        return fStartTime;
-    }
-
-    @Override
-    public long getEndTime() {
-        return fEndTime;
-    }
-
-    @Override
-    public boolean hasTimeEvents() {
-        return true;
-    }
-
-    @Override
-    public Iterator<ITimeEvent> getTimeEventsIterator() {
-        return new EventIterator(fEventList, fZoomedEventList);
-    }
-
-    @Override
-    public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
-        return new EventIterator(fEventList, fZoomedEventList, startTime, stopTime);
+        fType = type;
+        fQuark = quark;
     }
 
     /**
-     * Assign a parent entry to this one, to organize them in a tree in the
-     * view.
+     * Constructor
      *
-     * @param parent
-     *            The parent entry
+     * @param trace
+     *            The trace on which we are working
+     * @param name
+     *            The exec_name of this entry
+     * @param startTime
+     *            The start time of this entry lifetime
+     * @param endTime
+     *            The end time of this entry
+     * @param id
+     *            The id of this entry
      */
-    public void setParent(ITimeGraphEntry parent) {
-        fParent = parent;
+    public ResourcesEntry(LttngKernelTrace trace, String name, long startTime, long endTime, int id) {
+        this(-1, trace, name, startTime, endTime, Type.NULL, id);
     }
 
     /**
-     * Retrieve the attribute quark that's represented by this entry.
+     * Constructor
      *
-     * @return The integer quark
+     * @param quark
+     *            The attribute quark matching the entry
+     * @param trace
+     *            The trace on which we are working
+     * @param startTime
+     *            The start time of this entry lifetime
+     * @param endTime
+     *            The end time of this entry
+     * @param type
+     *            The type of this entry
+     * @param id
+     *            The id of this entry
      */
-    public int getQuark() {
-        return fQuark;
+    public ResourcesEntry(int quark, LttngKernelTrace trace, long startTime, long endTime, Type type, int id) {
+        this(quark, trace, type.toString() + " " + id, startTime, endTime, type, id); //$NON-NLS-1$
     }
 
     /**
-     * Retrieve the trace that is associated to this Resource view.
+     * Get the entry's id
      *
-     * @return The LTTng 2 kernel trace
+     * @return the entry's id
      */
+    public int getId() {
+        return fId;
+    }
+
+    @Override
     public LttngKernelTrace getTrace() {
-        return fTrace;
+        return (LttngKernelTrace) super.getTrace();
     }
 
     /**
@@ -156,36 +126,43 @@ public class ResourcesEntry implements ITimeGraphEntry {
     }
 
     /**
-     * Get the integer ID associated with this entry.
+     * Retrieve the attribute quark that's represented by this entry.
      *
-     * @return The ID
+     * @return The integer quark The attribute quark matching the entry
      */
-    public int getId() {
-        return fId;
+    public int getQuark() {
+        return fQuark;
     }
 
-    /**
-     * Assign the target event list to this view.
-     *
-     * @param eventList
-     *            The list of time events
-     */
-    public void setEventList(List<ITimeEvent> eventList) {
-        fEventList = eventList;
-        if (eventList != null && eventList.size() > 0) {
-            fStartTime = eventList.get(0).getTime();
-            ITimeEvent lastEvent = eventList.get(eventList.size() - 1);
-            fEndTime = lastEvent.getTime() + lastEvent.getDuration();
+    @Override
+    public boolean hasTimeEvents() {
+        if (fType == Type.NULL) {
+            return false;
         }
+        return true;
     }
 
     /**
-     * Assign the zoomed event list to this view.
+     * Add a child to this entry of type ResourcesEntry
      *
-     * @param eventList
-     *            The list of "zoomed" time events
+     * @param entry
+     *            The entry to add
      */
-    public void setZoomedEventList(List<ITimeEvent> eventList) {
-        fZoomedEventList = eventList;
+    public void addChild(ResourcesEntry entry) {
+        int index;
+        for (index = 0; index < getChildren().size(); index++) {
+            ResourcesEntry other = (ResourcesEntry) getChildren().get(index);
+            if (entry.getType().compareTo(other.getType()) < 0) {
+                break;
+            } else if (entry.getType().equals(other.getType())) {
+                if (entry.getId() < other.getId()) {
+                    break;
+                }
+            }
+        }
+
+        entry.setParent(this);
+        getChildren().add(index, entry);
     }
+
 }
diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEvent.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/resources/ResourcesEvent.java
deleted file mode 100644 (file)
index d8acb7d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *   Patrick Tasse - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.resources;
-
-import org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.resources.ResourcesEntry.Type;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent;
-
-/**
- * Time Event implementation specific to the Resource View
- *
- * @author Patrick Tasse
- */
-public class ResourcesEvent extends TimeEvent {
-
-    private final Type fType;
-    private int fValue;
-
-    /**
-     * Standard constructor
-     *
-     * @param entry
-     *            The entry that this event affects
-     * @param time
-     *            The start time of the event
-     * @param duration
-     *            The duration of the event
-     * @param value
-     *            The value type associated to this event
-     */
-    public ResourcesEvent(ResourcesEntry entry, long time, long duration,
-            int value) {
-        super(entry, time, duration);
-        fType = entry.getType();
-        fValue = value;
-    }
-
-    /**
-     * Base constructor, with no value assigned
-     *
-     * @param entry
-     *            The entry that this event affects
-     * @param time
-     *            The start time of the event
-     * @param duration
-     *            The duration of the event
-     */
-    public ResourcesEvent(ResourcesEntry entry, long time, long duration) {
-        super(entry, time, duration);
-        fType = Type.NULL;
-    }
-
-    /**
-     * Retrieve the value associated with this event
-     *
-     * @return The integer value
-     */
-    public int getValue() {
-        return fValue;
-    }
-
-    /**
-     * Retrieve the type of this entry. Uses the ResourcesEntry.Type interface.
-     *
-     * @return The entry type
-     */
-    public Type getType() {
-        return fType;
-    }
-
-    @Override
-    public String toString() {
-        return "ResourcesEvent start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + " type=" + fType + " value=" + fValue; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-    }
-}
index f604752bf70b91a8188e60822d0d73d2cf257542..52ad1a023f590af73ccb9d532fa6255be52d38dd 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
+ * Copyright (c) 2012, 2013 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
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
+ *   Geneviève Bastien - Move code to provide base classes for time graph view
  *******************************************************************************/
 
 package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.resources;
@@ -30,9 +31,10 @@ import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
 import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer;
 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.TimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
@@ -49,109 +51,102 @@ import org.eclipse.swt.graphics.Rectangle;
  */
 public class ResourcesPresentationProvider extends TimeGraphPresentationProvider {
 
-    private final TimeGraphViewer fTimeGraphViewer;
-    private long fLastThreadId = -1; // used to draw the process name label only once per thread id
+    private long fLastThreadId = -1;
 
     private enum State {
-        IDLE            (new RGB(200, 200, 200)),
-        USERMODE        (new RGB(0, 200, 0)),
-        SYSCALL         (new RGB(0, 0, 200)),
-        IRQ             (new RGB(200,   0, 100)),
-        SOFT_IRQ        (new RGB(200, 150, 100)),
-        IRQ_ACTIVE      (new RGB(200,   0, 100)),
-        SOFT_IRQ_RAISED (new RGB(200, 200, 0)),
-        SOFT_IRQ_ACTIVE (new RGB(200, 150, 100));
+        IDLE             (new RGB(200, 200, 200)),
+        USERMODE         (new RGB(0,   200, 0)),
+        SYSCALL          (new RGB(0,     0, 200)),
+        IRQ              (new RGB(200,   0, 100)),
+        SOFT_IRQ         (new RGB(200, 150, 100)),
+        IRQ_ACTIVE       (new RGB(200,   0, 100)),
+        SOFT_IRQ_RAISED  (new RGB(200, 200, 0)),
+        SOFT_IRQ_ACTIVE  (new RGB(200, 150, 100));
 
         public final RGB rgb;
 
-        private State (RGB rgb) {
+        private State(RGB rgb) {
             this.rgb = rgb;
         }
     }
 
     /**
      * Default constructor
-     *
-     * @param timeGraphViewer the time graph viewer
      */
-    public ResourcesPresentationProvider(TimeGraphViewer timeGraphViewer) {
+    public ResourcesPresentationProvider() {
         super();
-        this.fTimeGraphViewer = timeGraphViewer;
     }
 
-    @Override
-    public String getStateTypeName() {
-        return Messages.ResourcesView_stateTypeName;
+    private static State[] getStateValues() {
+        return State.values();
     }
 
-    @Override
-    public StateItem[] getStateTable() {
-        StateItem[] stateTable = new StateItem[State.values().length];
-        for (int i = 0; i < stateTable.length; i++) {
-            State state = State.values()[i];
-            stateTable[i] = new StateItem(state.rgb, state.toString());
+    private static State getEventState(ITimeEvent event) {
+        if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
+            TimeEvent tcEvent = (TimeEvent) event;
+
+            ResourcesEntry entry = (ResourcesEntry) event.getEntry();
+            int value = tcEvent.getValue();
+
+            if (entry.getType() == Type.CPU) {
+                if (value == StateValues.CPU_STATUS_IDLE) {
+                    return State.IDLE;
+                } else if (value == StateValues.CPU_STATUS_RUN_USERMODE) {
+                    return State.USERMODE;
+                } else if (value == StateValues.CPU_STATUS_RUN_SYSCALL) {
+                    return State.SYSCALL;
+                } else if (value == StateValues.CPU_STATUS_IRQ) {
+                    return State.IRQ;
+                } else if (value == StateValues.CPU_STATUS_SOFTIRQ) {
+                    return State.SOFT_IRQ;
+                }
+            } else if ((entry.getType() == Type.IRQ) && (tcEvent.hasValue()) && (value != ResourcesView.NO_VALUE_EVENT)) {
+                return State.IRQ_ACTIVE;
+            } else if ((entry.getType() == Type.SOFT_IRQ) && (tcEvent.hasValue()) && (value != ResourcesView.NO_VALUE_EVENT)) {
+                if (value == StateValues.SOFT_IRQ_RAISED) {
+                    return State.SOFT_IRQ_RAISED;
+                }
+                return State.SOFT_IRQ_ACTIVE;
+            }
         }
-        return stateTable;
+        return null;
     }
 
     @Override
     public int getStateTableIndex(ITimeEvent event) {
-        if (event instanceof ResourcesEvent) {
-            ResourcesEvent resourcesEvent = (ResourcesEvent) event;
-            if (resourcesEvent.getType() == Type.CPU) {
-                int status = resourcesEvent.getValue();
-                if (status == StateValues.CPU_STATUS_IDLE) {
-                    return State.IDLE.ordinal();
-                } else if (status == StateValues.CPU_STATUS_RUN_USERMODE) {
-                    return State.USERMODE.ordinal();
-                } else if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
-                    return State.SYSCALL.ordinal();
-                } else if (status == StateValues.CPU_STATUS_IRQ) {
-                    return State.IRQ.ordinal();
-                } else if (status == StateValues.CPU_STATUS_SOFTIRQ) {
-                    return State.SOFT_IRQ.ordinal();
-                }
-            } else if (resourcesEvent.getType() == Type.IRQ) {
-                return State.IRQ_ACTIVE.ordinal();
-            } else if (resourcesEvent.getType() == Type.SOFT_IRQ) {
-                int cpu = resourcesEvent.getValue();
-                if (cpu == StateValues.SOFT_IRQ_RAISED) {
-                    return State.SOFT_IRQ_RAISED.ordinal();
-                }
-                return State.SOFT_IRQ_ACTIVE.ordinal();
-            } else {
-                return INVISIBLE; // NULL
+        State state = getEventState(event);
+        if (state != null) {
+            return state.ordinal();
+        }
+        if (event instanceof TimeEvent) {
+            TimeEvent tcEvent = (TimeEvent) event;
+            if (tcEvent.hasValue()) {
+                return INVISIBLE;
             }
         }
         return TRANSPARENT;
     }
 
+    @Override
+    public StateItem[] getStateTable() {
+        State[] states = getStateValues();
+        StateItem[] stateTable = new StateItem[states.length];
+        for (int i = 0; i < stateTable.length; i++) {
+            State state = states[i];
+            stateTable[i] = new StateItem(state.rgb, state.toString());
+        }
+        return stateTable;
+    }
+
     @Override
     public String getEventName(ITimeEvent event) {
-        if (event instanceof ResourcesEvent) {
-            ResourcesEvent resourcesEvent = (ResourcesEvent) event;
-            if (resourcesEvent.getType() == Type.CPU) {
-                int status = resourcesEvent.getValue();
-                if (status == StateValues.CPU_STATUS_IDLE) {
-                    return State.IDLE.toString();
-                } else if (status == StateValues.CPU_STATUS_RUN_USERMODE) {
-                    return State.USERMODE.toString();
-                } else if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
-                    return State.SYSCALL.toString();
-                } else if (status == StateValues.CPU_STATUS_IRQ) {
-                    return State.IRQ.toString();
-                } else if (status == StateValues.CPU_STATUS_SOFTIRQ) {
-                    return State.SOFT_IRQ.toString();
-                }
-            } else if (resourcesEvent.getType() == Type.IRQ) {
-                return State.IRQ_ACTIVE.toString();
-            } else if (resourcesEvent.getType() == Type.SOFT_IRQ) {
-                int cpu = resourcesEvent.getValue();
-                if (cpu == StateValues.SOFT_IRQ_RAISED) {
-                    return State.SOFT_IRQ_RAISED.toString();
-                }
-                return State.SOFT_IRQ_ACTIVE.toString();
-            } else {
+        State state = getEventState(event);
+        if (state != null) {
+            return state.toString();
+        }
+        if (event instanceof TimeEvent) {
+            TimeEvent tcEvent = (TimeEvent) event;
+            if (tcEvent.hasValue()) {
                 return null;
             }
         }
@@ -162,119 +157,119 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider
     public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) {
 
         Map<String, String> retMap = new LinkedHashMap<String, String>();
-        if (event instanceof ResourcesEvent) {
+        if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
 
-            ResourcesEvent resourcesEvent = (ResourcesEvent) event;
+            TimeEvent tcEvent = (TimeEvent) event;
+            ResourcesEntry entry = (ResourcesEntry) event.getEntry();
 
-            // Check for IRQ or Soft_IRQ type
-            if (resourcesEvent.getType().equals(Type.IRQ) || resourcesEvent.getType().equals(Type.SOFT_IRQ)) {
+            if (tcEvent.hasValue()) {
+                // Check for IRQ or Soft_IRQ type
+                if (entry.getType().equals(Type.IRQ) || entry.getType().equals(Type.SOFT_IRQ)) {
 
-                // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
-                int cpu = resourcesEvent.getValue();
-                if (cpu >= 0) {
-                    retMap.put(Messages.ResourcesView_attributeCpuName, String.valueOf(cpu));
+                    // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
+                    int cpu = tcEvent.getValue();
+                    if (cpu >= 0) {
+                        retMap.put(Messages.ResourcesView_attributeCpuName, String.valueOf(cpu));
+                    }
                 }
-            }
 
-            // Check for type CPU
-            if (resourcesEvent.getType().equals(Type.CPU)) {
-                int status = resourcesEvent.getValue();
-
-                if (status == StateValues.CPU_STATUS_IRQ) {
-                    // In IRQ state get the IRQ that caused the interruption
-                    ResourcesEntry entry = (ResourcesEntry) event.getEntry();
-                    ITmfStateSystem ss = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
-                    int cpu = entry.getId();
-
-                    try {
-                        List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
-                        List<Integer> irqQuarks = ss.getQuarks(Attributes.RESOURCES, Attributes.IRQS, "*"); //$NON-NLS-1$
-
-                        for (int irqQuark : irqQuarks) {
-                            if (fullState.get(irqQuark).getStateValue().unboxInt() == cpu) {
-                                ITmfStateInterval value = ss.querySingleState(event.getTime(), irqQuark);
-                                if (!value.getStateValue().isNull()) {
-                                    int irq = Integer.parseInt(ss.getAttributeName(irqQuark));
-                                    retMap.put(Messages.ResourcesView_attributeIrqName, String.valueOf(irq));
+                // Check for type CPU
+                else if (entry.getType().equals(Type.CPU)) {
+                    int status = tcEvent.getValue();
+
+                    if (status == StateValues.CPU_STATUS_IRQ) {
+                        // In IRQ state get the IRQ that caused the interruption
+                        ITmfStateSystem ss = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
+                        int cpu = entry.getId();
+
+                        try {
+                            List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
+                            List<Integer> irqQuarks = ss.getQuarks(Attributes.RESOURCES, Attributes.IRQS, "*"); //$NON-NLS-1$
+
+                            for (int irqQuark : irqQuarks) {
+                                if (fullState.get(irqQuark).getStateValue().unboxInt() == cpu) {
+                                    ITmfStateInterval value = ss.querySingleState(event.getTime(), irqQuark);
+                                    if (!value.getStateValue().isNull()) {
+                                        int irq = Integer.parseInt(ss.getAttributeName(irqQuark));
+                                        retMap.put(Messages.ResourcesView_attributeIrqName, String.valueOf(irq));
+                                    }
+                                    break;
                                 }
-                                break;
                             }
+                        } catch (AttributeNotFoundException e) {
+                            e.printStackTrace();
+                        } catch (TimeRangeException e) {
+                            e.printStackTrace();
+                        } catch (StateValueTypeException e) {
+                            e.printStackTrace();
+                        } catch (StateSystemDisposedException e) {
+                            /* Ignored */
                         }
-                    } catch (AttributeNotFoundException e) {
-                        e.printStackTrace();
-                    } catch (TimeRangeException e) {
-                        e.printStackTrace();
-                    } catch (StateValueTypeException e) {
-                        e.printStackTrace();
-                    } catch (StateSystemDisposedException e) {
-                        /* Ignored */
-                    }
-                } else if (status == StateValues.CPU_STATUS_SOFTIRQ) {
-                    // In SOFT_IRQ state get the SOFT_IRQ that caused the interruption
-                    ResourcesEntry entry = (ResourcesEntry) event.getEntry();
-                    ITmfStateSystem ss = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
-                    int cpu = entry.getId();
-
-                    try {
-                        List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
-                        List<Integer> softIrqQuarks = ss.getQuarks(Attributes.RESOURCES, Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
-
-                        for (int softIrqQuark : softIrqQuarks) {
-                            if (fullState.get(softIrqQuark).getStateValue().unboxInt() == cpu) {
-                                ITmfStateInterval value = ss.querySingleState(event.getTime(), softIrqQuark);
-                                if (!value.getStateValue().isNull()) {
-                                    int softIrq = Integer.parseInt(ss.getAttributeName(softIrqQuark));
-                                    retMap.put(Messages.ResourcesView_attributeSoftIrqName, String.valueOf(softIrq));
+                    } else if (status == StateValues.CPU_STATUS_SOFTIRQ) {
+                        // In SOFT_IRQ state get the SOFT_IRQ that caused the interruption
+                        ITmfStateSystem ss = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
+                        int cpu = entry.getId();
+
+                        try {
+                            List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
+                            List<Integer> softIrqQuarks = ss.getQuarks(Attributes.RESOURCES, Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
+
+                            for (int softIrqQuark : softIrqQuarks) {
+                                if (fullState.get(softIrqQuark).getStateValue().unboxInt() == cpu) {
+                                    ITmfStateInterval value = ss.querySingleState(event.getTime(), softIrqQuark);
+                                    if (!value.getStateValue().isNull()) {
+                                        int softIrq = Integer.parseInt(ss.getAttributeName(softIrqQuark));
+                                        retMap.put(Messages.ResourcesView_attributeSoftIrqName, String.valueOf(softIrq));
+                                    }
+                                    break;
                                 }
-                                break;
                             }
+                        } catch (AttributeNotFoundException e) {
+                            e.printStackTrace();
+                        } catch (TimeRangeException e) {
+                            e.printStackTrace();
+                        } catch (StateValueTypeException e) {
+                            e.printStackTrace();
+                        } catch (StateSystemDisposedException e) {
+                            /* Ignored */
                         }
-                    } catch (AttributeNotFoundException e) {
-                        e.printStackTrace();
-                    } catch (TimeRangeException e) {
-                        e.printStackTrace();
-                    } catch (StateValueTypeException e) {
-                        e.printStackTrace();
-                    } catch (StateSystemDisposedException e) {
-                        /* Ignored */
-                    }
-                } else if (status == StateValues.CPU_STATUS_RUN_USERMODE || status == StateValues.CPU_STATUS_RUN_SYSCALL){
-                    // In running state get the current tid
-                    ResourcesEntry entry = (ResourcesEntry) event.getEntry();
-                    ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
-
-                    try {
-                        retMap.put(Messages.ResourcesView_attributeHoverTime, Utils.formatTime(hoverTime, TimeFormat.CALENDAR, Resolution.NANOSEC));
-                        int cpuQuark = entry.getQuark();
-                        int currentThreadQuark = ssq.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
-                        ITmfStateInterval interval = ssq.querySingleState(hoverTime, currentThreadQuark);
-                        if (!interval.getStateValue().isNull()) {
-                            ITmfStateValue value = interval.getStateValue();
-                            int currentThreadId = value.unboxInt();
-                            retMap.put(Messages.ResourcesView_attributeTidName, Integer.toString(currentThreadId));
-                            int execNameQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.EXEC_NAME);
-                            interval = ssq.querySingleState(hoverTime, execNameQuark);
+                    } else if (status == StateValues.CPU_STATUS_RUN_USERMODE || status == StateValues.CPU_STATUS_RUN_SYSCALL) {
+                        // In running state get the current tid
+                        ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
+
+                        try {
+                            retMap.put(Messages.ResourcesView_attributeHoverTime, Utils.formatTime(hoverTime, TimeFormat.CALENDAR, Resolution.NANOSEC));
+                            int cpuQuark = entry.getQuark();
+                            int currentThreadQuark = ssq.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
+                            ITmfStateInterval interval = ssq.querySingleState(hoverTime, currentThreadQuark);
                             if (!interval.getStateValue().isNull()) {
-                                value = interval.getStateValue();
-                                retMap.put(Messages.ResourcesView_attributeProcessName, value.unboxStr());
-                            }
-                            if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
-                                int syscallQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.SYSTEM_CALL);
-                                interval = ssq.querySingleState(hoverTime, syscallQuark);
+                                ITmfStateValue value = interval.getStateValue();
+                                int currentThreadId = value.unboxInt();
+                                retMap.put(Messages.ResourcesView_attributeTidName, Integer.toString(currentThreadId));
+                                int execNameQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.EXEC_NAME);
+                                interval = ssq.querySingleState(hoverTime, execNameQuark);
                                 if (!interval.getStateValue().isNull()) {
                                     value = interval.getStateValue();
-                                    retMap.put(Messages.ResourcesView_attributeSyscallName, value.unboxStr());
+                                    retMap.put(Messages.ResourcesView_attributeProcessName, value.unboxStr());
+                                }
+                                if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
+                                    int syscallQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.SYSTEM_CALL);
+                                    interval = ssq.querySingleState(hoverTime, syscallQuark);
+                                    if (!interval.getStateValue().isNull()) {
+                                        value = interval.getStateValue();
+                                        retMap.put(Messages.ResourcesView_attributeSyscallName, value.unboxStr());
+                                    }
                                 }
                             }
+                        } catch (AttributeNotFoundException e) {
+                            e.printStackTrace();
+                        } catch (TimeRangeException e) {
+                            e.printStackTrace();
+                        } catch (StateValueTypeException e) {
+                            e.printStackTrace();
+                        } catch (StateSystemDisposedException e) {
+                            /* Ignored */
                         }
-                    } catch (AttributeNotFoundException e) {
-                        e.printStackTrace();
-                    } catch (TimeRangeException e) {
-                        e.printStackTrace();
-                    } catch (StateValueTypeException e) {
-                        e.printStackTrace();
-                    } catch (StateSystemDisposedException e) {
-                        /* Ignored */
                     }
                 }
             }
@@ -285,21 +280,29 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider
 
     @Override
     public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) {
+        ITmfTimeGraphDrawingHelper drawingHelper = getDrawingHelper();
         if (bounds.width <= gc.getFontMetrics().getAverageCharWidth()) {
             return;
         }
-        if (!(event instanceof ResourcesEvent)) {
+
+        if (!(event instanceof TimeEvent)) {
             return;
         }
-        ResourcesEvent resourcesEvent = (ResourcesEvent) event;
-        if (!resourcesEvent.getType().equals(Type.CPU)) {
+        TimeEvent tcEvent = (TimeEvent) event;
+        if (!tcEvent.hasValue()) {
             return;
         }
-        int status = resourcesEvent.getValue();
+
+        ResourcesEntry entry = (ResourcesEntry) event.getEntry();
+        if (!entry.getType().equals(Type.CPU)) {
+            return;
+        }
+
+        int status = tcEvent.getValue();
         if (status != StateValues.CPU_STATUS_RUN_USERMODE && status != StateValues.CPU_STATUS_RUN_SYSCALL) {
             return;
         }
-        ResourcesEntry entry = (ResourcesEntry) event.getEntry();
+
         ITmfStateSystem ss = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
         long time = event.getTime();
         try {
@@ -318,9 +321,9 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider
                             gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
                             long startTime = Math.max(tidInterval.getStartTime(), event.getTime());
                             long endTime = Math.min(tidInterval.getEndTime() + 1, event.getTime() + event.getDuration());
-                            if (fTimeGraphViewer.getXForTime(endTime) > bounds.x) {
-                                int x = Math.max(fTimeGraphViewer.getXForTime(startTime), bounds.x);
-                                int width = Math.min(fTimeGraphViewer.getXForTime(endTime), bounds.x + bounds.width) - x;
+                            if (drawingHelper.getXForTime(endTime) > bounds.x) {
+                                int x = Math.max(drawingHelper.getXForTime(startTime), bounds.x);
+                                int width = Math.min(drawingHelper.getXForTime(endTime), bounds.x + bounds.width) - x;
                                 int drawn = Utils.drawText(gc, value.unboxStr(), x + 1, bounds.y - 2, width - 1, true, true);
                                 if (drawn > 0) {
                                     fLastThreadId = currentThreadId;
@@ -335,9 +338,9 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider
                             gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
                             long startTime = Math.max(tidInterval.getStartTime(), event.getTime());
                             long endTime = Math.min(tidInterval.getEndTime() + 1, event.getTime() + event.getDuration());
-                            if (fTimeGraphViewer.getXForTime(endTime) > bounds.x) {
-                                int x = Math.max(fTimeGraphViewer.getXForTime(startTime), bounds.x);
-                                int width = Math.min(fTimeGraphViewer.getXForTime(endTime), bounds.x + bounds.width) - x;
+                            if (drawingHelper.getXForTime(endTime) > bounds.x) {
+                                int x = Math.max(drawingHelper.getXForTime(startTime), bounds.x);
+                                int width = Math.min(drawingHelper.getXForTime(endTime), bounds.x + bounds.width) - x;
                                 Utils.drawText(gc, value.unboxStr().substring(4), x + 1, bounds.y - 2, width - 1, true, true);
                             }
                         }
@@ -345,7 +348,7 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider
                 }
                 time = tidInterval.getEndTime() + 1;
                 if (time < event.getTime() + event.getDuration()) {
-                    int x = fTimeGraphViewer.getXForTime(time);
+                    int x = drawingHelper.getXForTime(time);
                     if (x >= bounds.x) {
                         gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_GRAY));
                         gc.drawLine(x, bounds.y + 1, x, bounds.y + bounds.height - 2);
index 52c225c9e3e061190f3ba9cb62e801551008d7d1..69fb7e653651fd647eab9a4a0820e2471edf01fa 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
+ * Copyright (c) 2012, 2013 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
  *
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
+ *   Geneviève Bastien - Move code to provide base classes for time graph views
  *******************************************************************************/
 
 package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.resources;
 
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.Separator;
 import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
 import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Messages;
 import org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.resources.ResourcesEntry.Type;
 import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngKernelTrace;
-import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
 import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
 import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
 import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
 import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
-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.TmfTraceClosedSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
 import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
-import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
-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.views.TmfView;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer;
+import org.eclipse.linuxtools.tmf.ui.views.timegraph.AbstractTimeGraphView;
 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.TimeEvent;
-import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IActionBars;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
 
 /**
  * Main implementation for the LTTng 2.0 kernel Resource view
  *
  * @author Patrick Tasse
  */
-public class ResourcesView extends TmfView {
-
-    // ------------------------------------------------------------------------
-    // Constants
-    // ------------------------------------------------------------------------
+public class ResourcesView extends AbstractTimeGraphView {
 
     /** View ID. */
     public static final String ID = "org.eclipse.linuxtools.lttng2.kernel.ui.views.resources"; //$NON-NLS-1$
 
     /**
-     * Redraw state enum
+     * Default value for events with no other value. Since value in this case is
+     * often a CPU number, this constant should be <0
      */
-    private enum State { IDLE, BUSY, PENDING }
-
-    // ------------------------------------------------------------------------
-    // Fields
-    // ------------------------------------------------------------------------
-
-    // The time graph viewer
-    TimeGraphViewer fTimeGraphViewer;
-
-    // The selected trace
-    private ITmfTrace fTrace;
-
-    // The time graph entry list
-    private ArrayList<TraceEntry> fEntryList;
-
-    // The trace to entry list hash map
-    final private HashMap<ITmfTrace, ArrayList<TraceEntry>> fEntryListMap = new HashMap<ITmfTrace, ArrayList<TraceEntry>>();
-
-    // The trace to build thread hash map
-    final private HashMap<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<ITmfTrace, BuildThread>();
+    public static final int NO_VALUE_EVENT = -999;
 
-    // The start time
-    private long fStartTime;
+    private static final String PROCESS_COLUMN = Messages.ControlFlowView_processColumn;
 
-    // The end time
-    private long fEndTime;
+    private static final String[] COLUMN_NAMES = new String[] {
+            PROCESS_COLUMN
+    };
 
-    // The display width
-    private final int fDisplayWidth;
+    private static final String[] FILTER_COLUMN_NAMES = new String[] {
+            PROCESS_COLUMN
+    };
 
-    // The next resource action
-    private Action fNextResourceAction;
-
-    // The previous resource action
-    private Action fPreviousResourceAction;
-
-    // The zoom thread
-    private ZoomThread fZoomThread;
-
-    // The redraw state used to prevent unnecessary queuing of display runnables
-    private State fRedrawState = State.IDLE;
-
-    // The redraw synchronization object
-    final private Object fSyncObj = new Object();
-
-    // ------------------------------------------------------------------------
-    // Classes
-    // ------------------------------------------------------------------------
-
-    private class TraceEntry implements ITimeGraphEntry {
-        // The Trace
-        private final LttngKernelTrace fKernelTrace;
-        // The start time
-        private final long fTraceStartTime;
-        // The end time
-        private final long fTraceEndTime;
-        // The children of the entry
-        private final ArrayList<ResourcesEntry> fChildren;
-        // The name of entry
-        private final String fName;
-
-        public TraceEntry(LttngKernelTrace trace, String name, long startTime, long endTime) {
-            fKernelTrace = trace;
-            fChildren = new ArrayList<ResourcesEntry>();
-            fName = name;
-            fTraceStartTime = startTime;
-            fTraceEndTime = endTime;
-        }
-
-        @Override
-        public ITimeGraphEntry getParent() {
-            return null;
-        }
-
-        @Override
-        public boolean hasChildren() {
-            return fChildren != null && fChildren.size() > 0;
-        }
-
-        @Override
-        public List<ResourcesEntry> getChildren() {
-            return fChildren;
-        }
-
-        @Override
-        public String getName() {
-            return fName;
-        }
-
-        @Override
-        public long getStartTime() {
-            return fTraceStartTime;
-        }
-
-        @Override
-        public long getEndTime() {
-            return fTraceEndTime;
-        }
-
-        @Override
-        public boolean hasTimeEvents() {
-            return false;
-        }
-
-        @Override
-        public Iterator<ITimeEvent> getTimeEventsIterator() {
-            return null;
-        }
-
-        @Override
-        public <T extends ITimeEvent> Iterator<T> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
-            return null;
-        }
-
-        public LttngKernelTrace getTrace() {
-            return fKernelTrace;
-        }
-
-        public void addChild(ResourcesEntry entry) {
-            int index;
-            for (index = 0; index < fChildren.size(); index++) {
-                ResourcesEntry other = fChildren.get(index);
-                if (entry.getType().compareTo(other.getType()) < 0) {
-                    break;
-                } else if (entry.getType().equals(other.getType())) {
-                    if (entry.getId() < other.getId()) {
-                        break;
-                    }
-                }
-            }
-            entry.setParent(this);
-            fChildren.add(index, entry);
-        }
-    }
-
-    private static class TraceEntryComparator implements Comparator<ITimeGraphEntry> {
-        @Override
-        public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {
-            int result = o1.getStartTime() < o2.getStartTime() ? -1 : o1.getStartTime() > o2.getStartTime() ? 1 : 0;
-            if (result == 0) {
-                result = o1.getName().compareTo(o2.getName());
-            }
-            return result;
-        }
-    }
-
-    private class BuildThread extends Thread {
-        private final ITmfTrace fBuildTrace;
-        private final IProgressMonitor fMonitor;
-
-        public BuildThread(ITmfTrace trace) {
-            super("ResourcesView build"); //$NON-NLS-1$
-            fBuildTrace = trace;
-            fMonitor = new NullProgressMonitor();
-        }
-
-        @Override
-        public void run() {
-            buildEventList(fBuildTrace, fMonitor);
-            synchronized (fBuildThreadMap) {
-                fBuildThreadMap.remove(this);
-            }
-        }
-
-        public void cancel() {
-            fMonitor.setCanceled(true);
-        }
-    }
-
-    private class ZoomThread extends Thread {
-        private final ArrayList<TraceEntry> fZoomEntryList;
-        private final long fZoomStartTime;
-        private final long fZoomEndTime;
-        private final IProgressMonitor fMonitor;
-
-        public ZoomThread(ArrayList<TraceEntry> entryList, long startTime, long endTime) {
-            super("ResourcesView zoom"); //$NON-NLS-1$
-            fZoomEntryList = entryList;
-            fZoomStartTime = startTime;
-            fZoomEndTime = endTime;
-            fMonitor = new NullProgressMonitor();
-        }
-
-        @Override
-        public void run() {
-            if (fZoomEntryList == null) {
-                return;
-            }
-            long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
-            for (TraceEntry traceEntry : fZoomEntryList) {
-                if (!traceEntry.fKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID).waitUntilBuilt()) {
-                    return;
-                }
-                for (ITimeGraphEntry child : traceEntry.getChildren()) {
-                    if (fMonitor.isCanceled()) {
-                        break;
-                    }
-                    ResourcesEntry entry = (ResourcesEntry) child;
-                    if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {
-                        entry.setZoomedEventList(null);
-                    } else {
-                        List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, resolution, true, fMonitor);
-                        if (zoomedEventList != null) {
-                            entry.setZoomedEventList(zoomedEventList);
-                        }
-                    }
-                    redraw();
-                }
-            }
-        }
-
-        public void cancel() {
-            fMonitor.setCanceled(true);
-        }
-    }
+    private static final int[] WEIGHTS = { 15, 85 };
 
     // ------------------------------------------------------------------------
     // Constructors
@@ -302,215 +69,62 @@ public class ResourcesView extends TmfView {
      * Default constructor
      */
     public ResourcesView() {
-        super(ID);
-        fDisplayWidth = Display.getDefault().getBounds().width;
+        super(ID, COLUMN_NAMES, FILTER_COLUMN_NAMES, new ResourcesPresentationProvider());
+        setWeight(WEIGHTS);
     }
 
-    // ------------------------------------------------------------------------
-    // ViewPart
-    // ------------------------------------------------------------------------
-
     @Override
-    public void createPartControl(Composite parent) {
-        fTimeGraphViewer = new TimeGraphViewer(parent, SWT.NONE);
-
-        fTimeGraphViewer.setTimeGraphProvider(new ResourcesPresentationProvider(fTimeGraphViewer));
-
-        fTimeGraphViewer.setTimeFormat(TimeFormat.CALENDAR);
-
-        fTimeGraphViewer.addRangeListener(new ITimeGraphRangeListener() {
-            @Override
-            public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
-                long startTime = event.getStartTime();
-                long endTime = event.getEndTime();
-                TmfTimeRange range = new TmfTimeRange(new CtfTmfTimestamp(startTime), new CtfTmfTimestamp(endTime));
-                TmfTimestamp time = new CtfTmfTimestamp(fTimeGraphViewer.getSelectedTime());
-                broadcast(new TmfRangeSynchSignal(ResourcesView.this, range, time));
-                startZoomThread(startTime, endTime);
-            }
-        });
-
-        fTimeGraphViewer.addTimeListener(new ITimeGraphTimeListener() {
-            @Override
-            public void timeSelected(TimeGraphTimeEvent event) {
-                long time = event.getTime();
-                broadcast(new TmfTimeSynchSignal(ResourcesView.this, new CtfTmfTimestamp(time)));
-            }
-        });
-
-        // View Action Handling
-        makeActions();
-        contributeToActionBars();
-
-        ITmfTrace trace = getActiveTrace();
-        if (trace != null) {
-            traceSelected(new TmfTraceSelectedSignal(this, trace));
-        }
+    protected String getNextText() {
+        return Messages.ResourcesView_nextResourceActionNameText;
     }
 
     @Override
-    public void setFocus() {
-        fTimeGraphViewer.setFocus();
-    }
-
-    // ------------------------------------------------------------------------
-    // Signal handlers
-    // ------------------------------------------------------------------------
-
-    /**
-     * Handler for the trace opened signal.
-     * @param signal the trace selected signal
-     * @since 2.0
-     */
-    @TmfSignalHandler
-    public void traceOpened(TmfTraceOpenedSignal signal) {
-        fTrace = signal.getTrace();
-        loadTrace();
+    protected String getNextTooltip() {
+        return Messages.ResourcesView_nextResourceActionToolTipText;
     }
 
-    /**
-     * Handler for the trace selected signal
-     *
-     * @param signal
-     *            The incoming signal
-     */
-    @TmfSignalHandler
-    public void traceSelected(final TmfTraceSelectedSignal signal) {
-        if (signal.getTrace() == fTrace) {
-            return;
-        }
-        fTrace = signal.getTrace();
-        loadTrace();
-    }
-
-    /**
-     * Trace is disposed: clear the data structures and the view
-     *
-     * @param signal the signal received
-     */
-    @TmfSignalHandler
-    public void traceClosed(final TmfTraceClosedSignal signal) {
-        synchronized (fBuildThreadMap) {
-            BuildThread buildThread = fBuildThreadMap.remove(signal.getTrace());
-            if (buildThread != null) {
-                buildThread.cancel();
-            }
-        }
-        synchronized (fEntryListMap) {
-            fEntryListMap.remove(signal.getTrace());
-        }
-        if (signal.getTrace() == fTrace) {
-            fTrace = null;
-            fStartTime = 0;
-            fEndTime = 0;
-            if (fZoomThread != null) {
-                fZoomThread.cancel();
-            }
-            refresh();
-        }
-    }
-
-    /**
-     * Handler for the TimeSynch signal
-     *
-     * @param signal
-     *            The incoming signal
-     */
-    @TmfSignalHandler
-    public void synchToTime(final TmfTimeSynchSignal signal) {
-        if (signal.getSource() == this || fTrace == null) {
-            return;
-        }
-        final long time = signal.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-        Display.getDefault().asyncExec(new Runnable() {
-            @Override
-            public void run() {
-                if (fTimeGraphViewer.getControl().isDisposed()) {
-                    return;
-                }
-                fTimeGraphViewer.setSelectedTime(time, true);
-                startZoomThread(fTimeGraphViewer.getTime0(), fTimeGraphViewer.getTime1());
-            }
-        });
+    @Override
+    protected String getPrevText() {
+        return Messages.ResourcesView_previousResourceActionNameText;
     }
 
-    /**
-     * Handler for the RangeSynch signal
-     *
-     * @param signal
-     *            The incoming signal
-     */
-    @TmfSignalHandler
-    public void synchToRange(final TmfRangeSynchSignal signal) {
-        if (signal.getSource() == this || fTrace == null) {
-            return;
-        }
-        if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) {
-            return;
-        }
-        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 (fTimeGraphViewer.getControl().isDisposed()) {
-                    return;
-                }
-                fTimeGraphViewer.setStartFinishTime(startTime, endTime);
-                fTimeGraphViewer.setSelectedTime(time, false);
-                startZoomThread(startTime, endTime);
-            }
-        });
+    @Override
+    protected String getPrevTooltip() {
+        return Messages.ResourcesView_previousResourceActionToolTipText;
     }
 
     // ------------------------------------------------------------------------
     // Internal
     // ------------------------------------------------------------------------
 
-    private void loadTrace() {
-        synchronized (fEntryListMap) {
-            fEntryList = fEntryListMap.get(fTrace);
-            if (fEntryList == null) {
-                synchronized (fBuildThreadMap) {
-                    BuildThread buildThread = new BuildThread(fTrace);
-                    fBuildThreadMap.put(fTrace, buildThread);
-                    buildThread.start();
-                }
-            } else {
-                fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-                refresh();
-            }
-        }
-    }
+    @Override
+    protected void buildEventList(ITmfTrace trace, IProgressMonitor monitor) {
+        setStartTime(Long.MAX_VALUE);
+        setEndTime(Long.MIN_VALUE);
 
-    private void buildEventList(final ITmfTrace trace, IProgressMonitor monitor) {
-        fStartTime = Long.MAX_VALUE;
-        fEndTime = Long.MIN_VALUE;
-        ArrayList<TraceEntry> entryList = new ArrayList<TraceEntry>();
-        for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) {
+        ArrayList<ResourcesEntry> entryList = new ArrayList<ResourcesEntry>();
+        for (ITmfTrace aTrace : fTraceManager.getActiveTraceSet()) {
             if (monitor.isCanceled()) {
                 return;
             }
             if (aTrace instanceof LttngKernelTrace) {
-                LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) aTrace;
-                ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
+                LttngKernelTrace lttngKernelTrace = (LttngKernelTrace) aTrace;
+                ITmfStateSystem ssq = lttngKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
                 if (!ssq.waitUntilBuilt()) {
                     return;
                 }
                 long startTime = ssq.getStartTime();
                 long endTime = ssq.getCurrentEndTime() + 1;
-                TraceEntry groupEntry = new TraceEntry(ctfKernelTrace, aTrace.getName(), startTime, endTime);
+                ResourcesEntry groupEntry = new ResourcesEntry(lttngKernelTrace, aTrace.getName(), startTime, endTime, 0);
                 entryList.add(groupEntry);
-                fStartTime = Math.min(fStartTime, startTime);
-                fEndTime = Math.max(fEndTime, endTime);
+                setStartTime(Math.min(getStartTime(), startTime));
+                setEndTime(Math.max(getEndTime(), endTime));
                 List<Integer> cpuQuarks = ssq.getQuarks(Attributes.CPUS, "*"); //$NON-NLS-1$
                 ResourcesEntry[] cpuEntries = new ResourcesEntry[cpuQuarks.size()];
                 for (int i = 0; i < cpuQuarks.size(); i++) {
                     int cpuQuark = cpuQuarks.get(i);
                     int cpu = Integer.parseInt(ssq.getAttributeName(cpuQuark));
-                    ResourcesEntry entry = new ResourcesEntry(cpuQuark, ctfKernelTrace, Type.CPU, cpu);
+                    ResourcesEntry entry = new ResourcesEntry(cpuQuark, lttngKernelTrace, getStartTime(), getEndTime(), Type.CPU, cpu);
                     groupEntry.addChild(entry);
                     cpuEntries[i] = entry;
                 }
@@ -519,7 +133,7 @@ public class ResourcesView extends TmfView {
                 for (int i = 0; i < irqQuarks.size(); i++) {
                     int irqQuark = irqQuarks.get(i);
                     int irq = Integer.parseInt(ssq.getAttributeName(irqQuark));
-                    ResourcesEntry entry = new ResourcesEntry(irqQuark, ctfKernelTrace, Type.IRQ, irq);
+                    ResourcesEntry entry = new ResourcesEntry(irqQuark, lttngKernelTrace, getStartTime(), getEndTime(), Type.IRQ, irq);
                     groupEntry.addChild(entry);
                     irqEntries[i] = entry;
                 }
@@ -528,37 +142,37 @@ public class ResourcesView extends TmfView {
                 for (int i = 0; i < softIrqQuarks.size(); i++) {
                     int softIrqQuark = softIrqQuarks.get(i);
                     int softIrq = Integer.parseInt(ssq.getAttributeName(softIrqQuark));
-                    ResourcesEntry entry = new ResourcesEntry(softIrqQuark, ctfKernelTrace, Type.SOFT_IRQ, softIrq);
+                    ResourcesEntry entry = new ResourcesEntry(softIrqQuark, lttngKernelTrace, getStartTime(), getEndTime(), Type.SOFT_IRQ, softIrq);
                     groupEntry.addChild(entry);
                     softIrqEntries[i] = entry;
                 }
             }
         }
-        synchronized (fEntryListMap) {
-            fEntryListMap.put(trace, (ArrayList<TraceEntry>) entryList.clone());
-        }
-        if (trace == fTrace) {
+        putEntryList(trace, (ArrayList<TimeGraphEntry>) entryList.clone());
+
+        if (trace.equals(getTrace())) {
             refresh();
         }
-        for (TraceEntry traceEntry : entryList) {
+        for (ResourcesEntry traceEntry : entryList) {
             if (monitor.isCanceled()) {
                 return;
             }
-            LttngKernelTrace ctfKernelTrace = traceEntry.getTrace();
-            ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
+            LttngKernelTrace lttngKernelTrace = traceEntry.getTrace();
+            ITmfStateSystem ssq = lttngKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID);
             long startTime = ssq.getStartTime();
             long endTime = ssq.getCurrentEndTime() + 1;
-            long resolution = (endTime - startTime) / fDisplayWidth;
-            for (ResourcesEntry entry : traceEntry.getChildren()) {
-                List<ITimeEvent> eventList = getEventList(entry, startTime, endTime, resolution, false, monitor);
+            long resolution = (endTime - startTime) / getDisplayWidth();
+            for (TimeGraphEntry entry : traceEntry.getChildren()) {
+                List<ITimeEvent> eventList = getEventList(entry, startTime, endTime, resolution, monitor);
                 entry.setEventList(eventList);
                 redraw();
             }
         }
     }
 
-    private static List<ITimeEvent> getEventList(ResourcesEntry entry,
-            long startTime, long endTime, long resolution, boolean includeNull,
+    @Override
+    protected List<ITimeEvent> getEventList(TimeGraphEntry entry,
+            long startTime, long endTime, long resolution,
             IProgressMonitor monitor) {
         ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID);
         final long realStart = Math.max(startTime, ssq.getStartTime());
@@ -567,9 +181,15 @@ public class ResourcesView extends TmfView {
             return null;
         }
         List<ITimeEvent> eventList = null;
-        int quark = entry.getQuark();
+
+        if (!(entry instanceof ResourcesEntry)) {
+            return eventList;
+        }
+        ResourcesEntry resourcesEntry = (ResourcesEntry) entry;
+        int quark = resourcesEntry.getQuark();
+
         try {
-            if (entry.getType().equals(Type.CPU)) {
+            if (resourcesEntry.getType().equals(Type.CPU)) {
                 int statusQuark = ssq.getQuarkRelative(quark, Attributes.STATUS);
                 List<ITmfStateInterval> statusIntervals = ssq.queryHistoryRange(statusQuark, realStart, realEnd - 1, resolution, monitor);
                 eventList = new ArrayList<ITimeEvent>(statusIntervals.size());
@@ -585,15 +205,15 @@ public class ResourcesView extends TmfView {
                         if (lastEndTime != time && lastEndTime != -1) {
                             eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
                         }
-                        eventList.add(new ResourcesEvent(entry, time, duration, status));
+                        eventList.add(new TimeEvent(entry, time, duration, status));
                         lastEndTime = time + duration;
                     } else {
-                        if (includeNull) {
-                            eventList.add(new ResourcesEvent(entry, time, duration));
+                        if (true) {// includeNull) {
+                            eventList.add(new TimeEvent(entry, time, duration, NO_VALUE_EVENT));
                         }
                     }
                 }
-            } else if (entry.getType().equals(Type.IRQ)) {
+            } else if (resourcesEntry.getType().equals(Type.IRQ)) {
                 List<ITmfStateInterval> irqIntervals = ssq.queryHistoryRange(quark, realStart, realEnd - 1, resolution, monitor);
                 eventList = new ArrayList<ITimeEvent>(irqIntervals.size());
                 long lastEndTime = -1;
@@ -606,20 +226,20 @@ public class ResourcesView extends TmfView {
                     long duration = irqInterval.getEndTime() - time + 1;
                     if (!irqInterval.getStateValue().isNull()) {
                         int cpu = irqInterval.getStateValue().unboxInt();
-                        eventList.add(new ResourcesEvent(entry, time, duration, cpu));
+                        eventList.add(new TimeEvent(entry, time, duration, cpu));
                         lastIsNull = false;
                     } else {
                         if (lastEndTime != time && lastEndTime != -1 && lastIsNull) {
-                            eventList.add(new ResourcesEvent(entry, lastEndTime, time - lastEndTime, -1));
-                        }
-                        if (includeNull) {
-                            eventList.add(new ResourcesEvent(entry, time, duration));
+                            /* This is a special case where we want to show IRQ_ACTIVE state but we don't know the CPU (it is between two null samples) */
+                            eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime, -1));
+                        } else {
+                            eventList.add(new TimeEvent(entry, time, duration, NO_VALUE_EVENT));
                         }
                         lastIsNull = true;
                     }
                     lastEndTime = time + duration;
                 }
-            } else if (entry.getType().equals(Type.SOFT_IRQ)) {
+            } else if (resourcesEntry.getType().equals(Type.SOFT_IRQ)) {
                 List<ITmfStateInterval> softIrqIntervals = ssq.queryHistoryRange(quark, realStart, realEnd - 1, resolution, monitor);
                 eventList = new ArrayList<ITimeEvent>(softIrqIntervals.size());
                 long lastEndTime = -1;
@@ -632,19 +252,20 @@ public class ResourcesView extends TmfView {
                     long duration = softIrqInterval.getEndTime() - time + 1;
                     if (!softIrqInterval.getStateValue().isNull()) {
                         int cpu = softIrqInterval.getStateValue().unboxInt();
-                        eventList.add(new ResourcesEvent(entry, time, duration, cpu));
+                        eventList.add(new TimeEvent(entry, time, duration, cpu));
                     } else {
                         if (lastEndTime != time && lastEndTime != -1 && lastIsNull) {
-                            eventList.add(new ResourcesEvent(entry, lastEndTime, time - lastEndTime, -1));
-                        }
-                        if (includeNull) {
-                            eventList.add(new ResourcesEvent(entry, time, duration));
+                            /* This is a special case where we want to show IRQ_ACTIVE state but we don't know the CPU (it is between two null samples) */
+                            eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime, -1));
+                        } else {
+                            eventList.add(new TimeEvent(entry, time, duration, NO_VALUE_EVENT));
                         }
                         lastIsNull = true;
                     }
                     lastEndTime = time + duration;
                 }
             }
+
         } catch (AttributeNotFoundException e) {
             e.printStackTrace();
         } catch (TimeRangeException e) {
@@ -657,101 +278,4 @@ public class ResourcesView extends TmfView {
         return eventList;
     }
 
-    private void refresh() {
-        Display.getDefault().asyncExec(new Runnable() {
-            @Override
-            public void run() {
-                if (fTimeGraphViewer.getControl().isDisposed()) {
-                    return;
-                }
-                ITimeGraphEntry[] entries = null;
-                synchronized (fEntryListMap) {
-                    fEntryList = fEntryListMap.get(fTrace);
-                    if (fEntryList == null) {
-                        fEntryList = new ArrayList<TraceEntry>();
-                    }
-                    entries = fEntryList.toArray(new ITimeGraphEntry[0]);
-                }
-                if (entries != null) {
-                    Arrays.sort(entries, new TraceEntryComparator());
-                    fTimeGraphViewer.setInput(entries);
-                    fTimeGraphViewer.setTimeBounds(fStartTime, fEndTime);
-
-                    long timestamp = fTrace == null ? 0 : fTraceManager.getCurrentTime().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);
-                    fTimeGraphViewer.setSelectedTime(timestamp, false);
-                    fTimeGraphViewer.setStartFinishTime(startTime, endTime);
-
-                    startZoomThread(startTime, endTime);
-                }
-            }
-        });
-    }
-
-    private void redraw() {
-        synchronized (fSyncObj) {
-            if (fRedrawState == State.IDLE) {
-                fRedrawState = State.BUSY;
-            } else {
-                fRedrawState = State.PENDING;
-                return;
-            }
-        }
-        Display.getDefault().asyncExec(new Runnable() {
-            @Override
-            public void run() {
-                if (fTimeGraphViewer.getControl().isDisposed()) {
-                    return;
-                }
-                fTimeGraphViewer.getControl().redraw();
-                fTimeGraphViewer.getControl().update();
-                synchronized (fSyncObj) {
-                    if (fRedrawState == State.PENDING) {
-                        fRedrawState = State.IDLE;
-                        redraw();
-                    } else {
-                        fRedrawState = State.IDLE;
-                    }
-                }
-            }
-        });
-    }
-
-    private void startZoomThread(long startTime, long endTime) {
-        if (fZoomThread != null) {
-            fZoomThread.cancel();
-        }
-        fZoomThread = new ZoomThread(fEntryList, startTime, endTime);
-        fZoomThread.start();
-    }
-
-    private void makeActions() {
-        fPreviousResourceAction = fTimeGraphViewer.getPreviousItemAction();
-        fPreviousResourceAction.setText(Messages.ResourcesView_previousResourceActionNameText);
-        fPreviousResourceAction.setToolTipText(Messages.ResourcesView_previousResourceActionToolTipText);
-        fNextResourceAction = fTimeGraphViewer.getNextItemAction();
-        fNextResourceAction.setText(Messages.ResourcesView_nextResourceActionNameText);
-        fNextResourceAction.setToolTipText(Messages.ResourcesView_previousResourceActionToolTipText);
-    }
-
-    private void contributeToActionBars() {
-        IActionBars bars = getViewSite().getActionBars();
-        fillLocalToolBar(bars.getToolBarManager());
-    }
-
-    private void fillLocalToolBar(IToolBarManager manager) {
-        manager.add(fTimeGraphViewer.getShowLegendAction());
-        manager.add(new Separator());
-        manager.add(fTimeGraphViewer.getResetScaleAction());
-        manager.add(fTimeGraphViewer.getPreviousEventAction());
-        manager.add(fTimeGraphViewer.getNextEventAction());
-        manager.add(fPreviousResourceAction);
-        manager.add(fNextResourceAction);
-        manager.add(fTimeGraphViewer.getZoomInAction());
-        manager.add(fTimeGraphViewer.getZoomOutAction());
-        manager.add(new Separator());
-    }
 }
index 10904eacdd51171166cf883cc1fff729aeead973..8a2b06a839194e75ce798203815261458aa9b87f 100644 (file)
@@ -45,6 +45,7 @@ Export-Package: org.eclipse.linuxtools.internal.tmf.ui;x-friends:="org.eclipse.l
  org.eclipse.linuxtools.tmf.ui.views.statesystem,
  org.eclipse.linuxtools.tmf.ui.views.statistics,
  org.eclipse.linuxtools.tmf.ui.views.timechart,
+ org.eclipse.linuxtools.tmf.ui.views.timegraph,
  org.eclipse.linuxtools.tmf.ui.views.uml2sd,
  org.eclipse.linuxtools.tmf.ui.views.uml2sd.core,
  org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs,
index e7d037a0964f3c17488f1013960c8ff670f51bbf..ed5497be4e36fcd88858ee383c7dc1ef5dc1ed79 100644 (file)
@@ -46,6 +46,7 @@ public class CallStackEvent extends TimeEvent {
      *
      * @return The integer value
      */
+    @Override
     public int getValue() {
         return fValue;
     }
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java
new file mode 100644 (file)
index 0000000..615ad1e
--- /dev/null
@@ -0,0 +1,860 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 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
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Patrick Tasse - Initial API and implementation
+ *   Bernd Hufmann - Updated signal handling
+ *   Geneviève Bastien - Move code to provide base classes for time graph view
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.timegraph;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+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.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.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.ui.views.TmfView;
+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.model.ITimeEvent;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
+import org.eclipse.swt.SWT;
+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.ui.IActionBars;
+
+/**
+ * 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.
+ *
+ * @since 2.1
+ */
+public abstract class AbstractTimeGraphView extends TmfView {
+
+    private final String[] fColumns;
+    private final String[] fFilterColumns;
+
+    /**
+     * Redraw state enum
+     */
+    private enum State {
+        IDLE, BUSY, PENDING
+    }
+
+    // ------------------------------------------------------------------------
+    // Fields
+    // ------------------------------------------------------------------------
+
+    /** The timegraph combo */
+    private TimeGraphCombo fTimeGraphCombo;
+
+    /** The selected trace */
+    private ITmfTrace fTrace;
+
+    /** The timegraph entry list */
+    private List<TimeGraphEntry> fEntryList;
+
+    /** The trace to entry list hash map */
+    private final Map<ITmfTrace, List<TimeGraphEntry>> fEntryListMap = new HashMap<ITmfTrace, List<TimeGraphEntry>>();
+
+    /* The trace to build thread hash map */
+    private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<ITmfTrace, BuildThread>();
+
+    /** The start time */
+    private long fStartTime;
+
+    /** The end time */
+    private long fEndTime;
+
+    /** The display width */
+    private final int fDisplayWidth;
+
+    /** The zoom thread */
+    private ZoomThread fZoomThread;
+
+    /** The next resource action */
+    private Action fNextResourceAction;
+
+    /** 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 */
+    private State fRedrawState = State.IDLE;
+
+    /** The redraw synchronization object */
+    private final Object fSyncObj = new Object();
+
+    /** The presentation provider for this view */
+    private final TimeGraphPresentationProvider fPresentation;
+
+    private TreeLabelProvider fLabelProvider = new TreeLabelProvider();
+
+    // ------------------------------------------------------------------------
+    // Getters and setters
+    // ------------------------------------------------------------------------
+
+    /**
+     * Getter for the time graph combo
+     *
+     * @return The Time graph combo
+     */
+    protected TimeGraphCombo getTimeGraphCombo() {
+        return fTimeGraphCombo;
+    }
+
+    /**
+     * Sets the tree label provider
+     *
+     * @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
+     *
+     * @param weights
+     *            The array of relative weights of each part of the combo
+     */
+    protected void setWeight(final int[] weights) {
+        fWeight = weights;
+    }
+
+    /**
+     * 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 * Gets the display width
+     *
+     * @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;
+    }
+
+    /**
+     * Sets the trace to display
+     *
+     * @param trace
+     *            The trace
+     */
+    protected void setTrace(final ITmfTrace trace) {
+        fTrace = trace;
+    }
+
+    /**
+     * 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 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);
+        }
+    }
+
+    /**
+     * Text for the "next" button
+     *
+     * @return The "next" button text
+     */
+    protected String getNextText() {
+        return Messages.AbstractTimeGraphtView_NextText;
+    }
+
+    /**
+     * Tooltip for the "next" button
+     *
+     * @return Tooltip for the "next" button
+     */
+    protected String getNextTooltip() {
+        return Messages.AbstractTimeGraphView_NextTooltip;
+    }
+
+    /**
+     * Text for the "Previous" button
+     *
+     * @return The "Previous" button text
+     */
+    protected String getPrevText() {
+        return Messages.AbstractTimeGraphView_PreviousText;
+    }
+
+    /**
+     * Tooltip for the "previous" button
+     *
+     * @return Tooltip for the "previous" button
+     */
+    protected String getPrevTooltip() {
+        return Messages.AbstractTimeGraphView_PreviousTooltip;
+    }
+
+    // ------------------------------------------------------------------------
+    // Classes
+    // ------------------------------------------------------------------------
+
+    private class TreeContentProvider implements ITreeContentProvider {
+
+        @Override
+        public void dispose() {
+        }
+
+        @Override
+        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+        }
+
+        @Override
+        public Object[] getElements(Object inputElement) {
+            return (ITimeGraphEntry[]) inputElement;
+        }
+
+        @Override
+        public Object[] getChildren(Object parentElement) {
+            ITimeGraphEntry entry = (ITimeGraphEntry) parentElement;
+            List<? extends ITimeGraphEntry> children = entry.getChildren();
+            return children.toArray(new ITimeGraphEntry[children.size()]);
+        }
+
+        @Override
+        public Object getParent(Object element) {
+            ITimeGraphEntry entry = (ITimeGraphEntry) element;
+            return entry.getParent();
+        }
+
+        @Override
+        public boolean hasChildren(Object element) {
+            ITimeGraphEntry entry = (ITimeGraphEntry) element;
+            return entry.hasChildren();
+        }
+
+    }
+
+    /**
+     * 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
+     */
+    protected static class TreeLabelProvider implements ITableLabelProvider {
+
+        @Override
+        public void addListener(ILabelProviderListener listener) {
+        }
+
+        @Override
+        public void dispose() {
+        }
+
+        @Override
+        public boolean isLabelProperty(Object element, String property) {
+            return false;
+        }
+
+        @Override
+        public void removeListener(ILabelProviderListener listener) {
+        }
+
+        @Override
+        public Image getColumnImage(Object element, int columnIndex) {
+            return null;
+        }
+
+        @Override
+        public String getColumnText(Object element, int columnIndex) {
+            TimeGraphEntry entry = (TimeGraphEntry) element;
+            if (columnIndex == 0) {
+                return entry.getName();
+            }
+            return ""; //$NON-NLS-1$
+        }
+
+    }
+
+    private class BuildThread extends Thread {
+        private final ITmfTrace fBuildTrace;
+        private final IProgressMonitor fMonitor;
+
+        public BuildThread(final ITmfTrace trace, final String name) {
+            super(name + " build"); //$NON-NLS-1$
+            fBuildTrace = trace;
+            fMonitor = new NullProgressMonitor();
+        }
+
+        @Override
+        public void run() {
+            buildEventList(fBuildTrace, fMonitor);
+            synchronized (fBuildThreadMap) {
+                fBuildThreadMap.remove(this);
+            }
+        }
+
+        public void cancel() {
+            fMonitor.setCanceled(true);
+        }
+    }
+
+    private class ZoomThread extends Thread {
+        private final List<TimeGraphEntry> fZoomEntryList;
+        private final long fZoomStartTime;
+        private final long fZoomEndTime;
+        private final long fResolution;
+        private final IProgressMonitor fMonitor;
+
+        public ZoomThread(List<TimeGraphEntry> entryList, long startTime, long endTime, String name) {
+            super(name + " zoom"); //$NON-NLS-1$
+            fZoomEntryList = entryList;
+            fZoomStartTime = startTime;
+            fZoomEndTime = endTime;
+            fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
+            fMonitor = new NullProgressMonitor();
+        }
+
+        @Override
+        public void run() {
+            if (fZoomEntryList == null) {
+                return;
+            }
+            for (TimeGraphEntry entry : fZoomEntryList) {
+                if (fMonitor.isCanceled()) {
+                    break;
+                }
+                zoom(entry, fMonitor);
+            }
+        }
+
+        private void zoom(TimeGraphEntry entry, IProgressMonitor monitor) {
+            if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {
+                entry.setZoomedEventList(null);
+            } else {
+                List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor);
+                if (zoomedEventList != null) {
+                    entry.setZoomedEventList(zoomedEventList);
+                }
+            }
+            redraw();
+            for (TimeGraphEntry child : entry.getChildren()) {
+                if (fMonitor.isCanceled()) {
+                    return;
+                }
+                zoom(child, monitor);
+            }
+        }
+
+        public void cancel() {
+            fMonitor.setCanceled(true);
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor
+     *
+     * @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) {
+        super(id);
+        fColumns = cols;
+        fFilterColumns = filterCols;
+        fPresentation = pres;
+        fDisplayWidth = Display.getDefault().getBounds().width;
+    }
+
+    // ------------------------------------------------------------------------
+    // ViewPart
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void createPartControl(Composite parent) {
+        fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE, fWeight);
+
+        fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider());
+
+        fTimeGraphCombo.setTreeLabelProvider(fLabelProvider);
+
+        fTimeGraphCombo.setTimeGraphProvider(fPresentation);
+
+        fTimeGraphCombo.setTreeColumns(fColumns);
+
+        fTimeGraphCombo.setFilterContentProvider(new TreeContentProvider());
+
+        fTimeGraphCombo.setFilterLabelProvider(new TreeLabelProvider());
+
+        fTimeGraphCombo.setFilterColumns(fFilterColumns);
+
+        fTimeGraphCombo.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));
+                if (fZoomThread != null) {
+                    fZoomThread.cancel();
+                }
+                startZoomThread(startTime, endTime);
+            }
+        });
+
+        fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
+            @Override
+            public void timeSelected(TimeGraphTimeEvent event) {
+                long time = event.getTime();
+                broadcast(new TmfTimeSynchSignal(AbstractTimeGraphView.this, new CtfTmfTimestamp(time)));
+            }
+        });
+
+        fTimeGraphCombo.addSelectionListener(new ITimeGraphSelectionListener() {
+            @Override
+            public void selectionChanged(TimeGraphSelectionEvent event) {
+                // ITimeGraphEntry selection = event.getSelection();
+            }
+        });
+
+        fTimeGraphCombo.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
+
+        // View Action Handling
+        makeActions();
+        contributeToActionBars();
+
+        ITmfTrace trace = getActiveTrace();
+        if (trace != null) {
+            traceSelected(new TmfTraceSelectedSignal(this, trace));
+        }
+
+        // make selection available to other views
+        getSite().setSelectionProvider(fTimeGraphCombo.getTreeViewer());
+    }
+
+    @Override
+    public void setFocus() {
+        fTimeGraphCombo.setFocus();
+    }
+
+    // ------------------------------------------------------------------------
+    // Signal handlers
+    // ------------------------------------------------------------------------
+
+    /**
+     * Handler for the trace opened signal.
+     *
+     * @param signal
+     *            The incoming signal
+     * @since 2.0
+     */
+    @TmfSignalHandler
+    public void traceOpened(TmfTraceOpenedSignal signal) {
+        fTrace = signal.getTrace();
+        loadTrace();
+    }
+
+    /**
+     * Handler for the trace selected signal
+     *
+     * @param signal
+     *            The incoming signal
+     */
+    @TmfSignalHandler
+    public void traceSelected(final TmfTraceSelectedSignal signal) {
+        if (signal.getTrace() == fTrace) {
+            return;
+        }
+        fTrace = signal.getTrace();
+
+        loadTrace();
+    }
+
+    /**
+     * Trace is closed: clear the data structures and the view
+     *
+     * @param signal
+     *            the signal received
+     */
+    @TmfSignalHandler
+    public void traceClosed(final TmfTraceClosedSignal signal) {
+        synchronized (fBuildThreadMap) {
+            BuildThread buildThread = fBuildThreadMap.remove(signal.getTrace());
+            if (buildThread != null) {
+                buildThread.cancel();
+            }
+        }
+        synchronized (fEntryListMap) {
+            fEntryListMap.remove(signal.getTrace());
+        }
+        if (signal.getTrace() == fTrace) {
+            fTrace = null;
+            fStartTime = 0;
+            fEndTime = 0;
+            if (fZoomThread != null) {
+                fZoomThread.cancel();
+            }
+            refresh();
+        }
+    }
+
+    /**
+     * Handler for the synch signal
+     *
+     * @param signal
+     *            The signal that's received
+     */
+    @TmfSignalHandler
+    public void synchToTime(final TmfTimeSynchSignal signal) {
+        if (signal.getSource() == this || fTrace == null) {
+            return;
+        }
+        final long time = signal.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+
+        Display.getDefault().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+                if (fTimeGraphCombo.isDisposed()) {
+                    return;
+                }
+                fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);
+                startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
+
+                synchingToTime(time);
+            }
+        });
+    }
+
+    /**
+     * Handler for the range sync signal
+     *
+     * @param signal
+     *            The signal that's received
+     */
+    @TmfSignalHandler
+    public void synchToRange(final TmfRangeSynchSignal signal) {
+        if (signal.getSource() == this || fTrace == null) {
+            return;
+        }
+        if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) {
+            return;
+        }
+        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()) {
+                    return;
+                }
+                fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
+                fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);
+                startZoomThread(startTime, endTime);
+            }
+        });
+    }
+
+    // ------------------------------------------------------------------------
+    // Internal
+    // ------------------------------------------------------------------------
+
+    private void loadTrace() {
+        synchronized (fEntryListMap) {
+            fEntryList = fEntryListMap.get(fTrace);
+            if (fEntryList == null) {
+                synchronized (fBuildThreadMap) {
+                    BuildThread buildThread = new BuildThread(fTrace, this.getName());
+                    fBuildThreadMap.put(fTrace, buildThread);
+                    buildThread.start();
+                }
+            } else {
+                fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+                fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+                refresh();
+            }
+        }
+    }
+
+    /**
+     * Method called when synching to a given timestamp. Inheriting classes can
+     * perform actions here to update the view at the given timestamp.
+     *
+     * @param time
+     *            The currently selected time
+     */
+    protected void synchingToTime(long time) {
+
+    }
+
+    /**
+     * Build the entries list to show in this time graph
+     *
+     * Called from the BuildThread
+     *
+     * @param trace
+     *            The trace being built
+     * @param monitor
+     *            The progress monitor object
+     */
+    protected abstract void buildEventList(final ITmfTrace trace, IProgressMonitor monitor);
+
+    /**
+     * Gets the list of event for an entry in a given timerange
+     *
+     * @param entry
+     *            The entry to get events for
+     * @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 events for the entry
+     */
+    protected abstract List<ITimeEvent> getEventList(TimeGraphEntry entry,
+            long startTime, long endTime, long resolution,
+            IProgressMonitor monitor);
+
+    /**
+     * Refresh the display
+     */
+    protected void refresh() {
+        Display.getDefault().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+                if (fTimeGraphCombo.isDisposed()) {
+                    return;
+                }
+                ITimeGraphEntry[] entries = null;
+                synchronized (fEntryListMap) {
+                    fEntryList = fEntryListMap.get(fTrace);
+                    if (fEntryList == null) {
+                        fEntryList = new ArrayList<TimeGraphEntry>();
+                    }
+                    entries = fEntryList.toArray(new ITimeGraphEntry[0]);
+                }
+                if (fEntryComparator != null) {
+                    Arrays.sort(entries, fEntryComparator);
+                }
+                fTimeGraphCombo.setInput(entries);
+                fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
+
+                long timestamp = fTrace == null ? 0 : fTraceManager.getCurrentTime().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);
+
+                for (TreeColumn column : fTimeGraphCombo.getTreeViewer().getTree().getColumns()) {
+                    column.pack();
+                }
+
+                startZoomThread(startTime, endTime);
+            }
+        });
+    }
+
+    /**
+     * Redraw the canvas
+     */
+    protected void redraw() {
+        synchronized (fSyncObj) {
+            if (fRedrawState == State.IDLE) {
+                fRedrawState = State.BUSY;
+            } else {
+                fRedrawState = State.PENDING;
+                return;
+            }
+        }
+        Display.getDefault().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+                if (fTimeGraphCombo.isDisposed()) {
+                    return;
+                }
+                fTimeGraphCombo.redraw();
+                fTimeGraphCombo.update();
+                synchronized (fSyncObj) {
+                    if (fRedrawState == State.PENDING) {
+                        fRedrawState = State.IDLE;
+                        redraw();
+                    } else {
+                        fRedrawState = State.IDLE;
+                    }
+                }
+            }
+        });
+    }
+
+    private void startZoomThread(long startTime, long endTime) {
+        if (fZoomThread != null) {
+            fZoomThread.cancel();
+        }
+        fZoomThread = new ZoomThread(fEntryList, startTime, endTime, getName());
+        fZoomThread.start();
+    }
+
+    private void makeActions() {
+        fPreviousResourceAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction();
+        fPreviousResourceAction.setText(getPrevText());
+        fPreviousResourceAction.setToolTipText(getPrevTooltip());
+        fNextResourceAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction();
+        fNextResourceAction.setText(getNextText());
+        fNextResourceAction.setToolTipText(getNextTooltip());
+    }
+
+    private void contributeToActionBars() {
+        IActionBars bars = getViewSite().getActionBars();
+        fillLocalToolBar(bars.getToolBarManager());
+    }
+
+    private void fillLocalToolBar(IToolBarManager manager) {
+        if (fFilterColumns.length > 0) {
+            manager.add(fTimeGraphCombo.getShowFilterAction());
+        }
+        manager.add(fTimeGraphCombo.getTimeGraphViewer().getShowLegendAction());
+        manager.add(new Separator());
+        manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction());
+        manager.add(fTimeGraphCombo.getTimeGraphViewer().getPreviousEventAction());
+        manager.add(fTimeGraphCombo.getTimeGraphViewer().getNextEventAction());
+        manager.add(fPreviousResourceAction);
+        manager.add(fNextResourceAction);
+        manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction());
+        manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction());
+        manager.add(new Separator());
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/Messages.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/Messages.java
new file mode 100644 (file)
index 0000000..1d0ff0c
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.timegraph;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Generic messages for the bar charts
+ *
+ * @since 2.1
+ */
+@SuppressWarnings("javadoc")
+public class Messages extends NLS {
+    private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.timegraph.messages"; //$NON-NLS-1$
+
+    public static String AbstractTimeGraphtView_NextText;
+    public static String AbstractTimeGraphView_NextTooltip;
+    public static String AbstractTimeGraphView_PreviousText;
+    public static String AbstractTimeGraphView_PreviousTooltip;
+    public static String TimeGraphPresentationProvider_multipleStates;
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/messages.properties b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/messages.properties
new file mode 100644 (file)
index 0000000..ea1eba7
--- /dev/null
@@ -0,0 +1,5 @@
+AbstractTimeGraphtView_NextText=Next
+AbstractTimeGraphView_NextTooltip=Next element
+AbstractTimeGraphView_PreviousText=Previous
+AbstractTimeGraphView_PreviousTooltip=Previous element
+TimeGraphPresentationProvider_multipleStates=multiple states
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/ITimeGraphPresentationProvider2.java
new file mode 100644 (file)
index 0000000..8d5ea2c
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Add drawing helper methods
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.widgets.timegraph;
+
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper;
+
+/**
+ * Extension of the ITimeGraphPresentationProvider interface to avoid API breakage
+ *
+ * @author Geneviève Bastien
+ * @since 2.1
+ * TODO: Add me to ITimeGraphPresentationProvider before the 3.0 release
+ */
+public interface ITimeGraphPresentationProvider2 extends ITimeGraphPresentationProvider {
+
+    /**
+     * Returns the drawing helper for this presentation provider.
+     *
+     * @return The drawing helper
+     */
+    ITmfTimeGraphDrawingHelper getDrawingHelper();
+
+    /**
+     * Sets this presentation provider's drawing helper.
+     * This helper be needed to know where to draw items, get its coordinates
+     * given a time, etc.
+     *
+     * @param helper
+     *            The drawing helper
+     */
+    void setDrawingHelper(ITmfTimeGraphDrawingHelper helper);
+
+}
\ No newline at end of file
index 7ba43cde66aebe47eda024819b8de1ab2dcbab34..2c695fc491370706b45da90e980b8a1ee4696c88 100644 (file)
@@ -79,39 +79,45 @@ public class TimeGraphCombo extends Composite {
     // Fields
     // ------------------------------------------------------------------------
 
-    // The tree viewer
+    /** The tree viewer */
     private TreeViewer fTreeViewer;
 
-    // The time viewer
+    /** The time viewer */
     private TimeGraphViewer fTimeGraphViewer;
 
-    // The top-level input (children excluded)
+    /** The top-level input (children excluded) */
     private List<? extends ITimeGraphEntry> fTopInput;
 
-    // The selection listener map
+    /** The selection listener map */
     private final Map<ITimeGraphSelectionListener, SelectionListenerWrapper> fSelectionListenerMap = new HashMap<ITimeGraphSelectionListener, SelectionListenerWrapper>();
 
-    // The map of viewer filters
+    /** The map of viewer filters */
     private final Map<ViewerFilter, ViewerFilter> fViewerFilterMap = new HashMap<ViewerFilter, ViewerFilter>();
 
-    // Flag to block the tree selection changed listener when triggered by the time graph combo
+    /**
+     * Flag to block the tree selection changed listener when triggered by the
+     * time graph combo
+     */
     private boolean fInhibitTreeSelection = false;
 
-    // Number of filler rows used by the tree content provider
+    /** Number of filler rows used by the tree content provider */
     private int fNumFillerRows;
 
-    // Calculated item height for Linux workaround
+    /** Calculated item height for Linux workaround */
     private int fLinuxItemHeight = 0;
 
-    // The button that opens the filter dialog
+    /** The button that opens the filter dialog */
     private Action showFilterAction;
 
-    // The filter dialog
+    /** The filter dialog */
     private TimeGraphFilterDialog fFilterDialog;
 
-    // The filter generated from the filter dialog
+    /** The filter generated from the filter dialog */
     private RawViewerFilter fFilter;
 
+    /** Default weight of each part of the sash */
+    private static final int[] DEFAULT_WEIGHTS = { 1, 1 };
+
     // ------------------------------------------------------------------------
     // Classes
     // ------------------------------------------------------------------------
@@ -326,6 +332,23 @@ public class TimeGraphCombo extends Composite {
      * @param style the style of widget to construct
      */
     public TimeGraphCombo(Composite parent, int style) {
+        this(parent, style, DEFAULT_WEIGHTS);
+    }
+
+    /**
+     * Constructs a new instance of this class given its parent and a style
+     * value describing its behavior and appearance.
+     *
+     * @param parent
+     *            a widget which will be the parent of the new instance (cannot
+     *            be null)
+     * @param style
+     *            the style of widget to construct
+     * @param weights
+     *            The relative weights of each side of the sash form
+     * @since 2.1
+     */
+    public TimeGraphCombo(Composite parent, int style, int[] weights) {
         super(parent, style);
         setLayout(new FillLayout());
 
@@ -608,7 +631,7 @@ public class TimeGraphCombo extends Composite {
         // to a value that would cause blank space to be drawn at the bottom of the tree.
         fNumFillerRows = Display.getDefault().getBounds().height / getItemHeight(tree);
 
-        sash.setWeights(new int[] { 1, 1 });
+        sash.setWeights(weights);
     }
 
     // ------------------------------------------------------------------------
index a33d6c1e58c33acdca24a7b87bcb513cd33bfb42..807b174b0da5201053e0be9fb2cd4ca0e20b9109 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2013 Ericsson
+ * Copyright (c) 2009, 2013 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
@@ -9,6 +9,7 @@
  * Contributors:
  *   Alvaro Sanchez-Leon - Initial API and implementation
  *   Patrick Tasse - Refactoring
+ *   Geneviève Bastien - Add drawing helper methods
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph;
@@ -18,6 +19,7 @@ import java.util.Map;
 import org.eclipse.linuxtools.internal.tmf.ui.Messages;
 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.widgets.ITmfTimeGraphDrawingHelper;
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Rectangle;
@@ -29,7 +31,10 @@ import org.eclipse.swt.graphics.Rectangle;
  * @author Patrick Tasse
  *
  */
-public class TimeGraphPresentationProvider implements ITimeGraphPresentationProvider {
+public class TimeGraphPresentationProvider implements ITimeGraphPresentationProvider2 {
+
+    private ITmfTimeGraphDrawingHelper fDrawingHelper;
+    private final String fStateTypeName;
 
     // ------------------------------------------------------------------------
     // Constants
@@ -40,9 +45,26 @@ public class TimeGraphPresentationProvider implements ITimeGraphPresentationProv
     // Operations
     // ------------------------------------------------------------------------
 
+    /**
+     * Constructor
+     * @param stateTypeName  The state type name
+     * @since 2.1
+     */
+    public TimeGraphPresentationProvider(String stateTypeName) {
+        fStateTypeName = stateTypeName;
+    }
+
+    /**
+     * Constructor
+     * @since 2.1
+     */
+    public TimeGraphPresentationProvider() {
+        this(Messages.TmfTimeLegend_TRACE_STATES);
+    }
+
     @Override
     public String getStateTypeName() {
-        return Messages.TmfTimeLegend_TRACE_STATES;
+        return fStateTypeName;
     }
 
     /**
@@ -64,6 +86,22 @@ public class TimeGraphPresentationProvider implements ITimeGraphPresentationProv
         return 0;
     }
 
+    /**
+     * @since 2.1
+     */
+    @Override
+    public ITmfTimeGraphDrawingHelper getDrawingHelper() {
+        return fDrawingHelper;
+    }
+
+    /**
+     * @since 2.1
+     */
+    @Override
+    public void setDrawingHelper(ITmfTimeGraphDrawingHelper helper) {
+        fDrawingHelper = helper;
+    }
+
     @Override
     public void postDrawControl(Rectangle bounds, GC gc) {
         // Override to add own drawing code
index 6cd1c0a699d8ea539e765a3f0cf814c1e517756a..8b1db841cef6c2c84f4c12095b812164f4a2994a 100644 (file)
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
+ *   Geneviève Bastien - Added the fValue parameter to avoid subclassing
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model;
@@ -29,6 +30,13 @@ public class TimeEvent implements ITimeEvent {
     /** Duration of this time event */
     protected long fDuration;
 
+    private final int fValue;
+
+    /**
+     * Default value when no other value present
+     */
+    private static final int NOVALUE = Integer.MIN_VALUE;
+
     /**
      * Standard constructor
      *
@@ -40,9 +48,49 @@ public class TimeEvent implements ITimeEvent {
      *            The duration of the event
      */
     public TimeEvent(ITimeGraphEntry entry, long time, long duration) {
+        this(entry, time, duration, NOVALUE);
+
+    }
+
+    /**
+     * Constructor
+     *
+     * @param entry
+     *            The entry to which this time event is assigned
+     * @param time
+     *            The timestamp of this event
+     * @param duration
+     *            The duration of this event
+     * @param value
+     *            The status assigned to the event
+     * @since 2.1
+     */
+    public TimeEvent(ITimeGraphEntry entry, long time, long duration,
+            int value) {
         fEntry = entry;
         fTime = time;
         fDuration = duration;
+        fValue = value;
+    }
+
+    /**
+     * Get this event's status
+     *
+     * @return The integer matching this status
+     * @since 2.1
+     */
+    public int getValue() {
+        return fValue;
+    }
+
+    /**
+     * Return whether an event has a value
+     *
+     * @return true if the event has a value
+     * @since 2.1
+     */
+    public boolean hasValue() {
+        return (fValue != NOVALUE);
     }
 
     @Override
@@ -62,6 +110,6 @@ public class TimeEvent implements ITimeEvent {
 
     @Override
     public String toString() {
-        return "TimeEvent start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        return "TimeEvent start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + " value=" + (hasValue() ? fValue : "N/A"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
     }
 }
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java
new file mode 100644 (file)
index 0000000..a56ecbd
--- /dev/null
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 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
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Patrick Tasse - Initial API and implementation
+ *   Geneviève Bastien - Move code to provide base classes for time graph view
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * An entry for use in the time graph views
+ *
+ * @since 2.1
+ */
+public class TimeGraphEntry implements ITimeGraphEntry {
+
+    /** Id field that may be used by views, so they don't have to extend this class if they don't need to */
+    private final int fEntryId;
+    private final ITmfTrace fTrace;
+
+    /** Entry's parent */
+    private TimeGraphEntry fParent = null;
+
+    /** List of child entries */
+    private final List<TimeGraphEntry> fChildren = new ArrayList<TimeGraphEntry>();
+
+    /** Name of this entry (text to show) */
+    private String fName;
+    private long fStartTime = -1;
+    private long fEndTime = -1;
+    private List<ITimeEvent> fEventList = new ArrayList<ITimeEvent>();
+    private List<ITimeEvent> fZoomedEventList = null;
+
+    /**
+     * Constructor
+     *
+     * @param entryid
+     *            Some id attribute for the entry whose state is shown on this
+     *            row
+     * @param trace
+     *            The trace on which we are working
+     * @param name
+     *            The exec_name of this entry
+     * @param startTime
+     *            The start time of this process's lifetime
+     * @param endTime
+     *            The end time of this process
+     */
+    public TimeGraphEntry(int entryid, ITmfTrace trace, String name, long startTime, long endTime) {
+        fEntryId = entryid;
+        fTrace = trace;
+        fName = name;
+        fStartTime = startTime;
+        fEndTime = endTime;
+    }
+
+    // ---------------------------------------------
+    // Getters and setters
+    // ---------------------------------------------
+
+    @Override
+    public ITimeGraphEntry getParent() {
+        return fParent;
+    }
+
+    /**
+     * Sets the entry's parent
+     *
+     * @param entry The new parent entry
+     */
+    protected void setParent(TimeGraphEntry entry) {
+        fParent = entry;
+    }
+
+    @Override
+    public boolean hasChildren() {
+        return fChildren.size() > 0;
+    }
+
+    @Override
+    public List<TimeGraphEntry> getChildren() {
+        return fChildren;
+    }
+
+    @Override
+    public String getName() {
+        return fName;
+    }
+
+    /**
+     * Update the entry name
+     *
+     * @param name
+     *            the updated entry name
+     */
+    public void setName(String name) {
+        fName = name;
+    }
+
+    @Override
+    public long getStartTime() {
+        return fStartTime;
+    }
+
+    @Override
+    public long getEndTime() {
+        return fEndTime;
+    }
+
+    @Override
+    public boolean hasTimeEvents() {
+        return true;
+    }
+
+    @Override
+    public Iterator<ITimeEvent> getTimeEventsIterator() {
+        if (hasTimeEvents()) {
+            return new EventIterator(fEventList, fZoomedEventList);
+        }
+        return null;
+    }
+
+    @Override
+    public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
+        if (!hasTimeEvents()) {
+            return null;
+        }
+        return new EventIterator(fEventList, fZoomedEventList, startTime, stopTime);
+    }
+
+    /**
+     * Get the id of this entry
+     *
+     * @return The entry id
+     */
+    public int getEntryId() {
+        return fEntryId;
+    }
+
+    /**
+     * Get the trace object
+     *
+     * @return The trace
+     */
+    public ITmfTrace getTrace() {
+        return fTrace;
+    }
+
+    /**
+     * Add an event to this process's timeline
+     *
+     * @param event
+     *            The time event
+     */
+    public void addEvent(ITimeEvent event) {
+        long start = event.getTime();
+        long end = start + event.getDuration();
+        synchronized (fEventList) {
+            fEventList.add(event);
+            if (fStartTime == -1 || start < fStartTime) {
+                fStartTime = start;
+            }
+            if (fEndTime == -1 || end > fEndTime) {
+                fEndTime = end;
+            }
+        }
+    }
+
+    /**
+     * Set the general event list of this entry.
+     *
+     * Creates a copy of the list to avoid the caller still modifying the list
+     *
+     * @param eventList
+     *            The list of time events
+     */
+    public void setEventList(List<ITimeEvent> eventList) {
+        fEventList = new ArrayList<ITimeEvent>(eventList);
+    }
+
+    /**
+     * Set the zoomed event list of this entry.
+     *
+     * Creates a copy of the list to avoid the caller still modifying the list
+     *
+     * @param eventList
+     *            The list of time events
+     */
+    public void setZoomedEventList(List<ITimeEvent> eventList) {
+        fZoomedEventList = new ArrayList<ITimeEvent>(eventList);
+    }
+
+    /**
+     * Add a child entry to this one (to show relationships between processes as
+     * a tree)
+     *
+     * @param child
+     *            The child entry
+     */
+    public void addChild(TimeGraphEntry child) {
+        child.fParent = this;
+        fChildren.add(child);
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITmfTimeGraphDrawingHelper.java
new file mode 100644 (file)
index 0000000..26dbd21
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;
+
+/**
+ * This interface provides functions to convert a model element to a drawing
+ * element and vice versa.
+ *
+ * Views who implement this interface allow access to some model-to-canvas and
+ * vice-versa functions without having to expose their full functionnalities.
+ *
+ * @author gbastien
+ * @since 2.1
+ */
+public interface ITmfTimeGraphDrawingHelper {
+
+    /**
+     * Return the x coordinate corresponding to a time
+     *
+     * @param time
+     *            the time
+     * @return the x coordinate corresponding to the time
+     */
+    int getXForTime(long time);
+
+    /**
+     * Return the time corresponding to an x coordinate
+     *
+     * @param x
+     *            the x coordinate
+     * @return the time corresponding to the x coordinate
+     */
+    long getTimeAtX(int x);
+}
index dda1a0df2933873a7552a52f69101a4f4b80f116..df69754014fb0238bdb5939fc3c57a282589415a 100644 (file)
@@ -1,5 +1,6 @@
 /*****************************************************************************
- * Copyright (c) 2007, 2013 Intel Corporation, Ericsson.
+ * Copyright (c) 2007, 2013 Intel Corporation and others
+ *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,8 +9,10 @@
  * Contributors:
  *   Intel Corporation - Initial API and implementation
  *   Ruslan A. Scherbakov, Intel - Initial API and implementation
- *   Alvaro Sanchez-Leon - Updated for TMF
- *   Patrick Tasse - Refactoring
+ *   Alvaro Sanchez-Leon, Ericsson - Updated for TMF
+ *   Patrick Tasse, Ericsson - Refactoring
+ *   Geneviève Bastien, École Polytechnique de Montréal - Move code to
+ *                            provide base classes for time graph view
  *****************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;
@@ -26,6 +29,7 @@ import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.ViewerFilter;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider;
+import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTreeListener;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTreeExpansionEvent;
@@ -70,7 +74,7 @@ import org.eclipse.swt.widgets.ScrollBar;
  * @author Alvaro Sanchez-Leon
  * @author Patrick Tasse
  */
-public class TimeGraphControl extends TimeGraphBaseControl implements FocusListener, KeyListener, MouseMoveListener, MouseListener, MouseWheelListener, ControlListener, SelectionListener, MouseTrackListener, TraverseListener, ISelectionProvider, MenuDetectListener {
+public class TimeGraphControl extends TimeGraphBaseControl implements FocusListener, KeyListener, MouseMoveListener, MouseListener, MouseWheelListener, ControlListener, SelectionListener, MouseTrackListener, TraverseListener, ISelectionProvider, MenuDetectListener, ITmfTimeGraphDrawingHelper {
 
 
     /** Max scrollbar size */
@@ -211,6 +215,10 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
     public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) {
         fTimeGraphProvider = timeGraphProvider;
 
+        if (timeGraphProvider instanceof ITimeGraphPresentationProvider2) {
+            ((ITimeGraphPresentationProvider2) timeGraphProvider).setDrawingHelper(this);
+        }
+
         if (fEventColorMap != null) {
             for (Color color : fEventColorMap) {
                 fResourceManager.destroyColor(color.getRGB());
@@ -906,13 +914,9 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
     }
 
     /**
-     * Return the x coordinate corresponding to a time
-     *
-     * @param time the time
-     * @return the x coordinate corresponding to the time
-     *
      * @since 2.0
      */
+    @Override
     public int getXForTime(long time) {
         if (null == fTimeProvider) {
             return -1;
@@ -927,13 +931,9 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe
     }
 
     /**
-     * Return the time corresponding to an x coordinate
-     *
-     * @param coord The X coordinate
-     * @return The time corresponding to the x coordinate
-     *
      * @since 2.0
      */
+    @Override
     public long getTimeAtX(int coord) {
         if (null == fTimeProvider) {
             return -1;
This page took 0.082905 seconds and 5 git commands to generate.