Refactor the Histogram View (Bug352885)
authorFrancois Chouinard <fchouinard@gmail.com>
Fri, 22 Jul 2011 15:49:28 +0000 (11:49 -0400)
committerFrancois Chouinard <fchouinard@gmail.com>
Fri, 22 Jul 2011 15:49:28 +0000 (11:49 -0400)
41 files changed:
org.eclipse.linuxtools.lttng.ui.tests/src/org/eclipse/linuxtools/lttng/ui/tests/histogram/HistogramDataModelTest.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/META-INF/MANIFEST.MF
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/LTTngUILogger.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ChildrenHistogramCanvas.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/FullTraceHistogram.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/Histogram.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasControlListener.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasKeyListener.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasMouseListener.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCurrentTimeControl.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramDataModel.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramScaledData.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramTextControl.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramTimeRangeControl.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramUtils.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramView.java
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramZoom.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/Messages.java
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvas.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasControlListener.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasPaintListener.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeRangeHistogram.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeTextGroup.java [deleted file]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/messages.properties
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/ImportTraceWizardPage.java
org.eclipse.linuxtools.lttng/META-INF/MANIFEST.MF
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngException.java [deleted file]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/exceptions/EventOutOfSequenceException.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/exceptions/LttngException.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTrace.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTraceVersion.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java
org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/signal/TmfRangeSynchSignal.java

diff --git a/org.eclipse.linuxtools.lttng.ui.tests/src/org/eclipse/linuxtools/lttng/ui/tests/histogram/HistogramDataModelTest.java b/org.eclipse.linuxtools.lttng.ui.tests/src/org/eclipse/linuxtools/lttng/ui/tests/histogram/HistogramDataModelTest.java
new file mode 100644 (file)
index 0000000..7384e74
--- /dev/null
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.tests.histogram;
+
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramDataModel;
+import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramScaledData;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * <b><u>HistogramDataModelTest</u></b>
+ * <p>
+ * Unit tests for the HistogramDataModel class.
+ */
+public class HistogramDataModelTest {
+
+    // ------------------------------------------------------------------------
+    // Test data
+    // ------------------------------------------------------------------------
+
+    // ------------------------------------------------------------------------
+    // Housekeeping
+    // ------------------------------------------------------------------------
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    // ------------------------------------------------------------------------
+    // Tests
+    // ------------------------------------------------------------------------
+
+    /**
+     * Test method for
+     * {@link org.eclipse.linuxtools.tmf.HistogramDataModel.views.histogram.TmfHistogramDataModel#HistogramDataModel()}
+     * .
+     */
+    @Test
+    public void testHistogramDataModel() {
+        HistogramDataModel model = new HistogramDataModel();
+        assertTrue(model.getNbBuckets() == HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS);
+        assertTrue(model.getNbEvents() == 0);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == 0);
+        assertTrue(model.getTimeLimit() == HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS);
+    }
+
+    /**
+     * Test method for
+     * {@link org.eclipse.linuxtools.tmf.HistogramDataModel.views.histogram.TmfHistogramDataModel#HistogramDataModel(int)}
+     * .
+     */
+    @Test
+    public void testHistogramDataModelInt() {
+        final int nbBuckets = 5 * 1000;
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        assertTrue(model.getNbEvents() == 0);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == 0);
+        assertTrue(model.getTimeLimit() == nbBuckets);
+    }
+
+    /**
+     * Test methods for
+     * {@link org.eclipse.linuxtools.tmf.HistogramDataModel.views.histogram.TmfHistogramDataModel#countEvent(long)}
+     * .
+     */
+    @Test
+    public void testClear() {
+        final int nbBuckets = 100;
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        model.countEvent(-1);
+
+        assertTrue(model.getNbEvents() == 0);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == 0);
+        assertTrue(model.getTimeLimit() == nbBuckets);
+    }
+
+    /**
+     * Test methods for
+     * {@link org.eclipse.linuxtools.tmf.HistogramDataModel.views.histogram.TmfHistogramDataModel#countEvent(long)}
+     * .
+     */
+    @Test
+    public void testCountEvent_0() {
+        final int nbBuckets = 100;
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        model.countEvent(-1);
+
+        assertTrue(model.getNbEvents() == 0);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == 0);
+        assertTrue(model.getTimeLimit() == nbBuckets);
+    }
+
+    @Test
+    public void testCountEvent_1() {
+        final int nbBuckets = 100;
+        final int maxHeight = 10;
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == 0);
+        }
+
+        assertTrue(model.getNbEvents() == 0);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == 0);
+        assertTrue(model.getTimeLimit() == nbBuckets);
+    }
+
+    @Test
+    public void testCountEvent_2() {
+        final int nbBuckets = 100;
+        final int maxHeight = 10;
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        model.countEvent(1);
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        assertTrue(result.fData[0] == 1);
+        for (int i = 1; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == 0);
+        }
+
+        assertTrue(model.getNbEvents() == 1);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 1);
+        assertTrue(model.getEndTime() == 1);
+        assertTrue(model.getTimeLimit() == nbBuckets + 1);
+    }
+
+    @Test
+    public void testCountEvent_3() {
+        final int nbBuckets = 100;
+        final int maxHeight = 10;
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = 0; i < nbBuckets; i++) {
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == 1);
+        }
+
+        assertTrue(model.getNbEvents() == nbBuckets);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == nbBuckets - 1);
+        assertTrue(model.getTimeLimit() == nbBuckets);
+    }
+
+    @Test
+    public void testCountEvent_4() {
+        final int nbBuckets = 100;
+        final int maxHeight = 10;
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = 0; i < nbBuckets; i++) {
+            model.countEvent(i);
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == 2);
+        }
+
+        assertTrue(model.getNbEvents() == 2 * nbBuckets);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == nbBuckets - 1);
+        assertTrue(model.getTimeLimit() == nbBuckets);
+    }
+
+    @Test
+    public void testCountEvent_5() {
+        final int nbBuckets = 100;
+        final int startTime = 25;
+        final int maxHeight = 10;
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = startTime; i < startTime + nbBuckets; i++) {
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == 1);
+        }
+
+        assertTrue(model.getNbEvents() == nbBuckets);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == startTime);
+        assertTrue(model.getEndTime() == startTime + nbBuckets - 1);
+        assertTrue(model.getTimeLimit() == startTime + nbBuckets);
+    }
+
+    /**
+     * Test method for
+     * {@link org.eclipse.linuxtools.tmf.HistogramDataModel.views.histogram.TmfHistogramDataModel#scaleTo(int,int)}
+     * .
+     */
+    @Test
+    public void testScaleTo_1() {
+        final int nbBuckets = 10;
+        final int maxHeight = 10;
+        final int nbEvents = nbBuckets / 2;
+        final int[] expectedResult = new int[] { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = 0; i < nbEvents; i++) {
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == expectedResult[i]);
+        }
+
+        assertTrue(model.getNbEvents() == nbEvents);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == nbEvents - 1);
+        assertTrue(model.getTimeLimit() == nbBuckets);
+    }
+
+    @Test
+    public void testScaleTo_2() {
+        final int nbBuckets = 10;
+        final int maxHeight = 10;
+        final int nbEvents = nbBuckets;
+        final int[] expectedResult = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = 0; i < nbEvents; i++) {
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == expectedResult[i]);
+        }
+
+        assertTrue(model.getNbEvents() == nbEvents);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 1);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == nbEvents - 1);
+        assertTrue(model.getTimeLimit() == nbBuckets);
+    }
+
+    @Test
+    public void testScaleTo_3() {
+        final int nbBuckets = 10;
+        final int maxHeight = 10;
+        final int nbEvents = 2 * nbBuckets;
+        final int[] expectedResult = new int[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = 0; i < nbEvents; i++) {
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == expectedResult[i]);
+        }
+
+        assertTrue(model.getNbEvents() == nbEvents);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 2);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == nbEvents - 1);
+        assertTrue(model.getTimeLimit() == 2 * nbBuckets);
+    }
+
+    @Test
+    public void testScaleTo_4() {
+        final int nbBuckets = 10;
+        final int maxHeight = 10;
+        final int nbEvents = 3 * nbBuckets;
+        final int[] expectedResult = new int[] { 4, 4, 4, 4, 4, 4, 4, 2, 0, 0 };
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = 0; i < nbEvents; i++) {
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == expectedResult[i]);
+        }
+
+        assertTrue(model.getNbEvents() == nbEvents);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 4);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == nbEvents - 1);
+        assertTrue(model.getTimeLimit() == 4 * nbBuckets);
+    }
+
+    @Test
+    public void testScaleTo_5() {
+        final int nbBuckets = 100;
+        final int maxHeight = 20;
+        final int nbEvents = 2 * nbBuckets;
+        final int[] expectedResult = new int[] { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 };
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = 0; i < nbEvents; i++) {
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(10, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == expectedResult[i]);
+        }
+
+        assertTrue(model.getNbEvents() == nbEvents);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 2);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == nbEvents - 1);
+        assertTrue(model.getTimeLimit() == 2 * nbBuckets);
+    }
+
+    @Test
+    public void testScaleTo_6() {
+        final int nbBuckets = 100;
+        final int maxHeight = 24;
+        final int nbEvents = 2 * nbBuckets + 1;
+        final int[] expectedResult = new int[] { 24, 24, 24, 24, 24, 24, 24, 24, 9, 0 };
+
+        HistogramDataModel model = new HistogramDataModel(nbBuckets);
+        for (int i = 0; i < nbEvents; i++) {
+            model.countEvent(i);
+        }
+
+        HistogramScaledData result = model.scaleTo(10, maxHeight);
+        for (int i = 0; i < result.fData.length; i++) {
+            assertTrue(result.fData[i] == expectedResult[i]);
+        }
+
+        assertTrue(model.getNbEvents() == nbEvents);
+        assertTrue(model.getNbBuckets() == nbBuckets);
+        assertTrue(model.getBucketDuration() == 4);
+        assertTrue(model.getStartTime() == 0);
+        assertTrue(model.getEndTime() == nbEvents - 1);
+        assertTrue(model.getTimeLimit() == 4 * nbBuckets);
+    }
+
+}
index 48a739faed73cfd904ce01ca56497aa27c59a091..a9ddff05184a47027d4daf55fcd7b48f993a8643 100644 (file)
@@ -22,3 +22,33 @@ Require-Bundle: org.eclipse.ui,
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Bundle-Localization: plugin
+Export-Package: org.eclipse.linuxtools.lttng.ui;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.model.trange;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol.actions;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol.connectorservice;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol.dialogs;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol.model;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol.model.config;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol.subsystems;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol.utility;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.tracecontrol.wizards;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.common;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.control;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.controlflow;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.controlflow.model;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.events;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.histogram;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.project;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.project.dialogs;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.project.handlers;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.project.model;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.resources;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.resources.evProcessor;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.resources.model;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.statistics;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.statistics.model;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
+ org.eclipse.linuxtools.lttng.ui.views.timeframe;x-friends:="org.eclipse.linuxtools.lttng.ui.tests"
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/LTTngUILogger.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/LTTngUILogger.java
new file mode 100644 (file)
index 0000000..e6e163f
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui;
+
+/**
+ * <b><u>LTTngUILogger</u></b>
+ * <p>
+ * A logging utility 
+ */
+public class LTTngUILogger {
+
+       public static void logInfo(String message) {
+               LTTngUiPlugin.getDefault().getLogger().logInfo(message);
+       }
+
+       public static void logWarning(String message) {
+               LTTngUiPlugin.getDefault().getLogger().logWarning(message);
+       }
+
+       public static void logError(Throwable exception) {
+               logError("Unexpected exception", exception); //$NON-NLS-1$
+       }
+
+       public static void logError(String message, Throwable exception) {
+               LTTngUiPlugin.getDefault().getLogger().logError(message, exception);
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ChildrenHistogramCanvas.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ChildrenHistogramCanvas.java
deleted file mode 100644 (file)
index 23ba8ad..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *   
- * Modifications:
- * 2010-06-20 Yuriy Vashchuk - Histogram optimisations.   
- * 2010-07-16 Yuriy Vashchuk - Base Histogram class simplification.
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * <b><u>ChildrenHistogramCanvas</u></b>
- * <p>
- * Extended implementation of the HistogramCanvas.
- * <p>
- * This canvas goal is to display the "SelectionWindow" in details. 
- */
-public class ChildrenHistogramCanvas extends HistogramCanvas {
-       
-       private HistogramCanvasPaintListener    paintListener = null;
-       private HistogramCanvasControlListener  controlListener = null;
-       
-       /**
-        * ChildrenHistogramCanvas constructor.<p>
-        * Same as HistogramCanvas, but receive a parent HistogramView that we can call from here.
-        * 
-        * @param parent                Composite control which will be the parent of the new instance (cannot be null)
-        * @param                               Style the style of control to construct
-        */
-       public ChildrenHistogramCanvas(HistogramView histogramView, Composite parent, int style) {
-               super(histogramView, parent, style);
-               
-               // 2010-06-20 Yuriy: Moved from parent class
-               createAndAddPaintListener();
-               createAndAddControlListener();
-       }
-
-       /*
-        * Create a histogram paint listener and bind it to this canvas.<p>
-        * 
-        * Note : This one is a bit particular, as it is made to draw content that is of a power of 2.
-        *                      The default one draw content that is relative to the real pixels size.
-        */
-       private void createAndAddPaintListener() {
-               paintListener = new HistogramCanvasPaintListener(this);
-               this.addPaintListener( paintListener );
-       }
-       
-       /*
-        * Create a histogram control listener and bind it to this canvas.<p>
-        * 
-        *  @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
-        */
-       private void createAndAddControlListener() {
-               controlListener = new HistogramCanvasControlListener(this);
-               this.addControlListener(controlListener);
-       }
-       
-       /**
-        * Notify the parent HistogramView that we have updated information.<p>
-        * This is intended to be called at the end of the request when we know we have up-to-date information.
-        */
-       @Override
-       public void notifyParentUpdatedInformation() {
-               if(getHistogramView() != null) {
-                       getHistogramView().updateSelectedWindowInformation();
-               }
-       }
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/FullTraceHistogram.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/FullTraceHistogram.java
new file mode 100644 (file)
index 0000000..9cebbd4
--- /dev/null
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * <b><u>FullTraceHistogram</u></b>
+ * <p>
+ * A histogram that displays the full trace.
+ * <p>
+ * It also features a selected range window that can be dragged and zoomed.
+ */
+public class FullTraceHistogram extends Histogram implements MouseMoveListener {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    // Histogram colors
+    private final Color fTimeRangeColor = new Color(Display.getCurrent(), 255, 128, 0);
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    private final HistogramZoom fZoom;
+
+    private long fRangeStartTime;
+    private long fRangeDuration;
+
+    // ------------------------------------------------------------------------
+    // Construction
+    // ------------------------------------------------------------------------
+
+    public FullTraceHistogram(HistogramView view, Composite parent) {
+        super(view, parent);
+        fZoom = new HistogramZoom(this, fCanvas, getStartTime(), getTimeLimit());
+        fCanvas.addMouseMoveListener(this);
+    }
+
+    @Override
+    public void dispose() {
+        fTimeRangeColor.dispose();
+        super.dispose();
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    public void setTimeRange(long startTime, long duration) {
+        fRangeStartTime = startTime;
+        fRangeDuration = duration;
+        fZoom.setFullRange(getStartTime(), getEndTime());
+        fZoom.setNewRange(fRangeStartTime, fRangeDuration);
+        refresh();
+    }
+
+    @Override
+    public void updateTimeRange(long startTime, long endTime) {
+        ((HistogramView) fParentView).updateTimeRange(startTime, endTime);
+    }
+
+    // ------------------------------------------------------------------------
+    // MouseListener
+    // ------------------------------------------------------------------------
+
+    private boolean fMouseDown;
+    private int fStartPosition;
+
+    @Override
+    public void mouseDown(MouseEvent event) {
+        // Check if we are outside the time range; if so, just set the current
+        // event
+        long timestamp = getTimestamp(event.x);
+        if (timestamp < fZoom.getStartTime() || timestamp > fZoom.getEndTime()) {
+            super.mouseDown(event);
+            return;
+        }
+
+        // Otherwise start moving the range window
+        fMouseDown = true;
+        fStartPosition = event.x;
+    }
+
+    @Override
+    public void mouseUp(MouseEvent event) {
+        if (fMouseDown) {
+            fMouseDown = false;
+            ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fZoom.getDuration());
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // MouseMoveListener
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void mouseMove(MouseEvent event) {
+        if (fMouseDown) {
+            int nbBuckets = event.x - fStartPosition;
+            long delta = nbBuckets * fScaledData.fBucketDuration;
+            long newStart = fZoom.getStartTime() + delta;
+            if (newStart < getStartTime())
+                newStart = getStartTime();
+            long newEnd = newStart + fZoom.getDuration();
+            if (newEnd > getEndTime()) {
+                newEnd = getEndTime();
+                newStart = newEnd - fZoom.getDuration();
+            }
+            fRangeStartTime = newStart;
+            refresh();
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // PaintListener
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void paintControl(PaintEvent event) {
+        super.paintControl(event);
+
+        Image image = (Image) fCanvas.getData(IMAGE_KEY);
+        assert image != null;
+
+        Image rangeRectangleImage = new Image(image.getDevice(), image, SWT.IMAGE_COPY);
+        GC rangeWindowGC = new GC(rangeRectangleImage);
+
+        if (fRangeStartTime != 0) {
+            drawTimeRangeWindow(rangeWindowGC, rangeRectangleImage);
+        }
+
+        // Draws the buffer image onto the canvas.
+        event.gc.drawImage(rangeRectangleImage, 0, 0);
+
+        rangeWindowGC.dispose();
+        rangeRectangleImage.dispose();
+    }
+
+    private void drawTimeRangeWindow(GC imageGC, Image image) {
+
+        // Map times to histogram coordinates
+        long bucketSpan = fScaledData.fBucketDuration;
+        int rangeWidth = (int) (fRangeDuration / bucketSpan);
+
+        int left = (int) ((fRangeStartTime - fDataModel.getStartTime()) / bucketSpan);
+        int right = left + rangeWidth;
+        int center = (left + right) / 2;
+        int height = fCanvas.getSize().y - 2;
+
+        // Draw the selection window
+        imageGC.setForeground(fTimeRangeColor);
+        imageGC.setLineWidth(1);
+        imageGC.setLineStyle(SWT.LINE_SOLID);
+        imageGC.drawRoundRectangle(left, 0, rangeWidth, height - 1, 15, 15);
+
+        // Fill the selection window
+        imageGC.setBackground(fTimeRangeColor);
+        imageGC.setAlpha(35);
+        imageGC.fillRoundRectangle(left + 1, 1, rangeWidth - 1, height - 2, 15, 15);
+        imageGC.setAlpha(255);
+
+        // Draw the cross hair
+        imageGC.setForeground(fTimeRangeColor);
+        imageGC.setLineWidth(1);
+        imageGC.setLineStyle(SWT.LINE_SOLID);
+
+        int chHalfWidth = ((rangeWidth < 60) ? rangeWidth * 2 / 3 : 40) / 2;
+        imageGC.drawLine(center - chHalfWidth, height / 2, center + chHalfWidth, height / 2);
+        imageGC.drawLine(center, height / 2 - chHalfWidth, center, height / 2 + chHalfWidth);
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/Histogram.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/Histogram.java
new file mode 100644 (file)
index 0000000..fc60458
--- /dev/null
@@ -0,0 +1,575 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import org.eclipse.linuxtools.tmf.ui.views.TmfView;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * <b><u>Histogram</u></b>
+ * <p>
+ * Re-usable histogram widget with the following features:
+ * <ul>
+ * <li>Y-axis labels displaying min/max count values
+ * <li>X-axis labels displaying time range
+ * <li>a histogram displaying the distribution of values over time (note that
+ * the histogram might not necessarily fill the whole canvas)
+ * </ul>
+ * The widget also has 2 'markers' to identify:
+ * <ul>
+ * <li>a red dashed line over the bar that contains the currently selected event
+ * <li>a dark red dashed line that delimits the right end of the histogram (if
+ * it doesn't fill the canvas)
+ * </ul>
+ * Clicking on the histogram will select the current event at the mouse
+ * location.
+ * <p>
+ * Once the histogram is selected, there is some limited keyboard support:
+ * <ul>
+ * <li>Home: go to the first histogram bar
+ * <li>End: go to the last histogram bar
+ * <li>Left: go to the previous histogram
+ * <li>Right: go to the next histogram bar
+ * </ul>
+ * Finally, when the mouse hovers over the histogram, a tool tip showing the
+ * following information about the corresponding histogram bar time range:
+ * <ul>
+ * <li>start of the time range
+ * <li>end of the time range
+ * <li>number of events in that time range
+ * </ul>
+ */
+public abstract class Histogram implements ControlListener, PaintListener, KeyListener, MouseListener, MouseTrackListener {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    // Histogram refresh frequency
+    private final static int REFRESH_FREQUENCY = HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS;
+
+    // Histogram colors
+    private final Color fBackgroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
+    private final Color fCurrentEventColor = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
+    private final Color fLastEventColor = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED);
+    private final Color fHistoBarColor = new Color(Display.getDefault(), 74, 112, 139);
+
+    // Timestamp scale (nanosecond)
+    public static final byte TIME_SCALE = -9;
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    // Owner view
+    protected TmfView fParentView;
+
+    // Histogram text fields
+    private Text fMaxNbEventsText;
+    private Text fMinNbEventsText;
+    private Text fTimeRangeStartText;
+    private Text fTimeRangeEndText;
+
+    // Histogram drawing area
+    protected Canvas fCanvas;
+
+    // Data model
+    protected final HistogramDataModel fDataModel;
+    protected HistogramScaledData fScaledData;
+
+    protected long fCurrentEventTime = 0;
+
+    // ------------------------------------------------------------------------
+    // Construction
+    // ------------------------------------------------------------------------
+
+    public Histogram(TmfView view, Composite parent) {
+        fParentView = view;
+
+        createWidget(parent);
+        fDataModel = new HistogramDataModel();
+        clear();
+
+        fCanvas.addControlListener(this);
+        fCanvas.addPaintListener(this);
+        fCanvas.addKeyListener(this);
+        fCanvas.addMouseListener(this);
+        fCanvas.addMouseTrackListener(this);
+    }
+
+    public void dispose() {
+        fHistoBarColor.dispose();
+    }
+
+    private void createWidget(Composite parent) {
+
+        final Color labelColor = parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND);
+        final Font fFont = adjustFont(parent);
+
+        final int initalWidth = 10;
+
+        // --------------------------------------------------------------------
+        // Define the histogram
+        // --------------------------------------------------------------------
+
+        GridLayout gridLayout = new GridLayout();
+        gridLayout.numColumns = 3;
+        gridLayout.marginHeight = 0;
+        gridLayout.marginWidth = 0;
+        gridLayout.marginTop = 0;
+        gridLayout.horizontalSpacing = 0;
+        gridLayout.verticalSpacing = 0;
+        gridLayout.marginLeft = 0;
+        gridLayout.marginRight = 0;
+        Composite composite = new Composite(parent, SWT.FILL);
+        composite.setLayout(gridLayout);
+
+        // Use all the horizontal space
+        GridData gridData = new GridData();
+        gridData.horizontalAlignment = SWT.FILL;
+        gridData.verticalAlignment = SWT.FILL;
+        gridData.grabExcessHorizontalSpace = true;
+        composite.setLayoutData(gridData);
+
+        // Y-axis max event
+        gridData = new GridData();
+        gridData.horizontalAlignment = SWT.RIGHT;
+        gridData.verticalAlignment = SWT.TOP;
+        fMaxNbEventsText = new Text(composite, SWT.READ_ONLY | SWT.RIGHT);
+        fMaxNbEventsText.setFont(fFont);
+        fMaxNbEventsText.setBackground(labelColor);
+        fMaxNbEventsText.setEditable(false);
+        fMaxNbEventsText.setText("0"); //$NON-NLS-1$
+        fMaxNbEventsText.setLayoutData(gridData);
+
+        // Histogram itself
+        gridData = new GridData();
+        gridData.horizontalSpan = 2;
+        gridData.verticalSpan = 2;
+        gridData.horizontalAlignment = SWT.FILL;
+        gridData.verticalAlignment = SWT.FILL;
+        gridData.grabExcessHorizontalSpace = true;
+        fCanvas = new Canvas(composite, SWT.BORDER | SWT.DOUBLE_BUFFERED);
+        fCanvas.setLayoutData(gridData);
+
+        // Y-axis min event (always 0...)
+        gridData = new GridData();
+        gridData.horizontalAlignment = SWT.RIGHT;
+        gridData.verticalAlignment = SWT.BOTTOM;
+        fMinNbEventsText = new Text(composite, SWT.READ_ONLY | SWT.RIGHT);
+        fMinNbEventsText.setFont(fFont);
+        fMinNbEventsText.setBackground(labelColor);
+        fMinNbEventsText.setEditable(false);
+        fMinNbEventsText.setText("0"); //$NON-NLS-1$
+        fMinNbEventsText.setLayoutData(gridData);
+
+        // Dummy cell
+        gridData = new GridData(initalWidth, SWT.DEFAULT);
+        gridData.horizontalAlignment = SWT.RIGHT;
+        gridData.verticalAlignment = SWT.BOTTOM;
+        Text dummyText = new Text(composite, SWT.READ_ONLY);
+        dummyText.setFont(fFont);
+        dummyText.setBackground(labelColor);
+        dummyText.setEditable(false);
+        dummyText.setText(""); //$NON-NLS-1$
+        dummyText.setLayoutData(gridData);
+
+        // Window range start time
+        gridData = new GridData();
+        gridData.horizontalAlignment = SWT.LEFT;
+        gridData.verticalAlignment = SWT.BOTTOM;
+        fTimeRangeStartText = new Text(composite, SWT.READ_ONLY);
+        fTimeRangeStartText.setFont(fFont);
+        fTimeRangeStartText.setBackground(labelColor);
+        fTimeRangeStartText.setText(HistogramUtils.nanosecondsToString(0));
+        fTimeRangeStartText.setLayoutData(gridData);
+
+        // Window range end time
+        gridData = new GridData();
+        gridData.horizontalAlignment = SWT.RIGHT;
+        gridData.verticalAlignment = SWT.BOTTOM;
+        fTimeRangeEndText = new Text(composite, SWT.READ_ONLY);
+        fTimeRangeEndText.setFont(fFont);
+        fTimeRangeEndText.setBackground(labelColor);
+        fTimeRangeEndText.setText(HistogramUtils.nanosecondsToString(0));
+        fTimeRangeEndText.setLayoutData(gridData);
+    }
+
+    private Font adjustFont(Composite composite) {
+        // Reduce font size for a more pleasing rendering
+        int fontSizeAdjustment = -2;
+        Font font = composite.getFont();
+        FontData fontData = font.getFontData()[0];
+        return new Font(font.getDevice(), fontData.getName(), fontData.getHeight() + fontSizeAdjustment, fontData.getStyle());
+    }
+
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
+    public long getStartTime() {
+        return fDataModel.getStartTime();
+    }
+
+    public long getEndTime() {
+        return fDataModel.getEndTime();
+    }
+
+    public long getTimeLimit() {
+        return fDataModel.getTimeLimit();
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    public abstract void updateTimeRange(long startTime, long endTime);
+
+    /**
+     * Clear the histogram and reset the data
+     */
+    public void clear() {
+        fDataModel.clear();
+        fScaledData = null;
+        refresh();
+    }
+
+    /**
+     * Increase the histogram bucket corresponding to [timestamp]
+     * 
+     * @param timestamp
+     */
+    public void countEvent(long timestamp) {
+        fDataModel.countEvent(timestamp);
+        if (fDataModel.getNbEvents() % REFRESH_FREQUENCY == 0) {
+            refresh();
+            refresh();
+        }
+    }
+
+    /**
+     * Sets the current event time and refresh the display
+     * 
+     * @param timestamp
+     */
+    public void setCurrentEvent(long timestamp) {
+        fCurrentEventTime = timestamp;
+        fDataModel.setCurrentEvent(timestamp);
+        refresh();
+    }
+
+    /**
+     * Computes the timestamp of the bucket at [offset]
+     * 
+     * @param offset offset from the left on the histogram
+     * @return the start timestamp of the corresponding bucket
+     */
+    public synchronized long getTimestamp(int offset) {
+        assert offset > 0 && offset < fScaledData.fWidth;
+        try {
+            return fDataModel.getStartTime() + fScaledData.fBucketDuration * offset;
+        } catch (Exception e) {
+            return 0; // TODO: Fix that racing condition (NPE)
+        }
+    }
+
+    /**
+     * Computes the offset of the timestamp in the histogram
+     * 
+     * @param timestamp the timestamp
+     * @return the offset of the corresponding bucket (-1 if invalid)
+     */
+    public synchronized int getOffset(long timestamp) {
+        if (timestamp < fDataModel.getStartTime() || timestamp > fDataModel.getEndTime())
+            return -1;
+        return (int) ((timestamp - fDataModel.getStartTime()) / fScaledData.fBucketDuration);
+    }
+
+    /**
+     * Move the currently selected bar cursor to a non-empty bucket.
+     * 
+     * @param keyCode the SWT key code
+     */
+    protected void moveCursor(int keyCode) {
+
+        if (fScaledData.fCurrentBucket == HistogramScaledData.OUT_OF_RANGE_BUCKET)
+            return;
+
+        int index;
+        switch (keyCode) {
+
+            case SWT.HOME:
+                index = 0;
+                while (index < fScaledData.fLastBucket && fScaledData.fData[index] == 0)
+                    index++;
+                if (index < fScaledData.fLastBucket)
+                    fScaledData.fCurrentBucket = index;
+                break;
+
+            case SWT.ARROW_RIGHT:
+                index = fScaledData.fCurrentBucket + 1;
+                while (index < fScaledData.fWidth && fScaledData.fData[index] == 0)
+                    index++;
+                if (index < fScaledData.fLastBucket)
+                    fScaledData.fCurrentBucket = index;
+                break;
+
+            case SWT.END:
+                index = fScaledData.fLastBucket;
+                while (index >= 0 && fScaledData.fData[index] == 0)
+                    index--;
+                if (index >= 0)
+                    fScaledData.fCurrentBucket = index;
+                break;
+
+            case SWT.ARROW_LEFT:
+                index = fScaledData.fCurrentBucket - 1;
+                while (index >= 0 && fScaledData.fData[index] == 0)
+                    index--;
+                if (index >= 0)
+                    fScaledData.fCurrentBucket = index;
+                break;
+
+            default:
+                return;
+        }
+
+        updateCurrentEventTime();
+    }
+
+    /**
+     * Refresh the histogram display
+     */
+    protected void refresh() {
+        if (!fCanvas.isDisposed() && fCanvas.getDisplay() != null) {
+            fCanvas.getDisplay().asyncExec(new Runnable() {
+                @Override
+                public void run() {
+                    if (!fCanvas.isDisposed()) {
+                        // Retrieve and normalize the data
+                        int canvasWidth = fCanvas.getBounds().width;
+                        int canvasHeight = fCanvas.getBounds().height;
+                        fDataModel.setCurrentEvent(fCurrentEventTime);
+                        fScaledData = fDataModel.scaleTo(canvasWidth, canvasHeight);
+                        // If there's no data, just get out
+                        if (fScaledData.fData[0] == 0)
+                            return;
+                        // Display histogram and update X-,Y-axis labels
+                        fCanvas.redraw();
+                        fTimeRangeStartText.setText(HistogramUtils.nanosecondsToString(fDataModel.getStartTime()));
+                        fTimeRangeEndText.setText(HistogramUtils.nanosecondsToString(fDataModel.getEndTime()));
+                        if (fDataModel.getStartTime() > 0) {
+                            fMaxNbEventsText.setText(Long.toString(fScaledData.fMaxValue));
+                        }
+                        // The Y-axis area might need to be re-sized
+                        fMaxNbEventsText.getParent().layout();
+                    }
+                }
+            });
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // Helper functions
+    // ------------------------------------------------------------------------
+
+    private void updateCurrentEventTime() {
+        long bucketStartTime = getTimestamp(fScaledData.fCurrentBucket);
+        ((HistogramView) fParentView).updateCurrentEventTime(bucketStartTime);
+    }
+
+    // ------------------------------------------------------------------------
+    // PaintListener
+    // ------------------------------------------------------------------------
+
+    protected final String IMAGE_KEY = "double-buffer-image"; //$NON-NLS-1$
+
+    @Override
+    public void paintControl(PaintEvent event) {
+
+        // Get the geometry
+        int canvasWidth = fCanvas.getBounds().width;
+        int canvasHeight = fCanvas.getBounds().height;
+
+        // Make sure we have something to draw upon
+        if (canvasWidth <= 0 || canvasHeight <= 0)
+            return;
+
+        // Retrieve image; re-create only if necessary
+        Image image = (Image) fCanvas.getData(IMAGE_KEY);
+        if (image == null || image.getBounds().width != canvasWidth || image.getBounds().height != canvasHeight) {
+            image = new Image(event.display, canvasWidth, canvasHeight);
+            fCanvas.setData(IMAGE_KEY, image);
+        }
+
+        // Draw the histogram on its canvas
+        GC imageGC = new GC(image);
+        formatImage(imageGC, image);
+        event.gc.drawImage(image, 0, 0);
+        imageGC.dispose();
+    }
+
+    private void formatImage(GC imageGC, Image image) {
+
+        if (fScaledData == null)
+            return;
+
+        HistogramScaledData scaledData = new HistogramScaledData(fScaledData);
+
+        try {
+            // Get drawing boundaries
+            int width = image.getBounds().width;
+            int height = image.getBounds().height;
+
+            // Clear the drawing area
+            imageGC.setBackground(fBackgroundColor);
+            imageGC.fillRectangle(0, 0, image.getBounds().width + 1, image.getBounds().height + 1);
+
+            // Draw the histogram bars
+            imageGC.setBackground(fHistoBarColor);
+            int limit = width < scaledData.fWidth ? width : scaledData.fWidth;
+            for (int i = 1; i < limit; i++) {
+                int value = (int) (scaledData.fData[i] * scaledData.fScalingFactor);
+                imageGC.fillRectangle(i, height - value, 1, value);
+            }
+
+            // Draw the current event bar
+            int currentBucket = scaledData.fCurrentBucket;
+            if (currentBucket >= 0 && currentBucket < limit) {
+                drawDelimiter(imageGC, fCurrentEventColor, height, currentBucket);
+            }
+
+            // Add a dashed line as a delimiter (at the right of the last bar)
+            int lastEventIndex = limit - 1;
+            while (lastEventIndex >= 0 && scaledData.fData[lastEventIndex] == 0)
+                lastEventIndex--;
+            lastEventIndex += (lastEventIndex < limit - 1) ? 1 : 0;
+            drawDelimiter(imageGC, fLastEventColor, height, lastEventIndex);
+        } catch (Exception e) {
+            // Do nothing
+        }
+    }
+
+    private void drawDelimiter(GC imageGC, Color color, int height, int index) {
+        imageGC.setBackground(color);
+        int dash = height / 4;
+        imageGC.fillRectangle(index, 0 * dash, 1, dash - 1);
+        imageGC.fillRectangle(index, 1 * dash, 1, dash - 1);
+        imageGC.fillRectangle(index, 2 * dash, 1, dash - 1);
+        imageGC.fillRectangle(index, 3 * dash, 1, height - 3 * dash);
+    }
+
+    // ------------------------------------------------------------------------
+    // KeyListener
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void keyPressed(KeyEvent event) {
+        moveCursor(event.keyCode);
+    }
+
+    @Override
+    public void keyReleased(KeyEvent event) {
+    }
+
+    // ------------------------------------------------------------------------
+    // MouseListener
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void mouseDoubleClick(MouseEvent event) {
+    }
+
+    @Override
+    public void mouseDown(MouseEvent event) {
+        if (fDataModel.getNbEvents() > 0 && fScaledData.fLastBucket >= event.x) {
+            fScaledData.fCurrentBucket = event.x;
+            updateCurrentEventTime();
+        }
+    }
+
+    @Override
+    public void mouseUp(MouseEvent event) {
+    }
+
+    // ------------------------------------------------------------------------
+    // MouseTrackListener
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void mouseEnter(MouseEvent event) {
+    }
+
+    @Override
+    public void mouseExit(MouseEvent event) {
+    }
+
+    @Override
+    public void mouseHover(MouseEvent event) {
+        if (fDataModel.getNbEvents() > 0 && fScaledData.fLastBucket >= event.x) {
+            String tooltip = formatToolTipLabel(event.x);
+            fCanvas.setToolTipText(tooltip);
+        }
+    }
+
+    private String formatToolTipLabel(int index) {
+        long startTime = fDataModel.getStartTime() + fScaledData.fCurrentBucket * fScaledData.fBucketDuration;
+        long endTime = startTime + fScaledData.fBucketDuration;
+        int nbEvents = fScaledData.fData[index];
+
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("Range = ["); //$NON-NLS-1$
+        buffer.append(HistogramUtils.nanosecondsToString(startTime));
+        buffer.append(","); //$NON-NLS-1$
+        buffer.append(HistogramUtils.nanosecondsToString(endTime));
+        buffer.append(")\n"); //$NON-NLS-1$
+        buffer.append("Event count = "); //$NON-NLS-1$
+        buffer.append(nbEvents);
+        return buffer.toString();
+    }
+
+    // ------------------------------------------------------------------------
+    // ControlListener
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void controlMoved(ControlEvent event) {
+        refresh();
+    }
+
+    @Override
+    public void controlResized(ControlEvent event) {
+        refresh();
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java
deleted file mode 100644 (file)
index eaf22e0..0000000
+++ /dev/null
@@ -1,459 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *   
- * Modifications:
- * 2010-06-20 Yuriy Vashchuk - Histogram optimisations.
- * 2010-07-16 Yuriy Vashchuk - Histogram class simplification.
- *                                                        Selection Window related methods has been
- *                                                        implemented in Parent Histogram.
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * <b><u>HistogramCanvas</u></b>
- * <p>
- * Canvas implementation aimed to draw histograms.
- * <p>
- * This canvas goal is to display certain "HistogramContent" onto an histogram.<p>
- * Several method exist to extend it so it should suit most needs. 
- */
-public class HistogramCanvas extends Canvas
-{
-       private static HistogramView histogramView = null; 
-
-       protected AsyncCanvasRedrawer   canvasRedrawer   = null;
-       protected HistogramContent              histogramContent = null;
-       
-/*     
-       // 2010-07-16 Yuriy: Moved to child classes.
-       protected HistogramCanvasPaintListener          paintListener = null;
-       protected HistogramCanvasMouseListener          mouseListener = null;
-       protected HistogramCanvasKeyListener            keyListener   = null;
-       protected HistogramCanvasControlListener        controlListener = null;
-*/
-       protected HistogramCanvasFocusListener          focusListener = null;
-       
-/*     
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       protected HistogramSelectedWindow currentWindow = null;
-*/     
-       
-       /**
-        * HistogramCanvas constructor
-        * 
-        * @param parent                Composite control which will be the parent of the new instance (cannot be null)
-        * @param                               Style the style of control to construct
-        */
-       public HistogramCanvas(HistogramView histogramView, Composite parent, int style) {
-               super(parent, style | SWT.DOUBLE_BUFFERED);
-               HistogramCanvas.histogramView = histogramView;
-               addNeededListeners();
-               
-/*
-               // 2010-06-20 Yuriy: Moved to parent hitogram class.
-               // New selected window, not visible by default
-               createNewSelectedWindow(0L);
-*/             
-       }
-       
-       /*
-        * Create the needed "event listeners" and hook them to the Canvas.
-        */
-
-       protected void addNeededListeners() {
-               createAndAddCanvasRedrawer();
-               createAndAddFocusListener();
-               
-/*
-               // 2010-06-20 Yuriy: Moved to derived classes.
-               createAndAddPaintListener();
-               createAndAddMouseListener();
-               createAndAddKeyListener();
-               createAndAddControlListener();
-*/             
-       }
-       
-       /*
-        * Create a canvas redrawer and bind it to this canvas.<p>
-        * 
-        * Note : AsyncCanvasRedrawer is an internal class
-        *      This is used to redraw the canvas from a different thread 
-        *              without^H^H^H with less danger.
-        */
-       protected void createAndAddCanvasRedrawer() {
-               canvasRedrawer = new AsyncCanvasRedrawer(this);
-       }
-
-       /*
-        * Create a histogram paint listener and bind it to this canvas.<p>
-        * 
-        * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasPaintListener
-        */
-/*     
-       // 2010-07-16 Yuriy: Moved to derived classes.
-       protected void createAndAddPaintListener() {
-               paintListener = new HistogramCanvasPaintListener(this);
-               this.addPaintListener( paintListener );
-       }
-*/     
-       /*
-        * Create a histogram mouse listener and bind it to this canvas.<p>
-        * Note : this mouse listener handle the mouse, the move and the wheel at once.
-        * 
-        * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasMouseListener
-        */
-/*
-       // 2010-07-16 Yuriy: Moved to parent histogram class
-       protected void createAndAddMouseListener() {
-               mouseListener = new HistogramCanvasMouseListener(this);
-               this.addMouseListener(mouseListener);
-               this.addMouseMoveListener(mouseListener);
-               this.addMouseWheelListener(mouseListener);
-       }
-*/     
-       
-       /*
-        * Create a histogram key listener and bind it to this canvas.<p>
-        * 
-        * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasKeyListener
-        */
-/*     
-       // 2010-07-16 Yuriy: Moved to parent histogram class
-       protected void createAndAddKeyListener() {
-               keyListener   = new HistogramCanvasKeyListener(this);
-               this.addKeyListener(keyListener);
-       }
-*/     
-       /*
-        * Create a histogram focus listener and bind it to this canvas.<p>
-        * 
-        *  @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasFocusListener
-        */
-       protected void createAndAddFocusListener() {
-               focusListener = new HistogramCanvasFocusListener(this);
-               this.addFocusListener(focusListener);
-       }
-
-       /*
-        * Create a histogram control listener and bind it to this canvas.<p>
-        * 
-        *  @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
-        */
-/*
-       // 2010-07-16 Yuriy: Moved to derived classes.
-       protected void createAndAddControlListener() {
-               controlListener = new HistogramCanvasControlListener(this);
-               this.addControlListener(controlListener);
-       }
-*/     
-       /**
-        * Create a new HistogramContent for this HistogramCanvas<p>
-        * A new <I>empty</I> content will then be created.
-        * 
-        * IMPORTANT NOTE : Canvas size, bar width and bar height need to be known at this point, as these dimension are used to create a content 
-        *                                              of the correct size.
-        * 
-        * @param canvasSize                                    Size of the parent canvas.
-        * @param widthPerBar                                   Width of the histogram "bars"
-        * @param barsHeight                                    Height of the histogram "bars"
-        * @param maxBarsDifferenceToAverage    Factor used to "chop" bars that are too tall. Set to something big (100.0?) if not needed.
-        */
-       public void createNewHistogramContent(int canvasSize, int widthPerBar, int barsHeight, double maxBarsDifferenceToAverage) {
-               histogramContent = new HistogramContent( canvasSize / widthPerBar, canvasSize, widthPerBar, barsHeight, maxBarsDifferenceToAverage);
-       }
-       
-       /**
-        * Create a new selection window of the size (time width) given.<p>
-        * The window initial position is at X = 0.
-        * The window is created hidden, it won't be draw unless it is set to visible.<p> 
-        * 
-        * @param windowTimeDuration    Time width (in nanosecond) of the window.
-        */
-/*     
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public void createNewSelectedWindow(long windowTimeDuration) {
-               currentWindow = new HistogramSelectedWindow(histogramContent);
-               
-               currentWindow.setWindowTimeWidth(windowTimeDuration);
-               currentWindow.setWindowXPositionCenter(0);
-       }
-*/     
-       public HistogramContent getHistogramContent() {
-               return histogramContent;
-       }
-       
-       /**
-        * Getter for the selection window<p>
-        * 
-        * @return the current selection window
-        * 
-        * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramSelectedWindow
-        */
-/*     
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public HistogramSelectedWindow getCurrentWindow() {
-               return currentWindow;
-       }
-*/
-       
-       /**
-        * Getter for the selection window width<p>
-        * 
-        * @return Time width (in nanosecond) of the selection window.
-        */
-/*     
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public long getSelectedWindowSize() {
-               return currentWindow.getWindowTimeWidth();
-       }
-*/
-       
-       /**
-        * Setter for the selection window width<p>
-        * The window size will be ajusted if it does not respect one of these constraints :
-        * - The window size cannot be smaller than a single histogram content interval.<p>
-        * - The window size cannot be larger than twice the histogram content complete time interval.<p>
-        * 
-        * @param newSelectedWindowSize New time width (in nanosecond) of the selection window.
-        */
-/*     
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public void setSelectedWindowSize(long newSelectedWindowSize) {
-               
-               if ( newSelectedWindowSize <= 0 ) {
-                       newSelectedWindowSize = 1L;
-               }
-               else if ( newSelectedWindowSize > (2*histogramContent.getCompleteTimeInterval()) ) {
-                       newSelectedWindowSize = (2*histogramContent.getCompleteTimeInterval());
-               }
-               
-               currentWindow.setWindowTimeWidth(newSelectedWindowSize);
-       }
-*/     
-       /**
-        * Method to call the "Asynchronous redrawer" for this canvas<p>
-        * This allow safe redraw from different threads.
-        * 
-        */
-       public void redrawAsynchronously() {
-               // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
-               if ( canvasRedrawer == null ) {
-                       canvasRedrawer = new AsyncCanvasRedrawer(this);
-               }
-               
-               canvasRedrawer.asynchronousRedraw();
-       }
-       
-       /**
-        * Method to call the "Asynchronous NotifyParentSelectionWindowChanged" for this canvas<p>
-        * This allow safe update UI objects from different threads.
-        * 
-        */
-/*
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public void notifyParentSelectionWindowChangedAsynchronously() {
-               // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
-               if ( canvasRedrawer == null ) {
-                       canvasRedrawer = new AsyncCanvasRedrawer(this);
-               }
-               
-               canvasRedrawer.asynchronousNotifyParentSelectionWindowChanged();
-       }
-*/     
-       
-       /**
-        * Method to call the "Asynchronous NotifyParentUpdatedInformation" for this canvas<p>
-        * This allow safe redraw from different threads.
-        * 
-        */
-       public void notifyParentUpdatedInformationAsynchronously() {
-               // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
-               if ( canvasRedrawer == null ) {
-                       canvasRedrawer = new AsyncCanvasRedrawer(this);
-               }
-               
-               canvasRedrawer.asynchronousNotifyParentUpdatedInformation();
-       }
-       
-       /**
-        * Function that is called when the selection window is moved.<p>
-        * Note: Given position should be relative to the previous (centered) absolute position.
-        * 
-        * <B>METHOD INTENDED TO BE EXTENDED</B>
-        * 
-        * @param newRelativeXPosition  New position relative to the last known absolute position.
-        */
-/*
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public void moveWindow(int newRelativeXPosition) {
-               // Nothing : function is a place holder
-       }
-*/
-
-       /**
-        * Function that is called when the selection window is re-centered.<p>
-        * Note: Given position should be absolute to the window and need to be the selection window center.
-        * 
-        * <B>METHOD INTENDED TO BE EXTENDED</B>
-        * 
-        * @param newRelativeXPosition  New absolute position.
-        */
-/*
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public void setWindowCenterPosition(int newAbsoluteXPosition) {
-               // Nothing : function is a place holder
-       }
-*/
-       
-       /**
-        * Function that is called when the selection window size (time width) changed by an absolute time.<p>
-        * Note: Given time should be in nanoseconds, positive.
-        * 
-        * <B>METHOD INTENDED TO BE EXTENDED</B>
-        * 
-        * @param newTime        New absoulte time (in nanoseconds) to apply to the window.
-        */
-/*
-/*
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public void resizeWindowByAbsoluteTime(long newTime) {
-               // Nothing : function is a place holder
-       }
-*/     
-       /**
-        * Function that is called to tell the parent that the selection window changed.<p>
-        * 
-        * <B>METHOD INTENDED TO BE EXTENDED</B>
-        * 
-        */
-/*
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public void notifyParentSelectionWindowChanged() {
-               // Nothing : function is a place holder
-       }
-*/     
-       /**
-        * Function that is called to tell the parent that some information changed.<p>
-        * 
-        * <B>METHOD INTENDED TO BE EXTENDED</B>
-        * 
-        */
-       public void notifyParentUpdatedInformation() {
-               // Nothing : function is a place holder
-       }
-       
-       /**
-        * Getter for View
-        * 
-        * @return view instance
-        * 
-        */
-       public static HistogramView getHistogramView() {
-               return histogramView;
-       }
-
-       /**
-        * Setter for View
-        * 
-        * @param histogramView reference to object
-        */
-       public static void setHistogramView(HistogramView histogramView) {
-               HistogramCanvas.histogramView = histogramView;
-       }
-}
-
-
-/**
- * <b><u>AsyncCanvasRedrawer Inner Class</u></b>
- * <p>
- * Asynchronous redrawer for the HistogramCanvas
- * <p>
- * This class role is to call method that update the UI on asynchronously. 
- * This should prevent any "invalid thread access" exception when trying to update UI from a different thread.
- */
-class AsyncCanvasRedrawer {
-       
-       private HistogramCanvas parentCanvas = null; 
-       
-       /**
-        * AsyncCanvasRedrawer constructor.
-        * 
-        * @param newCanvas     Related histogram canvas.
-        */
-       public AsyncCanvasRedrawer(HistogramCanvas newCanvas) {
-               parentCanvas = newCanvas;
-       }
-       
-       /**
-        * Function to redraw the related canvas asynchonously.<p>
-        * 
-        * Basically, it just run "canvas.redraw()" in asyncExec.
-        * 
-        */
-       public void asynchronousRedraw() {
-               if ((parentCanvas != null) && (!parentCanvas.isDisposed())) {
-                       Display display = parentCanvas.getDisplay();
-                       display.asyncExec(new Runnable() {
-                               @Override
-                               public void run() {
-                                       if ((parentCanvas != null) && (!parentCanvas.isDisposed())) {
-                                               parentCanvas.redraw();
-                                       }
-                               }
-                       });
-               }
-       }
-       
-       /**
-        * Function to asynchronously notify the parent of the related canvas that the window changed.<p>
-        * 
-        * Basically, it just run "notifyParentSelectionWindowChanged()" in asyncExec.
-        * 
-        */
-/*     
-       // 2010-07-16 Yuriy: Moved to parent histogram class.
-       public void asynchronousNotifyParentSelectionWindowChanged() {
-               if(parentCanvas != null) {
-                       Display display = parentCanvas.getDisplay();
-                       display.asyncExec(new Runnable() {
-                               public void run() {
-                                       parentCanvas.notifyParentSelectionWindowChanged();
-                               }
-                       });
-               }
-       }
-*/     
-       
-       /**
-        * Function to asynchonously notify the parent of the related canvas that information changed.<p>
-        * 
-        * Basically, it just run "notifyParentUpdatedInformation()" in asyncExec.
-        * 
-        */
-       public void asynchronousNotifyParentUpdatedInformation() {
-               if((parentCanvas != null) && (!parentCanvas.isDisposed())) {
-                       Display display = parentCanvas.getDisplay();
-                       display.asyncExec(new Runnable() {
-                               @Override
-                               public void run() {
-                                       if((parentCanvas != null) && (!parentCanvas.isDisposed())) {
-                                               parentCanvas.notifyParentUpdatedInformation();
-                                       }
-                               }
-                       });
-               }
-       }
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasControlListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasControlListener.java
deleted file mode 100644 (file)
index 4da176b..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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
- * 
- * Modifications:
- * 2010-07-16 Yuriy Vashchuk - Base class simplification
- *******************************************************************************/
-
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-
-/**
- * <b><u>HistogramCanvasControlListener</u></b>
- * <p>
- * Implementation of a ControlListener for the need of the HistogramCanvas
- * <p> 
- */
-public class HistogramCanvasControlListener implements ControlListener {
-       
-       private HistogramCanvas ourCanvas = null;
-
-       /**
-        * HistogramCanvasControlListener default constructor
-        */
-       public HistogramCanvasControlListener() {
-       }       
-       
-       /**
-        * HistogramCanvasControlListener constructor
-        * 
-        * @param newCanvas Related canvas
-        */
-       public HistogramCanvasControlListener(HistogramCanvas newCanvas) {
-               ourCanvas = newCanvas;
-       }
-       
-       
-       /**
-        * Method called when the canvas is moved.<p>
-        * 
-        * Just redraw the canvas...
-        * 
-        * @param event         The controle event generated by the move.
-        */
-       @Override
-       public void controlMoved(ControlEvent event) {
-               if (ourCanvas != null)
-                       ourCanvas.redraw();
-       }
-       
-       /**
-        * Method called when the canvas is resized.<p>
-        * 
-        * We need to tell the content that the canvas size changed
-        * 
-        * @param event         The control event generated by the resize.
-        */
-       @Override
-       public void controlResized(ControlEvent event) {
-               
-               if ( (ourCanvas != null) && (ourCanvas.getHistogramContent() != null) ) {
-                       // Set the new canvas size
-                       ourCanvas.getHistogramContent().setCanvasWindowSize(ourCanvas.getSize().x);
-               }
-       }
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java
deleted file mode 100644 (file)
index 2451ba4..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *   
- * Modifications:
- * 2010-07-16 Yuriy Vashchuk - Heritage corrections.
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-
-/**
- * <b><u>HistogramCanvasFocusListener</u></b>
- * <p>
- * Implementation of a FocusListener for the need of the HistogramCanvas
- * <p> 
- */
-public class HistogramCanvasFocusListener implements FocusListener {
-       
-       private HistogramCanvas ourCanvas = null;
-       
-       /**
-        * HistogramCanvasFocusListener constructor
-        * 
-        * @param newCanvas Related canvas
-        */
-       public HistogramCanvasFocusListener(HistogramCanvas newCanvas) {
-               ourCanvas = newCanvas;
-       }
-       
-       /**
-        * Function that is called when the canvas get focus.<p>
-        * 
-        * Redraw the screen to make sure everything is sane. 
-        * 
-        * @param event  The focus event generated.
-        */
-       @Override
-       public void focusGained(FocusEvent event) {
-               ourCanvas.redrawAsynchronously();
-       }
-       
-       /**
-        * Function that is called when the canvas loose focus.<p>
-        * 
-        * Doesn't do anything yet... 
-        * 
-        * @param event  The focus event generated.
-        */
-       @Override
-       public void focusLost(FocusEvent event) {
-               // Nothing to do yet
-       }
-
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasKeyListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasKeyListener.java
deleted file mode 100644 (file)
index 4461011..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-
-/**
- * <b><u>HistogramCanvasKeyListener</u></b>
- * <p>
- * Implementation of a KeyListener for the need of the HistogramCanvas
- * <p> 
- */
-public class HistogramCanvasKeyListener implements KeyListener 
-{
-       private ParentHistogramCanvas parentCanvas = null;
-       private boolean isShiftPressed = false;
-       
-       /**
-        * HistogramCanvasKeyListener constructor
-        * 
-        * @param newCanvas Related canvas
-        */
-       public HistogramCanvasKeyListener(ParentHistogramCanvas newCanvas) {
-               parentCanvas = newCanvas;
-       }
-       
-       /**
-        * Function that is called when a key is pressed.<p>
-        * Possible actions : 
-        * - Left arrow  : move the selection window left.<p>
-        * - Right arrow : move the selection window right.<p>
-        * - Shift       : turn on "fast move" mode.<p>
-        * 
-        * @param event  The KeyEvent generated when the key was pressed.
-        */
-       @Override
-       public void keyPressed(KeyEvent event) {
-               switch (event.keyCode) {
-                       case SWT.SHIFT:
-                               isShiftPressed = true;
-                               break;
-                       case SWT.ARROW_LEFT:
-                               moveWindowPosition(HistogramConstant.BASIC_DISPLACEMENT_FACTOR * -1);
-                               break;
-                       case SWT.ARROW_RIGHT:
-                               moveWindowPosition(HistogramConstant.BASIC_DISPLACEMENT_FACTOR);
-                               break;
-                       default:
-                               break;
-               }
-       }
-       
-       /**
-        * Function that is called when a key is released.<p>
-        * Possible actions : 
-        * - Shift  : turn off "fast move" mode.
-        * 
-        * @param event  The KeyEvent generated when the key was pressed.
-        */
-       @Override
-       public void keyReleased(KeyEvent event) {
-               switch (event.keyCode) {
-                       case SWT.SHIFT:
-                               isShiftPressed = false;
-                               break;
-                       default:
-                               break;
-               }
-       }
-       
-       /**
-        * Function to move the window position of a given displacemnt.<p>
-        * 
-        * @param displacementFactor    The basic displacement to perform (positive or negative value)
-        */
-       public void moveWindowPosition(int displacementFactor) {
-               
-               // If we are in "fast move mode", multiply the basic displacement by a factor
-               if ( isShiftPressed == true ) {
-                       displacementFactor = (int)((double)displacementFactor * HistogramConstant.FAST_DISPLACEMENT_MULTIPLE);
-               }
-               
-               parentCanvas.moveWindow(displacementFactor);
-       }
-       
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasMouseListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasMouseListener.java
deleted file mode 100644 (file)
index d9e8ec1..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *   
- * Modifications:
- * 2010-06-20 Yuriy Vashchuk - Selection "red square" window optimisation.
- *                                                        Null pointer exception correction.
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.MouseWheelListener;
-
-/**
- * <b><u>HistogramCanvasMouseListener</u></b>
- * <p>
- * Implementation of a MouseListener for the need of the HistogramCanvas
- * <p> 
- */
-public class HistogramCanvasMouseListener implements MouseMoveListener, MouseListener, MouseWheelListener 
-{
-       private DelayedMouseScroll mouseScrollListener = null;
-       private ParentHistogramCanvas parentCanvas = null;
-       private int oldWindowXPositionCenter = 0;
-       
-       private boolean isWindowMoving = false;
-       
-       /**
-        * HistogramCanvasMouseListener constructor
-        * 
-        * @param newCanvas Related canvas
-        */
-       public HistogramCanvasMouseListener(ParentHistogramCanvas newCanvas) {
-               parentCanvas = newCanvas;
-       }
-       
-       /**
-        * Function called when the mouse is moved.<p>
-        * If the mouse button is clicked, we will move the selection window.
-        * 
-        * @param event  The generated mouse event when the mouse moved.
-        */
-       @Override
-       public void mouseMove(MouseEvent event) {
-               if ( parentCanvas.getHistogramContent() != null && isWindowMoving == true ) {
-
-                       parentCanvas.setWindowCenterPosition(event.x);
-               }
-       }
-       
-       /**
-        * Function called when the mouse buttons are clicked.<p>
-        * If the button is the first one (left button), turn on the "move window" mode
-        * 
-        * @param event  The generated mouse event when the mouse button was pressed.
-        */
-       @Override
-       public void mouseDown(MouseEvent event) {
-               if ( parentCanvas.getHistogramContent() != null && event.button == 1) {
-                       isWindowMoving = true;
-                       
-                       oldWindowXPositionCenter = parentCanvas.getCurrentWindow().getWindowXPositionCenter();
-                       parentCanvas.setWindowCenterPosition(event.x);
-               }
-       }
-       
-       /**
-        * Function called when the mouse buttons are released.<p>
-        * If the button is the first one (left button), turn off the "move window" mode
-        * 
-        * @param event  The generated mouse event when the mouse button was released.
-        */
-       @Override
-       public void mouseUp(MouseEvent event) {
-               if ( parentCanvas.getHistogramContent() != null && event.button == 1) {
-                       isWindowMoving = false;
-
-                       if( oldWindowXPositionCenter != parentCanvas.getCurrentWindow().getWindowXPositionCenter()) {
-                               parentCanvas.notifyParentSelectionWindowChangedAsynchronously();
-                       }
-               }
-       }
-       
-       /**
-        * Function called when the mouse perform a double-click.<p>
-        * Don't do anything yet...
-        * 
-        * @param event  The generated mouse event when the mouse double-click was issued.
-        */
-       @Override
-       public void mouseDoubleClick(MouseEvent event) {
-//             System.out.println("mouseDoubleClick");
-       }
-       
-       /**
-        * Function called when the mouse scroll button is used.<p>
-        * Start a "ScrollListener" that will wait for more scroll clicks as they are asynchonous.
-        * After a certain delay, the parent canvas will get notified.   
-        * 
-        * @param event  The generated mouse event when the mouse scroll was spinned.
-        */
-       @Override
-       public void mouseScrolled(MouseEvent event) {
-               
-               // Start a scrollListener if none exist yet and start its thread
-               // Otherwise, we will just notify the one that is currenly alive...
-               // Badly timed event could happen while the thread is dying but we can live with loss scroll events, I believe. 
-               if ( mouseScrollListener == null ) {
-                       mouseScrollListener = new DelayedMouseScroll(this, HistogramConstant.FULL_WAIT_MS_TIME_BETWEEN_MOUSE_SCROLL, HistogramConstant.INTERVAL_WAIT_MS_TIME_BETWEEN_POLL );
-                       mouseScrollListener.start();
-               }
-               
-               // *** NOTE ***
-               // We need to refer to the "count" to know if the scroll is done backward or forward.
-               // Positive count mean it is done backward (from the wall in the direction of the hand)
-               // Negative count mean it is done backward (from the hand in the direction of the wall)
-               if ( event.count > 0) {
-                       mouseScrollListener.incrementMouseScroll();
-               }
-               else {
-                       mouseScrollListener.decrementMouseScroll();
-               }
-       }
-
-       /**
-        * This will calculate the correct zoom time and call the canvas to resize its selection window.
-        * 
-        * @param nbMouseScroll
-        * @return new window timerange
-        */
-       public long receiveMouseScrollCount(int nbMouseScroll) {
-               
-               double ajustedTime = 0;
-               long selectedWindowSize = parentCanvas.getSelectedWindowSize();
-               
-               // If we received Negative scroll event, ZoomOut by ZOOM_OUT_FACTOR * the number of scroll events received.
-               if ( nbMouseScroll < 0 ) {
-                       ajustedTime = (double)selectedWindowSize * HistogramConstant.ZOOM_OUT_FACTOR;
-                       ajustedTime = ajustedTime * Math.abs(nbMouseScroll);
-                       ajustedTime = selectedWindowSize + ajustedTime;
-               }
-               // If we received Positive scroll event, ZoomIn by ZOOM_IN_FACTOR * the number of scroll events received.
-               else {
-                       if(selectedWindowSize > 2) {
-                               ajustedTime = (double)selectedWindowSize * HistogramConstant.ZOOM_IN_FACTOR;
-                               ajustedTime = ajustedTime * Math.abs(nbMouseScroll);
-                               ajustedTime = selectedWindowSize - ajustedTime;
-                       }
-               }
-               
-               return (long)ajustedTime;
-               
-       }       
-       
-       /**
-        * Function that will be called at the end of the "wait time" for scroll events.<p>
-        * This will calculate the correct zoom time and call the canvas to resize its selection window.
-        * 
-        * @param nbMouseScroll
-        */
-       public void receiveMouseScrollCountWithNotification(int nbMouseScroll) {
-               
-               if(parentCanvas.getHistogramContent() != null) { 
-               
-                       mouseScrollListener = null;
-                       
-                       // Resize the canvas selection window  
-                       parentCanvas.resizeWindowByAbsoluteTime( receiveMouseScrollCount(nbMouseScroll) );
-               }
-       }
-       
-       /**
-        * Function that will be called on mouse scroll.<p>
-        * This will calculate the correct zoom time and call the canvas to resize its selection window.
-        * 
-        * @param nbMouseScroll
-        */
-       public void receiveMouseScrollCountWithoutNotification(int nbMouseScroll) {
-               if(parentCanvas.getHistogramContent() != null) { 
-                       
-                       // Resize the canvas selection window  
-                       parentCanvas.resizeWindowByAbsoluteTimeWithoutNotification( receiveMouseScrollCount(nbMouseScroll) );
-               }
-       }
-       
-}
-
-/**
- * <b><u>DelayedMouseScroll Inner Class</u></b>
- * <p>
- * Asynchronous "Mouse Scroll Listener"
- * <p>
- * This class role is to wait for mouse scroll and count them during a certain delay.<p>
- * Once the time is up, it will notify the mouse listener of the number of scroll events received.<p>
- * 
- * Note that a new scroll event received will reset the wait timer.
- */
-class DelayedMouseScroll extends Thread {
-       
-       private HistogramCanvasMouseListener mouseListener = null;
-       
-       private long waitTimeBetweenScroll = 0;
-       private long waitTimeBetweenCheck = 0;
-       
-       private long lastScrollTime = 0L;
-       private int nbScrollClick = 0;
-       
-       /**
-        * Constructor of the DelayedMouseScroll listener.<p>
-        * Object will be initialized but start() need to be called for it start listening for scroll.
-        * 
-        * @param newListener                   The parent mouse listener
-        * @param newWaitFullTime               The time to wait for scroll events
-        * @param newWaitBeforeCheck    The delay between polling for scroll events
-        */
-       public DelayedMouseScroll(HistogramCanvasMouseListener newListener, long newWaitFullTime, long newWaitBeforePoll) {
-               
-               mouseListener = newListener;
-               
-               // Get the current system time. 
-               // This will be used to determine since how long we wait for click
-               lastScrollTime = System.currentTimeMillis();
-               
-               waitTimeBetweenScroll = newWaitFullTime;
-               waitTimeBetweenCheck = newWaitBeforePoll;
-       }
-       
-       /**
-        * Increment the counter for the number of scroll events received.<p>
-        * This is intended to be called by the MouseListener.
-        * 
-        * Note : A new scroll event receive will reset the wait timer.
-        */
-       public void incrementMouseScroll() {
-               // Reset the wait timer
-               lastScrollTime = System.currentTimeMillis();
-               nbScrollClick++;
-               mouseListener.receiveMouseScrollCountWithoutNotification(nbScrollClick);
-       }
-       
-       /**
-        * Decrement the counter for the number of scroll events received.<p>
-        * This is intended to be called by the MouseListener.
-        * 
-        * Note : A new scroll event receive will reset the wait timer.
-        */
-       public void decrementMouseScroll() {
-               // Reset the wait timer
-               lastScrollTime = System.currentTimeMillis();
-               nbScrollClick--;
-               mouseListener.receiveMouseScrollCountWithoutNotification(nbScrollClick);
-       }
-       
-       /**
-        * Threaded execution method.<p>
-        * This is the real "wait" method that will wait for mouse scroll events.<p>
-        * 
-        * The function will wake every "waitTimeBetweenCheck" to check if we exhausted the timer.<p>
-        * So, the "longest" we could wait after the last event is "waitTimeBetweenScroll" + "waitTimeBetweenCheck"
-        * 
-        */
-       @Override
-       public void run() {
-               // Check if we waited more than "waitTimeBetweenScroll"
-               while ( (System.currentTimeMillis() - lastScrollTime) < waitTimeBetweenScroll ) {
-                       try {
-                               Thread.sleep(waitTimeBetweenCheck);
-                       }
-                       catch (Exception e) { }
-               }
-               
-               // Tell the mouse listener the number of click received
-               mouseListener.receiveMouseScrollCountWithNotification(nbScrollClick);
-       }
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java
deleted file mode 100644 (file)
index f94ce74..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *
- * Modifications:
- * 2010-07-16 Yuriy Vashchuk - Heritage corrections. Redraw bug correction.
- *                                                        Double Buffering implementation.
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * <b><u>HistogramCanvasPaintListener</u></b>
- * <p>
- * Implementation of a PaintListener for the need of the HistogramCanvas
- * <p> 
- */
-public class HistogramCanvasPaintListener implements PaintListener 
-{
-       private static ChildrenHistogramCanvas childrenCanvas = null;
-       protected boolean isFinished = false;
-       
-       /**
-        * HistogramCanvasPaintListener default constructor
-        */     
-       public HistogramCanvasPaintListener() {
-       }
-       
-       /**
-        * HistogramCanvasPaintListener constructor
-        * 
-        * @param parentCanvas Related canvas
-        */
-       public HistogramCanvasPaintListener(ChildrenHistogramCanvas newCanvas) {
-               childrenCanvas = newCanvas;
-       }
-       
-       /**
-        * Function called when the canvas need to redraw.<p>
-        * 
-        * @param event  The generated paint event when redraw is called.
-        */
-       private final String DATA_KEY = "double-buffer-image"; //$NON-NLS-1$
-       @Override
-       public void paintControl(PaintEvent event) {
-
-               if (childrenCanvas.getSize().x > 0 && childrenCanvas.getSize().y > 0) {
-                       Image image = (Image) childrenCanvas.getData(DATA_KEY);
-                       
-                       // Creates new image only absolutely necessary.
-                       if (image == null
-                                       || image.getBounds().width != childrenCanvas.getBounds().width
-                                       || image.getBounds().height != childrenCanvas.getBounds().height) {
-
-                               image = new Image(
-                                               event.display,
-                                               childrenCanvas.getBounds().width,
-                                               childrenCanvas.getBounds().height
-                                               );
-
-                               childrenCanvas.setData(DATA_KEY, image);
-                       }
-                       
-                       // Initializes the graphics context of the image. 
-               GC imageGC = new GC(image);
-               
-                       // First clear the whole canvas to have a clean section where to draw
-                       clearDrawingSection(imageGC, image, childrenCanvas);
-               
-                       // If the content is null or has rady to draw we quit the function here
-                       if ( (childrenCanvas.getHistogramContent() != null)
-                                       && (childrenCanvas.getHistogramContent().getReadyUpToPosition() != 0) ) {
-                               
-                               // Call the function that draw the bars
-//                             if (!isFinished) {
-                                       drawHistogram(imageGC, image);
-//                             }
-                               
-                               // Pinpoint a position if set
-                               if (childrenCanvas.getHistogramContent().getSelectedEventTimeInWindow() > 0 ) {
-                                       drawSelectedEventInWindow(imageGC, image);
-                               }
-
-                               // Draws the buffer image onto the canvas. 
-                               event.gc.drawImage(image, 0, 0);
-                       }
-
-                       imageGC.dispose();
-               }
-       }
-       
-       /**
-        * Clear the drawing section of the canvas<p>
-        * This paint the whole background in EMPTY_BACKGROUND_COLOR, so we have something clean to draw on.
-        * 
-        * @param imageGC GC content.
-        * @param image Image content.
-        * @param ourCanvas Canvas to clean.
-        */
-       public void clearDrawingSection(GC imageGC, Image image, HistogramCanvas ourCanvas) {
-               // Fills background. 
-               imageGC.setBackground(ourCanvas.getDisplay().getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
-        imageGC.fillRectangle(0, 0, image.getBounds().width + 1, image.getBounds().height + 1);                
-       }
-       
-       // *** VERIFY ***
-       // Is it good to put this synchronized?
-       //
-       /**
-        * Draw the histogram bars in the canvas.<p>
-        * Use existing elements in HistogramContent to draw bars on the cancas; 
-        *      the element table in content need to be populated and have consistent value.  
-        * 
-        * @param imageGC GC content.
-        * @param image image content.
-        */
-       public synchronized void drawHistogram(GC imageGC, Image image) {
-               
-               // This will be the bottom color for all the bars that wil be draw below.
-               imageGC.setBackground( new Color( imageGC.getDevice(), 74, 112, 139) );
-               
-               // *** NOTE *** 
-               // Y Position in a canvas is REVERSED, so "0" is on top of the screen and "MAX" is on bottom.
-               // Not very instinctive, isn't it?
-
-               // Draw a bar from the left (pos X=0) until the pos=(NbBars*barWidth). If space is left, it will be blanked after.
-           for ( int x = 0; x < childrenCanvas.getHistogramContent().getReadyUpToPosition(); x++) {
-               imageGC.fillRectangle(
-                               childrenCanvas.getHistogramContent().getBarsWidth() * x,
-                               image.getBounds().height - childrenCanvas.getHistogramContent().getElementByIndex(x).intervalHeight,
-                               childrenCanvas.getHistogramContent().getBarsWidth(),
-                               childrenCanvas.getHistogramContent().getElementByIndex(x).intervalHeight
-                               );
-           }
-               
-       }
-       
-       /**
-        * Draw a certain event selected in the window.<p>
-        * 
-        * @param imageGC GC content.
-        * @param image image content.
-        */
-       public synchronized void drawSelectedEventInWindow(GC imageGC, Image image) {
-               
-               final HistogramContent tmpContent = childrenCanvas.getHistogramContent();
-               final int tmpBarWidth = tmpContent.getBarsWidth();
-               final int position = tmpContent.getClosestXPositionFromTimestamp(tmpContent.getSelectedEventTimeInWindow());
-               
-               // This will be the color for all the bars that will be draw below.
-               imageGC.setForeground(childrenCanvas.getDisplay().getSystemColor(HistogramConstant.SELECTED_EVENT_COLOR));
-               imageGC.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH);
-               imageGC.drawLine(
-                               tmpBarWidth * position,
-                               0,
-                               tmpBarWidth * position,
-                               image.getBounds().height
-                               );
-               }
-       
-       /**
-        * @param isFinished the flag value
-        */
-       public void setIsFinished(boolean isFinished) {
-               this.isFinished = isFinished;
-       }               
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java
deleted file mode 100644 (file)
index 051dcdd..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.linuxtools.lttng.LttngConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * <b><u>HistogramConstant</u></b>
- * <p>
- * Empty interface class to hold the different constants needed by the histogram.
- * <p>
- */
-public abstract class HistogramConstant {
-
-       // Constants relative to requests
-//     public final static int MAX_EVENTS_PER_READ = LttngConstants.DEFAULT_BLOCK_SIZE;
-       public final static int REDRAW_EVERY_NB_EVENTS = 20000;
-       public final static Boolean SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE = true;
-       
-       
-       // Constant relative to the content
-       public final static double DEFAULT_DIFFERENCE_TO_AVERAGE = 1000.0;
-       
-       
-       
-       // Constants relative to zoom. Factors need to be a percentage ( 0 < factors < 1 )
-       public final static double ZOOM_IN_FACTOR = 0.1;
-       public final static double ZOOM_OUT_FACTOR = 0.1;
-       
-       
-       // Constants relative to wait time while listening for scroll events
-       // "FULL" is time to wait to stop "to count" mouse scroll click events
-       // "INTERVAL" is time to wait between polling for scroll click events
-       public final static long FULL_WAIT_MS_TIME_BETWEEN_MOUSE_SCROLL = 1000L;
-       public final static long INTERVAL_WAIT_MS_TIME_BETWEEN_POLL = 100L;
-       
-       
-       // Constants relative to the displacement in the trace
-       // Factor represent a number of HistogramContent interval
-       // Multiple is the factor to multiply to basic during "fast" displacement 
-       public final static int BASIC_DISPLACEMENT_FACTOR = 1;
-       public final static double  FAST_DISPLACEMENT_MULTIPLE = 10.0;
-       
-       
-       // Constants relative to the drawing of the Histogram
-       // Colors for the histogram. Background should be the same as the background in use
-       public final static int EMPTY_BACKGROUND_COLOR = SWT.COLOR_WHITE;
-       public final static int SELECTED_EVENT_COLOR = SWT.COLOR_RED;
-       
-       // Dimension for the line of the "Selection Window"
-       public final static int MINIMUM_WINDOW_WIDTH = 3;
-       public final static int SELECTION_LINE_WIDTH = 1;
-       public final static int SELECTION_CROSSHAIR_WIDTH = 1;
-       
-       
-       /**
-        * Method to format a long representing nanosecond into a proper String.<p>
-        * The returned String will always be like "0.000000000", missing decimal will be added.
-        * 
-        * @param nanosecTime   This time to format
-        * 
-        * @return      The formatted string
-        */
-       public static String formatNanoSecondsTime(long nanosecTime) {
-               String returnedTime = Long.toString(nanosecTime);
-               
-               // If our number has over 9 digits, just add a dot after the ninth digits
-               if ( returnedTime.length() > 9 ) {
-                       returnedTime = returnedTime.substring(0, returnedTime.length() - 9 ) + "." + returnedTime.substring( returnedTime.length() - 9 ); //$NON-NLS-1$
-               }
-               // Otherwise, patch missing decimal with 0
-               else {
-                       int curSize = returnedTime.length();
-                       for (int l=0; (curSize+l)< 9; l++) {
-                               returnedTime = "0" + returnedTime; //$NON-NLS-1$
-                       }
-                       returnedTime = "0." + returnedTime; //$NON-NLS-1$
-               }
-               
-               return returnedTime;
-       }
-       
-       /**
-        * Convert a String representing nanoseconds into a valid long.<p>
-        * This can handle number like "0.5", "0.123456789" as well as plain number like "12".<p>
-        * 
-        * Note : This function ALWAYS return a number, if conversion failed, 0 will be returned.<p>
-        * 
-        * @param timeString    The string to convert
-        * 
-        * @return                              The converted nanoseconds time as long
-        */
-       public static long convertStringToNanoseconds( String timeString ) {
-               long returnedNumber = 0L;
-               
-           try {
-               // Avoid simple commat/dot mistake
-               timeString = timeString.replace(",", "."); //$NON-NLS-1$ //$NON-NLS-2$
-       
-               // If we have a dot, we have a decimal number to convert
-               int dotPosition = timeString.indexOf("."); //$NON-NLS-1$
-               
-               // If the user begun the line with a dot, we add a zero
-               if ( dotPosition == 0 ) {
-                timeString = "0" + timeString; //$NON-NLS-1$
-                dotPosition = 1;
-               }
-               
-               // If we found a dot, verify that we have 9 digits
-               if ( dotPosition != -1 ) {
-                int decimalNumber = (timeString.length() - dotPosition -1);
-                
-                // If we have less than 9 digits, we fill with 0
-                if ( decimalNumber <= 9 ) {
-                       StringBuffer strBuffer = new StringBuffer(timeString);
-                    for ( int nbDec=decimalNumber; nbDec<9; nbDec++) {
-                       strBuffer.append("0"); //$NON-NLS-1$
-                    }
-                    timeString = strBuffer.toString();
-                }
-                // We have OVER 9 digits, skip the useless part
-                else {
-                       timeString = timeString.substring(dotPosition, 9);
-                }
-               }
-               
-               // Conversion into decimal seconds
-               double dblMaxTimerange = Double.parseDouble(timeString);
-               // Conversion into nanoseconds
-               returnedNumber = (long)(dblMaxTimerange * 1000000000.0);
-           }
-           catch (NumberFormatException e) {
-               System.out.println("Warning : Could not convert string into nanoseconds (convertStringToLong)"); //$NON-NLS-1$
-           }
-           
-           return returnedNumber;
-    }
-       
-       /**
-        * Calculate the correcte width of a String.<p>
-        * Useful to set a control to its maximum size; since the size depends on characters, 
-        *              this will calculate the correct sum... should be platform independant (we hope).
-        * 
-        * @param parent        Parent control we will use as a reference. Could be any composite.
-        * @param text          The Text to measure the size from
-        * 
-        * @return                      The size calculated.
-        */
-       public static int getTextSizeInControl(Composite parent, String text) {
-               GC graphicContext = new GC(parent);
-        int textSize = 0;
-        for ( int pos=0; pos<text.length(); pos++ ) {
-               textSize += graphicContext.getAdvanceWidth( text.charAt(pos) );
-        }
-        // Add an extra space in case there was trailing whitespace in the message
-        textSize += graphicContext.getAdvanceWidth( ' ' );
-        
-        return textSize;
-       }
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java
deleted file mode 100644 (file)
index a0fd0bb..0000000
+++ /dev/null
@@ -1,789 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *   
- * Modifications:
- * 2010-07-16 Yuriy Vashchuk - Heritage correction.
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-
-/**
- * <b><u>HistogramContent</u></b>
- * <p>
- * This class hold the content that will be used to draw the Histograms.
- * <p>
- */
-public class HistogramContent {
-       
-       // Start and end time of the content
-       private long            startTime = 0L;
-       private long            endTime   = 0L;
-       
-       // Some information about the content
-       // Most of them are required to calculate position and/or draw
-       // Make sure they stay consistent!
-       private long            elementsTimeInterval = 1L;
-       private double  heightFactor = 100.0;
-       private long    heighestEventCount = 0L;
-       private int     maxHeight        = 0;
-       private int     canvasWindowSize = 0;
-       private int     barsWidth = 0;
-       
-       // This value is used to calculate at which point we should "cut" bar that are too tall.
-       // Default value is large enought so that no bar should be cut
-       private double  maxDifferenceToAverage = HistogramConstant.DEFAULT_DIFFERENCE_TO_AVERAGE;
-       // This is a factor we might apply on the max difference to average, as example if we concatenate interval together
-       private double  maxDifferenceFactor = 1.0;
-       
-       // By default we will only consider element up to this position 
-       private int     readyUpToPosition = 0;
-       
-       // The average number of events in the content
-       // Note : this IS needed to draw
-       private int     averageNumberOfEvents = 0;
-       
-       // This is to draw the selected event of the TMF framework in another color
-       // Set the 0 to ignore
-       private long selectedEventTimeInWindow = -1L;
-       
-       // The table that hold the elements
-       private HistogramElement[] elementTable;
-       
-       
-       /**
-        * Default constructor for the HistogramContent.
-        * 
-        * @param tableSize                     The size ofthe element table that will be created.
-        * @param newCanvasSize         The full size of the canvas. Used for positionning; need to be consistent with canvas.
-        * @param newMaxHeight          The maximum height of a bar, usually same as the height of the canvas.
-        */
-       public HistogramContent(int tableSize, int newCanvasSize, int newBarWidth, int newMaxHeight) {
-               this(tableSize, newCanvasSize, newBarWidth, newMaxHeight, HistogramConstant.DEFAULT_DIFFERENCE_TO_AVERAGE);
-       }
-       
-       /**
-        * Default constructor for the HistogramContent.
-        * 
-        * @param tableSize                     The size ofthe element table that will be created.
-        * @param newCanvasSize         The full size of the canvas. Used for positionning; need to be consistent with canvas.
-        * @param newMaxHeight          The maximum height of a bar, usually same as the height of the canvas.
-        * @param newDiffToAverage  This value at which point we "cut" bar that are too tall.
-        */
-       public HistogramContent(int tableSize, int newCanvasSize, int newBarWidth, int newMaxHeight, double newDiffToAverage) {
-               canvasWindowSize = newCanvasSize;
-               barsWidth = newBarWidth;
-               maxHeight = newMaxHeight;
-               maxDifferenceToAverage = newDiffToAverage;
-               
-               // Create a new element table from the above value
-               // The table will not get initialized until resetTable() is called. 
-               createNewTable(tableSize);
-       }
-       
-       /**
-        * Create a new table to hold the content element.<p>
-        * Note that the table is not initialized (and so unusable) until resetTable() is called.
-        * 
-        * @param newTableSize  The size (number of element) of the table.
-        */
-       public void createNewTable(int newTableSize) {
-               elementTable = new HistogramElement[newTableSize];
-               
-               for ( int x=0; x<elementTable.length; x++) {
-                       elementTable[x] = new HistogramElement();
-                       elementTable[x].index = x;
-               }
-       }
-       
-       /**
-        * Reset all HistogramContent attributes, but keep the elements table untouched.<p>
-        */
-       public void clearContentData() {
-               startTime = 0L;
-               endTime = 0L;
-               
-               elementsTimeInterval = 1L;
-               heightFactor = 100.0;
-               heighestEventCount = 0L;
-               
-               readyUpToPosition = 0;
-       }
-       
-       /**
-        * Reset the data in the elements table.<p>
-        * NOTE : For this to be consistent and usuable, "startTime", "endTime" and "intervalTime" need to be set already.
-        */
-       public void resetTable() {
-               for ( int x=0; x<elementTable.length; x++) {
-                       elementTable[x].index = x;
-                       elementTable[x].firstIntervalTimestamp = startTime + (x*elementsTimeInterval);
-                       elementTable[x].intervalNbEvents = 0L;
-                       elementTable[x].intervalHeight = 0;
-               }
-       }
-       
-       /**
-        * Reset the data in the elements table.<p>
-        * Start and EndTime will be used to calculate elementsTimeInterval.<p>
-        * 
-        *  @param      newStartTime    The new start time to use 
-        *  @param      newEndTime              The new stop time to use
-        */
-       public void resetTable(long newStartTime, long newEndTime) {
-               resetTable(newStartTime, newEndTime, elementsTimeInterval);
-       }
-       
-       /**
-        * Reset the data in the elements table.<p>
-        * elementsTimeInterval will be set to the one give, use this for fixed interval.<p>
-        * 
-        *  @param      newStartTime    The new start time to use 
-        *  @param      newEndTime              The new stop time to use
-        *  @param  newTimeInterval The new time interval to use
-        */
-       public void resetTable(long newStartTime, long newEndTime, long newTimeInterval) {
-               
-               startTime = newStartTime;
-               endTime = newEndTime;
-               recalculateElementsTimeInterval(newStartTime, newEndTime);
-               
-               for ( int x=0; x<elementTable.length; x++) {
-                       elementTable[x].index = x;
-                       elementTable[x].firstIntervalTimestamp = startTime + (x*elementsTimeInterval);
-                       elementTable[x].intervalNbEvents = 0L;
-                       elementTable[x].intervalHeight = 0;
-               }
-       }
-       
-       /**
-        * Clear (zeroed) the data in the elements table.<p>
-        * NOTE : Unlike reset, this does not recalculate the content, 
-        *                      so it should be done either by hand or by calling reset table after.
-        */
-       public void clearTable() {
-               for ( int x=0; x<elementTable.length; x++) {
-                       elementTable[x].index = x;
-                       elementTable[x].firstIntervalTimestamp = 0L;
-                       elementTable[x].intervalNbEvents = 0L;
-                       elementTable[x].intervalHeight = 0;
-               }
-       }
-       
-       /**
-        * Print all HistogramContent attributes, but the elements table.
-        */
-    @SuppressWarnings("nls")
-       public void printContentInfo() {
-               System.out.println("startTime          : " + startTime);
-               System.out.println("endTime            : " + endTime );
-               System.out.println();
-               System.out.println("intervalTime       : " + elementsTimeInterval);
-               System.out.println("heightFactor       : " + heightFactor);
-               System.out.println("heighestEventCount : " + heighestEventCount);
-               System.out.println();
-               System.out.println("readyUpToPosition  : " + readyUpToPosition);
-       }
-       
-       /**
-        * Print the data in the elements table.<p>
-        */
-    @SuppressWarnings("nls")
-       public void printTable() {
-               for ( int x=0; x<elementTable.length; x++) {
-                       System.out.println("X:" + x + " -> " + elementTable[x].intervalNbEvents + ":" + elementTable[x].intervalHeight + " (" + elementTable[x].firstIntervalTimestamp + ")");
-               }
-       }
-       
-       /**
-        * Getter for the timestamp of the selected event in the window.<p>
-        * 
-        * @return      The time of the event.
-        */
-       public long getSelectedEventTimeInWindow() {
-               return selectedEventTimeInWindow;
-       }
-       
-       /**
-        * Setter for the timestamp of the selected event in the window.<p>
-        * 
-        * This allow to pinpoint a certain event or position in the window.
-        * Set to 0 or lower to ignore.
-        * 
-        * @param newPosition The new event time.
-        */
-       public void setSelectedEventTimeInWindow(long newTime) {
-               this.selectedEventTimeInWindow = newTime;
-       }
-       
-       /**
-        * Get an element in the table by its index.<p>
-        * Null is returned if the index is out of range.<p>
-        * Note that you can get an element past "readyUpToPosition", the index is NOT tested against it. 
-        * 
-        * @param index The index of the element (0 < index < nbElement)
-        * 
-        * @return The element found or null if the index is wrong.
-        */
-       public HistogramElement getElementByIndex(int index) {
-               HistogramElement returnedElement = null;
-               
-               if ( (index >= 0) && (index < elementTable.length) ) {
-                       returnedElement = elementTable[index];
-               }
-               
-               return returnedElement;
-       }
-       
-       /**
-        * Return the closest element to a X position on the canvas.<p>
-        * Note : canvasWindowSize need to be set correctly here, otherwise unexpected element might be returned.<p>
-        * <p>
-        * NOTE : This <b>ALWAYS</b> return an element; 
-        *              If calculation lead outside the table, the first or the last element will be returned.  
-        * 
-        * @param position  The X position we are looking at (0 < pos < canvasWidth) 
-        * 
-        * @return      The <i>closest</i> element found.
-        */
-       public HistogramElement getClosestElementFromXPosition(int position) {
-               
-               int index = (int)Math.round((double)elementTable.length * ((double)position / (double)canvasWindowSize) );
-               
-               // If we are out of bound, return the closest border (first or last element)
-               if ( index < 0) {
-                       index = 0;
-               }
-               else if ( index >= elementTable.length ) {
-                       index = (elementTable.length -1);
-               }
-               
-               return elementTable[index];
-       }
-       
-       /**
-        * Return the closest element's timestamp to a X position on the canvas.<p>
-        * Note : canvasWindowSize need to be set correctly here, otherwise unexpected timestamp might be returned.<p>
-        * <p>
-        * NOTE : This <b>ALWAYS</b> return a timestamp; 
-        *              If calculation lead outside the table, the first or the last timestamp will be returned.  
-        * 
-        * @param position  The X position we are looking at (0 < pos < canvasWidth) 
-        * 
-        * @return      The <i>closest</i> timestamp found.
-        */
-       public long getClosestTimestampFromXPosition(int position) {
-               return getClosestElementFromXPosition(position).firstIntervalTimestamp;
-       }
-       
-       /**
-        * Return the X position (relative to the canvas) of a certain element.<p>
-        * Note : canvasWindowSize need to be set correctly here, otherwise unexpected element might be returned.<p>
-        * 
-        * NOTE : This <b>ALWAYS</b> return an element; 
-        *              If calculation lead outside the table, the first or the last element will be returned.
-        * 
-        * @param targetElement         The element we are looking to find the position 
-        * 
-        * @return                                      The <i>closest</i> found element. 
-        */
-       public int getXPositionFromElement(HistogramElement targetElement) {
-               return (int)Math.round( ((double)targetElement.index / (double)elementTable.length)*(double)canvasWindowSize );
-       }
-       
-       /**
-        * Return the closest element to a timestamp (long) given.<p>
-        * Note : startTime and intervalTime need to be set correctly here, otherwise unexpected element might be returned.<p>
-        * <p>
-        * NOTE : This <b>ALWAYS</b> return an element; 
-        *              If calculation lead outside the table, the first or the last element will be returned.  
-        * 
-        * @param timestamp  The timestamp (in nanosecond, as long) of the element we are looking for (startTime < timestamp < endTime) 
-        * 
-        * @return      The <i>closest</i> element found.
-        */
-       public HistogramElement getClosestElementFromTimestamp(long timestamp) {
-               int index = (int)Math.round( (double)(timestamp - startTime)/(double)elementsTimeInterval );
-               
-               // If we are out of bound, return the closest border (first or last element)
-               if ( index < 0) {
-                       index = 0;
-               }
-               else if ( index >= elementTable.length ) {
-                       index = (elementTable.length -1);
-               }
-               
-               return elementTable[index];
-       }
-       
-       /**
-        * Return the closest X position to a timestamp (long) given.<p>
-        * Note : startTime and intervalTime need to be set correctly here, otherwise unexpected position might be returned.<p>
-        * <p>
-        * NOTE : This <b>ALWAYS</b> return a position; 
-        *              If calculation lead outside the table, the first or the last position will be returned.  
-        * 
-        * @param timestamp  The timestamp (in nanosecond, as long) of the element we are looking for (startTime < timestamp < endTime) 
-        * 
-        * @return      The <i>closest</i> position found.
-        */
-       public int getClosestXPositionFromTimestamp(long timestamp) {
-               return getXPositionFromElement(getClosestElementFromTimestamp(timestamp));
-       }
-       
-       /**
-        * Return the closest element to an element and a time interval to this element.<p>
-        * The time interval can be negative or positive (before or after the element).
-        * 
-        * Note : IntervalTime and StartTime need to be set correctly here, otherwise unexpected result might be returned.<p>
-        * 
-        * @param targetElement                 The element we compare the interval with.
-        * @param intervalToElement             Time negative or positive time interval (in nanosecond) to this element. 
-        * 
-        * @return      The <i>closest</i> found element, or null if given data are wrong.
-        */
-       public HistogramElement getClosestElementByElementAndTimeInterval(HistogramElement targetElement, long intervalToElement) {
-               
-               // Get the timestamp of the target element
-               // This should always be valid as long the table is initialized
-               long elementTime = targetElement.firstIntervalTimestamp;
-               elementTime = elementTime + intervalToElement;
-               
-               return getClosestElementFromTimestamp(elementTime);
-       }
-       
-       /**
-        * Return the closest element to an element's timestamp (as long) and a time interval to this element.<p>
-        * The time interval can be negative or positive (before or after the element).
-        * 
-        * Note : IntervalTime and StartTime need to be set correctly here, otherwise unexpected result might be returned.<p>
-        * 
-        * @param timestamp                             The timestamp (in nanoseconds, as long) of the element we want to compare from.
-        * @param intervalToElement             Time negative or positive time interval (in nanosecond) to this element. 
-        * 
-        * @return      The <i>closest</i> found element, or null if given data are wrong.
-        */
-       public int getClosestElementByTimestampAndTimeInterval(long timestamp, long intervalToElement) {
-               HistogramElement targetElement = getClosestElementFromTimestamp(timestamp);
-               HistogramElement newElement = getClosestElementByElementAndTimeInterval(targetElement, intervalToElement);
-               
-               return getXPositionFromElement(newElement);
-       }
-       
-       /**
-        * Return the closest element to an element's position and a time interval to this element.<p>
-        * The time interval can be negative or positive (before or after the element).
-        * 
-        * Note : IntervalTime and StartTime need to be set correctly here, otherwise unexpected result might be returned.<p>
-        * 
-        * @param targetPosition                The position (relative to the canvas) of the element we want to compare from.
-        * @param intervalToElement             Time negative or positive time interval (in nanosecond) to this element.
-        * 
-        * @return      The <i>closest</i> found element, or null if given data are wrong.
-        */
-       public int getXPositionByPositionAndTimeInterval(int targetPosition, long intervalToElement) {
-               HistogramElement targetElement = getClosestElementFromXPosition(targetPosition);
-               HistogramElement newElement = getClosestElementByElementAndTimeInterval(targetElement, intervalToElement);
-               
-               return  getXPositionFromElement(newElement);
-       }
-       
-       /**
-        * Getter for the number of element.<p>
-        * The same as the value of tableSize given at construction.
-        * 
-        * @return The number of element in the elements table.
-        */
-       public int getNbElement() {
-               return elementTable.length;
-       }
-       
-       /**
-        * Getter for the average number of events by interval in the content.<p>
-        * 
-        * Note : Might be set externally (instead of calculated internally), so consistency with the content is not guarantee.
-        * 
-        * @return      Average number of events we currently use in
-        */
-       public int getAverageNumberOfEvents() {
-               return averageNumberOfEvents;
-       }
-       
-       /**
-        * Setter for averageNumberOfEvents.<p>
-        * 
-        * Note : this is used in some drawing calculation so make sure this number make sense.
-        * Note : you might want to call recalculateEventHeight() if you change this.
-        * 
-        * @param newAverageNumberOfEvents      The new average number of events to use.
-        */
-       public void setAverageNumberOfEvents(int newAverageNumberOfEvents) {
-               this.averageNumberOfEvents = newAverageNumberOfEvents;
-       }
-       
-       /**
-        * Recalculate the average number of events by time interval.<p>
-        * 
-        * Note : This run over all the element so this is quite cpu intensive, use with care. 
-        */
-       public void recalculateAverageNumberOfEvents() {
-               
-               int nbInterval = 0;
-               int totalNbEvents = 0;
-               
-               // Go over the element up to readyUpToPosition (further position might not be ready)
-               for ( int x=0; x<readyUpToPosition; x++) {
-                       // Skip the empty interval if we were asked to do so.
-                       if ( HistogramConstant.SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE ) {
-                               if ( elementTable[x].intervalNbEvents > 0 ) {
-                               nbInterval++;
-                               }
-               }
-               else {
-                       nbInterval++;
-               }
-                       
-                       totalNbEvents += elementTable[x].intervalNbEvents;
-               }
-               // Calculate the average here
-               averageNumberOfEvents = (int)Math.round((double)totalNbEvents / (double)nbInterval);
-       }
-       
-       /**
-        * Getter for the start time of the content.<p>
-        * 
-        * @return The start time we currently use.
-        */
-       public long getStartTime() {
-               return startTime;
-       }
-       
-       /**
-        * Setter for the start time of the content.<p>
-        * Note : You probably want to call "resetTable()" if you change this, otherwise data might be inconsistent.
-        * 
-        * @param newStartTime  the new start time
-        */
-       public void setStartTime(long newStartTime) {
-               this.startTime = newStartTime;
-       }
-       
-       
-       /**
-        * Getter for the end time of the content.<p>
-        * 
-        * @return The end time we currently use.
-        */
-       public long getEndTime() {
-               return endTime;
-       }
-       
-       /**
-        * Setter for the end time of the content.<p>
-        * Note : You probably want to call "resetTable()" if you change this, otherwise data might be inconsistent.
-        * 
-        * @param newStartTime  the new end time
-        */
-       public void setEndTime(long newEndTime) {
-               this.endTime = newEndTime;
-       }
-       
-       /**
-        * Getter for the complete time interval of the content.<p>
-        * Note : This return "endTime" minus "startTime", unlike getReadyTimeInterval() it won't check the actual time of elements.  
-        * 
-        * @return      The complete time interval
-        */
-       public long getCompleteTimeInterval() {
-               return ( endTime - startTime );
-       }
-       
-       /**
-        * Getter for the time interval for the element between first and readyUpToPosition<p>
-        * Note : This return element[readyPosition].time - element[first].time , not the full interval like getCompleteTimeInterval()
-        * 
-        * @return      The time interval of the position that are ready.
-        */
-       public long getReadyTimeInterval() {
-               return ( elementTable[readyUpToPosition].firstIntervalTimestamp - elementTable[0].firstIntervalTimestamp );
-       }
-       
-       /**
-        * Getter for the height factor of the bar.<p>
-        * Note : height =  "nb events in interval" * heightFactor
-        * 
-        * @return      Height factor currently used. 
-        */
-       public double getHeightFactor() {
-               return heightFactor;
-       }
-       
-       /**
-        * Recalculate the height factor of the element table.<p>
-        * Assume values of "maxHeight", "heighestEventCount" or "averageNumberOfEvents" are set correctly.
-        */
-       public void recalculateHeightFactor() {
-               // Recalculate the new HeightFactor for the element; 
-               //              the highest bar will get "maxHeight" and other bar a fraction of it.
-               double diffToConsider = (maxDifferenceToAverage * maxDifferenceFactor * (double)barsWidth);
-               
-               if ( heighestEventCount > (long)(diffToConsider * (double)averageNumberOfEvents) ) {
-                       heightFactor = (double)maxHeight/( diffToConsider * (double)averageNumberOfEvents);
-               }
-               else {
-                       heightFactor = (double)maxHeight/(double)heighestEventCount;
-               }
-       }
-       
-       /**
-        * Recalculate the height of each bar in the elements table.<p>
-        * This assume "heightFactor" is already set correctly.<p>
-        *  
-        * NOTE : if "maxHeight", "heighestEventCount" or "averageNumberOfEvents" changes, 
-        *                      recalculateHeightFactor() should be recalled.
-        */
-       public void recalculateEventHeight() {
-               // Recalculate the height of the bars up to "readyUpToPosition"
-               for ( int x=0; x<readyUpToPosition; x++) {
-                       elementTable[x].intervalHeight = (int)Math.ceil((double)elementTable[x].intervalNbEvents * heightFactor);
-               }
-       }
-       
-       /**
-        * Recalculate the height of each bar in a certain interval of the elements table.<p>
-        * Unlike recalculateEventHeight(), this only recalculate for the given range, not the whole table.
-        * 
-        */
-       public void recalculateEventHeightInInterval(int startPosition, int stopPosition) {
-               // Basic error checking on start : should be bigger than 0
-               if ( startPosition < 0 ) {
-                       startPosition = 0;
-               }
-               
-               // Basic error checking on start : should be smaller than length - 1
-               if ( stopPosition >= elementTable.length) {
-                       stopPosition = (elementTable.length-1);
-               }
-               
-               // Recalculate the height of the bars from startPosition to stopPosition
-               for ( int x=startPosition; x<stopPosition; x++) {
-                       elementTable[x].intervalHeight = (int)Math.ceil((double)elementTable[x].intervalNbEvents * heightFactor);
-               }
-       }
-       
-       /**
-        * Getter for the full size of the canvas.<p>
-        * This is used for the positionnal calculation so should be consistent with the real canvas size.
-        * 
-        * @return      Size of the canvas we currently use.
-        */
-       public int getCanvasWindowSize() {
-               return canvasWindowSize;
-       }
-       
-       /**
-        * Set a new full size of the canvas.<p>
-        * This is used for the positionnal calculation so should be consistent with the real canvas size.
-        * 
-        * @param       newSize New canvas size;
-        */
-       public void setCanvasWindowSize(int newSize) {
-               canvasWindowSize = newSize;
-       }
-       
-       /**
-        * Getter for the heighest event count recorded so far for an interval.<p>
-        * 
-        * Note : Might be set externally (instead of calculated internally), so consistency with the content is not guarantee.
-        * 
-        * @return Current heighestEventCount
-        */
-       public long getHeighestEventCount() {
-               return heighestEventCount;
-       }
-       
-       /**
-        * Setter for setHeighestEventCount.<p>
-        * 
-        * Note : this is used in some drawing calculation so make sure this number make sense.
-        * Note : you might want to call recalculateEventHeight() if you change this.
-        * 
-        * @param newHeighestEventCount Heighest event count for a single interval.
-        */
-       public void setHeighestEventCount(long newHeighestEventCount) {
-               this.heighestEventCount = newHeighestEventCount;
-       }
-       
-       /**
-        * Recalculate the heightest event count for a single time interval.<p>
-        * 
-        * Note : This run over all the element so this is quite cpu intensive, use with care. 
-        */
-       public void recalculateHeighestEventCount() {
-               // Go over the element up to readyUpToPosition (further position might not be ready)
-               for ( int x=0; x<readyUpToPosition; x++) {
-                       if ( elementTable[x].intervalNbEvents > heighestEventCount ) {
-                               this.heighestEventCount = elementTable[x].intervalNbEvents;
-                       }
-               }
-       }
-       
-       /**
-        * Getter for the max height of a bar in the content.<p>
-        * 
-        * @return      maximum height for a bar we currently use.
-        */
-       public int getMaxHeight() {
-               return maxHeight;
-       }
-       
-       /**
-        * Setter for maxHeight.<p>
-        * 
-        * Note : this is used in some drawing calculation so make sure this number make sense.
-        * Note : you might want to call recalculateEventHeight() if you change this.
-        * 
-        * @param maxHeight     The new maximum height for a bar to use.
-        */
-       public void setMaxHeight(int maxHeight) {
-               this.maxHeight = maxHeight;
-       }
-       
-       /**
-        * Getter for the max difference to the average height a bar can have.<p>
-        * This determine at which point a bar too tall is "cut". Set a very large value (like 1000.0) to ignore.
-        * 
-        * @return      maximum difference to the average we currently use.
-        */
-       public double getMaxDifferenceToAverage() {
-               return maxDifferenceToAverage;
-       }
-       
-       /**
-        * Setter for the max difference to the average height a bar can have.<p>
-        * This determine at which point a bar too tall is "cut". Set a very large value (like 1000.0) to ignore.
-        * 
-        * Note : this is used in some drawing calculation so make sure this number make sense.
-        * Note : you might want to call recalculateEventHeight() if you change this.
-        * 
-        * @param newDiffToAverage      The new maximum difference to the average to use.
-        */
-       public void setMaxDifferenceToAverage(double newDiffToAverage) {
-               maxDifferenceToAverage = newDiffToAverage;
-       }
-       
-       
-       /**
-        * Getter for a factor applied to the max difference to the average height a bar can have.<p>
-        * This is muliplied to maxDifferenceToAverage. Set to value 1.0 to ignore.
-        * 
-        * Note : this is useful if you concatenate some intervals to gether but want the average to be consistent
-        * 
-        * @return      maximum difference to the average we currently use.
-        */
-       public double getMaxDifferenceToAverageFactor() {
-               return maxDifferenceFactor;
-       }
-       
-       /**
-        * Setter for a factor applied to the max difference to the average height a bar can have.<p>
-        * 
-        * Note : this is used in some drawing calculation so make sure this number make sense.
-        * Note : you might want to call recalculateEventHeight() if you change this.
-        * Note : setting to 0 will cause bar to have a zero size... use 1.0 to desactivate
-        * 
-        * @param newFactor             The new factor to use.
-        */
-       public void setMaxDifferenceToAverageFactor(double newFactor) {
-               maxDifferenceFactor = newFactor;
-       }
-       
-       
-       /**
-        * Getter for the interval time of each interval.<p>
-        * This is usually "(EndTime - StartTime) / NbElement"
-        * 
-        * @return      Currently used interval time.
-        */
-       public long getElementsTimeInterval() {
-               return elementsTimeInterval;
-       }
-       
-       
-       /**
-        * Setter for the interval time of each interval.<p>
-        * 
-        * Note : this is used in some drawing calculation so make sure this number make sense.
-        * Note : you migth want to call resetTable() to to fill the element's table again if you change this.
-        * 
-        * @return New interval time.
-        */
-       public void setElementsTimeInterval(long newInterval) {
-               this.elementsTimeInterval = newInterval;
-       }
-       
-       
-       /**
-        * Calculate the correct time interval of each element from the given time.<p>
-        * 
-        * @return      The complete time interval
-        */
-       public void recalculateElementsTimeInterval(long startTime, long endTime) {
-               long tmpInterval = (long)Math.ceil((double)(endTime - startTime)/ (double)getNbElement());
-               
-               if ( tmpInterval <= 0 ) {
-                       tmpInterval = 1L;
-               }
-               
-               this.elementsTimeInterval = tmpInterval;
-       }
-       
-       
-       /**
-        * Getter for readyUpToPosition.<p>
-        * This should tell to which point the content is filled, calculated and ready to use.
-        * 
-        * @return Last position processed so far.
-        */
-       public int getReadyUpToPosition() {
-               return readyUpToPosition;
-       }
-       
-       /**
-        * Setter for readyUpToPosition.<p>
-        * Set a new point (position) up to where the content is filled, calculated and ready to use. 
-        * 
-        * @param newReadyUpToPosition  The new position to use.
-        */
-       public void setReadyUpToPosition(int newReadyUpToPosition) {
-               this.readyUpToPosition = newReadyUpToPosition;
-       }
-       
-       /**
-        * Getter for the bar width.<p>
-        * This is needed by the paint listener usually.
-        * 
-        * @return current bars width;
-        */
-       public int getBarsWidth() {
-               return barsWidth;
-       }
-       
-       /**
-        * Setter for the bar width.<p>
-        * Setting this to 0 will hide all the bar in the histogram.
-        * 
-        * @param newBarsWidth new bars width;
-        */
-       public void setBarsWidth(int newBarsWidth) {
-               this.barsWidth = newBarsWidth;
-       }
-       
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCurrentTimeControl.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCurrentTimeControl.java
new file mode 100644 (file)
index 0000000..bbdd3f1
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * <b><u>HistogramCurrentTimeControl</u></b>
+ * <p>
+ * This control provides a group containing a text control.
+ */
+public class HistogramCurrentTimeControl extends HistogramTextControl {
+
+    // ------------------------------------------------------------------------
+    // Construction
+    // ------------------------------------------------------------------------
+
+    public HistogramCurrentTimeControl(HistogramView parentView, Composite parent, int textStyle, int groupStyle) {
+        this(parentView, parent, textStyle, groupStyle, "", HistogramUtils.nanosecondsToString(0L)); //$NON-NLS-1$
+    }
+
+    public HistogramCurrentTimeControl(HistogramView parentView, Composite parent, int textStyle, int groupStyle, String groupValue, String textValue) {
+        super(parentView, parent, textStyle, groupStyle, groupValue, textValue);
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    @Override
+    protected void updateValue() {
+        String stringValue = fTextValue.getText();
+        long value = HistogramUtils.stringToNanoseconds(stringValue);
+
+        if (getValue() != value) {
+            setValue(value);
+            fParentView.updateCurrentEventTime(value);
+        }
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramDataModel.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramDataModel.java
new file mode 100644 (file)
index 0000000..5c70e3d
--- /dev/null
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import java.util.Arrays;
+
+import org.eclipse.linuxtools.lttng.exceptions.EventOutOfSequenceException;
+import org.eclipse.linuxtools.lttng.ui.LTTngUILogger;
+import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramScaledData;
+
+/**
+ * <b><u>HistogramDataModel</u></b>
+ * <p>
+ * Histogram-independent data model with the following characteristics:
+ * <ul>
+ * <li>The <i>basetime</i> is the timestamp of the first event
+ * <li>There is a fixed number (<i>n</i>) of buckets of uniform duration
+ * (<i>d</i>)
+ * <li>The <i>timespan</i> of the model is thus: <i>n</i> * <i>d</i> time units
+ * <li>Bucket <i>i</i> holds the number of events that occurred in time range:
+ * [<i>basetime</i> + <i>i</i> * <i>d</i>, <i>basetime</i> + (<i>i</i> + 1) *
+ * <i>d</i>)
+ * </ul>
+ * Initially, the bucket durations is set to 1ns. As the events are read, they
+ * are tallied (using <i>countEvent()</i>) in the appropriate bucket (relative
+ * to the <i>basetime</i>).
+ * <p>
+ * Eventually, an event will have a timestamp that exceeds the <i>timespan</i>
+ * high end (determined by <i>n</i>, the number of buckets, and <i>d</i>, the
+ * bucket duration). At this point, the histogram needs to be compacted. This is
+ * done by simply merging adjacent buckets by pair, in effect doubling the
+ * <i>timespan</i> (<i>timespan'</i> = <i>n</i> * <i>d'</i>, where <i>d'</i> =
+ * 2<i>d</i>). This compaction happens as needed as the trace is read.
+ * <p>
+ * The mapping from the model to the UI is performed by the <i>scaleTo()</i>
+ * method. By keeping the number of buckets <i>n</i> relatively large with
+ * respect to to the number of pixels in the actual histogram, we should achieve
+ * a nice result when visualizing the histogram.
+ * <p>
+ * TODO: Add filter support for more refined event counting (e.g. by trace,
+ * event type, etc.)
+ * <p>
+ * TODO: Cut-off eccentric values?
+ * TODO: Support for going back in time?
+ */
+public class HistogramDataModel {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    // The default number of buckets
+    public static final int DEFAULT_NUMBER_OF_BUCKETS = 16 * 1000;
+
+//    // The ratio where an eccentric value will be truncated
+//    private static final int MAX_TO_AVERAGE_CUTOFF_RATIO = 5;
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    // Bucket management
+    private final int fNbBuckets;
+    private final long[] fBuckets;
+    private long fBucketDuration;
+    private long fNbEvents;
+    private int fLastBucket;
+
+    // Timestamps
+    private long fFirstEventTime;
+    private long fLastEventTime;
+    private long fCurrentEventTime;
+    private long fTimeLimit;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    public HistogramDataModel() {
+        this(DEFAULT_NUMBER_OF_BUCKETS);
+    }
+
+    public HistogramDataModel(int nbBuckets) {
+        fNbBuckets = nbBuckets;
+        fBuckets = new long[nbBuckets];
+        clear();
+    }
+
+    public HistogramDataModel(HistogramDataModel other) {
+        fNbBuckets = other.fNbBuckets;
+        fBuckets = Arrays.copyOf(other.fBuckets, fNbBuckets);
+        fBucketDuration = other.fBucketDuration;
+        fNbEvents = other.fNbEvents;
+        fLastBucket = other.fLastBucket;
+        fFirstEventTime = other.fFirstEventTime;
+        fLastEventTime = other.fLastEventTime;
+        fCurrentEventTime = other.fCurrentEventTime;
+        fTimeLimit = other.fTimeLimit;
+    }
+
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
+    public long getNbEvents() {
+        return fNbEvents;
+    }
+
+    public int getNbBuckets() {
+        return fNbBuckets;
+    }
+
+    public long getBucketDuration() {
+        return fBucketDuration;
+    }
+
+    public long getStartTime() {
+        return fFirstEventTime;
+    }
+
+    public long getEndTime() {
+        return fLastEventTime;
+    }
+
+    public long getCurrentEventTime() {
+        return fCurrentEventTime;
+    }
+
+    public long getTimeLimit() {
+        return fTimeLimit;
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Clear the histogram model.
+     */
+    public void clear() {
+        Arrays.fill(fBuckets, 0);
+        fNbEvents = 0;
+        fFirstEventTime = 0;
+        fLastEventTime = 0;
+        fCurrentEventTime = 0;
+        fLastBucket = 0;
+        fBucketDuration = 1; // 1ns
+        updateEndTime();
+    }
+
+    /**
+     * Sets the current event time
+     * 
+     * @param timestamp
+     */
+    public void setCurrentEvent(long timestamp) {
+        fCurrentEventTime = timestamp;
+    }
+
+    /**
+     * Add event to the correct bucket, compacting the if needed.
+     * 
+     * @param timestamp the timestamp of the event to count
+     */
+    public void countEvent(long timestamp) {
+        // Set the start/end time if not already done
+        if (fLastBucket == 0 && fBuckets[0] == 0 && timestamp > 0) {
+            fFirstEventTime = timestamp;
+            updateEndTime();
+        }
+        if (fLastEventTime < timestamp) {
+            fLastEventTime = timestamp;
+        }
+
+        // Compact as needed
+        while (timestamp >= fTimeLimit) {
+            mergeBuckets();
+        }
+
+        // Validate
+        if (timestamp < fFirstEventTime) {
+            String message = "Out of order timestamp. Going back in time?"; //$NON-NLS-1$
+            EventOutOfSequenceException exception = new EventOutOfSequenceException(message);
+            LTTngUILogger.logError(message, exception);
+            return;
+        }
+
+        // Increment the right bucket
+        int index = (int) ((timestamp - fFirstEventTime) / fBucketDuration);
+        fBuckets[index]++;
+        fNbEvents++;
+        if (fLastBucket < index)
+            fLastBucket = index;
+    }
+
+    /**
+     * Scale the model data to the width and height requested.
+     * 
+     * @param width
+     * @param height
+     * @return the result array of size [width] and where the highest value
+     *         doesn't exceed [height]
+     */
+    public HistogramScaledData scaleTo(int width, int height) {
+        // Basic validation
+        assert width > 0 && height > 0;
+
+        // The result structure
+        HistogramScaledData result = new HistogramScaledData(width, height);
+
+        // Scale horizontally
+        int bucketsPerBar = fLastBucket / width + 1;
+        result.fBucketDuration = bucketsPerBar * fBucketDuration;
+        for (int i = 0; i < width; i++) {
+            int count = 0;
+            for (int j = i * bucketsPerBar; j < (i + 1) * bucketsPerBar; j++) {
+                if (fNbBuckets <= j)
+                    break;
+                count += fBuckets[j];
+            }
+            result.fData[i] = count;
+            result.fLastBucket = i;
+            if (result.fMaxValue < count)
+                result.fMaxValue = count;
+        }
+
+        // Scale vertically
+        if (result.fMaxValue > 0) {
+            result.fScalingFactor = (double) height / result.fMaxValue;
+        }
+
+        // Set the current event index in the scaled histogram
+        if (fCurrentEventTime >= fFirstEventTime && fCurrentEventTime <= fLastEventTime)
+            result.fCurrentBucket = (int) ((fCurrentEventTime - fFirstEventTime) / fBucketDuration) / bucketsPerBar;
+        else
+            result.fCurrentBucket = HistogramScaledData.OUT_OF_RANGE_BUCKET;
+
+        return result;
+    }
+
+    // ------------------------------------------------------------------------
+    // Helper functions
+    // ------------------------------------------------------------------------
+
+    private void updateEndTime() {
+        fTimeLimit = fFirstEventTime + fNbBuckets * fBucketDuration;
+    }
+
+    private void mergeBuckets() {
+        for (int i = 0; i < fNbBuckets / 2; i++) {
+            fBuckets[i] = fBuckets[2 * i] + fBuckets[2 * i + 1];
+        }
+        Arrays.fill(fBuckets, fNbBuckets / 2, fNbBuckets, 0);
+        fBucketDuration *= 2;
+        updateEndTime();
+        fLastBucket = fNbBuckets / 2 - 1;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java
deleted file mode 100644 (file)
index eb907d4..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-/**
- * <b><u>HistogramElement</u></b>
- * <p>
- * This is used by the content to keep its data. 
- * It would be a struct if such a thing would exist in java. 
- * <p>
- * Each "element" should represent a certain time interval
- */
-public class HistogramElement {
-       public int index = 0;                                   // Position of the element in the table (table index, obviously)
-       public long firstIntervalTimestamp = 0L;        // The first timestamp recorded for this interval 
-       public long intervalNbEvents = 0L;                      // Number of events recorded in this interval
-       public int intervalHeight = 0;                  // Height (in the canvas) of this element. Should be smaller than the canvas height.
-}
index 8990950c5f4b204d76519680e52ace0ef5cae0bc..7375f99a885639b7cb57e289078d05826dd560f8 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009 Ericsson
+ * Copyright (c) 2009, 2011 Ericsson
  * 
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -8,10 +8,10 @@
  * 
  * Contributors:
  *   William Bourque - Initial API and implementation
- *
- * Modifications:
- * 2010-07-16 Yuriy Vashchuk - Heritage correction.
+ *   Yuriy Vashchuk - Heritage correction.
+ *   Francois Chouinard - Cleanup and refactoring
  *******************************************************************************/
+
 package org.eclipse.linuxtools.lttng.ui.views.histogram;
 
 import org.eclipse.linuxtools.lttng.LttngConstants;
@@ -23,246 +23,51 @@ import org.eclipse.linuxtools.tmf.request.TmfEventRequest;
 /**
  * <b><u>HistogramRequest</u></b>
  * <p>
- * Request class, to perform a request to TMF for the histograms.
- * <p>
  */
 public class HistogramRequest extends TmfEventRequest<LttngEvent> {
-/*     
-       private HistogramContent histogramContent = null;
-*/     
-       
-       private int     lastInterval = 0;
-       private long    lastRangeTime = 0L;
-       private long    nbEventsInInterval = 0L;
-       
-       private int     nbIntervalNotEmpty = 1;
-       private int     nbEventRead = 0;
-       
-       private int     lastDrawPosition = 0;
-       
-       private HistogramCanvas parentCanvas = null;
-       
-       private boolean isCompleted = false;
-       
-       /**
-        * Constructor for HistogramRequest.<p>
-        * Prepare the request in TMF and reset the histogram content.
-        * 
-        * @param range                         Range of the request.
-        * @param nbRequested           Nb events requested. Can be "Infinity" for all.
-        * @param newParentCanvas       HistogramCanvas related to the request.
-        * @param timeInterval          Time interval to consider (i.e. : 1 interval is 1 bar in the histogram)
-        * 
-        * @see org.eclipse.linuxtools.tmf.request.TmfEventRequest
-        */
-       public HistogramRequest(TmfTimeRange range, int nbRequested, HistogramCanvas newParentCanvas, long timeInterval, ITmfDataRequest.ExecutionType execType) {
-        super((Class<LttngEvent>)LttngEvent.class, range, nbRequested, LttngConstants.DEFAULT_BLOCK_SIZE, execType);
-        
-       setIsCompleted(false);
-        
-        // *** FIXME ***
-        // This does not work! The request won't be processed or the number of events returned is wrong!
-        // We cannot use this !
-               //super((Class<LttngEvent>)dataType, range);
-        
-        parentCanvas = newParentCanvas;
-        
-        // Reset the content of the HistogramContent... the given data better be valid or this will fail.
-        parentCanvas.getHistogramContent().clearContentData();
-        parentCanvas.getHistogramContent().resetTable(range.getStartTime().getValue(), range.getEndTime().getValue(), timeInterval);
-        
-        lastRangeTime = range.getStartTime().getValue();
-        
-        // Notify the UI even before the request started, so we set the timestamp already.
-        parentCanvas.notifyParentUpdatedInformationAsynchronously();
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    private final Histogram fHistogram;
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    public HistogramRequest(Histogram histogram, TmfTimeRange range, int nbEvents, ITmfDataRequest.ExecutionType execType) {
+        super(LttngEvent.class, range, nbEvents, LttngConstants.DEFAULT_BLOCK_SIZE, execType);
+        fHistogram = histogram;
+    }
+
+    public HistogramRequest(Histogram histogram, TmfTimeRange range, ITmfDataRequest.ExecutionType execType) {
+        this(histogram, range, ALL_DATA, execType);
     }
-       
-       /**
-        * HandleData function : will be called by TMF each time a new event is receive for the request.<p>
-        * Calculation for the content is done here.
-        */
-//     @Override
-//    public void handleData() {
-//        LttngEvent[] result = getData();
-//        LttngEvent event = (result.length > 0) ? result[0] : null;
-        
-       @Override
-    public void handleData(LttngEvent event) {
-               super.handleData(event);
 
-        // *** FIXME ***
-       // *** EVIL BUG ***
-        // The request by timerange only does not work! (see constructor above) 
-       //      However, the request with number of events will loop until it reach its number or EOF
-       //  We have to filter out ourself the extra useless events!
-       //
+    // ------------------------------------------------------------------------
+    // TmfEventRequest
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void handleData(LttngEvent event) {
+        super.handleData(event);
         if (event != null) {
-        
-//                     Tracer.trace("Hst: " + event.getTimestamp());
-               
-               // This check is linked to the evil fix mentionned above
-               if ( ( event.getTimestamp().getValue() >= parentCanvas.getHistogramContent().getStartTime() ) &&
-                        ( event.getTimestamp().getValue() <= parentCanvas.getHistogramContent().getEndTime() ) )
-               {
-                       
-                       // Distance (in time) between this event and the last one we read
-                       long distance = ( event.getTimestamp().getValue() - lastRangeTime );
-                               
-                       // Check if we changed of interval (the distance is higher than the interval time)
-                               if  ( distance > parentCanvas.getHistogramContent().getElementsTimeInterval() ) {
-                                       
-                                       parentCanvas.getHistogramContent().getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
-                                       lastRangeTime = event.getTimestamp().getValue();
-                                       
-                                       // * NOTE *
-                                       // We can skip several interval at once, so we need to find what was our interval now
-                                       lastInterval = (int)((lastRangeTime - parentCanvas.getHistogramContent().getStartTime()) / parentCanvas.getHistogramContent().getElementsTimeInterval() );
-                                       
-                                       // *** HACK ***
-                                       // Because of the threads, weird phenomenons seem to happen here, like a position after the 
-                                       //       element range because another request was issued.
-                                       // This enforce the position but may result in slightly inconsistent result (i.e. a weird misplaced bar sometime).
-                                       if ( lastInterval < 0 ) {
-                                               lastInterval = 0;
-                                       }
-                                       else if ( lastInterval >= parentCanvas.getHistogramContent().getNbElement() ) {
-                                               lastInterval = (parentCanvas.getHistogramContent().getNbElement()-1);
-                                       }
-                                       
-                                       // * NOTE * 
-                                       // We save the time we have here. This mean only the FIRST time read in an interval will be saved. 
-                                       parentCanvas.getHistogramContent().getElementByIndex(lastInterval).firstIntervalTimestamp = lastRangeTime;
-                                       parentCanvas.getHistogramContent().setReadyUpToPosition(lastInterval);
-                                       
-                                       nbIntervalNotEmpty++;
-                                       nbEventsInInterval = 1L;
-                               }
-                               // We are still in the same interval, just keep counting
-                               else {
-                                       nbEventsInInterval++;
-                               }
-                               
-                               if ( nbEventsInInterval > parentCanvas.getHistogramContent().getHeighestEventCount() ) {
-                                       parentCanvas.getHistogramContent().setHeighestEventCount(nbEventsInInterval);
-                               }
-                               nbEventRead++;
-                               
-                               // Call an asynchronous redraw every REDRAW_EVERY_NB_EVENTS events
-                               // That way we don't need to wait until to end to have something on the screen
-                               if ( nbEventRead % HistogramConstant.REDRAW_EVERY_NB_EVENTS == 0 ) {
-                                       redrawAsyncronously();
-                               }
-               }
-               }
-        // We got a null event! This mean we reach the end of the request. 
-        // Save the last interval we had, so we won't miss the very last events at the end. 
-        else {
-               // Save the last events
-               parentCanvas.getHistogramContent().getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
-               // We reached the end of the request, so assume we fill up the content as well
-               parentCanvas.getHistogramContent().setReadyUpToPosition(parentCanvas.getHistogramContent().getNbElement());
-                       
-                       // If the interval wasn't null, count this as a "non empty" interval
-                       if (nbEventsInInterval > 0) {
-                               nbIntervalNotEmpty++;
-                       }
+            long timestamp = event.getTimestamp().getValue();
+            fHistogram.countEvent(timestamp);
         }
     }
-       
-       /**
-        * Function that is called when the request completed (successful or not).<p>
-        * Update information and redraw the screen.
-        */
+
     @Override
     public void handleCompleted() {
-       setIsCompleted(true);
-       parentCanvas.notifyParentUpdatedInformationAsynchronously();
-               redrawAsyncronously();
-               super.handleCompleted();
-//             System.out.println(System.currentTimeMillis() + ": HistogramView (" + ((getExecType() == ExecutionType.LONG) ? "long" : "short") + ") completed");
+        fHistogram.refresh();
+        super.handleCompleted();
     }
-    
-//    /**
-//      * Function that is called when the request completed successfully.<p>
-//      */
-//    @Override
-//    public void handleSuccess() {
-//     // Nothing different from completed.
-//    }
-    
-//    /**
-//      * Function that is called when the request completed in failure.<p>
-//      */
-//    @Override
-//    public void handleFailure() {
-//     // Nothing different from cancel.
-//    }
-    
-    /**
-        * Function that is called when the request was cancelled.<p>
-        * Redraw and set the requestCompleted flag to true;
-        */
+
     @Override
     public void handleCancel() {
-       redrawAsyncronously();
-               super.handleCancel();
-    }
-       
-    /**
-        * Update the HistogramContent with the latest information.<p>
-        * This will perform some calculation that might be a bit harsh so it should'nt be called too often.
-        */
-    public void updateEventsInfo() {
-       // *** Note *** 
-       // The average number of event is calculated while skipping empty interval if asked
-       int averageNumberOfEvents = 0;
-       if ( HistogramConstant.SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE ) {
-               averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)nbIntervalNotEmpty);
-       }
-       else {
-               averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)parentCanvas.getHistogramContent().getNbElement());
-       }
-       
-       parentCanvas.getHistogramContent().setAverageNumberOfEvents(averageNumberOfEvents);
-       
-       // It is possible that the height factor didn't change; 
-       //              If not, we only need to redraw the updated section, no the whole content
-       // Save the actual height, recalculate the height and check if there was any changes
-       double previousHeightFactor = parentCanvas.getHistogramContent().getHeightFactor();
-       parentCanvas.getHistogramContent().recalculateHeightFactor();
-       if ( parentCanvas.getHistogramContent().getHeightFactor() != previousHeightFactor ) {
-               parentCanvas.getHistogramContent().recalculateEventHeight();
-       }
-       else {
-               parentCanvas.getHistogramContent().recalculateEventHeightInInterval(lastDrawPosition, parentCanvas.getHistogramContent().getReadyUpToPosition());
-       }
-       
-       lastDrawPosition = parentCanvas.getHistogramContent().getReadyUpToPosition();
+        fHistogram.refresh();
+        super.handleCancel();
     }
-    
-    /**
-        * Perform an asynchonous redraw of the screen.
-        */
-    public void redrawAsyncronously() {
-       updateEventsInfo();
-       // Canvas redraw is already asynchronous
-       parentCanvas.redrawAsynchronously();
-    }
-
-       /**
-        * Getter for isCompleted variable
-        * @return true if the request is completed
-        */
-       public boolean getIsCompleted() {
-               return isCompleted;
-       }
 
-       /**
-        * Setter for isCompleted variable
-        * @param isCompleted value to set the completed flag
-        */
-       public void setIsCompleted(boolean isCompleted) {
-               this.isCompleted = isCompleted;
-       }
-    
 }
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramScaledData.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramScaledData.java
new file mode 100644 (file)
index 0000000..8260b4f
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import java.util.Arrays;
+
+/**
+ * <b><u>HistogramScaledData</u></b>
+ * <p>
+ * Convenience class/struct for scaled histogram data.
+ */
+public class HistogramScaledData {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    public static final int OUT_OF_RANGE_BUCKET = -1;
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    public int fWidth;
+    public int fHeight;
+    public int[] fData;
+    public long fBucketDuration;
+    public long fMaxValue;
+    public int fCurrentBucket;
+    public int fLastBucket;
+    public double fScalingFactor;
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    public HistogramScaledData(int width, int height) {
+        fWidth = width;
+        fHeight = height;
+        fData = new int[width];
+        Arrays.fill(fData, 0);
+        fBucketDuration = 1;
+        fMaxValue = 0;
+        fCurrentBucket = 0;
+        fLastBucket = 0;
+        fScalingFactor = 1;
+    }
+
+    public HistogramScaledData(HistogramScaledData other) {
+        fWidth = other.fWidth;
+        fHeight = other.fHeight;
+        fData = Arrays.copyOf(other.fData, fWidth);
+        fBucketDuration = other.fBucketDuration;
+        fMaxValue = other.fMaxValue;
+        fCurrentBucket = other.fCurrentBucket;
+        fLastBucket = other.fLastBucket;
+        fScalingFactor = other.fScalingFactor;
+    }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java
deleted file mode 100644 (file)
index cd8abad..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *
- * Modifications:
- * 2010-07-16 Yuriy Vashchuk - Heritage correction and selection window
- *                                                        optimisations.
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-/**
- * <b><u>HistogramSelectedWindow</u></b>
- * <p>
- * Selection window represent the selected section of the trace in the HistogramCanvas.
- * <p>
- * The selected window have 3 important attributes : 
- * <ul>
- * <li>Its central position
- * <li>Its time width
- * <li>Its visibility (to determine if we should draw it or not)
- * </ul>
- * The dimension are then deduced from the first 2 values.
- * This mean the window is always a perfectly symetrical rectangle.
- */
-public class HistogramSelectedWindow {
-       
-       private long timestampOfLeftPosition = 0;
-       private long timestampOfCenterPosition = 0;
-       private long timestampOfRightPosition = 0;
-       private long windowTimeWidth = 0L;
-       private int windowXPositionLeft = 0; 
-       private int windowXPositionCenter = 0; 
-       private int windowXPositionRight = 0; 
-       private Boolean isSelectedWindowVisible = false;
-       
-       /**
-        * Default constructor for HistogramSelectedWindow.<p>
-        * Position and TimeWidth are set to given value.
-        * 
-        * @param newTraceContent       HistogramContent to read window's data from
-        * @param centralPosition       Central X Position of the selection window in the canvas (0 to canvasWidth)
-        * @param newWindowWidth        Time width (size) of the window. (0 or greater)
-        */
-       public HistogramSelectedWindow(HistogramContent newTraceContent, long timestampOfLeftPosition, long newWindowWidth) {
-               if(newTraceContent != null) {
-                       setWindowTimeWidth(newWindowWidth);
-                       setTimestampOfLeftPosition(timestampOfLeftPosition);
-                       setTimestampOfRightPosition(timestampOfLeftPosition + newWindowWidth);
-                       setTimestampOfCenterPosition(timestampOfLeftPosition + newWindowWidth / 2);
-               }
-       }
-       
-       /**
-        * Getter for the window visibility.<p>
-        * 
-        * @return true if the window is visible (will be draw), false otherwise
-        */
-       public boolean getSelectedWindowVisible() {
-               return isSelectedWindowVisible;
-       }
-       
-       /**
-        * Setter for the window visibility.<p>
-        * True means the window will be draw, false that it will be hidden.
-        * 
-        * @param newIsSelectedWindowVisible    The visibility value
-        */
-       public void setSelectedWindowVisible(Boolean newIsSelectedWindowVisible) {
-               this.isSelectedWindowVisible = newIsSelectedWindowVisible;
-       }
-       
-       
-       /**
-        * Getter for the window time width (size)
-        * 
-        * @return Window time width (size)
-        */
-       public long getWindowTimeWidth() {
-               return windowTimeWidth;
-       }
-       
-       /**
-        * Setter for the window time width (size).<p>
-        * Width need to be a time (in nanoseconds) that's coherent to the data we are looking at.
-        * 
-        * @param newWindowTimeWidth    The new time width
-        */
-       public void setWindowTimeWidth(long newWindowTimeWidth) {
-               this.windowTimeWidth = newWindowTimeWidth;
-       }
-       
-       /**
-        * Getter for the timestamp of left border of the window.<p>
-        * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong.  
-        * 
-        * @return  The left timestamp of the window, or 0 if it cannot compute it. 
-        */
-       public long getTimestampOfLeftPosition() {
-               return timestampOfLeftPosition;
-       }
-       
-       /**
-        * Setter for the timestamp of left border of the window.<p>
-        * @param  timestampOfLeftPosition The left timestamp of the window. 
-        */
-       public void setTimestampOfLeftPosition(long timestampOfLeftPosition) {
-               this.timestampOfLeftPosition = timestampOfLeftPosition;
-       }               
-       
-       /**
-        * Getter for the timestamp of the center of the window.<p>
-        * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong.  
-        * 
-        * @return  The center timestamp of the window, or 0 if it cannot compute it. 
-        */
-       public long getTimestampOfCenterPosition() {
-               return timestampOfCenterPosition;
-       }
-
-       /**
-        * Setter for the timestamp of center border of the window.<p>
-        */
-       public void setTimestampOfCenterPosition(long timestampOfCenterPosition) {
-               this.timestampOfCenterPosition = timestampOfCenterPosition;
-       }
-       
-       /**
-        * Setter for the timestamp of center border of the window.<p>
-        */
-       public void setTimestampOfLeftCenterRightPositions(long timestampOfCenterPosition) {
-               this.timestampOfLeftPosition = timestampOfCenterPosition - windowTimeWidth / 2;
-               this.timestampOfCenterPosition = timestampOfCenterPosition;
-               this.timestampOfRightPosition = timestampOfCenterPosition + windowTimeWidth / 2;
-       }               
-       
-       /**
-        * Getter for the timestamp of right border of the window.<p>
-        * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong.  
-        * 
-        * @return  The right timestamp of the window, or 0 if it cannot compute it. 
-        */
-       public long getTimestampOfRightPosition() {
-               return timestampOfRightPosition;
-       }
-       
-       /**
-        * Setter for the timestamp of right border of the window.<p>
-        * @param  timestampOfRightPosition The right timestamp of the window. 
-        */
-       public void setTimestampOfRightPosition(long timestampOfRightPosition) {
-               this.timestampOfRightPosition = timestampOfRightPosition;
-       }
-
-       /**
-        * Getter for the coordinate of left border of the window.<p>
-        * 
-        * @return  The left coordinate. 
-        */
-       public int getWindowXPositionLeft() {
-               return windowXPositionLeft;
-       }
-
-       /**
-        * Setter for the coordinate of left border of the window.<p>
-        * @param  windowXPositionLeft The left coordinate of the window. 
-        */
-       public void setWindowXPositionLeft(int windowXPositionLeft) {
-               this.windowXPositionLeft = windowXPositionLeft;
-       }
-
-       /**
-        * Getter for the coordinate of center border of the window.<p>
-        * 
-        * @return  The center coordinate. 
-        */
-       public int getWindowXPositionCenter() {
-               return windowXPositionCenter;
-       }
-
-       /**
-        * Setter for the coordinate of center of the window.<p>
-        * @param  windowXPositionCenter The center coordinate of the window. 
-        */
-       public void setWindowXPositionCenter(int windowXPositionCenter) {
-               this.windowXPositionCenter = windowXPositionCenter;
-       }
-
-       /**
-        * Getter for the coordinate of right border of the window.<p>
-        * 
-        * @return  The right coordinate. 
-        */
-       public int getWindowXPositionRight() {
-               return windowXPositionRight;
-       }
-
-       /**
-        * Setter for the coordinate of right border of the window.<p>
-        * @param  windowXPositionRight The right coordinate of the window. 
-        */
-       public void setWindowXPositionRight(int windowXPositionRight) {
-               this.windowXPositionRight = windowXPositionRight;
-       }
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramTextControl.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramTextControl.java
new file mode 100644 (file)
index 0000000..009fa29
--- /dev/null
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2011 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:
+ *   Wiliam Bourque - Adapted from SpinnerGroup (in TimeFrameView)
+ *   Francois Chouinard - Cleanup and refactoring
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * <b><u>HistogramTextControl</u></b>
+ * <p>
+ * This control provides a group containing a text control.
+ */
+public abstract class HistogramTextControl implements FocusListener, KeyListener {
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    protected final HistogramView fParentView;
+    private final Composite fParent;
+
+    // Controls
+    private final Group fGroup;
+    protected final Text fTextValue;
+    private long fValue;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    public HistogramTextControl(HistogramView parentView, Composite parent, int textStyle, int groupStyle) {
+        this(parentView, parent, textStyle, groupStyle, "", HistogramUtils.nanosecondsToString(0L)); //$NON-NLS-1$
+    }
+
+    public HistogramTextControl(HistogramView parentView, Composite parent, int textStyle, int groupStyle, String groupValue, String textValue) {
+
+        fParentView = parentView;
+        fParent = parent;
+
+        // --------------------------------------------------------------------
+        // Reduce font size for a more pleasing rendering
+        // --------------------------------------------------------------------
+
+        final int fontSizeAdjustment = -1;
+        final Font font = parent.getFont();
+        final FontData fontData = font.getFontData()[0];
+        final Font adjustedFont = new Font(font.getDevice(), fontData.getName(), fontData.getHeight() + fontSizeAdjustment, fontData.getStyle());
+
+        // --------------------------------------------------------------------
+        // Pre-compute the size of the control
+        // --------------------------------------------------------------------
+
+        final String longestStringValue = "." + Long.MAX_VALUE; //$NON-NLS-1$
+        final int maxChars = longestStringValue.length();
+        final int textBoxSize = HistogramUtils.getTextSizeInControl(parent, longestStringValue);
+
+        // --------------------------------------------------------------------
+        // Create the group
+        // --------------------------------------------------------------------
+
+        // Re-used layout variables
+        GridLayout gridLayout;
+        GridData gridData;
+
+        // Group control
+        gridLayout = new GridLayout(1, false);
+        gridLayout.horizontalSpacing = 0;
+        gridLayout.verticalSpacing = 0;
+        fGroup = new Group(fParent, groupStyle);
+        fGroup.setText(groupValue);
+        fGroup.setFont(adjustedFont);
+        fGroup.setLayout(gridLayout);
+
+        // Group control
+        gridData = new GridData(SWT.LEFT, SWT.CENTER, true, false);
+        gridData.horizontalIndent = 0;
+        gridData.verticalIndent = 0;
+        gridData.minimumWidth = textBoxSize;
+        fTextValue = new Text(fGroup, textStyle);
+        fTextValue.setTextLimit(maxChars);
+        fTextValue.setText(textValue);
+        fTextValue.setFont(adjustedFont);
+        fTextValue.setLayoutData(gridData);
+
+        // --------------------------------------------------------------------
+        // Add listeners
+        // --------------------------------------------------------------------
+
+        fTextValue.addFocusListener(this);
+        fTextValue.addKeyListener(this);
+    }
+
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
+    // State
+    public boolean isDisposed() {
+        return fGroup.isDisposed();
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    protected abstract void updateValue();
+
+    // LayoutData
+    public void setLayoutData(GridData layoutData) {
+        fGroup.setLayoutData(layoutData);
+    }
+
+    // Time value
+    public void setValue(String timeString) {
+        long timeValue = HistogramUtils.stringToNanoseconds(timeString);
+        setValue(timeValue);
+    }
+
+    public void setValue(final long time) {
+        // If this is the UI thread, process now
+        Display display = Display.getCurrent();
+        if (display != null) {
+            fValue = time;
+            fTextValue.setText(HistogramUtils.nanosecondsToString(time));
+            return;
+        }
+
+        // Call "recursively" from the UI thread
+        if (!isDisposed()) {
+            Display.getDefault().asyncExec(new Runnable() {
+                @Override
+                public void run() {
+                    if (!isDisposed()) {
+                        setValue(time);
+                    }
+                }
+            });
+        }
+    }
+
+    public long getValue() {
+        return fValue;
+    }
+
+    // ------------------------------------------------------------------------
+    // FocusListener
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void focusGained(FocusEvent event) {
+    }
+
+    @Override
+    public void focusLost(FocusEvent event) {
+        updateValue();
+    }
+
+    // ------------------------------------------------------------------------
+    // KeyListener
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void keyPressed(KeyEvent event) {
+        switch (event.keyCode) {
+            case SWT.CR:
+                updateValue();
+                break;
+            default:
+                break;
+        }
+    }
+
+    @Override
+    public void keyReleased(KeyEvent e) {
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramTimeRangeControl.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramTimeRangeControl.java
new file mode 100644 (file)
index 0000000..b12c25d
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * <b><u>HistogramTimeRangeControl</u></b>
+ * <p>
+ * This control provides a group containing a text control.
+ */
+public class HistogramTimeRangeControl extends HistogramTextControl {
+
+    // ------------------------------------------------------------------------
+    // Construction
+    // ------------------------------------------------------------------------
+
+    public HistogramTimeRangeControl(HistogramView parentView, Composite parent, int textStyle, int groupStyle) {
+        this(parentView, parent, textStyle, groupStyle, "", HistogramUtils.nanosecondsToString(0L)); //$NON-NLS-1$
+    }
+
+    public HistogramTimeRangeControl(HistogramView parentView, Composite parent, int textStyle, int groupStyle, String groupValue, String textValue) {
+        super(parentView, parent, textStyle, groupStyle, groupValue, textValue);
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    @Override
+    protected void updateValue() {
+        String stringValue = fTextValue.getText();
+        long value = HistogramUtils.stringToNanoseconds(stringValue);
+
+        if (getValue() != value) {
+            fParentView.updateTimeRange(value);
+        }
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramUtils.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramUtils.java
new file mode 100644 (file)
index 0000000..a5b9d53
--- /dev/null
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2011 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:
+ *   William Bourque - Initial API and implementation
+ *   Francois Chouinard - Cleanup and refactoring
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * <b><u>HistogramUtils</u></b>
+ * <p>
+ * Bunch of conversion utilities.
+ * <p>
+ */
+public abstract class HistogramUtils {
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Format a long representing nanoseconds into a string of the form
+     * "[seconds].[nanoseconds]" with the appropriate zero-padding.
+     * <p>
+     * 
+     * @param ns the timestamp in nanoseconds
+     * @return the formatted string
+     */
+    public static String nanosecondsToString(long ns) {
+        ns = Math.abs(ns);
+        String time = Long.toString(ns);
+
+        int length = time.length();
+        if (time.length() > 9) {
+            // Just insert the decimal dot
+            time = time.substring(0, length - 9) + "." + time.substring(length - 9); //$NON-NLS-1$
+            return time;
+        }
+
+        // Zero-pad the value
+        for (int i = length; i < 9; i++) {
+            time = "0" + time; //$NON-NLS-1$
+        }
+        time = "0." + time; //$NON-NLS-1$
+        return time;
+    }
+
+    /**
+     * Convert a string representing a time to the corresponding long.
+     * <p>
+     * 
+     * @param time the string to convert
+     * @return the corresponding nanoseconds value
+     */
+    public static long stringToNanoseconds(String time) {
+
+        long result = 0L;
+        StringBuffer buffer = new StringBuffer(time);
+
+        try {
+            int dot = buffer.indexOf("."); //$NON-NLS-1$
+
+            // Prepend a "." if none was found (assume ns)
+            if (dot == -1) {
+                buffer.insert(0, "."); //$NON-NLS-1$
+                dot = 0;
+            }
+
+            // Zero-pad the string for nanoseconds
+            for (int i = buffer.length() - dot - 1; i < 9; i++)
+                buffer.append("0"); //$NON-NLS-1$
+
+            // Remove the extra decimals if present
+            int nbDecimals = buffer.substring(dot + 1).length();
+            if (nbDecimals > 9)
+                buffer.delete(buffer.substring(0, dot + 1 + 9).length(), buffer.length());
+
+            // Do the conversion
+            long seconds = (dot > 0) ? Long.parseLong(buffer.substring(0, dot)) : 0;
+            seconds = Math.abs(seconds);
+            long nanosecs = Long.parseLong(buffer.substring(dot + 1));
+            result = seconds * 1000000000 + nanosecs;
+
+        } catch (NumberFormatException e) {
+            // TODO: Find something interesting to say
+        }
+
+        return result;
+    }
+
+    /**
+     * Calculate the width of a String.
+     * <p>
+     * 
+     * @param parent The control used as reference
+     * @param text The Text to measure
+     * 
+     * @return The result size
+     */
+    public static int getTextSizeInControl(Composite parent, String text) {
+
+        GC controlGC = new GC(parent);
+
+        int textSize = 0;
+        for (int pos = 0; pos < text.length(); pos++) {
+            textSize += controlGC.getAdvanceWidth(text.charAt(pos));
+        }
+        // Add an extra space
+        textSize += controlGC.getAdvanceWidth(' ');
+
+        controlGC.dispose();
+
+        return textSize;
+    }
+
+}
index 7d30f4c832287fefacee0c1df58ba614ddaaa4fd..9bbb86f3484ed52c8fb220ebe53012db3bfeb627 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009 Ericsson
+ * Copyright (c) 2009, 2010, 2011 Ericsson
  * 
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
  * 
  * Contributors:
  *   William Bourque - Initial API and implementation
- * 
- * Modifications:
- * 2010-06-10 Yuriy Vashchuk - GUI reorganisation, simplification and some
- *                             related code improvements.
- * 2010-06-20 Yuriy Vashchuk - Histograms optimisation.   
- * 2010-07-16 Yuriy Vashchuk - Histogram Canvas Heritage correction
+ *   Yuriy Vashchuk - GUI reorganisation, simplification and some related code improvements.
+ *   Yuriy Vashchuk - Histograms optimisation.   
+ *   Yuriy Vashchuk - Histogram Canvas Heritage correction
+ *   Francois Chouinard - Cleanup and refactoring
  *******************************************************************************/
 
 package org.eclipse.linuxtools.lttng.ui.views.histogram;
 
 import org.eclipse.linuxtools.lttng.event.LttngEvent;
-import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
 import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
 import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
-import org.eclipse.linuxtools.tmf.request.ITmfDataRequest;
 import org.eclipse.linuxtools.tmf.request.ITmfDataRequest.ExecutionType;
 import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal;
 import org.eclipse.linuxtools.tmf.signal.TmfRangeSynchSignal;
 import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.signal.TmfSignalManager;
 import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;
 import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
 import org.eclipse.linuxtools.tmf.ui.views.TmfView;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
 
 /**
  * <b><u>HistogramView</u></b>
  * <p>
- * View that contain an visual approach to the window that control the request.
- * This is intended to replace the TimeFrameView
+ * The purpose of this view is to provide graphical time distribution statistics
+ * about the experiment/trace events.
  * <p>
- * This view is composed of 2 canvas, one for the whole experiment and one for the selected window in the experiment.
- * It also contain a certain number of controls to print or change informations about the experiment.
+ * The view is composed of two histograms and two controls:
+ * <ul>
+ * <li>an event distribution histogram for the whole experiment;
+ * <li>an event distribution histogram for current time window (window span);
+ * <li>the timestamp of the currently selected event;
+ * <li>the window span (size of the time window of the smaller histogram).
+ * </ul>
+ * The histograms x-axis show their respective time range.
  */
-public class HistogramView extends TmfView implements ControlListener {
-       
-       // *** TODO ***
-       // Here is what's left to do in this view
-       //
-       // 1- Make sure the interval time is small enough on very big trace (bug 311930)
-       //              The interval time of the content is dynamically assigned from the screen width and trace duration.
-       //              However, on very big trace (more than 1 hour), we could end up with time interval that are > 1 seconds,
-       //                      which is not very precise. 
-       //              An algorithm need to be implemented to make sure we "increase" the number of interval in the content if
-       //                      their precision is getting too bad. 
-       //
-       // 2- Make sure all control are thread safe (bug 309348)
-       //              Right now, all the basic controls (i.e. Text and Label) are sensible to "Thread Access Exception" if
-       //                      updated from different threads; we need to carefully decide when/where to redraw them.
-       //              This is a real problem since there is a lot of thread going on in this view.
-       //              All basic control should be subclassed to offer "Asynchronous" functions.
-       //
-       // 3- Implement a "preferences view" for the HistogramView (bug 311935)
-       //              There is a lot of adjustable preferences in the view, however there is no way to adjust them right now
-       //                      at run time. There should be a view of some kind of "menu" to allow the user to change them while executing.
-       //              Most of the pertinent values are in HistogramConstant.java or in this file.
-       
+public class HistogramView extends TmfView {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    // The view ID as defined in plugin.xml
     public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.histogram"; //$NON-NLS-1$
-    
-    // "Minimum" screen width size. On smaller screen, we will apply several space saving technique
-    private static final int SCREEN_SMALL_IF_SMALLER_THAN = 1600;
-    
-/*
-    // 2010-06-20 Yuriy: We will use the dynamic height.
-    // Size of the "full trace" canvas
-    private static final int FULL_TRACE_CANVAS_HEIGHT = 25;
-*/    
-    private static final int FULL_TRACE_BAR_WIDTH = 1;
-    private static final double FULL_TRACE_DIFFERENCE_TO_AVERAGE = 1.5;
-    
-    // Size of the "Selected Window" canvas
-/*    
-    // 2010-06-20 Yuriy 
-    private static final int SELECTED_WINDOW_CANVAS_WIDTH = 300;
-    private static final int SMALL_SELECTED_WINDOW_CANVAS_WIDTH = 200;
-    private static final int SELECTED_WINDOW_CANVAS_HEIGHT = 60;
-*/    
-    private static final int SELECTED_WINDOW_BAR_WIDTH = 1;
-    private static final double SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE = 10.0;
-    
-    // For the two "events" label (Max and Min number of events in the selection), we force a width
-    // This will prevent the control from moving horizontally if the number of events in the selection varies
-    private static final int NB_EVENTS_FIXED_WIDTH = 50;
-    
-    // The "small font" height used to display time will be "default font" minus this constant
-    private static final int SMALL_FONT_MODIFIER = 2;
-    private static final int VERY_SMALL_FONT_MODIFIER = 4;
-    
-    // *** TODO ***
-    // This need to be changed as soon the framework implement a "window"
-//    private static long DEFAULT_WINDOW_SIZE = (10L * 100 * 1000 * 1000); // 1sec
-    private static long DEFAULT_WINDOW_SIZE = (1L * 100 * 1000 * 1000); // .1sec
-    
-    // The last experiment received/used by the view
-    private TmfExperiment<LttngEvent> lastUsedExperiment = null;
-    
-    // Parent of the view
-    private Composite parent = null;
-    
-    // Request and canvas for the "full trace" part
-    private HistogramRequest dataBackgroundFullRequest = null;
-    private static ParentHistogramCanvas fullExperimentCanvas = null;
-    
-    // Request and canvas for the "selected window"
-       private HistogramRequest selectedWindowRequest = null;
-    private static ChildrenHistogramCanvas selectedWindowCanvas = null;
-    
-    // Content of the timeTextGroup
-    // Since the user can modify them with erroneous value, 
-    // we will keep track of the value internally 
-       private long currentEventTime = 0L;
-       
-    // *** All the UI control below
-       //
-       // NOTE : All textboxes will be READ_ONLY.
-       //                      So the user will be able to select/copy the value in them but not to change it
-       private Text txtExperimentStartTime = null;
-       private Text txtExperimentStopTime = null;
-       
-       private Text  txtWindowStartTime = null;
-       private Text  txtWindowStopTime  = null;
-       private Text  txtWindowMaxNbEvents = null;
-       private Text  txtWindowMinNbEvents = null;
-    
-       // We move the time label to header from TimeTextGroup.java
-       private static final String WINDOW_TIMESPAN_LABEL_TEXT    = Messages.HistogramView_windowSpanLabel;
-       private static final String WINDOW_CENTER_TIME_LABEL_TEXT = Messages.HistogramView_windowCenterLabel;
-       private static final String CURRENT_EVENT_TIME_LABEL_TEXT = Messages.HistogramView_currentEventLabel;
-       private TimeTextGroup  ntgWindowTimeSpan = null;
-       private TimeTextGroup  ntgWindowCenterTime = null;
-       private TimeTextGroup  ntgCurrentEventTime = null;
-       
-       /**
-        * Default constructor of the view
-        */
-       public HistogramView() {
-               super(ID);
-       }
-       
-       /**
-        * Create the UI controls of this view
-        * 
-        * @param  parent       The composite parent of this view
-        */
-       @Override
-       public void createPartControl(Composite newParent) {
-               // Save the parent
-               parent = newParent;
-               
-               // Default font
-               Font font = parent.getFont();
-               FontData tmpFontData = font.getFontData()[0];
-               
-               
-               Font smallFont = null;
-               int  nbEventWidth = -1; 
-               int selectedCanvasWidth = -1;
-               boolean doesTimeTextGroupNeedAdjustment = false;
-               
-               // Calculate if we need "small screen" fixes
-               if ( parent.getDisplay().getBounds().width < SCREEN_SMALL_IF_SMALLER_THAN ) {
-                       
-                       // A lot smaller font for timestamp
-                       smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight() - VERY_SMALL_FONT_MODIFIER, tmpFontData.getStyle());
-                       
-/*                     
-                       // 2010-06-20 Yuriy
-                       // Smaller selection window canvas
-                       selectedCanvasWidth = SMALL_SELECTED_WINDOW_CANVAS_WIDTH;
-*/                     
-                       // Smaller event number text field
-                       nbEventWidth = NB_EVENTS_FIXED_WIDTH/2;
-                       
-                       // Tell the text group to ajust
-                       doesTimeTextGroupNeedAdjustment = true;
-
-               } else {
-                       
-                       // Slightly smaller font for timestamp
-                       smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight() - SMALL_FONT_MODIFIER, tmpFontData.getStyle());
-                       // Usual size for selected window and event number text field
-                       nbEventWidth = NB_EVENTS_FIXED_WIDTH;
-/*                     
-                       // 2010-06-20 Yuriy
-                       selectedCanvasWidth = SELECTED_WINDOW_CANVAS_WIDTH;
-*/                     
-                       // No ajustement needed by the text group
-                       doesTimeTextGroupNeedAdjustment = false;
-                       
-               }
-
-               
-               /////////////////////////////////////////////////////////////////////////////////////
-               // Layout for the whole view, other elements will be in a child composite of this one 
-               // Contains :
-               //              Composite layoutSelectionWindow
-               //              Composite layoutTimesSpinner
-               //              Composite layoutExperimentHistogram
-               /////////////////////////////////////////////////////////////////////////////////////
-               Composite layoutFullView = new Composite(parent, SWT.FILL);
-               GridLayout gridFullView = new GridLayout();
-               gridFullView.numColumns = 2;
-               gridFullView.horizontalSpacing = 0;
-               gridFullView.verticalSpacing = 0;
-               gridFullView.marginHeight = 0;
-               gridFullView.marginWidth = 0;
-               layoutFullView.setLayout(gridFullView);
-
-               
-               /////////////////////////////////////////////////////////////////////////////////////
-               // Layout that contain the time spinners
-               // Contains : 
-               //              NanosecTextGroup  ntgCurrentEventTime
-               //              NanosecTextGroup  ntgTimeRangeWindow
-               //              NanosecTextGroup  ntgCurrentWindowTime
-               /////////////////////////////////////////////////////////////////////////////////////
-               Composite layoutTimeSpinners = new Composite(layoutFullView, SWT.NONE);
-               GridLayout gridTimesSpinner = new GridLayout();
-               gridTimesSpinner.numColumns = 3;
-               gridTimesSpinner.marginHeight = 0;
-               gridTimesSpinner.marginWidth = 0;
-               gridTimesSpinner.horizontalSpacing = 5;
-               gridTimesSpinner.verticalSpacing = 0;
-               gridTimesSpinner.makeColumnsEqualWidth = true;
-               gridTimesSpinner.marginLeft = 5;
-               gridTimesSpinner.marginRight = 5;
-               layoutTimeSpinners.setLayout(gridTimesSpinner);
-               
-               GridData gridDataCurrentEvent = new GridData();
-               gridDataCurrentEvent.horizontalAlignment = SWT.LEFT;
-               gridDataCurrentEvent.verticalAlignment = SWT.CENTER;
-               ntgCurrentEventTime = new TimeTextGroup(this, layoutTimeSpinners, SWT.BORDER, SWT.BORDER, CURRENT_EVENT_TIME_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment);
-               ntgCurrentEventTime.setLayoutData(gridDataCurrentEvent);                
-               
-               GridData gridDataTimeSpan = new GridData();
-               gridDataTimeSpan.horizontalAlignment = SWT.CENTER;
-               gridDataTimeSpan.verticalAlignment = SWT.CENTER;
-               ntgWindowTimeSpan = new TimeTextGroup(this, layoutTimeSpinners, SWT.BORDER, SWT.BORDER, WINDOW_TIMESPAN_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment);
-               ntgWindowTimeSpan.setLayoutData(gridDataTimeSpan);
-                               
-               GridData gridDataWindowCenter = new GridData();
-               gridDataWindowCenter.horizontalAlignment = SWT.RIGHT;
-               gridDataWindowCenter.verticalAlignment = SWT.CENTER;    
-               ntgWindowCenterTime = new TimeTextGroup(this, layoutTimeSpinners, SWT.BORDER, SWT.BORDER, WINDOW_CENTER_TIME_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment);
-               ntgWindowCenterTime.setLayoutData(gridDataWindowCenter);
-               
-               
-               /////////////////////////////////////////////////////////////////////////////////////
-               // Layout that contain the SelectionWindow
-               // Contains : 
-               //              Label txtWindowStartTime
-               //              Label txtWindowStopTime
-               //              Label txtWindowMaxNbEvents
-               //              Label txtWindowMinNbEvents
-               //              ChildrenHistogramCanvas selectedWindowCanvas
-               /////////////////////////////////////////////////////////////////////////////////////
-               Composite layoutSelectionWindow = new Composite(layoutFullView, SWT.FILL);
-               GridLayout gridSelectionWindow = new GridLayout();
-               gridSelectionWindow.numColumns = 3;
-               gridSelectionWindow.marginHeight = 0;
-               gridSelectionWindow.marginWidth = 2;
-               gridSelectionWindow.marginTop = 5;
-               gridSelectionWindow.horizontalSpacing = 0;
-               gridSelectionWindow.verticalSpacing = 0;
-               layoutSelectionWindow.setLayout(gridSelectionWindow);
-               
-               GridData gridDataSelectionWindow = new GridData();
-               gridDataSelectionWindow.horizontalAlignment = SWT.FILL;
-               gridDataSelectionWindow.verticalAlignment = SWT.FILL;   
-               layoutSelectionWindow.setLayoutData(gridDataSelectionWindow);
-               
-               GridData gridDataSelectionWindowCanvas = new GridData();
-               gridDataSelectionWindowCanvas.horizontalSpan = 2;
-               gridDataSelectionWindowCanvas.verticalSpan = 2;
-               gridDataSelectionWindowCanvas.horizontalAlignment = SWT.FILL;
-               gridDataSelectionWindowCanvas.grabExcessHorizontalSpace = true;
-               gridDataSelectionWindowCanvas.verticalAlignment = SWT.FILL;
-/*
-               // 2010-06-20 Yuriy 
-               gridDataSelectionWindowCanvas.heightHint = SELECTED_WINDOW_CANVAS_HEIGHT;
-               gridDataSelectionWindowCanvas.minimumHeight = SELECTED_WINDOW_CANVAS_HEIGHT;
-*/             
-               gridDataSelectionWindowCanvas.widthHint = selectedCanvasWidth;
-               gridDataSelectionWindowCanvas.minimumWidth = selectedCanvasWidth;
-               selectedWindowCanvas = new ChildrenHistogramCanvas(this, layoutSelectionWindow, SWT.BORDER);
-               selectedWindowCanvas.setLayoutData(gridDataSelectionWindowCanvas);
-               
-               GridData gridDataWindowMaxEvents = new GridData();
-               gridDataWindowMaxEvents.horizontalAlignment = SWT.RIGHT;
-               gridDataWindowMaxEvents.verticalAlignment = SWT.TOP;
-               // Force a width, to avoid the control to enlarge if the number of events change
-               gridDataWindowMaxEvents.minimumWidth = nbEventWidth;
-               txtWindowMaxNbEvents = new Text(layoutSelectionWindow, SWT.READ_ONLY);
-               txtWindowMaxNbEvents.setFont(smallFont);
-               txtWindowMaxNbEvents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
-               txtWindowMaxNbEvents.setEditable(false);
-               txtWindowMaxNbEvents.setText("0"); //$NON-NLS-1$
-               txtWindowMaxNbEvents.setLayoutData(gridDataWindowMaxEvents);
-               
-               GridData gridDataWindowMinEvents = new GridData();
-               gridDataWindowMinEvents.horizontalAlignment = SWT.RIGHT;
-               gridDataWindowMinEvents.verticalAlignment = SWT.BOTTOM;
-               // Force a width, to avoid the control to enlarge if the number of events change
-               gridDataWindowMinEvents.minimumWidth = nbEventWidth;
-               txtWindowMinNbEvents = new Text(layoutSelectionWindow, SWT.READ_ONLY);
-               txtWindowMinNbEvents.setFont(smallFont);
-               txtWindowMinNbEvents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
-               txtWindowMinNbEvents.setEditable(false);
-               txtWindowMinNbEvents.setText("0"); //$NON-NLS-1$
-               txtWindowMinNbEvents.setLayoutData(gridDataWindowMinEvents);
-               
-               GridData gridDataWindowStart = new GridData();
-               gridDataWindowStart.horizontalAlignment = SWT.LEFT;
-               gridDataWindowStart.verticalAlignment = SWT.BOTTOM;
-               txtWindowStartTime = new Text(layoutSelectionWindow, SWT.READ_ONLY);
-               txtWindowStartTime.setFont(smallFont);
-               txtWindowStartTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
-               txtWindowStartTime.setEditable(false);
-               txtWindowStartTime.setText("0.000000000");  //$NON-NLS-1$
-               txtWindowStartTime.setLayoutData(gridDataWindowStart);
-               
-               GridData gridDataWindowStop = new GridData();
-               gridDataWindowStop.horizontalAlignment = SWT.RIGHT;
-               gridDataWindowStop.verticalAlignment = SWT.BOTTOM;
-               txtWindowStopTime = new Text(layoutSelectionWindow, SWT.READ_ONLY);
-               txtWindowStopTime.setFont(smallFont);
-               txtWindowStopTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
-               txtWindowStopTime.setEditable(false);
-               txtWindowStopTime.setText("0.000000000"); //$NON-NLS-1$
-               txtWindowStopTime.setLayoutData(gridDataWindowStop);
-               
-
-/*
-               // 2010-06-10 Yuriy: NOT NEEDED AFTER GUI IMPROVEMENTS. WORK FINE WITOUT THIS HACK 
-               // *** HACK ***
-               // To align properly AND to make sure the canvas size is fixed, we NEED to make sure all "section" of the 
-               //              gridlayout are taken (and if possible of a fixed size).
-               // However, SWT is VERY VERY DUMB and won't consider griddata that contain no control. 
-               // Since there will be missing a section, the SelectedWindowCanvas + NbEventsText will take 3 spaces, but
-               //              startTimeText + stopTimeText will take only 2 (as if empty the other griddata of 1 will get ignored).
-               // StopTime will then take over the missing space; I want to align "stopTime" right on the end of canvas, so 
-               //              the added space to stop time would make it being aligned improperly
-               // So I NEED the empty griddata to be considered! 
-               // Visually : 
-               // |---------------|---------------|-----------|
-               // |SelectionCanvas SelectionCanvas|NbEventText|
-               // |SelectionCanvas SelectionCanvas|NbEventText|
-               // |---------------|---------------|-----------|
-               // |StartTime      |       StopTime|    ???    |
-               // |---------------|---------------|-----------|
-               //
-               // So since SWT will only consider griddata with control, 
-               //              I need to create a totally useless control in the ??? section.
-               // That's ugly, useless and it is generally a bad practice.
-               //
-               // *** SUB-HACK ***
-               // Other interesting fact about SWT : the way it draws (Fill/Expand control in grid) will change if 
-               //              the control is a Text or a Label. 
-               // A Label here will be "pushed" by startTime/stopTime Text and won't fill the full space as NbEventText.
-               // A Text  here will NOT be "pushed" and would give a nice visual output.
-               //              (NB : No, I am NOT kidding, try it for yourself!)
-               //
-               // Soooooo I guess I will use a Text here. Way to go SWT!
-               // Downside is that disabled textbox has a slightly different color (even if you force it yourself) so if I want
-               //              to make the text "invisible", I have to keep it enabled (but read only), so it can be clicked on.
-               //
-               // Label uselessControlToByPassSWTStupidBug = new Label(layoutSelectionWindow, SWT.BORDER); // WON'T align correctly!!!
-               //GridData gridDataSpacer = new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1);
-               GridData gridDataSpacer = new GridData();
-               gridDataWindowStop.horizontalAlignment = SWT.FILL;
-               gridDataWindowStop.verticalAlignment = SWT.TOP;
-               gridDataSpacer.minimumWidth = nbEventWidth;
-               Text uselessControlToByPassSWTStupidBug = new Text(layoutSelectionWindow, SWT.READ_ONLY); // WILL align correctly!!!
-               uselessControlToByPassSWTStupidBug.setEditable(false);
-               uselessControlToByPassSWTStupidBug.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
-               uselessControlToByPassSWTStupidBug.setLayoutData(gridDataSpacer);
-*/             
-               
-               
-               /////////////////////////////////////////////////////////////////////////////////////
-               // Layout that contain the complete experiment histogram and related controls.
-               // Contains : 
-               //              ParentHistogramCanvas fullExperimentCanvas
-               //              Text txtExperimentStartTime
-               //              Text txtExperimentStopTime
-               /////////////////////////////////////////////////////////////////////////////////////
-               Composite layoutExperimentHistogram = new Composite(layoutFullView, SWT.FILL);
-               
-               GridLayout gridExperimentHistogram = new GridLayout();
-               gridExperimentHistogram.numColumns = 2;
-               gridExperimentHistogram.marginHeight = 0;
-               gridExperimentHistogram.marginWidth = 0;
-               gridExperimentHistogram.horizontalSpacing = 0;
-               gridExperimentHistogram.verticalSpacing = 0;
-               gridExperimentHistogram.marginLeft = 5;
-               gridExperimentHistogram.marginRight = 5;
-               layoutExperimentHistogram.setLayout(gridExperimentHistogram);
-               
-/*
-               // 2010-06-10 Yuriy: NOT NEEDED AFTER GUI IMPROVEMENTS
-               GridData gridDataExperimentHistogram = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
-               layoutExperimentHistogram.setLayoutData(gridDataExperimentHistogram);
-*/
-               
-               // *** Everything related to the experiment canvas is below
-               GridData gridDataExperimentCanvas = new GridData();
-               gridDataExperimentCanvas.horizontalSpan = 2;
-               gridDataExperimentCanvas.horizontalAlignment = SWT.FILL;
-               gridDataExperimentCanvas.grabExcessHorizontalSpace = true;
-               gridDataExperimentCanvas.verticalAlignment = SWT.FILL;
-               gridDataExperimentCanvas.grabExcessVerticalSpace = true;
-/*             
-               // 2010-06-20 Yuriy: We use the dynamic height.
-               gridDataExperimentCanvas.heightHint = FULL_TRACE_CANVAS_HEIGHT;
-               gridDataExperimentCanvas.minimumHeight = FULL_TRACE_CANVAS_HEIGHT;
-*/             
-               fullExperimentCanvas = new ParentHistogramCanvas(this, layoutExperimentHistogram, SWT.BORDER);
-               fullExperimentCanvas.setLayoutData(gridDataExperimentCanvas);
-               layoutExperimentHistogram.setLayoutData(gridDataExperimentCanvas);
-               
-               GridData gridDataExperimentStart = new GridData();
-               gridDataExperimentStart.horizontalAlignment = SWT.LEFT;
-               gridDataExperimentStart.verticalAlignment = SWT.BOTTOM;
-               txtExperimentStartTime = new Text(layoutExperimentHistogram, SWT.READ_ONLY);
-               txtExperimentStartTime.setFont(smallFont);
-               txtExperimentStartTime.setText("0.000000000"); //$NON-NLS-1$
-               txtExperimentStartTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
-               txtExperimentStartTime.setEditable(false);
-               txtExperimentStartTime.setLayoutData(gridDataExperimentStart);
-               
-               GridData gridDataExperimentStop = new GridData();
-               gridDataExperimentStop.horizontalAlignment = SWT.RIGHT;
-               gridDataExperimentStop.verticalAlignment = SWT.BOTTOM;
-               txtExperimentStopTime = new Text(layoutExperimentHistogram, SWT.READ_ONLY);
-               txtExperimentStopTime.setFont(smallFont);
-               txtExperimentStopTime.setText("0.000000000"); //$NON-NLS-1$
-               txtExperimentStopTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
-               txtExperimentStopTime.setEditable(false);
-               txtExperimentStopTime.setLayoutData(gridDataExperimentStop);
-       }
-       
-       // *** FIXME ***
-       // This is mainly used because of a because in the "experimentSelected()" notification, we shouldn't need this
-       /**
-        * Method called when the view receive the focus.<p>
-        * If ExperimentSelected didn't send us a request yet, get the current Experiment and fire requests
-        */
-       @SuppressWarnings("unchecked")
-       @Override
-       public void setFocus() {
-               // WARNING : This does not seem to be thread safe
-               TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)TmfExperiment.getCurrentExperiment();
-               
-               if ( (dataBackgroundFullRequest == null) && (tmpExperiment != null) ) {
-                       createCanvasAndRequests(tmpExperiment);
-               }
-               
-               // Call a redraw for everything
-               parent.redraw();
-       }
-       
-       /**
-        * Method called when the user select (double-click on) an experiment.<p>
-        * We will create the needed canvas and fire the requests.
-        * 
-        * @param signal        Signal received from the framework. Contain the experiment.
-        */
+
+    // The initial window span (in nanoseconds)
+    public static long INITIAL_WINDOW_SPAN = (1L * 100 * 1000 * 1000); // .1sec
+
+    // Time scale
+    private final byte TIME_SCALE = Histogram.TIME_SCALE;
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    // Parent widget
+    private Composite fParent;
+
+    // The current experiment
+    private TmfExperiment<LttngEvent> fCurrentExperiment;
+
+    // Current timestamp/time window
+    private long fExperimentStartTime;
+    private long fExperimentEndTime;
+    private long fWindowStartTime;
+    private long fWindowEndTime;
+    private long fWindowSpan = INITIAL_WINDOW_SPAN;
+    private long fCurrentTimestamp;
+
+    // Time controls
+    private HistogramTextControl fCurrentEventTimeControl;
+    private HistogramTextControl fTimeSpanControl;
+
+    // Histogram/request for the full trace range
+    private static FullTraceHistogram fFullTraceHistogram;
+    private HistogramRequest fFullTraceRequest;
+
+    // Histogram/request for the selected time range
+    private static TimeRangeHistogram fTimeRangeHistogram;
+    private HistogramRequest fTimeRangeRequest;
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    public HistogramView() {
+        super(ID);
+    }
+
+    public void dispose() {
+       fFullTraceHistogram.dispose();
+       fTimeRangeHistogram.dispose();
+    }
+
+    // ------------------------------------------------------------------------
+    // TmfView
+    // ------------------------------------------------------------------------
+
+    @Override
     @SuppressWarnings("unchecked")
-       @TmfSignalHandler
-    public void experimentSelected(TmfExperimentSelectedSignal<LttngEvent> signal) {
-       TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)signal.getExperiment();
-       createCanvasAndRequests(tmpExperiment);
+    public void createPartControl(Composite parent) {
+
+        fParent = parent;
+
+        // Control labels
+        final String currentEventLabel = Messages.HistogramView_currentEventLabel;
+        final String windowSpanLabel = Messages.HistogramView_windowSpanLabel;
+
+        // --------------------------------------------------------------------
+        // Set the HistogramView layout
+        // --------------------------------------------------------------------
+
+        Composite viewComposite = new Composite(fParent, SWT.FILL);
+        GridLayout gridLayout = new GridLayout();
+        gridLayout.numColumns = 2;
+        gridLayout.horizontalSpacing = 5;
+        gridLayout.verticalSpacing = 0;
+        gridLayout.marginHeight = 0;
+        gridLayout.marginWidth = 0;
+        viewComposite.setLayout(gridLayout);
+
+        // Use all available space
+        GridData gridData = new GridData();
+        gridData.horizontalAlignment = SWT.FILL;
+        gridData.verticalAlignment = SWT.FILL;
+        gridData.grabExcessHorizontalSpace = true;
+        viewComposite.setLayoutData(gridData);
+
+        // --------------------------------------------------------------------
+        // Time controls
+        // --------------------------------------------------------------------
+
+        Composite controlsComposite = new Composite(viewComposite, SWT.FILL);
+        gridLayout = new GridLayout();
+        gridLayout.numColumns = 2;
+        gridLayout.marginHeight = 0;
+        gridLayout.marginWidth = 0;
+        gridLayout.horizontalSpacing = 5;
+        gridLayout.verticalSpacing = 0;
+        gridLayout.makeColumnsEqualWidth = true;
+        gridLayout.marginLeft = 5;
+        gridLayout.marginRight = 5;
+        controlsComposite.setLayout(gridLayout);
+
+        // Current event time control
+        gridData = new GridData();
+        gridData.horizontalAlignment = SWT.CENTER;
+        gridData.verticalAlignment = SWT.CENTER;
+        fCurrentEventTimeControl = new HistogramCurrentTimeControl(this, controlsComposite, SWT.BORDER, SWT.BORDER, currentEventLabel,
+                HistogramUtils.nanosecondsToString(0L));
+        fCurrentEventTimeControl.setLayoutData(gridData);
+
+        // Window span time control
+        gridData = new GridData();
+        gridData.horizontalAlignment = SWT.CENTER;
+        gridData.verticalAlignment = SWT.CENTER;
+        fTimeSpanControl = new HistogramTimeRangeControl(this, controlsComposite, SWT.BORDER, SWT.BORDER, windowSpanLabel,
+                HistogramUtils.nanosecondsToString(0L));
+        fTimeSpanControl.setLayoutData(gridData);
+
+        // --------------------------------------------------------------------
+        // Time range histogram
+        // --------------------------------------------------------------------
+
+        Composite timeRangeComposite = new Composite(viewComposite, SWT.FILL);
+        gridLayout = new GridLayout();
+        gridLayout.numColumns = 1;
+        gridLayout.marginHeight = 0;
+        gridLayout.marginWidth = 0;
+        gridLayout.marginTop = 5;
+        gridLayout.horizontalSpacing = 0;
+        gridLayout.verticalSpacing = 0;
+        gridLayout.marginLeft = 5;
+        gridLayout.marginRight = 5;
+        timeRangeComposite.setLayout(gridLayout);
+
+        // Use remaining horizontal space
+        gridData = new GridData();
+        gridData.horizontalAlignment = SWT.FILL;
+        gridData.verticalAlignment = SWT.FILL;
+        gridData.grabExcessHorizontalSpace = true;
+        timeRangeComposite.setLayoutData(gridData);
+
+        // Histogram
+        fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite);
+
+        // --------------------------------------------------------------------
+        // Full range histogram
+        // --------------------------------------------------------------------
+
+        Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL);
+        gridLayout = new GridLayout();
+        gridLayout.numColumns = 1;
+        gridLayout.marginHeight = 0;
+        gridLayout.marginWidth = 0;
+        gridLayout.marginTop = 5;
+        gridLayout.horizontalSpacing = 0;
+        gridLayout.verticalSpacing = 0;
+        gridLayout.marginLeft = 5;
+        gridLayout.marginRight = 5;
+        fullRangeComposite.setLayout(gridLayout);
+
+        // Use remaining horizontal space
+        gridData = new GridData();
+        gridData.horizontalAlignment = SWT.FILL;
+        gridData.verticalAlignment = SWT.FILL;
+        gridData.horizontalSpan = 2;
+        gridData.grabExcessHorizontalSpace = true;
+        fullRangeComposite.setLayoutData(gridData);
+
+        // Histogram
+        fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite);
+
+        // Load the experiment if present
+        fCurrentExperiment = (TmfExperiment<LttngEvent>) TmfExperiment.getCurrentExperiment();
+        if (fCurrentExperiment != null)
+            loadExperiment();
     }
-    
-
-    // *** VERIFY ***
-       // Not sure what this should do since I don't know when it will be called
-       // Let's do the same thing as experimentSelected for now
-       //
-    /**
-        * Method called when an experiment is updated (??).<p>
-        * ...for now, do nothing, as udating an experiment running in the background might cause crash 
-        * 
-        * @param signal        Signal received from the framework. Contain the experiment.
-        */
-/*
+
+    @Override
     @SuppressWarnings("unchecked")
-       @TmfSignalHandler
-    public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
-                       
-               TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)signal.getExperiment();
-                       
-               // Make sure the UI object are sane
-               resetControlsContent();
-                               
-               // Redraw the canvas right away to have something "clean" as soon as we can
-               fullExperimentCanvas.redraw();
-               selectedWindowCanvas.redraw();
-               
-               // Recreate the request
-               createCanvasAndRequests(tmpExperiment);
+    public void setFocus() {
+        TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) TmfExperiment.getCurrentExperiment();
+        if ((experiment != null) && (experiment != fCurrentExperiment)) {
+            fCurrentExperiment = experiment;
+            initializeHistograms();
+        }
+        fParent.redraw();
     }
-*/
-    
-    /**
-     * Method called when synchronization is active and that the user select an event.
-     * We update the current event timeTextGroup and move the selected window if needed.
-     * 
-     * @param signal   Signal received from the framework. Contain the event.
-     */
-    @TmfSignalHandler
-    public void currentTimeUpdated(TmfTimeSynchSignal signal) {
-       // In case we received our own signal
-       if ( (signal != null) && (signal.getSource() != this) ) {
-            TmfTimestamp currentTime = signal.getCurrentTime();
-            
-            // Update the current event controls
-            currentEventTime = currentTime.getValue();
-            updateSelectedEventTime();
+
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
+    public TmfTimeRange getTimeRange() {
+        return new TmfTimeRange(new TmfTimestamp(fWindowStartTime, TIME_SCALE), new TmfTimestamp(fWindowEndTime, TIME_SCALE));
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    public void updateCurrentEventTime(long newTime) {
+        if (fCurrentExperiment != null) {
+            TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(newTime, TIME_SCALE), TmfTimestamp.BigCrunch);
+            HistogramRequest request = new HistogramRequest(fTimeRangeHistogram, timeRange, 1, ExecutionType.FOREGROUND) {
+                @Override
+                public void handleData(LttngEvent event) {
+                    if (event != null) {
+                        TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, event.getTimestamp());
+                        TmfSignalManager.dispatchSignal(signal);
+                    }
+                }
+            };
+            fCurrentExperiment.sendRequest(request);
+        }
+    }
+
+    public void updateTimeRange(long startTime, long endTime) {
+        if (fCurrentExperiment != null) {
+            // Build the new time range; keep the current time
+            TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(startTime, TIME_SCALE), new TmfTimestamp(endTime, TIME_SCALE));
+            TmfTimestamp currentTime = new TmfTimestamp(fCurrentTimestamp, TIME_SCALE);
             
-            // If the given event is outside the selection window, recenter the window
-            if ( isGivenTimestampInSelectedWindow( currentEventTime ) == false) {
-                fullExperimentCanvas.setWindowCenterPosition(currentEventTime);
-
-               // Notify control that the window changed
-               windowChangedNotification();
-               // Send a broadcast to the framework about the window change
-                       sendTmfRangeSynchSignalBroadcast();
-            }
-       }
+            fTimeSpanControl.setValue(endTime - startTime);
+
+            // Send the FW signal
+            TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange, currentTime);
+            TmfSignalManager.dispatchSignal(signal);
+        }
+    }
+
+    public synchronized void updateTimeRange(long newDuration) {
+        if (fCurrentExperiment != null) {
+               long delta = newDuration - fWindowSpan;
+               long newStartTime = fWindowStartTime + delta / 2;
+               setNewRange(newStartTime, newDuration);
+        }
+    }
+
+    private void setNewRange(long startTime, long duration) {
+        if (startTime < fExperimentStartTime)
+               startTime = fExperimentStartTime;
+
+        long endTime = startTime + duration;
+        if (endTime > fExperimentEndTime) {
+               endTime = fExperimentEndTime;
+               if (endTime - duration > fExperimentStartTime)
+                       startTime = endTime - duration;
+               else {
+                       startTime = fExperimentStartTime;
+               }
+        }
+        updateTimeRange(startTime, endTime);
     }
-    
+
+    // ------------------------------------------------------------------------
+    // Signal handlers
+    // ------------------------------------------------------------------------
+
     @TmfSignalHandler
-       public void synchToTimeRange(TmfRangeSynchSignal signal) {
-        if ( (signal != null) ) {
-                       if ( lastUsedExperiment != null ) {
-                               long currentTime                = signal.getCurrentTime().getValue();
-                               long windowStart                = signal.getCurrentRange().getStartTime().getValue();
-                               long windowEnd                  = signal.getCurrentRange().getEndTime().getValue();
-                               long windowTimeWidth    = (windowEnd - windowStart); 
-                               
-                               // Recenter the window
-                               fullExperimentCanvas.setSelectedWindowSize(windowTimeWidth);
-                               fullExperimentCanvas.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(windowStart + (windowTimeWidth/2)) );
-                               
-                               // *** HACK ***
-                               // Views could send us incorrect current event value (event outside the current window)
-                               // Here we make sure the value is sane, otherwise, we force it as the left border of the window
-                               if ( isGivenTimestampInSelectedWindow( currentTime ) == false ) {
-                                       currentTime = windowStart;
-                               }
-                               currentEventTime = currentTime;
-                               
-                               // Notify control that the window changed
-               windowChangedNotification();
-               
-               // Make sure we redraw the change
-               fullExperimentCanvas.redraw();
-                       }
-               }
-       }
-    
-    
-    /*
-     * Create the canvas needed and issue the requests
-     * 
-     * @param newExperiment    Experiment we will use for the request
-     */
-    private void createCanvasAndRequests(TmfExperiment<LttngEvent> newExperiment) {
-       // Save the experiment we are about to use
-       lastUsedExperiment = newExperiment;
-       
-//     // Create a copy of the trace that will be use only by the full experiment request
-//     TmfExperiment<LttngEvent> experimentCopy = newExperiment.createTraceCopy();
-       
-       // Create the content for the full experiment. 
-       // This NEED to be created first, as we use it in the selectedWindowCanvas
-               fullExperimentCanvas.createNewHistogramContent(
-                       fullExperimentCanvas.getSize().x,
-                       FULL_TRACE_BAR_WIDTH,
-/*
-                       // 2010-06-20 Yuriy: We will use the dynamic height.
-                       FULL_TRACE_CANVAS_HEIGHT
-*/
-                       fullExperimentCanvas.getSize().y / 2,
-                       FULL_TRACE_DIFFERENCE_TO_AVERAGE
-               );
-
-               TmfTimeRange timeRange = getExperimentTimeRange(newExperiment);
-
-               // We will take the half of the full experiment length in case of bigger window size than the full experiment length
-               if(timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() >  DEFAULT_WINDOW_SIZE ) {
-                       fullExperimentCanvas.createNewSelectedWindow(
-                                       timeRange.getStartTime().getValue(),
-                                       DEFAULT_WINDOW_SIZE
-                                       );
-               } else {
-                       fullExperimentCanvas.createNewSelectedWindow(
-                                       timeRange.getStartTime().getValue(),
-                                       (timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() ) / 2
-                                       );
-               }
-
-               currentEventTime = timeRange.getStartTime().getValue();
-
-               // Set the window of the fullTrace canvas visible.
-               fullExperimentCanvas.getCurrentWindow().setSelectedWindowVisible(true);
-               fullExperimentCanvas.getHistogramContent().resetTable(timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue());
-
-               // Create the content for the selected window. 
-               selectedWindowCanvas.createNewHistogramContent(
-                               selectedWindowCanvas.getSize().x,
-                               SELECTED_WINDOW_BAR_WIDTH,
-                               selectedWindowCanvas.getSize().y,
-                               SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE
-                               );
-               selectedWindowCanvas.getHistogramContent().resetTable(fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition(), fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition());
-               
-       // Make sure the UI object are sane
-               resetControlsContent();
-               
-               // Redraw the canvas right away to have something "clean" as soon as we can
-       if ( dataBackgroundFullRequest != null ) {
-               fullExperimentCanvas.redraw();
-               selectedWindowCanvas.redraw();
-       }
-       // Nullify the (possible) old request to be sure we start we something clean
-       // Note : this is very important for the order of the request below, 
-       //      see "TODO" in performSelectedWindowEventsRequest
-       dataBackgroundFullRequest = null;
-       selectedWindowRequest = null;
-               
-               // Perform both request. 
-               // Order is important here, the small/synchronous request for the selection window should go first
-               performSelectedWindowEventsRequest(newExperiment);
-               performAllTraceEventsRequest(newExperiment);
+    @SuppressWarnings("unchecked")
+    public void experimentSelected(TmfExperimentSelectedSignal<LttngEvent> signal) {
+        assert (signal != null);
+        fCurrentExperiment = (TmfExperiment<LttngEvent>) signal.getExperiment();
+        loadExperiment();
     }
 
-       // Before completing its indexing, the experiment doesn't know start/end time.
-       // However, LTTng individual traces have this knowledge so we should ask them
-       // directly.
-    private TmfTimeRange getExperimentTimeRange(TmfExperiment<LttngEvent> experiment) {
-       // Before completing its indexing, the experiment doesn't know start/end time.
-       // However, LTTng individual traces have this knowledge so we should ask them
-       // directly.
-               TmfTimestamp startTime = TmfTimestamp.BigCrunch;
-               TmfTimestamp endTime   = TmfTimestamp.BigBang;
-               for (ITmfTrace trace : experiment.getTraces()) {
-          TmfTimestamp traceStartTime = trace.getStartTime();
-                       if (traceStartTime.compareTo(startTime, true) < 0)
-                               startTime = traceStartTime;
-                       TmfTimestamp traceEndTime = trace.getEndTime();
-                       if (traceEndTime.compareTo(endTime, true) > 0)
-                               endTime = traceEndTime;
-       }
-        TmfTimeRange tmpRange = new TmfTimeRange(startTime, endTime);
-        return tmpRange;
+    private void loadExperiment() {
+        fExperimentStartTime = fCurrentExperiment.getStartTime().getValue();
+        fExperimentEndTime = fCurrentExperiment.getEndTime().getValue();
+        fCurrentTimestamp = fExperimentStartTime;
+        initializeHistograms();
+        fParent.redraw();
     }
 
-    /**
-     * Perform a new request for the Selection window.<p>
-     * This assume the full experiment canvas has correct information about the selected window; 
-     *                 we need the fullExperimentCanvas' HistogramContent to be created and a selection window to be set.
-     * 
-     * @param experiment       The experiment we will select from
-     */
-    public void performSelectedWindowEventsRequest(TmfExperiment<LttngEvent> experiment) {
-       
-       if(fullExperimentCanvas != null) {
-               HistogramSelectedWindow curSelectedWindow = fullExperimentCanvas.getCurrentWindow();
-               
-               TmfTimeRange timeRange = getExperimentTimeRange(experiment);
-               
-               // If no selection window exists, we will try to create one; 
-               //      however this will most likely fail as the content is probably not created either
-               if ( curSelectedWindow == null ) {
-                       // We will take the half of the full experiment length in case of bigger window size than the full experiment length
-                       if(timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() >  DEFAULT_WINDOW_SIZE ) {
-                               fullExperimentCanvas.createNewSelectedWindow(
-                                               timeRange.getStartTime().getValue(),
-                                               DEFAULT_WINDOW_SIZE
-                                               );
-                       } else {
-                               fullExperimentCanvas.createNewSelectedWindow(
-                                               timeRange.getStartTime().getValue(),
-                                               (timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() ) / 2
-                                               );
-                       }
-                       curSelectedWindow = fullExperimentCanvas.getCurrentWindow();
-               }
-               
-               // The request will go from the Left timestamp of the window to the Right timestamp
-               // This assume that out-of-bound value are handled by the SelectionWindow itself
-                       LttngTimestamp ts1 = new LttngTimestamp( curSelectedWindow.getTimestampOfLeftPosition() );
-                       LttngTimestamp ts2 = new LttngTimestamp( curSelectedWindow.getTimestampOfRightPosition() );
-               TmfTimeRange tmpRange = new TmfTimeRange(ts1, ts2);
-               
-               // Set a (dynamic) time interval
-               long intervalTime = ( (ts2.getValue() - ts1.getValue()) / selectedWindowCanvas.getHistogramContent().getNbElement() );
-               
-                       selectedWindowRequest = performRequest(experiment, selectedWindowCanvas, tmpRange, intervalTime, ExecutionType.FOREGROUND);
-               selectedWindowCanvas.redrawAsynchronously();
-       }
-       
+//    @TmfSignalHandler
+//    @SuppressWarnings("unchecked")
+//    public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
+//        fCurrentExperiment = (TmfExperiment<LttngEvent>) signal.getExperiment();
+//        fFullRangeHistogramCanvas.redraw();
+//        fTimespanHistogramCanvas.redraw();
+//        createCanvasAndRequests();
+//    }
+
+    @TmfSignalHandler
+    public void currentTimeUpdated(TmfTimeSynchSignal signal) {
+        // Because this can't happen :-)
+        assert (signal != null);
+
+        // Update the selected event time
+        TmfTimestamp currentTime = signal.getCurrentTime();
+        fCurrentTimestamp = currentTime.getValue();
+
+        // Notify the relevant widgets
+        fFullTraceHistogram.setCurrentEvent(fCurrentTimestamp);
+        fTimeRangeHistogram.setCurrentEvent(fCurrentTimestamp);
+        fCurrentEventTimeControl.setValue(fCurrentTimestamp);
     }
-    
-    /**
-     * Perform a new request for the full experiment.<p>
-     * NOTE : this is very long, we need to implement a way to run this in parallel (see TODO)
-     * 
-     * @param experiment       The experiment we will select from
-     */
-    public void performAllTraceEventsRequest(TmfExperiment<LttngEvent> experiment) {
-       // Create a new time range from "start" to "end"
-        //     That way, we will get "everything" in the trace
-//        LttngTimestamp ts1 = new LttngTimestamp( experiment.getStartTime() );
-//        LttngTimestamp ts2 = new LttngTimestamp( experiment.getEndTime() );
-//        TmfTimeRange tmpRange = new TmfTimeRange(ts1, ts2);
-       
-        TmfTimeRange tmpRange  = getExperimentTimeRange(experiment);
-               TmfTimestamp startTime = tmpRange.getStartTime();
-               TmfTimestamp endTime   = tmpRange.getEndTime();
-        
-        // Set a (dynamic) time interval
-        long intervalTime = ( (endTime.getValue() - startTime.getValue()) / fullExperimentCanvas.getHistogramContent().getNbElement() );
-        
-        // *** VERIFY ***
-        // This would enable "fixed interval" instead of dynamic one.
-        // ... we don't need it, do we?
-        //
-        // long intervalTime = ((long)(0.001 * (double)1000000000));
-        
-        // *** TODO ***
-        // It would be interesting if there was a way to tell the framework to run the request "in parallel" here.
-        // Mean a completetly independant copy of the Expereiment would be done and we would proceed on that.
-        //
-        dataBackgroundFullRequest = performRequest(experiment, fullExperimentCanvas, tmpRange, intervalTime, ExecutionType.BACKGROUND);
-        
-               
-        fullExperimentCanvas.getCurrentWindow().setWindowXPositionLeft(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition()));
-        fullExperimentCanvas.getCurrentWindow().setWindowXPositionCenter(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition()));
-        fullExperimentCanvas.getCurrentWindow().setWindowXPositionRight(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition()));
 
-        fullExperimentCanvas.redrawAsynchronously();
+    @TmfSignalHandler
+    public void timeRangeUpdated(TmfRangeSynchSignal signal) {
+        // Because this can't happen :-)
+        assert (signal != null);
+
+        if (fCurrentExperiment != null) {
+            // Update the time range
+            fWindowStartTime = signal.getCurrentRange().getStartTime().getValue();
+            fWindowEndTime = signal.getCurrentRange().getEndTime().getValue();
+            fWindowSpan = fWindowEndTime - fWindowStartTime;
+
+            // Notify the relevant widgets
+            sendTimeRangeRequest(fWindowStartTime, fWindowEndTime);
+            fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan);
+            fTimeSpanControl.setValue(fWindowSpan);
+        }
     }
-    
-    // *** VERIFY ***
-    // This function is synchronized, is it a good idea?
-    // Tis is done to make sure requests arrive somewhat in order, 
-    // this is especially important when request are issued from different thread.
-    /**
-     * Create a new request from the given data and send it to the framework.<p>
-     * The request will be queued and processed later.
-     * 
-     * @param experiment               The experiment we will process the request on
-     * @param targetCanvas             The canvas that will received the result
-     * @param newRange                 The range of the request
-     * @param newInterval              The interval of time we use to store the result into the HistogramContent
-     */
-    private synchronized HistogramRequest performRequest(TmfExperiment<LttngEvent> experiment, HistogramCanvas targetCanvas, TmfTimeRange newRange, long newInterval, ITmfDataRequest.ExecutionType execType) {
-       HistogramRequest returnedRequest = null;
-       
-        // *** FIXME ***
-        // EVIL BUG!
-           // We use int.MAX_VALUE because we want every events BUT we don't know the number inside the range.
-        // HOWEVER, this would cause the request to run forever (or until it reach the end of trace).
-        // Seeting an EndTime does not seems to stop the request
-        returnedRequest = new HistogramRequest(newRange, Integer.MAX_VALUE, targetCanvas, newInterval, execType );
+
+    // ------------------------------------------------------------------------
+    // Helper functions
+    // ------------------------------------------------------------------------
+
+    private void initializeHistograms() {
+        updateExperimentTimeRange(fCurrentExperiment);
+        fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
+        fTimeRangeHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
+        fTimeRangeHistogram.setCurrentEvent(fExperimentStartTime);
+
+        fFullTraceHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
+        fFullTraceHistogram.setCurrentEvent(fExperimentStartTime);
+
+        fWindowStartTime = fExperimentStartTime;
+        fWindowSpan = INITIAL_WINDOW_SPAN;
+        fWindowEndTime = fWindowStartTime + fWindowSpan;
         
-        // Send the request to the framework : it will be queued and processed later
-        experiment.sendRequest(returnedRequest);
+        fCurrentEventTimeControl.setValue(fExperimentStartTime);
+        fTimeSpanControl.setValue(fWindowSpan);
         
-        return returnedRequest;
+        sendTimeRangeRequest(fExperimentStartTime, fExperimentStartTime + fWindowSpan);
+        sendFullRangeRequest();
     }
-    
-    /**
-     * Function used to warn that the selection window changed.<p>
-     * This might be called because the window moved or because its size changed.<p>
-     * 
-     * We will update the different control related to the selection window.
-     */
-    public void windowChangedNotification() {
-       
-       if ( lastUsedExperiment != null ) {
-               // If a request is ongoing, try to stop it
-               if (selectedWindowRequest != null && !selectedWindowRequest.isCompleted()) {
-                       selectedWindowRequest.cancel();
-               }
-               
-               if(fullExperimentCanvas != null) {
-                       // If the current event time is outside the new window, change the current event
-                       //              The new current event will be the one closest to the LEFT side of the new window
-                       if ( isGivenTimestampInSelectedWindow(currentEventTime) == false ) {
-                               currentEventChangeNotification( fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition() );
-                       }
-               }
-               
-               // Perform a new request to read data about the new window
-               performSelectedWindowEventsRequest(lastUsedExperiment);
-       }
-    }
-    
-    /**
-     * Function used to tell that the current event changed.<p>
-     * This might be called because the user changed the current event or
-     *                 because the last current event is now outside the selection window.<p>
-     * 
-     * We update the related control and send a signal to notify other views of the new current event.
-     * 
-     * @param newCurrentEventTime
-     */
-    public void currentEventChangeNotification(long newCurrentEventTime) {
-       
-       // Notify other views in the framework
-        if (currentEventTime != newCurrentEventTime) {
-            currentEventTime = newCurrentEventTime;
-            
-            if ( currentEventTime < fullExperimentCanvas.getHistogramContent().getStartTime() ) {
-                currentEventTime = fullExperimentCanvas.getHistogramContent().getStartTime();
-            }
-            
-            if ( currentEventTime > fullExperimentCanvas.getHistogramContent().getEndTime() ) {
-                currentEventTime = fullExperimentCanvas.getHistogramContent().getEndTime();
-            }
-            
-               // Update the UI control
-               updateSelectedEventTime();
+
+    private void sendTimeRangeRequest(long startTime, long endTime) {
+        if (fTimeRangeRequest != null && !fTimeRangeRequest.isCompleted()) {
+            fTimeRangeRequest.cancel();
         }
+        TmfTimestamp startTS = new TmfTimestamp(startTime, TIME_SCALE);
+        TmfTimestamp endTS = new TmfTimestamp(endTime, TIME_SCALE);
+        TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS);
+
+        fTimeRangeHistogram.clear();
+        fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
+        fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram, timeRange, ExecutionType.FOREGROUND);
+        fCurrentExperiment.sendRequest(fTimeRangeRequest);
     }
-    
-    public void sendTmfTimeSynchSignalBroadcast() {
-       
-//     System.out.println("sendTmfTimeSynchSignalBroadcast " + System.currentTimeMillis());
-       
-       // Send a signal to the framework
-        LttngTimestamp tmpTimestamp = new LttngTimestamp(currentEventTime);
-        broadcast(new TmfTimeSynchSignal(this, tmpTimestamp));
-    }
-    
-    /**
-     * Function used to tell that the timerange (window) changed.<p>
-     * This will most likely be called if the time window is resized.
-     * 
-     * We send a signal to notify other views of the new timerange.
-     */
-    public void sendTmfRangeSynchSignalBroadcast() {
-       
-       if (TmfExperiment.getCurrentExperiment() == null)
-               return;
-
-       long startTime = fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition();
-       if ( startTime < fullExperimentCanvas.getHistogramContent().getStartTime() ) {
-               startTime = fullExperimentCanvas.getHistogramContent().getStartTime();
-       }
-        LttngTimestamp tmpStartTime = new LttngTimestamp(startTime);
-        
-        long endTime = fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition();
-       if ( endTime > fullExperimentCanvas.getHistogramContent().getEndTime() ) {
-               endTime = fullExperimentCanvas.getHistogramContent().getEndTime();
-       }
-       LttngTimestamp tmpEndTime = new LttngTimestamp(endTime);
-       
-        TmfTimeRange tmpTimeRange = new TmfTimeRange(tmpStartTime, tmpEndTime);
-        LttngTimestamp tmpEventTime = new LttngTimestamp(currentEventTime);
-        
-        // Send a signal to the framework
-        broadcast(new TmfRangeSynchSignal(this, tmpTimeRange, tmpEventTime));
+
+    private void sendFullRangeRequest() {
+        if (fFullTraceRequest != null && !fFullTraceRequest.isCompleted()) {
+            fFullTraceRequest.cancel();
+        }
+        fFullTraceHistogram.clear();
+        TmfTimeRange timeRange = updateExperimentTimeRange(fCurrentExperiment);
+        fFullTraceRequest = new HistogramRequest(fFullTraceHistogram, timeRange, ExecutionType.BACKGROUND);
+        fCurrentExperiment.sendRequest(fFullTraceRequest);
     }
-    
-    /**
-     * Function that will be called when one of the time text group value is changed.<p>
-     * Since we don't (and can't unless we subclass them) know which one, we check them all.
-     */
-    public void timeTextGroupChangeNotification() {
-       
-       if(ntgCurrentEventTime != null) {
-               // If the user changed the current event time, call the notification
-               long newCurrentTime = ntgCurrentEventTime.getValue();
-               if ( newCurrentTime != currentEventTime ) {
-                       currentEventChangeNotification( newCurrentTime );
-                       // Send a broadcast to the framework about the window change
-                       sendTmfTimeSynchSignalBroadcast();
-               }
-       }
-       
-       if(ntgWindowCenterTime != null && fullExperimentCanvas != null) {
-               // If the user changed the selected window time, recenter the window and call the notification
-               long newSelectedWindowTime = ntgWindowCenterTime.getValue();
-               if ( newSelectedWindowTime != fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition() ) {
-                       fullExperimentCanvas.setWindowCenterPosition(newSelectedWindowTime);    
-                       // Send a broadcast to the framework about the window change
-                       sendTmfRangeSynchSignalBroadcast();
-               }
-       }
-       
-       if(ntgWindowTimeSpan != null && fullExperimentCanvas != null) {
-               // If the user changed the selected window size, resize the window and call the notification
-               long newSelectedWindowTimeRange = ntgWindowTimeSpan.getValue();
-               if ( newSelectedWindowTimeRange != fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth() ) {
-                       fullExperimentCanvas.resizeWindowByAbsoluteTime(newSelectedWindowTimeRange);
-                       // Send a broadcast to the framework about the window change
-                       sendTmfRangeSynchSignalBroadcast();
-               }
-       }
-       
+
+    private TmfTimeRange updateExperimentTimeRange(TmfExperiment<LttngEvent> experiment) {
+        TmfTimestamp startTime = TmfTimestamp.BigCrunch;
+        TmfTimestamp endTime = TmfTimestamp.BigBang;
+        for (ITmfTrace trace : experiment.getTraces()) {
+            TmfTimestamp traceStartTime = trace.getStartTime();
+            if (traceStartTime.compareTo(startTime, true) < 0)
+                startTime = traceStartTime;
+            TmfTimestamp traceEndTime = trace.getEndTime();
+            if (traceEndTime.compareTo(endTime, true) > 0)
+                endTime = traceEndTime;
+        }
+        fExperimentStartTime = startTime.getValue();
+        fExperimentEndTime = endTime.getValue();
+
+        return new TmfTimeRange(startTime, endTime);
     }
-    
-    /**
-     * Getter for the last used experiment.<p>
-     * This might be different than the current experiment or even null.
-     * 
-     * @return the last experiment we used in this view
-     */
-       public TmfExperiment<LttngEvent> getLastUsedExperiment() {
-               return lastUsedExperiment;
-       }
-       
-       /**
-        * Check if a given timestamp is inside the selection window.<p>
-        * This assume fullExperimentCanvas contain a valid HistogramContent
-        * 
-        * @param timestamp     the timestamp to check
-        * 
-        * @return      if the time is inside the selection window or not
-        */
-       public boolean isGivenTimestampInSelectedWindow(long timestamp) {
-               boolean returnedValue = true;
-               
-               // If the content is not set correctly, this will return weird (or even null) result
-               if ( (timestamp < fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition()  ) ||
-                (timestamp > fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition() ) ) 
-               {
-                       returnedValue = false;
-               }
-               
-               return returnedValue;
-       }
-       
-       /**
-        * Reset the content of all Controls.<p>
-        * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
-        */
-       public void resetControlsContent() {
-               
-               TmfExperiment<LttngEvent> tmpExperiment = getLastUsedExperiment();
-               
-               // Use the previous Start and End time, or default if they are not available
-               String startTime = null;
-               String stopTime = null;
-               if ( tmpExperiment != null ) {
-                       startTime = HistogramConstant.formatNanoSecondsTime( tmpExperiment.getStartTime().getValue() );
-                       stopTime = HistogramConstant.formatNanoSecondsTime( tmpExperiment.getEndTime().getValue() );
-               }
-               else {
-                       startTime = HistogramConstant.formatNanoSecondsTime( 0L );
-                       stopTime = HistogramConstant.formatNanoSecondsTime( 0L );
-               }
-               
-       txtExperimentStartTime.setText( startTime );
-               txtExperimentStopTime.setText( stopTime );
-               txtExperimentStartTime.getParent().layout();
-               
-               txtWindowMaxNbEvents.setText("" + 0); //$NON-NLS-1$
-               txtWindowMinNbEvents.setText("" + 0); //$NON-NLS-1$
-               txtWindowStartTime.setText( HistogramConstant.formatNanoSecondsTime( 0L ) );
-               txtWindowStopTime.setText( HistogramConstant.formatNanoSecondsTime( 0L ) );
-               txtWindowStartTime.getParent().layout();
-               
-               ntgWindowCenterTime.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) );
-               ntgWindowTimeSpan.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) );
-               
-               // Using "startTime" here can avoid an useless TmfTimeSynchSignal here
-               // However it look ugly to have only this time
-               ntgCurrentEventTime.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) );
-       }
-       
-       /**
-        * Update the content of the controls related to the full experiment canvas<p>
-        * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
-        */
-       public void updateFullExperimentInformation() {
-               
-               if(fullExperimentCanvas != null) {
-                       String startTime = HistogramConstant.formatNanoSecondsTime( fullExperimentCanvas.getHistogramContent().getStartTime() );
-                       String stopTime = HistogramConstant.formatNanoSecondsTime( fullExperimentCanvas.getHistogramContent().getEndTime() );
-                       
-                       txtExperimentStartTime.setText( startTime );
-                       txtExperimentStopTime.setText( stopTime );
-               }
-               
-               // Take one of the parent and call its layout to update control size
-               // Since both control have the same parent, only one call is needed 
-               txtExperimentStartTime.getParent().layout();
-               
-               // Update the selected window, just in case
-               // This should give a better user experience and it is low cost 
-               updateSelectedWindowInformation();
-       }
-       
-       /**
-        * Update the content of the controls related to the selection window canvas<p>
-        * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
-        */
-       public void updateSelectedWindowInformation() {
-               // Update the timestamp as well
-               updateSelectedWindowTimestamp();
-               
-               if(selectedWindowCanvas != null) {
-                       txtWindowMaxNbEvents.setText( Long.toString(selectedWindowCanvas.getHistogramContent().getHeighestEventCount()) );
-                       txtWindowMinNbEvents.setText(Long.toString(0));
-               }
-               
-               // Refresh the layout
-               txtWindowMaxNbEvents.getParent().layout();
-       }
-       
-       /**
-        * Update the content of the controls related to the timestamp of the selection window<p>
-        * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
-        */
-       public void updateSelectedWindowTimestamp() {
-               
-               if(selectedWindowCanvas != null) {
-                       String startTime = HistogramConstant.formatNanoSecondsTime( selectedWindowCanvas.getHistogramContent().getStartTime() );
-                       String stopTime = HistogramConstant.formatNanoSecondsTime( selectedWindowCanvas.getHistogramContent().getEndTime() );
-                       txtWindowStartTime.setText( startTime );
-                       txtWindowStopTime.setText( stopTime );
-               }
-               
-               if(fullExperimentCanvas != null) {
-                       ntgWindowCenterTime.setValue( fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition() );
-                       ntgWindowTimeSpan.setValue(  fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth() );
-                       
-                       // If the current event time is outside the selection window, recenter our window 
-                       if ( isGivenTimestampInSelectedWindow(ntgCurrentEventTime.getValue()) == false ) {
-                               currentEventChangeNotification( fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition() );
-                       }
-               }
-               
-               // Take one control in each group to call to refresh the layout
-               // Since both control have the same parent, only one call is needed 
-               txtWindowStartTime.getParent().layout();
-               ntgWindowCenterTime.getParent().layout();
-       }
-       
-       /**
-        * Update the controls related current event.<p>
-        * The call here SHOULD be thread safe and can be call from any threads.
-        */
-       public void updateSelectedEventTime() {
-       ntgCurrentEventTime.setValueAsynchronously(currentEventTime);
-//     sendTmfTimeSynchSignalBroadcast();
-       // Tell the selection canvas which event is currently selected
-       // This give a nice graphic output
-       selectedWindowCanvas.getHistogramContent().setSelectedEventTimeInWindow(currentEventTime);
-       selectedWindowCanvas.redrawAsynchronously();
-       }
-       
-       /**
-        * Method called when the view is moved.<p>
-        * 
-        * Just redraw everything...
-        * 
-        * @param event         The control event generated by the move.
-        */
-       @Override
-       public void controlMoved(ControlEvent event) {
-               parent.redraw();
-       }
-       
-       /**
-        * Method called when the view is resized.<p>
-        * 
-        * We will make sure that the size didn't change more than the content size.<p>
-        * Otherwise we need to perform a new request for the full experiment because we are missing data).
-        * 
-        * @param event         The control event generated by the resize.
-        */
-       @Override
-       public void controlResized(ControlEvent event) {
-               
-               // Ouch! The screen enlarged (screen resolution changed?) so far that we miss content to fill the space.
-               if ( parent.getDisplay().getBounds().width > fullExperimentCanvas.getHistogramContent().getNbElement() ) {
-                       if ( lastUsedExperiment != null ) {
-                               createCanvasAndRequests(lastUsedExperiment);
-                       }
-               }
-               
-       }
-
-       /*
-        * Getter of FullExperimentCanvas
-        * 
-        * @return FullExperimentCanvas object
-        */
-       public static ParentHistogramCanvas getFullExperimentCanvas() {
-               return fullExperimentCanvas;
-       }
-
-       /*
-        * Getter of SelectedWindowCanvas
-        * 
-        * @return SelectedWindowCanvas object
-        */
-       public static ChildrenHistogramCanvas getSelectedWindowCanvas() {
-               return selectedWindowCanvas;
-       }
-
-       
-       /*
-        * Getter of DEFAULT_WINDOW_SIZE
-        * 
-        * @return DEFAULT_WINDOW_SIZE value
-        */
-       public static long getDEFAULT_WINDOW_SIZE() {
-               return DEFAULT_WINDOW_SIZE;
-       }
-
-       /**
-        * Getter for dataBackgroundFullRequest variable
-        * @return the dataBackgroundFullRequest instance
-        */
-       public HistogramRequest getDataBackgroundFullRequest() {
-               return dataBackgroundFullRequest;
-       }
-
-       /**
-        * Getter for selectedWindowRequest variable
-        * @return the selectedWindowRequest instance
-        */
-       public HistogramRequest getSelectedWindowRequest() {
-               return selectedWindowRequest;
-       }
 
 }
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramZoom.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramZoom.java
new file mode 100644 (file)
index 0000000..437fb16
--- /dev/null
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseWheelListener;
+import org.eclipse.swt.widgets.Canvas;
+
+/**
+ * <b><u>HistogramZoom</u></b>
+ * <p>
+ * TODO: Document me...
+ */
+public class HistogramZoom implements MouseWheelListener {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    private final static double ZOOM_FACTOR = 0.8;
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    private final Histogram fHistogram;
+    private final Canvas fCanvas;
+
+    private long fAbsoluteStartTime;
+    private long fAbsoluteEndTime;
+    private final long fMinWindowSize;
+
+    private long fRangeStartTime;
+    private long fRangeDuration;
+
+    private MouseScrollCounter fScrollCounter;
+
+    // ------------------------------------------------------------------------
+    // Construction
+    // ------------------------------------------------------------------------
+
+    public HistogramZoom(Histogram histogram, Canvas canvas, long start, long end) {
+        fHistogram = histogram;
+        fCanvas = canvas;
+        fAbsoluteStartTime = start;
+        fAbsoluteEndTime = end;
+        fMinWindowSize = fCanvas.getBounds().x;
+
+        fRangeStartTime = fAbsoluteStartTime;
+        fRangeDuration = fAbsoluteStartTime + fMinWindowSize;
+
+        canvas.addMouseWheelListener(this);
+    }
+
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
+    public long getStartTime() {
+        return fRangeStartTime;
+    }
+
+    public long getEndTime() {
+        return fRangeStartTime + fRangeDuration;
+    }
+
+    public long getDuration() {
+        return fRangeDuration;
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    public synchronized void stop() {
+        if (fScrollCounter != null) {
+            fScrollCounter.interrupt();
+            fScrollCounter = null;
+        }
+    }
+
+    public void setFullRange(long startTime, long endTime) {
+        fAbsoluteStartTime = startTime;
+        fAbsoluteEndTime = endTime;
+    }
+
+    public void setNewRange(long startTime, long duration) {
+        if (startTime < fAbsoluteStartTime)
+            startTime = fAbsoluteStartTime;
+
+        long endTime = startTime + duration;
+        if (endTime > fAbsoluteEndTime) {
+            endTime = fAbsoluteEndTime;
+            if (endTime - duration > fAbsoluteStartTime)
+                startTime = endTime - duration;
+            else {
+                startTime = fAbsoluteStartTime;
+            }
+        }
+
+        fRangeStartTime = startTime;
+        fRangeDuration = endTime - startTime;
+    }
+
+    // ------------------------------------------------------------------------
+    // MouseWheelListener
+    // ------------------------------------------------------------------------
+
+    private long fMouseTimestamp = 0;
+
+    @Override
+    public synchronized void mouseScrolled(MouseEvent event) {
+        if (fScrollCounter == null) {
+            fScrollCounter = new MouseScrollCounter(this);
+            fScrollCounter.start();
+            fMouseTimestamp = fHistogram.getTimestamp(event.x);
+        }
+        fScrollCounter.incrementMouseScroll(event.count);
+    }
+
+    private synchronized void zoom(int nbClicks) {
+        // The job is finished
+        fScrollCounter = null;
+
+        // Compute the new time range
+        long requestedRange = (nbClicks > 0) ? Math.round(ZOOM_FACTOR * fRangeDuration) : (long) Math.ceil(fRangeDuration * (1.0 / ZOOM_FACTOR));
+
+        // Perform a proportional zoom wrt the mouse position
+        double ratio = ((double) (fMouseTimestamp - fRangeStartTime)) / fRangeDuration;
+        long requestedStart = validateStart(fRangeStartTime + (long) ((fRangeDuration - requestedRange) * ratio));
+        long requestedEnd = validateEnd(requestedStart, requestedStart + requestedRange);
+        requestedStart = validateStart(requestedEnd - requestedRange);
+
+        fHistogram.updateTimeRange(requestedStart, requestedEnd);
+    }
+
+    private long validateStart(long start) {
+        if (start < fAbsoluteStartTime)
+            start = fAbsoluteStartTime;
+        if (start > fAbsoluteEndTime)
+            start = fAbsoluteEndTime - fMinWindowSize;
+        return start;
+    }
+
+    private long validateEnd(long start, long end) {
+        if (end > fAbsoluteEndTime)
+            end = fAbsoluteEndTime;
+        if (end < start + fMinWindowSize)
+            end = start + fMinWindowSize;
+        return end;
+    }
+
+    // ------------------------------------------------------------------------
+    // DelayedMouseScroll
+    // ------------------------------------------------------------------------
+
+    private class MouseScrollCounter extends Thread {
+
+        // --------------------------------------------------------------------
+        // Constants
+        // --------------------------------------------------------------------
+
+        private final static long QUIET_TIME = 100L;
+        private final static long POLLING_INTERVAL = 10L;
+
+        // --------------------------------------------------------------------
+        // Attributes
+        // --------------------------------------------------------------------
+
+        private HistogramZoom fZoom = null;
+
+        private long fLastPoolTime = 0L;
+        private int nbScrollClick = 0;
+
+        // --------------------------------------------------------------------
+        // Construction
+        // --------------------------------------------------------------------
+
+        public MouseScrollCounter(HistogramZoom zoom) {
+            fZoom = zoom;
+            fLastPoolTime = System.currentTimeMillis();
+        }
+
+        // --------------------------------------------------------------------
+        // Operation
+        // --------------------------------------------------------------------
+
+        public void incrementMouseScroll(int nbScrolls) {
+            fLastPoolTime = System.currentTimeMillis();
+            nbScrollClick += nbScrolls;
+        }
+
+        // --------------------------------------------------------------------
+        // Thread
+        // --------------------------------------------------------------------
+
+        @Override
+        public void run() {
+            while ((System.currentTimeMillis() - fLastPoolTime) < QUIET_TIME) {
+                try {
+                    Thread.sleep(POLLING_INTERVAL);
+                } catch (Exception e) {
+                    return;
+                }
+            }
+            // Done waiting. Notify the histogram.
+            if (!isInterrupted())
+                fZoom.zoom(nbScrollClick);
+        }
+    }
+
+}
index 595b21f31cbd6611a7733f216416aafa60f09ba3..719ef6299a751e96ce8acd111e8cc6c847a68731 100644 (file)
@@ -1,17 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2011 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:
+ *   William Bourque - Initial API and implementation
+ *   Francois Chouinard - Cleanup and refactoring
+ *******************************************************************************/
+
 package org.eclipse.linuxtools.lttng.ui.views.histogram;
 
 import org.eclipse.osgi.util.NLS;
 
+/**
+ * <b><u>Messages</u></b>
+ * <p>
+ */
 public class Messages extends NLS {
+
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
        private static final String BUNDLE_NAME = "org.eclipse.linuxtools.lttng.ui.views.histogram.messages"; //$NON-NLS-1$
+    
        public static String HistogramView_currentEventLabel;
-       public static String HistogramView_windowCenterLabel;
-       public static String HistogramView_windowSpanLabel;
-       static {
-               // initialize resource bundle
-               NLS.initializeMessages(BUNDLE_NAME, Messages.class);
-       }
-
-       private Messages() {
-       }
+    public static String HistogramView_windowSpanLabel;
+    
+    // ------------------------------------------------------------------------
+    // Initializer
+    // ------------------------------------------------------------------------
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    private Messages() {
+    }
+
 }
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvas.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvas.java
deleted file mode 100644 (file)
index fb1246a..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *   
- * Modifications:
- * 2010-06-20 Yuriy Vashchuk - Histogram optimisations.   
- * 2010-07-16 Yuriy Vashchuk - Base Histogram class simplification.
- *                                                        Selection Window related methods has been
- *                                                        implemented here (Parent Histogram).
- *******************************************************************************/
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * <b><u>ParentHistogramCanvas</u></b>
- * <p>
- * Extended implementation of the HistogramCanvas.
- * <p>
- * This canvas goal is to display the "Full experiment" histogram. 
- */
-public class ParentHistogramCanvas extends HistogramCanvas {
-       
-       private ParentHistogramCanvasPaintListener              paintListener = null;
-       private HistogramCanvasMouseListener                    mouseListener = null;
-       private HistogramCanvasKeyListener                              keyListener   = null;
-       private ParentHistogramCanvasControlListener    controlListener = null;
-       
-       private HistogramSelectedWindow currentWindow = null;
-       
-       /**
-        * ParentHistogramCanvas constructor.<p>
-        * Same as HistogramCanvas, but receive a parent HistogramView that we can call from here.
-        * 
-        * @param parent                Composite control which will be the parent of the new instance (cannot be null)
-        * @param                               Style the style of control to construct
-        */
-       public ParentHistogramCanvas(HistogramView histogramView, Composite parent, int style) {
-               super(histogramView, parent, style);
-               
-               // New selected window, not visible by default
-               if (histogramView !=null && HistogramView.getFullExperimentCanvas() != null) {
-                       createNewSelectedWindow(
-                                       HistogramView.getFullExperimentCanvas().getHistogramContent().getStartTime() + HistogramView.getDEFAULT_WINDOW_SIZE() / 2,
-                                       HistogramView.getDEFAULT_WINDOW_SIZE()
-                                       );
-               }
-               
-               // 2010-06-20 Yuriy: Moved from parent class
-               createAndAddPaintListener();
-               createAndAddMouseListener();
-               createAndAddKeyListener();
-               createAndAddControlListener();
-       }
-       
-       /**
-        * Create a new HistogramContent for this HistogramCanvas<p>
-        * A new <I>empty</I> canvas will then be created.
-        * 
-        * IMPORTANT NOTE : This implementaton use the next power of 2 to the full screen resolution as the content size.
-        *                                      This allow us to resize the canvas at low cost (i.e. : no need to reissue a full request)
-        *                                      We need a "particular" paint listener that know about this.
-        * 
-        * @param canvasSize                                    Size of the parent canvas.
-        * @param widthPerBar                                   Width of the histogram "bars"
-        * @param barsHeight                                    Height of the histogram "bars"
-        * @param maxBarsDifferenceToAverage    Factor used to "chop" bars that are too tall. Set to something big (100.0?) if not needed.
-        */
-       @Override
-       public void createNewHistogramContent(int canvasSize, int widthPerBar, int barsHeight, double maxBarsDifferenceToAverage) {
-               
-               // *** FIXME ***
-               // Note there MIGHT be some unhandled case, like if the resolution of the screen change 
-               //              or if a new screen is plugged.
-               // Let's ignore them for now.
-               //
-               // The maximum size the canvas could ever had
-               int canvasMaxSize = getParent().getDisplay().getBounds().width;
-               
-               // Calculate the power of two superior to the max size
-               int exp = (int)Math.ceil( Math.log( (double)canvasMaxSize ) / Math.log(2.0) );
-               int contentSize = (int)Math.pow(2, exp);
-               
-               // Create the content
-               histogramContent = new HistogramContent( contentSize, canvasSize, widthPerBar, barsHeight, maxBarsDifferenceToAverage);
-               
-               // We need to ajust the "maxDifferenceToAverageFactor" as the bars we draw might be slitghly larger than the value asked
-               // Each "interval" are concatenated when draw so the worst case should be : 
-               // contentSize / (closest power of 2 to canvasMaxSize)
-               // Ex : if canvasSize is 1500 -> (2048 / 1024) == 2  so maxDiff should be twice larger
-               //
-               // Note : this is not perfect, if the screen is resized after we calculate this, the resulting output can be quite ugly
-               // For this reason, this will be recalculated in the paintListener as well. 
-               double maxBarsDiffFactor = ((double)contentSize / Math.pow(2, exp-1));
-               histogramContent.setMaxDifferenceToAverageFactor(maxBarsDiffFactor);
-       }
-
-       
-       /*
-        * Create a histogram paint listener and bind it to this canvas.<p>
-        * 
-        * Note : This one is a bit particular, as it is made to draw content that is of a power of 2.
-        *                      The default one draw content that is relative to the real pixels size.
-        */
-       private void createAndAddPaintListener() {
-               paintListener = new ParentHistogramCanvasPaintListener(this);
-               this.addPaintListener( paintListener );
-       }
-
-       /*
-        * Create a histogram mouse listener and bind it to this canvas.<p>
-        * Note : this mouse listener handle the mouse, the move and the wheel at once.
-        * 
-        * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasMouseListener
-        */
-       private void createAndAddMouseListener() {
-               mouseListener = new HistogramCanvasMouseListener(this);
-               this.addMouseListener(mouseListener);
-               this.addMouseMoveListener(mouseListener);
-               this.addMouseWheelListener(mouseListener);
-       }
-       
-       /*
-        * Create a histogram key listener and bind it to this canvas.<p>
-        * 
-        * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasKeyListener
-        */
-       private void createAndAddKeyListener() {
-               keyListener   = new HistogramCanvasKeyListener(this);
-               this.addKeyListener(keyListener);
-       }       
-       
-       /*
-        * Create a histogram control listener and bind it to this canvas.<p>
-        * 
-        *  @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
-        */
-       private void createAndAddControlListener() {
-               controlListener = new ParentHistogramCanvasControlListener(this);
-               this.addControlListener(controlListener);
-       }
-
-       /**
-        * Create a new selection window of the size (time width) given.<p>
-        * The window initial position is at X = 0.
-        * The window is created hidden, it won't be draw unless it is set to visible.<p> 
-        * 
-        * @param windowTimeDuration    Time width (in nanosecond) of the window.
-        */
-       public void createNewSelectedWindow(long timestampOfLeftPosition, long windowTimeDuration) {
-               currentWindow = new HistogramSelectedWindow(histogramContent, timestampOfLeftPosition, windowTimeDuration);
-       }
-       
-       /**
-        * Getter for the selection window<p>
-        * 
-        * @return the current selection window
-        * 
-        * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramSelectedWindow
-        */
-       public HistogramSelectedWindow getCurrentWindow() {
-               return currentWindow;
-       }
-       
-       /**
-        * Getter for the selection window width<p>
-        * 
-        * @return Time width (in nanosecond) of the selection window.
-        */
-       public long getSelectedWindowSize() {
-               return currentWindow.getWindowTimeWidth();
-       }
-       
-       /**
-        * Setter for the selection window width<p>
-        * The window size will be ajusted if it does not respect one of these constraints :
-        * - The window size cannot be smaller than a single histogram content interval.<p>
-        * - The window size cannot be larger than twice the histogram content complete time interval.<p>
-        * 
-        * @param newSelectedWindowSize New time width (in nanosecond) of the selection window.
-        */
-       public void setSelectedWindowSize(long newSelectedWindowSize) {
-               
-               if ( newSelectedWindowSize <= 0 ) {
-                       newSelectedWindowSize = 1L;
-               }
-               else if ( newSelectedWindowSize > (2*histogramContent.getCompleteTimeInterval()) ) {
-                       newSelectedWindowSize = (2*histogramContent.getCompleteTimeInterval());
-               }
-               
-               currentWindow.setWindowTimeWidth(newSelectedWindowSize);
-       }       
-       
-       /**
-        * Function that is called when the selection window is moved.<p>
-        * Note: Given position should be relative to the previous (centered) absolute position.<p>
-        * 
-        * Calculate the new position then re-center the window.<p> 
-        * It will also notify the HistogramView that the window changed. 
-        * 
-        * @param newRelativeXPosition  New position relative to the last known absolute position.
-        */
-       public void moveWindow(int newRelativeXPosition) {
-               int absolutePosition = currentWindow.getWindowXPositionCenter() + newRelativeXPosition;
-               
-               setWindowCenterPosition(absolutePosition);
-               notifyParentSelectionWindowChangedAsynchronously();
-       }
-
-       /**
-        * Function that is called when the selection window is re-centered.<p>
-        * Note: Given position should be absolute to the window and need to be the selection window center.<p>
-        * 
-        * Recenter the window and notify the HistogramView that the window changed. 
-        * 
-        * @param newRelativeXPosition  New absolute position.
-        */
-       public void setWindowCenterPosition(int newAbsoluteXPosition) {
-               
-               // We will check if the coordinate the same
-               if ( newAbsoluteXPosition != currentWindow.getWindowXPositionCenter() ) {
-
-                       long timestampOfLeftPosition = this.getHistogramContent().getClosestElementFromXPosition( newAbsoluteXPosition ).firstIntervalTimestamp - currentWindow.getWindowTimeWidth() / 2;
-                       long timestampOfCenterPosition = 0;
-                       long timestampOfRightPosition = 0;
-                       
-                       // Let's do the border verifications
-                       if ( timestampOfLeftPosition < histogramContent.getStartTime() ) {
-
-                               timestampOfLeftPosition = histogramContent.getStartTime();
-                               timestampOfCenterPosition = timestampOfLeftPosition + currentWindow.getWindowTimeWidth() / 2;
-                               timestampOfRightPosition = timestampOfLeftPosition + currentWindow.getWindowTimeWidth();
-
-                       } else {
-                       
-                               timestampOfRightPosition = this.getHistogramContent().getClosestElementFromXPosition( newAbsoluteXPosition ).firstIntervalTimestamp + currentWindow.getWindowTimeWidth() / 2;
-                               
-                               if ( timestampOfRightPosition > histogramContent.getEndTime() ) {
-                                       
-                                       timestampOfRightPosition = histogramContent.getEndTime();
-                                       timestampOfCenterPosition = timestampOfRightPosition - currentWindow.getWindowTimeWidth() / 2;
-                                       timestampOfLeftPosition = timestampOfRightPosition - currentWindow.getWindowTimeWidth();
-                                       
-                               } else {
-                                       
-                                       timestampOfCenterPosition = this.getHistogramContent().getClosestElementFromXPosition( newAbsoluteXPosition ).firstIntervalTimestamp;
-                                       
-                               }
-                               
-                       }
-               
-                       // We will do the update in case of different center timestamp
-                       if( timestampOfCenterPosition != currentWindow.getTimestampOfCenterPosition() ) {
-                               // Firstly we will setup new left, right and center timestamps
-                               currentWindow.setTimestampOfLeftPosition( timestampOfLeftPosition );
-                               currentWindow.setTimestampOfCenterPosition( timestampOfCenterPosition );
-                               currentWindow.setTimestampOfRightPosition( timestampOfRightPosition );
-       
-                               // After we will update coordonates using timestamps already recalculated
-                               currentWindow.setWindowXPositionLeft( histogramContent.getClosestXPositionFromTimestamp(timestampOfLeftPosition) );
-                               currentWindow.setWindowXPositionCenter( histogramContent.getClosestXPositionFromTimestamp(timestampOfCenterPosition) );
-                               currentWindow.setWindowXPositionRight( histogramContent.getClosestXPositionFromTimestamp(timestampOfRightPosition) );
-                               
-                               redrawAsynchronously();
-                       }
-               }
-       }
-
-       /**
-        * Function that is called when the selection window is re-centered.<p>
-        * Note: Given position should be timestamp in the experiment timerange<p>
-        * 
-        * Recenter the window and notify the HistogramView that the window changed. 
-        * 
-        * @param timestampOfCenterPosition     New timestamp of center position.
-        */
-       public void setWindowCenterPosition(long timestampOfCenterPosition) {
-               
-               // We will check if the coordinate the same
-               if ( timestampOfCenterPosition != currentWindow.getTimestampOfCenterPosition() ) {
-
-                       long timestampOfLeft = timestampOfCenterPosition - currentWindow.getWindowTimeWidth() / 2;
-                       long timestampOfCenter = 0;
-                       long timestampOfRight = 0;
-
-                       int windowXPositionLeft = histogramContent.getClosestXPositionFromTimestamp(timestampOfLeft);
-                       int windowXPositionCenter = 0;
-                       int windowXPositionRight = 0;
-                       
-                       // Let's do the border verifications
-                       if ( timestampOfLeft < histogramContent.getStartTime() ) {
-                               
-                               timestampOfLeft = histogramContent.getStartTime();
-                               timestampOfCenter = timestampOfLeft + currentWindow.getWindowTimeWidth() / 2;
-                               timestampOfRight = timestampOfLeft + currentWindow.getWindowTimeWidth();
-
-                               windowXPositionLeft = histogramContent.getClosestXPositionFromTimestamp(timestampOfLeft);
-                               windowXPositionCenter = histogramContent.getClosestXPositionFromTimestamp(timestampOfCenter); 
-                               windowXPositionRight = histogramContent.getClosestXPositionFromTimestamp(timestampOfRight);
-
-                       } else {
-                       
-                               timestampOfRight = timestampOfCenterPosition + currentWindow.getWindowTimeWidth() / 2;
-                               windowXPositionRight = histogramContent.getClosestXPositionFromTimestamp(timestampOfRight);
-                               
-                               if ( timestampOfRight > histogramContent.getEndTime() ) {
-
-                                       timestampOfRight = histogramContent.getEndTime();
-                                       timestampOfCenter = timestampOfRight - currentWindow.getWindowTimeWidth() / 2;
-                                       timestampOfLeft = timestampOfRight - currentWindow.getWindowTimeWidth();
-                                       
-                                       windowXPositionLeft = histogramContent.getClosestXPositionFromTimestamp(timestampOfLeft);
-                                       windowXPositionCenter = histogramContent.getClosestXPositionFromTimestamp(timestampOfCenter); 
-                                       windowXPositionRight = histogramContent.getClosestXPositionFromTimestamp(timestampOfRight);
-                                       
-                               } else {
-                                       
-                                       timestampOfCenter = timestampOfCenterPosition;
-                                       windowXPositionCenter = histogramContent.getClosestXPositionFromTimestamp(timestampOfCenter);
-                                       
-                               }
-                               
-                       }
-
-                       // Firstly we will setup new left, right and center timestamps
-                       currentWindow.setTimestampOfLeftPosition( timestampOfLeft );
-                       currentWindow.setTimestampOfCenterPosition( timestampOfCenter );
-                       currentWindow.setTimestampOfRightPosition( timestampOfRight );
-                       
-                       // We will do the update in case of different center timestamp
-                       if( windowXPositionCenter != currentWindow.getWindowXPositionCenter() ) {
-
-                               // After we will update coordonates using timestamps already recalculated
-                               currentWindow.setWindowXPositionLeft(windowXPositionLeft);
-                               currentWindow.setWindowXPositionCenter(windowXPositionCenter);
-                               currentWindow.setWindowXPositionRight(windowXPositionRight);
-                               
-                               redrawAsynchronously();
-                       }
-               }
-       }
-       
-       
-       /**
-        * Function that is called when the selection window size (time width) changed by an absolute time.<p>
-        * Note: Given time should be in nanoseconds, positive.
-        * 
-        * Set the new window size and notify the HistogramView that the window changed.
-        * 
-        * @param newTime        New absoulte time (in nanoseconds) to apply to the window.
-        */
-       public void resizeWindowByAbsoluteTime(long newTime) {
-               if ( newTime != getSelectedWindowSize() ) {
-                       
-                       resizeWindowByAbsoluteTimeWithoutNotification(newTime);
-                       
-                       notifyParentSelectionWindowChangedAsynchronously();
-               }
-       }
-       
-       /**
-        * Function that is called when the selection window size (time width) changed by an absolute time.<p>
-        * Note: Given time should be in nanoseconds, positive.
-        * 
-        * Set the new window size and notify the HistogramView that the window changed.
-        * 
-        * @param newTime        New absoulte time (in nanoseconds) to apply to the window.
-        */
-       public void resizeWindowByAbsoluteTimeWithoutNotification(long newTime) {
-               
-               // We will change the size in case of delta (newTime) != 0
-               if (newTime != 0 ) { 
-                       
-                       if(newTime > getHistogramContent().getEndTime() - getHistogramContent().getStartTime()) {
-                               newTime = getHistogramContent().getEndTime() - getHistogramContent().getStartTime();
-                       }
-       
-                       setSelectedWindowSize(newTime);
-       
-       /*                      
-                       // Yuriy: we can't use this function because we change the left and right coordinates.
-                       setWindowCenterPosition(currentWindow.getWindowXPositionCenter());
-       */                      
-       
-                       long timestampOfLeftPosition = currentWindow.getTimestampOfCenterPosition() - currentWindow.getWindowTimeWidth() / 2;
-                       long timestampOfCenterPosition = currentWindow.getTimestampOfCenterPosition();
-                       long timestampOfRightPosition = 0;
-                               
-                       // Let's do the border verifications
-                       if ( timestampOfLeftPosition < histogramContent.getStartTime() ) {
-       
-                               timestampOfLeftPosition = histogramContent.getStartTime();
-                               timestampOfCenterPosition = timestampOfLeftPosition + currentWindow.getWindowTimeWidth() / 2;
-                               timestampOfRightPosition = timestampOfLeftPosition + currentWindow.getWindowTimeWidth();
-       
-                       } else {
-                               
-                               timestampOfRightPosition = currentWindow.getTimestampOfCenterPosition() + currentWindow.getWindowTimeWidth() / 2;
-                                       
-                               if ( timestampOfRightPosition > histogramContent.getEndTime() ) {
-                                               
-                                       timestampOfRightPosition = histogramContent.getEndTime();
-                                       timestampOfCenterPosition = timestampOfRightPosition - currentWindow.getWindowTimeWidth() / 2;
-                                       timestampOfLeftPosition = timestampOfRightPosition - currentWindow.getWindowTimeWidth();
-                                               
-                               }
-                               
-                       }
-                       
-                       // Firstly we will setup new left, right and center timestamps
-                       currentWindow.setTimestampOfLeftPosition( timestampOfLeftPosition );
-                       currentWindow.setTimestampOfCenterPosition( timestampOfCenterPosition );
-                       currentWindow.setTimestampOfRightPosition( timestampOfRightPosition );
-               
-                       // After we will update coordonates using timestamps already recalculated
-                       currentWindow.setWindowXPositionLeft( histogramContent.getClosestXPositionFromTimestamp(timestampOfLeftPosition) );
-                       currentWindow.setWindowXPositionCenter( histogramContent.getClosestXPositionFromTimestamp(timestampOfCenterPosition) );
-                       currentWindow.setWindowXPositionRight( histogramContent.getClosestXPositionFromTimestamp(timestampOfRightPosition) );
-                       
-                       redrawAsynchronously();
-               }
-       }
-       
-       /**
-        * Notify the parent HistogramView that we have updated information.<p>
-        * This is intended to be called at the end of the request when we know we have up-to-date information.
-        */
-       @Override
-       public void notifyParentUpdatedInformation() {
-               getHistogramView().updateFullExperimentInformation();
-       }
-       
-       /**
-        * Notify the parent HistogramView that the SelectionWindow changed.<p>
-        * This is intended to be called when the window move or is resized.
-        */
-       public void notifyParentSelectionWindowChanged() {
-               // Notify the parent view that something changed
-               getHistogramView().windowChangedNotification();
-               // Send a broadcast to the framework about the window change
-               getHistogramView().sendTmfRangeSynchSignalBroadcast();
-       }
-
-       /**
-        * Method to call the "Asynchronous NotifyParentSelectionWindowChanged" for this canvas<p>
-        * This allow safe update UI objects from different threads.
-        * 
-        */
-       public void notifyParentSelectionWindowChangedAsynchronously() {
-               // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
-               if ( canvasRedrawer == null ) {
-                       canvasRedrawer = new AsyncCanvasRedrawer(this);
-               }
-               
-               asynchronousNotifyParentSelectionWindowChanged();
-       }       
-       
-       /**
-        * Function to asynchonously notify the parent of the related canvas that the window changed.<p>
-        * 
-        * Basically, it just run "notifyParentSelectionWindowChanged()" in asyncExec.
-        * 
-        */
-       public void asynchronousNotifyParentSelectionWindowChanged() {
-               // Ignore update if widget is disposed
-               if (this.isDisposed()) return;
-
-               Display display = this.getDisplay();
-               display.asyncExec(new Runnable() {
-                       @Override
-                       public void run() {
-                               if(!ParentHistogramCanvas.this.isDisposed())
-                                       notifyParentSelectionWindowChanged();
-                       }
-               });
-       }       
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasControlListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasControlListener.java
deleted file mode 100644 (file)
index ba5e4c6..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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:
- *   2010-06-20 Yuriy Vashchuk - Initial API and implementation
- *   
- * Modifications:
- * 2010-07-16 Yuriy Vashchuk - Base class simplification.   
- *******************************************************************************/
-
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.events.ControlEvent;
-
-/**
- * <b><u>ParentHistogramCanvasControlListener</u></b>
- * <p>
- * Implementation of a ControlListener for the need of the ParentHistogramCanvas
- * <p> 
- */
-public class ParentHistogramCanvasControlListener extends HistogramCanvasControlListener {
-
-       private ParentHistogramCanvas ourCanvas = null;
-       
-       /**
-        * ParentHistogramCanvasControlListenerl constructor
-        * 
-        * @param newCanvas Related canvas
-        */
-       public ParentHistogramCanvasControlListener(ParentHistogramCanvas newCanvas) {
-               ourCanvas = newCanvas;
-       }
-       
-       
-       /**
-        * Method called when the canvas is resized.<p>
-        * 
-        * We need to tell the content that the canvas size changed and to recenter the windows
-        * 
-        * @param event         The control event generated by the resize.
-        */
-       @Override
-       public void controlResized(ControlEvent event) {
-               
-               if ( (ourCanvas != null) && (ourCanvas.getHistogramContent() != null) ) {
-                       int newSize = ourCanvas.getSize().x;
-                       int oldSize = ourCanvas.getHistogramContent().getCanvasWindowSize();
-                       
-                       // Set the new canvas size
-                       ourCanvas.getHistogramContent().setCanvasWindowSize(newSize);
-                       
-                       // Try to recenter to window at the same place it was
-                       // Note : this is a best hope approach and is not intended to be precise;
-                       //              the idea is to avoid issuing a (maybe) long request fo the selection window;
-                       // There WILL be slight discrepancy between the "window values" (timestamp, etc...) showed 
-                       //              and what it really points to. The user should reclick by himself to refresh it. 
-                       int oldWindowCenter = ourCanvas.getCurrentWindow().getWindowXPositionCenter();
-                       int newWindowCenter = (int)Math.ceil((double)newSize * ((double)oldWindowCenter / (double)oldSize));
-                       ourCanvas.setWindowCenterPosition(newWindowCenter);
-               }
-       }
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasPaintListener.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasPaintListener.java
deleted file mode 100644 (file)
index 63ca7e3..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   William Bourque - Initial API and implementation
- *   
- * Modifications:
- * 2010-07-16 Yuriy Vashchuk - Base class simplification. Redraw bug correction.
- *                                                        Double Buffering implementation.
- *******************************************************************************/
-
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.PaintEvent;
-
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * <b><u>HistogramCanvasPaintListener</u></b>
- * <p>
- * Implementation of a PaintListener for the specific need of the ParentHistogramCanvas.
- * <p> 
- * The difference with the default one is that this one take a content that is the power of 2 higher 
- *             than the display size.<p>
- * 
- * When it is time to draw, it takes the closest power of 2 smaller than the canvas size; it is then easy to 
- *             concatenate the interval as they are both power of 2.<p>
- * The difference between the power of 2 and the not-power-of-2 canvas size is then filled by drawing bar that are
- *             slightly larger every (power/canvasSize) interval.<p> 
- */
-public class ParentHistogramCanvasPaintListener extends HistogramCanvasPaintListener 
-{
-       private static ParentHistogramCanvas  parentCanvas = null;
-
-       /**
-        * ParentHistogramCanvasPaintListener constructor
-        * 
-        * @param newCanvas Related canvas
-        */     
-       public ParentHistogramCanvasPaintListener(ParentHistogramCanvas newCanvas) {
-               parentCanvas = newCanvas;
-       }
-       
-       // *** VERIFY ***
-       // Is it good to put this synchronized?
-       //
-       /**
-        * Draw the histogram bars in the canvas.<p>
-        * This drawing function expect the content to be the power of 2 higher than the canvas size.
-        * The bars size will be slightly dynamic to fill the gap between the power and the canvas size.<p>
-        * 
-        * Note : This draw function is somewhat heavier than the default one.
-        * 
-        * @param event The generated paint event when redraw is called.
-        */
-       @Override
-       public synchronized void drawHistogram(GC imageGC, Image image) {
-               final HistogramContent tmpContent = parentCanvas.getHistogramContent();
-               final int tmpBarWidth = tmpContent.getBarsWidth();
-               
-               // Calculate the closest power of 2 just smaller than the canvas size
-               final int closestPowerToCanvas = (int)Math.pow(2, Math.floor( Math.log( image.getBounds().width ) / Math.log(2.0) ));
-
-               // First clear the whole canvas to have a clean section where to draw
-               clearDrawingSection(imageGC, image, parentCanvas);
-               
-               // Make sure the canvas didn't change size, it which case we need to recalculate our heights
-               recalculateHeightIfCanvasSizeChanged();
-               
-               // Calculate the factor of difference between canvas and the power
-               final double factor = (double)image.getBounds().width / (double)closestPowerToCanvas;
-               // Calculate how many interval will need to be concatenated into one pixel
-               final int intervalDifference = (tmpContent.getNbElement() / closestPowerToCanvas)*tmpBarWidth;
-               
-               // This keep a link between the position in "power" and the pixel we draw 
-               // I.e. correlation between position in the power ("fake" pixels) and the position in the canvas ("real" pixels)
-               // So if pos == 30 and factor == 1.5, we know that the pixel that draw this pos is (30 * 1.5) == 45
-               int posInPower = 0;
-               int widthFilled = 0;
-               
-               // This will be the color for all the bars that wil be draw below.
-               imageGC.setBackground( new Color( imageGC.getDevice(), 74, 112, 139) );
-
-               // Read from 0 up to the currently ready position
-               // We advance by "intervalDifference" as the bars migth not represent 1 interval only
-               int itemWidth = 0;
-               int thisElementHeight = 0;
-               for( int contentPos=0; contentPos < tmpContent.getReadyUpToPosition(); contentPos += intervalDifference ) {
-                       // Width of the current item. 
-                       // Vary because of the difference between the power of 2 and the canvas size
-                       // Ex: if power == 1024 and canvas == 1500, a bars every (1024/1500) will have a size of 2 instead of 1.
-                       itemWidth = (int)( Math.ceil((double)(posInPower+1)*factor) - Math.ceil((double)posInPower*factor) );
-                       itemWidth = itemWidth * tmpBarWidth;
-                       
-                       // Concatenate all the element in the interval
-                       // Ex : if power == 1024 and content == 2048, every (2048/1024)*bars_width will be concatenated 
-               thisElementHeight = 0;
-               for ( int concatPos=0; concatPos<intervalDifference; concatPos++) {
-                       // Make sure we don't cross the last element available.
-                       if ( contentPos + concatPos < tmpContent.getReadyUpToPosition() ) {
-                               thisElementHeight += tmpContent.getElementByIndex(contentPos + concatPos).intervalHeight;
-                       }
-               }
-               
-               // *** NOTE *** 
-                       // Y Position in a canvas is REVERSED, so "0" is on top of the screen and "MAX" is on bottom.
-                       // Not very instinctive, isn't it?
-                       // Draw our rectangle
-               imageGC.fillRectangle(
-                               widthFilled,
-                               (thisElementHeight > image.getBounds().height ? 0 : image.getBounds().height - thisElementHeight),
-                               itemWidth,
-                               thisElementHeight
-                               );
-               
-               // Keep in a variable how much width we filld so far
-               widthFilled += itemWidth;
-               // Keep a correlation between fake_pixel -> real_pixel, 
-               //      this is used to calculate the width of each element 
-               posInPower++;
-           }
-       }
-       
-       /*
-        * The function will make sure that the "max difference average" factor is still the same as before;
-        *              if not, the heigth of the events will be recalculated.<p>
-        * 
-        * The factor might change if the canvas is resized by a big factor.<p>
-        */
-       protected void recalculateHeightIfCanvasSizeChanged() {
-               final HistogramContent tmpContent = parentCanvas.getHistogramContent();
-               // We need to ajust the "maxDifferenceToAverageFactor" as the bars we draw might be slitghly larger than the value asked
-               // Each "interval" are concatenated when draw so the worst case should be : 
-               // contentSize / (closest power of 2 to canvasMaxSize)
-               // Ex : if canvasSize is 1500 -> (2048 / 1024) == 2  so maxDiff should be twice larger
-               //
-               // His is set in the create content of the canvas, but we need to recalculate it 
-               //      here because the window might have been resized!
-               final int exp = (int)Math.floor( Math.log( (double)tmpContent.getCanvasWindowSize() ) / Math.log(2.0) );
-               final int contentSize = (int)Math.pow(2, exp);
-               final double maxBarsDiffFactor = ((double)tmpContent.getNbElement() / (double)contentSize );
-               
-               // Floating point comparaison : 
-               //      We consider it is different if the difference is greater than 10^-3
-               if ( Math.abs(maxBarsDiffFactor - tmpContent.getMaxDifferenceToAverageFactor()) > 0.001 ) {
-                       // The factor changed! That's unfortunate because it will take a while to recalculate.
-                       tmpContent.setMaxDifferenceToAverageFactor(maxBarsDiffFactor);
-                       tmpContent.recalculateHeightFactor();
-                       tmpContent.recalculateEventHeight();
-               }
-       }
-       
-       /**
-        * Function called when the canvas need to redraw.<p>
-        * 
-        * @param event  The generated paint event when redraw is called.
-        */
-       private final String DATA_KEY = "double-buffer-image"; //$NON-NLS-1$
-       @Override
-       public void paintControl(PaintEvent event) {
-               
-               if (parentCanvas.getSize().x > 0 && parentCanvas.getSize().y > 0) {
-                       Image image = (Image) parentCanvas.getData(DATA_KEY);
-                       
-                       // Creates new image only absolutely necessary.
-                       if (image == null
-                                       || image.getBounds().width != parentCanvas.getClientArea().width
-                                       || image.getBounds().height != parentCanvas.getClientArea().height) {
-
-                               image = new Image(
-                                               event.display,
-                                               parentCanvas.getClientArea().width,
-                                               parentCanvas.getClientArea().height
-                                               );
-
-                               parentCanvas.setData(DATA_KEY, image);
-//                             isFinished = false;
-                       }
-                       
-                       // Initializes the graphics context of the image. 
-               GC imageGC = new GC(image);
-               
-                       // If the content is null or has rady to draw we quit the function here
-                       if ( (parentCanvas.getHistogramContent() != null)
-                                       && (parentCanvas.getHistogramContent().getReadyUpToPosition() != 0)     ) {
-                               
-                               // Call the function that draw the bars
-//                             if (!isFinished) {
-                                       drawHistogram(imageGC, image);
-//                                     isFinished = HistogramCanvas.getHistogramView().getDataBackgroundFullRequest().isCompleted();
-//                             }
-
-                               Image img = new Image (image.getDevice(), image, SWT.IMAGE_COPY);
-                               GC imgGC = new GC(img);
-                               
-                               // If we have a selected window set to visible, call the function to draw it
-                               if ( (parentCanvas.getCurrentWindow() != null) && (parentCanvas.getCurrentWindow().getSelectedWindowVisible()) ) {
-                                       drawSelectedWindow(
-                                                       imgGC,
-                                                       img
-                                                       );
-                               }
-
-                               // Draws the buffer image onto the canvas. 
-                               event.gc.drawImage(img, 0, 0);
-                               
-                               imgGC.dispose();
-                               img.dispose();
-                       }
-
-                       imageGC.dispose();
-               }
-               
-       }
-
-       /**
-        * Draw the selection window in the canvas.<p>
-        * This draw a square around the selected section with a crosshair in the middle.
-        * The square cannot be smaller than "MINIMUM_WINDOW_WIDTH"
-        * 
-        * @param imageGC GC content.
-        * @param image Image content.
-        */
-       public void drawSelectedWindow(GC imageGC, Image image) {
-               // Get the window position... this would fail if the window is not initialized yet
-               final int positionCenter = parentCanvas.getCurrentWindow().getWindowXPositionCenter();
-               final int positionLeft = parentCanvas.getCurrentWindow().getWindowXPositionLeft();
-               final int positionRight = parentCanvas.getCurrentWindow().getWindowXPositionRight();
-               
-               final int imageHeight = image.getBounds().height;
-               final int imageHalfHeight = image.getBounds().height / 2;
-               final int crosshairHalfWidth = HistogramConstant.SELECTION_CROSSHAIR_WIDTH / 2;
-               final int lineHalfWidth = HistogramConstant.SELECTION_LINE_WIDTH / 2;
-               
-               // Draw the crosshair
-               imageGC.setForeground( new Color (imageGC.getDevice(), 255, 128, 0) );
-               imageGC.setLineWidth(HistogramConstant.SELECTION_CROSSHAIR_WIDTH);
-               imageGC.setLineStyle(SWT.LINE_SOLID);
-               if(imageHeight > 40) {
-                       imageGC.drawLine(
-                                       positionCenter - crosshairHalfWidth,
-                                       imageHalfHeight - 20,
-                                       positionCenter - crosshairHalfWidth,
-                                       imageHalfHeight + 20
-                                       );
-               }
-               if(positionRight - positionLeft > 40) {
-                       imageGC.drawLine(
-                                       positionCenter - 20,
-                                       imageHalfHeight - crosshairHalfWidth,
-                                       positionCenter + 20,
-                                       imageHalfHeight - crosshairHalfWidth
-                                       );
-               }
-               
-               // Draw the selection window square
-               imageGC.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH);
-               imageGC.setLineStyle(SWT.LINE_SOLID);
-               imageGC.drawRoundRectangle(
-                               positionLeft + lineHalfWidth,
-                               lineHalfWidth,
-                               (positionRight - positionLeft) - lineHalfWidth,
-                               imageHeight - HistogramConstant.SELECTION_LINE_WIDTH,
-                               15,
-                               15
-                               );
-
-               // Show the selection
-               imageGC.setBackground( new Color (imageGC.getDevice(), 255, 128, 0) );
-               imageGC.setAlpha(25);
-               imageGC.fillRoundRectangle(
-                               positionLeft + 1,
-                               lineHalfWidth + 1,
-                               (positionRight - positionLeft) - lineHalfWidth - 1,
-                               imageHeight - lineHalfWidth - 1,
-                               15,
-                               15
-                               );
-       }
-       
-}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeRangeHistogram.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeRangeHistogram.java
new file mode 100644 (file)
index 0000000..265e269
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.histogram;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * <b><u>TimeRangeHistogram</u></b>
+ * <p>
+ * A basic histogram with the following additional features:
+ * <ul>
+ * <li>zoom in: mouse wheel up (or forward)
+ * <li>zoom out: mouse wheel down (or backward)
+ * </ul>
+ */
+public class TimeRangeHistogram extends Histogram {
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    HistogramZoom fZoom;
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    public TimeRangeHistogram(HistogramView view, Composite parent) {
+        super(view, parent);
+        fZoom = new HistogramZoom(this, fCanvas, getStartTime(), getTimeLimit());
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void updateTimeRange(long startTime, long endTime) {
+        ((HistogramView) fParentView).updateTimeRange(startTime, endTime);
+    }
+
+    @Override
+    public synchronized void clear() {
+        if (fZoom != null)
+            fZoom.stop();
+        super.clear();
+    }
+
+    public synchronized void setTimeRange(long startTime, long duration) {
+        fZoom.setNewRange(startTime, duration);
+    }
+
+    public void setFullRange(long startTime, long endTime) {
+        fZoom.setFullRange(startTime, endTime);
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeTextGroup.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeTextGroup.java
deleted file mode 100644 (file)
index 3d760d0..0000000
+++ /dev/null
@@ -1,506 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 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:
- *   Francois Chouinard - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.linuxtools.lttng.ui.views.histogram;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * <b><u>TimeTextGroup</u></b>
- * <p>
- * Special control for HistogramView
- * <p>
- * This control will give you a group, a text box and a label at once.
- */
-public class TimeTextGroup implements FocusListener, KeyListener {
-
-/*     
-       // 2010-06-10 Yuriy: Has been moved to header into HistogramView.java
-       protected static final String   NANOSEC_LABEL = "sec";
-*/     
-       private static final String     LONGEST_STRING_VALUE = "." + Long.MAX_VALUE; //$NON-NLS-1$
-       private static final int        MAX_CHAR_IN_TEXTBOX = LONGEST_STRING_VALUE.length();
-    
-    // The "small font" height used to display time will be "default font" minus this constant
-       private static final int VERY_SMALL_FONT_MODIFIER = 2;
-       private static final int SMALL_FONT_MODIFIER = 1;
-    
-    // Indentation size 
-//     private static final int DEFAULT_INDENT_SIZE = 10;
-    
-       private HistogramView parentView = null;
-       private AsyncTimeTextGroupRedrawer asyncRedrawer = null;
-    
-       private Group grpName   = null;
-       private Text    txtNanosec      = null;
-       private Label lblNanosec        = null;
-    
-       private long    timeValue       = 0L; 
-    
-    /**
-     * Default Constructor.<p>
-     * 
-     * @param newParentView            Parent HistogramView
-     * @param parent                   Parent Composite, used to position the inner controls.
-     * @param textStyle                        Style of the textbox. Usually SWT.BORDER or SWT.NONE (or anything that suit a Text)
-     * @param groupStyle               Style of the group.   Anything that suite a Text
-     */
-    public TimeTextGroup(HistogramView newParentView, Composite parent, int textStyle, int groupStyle) {
-       this(newParentView, parent, textStyle, groupStyle, "", HistogramConstant.formatNanoSecondsTime(0L), false); //$NON-NLS-1$
-    }
-    
-    /**
-     * Default Constructor with adjustement for small screen.<p>
-     * 
-     * @param newParentView            Parent HistogramView
-     * @param parent                   Parent Composite, used to position the inner controls.
-     * @param textStyle                        Style of the textbox. Usually SWT.BORDER or SWT.NONE (or anything that suit a Text)
-     * @param groupStyle               Style of the group.   Anything that suite a Text
-     * @param isSpaceSaverNeeded Value that tell if we try to save some space in the control.
-     */
-    public TimeTextGroup(HistogramView newParentView, Composite parent, int textStyle, int groupStyle, boolean isSpaceSaverNeeded) {
-       this(newParentView, parent, textStyle, groupStyle, "", HistogramConstant.formatNanoSecondsTime(0L), isSpaceSaverNeeded); //$NON-NLS-1$
-    }
-    
-    /**
-     * Default Constructor, allow you to give the groupname and the textbox value.<p>
-     * 
-     * @param newParentView            Parent HistogramView
-     * @param parent                   Parent Composite, used to position the inner controls.
-     * @param textStyle                        Style of the textbox. Usually SWT.BORDER or SWT.NONE (or anything that suit a Text)
-     * @param groupStyle               Style of the group.   Anything that suite a Text
-     * @param groupValue               Value (label) of the group. 
-     * @param textValue         Value of the textbox.
-     */
-    public TimeTextGroup(HistogramView newParentView, Composite parent, int textStyle, int groupStyle, String groupValue, String textValue) {
-       this(newParentView, parent, textStyle, groupStyle, groupValue, textValue, false);
-    }
-    
-    /**
-     * Default Constructor with adjustment for small screen, allow you to give the group name and the text box value.<p>
-     *  
-     * @param newParentView            Parent HistogramView
-     * @param parent                   Parent Composite, used to position the inner controls.
-     * @param textStyle                        Style of the text box. Usually SWT.BORDER or SWT.NONE (or anything that suit a Text)
-     * @param groupStyle               Style of the group.   Anything that suite a Text
-     * @param groupValue               Value (label) of the group. 
-     * @param textValue         Value of the text box.
-     * @param isSpaceSaverNeeded Value that tell if we try to save some space in the control.
-     */
-    public TimeTextGroup(HistogramView newParentView, Composite parent, int textStyle, int groupStyle, String groupValue, String textValue, boolean isSpaceSaverNeeded) {
-       Font font = parent.getFont();
-               FontData tmpFontData = font.getFontData()[0];
-               
-               Font smallFont = null;
-               int textBoxSize = -1;
-//             int indentSize = -1;
-               
-               // If we were asked to save size, calculate the correct value here
-               if ( isSpaceSaverNeeded == true ) {
-                       smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight()-VERY_SMALL_FONT_MODIFIER, tmpFontData.getStyle());
-                       
-                       // No minimum textBoxSize and no indent size
-                       textBoxSize = 0;
-//             indentSize = 0;
-               }
-               else {
-                       // We use only a slightly smaller font
-                       smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight()-SMALL_FONT_MODIFIER, tmpFontData.getStyle());
-                       
-                       // ** Creation of the textbox
-               // Calculate the optimal size of the textbox already
-               // This will avoid the control to move around and resize when bigger value are given 
-               textBoxSize = HistogramConstant.getTextSizeInControl(parent, LONGEST_STRING_VALUE);
-                       
-               // Default indent
-//             indentSize = DEFAULT_INDENT_SIZE;
-               }
-                       
-               parentView = newParentView;
-               
-               // ** Creation of the group
-//             GridLayout gridLayoutgroup = new GridLayout(2, false);
-               GridLayout gridLayoutgroup = new GridLayout(1, false);
-               gridLayoutgroup.horizontalSpacing = 0;
-               gridLayoutgroup.verticalSpacing = 0;
-        grpName = new Group(parent, groupStyle);
-        grpName.setText(groupValue);
-        grpName.setFont(smallFont);
-        grpName.setLayout(gridLayoutgroup);
-        
-        txtNanosec = new Text(grpName, textStyle);
-        txtNanosec.setTextLimit( MAX_CHAR_IN_TEXTBOX );
-        txtNanosec.setText(textValue);
-        txtNanosec.setFont(smallFont);
-        GridData gridDataTextBox = new GridData(SWT.LEFT, SWT.CENTER, true, false);
-        gridDataTextBox.horizontalIndent = 0; // indentSize;
-        gridDataTextBox.verticalIndent = 0;
-        gridDataTextBox.minimumWidth = textBoxSize;
-        txtNanosec.setLayoutData(gridDataTextBox);
-        
-        // ** Creation of the label
-/*        
-        lblNanosec = new Label(grpName, SWT.LEFT);
-        lblNanosec.setText(NANOSEC_LABEL);
-        lblNanosec.setFont(smallFont);
-        GridData gridDataLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false);
-        gridDataLabel.horizontalIndent = indentSize;
-        gridDataLabel.verticalIndent = 0;
-        lblNanosec.setLayoutData(gridDataLabel);
-*/
-        
-        // Add all listener
-        addNeededListeners();
-    }
-    
-    /*
-     * Create and add all listeners needed by our control.<p>
-     */
-    protected void addNeededListeners() {
-       
-       // AsyncCanvasRedrawer is an internal class
-               // This is used to redraw the canvas without danger from a different thread
-               asyncRedrawer = new AsyncTimeTextGroupRedrawer(this);
-       
-       txtNanosec.addFocusListener(this);
-       txtNanosec.addKeyListener(this);
-    }
-    
-    /**
-     * Getter for the layout data currently in use.<p>
-     * 
-     * @return the layout
-     */
-    public Object getLayoutData() {
-       return grpName.getLayoutData();
-    }
-    
-    /**
-     * Set a new layoutData for our control.<p>
-     * 
-     * @param layoutData       the new layout data
-     */
-    public void setLayoutData(Object layoutData) {
-       grpName.setLayoutData(layoutData);
-    } 
-    
-    /**
-     * Get the control's parent.<p>
-     * 
-     * @return Currently used parent
-     */
-    public Composite getParent() {
-       return grpName.getParent();
-    }
-    
-    /**
-     * Set a new parent for the control.<p>
-     * 
-     * @return Currently used parent
-     */
-    public void setParent(Composite newParent) {
-       grpName.setParent(newParent);
-       txtNanosec.setParent(newParent);
-       lblNanosec.setParent(newParent);
-    }
-    
-    
-    public boolean isDisposed() {
-        return grpName.isDisposed();
-    }
-    
-    /**
-     * Getter for the time value of the control.<p>
-     * 
-     * @return The nanoseconds time value
-     */
-    public long getValue() {
-       return timeValue;
-    }
-    
-    /**
-     * Set a new String value to the control.<p>
-     * Note : The String value will be converted in long before being applied;
-     *                         if any conversion error occur, 0 will be used. <p>
-     * 
-     * @param newTimeAsString  The value to convert and set.
-     */
-    public void setValue(String newTimeAsString) {
-       long timeAsLong = HistogramConstant.convertStringToNanoseconds(newTimeAsString);
-       setValue( timeAsLong );
-    }
-    
-    /**
-     * Set a new value to the control.<p>
-     * Note : The value will be formatted as nanosecond value, 
-     *                         missing zero will be added if needed.<p>
-     * 
-     * @param newTime  The value to set.
-     */
-    public void setValue(long newTime) {
-       timeValue = newTime;
-       txtNanosec.setText( HistogramConstant.formatNanoSecondsTime(newTime) );
-    }
-    
-    /**
-     * Set a new String value, asynchronously.<p>
-     * This will call setValue(String) in async.Exec to avoid Thread Access problem to UI.<p>
-     * 
-     * @param newTimeAsString  The value to convert and set.
-     */
-    public void setValueAsynchronously(String newTimeAsString) {
-       long timeAsLong = HistogramConstant.convertStringToNanoseconds(newTimeAsString);
-       setValueAsynchronously( timeAsLong );
-    }
-    
-    /**
-     * Set a new String value, asynchronously.<p>
-     * This will call setValue(long) in async.Exec to avoid Thread Access problem to UI.<p>
-     * 
-     * @param newTimeAsString  The value to set.
-     */
-    public void setValueAsynchronously(long newTime) {
-       // Set the correct value ASAP
-       timeValue = newTime;
-       
-       // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
-               if ( asyncRedrawer == null ) {
-                       asyncRedrawer = new AsyncTimeTextGroupRedrawer(this);
-               }
-               
-               asyncRedrawer.asynchronousSetValue(newTime);
-    }
-    
-    /**
-     * Set a new group name (label) for this control.<p>
-     * 
-     * @param newName  The new name to set.
-     */
-    public void setGroupName(String newName) {
-       grpName.setText(newName);
-    }
-    
-    /**
-     * Set a new group name (label) for this control, asynchronously.<p>
-     * This will call setValue(long) in async.Exec to avoid Thread Access problem to UI.<p>
-     * 
-     * @param newName  The new name to set.
-     */
-    public void setGroupNameAsynchronously(String newGroupName) {
-       // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
-               if ( asyncRedrawer == null ) {
-                       asyncRedrawer = new AsyncTimeTextGroupRedrawer(this);
-               }
-               
-               asyncRedrawer.asynchronousSetGroupName(newGroupName);
-    }
-    
-       
-       /**
-        * Method to call the "Asynchronous redrawer" for this time text group<p>
-        * This allow safe redraw from different threads.
-        */
-       public void redrawAsynchronously() {
-               // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
-               if ( asyncRedrawer == null ) {
-                       asyncRedrawer = new AsyncTimeTextGroupRedrawer(this);
-               }
-               
-               asyncRedrawer.asynchronousRedraw();
-       }
-       
-       /**
-        * Redraw the control
-        */
-       public void redraw () {
-               grpName.redraw();
-       txtNanosec.redraw();
-       lblNanosec.redraw();
-       }
-    
-    /*
-     * This function is called when an user enter a new string in the control by hand.<p>
-     * It will ensure the format of the String is valid.
-     */
-       protected void handleNewStringValue() {
-       String valueInText = txtNanosec.getText();
-               long valueAsLong = HistogramConstant.convertStringToNanoseconds(valueInText);
-               
-               if ( getValue() != valueAsLong ) {
-                       setValue(valueAsLong);
-                       // Notify our parent that the control was updated
-                       notifyParentUpdatedTextGroupValue();
-               }
-    }
-    
-    /**
-     * This function notify our parent HistogramView that our value changed.
-     */
-    public void notifyParentUpdatedTextGroupValue() {
-       parentView.timeTextGroupChangeNotification();
-    }
-    
-    /**
-        * Function that is called when the canvas get focus.<p>
-        * 
-        * Doesn't do anything yet... 
-        * 
-        * @param event  The focus event generated.
-        */
-       @Override
-       public void focusGained(FocusEvent event) {
-               // Nothing to do yet
-       }
-       
-       /**
-        * Function that is called when the canvas loose focus.<p>
-        * It will validate that the String entered by the user (if any) is valid.<p>
-        * 
-        * @param event  The focus event generated.
-        */
-       @Override
-       public void focusLost(FocusEvent event) {
-               handleNewStringValue();
-       }
-       
-       /**
-        * Function that is called when a key is pressed.<p>
-        * Possible actions : 
-        * - Enter (CR) : Validate the entered String.<p>
-        * 
-        * @param event  The KeyEvent generated when the key was pressed.
-        */
-       @Override
-       public void keyPressed(KeyEvent event) {
-               switch (event.keyCode) {
-                       // SWT.CR is "ENTER" Key
-                       case SWT.CR:
-                               handleNewStringValue();
-                               break;
-                       default:
-                               break;
-               }
-       }
-       
-       /**
-        * Function that is called when a key is released.<p>
-        * Possible actions : 
-        *              Nothing yet
-        * 
-        * @param event  The KeyEvent generated when the key was pressed.
-        */
-       @Override
-       public void keyReleased(KeyEvent e) {
-               
-       }
-}
-
-/**
- * <b><u>AsyncTimeTextGroupRedrawer Inner Class</u></b>
- * <p>
- * Asynchronous redrawer for the TimeTextGroup
- * <p>
- * This class role is to call method that update the UI on asynchronously. 
- * This should prevent any "invalid thread access" exception when trying to update UI from a different thread.
- */
-class AsyncTimeTextGroupRedrawer {
-       
-       private TimeTextGroup parentTimeTextGroup = null; 
-       
-       /**
-        * AsyncTimeTextGroupRedrawer constructor.
-        * 
-        * @param newParent     Related time text group.
-        */
-       public AsyncTimeTextGroupRedrawer(TimeTextGroup newParent) {
-               parentTimeTextGroup = newParent;
-       }
-       
-       /**
-        * Asynchronous SetValue for time text group.
-        * 
-        * Basically, it just run "getParent().setValue(time)" in asyncExec.
-        * 
-        * @param newTime       The new time to set
-        */
-       public void asynchronousSetValue(final long newTime) {
-               // Ignore setting of value if widget is disposed
-               if (parentTimeTextGroup.isDisposed()) return;
-               
-               Display display =  parentTimeTextGroup.getParent().getDisplay();
-               display.asyncExec(new Runnable() {
-                       @Override
-            public void run() {
-                               if (!parentTimeTextGroup.isDisposed()) {
-                                       parentTimeTextGroup.setValue(newTime);
-                               }
-                       }
-               });
-       }
-       
-       /**
-        * Asynchronous SetGroupName for time text group.
-        * 
-        * Basically, it just run "getParent().setGroupName(name)" in asyncExec.
-        * 
-        * @param newGroupName  The new group name to set
-        */
-       public void asynchronousSetGroupName(String newGroupName) {
-               // Ignore setting of name if widget is disposed
-               if (parentTimeTextGroup.isDisposed()) return;
-
-               final String tmpName = newGroupName;
-               Display display =  parentTimeTextGroup.getParent().getDisplay();
-               display.asyncExec(new Runnable() {
-                       @Override
-            public void run() {
-                               if (!parentTimeTextGroup.isDisposed()) {
-                                       parentTimeTextGroup.setGroupName(tmpName);
-                               }
-                       }
-               });
-       }
-       
-       /**
-        * Function to redraw the related time text group asynchonously.<p>
-        * 
-        * Basically, it just run "getParent().redraw()" in asyncExec.
-        * 
-        */
-       public void asynchronousRedraw() {
-               // Ignore redraw if widget is disposed
-               if (parentTimeTextGroup.isDisposed()) return;
-
-               Display display =  parentTimeTextGroup.getParent().getDisplay();
-               display.asyncExec(new Runnable() {
-                       @Override
-            public void run() {
-                               if (!parentTimeTextGroup.isDisposed()) {
-                                       parentTimeTextGroup.getParent().redraw();
-                               }
-                       }
-               });
-       }
-}
\ No newline at end of file
index f6d232292be6aa9c3803a953492aae1a69a0a522..2078673bfe08c260b828503d4b32317d56247418 100644 (file)
@@ -1,3 +1,2 @@
 HistogramView_currentEventLabel=Current Event (sec)
-HistogramView_windowCenterLabel=Window Center (sec)
 HistogramView_windowSpanLabel=Window Span (sec)
index 36670ef2c75971dcfd8806d99199aadd9c34653e..ba8e2999c9654cf3f5307f15593f5799162b6d32 100644 (file)
@@ -13,7 +13,7 @@
 package org.eclipse.linuxtools.lttng.ui.views.project.dialogs;
 
 import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.linuxtools.lttng.LttngException;
+import org.eclipse.linuxtools.lttng.exceptions.LttngException;
 import org.eclipse.linuxtools.lttng.trace.LTTngTraceVersion;
 import org.eclipse.linuxtools.lttng.ui.views.project.handlers.TraceErrorHandler;
 import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
index c836b188bcfbefb8b65250406ed7b2890c0eb1e7..73ee3033eb4b2020ffaef992f634bf857ac83d8b 100644 (file)
@@ -15,6 +15,7 @@ Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.linuxtools.lttng,
  org.eclipse.linuxtools.lttng.control,
  org.eclipse.linuxtools.lttng.event,
+ org.eclipse.linuxtools.lttng.exceptions,
  org.eclipse.linuxtools.lttng.model,
  org.eclipse.linuxtools.lttng.request,
  org.eclipse.linuxtools.lttng.signal,
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngException.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngException.java
deleted file mode 100644 (file)
index 36de9fa..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.eclipse.linuxtools.lttng;
-
-/**
- * <b><u>LttngException</u></b>
- * <p>
- * Super exception class for Lttng
- */
-public class LttngException extends Exception {
-       static final long serialVersionUID = 4016530589556719360L;
-
-    public LttngException(String errMsg) {
-        super(errMsg);
-    }
-}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/exceptions/EventOutOfSequenceException.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/exceptions/EventOutOfSequenceException.java
new file mode 100644 (file)
index 0000000..5e00280
--- /dev/null
@@ -0,0 +1,17 @@
+/**
+ * 
+ */
+package org.eclipse.linuxtools.lttng.exceptions;
+
+/**
+ * @author francois
+ *
+ */
+public class EventOutOfSequenceException extends Exception {
+
+       private static final long serialVersionUID = -3537822357348706661L;
+
+       public EventOutOfSequenceException(String errMsg) {
+        super(errMsg);
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/exceptions/LttngException.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/exceptions/LttngException.java
new file mode 100644 (file)
index 0000000..00226c8
--- /dev/null
@@ -0,0 +1,14 @@
+package org.eclipse.linuxtools.lttng.exceptions;
+
+/**
+ * <b><u>LttngException</u></b>
+ * <p>
+ * Super exception class for Lttng
+ */
+public class LttngException extends Exception {
+       static final long serialVersionUID = 4016530589556719360L;
+
+    public LttngException(String errMsg) {
+        super(errMsg);
+    }
+}
index 060cad3a0e5b249eddfed967cd9ddc555f0aed72..ae5b10d658347b93a9ab6999647cc045561c1a4f 100644 (file)
@@ -16,7 +16,6 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Vector;
 
-import org.eclipse.linuxtools.lttng.LttngException;
 import org.eclipse.linuxtools.lttng.event.LttngEvent;
 import org.eclipse.linuxtools.lttng.event.LttngEventContent;
 import org.eclipse.linuxtools.lttng.event.LttngEventReference;
@@ -24,6 +23,7 @@ import org.eclipse.linuxtools.lttng.event.LttngEventSource;
 import org.eclipse.linuxtools.lttng.event.LttngEventType;
 import org.eclipse.linuxtools.lttng.event.LttngLocation;
 import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
+import org.eclipse.linuxtools.lttng.exceptions.LttngException;
 import org.eclipse.linuxtools.lttng.jni.JniEvent;
 import org.eclipse.linuxtools.lttng.jni.JniMarker;
 import org.eclipse.linuxtools.lttng.jni.JniTrace;
index 884af99e34ba9417ed26f3c3f3638d99b876ff9c..6532aed227cd74db35a42dcd023739a5551eaa36 100644 (file)
@@ -11,7 +11,7 @@ package org.eclipse.linuxtools.lttng.trace;
  *   William Bourque (wbourque@gmail.com) - Initial API and implementation
  *******************************************************************************/
 
-import org.eclipse.linuxtools.lttng.LttngException;
+import org.eclipse.linuxtools.lttng.exceptions.LttngException;
 import org.eclipse.linuxtools.lttng.jni.exception.JniTraceVersionException;
 import org.eclipse.linuxtools.lttng.jni.factory.JniTraceVersion;
 
index 9e9f1bd1597fcd43d8be3cba535242bf8297b45a..2989b8d29a9d7f5d88b02d28b7863da148e9dbdc 100644 (file)
@@ -1555,6 +1555,8 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                // the method fTrace.getRank() from interfering and delaying ongoing requests.\r
                final TmfDataRequest<TmfEvent> subRequest = new TmfDataRequest<TmfEvent>(TmfEvent.class, 0, 1, ExecutionType.FOREGROUND) {\r
 \r
+                       TmfTimestamp ts = new TmfTimestamp(signal.getCurrentTime());\r
+                       \r
                        @Override\r
                        public void handleData(TmfEvent event) {\r
                                super.handleData(event);\r
@@ -1565,7 +1567,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
 \r
                                // Verify if event is within the trace range\r
                                final TmfTimestamp timestamp[] = new TmfTimestamp[1];\r
-                               timestamp[0] = signal.getCurrentTime();\r
+                               timestamp[0] = ts; // signal.getCurrentTime();\r
                                if (timestamp[0].compareTo(fTrace.getStartTime(), true) == -1) {\r
                                        timestamp[0] = fTrace.getStartTime();\r
                                }\r
index 61f90eddad98214d54c29d619e09691c2fcd97ae..b73b0d7fce76415e62fac8e0c14e58e0bb684fd5 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009 Ericsson
+ * Copyright (c) 2009, 2011 Ericsson
  * 
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -18,25 +18,24 @@ import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
 /**
  * <b><u>TmfRangeSynchSignal</u></b>
  * <p>
- * TODO: Implement me. Please.
  */
 public class TmfRangeSynchSignal extends TmfSignal {
 
-       private final TmfTimeRange fCurrentRange;
-       private final TmfTimestamp fCurrentTime;
+    private final TmfTimeRange fCurrentRange;
+    private final TmfTimestamp fCurrentTime;
 
-       public TmfRangeSynchSignal(Object source, TmfTimeRange range, TmfTimestamp ts) {
-               super(source);
-               fCurrentRange = range;
-               fCurrentTime = ts;
-       }
+    public TmfRangeSynchSignal(Object source, TmfTimeRange range, TmfTimestamp ts) {
+        super(source);
+        fCurrentRange = range;
+        fCurrentTime = ts;
+    }
 
-       public TmfTimeRange getCurrentRange() {
-               return fCurrentRange;
-       }
+    public TmfTimeRange getCurrentRange() {
+        return fCurrentRange;
+    }
 
-       public TmfTimestamp getCurrentTime() {
-               return fCurrentTime;
-       }
+    public TmfTimestamp getCurrentTime() {
+        return fCurrentTime;
+    }
 
 }
This page took 0.117481 seconds and 5 git commands to generate.