(no commit message)
authorAlvaro Sanchez-Leon <alvsan09@gmail.com>
Mon, 31 May 2010 19:22:58 +0000 (19:22 +0000)
committerAlvaro Sanchez-Leon <alvsan09@gmail.com>
Mon, 31 May 2010 19:22:58 +0000 (19:22 +0000)
119 files changed:
org.eclipse.linuxtools.lttng.ui/.classpath [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/.project [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/META-INF/MANIFEST.MF [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/build.properties [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/LTTng.png [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/control_flow_view.gif [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/control_view.gif [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/events_view.gif [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/garland16.png [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/garland32.png [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/histogram.gif [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/project_view.gif [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/resources_view.gif [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/statistics_view.gif [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/icons/time_frame_view.gif [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/plugin.properties [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/plugin.xml [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/LTTngUiPlugin.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/TraceDebug.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/ITimeRangeComponent.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/ItemContainer.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeComponent.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeComposite.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEvent.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEventProcess.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEventResource.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeResourceFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeViewerProvider.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/PerspectiveFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/AbsTRangeUpdate.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/AbsTimeUpdateView.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/ParamsUpdater.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/control/ControlView.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/ControlFlowView.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/Messages.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/AbsFlowTRangeUpdate.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowAfterUpdateHandlers.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowBeforeUpdateHandlers.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowEventToHandlerFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowFinishUpdateHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/messages.properties [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/model/FlowModelFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/model/FlowProcessContainer.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/events/EventsView.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ChildrenHistogramCanvas.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasControlListener.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasKeyListener.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasMouseListener.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramView.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvas.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasPaintListener.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeTextGroup.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/LTTngProjectNature.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/ProjectView.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/AddTraceWizard.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/AddTraceWizardPage.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/DialogTraceContentProvider.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/DialogTraceLabelProvider.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/ImportTraceWizard.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/ImportTraceWizardPage.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewExperimentDialog.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewProjectMainWizardPage.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewProjectWizard.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/TraceErrorDialog.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/CloseProjectHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteExperimentHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteProjectHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteTraceHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/ImportTraceHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/NewExperimentHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/NewProjectHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenExperimentHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenProjectHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenTraceHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RefreshHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameExperimentHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameProjectHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameTraceHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/SelectTracesHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/TraceErrorHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/ILTTngProjectTreeNode.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngExperimentFolderNode.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngExperimentNode.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectContentProvider.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectLabelProvider.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectNode.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectRoot.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectTreeNode.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngTraceFolderNode.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngTraceNode.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/Messages.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/ResourcesView.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/AbsResourcesTRangeUpdate.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesAfterUpdateHandlers.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesBeforeUpdateHandlers.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesEventToHandlerFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesFinishUpdateHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/messages.properties [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/model/ResourceContainer.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/model/ResourceModelFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/StatisticsView.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/AbstractStatsEventHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsModeChangeHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsModeEndHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsTimeCountHandlerFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsTimeCountHandlers.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/Statistics.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/StatisticsTreeNode.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/StatisticsTreeRootFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/timeframe/SpinnerGroup.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/timeframe/TimeFrameView.java [new file with mode: 0644]

diff --git a/org.eclipse.linuxtools.lttng.ui/.classpath b/org.eclipse.linuxtools.lttng.ui/.classpath
new file mode 100644 (file)
index 0000000..64c5e31
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.linuxtools.lttng.ui/.project b/org.eclipse.linuxtools.lttng.ui/.project
new file mode 100644 (file)
index 0000000..b6f70c2
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.eclipse.linuxtools.lttng.ui</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.eclipse.linuxtools.lttng.ui/META-INF/MANIFEST.MF b/org.eclipse.linuxtools.lttng.ui/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..dfce508
--- /dev/null
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.linuxtools.lttng.ui;singleton:=true
+Bundle-Version: 0.2.0.qualifier
+Bundle-Activator: org.eclipse.linuxtools.lttng.ui.LTTngUiPlugin
+Bundle-Vendor: %Bundle-Vendor
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.ui.ide,
+ org.eclipse.core.resources,
+ org.eclipse.core.filesystem,
+ org.eclipse.core.runtime,
+ org.eclipse.linuxtools.tmf;bundle-version="0.2.0",
+ org.eclipse.linuxtools.tmf.ui;bundle-version="0.2.0",
+ org.eclipse.linuxtools.lttng;bundle-version="0.2.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
diff --git a/org.eclipse.linuxtools.lttng.ui/build.properties b/org.eclipse.linuxtools.lttng.ui/build.properties
new file mode 100644 (file)
index 0000000..6b4afb7
--- /dev/null
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               icons/,\
+               plugin.properties
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/LTTng.png b/org.eclipse.linuxtools.lttng.ui/icons/LTTng.png
new file mode 100644 (file)
index 0000000..3083054
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/LTTng.png differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/control_flow_view.gif b/org.eclipse.linuxtools.lttng.ui/icons/control_flow_view.gif
new file mode 100644 (file)
index 0000000..3971b50
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/control_flow_view.gif differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/control_view.gif b/org.eclipse.linuxtools.lttng.ui/icons/control_view.gif
new file mode 100644 (file)
index 0000000..0dc862c
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/control_view.gif differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/events_view.gif b/org.eclipse.linuxtools.lttng.ui/icons/events_view.gif
new file mode 100644 (file)
index 0000000..1ef74cf
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/events_view.gif differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/garland16.png b/org.eclipse.linuxtools.lttng.ui/icons/garland16.png
new file mode 100644 (file)
index 0000000..74f9751
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/garland16.png differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/garland32.png b/org.eclipse.linuxtools.lttng.ui/icons/garland32.png
new file mode 100644 (file)
index 0000000..3083054
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/garland32.png differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/histogram.gif b/org.eclipse.linuxtools.lttng.ui/icons/histogram.gif
new file mode 100644 (file)
index 0000000..dd2dda5
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/histogram.gif differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/project_view.gif b/org.eclipse.linuxtools.lttng.ui/icons/project_view.gif
new file mode 100644 (file)
index 0000000..4b98a62
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/project_view.gif differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/resources_view.gif b/org.eclipse.linuxtools.lttng.ui/icons/resources_view.gif
new file mode 100644 (file)
index 0000000..2344861
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/resources_view.gif differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/statistics_view.gif b/org.eclipse.linuxtools.lttng.ui/icons/statistics_view.gif
new file mode 100644 (file)
index 0000000..d11c996
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/statistics_view.gif differ
diff --git a/org.eclipse.linuxtools.lttng.ui/icons/time_frame_view.gif b/org.eclipse.linuxtools.lttng.ui/icons/time_frame_view.gif
new file mode 100644 (file)
index 0000000..c984fba
Binary files /dev/null and b/org.eclipse.linuxtools.lttng.ui/icons/time_frame_view.gif differ
diff --git a/org.eclipse.linuxtools.lttng.ui/plugin.properties b/org.eclipse.linuxtools.lttng.ui/plugin.properties
new file mode 100644 (file)
index 0000000..75b2914
--- /dev/null
@@ -0,0 +1,28 @@
+#Properties file for org.eclipse.linuxtools.lttng.ui
+Bundle-Name = Linux Tracing Toolkit (LTTng) UI (Incubation)
+Bundle-Vendor = Eclipse Linux Tools
+
+# org.eclipse.ui.perspectives
+extension.name.0 = LTTng Perspective
+perspective.name = LTTng
+
+# org.eclipse.ui.views
+extension.name.1 = LTTng Views
+category.name = LTTng
+view.name.0 = Project
+view.name.1 = Control
+view.name.2 = Events
+view.name.3 = Time Frame
+view.name.4 = Control Flow
+view.name.5 = Resources
+view.name.6 = Statistics
+view.name.7 = Histogram
+
+# org.eclipse.ui.newWizards
+extension.name.2 = LTTng New Wizards
+category.name.0 = LTTng
+wizard.name.0 = LTTng Project
+wizard.description.0 = Create an LTTng project
+
+# org.eclipse.core.resources.natures
+extension.name.3 = LTTng Project Nature
diff --git a/org.eclipse.linuxtools.lttng.ui/plugin.xml b/org.eclipse.linuxtools.lttng.ui/plugin.xml
new file mode 100644 (file)
index 0000000..55bf508
--- /dev/null
@@ -0,0 +1,416 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="org,eclipse.linuxtools.lttng.ui.perspective"
+         name="%extension.name.0"
+         point="org.eclipse.ui.perspectives">
+      <perspective
+            class="org.eclipse.linuxtools.lttng.ui.views.PerspectiveFactory"
+            icon="icons/garland32.png"
+            id="org.eclipse.linuxtools.lttng.ui.perspective"
+            name="%perspective.name">
+      </perspective>
+   </extension>
+   <extension
+         id="org.eclipse.linuxtools.lttng.ui.views"
+         name="%extension.name.1"
+         point="org.eclipse.ui.views">
+      <category
+            id="org.eclipse.linuxtools.lttng.ui.views.category"
+            name="%category.name">
+      </category>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng.ui.views.category"
+            class="org.eclipse.linuxtools.lttng.ui.views.project.ProjectView"
+            icon="icons/project_view.gif"
+            id="org.eclipse.linuxtools.lttng.ui.views.project"
+            name="%view.name.0"
+            restorable="true">
+      </view>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng.ui.views.category"
+            class="org.eclipse.linuxtools.lttng.ui.views.control.ControlView"
+            icon="icons/control_view.gif"
+            id="org.eclipse.linuxtools.lttng.ui.views.control"
+            name="%view.name.1"
+            restorable="true">
+      </view>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng.ui.views.category"
+            class="org.eclipse.linuxtools.lttng.ui.views.events.EventsView"
+            icon="icons/events_view.gif"
+            id="org.eclipse.linuxtools.lttng.ui.views.events"
+            name="%view.name.2"
+            restorable="true">
+      </view>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng.ui.views.category"
+            class="org.eclipse.linuxtools.lttng.ui.views.timeframe.TimeFrameView"
+            icon="icons/time_frame_view.gif"
+            id="org.eclipse.linuxtools.lttng.ui.views.timeframe"
+            name="%view.name.3"
+            restorable="true">
+      </view>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng.ui.views.category"
+            class="org.eclipse.linuxtools.lttng.ui.views.controlflow.ControlFlowView"
+            icon="icons/control_flow_view.gif"
+            id="org.eclipse.linuxtools.lttng.ui.views.controlflow"
+            name="%view.name.4"
+            restorable="true">
+      </view>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng.ui.views.category"
+            class="org.eclipse.linuxtools.lttng.ui.views.resources.ResourcesView"
+            icon="icons/resources_view.gif"
+            id="org.eclipse.linuxtools.lttng.ui.views.resources"
+            name="%view.name.5"
+            restorable="true">
+      </view>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng.ui.views.category"
+            class="org.eclipse.linuxtools.lttng.ui.views.statistics.StatisticsView"
+            icon="icons/statistics_view.gif"
+            id="org.eclipse.linuxtools.lttng.ui.views.statistics"
+            name="%view.name.6"
+            restorable="true">
+      </view>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng.ui.views.category"
+            class="org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramView"
+            icon="icons/histogram.gif"
+            id="org.eclipse.linuxtools.lttng.ui.views.histogram"
+            name="%view.name.7"
+            restorable="true">
+      </view>
+   </extension>
+   <extension
+         id="org.eclipse.linuxtools.lttng.wizards.new"
+         name="%extension.name.2"
+         point="org.eclipse.ui.newWizards">
+      <category
+            id="org.eclipse.linuxtools.lttng.ui.wizards.new"
+            name="%category.name.0">
+      </category>
+      <wizard
+            category="org.eclipse.linuxtools.lttng.ui.wizards.new"
+            class="org.eclipse.linuxtools.lttng.ui.views.project.dialogs.NewProjectWizard"
+            descriptionImage="icons/garland16.png"
+            finalPerspective="org.eclipse.linuxtools.lttng.ui.perspective"
+            icon="icons/garland16.png"
+            id="org.eclipse.linuxtools.lttng.ui.views.ui.wizards.newProject"
+            name="%wizard.name.0"
+            project="true">
+         <description>
+            %wizard.description.0
+         </description>
+      </wizard>
+   </extension>
+   <extension
+         id="org.eclipse.linuxtools.lttng.ui.views.project.LTTngProjectNature"
+         name="%extension.name.3"
+         point="org.eclipse.core.resources.natures">
+      <runtime>
+         <run
+               class="org.eclipse.linuxtools.lttng.ui.views.project.LTTngProjectNature">
+         </run>
+      </runtime>
+   </extension>
+   <extension
+         id="org.eclipse.linuxtools.lttng.ui.actionSets"
+         name="LTTng Action Sets"
+         point="org.eclipse.ui.actionSets">
+      <actionSet
+            description="LTTng Action Set"
+            id="org.eclipse.linuxtools.lttng.ui.actionSet"
+            label="LTTng Action Set"
+            visible="true">
+      </actionSet>
+   </extension>
+   <extension
+         id="org.eclipse.linuxtools.lttng.ui.commands"
+         name="LTTng Commands"
+         point="org.eclipse.ui.commands">
+      <category
+            description="LTTng Project Commands"
+            id="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            name="LTTng Project Commands">
+      </category>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Create an LTTng Project"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.new"
+            name="New Project">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Open an LTTng Project"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.open"
+            name="Open Project">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Close an LTTng Project"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.close"
+            name="Close Project">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Rename an LTTng Project"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.rename"
+            name="Rename Project">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Delete an LTTng Project"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.delete"
+            name="Delete Project">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Import an LTTng Trace"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.trace.import"
+            name="Import Trace">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Open an LTTng Trace"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.trace.open"
+            name="Open Trace">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Rename an LTTng Trace"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.trace.rename"
+            name="Rename Trace">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Delete an LTTng Trace"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.trace.delete"
+            name="Delete Trace">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Create an LTTng Experiment"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.experiment.new"
+            name="New Experiment">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Select LTTng Traces"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.experiment.select"
+            name="Select Traces">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Open an LTTng Experiment"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.experiment.open"
+            name="Open Experiment">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Rename an LTTng Experiment"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.experiment.rename"
+            name="Rename Experiment">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Delete an LTTng Experiment"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.experiment.delete"
+            name="Delete Experiment">
+      </command>
+      <command
+            categoryId="org.eclipse.linuxtools.lttng.ui.commands.project.category"
+            description="Refresh View"
+            id="org.eclipse.linuxtools.lttng.ui.command.project.refresh"
+            name="Refresh View">
+      </command>
+   </extension>
+   <extension
+         id="org.eclipse.linuxtools.lttng.ui.menus"
+         name="LTTng Menus"
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            locationURI="popup:org.eclipse.linuxtools.lttng.ui.views.project?after=additions">
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.new"
+               icon="icons/garland16.png"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.new"
+               label="New Project"
+               style="push">
+         </command>
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.open"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.open"
+               label="Open Project"
+               style="push">
+         </command>
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.close"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.close"
+               label="Close Project"
+               style="push">
+         </command>
+         <!-- command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.rename"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.rename"
+               label="Rename Project"
+               style="push">
+         </command -->
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.delete"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.delete"
+               label="Delete Project"
+               style="push">
+         </command>
+         <separator
+               name="org.eclipse.linuxtools.lttng.ui.menu.popup.project.separator1"
+               visible="true">
+         </separator>
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.new"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.experiment.new"
+               label="New Experiment"
+               style="push">
+         </command>
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.select"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.experiment.select"
+               label="Select Traces"
+               style="push">
+         </command>
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.open"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.experiment.open"
+               label="Open Experiment"
+               style="push">
+         </command>
+         <!-- command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.rename"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.experiment.rename"
+               label="Rename Experiment"
+               style="push">
+         </command -->
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.delete"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.experiment.delete"
+               label="Delete Experiment"
+               style="push">
+         </command>
+         <separator
+               name="org.eclipse.linuxtools.lttng.ui.menu.popup.project.separator2"
+               visible="true">
+         </separator>
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.trace.import"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.trace.import"
+               label="Import Traces"
+               style="push">
+         </command>
+         <!-- command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.trace.open"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.trace.open"
+               label="Open Trace"
+               style="push">
+         </command -->
+         <!-- command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.trace.rename"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.trace.rename"
+               label="Rename Trace"
+               style="push">
+         </command -->
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.trace.delete"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.trace.delete"
+               label="Delete Trace"
+               style="push">
+         </command>
+         <separator
+               name="org.eclipse.linuxtools.lttng.ui.menu.popup.project.separator3"
+               visible="true">
+         </separator>
+         <command
+               commandId="org.eclipse.linuxtools.lttng.ui.command.project.refresh"
+               id="org.eclipse.linuxtools.lttng.ui.menu.popup.project.refresh"
+               label="Refresh View"
+               style="push">
+         </command>
+      </menuContribution>
+   </extension>
+   <extension
+         id="org.eclipse.linuxtools.lttng.ui.handlers"
+         name="LTTng Command Handlers"
+         point="org.eclipse.ui.handlers">
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.NewProjectHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.new">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.OpenProjectHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.open">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.CloseProjectHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.close">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.RenameProjectHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.rename">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.DeleteProjectHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.delete">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.ImportTraceHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.trace.import">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.OpenTraceHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.trace.open">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.RenameTraceHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.trace.rename">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.DeleteTraceHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.trace.delete">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.NewExperimentHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.new">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.SelectTracesHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.select">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.OpenExperimentHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.open">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.RenameExperimentHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.rename">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.DeleteExperimentHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.experiment.delete">
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.lttng.ui.views.project.handlers.RefreshHandler"
+            commandId="org.eclipse.linuxtools.lttng.ui.command.project.refresh">
+      </handler>
+   </extension>
+
+</plugin>
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/LTTngUiPlugin.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/LTTngUiPlugin.java
new file mode 100644 (file)
index 0000000..460ed6a
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class LTTngUiPlugin extends AbstractUIPlugin {
+
+       // The plug-in ID
+       public static final String PLUGIN_ID = "org.eclipse.linuxtools.lttng.ui";
+
+       // The shared instance
+       private static LTTngUiPlugin plugin;
+       
+       /**
+        * The constructor
+        */
+       public LTTngUiPlugin() {
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+        */
+       @Override
+       public void start(BundleContext context) throws Exception {
+               super.start(context);
+               TraceDebug.init();
+               plugin = this;
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+        */
+       @Override
+       public void stop(BundleContext context) throws Exception {
+               plugin = null;
+               super.stop(context);
+       }
+
+       /**
+        * Returns the shared instance
+        *
+        * @return the shared instance
+        */
+       public static LTTngUiPlugin getDefault() {
+               return plugin;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/TraceDebug.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/TraceDebug.java
new file mode 100644 (file)
index 0000000..c0b24d2
--- /dev/null
@@ -0,0 +1,132 @@
+package org.eclipse.linuxtools.lttng.ui;\r
+\r
+import java.text.SimpleDateFormat;\r
+import java.util.Date;\r
+\r
+import org.eclipse.core.runtime.ILog;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.core.runtime.Plugin;\r
+import org.eclipse.core.runtime.Status;\r
+\r
+public class TraceDebug {\r
+       static boolean DEBUG = false;\r
+       static boolean INFO = false;\r
+       static boolean WARN = false;\r
+\r
+       private static Plugin plugin = LTTngUiPlugin.getDefault();\r
+       private static String pluginID = LTTngUiPlugin.PLUGIN_ID;\r
+       private static SimpleDateFormat stimeformat = new SimpleDateFormat(\r
+                       "HH:mm:ss:SSS");\r
+\r
+       public static void init() {\r
+               // Update Trace configuration options\r
+               String debugTrace = Platform.getDebugOption(pluginID + "/debug");\r
+               String infoTrace = Platform.getDebugOption(pluginID + "/info");\r
+               String warnTrace = Platform.getDebugOption(pluginID + "/warn");\r
+\r
+               if (debugTrace != null) {\r
+                       DEBUG = (new Boolean(debugTrace)).booleanValue();\r
+               }\r
+\r
+               if (infoTrace != null) {\r
+                       INFO = (new Boolean(infoTrace)).booleanValue();\r
+               }\r
+\r
+               if (warnTrace != null) {\r
+                       WARN = (new Boolean(warnTrace)).booleanValue();\r
+               }\r
+       }\r
+\r
+       public static void info(String message) {\r
+               if (INFO) {\r
+                       ILog logger = plugin.getLog();\r
+                       logger.log(new Status(IStatus.INFO, LTTngUiPlugin.PLUGIN_ID,\r
+                                       IStatus.OK, message, null));\r
+               }\r
+       }\r
+\r
+       public static void warn(String message) {\r
+               if (WARN) {\r
+                       ILog logger = plugin.getLog();\r
+                       logger.log(new Status(IStatus.WARNING, LTTngUiPlugin.PLUGIN_ID,\r
+                                       IStatus.WARNING, message, null));\r
+               }\r
+       }\r
+\r
+       public static void debug(String message) {\r
+               if (DEBUG) {\r
+                       String location = getCallingLocation();\r
+                       System.out.println(location + "\n\t-> " + message);\r
+\r
+               }\r
+       }\r
+\r
+       public static void debug(String message, int additionalStackLines) {\r
+               if (DEBUG) {\r
+                       String location = getCallingLocation(additionalStackLines);\r
+                       System.out.println(location + "\n\t-> " + message);\r
+               }\r
+       }\r
+\r
+       public static void throwException(String message) {\r
+               if (DEBUG) {\r
+                       try {\r
+                               triggerException(message);\r
+                       } catch (Exception e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+       }\r
+\r
+       private static void triggerException(String message) throws Exception {\r
+               throw new Exception(message);\r
+       }\r
+\r
+       private static String getCallingLocation() {\r
+               StringBuilder sb = new StringBuilder();\r
+               sb.append(trace(Thread.currentThread().getStackTrace(), 4));\r
+               sb.append("\n" + trace(Thread.currentThread().getStackTrace(), 3));\r
+               return sb.toString();\r
+       }\r
+\r
+       private static String getCallingLocation(int numOfStackLines) {\r
+               int stackCalledFromIdx = 3;\r
+               int earliestRequested = numOfStackLines > 0 ? stackCalledFromIdx\r
+                               + numOfStackLines : stackCalledFromIdx;\r
+               StringBuilder sb = new StringBuilder();\r
+               for (int i = earliestRequested; i >= stackCalledFromIdx; i--) {\r
+                       sb.append(trace(Thread.currentThread().getStackTrace(), i) + "\n");\r
+               }\r
+               return sb.toString();\r
+       }\r
+\r
+       private static String trace(StackTraceElement e[], int level) {\r
+               if (e != null) {\r
+                       level = level >= e.length ? e.length - 1 : level;\r
+                       StackTraceElement s = e[level];\r
+                       if (s != null) {\r
+                               String simpleClassName = s.getClassName();\r
+                               String[] clsNameSegs = simpleClassName.split("\\.");\r
+                               if (clsNameSegs.length > 0)\r
+                                       simpleClassName = clsNameSegs[clsNameSegs.length - 1];\r
+                               return stimeformat.format(new Date()) + " " + simpleClassName\r
+                                               + "." + s.getLineNumber() + "." + s.getMethodName();\r
+                       }\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       public static boolean isDEBUG() {\r
+               return DEBUG;\r
+       }\r
+\r
+       public static boolean isINFO() {\r
+               return INFO;\r
+       }\r
+\r
+       public static boolean isWARN() {\r
+               return WARN;\r
+       }\r
+}\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/ITimeRangeComponent.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/ITimeRangeComponent.java
new file mode 100644 (file)
index 0000000..9cb42a5
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.model.trange;
+
+/**
+ * The common component of the Composite related to time-range events its
+ * components or containers
+ * 
+ * @author alvaro
+ * 
+ */
+public interface ITimeRangeComponent {
+
+       public long getStartTime();
+
+       public void setStartTime(long startTime);
+
+       public long getStopTime();
+
+       public void setStopTime(long endTime);
+
+       public ITimeRangeComponent getEventParent();
+
+       public String getName();
+
+       /**
+        * Flag to indicate if this Time Range is visible within the GUI, May not be
+        * visible if the duration can not be represented in one pixel
+        * 
+        * @return true if visible i.e. represented at least in one pixel
+        */
+       public boolean isVisible();
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/ItemContainer.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/ItemContainer.java
new file mode 100644 (file)
index 0000000..89298be
--- /dev/null
@@ -0,0 +1,53 @@
+package org.eclipse.linuxtools.lttng.ui.model.trange;
+
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
+
+public interface ItemContainer<T extends ITmfTimeAnalysisEntry> {
+
+       /**
+        * Interface to add resources.
+        * 
+        * @param process
+        */
+       public abstract void addItem(T newItem);
+
+       // ========================================================================
+       // Methods
+       // ========================================================================
+       /**
+        * Request a unique ID
+        * 
+        * @return Integer
+        */
+       public abstract Integer getUniqueId();
+
+       /**
+        * This method is intended for read only purposes in order to keep the
+        * internal data structure in Synch
+        * 
+        * @return
+        */
+       public abstract T[] readItems();
+
+       /**
+        * Clear the children information for resources related to a specific trace
+        * e.g. just before refreshing data with a new time range
+        * 
+        * @param traceId
+        */
+       public abstract void clearChildren();
+
+       /**
+        * Clear all resources items e.g. when a new experiment is selected
+        */
+       public abstract void clearItems();
+
+       /**
+        * Remove the resources related to a specific trace e.g. during trace
+        * removal
+        * 
+        * @param traceId
+        */
+       public abstract void removeItems(String traceId);
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeComponent.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeComponent.java
new file mode 100644 (file)
index 0000000..d7a4fc2
--- /dev/null
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.model.trange;
+
+
+/**
+ * @author alvaro
+ * 
+ */
+public abstract class TimeRangeComponent implements ITimeRangeComponent {
+
+       // ========================================================================
+       // Data
+       // =======================================================================
+       protected Long startTime = 0L;
+       protected Long stopTime = Long.MAX_VALUE;
+       protected TimeRangeComposite eventParent = null;
+       private boolean visible = true;
+       
+
+
+       // ========================================================================
+       // Constructor
+       // =======================================================================
+       public TimeRangeComponent(Long stime, Long etime,
+                       TimeRangeComposite eventParent) {
+               this.startTime = stime;
+               this.stopTime = etime;
+               this.eventParent = eventParent;
+       }
+
+       // ========================================================================
+       // Methods
+       // =======================================================================
+       /**
+        * This method shall not be used to estimate the starting drawing point of
+        * the time range-event. see interface method getTime(). However this method
+        * can be used to retrieve the tool tip information where we need to reflect
+        * that the actual start of this event is unknown
+        * 
+        * @param time
+        */
+       public long getStartTime() {
+               return startTime.longValue();
+       }
+
+       public void setStartTime(long time) {
+               if (time > -1) {
+                       startTime = time;
+               }
+       }
+
+       public long getStopTime() {
+               return stopTime.longValue();
+       }
+
+       public void setStopTime(long stopTime) {
+               if (stopTime > -1) {
+                       this.stopTime = stopTime;
+               }
+       }
+
+       public ITimeRangeComponent getEventParent() {
+               return eventParent;
+       }
+
+       public void setEventParent(TimeRangeComposite eventParent) {
+               this.eventParent = eventParent;
+       }
+
+       public abstract String getName();
+
+       
+       public void setVisible(boolean visible) {
+               this.visible = visible;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.ui.model.trange.ITimeRangeComponent#isVisible()
+        */
+       public boolean isVisible() {
+               return visible;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeComposite.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeComposite.java
new file mode 100644 (file)
index 0000000..7cf42f2
--- /dev/null
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.model.trange;
+
+import java.util.Vector;
+
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
+
+public class TimeRangeComposite extends TimeRangeComponent implements
+ITmfTimeAnalysisEntry {
+
+       // ========================================================================
+       // Data
+       // =======================================================================
+       /**
+        * Type of Composites or Containers
+        * <p>
+        * PROPERTY: Refers to a sub-composite of a RESOURCE or a PROCESS e.g the
+        * cpu which can vary over time and can have time range events associated to
+        * it, and at the same time PROPERTY is associated to a Composite parent
+        * like a PROCESS
+        * </p>
+        * <p>
+        * PROCESS: A composite of time range events representing a Process
+        * </p>
+        * <p>
+        * RESOURCE: A composite of time range events representing a resource i.g.
+        * irq, softIrq, trap, bdev, cpu
+        * </p>
+        * 
+        * @author alvaro
+        * 
+        */
+       public static enum CompositeType {
+               UNKNOWN, PROPERTY, PROCESS, RESOURCE
+       }
+
+       protected final Vector<TimeRangeComponent> ChildEventLeafs = new Vector<TimeRangeComponent>();
+       protected final Vector<TimeRangeComponent> ChildEventComposites = new Vector<TimeRangeComponent>();
+       protected Integer id = 0;
+       protected String name;
+       protected String groupName = "";
+       protected String className = "";
+       protected CompositeType contType = CompositeType.UNKNOWN;
+       protected Long next_good_time = -1L;
+       /*Time of first event which trigger the creation of this local resource */
+       protected Long insertionTime = -1L; 
+
+       // ========================================================================
+       // Constructors
+       // =======================================================================
+       public TimeRangeComposite(Integer id, Long stime, Long etime, String name,
+                       CompositeType type, long insertionTime) {
+               super(stime, etime, null);
+               this.id = id;
+               this.name = name;
+               contType = type;
+               this.insertionTime = insertionTime;
+               // Adjust the first good drawing position to the event time creating this resource
+               next_good_time = insertionTime;
+       }
+
+       public TimeRangeComposite(Integer id, Long stime, Long etime, String name,
+                       String groupName, String className, CompositeType type,
+                       long insertionTime) {
+               this(id, stime, etime, name, type, insertionTime);
+               this.groupName = groupName;
+               this.className = className;
+    }
+       
+       // ========================================================================
+       // Methods
+       // =======================================================================
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeComponent#getName()
+        */
+       @Override
+       public String getName() {
+               return name;
+       }
+
+       /**
+        * @param name
+        */
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.
+        * ITmfTimeAnalysisEntry#getGroupName()
+        */
+       public String getGroupName() {
+               return groupName;
+       }
+
+       /**
+        * @param groupName
+        */
+       public void setGroupName(String groupName) {
+               this.groupName = groupName;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.
+        * ITmfTimeAnalysisEntry#getId()
+        */
+       public int getId() {
+               return id;
+       }
+
+       /**
+        * @param id
+        */
+       public void setId(int id) {
+               this.id = id;
+       }
+
+       /**
+        * @return
+        */
+       public String getClassName() {
+               return className;
+       }
+
+       /**
+        * @param className
+        */
+       public void setClassName(String className) {
+               this.className = className;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.
+        * ITmfTimeAnalysisEntry#getTraceEvents()
+        */
+       @SuppressWarnings("unchecked")
+       public Vector<TimeRangeComponent> getTraceEvents() {
+               return ChildEventLeafs;
+       }
+
+       /**
+        * @return
+        */
+       public Vector<TimeRangeComponent> getChildEventComposites() {
+               return ChildEventComposites;
+       }
+
+       /**
+        * Represents the time where the next time range can start the drawing i.e.
+        * right after previous time range.
+        * 
+        * @return
+        */
+       public long getNext_good_time() {
+               return next_good_time;
+       }
+
+       /**
+        * Represents the time where the next time range can start the drawing i.e.
+        * right after previous time range.
+        * 
+        * @param nextGoodTime
+        */
+       public void setNext_good_time(long nextGoodTime) {
+               next_good_time = nextGoodTime;
+       }
+
+       /**
+        * Reset this resource to the construction state
+        */
+       public void reset() {
+               getChildEventComposites().clear();
+               getTraceEvents().clear();
+               next_good_time = insertionTime;
+       }
+
+       /**
+        * Event Time reflecting the creation of this local resource e.g. at Reception of Fork, etc.
+        * 
+        * @return
+        */
+       public long getInsertionTime() {
+               return insertionTime;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEvent.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEvent.java
new file mode 100644 (file)
index 0000000..acf57fb
--- /dev/null
@@ -0,0 +1,156 @@
+/*******************************************************************************\r
+ * Copyright (c) 2009 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.linuxtools.lttng.ui.model.trange;\r
+\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
+\r
+/**\r
+ * @author alvaro\r
+ * \r
+ */\r
+public class TimeRangeEvent extends TimeRangeComponent implements ITimeEvent {\r
+       // =======================================================================\r
+       // Data\r
+       // =======================================================================\r
+       TimeRangeComposite parent = null;\r
+\r
+       public static enum Type {\r
+               UNKNOWN, PROPERTY, PROCESS_MODE, BDEV_MODE, TRAP_MODE, SOFT_IRQ_MODE, IRQ_MODE, CPU_MODE\r
+       }\r
+\r
+       protected Type eventType = Type.UNKNOWN;\r
+       protected String stateMode = "";\r
+\r
+       // =======================================================================\r
+       // Constructors\r
+       // =======================================================================\r
+       /**\r
+        * @param stime\r
+        *            Event Start Time (may be unknown)\r
+        * @param etime\r
+        *            Event EndTime (may be unknown)\r
+        * @param eventParent\r
+        * @param type\r
+        * @param duration\r
+        */\r
+       public TimeRangeEvent(Long stime, Long etime,\r
+                       TimeRangeComposite eventParent, Type type, String stateMode) {\r
+               super(stime, etime, eventParent);\r
+\r
+               this.eventType = type;\r
+               this.stateMode = stateMode;\r
+       }\r
+\r
+       // =======================================================================\r
+       // Methods\r
+       // =======================================================================\r
+       \r
+       // @Override\r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @see\r
+        * org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent#getTime\r
+        * ()\r
+        */\r
+       public long getTime() {\r
+               // The value provided by this method is used to start drawing the\r
+               // time-range,\r
+               // so a null value shall not be provided.\r
+               // If the actual start time is unknown then use the start of the Trace\r
+               // as the\r
+               // starting reference point.\r
+               if (startTime == null) {\r
+                       return eventParent.getStartTime();\r
+               }\r
+               return startTime;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @see\r
+        * org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent#getEntry\r
+        * ()\r
+        */\r
+       public ITmfTimeAnalysisEntry getEntry() {\r
+               return parent;\r
+       }\r
+\r
+       /**\r
+        * return the duration between end and start time , if the start time or end\r
+        * time are unknown, use the Trace start and End times to estimate it, this\r
+        * value will be used to draw the time range and need to provide a valid\r
+        * time width.\r
+        * \r
+        * @return the duration\r
+        */\r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @seeorg.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent#\r
+        * getDuration()\r
+        */\r
+       public long getDuration() {\r
+               long duration = -1;\r
+               long endT = (stopTime == null) ? parent.getStopTime() : stopTime;\r
+               long startT = (startTime == null) ? parent.getStartTime() : startTime;\r
+\r
+               if (endT > startT) {\r
+                       return stopTime - startTime;\r
+               }\r
+               return duration;\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public String getStateMode() {\r
+               return stateMode;\r
+       }\r
+\r
+       /**\r
+        * @param stateMode\r
+        */\r
+       public void setStateMode(String stateMode) {\r
+               if (stateMode != null) {\r
+                       this.stateMode = stateMode;\r
+               }\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @see org.eclipse.linuxtools.lttng.ui.model.ITimeRangeComponent#getName()\r
+        */\r
+       @Override\r
+       public String getName() {\r
+               return stateMode;\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public Type getEventType() {\r
+               return eventType;\r
+       }\r
+\r
+       /**\r
+        * @param eventType\r
+        */\r
+       public void setEventType(Type eventType) {\r
+               this.eventType = eventType;\r
+       }\r
+\r
+}\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEventProcess.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEventProcess.java
new file mode 100644 (file)
index 0000000..bceef5f
--- /dev/null
@@ -0,0 +1,222 @@
+/*******************************************************************************\r
+ * Copyright (c) 2009 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation\r
+ *******************************************************************************/\r
+package org.eclipse.linuxtools.lttng.ui.model.trange;\r
+\r
+public class TimeRangeEventProcess extends TimeRangeComposite implements\r
+               Comparable<TimeRangeEventProcess> {\r
+       // ========================================================================\r
+       // Data\r
+       // =======================================================================\r
+       // GUI information\r
+       private Long pid = 0L;\r
+       private Long tgid = 0L;\r
+       private Long ppid = 0L;\r
+       private Long creationTime = 0L;\r
+       private String traceID = "";\r
+       private String processType = "User"; // Kernel or user thread\r
+       private Long cpu = 0L;\r
+       private String brand = "";\r
+\r
+       // ========================================================================\r
+       // Constructor\r
+       // =======================================================================\r
+       /**\r
+        * @param id\r
+        * @param name\r
+        * @param sTime\r
+        *            normally set to the Trace start time\r
+        * @param stopTime\r
+        *            normally set to the Trace end time\r
+        * @param groupName\r
+        * @param className\r
+        */\r
+       public TimeRangeEventProcess(int id, String name, long startTime,\r
+                       long stopTime, String groupName, String className, Long cpu,\r
+                       long insertionTime) {\r
+\r
+               super(id, startTime, stopTime, name, CompositeType.PROCESS,\r
+                               insertionTime);\r
+               this.cpu = cpu;\r
+       }\r
+\r
+       // ========================================================================\r
+       // Methods\r
+       // =======================================================================\r
+       \r
+       \r
+       /**\r
+     * Interface to add children to this process\r
+     * \r
+     * @param newEvent\r
+     */\r
+    public void addChildren(TimeRangeEvent newEvent) {\r
+        if ((newEvent != null)) {\r
+            this.ChildEventLeafs.add(newEvent);\r
+        }\r
+    }\r
+       \r
+       /**\r
+        * @return\r
+        */\r
+       public Long getPid() {\r
+               return pid;\r
+       }\r
+\r
+       /**\r
+        * @param pid\r
+        */\r
+       public void setPid(Long pid) {\r
+               this.pid = pid;\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public Long getTgid() {\r
+               return tgid;\r
+       }\r
+\r
+       /**\r
+        * @param tgid\r
+        */\r
+       public void setTgid(Long tgid) {\r
+               this.tgid = tgid;\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public Long getPpid() {\r
+               return ppid;\r
+       }\r
+\r
+       /**\r
+        * @param ppid\r
+        */\r
+       public void setPpid(Long ppid) {\r
+               this.ppid = ppid;\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public Long getCreationTime() {\r
+               return creationTime;\r
+       }\r
+\r
+       /**\r
+        * @param creationTime\r
+        */\r
+       public void setCreationTime(Long creationTime) {\r
+               this.creationTime = creationTime;\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public String getTraceID() {\r
+               return traceID;\r
+       }\r
+\r
+       /**\r
+        * @param traceID\r
+        */\r
+       public void setTraceID(String traceID) {\r
+               if (traceID != null) {\r
+                       this.traceID = traceID;\r
+               } else {\r
+                       this.traceID = "";\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public String getProcessType() {\r
+               return processType;\r
+       }\r
+\r
+       /**\r
+        * @param processType\r
+        */\r
+       public void setProcessType(String processType) {\r
+               if (processType != null) {\r
+                       this.processType = processType;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public Long getCpu() {\r
+               return cpu;\r
+       }\r
+\r
+       /**\r
+        * @param cpu\r
+        */\r
+       public void setCpu(Long cpu) {\r
+               if (cpu != null) {\r
+                       this.cpu = cpu;\r
+               } else {\r
+                       cpu = 0L;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public String getBrand() {\r
+        return brand;\r
+    }\r
+\r
+       /**\r
+        * @param brand\r
+        */\r
+    public void setBrand(String brand) {\r
+        if (brand != null) {\r
+            this.brand = brand;\r
+        } else {\r
+            brand = "";\r
+        }\r
+    }\r
+       \r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @see java.lang.Comparable#compareTo(java.lang.Object)\r
+        */\r
+       public int compareTo(TimeRangeEventProcess process) {\r
+               if (process != null) {\r
+                       int result = 0;\r
+                       // Compare by trace first\r
+                       String anotherTraceId = process.getTraceID();\r
+                       result = traceID.compareTo(anotherTraceId);\r
+                       if (result != 0) {\r
+                               return result;\r
+                       }\r
+\r
+                       // Then by CPU\r
+                       Long anotherCpu = process.getCpu();\r
+                       result = cpu.compareTo(anotherCpu);\r
+                       if (result != 0) {\r
+                               return result;\r
+                       }\r
+\r
+                       // finally Compare by pid\r
+                       Long anotherPid = process.getPid();\r
+                       return pid.compareTo(anotherPid);\r
+               }\r
+\r
+               return 0;\r
+       }\r
+}\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEventResource.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeEventResource.java
new file mode 100644 (file)
index 0000000..b7a417a
--- /dev/null
@@ -0,0 +1,176 @@
+/*******************************************************************************\r
+ * Copyright (c) 2009 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation\r
+ *******************************************************************************/\r
+package org.eclipse.linuxtools.lttng.ui.model.trange;\r
+\r
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;\r
+\r
+/**\r
+ * @author alvaro\r
+ * \r
+ */\r
+public abstract class TimeRangeEventResource extends TimeRangeComposite\r
+               implements\r
+               Comparable<TimeRangeEventResource> {\r
+\r
+       // ========================================================================\r
+       // Data\r
+       // =======================================================================\r
+       public static enum ResourceTypes {\r
+               UNKNOWN, IRQ, TRAP, SOFT_IRQ, BDEV, CPU\r
+       }\r
+\r
+       private ResourceTypes type = ResourceTypes.UNKNOWN;\r
+       private Long resourceId = null;\r
+\r
+       // ========================================================================\r
+       // Constructor\r
+       // =======================================================================\r
+       /**\r
+        * Constructor<br>\r
+        * \r
+        * @param newId            Id used by the UI\r
+        * @param newStartTime     normally set to the Trace start time\r
+        * @param newStopTime      normally set to the Trace end time\r
+        * @param newName          the name of this resource\r
+        * @param newGroupName     the group name of this resource. Should be same as the traceId\r
+        * @param newClassName     the classname of this resource.\r
+        * @param newType          the type of the resource, as defined in the ResourceTypes enum\r
+        * @param newResourceId    the resourceId, unique id identifying this resource \r
+        * \r
+        */\r
+       public TimeRangeEventResource(int newId, long newStartTime,\r
+                       long newStopTime, String newName, String newGroupName,\r
+                       String newClassName, ResourceTypes newType, Long newResourceId,\r
+                       long insertionTime) {\r
+\r
+               super(newId, newStartTime, newStopTime, newName, newGroupName,\r
+                               newClassName, CompositeType.RESOURCE, insertionTime);\r
+\r
+               type = newType;\r
+               resourceId = newResourceId;\r
+       }\r
+\r
+       // ========================================================================\r
+       // Methods\r
+       // =======================================================================\r
+\r
+       /**\r
+        * Interface to add children to this resource\r
+        * \r
+        * @param newEvent\r
+        */\r
+       public void addChildren(TimeRangeEvent newEvent) {\r
+               if ((newEvent != null)) {\r
+                       this.ChildEventLeafs.add(newEvent);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public Long getResourceId() {\r
+               return resourceId;\r
+       }\r
+\r
+       /**\r
+        * @param newResId\r
+        */\r
+       public void setResourceId(Long newResId) {\r
+               this.resourceId = newResId;\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public ResourceTypes getType() {\r
+               return type;\r
+       }\r
+\r
+       /**\r
+        * @param type\r
+        */\r
+       public void setType(ResourceTypes type) {\r
+               this.type = type;\r
+       }\r
+\r
+       /**\r
+        * Getter for traceId.<br>\r
+        * Note : traceId and groupName are the same for EventResource\r
+        * \r
+        * @return String\r
+        */\r
+       public String getTraceId() {\r
+               return groupName;\r
+       }\r
+\r
+       /**\r
+        * Getter for traceId.<br>\r
+        * Note : traceId and groupName are the same for EventResource\r
+        * \r
+        * @return String\r
+        */\r
+       public void setTraceId(String traceId) {\r
+               this.groupName = traceId;\r
+       }\r
+\r
+       // @Override\r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @see java.lang.Object#toString()\r
+        */\r
+       @Override\r
+       public String toString() {\r
+               return getResourceId().toString() + ":" + getTraceId().toString() + ":"\r
+                               + getType().toString();\r
+       }\r
+\r
+       /**\r
+        * Compare function to implement Comparable<br>\r
+        * <br>\r
+        * Compare by traceId THEN IF EQUAL by resourceType THEN IF EQUAL by\r
+        * resourceId\r
+        * \r
+        * @param comparedResource\r
+        *            The resource to compare to\r
+        * \r
+        * @return int 0 if equals, negative number if "smaller", positive if\r
+        *         "bigger".\r
+        */\r
+       // @Override\r
+       public int compareTo(TimeRangeEventResource comparedResource) {\r
+               int returnedValue = 0;\r
+\r
+               if (comparedResource != null) {\r
+                       // Compare by trace id first\r
+                       returnedValue = this.getTraceId().compareTo(\r
+                                       comparedResource.getTraceId());\r
+\r
+                       // If same, compare by resourceName\r
+                       if (returnedValue == 0) {\r
+                               returnedValue = this.getName().compareTo(\r
+                                               comparedResource.getName());\r
+\r
+                               // Finally, if same, compare by ResourceId\r
+                               if (returnedValue == 0) {\r
+                                       returnedValue = this.getResourceId().compareTo(\r
+                                                       comparedResource.getResourceId());\r
+                               }\r
+                       }\r
+\r
+               }\r
+\r
+               return returnedValue;\r
+       }\r
+\r
+       public abstract String getStateMode(LttngTraceState traceState);\r
+}\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeResourceFactory.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeResourceFactory.java
new file mode 100644 (file)
index 0000000..94f2340
--- /dev/null
@@ -0,0 +1,248 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.model.trange;
+
+
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.model.LttngIRQState;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.state.model.LttngTrapState;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventResource.ResourceTypes;
+
+/**
+ * Creates Resources with custom implementation to obtain its corresponding
+ * state mode
+ * <p>
+ * The state mode resolution is needed at the end of a data request, as well as
+ * in the before and after handlers
+ * </p>
+ * 
+ * @author alvaro
+ * 
+ */
+public class TimeRangeResourceFactory {
+       // ========================================================================
+       // Data
+       // =======================================================================
+       private static TimeRangeResourceFactory instance = null;
+
+       // ========================================================================
+       // Create instance
+       // =======================================================================
+       /**
+        * Factory singleton
+        * 
+        * @return
+        */
+       public static TimeRangeResourceFactory getInstance() {
+               if (instance == null) {
+                       instance = new TimeRangeResourceFactory();
+               }
+               return instance;
+       }
+
+       // ========================================================================
+       // Public methods
+       // =======================================================================
+       public TimeRangeEventResource createResource(int newId, long newStartTime,
+                       long newStopTime, String newName, String newGroupName,
+                       String newClassName, ResourceTypes type, Long newResourceId,
+                       long insertionTime) {
+
+               TimeRangeEventResource resource = null;
+               switch (type) {
+               case CPU:
+                       resource = createCpuResource(newId, newStartTime, newStopTime,
+                                       newName, newGroupName, newClassName, type, newResourceId,
+                                       insertionTime);
+                       break;
+               case IRQ:
+                       resource = createIrqResource(newId, newStartTime, newStopTime,
+                                       newName, newGroupName, newClassName, type, newResourceId,
+                                       insertionTime);
+                       break;
+               case SOFT_IRQ:
+                       resource = createSoftIrqResource(newId, newStartTime, newStopTime,
+                                       newName, newGroupName, newClassName, type, newResourceId,
+                                       insertionTime);
+                       break;
+               case TRAP:
+                       resource = createTrapResource(newId, newStartTime, newStopTime,
+                                       newName, newGroupName, newClassName, type, newResourceId,
+                                       insertionTime);
+                       break;
+               case BDEV:
+                       resource = createBdevResource(newId, newStartTime, newStopTime,
+                                       newName, newGroupName, newClassName, type, newResourceId,
+                                       insertionTime);
+                       break;
+               default:
+                       break;
+               }
+
+               return resource;
+       }
+
+       // ========================================================================
+       // Private methods
+       // =======================================================================
+       private TimeRangeEventResource createIrqResource(int newId,
+                       long newStartTime, long newStopTime, String newName,
+                       String newGroupName, String newClassName, ResourceTypes newType,
+                       Long newResourceId, long insertionTime) {
+
+               TimeRangeEventResource resource = new TimeRangeEventResource(newId,
+                               newStartTime, newStopTime, newName, newGroupName, newClassName,
+                               newType, newResourceId, insertionTime) {
+
+                       @Override
+                       public String getStateMode(LttngTraceState traceSt) {
+                               LttngIRQState irqState = traceSt.getIrq_states().get(
+                                               getResourceId());
+                               String statemode = "";
+                               if (irqState != null) {
+                                       statemode = irqState.peekFromIrqStack().getInName();
+                               }
+
+                               return statemode;
+                       }
+               };
+               
+               return resource;
+       }
+
+       private TimeRangeEventResource createTrapResource(int newId,
+                       long newStartTime, long newStopTime, String newName,
+                       String newGroupName, String newClassName, ResourceTypes newType,
+                       Long newResourceId, long insertionTime) {
+
+               TimeRangeEventResource resource = new TimeRangeEventResource(newId,
+                               newStartTime, newStopTime, newName, newGroupName, newClassName,
+                               newType, newResourceId, insertionTime) {
+
+                       @Override
+                       public String getStateMode(LttngTraceState traceSt) {
+                               // Determine the trap state.
+                               String trapStateMode = "";
+                               LttngTrapState ts = traceSt.getTrap_states().get(getResourceId());
+                               
+                               // *** Note : 
+                               //      Ts might not have been created yet.
+                               //      This is because the state system will be updated next to this before hook
+                               //      It should be correct to create it here as Busy 
+                               //              (traps are created with running++ so it wont be idle)
+                               if ( ts != null ) {
+                                       Long trapState = ts.getRunning();
+                                       
+                                       if (trapState == 0) {
+                                               trapStateMode = StateStrings.TrapMode.LTTV_TRAP_IDLE.getInName();
+                                       } else {
+                                               trapStateMode = StateStrings.TrapMode.LTTV_TRAP_BUSY.getInName();
+                                       }
+                               }
+                               else {
+                                       trapStateMode = StateStrings.TrapMode.LTTV_TRAP_BUSY.getInName();
+                               }
+                               
+                               return trapStateMode;
+                       }
+               };
+
+               return resource;
+       }
+
+       private TimeRangeEventResource createSoftIrqResource(int newId,
+                       long newStartTime, long newStopTime, String newName,
+                       String newGroupName, String newClassName, ResourceTypes newType,
+                       Long newResourceId, long insertionTime) {
+
+               TimeRangeEventResource resource = new TimeRangeEventResource(newId,
+                               newStartTime, newStopTime, newName, newGroupName, newClassName,
+                               newType, newResourceId, insertionTime) {
+
+                       @Override
+                       public String getStateMode(LttngTraceState traceSt) {
+                               // Get the resource id.
+                               Long softIrqId = getResourceId();
+                               // Get the resource state mode
+                               long running = traceSt.getSoft_irq_states().get(softIrqId)
+                                               .getRunning().longValue();
+                               long pending = traceSt.getSoft_irq_states().get(softIrqId)
+                                               .getPending().longValue();
+
+                               String softIrqStateMode;
+                               if (running > 0) {
+                                       softIrqStateMode = StateStrings.SoftIRQMode.LTTV_SOFT_IRQ_BUSY
+                                                       .getInName();
+                               } else if (pending > 0) {
+                                       softIrqStateMode = StateStrings.SoftIRQMode.LTTV_SOFT_IRQ_PENDING
+                                                       .getInName();
+                               } else {
+                                       softIrqStateMode = StateStrings.SoftIRQMode.LTTV_SOFT_IRQ_IDLE
+                                                       .getInName();
+                               }
+
+                               return softIrqStateMode;
+                       }
+
+               };
+
+               return resource;
+       }
+
+       private TimeRangeEventResource createBdevResource(int newId,
+                       long newStartTime, long newStopTime, String newName,
+                       String newGroupName, String newClassName, ResourceTypes newType,
+                       Long newResourceId, long insertionTime) {
+
+               TimeRangeEventResource resource = new TimeRangeEventResource(newId,
+                               newStartTime, newStopTime, newName, newGroupName, newClassName,
+                               newType, newResourceId, insertionTime) {
+
+                       @Override
+                       public String getStateMode(LttngTraceState traceSt) {
+                               // Get the resource state mode
+                               String bdevStateMode = traceSt.getBdev_states().get(
+                                               getResourceId()).peekFromBdevStack().getInName();
+
+                               return bdevStateMode;
+                       }
+
+               };
+
+               return resource;
+       }
+
+       private TimeRangeEventResource createCpuResource(int newId,
+                       long newStartTime, long newStopTime, String newName,
+                       String newGroupName, String newClassName, ResourceTypes newType,
+                       Long newResourceId, long insertionTime) {
+
+               TimeRangeEventResource resource = new TimeRangeEventResource(newId,
+                               newStartTime, newStopTime, newName, newGroupName, newClassName,
+                               newType, newResourceId, insertionTime) {
+
+                       @Override
+                       public String getStateMode(LttngTraceState traceSt) {
+                               // Get the resource state mode
+                               String cpuStateMode = traceSt.getCpu_states().get(
+                                               getResourceId())
+                                               .peekFromCpuStack().getInName();
+
+                               return cpuStateMode;
+                       }
+
+               };
+
+               return resource;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeViewerProvider.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/model/trange/TimeRangeViewerProvider.java
new file mode 100644 (file)
index 0000000..c071627
--- /dev/null
@@ -0,0 +1,229 @@
+/*******************************************************************************\r
+ * Copyright (c) 2009 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation\r
+ *******************************************************************************/\r
+package org.eclipse.linuxtools.lttng.ui.model.trange;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.linuxtools.lttng.state.StateStrings.BdevMode;\r
+import org.eclipse.linuxtools.lttng.state.StateStrings.CpuMode;\r
+import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode;\r
+import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;\r
+import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;\r
+import org.eclipse.linuxtools.lttng.state.StateStrings.SoftIRQMode;\r
+import org.eclipse.linuxtools.lttng.state.StateStrings.TrapMode;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeAnalysisProvider;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
+\r
+public class TimeRangeViewerProvider extends TmfTimeAnalysisProvider {\r
+       // ========================================================================\r
+       // Data\r
+       // =======================================================================\r
+       Map<String, StateColor> procStateToColor = new HashMap<String, StateColor>(\r
+                       16);\r
+       Map<String, StateColor> bdevStateToColor = new HashMap<String, StateColor>(\r
+                       4);\r
+       Map<String, StateColor> softIrqStateToColor = new HashMap<String, StateColor>(\r
+                       4);\r
+       Map<String, StateColor> trapStateToColor = new HashMap<String, StateColor>(\r
+                       4);\r
+       Map<String, StateColor> irqStateToColor = new HashMap<String, StateColor>(4);\r
+       Map<String, StateColor> cpuStateToColor = new HashMap<String, StateColor>(8);\r
+\r
+       // ========================================================================\r
+       // Constructors\r
+       // =======================================================================\r
+       public TimeRangeViewerProvider() {\r
+               // Fill the statemode to color maps\r
+               fillProcessStateToColor();\r
+               fillBdevStateToColor();\r
+               fillSoftIRQStateToColor();\r
+               fillTrapStateToColor();\r
+               fillIrqStateToColor();\r
+               fillCpuStateToColor();\r
+       }\r
+\r
+       // ========================================================================\r
+       // Methods\r
+       // =======================================================================\r
+       @Override\r
+       public StateColor getEventColor(ITimeEvent event) {\r
+               StateColor retColor = null;\r
+               \r
+               if (event instanceof TimeRangeEvent) {\r
+                       TimeRangeEvent devent = (TimeRangeEvent) event;\r
+                       String stateMode = devent.getStateMode();\r
+                       switch (devent.getEventType()) {\r
+                       case PROCESS_MODE:\r
+                               retColor = procStateToColor.get(stateMode);\r
+                               break;\r
+                       case BDEV_MODE:\r
+                               retColor = bdevStateToColor.get(stateMode);\r
+                               break;\r
+                       case IRQ_MODE:\r
+                               retColor = irqStateToColor.get(stateMode);\r
+                               break;\r
+                       case SOFT_IRQ_MODE:\r
+                               retColor = softIrqStateToColor.get(stateMode);\r
+                               break;\r
+                       case CPU_MODE:\r
+                               retColor = cpuStateToColor.get(stateMode);\r
+                               break;\r
+                       case TRAP_MODE:\r
+                               retColor = trapStateToColor.get(stateMode);\r
+                               break;\r
+                       }\r
+               }\r
+               \r
+               if (retColor == null) {\r
+                       return StateColor.MAGENTA3;\r
+               }\r
+               return retColor;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.linuxtools.tmf.ui.widgets.timeAnalysis.api.TsfTmAbstractImplProvider#getStateName(org.eclipse.linuxtools.tmf.ui.widgets.timeAnalysis.api.TsfTmAbstractImplProvider.StateColor)\r
+        */\r
+       @Override\r
+       public String getStateName(StateColor color) {\r
+               //Override to multiple instances of the widget, the same color can have multiple meanings\r
+               return "Not mapped";\r
+       }\r
+\r
+       @Override\r
+       public Map<String, String> getEventHoverToolTipInfo(ITimeEvent revent) {\r
+               Map<String, String> toolTipEventMsgs = new HashMap<String, String>();\r
+               //if the selected resource is a Process, add the Process type to the tool tip\r
+               if (revent instanceof TimeRangeComponent) {\r
+                       ITimeRangeComponent parent = ((TimeRangeComponent) revent)\r
+                                       .getEventParent();\r
+                       if (parent != null && parent instanceof TimeRangeEventProcess) {\r
+                               TimeRangeEventProcess localProcess = (TimeRangeEventProcess) parent;\r
+                               toolTipEventMsgs.put("Process Type", localProcess\r
+                                               .getProcessType());\r
+                       }\r
+               }\r
+\r
+               return toolTipEventMsgs;\r
+       }\r
+\r
+       @Override\r
+       public String getEventName(ITimeEvent event, boolean upper, boolean extInfo) {\r
+               String name = null;\r
+               //The relevant event name for the time range is the actual state mode\r
+               if (event instanceof TimeRangeEvent) {\r
+                       TimeRangeEvent devent = (TimeRangeEvent) event;\r
+                       StringBuilder sb = new StringBuilder(devent.getStateMode());\r
+                       name = sb.toString();\r
+               }\r
+               \r
+               if (name == null) {\r
+                       return "Unknown";\r
+               }\r
+               return name;\r
+       }\r
+\r
+       @Override\r
+       public String getTraceClassName(ITmfTimeAnalysisEntry trace) {\r
+               String name = "";\r
+               if (trace instanceof TimeRangeComposite) {\r
+                       TimeRangeComposite dTrace = (TimeRangeComposite) trace;\r
+                       name = dTrace.getClassName();\r
+               }\r
+               return name;\r
+       }\r
+\r
+       private void fillCpuStateToColor() {\r
+               cpuStateToColor.put(CpuMode.LTTV_CPU_UNKNOWN.getInName(),\r
+                               StateColor.BLACK);\r
+               cpuStateToColor.put(CpuMode.LTTV_CPU_IDLE.getInName(), StateColor.GRAY);\r
+               cpuStateToColor.put(CpuMode.LTTV_CPU_BUSY.getInName(),\r
+                               StateColor.LIGHT_BLUE);\r
+               cpuStateToColor\r
+                               .put(CpuMode.LTTV_CPU_IRQ.getInName(), StateColor.ORANGE);\r
+               cpuStateToColor.put(CpuMode.LTTV_CPU_SOFT_IRQ.getInName(),\r
+                               StateColor.PURPLE1);\r
+               cpuStateToColor.put(CpuMode.LTTV_CPU_TRAP.getInName(), StateColor.GOLD);\r
+       }\r
+\r
+       private void fillIrqStateToColor() {\r
+               irqStateToColor.put(IRQMode.LTTV_IRQ_UNKNOWN.getInName(),\r
+                               StateColor.BLACK);\r
+               irqStateToColor.put(IRQMode.LTTV_IRQ_IDLE.getInName(), StateColor.GRAY);\r
+               irqStateToColor.put(IRQMode.LTTV_IRQ_BUSY.getInName(),\r
+                               StateColor.ORANGE);\r
+       }\r
+\r
+       private void fillTrapStateToColor() {\r
+               trapStateToColor.put(TrapMode.LTTV_TRAP_UNKNOWN.getInName(),\r
+                               StateColor.BLACK);\r
+               trapStateToColor.put(TrapMode.LTTV_TRAP_IDLE.getInName(),\r
+                               StateColor.BLACK);\r
+               trapStateToColor.put(TrapMode.LTTV_TRAP_BUSY.getInName(),\r
+                               StateColor.GOLD);\r
+       }\r
+\r
+       private void fillSoftIRQStateToColor() {\r
+               softIrqStateToColor.put(SoftIRQMode.LTTV_SOFT_IRQ_UNKNOWN.getInName(),\r
+                               StateColor.BLACK);\r
+               softIrqStateToColor.put(SoftIRQMode.LTTV_SOFT_IRQ_IDLE.getInName(),\r
+                               StateColor.BLACK);\r
+               softIrqStateToColor.put(SoftIRQMode.LTTV_SOFT_IRQ_PENDING.getInName(),\r
+                               StateColor.PINK1);\r
+               softIrqStateToColor.put(SoftIRQMode.LTTV_SOFT_IRQ_BUSY.getInName(),\r
+                               StateColor.PURPLE1);\r
+       }\r
+\r
+       private void fillBdevStateToColor() {\r
+               softIrqStateToColor.put(BdevMode.LTTV_BDEV_UNKNOWN.getInName(),\r
+                               StateColor.BLACK);\r
+               softIrqStateToColor.put(BdevMode.LTTV_BDEV_IDLE.getInName(),\r
+                               StateColor.BLACK);\r
+               softIrqStateToColor.put(BdevMode.LTTV_BDEV_BUSY_READING.getInName(),\r
+                               StateColor.DARK_BLUE);\r
+               softIrqStateToColor.put(BdevMode.LTTV_BDEV_BUSY_WRITING.getInName(),\r
+                               StateColor.RED);\r
+       }\r
+\r
+       private void fillProcessStateToColor() {\r
+               // Process Status\r
+               procStateToColor.put(ProcessStatus.LTTV_STATE_UNNAMED.getInName(),\r
+                               StateColor.GRAY);\r
+               procStateToColor.put(ProcessStatus.LTTV_STATE_DEAD.getInName(),\r
+                               StateColor.BLACK);\r
+               procStateToColor.put(ProcessStatus.LTTV_STATE_WAIT_FORK.getInName(),\r
+                               StateColor.DARK_GREEN);\r
+               procStateToColor.put(ProcessStatus.LTTV_STATE_WAIT_CPU.getInName(),\r
+                               StateColor.DARK_YELLOW);\r
+               procStateToColor.put(ProcessStatus.LTTV_STATE_EXIT.getInName(),\r
+                               StateColor.MAGENTA3);\r
+               procStateToColor.put(ProcessStatus.LTTV_STATE_ZOMBIE.getInName(),\r
+                               StateColor.PURPLE1);\r
+               procStateToColor.put(ProcessStatus.LTTV_STATE_WAIT.getInName(),\r
+                               StateColor.RED);\r
+\r
+               // Execution Mode\r
+               procStateToColor.put(ExecutionMode.LTTV_STATE_MODE_UNKNOWN.getInName(),\r
+                               StateColor.BLACK);\r
+               procStateToColor.put(ExecutionMode.LTTV_STATE_USER_MODE.getInName(),\r
+                               StateColor.GREEN);\r
+               procStateToColor.put(ExecutionMode.LTTV_STATE_SYSCALL.getInName(),\r
+                               StateColor.DARK_BLUE);\r
+               procStateToColor.put(ExecutionMode.LTTV_STATE_TRAP.getInName(),\r
+                               StateColor.GOLD);\r
+               procStateToColor.put(ExecutionMode.LTTV_STATE_IRQ.getInName(),\r
+                               StateColor.ORANGE);\r
+               procStateToColor.put(ExecutionMode.LTTV_STATE_SOFT_IRQ.getInName(),\r
+                               StateColor.PINK1);\r
+       }\r
+}\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/PerspectiveFactory.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/PerspectiveFactory.java
new file mode 100644 (file)
index 0000000..bd28bc3
--- /dev/null
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * 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;
+
+import org.eclipse.linuxtools.lttng.ui.views.control.ControlView;
+import org.eclipse.linuxtools.lttng.ui.views.controlflow.ControlFlowView;
+import org.eclipse.linuxtools.lttng.ui.views.events.EventsView;
+import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramView;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.resources.ResourcesView;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.StatisticsView;
+import org.eclipse.linuxtools.lttng.ui.views.timeframe.TimeFrameView;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+/**
+ * <b><u>PerspectiveFactory</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class PerspectiveFactory implements IPerspectiveFactory {
+
+    // LTTng views
+    private static final String PROJECT_VIEW_ID      = ProjectView.ID;
+    private static final String CONTROL_VIEW_ID      = ControlView.ID;
+    private static final String EVENTS_VIEW_ID       = EventsView.ID;
+    private static final String TIME_FRAME_VIEW_ID   = TimeFrameView.ID;
+    private static final String CONTROL_FLOW_VIEW_ID = ControlFlowView.ID;
+    private static final String RESOURCES_VIEW_ID    = ResourcesView.ID;
+    private static final String STATISTICS_VIEW_ID   = StatisticsView.ID;
+    private static final String HISTOGRAM_VIEW_ID    = HistogramView.ID;
+
+    // Standard Eclipse views
+    private static final String PROPERTIES_VIEW_ID   = IPageLayout.ID_PROP_SHEET;
+    private static final String PROBLEM_VIEW_ID      = IPageLayout.ID_PROBLEM_VIEW;
+
+       /* (non-Javadoc)
+        * @see org.eclipse.ui.IPerspectiveFactory#createInitialLayout(org.eclipse.ui.IPageLayout)
+        */
+       public void createInitialLayout(IPageLayout layout) {
+
+        layout.setEditorAreaVisible(false);
+
+        addFastViews(layout);
+        addViewShortcuts(layout);
+        addPerspectiveShortcuts(layout);
+
+        // Create the top left folder
+        IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA);
+        topLeftFolder.addView(PROJECT_VIEW_ID);
+        topLeftFolder.addView(CONTROL_VIEW_ID);
+
+        // Create the bottom left folder
+        IFolderLayout bottomLeftFolder = layout.createFolder("bottomLeftFolder", IPageLayout.BOTTOM, 0.50f, "topLeftFolder");
+        bottomLeftFolder.addView(PROPERTIES_VIEW_ID);
+   
+        // Create the middle right folder
+        IFolderLayout topRightFolder = layout.createFolder("topRightFolder", IPageLayout.TOP, 0.50f, IPageLayout.ID_EDITOR_AREA);
+        topRightFolder.addView(CONTROL_FLOW_VIEW_ID);
+        topRightFolder.addView(RESOURCES_VIEW_ID);
+        topRightFolder.addView(STATISTICS_VIEW_ID);
+
+        // Create the middle right folder
+        IFolderLayout middleRightFolder = layout.createFolder("middleRightFolder", IPageLayout.BOTTOM, 0.50f, "topRightFolder");
+        middleRightFolder.addView(EVENTS_VIEW_ID);
+
+        // Create the bottom right folder
+        IFolderLayout bottomRightFolder = layout.createFolder("bottomRightFolder", IPageLayout.BOTTOM, 0.65f, "middleRightFolder");
+        bottomRightFolder.addView(TIME_FRAME_VIEW_ID);
+        bottomRightFolder.addView(HISTOGRAM_VIEW_ID);
+        bottomRightFolder.addView(PROBLEM_VIEW_ID);
+
+       }
+
+    /**
+     * Add fast views to the perspective
+     * 
+     * @param layout
+     */
+    private void addFastViews(IPageLayout layout) {
+        // TODO Auto-generated method stub
+    }
+
+    /**
+     * Add view shortcuts to the perspective
+     * 
+     * @param layout
+     */
+    private void addViewShortcuts(IPageLayout layout) {
+        // TODO Auto-generated method stub
+    }
+
+    /**
+     * Add perspective shortcuts to the perspective
+     * 
+     * @param layout
+     */
+    private void addPerspectiveShortcuts(IPageLayout layout) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/AbsTRangeUpdate.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/AbsTRangeUpdate.java
new file mode 100644 (file)
index 0000000..9664c52
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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: Alvaro Sanchez-Leon - Initial implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.common;
+
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.evProcessor.state.AbsStateProcessing;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+
+public abstract class AbsTRangeUpdate extends AbsStateProcessing implements
+               ILttngEventProcessor {
+
+    private static final long MINORBITS = 20;
+    
+       // ========================================================================
+       // General methods
+       // =======================================================================
+    
+    /**
+     * Get the mkdev node id<br>
+     * <br>
+     * This is an implementation of a KERNEL macro used in Lttv
+     * 
+     */
+    public long getMkdevId(long major, long minor) {
+        return (((major) << MINORBITS) | (minor));
+    }
+
+       /**
+        * Get the pixels per Nano second, either from active widgets or initialise
+        * with the experiment time range values
+        * 
+        * @param traceSt
+        * @param params
+        * 
+        * @return double
+        */
+    protected double getPixelsPerNs(LttngTraceState traceSt, ParamsUpdater params) {
+        double pixPerNs = params.getPixelsPerNs();
+        if (pixPerNs == 0) {
+            TmfTimeRange tsetRange = traceSt.getContext().getExperimentTimeWindow();
+            
+            long startTime = tsetRange.getStartTime().getValue();
+            long endTime = tsetRange.getEndTime().getValue();
+            long delta = endTime - startTime;
+            
+            if (delta > 0) {
+                pixPerNs = (double) params.getWidth() / (double) delta;
+                params.setPixelsPerNs(pixPerNs);
+            }
+        }
+        return pixPerNs;
+       }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/AbsTimeUpdateView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/AbsTimeUpdateView.java
new file mode 100644 (file)
index 0000000..58b8e65
--- /dev/null
@@ -0,0 +1,669 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.common;
+
+import java.util.Arrays;
+
+import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory;
+import org.eclipse.linuxtools.lttng.control.LttngSyntheticEventProvider;
+import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent;
+import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd;
+import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
+import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest;
+import org.eclipse.linuxtools.lttng.request.IRequestStatusListener;
+import org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest;
+import org.eclipse.linuxtools.lttng.request.RequestCompletedSignal;
+import org.eclipse.linuxtools.lttng.request.RequestStartedSignal;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer;
+import org.eclipse.linuxtools.lttng.ui.views.resources.model.ResourceModelFactory;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+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.TmfDataRequest;
+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.ui.viewers.timeAnalysis.ITimeAnalysisViewer;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
+import org.eclipse.linuxtools.tmf.ui.views.TmfView;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * <p>
+ * Abstract class used as a base for views handling specific time range data
+ * requests
+ * </p>
+ * <p>
+ * The class handles a single element queue of data requests, i.e. request can
+ * be triggered from different sources e.g. opening a file as well as a new
+ * selected time window
+ * </p>
+ * 
+ * @author alvaro
+ * 
+ */
+public abstract class AbsTimeUpdateView extends TmfView implements
+               IRequestStatusListener {
+
+       // ========================================================================
+       // Data
+       // ========================================================================
+       /**
+        * One second in nanoseconds
+        */
+       private static final long INITIAL_WINDOW_OFFSET = 1000000000L; /*
+                                                                                                                                        * 1 sec //
+                                                                                                                                        * in ns //
+                                                                                                                                        */
+       // private static final long INITIAL_WINDOW_OFFSET = 100000000L; /* 100 ms
+       // in ns */
+       /**
+        * Number of events before a GUI refresh
+        */
+       private static final Long INPUT_CHANGED_REFRESH = 3000L;
+       private static final long DEFAULT_OFFSET = 0L;
+       private static final int DEFAULT_CHUNK = 1;
+
+       protected boolean synch = true; // time synchronisation, used to be an
+                                                                       // option
+       protected ITimeAnalysisViewer tsfviewer = null;
+
+       // ========================================================================
+       // Constructor
+       // ========================================================================
+       public AbsTimeUpdateView(String viewID) {
+               super(viewID);
+               // freqState = UiCommonFactory.getQueue(this);
+       }
+
+       // ========================================================================
+       // Methods
+       // ========================================================================
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.lttng.state.IStateDataRequestListener#
+        * processingStarted(org.eclipse.linuxtools.lttng.state.StateDataRequest)
+        */
+       @TmfSignalHandler
+       public synchronized void processingStarted(RequestStartedSignal signal) {
+               LttngSyntEventRequest request = signal.getRequest();
+               if (request != null) {
+                       // update queue with the id of the current request.
+                       // freqState.requestStarted(request);
+
+                       // if there was no new request then this one is still on
+                       // prepare for the reception of new data
+                       waitCursor(true);
+
+                       // no new time range for zoom orders
+                       TmfTimeRange trange = null;
+                       // Time Range will be used to filter out events which are
+                       // not visible in one pixel
+                       trange = request.getRange();
+
+                       // indicate if the data model needs to be cleared e.g. a new
+                       // experiment is being selected
+                       boolean clearData = request.isclearDataInd();
+                       // Indicate if current data needs to be cleared and if so
+                       // specify the new experiment time range that applies
+                       ModelUpdatePrep(trange, clearData);
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.lttng.state.IStateDataRequestListener#
+        * processingCompleted(org.eclipse.linuxtools.lttng.state.StateDataRequest)
+        */
+       @TmfSignalHandler
+       public void processingCompleted(RequestCompletedSignal signal) {
+               ILttngSyntEventRequest request = signal.getRequest();
+
+               if (request == null) {
+                       return;
+               }
+
+               // Update wait cursor
+               waitCursor(false);
+
+               // No data refresh actions for cancelled requests.
+               if (request.isCancelled() || request.isFailed()) {
+                       if (TraceDebug.isDEBUG()) {
+                               TmfTimeRange trange = request.getRange();
+                               if (request.isCancelled()) {
+                                       TraceDebug.debug("Request cancelled "
+                                                       + trange.getStartTime() + "-" + trange.getEndTime()
+                                                       + " Handled Events: " + request.getSynEventCount()
+                                                       + " " + request.toString(), 15);
+                               } else if (request.isFailed()) {
+                                       TraceDebug.debug("Request Failed " + trange.getStartTime()
+                                                       + "-" + trange.getEndTime() + " Handled Events: "
+                                                       + request.getSynEventCount() + " "
+                                                       + request.toString());
+                               }
+                       }
+
+                       return;
+               } else {
+                       modelInputChanged(request, true);
+               }
+       }
+
+       /**
+        * Registers as listener of time selection from other views
+        * 
+        * @param signal
+        */
+       public void synchToTime(TmfTimeSynchSignal signal) {
+               if (synch) {
+                       Object source = signal.getSource();
+                       if (signal != null && source != null && source != this) {
+                               // Internal value is expected in nano seconds.
+                               long selectedTime = signal.getCurrentTime().getValue();
+                               if (tsfviewer != null) {
+                                       tsfviewer.setSelectedTime(selectedTime, true, source);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Process the reception of time window adjustment in this view if the
+        * source of the update is not this view.
+        * 
+        * @param signal
+        * @param clearingData
+        */
+       public void synchToTimeRange(TmfRangeSynchSignal signal, boolean clearingData) {
+               if (synch) {
+                       Object source = signal.getSource();
+                       if (signal != null && source != null && source != this) {
+                               // Internal value is expected in nano seconds.
+                               TmfTimeRange trange = signal.getCurrentRange();
+                               TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment();
+                               if (experiment == null) {
+                                       TraceDebug.debug("Current selected experiment is null");
+                                       return;
+                               }
+
+                               // Clearing of process data is configurable
+                               dataRequest(trange, experiment.getTimeRange(), clearingData);
+                       }
+               }
+       }
+
+       /**
+        * Trigger time synchronisation to other views this method shall be called
+        * when a check has been performed to note that an actual change of time has
+        * been performed vs a pure re-selection of the same time
+        * 
+        * @param time
+        * @param source
+        */
+       protected void synchTimeNotification(long time, Object source) {
+               // if synchronisation selected
+               if (synch) {
+                       // Notify other views
+                       TmfSignalManager.dispatchSignal(new TmfTimeSynchSignal(source, new LttngTimestamp(time)));
+               }
+       }
+
+       /**
+        * Common implementation of ITmfTimeSelectionListener, not used by all the
+        * views extending this abstract class
+        * 
+        * @param event
+        */
+       protected void tsfTmProcessSelEvent(TmfTimeSelectionEvent event) {
+               Object source = event.getSource();
+               if (source == null) {
+                       return;
+               }
+
+               ParamsUpdater paramUpdater = getParamsUpdater();
+               Long savedSelTime = paramUpdater.getSelectedTime();
+
+               long selTimens = event.getSelectedTime();
+
+               // make sure the new selected time is different than saved before
+               // executing update
+               if (savedSelTime == null || savedSelTime != selTimens) {
+                       // Notify listener views.
+                       synchTimeNotification(selTimens, source);
+
+                       // Update the parameter updater to save the selected time
+                       paramUpdater.setSelectedTime(selTimens);
+
+                       if (TraceDebug.isDEBUG()) {
+                               TraceDebug.debug("Selected Time: " + new LttngTimestamp(selTimens) + "\n\t\t" + getName());
+                       }
+               }
+       }
+
+       /**
+        * Common implementation of ITmfTimeScaleSelectionListener, not used by all
+        * the views extending this abstract class
+        * 
+        * @param event
+        */
+       protected synchronized void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event) {
+               // source needed to keep track of source values
+               Object source = event.getSource();
+
+               if (source != null) {
+                       // Update the parameter updater before carrying out a read request
+                       ParamsUpdater paramUpdater = getParamsUpdater();
+                       boolean newParams = paramUpdater.processTimeScaleEvent(event);
+
+                       if (newParams) {
+                               // Read the updated time window
+                               TmfTimeRange trange = paramUpdater.getTrange();
+                               if (trange != null) {
+
+                                       // Notify listener views. to perform data requests
+                                       // upon this notification
+                                       synchTimeRangeNotification(trange, paramUpdater.getSelectedTime(), source);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Inform registered listeners about the new time range
+        * 
+        * @param trange
+        * @param selectedTime
+        * @param source
+        */
+       protected void synchTimeRangeNotification(TmfTimeRange trange, Long selectedTime, Object source) {
+               // if synchronisation selected
+               if (synch) {
+                       // Notify other views
+                       TmfSignalManager.dispatchSignal(new TmfRangeSynchSignal(source, trange, new LttngTimestamp(selectedTime)));
+               }
+       }
+
+       /**
+        * @param zoomedTRange
+        * @param experimentTRange
+        */
+       public void dataRequest(TmfTimeRange zoomedTRange,
+                       TmfTimeRange experimentTRange, boolean clearingData) {
+
+               // timeRange is the Experiment time range
+                boolean sent = processDataRequest(zoomedTRange, experimentTRange, clearingData);
+
+               if (sent) {
+                       waitCursor(true);
+               }
+       }
+
+       /**
+        * send data request directly e.g. doesn't use a queue
+        * 
+        * @param requestTrange
+        * @param listener
+        * @param experimentTRange
+        * @param processor
+        * @return
+        */
+       private boolean processDataRequest(TmfTimeRange requestTrange,
+                       TmfTimeRange experimentTRange, boolean clearingData) {
+               // Validate input
+               if (requestTrange == null || experimentTRange == null) {
+                       TraceDebug.debug("Invalid input");
+                       return false;
+               }
+
+               LttngSyntEventRequest request = new LttngSyntEventRequest(
+                               requestTrange, DEFAULT_OFFSET, TmfDataRequest.ALL_DATA,
+                               DEFAULT_CHUNK, this, experimentTRange, getEventProcessor()) {
+       
+                       Long fCount = getSynEventCount();
+                       ITransEventProcessor processor = getProcessor();
+                       TmfTimestamp frunningTimeStamp;
+       
+                       /*
+                        * (non-Javadoc)
+                        * 
+                        * @see
+                        * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
+                        * ()
+                        */
+                       public void handleData() {
+                               TmfEvent[] result = getData();
+       
+                               TmfEvent evt = (result.length > 0) ? result[0] : null;
+                               if (evt != null) {
+                                       LttngSyntheticEvent synEvent = (LttngSyntheticEvent) evt;
+                                       // process event
+                                       SequenceInd indicator = synEvent.getSynType();
+                                       if (indicator == SequenceInd.BEFORE
+                                                       || indicator == SequenceInd.AFTER) {
+                                               processor.process(evt, synEvent.getTraceModel());
+                                       } else if (indicator == SequenceInd.STARTREQ) {
+                                               handleRequestStarted();
+                                       } else if (indicator == SequenceInd.ENDREQ) {
+                                               processor.process(evt, synEvent.getTraceModel());
+                                               // handleCompleted();
+                                       }
+       
+                                       if (indicator == SequenceInd.BEFORE) {
+                                               fCount++;
+                                               if (fCount != 0 && fCount % INPUT_CHANGED_REFRESH == 0) {
+                                                       // send partial update
+                                                       modelInputChanged(this, false);
+       
+                                                       if (TraceDebug.isDEBUG()) {
+                                                               frunningTimeStamp = evt.getTimestamp();
+                                                               TraceDebug.debug("handled: " + fCount + " sequence: " + synEvent.getSynType());
+                                                       }
+       
+                                               }
+                                       }
+                               }
+                       }
+       
+                       public void handleRequestStarted() {
+                               notifyStarting();
+                       }
+       
+                       public void handleCompleted() {
+                               super.handleCompleted();
+
+                               // Data is not complete and should be handled as such
+                               if (isFailed() || isCancelled()) {
+                                       modelIncomplete(this);
+                               }
+
+                               if (TraceDebug.isDEBUG()) {
+                                       if (frunningTimeStamp != null) {
+                                               TraceDebug.debug("Last event time stamp: "
+                                                               + frunningTimeStamp.getValue());
+                                       }
+                               }
+                       }
+               };
+       
+               // obtain singleton core provider
+               LttngSyntheticEventProvider provider = LttngCoreProviderFactory
+                               .getEventProvider();
+       
+               // send the request to TMF
+               request.startRequestInd(provider);
+               request.setclearDataInd(clearingData);
+               return true;
+       }
+
+       /**
+        * Returns an initial smaller window to allow the user to select the area of
+        * interest
+        * 
+        * @param experimentTRange
+        * @return
+        */
+       protected TmfTimeRange getInitTRange(TmfTimeRange experimentTRange) {
+               TmfTimestamp expStartTime = experimentTRange.getStartTime();
+               TmfTimestamp expEndTime = experimentTRange.getEndTime();
+               TmfTimestamp initialEndOfWindow = new LttngTimestamp(expStartTime
+                               .getValue()
+                               + INITIAL_WINDOW_OFFSET);
+               if (initialEndOfWindow.compareTo(expEndTime, false) < 0) {
+                       return new TmfTimeRange(expStartTime, initialEndOfWindow);
+               }
+
+               // The original size of the experiment is smaller than proposed adjusted
+               // time
+               return experimentTRange;
+       }
+
+       /**
+        * Request the Time Analysis widget to enable or disable the wait cursor
+        * e.g. data request in progress or data request completed
+        * 
+        * @param waitInd
+        */
+       protected void waitCursor(final boolean waitInd) {
+               if (tsfviewer != null) {
+                       Display display = tsfviewer.getControl().getDisplay();
+
+                       // Perform the updates on the UI thread
+                       display.asyncExec(new Runnable() {
+                               public void run() {
+                                       tsfviewer.waitCursor(waitInd);
+                               }
+                       });
+               }
+       }
+
+       /**
+        * View preparation to override the current local information
+        * 
+        * @param timeRange
+        *            - new total time range e.g. Experiment level
+        * @param clearAllData
+        */
+       protected void ModelUpdatePrep(TmfTimeRange timeRange, boolean clearAllData) {
+               ItemContainer<?> itemContainer = getItemContainer();
+               if (clearAllData) {
+                       // start fresh e.g. new experiment selected
+                       itemContainer.clearItems();
+               } else {
+                       // clear children but keep processes
+                       itemContainer.clearChildren();
+               }
+
+               // Obtain the current resource array
+               ITmfTimeAnalysisEntry[] itemArr = itemContainer.readItems();
+
+               // clean up data and boundaries
+               displayModel(itemArr, -1, -1, false, -1, -1, null);
+
+               ParamsUpdater updater = getParamsUpdater();
+               if (updater != null) {
+                       // Start over
+                       updater.setEventsDiscarded(0);
+
+                       // Update new visible time range if available
+                       if (timeRange != null) {
+                               updater.update(timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue());
+                       }
+               }
+       }
+
+       /**
+        * Initialize the model and view before reloading items
+        * 
+        * @param boundaryRange
+        * @param visibleRange
+        * @param source
+        */
+       protected void ModelUpdateInit(TmfTimeRange boundaryRange, TmfTimeRange visibleRange, Object source) {
+               // Update the view boundaries
+               if (boundaryRange != null) {
+                       ItemContainer<?> itemContainer = getItemContainer();
+                       if (itemContainer != null) {
+                               itemContainer.clearItems();
+                               // Obtain the current process array
+                               ITmfTimeAnalysisEntry[] itemArr = itemContainer.readItems();
+
+                               long startTime = boundaryRange.getStartTime().getValue();
+                               long endTime = boundaryRange.getEndTime().getValue();
+
+                               // Update the view part
+                               displayModel(itemArr, startTime, endTime, true, visibleRange.getStartTime().getValue(), visibleRange
+                                               .getEndTime().getValue(), source);
+                       }
+               }
+
+               // update the view filtering parameters
+               if (visibleRange != null) {
+                       ParamsUpdater updater = getParamsUpdater();
+                       if (updater != null) {
+                               // Start over
+                               updater.setEventsDiscarded(0);
+                               // Update new visible time range if available
+                               updater.update(visibleRange.getStartTime().getValue(), visibleRange.getEndTime().getValue());
+                       }
+               }
+       }
+
+       /**
+        * Actions taken by the view to refresh its widget(s) with the updated data
+        * model
+        * 
+        * @param request
+        * @param complete
+        *            true: yes, false: partial update
+        */
+       protected void modelInputChanged(ILttngSyntEventRequest request, boolean complete) {
+               long experimentStartTime = -1;
+               long experimentEndTime = -1;
+               TmfTimeRange experimentTimeRange = request.getExperimentTimeRange();
+               if (experimentTimeRange != null) {
+                       experimentStartTime = experimentTimeRange.getStartTime().getValue();
+                       experimentEndTime = experimentTimeRange.getEndTime().getValue();
+               }
+
+               // Obtain the current resource list
+               ITmfTimeAnalysisEntry[] itemArr = getItemContainer().readItems();
+
+               if (itemArr != null) {
+                       // Sort the array by pid
+                       Arrays.sort(itemArr);
+
+                       // Update the view part
+                       displayModel(itemArr, experimentStartTime, experimentEndTime, false, request.getRange().getStartTime()
+                                       .getValue(), request.getRange().getEndTime().getValue(), request.getSource());
+               }
+
+               if (complete) {
+                       // reselect to original time
+                       ParamsUpdater paramUpdater = ResourceModelFactory.getParamsUpdater();
+                       if (paramUpdater != null && tsfviewer != null) {
+                               final Long selTime = paramUpdater.getSelectedTime();
+                               if (selTime != null) {
+                                       TraceDebug.debug("View: " + getName() + "\n\t\tRestoring the selected time to: " + selTime);
+                                       Display display = tsfviewer.getControl().getDisplay();
+                                       display.asyncExec(new Runnable() {
+                                               public void run() {
+                                                       tsfviewer.setSelectedTime(selTime, false, this);
+                                               }
+                                       });
+                               }
+
+                               if (TraceDebug.isDEBUG()) {
+                                       int eventCount = 0;
+                                       Long count = request.getSynEventCount();
+                                       for (int pos = 0; pos < itemArr.length; pos++) {
+                                               eventCount += itemArr[pos].getTraceEvents().size();
+                                       }
+
+                                       int discarded = getParamsUpdater().getEventsDiscarded();
+                                       int discardedOutofOrder = paramUpdater.getEventsDiscardedWrongOrder();
+                                       TmfTimeRange range = request.getRange();
+                                       StringBuilder sb = new StringBuilder("View: " + getName() + ", Events handled: " + count
+                                                       + ", Events loaded in view: " + eventCount + ", Number of events discarded: " + discarded
+                                                       + "\n\tNumber of events discarded with start time earlier than next good time: "
+                                                       + discardedOutofOrder);
+
+                                       sb.append("\n\t\tRequested Time Range: " + range.getStartTime() + "-" + range.getEndTime());
+                                       sb.append("\n\t\tExperiment Time Range: " + experimentStartTime + "-" + experimentEndTime);
+                                       TraceDebug.debug(sb.toString());
+                               }
+                       }
+
+               }
+       }
+
+       // /**
+       // * Obtains the remainder fraction on unit Seconds of the entered value in
+       // * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds
+       // can
+       // * be obtain by removing the last 9 digits: 1241207054 the fractional
+       // * portion of seconds, expressed in ns is: 171080214
+       // *
+       // * @param v
+       // * @return
+       // */
+       // protected String formatNs(long v) {
+       // StringBuffer str = new StringBuffer();
+       // boolean neg = v < 0;
+       // if (neg) {
+       // v = -v;
+       // str.append('-');
+       // }
+       //
+       // String strVal = String.valueOf(v);
+       // if (v < 1000000000) {
+       // return strVal;
+       // }
+       //
+       // // Extract the last nine digits (e.g. fraction of a S expressed in ns
+       // return strVal.substring(strVal.length() - 9);
+       // }
+
+       /**
+        * The request was stopped, the data is incomplete
+        * 
+        * @param request
+        */
+       protected abstract void modelIncomplete(ILttngSyntEventRequest request);
+
+       /**
+        * Returns the Event processor instance related to a specific view
+        * 
+        * @return
+        */
+       protected abstract ITransEventProcessor getEventProcessor();
+
+       /**
+        * To be overridden by some sub-classes although may not be needed in some
+        * e.g. statistics view
+        * 
+        * @param items
+        * @param startBoundTime
+        * @param endBoundTime
+        * @param updateTimeBounds
+        *            - Time bounds updated needed e.g. if a new Experiment or trace
+        *            is selected
+        * @param startVisibleWindow
+        * @param endVisibleWindow
+        * @param source
+        */
+       protected abstract void displayModel(final ITmfTimeAnalysisEntry[] items, final long startBoundTime,
+                       final long endBoundTime, final boolean updateTimeBounds, final long startVisibleWindow,
+                       final long endVisibleWindow, final Object source);
+
+       /**
+        * To be overridden by some sub-classes although may not be needed in some
+        * e.g. statistics view
+        * 
+        * @return
+        */
+       protected abstract ParamsUpdater getParamsUpdater();
+
+       /**
+        * Returns the model's item container
+        * 
+        * @return
+        */
+       protected abstract ItemContainer<?> getItemContainer();
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/ParamsUpdater.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/common/ParamsUpdater.java
new file mode 100644 (file)
index 0000000..ae9c3a5
--- /dev/null
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.common;
+
+import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent;
+
+/**
+ * 
+ * Preserve the time and space width parameters applicable to a particular view
+ * in order to facilitate filtering of events and request handling.
+ * 
+ * @author alvaro
+ * 
+ */
+public class ParamsUpdater {
+       // ========================================================================
+       // Data
+       // ========================================================================
+
+       private long startTime = 0;
+       private long endTime = Long.MAX_VALUE;
+       private Long selectedTime = null;
+       private final int DEFAULT_WIDTH = 2000; // number of estimated pixels
+                                                                                                       // that
+       // can hold the time range space
+       private int width = DEFAULT_WIDTH; // width in pixels used to represent the
+       // time interval
+       private double pixelsPerNs = 0;
+       private int eventsDiscarded = 0;
+       private int eventsDiscardedWrongOrder = 0;
+       private TmfTimeRange trange = null;
+
+       // ========================================================================
+       // Methods
+       // ========================================================================
+
+       /**
+        * @param event
+        * @return
+        */
+       public synchronized boolean processTimeScaleEvent(
+                       TmfTimeScaleSelectionEvent event) {
+
+               boolean updated = false;
+               if (event != null) {
+                       long time0 = event.getTime0();
+                       long time1 = event.getTime1();
+                       int dwidth = event.getWidth();
+
+                       updated = update(time0, time1, dwidth);
+
+                       // initialization only, otherwise wait for the actual selection
+                       // event to update its value. Note that the time must be different
+                       // upon selection of a new time in order to trigger an update to all
+                       if (selectedTime == null) {
+                               setSelectedTime(event.getSelectedTime());
+                       }
+
+               }
+
+               return updated;
+
+       }
+
+       /**
+        * Save the selected time
+        * @param selTime
+        */
+       public void setSelectedTime(long selTime) {
+               TraceDebug.debug("Selected time changed from: \n\t" + selectedTime
+                               + " to: \n\t" + selTime);
+               selectedTime = selTime;
+       }
+
+       /**
+        * May return null, if the selected time is invalid
+        * 
+        * @return
+        */
+       public Long getSelectedTime() {
+               return selectedTime;
+       }
+
+       /**
+        * Update time range but keep width as is
+        * 
+        * @param time0
+        * @param time1
+        * @return
+        */
+       public boolean update(long time0, long time1) {
+               return update(time0, time1, width);
+       }
+
+       /**
+        * Only positive attributes are expected
+        * 
+        * @param time0
+        * @param time1
+        * @param dwidth
+        * @return
+        */
+       public boolean update(long time0, long time1, int dwidth) {
+               boolean updated = false;
+
+               if (time0 == startTime && time1 == endTime && dwidth == width) {
+                       // No updated needed
+                       return updated;
+               }
+
+               // Negatives are invalid
+               time0 = time0 > 0 ? time0 : 0;
+               time1 = time1 > 0 ? time1 : 0;
+               dwidth = dwidth > 0 ? dwidth : 0;
+
+               if (time1 > time0) {
+                       // Store the new values as long as they are within range
+                       startTime = time0;
+                       endTime = time1;
+                       width = dwidth;
+
+                       pixelsPerNs = (double) width / (double) (endTime - startTime);
+
+                       TmfTimestamp fTimeStart = new LttngTimestamp(startTime);
+                       TmfTimestamp fTimeEnd = new LttngTimestamp(endTime);
+                       trange = new TmfTimeRange(fTimeStart, fTimeEnd);
+
+                       // make sure the selected time is within the new range or else set
+                       // mark it as invalid
+                       if (selectedTime != null) {
+                               setSelectedTime(selectedTime);
+                       }
+
+                       // update succeeded
+                       updated = true;
+
+                       TraceDebug.debug("Configuration updated to: StartTime: " /* */
+                                       + fTimeStart /* */
+                                       + "-" /* */
+                                       + fTimeEnd /* */
+                                       + " width: " /* */
+                                       + width + " k: " + pixelsPerNs); /* */
+               } else {
+                       TraceDebug
+                                       .debug("End time is not greater than start time, start time: "
+                                                       + time0 + " end time: " + time1);
+               }
+
+               return updated;
+       }
+
+       /**
+        * @return
+        */
+       public long getStartTime() {
+               return startTime;
+       }
+
+       /**
+        * @return
+        */
+       public long getEndTime() {
+               return endTime;
+       }
+
+       /**
+        * @return
+        */
+       public int getWidth() {
+               if (width == 0) {
+                       TraceDebug
+                                       .debug("Unexpected width value of 0 pixels, returning default");
+                       return DEFAULT_WIDTH;
+               }
+
+               return width;
+       }
+
+       /**
+        * Return the current constant "K" of pixels per nano second used for the
+        * widest time space widget registered in this instance.
+        * 
+        * @return
+        */
+       public double getPixelsPerNs() {
+               return pixelsPerNs;
+       }
+
+       /**
+        * Set the value of pixels per nano second as long as the value is grater
+        * positive
+        * 
+        * @return
+        */
+       public void setPixelsPerNs(double pixperNsec) {
+               if (pixperNsec > 0) {
+                       pixelsPerNs = pixperNsec;
+               }
+       }
+
+       /**
+        * @param value
+        */
+       public void setEventsDiscarded(int value) {
+               eventsDiscarded = value;
+               if (value == 0) {
+                       eventsDiscardedWrongOrder = 0;
+               }
+       }
+
+       /**
+        * 
+        */
+       public void incrementEventsDiscarded() {
+               this.eventsDiscarded++;
+       }
+
+       /**
+        * @return
+        */
+       public int getEventsDiscarded() {
+               return eventsDiscarded;
+       }
+
+       /**
+        * increase the number of events discarder since they were not received in a
+        * later time than previous events
+        */
+       public void incrementEventsDiscardedWrongOrder() {
+               this.eventsDiscarded++;
+               this.eventsDiscardedWrongOrder++;
+       }
+
+       /**
+        * @return
+        */
+       public int getEventsDiscardedWrongOrder() {
+               return eventsDiscardedWrongOrder;
+
+       }
+
+       /**
+        * @return
+        */
+       public TmfTimeRange getTrange() {
+               return trange;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/control/ControlView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/control/ControlView.java
new file mode 100644 (file)
index 0000000..5571fac
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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.control;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * <b><u>ControlView</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class ControlView extends ViewPart {
+
+    public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.control";
+
+       /**
+        * 
+        */
+       public ControlView() {
+               // TODO Auto-generated constructor stub
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+        */
+       @Override
+       public void createPartControl(Composite parent) {
+               // TODO Auto-generated method stub
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
+        */
+       @Override
+       public void setFocus() {
+               // TODO Auto-generated method stub
+
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/ControlFlowView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/ControlFlowView.java
new file mode 100644 (file)
index 0000000..db48078
--- /dev/null
@@ -0,0 +1,1094 @@
+/*******************************************************************************
+ * 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: Alvaro Sanchez-Leon - Initial implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.controlflow;
+
+import java.util.Vector;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
+import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventProcess;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeViewerProvider;
+import org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView;
+import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
+import org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor.FlowEventToHandlerFactory;
+import org.eclipse.linuxtools.lttng.ui.views.controlflow.model.FlowModelFactory;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
+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.TmfTimeSynchSignal;
+import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewerFactory;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeFilterSelectionListener;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeScaleSelectionListener;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeSelectionListener;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeFilterSelectionEvent;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * <b><u>ControlFlowView</u></b>
+ */
+/**
+ * @author alvaro
+ * 
+ */
+public class ControlFlowView extends AbsTimeUpdateView implements
+               ITmfTimeSelectionListener, ITmfTimeScaleSelectionListener,
+               ITmfTimeFilterSelectionListener {
+
+    public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.controlflow";
+    
+       // ========================================================================
+       // Table data
+       // ========================================================================
+       private final String PROCESS_COLUMN = "Process";
+       private final String BRAND_COLUMN = "Brand";
+       private final String PID_COLUMN = "PID";
+       private final String TGID_COLUMN = "TGID";
+       private final String PPID_COLUMN = "PPID";
+       private final String CPU_COLUMN = "CPU";
+       private final String BIRTH_SEC_COLUMN = "Birth sec";
+       private final String BIRTH_NSEC_COLUMN = "Birth nsec";
+       private final String TRACE = "TRACE";
+
+       private final String[] columnNames = new String[] { PROCESS_COLUMN, /* */
+       BRAND_COLUMN,/* */
+       PID_COLUMN,/* */
+       TGID_COLUMN,/* */
+       PPID_COLUMN,/* */
+       CPU_COLUMN, /* */
+       BIRTH_SEC_COLUMN,/* */
+       BIRTH_NSEC_COLUMN,/* */
+       TRACE /* */
+       };
+
+       // ========================================================================
+       // Data
+       // ========================================================================
+       private TableViewer tableViewer;
+       // private int totalNumItems = 0;
+       // Actions
+       private Action doubleClickAction;
+       private Action resetScale;
+       private Action nextEvent;
+       private Action prevEvent;
+       private Action nextTrace;
+       private Action prevTrace;
+       private Action showLegend;
+       private Action filterTraces;
+       private Action zoomIn;
+       private Action zoomOut;
+       private Action zoomFilter;
+
+       private ViewProcessFilter tableFilter = null;
+       private ScrolledComposite scrollFrame = null;
+
+       // private static SimpleDateFormat stimeformat = new SimpleDateFormat(
+       // "yy/MM/dd HH:mm:ss");
+
+       // private TraceModelImplFactory fact;
+
+       // ========================================================================
+       // Methods
+       // ========================================================================
+       /*
+        * The content provider class is responsible for providing objects to the
+        * view. It can wrap existing objects in adapters or simply return objects
+        * as-is. These objects may be sensitive to the current input of the view,
+        * or ignore it and always show the same content (like Task List, for
+        * example).
+        */
+
+       class ViewContentProvider implements
+       /* ILazyContentProvider, */IStructuredContentProvider {
+               private TableViewer cviewer = null;
+               private ITmfTimeAnalysisEntry[] elements = null;
+
+               public ViewContentProvider(TableViewer v) {
+                       cviewer = v;
+               }
+
+               public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+                       this.elements = (ITmfTimeAnalysisEntry[]) newInput;
+                       if (elements != null) {
+                               TraceDebug.debug("Total number of processes provided to Control Flow view: " + elements.length);
+                       } else {
+                               TraceDebug.debug("New input = null");
+                       }
+               }
+
+               public void dispose() {
+
+               }
+
+               // Needed with the use of virtual tables in order to initialize items
+               // which were not initially visible.
+               public void updateElement(int index) {
+                       cviewer.replace(elements[index], index);
+               }
+
+               // @Override
+               public Object[] getElements(Object inputElement) {
+                       return elements;
+               }
+       }
+
+       class ViewLabelProvider extends LabelProvider implements
+                       ITableLabelProvider {
+               public String getColumnText(Object obj, int index) {
+                       String strRes = ""; //$NON-NLS-1$
+                       LttngTimestamp time;
+                       if (obj instanceof TimeRangeEventProcess) {
+                               TimeRangeEventProcess process = (TimeRangeEventProcess) obj;
+                               switch (index) {
+                               case 0:
+                                       strRes = process.getName();
+                                       break;
+                               case 1:
+                                       strRes = process.getBrand();
+                                       break;
+                               case 2:
+                                       strRes = process.getPid().toString();
+                                       break;
+                               case 3:
+                                       strRes = process.getTgid().toString();
+                                       break;
+                               case 4:
+                                       strRes = process.getPpid().toString();
+                                       break;
+                               case 5:
+                                       strRes = process.getCpu().toString();
+                                       break;
+                               case 6:
+                                       time = new LttngTimestamp(process.getCreationTime()
+                                                       .longValue());
+                                       strRes = time.getSeconds();
+                                       break;
+                               case 7:
+                                       time = new LttngTimestamp(process.getCreationTime()
+                                                       .longValue());
+                                       strRes = time.getNanoSeconds();
+                                       break;
+                               case 8:
+                                       strRes = process.getTraceID();
+                                       break;
+                               default:
+                                       break;
+                               }
+                       } else {
+                               return getText(obj);
+                       }
+
+                       return strRes;
+               }
+
+               public Image getColumnImage(Object obj, int index) {
+                       return getImage(obj);
+               }
+
+               @Override
+               public Image getImage(Object obj) {
+                       // No image needed for the time being
+                       // return PlatformUI.getWorkbench().getSharedImages().getImage(
+                       // ISharedImages.IMG_OBJ_ELEMENT);
+                       return null;
+               }
+       }
+
+       class ViewProcessFilter extends ViewerFilter {
+
+               private Vector<ITmfTimeAnalysisEntry> filteredSet = new Vector<ITmfTimeAnalysisEntry>();
+               StructuredViewer viewer;
+
+               public ViewProcessFilter(StructuredViewer rviewer) {
+                       this.viewer = rviewer;
+               }
+
+               public void setFilter(Vector<ITmfTimeAnalysisEntry> filtered) {
+                       if (filtered != null) {
+                               this.filteredSet = filtered;
+                               viewer.refresh();
+                       }
+               }
+
+               @Override
+               public boolean select(Viewer viewer, Object parentElement,
+                               Object element) {
+                       boolean filteredIn = true;
+                       if (element instanceof ITmfTimeAnalysisEntry) {
+                               ITmfTimeAnalysisEntry process = (ITmfTimeAnalysisEntry) element;
+                               if (filteredSet.contains(process)) {
+                                       // The element is marked to be filtered out
+                                       return false;
+                               }
+                       } else {
+                               TraceDebug.debug("Unexpected type of filter element received: "
+                                               + element.toString());
+                       }
+                       // Compare element versus a list of filtered out
+                       return filteredIn;
+               }
+       }
+
+       /**
+        * The constructor.
+        */
+       public ControlFlowView() {
+               super(ID);
+       }
+
+       /**
+        * This is a callback that will allow us to create the viewer and initialize
+        * it.
+        */
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.linuxtools.tmf.ui.views.TmfView#createPartControl(org.eclipse
+        * .swt.widgets.Composite)
+        */
+       @Override
+       public void createPartControl(Composite parent) {
+
+               scrollFrame = new ScrolledComposite(parent, SWT.V_SCROLL);
+               
+               scrollFrame.setExpandVertical(true);
+               scrollFrame.setExpandHorizontal(true);
+               scrollFrame.setAlwaysShowScrollBars(true);
+               
+               SashForm sash = new SashForm(scrollFrame, SWT.NONE);
+               scrollFrame.setContent(sash);
+
+               tableViewer = new TableViewer(sash, SWT.FULL_SELECTION | SWT.H_SCROLL);
+               tableViewer.setContentProvider(new ViewContentProvider(tableViewer));
+               tableViewer.setLabelProvider(new ViewLabelProvider());
+               Table table = tableViewer.getTable();
+               tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+                       public void selectionChanged(SelectionChangedEvent event) {
+                               ISelection sel = event.getSelection();
+                               if (!sel.isEmpty()) {
+                                       Object firstSel = null;
+                                       if (sel instanceof IStructuredSelection) {
+                                               firstSel = ((IStructuredSelection) sel).getFirstElement();
+
+                                               // Make sure the selection is visible
+                                               updateScrollOrigin();
+
+                                               if (firstSel instanceof ITmfTimeAnalysisEntry) {
+                                                       ITmfTimeAnalysisEntry trace = (ITmfTimeAnalysisEntry) firstSel;
+                                                       tsfviewer.setSelectedTrace(trace);
+                                               }
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Make sure the selected item is visible
+                        */
+                       private void updateScrollOrigin() {
+                               Table table = tableViewer.getTable();
+                               if (table != null && table.getItemCount() > 0) {
+                                       TableItem item = table.getSelection()[0];
+                                       if (item == null) {
+                                               // no selected reference to go up or down
+                                               return;
+                                       }
+
+                                       Rectangle itemRect = item.getBounds();
+                                       int step = itemRect.height;
+
+                                       // calculate height of horizontal bar
+                                       int hscrolly = 0;
+                                       ScrollBar hbar = scrollFrame.getHorizontalBar();
+                                       if (hbar != null) {
+                                               hscrolly = hbar.getSize().y;
+                                       }
+
+                                       int visibleHeight = scrollFrame.getSize().y - hscrolly;
+
+                                       // the current scrollbar offset to adjust i.e. start
+                                       // of
+                                       // the visible window
+                                       Point origin = scrollFrame.getOrigin();
+                                       // end of visible window
+                                       int endy = origin.y + visibleHeight;
+
+                                       int itemStartPos = itemRect.y + table.getHeaderHeight() + table.getBorderWidth()
+                                                       + table.getParent().getBorderWidth();
+
+                                       // Item End Position
+                                       int itemEndPos = itemStartPos + step;
+
+                                       // check if need to go up
+                                       if (origin.y >= step && itemStartPos < origin.y) {
+                                               // one step up
+                                               scrollFrame.setOrigin(origin.x, origin.y - step);
+
+                                       }
+
+                                                       // check if it needs to go down
+                                       if (itemEndPos > endy) {
+                                               // one step down
+                                               scrollFrame.setOrigin(origin.x, origin.y + step);
+
+                                                       }
+                               }
+                       }
+               });
+               
+               // Listen to page up /down and Home / Enc keys
+               tableViewer.getTable().addKeyListener(new KeyListener() {
+                       public void keyPressed(KeyEvent e) {
+                               Table table = tableViewer.getTable();
+                               Point origin = scrollFrame.getOrigin();
+                               if (table == null || table.getItemCount() < 1) {
+                                       // nothing to page
+                                       return;
+                               }
+
+                               TableItem item;
+                               int count;
+
+                               switch (e.keyCode) {
+                               case SWT.PAGE_DOWN:
+                                       updateScrollPageDown();
+                                       break;
+                               case SWT.PAGE_UP:
+                                       updateScrollUp();
+                                       break;
+                               case SWT.HOME:
+                                       // Home
+                                       count = table.getItemCount();
+                                       item = table.getItem(0);
+                                       // Go to the top
+                                       scrollFrame.setOrigin(origin.x, 0);
+                                       break;
+                               case SWT.END:
+                                       // End Selected
+                                       count = table.getItemCount();
+                                       item = table.getItem(count - 1);
+                                       int itemStartPos = item.getBounds().y;
+                                       // Get to the bottom
+                                       scrollFrame.setOrigin(origin.x, itemStartPos);
+                                       break;
+                               default:
+                                       break;
+                               }
+                       }
+
+                       public void keyReleased(KeyEvent e) {
+                               // Nothing to do
+
+                       }
+
+                       /**
+                        * Scroll one page down
+                        */
+                       private void updateScrollPageDown() {
+                               // null protection before calling private method
+                               Table table = tableViewer.getTable();
+                               int step = table.getItemHeight();
+
+                               int hscrolly = 0;
+                               ScrollBar hbar = scrollFrame.getHorizontalBar();
+                               if (hbar != null) {
+                                       hscrolly = hbar.getSize().y;
+                               }
+
+                               Point origin = scrollFrame.getOrigin();
+                               int visibleHeight = scrollFrame.getSize().y - hscrolly;
+                               int endy = origin.y + visibleHeight;
+
+                               scrollFrame.setOrigin(origin.x, endy - step);
+                       }
+
+                       /**
+                        * Scroll one page up
+                        */
+                       private void updateScrollUp() {
+                               // null protection before calling private method
+                               Table table = tableViewer.getTable();
+                               int step = table.getItemHeight();
+
+                               int hscrolly = 0;
+                               ScrollBar hbar = scrollFrame.getHorizontalBar();
+                               if (hbar != null) {
+                                       hscrolly = hbar.getSize().y;
+                               }
+
+                               Point origin = scrollFrame.getOrigin();
+                               int visibleHeight = scrollFrame.getSize().y - hscrolly;
+                               int pageUpPos = origin.y - visibleHeight + step;
+                               pageUpPos = pageUpPos > 0 ? pageUpPos : 0;
+                               scrollFrame.setOrigin(origin.x, pageUpPos);
+                       }
+
+               });
+               // Describe table
+               applyTableLayout(table);
+
+               int borderWidth = table.getBorderWidth();
+
+               int itemHeight = table.getItemHeight() + checkForSWTBugItemHeightAdjustement();
+               int headerHeight = table.getHeaderHeight();
+               table.getVerticalBar().setVisible(false);
+
+               tsfviewer = TmfViewerFactory.createViewer(sash,
+                               new TimeRangeViewerProvider());
+
+               tsfviewer.addWidgetSelectionListner(this);
+               tsfviewer.addWidgetTimeScaleSelectionListner(this);
+
+               // Traces shall not be grouped to allow synchronisation
+               tsfviewer.groupTraces(false);
+               tsfviewer.setItemHeight(itemHeight);
+               tsfviewer.setBorderWidth(borderWidth);
+               tsfviewer.setHeaderHeight(headerHeight);
+               tsfviewer.setVisibleVerticalScroll(false);
+               // Names provided by the table
+               tsfviewer.setNameWidthPref(0);
+               tsfviewer.setAcceptSelectionAPIcalls(true);
+
+               // Viewer to notify selection to this class
+               // This class will synchronise selections with table.
+               tsfviewer.addWidgetSelectionListner(this);
+               tsfviewer.addFilterSelectionListner(this);
+               tsfviewer.addWidgetTimeScaleSelectionListner(this);
+
+               sash.setWeights(new int[] { 1, 1 });
+               // Create the help context id for the viewer's control
+               // TODO: Associate with help system
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(
+                               tableViewer.getControl(),
+                               "org.eclipse.linuxtools.lttnng.ui.views.flow.viewer"); //$NON-NLS-1$
+
+               makeActions();
+               hookContextMenu();
+               hookDoubleClickAction();
+               contributeToActionBars();
+
+               // scrollFrame.addControlListener(new ControlAdapter() {
+               //
+               // @Override
+               // public void controlResized(ControlEvent e) {
+               // tsfviewer.resizeControls();
+               // updateScrolls(scrollFrame);
+               // }
+               // });
+
+               // set the initial view parameter values
+               // Experiment start and end time
+               // as well as time space width in pixels, used by the time analysis
+               // widget
+               // Read relevant values
+               int timeSpaceWidth = tsfviewer.getTimeSpace();
+               if (timeSpaceWidth < 0) {
+                       timeSpaceWidth = -timeSpaceWidth;
+               }
+
+               TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment();
+               if (experiment != null) {
+                       TmfTimeRange experimentTRange = experiment.getTimeRange();
+
+                       // send request and received the adjusted time used
+                       TmfTimeRange adjustedTimeRange = initialExperimentDataRequest(this,
+                                       experimentTRange);
+
+                       // initialize widget time boundaries and filtering parameters
+                       ModelUpdateInit(experimentTRange, adjustedTimeRange, this);
+               } else {
+                       TraceDebug.debug("No selected experiment information available");
+               }
+       }
+
+       private void hookContextMenu() {
+               MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+               menuMgr.setRemoveAllWhenShown(true);
+               menuMgr.addMenuListener(new IMenuListener() {
+                       public void menuAboutToShow(IMenuManager manager) {
+                               ControlFlowView.this.fillContextMenu(manager);
+                       }
+               });
+               Menu menu = menuMgr.createContextMenu(tableViewer.getControl());
+               tableViewer.getControl().setMenu(menu);
+               getSite().registerContextMenu(menuMgr, tableViewer);
+       }
+
+       private void contributeToActionBars() {
+               IActionBars bars = getViewSite().getActionBars();
+               fillLocalPullDown(bars.getMenuManager());
+               fillLocalToolBar(bars.getToolBarManager());
+       }
+
+       private void fillLocalPullDown(IMenuManager manager) {
+               manager.add(new Separator());
+               // manager.add(showLegend);
+               manager.add(new Separator());
+               manager.add(resetScale);
+               manager.add(nextEvent);
+               manager.add(prevEvent);
+               manager.add(nextTrace);
+               manager.add(prevTrace);
+               // manager.add(filterTraces);
+               manager.add(zoomIn);
+               manager.add(zoomOut);
+               manager.add(zoomFilter);
+               manager.add(new Separator());
+       }
+
+       private void fillContextMenu(IMenuManager manager) {
+               // manager.add(showLegend);
+               manager.add(new Separator());
+               manager.add(resetScale);
+               manager.add(nextEvent);
+               manager.add(prevEvent);
+               manager.add(nextTrace);
+               manager.add(prevTrace);
+               // manager.add(showLegend);
+               // manager.add(filterTraces);
+               manager.add(zoomIn);
+               manager.add(zoomOut);
+               manager.add(zoomFilter);
+               manager.add(new Separator());
+               manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+       }
+
+       private void fillLocalToolBar(IToolBarManager manager) {
+               // manager.add(showLegend);
+               manager.add(new Separator());
+               manager.add(resetScale);
+               manager.add(nextEvent);
+               manager.add(prevEvent);
+               manager.add(nextTrace);
+               manager.add(prevTrace);
+               // manager.add(filterTraces);
+               manager.add(zoomIn);
+               manager.add(zoomOut);
+               manager.add(zoomFilter);
+               manager.add(new Separator());
+       }
+
+       private void makeActions() {
+               // resetScale
+               resetScale = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.resetStartFinishTime();
+                               }
+
+                       }
+               };
+               resetScale.setText(Messages.getString("ControlFlowView.Action.Reset")); //$NON-NLS-1$
+               resetScale.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.Reset.ToolTip")); //$NON-NLS-1$
+               resetScale.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ControlFlowView.tmf.UI"),
+                                               "icons/home_nav.gif"));
+
+               // nextEvent
+               nextEvent = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.selectNextEvent();
+                               }
+                       }
+               };
+               nextEvent.setText(Messages
+                               .getString("ControlFlowView.Action.NextEvent")); //$NON-NLS-1$
+               nextEvent.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.NextEvent.Tooltip")); //$NON-NLS-1$
+               nextEvent.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ControlFlowView.tmf.UI"),
+                                               "icons/next_event.gif"));
+
+               // prevEvent
+               prevEvent = new Action() {
+               @Override
+               public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.selectPrevEvent();
+                               }
+                       }
+               };
+               prevEvent.setText(Messages
+                               .getString("ControlFlowView.Action.PrevEvent")); //$NON-NLS-1$
+               prevEvent.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.PrevEvent.Tooltip")); //$NON-NLS-1$
+               prevEvent.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ControlFlowView.tmf.UI"),
+                                               "icons/prev_event.gif"));
+
+               // nextTrace
+               nextTrace = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.selectNextTrace();
+                               }
+                       }
+               };
+               nextTrace.setText(Messages
+                               .getString("ControlFlowView.Action.NextProcess")); //$NON-NLS-1$
+               nextTrace.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.NextProcess.ToolTip")); //$NON-NLS-1$
+               nextTrace.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ControlFlowView.tmf.UI"),
+                                               "icons/next_item.gif"));
+
+               // prevTrace
+               prevTrace = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.selectPrevTrace();
+                               }
+                       }
+               };
+               prevTrace.setText(Messages
+                               .getString("ControlFlowView.Action.PreviousProcess")); //$NON-NLS-1$
+               prevTrace.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.PreviousProcess.Tooltip")); //$NON-NLS-1$
+               prevTrace.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ControlFlowView.tmf.UI"),
+                                               "icons/prev_item.gif"));
+
+               // showLegend
+               showLegend = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.showLegend();
+                               }
+                       }
+               };
+               showLegend.setText(Messages.getString("ControlFlowView.Action.Legend")); //$NON-NLS-1$
+               showLegend.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.Legend.ToolTip")); //$NON-NLS-1$
+
+               // filterTraces
+               filterTraces = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.filterTraces();
+                               }
+                       }
+               };
+               filterTraces.setText(Messages
+                               .getString("ControlFlowView.Action.Filter")); //$NON-NLS-1$
+               filterTraces.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.Filter.ToolTip")); //$NON-NLS-1$
+               filterTraces.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ControlFlowView.tmf.UI"),
+                                               "icons/filter_items.gif"));
+
+               // zoomIn
+               zoomIn = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.zoomIn();
+                               }
+                       }
+               };
+               zoomIn.setText(Messages.getString("ControlFlowView.Action.ZoomIn")); //$NON-NLS-1$
+               zoomIn.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.ZoomIn.Tooltip")); //$NON-NLS-1$
+               zoomIn.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
+                               Messages.getString("ControlFlowView.tmf.UI"),
+                               "icons/zoomin_nav.gif"));
+
+               // zoomOut
+               zoomOut = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.zoomOut();
+                               }
+                       }
+               };
+               zoomOut.setText(Messages.getString("ControlFlowView.Action.ZoomOut")); //$NON-NLS-1$
+               zoomOut.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.ZoomOut.tooltip")); //$NON-NLS-1$
+               zoomOut.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
+                               Messages.getString("ControlFlowView.tmf.UI"),
+                               "icons/zoomout_nav.gif"));
+
+               // zoomFilter
+               zoomFilter = new Action() {
+                       @Override
+                       public void run() {
+                               // Nothing to do, however the selection status is needed by the
+                               // application
+                       }
+               };
+               zoomFilter.setText(Messages
+                               .getString("ControlFlowView.Action.ZoomFilter")); //$NON-NLS-1$
+               zoomFilter.setToolTipText(Messages
+                               .getString("ControlFlowView.Action.ZoomFilter.tooltip")); //$NON-NLS-1$
+               zoomFilter.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ControlFlowView.tmf.UI"),
+                                               "icons/filter_items.gif"));
+               zoomFilter.setChecked(false);
+
+               // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);
+
+               doubleClickAction = new Action() {
+                       @Override
+                       public void run() {
+                               ISelection selection = tableViewer.getSelection();
+                               Object obj = ((IStructuredSelection) selection)
+                                               .getFirstElement();
+                               showMessage("Double-click detected on " + obj.toString()); //$NON-NLS-1$
+                       }
+               };
+       }
+
+       private void hookDoubleClickAction() {
+               tableViewer.addDoubleClickListener(new IDoubleClickListener() {
+                       public void doubleClick(DoubleClickEvent event) {
+                               doubleClickAction.run();
+                       }
+               });
+       }
+
+       private void showMessage(String message) {
+               MessageDialog.openInformation(tableViewer.getControl().getShell(),
+                               Messages.getString("ControlFlowView.msgSlogan"), message); //$NON-NLS-1$
+       }
+
+       /**
+        * Passing the focus request to the viewer's control.
+        */
+       @Override
+       public void setFocus() {
+               tableViewer.getControl().setFocus();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * tsfTmProcessSelEvent
+        * (org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent
+        * )
+        */
+       public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event) {
+               // common implementation
+               super.tsfTmProcessSelEvent(event);
+
+               // Reselect the table viewer to widget selection
+               ISelection sel = tsfviewer.getSelectionTrace();
+               if (sel != null && !sel.isEmpty()) {
+                       tableViewer.setSelection(sel);
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.
+        * ITmfTimeScaleSelectionListener
+        * #tsfTmProcessTimeScaleEvent(org.eclipse.linuxtools
+        * .tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent)
+        */
+       public synchronized void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event) {
+               super.tsfTmProcessTimeScaleEvent(event);
+       }
+
+       private void applyTableLayout(Table table) {
+               for (int i = 0; i < columnNames.length; i++) {
+                       TableColumn tableColumn = new TableColumn(table, SWT.LEFT);
+                       tableColumn.setText(columnNames[i]);
+                       tableColumn.pack();
+               }
+               table.setHeaderVisible(true);
+               table.setLinesVisible(true);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#displayModel
+        * (org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.
+        * ITmfTimeAnalysisEntry[], long, long, boolean, long, long,
+        * java.lang.Object)
+        */
+       public void displayModel(final ITmfTimeAnalysisEntry[] items,
+                       final long startBoundTime, final long endBoundTime,
+                       final boolean updateTimeBounds, final long startVisibleWindow,
+                       final long endVisibleWindow, final Object source) {
+               final Table table = tableViewer.getTable();
+               Display display = table.getDisplay();
+
+               // Perform the updates on the UI thread)
+               display.asyncExec(new Runnable() {
+                       public void run() {
+
+                               tableViewer.setInput(items); // This shall be the minimal
+                               // initial
+                               tableFilter = new ViewProcessFilter(tableViewer);
+                               tableViewer.setFilters(new ViewerFilter[] { tableFilter });
+
+                               resizeTableColumns(table);
+                               table.update();
+                               tableViewer.refresh();
+
+                               tsfviewer.display(items, startBoundTime, endBoundTime,
+                                               updateTimeBounds);
+
+                               // validate visible boundaries
+                               if (startVisibleWindow > -1 && endVisibleWindow > -1) {
+                                       tsfviewer.setSelectVisTimeWindow(startVisibleWindow,
+                                                       endVisibleWindow, source);
+                               }
+
+                               tsfviewer.resizeControls();
+
+                               // Adjust the size of the vertical scroll bar to fit the
+                               // contents
+                               if (scrollFrame != null) {
+                                       updateScrolls(scrollFrame);
+                               }
+                       }
+               });
+       }
+
+       @Override
+       public void dispose() {
+               // dispose parent resources
+               super.dispose();
+
+               tsfviewer.removeFilterSelectionListner(this);
+               tsfviewer.removeWidgetSelectionListner(this);
+               tsfviewer.removeWidgetTimeScaleSelectionListner(this);
+               tableViewer = null;
+               tsfviewer = null;
+       }
+
+       /**
+        * @param tableComposite
+        * @param table
+        */
+       private synchronized void resizeTableColumns(Table table) {
+               if (table != null) {
+                       Composite parent = table.getParent();
+                       int tableWidthSum = parent.getBorderWidth();
+
+                       TableColumn[] columns = table.getColumns();
+                       for (TableColumn column : columns) {
+                               column.pack();
+                               tableWidthSum += column.getWidth();
+                       }
+               }
+       }
+
+       // @Override
+       public void tmfTaProcessFilterSelection(TmfTimeFilterSelectionEvent event) {
+               if (tableFilter != null) {
+                       Vector<ITmfTimeAnalysisEntry> filteredout = event.getFilteredOut();
+                       if (filteredout != null) {
+                               tableFilter.setFilter(filteredout);
+                       } else {
+                               tableFilter.setFilter(new Vector<ITmfTimeAnalysisEntry>());
+                       }
+                       tableViewer.refresh();
+               }
+       }
+
+       /**
+        * @param scrollFrame
+        * @param wrapper
+        */
+       private void updateScrolls(final ScrolledComposite scrollFrame) {
+               scrollFrame.setMinSize(tableViewer.getTable().computeSize(SWT.DEFAULT, SWT.DEFAULT));
+       }
+
+       /**
+        * Registers as listener of time selection from other views
+        * 
+        * @param signal
+        */
+       @TmfSignalHandler
+       public void synchToTime(TmfTimeSynchSignal signal) {
+               super.synchToTime(signal);
+       }
+
+       /**
+        * Annotation Registers as listener of time range selection from other views
+        * The implementation handles the entry of the signal.
+        * 
+        * @param signal
+        */
+       @TmfSignalHandler
+       public void synchToTimeRange(TmfRangeSynchSignal signal) {
+               if (zoomFilter != null) {
+                       synchToTimeRange(signal, zoomFilter.isChecked());
+               }
+       }
+
+       @Override
+       public void modelIncomplete(ILttngSyntEventRequest request) {
+               // Nothing to do
+               // The data will be refreshed on the next request
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * getEventProcessor()
+        */
+       @Override
+       public ITransEventProcessor getEventProcessor() {
+               return FlowEventToHandlerFactory.getInstance();
+       }
+
+       /**
+        * @param signal
+        */
+       @TmfSignalHandler
+       public void experimentSelected(
+                       TmfExperimentSelectedSignal<? extends TmfEvent> signal) {
+               if (signal != null) {
+                       TmfTimeRange experimentTRange = signal.getExperiment()
+                                       .getTimeRange();
+
+                       // prepare time intervals in widget
+                       ModelUpdateInit(experimentTRange, experimentTRange, signal
+                                       .getSource());
+
+                       // request initial data
+                       initialExperimentDataRequest(signal
+                                       .getSource(), experimentTRange);
+               }
+       }
+
+       /**
+        * @param source
+        * @param experimentTRange
+        * @return Adjusted time window used for the request (smaller window to
+        *         initialize view)
+        */
+       private TmfTimeRange initialExperimentDataRequest(Object source,
+                       TmfTimeRange experimentTRange) {
+               // Adjust the initial time window to a shorter interval to allow
+               // user to select the interesting area based on the perspective
+               TmfTimeRange initTimeWindow = getInitTRange(experimentTRange);
+
+               dataRequest(initTimeWindow, experimentTRange, true);
+               if (TraceDebug.isDEBUG()) {
+                       TraceDebug.debug("Initialization request time range is: "
+                                       + initTimeWindow.getStartTime().toString() + "-"
+                                       + initTimeWindow.getEndTime().toString());
+               }
+
+               return initTimeWindow;
+       }
+       
+       // *** HACK ***
+       //
+       //
+       //
+       public int checkForSWTBugItemHeightAdjustement() {
+               int returnedAjustement = 0;
+               String desktopSessionName = System.getenv("DESKTOP_SESSION");
+               
+               // Gnome : most common case, no adjustement
+               if ( desktopSessionName.equals("gnome") ) {
+                       returnedAjustement = 0;
+               }
+               // Kde : ajustement of 2 is needed
+               else if ( desktopSessionName.equals("kde") ) {
+                       returnedAjustement = 2;
+               }
+               
+               return returnedAjustement;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * getParamsUpdater()
+        */
+       @Override
+       protected ParamsUpdater getParamsUpdater() {
+               return FlowModelFactory.getParamsUpdater();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * getItemContainer()
+        */
+       @Override
+       protected ItemContainer<?> getItemContainer() {
+               return FlowModelFactory.getProcContainer();
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/Messages.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/Messages.java
new file mode 100644 (file)
index 0000000..a7c8bc9
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2009 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation\r
+ *******************************************************************************/\r
+package org.eclipse.linuxtools.lttng.ui.views.controlflow;\r
+\r
+import java.util.MissingResourceException;\r
+import java.util.ResourceBundle;\r
+\r
+public class Messages {\r
+       private static final String BUNDLE_NAME = "org.eclipse.linuxtools.lttng.ui.views.controlflow.messages"; //$NON-NLS-1$\r
+\r
+       private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle\r
+                       .getBundle(BUNDLE_NAME);\r
+\r
+       private Messages() {\r
+       }\r
+\r
+       public static String getString(String key) {\r
+               try {\r
+                       return RESOURCE_BUNDLE.getString(key);\r
+               } catch (MissingResourceException e) {\r
+                       return '!' + key + '!';\r
+               }\r
+       }\r
+}\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/AbsFlowTRangeUpdate.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/AbsFlowTRangeUpdate.java
new file mode 100644 (file)
index 0000000..0417d05
--- /dev/null
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * 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: Alvaro Sanchez-Leon - Initial implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor;
+
+import java.util.Vector;
+
+import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngProcessState;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeComponent;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEvent;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventProcess;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEvent.Type;
+import org.eclipse.linuxtools.lttng.ui.views.common.AbsTRangeUpdate;
+import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
+import org.eclipse.linuxtools.lttng.ui.views.controlflow.model.FlowModelFactory;
+import org.eclipse.linuxtools.lttng.ui.views.controlflow.model.FlowProcessContainer;
+
+public abstract class AbsFlowTRangeUpdate extends AbsTRangeUpdate implements ILttngEventProcessor {
+
+       // ========================================================================
+       // Data
+       // =======================================================================
+
+       protected FlowProcessContainer procContainer = FlowModelFactory.getProcContainer();
+       protected ParamsUpdater params = FlowModelFactory.getParamsUpdater();
+       protected static final Long ANY_CPU = 0L;
+
+
+       // ========================================================================
+       // Methods
+       // =======================================================================
+       protected TimeRangeEventProcess addLocalProcess(LttngProcessState stateProcess, long traceStartTime, long traceEndTime, String traceId) {
+               // TimeRangeEventProcess localProcess = new TimeRangeEventProcess(id, name, startTime, stopTime, groupName, className)
+               TimeRangeEventProcess localProcess = new TimeRangeEventProcess(
+                               procContainer.getUniqueId(), stateProcess.getName(),
+                               traceStartTime, traceEndTime, "", stateProcess.getType()
+                                               .getInName(), stateProcess.getCpu(), stateProcess
+                                               .getInsertion_time());
+               
+               
+               localProcess.setCreationTime(stateProcess.getCreation_time());
+               localProcess.setPid(stateProcess.getPid());
+               localProcess.setTgid(stateProcess.getTgid());
+               localProcess.setPpid(stateProcess.getPpid());
+               localProcess.setName(stateProcess.getName());
+               localProcess.setBrand(stateProcess.getBrand());
+               localProcess.setTraceID(traceId);
+               localProcess.setProcessType(stateProcess.getType().getInName());
+               procContainer.addItem(localProcess);
+               return localProcess;
+       }
+       
+       /**
+        * Used to check if the event is visible within the current visible time
+        * window
+        * 
+        * @return
+        */
+       protected boolean withinViewRange(long stime, long etime) {
+               long windowStartTime = params.getStartTime();
+               long windowEndTime = params.getEndTime();
+
+               // start time is within window
+               if (stime >= windowStartTime && stime <= windowEndTime) {
+                       // The event or part of it shall be displayed.
+                       return true;
+               }
+
+               // end time is within window
+               if (etime >= windowStartTime && etime <= windowEndTime) {
+                       // The event or part of it shall be displayed.
+                       return true;
+               }
+
+               // check that a portion is within the window
+               if (stime < windowStartTime && etime > windowEndTime) {
+                       // The time range is bigger than the selected time window and
+                       // crosses it
+                       return true;
+               }
+
+               return false;
+       }
+
+       /**
+        * @param traceSt
+        * @param startTime
+        * @param endTime
+        * @param localProcess
+        * @param params
+        * @param stateMode
+        * @return
+        */
+       protected boolean makeDraw(LttngTraceState traceSt, long startTime,
+                       long endTime, TimeRangeEventProcess localProcess,
+                       ParamsUpdater params, String stateMode) {
+
+               // Determine start and end times to establish duration
+               Long stime = startTime;
+               Long etime = endTime;
+
+               if (etime < stime) {
+                       // Validate the sequential order of events
+                       params.incrementEventsDiscardedWrongOrder();
+                       return false;
+               }
+
+               // Store the next good time to start drawing the next event
+               // this is done this early to display an accurate start time of the
+               // first event
+               // within the display window
+               // ****** moved at the end since it produces gaps among the coloured rectangles
+               // localProcess.setNext_good_time(etime);
+               if (!withinViewRange(stime, etime)) {
+                       // No use to process the event since it's outside
+                       // the visible time range of the window
+                       params.incrementEventsDiscarded();
+                       return false;
+               }
+
+               // Determine if the time range event will fit it the current
+               // pixel map
+               double duration = etime - stime;
+               double k = getPixelsPerNs(traceSt, params);
+               double pixels = duration * k;
+
+               // Visibility check
+               // Display a "more information" indication by allowing non visible event
+               // as long as its previous event is visible.
+               boolean visible = true;
+               if (pixels < 1) {
+                       boolean prevEventVisibility = true;
+                       // Get the visibility indication on previous event for
+                       // this process
+                       Vector<TimeRangeComponent> inMemEvents = localProcess
+                                       .getTraceEvents();
+                       if (inMemEvents.size() != 0) {
+                               TimeRangeComponent prevEvent = inMemEvents.get(inMemEvents
+                                               .size() - 1);
+                               prevEventVisibility = prevEvent.isVisible();
+
+                               // if previous event visibility is false and the time span
+                               // between events less than two pixels, there is no need to
+                               // load it in memory i.e. not visible and a more indicator is
+                               // within two pixels.
+                               // return i.e. event discarded to free up memory
+                               Long eventSpan = stime - prevEvent.getStartTime();
+                               if (prevEventVisibility == false
+                                               && ((double) eventSpan * k) < 2) {
+
+                                       // discard the item
+                                       params.incrementEventsDiscarded();
+                                       return false;
+
+                               }
+                       }
+
+                       // if previous event is visible, set this one to not
+                       // visible and continue
+                       visible = false;
+               }
+
+               // Create the time-range event
+               TimeRangeEvent time_window = new TimeRangeEvent(stime, etime,
+                               localProcess, Type.PROCESS_MODE, stateMode);
+
+               time_window.setVisible(visible);
+               localProcess.getTraceEvents().add(time_window);
+               localProcess.setNext_good_time(etime);
+
+               return false;
+       }
+
+       /**
+        * @param traceSt
+        * @param evTime
+        * @param process
+        * @param localProcess
+        * @param params
+        * @return
+        */
+       protected boolean makeDraw(LttngTraceState traceSt, long evTime,
+                       LttngProcessState process, TimeRangeEventProcess localProcess,
+                       ParamsUpdater params) {
+
+               // TmfTimestamp stime = process.getState().getChange_LttTime();
+               long stime = localProcess.getNext_good_time();
+
+               String stateMode;
+               ProcessStatus procStatus = process.getState().getProc_status();
+               // Use Execution mode if process state is RUN otherwise use the actual
+               // process state,
+               // this selection will determine the actual color selected for the event
+               if (procStatus == ProcessStatus.LTTV_STATE_RUN) {
+                       stateMode = process.getState().getExec_mode().getInName();
+               } else {
+                       stateMode = procStatus.getInName();
+               }
+
+               return makeDraw(traceSt, stime, evTime, localProcess, params, stateMode);
+
+       }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowAfterUpdateHandlers.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowAfterUpdateHandlers.java
new file mode 100644 (file)
index 0000000..0f7c18b
--- /dev/null
@@ -0,0 +1,380 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Fields;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngProcessState;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventProcess;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+
+/**
+ * Creates instances of specific after state update handlers, per corresponding
+ * event.
+ * 
+ * @author alvaro
+ * 
+ */
+class FlowAfterUpdateHandlers {
+       /**
+        * <p>
+        * Handles: LTT_EVENT_SCHED_SCHEDULE
+        * </p>
+        * Replace C function "after_schedchange_hook" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getSchedChangeHandler() {
+               AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+                               
+                               // get event time, cpu, trace_number, process, pid
+                               LttngProcessState process_in = traceSt.getRunning_process().get(trcEvent.getCpuId());
+                               
+                               // pid_out is never used, even in LTTv!
+                               //Long pid_out = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PREV_PID);
+                               Long pid_in = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_NEXT_PID);
+                               
+                               if ( !(pid_in.equals(process_in.getPid())) ) {
+                                   TraceDebug.debug("pid_in != PID!  (getSchedChangeHandler)");
+                }
+                               
+                               //hashed_process_data = processlist_get_process_data(process_list,pid_out,process->cpu,&birth,trace_num);
+                               TimeRangeEventProcess localProcess = procContainer.findProcess(process_in.getPid(), process_in.getCpu(), traceSt.getTraceId(),process_in.getCreation_time() );
+                               
+                               if ( localProcess == null ) {
+                                       if ( (pid_in == 0) || (pid_in != process_in.getPpid()) ) {
+                                           TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow();
+                           localProcess = addLocalProcess(process_in, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId());
+                                       }
+                                       else {
+                                               TraceDebug
+                                                               .debug("pid_in is not 0 or pid_in == PPID!  (getSchedChangeHandler)");
+                                       }
+                               }
+
+                               // There is no drawing done by the C code below, only refreshing
+                               // the references to the current hash data to make it ready for
+                               // next event
+
+                               // This current implementation does not support the use of
+                               // current hashed data
+                               // although an equivalent would be good in order to improve the
+                               // time to find the currently running process per cpu.
+                               /*
+                               if(ltt_time_compare(hashed_process_data_in->next_good_time, evtime) <= 0)
+                               {
+                                   TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab);
+                                 
+                                       #ifdef EXTRA_CHECK
+                                   if(ltt_time_compare(evtime, time_window.start_time) == -1 || ltt_time_compare(evtime, time_window.end_time) == 1)
+                                      return FALSE;
+                                       #endif //EXTRA_CHECK
+                               
+                                   Drawing_t *drawing = control_flow_data->drawing;
+                                   guint width = drawing->width;
+                                   guint new_x;
+                                     
+                                   convert_time_to_pixels(time_window,evtime,width,&new_x);
+                                       
+                                   if(hashed_process_data_in->x.middle != new_x) {
+                                       hashed_process_data_in->x.middle = new_x;
+                                       hashed_process_data_in->x.middle_used = FALSE;
+                                       hashed_process_data_in->x.middle_marked = FALSE;
+                                   }
+                               }*/
+                               
+                               return false;
+
+                       }
+               };
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_PROCESS_FORK
+        * </p>
+        * Replace C function "after_process_fork_hook" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_CHILD_PID
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getProcessForkHandler() {
+           AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {  
+                           
+                Long child_pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_CHILD_PID);
+                LttngProcessState process_child = lttv_state_find_process(traceSt, trcEvent.getCpuId(), child_pid );
+                           
+                           if ( process_child != null ) {
+                               TimeRangeEventProcess localProcess = procContainer.findProcess(process_child.getPid(), process_child.getCpu(), traceSt.getTraceId(), process_child.getCreation_time() );
+                               
+                               if ( localProcess == null ) {
+                                   if ( (child_pid == 0) || (child_pid != process_child.getPpid()) ) {            
+                                       TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow();
+                            localProcess = addLocalProcess(process_child, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId());
+                                   }
+                                   else {
+                                       TraceDebug.debug("localProcess is null with child_pid not 0 or child_pid equals PPID (getProcessForkHandler)");
+                                   }
+                                       } else {
+                                               // If we found the process, the Ppid and the Tgid might
+                                               // be missing, let's add them
+                                               localProcess.setPpid(process_child.getPpid());
+                                               localProcess.setTgid(process_child.getTgid());
+                               }
+                           }
+                           else {
+                               TraceDebug.debug("process_child is null! (getProcessForkHandler)");
+                           }
+                     
+                               return false;
+                       }
+               };
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_PROCESS_EXIT
+        * </p>
+        * Replace C function "after_process_exit_hook" in eventhooks.c
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getProcessExitHandler() {
+           AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+                           
+                           LttngProcessState process = traceSt.getRunning_process().get(trcEvent.getCpuId());
+
+                           if ( process != null ) {
+                               
+                                       // *** TODO: ***
+                                       // We shall look into a way to find the current process
+                                       // faster, see the c library
+                                       // (current_hash) in order to speed up the find. see c-code
+                               //   if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
+                           //        hashed_process_data = process_list->current_hash_data[trace_num][cpu];
+                           //   }
+                               TimeRangeEventProcess localProcess = procContainer.findProcess(process.getPid(), process.getCpu(), traceSt.getTraceId(),  process.getCreation_time());
+                               
+                               if ( localProcess == null ) {
+                                   if ( (process.getPid() == 0) || (process.getPid() != process.getPpid()) ) {                                 
+                                       TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow();
+                                   localProcess = addLocalProcess(process, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId());
+                                   }
+                                   else {
+                                       TraceDebug.debug("process pid is not 0 or pid equals ppid! (getProcessExitHandler)");
+                                   }
+                                       }
+                           }
+                           else {
+                               TraceDebug.debug("process is null! (getProcessExitHandler)");
+                           }                       
+                           
+                               return false;
+                       }
+               };
+               return handler;
+       }
+
+       
+       /**
+        * <p>
+        * Handles: LTT_EVENT_EXEC
+        * </p>
+        * Replace C function "after_fs_exec_hook" in eventhooks.c
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getProcessExecHandler() {
+           AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+                           
+                           LttngProcessState process = traceSt.getRunning_process().get(trcEvent.getCpuId());
+
+                if ( process != null ) {
+                    
+                    TimeRangeEventProcess localProcess = procContainer.findProcess(process.getPid(),  process.getCpu(), traceSt.getTraceId(), process.getCreation_time());
+                    
+                    if ( localProcess == null ) {
+                        if ( (process.getPid() == 0) || (process.getPid() != process.getPpid()) ) {
+                            TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow();
+                            localProcess = addLocalProcess(process, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId());
+                        }
+                        else {
+                            TraceDebug.debug("process pid is not 0 or pid equals ppid! (getProcessExecHandler)");
+                        }
+                    }
+                    else {
+                        // If we found the process, the name might be missing. Let's add it here.
+                        localProcess.setName(process.getName());
+                    }
+                }
+                else {
+                    TraceDebug.debug("process is null! (getProcessExecHandler)");
+                }
+                
+                               return false;
+                       }
+               };
+               return handler;
+       }
+       
+       /**
+        * <p>
+        * LTT_EVENT_THREAD_BRAND
+        * </p>
+        * Replace C function "after_user_generic_thread_brand_hook" in eventhooks.c
+        * 
+        * @return
+        */
+       final ILttngEventProcessor GetThreadBrandHandler() {
+           AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+                           
+                           LttngProcessState process = traceSt.getRunning_process().get(trcEvent.getCpuId());
+
+                if ( process != null ) {
+                    
+                                       // Similar to above comments, implement a faster way to find
+                                       // the local process
+                    //   if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
+                    //        hashed_process_data = process_list->current_hash_data[trace_num][cpu];
+                    //   }
+                    TimeRangeEventProcess localProcess = procContainer.findProcess(process.getPid(), process.getCpu(), traceSt.getTraceId(), process.getCreation_time());
+                    
+                    if ( localProcess == null ) {
+                        if ( (process.getPid() == 0) || (process.getPid() != process.getPpid()) ) {                         
+                            TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow();
+                            localProcess = addLocalProcess(process, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId());
+                        }
+                        else {
+                            TraceDebug.debug("process pid is not 0 or pid equals ppid! (GetThreadBrandHandler)");
+                        }
+                    }
+                    else {
+                                               // If we found the process, the brand might be missing
+                                               // on it, add it.
+                        localProcess.setBrand(process.getBrand());
+                    }
+                }
+                else {
+                    TraceDebug.debug("process is null! (GetThreadBrandHandler)");
+                }
+                
+                return false;
+                           
+                       }
+               };
+               return handler;
+       }
+
+       /**
+        * <p>
+        * LTT_EVENT_PROCESS_STATE
+        * </p>
+        * Replace C function "after_event_enum_process_hook" in eventhooks.c
+        * <p>
+        * <p>
+        * Creates the processlist entry for the child process. Put the last
+        * position in x at the current time value.
+        * </p>
+        * 
+        * <p>
+        * Fields: LTT_FIELD_PID
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getEnumProcessStateHandler() {
+           AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+                           
+                               int first_cpu;
+                               int nb_cpus;
+                           
+                               Long pid_in = getAFieldLong(trcEvent, traceSt,
+                                               Fields.LTT_FIELD_PID);
+                           
+                // Lttv assume that pid_in will NEVER be null or incoherent
+                // What if ... ?    (let's add some debug)
+                           if ( pid_in != null  ) {
+                           if(pid_in == 0L) {
+                                               first_cpu = 0;
+                                               nb_cpus = traceSt.getNumberOfCPUs();
+                           } 
+                           else {
+                                               first_cpu = ANY_CPU.intValue();
+                                               nb_cpus = ANY_CPU.intValue() + 1;
+                           }
+                           
+                                       for (int cpu = first_cpu; cpu < nb_cpus; cpu++) {
+                               LttngProcessState process_in = lttv_state_find_process(traceSt, trcEvent.getCpuId(), pid_in );
+                               
+                               if ( process_in != null ) {
+                                   TimeRangeEventProcess localProcess = procContainer.findProcess(process_in.getPid(), process_in.getCpu(), traceSt.getTraceId(), process_in.getCreation_time());
+                           
+                                   if (localProcess == null) {
+                                           if ( (process_in.getPid() == 0) || (process_in.getPid() != process_in.getPpid()) ) {
+                                    TmfTimeRange timeRange = traceSt.getContext().getTraceTimeWindow();
+                                    localProcess = addLocalProcess(process_in, timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue(), traceSt.getTraceId());
+                                }
+                                else {
+                                    TraceDebug.debug("process pid is not 0 or pid equals ppid! (getEnumProcessStateHandler)");
+                                }
+                                   }
+                                   else {
+                                       // If the process was found, it might be missing informations, add it here
+                                       localProcess.setName(process_in.getName());
+                                       localProcess.setPpid(process_in.getPpid());
+                                       localProcess.setTgid(process_in.getTgid());
+                                   }
+                               }
+                               else {
+                                   TraceDebug.debug("process_in is null! This should never happen. (getEnumProcessStateHandler)");
+                               }
+                           }
+                           }
+                           else {
+                               TraceDebug.debug("pid_in is null! This should never happen, really... (getEnumProcessStateHandler)");
+                           }
+                           
+                               return false;
+                       }
+               };
+               return handler;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowBeforeUpdateHandlers.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowBeforeUpdateHandlers.java
new file mode 100644 (file)
index 0000000..78a9fd2
--- /dev/null
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Fields;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngProcessState;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventProcess;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+
+/**
+ * Creates instances of specific before state update handlers, per corresponding
+ * event.
+ * 
+ * @author alvaro
+ * 
+ */
+class FlowBeforeUpdateHandlers {
+       /**
+        * <p>
+        * Handles: LTT_EVENT_SYSCALL_ENTRY
+        * </p>
+        * Replace C function named "before_execmode_hook" in eventhooks.c
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getStateModesHandler() {
+               AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+
+                               Long cpu = trcEvent.getCpuId();
+                               LttngProcessState stateProcess = traceSt.getRunning_process()
+                                               .get(cpu);
+                               // TraceDebug.debug("Before handler called");
+                               String traceId = traceSt.getTraceId();
+
+                               if (stateProcess != null) {
+                                       // Find process within the list of registered time-range
+                                       // related
+                                       // processes
+
+                                       // key process attributes to look for it or store it
+                                       // are: pid, birth, trace_num, note: cpu not relevant since
+                                       // it
+                                       // may change
+                                       TimeRangeEventProcess localProcess = procContainer
+                                                       .findProcess(stateProcess.getPid(), stateProcess.getCpu(), traceId, stateProcess
+                                    .getCreation_time());
+
+                                       // Add process to process list if not present
+                                       if (localProcess == null) {
+                                               TmfTimeRange timeRange = traceSt.getContext()
+                                                               .getTraceTimeWindow();
+                                               localProcess = addLocalProcess(stateProcess, timeRange
+                                                               .getStartTime().getValue(), timeRange
+                                                               .getEndTime().getValue(), traceId);
+                                       }
+
+                                       // Do the actual drawing
+                                       makeDraw(traceSt, trcEvent.getTimestamp().getValue(),
+                                                       stateProcess, localProcess, params);
+                               } else {
+                                       TraceDebug
+                                                       .debug("Running state process is null! (getStateModesHandler)");
+                               }
+
+                               return false;
+                       }
+               };
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_SCHED_SCHEDULE
+        * </p>
+        * Replace C function named "before_schedchange_hook" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE (?)
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getBeforeSchedChangeHandler() {
+               AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+
+                               Long pid_out = getAFieldLong(trcEvent, traceSt,
+                                               Fields.LTT_FIELD_PREV_PID);
+                               Long pid_in = getAFieldLong(trcEvent, traceSt,
+                                               Fields.LTT_FIELD_NEXT_PID);
+
+                               // This is useless even in Lttv !!
+                               // Long state_out = getAFieldLong(trcEvent, traceSt,
+                               // Fields.LTT_FIELD_PREV_STATE);
+
+                               // We need to process information.
+                               LttngProcessState process = traceSt.getRunning_process().get(
+                                               trcEvent.getCpuId());
+
+                               if (process != null) {
+                                       if (process.getPid().equals(pid_out) == false) {
+                                               // To replace :
+                                               // process = lttv_state_find_process(ts,tfs->cpu,
+                                               // pid_out);
+                                               process = lttv_state_find_process(traceSt, trcEvent
+                                                               .getCpuId(), pid_out);
+                                               // Also, removed :
+                                               // guint trace_num = ts->parent.index;
+                                       }
+
+                                       if (process != null) {
+                                               // TODO: Implement something similar to current hash in
+                                               // order to keep track of the current process and speed
+                                               // up finding the local resource.
+
+                                               // HashedProcessData *hashed_process_data = NULL;
+                                               // hashed_process_data =
+                                               // processlist_get_process_data(process_list,pid_out,process->cpu,&birth,trace_num);
+                                               TimeRangeEventProcess localProcess = procContainer
+                                                               .findProcess(process.getPid(), process.getCpu(), traceSt
+                                                                               .getTraceId(), process.getCreation_time());
+
+                                               // Add process to process list if not present
+                                               // Replace C Call :
+                                               // processlist_add(process_list,drawing,pid_out,process->tgid,process->cpu,process->ppid,&birth,trace_num,process->name,process->brand,&pl_height,&process_info,&hashed_process_data);
+                                               if (localProcess == null) {
+                                                       TmfTimeRange timeRange = traceSt.getContext()
+                                                                       .getTraceTimeWindow();
+                                                       localProcess = addLocalProcess(process, timeRange
+                                                                       .getStartTime().getValue(), timeRange
+                                                                       .getEndTime().getValue(), traceSt
+                                                                       .getTraceId());
+                                               }
+
+                                               // Do the actual drawing
+                                               makeDraw(traceSt, trcEvent.getTimestamp().getValue(),
+                                                               process,
+                                                               localProcess, params);
+                                       } else {
+                                               // Process may be null if the process started BEFORE the
+                                               // trace start
+                                               // TraceDebug.debug("Process is null for pid_out! (getBeforeSchedChangeHandler)");
+                                       }
+
+                                       // PID_IN section
+                                       process = lttv_state_find_process(traceSt, trcEvent
+                                                       .getCpuId(), pid_in);
+
+                                       if (process != null) {
+                                               // HashedProcessData *hashed_process_data = NULL;
+                                               // hashed_process_data =
+                                               // processlist_get_process_data(process_list, pid_in,
+                                               // tfs->cpu, &birth, trace_num);
+                                               TimeRangeEventProcess localProcess = procContainer
+                                                               .findProcess(process.getPid(), process.getCpu(), traceSt
+                                                                               .getTraceId(), process.getCreation_time());
+
+                                               // Add process to process list if not present
+                                               // Replace C Call :
+                                               // processlist_add(process_list, drawing, pid_in,
+                                               // process->tgid, tfs->cpu, process->ppid, &birth,
+                                               // trace_num, process->name, process->brand, &pl_height,
+                                               // &process_info, &hashed_process_data);
+                                               if (localProcess == null) {
+                                                       TmfTimeRange timeRange = traceSt.getContext()
+                                                                       .getTraceTimeWindow();
+                                                       localProcess = addLocalProcess(process, timeRange
+                                                                       .getStartTime().getValue(), timeRange
+                                                                       .getEndTime().getValue(), traceSt
+                                                                       .getTraceId());
+                                               }
+
+                                               // Do the actual drawing
+                                               makeDraw(traceSt, trcEvent.getTimestamp().getValue(),
+                                                               process,
+                                                               localProcess, params);
+
+                                       } else {
+                                               // Process can be null if it started AFTER the trace
+                                               // end. Do nothing...
+                                               // TraceDebug.debug("No process found for pid_in! Something is wrong? (getBeforeSchedChangeHandler)");
+                                       }
+                               } else {
+                                       TraceDebug
+                                                       .debug("Running process is null! (getBeforeSchedChangeHandler)");
+                               }
+
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_PROCESS_EXIT
+        * </p>
+        * Replace C function named "before_process_exit_hook" in eventhooks.c
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getProcessExitHandler() {
+               AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+
+                               // We need to process information.
+                               LttngProcessState process = traceSt.getRunning_process().get(
+                                               trcEvent.getCpuId());
+
+                               if (process != null) {
+                                       // TODO: Implement a similar method to track the current
+                                       // local process in order to speed up finding the local
+                                       // resource
+
+                                       // hashed_process_data =
+                                       // processlist_get_process_data(process_list, pid,
+                                       // process->cpu, &birth,trace_num);
+                                       TimeRangeEventProcess localProcess = procContainer
+                                                       .findProcess(process.getPid(), process.getCpu(), traceSt
+                                                                       .getTraceId(), process.getCreation_time());
+
+                                       // Add process to process list if not present
+                                       // Replace C Call :
+                                       // processlist_add(process_list, drawing, pid,
+                                       // process->tgid, process->cpu, process->ppid, &birth,
+                                       // trace_num, process->name, process->brand,&pl_height,
+                                       // &process_info, &hashed_process_data);
+                                       if (localProcess == null) {
+                                               TmfTimeRange timeRange = traceSt.getContext()
+                                                               .getTraceTimeWindow();
+                                               localProcess = addLocalProcess(process, timeRange
+                                                               .getStartTime().getValue(), timeRange
+                                                               .getEndTime().getValue(), traceSt.getTraceId());
+                                       }
+
+                                       // Call the function that does the actual drawing
+                                       makeDraw(traceSt, trcEvent.getTimestamp().getValue(),
+                                                       process, localProcess, params);
+
+                               } else {
+                                       TraceDebug
+                                                       .debug("Running process is null! (getProcessExitHandler)");
+                               }
+
+                               return false;
+                       }
+               };
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_PROCESS_FREE
+        * </p>
+        * Replace C function named "before_process_release_hook" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_PID
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getProcessFreeHandler() {
+               AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+                               // PID of the process to release
+                               Long release_pid = getAFieldLong(trcEvent, traceSt,
+                                               Fields.LTT_FIELD_PID);
+
+                               if ((release_pid != null)) {
+                                       LttngProcessState process = lttv_state_find_process(
+                                                       traceSt, ANY_CPU, release_pid);
+                                       if (process != null) {
+
+                                               // Replace the C call :
+                                               // hashed_process_data =
+                                               // processlist_get_process_data(process_list,pid,process->cpu,&birth,trace_num);
+                                               TimeRangeEventProcess localProcess = procContainer
+                                                               .findProcess(process.getPid(), process.getCpu(), traceSt
+                                                                               .getTraceId(), process
+                                        .getCreation_time());
+
+                                               // This is as it was in the C ... ?
+                                               if (localProcess == null) {
+                                                       return false;
+                                               }
+
+                                               // Perform the drawing
+                                               makeDraw(traceSt, trcEvent.getTimestamp().getValue(),
+                                                               process,
+                                                               localProcess, params);
+                                       }
+                               } else {
+                                       TraceDebug
+                                                       .debug("Release_pid is null! (getProcessFreeHandler)");
+                               }
+
+                               return false;
+                       }
+               };
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_STATEDUMP_END
+        * </p>
+        * Replace C function named "before_statedump_end" in eventhooks.c
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getStateDumpEndHandler() {
+               AbsFlowTRangeUpdate handler = new AbsFlowTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+
+                               // What's below should replace the following call in C :
+                               // ClosureData closure_data;
+                               // closure_data.events_request = events_request;
+                               // closure_data.tss = tss;
+                               // closure_data.end_time = evtime;
+                               // convert_time_to_pixels(time_window,evtime,width,&closure_data.x_end);
+                               // g_hash_table_foreach(process_list->process_hash,
+                               // draw_closure,(void*)&closure_data);
+                               //
+                               // And the draw is always the same then...
+
+                               // The c-library loops through the local processes, search for
+                               // the local processes in the state provider and then draws
+                               // If it's present is the local processes why shuldn't they be
+                               // present in the state provider?
+                               // This seems more direct. and makes sure all processes are
+                               // reflected in the control flow view.
+                               LttngProcessState[] processes = traceSt.getProcesses();
+                               for (int pos=0; pos < processes.length; pos++) {
+                                       LttngProcessState process = processes[pos];
+                                       
+                                       // Replace the C call :
+                                       // hashed_process_data =
+                                       // processlist_get_process_data(process_list,pid,process->cpu,&birth,trace_num);
+                                       TimeRangeEventProcess localProcess = procContainer
+                                                       .findProcess(process.getPid(), process.getCpu(), traceSt
+                                                                       .getTraceId(), process
+                                    .getCreation_time());
+
+                                       // Add process to process list if not present
+                                       if (localProcess == null) {
+                                               TmfTimeRange timeRange = traceSt.getContext()
+                                                               .getTraceTimeWindow();
+                                               localProcess = addLocalProcess(process, timeRange
+                                                               .getStartTime().getValue(), timeRange
+                                                               .getEndTime().getValue(), traceSt.getTraceId());
+                                       }
+
+                                       // Call the function that will does the actual
+                                       // drawing
+                                       makeDraw(traceSt, trcEvent.getTimestamp().getValue(),
+                                                       process, localProcess, params);
+                               }
+
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowEventToHandlerFactory.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowEventToHandlerFactory.java
new file mode 100644 (file)
index 0000000..ea60199
--- /dev/null
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventToHandlerResolver;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+
+/**
+ * Builds a Map from string event name to a processing handler object, the
+ * processors implement the same interface to facilitate transparent methods
+ * call,
+ * 
+ * The map key STring is the entry point of the raw events, using a hash speeds
+ * up the resolution of the appropriate processor
+ * 
+ * @author alvaro
+ * 
+ */
+public class FlowEventToHandlerFactory extends AbsEventToHandlerResolver {
+       // ========================================================================
+       // Data
+       // =======================================================================
+       private final Map<String, ILttngEventProcessor> eventNametoBeforeProcessor = new HashMap<String, ILttngEventProcessor>();
+       private final Map<String, ILttngEventProcessor> eventNametoAfterProcessor = new HashMap<String, ILttngEventProcessor>();
+       private ILttngEventProcessor finishProcesor = null;
+       private static FlowEventToHandlerFactory instance = null;
+       private FlowBeforeUpdateHandlers instantiateBeforeHandler = new FlowBeforeUpdateHandlers();
+       private FlowAfterUpdateHandlers instantiateAfterHandler = new FlowAfterUpdateHandlers();
+
+       // ========================================================================
+       // Constructors
+       // =======================================================================
+       private FlowEventToHandlerFactory() {
+               super();
+               // Create one instance of each individual event handler and add the
+               // instance to the map
+
+               // BEFORE HOOKS
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SYSCALL_ENTRY.getInName(),
+                               instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SYSCALL_EXIT.getInName(),
+                               instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_ENTRY
+                               .getInName(), instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_EXIT
+                               .getInName(), instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PAGE_FAULT_ENTRY.getInName(),
+                               instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PAGE_FAULT_EXIT.getInName(),
+                               instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY
+                                               .getInName(), instantiateBeforeHandler
+                                               .getStateModesHandler());
+
+               eventNametoBeforeProcessor
+                               .put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_EXIT
+                                               .getInName(), instantiateBeforeHandler
+                                               .getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_ENTRY
+                               .getInName(), instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_EXIT
+                               .getInName(), instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SOFT_IRQ_ENTRY.getInName(),
+                               instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SOFT_IRQ_EXIT.getInName(),
+                               instantiateBeforeHandler.getStateModesHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE.getInName(),
+                               instantiateBeforeHandler.getBeforeSchedChangeHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PROCESS_EXIT.getInName(),
+                               instantiateBeforeHandler.getProcessExitHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PROCESS_FREE.getInName(),
+                               instantiateBeforeHandler.getProcessFreeHandler());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_STATEDUMP_END.getInName(),
+                               instantiateBeforeHandler.getStateDumpEndHandler());
+
+
+               // AFTER HOOKS
+               eventNametoAfterProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE.getInName(),
+                               instantiateAfterHandler.getSchedChangeHandler());
+
+               eventNametoAfterProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PROCESS_FORK.getInName(),
+                               instantiateAfterHandler.getProcessForkHandler());
+
+               eventNametoAfterProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PROCESS_EXIT.getInName(),
+                               instantiateAfterHandler.getProcessExitHandler());
+
+               eventNametoAfterProcessor.put(StateStrings.Events.LTT_EVENT_EXEC
+                               .getInName(), instantiateAfterHandler.getProcessExecHandler());
+
+               eventNametoAfterProcessor.put(
+                               StateStrings.Events.LTT_EVENT_THREAD_BRAND.getInName(),
+                               instantiateAfterHandler.GetThreadBrandHandler());
+
+               eventNametoAfterProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PROCESS_STATE.getInName(),
+                               instantiateAfterHandler.getEnumProcessStateHandler());
+
+               finishProcesor = new FlowFinishUpdateHandler();
+       }
+
+       // ========================================================================
+       // Public methods
+       // =======================================================================
+       /**
+        * The event processors are common to all traces an multiple instances will
+        * use more memory unnecessarily
+        * 
+        * @return
+        */
+       public static AbsEventToHandlerResolver getInstance() {
+               if (instance == null) {
+                       instance = new FlowEventToHandlerFactory();
+               }
+               return instance;
+       }
+
+       @Override
+       public ILttngEventProcessor getAfterProcessor(String eventType) {
+               return eventNametoAfterProcessor.get(eventType);
+       }
+
+       @Override
+       public ILttngEventProcessor getBeforeProcessor(String eventType) {
+               return eventNametoBeforeProcessor.get(eventType);
+       }
+
+       @Override
+       public ILttngEventProcessor getfinishProcessor() {
+               return finishProcesor;
+       }
+
+       @Override
+       public ILttngEventProcessor getStateUpdaterProcessor(String eventType) {
+               return null;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowFinishUpdateHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/evProcessor/FlowFinishUpdateHandler.java
new file mode 100644 (file)
index 0000000..c441c5d
--- /dev/null
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * 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: Alvaro Sanchez-Leon - Initial implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor;
+
+import java.util.Vector;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Events;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngProcessState;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeComponent;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEvent;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventProcess;
+
+/**
+ * Creates specific finish state data request
+ * 
+ * @author alvaro
+ * 
+ */
+public class FlowFinishUpdateHandler extends AbsFlowTRangeUpdate
+               implements ILttngEventProcessor {
+
+       public Events getEventHandleType() {
+               // No specific event
+               return null;
+       }
+
+       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+               // Draw a last known state to the end of the trace
+               long endReqTime = traceSt.getContext().getTraceTimeWindow()
+                               .getEndTime().getValue();
+               TraceDebug.debug("Number of localProcesses: "
+                               + procContainer.readItems().length);
+               // to identify the process relevant to the traceState
+               String traceId = traceSt.getTraceId();
+               int numLocalFound = 0;
+               int numLocalNotFound = 0;
+               int numWithNoChildren = 0;
+               for (TimeRangeEventProcess localProcess : procContainer.readItems()) {
+                       LttngProcessState stateProcess = lttv_state_find_process(traceSt,
+                                       localProcess.getCpu(), localProcess.getPid());
+
+                       // Drawing the last state for processes related to the current trace
+                       // id.
+                       if (!localProcess.getTraceID().equals(traceId)) {
+                               continue;
+                       }
+
+                       // Check if the process is in the state provider, it is the case
+                       // when the requested time frame did not include any events for a
+                       // process
+                       if (stateProcess == null) {
+                               // Get Start time from the end time of previous event
+                               Vector<TimeRangeComponent> childrenEvents = localProcess
+                                               .getTraceEvents();
+                               long nextGoodTime;
+                               String stateMode;
+                               if (childrenEvents.size() > 0) {
+                                       TimeRangeComponent prevEvent = childrenEvents
+                                                       .get(childrenEvents.size() - 1);
+                                       if (prevEvent instanceof TimeRangeEvent) {
+                                               TimeRangeEvent prevTimeRange = (TimeRangeEvent) prevEvent;
+                                               // calculate the next good time to draw the event
+                                               // nextGoodTime = prevTimeRange.getStopTime() + 1;
+                                               nextGoodTime = localProcess.getNext_good_time();
+                                               stateMode = prevTimeRange.getStateMode();
+
+                                               // Draw with the Local information since the current
+                                               // request did
+                                               // not contain events related to this process
+                                               makeDraw(traceSt, nextGoodTime,
+                                                               endReqTime, localProcess, params, stateMode);
+                                       } else {
+                                               TraceDebug
+                                                               .debug("previous event not instance of TimeRangeEvent?: "
+                                                                               + prevEvent.getClass().getSimpleName());
+                                       }
+                               } else {
+                                       numWithNoChildren++;
+                               }
+
+                               numLocalNotFound++;
+                               continue;
+                       }
+                       numLocalFound++;
+                       // Draw the last state for this process
+
+                       makeDraw(traceSt, endReqTime, stateProcess, localProcess, params);
+               }
+
+               TraceDebug.debug("Print Last Event: NumLocalFound " + numLocalFound
+                               + "; NumLocalNotFound: " + numLocalNotFound
+                               + "; NumWithNoChildren: " + numWithNoChildren);
+
+               return false;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/messages.properties b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/messages.properties
new file mode 100644 (file)
index 0000000..0260851
--- /dev/null
@@ -0,0 +1,26 @@
+ControlFlowView.Action.Filter=Filter\r
+ControlFlowView.Action.Filter.ToolTip=Process Filter options\r
+ControlFlowView.Action.Legend=Legend\r
+ControlFlowView.Action.Legend.ToolTip=Show Legend\r
+ControlFlowView.Action.LoadData=LoadData\r
+ControlFlowView.Action.LoadData.ToolTip=Load data from external plug-in\r
+ControlFlowView.Action.NextEvent=NextEv\r
+ControlFlowView.Action.NextEvent.Tooltip=Next Event\r
+ControlFlowView.Action.NextProcess=NextProcess\r
+ControlFlowView.Action.NextProcess.ToolTip=Select Next Process\r
+ControlFlowView.Action.PrevEvent=PrevEv\r
+ControlFlowView.Action.PrevEvent.Tooltip=Previous Event\r
+ControlFlowView.Action.PreviousProcess=PreviousProcess\r
+ControlFlowView.Action.PreviousProcess.Tooltip=Select Previous Process\r
+ControlFlowView.Action.Reset=Reset\r
+ControlFlowView.Action.Reset.ToolTip=Reset the Time Scale to Default\r
+ControlFlowView.Action.Synchronize=Synchronise\r
+ControlFlowView.Action.Synchronize.ToolTip=Synchronise by listening to external API selection calls\r
+ControlFlowView.Action.ZoomIn=Zoom In\r
+ControlFlowView.Action.ZoomIn.Tooltip=Zoom In\r
+ControlFlowView.Action.ZoomOut=Zoom Out\r
+ControlFlowView.Action.ZoomOut.tooltip=Zoom Out\r
+ControlFlowView.Action.ZoomFilter=Zoom Filter\r
+ControlFlowView.Action.ZoomFilter.tooltip=Display elements with events within the zoomed time window\r
+ControlFlowView.msgSlogan=Control Flow View\r
+ControlFlowView.tmf.UI=org.eclipse.linuxtools.tmf.ui\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/model/FlowModelFactory.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/model/FlowModelFactory.java
new file mode 100644 (file)
index 0000000..25a14ff
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.controlflow.model;
+
+import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
+
+/**
+ * Instantiates the entry point classes to build the data model for this view
+ * 
+ * @author alvaro
+ * 
+ */
+public class FlowModelFactory {
+       // ========================================================================
+       // Data
+       // ========================================================================
+       private static FlowProcessContainer procContainer = null;
+       private static ParamsUpdater updater = null;
+       
+       
+       // ========================================================================
+       // Methods
+       // ========================================================================
+       /**
+        * Get Process data container
+        * @return
+        */
+       public static FlowProcessContainer getProcContainer() {
+               if (procContainer == null) {
+                       procContainer = new FlowProcessContainer();
+               }
+               return procContainer;
+       }
+       
+       public static ParamsUpdater getParamsUpdater() {
+               if (updater == null) {
+                       updater = new ParamsUpdater();
+               }
+               return updater;
+       }
+       
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/model/FlowProcessContainer.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/controlflow/model/FlowProcessContainer.java
new file mode 100644 (file)
index 0000000..edcd107
--- /dev/null
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.controlflow.model;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.linuxtools.lttng.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventProcess;
+
+/**
+ * Contains the processes in use by the Control flow view
+ * 
+ * @author alvaro
+ * 
+ */
+public class FlowProcessContainer implements ItemContainer<TimeRangeEventProcess> {
+       // ========================================================================
+       // Data
+       // ========================================================================
+       private final HashMap<ProcessKey, TimeRangeEventProcess> allProcesses = new HashMap<ProcessKey, TimeRangeEventProcess>();
+       private static Integer uniqueId = 0;
+       
+       // ========================================================================
+       // Constructor
+       // ========================================================================
+
+       /**
+        * Package level constructor
+        */
+       FlowProcessContainer() {
+
+       }
+
+       // ========================================================================
+       // Methods
+       // ========================================================================
+       /**
+        * Interface to add a new process.<p>
+        * 
+        * Note : Process with the same key will be overwritten, it's calling function job to make sure the new process is unique.
+        * 
+        * @param newProcess   The process to add
+        */
+       public void addItem(TimeRangeEventProcess newItem) {
+               if (newItem != null) {
+                       allProcesses.put(new ProcessKey(newItem), newItem);
+               }
+       }
+       
+       /**
+     * Request a unique ID
+     * 
+     * @return Integer
+     */
+    public Integer getUniqueId() {
+        return uniqueId++;
+    }
+    
+    /**
+     * This method is intended for read only purposes in order to keep the
+     * internal data structure in synch
+     * 
+     * @return TimeRangeEventProcess[]
+     */
+       public TimeRangeEventProcess[] readItems() {
+               
+           // This allow us to return an Array of the correct type of the exact correct dimension, without looping
+               return allProcesses.values().toArray(new TimeRangeEventProcess[allProcesses.size()]);
+       }
+       
+       /**
+        * Clear the children information for processes e.g. just before refreshing
+        * data with a new time range
+        */
+       public void clearChildren() {
+           TimeRangeEventProcess process = null;
+        Iterator<ProcessKey> iterator = allProcesses.keySet().iterator();
+        
+        while (iterator.hasNext()) {
+            process = allProcesses.get(iterator.next());
+                       process.reset();
+        }
+       }
+       
+       /**
+     * Clear all process items
+     */
+    public void clearItems() {
+        allProcesses.clear();
+    }
+       
+    /**
+     * Remove the process related to a specific trace e.g. during trace
+     * removal
+     * 
+     * @param traceId   The trace unique id (trace name?) on which we want to remove process
+     */
+       public void removeItems(String traceId) {
+           ProcessKey iterKey = null;
+
+        Iterator<ProcessKey> iterator = allProcesses.keySet().iterator();
+        while (iterator.hasNext()) {
+            iterKey = iterator.next();
+            
+            if (allProcesses.get(iterKey).getTraceID().equals(traceId)) {
+                allProcesses.remove(iterKey);
+            }
+        }
+       }
+       
+    /**
+     * Search by keys (pid, cpuId, traceId and creationTime)<p>
+     * 
+     * A match is returned if the four arguments received match an entry
+     *  Otherwise null is returned
+     *  
+     * @param searchedPid       The processId (Pid) we are looking for
+     * @param searchedCpuId     The cpu Id we are looking for
+     * @param searchedTraceID   The traceId (trace name?) we are looking for
+     * @param searchedCreationtime The creation time we are looking for
+     * 
+     * @return TimeRangeEventProcess
+     */
+    public TimeRangeEventProcess findProcess(Long searchedPid, Long searchedCpuId, String searchedTraceID, Long searchedCreationtime) {
+       // Get the TimeRangeEventProcess associated to a key we create here
+        TimeRangeEventProcess foundProcess = allProcesses.get( new ProcessKey(searchedPid, searchedCpuId, searchedTraceID, searchedCreationtime) );
+        
+        return foundProcess;
+    }
+}
+
+
+class ProcessKey {
+    private TimeRangeEventProcess valueRef = null;
+    
+    private Long    pid = null;
+    private Long    cpuId = null;
+    private String  traceId = null;
+    private Long    creationtime = null;
+    
+    @SuppressWarnings("unused")
+    private ProcessKey() { }
+    
+    public ProcessKey(TimeRangeEventProcess newRef) {
+        valueRef = newRef;
+    }
+    
+    public ProcessKey(Long newPid, Long newCpuId, String newTraceId, Long newCreationTime) {
+        pid = newPid;
+        cpuId = newCpuId;
+        traceId = newTraceId;
+        creationtime = newCreationTime;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        boolean isSame = false;
+        
+        if ( obj instanceof ProcessKey ) {
+               ProcessKey procKey = (ProcessKey) obj;
+               
+               if ( valueRef != null ) {
+                   if ( (procKey.getPid().equals(valueRef.getPid()) ) &&
+                        (procKey.getTraceId().equals(valueRef.getTraceID()) ) &&
+                        (procKey.getCpuId().equals(valueRef.getCpu()) ) &&
+                        (procKey.getCreationtime().equals(valueRef.getCreationTime()) )  )
+                   {
+                       isSame = true;
+                   }
+               }
+               else {
+                       if ( (procKey.getPid().equals(this.pid ) ) &&
+                        (procKey.getTraceId().equals(this.traceId ) ) &&
+                        (procKey.getCpuId().equals(this.cpuId ) ) &&
+                        (procKey.getCreationtime().equals(this.creationtime ) )  )
+                   {
+                       isSame = true;
+                   }
+               }
+        }
+        else {
+               TraceDebug.debug("ERROR : The given key is not of the type ProcessKey!" + obj.getClass().toString());
+        }
+        
+        return isSame;
+    }
+    
+    // *** WARNING : Everything in there work because the check "valueRef != null" is the same for ALL getter
+    // Do NOT change this check without checking.
+    public Long getPid() {
+       if ( valueRef != null ) {
+            return valueRef.getPid();
+        }
+        else {
+            return pid;
+        }
+    }
+
+    public Long getCpuId() {
+        if ( valueRef != null ) {
+            return valueRef.getCpu();
+        }
+        else {
+            return cpuId;
+        }
+    }
+    
+    public String getTraceId() {
+        if ( valueRef != null ) {
+            return valueRef.getTraceID();
+        }
+        else {
+            return traceId;
+        }
+    }
+    
+    public Long getCreationtime() {
+        if ( valueRef != null ) {
+            return valueRef.getCreationTime();
+        }
+        else {
+            return creationtime;
+        }
+    }
+    
+    @Override
+    public int hashCode() {
+       return this.toString().hashCode();
+    }
+    
+    
+    @Override
+    public String toString() {
+        if ( valueRef != null ) {
+            return (valueRef.getPid().toString() + ":" + valueRef.getCpu().toString() + ":" + valueRef.getTraceID().toString() + ":" + valueRef.getCreationTime().toString());
+        } 
+        
+        return (pid.toString() + ":" + cpuId.toString() + ":" + traceId.toString() + ":" + creationtime.toString());
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/events/EventsView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/events/EventsView.java
new file mode 100644 (file)
index 0000000..306adfe
--- /dev/null
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.events;
+
+import org.eclipse.linuxtools.lttng.event.LttngEventContent;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.ui.views.TmfEventsView;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * <b><u>EventsView</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class EventsView extends TmfEventsView {
+
+    public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.events";
+
+    // ------------------------------------------------------------------------
+    // Table data
+    // ------------------------------------------------------------------------
+
+    // Table column names
+    private final String TIMESTAMP_COLUMN = "Timestamp";
+    private final String SOURCE_COLUMN    = "Source";
+    private final String TYPE_COLUMN      = "Type";
+    private final String REFERENCE_COLUMN = "Reference";
+    private final String CONTENT_COLUMN   = "Content";
+    private final String[] columnProperties =  new String[] {
+        TIMESTAMP_COLUMN,
+        SOURCE_COLUMN,
+        TYPE_COLUMN,
+        REFERENCE_COLUMN,
+        CONTENT_COLUMN
+    };
+
+    // Column data
+    private class ColumnData {
+        public final String header;
+        public final int    width;
+        public final int    alignment;
+
+        public ColumnData(String h, int w, int a) {
+            header = h;
+            width = w;
+            alignment = a;
+        }
+    };
+
+    private ColumnData[] columnData = new ColumnData[] {
+        new ColumnData(columnProperties[0], 125, SWT.LEFT),
+        new ColumnData(columnProperties[1], 100, SWT.LEFT),
+        new ColumnData(columnProperties[2], 200, SWT.LEFT),
+        new ColumnData(columnProperties[3], 200, SWT.LEFT),
+        new ColumnData(columnProperties[4], 100, SWT.LEFT)
+    };
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    public EventsView() {
+       super(1);
+    }
+
+       /**
+        * @param table
+        * 
+        * FIXME: Add support for column selection
+        */
+       @Override
+       protected void createColumnHeaders(Table table) {
+        for (int i = 0; i < columnData.length; i++) {
+            final TableColumn column = new TableColumn(table, columnData[i].alignment, i);
+            column.setText(columnData[i].header);
+            column.setWidth(columnData[i].width);
+            // TODO: Investigate why the column resizing doesn't work by default
+            // Anything to do with SWT_VIRTUAL?
+            column.addSelectionListener(new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       // TODO Auto-generated method stub
+                               }
+                               public void widgetSelected(SelectionEvent e) {
+                                       column.pack();
+                               }
+            });
+        }
+       }
+
+    /**
+     * @param event
+     * @return
+     */
+    @Override
+       protected String[] extractItemFields(TmfEvent event) {
+        String[] fields = new String[0];
+        
+        if (event != null) {
+            fields = new String[] {
+                    event.getTimestamp().toString(),
+                    event.getSource().toString(),
+                    event.getType().toString(),
+                    event.getReference().toString(),
+                    ((LttngEventContent)event.getContent()).toString() 
+                };
+        }
+        return fields;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+       public String toString() {
+       return "[EventsView]";
+    }
+
+
+}
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
new file mode 100644 (file)
index 0000000..87464d0
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.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 {
+       
+       protected HistogramView parentHistogramWindow = 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 newParentWindow, Composite parent, int style) {
+               super(parent, style);
+               
+               parentHistogramWindow = newParentWindow;
+       }
+       
+       /**
+        * 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() {
+               parentHistogramWindow.updateSelectedWindowInformation();
+       }
+}
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
new file mode 100644 (file)
index 0000000..b362367
--- /dev/null
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * 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.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
+{
+       protected AsyncCanvasRedrawer   canvasRedrawer   = null;
+       protected HistogramContent              histogramContent = null;
+       
+       protected HistogramCanvasPaintListener          paintListener = null;
+       protected HistogramCanvasMouseListener          mouseListener = null;
+       protected HistogramCanvasKeyListener            keyListener   = null;
+       protected HistogramCanvasFocusListener          focusListener = null;
+       protected HistogramCanvasControlListener        controlListener = null;
+       
+       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(Composite parent, int style) {
+               super(parent, style);
+               addNeededListeners();
+               
+               // New selected window, not visible by default
+               createNewSelectedWindow(0L);
+       }
+       
+       /*
+        * Create the needed "event listeners" and hook them to the Canvas.
+        */
+       protected void addNeededListeners() {
+               createAndAddCanvasRedrawer();
+               createAndAddPaintListener();
+               createAndAddMouseListener();
+               createAndAddKeyListener();
+               createAndAddFocusListener();
+               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
+        */
+       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
+        */
+       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
+        */
+       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
+        */
+       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.
+        */
+       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
+        */
+       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);
+       }
+       
+       /**
+        * 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.
+        * 
+        */
+       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.
+        */
+       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.
+        */
+       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.
+        */
+       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>
+        * 
+        */
+       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
+       }
+}
+
+
+/**
+ * <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() {
+               Display display = parentCanvas.getDisplay();
+               display.asyncExec(new Runnable() {
+                       public void run() {
+                               parentCanvas.redraw();
+                       }
+               });
+       }
+       
+       /**
+        * 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() {
+               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() {
+               Display display = parentCanvas.getDisplay();
+               display.asyncExec(new Runnable() {
+                       public void run() {
+                               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
new file mode 100644 (file)
index 0000000..f361717
--- /dev/null
@@ -0,0 +1,63 @@
+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 {
+       
+       protected HistogramCanvas parentCanvas = null;
+       
+       /**
+        * HistogramCanvasControlListener constructor
+        * 
+        * @param newCanvas Related canvas
+        */
+       public HistogramCanvasControlListener(HistogramCanvas newCanvas) {
+               parentCanvas = newCanvas;
+       }
+       
+       
+       /**
+        * Method called when the canvas is moved.<p>
+        * 
+        * Just redraw the canvas...
+        * 
+        * @param event         The controle event generated by the move.
+        */
+       public void controlMoved(ControlEvent event) {
+               parentCanvas.redraw();
+       }
+       
+       /**
+        * 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.
+        */
+       public void controlResized(ControlEvent event) {
+               
+               if ( (parentCanvas != null) && (parentCanvas.getHistogramContent() != null) ) {
+                       int newSize = parentCanvas.getSize().x;
+                       int oldSize = parentCanvas.getHistogramContent().getCanvasWindowSize();
+                       
+                       // Set the new canvas size
+                       parentCanvas.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 = parentCanvas.getCurrentWindow().getWindowXPositionCenter();
+                       int newWindowCenter = (int)Math.ceil((double)newSize * ((double)oldWindowCenter / (double)oldSize));
+                       parentCanvas.setWindowCenterPosition(newWindowCenter);
+               }
+       }
+}
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
new file mode 100644 (file)
index 0000000..8bf3dff
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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.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 {
+       
+       protected HistogramCanvas parentCanvas = null;
+       
+       /**
+        * HistogramCanvasFocusListener constructor
+        * 
+        * @param newCanvas Related canvas
+        */
+       public HistogramCanvasFocusListener(HistogramCanvas newCanvas) {
+               parentCanvas = 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.
+        */
+       public void focusGained(FocusEvent event) {
+               parentCanvas.redrawAsynchronously();
+       }
+       
+       /**
+        * Function that is called when the canvas loose focus.<p>
+        * 
+        * Doesn't do anything yet... 
+        * 
+        * @param event  The focus event generated.
+        */
+       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
new file mode 100644 (file)
index 0000000..84408e1
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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 
+{
+       protected HistogramCanvas parentCanvas = null;
+       protected boolean isShiftPressed = false;
+       
+       /**
+        * HistogramCanvasKeyListener constructor
+        * 
+        * @param newCanvas Related canvas
+        */
+       public HistogramCanvasKeyListener(HistogramCanvas 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.
+        */
+       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.
+        */
+       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
new file mode 100644 (file)
index 0000000..7c06cd6
--- /dev/null
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * 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.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 
+{
+       protected DelayedMouseScroll mouseScrollListener = null;
+       protected HistogramCanvas parentCanvas = null;
+       
+       protected boolean isWindowMoving = false;
+       
+       /**
+        * HistogramCanvasMouseListener constructor
+        * 
+        * @param newCanvas Related canvas
+        */
+       public HistogramCanvasMouseListener(HistogramCanvas 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.
+        */
+       public void mouseMove(MouseEvent event) {
+               if ( 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.
+        */
+       public void mouseDown(MouseEvent event) {
+               if ( event.button == 1) {
+                       isWindowMoving = true;
+                       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.
+        */
+       public void mouseUp(MouseEvent event) {
+               if ( event.button == 1) {
+                       isWindowMoving = false;
+                       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.
+        */
+       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.
+        */
+       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();
+               }
+       }
+       
+       /**
+        * 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 receiveMouseScrollCount(int nbMouseScroll) {
+               mouseScrollListener = null;
+               
+               long ajustedTime = 0;
+               
+               // If we received Negative scroll event, ZoomOut by ZOOM_OUT_FACTOR * the number of scroll events received.
+               if ( nbMouseScroll < 0 ) {
+                       ajustedTime = (long)((double)parentCanvas.getSelectedWindowSize() * HistogramConstant.ZOOM_OUT_FACTOR);
+                       ajustedTime = ajustedTime * Math.abs(nbMouseScroll);
+                       ajustedTime = parentCanvas.getSelectedWindowSize() + ajustedTime;
+               }
+               // If we received Positive scroll event, ZoomIn by ZOOM_IN_FACTOR * the number of scroll events received.
+               else {
+                       ajustedTime = (long)((double)parentCanvas.getSelectedWindowSize() * HistogramConstant.ZOOM_IN_FACTOR);
+                       ajustedTime = ajustedTime * Math.abs(nbMouseScroll);
+                       ajustedTime = parentCanvas.getSelectedWindowSize() - ajustedTime;
+               }
+               
+               // Resize the canvas selection window  
+               parentCanvas.resizeWindowByAbsoluteTime(ajustedTime);
+       }
+       
+}
+
+/**
+ * <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++;
+       }
+       
+       /**
+        * 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--;
+       }
+       
+       /**
+        * 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.receiveMouseScrollCount(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
new file mode 100644 (file)
index 0000000..5b5cc86
--- /dev/null
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * 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.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * <b><u>HistogramCanvasPaintListener</u></b>
+ * <p>
+ * Implementation of a PaintListener for the need of the HistogramCanvas
+ * <p> 
+ */
+public class HistogramCanvasPaintListener implements PaintListener 
+{
+       protected HistogramCanvas  parentCanvas = null;
+       
+       /**
+        * HistogramCanvasPaintListener constructor
+        * 
+        * @param parentCanvas Related canvas
+        */
+       public HistogramCanvasPaintListener(HistogramCanvas newParentCanvas) {
+               parentCanvas = newParentCanvas;
+       }
+       
+       /**
+        * Function called when the canvas need to redraw.<p>
+        * 
+        * @param event  The generated paint event when redraw is called.
+        */
+       public void paintControl(PaintEvent event) {
+               
+               // First clear the whole canvas to have a clean section where to draw
+               clearDrawingSection(event);
+               
+               // If the content is null or has rady to draw we quit the function here
+               if ( (parentCanvas.getHistogramContent() == null) || (parentCanvas.getHistogramContent().getReadyUpToPosition() == 0) ) {
+                       return;
+               }
+               
+               // Call the function that draw the bars
+               drawHistogram(event);
+               
+               // Pinpoint a position if set
+               if (parentCanvas.getHistogramContent().getSelectedEventTimeInWindow() > 0 ) {
+                       drawSelectedEventInWindow(event);
+               }
+               
+               // If we have a selected window set to visible, call the function to draw it
+               if ( (parentCanvas.getCurrentWindow()  != null) && (parentCanvas.getCurrentWindow().getSelectedWindowVisible() == true) ) {
+                       drawSelectedWindow(event);
+               }
+       }
+       
+       /**
+        * 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 event The generated paint event when redraw is called.
+        */
+       public void clearDrawingSection(PaintEvent event) {
+               event.gc.setForeground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
+               event.gc.setBackground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
+               Rectangle allSection = new Rectangle(0, 0, event.width, event.height);
+               event.gc.fillRectangle(allSection);
+               event.gc.drawRectangle(allSection);
+       }
+       
+       // *** 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 event The generated paint event when redraw is called.
+        */
+       public synchronized void drawHistogram(PaintEvent event) {
+               HistogramContent tmpContent = parentCanvas.getHistogramContent();
+               int tmpBarWidth = tmpContent.getBarsWidth();
+               
+               // This will be the color for all the bars that wil be draw below.
+               event.gc.setBackground(event.display.getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR));
+               
+               // *** 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<tmpContent.getReadyUpToPosition(); x++) {
+               Rectangle rect = new Rectangle(tmpBarWidth*x, event.height - tmpContent.getElementByIndex(x).intervalHeight, tmpBarWidth, tmpContent.getElementByIndex(x).intervalHeight);
+               event.gc.fillRectangle(rect);
+           }
+           
+           // Clear the remaining space in the canvas (if any) so it appears clean.
+           event.gc.setBackground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
+           Rectangle rect = new Rectangle(tmpBarWidth*tmpContent.getNbElement(), 0, event.width, event.height);
+           event.gc.fillRectangle(rect);
+       }
+       
+       /**
+        * Draw a certain event selected in the window.<p>
+        * 
+        * @param event The generated paint event when redraw is called.
+        */
+       public synchronized void drawSelectedEventInWindow(PaintEvent event) {
+               HistogramContent tmpContent = parentCanvas.getHistogramContent();
+               int tmpBarWidth = tmpContent.getBarsWidth();
+               
+               // This will be the color for all the bars that wil be draw below.
+               event.gc.setBackground(event.display.getSystemColor(HistogramConstant.SELECTED_EVENT_COLOR));
+               
+               int position = tmpContent.getClosestXPositionFromTimestamp(tmpContent.getSelectedEventTimeInWindow());
+               
+               Rectangle rect = new Rectangle(tmpBarWidth*position, 0, tmpBarWidth, event.height);
+               event.gc.fillRectangle(rect);
+       }
+       
+       /**
+        * 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 event The generated paint event when redraw is called.
+        */
+       public void drawSelectedWindow(PaintEvent event) {
+               HistogramSelectedWindow tmpWindow = parentCanvas.getCurrentWindow();
+               
+               // Attributes (color and width) of the lines
+               event.gc.setForeground(event.display.getSystemColor(HistogramConstant.SELECTION_WINDOW_COLOR));
+               event.gc.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH);
+           
+               // Get the window position... this would fail if the window is not initialized yet
+               int positionCenter = tmpWindow.getWindowXPositionCenter();
+               int positionLeft = tmpWindow.getWindowXPositionLeft();
+               int positionRight = tmpWindow.getWindowXPositionRight();
+               
+               // Minimal size verification.
+               if ( (positionRight - positionLeft) < HistogramConstant.MINIMUM_WINDOW_WIDTH ) {
+                       positionLeft  = positionCenter - (HistogramConstant.MINIMUM_WINDOW_WIDTH/2);
+                       positionRight = positionCenter + (HistogramConstant.MINIMUM_WINDOW_WIDTH/2);
+               }
+               
+               // Draw the selection window square
+               event.gc.drawLine(positionLeft , 0               , positionLeft , event.height);
+               event.gc.drawLine(positionLeft , event.height, positionRight, event.height);
+               event.gc.drawLine(positionRight, event.height, positionRight, 0);
+               event.gc.drawLine(positionLeft , 0               , positionRight, 0);
+           
+               // Draw the crosshair section
+               event.gc.drawLine(positionCenter + HistogramConstant.SELECTION_CROSSHAIR_LENGTH, event.height/2, positionCenter - HistogramConstant.SELECTION_CROSSHAIR_LENGTH, event.height/2);
+               event.gc.drawLine(positionCenter, (event.height/2) + HistogramConstant.SELECTION_CROSSHAIR_LENGTH, positionCenter, (event.height/2) - HistogramConstant.SELECTION_CROSSHAIR_LENGTH);
+       }
+       
+}
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
new file mode 100644 (file)
index 0000000..092a10d
--- /dev/null
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * 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.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 = 1;
+       public final static int REDRAW_EVERY_NB_EVENTS = 10000;
+       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 = 500L;
+       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 HISTOGRAM_BARS_COLOR = SWT.COLOR_DARK_CYAN;
+       public final static int SELECTED_EVENT_COLOR = SWT.COLOR_RED;
+       public final static int SELECTION_WINDOW_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 = 2;
+       public final static int SELECTION_CROSSHAIR_LENGTH = 3;
+       
+       
+       /**
+        * 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 );
+               }
+               // Otherwise, patch missing decimal with 0
+               else {
+                       int curSize = returnedTime.length();
+                       for (int l=0; (curSize+l)< 9; l++) {
+                               returnedTime = "0" + returnedTime;
+                       }
+                       returnedTime = "0." + returnedTime;
+               }
+               
+               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(",", ".");
+       
+               // If we have a dot, we have a decimal number to convert
+               int dotPosition = timeString.indexOf(".");
+               
+               // If the user begun the line with a dot, we add a zero
+               if ( dotPosition == 0 ) {
+                timeString = "0" + timeString;
+                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");
+                    }
+                    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)");
+           }
+           
+           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
new file mode 100644 (file)
index 0000000..0959def
--- /dev/null
@@ -0,0 +1,785 @@
+/*******************************************************************************
+ * 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>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
+       protected long          startTime = 0L;
+       protected long          endTime   = 0L;
+       
+       // Some information about the content
+       // Most of them are required to calculate position and/or draw
+       // Make sure they stay consistent!
+       protected long          elementsTimeInterval = 1L;
+       protected double        heightFactor = 100.0;
+       protected long          heighestEventCount = 0L;
+       protected int   maxHeight        = 0;
+       protected int   canvasWindowSize = 0;
+       protected 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
+       protected 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
+       protected double  maxDifferenceFactor = 1.0;
+       
+       // By default we will only consider element up to this position 
+       protected int   readyUpToPosition = 0;
+       
+       // The average number of events in the content
+       // Note : this IS needed to draw
+       protected int   averageNumberOfEvents = 0;
+       
+       // This is to draw the selected event of the TMF framework in another color
+       // Set the 0 to ignore
+       protected long selectedEventTimeInWindow = -1L;
+       
+       // The table that hold the elements
+       protected 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) {
+               recalculateElementsTimeInterval(newStartTime, 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.
+        */
+       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>
+        */
+       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/HistogramElement.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramElement.java
new file mode 100644 (file)
index 0000000..eb907d4
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java
new file mode 100644 (file)
index 0000000..34d0057
--- /dev/null
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * 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.event.LttngEvent;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+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> {
+       protected HistogramContent histogramContent = null;
+       
+       protected int   lastInterval = 0;
+       protected long          lastRangeTime = 0L;
+       protected long          nbEventsInInterval = 0L;
+       
+       protected int   nbIntervalNotEmpty = 1;
+       protected int   nbEventRead = 0;
+       
+       protected int   lastDrawPosition = 0;
+       
+       protected HistogramCanvas parentCanvas = null;
+       
+       /**
+        * 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) {
+        super((Class<LttngEvent>)LttngEvent.class, range, nbRequested, HistogramConstant.MAX_EVENTS_PER_READ);
+        
+        // *** 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;
+        histogramContent = parentCanvas.getHistogramContent();
+        
+        // Reset the content of the HistogramContent... the given data better be valid or this will fail.
+        histogramContent.clearContentData();
+        histogramContent.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();
+    }
+       
+       /**
+        * 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() {
+        TmfEvent[] result = getData();
+        TmfEvent[] evt = new TmfEvent[1];
+        
+        evt[0] = (result.length > 0) ? result[0] : null;
+        
+        // *** 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!
+       //
+        if (evt[0] != null) {
+        
+               LttngEvent tmpEvent = (LttngEvent)evt[0];
+               
+               // This check is linked to the evil fix mentionned above
+               if ( ( tmpEvent.getTimestamp().getValue() >= histogramContent.getStartTime() ) &&
+                        ( tmpEvent.getTimestamp().getValue() <= histogramContent.getEndTime() ) )
+               {
+                       
+                       // Distance (in time) between this event and the last one we read
+                       long distance = ( tmpEvent.getTimestamp().getValue() - lastRangeTime );
+                               
+                       // Check if we changed of interval (the distance is higher than the interval time)
+                               if  ( distance > histogramContent.getElementsTimeInterval() ) {
+                                       
+                                       histogramContent.getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
+                                       lastRangeTime = tmpEvent.getTimestamp().getValue();
+                                       
+                                       // * NOTE *
+                                       // We can skip several interval at once, so we need to find what was our interval now
+                                       lastInterval = (int)((lastRangeTime - histogramContent.getStartTime()) / histogramContent.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 >= histogramContent.getNbElement() ) {
+                                               lastInterval = (histogramContent.getNbElement()-1);
+                                       }
+                                       
+                                       // * NOTE * 
+                                       // We save the time we have here. This mean only the FIRST time read in an interval will be saved. 
+                                       histogramContent.getElementByIndex(lastInterval).firstIntervalTimestamp = lastRangeTime;
+                                       histogramContent.setReadyUpToPosition(lastInterval);
+                                       
+                                       nbIntervalNotEmpty++;
+                                       nbEventsInInterval = 1L;
+                               }
+                               // We are still in the same interval, just keep counting
+                               else {
+                                       nbEventsInInterval++;
+                               }
+                               
+                               if ( nbEventsInInterval > histogramContent.getHeighestEventCount() ) {
+                                       histogramContent.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
+               histogramContent.getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
+               // We reached the end of the request, so assume we fill up the content as well
+                       histogramContent.setReadyUpToPosition(histogramContent.getNbElement());
+                       
+                       // If the interval wasn't null, count this as a "non empty" interval
+                       if (nbEventsInInterval > 0) {
+                               nbIntervalNotEmpty++;
+                       }
+        }
+    }
+       
+       /**
+        * Function that is called when the request completed (successful or not).<p>
+        * Update information and redraw the screen.
+        */
+    @Override
+    public void handleCompleted() {
+       parentCanvas.notifyParentUpdatedInformationAsynchronously();
+               redrawAsyncronously();
+    }
+    
+    /**
+        * 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();
+    }
+       
+    /**
+        * 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)histogramContent.getNbElement());
+       }
+       
+       histogramContent.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 = histogramContent.getHeightFactor();
+       histogramContent.recalculateHeightFactor();
+       if ( histogramContent.getHeightFactor() != previousHeightFactor ) {
+                       histogramContent.recalculateEventHeight();
+       }
+       else {
+               histogramContent.recalculateEventHeightInInterval(lastDrawPosition, histogramContent.getReadyUpToPosition());
+       }
+       
+       lastDrawPosition = histogramContent.getReadyUpToPosition();
+    }
+    
+    /**
+        * Perform an asynchonous redraw of the screen.
+        */
+    public void redrawAsyncronously() {
+       updateEventsInfo();
+       // Canvas redraw is already asynchronous
+       parentCanvas.redrawAsynchronously();
+    }
+    
+}
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
new file mode 100644 (file)
index 0000000..562da82
--- /dev/null
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * 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>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 {
+       
+       protected int windowCenterPosition = 0;
+       protected long  windowTimeWidth = 0L;
+       
+       protected Boolean isSelectedWindowVisible = false;
+       
+       protected HistogramContent histogramContent = null;
+       
+       /**
+        * Default constructor for HistogramSelectedWindow.<p>
+        * Position and TimeWidth are both set to 0
+        * 
+        * @param newTraceContent       HistogramContent to read window's data from
+        */
+       public HistogramSelectedWindow(HistogramContent newTraceContent) {
+               histogramContent = newTraceContent;
+       }
+       
+       /**
+        * 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, int centralPosition, long newWindowWidth) {
+               histogramContent = newTraceContent;
+               windowCenterPosition = centralPosition;
+               windowTimeWidth = newWindowWidth;
+       }
+       
+       /** 
+        * Getter for the HistogramContent used by the window.<p>
+        * 
+        * @return HistogramContent tied to this selection window.
+        */
+       public HistogramContent getTraceContent() {
+               return histogramContent;
+       }
+       
+       /**
+        * Setter for the HistogramContent used by the window.<p>
+        * This need to be a valid, initialized HistogramContent;
+        *      the data in the content are needed for positionning the window.
+        * 
+        * @param newTraceContent  A new HistogramContent
+        */
+       public void setTraceContent(HistogramContent newTraceContent) {
+               this.histogramContent = newTraceContent;
+       }
+       
+       
+       /**
+        * 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 central position of the window.<p>
+        * 
+        * @return Center X position of this window on the canvas.
+        */
+       public int getWindowXPositionCenter() {
+               return windowCenterPosition;
+       }
+       
+       /**
+        * Setter for the central position of the window.<p>
+        * The new position need to be valid on the canvas (0 to canvasWidth).
+        * 
+        * @param newPosCenter  The new central position.
+        */
+       public void setWindowXPositionCenter(int newPosCenter) {
+               this.windowCenterPosition = newPosCenter;
+       }
+       
+       /**
+        * Getter for the left border of the window.<p>
+        * Compute the position from the HistogramContent data; may return 0 if the content data are wrong.  
+        * 
+        * @return The left position of the window, or 0 if it cannot compute it. 
+        */
+       public int getWindowXPositionLeft() {
+               
+               // If the timewidth is too small, we would pick the same position as the center one.
+               // To avoid this, we take a "full interval" when the window size is too small
+               if ( windowTimeWidth < histogramContent.getElementsTimeInterval() ) {
+                       // Use intervalTime and not intervalTime/2 to make sure we step into the next interval
+                       // Otherwise, if we are in the beginning of an interval, adding IntervalTime/2 could lead us into the same one
+                       // The rounding operation will then return a correct position
+                       return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterPosition, -(histogramContent.getElementsTimeInterval() ) );
+               }
+               else {
+                       return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterPosition, -(windowTimeWidth / 2) );
+               }
+       }
+       
+       /**
+        * Getter for the right border of the window.<p>
+        * Compute the position from the HistogramContent data; may return 0 if the content data are wrong.  
+        * 
+        * @return The right position of the window, or 0 if it cannot compute it. 
+        */
+       public int getWindowXPositionRight() {
+               // If the timewidth is too small, we would pick the same position as the center one.
+               // To avoid this, we take a "full interval" when the window size is too small
+               if ( windowTimeWidth < histogramContent.getElementsTimeInterval() ) {
+                       // Use intervalTime and not intervalTime/2 to make sure we step into the next interval
+                       // Otherwise, if we are in the beginning of an interval, adding IntervalTime/2 could lead us into the same one
+                       // The rounding operation will then return a correct position
+                       return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterPosition, +(histogramContent.getElementsTimeInterval() ) );
+               }
+               else {
+                       return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterPosition, +(windowTimeWidth / 2) );
+               }
+               
+       }
+       
+       /**
+        * 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 histogramContent.getClosestElementFromXPosition( getWindowXPositionLeft() ).firstIntervalTimestamp;
+       }
+       
+       /**
+        * 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 histogramContent.getClosestElementFromXPosition( getWindowXPositionCenter() ).firstIntervalTimestamp;
+       }
+       
+       /**
+        * 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 histogramContent.getClosestElementFromXPosition( getWindowXPositionRight() ).firstIntervalTimestamp;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramView.java
new file mode 100644 (file)
index 0000000..25df24c
--- /dev/null
@@ -0,0 +1,936 @@
+/*******************************************************************************
+ * 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.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.signal.TmfExperimentSelectedSignal;
+import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal;
+import org.eclipse.linuxtools.tmf.signal.TmfRangeSynchSignal;
+import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;
+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
+ * <p>
+ * This view is composed of 2 canvas, one for the whole experiment and one for the selectionned window in the experiment.
+ * It also contain a certain number of controls to print or change informations about the experiment.
+ */
+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 enought 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 ajustable preferences in the view, however there is no way to ajust 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 static final String ID = "org.eclipse.linuxtools.lttng.ui.views.histogram";
+    
+    // "Minimum" screen width size. On smaller screen, we will apply several space saving technique
+    private static final int SCREEN_SMALL_IF_SMALLER_THAN = 1600;
+    
+    // Size of the "fulll 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
+    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 = (1L * 100 * 1000 * 1000); // 0.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 ParentHistogramCanvas fullExperimentCanvas = null;
+    
+    // Request and canvas for the "selected window"
+       private HistogramRequest selectedWindowRequest = null;
+    private 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 selectedWindowTime = 0L;
+       private long selectedWindowTimerange = 0L;
+       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;
+    
+       private static final String WINDOW_TIMERANGE_LABEL_TEXT         = "Window Timerange   ";
+       private static final String WINDOW_CURRENT_TIME_LABEL_TEXT      = "Cursor Centered on ";
+       private static final String EVENT_CURRENT_TIME_LABEL_TEXT       = "Current Event Time ";
+       private TimeTextGroup  ntgTimeRangeWindow = null;
+       private TimeTextGroup  ntgCurrentWindowTime = null;
+       private TimeTextGroup  ntgCurrentEventTime = null;
+       
+       /**
+        * Default contructor 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 timstampe
+                       smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight() - VERY_SMALL_FONT_MODIFIER, tmpFontData.getStyle());
+                       
+                       // 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;
+                       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.NONE);
+               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 SelectionWindow
+               // Contains : 
+               //              Label lblWindowStartTime
+               //              Label lblWindowStopTime
+               //              Label lblWindowMaxNbEvents
+               //              Label lblWindowMinNbEvents
+               //              ChildrenHistogramCanvas selectedWindowCanvas
+               Composite layoutSelectionWindow = new Composite(layoutFullView, SWT.NONE);
+               GridLayout gridSelectionWindow = new GridLayout();
+               gridSelectionWindow.numColumns = 3;
+               gridSelectionWindow.marginHeight = 0;
+               gridSelectionWindow.marginWidth = 0;
+               gridSelectionWindow.horizontalSpacing = 0;
+               gridSelectionWindow.verticalSpacing = 0;
+               layoutSelectionWindow.setLayout(gridSelectionWindow);
+               GridData gridDataSelectionWindow = new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1);
+               layoutSelectionWindow.setLayoutData(gridDataSelectionWindow);
+               
+               
+               // Layout that contain the time spinner
+               // Contains : 
+               //              NanosecTextGroup  spTimeRangeWindow
+               //              NanosecTextGroup  spCurrentWindowTime
+               //              NanosecTextGroup  spCurrentEventTime
+               Composite layoutTimesSpinner = new Composite(layoutFullView, SWT.NONE);
+               GridLayout gridTimesSpinner = new GridLayout();
+               gridTimesSpinner.numColumns = 3;
+               gridTimesSpinner.marginHeight = 0;
+               gridTimesSpinner.marginWidth = 0;
+               gridTimesSpinner.horizontalSpacing = 0;
+               gridTimesSpinner.verticalSpacing = 0;
+               layoutTimesSpinner.setLayout(gridTimesSpinner);
+               GridData gridDataTimesSpinner = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
+               layoutTimesSpinner.setLayoutData(gridDataTimesSpinner);
+               
+               
+               // Layout that contain the complete experiment histogram and related controls.
+               // Contains : 
+               //              Label lblExperimentStartTime
+               //              Label lblExperimentStopTime
+               //              ParentHistogramCanvas fullTraceCanvas
+               Composite layoutExperimentHistogram = new Composite(layoutFullView, SWT.NONE);
+               GridLayout gridExperimentHistogram = new GridLayout();
+               gridExperimentHistogram.numColumns = 2;
+               gridExperimentHistogram.marginHeight = 0;
+               gridExperimentHistogram.marginWidth = 0;
+               gridExperimentHistogram.horizontalSpacing = 0;
+               gridExperimentHistogram.verticalSpacing = 0;
+               layoutExperimentHistogram.setLayout(gridExperimentHistogram);
+               GridData gridDataExperimentHistogram = new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1);
+               layoutExperimentHistogram.setLayoutData(gridDataExperimentHistogram);
+               
+               
+               
+               // *** Everything related to the selection window is below
+               GridData gridDataSelectionWindowCanvas = new GridData(SWT.LEFT, SWT.TOP, true, false, 2, 2);
+               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(SWT.FILL, SWT.TOP, true, false, 1, 1);
+               // 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("");
+               txtWindowMaxNbEvents.setLayoutData(gridDataWindowMaxEvents);
+               
+               GridData gridDataWindowMinEvents = new GridData(SWT.LEFT, SWT.BOTTOM, true, false, 1, 1);
+               // 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("");
+               txtWindowMinNbEvents.setLayoutData(gridDataWindowMinEvents);
+               
+               GridData gridDataWindowStart = new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1);
+               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("");
+               txtWindowStartTime.setLayoutData(gridDataWindowStart);
+               
+               GridData gridDataWindowStop = new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1);
+               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("");
+               txtWindowStopTime.setLayoutData(gridDataWindowStop);
+               
+               GridData gridDataSpacer = new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1);
+               gridDataSpacer.minimumWidth = nbEventWidth;
+               // *** 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!!!
+               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);
+               
+               
+               
+               // *** Everything related to the time text group is below
+               GridData gridDataCurrentEvent = new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 2);
+               ntgCurrentEventTime = new TimeTextGroup(this, layoutTimesSpinner, SWT.BORDER, SWT.BORDER, EVENT_CURRENT_TIME_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime( 0L ), doesTimeTextGroupNeedAdjustment);
+               ntgCurrentEventTime.setLayoutData(gridDataCurrentEvent);
+               
+               GridData gridDataTimeRange = new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 2);
+               ntgTimeRangeWindow = new TimeTextGroup(this, layoutTimesSpinner, SWT.BORDER, SWT.BORDER, WINDOW_TIMERANGE_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime( 0L ), doesTimeTextGroupNeedAdjustment);
+               ntgTimeRangeWindow.setLayoutData(gridDataTimeRange);
+               
+               GridData gridDataCurrentWindow = new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 2);
+               ntgCurrentWindowTime = new TimeTextGroup(this, layoutTimesSpinner, SWT.BORDER, SWT.BORDER, WINDOW_CURRENT_TIME_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime( 0L ), doesTimeTextGroupNeedAdjustment);
+               ntgCurrentWindowTime.setLayoutData(gridDataCurrentWindow);
+               
+               
+               
+               // *** Everything related to the experiment canvas is below
+               GridData gridDataExperimentCanvas = new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1);
+               gridDataExperimentCanvas.heightHint = FULL_TRACE_CANVAS_HEIGHT;
+               gridDataExperimentCanvas.minimumHeight = FULL_TRACE_CANVAS_HEIGHT;
+               fullExperimentCanvas = new ParentHistogramCanvas(this, layoutExperimentHistogram, SWT.BORDER);
+               fullExperimentCanvas.setLayoutData(gridDataExperimentCanvas);
+               
+               GridData gridDataExperimentStart = new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1);
+               txtExperimentStartTime = new Text(layoutExperimentHistogram, SWT.READ_ONLY);
+               txtExperimentStartTime.setFont(smallFont);
+               txtExperimentStartTime.setText("");
+               txtExperimentStartTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
+               txtExperimentStartTime.setEditable(false);
+               txtExperimentStartTime.setLayoutData(gridDataExperimentStart);
+               
+               GridData gridDataExperimentStop = new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1);
+               txtExperimentStopTime = new Text(layoutExperimentHistogram, SWT.READ_ONLY);
+               txtExperimentStopTime.setFont(smallFont);
+               txtExperimentStopTime.setText("");
+               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.
+        */
+    @SuppressWarnings("unchecked")
+       @TmfSignalHandler
+    public void experimentSelected(TmfExperimentSelectedSignal<LttngEvent> signal) {
+       TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)signal.getExperiment();
+       createCanvasAndRequests(tmpExperiment);
+    }
+    
+    // *** 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.
+        */
+//    @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);
+    }
+    
+    /**
+     * Method called when synchonization is active and that the user select an event.<p>
+     * 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.getSource() != this) {
+            TmfTimestamp currentTime = signal.getCurrentTime();
+            
+            // Update the current event controls
+            currentEventTime = currentTime.getValue();
+            updateSelectedEventTime();
+            
+            // If the given event is outside the selection window, recenter the window
+            if ( isGivenTimestampInSelectedWindow( currentEventTime ) == false) {
+               fullExperimentCanvas.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(currentEventTime) );
+               // Notify control that the window changed
+               windowChangedNotification();
+               // Send a broadcast to the framework about the window change
+                       sendTmfRangeSynchSignalBroadcast();
+            }
+       }
+    }
+    
+    @TmfSignalHandler
+       public void synchToTimeRange(TmfRangeSynchSignal signal) {
+               if ( (signal != null) && (signal.getSource() != this) ) {
+                       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.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(windowStart + (windowTimeWidth/2)) );
+                               fullExperimentCanvas.setSelectedWindowSize(windowTimeWidth);
+                               
+                               // *** 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, FULL_TRACE_CANVAS_HEIGHT, FULL_TRACE_DIFFERENCE_TO_AVERAGE);
+               fullExperimentCanvas.createNewSelectedWindow(DEFAULT_WINDOW_SIZE);
+               currentEventTime = newExperiment.getStartTime().getValue();
+       // Set the window of the fullTrace canvas visible.
+               fullExperimentCanvas.getCurrentWindow().setSelectedWindowVisible(true);
+               fullExperimentCanvas.getHistogramContent().resetTable(newExperiment.getStartTime().getValue(), newExperiment.getEndTime().getValue());
+               
+               // Create the content for the selected window. 
+               selectedWindowCanvas.createNewHistogramContent(selectedWindowCanvas.getSize().x ,SELECTED_WINDOW_BAR_WIDTH, SELECTED_WINDOW_CANVAS_HEIGHT, 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(experimentCopy);
+    }
+    
+    /**
+     * 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) {
+       
+       HistogramSelectedWindow curSelectedWindow = fullExperimentCanvas.getCurrentWindow();
+       
+       // If no selection window exists, we will try to cerate one; 
+       //      however this will most likely fail as the content is probably not created either
+       if ( curSelectedWindow == null ) {
+               fullExperimentCanvas.createNewSelectedWindow( DEFAULT_WINDOW_SIZE );
+               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);
+        selectedWindowCanvas.redrawAsynchronously();
+    }
+    
+    /**
+     * 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);
+        
+        // Set a (dynamic) time interval
+        long intervalTime = ( (ts2.getValue() - ts1.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);
+        fullExperimentCanvas.redrawAsynchronously();
+    }
+    
+    // *** 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
+     */
+    public synchronized HistogramRequest performRequest(TmfExperiment<LttngEvent> experiment, HistogramCanvas targetCanvas, TmfTimeRange newRange, long newInterval) {
+       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 );
+        
+        // Send the request to the framework : it will be queued and processed later
+        experiment.sendRequest(returnedRequest);
+        
+        return returnedRequest;
+    }
+    
+    /**
+     * 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.isCompleted() == false ) {
+                       selectedWindowRequest.cancel();
+               }
+               
+               // Get the latest window information
+               selectedWindowTime = fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition();
+               selectedWindowTimerange = fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth();
+               
+               // 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;
+               
+               // Update the UI control
+               updateSelectedEventTime();
+        }
+    }
+    
+    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() {
+       
+//     System.out.println("sendTmfRangeSynchSignalBroadcast " + System.currentTimeMillis());
+       
+       // *** TODO ***
+       // Not very elegant... we need to chance this below.
+       //
+       long centerTime = fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition();
+       long windowWidth = fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth();
+       
+       long startTime = centerTime-windowWidth;
+       if ( startTime < fullExperimentCanvas.getHistogramContent().getStartTime() ) {
+               startTime = fullExperimentCanvas.getHistogramContent().getStartTime();
+       }
+        LttngTimestamp tmpStartTime = new LttngTimestamp(startTime);
+        
+        long endTime = centerTime+windowWidth;
+       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));
+    }
+    
+    /**
+     * 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() {
+       
+       // Get all the time text group value
+       long newCurrentTime = ntgCurrentEventTime.getValue();
+       long newSelectedWindowTime = ntgCurrentWindowTime.getValue();
+       long newSelectedWindowTimeRange = ntgTimeRangeWindow.getValue();
+       
+       // If the user changed the current event time, call the notification
+       if ( newCurrentTime != currentEventTime ) {
+               currentEventChangeNotification( newCurrentTime );
+               // Send a broadcast to the framework about the window change
+               sendTmfTimeSynchSignalBroadcast();
+       }
+       
+       // If the user changed the selected window time, recenter the window and call the notification
+       if ( newSelectedWindowTime != selectedWindowTime ) {
+               selectedWindowTime = newSelectedWindowTime;
+               fullExperimentCanvas.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(selectedWindowTime) );
+               windowChangedNotification();
+               // Send a broadcast to the framework about the window change
+               sendTmfRangeSynchSignalBroadcast();
+       }
+       
+       // If the user changed the selected window size, resize the window and call the notification
+       if ( newSelectedWindowTimeRange != selectedWindowTimerange ) {
+               selectedWindowTimerange = newSelectedWindowTimeRange;
+               fullExperimentCanvas.resizeWindowByAbsoluteTime(selectedWindowTimerange);
+               windowChangedNotification();
+               // Send a broadcast to the framework about the window change
+               sendTmfRangeSynchSignalBroadcast();
+       }
+       
+    }
+    
+    /**
+     * 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);
+               txtWindowMinNbEvents.setText("" + 0);
+               txtWindowStartTime.setText( HistogramConstant.formatNanoSecondsTime( 0L ) );
+               txtWindowStopTime.setText( HistogramConstant.formatNanoSecondsTime( 0L ) );
+               txtWindowStartTime.getParent().layout();
+               
+               ntgCurrentWindowTime.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) );
+               ntgTimeRangeWindow.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() {
+               
+               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();
+               
+               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() {
+               String startTime = HistogramConstant.formatNanoSecondsTime( selectedWindowCanvas.getHistogramContent().getStartTime() );
+               String stopTime = HistogramConstant.formatNanoSecondsTime( selectedWindowCanvas.getHistogramContent().getEndTime() );
+               txtWindowStartTime.setText( startTime );
+               txtWindowStopTime.setText( stopTime );
+               
+               ntgCurrentWindowTime.setValue( fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition() );
+               ntgTimeRangeWindow.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();
+               ntgCurrentWindowTime.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);
+       // 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 controle event generated by the move.
+        */
+       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.
+        */
+       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);
+                       }
+               }
+               
+       }
+}
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
new file mode 100644 (file)
index 0000000..cb2ce61
--- /dev/null
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * 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.widgets.Composite;
+
+/**
+ * <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 {
+       
+       protected HistogramView parentHistogramWindow = 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 newParentWindow, Composite parent, int style) {
+               super(parent, style);
+               
+               parentHistogramWindow = newParentWindow;
+       }
+       
+       /**
+        * 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.
+        */
+       @Override
+       protected void createAndAddPaintListener() {
+               paintListener = new ParentHistogramCanvasPaintListener(this);;
+               this.addPaintListener( paintListener );
+       }
+       
+       /**
+        * 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.
+        */
+       @Override
+       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.
+        */
+       @Override
+       public void setWindowCenterPosition(int newAbsoluteXPosition) {
+               
+               if ( newAbsoluteXPosition < 0 ) {
+                       newAbsoluteXPosition = 0;
+               }
+               else if ( newAbsoluteXPosition > getParent().getSize().x ) {
+                       newAbsoluteXPosition = getParent().getSize().x;
+               }
+               
+               if ( newAbsoluteXPosition != currentWindow.getWindowXPositionCenter() ) {
+                       currentWindow.setWindowXPositionCenter(newAbsoluteXPosition);
+                       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.
+        */
+       @Override
+       public void resizeWindowByAbsoluteTime(long newTime) {
+               if ( newTime != getSelectedWindowSize() ) {
+                       setSelectedWindowSize(newTime);
+                       
+                       notifyParentSelectionWindowChangedAsynchronously();
+                       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() {
+               parentHistogramWindow.updateFullExperimentInformation();
+       }
+       
+       /**
+        * Notify the parent HistogramView that the SelectionWindow changed.<p>
+        * This is intended to be called when the window move or is resized.
+        */
+       @Override
+       public void notifyParentSelectionWindowChanged() {
+               // Notify the parent view that something changed
+               parentHistogramWindow.windowChangedNotification();
+               // Send a broadcast to the framework about the window change
+               parentHistogramWindow.sendTmfRangeSynchSignalBroadcast();
+       }
+}
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
new file mode 100644 (file)
index 0000000..932aaec
--- /dev/null
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * 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.events.PaintEvent;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * <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 
+{
+       public ParentHistogramCanvasPaintListener(HistogramCanvas newParentCanvas) {
+               super(newParentCanvas);
+       }
+       
+       
+       // *** 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(PaintEvent event) {
+               HistogramContent tmpContent = parentCanvas.getHistogramContent();
+               int tmpBarWidth = tmpContent.getBarsWidth();
+               int canvasSize = event.width;
+               
+               event.gc.setBackground(event.display.getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR));
+               
+               // Calculate the closest power of 2 just smaller than the canvas size
+               int closestPowerToCanvas = (int)Math.pow(2, Math.floor( Math.log( canvasSize ) / Math.log(2.0) ));
+               
+               // 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
+               double factor = (double)canvasSize / (double)closestPowerToCanvas;
+               // Calculate how many interval will need to be concatenated into one pixel
+               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;
+               
+               // Read from 0 up to the currently ready position
+               // We advance by "intervalDifference" as the bars migth not represent 1 interval only
+               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.
+                       int 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 
+               int thisElementHeight = 0;
+               for ( int concatPos=0; concatPos<intervalDifference; concatPos++) {
+                       int updatedPos = contentPos + concatPos;
+                       // Make sure we don't cross the last element available.
+                       if ( updatedPos < 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 
+               Rectangle rect = new Rectangle(widthFilled, event.height - thisElementHeight, itemWidth, thisElementHeight);
+               event.gc.fillRectangle(rect);
+               
+               // 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++;
+           }
+           
+               // Clear the remaining space in the canvas (there should not be any) so it appears clean.
+           event.gc.setBackground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
+           Rectangle rect = new Rectangle(widthFilled, 0, event.width, event.height);
+           event.gc.fillRectangle(rect);
+       }
+       
+       /*
+        * 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() {
+               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!
+               int exp = (int)Math.floor( Math.log( (double)tmpContent.getCanvasWindowSize() ) / Math.log(2.0) );
+               int contentSize = (int)Math.pow(2, exp);
+               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();
+               }
+       }
+       
+}
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
new file mode 100644 (file)
index 0000000..1c887aa
--- /dev/null
@@ -0,0 +1,476 @@
+/*******************************************************************************
+ * 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 {
+       
+       protected static final String   NANOSEC_LABEL = "sec";
+       protected static final String   LONGEST_STRING_VALUE = "." + Long.MAX_VALUE;
+       protected 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
+       protected static final int VERY_SMALL_FONT_MODIFIER = 2;
+    protected static final int SMALL_FONT_MODIFIER = 1;
+    
+    // Indentation size 
+    protected static final int DEFAULT_INDENT_SIZE = 10;
+    
+    protected HistogramView parentView = null;
+    protected AsyncTimeTextGroupRedrawer asyncRedrawer = null;
+    
+    protected Group grpName    = null;
+    protected Text     txtNanosec      = null;
+    protected Label lblNanosec         = null;
+    
+    protected 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);
+    }
+    
+    /**
+     * 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);
+    }
+    
+    /**
+     * 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 adjustement for small screen, 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.
+     * @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);
+               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 = 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);
+    }
+    
+    /**
+     * 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.
+        */
+       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.
+        */
+       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.
+        */
+       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.
+        */
+       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(long newTime) {
+               final long tmpTime = newTime;
+               
+               Display display =  parentTimeTextGroup.getParent().getDisplay();
+               display.asyncExec(new Runnable() {
+                       public void run() {
+                               parentTimeTextGroup.setValue(tmpTime);
+                       }
+               });
+       }
+       
+       /**
+        * 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) {
+               final String tmpName = newGroupName;
+               
+               Display display =  parentTimeTextGroup.getParent().getDisplay();
+               display.asyncExec(new Runnable() {
+                       public void run() {
+                               parentTimeTextGroup.setGroupName(tmpName);
+                       }
+               });
+       }
+       
+       /**
+        * Function to redraw the related time text group asynchonously.<p>
+        * 
+        * Basically, it just run "getParent().redraw()" in asyncExec.
+        * 
+        */
+       public void asynchronousRedraw() {
+               Display display =  parentTimeTextGroup.getParent().getDisplay();
+               display.asyncExec(new Runnable() {
+                       public void run() {
+                               parentTimeTextGroup.getParent().redraw();
+                       }
+               });
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/LTTngProjectNature.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/LTTngProjectNature.java
new file mode 100644 (file)
index 0000000..2e14ccd
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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.project;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * <b><u>LTTngProjectNature</u></b>
+ * <p>
+ * This is really a marker for the LTTng projects.
+ */
+public class LTTngProjectNature implements IProjectNature {
+
+       public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.project.LTTngProjectNature";
+
+       private IProject fProject;
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.core.resources.IProjectNature#configure()
+        */
+       public void configure() throws CoreException {
+               // TODO Auto-generated method stub
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.core.resources.IProjectNature#deconfigure()
+        */
+       public void deconfigure() throws CoreException {
+               // TODO Auto-generated method stub
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.core.resources.IProjectNature#getProject()
+        */
+       public IProject getProject() {
+               return fProject;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
+        */
+       public void setProject(IProject project) {
+               fProject = project;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/ProjectView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/ProjectView.java
new file mode 100644 (file)
index 0000000..c76654f
--- /dev/null
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project;
+
+import java.io.FileNotFoundException;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.experiment.StateManagerFactory;
+import org.eclipse.linuxtools.lttng.trace.LTTngTrace;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.ILTTngProjectTreeNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngExperimentNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectContentProvider;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectLabelProvider;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectRoot;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngTraceNode;
+import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
+import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal;
+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.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * <b><u>ProjectView</u></b>
+ * <p>
+ * The ProjectView keeps track of the LTTng projects in the workspace.
+ */
+public class ProjectView extends TmfView {
+
+    public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.project";
+
+    // ------------------------------------------------------------------------
+    // Main data structures
+    // ------------------------------------------------------------------------
+
+    private TreeViewer fViewer;
+    private LTTngProjectRoot fProjectRoot;
+    private TmfExperiment<LttngEvent> fSelectedExperiment = null;
+
+    private IWorkspace fWorkspace;
+    private IResourceChangeListener fResourceChangeListener;
+
+    // ------------------------------------------------------------------------
+    // View refresher
+    // ------------------------------------------------------------------------
+
+    // Perform updates on the UI thread
+    private Runnable fViewRefresher = new Runnable() {
+       public void run() {
+               if (fViewer != null) {
+                       Object[] elements = fViewer.getExpandedElements();
+                       fViewer.refresh();
+                       fViewer.setExpandedElements(elements);
+               }
+       }
+    };
+
+    public LTTngProjectRoot getRoot() {
+       return fProjectRoot;
+    }
+   
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+       public ProjectView() {
+               
+               super("ProjectView");
+        fProjectRoot = new LTTngProjectRoot(this);
+
+               fWorkspace = ResourcesPlugin.getWorkspace();
+               fResourceChangeListener = new IResourceChangeListener() {
+            public void resourceChanged(IResourceChangeEvent event) {
+                if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+                       fProjectRoot.refreshChildren();
+                       refresh();
+                }
+            }            
+        };
+        fWorkspace.addResourceChangeListener(fResourceChangeListener);
+       }
+
+       public void refresh() {
+               Tree tree = fViewer.getTree();
+               if (tree != null && !tree.isDisposed())
+                       tree.getDisplay().asyncExec(fViewRefresher);
+       }
+
+       public void setSelection(ILTTngProjectTreeNode node) {
+               fViewer.setSelection(new StructuredSelection(node), true);
+       }
+
+    @Override
+       public void dispose() {
+       fWorkspace.removeResourceChangeListener(fResourceChangeListener);
+    }
+
+       @Override
+       public void createPartControl(Composite parent) {
+
+               fViewer = new TreeViewer(parent, SWT.SINGLE);
+        fViewer.setContentProvider(new LTTngProjectContentProvider());
+        fViewer.setSorter(new ViewerSorter());
+        fViewer.setLabelProvider(new LTTngProjectLabelProvider());
+        fViewer.setInput(fProjectRoot);
+
+        getSite().setSelectionProvider(fViewer);
+        hookMouse();
+
+        createContextMenu();
+       }
+
+    // ------------------------------------------------------------------------
+    // ViewPart
+    // ------------------------------------------------------------------------
+
+       @Override
+       public String toString() {
+               return "[ProjectView]";
+       }
+
+    // ------------------------------------------------------------------------
+    // hookMouse
+    // ------------------------------------------------------------------------
+
+    private void hookMouse() {
+        fViewer.getTree().addMouseListener(new MouseAdapter() {
+               @Override
+                       public void mouseDoubleClick(MouseEvent event) {
+                TreeSelection selection = (TreeSelection) fViewer.getSelection();
+                Object element = selection.getFirstElement();
+                if (element instanceof LTTngExperimentNode) {
+                       LTTngExperimentNode experiment = (LTTngExperimentNode) element;
+                       selectExperiment(experiment);                
+                }
+            }
+        });
+    }
+
+       private boolean waitForCompletion = true;
+
+       /**
+        * @param experiment
+        */
+       public void selectExperiment(LTTngExperimentNode experiment) {
+       String expId = experiment.getName();
+        if (fSelectedExperiment != null)
+               fSelectedExperiment.dispose();
+        try {
+               LTTngTraceNode[] traceEntries = experiment.getTraces();
+               int nbTraces = traceEntries.length;
+               ITmfTrace[] traces = new ITmfTrace[nbTraces];
+               for (int i = 0; i < nbTraces; i++) {
+                       IResource res = traceEntries[i].getFolder();
+                       String location = res.getLocation().toOSString();
+                       ITmfTrace trace = new LTTngTrace(location, waitForCompletion);
+                traces[i] = trace;
+               }
+            fSelectedExperiment = new TmfExperiment<LttngEvent>(LttngEvent.class, expId, traces);
+            fSelectedExperiment.indexExperiment(waitForCompletion);
+                       // Make sure the lttng-core, experiment selection context is ready
+                       // for an event request from any view
+                       StateManagerFactory.getExperimentManager().experimentSelected_prep(
+                                       (TmfExperiment<LttngEvent>) fSelectedExperiment);
+
+            broadcast(new TmfExperimentSelectedSignal<LttngEvent>(this, fSelectedExperiment));
+        } catch (FileNotFoundException e) {
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // createContextMenu
+    // ------------------------------------------------------------------------
+
+       // Populated from the plug-in
+    private void createContextMenu() {
+        MenuManager menuManager = new MenuManager("#PopupMenu");
+        menuManager.setRemoveAllWhenShown(true);
+        Menu menu = menuManager.createContextMenu(fViewer.getControl());
+        fViewer.getControl().setMenu(menu);
+        getSite().registerContextMenu(menuManager, fViewer);
+    }
+                       
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/AddTraceWizard.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/AddTraceWizard.java
new file mode 100644 (file)
index 0000000..eac20e8
--- /dev/null
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.dialogs;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngExperimentNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngTraceNode;
+import org.eclipse.ui.IImportWizard;
+import org.eclipse.ui.IWorkbench;
+
+/**
+ * <b><u>AddTraceWizard</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class AddTraceWizard extends Wizard implements IImportWizard {
+
+    private LTTngProjectNode fProject;
+    private LTTngExperimentNode fExperiment;
+    private AddTraceWizardPage fMainPage;
+
+    /**
+     * @param project
+     */
+    public AddTraceWizard(LTTngProjectNode project, LTTngExperimentNode experiment) {
+       fProject = project;
+       fExperiment = experiment;
+    }
+
+    /* (non-Javadoc)
+        * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection)
+        */
+       public void init(IWorkbench workbench, IStructuredSelection selection) {
+       setWindowTitle("Adding traces to experiment");
+       }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.wizard.Wizard#addPages()
+     */
+    @Override
+       public void addPages() {
+        super.addPages();
+        fMainPage = new AddTraceWizardPage(fProject, "Some string");
+        addPage(fMainPage);
+    }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.wizard.Wizard#performFinish()
+        */
+       @Override
+       public boolean performFinish() {
+
+               IWorkspace workspace = ResourcesPlugin.getWorkspace();
+               IFolder experimentFolder = fExperiment.getFolder();
+
+               LTTngTraceNode[] traces = fMainPage.getSelection();
+               for (LTTngTraceNode trace : traces) {
+                       try {
+                               IFolder folder = experimentFolder.getFolder(trace.getName());
+                               IPath location = trace.getFolder().getLocation();
+                               if (workspace.validateLinkLocation(folder, location).isOK()) {
+                                       folder.createLink(location, IResource.REPLACE, null);
+                                       fExperiment.addTrace(folder);
+                               }
+                               else {
+                                       System.out.println("Problem");
+                               }
+                       } catch (CoreException e) {
+                               e.printStackTrace();
+                       }
+               }
+
+               return true;
+       }       
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/AddTraceWizardPage.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/AddTraceWizardPage.java
new file mode 100644 (file)
index 0000000..ded48a0
--- /dev/null
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.dialogs;
+
+import java.util.Vector;
+
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngTraceNode;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * <b><u>AddTraceWizardPage</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class AddTraceWizardPage extends WizardPage {
+
+       private LTTngProjectNode fProject;
+       private CheckboxTableViewer fCheckboxTableViewer;
+       
+       protected AddTraceWizardPage(LTTngProjectNode project, String pageName) {
+               super(pageName);
+               setTitle("Select traces");
+               setDescription("Select the traces to add to the experiment");
+               fProject = project;
+       }
+
+       public void createControl(Composite parent) {
+               Composite container = new Composite(parent, SWT.NULL);
+               container.setLayout(new FormLayout());
+               setControl(container);
+
+               fCheckboxTableViewer = CheckboxTableViewer.newCheckList(container, SWT.BORDER);
+               fCheckboxTableViewer.setContentProvider(new DialogTraceContentProvider());
+               fCheckboxTableViewer.setLabelProvider(new DialogTraceLabelProvider());
+
+               final Table table = fCheckboxTableViewer.getTable();
+               final FormData formData = new FormData();
+               formData.bottom = new FormAttachment(100, 0);
+               formData.right  = new FormAttachment(100, 0);
+               formData.top    = new FormAttachment(0, 0);
+               formData.left   = new FormAttachment(0, 0);
+               table.setLayoutData(formData);
+               table.setHeaderVisible(true);
+
+               final TableColumn tableColumn = new TableColumn(table, SWT.NONE);
+               tableColumn.setWidth(200);
+               tableColumn.setText("Trace");
+
+        fCheckboxTableViewer.setInput(fProject.getTracesFolder());
+       }
+
+       public LTTngTraceNode[] getSelection() {
+               Vector<LTTngTraceNode> traces = new Vector<LTTngTraceNode>();
+               Object[] selection = fCheckboxTableViewer.getCheckedElements();
+               for (Object sel : selection) {
+                       if (sel instanceof LTTngTraceNode)
+                               traces.add((LTTngTraceNode) sel);
+               }
+               LTTngTraceNode[] result = new LTTngTraceNode[traces.size()];
+               traces.toArray(result); 
+               return result;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/DialogTraceContentProvider.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/DialogTraceContentProvider.java
new file mode 100644 (file)
index 0000000..d3efae9
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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.project.dialogs;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngTraceFolderNode;
+
+/**
+ * <b><u>LTTngTracesContentProvider</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class DialogTraceContentProvider implements IStructuredContentProvider {
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+        */
+       public Object[] getElements(Object inputElement) {
+               if (inputElement instanceof LTTngTraceFolderNode) {
+                       LTTngTraceFolderNode folder = (LTTngTraceFolderNode) inputElement;
+                       return folder.getTraces();
+               }
+               return null;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+        */
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+        */
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/DialogTraceLabelProvider.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/DialogTraceLabelProvider.java
new file mode 100644 (file)
index 0000000..d3ff08b
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.project.dialogs;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngTraceNode;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * <b><u>LTTngTracesLabelProvider</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class DialogTraceLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+        */
+       public Image getColumnImage(Object element, int columnIndex) {
+               return null;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+        */
+       public String getColumnText(Object element, int columnIndex) {
+               if (element instanceof LTTngTraceNode) {
+                       LTTngTraceNode entry = (LTTngTraceNode) element;
+                       switch (columnIndex) {
+                               case 0:
+                                       return entry.getName();
+                               default:
+                                       return null;
+                       }
+               }
+               return null;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/ImportTraceWizard.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/ImportTraceWizard.java
new file mode 100644 (file)
index 0000000..77dd476
--- /dev/null
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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.project.dialogs;
+
+import java.util.List;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.IImportWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages;
+
+/**
+ * <b><u>ImportTraceWizard</u></b>
+ * <p>
+ *
+ * TODO: Implement me. Please.
+ */
+@SuppressWarnings("restriction")
+public class ImportTraceWizard extends Wizard implements IImportWizard {
+
+    private IWorkbench fWorkbench;
+    private IStructuredSelection fSelection;
+    private ImportTraceWizardPage fMainPage;
+
+       /**
+     * 
+     */
+    public ImportTraceWizard() {
+        IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault().getDialogSettings();
+        IDialogSettings section = workbenchSettings.getSection("LTTngTraceImportWizard");
+        if (section == null) {
+                       section = workbenchSettings.addNewSection("LTTngTraceImportWizard");
+               }
+        
+        setDialogSettings(section);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.wizard.Wizard#addPages()
+     */
+    @Override
+       public void addPages() {
+        super.addPages();
+        fMainPage = new ImportTraceWizardPage(fWorkbench, fSelection);
+        addPage(fMainPage);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection)
+     */
+       @SuppressWarnings("rawtypes")
+       public void init(IWorkbench workbench, IStructuredSelection selection) {
+        fWorkbench = workbench;
+        fSelection = selection;
+
+        List selectedResources = IDE.computeSelectedResources(selection);
+        if (!selectedResources.isEmpty()) {
+            fSelection = new StructuredSelection(selectedResources);
+        }
+        
+        setWindowTitle(DataTransferMessages.DataTransfer_importTitle);
+        setDefaultPageImageDescriptor(IDEWorkbenchPlugin.getIDEImageDescriptor("wizban/importdir_wiz.png"));
+        setNeedsProgressMonitor(true);
+    }
+       
+    public ImportTraceWizardPage getMainPage() {
+               return fMainPage;
+       }
+       
+       /**
+        * performFinish is called after the "finish" button is pressed in the import wizard
+        * If we return "false", the wizard will not close. 
+        * 
+        * We perform here version check on the imported LTTng trace
+        * 
+        */
+    @Override
+       public boolean performFinish() {
+       
+       if ( fMainPage.getDestination().equals( fMainPage.getInitialContainerString() ) ) {
+               
+               String errMessage[] = { "Error : import destination is wrong." }; 
+                       errMessage = fMainPage.extendErrorMessage(errMessage, "");
+                       errMessage = fMainPage.extendErrorMessage(errMessage, "You cannot import your trace directly into the \"" + fMainPage.getInitialContainerString() + "\"");
+                       errMessage = fMainPage.extendErrorMessage(errMessage, "The trace has to be into a subdirectly, like \"" + fMainPage.getInitialContainerString() + "/MyTrace\"" );
+                       errMessage = fMainPage.extendErrorMessage(errMessage, "");
+                       errMessage = fMainPage.extendErrorMessage(errMessage, "Please change the destination folder.");
+                       fMainPage.showVersionErrorPopup(errMessage);
+               
+                       return false;
+       }
+       
+       return fMainPage.finish();
+    }
+    
+    @Override
+       public boolean canFinish() {
+       return fMainPage.isSelectedElementsValidLttngTraces();
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/ImportTraceWizardPage.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/ImportTraceWizardPage.java
new file mode 100644 (file)
index 0000000..5c8e041
--- /dev/null
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+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.trace.LTTngTraceVersion;
+import org.eclipse.linuxtools.lttng.ui.views.project.handlers.TraceErrorHandler;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.internal.wizards.datatransfer.WizardFileSystemResourceImportPage1;
+
+/**
+ * <b><u>ImportTraceWizardPage</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+@SuppressWarnings("restriction")
+public class ImportTraceWizardPage extends WizardFileSystemResourceImportPage1 {
+       
+       private boolean isContainerSet = false;
+       private String  initialContainerString = "";
+       private String  selectedSourceDirectory = "";
+       
+       public ImportTraceWizardPage(IWorkbench workbench, IStructuredSelection selection) {
+               super(workbench, selection);
+               
+               LTTngProjectNode folder = (LTTngProjectNode) selection.getFirstElement();
+               String path = folder.getTracesFolder().getFolder().getFullPath().toOSString();
+               
+               initialContainerString = path;
+               setContainerFieldValue(path);
+       }
+       
+       
+       public String getTraceDirectory() {
+               String tmpPath = "";
+               if ( (getSourceDirectory() != null) && (getSourceDirectory().getName() != null) ) {
+                       tmpPath = this.getSourceDirectory().getName().toString();
+               }
+               
+               return tmpPath;
+       }
+       
+       public String getInitialContainerString() {
+               return initialContainerString;
+       }
+       
+       public String getTracepath() {
+               String tmpPath = "";
+               if ( (getSourceDirectory() != null) && (getSourceDirectory().getPath() != null) ) {
+                       tmpPath = this.getSourceDirectory().getPath().toString();
+               }
+               
+               return tmpPath;
+       }
+       
+       public String getDestination() {
+               String returnPath = null;
+               
+               if ( getContainerFullPath() != null ) {
+                       returnPath = getContainerFullPath().toString();
+               }
+               return returnPath;
+       }
+       
+       public boolean isSelectedElementsValidLttngTraces() {
+               boolean returnedValue = true;
+               
+               // We don't want to test until something is selected
+               if ( selectionGroup.getCheckedElementCount() > 0 ) {
+                       
+                       // We don't want to revalidate each time, only want a new directory is selected
+                       if ( ! selectedSourceDirectory.equals(getSourceDirectory().getAbsolutePath().toString()) )
+                       {
+                               try {
+                                       if ( isPathLttngTrace( getSourceDirectory().getAbsolutePath() ) == false ) {
+                                               returnedValue = false;
+                                               selectedSourceDirectory = "";
+                                               
+                                               String errMessage[] = { "Couldn't get LTTng version number for the path : " }; 
+                                               errMessage = extendErrorMessage(errMessage, getSourceDirectory().getAbsolutePath() );
+                                               errMessage = extendErrorMessage(errMessage, "");
+                                       errMessage = extendErrorMessage(errMessage, "Verify that the directory is a valid LTTng trace directory.");
+                                       errMessage = extendErrorMessage(errMessage, "Make sure the top directory is the trace itself and not any of its parent.");
+                                       showVersionErrorPopup(errMessage);
+                                       selectionGroup.setAllSelections(false);
+                                       }
+                                       else {
+                                               selectedSourceDirectory = getSourceDirectory().getAbsolutePath();
+                                               
+                                               if ( isContainerSet == false ) {
+                                                       isContainerSet = true;
+                                                       
+                                                       if ( ! getDestination().toString().equals( getInitialContainerString() + "/" + getTraceDirectory() )  ) {
+                                                               // *** HACK ***
+                                                       // Force a sane destination to avoid imported files to end up in the root of the "Traces/" directory
+                                                       setContainerFieldValue(getInitialContainerString() + "/" + getTraceDirectory());
+                                                       }
+                                               }
+                                       }
+                       }
+                       catch (LttngException e) {
+                               String[] errorMessages = e.toString().split("\n");
+                               String exceptionMessage[] = { "Version check failed for the path : ", this.getTracepath(), "", "Returned error was :" }; 
+                               
+                               for ( int pos=0; pos<errorMessages.length; pos++) {
+                                       exceptionMessage = extendErrorMessage(exceptionMessage, errorMessages[pos]);
+                               }
+                               
+                               showVersionErrorPopup(exceptionMessage);
+                               selectionGroup.setAllSelections(false);
+                               returnedValue = false;
+                       }
+                       }
+               }
+               isContainerSet = false;
+               
+       return returnedValue;
+       }
+       
+       
+       public boolean isPathLttngTrace(String path) throws LttngException {
+               
+               boolean returnedValue = true;
+               
+               // Ask for a LttngTraceVersion for the given path
+               LTTngTraceVersion traceVersion = new LTTngTraceVersion( path );
+               
+               // If this is not a valid LTTng trace
+               if ( traceVersion.isValidLttngTrace() == false ) {
+               returnedValue = false;
+       }
+               
+               return returnedValue;
+       }
+       
+       
+       public String[] extendErrorMessage(String[] oldErrorMessage, String lineToAdd) {
+               String tmSwapMessage[] = new String[oldErrorMessage.length + 1];
+               for ( int pos = 0; pos<oldErrorMessage.length; pos++) {
+                       tmSwapMessage[pos] = oldErrorMessage[pos];
+               }
+               tmSwapMessage[oldErrorMessage.length] = lineToAdd;
+               
+               return tmSwapMessage;
+       }
+       
+       
+    /**
+     * This function will show a version error popup that contain the given message.
+     * 
+     */
+    public void showVersionErrorPopup(String[] errMessages) {
+       TraceErrorHandler errorDialog = new TraceErrorHandler(errMessages);
+       try {
+               errorDialog.execute(null);
+       }
+       catch (Exception e) {
+               e.printStackTrace();
+       }
+    }
+       
+    
+//    // *** HACK HACK AND HACK ***
+//    // Everything below is a proof of concept on how we could tweak the import wizard to act according to our plan
+//    // Uncomment everything below if you want to test it, but please, does not put any of this into production
+//    @SuppressWarnings({ "unchecked", "rawtypes" })
+//     @Override
+//    public boolean finish() {
+//        if (!ensureSourceIsValid()) {
+//                     return false;
+//             }
+//        saveWidgetValues();
+//        
+//        Iterator resourcesEnum = getSelectedResources().iterator();
+//        List listRealFiles = new ArrayList();
+//        
+//        // ****
+//        // HACK #1 : 
+//        // We need to convert everything into java.io.File because ImportOperation does NOT support FileSystemElement
+//        while (resourcesEnum.hasNext()) {
+//             FileSystemElement tmpFileElement = ((FileSystemElement)resourcesEnum.next());
+//             java.io.File tmpRealFile = new java.io.File(tmpFileElement.getFileSystemObject().toString());
+//             
+//            listRealFiles.add(tmpRealFile);
+//        }
+//        
+//        if (listRealFiles.size() > 0) {
+//             // Call import ressources (code is below)
+//                     return importResources(listRealFiles);
+//             }
+//
+//        MessageDialog.openInformation(getContainer().getShell(),
+//                DataTransferMessages.DataTransfer_information,
+//                DataTransferMessages.FileImport_noneSelected);
+//        return false;
+//    }
+//    
+//    @Override
+//    protected boolean importResources(List fileSystemObjects) {
+//     // *** Explanation of the hackssss
+//     // We want the import wizard to import everything in the form of : 
+//     //              trace1/ -> tracefiles*
+//     //
+//     // However, the wizard is too dumb to do the following and will recreate the full architecture the user selected.
+//     // So, depending what the user select, we could end up with something like : 
+//     //              home/user/somewhere/trace1/ -> tracefiles*
+//     //
+//     // Since there is nothing to do with that, we need to change the "source" and the "to-import files" to reflect this.
+//     // Basically, from the case above, the "source" should be changed to "trace1/" and "to-import files" 
+//     //              should have the correct parent so the wizard can still find them
+//     //
+//     // Let's see how fun it is to do with mr. import wizard.
+//     
+//     
+//     List listRealFilesShortPath = new ArrayList();
+//     java.io.File newFullSource = getSourceDirectory();
+//     
+//     // We will loop for every "to-import full path files" we have and recreate "short path" files
+//     // Mean, the current path of the file is currently something like : 
+//     //              Path : /home/billybob/mytraces/trace1/metadata_0        Parent : null
+//     // And we want something less dumb like : 
+//     //              Path : metadata_0                                                                       Parent : /home/billybob/mytraces/trace1/
+//     for (int pos=0; pos<fileSystemObjects.size(); pos++) {
+//             java.io.File oldFile  = (java.io.File)fileSystemObjects.get(pos);
+//             java.io.File newShortPathFile = oldFile;
+//             
+//             // ***
+//             // HACK #2 : We need to ajust the source of the files!
+//             // Our current source is probably like : 
+//             //              (Source)        Path : / (or null?)
+//             //              (Files)         Path : /home/billybob/mytraces/trace1/metadata_0        Parent : null
+//             // We want something like : 
+//             //              (Source)        Path : /home/billybob/mytraces/trace1/
+//             //      (Files)         Path : metadata_0                                                                       Parent : /home/billybob/mytraces/trace1/
+//             // 
+//             // *BUG : However, we might need MULTIPLE sources since we could have MULTIPLE traces selected... 
+//             //      THIS IS NOT HANDLED YET.
+//             
+//             // Make a new path like -> /home/billybob/mytraces/trace1/
+//             String newParent = oldFile.getAbsolutePath().substring(0, oldFile.getAbsolutePath().lastIndexOf("/") );
+//             
+//             // Create a "short path file" with the good parent from it. This give : 
+//             // (Files)      Path : metadata_0  Parent : /home/billybob/mytraces/trace1/
+//                     newShortPathFile = new java.io.File(newParent, oldFile.getName() );
+//                     
+//                     // Create a new "full source" directory -> /home/billybob/mytraces/trace1/
+//                     newFullSource = new java.io.File( newParent );
+//                     
+//                     // Add our pretty file to the new List
+//             listRealFilesShortPath.add(newShortPathFile);
+//     }
+//     
+//     // ***
+//     // HACK #3
+//     // Now that we have everything, we need to AJUST THE DESTINATION
+//     // To do so, we ajust the "ContainerValue" text field.
+//     //
+//     // Right now we have something like : 
+//     //              Path -> /where/to/import/
+//     //      (Files)         Path : metadata_0       Parent : /home/billybob/mytraces/trace1/
+//             // We want something like : 
+//     //              Path -> /where/to/import/trace1/
+//     //      (Files)         Path : metadata_0       Parent : /home/billybob/mytraces/trace1/
+//     //
+//     
+//     // We take the current text field and we add the "full source" name
+//     //      Note : the "name" is the last directory name so "trace1" is returned for a path like "/home/billybob/mytraces/trace1/"
+//     setContainerFieldValue(getContainerFullPath() + "/" + newFullSource.getName());
+//     
+//     /*
+//     System.out.println("\n\n" + getContainerFullPath());
+//     System.out.println(newFullSource);
+//     System.out.println(FileSystemStructureProvider.INSTANCE);
+//     System.out.println(this.getContainer());
+//     System.out.println(fileSystemObjects);
+//     */
+//     
+//     // Finally import !!
+//        ImportOperation operation = new ImportOperation(getContainerFullPath(), newFullSource, FileSystemStructureProvider.INSTANCE, this, listRealFilesShortPath);
+//        
+//        operation.setContext(getShell());
+//        return executeImportOperation(operation);
+//    }
+//    
+//    // This function test if the selected directory are LTTng traces
+//    // This one is made to work with the madness above.
+//     public boolean isSelectedElementsValidLttngTraces() {
+//             boolean returnedValue = true;
+//             
+//             String errMessage[] = { "Couldn't get LTTng version number for the path : " }; 
+//             
+//             // We don't want to test until something is selected
+//             if ( selectionGroup.getCheckedElementCount() > 0 ) {
+//                     try {
+//                             List<MinimizedFileSystemElement> selectionList = selectionGroup.getAllWhiteCheckedItems();
+//                             MinimizedFileSystemElement tmpSelectedElement = null;
+//                             
+//                             for ( int x=0; x<selectionList.size(); x++) {
+//                                     tmpSelectedElement = selectionList.get(x);
+//                                     
+//                                     // *** VERIFY ***
+//                                     // Not sure ALL directory are checked.
+//                                     if ( tmpSelectedElement.isDirectory() ) {
+//                                             String tmpPath = tmpSelectedElement.getFileSystemObject().toString();
+//                                             if ( isPathLttngTrace( tmpPath ) == false ) {
+//                                                     returnedValue = false;
+//                                                     errMessage = extendErrorMessage(errMessage, tmpPath);
+//                                             }
+//                                     }
+//                             }
+//                             
+//                     if ( returnedValue == false ) {
+//                             errMessage = extendErrorMessage(errMessage, "");
+//                             errMessage = extendErrorMessage(errMessage, "Verify that the directory is a valid LTTng trace directory.");
+//                             showVersionErrorPopup(errMessage);
+//                             selectionGroup.setAllSelections(false);
+//                     }
+//             }
+//             catch (LttngException e) {
+//                     String exceptionMessage[] = { "Version check failed for the path : ", this.getTracepath(), "", "Returned error was :", e.toString() }; 
+//                     showVersionErrorPopup(exceptionMessage);
+//                     selectionGroup.setAllSelections(false);
+//                     returnedValue = false;
+//             }
+//             }
+//             
+//     return returnedValue;
+//     }
+    
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewExperimentDialog.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewExperimentDialog.java
new file mode 100644 (file)
index 0000000..1cb3929
--- /dev/null
@@ -0,0 +1,335 @@
+/*******************************************************************************
+ * 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.project.dialogs;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngExperimentFolderNode;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.SelectionStatusDialog;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.ide.dialogs.CreateLinkedResourceGroup;
+
+/**
+ * NewExperimentDialog
+ * 
+ * This is stripped down version of NewFolderDialog.
+ */
+@SuppressWarnings("restriction")
+public class NewExperimentDialog extends SelectionStatusDialog {
+
+       private Text folderNameField;
+       private IContainer container;
+       private boolean firstLinkCheck = true;
+       private CreateLinkedResourceGroup linkedResourceGroup;
+
+       /**
+        * Creates a NewFolderDialog
+        * 
+        * @param parentShell parent of the new dialog
+        * @param container parent of the new folder
+        */
+       public NewExperimentDialog(Shell parentShell, LTTngExperimentFolderNode experimentFolder) {
+               super(parentShell);
+               this.container = experimentFolder.getFolder();
+               setTitle("LTTng Experiment");
+               setStatusLineAboveButtons(true);
+       }
+
+       /**
+        * Creates the folder using the name and link target entered by the user.
+        * Sets the dialog result to the created folder.  
+        */
+       @Override
+       protected void computeResult() {
+       }
+
+       /**
+        * @see org.eclipse.jface.window.Window#create()
+        */
+       @Override
+       public void create() {
+               super.create();
+               getButton(IDialogConstants.OK_ID).setEnabled(false);
+       }
+
+       /**
+        * Creates the widget for advanced options.
+        *  
+        * @param parent the parent composite
+        */
+       protected void createLinkResourceGroup(Composite parent) {
+               linkedResourceGroup = new CreateLinkedResourceGroup(IResource.FOLDER,
+                               new Listener() {
+                                       public void handleEvent(Event e) {
+                                               validateLinkedResource();
+                                               firstLinkCheck = false;
+                                       }
+                               }, new CreateLinkedResourceGroup.IStringValue() {
+                                       public void setValue(String string) {
+                                               folderNameField.setText(string);
+                                       }
+
+                                       public String getValue() {
+                                               return folderNameField.getText();
+                                       }
+
+                                       public IResource getResource() {
+                                               // TODO Auto-generated method stub
+                                               return null;
+                                       }
+                               });
+       }
+
+       /* (non-Javadoc)
+        * Method declared on Dialog.
+        */
+       @Override
+       protected Control createDialogArea(Composite parent) {
+               Composite composite = (Composite) super.createDialogArea(parent);
+               composite.setLayout(new GridLayout());
+               composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+               createFolderNameGroup(composite);
+               createLinkResourceGroup(composite);
+               return composite;
+       }
+
+       /**
+        * Creates the folder name specification controls.
+        *
+        * @param parent the parent composite
+        */
+       private void createFolderNameGroup(Composite parent) {
+               Font font = parent.getFont();
+               Composite folderGroup = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               folderGroup.setLayout(layout);
+               folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               // new folder label
+               Label folderLabel = new Label(folderGroup, SWT.NONE);
+               folderLabel.setFont(font);
+               folderLabel.setText("Experiment name: ");
+
+               // new folder name entry field
+               folderNameField = new Text(folderGroup, SWT.BORDER);
+               GridData data = new GridData(GridData.FILL_HORIZONTAL);
+               data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+               folderNameField.setLayoutData(data);
+               folderNameField.setFont(font);
+               folderNameField.addListener(SWT.Modify, new Listener() {
+                       public void handleEvent(Event event) {
+                               validateLinkedResource();
+                       }
+               });
+       }
+
+       /**
+        * Creates a folder resource handle for the folder with the given name.
+        * The folder handle is created relative to the container specified during 
+        * object creation. 
+        *
+        * @param folderName the name of the folder resource to create a handle for
+        * @return the new folder resource handle
+        */
+       private IFolder createFolderHandle(String folderName) {
+               IWorkspaceRoot workspaceRoot = container.getWorkspace().getRoot();
+               IPath folderPath = container.getFullPath().append(folderName);
+               IFolder folderHandle = workspaceRoot.getFolder(folderPath);
+
+               return folderHandle;
+       }
+
+       /**
+        * Creates a new folder with the given name and optionally linking to
+        * the specified link target.
+        * 
+        * @param folderName name of the new folder
+        * @param linkTarget name of the link target folder. may be null.
+        * @return IFolder the new folder
+        */
+       private IFolder createNewFolder(String folderName, final URI linkTarget) {
+               final IFolder folderHandle = createFolderHandle(folderName);
+
+               WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
+                       @Override
+                       public void execute(IProgressMonitor monitor) throws CoreException {
+                               try {
+                                       monitor.beginTask(IDEWorkbenchMessages.NewFolderDialog_progress, 2000);
+                                       if (monitor.isCanceled()) {
+                                               throw new OperationCanceledException();
+                                       }
+                                       if (linkTarget == null) {
+                                               folderHandle.create(false, true, monitor);
+                                       } else {
+                                               folderHandle.createLink(linkTarget, IResource.ALLOW_MISSING_LOCAL, monitor);
+                                       }
+                                       if (monitor.isCanceled()) {
+                                               throw new OperationCanceledException();
+                                       }
+                               } finally {
+                                       monitor.done();
+                               }
+                       }
+               };
+               try {
+                       PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation);
+               } catch (InterruptedException exception) {
+                       return null;
+               } catch (InvocationTargetException exception) {
+                       if (exception.getTargetException() instanceof CoreException) {
+                               ErrorDialog.openError(getShell(),
+                                               IDEWorkbenchMessages.NewFolderDialog_errorTitle, null, // no special message
+                                               ((CoreException) exception.getTargetException()).getStatus());
+                       } else {
+                               // CoreExceptions are handled above, but unexpected runtime exceptions and errors may still occur.
+                               IDEWorkbenchPlugin.log(getClass(),
+                                               "createNewExperiment", exception.getTargetException());
+                               MessageDialog.openError(getShell(),
+                                               IDEWorkbenchMessages.NewFolderDialog_errorTitle,
+                                               NLS.bind(IDEWorkbenchMessages.NewFolderDialog_internalError,
+                                                       exception.getTargetException().getMessage()));
+                       }
+                       return null;
+               }
+               return folderHandle;
+       }
+
+       /**
+        * Update the dialog's status line to reflect the given status. It is safe to call
+        * this method before the dialog has been opened.
+        */
+       @Override
+       protected void updateStatus(IStatus status) {
+               if (firstLinkCheck && status != null) {
+                       Status newStatus = new Status(IStatus.OK, status.getPlugin(),
+                                       status.getCode(), status.getMessage(), status.getException());
+                       super.updateStatus(newStatus);
+               } else {
+                       super.updateStatus(status);
+               }
+       }
+
+       /**
+        * Update the dialog's status line to reflect the given status. It is safe to call
+        * this method before the dialog has been opened.
+        * @param severity
+        * @param message
+        */
+       private void updateStatus(int severity, String message) {
+               updateStatus(new Status(severity, IDEWorkbenchPlugin.IDE_WORKBENCH, severity, message, null));
+       }
+
+       /**
+        * Checks whether the folder name and link location are valid.
+        * Disable the OK button if the folder name and link location are valid.
+        * a message that indicates the problem otherwise.
+        */
+       private void validateLinkedResource() {
+               boolean valid = validateFolderName();
+
+               if (valid) {
+                       IFolder linkHandle = createFolderHandle(folderNameField.getText());
+                       IStatus status = linkedResourceGroup.validateLinkLocation(linkHandle);
+
+                       if (status.getSeverity() != IStatus.ERROR) {
+                               getOkButton().setEnabled(true);
+                       } else {
+                               getOkButton().setEnabled(false);
+                       }
+
+                       if (status.isOK() == false) {
+                               updateStatus(status);
+                       }
+               } else {
+                       getOkButton().setEnabled(false);
+               }
+       }
+
+       /**
+        * Checks if the folder name is valid.
+        *
+        * @return null if the new folder name is valid.
+        *      a message that indicates the problem otherwise.
+        */
+       private boolean validateFolderName() {
+               String name = folderNameField.getText();
+               IWorkspace workspace = container.getWorkspace();
+               IStatus nameStatus = workspace.validateName(name, IResource.FOLDER);
+
+               if ("".equals(name)) {
+                       updateStatus(IStatus.ERROR, "Experiment name is empty");
+                       return false;
+               }
+               if (nameStatus.isOK() == false) {
+                       updateStatus(nameStatus);
+                       return false;
+               }
+               IPath path = new Path(name);
+               if (container.getFolder(path).exists()
+                               || container.getFile(path).exists()) {
+                       updateStatus(IStatus.ERROR, NLS.bind("Experiment already exists", name));
+                       return false;
+               }
+               updateStatus(IStatus.OK, "");
+               return true;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.ui.dialogs.SelectionStatusDialog#okPressed()
+        */
+       @Override
+       protected void okPressed() {
+               URI linkTarget = linkedResourceGroup.getLinkTargetURI();
+               IFolder folder = createNewFolder(folderNameField.getText(), linkTarget);
+               if (folder == null) {
+                       return;
+               }
+
+               setSelectionResult(new IFolder[] { folder });
+
+               super.okPressed();
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewProjectMainWizardPage.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewProjectMainWizardPage.java
new file mode 100644 (file)
index 0000000..48da18e
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.project.dialogs;
+
+import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
+
+/**
+ * <b><u>NewProjectMainWizardPage</u></b>
+ * <p>
+ *
+ * TODO: Implement me. Please.
+ */
+public class NewProjectMainWizardPage extends WizardNewProjectCreationPage {
+
+    /**
+     * @param pageName
+     */
+    public NewProjectMainWizardPage(String pageName) {
+        super(pageName);
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewProjectWizard.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/NewProjectWizard.java
new file mode 100644 (file)
index 0000000..e0bd8a3
--- /dev/null
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * 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.project.dialogs;
+
+import java.net.URI;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.linuxtools.lttng.ui.LTTngUiPlugin;
+import org.eclipse.linuxtools.lttng.ui.views.project.LTTngProjectNature;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
+
+/**
+ * <b><u>NewProjectWizard</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class NewProjectWizard extends BasicNewResourceWizard {
+
+    private String fTtitle;
+    private String fDescription;
+
+    protected NewProjectMainWizardPage fMainPage;
+    protected String fProjectName;
+    protected URI fProjectLocation;
+    protected IConfigurationElement fConfigElement;
+
+    protected IProject fProject;
+
+    /**
+     * 
+     */
+    public NewProjectWizard() {
+        this("LTTng Project", "Create an LTTng Project");
+    }
+
+    /**
+     * @param title
+     * @param desc
+     */
+    public NewProjectWizard(String title, String desc) {
+        super();
+        setDialogSettings(LTTngUiPlugin.getDefault().getDialogSettings());
+        setNeedsProgressMonitor(true);
+        setForcePreviousAndNextButtons(true);
+        setWindowTitle(title);
+        fTtitle = title;
+        fDescription = desc;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.wizard.Wizard#addPages()
+     */
+    @Override
+    public void addPages() {
+        fMainPage= new NewProjectMainWizardPage("LTTng Project");
+        fMainPage.setTitle(fTtitle);
+        fMainPage.setDescription(fDescription);
+        addPage(fMainPage);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.wizard.Wizard#performCancel()
+     */
+    @Override
+    public boolean performCancel() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.wizard.Wizard#performFinish()
+     */
+    @Override
+    public boolean performFinish() {
+        fProjectName = fMainPage.getProjectName();
+        fProjectLocation = fMainPage.useDefaults() ? null : fMainPage.getLocationURI();
+        fProject = createProject(fProjectName, fProjectLocation, new NullProgressMonitor());
+        return true;
+    }
+
+    public IProject getProject() {
+       return fProject;
+    }
+    /**
+     * @param projectName
+     * @param projectLocation
+     * @param monitor
+     * @return
+     */
+    private IProject createProject(String projectName, URI projectLocation, IProgressMonitor monitor) {
+
+        IWorkspace workspace = ResourcesPlugin.getWorkspace();
+        IWorkspaceRoot root = workspace.getRoot();
+        IProject project = root.getProject(projectName);
+
+        try {
+            if (!project.exists()) {
+                IProjectDescription description = workspace.newProjectDescription(project.getName());
+                if (projectLocation != null)
+                    description.setLocationURI(projectLocation);
+                project.create(description, monitor);
+            }
+
+            if (!project.isOpen())
+                project.open(monitor);
+
+            IProjectDescription description = project.getDescription();
+            description.setNatureIds(new String[] { LTTngProjectNature.ID } );
+            project.setDescription(description, null);
+
+            IFolder folder = project.getFolder(LTTngProjectNode.TRACE_FOLDER_NAME);
+            if (!folder.exists())
+                folder.create(true, true, null);
+
+            folder = project.getFolder(LTTngProjectNode.EXPER_FOLDER_NAME);
+            if (!folder.exists())
+                folder.create(true, true, null);
+
+            return project;
+        }
+        catch (CoreException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/TraceErrorDialog.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/dialogs/TraceErrorDialog.java
new file mode 100644 (file)
index 0000000..06bbcc2
--- /dev/null
@@ -0,0 +1,135 @@
+package org.eclipse.linuxtools.lttng.ui.views.project.dialogs;
+
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SelectionStatusDialog;
+
+public class TraceErrorDialog extends SelectionStatusDialog {
+       
+       private String[] messages = null; 
+       
+       public TraceErrorDialog(Shell parentShell, String[] newMessages) {
+               super(parentShell);
+               
+               messages = newMessages;
+               setTitle("Trace Selection");
+               setStatusLineAboveButtons(true);
+       }
+       
+       @Override
+       protected void computeResult() {
+       }
+       
+       @Override
+       public void create() {
+               super.create();
+               getButton(IDialogConstants.OK_ID).setEnabled(true);
+               getButton(IDialogConstants.OK_ID).setAlignment(GridData.CENTER);
+               getButton(IDialogConstants.CANCEL_ID).setVisible(false);
+       }
+       
+       @Override
+       protected Control createDialogArea(Composite parent) {
+               Composite composite = (Composite) super.createDialogArea(parent);
+               composite.setLayout(new GridLayout());
+               composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+               
+               createFolderNameGroup(composite);
+               return composite;
+       }
+       
+       private void createFolderNameGroup(Composite parent) {
+               Font font = parent.getFont();
+               Composite folderGroup = new Composite(parent, SWT.NONE);
+               
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               layout.verticalSpacing = 3;
+               folderGroup.setLayout(layout);
+               folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               
+               
+               // Position grid for the messages
+               GridData positionningData = new GridData(GridData.FILL_VERTICAL);
+               
+               // New message label
+               Label lblMessage = new Label(folderGroup, SWT.NONE);
+               lblMessage.setFont(font);
+               lblMessage.setText("Error while opening the trace! Error message was : ");
+               lblMessage.setLayoutData(positionningData);
+               
+               // The actual messages
+               GC graphicContext = new GC(parent);
+               String longuestLine = "";
+               int msgSize = 0;
+               
+               // *** Font and FontData are nowhere near elegant to use.
+               Font errorFont = new Font(graphicContext.getDevice(), font.getFontData()[0].getName(), font.getFontData()[0].getHeight(), SWT.ITALIC);
+               
+               Label[] lblErrorMessages = new Label[messages.length];
+               for(int x=0; x<messages.length; x++) {
+                       lblErrorMessages[x] = new Label(folderGroup, SWT.NONE);
+                       lblErrorMessages[x].setFont(errorFont);
+                       
+                       lblErrorMessages[x].setForeground(new Color(lblErrorMessages[x].getForeground().getDevice(), 255, 0, 0));
+                       lblErrorMessages[x].setText(messages[x]);
+                       lblErrorMessages[x].setLayoutData(positionningData);
+                       
+                       if ( messages[x].length() > longuestLine.length() ) {
+                               longuestLine = messages[x];
+                       }
+               }
+               
+               for ( int pos=0; pos<longuestLine.length(); pos++ ) {
+                       msgSize += graphicContext.getAdvanceWidth( longuestLine.charAt(pos) );
+               }
+               // Seems we need to count the final \n of the line otherwise we miss some space
+               msgSize += graphicContext.getAdvanceWidth( '\n' );
+               
+               positionningData.widthHint = msgSize;
+               positionningData.grabExcessHorizontalSpace = true;
+               
+               graphicContext.dispose();
+               
+       }
+       
+       
+       @Override
+       protected void updateStatus(IStatus status) {
+               if (status != null) {
+                       Status newStatus = new Status(IStatus.OK, status.getPlugin(),
+                                       status.getCode(), status.getMessage(), status.getException());
+                       super.updateStatus(newStatus);
+               } else {
+                       super.updateStatus(status);
+               }
+       }
+       
+       @Override
+       protected void okPressed() {
+               super.okPressed();
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/CloseProjectHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/CloseProjectHandler.java
new file mode 100644 (file)
index 0000000..c00e60d
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>CloseProjectHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class CloseProjectHandler implements IHandler {
+
+       private LTTngProjectNode fProject = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if we are in the Project View
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check if a project is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       fProject = (element instanceof LTTngProjectNode) ? (LTTngProjectNode) element : null;
+               }
+               return (fProject != null && fProject.isOpen());
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               if (fProject != null) {
+                       fProject.closeProject();
+                       fProject.refresh();
+               }
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteExperimentHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteExperimentHandler.java
new file mode 100644 (file)
index 0000000..ed736ef
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.ILTTngProjectTreeNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngExperimentNode;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>DeleteExperimentHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class DeleteExperimentHandler implements IHandler {
+
+       private LTTngExperimentNode fExperiment = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if a trace is selected
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check if a trace is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       fExperiment = (element instanceof LTTngExperimentNode) ? (LTTngExperimentNode) element : null;
+               }
+
+               return (fExperiment != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               IFolder folder = fExperiment.getFolder();
+               ILTTngProjectTreeNode parent = fExperiment.getParent();
+               try {
+                       parent.removeChild(fExperiment);
+                       parent.refresh();
+                       folder.delete(true, true, null);
+               } catch (CoreException e) {
+                       e.printStackTrace();
+               }
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteProjectHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteProjectHandler.java
new file mode 100644 (file)
index 0000000..328dd97
--- /dev/null
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.ILTTngProjectTreeNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>DeleteProjectHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class DeleteProjectHandler implements IHandler {
+
+       private LTTngProjectNode fProject = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if we are in the Project View
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check if a project is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       fProject = (element instanceof LTTngProjectNode) ? (LTTngProjectNode) element : null;
+               }
+               return (fProject != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               IProject project = fProject.getProject();
+               ILTTngProjectTreeNode parent = fProject.getParent();
+               try {
+                       parent.removeChild(fProject);
+                       parent.refresh();
+                       project.delete(true, true, null);
+               } catch (CoreException e) {
+                       e.printStackTrace();
+               }
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteTraceHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/DeleteTraceHandler.java
new file mode 100644 (file)
index 0000000..beb0d05
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.ILTTngProjectTreeNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngTraceNode;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>DeleteTraceHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class DeleteTraceHandler implements IHandler {
+
+       private LTTngTraceNode fTrace = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if a trace is selected
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check if a trace is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       fTrace = (element instanceof LTTngTraceNode) ? (LTTngTraceNode) element : null;
+               }
+
+               return (fTrace != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               IFolder folder = fTrace.getFolder();
+               ILTTngProjectTreeNode parent = fTrace.getParent();
+               try {
+                       parent.removeChild(fTrace);
+                       parent.refresh();
+                       folder.delete(true, true, null);
+               } catch (CoreException e) {
+                       e.printStackTrace();
+               }
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/ImportTraceHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/ImportTraceHandler.java
new file mode 100644 (file)
index 0000000..907c428
--- /dev/null
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.dialogs.ImportTraceWizard;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.ILTTngProjectTreeNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>ImportTraceHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class ImportTraceHandler implements IHandler {
+
+       private LTTngProjectNode fProject = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if we are in the Project View
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check if a project is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       if (element instanceof ILTTngProjectTreeNode) {
+                               ILTTngProjectTreeNode node = (ILTTngProjectTreeNode) element;
+                               while (node != null && !(node instanceof LTTngProjectNode)) {
+                                       node = node.getParent();
+                               }
+                               fProject = (node instanceof LTTngProjectNode) ? (LTTngProjectNode) node : null;
+                       }
+               }
+
+               return (fProject != null && fProject.isOpen() && fProject.isLTTngProject());
+       }
+
+       // Always handled
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               // Set the selection to the project
+               IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+               ProjectView view = (ProjectView) page.getActivePart();
+               view.setSelection(fProject);
+
+               // Fire the Import Trace Wizard
+               IWorkbench workbench = PlatformUI.getWorkbench();
+               Shell shell = workbench.getActiveWorkbenchWindow().getShell();
+
+               ImportTraceWizard wizard = new ImportTraceWizard();
+               wizard.init(PlatformUI.getWorkbench(), new StructuredSelection(fProject));
+               WizardDialog dialog = new WizardDialog(shell, wizard);
+               dialog.open();
+
+               if (dialog.getReturnCode() == Window.OK && fProject != null) {
+                       fProject.refreshChildren();
+                       fProject.refresh();
+               }
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/NewExperimentHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/NewExperimentHandler.java
new file mode 100644 (file)
index 0000000..b6e760e
--- /dev/null
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.dialogs.NewExperimentDialog;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.ILTTngProjectTreeNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngExperimentFolderNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>NewExperimentHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class NewExperimentHandler implements IHandler {
+
+       private LTTngProjectNode fProject = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if we are in the Project View
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check if a project is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       if (element instanceof ILTTngProjectTreeNode) {
+                               ILTTngProjectTreeNode node = (ILTTngProjectTreeNode) element;
+                               while (node != null && !(node instanceof LTTngProjectNode)) {
+                                       node = node.getParent();
+                               }
+                               fProject = (node instanceof LTTngProjectNode) ? (LTTngProjectNode) node : null;
+                       }
+               }
+
+               return (fProject != null && fProject.isOpen() && fProject.isLTTngProject());
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               // Open the experiment creation dialog
+               LTTngExperimentFolderNode experimentFolder = fProject.getExperimentsFolder();
+               Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+               NewExperimentDialog dialog = new NewExperimentDialog(shell, experimentFolder);
+               dialog.open();
+
+               if (dialog.getReturnCode() == Window.OK) {
+                       Object[] experiments = dialog.getResult();
+                       if (experiments[0] instanceof IFolder) {
+                               experimentFolder.addExperiment((IFolder) experiments[0]);
+                       }
+               }
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/NewProjectHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/NewProjectHandler.java
new file mode 100644 (file)
index 0000000..a486307
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.dialogs.NewProjectWizard;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectRoot;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>NewProjectHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class NewProjectHandler implements IHandler {
+
+       private LTTngProjectRoot fProjectRoot = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if we are in the Project View
+               IWorkbenchPart part = window.getActivePage().getActivePart();
+               if (!(part instanceof ProjectView))
+                       return false;
+
+               fProjectRoot = ((ProjectView) part).getRoot();
+
+               return (fProjectRoot != null);
+       }
+
+       // Always handled
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               // Fire the New Project Wizard
+               Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+               NewProjectWizard wizard = new NewProjectWizard();
+               WizardDialog dialog = new WizardDialog(shell, wizard);
+               dialog.open();
+
+               // Update the project model
+               if (dialog.getReturnCode() == Window.OK) {
+                       IProject project = wizard.getProject();
+                       if (project != null && fProjectRoot != null) {
+                               fProjectRoot.refreshChildren();
+                               fProjectRoot.refresh();
+                       }
+               }
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenExperimentHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenExperimentHandler.java
new file mode 100644 (file)
index 0000000..c7948b4
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngExperimentNode;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>OpenExperimentHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class OpenExperimentHandler implements IHandler {
+
+       private LTTngExperimentNode fExperiment = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if a trace is selected
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check if a trace is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       fExperiment = (element instanceof LTTngExperimentNode) ? (LTTngExperimentNode) element : null;
+               }
+
+               return (fExperiment != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               // Set the selection to the project
+               IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+               ProjectView projectView = (ProjectView) page.getActivePart();
+
+               if (projectView != null) {
+                       projectView.selectExperiment(fExperiment);
+               }
+
+               return null;
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+               
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenProjectHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenProjectHandler.java
new file mode 100644 (file)
index 0000000..8aabb38
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>OpenProjectHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class OpenProjectHandler implements IHandler {
+
+       private LTTngProjectNode fProject = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if we are in the Project View
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check if a project is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       fProject = (element instanceof LTTngProjectNode) ? (LTTngProjectNode) element : null;
+               }
+               return (fProject != null && !fProject.isOpen());
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               if (fProject != null) {
+                       fProject.openProject();
+                       fProject.refresh();
+               }
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenTraceHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/OpenTraceHandler.java
new file mode 100644 (file)
index 0000000..8e01111
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngTraceNode;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>OpenTraceHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class OpenTraceHandler implements IHandler {
+
+       private LTTngTraceNode fTrace = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               return (fTrace != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+               mb.setText("Open Trace");
+               mb.setMessage("Not implemented yet");
+               mb.open();
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RefreshHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RefreshHandler.java
new file mode 100644 (file)
index 0000000..740ed30
--- /dev/null
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.ILTTngProjectTreeNode;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectRoot;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>RefreshHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class RefreshHandler implements IHandler {
+
+       private LTTngProjectRoot fProjectRoot = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if we can find the project model root node
+               ISelection selection = window.getActivePage().getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       if (element instanceof ILTTngProjectTreeNode) {
+                               ILTTngProjectTreeNode node = (ILTTngProjectTreeNode) element;
+                               while (node != null && !(node instanceof LTTngProjectRoot)) {
+                                       node = node.getParent();
+                               }
+                               fProjectRoot = (node instanceof LTTngProjectRoot) ? (LTTngProjectRoot) node : null;
+                       }
+               }
+
+               return (fProjectRoot != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               if (fProjectRoot != null) {
+                       fProjectRoot.refreshChildren();
+                       fProjectRoot.refresh();
+               }
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameExperimentHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameExperimentHandler.java
new file mode 100644 (file)
index 0000000..7651437
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngExperimentNode;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>RenameExperimentHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class RenameExperimentHandler implements IHandler {
+
+       private LTTngExperimentNode fExperiment = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               return (fExperiment != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+               mb.setText("Rename Experiment");
+               mb.setMessage("Not implemented yet");
+               mb.open();
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameProjectHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameProjectHandler.java
new file mode 100644 (file)
index 0000000..43dc44b
--- /dev/null
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngProjectNode;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>RenameProjectHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class RenameProjectHandler implements IHandler {
+
+       private LTTngProjectNode fProject = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+
+//             // Check if we are closing down
+//             IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+//             if (window == null)
+//                     return false;
+//
+//             // Check if we are in the Project View
+//             IWorkbenchPage page = window.getActivePage();
+//             if (!(page.getActivePart() instanceof ProjectView))
+//                     return false;
+//
+//             // Check if a project is selected
+//             ISelection selection = page.getSelection(ProjectView.ID);
+//             if (selection instanceof StructuredSelection) {
+//                     Object element = ((StructuredSelection) selection).getFirstElement();
+//                     fProjectNode = (element instanceof LTTngProjectNode) ? (LTTngProjectNode) element : null;
+//             }
+
+               return (fProject != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return false;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+               mb.setText("Rename Project");
+               mb.setMessage("Not implemented yet");
+               mb.open();
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameTraceHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/RenameTraceHandler.java
new file mode 100644 (file)
index 0000000..3c1457d
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngTraceNode;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>RenameTraceHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class RenameTraceHandler implements IHandler {
+
+       private LTTngTraceNode fTrace = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+               return (fTrace != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+               mb.setText("Rename Trace");
+               mb.setMessage("Not implemented yet");
+               mb.open();
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/SelectTracesHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/SelectTracesHandler.java
new file mode 100644 (file)
index 0000000..ef3804d
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+import org.eclipse.linuxtools.lttng.ui.views.project.dialogs.AddTraceWizard;
+import org.eclipse.linuxtools.lttng.ui.views.project.model.LTTngExperimentNode;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>SelectTracesHandler</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class SelectTracesHandler implements IHandler {
+
+       private LTTngExperimentNode fExperiment = null;
+
+       // ------------------------------------------------------------------------
+       // Validation
+       // ------------------------------------------------------------------------
+
+       public boolean isEnabled() {
+
+               // Check if we are closing down
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window == null)
+                       return false;
+
+               // Check if we are in the Project View
+               IWorkbenchPage page = window.getActivePage();
+               if (!(page.getActivePart() instanceof ProjectView))
+                       return false;
+
+               // Check that an experiment is selected
+               ISelection selection = page.getSelection(ProjectView.ID);
+               if (selection instanceof StructuredSelection) {
+                       Object element = ((StructuredSelection) selection).getFirstElement();
+                       fExperiment = (element instanceof LTTngExperimentNode) ? (LTTngExperimentNode) element : null;
+               }
+
+               return (fExperiment != null);
+       }
+
+       // Handled if we are in the ProjectView
+       public boolean isHandled() {
+               return true;
+       }
+
+       // ------------------------------------------------------------------------
+       // Execution
+       // ------------------------------------------------------------------------
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               // Open the trace addition wizard
+               IWorkbench workbench = PlatformUI.getWorkbench();
+               Shell shell = workbench.getActiveWorkbenchWindow().getShell();
+
+               AddTraceWizard wizard = new AddTraceWizard(fExperiment.getProject(), fExperiment);
+               wizard.init(PlatformUI.getWorkbench(), null);
+               WizardDialog dialog = new WizardDialog(shell, wizard);
+               dialog.open();
+
+               return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       // ------------------------------------------------------------------------
+       // IHandlerListener
+       // ------------------------------------------------------------------------
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/TraceErrorHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/handlers/TraceErrorHandler.java
new file mode 100644 (file)
index 0000000..ebd6f4d
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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:
+ *   William Bourque - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.linuxtools.lttng.ui.views.project.dialogs.TraceErrorDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+
+public class TraceErrorHandler implements IHandler {
+       
+       private String[] messages;
+       
+       public TraceErrorHandler(String[] newMessages) {
+               messages = newMessages;
+       }
+       
+       public boolean isEnabled() {
+               return true;
+       }
+       
+       public boolean isHandled() {
+               return true;
+       }
+       
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               IWorkbench workbench = PlatformUI.getWorkbench();
+               Shell shell = workbench.getActiveWorkbenchWindow().getShell();
+               
+               TraceErrorDialog dialog = new TraceErrorDialog(shell, messages);
+               dialog.open();
+
+               return null;
+       }
+
+       public void dispose() {
+       }
+       
+       public void addHandlerListener(IHandlerListener handlerListener) {
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+       }
+
+}
+
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/ILTTngProjectTreeNode.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/ILTTngProjectTreeNode.java
new file mode 100644 (file)
index 0000000..dea2e32
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.model;
+
+import java.util.List;
+
+/**
+ * <b><u>ILTTngProjectTreeNode</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ * TODO: Make ILTTngProjectTreeNode extends IAdaptable
+ */
+public interface ILTTngProjectTreeNode {
+
+       public String getName();
+
+       public ILTTngProjectTreeNode getParent();
+
+       public boolean hasChildren();
+       
+       public List<ILTTngProjectTreeNode> getChildren();
+       
+       public void removeChild(ILTTngProjectTreeNode child);
+
+       public void removeChildren();
+
+       public void refreshChildren();
+
+       public void refresh();
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngExperimentFolderNode.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngExperimentFolderNode.java
new file mode 100644 (file)
index 0000000..5f5416b
--- /dev/null
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.model;
+
+import java.lang.reflect.Array;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * <b><u>LTTngExperimentFolderNode</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class LTTngExperimentFolderNode extends LTTngProjectTreeNode {
+
+       private final IFolder fExperimentFolder;
+
+       // ------------------------------------------------------------------------
+       // Constructors
+       // ------------------------------------------------------------------------
+
+       public LTTngExperimentFolderNode(IFolder folder) {
+               this(null, folder);
+       }
+
+       public LTTngExperimentFolderNode(ILTTngProjectTreeNode parent, IFolder folder) {
+               super(parent);
+               fExperimentFolder = folder;
+       }
+
+       // ------------------------------------------------------------------------
+       // LTTngProjectTreeNode
+       // ------------------------------------------------------------------------
+
+       public String getName() {
+               return fExperimentFolder.getName();
+       }
+
+       @Override
+       public void refreshChildren() {
+               try {
+                       IResource[] resources = fExperimentFolder.members();
+                       for (IResource resource : resources) {
+                               if (resource instanceof IFolder) {
+                                       LTTngExperimentNode node = find(resource.getName());
+                                       if (node == null) {
+                                               node = new LTTngExperimentNode(this, (IFolder) resource);
+                                               fChildren.add(node);
+                                       }
+                               }
+                       }
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (exists(node.getName(), resources)) {
+                               node.refreshChildren();
+                       }
+                       else {
+                               fChildren.remove(node);
+                       }
+               }
+               } catch (CoreException e) {
+               }
+       }
+
+       private LTTngExperimentNode find(String name) {
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (node instanceof LTTngExperimentNode && node.getName().equals(name)) {
+                               return (LTTngExperimentNode) node;
+                       }
+               }
+               return null;
+       }
+
+       private boolean exists(String name, IResource[] resources) {
+        for (IResource resource : resources) {
+                       if (resource.getName().equals(name))
+                               return true;
+        }
+               return false;
+       }
+
+       // ------------------------------------------------------------------------
+       // Accessors
+       // ------------------------------------------------------------------------
+
+       /**
+        * @return
+        */
+       public LTTngProjectNode getProject() {
+               return (LTTngProjectNode) getParent();
+       }
+
+       /**
+        * @return
+        */
+       public IFolder getFolder() {
+               return fExperimentFolder;
+       }
+
+       /**
+        * @return
+        */
+       public LTTngExperimentNode[] getExperiments() {
+               LTTngExperimentNode[] result = (LTTngExperimentNode[]) Array.newInstance(LTTngExperimentNode.class, fChildren.size());
+               return fChildren.toArray(result);
+       }
+
+       // ------------------------------------------------------------------------
+       // Modifiers
+       // ------------------------------------------------------------------------
+
+//     No longer needed: handled by the IResourceChangeListener in the View
+       public void addExperiment(IFolder experiment) {
+//             LTTngExperimentNode node = new LTTngExperimentNode(this, experiment);
+//             fChildren.add(node);
+//             refresh();
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngExperimentNode.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngExperimentNode.java
new file mode 100644 (file)
index 0000000..e494bc4
--- /dev/null
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * 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.project.model;
+
+import java.lang.reflect.Array;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * <b><u>LTTngExperimentNode</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class LTTngExperimentNode extends LTTngProjectTreeNode {
+
+       private final IFolder fExperiment;
+
+       // ------------------------------------------------------------------------
+       // Constructors
+       // ------------------------------------------------------------------------
+
+       public LTTngExperimentNode(IFolder resource) {
+               this(null, resource);
+       }
+       
+       public LTTngExperimentNode(ILTTngProjectTreeNode parent, IFolder folder) {
+               super(parent);
+               fExperiment = folder;
+       }
+       
+       // ------------------------------------------------------------------------
+       // LTTngProjectTreeNode
+       // ------------------------------------------------------------------------
+
+       public String getName() {
+               return fExperiment.getName();
+       }
+
+       @Override
+       public void refreshChildren() {
+               try {
+                       IResource[] resources = fExperiment.members(0);
+                       for (IResource resource : resources) {
+                               LTTngTraceNode node = find(resource.getName());
+                               if (node == null) {
+                                       node = new LTTngTraceNode(this, (IFolder) resource);
+                                       fChildren.add(node);
+                               }
+                       }
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (!exists(node.getName(), resources)) {
+                               fChildren.remove(node);
+                       }
+               }
+               } catch (CoreException e) {
+               }
+       }
+
+       private LTTngTraceNode find(String name) {
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (node instanceof LTTngTraceNode && node.getName().equals(name)) {
+                               return (LTTngTraceNode) node;
+                       }
+               }
+               return null;
+       }
+
+       private boolean exists(String name, IResource[] resources) {
+        for (IResource resource : resources) {
+                       if (resource.getName().equals(name))
+                               return true;
+        }
+               return false;
+       }
+
+       // ------------------------------------------------------------------------
+       // Modifiers
+       // ------------------------------------------------------------------------
+
+//     No longer needed: handled by the IResourceChangeListener in the View
+       public void addTrace(IFolder trace) {
+//             LTTngTraceNode node = new LTTngTraceNode(this, trace);
+//             fChildren.add(node);
+//             refresh();
+       }
+
+       // ------------------------------------------------------------------------
+       // Accessors
+       // ------------------------------------------------------------------------
+
+       /**
+        * @return
+        */
+       public IFolder getFolder() {
+               return fExperiment;
+       }
+
+       /**
+        * @return
+        */
+       public LTTngTraceNode[] getTraces() {
+               LTTngTraceNode[] result = (LTTngTraceNode[]) Array.newInstance(LTTngTraceNode.class, fChildren.size());
+               return fChildren.toArray(result);
+       }
+
+       /**
+        * @return
+        */
+       public LTTngProjectNode getProject() {
+               return (LTTngProjectNode) getParent().getParent();
+       }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectContentProvider.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectContentProvider.java
new file mode 100644 (file)
index 0000000..12a8f74
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.model;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * <b><u>LTTngProjectContentProvider</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+ public class LTTngProjectContentProvider implements ITreeContentProvider {
+
+       public Object[] getChildren(Object parentElement) {
+               return ((ILTTngProjectTreeNode) parentElement).getChildren().toArray();
+       }
+
+       public Object getParent(Object element) {
+               return ((ILTTngProjectTreeNode) element).getParent();
+       }
+
+       public boolean hasChildren(Object element) {
+               return ((ILTTngProjectTreeNode) element).hasChildren();
+       }
+
+       public Object[] getElements(Object inputElement) {
+               if (inputElement instanceof LTTngProjectRoot) {
+                       return ((LTTngProjectRoot) inputElement).getChildren().toArray();
+               }
+        return null;
+       }
+
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectLabelProvider.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectLabelProvider.java
new file mode 100644 (file)
index 0000000..6dee2d4
--- /dev/null
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * 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.project.model;
+
+import java.net.URL;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.linuxtools.lttng.ui.LTTngUiPlugin;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>LTTngProjectLabelProvider</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ * TODO: Find proper icons for traces and experiments
+ */
+public class LTTngProjectLabelProvider implements ILabelProvider {
+
+       private final String fTraceIconFile      = "icons/garland16.png";
+//     private final String fExperimentIconFile = "icons/garland16.png";
+
+       private final Image fOpenedProjectIcon;
+       private final Image fClosedProjectIcon;
+       private final Image fFolderIcon;
+       private final Image fTraceIcon;
+       private final Image fExperimentIcon;
+
+       /**
+        * 
+        */
+       public LTTngProjectLabelProvider() {
+
+               fOpenedProjectIcon = PlatformUI.getWorkbench().getSharedImages().getImage(org.eclipse.ui.ide.IDE.SharedImages.IMG_OBJ_PROJECT);
+               fClosedProjectIcon = PlatformUI.getWorkbench().getSharedImages().getImage(org.eclipse.ui.ide.IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED);
+               fFolderIcon  = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+
+               fTraceIcon = loadIcon(fTraceIconFile);
+               fExperimentIcon = fFolderIcon; // loadIcon(fExperimentIconFile);
+       }
+
+       private Image loadIcon(String url) {
+               LTTngUiPlugin plugin = LTTngUiPlugin.getDefault();
+               Image icon = plugin.getImageRegistry().get(url);
+               if (icon == null) {
+                       URL imageURL = plugin.getBundle().getEntry(url);
+                       ImageDescriptor descriptor = ImageDescriptor.createFromURL(imageURL);
+                       icon = descriptor.createImage();
+                       plugin.getImageRegistry().put(url, icon);
+               }
+               return icon;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+        */
+       public Image getImage(Object element) {
+
+               if (element instanceof LTTngProjectNode) {
+                       LTTngProjectNode project = (LTTngProjectNode) element;
+                       return (project.isOpen()) ? fOpenedProjectIcon : fClosedProjectIcon;
+               }
+
+               if (element instanceof LTTngTraceFolderNode) {
+                       return fFolderIcon;
+               }
+
+               if (element instanceof LTTngTraceNode) {
+                       return fTraceIcon;
+               }
+
+               if (element instanceof LTTngExperimentFolderNode) {
+                       return fFolderIcon;
+               }
+
+               if (element instanceof LTTngExperimentNode) {
+                       return fExperimentIcon;
+               }
+
+               return null;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+        */
+       public String getText(Object element) {
+               ILTTngProjectTreeNode node = (ILTTngProjectTreeNode) element;
+               String label = node.getName();
+               if (node instanceof LTTngTraceFolderNode      || 
+                       node instanceof LTTngExperimentFolderNode ||
+                       node instanceof LTTngExperimentNode)
+               {
+                       label += " [" + node.getChildren().size() + "]";
+               }
+               return label;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
+        */
+       public void addListener(ILabelProviderListener listener) {
+               // TODO Auto-generated method stub
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
+        */
+       public void dispose() {
+               // TODO Auto-generated method stub
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
+        */
+       public boolean isLabelProperty(Object element, String property) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
+        */
+       public void removeListener(ILabelProviderListener listener) {
+               // TODO Auto-generated method stub
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectNode.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectNode.java
new file mode 100644 (file)
index 0000000..748dce7
--- /dev/null
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.lttng.ui.views.project.LTTngProjectNature;
+
+/**
+ * <b><u>LTTngProjectNode</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class LTTngProjectNode extends LTTngProjectTreeNode {
+
+       public static final String TRACE_FOLDER_NAME = "Traces";
+       public static final String EXPER_FOLDER_NAME = "Experiments";
+
+       private final IProject fProject;
+       private boolean fIsLTTngProject;
+       private boolean fIsOpen;
+       private LTTngTraceFolderNode fTracesFolder;
+       private LTTngExperimentFolderNode fExperimentsFolder;
+
+       // ------------------------------------------------------------------------
+       // Constructors
+       // ------------------------------------------------------------------------
+
+       public LTTngProjectNode(IProject project) {
+               this(null, project);
+       }
+
+       public LTTngProjectNode(ILTTngProjectTreeNode parent, IProject project) {
+               super(parent);
+               fProject = project;
+               updateState();
+       }
+
+       // ------------------------------------------------------------------------
+       // LTTngProjectTreeNode
+       // ------------------------------------------------------------------------
+
+       public String getName() {
+               return fProject.getName();
+       }
+
+       @Override
+       public void refreshChildren() {
+
+               if (!(fIsOpen && fIsLTTngProject))
+                       return;
+
+               try {
+                       IResource[] resources = fProject.members();
+                       for (IResource resource : resources) {
+                               if (resource.getType() == IResource.FOLDER) {
+                                       String name = resource.getName();
+                                       if (name.equals(TRACE_FOLDER_NAME) && !isIncluded(true, name, fChildren)) {
+                                               fTracesFolder = new LTTngTraceFolderNode(this, (IFolder) resource);
+                                               fChildren.add(fTracesFolder);
+                                       } else
+                                       if (name.equals(EXPER_FOLDER_NAME) && !isIncluded(false, name, fChildren)) {
+                                               fExperimentsFolder = new LTTngExperimentFolderNode(this, (IFolder) resource);
+                                               fChildren.add(fExperimentsFolder);
+                                       }
+                               }
+                       }
+               List<ILTTngProjectTreeNode> toRemove = new ArrayList<ILTTngProjectTreeNode>();
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (exists(node.getName(), resources)) {
+                               node.refreshChildren();
+                       }
+                       else {
+                               toRemove.add(node);
+                       }
+               }
+               for (ILTTngProjectTreeNode node : toRemove) {
+                       fChildren.remove(node);
+               }
+               
+               } catch (CoreException e) {
+               }
+       }
+
+       private boolean isIncluded(boolean isTraces, String name, List<ILTTngProjectTreeNode> list) {
+               boolean found = false;
+               for (ILTTngProjectTreeNode node : list) {
+                       if (node instanceof LTTngTraceFolderNode && isTraces) {
+                               found |= node.getName().equals(name);
+                       } else
+                       if (node instanceof LTTngExperimentFolderNode && !isTraces) {
+                               found |= node.getName().equals(name);
+                       }
+               }
+               return found;
+       }
+
+       private boolean exists(String name, IResource[] resources) {
+        for (IResource resource : resources) {
+                       if (resource.getName().equals(name))
+                               return true;
+        }
+               return false;
+       }
+
+       // ------------------------------------------------------------------------
+       // Modifiers
+       // ------------------------------------------------------------------------
+
+       public void openProject() {
+               try {
+                       fProject.open(null);
+                       updateState();
+                       refreshChildren();
+               } catch (CoreException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public void closeProject() {
+               try {
+                       fProject.close(null);
+                       updateState();
+                       removeChildren();
+               } catch (CoreException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       private boolean isLTTngProject(IProject project) {
+               boolean result = false;
+               if (project != null && project.isAccessible()) {
+                       try {
+                               result = project.hasNature(LTTngProjectNature.ID);
+                       } catch (CoreException e) {
+                       }
+               }
+               return result;
+       }
+
+       public void updateState() {
+               fIsOpen = (fProject != null) ? fProject.isAccessible() : false;
+               fIsLTTngProject = isLTTngProject(fProject);
+       }
+
+       // ------------------------------------------------------------------------
+       // Accessors
+       // ------------------------------------------------------------------------
+
+       /**
+        * @return
+        */
+       public boolean isLTTngProject() {
+               return fIsLTTngProject;
+       }
+
+       /**
+        * @return
+        */
+       public boolean isOpen() {
+               return fIsOpen;
+       }
+
+       /**
+        * @return
+        */
+       public IProject getProject() {
+               return fProject;
+       }
+
+       /**
+        * @return
+        */
+       public LTTngTraceFolderNode getTracesFolder() {
+               return fTracesFolder;
+       }
+
+       /**
+        * @return
+        */
+       public LTTngExperimentFolderNode getExperimentsFolder() {
+               return fExperimentsFolder;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectRoot.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectRoot.java
new file mode 100644 (file)
index 0000000..b54831c
--- /dev/null
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.linuxtools.lttng.ui.views.project.ProjectView;
+
+/**
+ * <b><u>LTTngProjectRoot</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class LTTngProjectRoot extends LTTngProjectTreeNode {
+
+       private final ProjectView fView;
+       
+       // ------------------------------------------------------------------------
+       // Constructors
+       // ------------------------------------------------------------------------
+
+       public LTTngProjectRoot(ProjectView view) {
+               super(null);
+               fView = view;
+               refreshChildren();
+       }
+
+       @Override
+       public void refresh() {
+               fView.refresh();
+       }
+
+       // ------------------------------------------------------------------------
+       // LTTngProjectTreeNode
+       // ------------------------------------------------------------------------
+
+       public String getName() {
+               return null;
+       }
+
+       @Override
+       public void refreshChildren() {
+        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+        IProject[] projects = root.getProjects();
+        for (IProject project : projects) {
+                       LTTngProjectNode node = find(project.getName());
+                       if (node == null) {
+                               node = new LTTngProjectNode(this, project);
+                               fChildren.add(node);
+                       } else {
+                               node.updateState();
+                       }
+        }
+       List<ILTTngProjectTreeNode> toRemove = new ArrayList<ILTTngProjectTreeNode>();
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (exists(node.getName(), projects)) {
+                               node.refreshChildren();
+                       }
+                       else {
+                       toRemove.add(node);
+                       }
+        }
+               for (ILTTngProjectTreeNode node : toRemove) {
+                       fChildren.remove(node);
+               }
+       }
+
+       private LTTngProjectNode find(String name) {
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (node instanceof LTTngProjectNode && node.getName().equals(name)) {
+                               return (LTTngProjectNode) node;
+                       }
+               }
+               return null;
+       }
+
+       private boolean exists(String name, IProject[] projects) {
+        for (IProject project : projects) {
+                       if (project.getName().equals(name))
+                               return true;
+        }
+               return false;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectTreeNode.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngProjectTreeNode.java
new file mode 100644 (file)
index 0000000..b35bbfd
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <b><u>LTTngProjectTreeNode</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public abstract class LTTngProjectTreeNode implements ILTTngProjectTreeNode {
+
+       protected ILTTngProjectTreeNode fParent = null;
+       protected List<ILTTngProjectTreeNode> fChildren = null;
+
+       // ------------------------------------------------------------------------
+       // Constructor
+       // ------------------------------------------------------------------------
+
+       public LTTngProjectTreeNode(ILTTngProjectTreeNode parent) {
+               fParent = parent;
+               fChildren = new ArrayList<ILTTngProjectTreeNode>();
+       }
+
+       @Override
+       public String toString() {
+               return getName();
+       }
+       
+       // ------------------------------------------------------------------------
+       // ILTTngProjectTreeNode
+       // ------------------------------------------------------------------------
+
+       public ILTTngProjectTreeNode getParent() {
+               return fParent;
+       }
+
+       public boolean hasChildren() {
+               return fChildren.size() > 0;
+       }
+
+       public List<ILTTngProjectTreeNode> getChildren() {
+               return fChildren;
+       }
+
+       public abstract void refreshChildren();
+
+       public void refresh() {
+               fParent.refresh();
+       }
+
+       public void removeChild(ILTTngProjectTreeNode child) {
+        for (ILTTngProjectTreeNode node : fChildren) {
+               if (node == child) {
+                       node.removeChildren();
+                       // We can do it since we are returning right away
+                       fChildren.remove(node);
+                       return;
+               }
+        }
+       }
+
+       public void removeChildren() {
+        for (ILTTngProjectTreeNode node : fChildren) {
+                       node.removeChildren();
+        }
+               fChildren.clear();
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngTraceFolderNode.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngTraceFolderNode.java
new file mode 100644 (file)
index 0000000..de11690
--- /dev/null
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.model;
+
+import java.lang.reflect.Array;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * <b><u>LTTngTraceFolderNode</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class LTTngTraceFolderNode extends LTTngProjectTreeNode {
+
+       private final IFolder fTraceFolder;
+
+       // ------------------------------------------------------------------------
+       // Constructors
+       // ------------------------------------------------------------------------
+
+       public LTTngTraceFolderNode(IFolder folder) {
+               this(null, folder);
+       }
+
+       public LTTngTraceFolderNode(ILTTngProjectTreeNode parent, IFolder folder) {
+               super(parent);
+               fTraceFolder = folder;
+       }
+
+       // ------------------------------------------------------------------------
+       // LTTngProjectTreeNode
+       // ------------------------------------------------------------------------
+
+       public String getName() {
+               return fTraceFolder.getName();
+       }
+
+       @Override
+       public void refreshChildren() {
+               try {
+                       IResource[] resources = fTraceFolder.members();
+                       for (IResource resource : resources) {
+                               if (resource instanceof IFolder) {
+                                       LTTngTraceNode node = find(resource.getName());
+                                       if (node == null) {
+                                               node = new LTTngTraceNode(this, (IFolder) resource);
+                                               fChildren.add(node);
+                                       }
+                               }
+                       }
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (!exists(node.getName(), resources)) {
+                               fChildren.remove(node);
+                       }
+               }
+               } catch (CoreException e) {
+               }
+       }
+
+       private LTTngTraceNode find(String name) {
+               for (ILTTngProjectTreeNode node : fChildren) {
+                       if (node instanceof LTTngTraceNode && node.getName().equals(name)) {
+                               return (LTTngTraceNode) node;
+                       }
+               }
+               return null;
+       }
+
+       private boolean exists(String name, IResource[] resources) {
+        for (IResource resource : resources) {
+                       if (resource.getName().equals(name))
+                               return true;
+        }
+               return false;
+       }
+
+       // ------------------------------------------------------------------------
+       // Accessors
+       // ------------------------------------------------------------------------
+
+       /**
+        * @return
+        */
+       public LTTngProjectNode getProject() {
+               return (LTTngProjectNode) getParent();
+       }
+
+       /**
+        * @return
+        */
+       public IFolder getFolder() {
+               return fTraceFolder;
+       }
+
+       /**
+        * @return
+        */
+       public LTTngTraceNode[] getTraces() {
+               LTTngTraceNode[] result = (LTTngTraceNode[]) Array.newInstance(LTTngTraceNode.class, fChildren.size());
+               return fChildren.toArray(result);
+       }
+
+       // ------------------------------------------------------------------------
+       // Modifiers
+       // ------------------------------------------------------------------------
+
+//     No longer needed: handled by the IResourceChangeListener in the View
+       public void addTrace(IFolder trace) {
+//             LTTngTraceNode node = new LTTngTraceNode(this, trace);
+//             fChildren.add(node);
+//             refresh();
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngTraceNode.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/project/model/LTTngTraceNode.java
new file mode 100644 (file)
index 0000000..4312a2d
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.project.model;
+
+import org.eclipse.core.resources.IFolder;
+
+/**
+ * <b><u>LTTngTraceNode</u></b>
+ * <p>
+ * TODO: Implement me. Please.
+ */
+public class LTTngTraceNode extends LTTngProjectTreeNode {
+       
+       private final IFolder fTrace;
+
+       // ------------------------------------------------------------------------
+       // Constructors
+       // ------------------------------------------------------------------------
+
+       public LTTngTraceNode(IFolder folder) {
+               this(null, folder);
+       }
+
+       public LTTngTraceNode(ILTTngProjectTreeNode parent, IFolder trace) {
+               super(parent);
+               fTrace = trace;
+       }
+
+       // ------------------------------------------------------------------------
+       // LTTngProjectTreeNode
+       // ------------------------------------------------------------------------
+
+       public String getName() {
+               return fTrace.getName();
+       }
+
+       @Override
+       public void refreshChildren() {
+       }
+
+       // ------------------------------------------------------------------------
+       // Accessors
+       // ------------------------------------------------------------------------
+
+       /**
+        * @return
+        */
+       public LTTngProjectNode getProject() {
+               return (LTTngProjectNode) getParent().getParent();
+       }
+
+       /**
+        * @return
+        */
+       public IFolder getFolder() {
+               return fTrace;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/Messages.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/Messages.java
new file mode 100644 (file)
index 0000000..e01dae1
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2009 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation\r
+ *******************************************************************************/\r
+package org.eclipse.linuxtools.lttng.ui.views.resources;\r
+\r
+import java.util.MissingResourceException;\r
+import java.util.ResourceBundle;\r
+\r
+public class Messages {\r
+       private static final String BUNDLE_NAME = "org.eclipse.linuxtools.lttng.ui.views.resources.messages"; //$NON-NLS-1$\r
+\r
+       private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle\r
+                       .getBundle(BUNDLE_NAME);\r
+\r
+       private Messages() {\r
+       }\r
+\r
+       public static String getString(String key) {\r
+               try {\r
+                       return RESOURCE_BUNDLE.getString(key);\r
+               } catch (MissingResourceException e) {\r
+                       return '!' + key + '!';\r
+               }\r
+       }\r
+}\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/ResourcesView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/ResourcesView.java
new file mode 100644 (file)
index 0000000..c658ac2
--- /dev/null
@@ -0,0 +1,560 @@
+/*******************************************************************************
+ * 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: Alvaro Sanchez-Leon - Initial implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.resources;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeViewerProvider;
+import org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView;
+import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
+import org.eclipse.linuxtools.lttng.ui.views.resources.evProcessor.ResourcesEventToHandlerFactory;
+import org.eclipse.linuxtools.lttng.ui.views.resources.model.ResourceModelFactory;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
+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.TmfTimeSynchSignal;
+import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewerFactory;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeScaleSelectionListener;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeSelectionListener;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @author alvaro
+ * 
+ */
+public class ResourcesView extends AbsTimeUpdateView implements
+               ITmfTimeSelectionListener, ITmfTimeScaleSelectionListener {
+
+       // ========================================================================
+       // Data
+       // ========================================================================
+       public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.resources";
+
+       // private int totalNumItems = 0;
+       // Actions
+       private Action resetScale;
+       private Action nextEvent;
+       private Action prevEvent;
+       private Action nextTrace;
+       private Action prevTrace;
+       private Action showLegend;
+       private Action filterTraces;
+       private Action zoomIn;
+       private Action zoomOut;
+       private Action zoomFilter;
+       private Composite top;
+
+       // private static SimpleDateFormat stimeformat = new SimpleDateFormat(
+       // "yy/MM/dd HH:mm:ss");
+
+       // private TraceModelImplFactory fact;
+
+       // ========================================================================
+       // Constructor
+       // ========================================================================
+
+       /**
+        * The constructor.
+        */
+       public ResourcesView() {
+               super(ID);
+       }
+
+       // ========================================================================
+       // Methods
+       // ========================================================================
+
+       /**
+        * This is a callback that will allow us to create the viewer and initialize
+        * it.
+        */
+       @Override
+       public void createPartControl(Composite parent) {
+               top = new Composite(parent, SWT.BORDER);
+
+               top.setLayout(new FillLayout());
+               tsfviewer = TmfViewerFactory.createViewer(top,
+                               new TimeRangeViewerProvider());
+
+               tsfviewer.addWidgetSelectionListner(this);
+               tsfviewer.addWidgetTimeScaleSelectionListner(this);
+
+               // Traces shall not be grouped to allow synchronisation
+               tsfviewer.groupTraces(true);
+               tsfviewer.setAcceptSelectionAPIcalls(true);
+
+               // Viewer to notify selection to this class
+               // This class will synchronise selections with table.
+               tsfviewer.addWidgetSelectionListner(this);
+               tsfviewer.addWidgetTimeScaleSelectionListner(this);
+
+               // Create the help context id for the viewer's control
+               // TODO: Associate with help system
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(
+                               tsfviewer.getControl(),
+                               "org.eclipse.linuxtools.lttng.ui.views.resource.view"); //$NON-NLS-1$
+
+               makeActions();
+               hookContextMenu();
+               contributeToActionBars();
+
+               // Read relevant values
+               int timeSpaceWidth = tsfviewer.getTimeSpace();
+               if (timeSpaceWidth < 0) {
+                       timeSpaceWidth = -timeSpaceWidth;
+               }
+
+               TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment();
+               if (experiment != null) {
+                       TmfTimeRange experimentTRange = experiment.getTimeRange();
+                       if (experimentTRange != null) {
+                               long time0 = experimentTRange.getStartTime().getValue();
+                               long time1 = experimentTRange.getEndTime().getValue();
+                               ParamsUpdater paramUpdater = getParamsUpdater();
+                               paramUpdater.update(time0, time1, timeSpaceWidth);
+                       }
+                       // send the initial request and obtained the adjusted time used
+                       TmfTimeRange adjustedTimeRange = initialExperimentDataRequest(this, experimentTRange);
+
+                       // initialize widget time boundaries and filtering parameters
+                       ModelUpdateInit(experimentTRange, adjustedTimeRange, this);
+               } else {
+                       TraceDebug.debug("No selected experiment information available");
+               }
+       }
+
+       private void hookContextMenu() {
+               MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+               menuMgr.setRemoveAllWhenShown(true);
+               menuMgr.addMenuListener(new IMenuListener() {
+                       public void menuAboutToShow(IMenuManager manager) {
+                               ResourcesView.this.fillContextMenu(manager);
+                       }
+               });
+
+               Menu menu = menuMgr.createContextMenu(tsfviewer.getControl());
+               tsfviewer.getControl().setMenu(menu);
+               getSite()
+                               .registerContextMenu(menuMgr, tsfviewer.getSelectionProvider());
+       }
+
+       private void contributeToActionBars() {
+               IActionBars bars = getViewSite().getActionBars();
+               fillLocalPullDown(bars.getMenuManager());
+               fillLocalToolBar(bars.getToolBarManager());
+       }
+
+       private void fillLocalPullDown(IMenuManager manager) {
+               manager.add(new Separator());
+               // manager.add(showLegend);
+               manager.add(new Separator());
+               manager.add(resetScale);
+               manager.add(nextEvent);
+               manager.add(prevEvent);
+               manager.add(nextTrace);
+               manager.add(prevTrace);
+               // manager.add(filterTraces);
+               manager.add(zoomIn);
+               manager.add(zoomOut);
+               manager.add(zoomFilter);
+               manager.add(new Separator());
+       }
+
+       private void fillContextMenu(IMenuManager manager) {
+               // manager.add(showLegend);
+               manager.add(new Separator());
+               manager.add(resetScale);
+               manager.add(nextEvent);
+               manager.add(prevEvent);
+               manager.add(nextTrace);
+               manager.add(prevTrace);
+               // manager.add(showLegend);
+               // manager.add(filterTraces);
+               manager.add(zoomIn);
+               manager.add(zoomOut);
+               manager.add(zoomFilter);
+               manager.add(new Separator());
+               manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+       }
+
+       private void fillLocalToolBar(IToolBarManager manager) {
+               // manager.add(showLegend);
+               manager.add(new Separator());
+               manager.add(resetScale);
+               manager.add(nextEvent);
+               manager.add(prevEvent);
+               manager.add(nextTrace);
+               manager.add(prevTrace);
+               // manager.add(filterTraces);
+               manager.add(zoomIn);
+               manager.add(zoomOut);
+               manager.add(zoomFilter);
+               manager.add(new Separator());
+       }
+
+       private void makeActions() {
+               // action4
+               resetScale = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.resetStartFinishTime();
+                               }
+
+                       }
+               };
+               resetScale.setText(Messages.getString("ResourcesView.Action.Reset")); //$NON-NLS-1$
+               resetScale.setToolTipText(Messages
+                               .getString("ResourcesView.Action.Reset.ToolTip")); //$NON-NLS-1$
+               resetScale.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ResourcesView.tmf.UI"),
+                                               "icons/home_nav.gif"));
+
+               // action5
+               nextEvent = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.selectNextEvent();
+                               }
+                       }
+               };
+               nextEvent.setText(Messages.getString("ResourcesView.Action.NextEvent")); //$NON-NLS-1$
+               nextEvent.setToolTipText(Messages
+                               .getString("ResourcesView.Action.NextEvent.Tooltip")); //$NON-NLS-1$
+               nextEvent.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ResourcesView.tmf.UI"),
+                                               "icons/next_event.gif"));
+
+               // action6
+               prevEvent = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.selectPrevEvent();
+                               }
+                       }
+               };
+               prevEvent.setText(Messages.getString("ResourcesView.Action.PrevEvent")); //$NON-NLS-1$
+               prevEvent.setToolTipText(Messages
+                               .getString("ResourcesView.Action.PrevEvent.Tooltip")); //$NON-NLS-1$
+               prevEvent.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ResourcesView.tmf.UI"),
+                                               "icons/prev_event.gif"));
+
+               // action7
+               nextTrace = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.selectNextTrace();
+                               }
+                       }
+               };
+               nextTrace.setText(Messages
+                               .getString("ResourcesView.Action.NextResource")); //$NON-NLS-1$
+               nextTrace.setToolTipText(Messages
+                               .getString("ResourcesView.Action.NextResource.ToolTip")); //$NON-NLS-1$
+               nextTrace.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ResourcesView.tmf.UI"),
+                                               "icons/next_item.gif"));
+
+               // action8
+               prevTrace = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.selectPrevTrace();
+                               }
+                       }
+               };
+               prevTrace.setText(Messages
+                               .getString("ResourcesView.Action.PreviousResource")); //$NON-NLS-1$
+               prevTrace.setToolTipText(Messages
+                               .getString("ResourcesView.Action.PreviousResource.Tooltip")); //$NON-NLS-1$
+               prevTrace.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ResourcesView.tmf.UI"),
+                                               "icons/prev_item.gif"));
+
+               // action9
+               showLegend = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.showLegend();
+                               }
+                       }
+               };
+               showLegend.setText(Messages.getString("ResourcesView.Action.Legend")); //$NON-NLS-1$
+               showLegend.setToolTipText(Messages
+                               .getString("ResourcesView.Action.Legend.ToolTip")); //$NON-NLS-1$
+
+               // action10
+               filterTraces = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.filterTraces();
+                               }
+                       }
+               };
+               filterTraces.setText(Messages.getString("ResourcesView.Action.Filter")); //$NON-NLS-1$
+               filterTraces.setToolTipText(Messages
+                               .getString("ResourcesView.Action.Filter.ToolTip")); //$NON-NLS-1$
+               filterTraces.setImageDescriptor(AbstractUIPlugin
+                               .imageDescriptorFromPlugin(Messages
+                                               .getString("ResourcesView.tmf.UI"),
+                                               "icons/filter_items.gif"));
+
+               // action10
+               zoomIn = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.zoomIn();
+                               }
+                       }
+               };
+               zoomIn.setText(Messages.getString("ResourcesView.Action.ZoomIn")); //$NON-NLS-1$
+               zoomIn.setToolTipText(Messages
+                               .getString("ResourcesView.Action.ZoomIn.Tooltip")); //$NON-NLS-1$
+               zoomIn.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
+                               Messages.getString("ResourcesView.tmf.UI"),
+                               "icons/zoomin_nav.gif"));
+
+               // action10
+               zoomOut = new Action() {
+                       @Override
+                       public void run() {
+                               if (tsfviewer != null) {
+                                       tsfviewer.zoomOut();
+                               }
+                       }
+               };
+               zoomOut.setText(Messages.getString("ResourcesView.Action.ZoomOut")); //$NON-NLS-1$
+               zoomOut.setToolTipText(Messages
+                               .getString("ResourcesView.Action.ZoomOut.tooltip")); //$NON-NLS-1$
+               zoomOut.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
+                               Messages.getString("ResourcesView.tmf.UI"),
+                               "icons/zoomout_nav.gif"));
+
+               // zoomFilter
+               zoomFilter = new Action() {
+                       @Override
+                       public void run() {
+                               // Nothing to do, however the selection status is needed by the
+                               // application
+                       }
+               };
+
+               zoomFilter.setText(Messages.getString("ResourcesView.Action.ZoomFilter")); //$NON-NLS-1$
+               zoomFilter.setToolTipText(Messages.getString("ResourcesView.Action.ZoomFilter.tooltip")); //$NON-NLS-1$
+               zoomFilter.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Messages
+                               .getString("ResourcesView.tmf.UI"), "icons/filter_items.gif"));
+               zoomFilter.setChecked(false);
+
+               // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);
+       }
+
+       /**
+        * Passing the focus request to the viewer's control.
+        */
+       @Override
+       public void setFocus() {
+               tsfviewer.getControl().setFocus();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * tsfTmProcessSelEvent
+        * (org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent
+        * )
+        */
+       public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event) {
+               // common implementation
+               super.tsfTmProcessSelEvent(event);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.
+        * ITmfTimeScaleSelectionListener
+        * #tsfTmProcessTimeScaleEvent(org.eclipse.linuxtools
+        * .tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent)
+        */
+       public void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event) {
+               super.tsfTmProcessTimeScaleEvent(event);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#displayModel
+        * (org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.
+        * ITmfTimeAnalysisEntry[], long, long, boolean, long, long,
+        * java.lang.Object)
+        */
+       public void displayModel(final ITmfTimeAnalysisEntry[] items, final long startBoundTime,
+                       final long endBoundTime, final boolean updateTimeBounds, final long startVisibleWindow,
+                       final long endVisibleWindow, final Object source) {
+
+               Display display = tsfviewer.getControl().getDisplay();
+               display.asyncExec(new Runnable() {
+
+                       public void run() {
+                               tsfviewer.display(items, startBoundTime, endBoundTime, updateTimeBounds);
+                               // validate visible boundaries
+                               if (startVisibleWindow > -1 && endVisibleWindow > -1) {
+                                       tsfviewer.setSelectVisTimeWindow(startVisibleWindow, endVisibleWindow, source);
+                               }
+                               tsfviewer.resizeControls();
+                       }
+               });
+       }
+
+       @Override
+       public void dispose() {
+               // dispose parent resources
+               super.dispose();
+
+               tsfviewer.removeWidgetSelectionListner(this);
+               tsfviewer.removeWidgetTimeScaleSelectionListner(this);
+               tsfviewer = null;
+       }
+
+       /**
+        * Registers as listener of time selection from other tmf views
+        * 
+        * @param signal
+        */
+       @TmfSignalHandler
+       public void synchToTime(TmfTimeSynchSignal signal) {
+               super.synchToTime(signal);
+       }
+
+       /**
+        * Annotation Registers as listener of time range selection from other views
+        * The implementation handles the entry of the signal.
+        * 
+        * @param signal
+        */
+       @TmfSignalHandler
+       public void synchToTimeRange(TmfRangeSynchSignal signal) {
+               if (zoomFilter != null) {
+                       synchToTimeRange(signal, zoomFilter.isChecked());
+               }
+       }
+
+       @Override
+       public void modelIncomplete(ILttngSyntEventRequest request) {
+               // Nothing to do
+               // The data will be refreshed on the next request
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * getEventProcessor()
+        */
+       @Override
+       public ITransEventProcessor getEventProcessor() {
+               return ResourcesEventToHandlerFactory.getInstance();
+       }
+
+       /**
+        * @param signal
+        */
+       @TmfSignalHandler
+       public void experimentSelected(TmfExperimentSelectedSignal<? extends TmfEvent> signal) {
+               if (signal != null) {
+                       TmfTimeRange experimentTRange = signal.getExperiment().getTimeRange();
+
+                       // prepare time intervals in widget
+                       ModelUpdateInit(experimentTRange, experimentTRange, signal.getSource());
+
+                       // request initial data
+                       initialExperimentDataRequest(signal.getSource(), experimentTRange);
+               }
+       }
+
+       /**
+        * @param source
+        * @param experimentTRange
+        * @return Adjusted time window used for the request (smaller window to
+        *         initialize view)
+        */
+       private TmfTimeRange initialExperimentDataRequest(Object source, TmfTimeRange experimentTRange) {
+               // Adjust the initial time window to a shorter interval to allow
+               // user to select the interesting area based on the perspective
+               TmfTimeRange initTimeWindow = getInitTRange(experimentTRange);
+
+               dataRequest(initTimeWindow, experimentTRange, true);
+               if (TraceDebug.isDEBUG()) {
+                       TraceDebug.debug("Initialization request time range is: " + initTimeWindow.getStartTime().toString() + "-"
+                                       + initTimeWindow.getEndTime().toString());
+               }
+
+               return initTimeWindow;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * getParamsUpdater()
+        */
+       protected ParamsUpdater getParamsUpdater() {
+               return ResourceModelFactory.getParamsUpdater();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * getItemContainer()
+        */
+       @Override
+       protected ItemContainer<?> getItemContainer() {
+               return ResourceModelFactory.getResourceContainer();
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/AbsResourcesTRangeUpdate.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/AbsResourcesTRangeUpdate.java
new file mode 100644 (file)
index 0000000..fa92ab1
--- /dev/null
@@ -0,0 +1,305 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.resources.evProcessor;
+
+import java.util.Vector;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeComponent;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEvent;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEvent.Type;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventResource;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventResource.ResourceTypes;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeResourceFactory;
+import org.eclipse.linuxtools.lttng.ui.views.common.AbsTRangeUpdate;
+import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
+import org.eclipse.linuxtools.lttng.ui.views.resources.model.ResourceContainer;
+import org.eclipse.linuxtools.lttng.ui.views.resources.model.ResourceModelFactory;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+
+public abstract class AbsResourcesTRangeUpdate extends AbsTRangeUpdate
+               implements ILttngEventProcessor {
+
+       // ========================================================================
+       // Data
+       // =======================================================================
+       protected ResourceContainer resContainer = ResourceModelFactory
+                       .getResourceContainer();
+       protected ParamsUpdater params = ResourceModelFactory.getParamsUpdater();
+       protected static final Long ANY_CPU = 0L;
+
+       // ========================================================================
+       // Methods
+       // =======================================================================
+       protected TimeRangeEventResource addLocalResource(long traceStartTime,
+                       long traceEndTime, String traceId, ResourceTypes type, Long resId,
+                       long insertionTime) {
+
+               String resourceName = type.toString() + " " + resId.toString();
+               // Note : the "traceid" here is assigned to the "groupname" as we group
+               // by trace in the UI
+               TimeRangeEventResource localRessource = TimeRangeResourceFactory
+                               .getInstance().createResource(resContainer.getUniqueId(),
+                                               traceStartTime, traceEndTime, resourceName, traceId,
+                                               "", type, resId, insertionTime);
+               resContainer.addItem(localRessource);
+               return localRessource;
+       }
+
+       /**
+        * Used to check if the event is visible within the current visible time
+        * window
+        * 
+        * @return
+        */
+       protected boolean withinViewRange(long stime, long etime) {
+               long windowStartTime = params.getStartTime();
+               long windowEndTime = params.getEndTime();
+
+               if (stime == 13589765052286L) {
+                       TraceDebug.debug("Debug event catched");
+               }
+
+               // Start of event is already out of range
+               if (stime > windowEndTime) {
+                       return false;
+               }
+
+               // End time within or beyond start of window as long as the start time
+               // is before the end of the window (condition above)
+               if (etime >= windowStartTime) {
+                       return true;
+               }
+
+               // // start time is within window
+               // if (stime >= windowStartTime && stime <= windowEndTime) {
+               // // The event or part of it shall be displayed.
+               // return true;
+               // }
+               //
+               // // end time is within window
+               // if (etime >= windowStartTime && etime <= windowEndTime) {
+               // // The event or part of it shall be displayed.
+               // return true;
+               // }
+
+               // crosses the window
+               if (stime <= windowStartTime && etime >= windowEndTime) {
+                       // The time range is bigger than the selected time window and
+                       // crosses it
+                       return true;
+               }
+
+               return false;
+       }
+
+       public TimeRangeEventResource resourcelist_obtain_bdev(
+                       LttngTraceState traceState, Long resourceId) {
+               return resourcelist_obtain_generic(resourceId, ResourceTypes.BDEV,
+                               traceState.getTraceId());
+       }
+
+       public TimeRangeEventResource resourcelist_obtain_trap(
+                       LttngTraceState traceState, Long resourceId) {
+               return resourcelist_obtain_generic(resourceId, ResourceTypes.TRAP,
+                               traceState.getTraceId());
+       }
+
+       public TimeRangeEventResource resourcelist_obtain_irq(
+                       LttngTraceState traceState, Long resourceId) {
+               return resourcelist_obtain_generic(resourceId, ResourceTypes.IRQ,
+                               traceState.getTraceId());
+       }
+
+       public TimeRangeEventResource resourcelist_obtain_soft_irq(
+                       LttngTraceState traceState, Long resourceId) {
+               return resourcelist_obtain_generic(resourceId, ResourceTypes.SOFT_IRQ,
+                               traceState.getTraceId());
+       }
+
+       public TimeRangeEventResource resourcelist_obtain_cpu(
+                       LttngTraceState traceState, Long resourceId) {
+               return resourcelist_obtain_generic(resourceId, ResourceTypes.CPU,
+                               traceState.getTraceId());
+       }
+
+       public TimeRangeEventResource resourcelist_obtain_machine(
+                       LttngTraceState traceState, Long resourceId) {
+               // *** VERIFY ***
+               // Does "UNKNOWN" make sense for "obtain_machine" ?
+               // It seems to be the only choice, thought...
+               return resourcelist_obtain_generic(resourceId, ResourceTypes.UNKNOWN,
+                               traceState.getTraceId());
+       }
+
+       public TimeRangeEventResource resourcelist_obtain_generic(Long resourceId,
+                       ResourceTypes resourceType, String traceId) {
+               return resContainer.findItem(resourceId, resourceType, traceId);
+       }
+
+       protected boolean globalProcessBeforeExecmode(LttngEvent trcEvent,
+                       LttngTraceState traceSt) {
+
+               // TODO: Implement the tracking of current resource in order ot speed up
+               // searching for the relevant resource similar to current_hash_data in
+               // the C implementation
+               // e.g.
+               // hashed_process_data =
+               // process_list->current_hash_data[trace_num][cpu];
+
+               TimeRangeEventResource localResource = resourcelist_obtain_cpu(traceSt,
+                               trcEvent.getCpuId());
+               Long cpu = trcEvent.getCpuId();
+               if (localResource == null) {
+                       TmfTimeRange timeRange = traceSt.getContext()
+                                       .getTraceTimeWindow();
+                       localResource = addLocalResource(timeRange.getStartTime()
+                                       .getValue(), timeRange.getEndTime().getValue(), traceSt
+                                       .getTraceId(), ResourceTypes.CPU, cpu, trcEvent
+                                       .getTimestamp().getValue());
+               }
+
+               // get the start time
+               long stime = localResource.getNext_good_time();
+               // Get the resource state mode
+               String cpuStateMode = localResource.getStateMode(traceSt);
+               // Call the makeDraw function
+               makeDraw(traceSt, stime, trcEvent.getTimestamp().getValue(),
+                               localResource, params, cpuStateMode);
+
+               return false;
+       }
+
+       /**
+        * @param traceSt
+        * @param startTime
+        * @param endTime
+        * @param localResource
+        * @param params
+        * @param stateMode
+        * @return
+        */
+       protected boolean makeDraw(LttngTraceState traceSt, long stime, long etime,
+                       TimeRangeEventResource localResource,
+                       ParamsUpdater params, String stateMode) {
+
+               // Check if the event is out of range
+               if (!withinViewRange(stime, etime)) {
+                       params.incrementEventsDiscarded();
+                       return false;
+               }
+
+               // Check if the time range is consistent.
+               if (etime < stime) {
+                       params.incrementEventsDiscardedWrongOrder();
+                       return false;
+               }
+
+               // Store the next good time to start drawing the next event
+               // this is done this early to display an accurate start time of the
+               // first event
+               // within the display window
+               // Moved at the end since it produces space gaps among events
+               // localResource.setNext_good_time(etime);
+
+               // Determine if the time range event will fit it the current
+               // pixel map
+               double duration = etime - stime;
+               double k = getPixelsPerNs(traceSt, params);
+               double pixels = duration * k;
+
+               // Visibility check
+               // Display a "more information" indication by allowing non visible event
+               // as long as its previous event is visible.
+               boolean visible = true;
+               if (pixels < 1) {
+                       boolean prevEventVisibility = true;
+                       // Get the visibility indication on previous event for
+                       // this process
+                       Vector<TimeRangeComponent> inMemEvents = localResource
+                                       .getTraceEvents();
+                       if (inMemEvents.size() != 0) {
+                               TimeRangeComponent prevEvent = inMemEvents.get(inMemEvents
+                                               .size() - 1);
+                               prevEventVisibility = prevEvent.isVisible();
+
+                               // if previous event visibility is false and the time span
+                               // between events less than two pixels, there is no need to
+                               // load it in memory i.e. not visible and a more indicator is
+                               // within two pixels.
+                               // return i.e. event discarded to free up memory
+                               Long eventSpan = stime - prevEvent.getStartTime();
+                               if (prevEventVisibility == false
+                                               && ((double) eventSpan * k) < 2) {
+                                       params.incrementEventsDiscarded();
+                                       return false;
+                               }
+                       }
+
+                       // if previous event is visible, set this one to not
+                       // visible and continue
+                       visible = false;
+               }
+
+               Type eventType = getEventType(localResource);
+               if (eventType != null) {
+                       TimeRangeEvent time_window = new TimeRangeEvent(stime, etime,
+                                       localResource, eventType, stateMode);
+
+                       time_window.setVisible(visible);
+                       localResource.addChildren(time_window);
+
+                       localResource.setNext_good_time(etime);
+               }
+
+               return false;
+       }
+
+       /**
+        * Convert between resource type and timeRange event type
+        * 
+        * @param resource
+        * @return
+        */
+       private Type getEventType(TimeRangeEventResource resource) {
+               // TODO: Can we merge into one type
+               ResourceTypes resType = resource.getType();
+               Type eventType = null;
+
+               switch (resType) {
+               case CPU:
+                       eventType = Type.CPU_MODE;
+                       break;
+               case IRQ:
+                       eventType = Type.IRQ_MODE;
+                       break;
+               case SOFT_IRQ:
+                       eventType = Type.SOFT_IRQ_MODE;
+                       break;
+               case TRAP:
+                       eventType = Type.TRAP_MODE;
+                       break;
+               case BDEV:
+                       eventType = Type.BDEV_MODE;
+                       break;
+               default:
+                       eventType = Type.PROCESS_MODE;
+                       break;
+               }
+
+               return eventType;
+       }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesAfterUpdateHandlers.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesAfterUpdateHandlers.java
new file mode 100644 (file)
index 0000000..11aad14
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.resources.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+
+/**
+ * Creates instances of specific after state update handlers, per corresponding
+ * event.
+ * 
+ * @author alvaro
+ * 
+ */
+public class ResourcesAfterUpdateHandlers {
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_SCHED_SCHEDULE
+        * </p>
+        * Replace C function named "after_schedchange_hook" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getAfterSchedChangeHandler() {
+               AbsResourcesTRangeUpdate handler = new AbsResourcesTRangeUpdate() {
+
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+
+                               // TODO: After sched scheduler handler should implement an
+                               // update to the current resource data, similar to
+                               // current_hash_data in C
+                               // We don't keep track of current hashed resource, we look in
+                               // the hash table every time. keeping track of current hash may
+                               // improve performance, although needs to be bench marked to
+                               // verify
+                               // if there's is a real gain.
+
+                               // process_list->current_hash_data[trace_num][process_in->cpu] =
+                               // hashed_process_data_in;
+
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+
+       /**
+        * Drawing stuff ?
+        */
+       // int after_request(void *hook_data, void *call_data)
+       // int after_chunk(void *hook_data, void *call_data)
+       // int before_statedump_end(void *hook_data, void *call_data)
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesBeforeUpdateHandlers.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesBeforeUpdateHandlers.java
new file mode 100644 (file)
index 0000000..ff562de
--- /dev/null
@@ -0,0 +1,374 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.resources.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Channels;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Events;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Fields;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventResource;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventResource.ResourceTypes;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+
+/**
+ * Creates instances of specific before state update handlers, per corresponding
+ * event.
+ * 
+ * @author alvaro
+ * 
+ */
+public class ResourcesBeforeUpdateHandlers {
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_SCHED_SCHEDULE
+        * </p>
+        * Replace C function named "before_schedchange_hook" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID(?), LTT_FIELD_PREV_STATE
+        * (?)
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getBeforeSchedChangeHandler() {
+               AbsResourcesTRangeUpdate handler = new AbsResourcesTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+                               // Create a time range for the cpu.
+                               globalProcessBeforeExecmode(trcEvent, traceSt);
+
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_IRQ_ENTRY, LTT_EVENT_IRQ_EXIT
+        * </p>
+        * Replace C function named "before_execmode_hook_irq" in eventhooks.c
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getBeforeExecutionModeIrq() {
+               AbsResourcesTRangeUpdate handler = new AbsResourcesTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+
+                               Long irqId = null;
+
+                               // According to Ltt, we should not draw anything if the channel
+                               // is the kernel one
+                               if (trcEvent.getChannelName().equals(
+                                               Channels.LTT_CHANNEL_KERNEL)) {
+                                       return false;
+                               } else {
+
+                                       if (trcEvent.getMarkerName().equals(
+                                                       Events.LTT_EVENT_IRQ_ENTRY.getInName())) {
+                                               irqId = getAFieldLong(trcEvent, traceSt,
+                                                               Fields.LTT_FIELD_IRQ_ID);
+                                       } else if (trcEvent.getMarkerName().equals(
+                                                       Events.LTT_EVENT_IRQ_EXIT.getInName())) {
+                                               long cpu = trcEvent.getCpuId();
+                                               irqId = traceSt.getCpu_states().get(cpu)
+                                                               .peekFromIrqStack();
+                                               if (irqId.equals(-1L)) {
+                                                       // nothing to update
+                                                       return false;
+                                               }
+                                       }
+
+
+                                       // softIrqId is the resource id here
+                                       TimeRangeEventResource localResource = resourcelist_obtain_irq(
+                                                       traceSt, irqId);
+
+                                       // If the resource is missing in the list, add it
+                                       if (localResource == null) {
+                                               TmfTimeRange timeRange = traceSt.getContext()
+                                                               .getTraceTimeWindow();
+                                               localResource = addLocalResource(timeRange
+                                                               .getStartTime().getValue(), timeRange
+                                                               .getEndTime().getValue(), traceSt.getTraceId(),
+                                                               ResourceTypes.IRQ, irqId, trcEvent
+                                                                               .getTimestamp().getValue());
+                                       }
+
+                                       // get the start time
+                                       long stime = localResource.getNext_good_time();
+
+                                       // Get the resource state mode
+                                       String irqStateMode = localResource.getStateMode(traceSt);
+
+                                       // Call the makeDraw function
+                                       makeDraw(traceSt, stime,
+                                                       trcEvent.getTimestamp().getValue(), localResource,
+                                                       params, irqStateMode);
+
+                                       // Call the globalProcessBeforeExecmode() after, as
+                                       // it is needed by all
+                                       // getBeforeExecmode*SOMETHING*()
+                                       globalProcessBeforeExecmode(trcEvent, traceSt);
+                               }
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_SOFT_IRQ_RAISE, LTT_EVENT_SOFT_IRQ_ENTRY,
+        * LTT_EVENT_SOFT_IRQ_EXIT,
+        * </p>
+        * Replace C function named "before_execmode_hook_soft_irq" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_SOFT_IRQ_ID
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getBeforeExecutionModeSoftIrq() {
+               AbsResourcesTRangeUpdate handler = new AbsResourcesTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+
+                               Long softIrqId = null;
+
+                               // According to Ltt, we should not draw anything if the channel
+                               // is the kernel one
+                               if (trcEvent.getChannelName().equals(
+                                               Channels.LTT_CHANNEL_KERNEL)) {
+                                       return false;
+                               } else {
+
+                                       if ((trcEvent.getMarkerName()
+                                                       .equals(Events.LTT_EVENT_SOFT_IRQ_RAISE.getInName()))
+                                                       || (trcEvent.getMarkerName()
+                                                                       .equals(Events.LTT_EVENT_SOFT_IRQ_ENTRY
+                                                                                       .getInName()))) {
+                                               softIrqId = getAFieldLong(trcEvent, traceSt,
+                                                               Fields.LTT_FIELD_SOFT_IRQ_ID);
+                                       } else if (trcEvent.getMarkerName().equals(
+                                                       Events.LTT_EVENT_SOFT_IRQ_EXIT.getInName())) {
+                                               long cpu = trcEvent.getCpuId();
+                                               softIrqId = traceSt.getCpu_states().get(cpu)
+                                                               .peekFromSoftIrqStack();
+                                               if (softIrqId < 0) {
+                                                       // nothing to update
+                                                       return false;
+                                               }
+                                       }
+
+                                       // Add the resource to the resource list
+                                       // softIrqId is the resource id here
+                                       TimeRangeEventResource localResource = resourcelist_obtain_soft_irq(
+                                                       traceSt, softIrqId);
+
+                                       // If the resource is missing in the list, add it
+                                       if (localResource == null) {
+                                               TmfTimeRange timeRange = traceSt.getContext()
+                                                               .getTraceTimeWindow();
+                                               localResource = addLocalResource(timeRange
+                                                               .getStartTime().getValue(), timeRange
+                                                               .getEndTime().getValue(), traceSt.getTraceId(),
+                                                               ResourceTypes.SOFT_IRQ, softIrqId, trcEvent
+                                                                               .getTimestamp().getValue());
+                                       }
+
+                                       // get the start time
+                                       long stime = localResource.getNext_good_time();
+
+                                       // Get the resource state mode
+                                       String softIrqStateMode = localResource
+                                                       .getStateMode(traceSt);
+
+                                       // Call the makeDraw function
+                                       makeDraw(traceSt, stime,
+                                                       trcEvent.getTimestamp().getValue(), localResource,
+                                                       params, softIrqStateMode);
+
+                                       // Call the globalProcessBeforeExecmode() after, as
+                                       // it is needed by all
+                                       // getBeforeExecmode*SOMETHING*()
+                                       globalProcessBeforeExecmode(trcEvent, traceSt);
+
+                               }
+
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_TRAP_ENTRY, LTT_EVENT_TRAP_EXIT,
+        * LTT_EVENT_PAGE_FAULT_ENTRY, LTT_EVENT_PAGE_FAULT_EXIT,
+        * LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY, LTT_EVENT_PAGE_FAULT_NOSEM_EXIT
+        * </p>
+        * Replace C function named "before_execmode_hook_trap" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_TRAP_ID
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getBeforeExecutionModeTrap() {
+               AbsResourcesTRangeUpdate handler = new AbsResourcesTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+
+                               Long trapId = null;
+
+                               // According to Ltt, we should not draw anything if the channel
+                               // is the kernel one
+                               if (trcEvent.getChannelName().equals(
+                                               Channels.LTT_CHANNEL_KERNEL)) {
+                                       return false;
+                               } else {
+
+                                       if ((trcEvent.getMarkerName()
+                                                       .equals(Events.LTT_EVENT_TRAP_ENTRY.getInName()))
+                                                       || (trcEvent.getMarkerName()
+                                                                       .equals(Events.LTT_EVENT_PAGE_FAULT_ENTRY
+                                                                                       .getInName()))
+                                                       || (trcEvent.getMarkerName()
+                                                                       .equals(Events.LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY
+                                                                                       .getInName()))) {
+                                               trapId = getAFieldLong(trcEvent, traceSt,
+                                                               Fields.LTT_FIELD_TRAP_ID);
+                                       } else if ((trcEvent.getMarkerName()
+                                                       .equals(Events.LTT_EVENT_TRAP_EXIT.getInName()))
+                                                       || (trcEvent.getMarkerName()
+                                                                       .equals(Events.LTT_EVENT_PAGE_FAULT_EXIT
+                                                                                       .getInName()))
+                                                       || (trcEvent.getMarkerName()
+                                                                       .equals(Events.LTT_EVENT_PAGE_FAULT_NOSEM_EXIT
+                                                                                       .getInName()))) {
+                                               long cpu = trcEvent.getCpuId();
+                                               trapId = traceSt.getCpu_states().get(cpu)
+                                                               .peekFromTrapStack();
+
+                                               if (trapId.equals(-1L)) {
+                                                       // Nothing to update
+                                                       return false;
+                                               }
+                                       } else {
+                                               return false;
+                                       }
+
+                                       // Add the resource to the resource list
+                                       // trapId is the resource id here
+                                       TimeRangeEventResource localResource = resourcelist_obtain_trap(
+                                                       traceSt, trapId);
+
+                                       // If the resource is missing in the list, add it
+                                       if (localResource == null) {
+                                               TmfTimeRange timeRange = traceSt.getContext()
+                                                               .getTraceTimeWindow();
+                                               localResource = addLocalResource(timeRange
+                                                               .getStartTime().getValue(), timeRange
+                                                               .getEndTime().getValue(), traceSt.getTraceId(),
+                                                               ResourceTypes.TRAP, trapId, trcEvent
+                                                                               .getTimestamp().getValue());
+                                       }
+
+                                       // Determine the trap state.
+                                       String trapStateMode = localResource.getStateMode(traceSt);
+
+                                       long stime = localResource.getNext_good_time();
+                                       makeDraw(traceSt, stime,
+                                                       trcEvent.getTimestamp().getValue(), localResource,
+                                                       params, trapStateMode);
+
+                                       // Call the globalProcessBeforeExecmode() after, as
+                                       // it is needed by all
+                                       // getBeforeExecmode*SOMETHING*()
+                                       globalProcessBeforeExecmode(trcEvent, traceSt);
+
+                               }
+
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles: LTT_EVENT_REQUEST_ISSUE, LTT_EVENT_REQUEST_COMPLETE
+        * </p>
+        * Replace C function named "before_bdev_event_hook" in eventhooks.c
+        * <p>
+        * Fields: LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION (?)
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getBeforeBdevEvent() {
+               AbsResourcesTRangeUpdate handler = new AbsResourcesTRangeUpdate() {
+
+                       // @Override
+                       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+                               Long major = getAFieldLong(trcEvent, traceSt,
+                                               Fields.LTT_FIELD_MAJOR);
+                               Long minor = getAFieldLong(trcEvent, traceSt,
+                                               Fields.LTT_FIELD_MINOR);
+                               // This is useless even in LTTv!
+                               // Long oper = getAFieldLong(trcEvent, traceSt,
+                               // Fields.LTT_FIELD_OPERATION);
+
+                               Long bdevId = getMkdevId(major, minor);
+
+                               // According to Lttv, bdevId (obtain from MKDEV macro) is
+                               // the id here
+                               TimeRangeEventResource localResource = resourcelist_obtain_bdev(
+                                               traceSt, bdevId);
+
+                               if (localResource == null) {
+                                       TmfTimeRange timeRange = traceSt.getContext()
+                                                       .getTraceTimeWindow();
+                                       localResource = addLocalResource(timeRange.getStartTime()
+                                                       .getValue(), timeRange.getEndTime().getValue(),
+                                                       traceSt.getTraceId(), ResourceTypes.BDEV, bdevId,
+                                                       trcEvent.getTimestamp().getValue());
+                               }
+
+                               // get the start time
+                               long stime = localResource.getNext_good_time();
+                               // Get the resource state mode
+                               String bdevStateMode = localResource.getStateMode(traceSt);
+                               // Call the makeDraw function
+                               makeDraw(traceSt, stime, trcEvent.getTimestamp().getValue(),
+                                               localResource, params, bdevStateMode);
+
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesEventToHandlerFactory.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesEventToHandlerFactory.java
new file mode 100644 (file)
index 0000000..234435c
--- /dev/null
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.resources.evProcessor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent;
+import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd;
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventToHandlerResolver;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+
+/**
+ * Builds a Map from string event name to a processing handler object, the
+ * processors implement the same interface to facilitate transparent methods
+ * call,
+ * 
+ * The map key String is the entry point of the raw events. Using a hash speeds
+ * up the resolution of the appropriate processor
+ * 
+ * @author alvaro
+ * 
+ */
+public class ResourcesEventToHandlerFactory extends AbsEventToHandlerResolver {
+       // ========================================================================
+       // Data
+       // =======================================================================
+       private final Map<String, ILttngEventProcessor> eventNametoBeforeProcessor = new HashMap<String, ILttngEventProcessor>();
+       private final Map<String, ILttngEventProcessor> eventNametoAfterProcessor = new HashMap<String, ILttngEventProcessor>();
+       private ResourcesFinishUpdateHandler finishProcessor = null;
+       private static ResourcesEventToHandlerFactory instance = null;
+       private ResourcesBeforeUpdateHandlers instantiateBeforeHandler = new ResourcesBeforeUpdateHandlers();
+       private ResourcesAfterUpdateHandlers instantiateAfterHandler = new ResourcesAfterUpdateHandlers();
+
+       private ResourcesEventToHandlerFactory() {
+               super();
+               // Create one instance of each individual event handler and add the
+               // instance to the map
+
+               // *** BEFORE HOOKS ***
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE.getInName(),
+                               instantiateBeforeHandler.getBeforeSchedChangeHandler());
+
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_ENTRY
+                               .getInName(), instantiateBeforeHandler
+                               .getBeforeExecutionModeTrap());
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_EXIT
+                               .getInName(), instantiateBeforeHandler
+                               .getBeforeExecutionModeTrap());
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PAGE_FAULT_ENTRY.getInName(),
+                               instantiateBeforeHandler.getBeforeExecutionModeTrap());
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PAGE_FAULT_EXIT.getInName(),
+                               instantiateBeforeHandler.getBeforeExecutionModeTrap());
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY
+                                               .getInName(), instantiateBeforeHandler
+                                               .getBeforeExecutionModeTrap());
+               eventNametoBeforeProcessor
+                               .put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_EXIT
+                                               .getInName(), instantiateBeforeHandler
+                                               .getBeforeExecutionModeTrap());
+
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_ENTRY
+                               .getInName(), instantiateBeforeHandler
+                               .getBeforeExecutionModeIrq());
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_EXIT
+                               .getInName(), instantiateBeforeHandler
+                               .getBeforeExecutionModeIrq());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SOFT_IRQ_RAISE.getInName(),
+                               instantiateBeforeHandler.getBeforeExecutionModeSoftIrq());
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SOFT_IRQ_ENTRY.getInName(),
+                               instantiateBeforeHandler.getBeforeExecutionModeSoftIrq());
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SOFT_IRQ_EXIT.getInName(),
+                               instantiateBeforeHandler.getBeforeExecutionModeSoftIrq());
+
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_REQUEST_ISSUE.getInName(),
+                               instantiateBeforeHandler.getBeforeBdevEvent());
+               eventNametoBeforeProcessor.put(
+                               StateStrings.Events.LTT_EVENT_REQUEST_COMPLETE.getInName(),
+                               instantiateBeforeHandler.getBeforeBdevEvent());
+
+               // *** AFTER HOOKS ***
+               eventNametoAfterProcessor.put(
+                               StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE.getInName(),
+                               instantiateAfterHandler.getAfterSchedChangeHandler());
+
+               finishProcessor = new ResourcesFinishUpdateHandler();
+       }
+
+       /**
+     * 
+     */
+       public static AbsEventToHandlerResolver getInstance() {
+               if (instance == null) {
+                       instance = new ResourcesEventToHandlerFactory();
+               }
+               return instance;
+       }
+
+       @Override
+       public ILttngEventProcessor getAfterProcessor(String eventType) {
+               return eventNametoAfterProcessor.get(eventType);
+       }
+
+       @Override
+       public ILttngEventProcessor getBeforeProcessor(String eventType) {
+               return eventNametoBeforeProcessor.get(eventType);
+       }
+
+       @Override
+       public ILttngEventProcessor getfinishProcessor() {
+               return finishProcessor;
+       }
+
+       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+               if (trcEvent instanceof LttngSyntheticEvent) {
+
+                       LttngSyntheticEvent synEvent = (LttngSyntheticEvent) trcEvent;
+                       String eventType = synEvent.getMarkerName();
+                       ILttngEventProcessor processor = null;
+                       if (synEvent.getSynType() == SequenceInd.BEFORE) {
+                               processor = getBeforeProcessor(eventType);
+                       }
+
+                       if (synEvent.getSynType() == SequenceInd.AFTER) {
+                               processor = getAfterProcessor(eventType);
+                       }
+
+                       if (synEvent.getSynType() == SequenceInd.ENDREQ) {
+                               processor = getfinishProcessor();
+                       }
+
+                       if (processor != null) {
+                               processor.process(trcEvent, traceSt);
+                       }
+               }
+               return false;
+       }
+
+       @Override
+       public ILttngEventProcessor getStateUpdaterProcessor(String eventType) {
+               return null;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesFinishUpdateHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/evProcessor/ResourcesFinishUpdateHandler.java
new file mode 100644 (file)
index 0000000..76743e6
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.resources.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Events;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventResource;
+import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
+
+/**
+ * Creates specific finish state data request
+ * 
+ * @author alvaro
+ * 
+ */
+public class ResourcesFinishUpdateHandler extends
+ AbsResourcesTRangeUpdate
+               implements ILttngEventProcessor {
+
+       public Events getEventHandleType() {
+               // No specific event
+               return null;
+       }
+
+       public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
+               // Draw a last known state to the end of the trace
+               TmfTimestamp endReqTime = traceSt.getContext()
+                               .getTraceTimeWindow().getEndTime();
+
+               TraceDebug.debug("Number of localResources: "
+                               + resContainer.readItems().length);
+
+               // for each existing resource
+               for (TimeRangeEventResource localResource : resContainer
+                               .readItems()) {
+
+                       // get the start time
+                       long stime = localResource.getNext_good_time();
+
+                       // Get the resource state mode
+                       String stateMode = localResource.getStateMode(traceSt);
+
+                       // Insert an instance from previous time to end request time with
+                       // the current state
+                       makeDraw(traceSt, stime, endReqTime.getValue(),
+                                       localResource, params, stateMode);
+               }
+
+               return false;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/messages.properties b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/messages.properties
new file mode 100644 (file)
index 0000000..032d20a
--- /dev/null
@@ -0,0 +1,26 @@
+ResourcesView.Action.Filter=Filter\r
+ResourcesView.Action.Filter.ToolTip=Resource Filter options\r
+ResourcesView.Action.Legend=Legend\r
+ResourcesView.Action.Legend.ToolTip=Show Legend\r
+ResourcesView.Action.LoadData=LoadData\r
+ResourcesView.Action.LoadData.ToolTip=Load data from external plug-in\r
+ResourcesView.Action.NextEvent=NextEv\r
+ResourcesView.Action.NextEvent.Tooltip=Next Event\r
+ResourcesView.Action.NextResource=NextResource\r
+ResourcesView.Action.NextResource.ToolTip=Select Next Resource\r
+ResourcesView.Action.PrevEvent=PrevEv\r
+ResourcesView.Action.PrevEvent.Tooltip=Previous Event\r
+ResourcesView.Action.PreviousResource=PreviousResource\r
+ResourcesView.Action.PreviousResource.Tooltip=Select Previous Resource\r
+ResourcesView.Action.Reset=Reset\r
+ResourcesView.Action.Reset.ToolTip=Reset the Time Scale to Default\r
+ResourcesView.Action.Synchronize=Synchronise\r
+ResourcesView.Action.Synchronize.ToolTip=Synchronise by listening to external API selection calls\r
+ResourcesView.Action.ZoomIn=Zoom In\r
+ResourcesView.Action.ZoomIn.Tooltip=Zoom In\r
+ResourcesView.Action.ZoomOut=Zoom Out\r
+ResourcesView.Action.ZoomOut.tooltip=Zoom Out\r
+ResourcesView.Action.ZoomFilter=Zoom Filter\r
+ResourcesView.Action.ZoomFilter.tooltip=Display elements with events within the zoomed time window\r
+ResourcesView.msgSlogan=Resources View\r
+ResourcesView.tmf.UI=org.eclipse.linuxtools.tmf.ui\r
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/model/ResourceContainer.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/model/ResourceContainer.java
new file mode 100644 (file)
index 0000000..4728764
--- /dev/null
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.resources.model;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.linuxtools.lttng.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventResource;
+import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventResource.ResourceTypes;
+
+/**
+ * Common location to allocate the resources in use by the resource view
+ * 
+ * @author alvaro
+ * 
+ */
+public class ResourceContainer implements ItemContainer<TimeRangeEventResource> {
+       // ========================================================================
+       // Data
+       // ========================================================================
+       private final HashMap<ResourceKey, TimeRangeEventResource> resources = new HashMap<ResourceKey, TimeRangeEventResource>();
+       private static Integer uniqueId = 0;
+       
+       
+       // ========================================================================
+       // Constructor
+       // ========================================================================
+       /**
+        * Package level constructor
+        */
+       public ResourceContainer() { }
+       
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.linuxtools.lttng.ui.views.resources.model.ItemContainer#addItem
+        * (org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.
+        * ITmfTimeAnalysisEntry)
+        */
+       public void addItem(TimeRangeEventResource newItem) {
+               if (newItem != null) {
+                   resources.put( new ResourceKey(newItem),newItem);
+               }
+       }
+       
+       // ========================================================================
+       // Methods
+       // ========================================================================
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.ui.views.resources.model.ItemContainer#getUniqueId()
+        */
+    public Integer getUniqueId() {
+        return uniqueId++;
+    }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.ui.views.resources.model.ItemContainer#readItems()
+        */
+       public TimeRangeEventResource[] readItems() {
+               return resources.values().toArray(
+                               new TimeRangeEventResource[resources.size()]);
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.ui.views.resources.model.ItemContainer#clearChildren()
+        */
+       public void clearChildren() {
+           TimeRangeEventResource newRes = null;
+        Iterator<ResourceKey> iterator = resources.keySet().iterator();
+        
+        while (iterator.hasNext()) {
+                       newRes = resources.get(iterator.next());
+                       newRes.reset();
+        }
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.ui.views.resources.model.ItemContainer#clearItems()
+        */
+       public void clearItems() {
+               resources.clear();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.ui.views.resources.model.ItemContainer#removeItems(java.lang.String)
+        */
+       public void removeItems(String traceId) {
+           ResourceKey newKey = null;
+
+           Iterator<ResourceKey> iterator = resources.keySet().iterator();
+        while (iterator.hasNext()) {
+            newKey = iterator.next();
+            
+            if (resources.get(newKey).getTraceId().equals(traceId)) {
+                resources.remove(newKey);
+            }
+        }
+       }
+       
+       
+       /**
+        * Search by keys (resourceId, traceId and type)
+        * <p>
+        * 
+        * A match is returned if the three arguments received match an entry
+        * Otherwise null is returned
+        * 
+        * @param searchedId
+        *            The ressourceId we are looking for
+        * @param searchedType
+        *            The ressourceType we are looking for
+        * @param searchedTraceId
+        *            The traceId (trace name?) we are looking for
+        * 
+        * @return TimeRangeEventResource
+        */
+    public TimeRangeEventResource findItem(Long searchedId, ResourceTypes searchedType, String searchedTraceId) {
+               // Get the EventResource associated to a key we create here
+        TimeRangeEventResource foundResource = resources.get( new ResourceKey(searchedId, searchedTraceId, searchedType) );
+        
+        return foundResource;
+    }
+}
+
+class ResourceKey {
+    
+    private TimeRangeEventResource valueRef = null;
+    
+    private Long       resourceId = null;
+    private String        traceId = null;
+    private ResourceTypes type = null;
+    
+    @SuppressWarnings("unused")
+    private ResourceKey() { }
+    
+    public ResourceKey(TimeRangeEventResource newRef) {
+        valueRef = newRef;
+    }
+    
+    public ResourceKey(Long newId, String newTraceId, ResourceTypes newType) {
+        resourceId = newId;
+        traceId = newTraceId;
+        type = newType;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        boolean isSame = false;
+        
+        if ( obj instanceof ResourceKey ) {
+               if ( valueRef != null )  {
+                   if ( (  ((ResourceKey)obj).getResourceId().equals(valueRef.getResourceId()) ) &&
+                        (  ((ResourceKey)obj).getTraceId().equals(valueRef.getTraceId()) ) &&
+                        (  ((ResourceKey)obj).getType().equals(valueRef.getType()) ) )
+                   {
+                       isSame = true;
+                   }
+               }
+               else {
+                       if ( (  ((ResourceKey)obj).getResourceId().equals(this.resourceId)) &&
+                        (  ((ResourceKey)obj).getTraceId().equals(this.traceId)) &&
+                        (  ((ResourceKey)obj).getType().equals(this.type)) )
+                   {
+                       isSame = true;
+                   }
+               }
+        }
+        else {
+               TraceDebug.debug("ERROR : The given key is not of the type ProcessKey!" + obj.getClass().toString());
+        }
+        
+        return isSame;
+    }
+    
+    // *** WARNING : Everything in there work because the check "valueRef != null" is the same for ALL getter
+    // Do NOT change this check without checking.
+    public Long getResourceId() {
+        if ( valueRef != null ) {
+            return valueRef.getResourceId();
+        }
+        else {
+            return resourceId;
+        }
+    }
+
+    public String getTraceId() {
+        if ( valueRef != null ) {
+            return valueRef.getTraceId();
+        }
+        else {
+            return traceId;
+        }
+    }
+
+    public ResourceTypes getType() {
+        if ( valueRef != null ) {
+            return valueRef.getType();
+        }
+        else {
+            return type;
+        }
+    }
+
+    @Override
+    public int hashCode() { 
+        return this.toString().hashCode();
+    }
+    
+    
+    @Override
+    public String toString() {
+        if ( valueRef != null ) {
+            return (valueRef.getResourceId().toString() + ":" + valueRef.getTraceId().toString() + ":" + valueRef.getType().toString());
+        }
+        return (resourceId + ":" + traceId + ":" + type);
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/model/ResourceModelFactory.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/resources/model/ResourceModelFactory.java
new file mode 100644 (file)
index 0000000..496f669
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.resources.model;
+
+import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
+
+/**
+ * Instantiates the entry point classes to build the data model for this view
+ * 
+ * @author alvaro
+ * 
+ */
+public class ResourceModelFactory {
+       // ========================================================================
+       // Data
+       // ========================================================================
+       private static ResourceContainer resContainer = null;
+       private static ParamsUpdater updater = null;
+       
+       
+       // ========================================================================
+       // Methods
+       // ========================================================================
+       /**
+        * Get Process data container
+        * @return
+        */
+       public static ResourceContainer getResourceContainer() {
+               if (resContainer == null) {
+                       resContainer = new ResourceContainer();
+               }
+               return resContainer;
+       }
+       
+       
+       public static ParamsUpdater getParamsUpdater() {
+               if (updater == null) {
+                       updater = new ParamsUpdater();
+               }
+               return updater;
+       }
+       
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/StatisticsView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/StatisticsView.java
new file mode 100644 (file)
index 0000000..ccce8ea
--- /dev/null
@@ -0,0 +1,655 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin    (dhaemon@gmail.com)    - Implementation
+ *   Francois Chouinard (fchouinard@gmail.com) - Initial API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.statistics;
+
+import java.text.DecimalFormat;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventToHandlerResolver;
+import org.eclipse.linuxtools.lttng.ui.TraceDebug;
+import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer;
+import org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView;
+import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor.StatsTimeCountHandlerFactory;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeNode;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeRootFactory;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
+import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal;
+import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * <b><u>StatisticsView</u></b>
+ * <p>
+ * The Statistics View displays statistics for traces.
+ * 
+ * It is implemented according to the MVC pattern. - The model is a
+ * StatisticsTreeNode built by the State Manager. - The view is built with a
+ * TreeViewer. - The controller that keeps model and view synchronised is an
+ * observer of the model.
+ */
+public class StatisticsView extends AbsTimeUpdateView {
+       public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.statistics";
+       private TreeViewer treeViewer;
+
+       // Table column names
+       private final String LEVEL_COLUMN = "Level";
+       private final String EVENTS_COUNT_COLUMN = "Number of Events";
+       private final String CPU_TIME_COLUMN = "CPU Time";
+       private final String CUMULATIVE_CPU_TIME_COLUMN = "Cumulative CPU Time";
+       private final String ELAPSED_TIME_COLUMN = "Elapsed Time";
+
+       // Table column tooltips
+       private final String LEVEL_COLUMN_TIP = "Level at which statistics apply.";
+       private final String EVENTS_COUNT_COLUMN_TIP = "Total amount of events that are tied to given resource.";
+       private final String CPU_TIME_COLUMN_TIP = "Total amount of time the CPU was used excluding wait times(I/O, etc.) at that level.";
+       private final String CUMULATIVE_CPU_TIME_COLUMN_TIP = "Total amount of time between the first and last event excluding wait times in a level.";
+       private final String ELAPSED_TIME_COLUMN_TIP = "Total amount of time the CPU was used including wait times(I/O, etc.) at that level.";
+
+       // Level for which statistics should not be displayed.
+       private Set<String> folderLevels = new HashSet<String>(Arrays
+                       .asList(new String[] { "Event Types", "Modes", "Submodes", "CPUs",
+                                       "Processes", "Functions" }));
+
+       // Levels for which sub-levels should not contain time-related statistics.
+       private Set<String> levelsWithEmptyTime = new HashSet<String>(Arrays
+                       .asList(new String[] { "Event Types" }));
+
+       private DecimalFormat decimalFormat = new DecimalFormat("0.#########");
+       private Cursor fwaitCursor = null;
+
+       // Used to draw bar charts in columns.
+       private interface ColumnPercentageProvider {
+               public double getPercentage(StatisticsTreeNode node);
+       }
+
+       /**
+        * Contains all the information necessary to build a column of the table.
+        */
+       private class ColumnData {
+               // Name of the column.
+               public final String header;
+               // Width of the column.
+               public final int width;
+               // Alignment of the column.
+               public final int alignment;
+               // Tooltip of the column.
+               public final String tooltip;
+               // Adapts a StatisticsTreeNode into the content of it's corresponding
+               // cell for that column.
+               public final ColumnLabelProvider labelProvider;
+               // Used to sort elements of this column. Can be null.
+               public final ViewerComparator comparator;
+               // Used to draw bar charts in this column. Can be null.
+               public final ColumnPercentageProvider percentageProvider;
+
+               public ColumnData(String h, int w, int a, String t,
+                               ColumnLabelProvider l, ViewerComparator c,
+                               ColumnPercentageProvider p) {
+                       header = h;
+                       width = w;
+                       alignment = a;
+                       tooltip = t;
+                       labelProvider = l;
+                       comparator = c;
+                       percentageProvider = p;
+               }
+       };
+
+       // List that will be used to create the table.
+       private ColumnData[] columnDataList = new ColumnData[] {
+                       new ColumnData(LEVEL_COLUMN, 200, SWT.LEFT, LEVEL_COLUMN_TIP,
+                                       new ColumnLabelProvider() {
+                                               @Override
+                                               public String getText(Object element) {
+                                                       return ((StatisticsTreeNode) element).getKey();
+                                               }
+
+                                               @Override
+                                               public Image getImage(Object element) {
+                                                       StatisticsTreeNode node = (StatisticsTreeNode) element;
+                                                       if (folderLevels.contains(node.getKey())) {
+                                                               return PlatformUI.getWorkbench()
+                                                                               .getSharedImages().getImage(
+                                                                                               ISharedImages.IMG_OBJ_FOLDER);
+                                                       } else {
+                                                               return PlatformUI.getWorkbench()
+                                                                               .getSharedImages().getImage(
+                                                                                               ISharedImages.IMG_OBJ_ELEMENT);
+                                                       }
+                                               }
+                                       }, new ViewerComparator() {
+                                               @Override
+                                               public int compare(Viewer viewer, Object e1, Object e2) {
+                                                       StatisticsTreeNode n1 = (StatisticsTreeNode) e1;
+                                                       StatisticsTreeNode n2 = (StatisticsTreeNode) e2;
+
+                                                       return n1.getKey().compareTo(n2.getKey());
+                                               }
+                                       }, null),
+                       new ColumnData(EVENTS_COUNT_COLUMN, 125, SWT.LEFT,
+                                       EVENTS_COUNT_COLUMN_TIP, new ColumnLabelProvider() {
+                                               @Override
+                                               public String getText(Object element) {
+                                                       StatisticsTreeNode node = (StatisticsTreeNode) element;
+                                                       if (!folderLevels.contains(node.getKey())) {
+                                                               return Long.toString(node.getValue().nbEvents);
+                                                       } else {
+                                                               return "";
+                                                       }
+                                               }
+                                       }, new ViewerComparator() {
+                                               @Override
+                                               public int compare(Viewer viewer, Object e1, Object e2) {
+                                                       StatisticsTreeNode n1 = (StatisticsTreeNode) e1;
+                                                       StatisticsTreeNode n2 = (StatisticsTreeNode) e2;
+
+                                                       return (int) (n1.getValue().nbEvents - n2
+                                                                       .getValue().nbEvents);
+                                               }
+                                       }, new ColumnPercentageProvider() {
+                                               public double getPercentage(StatisticsTreeNode node) {
+                                                       StatisticsTreeNode parent = node;
+                                                       do {
+                                                               parent = parent.getParent();
+                                                       } while (parent != null
+                                                                       && parent.getValue().nbEvents == 0);
+
+                                                       if (parent == null) {
+                                                               return 0;
+                                                       } else {
+                                                               return (double) node.getValue().nbEvents
+                                                                               / parent.getValue().nbEvents;
+                                                       }
+                                               }
+                                       }),
+                       new ColumnData(CPU_TIME_COLUMN, 125, SWT.LEFT, CPU_TIME_COLUMN_TIP,
+                                       new ColumnLabelProvider() {
+                                               @Override
+                                               public String getText(Object element) {
+                                                       StatisticsTreeNode node = (StatisticsTreeNode) element;
+
+                                                       if (folderLevels.contains(node.getKey())) {
+                                                               return "";
+                                                       } else if (node.getParent() != null
+                                                                       && levelsWithEmptyTime.contains(node
+                                                                                       .getParent().getKey())) {
+                                                               return "";
+                                                       } else {
+                                                               return decimalFormat
+                                                                               .format(node.getValue().cpuTime
+                                                                                               / Math.pow(10, 9));
+                                                       }
+                                               }
+                                       }, null, null),
+                       new ColumnData(CUMULATIVE_CPU_TIME_COLUMN, 155, SWT.LEFT,
+                                       CUMULATIVE_CPU_TIME_COLUMN_TIP, new ColumnLabelProvider() {
+                                               @Override
+                                               public String getText(Object element) {
+                                                       StatisticsTreeNode node = (StatisticsTreeNode) element;
+                                                       if (folderLevels.contains(node.getKey())) {
+                                                               return "";
+                                                       } else if (node.getParent() != null
+                                                                       && levelsWithEmptyTime.contains(node
+                                                                                       .getParent().getKey())) {
+                                                               return "";
+                                                       } else {
+                                                               return decimalFormat
+                                                                               .format(node.getValue().cumulativeCpuTime
+                                                                                               / Math.pow(10, 9));
+                                                       }
+                                               }
+                                       }, null, null),
+                       new ColumnData(ELAPSED_TIME_COLUMN, 100, SWT.LEFT,
+                                       ELAPSED_TIME_COLUMN_TIP, new ColumnLabelProvider() {
+                                               @Override
+                                               public String getText(Object element) {
+                                                       StatisticsTreeNode node = (StatisticsTreeNode) element;
+                                                       if (folderLevels.contains(node.getKey())) {
+                                                               return "";
+                                                       } else if (node.getParent() != null
+                                                                       && levelsWithEmptyTime.contains(node
+                                                                                       .getParent().getKey())) {
+                                                               return "";
+                                                       } else {
+                                                               return decimalFormat
+                                                                               .format(node.getValue().elapsedTime
+                                                                                               / Math.pow(10, 9));
+                                                       }
+                                               }
+                                       }, null, null) };
+
+       /**
+        * Adapter TreeViewers can use to interact with StatisticsTreeNode objects.
+        * 
+        * @see org.eclipse.jface.viewers.ITreeContentProvider
+        */
+       class TreeContentProvider implements ITreeContentProvider {
+               /*
+                * (non-Javadoc)
+                * 
+                * @see
+                * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang
+                * .Object)
+                */
+               public Object[] getChildren(Object parentElement) {
+                       return ((StatisticsTreeNode) parentElement).getChildren().toArray();
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see
+                * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang
+                * .Object)
+                */
+               public Object getParent(Object element) {
+                       return ((StatisticsTreeNode) element).getParent();
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see
+                * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang
+                * .Object)
+                */
+               public boolean hasChildren(Object element) {
+                       return ((StatisticsTreeNode) element).hasChildren();
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see
+                * org.eclipse.jface.viewers.IStructuredContentProvider#getElements(
+                * java.lang.Object)
+                */
+               public Object[] getElements(Object inputElement) {
+                       return getChildren(inputElement);
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+                */
+               public void dispose() {
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see
+                * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse
+                * .jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+                */
+               // @Override
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               }
+       }
+
+       public StatisticsView(String viewName) {
+               super(viewName);
+       }
+
+       public StatisticsView() {
+               this("StatisticsView");
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets
+        * .Composite)
+        */
+       @Override
+       public void createPartControl(Composite parent) {
+               parent.setLayout(new FillLayout());
+
+               treeViewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL
+                               | SWT.V_SCROLL);
+               treeViewer.setContentProvider(new TreeContentProvider());
+               treeViewer.getTree().setHeaderVisible(true);
+               treeViewer.setUseHashlookup(true);
+
+               for (final ColumnData columnData : columnDataList) {
+                       final TreeViewerColumn treeColumn = new TreeViewerColumn(
+                                       treeViewer, columnData.alignment);
+                       treeColumn.getColumn().setText(columnData.header);
+                       treeColumn.getColumn().setWidth(columnData.width);
+                       treeColumn.getColumn().setToolTipText(columnData.tooltip);
+                       if (columnData.comparator != null) {
+                               treeColumn.getColumn().addSelectionListener(
+                                               new SelectionAdapter() {
+                                                       @Override
+                                                       public void widgetSelected(SelectionEvent e) {
+                                                               if (treeViewer.getTree().getSortDirection() == SWT.UP
+                                                                               || treeViewer.getTree().getSortColumn() != treeColumn
+                                                                                               .getColumn()) {
+                                                                       treeViewer
+                                                                                       .setComparator(columnData.comparator);
+                                                                       treeViewer.getTree().setSortDirection(
+                                                                                       SWT.DOWN);
+                                                               } else {
+                                                                       treeViewer
+                                                                                       .setComparator(new ViewerComparator() {
+                                                                                               @Override
+                                                                                               public int compare(
+                                                                                                               Viewer viewer,
+                                                                                                               Object e1, Object e2) {
+                                                                                                       return -1
+                                                                                                                       * columnData.comparator
+                                                                                                                                       .compare(
+                                                                                                                                                       viewer,
+                                                                                                                                                       e1,
+                                                                                                                                                       e2);
+                                                                                               }
+                                                                                       });
+                                                                       treeViewer.getTree().setSortDirection(
+                                                                                       SWT.UP);
+                                                               }
+                                                               treeViewer.getTree().setSortColumn(
+                                                                               treeColumn.getColumn());
+                                                       }
+                                               });
+                       }
+                       treeColumn.setLabelProvider(columnData.labelProvider);
+               }
+
+               // Handler that will draw the bar charts.
+               treeViewer.getTree().addListener(SWT.EraseItem, new Listener() {
+                       // @Override
+                       public void handleEvent(Event event) {
+                               if (columnDataList[event.index].percentageProvider != null) {
+                                       StatisticsTreeNode node = (StatisticsTreeNode) event.item
+                                                       .getData();
+
+                                       double percentage = columnDataList[event.index].percentageProvider
+                                                       .getPercentage(node);
+                                       if (percentage == 0) {
+                                               return;
+                                       }
+
+                                       if ((event.detail & SWT.SELECTED) > 0) {
+                                               Color oldForeground = event.gc.getForeground();
+                                               event.gc.setForeground(event.item.getDisplay()
+                                                               .getSystemColor(SWT.COLOR_LIST_SELECTION));
+                                               event.gc.fillRectangle(event.x, event.y, event.width,
+                                                               event.height);
+                                               event.gc.setForeground(oldForeground);
+                                               event.detail &= ~SWT.SELECTED;
+                                       }
+
+                                       int barWidth = (int) ((treeViewer.getTree().getColumn(1)
+                                                       .getWidth() - 8) * percentage);
+                                       int oldAlpha = event.gc.getAlpha();
+                                       Color oldForeground = event.gc.getForeground();
+                                       Color oldBackground = event.gc.getBackground();
+                                       event.gc.setAlpha(64);
+                                       event.gc.setForeground(event.item.getDisplay()
+                                                       .getSystemColor(SWT.COLOR_BLUE));
+                                       event.gc.setBackground(event.item.getDisplay()
+                                                       .getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+                                       event.gc.fillGradientRectangle(event.x, event.y, barWidth,
+                                                       event.height, true);
+                                       event.gc.drawRectangle(event.x, event.y, barWidth,
+                                                       event.height);
+                                       event.gc.setForeground(oldForeground);
+                                       event.gc.setBackground(oldBackground);
+                                       event.gc.setAlpha(oldAlpha);
+                                       event.detail &= ~SWT.BACKGROUND;
+                               }
+                       }
+               });
+
+               treeViewer.setComparator(columnDataList[0].comparator);
+               treeViewer.getTree().setSortColumn(treeViewer.getTree().getColumn(0));
+               treeViewer.getTree().setSortDirection(SWT.DOWN);
+
+               // Read current data if any available
+               TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment();
+               if (experiment != null) {
+                       requestData(experiment);
+               } else {
+                       TraceDebug.debug("No selected experiment information available");
+               }
+       }
+
+       @Override
+       public void dispose() {
+               super.dispose();
+               if (fwaitCursor != null) {
+                       fwaitCursor.dispose();
+               }
+
+               // clean the model
+               StatisticsTreeRootFactory.removeAll();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
+        */
+       @Override
+       public void setFocus() {
+               treeViewer.getTree().setFocus();
+       }
+
+
+       /**
+        * @return
+        */
+       public AbsEventToHandlerResolver getEventProcessor() {
+               return StatsTimeCountHandlerFactory.getInstance();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#waitCursor
+        * (boolean)
+        */
+       protected void waitCursor(final boolean waitInd) {
+               if (treeViewer == null) {
+                       return;
+               }
+
+               Display display = treeViewer.getControl().getDisplay();
+               if (fwaitCursor == null) {
+                       fwaitCursor = new Cursor(display, SWT.CURSOR_WAIT);
+               }
+
+               // Perform the updates on the UI thread
+               display.asyncExec(new Runnable() {
+                       public void run() {
+                               Cursor cursor = null; /* indicates default */
+                               if (waitInd) {
+                                       cursor = fwaitCursor;
+                               }
+                               treeViewer.getControl().setCursor(cursor);
+                       }
+               });
+       }
+
+       @Override
+       public void ModelUpdatePrep(TmfTimeRange timeRange, boolean clearAllData) {
+               Object input = treeViewer.getInput();
+               if (input != null && input instanceof StatisticsTreeNode) {
+                       ((StatisticsTreeNode) input).reset();
+                       treeViewer.getTree().getDisplay().asyncExec(new Runnable() {
+                               // @Override
+                               public void run() {
+                                       treeViewer.refresh();
+                               }
+                       });
+               }
+       }
+
+       @Override
+       public void modelInputChanged(ILttngSyntEventRequest request, boolean complete) {
+               treeViewer.getTree().getDisplay().asyncExec(new Runnable() {
+                       // @Override
+                       public void run() {
+                               treeViewer.refresh();
+                       }
+               });
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * modelIncomplete
+        * (org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest)
+        */
+       @Override
+       public void modelIncomplete(ILttngSyntEventRequest request) {
+               Object input = treeViewer.getInput();
+               if (input != null && input instanceof StatisticsTreeNode) {
+                       // The data from this experiment is invalid and shall be removed to
+                       // refresh upon next selection
+                       String name = ((StatisticsTreeNode) input).getKey();
+                       StatisticsTreeRootFactory.removeStatTreeRoot(name);
+               }
+       }
+
+       /**
+        * @param signal
+        */
+       @TmfSignalHandler
+       public void experimentSelected(TmfExperimentSelectedSignal<? extends TmfEvent> signal) {
+               if (signal != null) {
+                       TmfExperiment<?> experiment = signal.getExperiment();
+                       String experimentName =  experiment.getName();
+
+                       if (StatisticsTreeRootFactory.containsTreeRoot(experimentName)) {
+                               // The experiment root is already present
+                               StatisticsTreeNode experimentTreeNode = StatisticsTreeRootFactory.getStatTreeRoot(experimentName);
+
+                               ITmfTrace[] traces = experiment.getTraces();
+
+                               // check if there is partial data loaded in the experiment
+                               int numTraces = experiment.getTraces().length;
+                               int numNodeTraces = experimentTreeNode.getNbChildren();
+
+                               if (numTraces == numNodeTraces) {
+                                       boolean same = true;
+                                       // Detect if the experiment contains the same traces as when
+                                       // previously selected
+                                       for (int i = 0; i < numTraces; i++) {
+                                               String traceName = traces[i].getName();
+                                               if (!experimentTreeNode.containsChild(traceName)) {
+                                                       same = false;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (same) {
+                                               // no need to reload data, all traces are already loaded
+                                               treeViewer.setInput(experimentTreeNode);
+                                               return;
+                                       }
+                               }
+                       }
+
+                       // if the data is not available or has changed, reload it
+                       requestData(experiment);
+               }
+       }
+
+       /**
+        * @param experiment
+        */
+       private void requestData(TmfExperiment<?> experiment) {
+               if (experiment != null) {
+                       StatisticsTreeNode treeModelRoot = StatisticsTreeRootFactory.getStatTreeRoot(experiment.getName());
+
+                       // if the model has contents, clear to start over
+                       if (treeModelRoot.hasChildren()) {
+                               treeModelRoot.reset();
+                       }
+
+                       // set input to a clean data model
+                       treeViewer.setInput(treeModelRoot);
+                       TmfTimeRange experimentTRange = experiment.getTimeRange();
+
+                       // send the initial request, to start filling up model
+                       dataRequest(experimentTRange, experimentTRange, true);
+               } else {
+                       TraceDebug.debug("No selected experiment information available");
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#displayModel
+        * (org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.
+        * ITmfTimeAnalysisEntry[], long, long, boolean, long, long,
+        * java.lang.Object)
+        */
+       @Override
+       protected void displayModel(ITmfTimeAnalysisEntry[] items, long startBoundTime, long endBoundTime,
+                       boolean updateTimeBounds, long startVisibleWindow, long endVisibleWindow, Object source) {
+               // No applicable to statistics view
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
+        * getParamsUpdater()
+        */
+       @Override
+       protected ParamsUpdater getParamsUpdater() {
+               // Not applicable to statistics view
+               return null;
+       }
+
+       @Override
+       protected ItemContainer<?> getItemContainer() {
+               // Not applicable to statistics view
+               return null;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/AbstractStatsEventHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/AbstractStatsEventHandler.java
new file mode 100644 (file)
index 0000000..91a0236
--- /dev/null
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin     (dhaemon@gmail.com)  - Implementation for stats
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Events;
+import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode;
+import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngProcessState;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeRootFactory;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeNode;
+
+abstract class AbstractStatsEventHandler implements ILttngEventProcessor {
+       private Events eventType;
+       
+       public AbstractStatsEventHandler(Events eventType) {
+               super();
+               this.eventType = eventType;
+       }
+
+       /**
+        * @return root of of the tree for this experiment.
+        */
+       protected StatisticsTreeNode getStatisticsTree(LttngTraceState trcState) {
+               String experimentName = trcState.getContext().getExperimentName();
+               StatisticsTreeNode tree = StatisticsTreeRootFactory.getStatTreeRoot(experimentName);
+               return tree;
+       }
+       
+       /**
+        * @return list of paths that should be updated for this event.
+        */
+       protected String[][] getRelevantPaths(LttngEvent event,
+                       LttngTraceState traceState) {
+               String trace = traceState.getContext().getTraceId();
+               
+               Long cpu = event.getCpuId();
+               
+               LttngProcessState process = traceState.getRunning_process().get(
+                               cpu);
+               
+               String processName = getPocessName(process);
+                               
+               String mode = process.getState().getExec_mode().getInName();
+               
+               String submode = process.getState().getExec_submode();
+               
+               Long function = process.getCurrent_function();
+               
+               // String type = event.getType().getTypeId();
+
+               String[][] paths = {
+                               {trace},
+                               {trace, "Modes", mode},
+                               {trace, "Modes", mode, "Submodes", submode},
+                               {trace, "Processes", processName},
+                               {trace, "Processes", processName, "CPUs", cpu.toString()},
+                               {trace, "Processes", processName, "CPUs", cpu.toString(), "Functions", function.toString()},
+                               {trace, "Processes", processName, "CPUs", cpu.toString(), "Modes", mode},
+                               {trace, "Processes", processName, "CPUs", cpu.toString(), "Modes", mode, "Submodes", submode},
+                               {trace, "Processes", processName, "Modes", mode},
+                               {trace, "Processes", processName, "Modes", mode, "Submodes", submode},
+                               {trace, "CPUs", cpu.toString()},
+                               {trace, "CPUs", cpu.toString(), "Modes", mode},
+                               {trace, "CPUs", cpu.toString(), "Modes", mode, "Submodes", submode},
+               };
+               return paths;
+       }
+       
+       /**
+        * @return list of event types paths that should be updated for this event.
+        */
+       protected String[][] getRelevantEventTypesPaths(LttngEvent event,
+                       LttngTraceState traceState) {
+               String trace = traceState.getContext().getTraceId();
+               
+               Long cpu = event.getCpuId();
+               
+               LttngProcessState process = traceState.getRunning_process().get(
+                               cpu);
+               
+               String processName = getPocessName(process);
+                               
+               String mode = process.getState().getExec_mode().getInName();
+               
+               String submode = process.getState().getExec_submode();
+               
+               Long function = process.getCurrent_function();
+               
+               String type = event.getType().getTypeId();
+
+               String[][] paths = {
+                               {trace, "Event Types", type},
+                               {trace, "Modes", mode, "Event Types", type},
+                               {trace, "Modes", mode, "Submodes", submode, "Event Types", type},
+                               {trace, "Processes", processName, "Event Types", type},
+                               {trace, "Processes", processName, "CPUs", cpu.toString(), "Event Types", type},
+                               {trace, "Processes", processName, "CPUs", cpu.toString(), "Functions", function.toString(), "Event Types", type},
+                               {trace, "Processes", processName, "CPUs", cpu.toString(), "Modes", mode, "Event Types", type},
+                               {trace, "Processes", processName, "CPUs", cpu.toString(), "Modes", mode, "Submodes", submode, "Event Types", type},
+                               {trace, "Processes", processName, "Modes", mode, "Event Types", type},
+                               {trace, "Processes", processName, "Modes", mode, "Submodes", submode, "Event Types", type},
+                               {trace, "CPUs", cpu.toString(), "Event Types", type},
+                               {trace, "CPUs", cpu.toString(), "Modes", mode, "Event Types", type},
+                               {trace, "CPUs", cpu.toString(), "Modes", mode, "Submodes", submode, "Event Types", type},
+               };
+               return paths;
+       }
+       
+       /**
+        * @return name of the process. Returns special string if the name is "".
+        */
+       private String getPocessName(LttngProcessState process) {
+               if (process.getName() == null) {
+                       return "Unknown process";
+               }
+               if (process.getName() == "") {
+                       return process.getPid().toString();
+               }
+               else {
+                       return process.getName();
+               }
+       }
+       
+       /**
+        * Increase the NbEvents counter of this node.
+        */
+       protected void increaseNbEvents(StatisticsTreeNode node) {
+               node.getValue().nbEvents++;
+       }
+       
+       /**
+        * Increase the CPU Time according to the trace state.
+        */
+       protected void increaseCPUTime(StatisticsTreeNode node, LttngEvent event,
+                       LttngTraceState traceState) {
+               Long cpu = event.getCpuId();
+               
+               LttngProcessState process = traceState.getRunning_process().get(
+                               cpu);
+               
+               if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) &&
+                               !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) {
+                       node.getValue().cpuTime += event.getTimestamp().getValue()
+                               - process.getState().getChange_LttTime();
+               }
+       }
+       
+       /**
+        * Increase the Elapsed Time according to the trace state.
+        */
+       protected void increaseElapsedTime(StatisticsTreeNode node, LttngEvent event,
+                       LttngTraceState traceState) {
+               Long cpu = event.getCpuId();
+               
+               LttngProcessState process = traceState.getRunning_process().get(
+                               cpu);
+               
+               if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) {
+                       node.getValue().elapsedTime += event.getTimestamp().getValue()
+                               - process.getState().getEntry_LttTime();
+               }
+       }
+       
+       /**
+        * Increase the Cumulative CPU Time according to the trace state.
+        */
+       protected void increaseCumulativeCPUTime(StatisticsTreeNode node, LttngEvent event,
+                       LttngTraceState traceState) {
+               Long cpu = event.getCpuId();
+               
+               LttngProcessState process = traceState.getRunning_process().get(
+                               cpu);
+               
+               if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) {
+                       long cumulativeCpuTime = process.getState().getCum_cpu_time();
+                       long delta = event.getTimestamp().getValue() - process.getState().getEntry_LttTime();
+                       process.getState().setCum_cpu_time(cumulativeCpuTime + delta);
+                       node.getValue().cumulativeCpuTime += process.getState().getCum_cpu_time();
+               }
+               else if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) &&
+                               !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) {
+                       long cumulativeCpuTime = process.getState().getCum_cpu_time();
+                       long delta = event.getTimestamp().getValue() - process.getState().getChange_LttTime();
+                       process.getState().setCum_cpu_time(cumulativeCpuTime + delta);
+                       node.getValue().cumulativeCpuTime += process.getState().getCum_cpu_time();
+               }
+       }
+       
+       /**
+        * Increase the State-bound Cumulative CPU Time according to the trace state.
+        */
+       protected void increaseStateCumulativeCPUTime(LttngEvent event,
+                       LttngTraceState traceState) {
+               Long cpu = event.getCpuId();
+               
+               LttngProcessState process = traceState.getRunning_process().get(cpu);
+               
+               if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) &&
+                               !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) {
+                       long cumulativeCpuTime = process.getState().getCum_cpu_time();
+                       long delta = event.getTimestamp().getValue() - process.getState().getChange_LttTime();
+                       process.getState().setCum_cpu_time(cumulativeCpuTime + delta);
+               }
+       }
+       
+//     @Override
+       public Events getEventHandleType() {
+               return eventType;
+       }
+       
+       protected void stepCount(LttngEvent event, LttngTraceState traceState) {
+               StatisticsTreeNode root = getStatisticsTree(traceState);
+               
+               String[][] paths = getRelevantPaths(event, traceState);
+               
+               for (String[] path : paths) {
+                       StatisticsTreeNode node = root.getOrCreateChildFromPath(path); 
+                       
+                       increaseNbEvents(node);
+               }
+               
+               String[][] eventTypesPaths = getRelevantEventTypesPaths(event, traceState);
+               
+               for (String[] path : eventTypesPaths) {
+                       StatisticsTreeNode node = root.getOrCreateChildFromPath(path); 
+                       
+                       increaseNbEvents(node);
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsModeChangeHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsModeChangeHandler.java
new file mode 100644 (file)
index 0000000..0e0b861
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin     (dhaemon@gmail.com)  - Implementation for stats
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Events;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeNode;
+
+class StatsModeChangeHandler extends AbstractStatsEventHandler {
+       
+       public StatsModeChangeHandler(Events eventType) {
+               super(eventType);
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing#process(org.eclipse.linuxtools.lttng.event.LttngEvent, org.eclipse.linuxtools.lttng.state.model.LttngTraceState)
+        */
+       public boolean process(LttngEvent event, LttngTraceState traceState) {          
+               StatisticsTreeNode root = getStatisticsTree(traceState);
+               
+               String[][] paths = getRelevantPaths(event, traceState);
+               
+               for (String[] path : paths) {
+                       StatisticsTreeNode node = root.getOrCreateChildFromPath(path);
+                       
+                       increaseCPUTime(node, event, traceState);
+                       
+                       increaseStateCumulativeCPUTime(event, traceState);
+               }
+               
+               return false;
+       }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsModeEndHandler.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsModeEndHandler.java
new file mode 100644 (file)
index 0000000..265b92e
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin     (dhaemon@gmail.com)  - Implementation for stats
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Events;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeNode;
+
+class StatsModeEndHandler extends AbstractStatsEventHandler {
+       
+       public StatsModeEndHandler(Events eventType) {
+               super(eventType);
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing#process(org.eclipse.linuxtools.lttng.event.LttngEvent, org.eclipse.linuxtools.lttng.state.model.LttngTraceState)
+        */
+       public boolean process(LttngEvent event, LttngTraceState traceState) {
+               StatisticsTreeNode root = getStatisticsTree(traceState);
+               
+               String[][] paths = getRelevantPaths(event, traceState);
+               
+               for (String[] path : paths) {
+                       StatisticsTreeNode node = root.getOrCreateChildFromPath(path); 
+                       
+                       increaseCPUTime(node, event, traceState);
+                       
+                       increaseElapsedTime(node, event, traceState);
+                       
+                       increaseCumulativeCPUTime(node, event, traceState);
+               }
+               
+               return false;
+       }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsTimeCountHandlerFactory.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsTimeCountHandlerFactory.java
new file mode 100644 (file)
index 0000000..9723691
--- /dev/null
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin     (dhaemon@gmail.com)  - Implementation for stats
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventToHandlerResolver;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+
+/**
+ * Provide the handlers that will count the CPU Time, Cumulative CPU Time and
+ * Elapsed Time and update the appropriate tree.
+ * 
+ * Builds a Map from string event name to a processing handler object, the
+ * processors implement the same interface to facilitate transparent methods
+ * call,
+ * 
+ * The map key STring is the entry point of the raw events, using a hash speeds
+ * up the resolution of the appropriate processor
+ * 
+ * @author alvaro
+ * 
+ */
+public class StatsTimeCountHandlerFactory extends AbsEventToHandlerResolver {
+       // ========================================================================
+       // Data
+       // =======================================================================
+       private final Map<String, ILttngEventProcessor> eventNametoBeforeProcessor = new HashMap<String, ILttngEventProcessor>();
+       ILttngEventProcessor afterhandler;
+       private static StatsTimeCountHandlerFactory instance = null;
+       private StatsTimeCountHandlers instantiateHandler = new StatsTimeCountHandlers();
+
+       // ========================================================================
+       // Constructors
+       // =======================================================================
+       private StatsTimeCountHandlerFactory() {
+               super();
+               //create one instance of each individual event handler and add the instance to the map
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_SYSCALL_ENTRY
+                               .getInName(), instantiateHandler.getSyscallEntryBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_SYSCALL_EXIT
+                               .getInName(), instantiateHandler.getsySyscallExitBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_ENTRY
+                               .getInName(), instantiateHandler.getTrapEntryBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_EXIT
+                               .getInName(), instantiateHandler.getTrapExitBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_ENTRY
+                               .getInName(), instantiateHandler.getTrapEntryBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_EXIT
+                               .getInName(), instantiateHandler.getTrapExitBeforeHandler());
+
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY
+                               .getInName(), instantiateHandler.getTrapEntryBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_EXIT
+                               .getInName(), instantiateHandler.getTrapExitBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_ENTRY
+                               .getInName(), instantiateHandler.getIrqEntryBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_EXIT
+                               .getInName(), instantiateHandler.getIrqExitBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_ENTRY
+                               .getInName(), instantiateHandler.getSoftIrqEntryBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_EXIT
+                               .getInName(), instantiateHandler.getSoftIrqExitBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_FUNCTION_ENTRY
+                               .getInName(), instantiateHandler.getFunctionEntryBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_FUNCTION_EXIT
+                               .getInName(), instantiateHandler.getFunctionExitBeforeHandler());
+               
+               eventNametoBeforeProcessor.put(StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE
+                               .getInName(), instantiateHandler.getSchedChangeBeforeHandler());
+               
+               afterhandler = instantiateHandler.getAfterHandler();
+
+       }
+
+       // ========================================================================
+       // Public methods
+       // =======================================================================
+       /**
+        * The event processors are common to all traces an multiple instances will
+        * use more memory unnecessarily
+        * 
+        * @return
+        */
+       public static AbsEventToHandlerResolver getInstance() {
+               if (instance == null) {
+                       instance = new StatsTimeCountHandlerFactory();
+               }
+               return instance;
+       }
+
+
+       @Override
+       public ILttngEventProcessor getAfterProcessor(String eventType) {
+               return afterhandler;
+       }
+
+       @Override
+       public ILttngEventProcessor getBeforeProcessor(String eventType) {
+               return eventNametoBeforeProcessor.get(eventType);
+       }
+
+       @Override
+       public ILttngEventProcessor getfinishProcessor() {
+               // No finishing processor used
+               return null;
+       }
+
+       @Override
+       public ILttngEventProcessor getStateUpdaterProcessor(String eventType) {
+               return null;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsTimeCountHandlers.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsTimeCountHandlers.java
new file mode 100644 (file)
index 0000000..2fb581e
--- /dev/null
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin     (dhaemon@gmail.com)  - Implementation for stats
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.StateStrings.Events;
+import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+
+/**
+ * Process the system call entry event
+ * 
+ * @author alvaro
+ * 
+ */
+class StatsTimeCountHandlers {
+       
+       /**
+        * Method to handle the event: LTT_EVENT_SYSCALL_ENTRY
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getSyscallEntryBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeChangeHandler(Events.LTT_EVENT_SYSCALL_ENTRY);
+               return handler;
+       }
+       
+       /**
+        * Method to handle the event: LTT_EVENT_SYSCALL_EXIT
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getsySyscallExitBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeEndHandler(Events.LTT_EVENT_SYSCALL_EXIT);
+               return handler;
+       }
+       
+       /**
+        * Method to handle the event: LTT_EVENT_TRAP_ENTRY
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getTrapEntryBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeChangeHandler(Events.LTT_EVENT_TRAP_ENTRY);
+               return handler;
+       }
+       
+       /**
+        * Method to handle the event: LTT_EVENT_TRAP_EXIT
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getTrapExitBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeEndHandler(Events.LTT_EVENT_TRAP_EXIT);
+               return handler;
+       }
+       
+       /**
+        * Method to handle the event: LTT_EVENT_IRQ_ENTRY
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getIrqEntryBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeChangeHandler(Events.LTT_EVENT_IRQ_ENTRY);
+               return handler;
+       }
+       
+       /**
+        * Method to handle the event: LTT_EVENT_IRQ_EXIT
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getIrqExitBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeEndHandler(Events.LTT_EVENT_IRQ_EXIT);
+               return handler;
+       }
+       
+       /**
+        * Method to handle the event: LTT_EVENT_SOFT_IRQ_ENTRY
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getSoftIrqEntryBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeChangeHandler(Events.LTT_EVENT_SOFT_IRQ_ENTRY);
+               return handler;
+       }
+       
+       /**
+        * Method to handle the event: LTT_EVENT_SOFT_IRQ_EXIT
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getSoftIrqExitBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeEndHandler(Events.LTT_EVENT_SOFT_IRQ_EXIT);
+               return handler;
+       }
+
+       /**
+        * <p>
+        * Handles event: LTT_EVENT_FUNCTION_ENTRY
+        * </p>
+        * <p>
+        * FIELDS: LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getFunctionEntryBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeChangeHandler(Events.LTT_EVENT_FUNCTION_ENTRY);
+               return handler;
+       }
+
+       /**
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getFunctionExitBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeEndHandler(Events.LTT_EVENT_FUNCTION_EXIT);
+               return handler;
+       }
+       
+       /**
+        * <p>
+        * Handles: LTT_EVENT_SCHED_SCHEDULE
+        * </p>
+        * <p>
+        * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getSchedChangeBeforeHandler() {
+               AbstractStatsEventHandler handler = new StatsModeChangeHandler(Events.LTT_EVENT_SCHED_SCHEDULE);
+               return handler;
+       }
+       
+       /**
+        * <p>
+        * Handles: LTT_EVENT_SCHED_SCHEDULE
+        * </p>
+        * <p>
+        * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE
+        * </p>
+        * 
+        * @return
+        */
+       final ILttngEventProcessor getAfterHandler() {
+               AbstractStatsEventHandler handler = new StatsModeChangeHandler(null) {
+                       int sched_hash = StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE.getInName().hashCode();
+                       public boolean process(LttngEvent event, LttngTraceState traceState) {
+                               // Step the event counter for any after event
+                               stepCount(event, traceState);
+
+                               int eventNameHash = event.getMarkerName().hashCode();
+                               // specific processing for after sched schedule
+                               if (sched_hash == eventNameHash
+                                               && event.getMarkerName().equals(StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE.getInName())) {
+                                       return super.process(event, traceState);
+                               }
+
+                               return false;
+                       }
+               };
+
+               return handler;
+       }
+       
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/Statistics.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/Statistics.java
new file mode 100644 (file)
index 0000000..53caa96
--- /dev/null
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin     (dhaemon@gmail.com)  - Implementation for stats
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.statistics.model;
+
+public class Statistics {
+       public long nbEvents = 0;
+       
+       public long cpuTime = 0;
+       
+       public long cumulativeCpuTime = 0;
+       
+       public long elapsedTime = 0;
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/StatisticsTreeNode.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/StatisticsTreeNode.java
new file mode 100644 (file)
index 0000000..172e05e
--- /dev/null
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin     (dhaemon@gmail.com)  - Implementation for stats
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.statistics.model;
+
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.HashMap;
+
+/*
+ * A tree where nodes can be accessed efficiently using paths.
+ * 
+ * It works like file systems. Each node is identified by a key. A path is a list of keys separated by the character '/'.
+ * For example, the path 'persons/yann' will browse to the child 'persons' and return it's 'yann' child.
+ * 
+ * If a key might contains the character '/', use the #escapeKey method to get an escaped key. Use the #unescapeKey
+ * method to unescaped the key.
+ */
+public class StatisticsTreeNode {
+
+       private StatisticsTreeNode parent;
+
+       private String key;
+
+       private Statistics value;
+
+       private AbstractMap<String, StatisticsTreeNode> children;
+
+       /*
+        * Construct a node with the given key
+        */
+       public StatisticsTreeNode(String key) {
+               this(null, key);
+       }
+
+       /*
+        * Construct a node with the given parent, key and value.
+        */
+       public StatisticsTreeNode(StatisticsTreeNode parent, String key) {
+               super();
+               this.parent = parent;
+               this.key = key;
+               this.value = new Statistics();
+               this.children = new HashMap<String, StatisticsTreeNode>();
+       }
+
+       /*
+        * @return key associated with this node.
+        */
+       public StatisticsTreeNode getParent() {
+               return this.parent;
+       }
+
+       /*
+        * @return key associated with this node.
+        */
+       public String getKey() {
+               return this.key;
+       }
+
+       /*
+        * @return value associated with this node.
+        */
+       public Statistics getValue() {
+               return this.value;
+       }
+
+       /*
+        * Add a direct child with the given value at the given path.
+        * 
+        * @return children node that was created.
+        */
+       public StatisticsTreeNode addChild(String key) {
+               StatisticsTreeNode created = new StatisticsTreeNode(this, key);
+
+               this.children.put(key, created);
+
+               return created;
+       }
+
+       /*
+        * @return direct children node with the given key. null if not found.
+        */
+       public StatisticsTreeNode getChild(String key) {
+               if (!this.children.containsKey(key)) {
+                       return null;
+               }
+
+               return this.children.get(key);
+       }
+
+       /*
+        * @return number of direct children of this node.
+        */
+       public boolean hasChildren() {
+               return getNbChildren() > 0;
+       }
+
+       /*
+        * @return direct children of this node.
+        */
+       public Collection<StatisticsTreeNode> getChildren() {
+               return children.values();
+       }
+
+       /*
+        * @return number of direct children of this node.
+        */
+       public int getNbChildren() {
+               return children.size();
+       }
+
+       /*
+        * Get the node at the given path. If it doesn't exist each node in the path
+        * will be created with the given class.
+        * 
+        * @return children node with the given path. null if not found.
+        */
+       public StatisticsTreeNode getOrCreateChildFromPath(String[] path) {
+               // StatisticsTreeNode previous = this.parent;
+               StatisticsTreeNode current = this;
+               for (String key : path) {
+                       if (!current.children.containsKey(key)) {
+                               current.children.put(key, new StatisticsTreeNode(current, key));
+                       }
+
+                       // previous = current;
+                       current = current.children.get(key);
+               }
+
+               return current;
+       }
+
+       /*
+        * Get the node at the given path. If it doesn't exist each node in the path
+        * will be created with the given class.
+        * 
+        * @return children node with the given path. null if not found.
+        */
+       public StatisticsTreeNode getOrCreateChildFromPath(String path) {
+               StatisticsTreeNode previous = this.parent;
+               StatisticsTreeNode current = this;
+               for (String key : path.split("/")) {
+                       if (!current.children.containsKey(key)) {
+                               current.children.put(key, new StatisticsTreeNode(previous, key));
+                       }
+
+                       previous = current;
+                       current = current.children.get(key);
+               }
+
+               return current;
+       }
+
+       /*
+        * @return children node with the given path. null if not found.
+        */
+       public StatisticsTreeNode getChildFromPath(String path) {
+               StatisticsTreeNode current = this;
+               for (String key : path.split("/")) {
+                       if (!current.children.containsKey(key)) {
+                               return null;
+                       }
+
+                       current = current.children.get(key);
+               }
+
+               return current;
+       }
+
+       /*
+        * Use this to escape a key that might contain the '/' character.
+        * 
+        * @return escaped key
+        */
+       public static String escapeKey(String key) {
+               return key.replace("%", "%25").replace("/", "%2F");
+       }
+
+       /*
+        * Use this to unescape a key.
+        * 
+        * @return unescaped key
+        */
+       public static String unescapeKey(String key) {
+               return key.replace("%2F", "/").replace("%25", "%");
+       }
+
+       /**
+        * Start from creation time i.e. keep key and parent but new statistics and
+        * no children
+        */
+       public void reset() {
+               this.value = new Statistics();
+               this.children = new HashMap<String, StatisticsTreeNode>();
+       }
+
+       /**
+        * 
+        * @param key
+        * @return true: if child with given key is present, false: if no child
+        *         exists with given key name
+        */
+       public boolean containsChild(String key) {
+               return children.containsKey(key);
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/StatisticsTreeRootFactory.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/statistics/model/StatisticsTreeRootFactory.java
new file mode 100644 (file)
index 0000000..2303806
--- /dev/null
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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:
+ *   Yann N. Dauphin     (dhaemon@gmail.com)  - Implementation for stats
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.ui.views.statistics.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class StatisticsTreeRootFactory {
+       // ========================================================================
+       // Data
+       // =======================================================================
+
+       private static final Map<String, StatisticsTreeNode> rootInstances = new HashMap<String, StatisticsTreeNode>();
+       
+       // ========================================================================
+       // Methods
+       // =======================================================================
+
+       /**
+        * Provide a statisticsTree instance per trace
+        * 
+        * @return
+        */
+       public static StatisticsTreeNode getStatTreeRoot(String traceUniqueId) {
+               if (traceUniqueId == null) {
+                       return null;
+               }
+
+               if (rootInstances.containsKey(traceUniqueId)) {
+                       return rootInstances.get(traceUniqueId);
+               }
+               
+               StatisticsTreeNode tree = new StatisticsTreeNode(traceUniqueId);
+
+               rootInstances.put(traceUniqueId, tree);
+               
+               return tree;
+       }
+
+       /**
+        * @param traceUniqueId
+        * @return
+        */
+       public static boolean containsTreeRoot(String traceUniqueId) {
+               return rootInstances.containsKey(traceUniqueId);
+       }
+
+       /**
+        * Remove previously registered statistics tree.
+        * @param traceUniqueId
+        */
+       public static void removeStatTreeRoot(String traceUniqueId) {
+               if (traceUniqueId != null && rootInstances.containsKey(traceUniqueId)) {
+                       rootInstances.remove(traceUniqueId);
+               }
+       }
+
+       /**
+        * Remove all tree root instances
+        */
+       public static void removeAll() {
+               rootInstances.clear();
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/timeframe/SpinnerGroup.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/timeframe/SpinnerGroup.java
new file mode 100644 (file)
index 0000000..be2a5e7
--- /dev/null
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * 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.timeframe;
+
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Spinner;
+
+// ========================================================================
+// SpinnerGroup
+// ========================================================================
+
+/**
+ * <b><u>SpinnerGroup</u></b>
+ * <p>
+ * A SpinnerGroup holds two coordinated spinners (for seconds and
+ * nanoseconds) representing the current time within the trace.
+ * <p>
+ * The current time can take any value anything within the time range (start
+ * and end time).
+ */
+public class SpinnerGroup {
+
+    // The nanosecond scale (10^9)
+    private static final int  NS_PER_SECOND = 1000 * 1000 * 1000;
+    private static final byte NS_SCALING_FACTOR = -9;
+
+    // Labels
+    private static final String SECONDS_LABEL = "sec";
+    private static final String NANOSEC_LABEL = "ns";
+
+    // Widgets
+    private Group group;
+    private Spinner seconds;
+    private Spinner nanosec;
+
+    // The valid time range - start time
+    private TmfTimestamp startTime;
+    private int startSeconds;
+    private int startNanosec;
+
+    // The valid time range - end time
+    private TmfTimestamp endTime;
+    private int endSeconds;
+    private int endNanosec;
+
+    // The current time value
+    private TmfTimestamp currentTime;
+    private int currentSeconds;
+    private int currentNanosec;
+    
+       @SuppressWarnings("unused")
+       private TimeFrameView fOwner;
+
+    /**
+     * <b><u>Constructor</u></b>
+     * <p>
+     * <li>Creates the display group and formats it for the grid cell
+     * <li>Sets the initial values for Start/End/Current time
+     * </li>
+     * <p>
+     * @param parent    - the parent Composite
+     * @param groupName - the group name
+     * @param range     - the valid time range (start/end time)
+     * @param current   - the current time
+     */
+    public SpinnerGroup(TimeFrameView owner, Composite parent, String groupName, TmfTimeRange range, TmfTimestamp current) {
+
+       fOwner = owner;
+
+        // Create the group
+        group = new Group(parent, SWT.BORDER);
+        group.setText(groupName);
+
+        // Make it use the whole grid cell
+        GridData gridData = new GridData(SWT.LEFT, SWT.TOP, true, false);
+        gridData.horizontalAlignment = SWT.FILL;
+        group.setLayoutData(gridData);
+
+        // Create and position the widgets
+        seconds = new Spinner(group, SWT.BORDER);
+        seconds.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                currentSeconds = seconds.getSelection();
+                refreshCurrentTime();
+            }
+        });
+        seconds.setBounds(5, 25, 110, 25);
+
+        Label label = new Label(group, SWT.LEFT);
+        label.setText(SECONDS_LABEL);
+        label.setBounds(120, 28, 25, 22);
+
+        nanosec = new Spinner(group, SWT.BORDER);
+        nanosec.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                currentNanosec = nanosec.getSelection();
+                // Correct for nanosec underflow
+                if (currentNanosec < 0) {
+                    currentSeconds--;
+                    currentNanosec = NS_PER_SECOND - 1;
+                }
+                // Correct for nanosec overflow
+                if (currentNanosec >= NS_PER_SECOND) {
+                    currentSeconds++;
+                    currentNanosec = 0;
+                }
+                refreshCurrentTime();
+            }
+        });
+        nanosec.setBounds(150, 25, 110, 25);
+
+        label = new Label(group, SWT.LEFT);
+        label.setText(NANOSEC_LABEL);
+        label.setBounds(265, 28, 25, 22);
+
+        setContent(range, current);
+    }
+
+    private void refreshCurrentTime() {
+        long newCurrentTime = ((long) currentSeconds) * NS_PER_SECOND + currentNanosec;
+        TmfTimestamp ts = new TmfTimestamp(newCurrentTime, NS_SCALING_FACTOR, 0);
+        currentTime = ts;
+//        fOwner.synchTimeFrameWidgets(this);
+    }
+
+    // ====================================================================
+    // Get/Set
+    // ====================================================================
+
+    public TmfTimestamp getStartTime() {
+        return startTime;
+    }
+
+    public TmfTimestamp getEndTime() {
+        return endTime;
+    }
+
+    public TmfTimestamp getCurrentTime() {
+        return currentTime;
+    }
+
+    public TmfTimestamp getSpan() {
+        TmfTimestamp span = new TmfTimestamp(startTime.getAdjustment(endTime, NS_SCALING_FACTOR), NS_SCALING_FACTOR, 0);
+        return span;
+    }
+
+    public TmfTimeRange getTimeRange() {
+        TmfTimeRange range = new TmfTimeRange(startTime, endTime);
+        return range;
+    }
+
+    public void setStartTime(TmfTimestamp ts) {
+       try {
+               startTime = ts.synchronize(0, NS_SCALING_FACTOR);
+               startSeconds = (int) (startTime.getValue() / NS_PER_SECOND);
+               startNanosec = (int) (startTime.getValue() % NS_PER_SECOND);
+       }
+       catch (ArithmeticException e) {
+       }
+    }
+
+    public void setEndTime(TmfTimestamp ts) {
+       try {
+               endTime = ts.synchronize(0, NS_SCALING_FACTOR);
+               endSeconds = (int) (endTime.getValue() / NS_PER_SECOND);
+               endNanosec = (int) (endTime.getValue() % NS_PER_SECOND);
+       }
+       catch (ArithmeticException e) {
+       }
+    }
+
+    public void setCurrentTime(TmfTimestamp ts) {
+       try {
+               currentTime = ts.synchronize(0, NS_SCALING_FACTOR);
+               currentSeconds = (int) (currentTime.getValue() / NS_PER_SECOND);
+               currentNanosec = (int) (currentTime.getValue() % NS_PER_SECOND);
+       }
+       catch (ArithmeticException e) {
+       }
+    }
+
+    // ====================================================================
+    // Operators
+    // ====================================================================
+
+    /**
+     * <b><u>setContent</u></b>
+     * <p>
+     * <li>validates that [startTime <= currentTime <= endTime] is respected
+     * <li>sets the start/current/end time and update the spinners
+     * </li>
+     * <p>
+     * 
+     * @param range
+     * @param current
+     */
+    public void setContent(TmfTimeRange range, TmfTimestamp current) {
+
+       if (range != null) {
+               // Extract the time range
+            TmfTimestamp start = range.getStartTime();
+            TmfTimestamp end   = range.getEndTime();
+
+            // Assume start time is OK
+            setStartTime(start);
+
+            // Make sure end time >= start time
+            if (end.compareTo(start, false) < 0) {
+                end = start;
+            }
+            setEndTime(end);
+
+            // Make sure [start time <= current time <= end time]
+            // If not: current = min(max(start, current), end);
+            if (current.compareTo(start, false) < 0) {
+                current = start;
+            }
+            if (current.compareTo(end, false) > 0) {
+                current = end;
+            }
+       }
+        setCurrentTime(current);
+
+        // And configure the spinners
+        updateSpinners();
+    }
+
+    /**
+     * <b><u>setValue</u></b>
+     * <p>
+     * <li>validates that [startTime <= currentTime <= endTime] is respected
+     * <li>sets the current time and the spinners
+     * </li>
+     * <p>
+     * 
+     * @param range
+     * @param current
+     */
+    public void setValue(TmfTimestamp current) {
+
+        // Make sure [start time <= current time <= end time]
+        // If not: current = min(max(start, current), end);
+        if (current.compareTo(startTime, false) < 0) {
+            current = startTime;
+        }
+        if (current.compareTo(endTime, false) > 0) {
+            current = endTime;
+        }
+        setCurrentTime(current);
+
+        // And configure the spinners
+        updateSpinners();
+    }
+
+    /**
+     * Update the spinners with the new current time value
+     * Perform the update on the UI thread
+     */
+    public void updateSpinners() {
+
+        seconds.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if (!seconds.isDisposed() && !nanosec.isDisposed()) {
+                           // If we are on the start second, ensure that [currentNS >= startNS]
+                           // If the currentSeconds > startSeconds, set startns to -1 so we can
+                           // "underflow"
+                           int startns = -1;
+                           if (currentSeconds <= startSeconds) {
+                               currentSeconds = startSeconds;
+                               startns = startNanosec;
+                               if (currentNanosec < startns) {
+                                   currentNanosec = startns;
+                               }
+                           }
+
+                           // If we are on the end second, ensure that [currentNS <= endNS]
+                           // If the currentSeconds < endSeconds, set endns to MAX so we can
+                           // "overflow"
+                           int endns = NS_PER_SECOND;
+                           if (currentSeconds >= endSeconds) {
+                               currentSeconds = endSeconds;
+                               endns = endNanosec;
+                               if (currentNanosec > endns) {
+                                   currentNanosec = endns;
+                               }
+                           }
+
+                           // Refresh the spinners (value, range, increments, ...)
+                                       // To ensure that the spinners are properly set, the range has to be > 0 
+//                                     seconds.setValues(currentSeconds, startSeconds - 1, endSeconds + 1, 0, 1, 10);
+//                                     nanosec.setValues(currentNanosec, startns - 1, endns + 1, 0, 1, 1000000);
+                                       seconds.setValues(currentSeconds, startSeconds, endSeconds, 0, 1, 10);
+                                       nanosec.setValues(currentNanosec, startns, endns, 0, 100000, 10000000);
+
+                           // If start == end (i.e. no range), disable the spinner
+                           // (if start == end, the spinner widget range is set to [0..100] by default)
+                           seconds.setEnabled(startSeconds != endSeconds);
+                           nanosec.setEnabled(startns != endns);
+                               }
+                       }
+        });
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/timeframe/TimeFrameView.java b/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/timeframe/TimeFrameView.java
new file mode 100644 (file)
index 0000000..1ee5543
--- /dev/null
@@ -0,0 +1,380 @@
+/*******************************************************************************
+ * 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.ui.views.timeframe;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+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.signal.TmfExperimentSelectedSignal;
+import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal;
+import org.eclipse.linuxtools.tmf.signal.TmfRangeSynchSignal;
+import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;
+import org.eclipse.linuxtools.tmf.ui.views.TmfView;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Slider;
+
+/**
+ * <b><u>TimeFrameView</u></b>
+ * <p>
+ * The TimeFrameView provides a set of spinners to monitor and set the start
+ * time, end time, the current time interval and current time of the trace
+ * set at the nanosecond level.
+ * <p>
+ * It ensures that the following relations are always true:
+ * <p>
+ * <li>[ startTime >= start time of the trace ]
+ * <li>[ endTime <= end time of the trace ]
+ * <li>[ startTime <= currentTime <= endTime ]
+ * <li>[ interval == (endTime - startTime) ]
+ * </li>
+ * <p>
+ * It provides a slider to rapidly set the current time within the time range
+ * (i.e. between startTime and endTime).
+ * <p>
+ * Finally, it allows modification of the time range and the current time. This
+ * triggers notifications to the other LTTng views.
+ * <p>
+ * FIXME: The slider is very jumpy due to the large number of async updates
+ * FIXME: Revisit the control flow between View, Spinners and Slider
+ */
+public class TimeFrameView extends TmfView {
+
+    public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.timeframe";
+
+    // ========================================================================
+    // TimeFrameView
+    // ========================================================================
+
+    // The event log timestamp characteristics
+    private TmfTimestamp fTraceStartTime = new TmfTimestamp();
+    private TmfTimestamp fTraceEndTime   = new TmfTimestamp();
+
+    private TmfTimestamp fCurrentTime   = new TmfTimestamp();
+    
+    private TmfTimeRange fTraceTimeRange = new TmfTimeRange(fTraceStartTime, fTraceEndTime);
+    private TmfTimeRange fTraceSpan      = new TmfTimeRange(fTraceStartTime, fTraceEndTime);
+    private byte fScale = 0;
+
+    // Labels
+    private static final String START_TIME_LABEL   = "Window Start Time";
+    private static final String END_TIME_LABEL     = "Window End Time";
+    private static final String TIME_RANGE_LABEL   = "Window Range";
+    private static final String CURRENT_TIME_LABEL = "Current Time";
+
+    private static final int SLIDER_RANGE = 10000;
+
+    private SpinnerGroup fStartGroup;
+    private SpinnerGroup fEndGroup;
+    private SpinnerGroup fRangeGroup;
+    private SpinnerGroup fCurrentGroup;
+
+    // The slider
+    private Slider fSlider;
+
+    // The current experiment
+    TmfExperiment<LttngEvent> fExperiment = null;
+       // notify external listeners may not be needed if the update originated
+       // externally
+       private boolean fupdateExternalListeners = true;
+
+
+    /**
+     * Constructor
+     */
+    public TimeFrameView() {
+       super("TimeFrameView");
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+     */
+       @Override
+       public void createPartControl(Composite parent) {
+
+        // Set the view layout
+        GridLayout layout = new GridLayout(4, true);
+        parent.setLayout(layout);
+
+        fStartGroup   = new SpinnerGroup(this, parent, START_TIME_LABEL,   fTraceTimeRange, fTraceStartTime);
+        fEndGroup     = new SpinnerGroup(this, parent, END_TIME_LABEL,     fTraceTimeRange, fTraceEndTime);
+        fRangeGroup   = new SpinnerGroup(this, parent, TIME_RANGE_LABEL,   fTraceTimeRange, fTraceEndTime);
+        fCurrentGroup = new SpinnerGroup(this, parent, CURRENT_TIME_LABEL, fTraceTimeRange, fTraceStartTime);
+
+        // Create the slider
+        createSlider(parent);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
+     */
+       @Override
+       public void setFocus() {
+        // TODO Auto-generated method stub
+    }
+
+    // ========================================================================
+    // Operators
+    // ========================================================================
+
+    /**
+     * One of the spinners has been updated. Synchronize the other widgets.
+     */
+    public void synchTimeFrameWidgets(SpinnerGroup trigger) {
+               boolean trangeUpdated = false;
+
+        // Collect the data
+        TmfTimestamp startTime   = fStartGroup.getCurrentTime();
+        TmfTimestamp endTime     = fEndGroup.getCurrentTime();
+        TmfTimestamp timeRange   = fRangeGroup.getCurrentTime();
+        TmfTimestamp currentTime = fCurrentGroup.getCurrentTime();
+
+        // If startTime was set beyond endTime, adjust endTime and interval
+        if (trigger == fStartGroup) {
+            if (startTime.compareTo(endTime, false) > 0) {
+                endTime = startTime;
+                               trangeUpdated = true;
+            }
+        }
+
+        // If endTime was set beyond startTime, adjust startTime and interval
+        if (trigger == fEndGroup) {
+            if (endTime.compareTo(startTime, false) < 0) {
+                startTime = endTime;
+                               trangeUpdated = true;
+            }
+        }
+
+        // If timeRange was set, adjust endTime
+        if (trigger == fRangeGroup) {
+            long start = startTime.getValue();
+            long span  = timeRange.getValue();
+            TmfTimestamp ts = new TmfTimestamp(start + span, startTime.getScale(), 0);
+            if (ts.compareTo(fTraceEndTime, false) > 0) {
+                ts = fTraceEndTime.synchronize(fTraceEndTime.getValue(), startTime.getScale());
+            }
+            endTime = ts;
+                       trangeUpdated = true;
+        }
+
+        // Compute the new time range
+        TmfTimeRange subrange = new TmfTimeRange(startTime, endTime);
+        byte scale = startTime.getScale();
+        TmfTimestamp interval = new TmfTimestamp(startTime.getAdjustment(endTime, scale), scale, 0);
+
+        // Update the spinner groups
+        fStartGroup.setContent(fTraceTimeRange, startTime);
+        fEndGroup.setContent(fTraceTimeRange, endTime);
+        fRangeGroup.setContent(fTraceSpan, interval);
+        fCurrentGroup.setContent(subrange, currentTime);
+
+        updateSlider(subrange, currentTime);
+               // Notify other views, only if the update originated from this view
+               if (fupdateExternalListeners) {
+                       if (!fCurrentTime.equals(currentTime)) {
+                               fCurrentTime = currentTime;
+                               broadcast(new TmfTimeSynchSignal(this, currentTime));
+                       }
+
+                       // Notify the views if the time range has been impacted
+                       if (trangeUpdated) {
+                               TmfTimeRange trange = new TmfTimeRange(startTime, endTime);
+                               broadcast(new TmfRangeSynchSignal(this, trange, currentTime));
+                       }
+        }
+    }
+
+    // ========================================================================
+    // Slider Handling
+    // ========================================================================
+
+    /**
+     * @param parent
+     */
+    private void createSlider(Composite parent) {
+        fSlider = new Slider(parent, SWT.SMOOTH | SWT.FILL);
+        fSlider.setMinimum(0);
+        fSlider.setMaximum(SLIDER_RANGE + fSlider.getThumb());
+        fSlider.setIncrement(SLIDER_RANGE / 100);
+        fSlider.setPageIncrement(SLIDER_RANGE / 10);
+        fSlider.setSelection(0);
+
+        GridData gridData = new GridData(SWT.LEFT, SWT.TOP, true, false);
+        gridData.horizontalAlignment = SWT.FILL;
+        gridData.horizontalSpan = 4;
+        fSlider.setLayoutData(gridData);
+
+        fSlider.addListener(SWT.Selection, new Listener() {
+               public void handleEvent(Event event) {
+                               int ratio = fSlider.getSelection();
+                               TmfTimestamp span = fCurrentGroup.getSpan();
+                               long value = span.getValue() * ratio / SLIDER_RANGE;
+                               TmfTimestamp start = fCurrentGroup.getStartTime();
+                               TmfTimestamp current = new TmfTimestamp(start.getValue() + value, start.getScale(), 0);
+                               fCurrentGroup.setValue(current);
+                       }
+        });
+
+    }
+
+    /**
+     * @param range
+     * @param timestamp
+     */
+    private void updateSlider(TmfTimeRange range, TmfTimestamp timestamp) {
+
+        // Determine the new relative position
+       byte scale = range.getEndTime().getScale();
+        long total    = range.getStartTime().getAdjustment(range.getEndTime(), scale);
+        long relative = range.getStartTime().getAdjustment(timestamp, scale);
+
+        // Set the slider value
+        final long position = (total > 0) ? (relative * SLIDER_RANGE / total) : 0;
+
+        // Update the slider on the UI thread
+        long current = fSlider.getSelection();
+        if (position != current) {
+               fSlider.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               fSlider.setSelection((int) position);
+                       }
+               });
+        }
+    }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public String toString() {
+               return "[TimeFrameView]";
+       }
+
+    // ========================================================================
+    // TMF Signal Handling
+    // ========================================================================
+
+       /**
+     * @param signal
+     */
+    @SuppressWarnings("unchecked")
+    @TmfSignalHandler
+    public void experimentSelected(TmfExperimentSelectedSignal<LttngEvent> signal) {
+
+        // Update the trace reference
+        fExperiment = (TmfExperiment<LttngEvent>) signal.getExperiment();
+
+        // Update the time frame
+        fTraceTimeRange = fExperiment.getTimeRange();
+        fTraceStartTime = fTraceTimeRange.getStartTime();
+        fTraceEndTime   = fTraceTimeRange.getEndTime();
+        fScale          = fTraceStartTime.getScale();
+
+        // Update the widgets
+        fStartGroup.setContent(fTraceTimeRange, fTraceStartTime);
+        fEndGroup.setContent(fTraceTimeRange, fTraceEndTime);
+        fCurrentGroup.setContent(fTraceTimeRange, fTraceStartTime);
+
+        fCurrentTime = fTraceStartTime;
+
+        TmfTimestamp delta = new TmfTimestamp(fTraceStartTime.getAdjustment(fTraceEndTime, fScale), fScale, 0);
+        fTraceSpan = new TmfTimeRange(new TmfTimestamp(0, fScale, 0), delta);
+//        fRangeGroup.setContent(fTraceSpan, delta);
+        TmfTimestamp start = new TmfTimestamp(1, (byte) -1, 0);
+        fRangeGroup.setContent(fTraceSpan, start);
+    }
+
+    /**
+     * @param signal
+     */
+    @TmfSignalHandler
+    public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
+
+        // Update the time frame
+               fTraceTimeRange = signal.getTrace().getTimeRange();
+        fTraceStartTime = fTraceTimeRange.getStartTime();
+        fTraceEndTime   = fTraceTimeRange.getEndTime();
+        fScale          = fTraceStartTime.getScale();
+
+        // Update the widgets
+        fStartGroup.setContent(fTraceTimeRange, fStartGroup.getCurrentTime());
+        fEndGroup.setContent(fTraceTimeRange, fTraceEndTime);
+        fCurrentGroup.setContent(fTraceTimeRange, fCurrentGroup.getCurrentTime());
+
+        TmfTimestamp delta = new TmfTimestamp(fTraceStartTime.getAdjustment(fTraceEndTime, fScale), fScale, 0);
+        fTraceSpan = new TmfTimeRange(new TmfTimestamp(0, fScale, 0), delta);
+        fRangeGroup.setContent(fTraceSpan, delta);
+    }
+
+       /**
+        * @param signal
+        */
+       @TmfSignalHandler
+       public void currentTimeRangeUpdated(TmfRangeSynchSignal signal) {
+               if (signal.getSource() != this) {
+                       // Update the time frame
+                       TmfTimeRange selTimeRange = signal.getCurrentRange();
+                       TmfTimestamp selStart = selTimeRange.getStartTime().synchronize(0,
+                                       fScale);
+                       TmfTimestamp selEnd = selTimeRange.getEndTime().synchronize(0,
+                                       fScale);
+
+                       fupdateExternalListeners = false;
+                       // Update the widgets and prevent broadcast notifications to
+                       // the views which have been notified already.
+                       {
+                               fStartGroup.setContent(fTraceTimeRange, selStart);
+                               fEndGroup.setContent(fTraceTimeRange, selEnd);
+
+                               TmfTimestamp delta = new TmfTimestamp(selStart.getAdjustment(
+                                               selEnd, fScale), fScale, 0);
+
+                               fRangeGroup.setContent(fTraceSpan, delta);
+                       }
+
+                       // restore the external notification flag
+                       fupdateExternalListeners = true;
+
+               }
+       }
+
+    /**
+     * @param signal
+     */
+    @TmfSignalHandler
+    public void currentTimeUpdated(TmfTimeSynchSignal signal) {
+       if (signal.getSource() != this) {
+                       // prevent loop to external notifications
+                       fupdateExternalListeners = false;
+            fCurrentTime = signal.getCurrentTime().synchronize(0, fStartGroup.getCurrentTime().getScale());
+            if (fStartGroup.getCurrentTime().compareTo(fCurrentTime, false) > 0) {
+               fStartGroup.setContent(new TmfTimeRange(fCurrentTime, fEndGroup.getCurrentTime()), fCurrentTime);
+            }
+            if (fEndGroup.getCurrentTime().compareTo(fCurrentTime, false) < 0) {
+               fEndGroup.setContent(new TmfTimeRange(fStartGroup.getCurrentTime(), fCurrentTime), fCurrentTime);
+            }
+            fCurrentGroup.setContent(null, fCurrentTime);
+            updateSlider(fCurrentGroup.getTimeRange(), fCurrentTime);
+
+                       // Enable external notifications
+                       fupdateExternalListeners = true;
+       }
+    }
+
+}
\ No newline at end of file
This page took 0.234957 seconds and 5 git commands to generate.