]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
First implementation of jfreechart charts
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 22 Nov 2011 13:35:43 +0000 (13:35 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 22 Nov 2011 13:35:43 +0000 (13:35 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@23325 ac1ea38d-2e2b-0410-8846-a27921b304fc

54 files changed:
org.simantics.sysdyn.feature/feature.xml
org.simantics.sysdyn.ontology/META-INF/MANIFEST.MF
org.simantics.sysdyn.ontology/graph.tg
org.simantics.sysdyn.ontology/graph/ChartAxisAndVariablesViewpoint.pgraph [new file with mode: 0644]
org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph
org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java
org.simantics.sysdyn.ui/META-INF/MANIFEST.MF
org.simantics.sysdyn.ui/adapters.xml
org.simantics.sysdyn.ui/plugin.xml
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Model.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/profiles/SimulationPlaybackStyle.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewChartHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultVariable.java [deleted file]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryVariable.java [deleted file]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModelTab.java [deleted file]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ChartPanel.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ChartPanelElement.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ChartPanelHeader.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ChartPanelSeparator.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ChartComposite.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IAxis.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IDataset.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChart.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChartComponent.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IPlot.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ITitle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/JFreeChart.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/NumberAxis.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/TextTitle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYDataset.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYPlot.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/AxisChildRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/VariableChildRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisPropertyComposite.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/BooleanPropertyFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/BooleanSelectionListener.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartAxisAndVariablesTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ColorPicker.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/GeneralChartPropertiesTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/JFreeChartPropertyColorProvider.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/SeriesPropertyComposite.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TrackedSpinner.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java

index 66b609d26bcca39e42fd8e1a46c87336e9e08060..d5e62a54d7f689530b211f8c016763c78a4f7092 100644 (file)
          install-size="0"\r
          version="0.0.0"/>\r
 \r
+   <plugin\r
+         id="org.simantics.jfreechart.ontology"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
 </feature>\r
index be16f573c4d332a7080e100c2be36e9058b1429d..c12c356d3c64a9c5e5c0510bee10c6c7cad71ed7 100644 (file)
@@ -11,7 +11,8 @@ Require-Bundle: org.simantics.layer0,
  org.simantics.project.ontology;bundle-version="1.0.0",
  org.simantics.viewpoint.ontology;bundle-version="1.0.0",
  org.simantics.layer0x.ontology;bundle-version="1.0.0",
- org.simantics.issues.ontology;bundle-version="1.1.0"
+ org.simantics.issues.ontology;bundle-version="1.1.0",
+ org.simantics.jfreechart.ontology;bundle-version="0.1.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Export-Package: org.simantics.sysdyn
 Bundle-Vendor: VTT Technical Reserarch Centre of Finland
index eaa15267e151cd2190bea2f1d2c155d5ac4bed0e..2a4147273fc6214aadda96669484067899db53e2 100644 (file)
Binary files a/org.simantics.sysdyn.ontology/graph.tg and b/org.simantics.sysdyn.ontology/graph.tg differ
diff --git a/org.simantics.sysdyn.ontology/graph/ChartAxisAndVariablesViewpoint.pgraph b/org.simantics.sysdyn.ontology/graph/ChartAxisAndVariablesViewpoint.pgraph
new file mode 100644 (file)
index 0000000..d07ed22
--- /dev/null
@@ -0,0 +1,25 @@
+L0 = <http://www.simantics.org/Layer0-1.0>\r
+VP = <http://www.simantics.org/Viewpoint-1.1>\r
+PROJECT = <http://www.simantics.org/Project-1.1>\r
+MOD = <http://www.simantics.org/Modeling-1.1>\r
+IMAGE = <http://www.simantics.org/Image2-1.1>\r
+COLOR = <http://www.simantics.org/Color-1.0>\r
+ACT = <http://www.simantics.org/Action-1.0>\r
+JFREE = <http://www.simantics.org/JFreeChart-1.0>\r
+SYSDYN = <http://www.simantics.org/Sysdyn-1.1>\r
+\r
+CBC = SYSDYN.ChartAxisAndVariablesBrowseContext : VP.BrowseContext\r
+CAC = SYSDYN.ChartAxisAndVariablesActionContext : VP.BrowseContext\r
+\r
+CBC.AxisChildRule : VP.ChildRule\r
+CBC.VariableChildRule : VP.ChildRule\r
+\r
+CBC\r
+    @VP.customChildRule JFREE.Chart CBC.AxisChildRule\r
+        JFREE.Axis : VP.ResourceNodeType\r
+    @VP.customChildRule JFREE.Axis CBC.VariableChildRule\r
+        JFREE.Series : VP.ResourceNodeType\r
+\r
+CBC        \r
+    @VP.customLabelRule             JFREE.Axis          VP.ResourceLabelLabelRule\r
+    @VP.customLabelRule             JFREE.Series        VP.ResourceLabelLabelRule
\ No newline at end of file
index a00b29db32edc91d91de3c004c9da0d84ff85591..e3ed74d54c767d6e2bfb21e6baf3ae5e22630a8c 100644 (file)
@@ -6,6 +6,7 @@ DIA = <http://www.simantics.org/Diagram-2.1>
 SIMU = <http://www.simantics.org/Simulation-1.0>
 MOD = <http://www.simantics.org/Modeling-1.1>
 PROJ = <http://www.simantics.org/Project-1.1>
+JFREE = <http://www.simantics.org/JFreeChart-1.0>
  
 //#####################################################################
 // Defines ontology and attaches it to SimanticsDomain
@@ -371,9 +372,8 @@ SYSDYN.HasParameterFile <R L0.HasProperty
     L0.HasRange L0.String  
 
 SYSDYN.HasResultFile <R L0.HasProperty
-    L0.HasRange L0.String
-    
-    
+    L0.HasRange L0.String  
+   
 //#####################################################################
 //#####################################################################
 //################              DIAGRAM               #################
index 2260b23f8842d12ae7a3f9f296ff947bb85e03c5..d6ff18c96fb6535499d75e3dccd408512a86944b 100644 (file)
@@ -46,6 +46,10 @@ public class SysdynResource {
     public final Resource Built$in_Functions_xidz;\r
     public final Resource Built$in_Functions_zidz;\r
     public final Resource Center;\r
+    public final Resource ChartAxisAndVariablesActionContext;\r
+    public final Resource ChartAxisAndVariablesBrowseContext;\r
+    public final Resource ChartAxisAndVariablesBrowseContext_AxisChildRule;\r
+    public final Resource ChartAxisAndVariablesBrowseContext_VariableChildRule;\r
     public final Resource Cloud;\r
     public final Resource CloudSymbol;\r
     public final Resource Configuration;\r
@@ -285,6 +289,10 @@ public class SysdynResource {
         public static final String Built$in_Functions_xidz = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/xidz";\r
         public static final String Built$in_Functions_zidz = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/zidz";\r
         public static final String Center = "http://www.simantics.org/Sysdyn-1.1/Center";\r
+        public static final String ChartAxisAndVariablesActionContext = "http://www.simantics.org/Sysdyn-1.1/ChartAxisAndVariablesActionContext";\r
+        public static final String ChartAxisAndVariablesBrowseContext = "http://www.simantics.org/Sysdyn-1.1/ChartAxisAndVariablesBrowseContext";\r
+        public static final String ChartAxisAndVariablesBrowseContext_AxisChildRule = "http://www.simantics.org/Sysdyn-1.1/ChartAxisAndVariablesBrowseContext/AxisChildRule";\r
+        public static final String ChartAxisAndVariablesBrowseContext_VariableChildRule = "http://www.simantics.org/Sysdyn-1.1/ChartAxisAndVariablesBrowseContext/VariableChildRule";\r
         public static final String Cloud = "http://www.simantics.org/Sysdyn-1.1/Cloud";\r
         public static final String CloudSymbol = "http://www.simantics.org/Sysdyn-1.1/CloudSymbol";\r
         public static final String Configuration = "http://www.simantics.org/Sysdyn-1.1/Configuration";\r
@@ -534,6 +542,10 @@ public class SysdynResource {
         Built$in_Functions_xidz = getResourceOrNull(graph, URIs.Built$in_Functions_xidz);\r
         Built$in_Functions_zidz = getResourceOrNull(graph, URIs.Built$in_Functions_zidz);\r
         Center = getResourceOrNull(graph, URIs.Center);\r
+        ChartAxisAndVariablesActionContext = getResourceOrNull(graph, URIs.ChartAxisAndVariablesActionContext);\r
+        ChartAxisAndVariablesBrowseContext = getResourceOrNull(graph, URIs.ChartAxisAndVariablesBrowseContext);\r
+        ChartAxisAndVariablesBrowseContext_AxisChildRule = getResourceOrNull(graph, URIs.ChartAxisAndVariablesBrowseContext_AxisChildRule);\r
+        ChartAxisAndVariablesBrowseContext_VariableChildRule = getResourceOrNull(graph, URIs.ChartAxisAndVariablesBrowseContext_VariableChildRule);\r
         Cloud = getResourceOrNull(graph, URIs.Cloud);\r
         CloudSymbol = getResourceOrNull(graph, URIs.CloudSymbol);\r
         Configuration = getResourceOrNull(graph, URIs.Configuration);\r
index 8b918eabb3a20d956ad6adfc5688e127a54f574b..420583114dd94dfd03a29ac85f06b29eadda1e07 100644 (file)
@@ -49,7 +49,9 @@ Require-Bundle: org.simantics.layer0.utils;bundle-version="0.6.2",
  org.simantics.scenegraph.profile;bundle-version="1.0.0",
  org.simantics.trend;bundle-version="1.0.0",
  org.simantics.history;bundle-version="1.0.0",
- org.simantics.utils.thread.swt;bundle-version="1.1.0"
+ org.simantics.utils.thread.swt;bundle-version="1.1.0",
+ org.simantics.jfreechart.ontology;bundle-version="0.1.0",
+ org.eclipse.ui.forms;bundle-version="3.5.2"
 Bundle-Activator: org.simantics.sysdyn.ui.Activator
 Bundle-ActivationPolicy: lazy
 Export-Package: org.simantics.sysdyn.ui.browser.nodes
index b1be736a7087a95ad896b9fbd8b91cf78921d33b..3a9a9e3cf7525439c34f77b139b169a446a46092 100644 (file)
@@ -10,5 +10,5 @@
         VTT Technical Research Centre of Finland - initial API and implementation\r
  -->\r
 
-<adapters>\r\r   <target interface="org.simantics.db.layer0.adapter.Realization">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/Module"\r                 class="org.simantics.structural2.realization.StructuralRealization">\r                   <this />\r               </type>\r        </target>\r\r<!-- \r       <target interface="org.simantics.db.layer0.variable.Variable">\r         <type uri="http://www.simantics.org/Sysdyn-0.0/HistoryRealization"\r                     class="org.simantics.sysdyn.ui.project.HistoryVariable" >\r                      <this />\r               </type>\r                <type uri="http://www.simantics.org/Sysdyn-0.0/DefaultRealization"\r                     class="org.simantics.sysdyn.ui.project.DefaultVariable" >\r                      <this />\r               </type>\r        </target>\r -->\r\r        <target interface="org.simantics.layer0.utils.triggers.ITrigger">\r      <type uri = "http://www.simantics.org/Sysdyn-0.0/DiagramToCompositeMapping"\r          class = "org.simantics.sysdyn.ui.editor.DiagramToCompositeMapping3">\r         <graph/>\r           <this />\r       </type>\r        </target>\r      \r       <target interface="org.simantics.structural.ui.modelBrowser.nodes.AbstractNode">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                    class="org.simantics.structural.ui.modelBrowser.nodes.ModelNode">\r                      <this />\r               </type>\r        </target>               \r               \r\r      <target\r                interface="org.simantics.browsing.ui.common.node.AbstractNode">\r                <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                  class="org.simantics.sysdyn.ui.browser.nodes.ModelNode">\r                       <this />\r               </type>\r\r               <resource\r                      uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                 class="org.simantics.sysdyn.ui.browser.nodes.SymbolNode">\r                      <this />\r               </resource>\r\r           <type\r                  uri="http://www.simantics.org/Simulation-1.0/Experiment"\r                       class="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode">\r                  <this />\r               </type>\r                \r               <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/Result"\r                       class="org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode">\r                    <this />\r               </type>\r                \r       </target>\r\r     <!-- Inject default connection routing algorithm for sysdyn diagrams -->\r       <target interface="org.simantics.g2d.diagram.DiagramClass">\r            <adapter uri="http://www.simantics.org/Sysdyn-0.0/ConfigurationDiagram"\r                        adapterClass="org.simantics.sysdyn.ui.elements2.ConfigurationDiagramClassAdapter" />\r   </target>\r\r     <!-- Sysdyn symbols -->\r        <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.StockFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                       class="org.simantics.sysdyn.ui.elements2.ModuleFactory" />\r             <resource uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.ValveFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                    class="org.simantics.sysdyn.ui.elements2.AuxiliaryFactory" />\r          <resource uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.CloudFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.InputFactory" />\r\r             <type uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.StockFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                   class="org.simantics.sysdyn.ui.elements2.ModuleFactory" />\r             <type uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.ValveFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                        class="org.simantics.sysdyn.ui.elements2.AuxiliaryFactory" />\r          <type uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.CloudFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.InputFactory" />                       \r       </target>\r      \r       <!-- Sysdyn connections -->\r    <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <!-- Edges -->       \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowEdgeFactory" />\r        <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowEdgeFactory" />            \r        <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowConnectionFactory">\r            <graph/>\r        </type>                       \r                       \r               <resource uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                       class="org.simantics.sysdyn.ui.elements2.connections.DependencyEdgeFactory" />\r         <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements2.connections.DependencyEdgeFactory" />\r         <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements2.connections.DependencyConnectionFactory" />\r   </target>\r      \r       <target interface="org.simantics.g2d.connection.EdgeVisualsConfigurer">\r          <baseType uri="http://www.simantics.org/Diagram-0.0/HasConnector" />\r   <resource uri="http://www.simantics.org/Diagram-0.0/HasPlainConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>none 0</string>\r       </resource>\r    <resource uri="http://www.simantics.org/Diagram-0.0/HasArrowConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>fill 1</string>\r       </resource>\r  </target>\r      \r       <!-- ModelBrowser2 -->\r \r       <target interface="org.simantics.browsing.ui.model.children.ChildRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleTypeChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleTypeChildRule"/>\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleContentChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleContentChildRule"/>            \r    </target>\r    \r    <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleTypeLabelRule"\r            class="org.simantics.sysdyn.ui.browser.labelrules.ModuleTypeLabelRule"/>\r    </target>    \r    \r    <target interface="org.simantics.db.layer0.adapter.ActionFactory">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewModuleType"\r            class="org.simantics.sysdyn.ui.browser.actions.NewModuleTypeAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewEnumeration"\r            class="org.simantics.sysdyn.ui.browser.actions.NewEnumerationAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/OpenWorkbook"\r            class="org.simantics.sysdyn.ui.browser.actions.OpenWorkbookAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewFunction"\r            class="org.simantics.sysdyn.ui.browser.actions.NewFunctionAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.NewFunctionLibraryAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewSharedFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.NewSharedFunctionLibraryAction" />            \r    </target>              \r  \r  <!-- PROFILES -->\r    <target interface="org.simantics.scenegraph.profile.Style">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/SimulationPlaybackStyle"\r            class="org.simantics.sysdyn.ui.elements2.profiles.SimulationPlaybackStyle">\r        </resource>\r                <resource uri="http://www.simantics.org/Sysdyn-0.0/IssueStyle"\r            class="org.simantics.sysdyn.ui.elements2.profiles.IssueDecorationStyle">\r        </resource>\r    </target>\r
+<adapters>\r\r   <target interface="org.simantics.db.layer0.adapter.Realization">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/Module"\r                 class="org.simantics.structural2.realization.StructuralRealization">\r                   <this />\r               </type>\r        </target>\r\r     <target interface="org.simantics.layer0.utils.triggers.ITrigger">\r      <type uri = "http://www.simantics.org/Sysdyn-0.0/DiagramToCompositeMapping"\r          class = "org.simantics.sysdyn.ui.editor.DiagramToCompositeMapping3">\r         <graph/>\r           <this />\r       </type>\r        </target>\r      \r       <target interface="org.simantics.structural.ui.modelBrowser.nodes.AbstractNode">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                    class="org.simantics.structural.ui.modelBrowser.nodes.ModelNode">\r                      <this />\r               </type>\r        </target>               \r               \r\r      <target\r                interface="org.simantics.browsing.ui.common.node.AbstractNode">\r                <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                  class="org.simantics.sysdyn.ui.browser.nodes.ModelNode">\r                       <this />\r               </type>\r\r               <resource\r                      uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                 class="org.simantics.sysdyn.ui.browser.nodes.SymbolNode">\r                      <this />\r               </resource>\r\r           <type\r                  uri="http://www.simantics.org/Simulation-1.0/Experiment"\r                       class="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode">\r                  <this />\r               </type>\r                \r               <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/Result"\r                       class="org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode">\r                    <this />\r               </type>\r                \r       </target>\r\r     <!-- Inject default connection routing algorithm for sysdyn diagrams -->\r       <target interface="org.simantics.g2d.diagram.DiagramClass">\r            <adapter uri="http://www.simantics.org/Sysdyn-0.0/ConfigurationDiagram"\r                        adapterClass="org.simantics.sysdyn.ui.elements2.ConfigurationDiagramClassAdapter" />\r   </target>\r\r     <!-- Sysdyn symbols -->\r        <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.StockFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                       class="org.simantics.sysdyn.ui.elements2.ModuleFactory" />\r             <resource uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.ValveFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                    class="org.simantics.sysdyn.ui.elements2.AuxiliaryFactory" />\r          <resource uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.CloudFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.InputFactory" />\r\r             <type uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.StockFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                   class="org.simantics.sysdyn.ui.elements2.ModuleFactory" />\r             <type uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.ValveFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                        class="org.simantics.sysdyn.ui.elements2.AuxiliaryFactory" />\r          <type uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.CloudFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.InputFactory" />                       \r       </target>\r      \r       <!-- Sysdyn connections -->\r    <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <!-- Edges -->       \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowEdgeFactory" />\r        <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowEdgeFactory" />            \r        <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowConnectionFactory">\r            <graph/>\r        </type>                       \r                       \r               <resource uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                       class="org.simantics.sysdyn.ui.elements2.connections.DependencyEdgeFactory" />\r         <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements2.connections.DependencyEdgeFactory" />\r         <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements2.connections.DependencyConnectionFactory" />\r   </target>\r      \r       <target interface="org.simantics.g2d.connection.EdgeVisualsConfigurer">\r          <baseType uri="http://www.simantics.org/Diagram-0.0/HasConnector" />\r   <resource uri="http://www.simantics.org/Diagram-0.0/HasPlainConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>none 0</string>\r       </resource>\r    <resource uri="http://www.simantics.org/Diagram-0.0/HasArrowConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>fill 1</string>\r       </resource>\r  </target>\r      \r       <!-- ModelBrowser2 -->\r \r       <target interface="org.simantics.browsing.ui.model.children.ChildRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleTypeChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleTypeChildRule"/>\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleContentChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleContentChildRule"/>     \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ChartAxisAndVariablesBrowseContext/AxisChildRule"\r            class="org.simantics.sysdyn.ui.trend.chart.graphexplorer.AxisChildRule"/>     \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ChartAxisAndVariablesBrowseContext/VariableChildRule"\r            class="org.simantics.sysdyn.ui.trend.chart.graphexplorer.VariableChildRule"/>        \r    </target>\r    \r    <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleTypeLabelRule"\r            class="org.simantics.sysdyn.ui.browser.labelrules.ModuleTypeLabelRule"/>\r    </target>    \r    \r    <target interface="org.simantics.db.layer0.adapter.ActionFactory">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewModuleType"\r            class="org.simantics.sysdyn.ui.browser.actions.NewModuleTypeAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewEnumeration"\r            class="org.simantics.sysdyn.ui.browser.actions.NewEnumerationAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/OpenWorkbook"\r            class="org.simantics.sysdyn.ui.browser.actions.OpenWorkbookAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewFunction"\r            class="org.simantics.sysdyn.ui.browser.actions.NewFunctionAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.NewFunctionLibraryAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewSharedFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.NewSharedFunctionLibraryAction" />            \r    </target>              \r  \r  <!-- PROFILES -->\r    <target interface="org.simantics.scenegraph.profile.Style">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/SimulationPlaybackStyle"\r            class="org.simantics.sysdyn.ui.elements2.profiles.SimulationPlaybackStyle">\r        </resource>\r                <resource uri="http://www.simantics.org/Sysdyn-0.0/IssueStyle"\r            class="org.simantics.sysdyn.ui.elements2.profiles.IssueDecorationStyle">\r        </resource>\r    </target>\r    \r  <!-- Charts -->\r    <target interface="org.simantics.sysdyn.ui.trend.chart.IJFreeChart">\r        <type uri="http://www.simantics.org/JFreeChart-1.0/Chart"\r            class="org.simantics.sysdyn.ui.trend.chart.JFreeChart">\r            <graph />\r            <this />\r        </type>\r    </target>  \r    \r    <target interface="org.simantics.sysdyn.ui.trend.chart.IDataset">\r        <type uri="http://www.simantics.org/JFreeChart-1.0/XYDataset"\r            class="org.simantics.sysdyn.ui.trend.chart.XYDataset">\r            <graph />\r            <this />\r        </type>\r    </target>\r    \r     <target interface="org.simantics.sysdyn.ui.trend.chart.ITitle">\r        <type uri="http://www.simantics.org/JFreeChart-1.0/TextTitle"\r            class="org.simantics.sysdyn.ui.trend.chart.TextTitle">\r            <graph />\r            <this />\r        </type>\r    </target>\r    \r    <target interface="org.simantics.sysdyn.ui.trend.chart.IAxis">\r        <type uri="http://www.simantics.org/JFreeChart-1.0/NumberAxis"\r            class="org.simantics.sysdyn.ui.trend.chart.NumberAxis">\r            <graph />\r            <this />\r        </type>\r    </target>\r       \r    <target interface="org.simantics.sysdyn.ui.trend.chart.IPlot">\r        <type uri="http://www.simantics.org/JFreeChart-1.0/XYPlot"\r            class="org.simantics.sysdyn.ui.trend.chart.XYPlot">\r            <graph />\r            <this />\r        </type>\r    </target>\r       \r
 </adapters>
\ No newline at end of file
index 2eedf70dc720c5a9fa4405e35b99947da113abc4..dc462d7c02a6f51392facd65efe4ba3cabfb0a01 100644 (file)
                   </with>\r
                </visibleWhen>\r
             </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newChart"\r
+                  id="org.simantics.sysdyn.ui.browser.newChart"\r
+                  label="Chart"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ChartsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
          </menu>\r
          <dynamic\r
                class="org.simantics.ui.contribution.OpenWithMenuContribution"\r
             id="org.simantics.sysdyn.ui.chartPanelOrientation"\r
             name="Chart Panel Orientation">\r
       </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewChartHandler"\r
+            id="org.simantics.sysdyn.ui.newChart"\r
+            name="New Chart">\r
+      </command>\r
    </extension>\r
    <extension\r
          point="org.eclipse.ui.handlers">\r
                class="org.simantics.sysdyn.ui.browser.contributions.Book"\r
                preference="2.0">\r
          </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.Charts"\r
+               preference="2.0">\r
+         </implementation>\r
       </binding>\r
       <binding browseContext="http://www.simantics.org/Sysdyn-0.0/SysdynOperationBrowser">\r
         <implementation class="org.simantics.sysdyn.ui.property.OperationProjectContributor" preference="1.0"/>\r
                class="org.simantics.sysdyn.ui.browser.contributions.SheetLabeler"\r
                preference="2.0">\r
          </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ChartLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ChartsLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
       </binding>\r
       <binding browseContext="http://www.simantics.org/Sysdyn-0.0/SysdynOperationBrowser">\r
         <implementation class="org.simantics.sysdyn.ui.property.OperationModelLabels" preference="1.0"/>\r
                class="org.simantics.sysdyn.ui.browser.contributions.SimulationResultImager"\r
                preference="2.0">\r
          </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ChartImager"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ChartsImager"\r
+               preference="2.0">\r
+         </implementation>\r
       </binding>\r
       <binding browseContext="http://www.simantics.org/Sysdyn-0.0/SysdynOperationBrowser">\r
 <!--        <implementation class="org.simantics.sysdyn.ui.property.LibraryVariableImager" preference="2.0"/> -->\r
       </doubleClickAction>\r
       <doubleClickAction\r
             class="org.simantics.sysdyn.ui.actions.ShowInstantiatedModuleAction"\r
-            name="Consume unnecessary enters"\r
+            name="Show instantiated module"\r
             priority="100.0">\r
       </doubleClickAction>\r
    </extension>\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java
new file mode 100644 (file)
index 0000000..6cc2a41
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.simantics.browsing.ui.swt.ImagerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartNode;\r
+\r
+/**\r
+ * Provides image for {@link ChartNode} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartImager extends ImagerContributor<ChartNode> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, ChartNode input) throws DatabaseException {\r
+        return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_organisation.png"));\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java
new file mode 100644 (file)
index 0000000..5593683
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartNode;\r
+\r
+/**\r
+ * Provides label for {@link ChartNode} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartLabeler extends LabelerContributor<ChartNode> {\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, ChartNode chart) throws DatabaseException {\r
+        String name = graph.getPossibleRelatedValue(chart.data, Layer0.getInstance(graph).HasName);\r
+        return name == null ? "Chart (no name)" : name;\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java
new file mode 100644 (file)
index 0000000..766aec6
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+\r
+/**\r
+ * Class for creating chart nodes for model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Charts extends ViewpointContributor<ChartsFolder> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, ChartsFolder folder) throws DatabaseException {\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        for(Resource chart : graph.syncRequest(\r
+                new ObjectsWithType(folder.data,\r
+                        Layer0.getInstance(graph).ConsistsOf, \r
+                        JFreeChartResource.getInstance(graph).Chart))) {\r
+            result.add(new ChartNode(chart));\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java
new file mode 100644 (file)
index 0000000..e51b8e7
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.simantics.browsing.ui.swt.ImagerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+\r
+/**\r
+ * Provides image for {@link ChartsFolder} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartsImager extends ImagerContributor<ChartsFolder> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, ChartsFolder chartNode) throws DatabaseException {\r
+        return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/folder.png"));\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.java
new file mode 100644 (file)
index 0000000..fe718b2
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+\r
+/**\r
+ * Provides label for {@link ChartsFolder} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartsLabeler extends LabelerContributor<ChartsFolder> {\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, ChartsFolder input) throws DatabaseException {\r
+        return "Charts";\r
+    }\r
+\r
+}\r
index 1d50d2f1d3b19199e76b45ab0228467956427c90..01c21fb1218468f7e9cc330598fc7842ee87b1e7 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
  * Industry THTH ry.\r
  * All rights reserved. This program and the accompanying materials\r
  * are made available under the terms of the Eclipse Public License v1.0\r
@@ -23,12 +23,18 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.variable.Variable;\r
 import org.simantics.db.layer0.variable.Variables;\r
 import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
 import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode;\r
 import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder;\r
 import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder;\r
 import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
 import org.simantics.sysdyn.ui.browser.nodes.ModulesNode;\r
 \r
+/**\r
+ * Provides children for a model in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class Model  extends ViewpointContributor<ModelNode> {\r
 \r
     @Override\r
@@ -49,6 +55,7 @@ public class Model  extends ViewpointContributor<ModelNode> {
         result.add(new ExperimentsFolder(model.data));\r
         result.add(new ModulesNode(model.data));\r
         result.add(new FunctionsFolder(model.data));\r
+        result.add(new ChartsFolder(model.data));\r
         return result;\r
     }\r
 \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartNode.java
new file mode 100644 (file)
index 0000000..a51a9e4
--- /dev/null
@@ -0,0 +1,94 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import java.util.Iterator;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.IDropTargetNode;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.SingleObjectWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Node representing a chart\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartNode extends AbstractNode<Resource> implements IDropTargetNode {\r
+\r
+    public ChartNode(Resource data) {\r
+        super(data);\r
+    }\r
+\r
+    /**\r
+     * Add variable to this chart, if the dropped element(s) can be adapted to a {@link Variable} \r
+     */\r
+    @Override\r
+    public void drop(Object data) {\r
+        IStructuredSelection selection = (IStructuredSelection)data;\r
+        Iterator<?> iterator = selection.iterator();\r
+        while(iterator.hasNext()) {\r
+            Object o = iterator.next();\r
+            if(o instanceof IAdaptable) {\r
+                Variable v = (Variable) ((IAdaptable)o).getAdapter(Variable.class);\r
+                if(v != null) {\r
+                    addVariableToChart(v);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Adds a variable to this chart\r
+     * @param variable\r
+     */\r
+    private void addVariableToChart(final Variable variable) {\r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                Layer0 l0 = Layer0.getInstance(graph);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+                Resource plot = graph.syncRequest(new SingleObjectWithType(data, l0.ConsistsOf, jfree.Plot));\r
+\r
+                Resource dataset = graph.syncRequest(new SingleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); //FIXME: Support multiple datasets\r
+\r
+                String rvi = Variables.getRVI(graph, variable);\r
+                Resource type = l0.String;\r
+                Resource literal = graph.newResource();\r
+                graph.claim(literal, l0.InstanceOf, null, type);\r
+                graph.claimValue(literal, rvi, Bindings.STRING); \r
+                \r
+                GraphUtils.create2(graph, jfree.Series,\r
+                        l0.HasLabel, rvi,\r
+                        jfree.HasVariableRVI, literal,\r
+                        l0.PartOf, dataset);\r
+            }\r
+        });\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.java
new file mode 100644 (file)
index 0000000..d75b01b
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+\r
+/**\r
+ * Folder containing all sysdyn charts\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartsFolder extends AbstractNode<Resource> {\r
+\r
+    public ChartsFolder(Resource resource) {\r
+        super(resource);\r
+    }\r
+    \r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(clazz == adapter) // There is no resource for this node..\r
+            return null;\r
+        return super.getAdapter(adapter);\r
+    }\r
+\r
+}\r
index 66c366222a42e95fe0816435e16cab1b5433eef5..91084b6c83befb064e7fd0f39d47fb8f25b4ab4d 100644 (file)
@@ -11,7 +11,6 @@
  *******************************************************************************/\r
 package org.simantics.sysdyn.ui.elements2.profiles;\r
 \r
-//import java.awt.Color;\r
 import java.awt.geom.AffineTransform;\r
 import java.awt.geom.Rectangle2D;\r
 import java.util.ArrayList;\r
@@ -48,15 +47,27 @@ import org.simantics.utils.ui.color.Color;
 import org.simantics.utils.ui.color.ColorGradient;\r
 import org.simantics.utils.ui.color.ColorValue;\r
 \r
+/**\r
+ * Profile style definition for simulation playback mode. Works only with SimulationPlaybackExperiment\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, Double, ColorGradient>> {\r
     \r
     Resource gradientResource;\r
     ColorGradient cg;\r
     byte[] gradient;\r
     \r
+    /**\r
+     * Determine if style needs to be redrawn and return objects that are needed to redraw the style.\r
+     * \r
+     * @return All necessary components that are needed to draw this style\r
+     */\r
     @Override\r
     public Triple<AffineTransform, Double, ColorGradient> calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
         \r
+        // Find SimulationPlaybackExperiment\r
         IProject project = SimanticsUI.getProject();\r
         IExperimentManager em = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
         IExperiment experiment = em.getActiveExperiment();\r
@@ -74,6 +85,7 @@ public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, D
 \r
         try {\r
 \r
+            // Find Variable for this component\r
             String dv = graph.getPossibleRelatedValue(runtimeDiagram, dr.RuntimeDiagram_HasVariable);\r
             Variable rootVariable = graph.getPossibleAdapter(graph.getRootLibrary(), Variable.class);\r
             if (rootVariable == null) \r
@@ -86,21 +98,25 @@ public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, D
             if(var == null)\r
                 return null;\r
             \r
-            Double[] va = var.getPossiblePropertyValue(graph, SysdynVariableProperties.VALUES , Bindings.DOUBLE_ARRAY);\r
+            // Get simulation rsult values for this component\r
+            double[] va = var.getPossiblePropertyValue(graph, SysdynVariableProperties.VALUES , Bindings.DOUBLE_ARRAY);\r
             if(va == null || va.length < 2)\r
                 return null;\r
             \r
-            Double[] ta = var.getPossiblePropertyValue(graph, SysdynVariableProperties.TIMES , Bindings.DOUBLE_ARRAY);\r
+            // Get simulation timesteps for this component\r
+            double[] ta = var.getPossiblePropertyValue(graph, SysdynVariableProperties.TIMES , Bindings.DOUBLE_ARRAY);\r
             if(ta == null || ta.length < 2)\r
                 return null;\r
             \r
             if(va.length == 0 || va.length == 2)\r
                 return null;\r
             \r
+            // Get playback time from the experiment\r
             Double time = var.getPossiblePropertyValue(graph, SysdynVariableProperties.TIME , Bindings.DOUBLE);\r
             if(time == null)\r
                 return null;\r
             \r
+            // Find minimum and maximum values for this variable\r
             double min = va[0], max = va[0];\r
             for(double d : va) {\r
                 if(d < min) \r
@@ -108,7 +124,9 @@ public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, D
                 if(d > max)\r
                     max = d;\r
             }\r
-            \r
+           \r
+            // Find the index in time and value arrays for this time \r
+            // (time steps may vary, we need to loop to find the correct time) \r
             int index = 0;\r
             if(ta[ta.length - 1] - time > ta[ta.length / 2] ) {\r
                 index = ta.length - 1;\r
@@ -121,10 +139,14 @@ public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, D
             \r
             double value = va[index];\r
             \r
+            // Calculate where the value is located between min and max values [0..1].   \r
             double multiplier = (value - min) / (max - min);\r
 \r
+            \r
+            // Get the transform of this element\r
             AffineTransform at = (AffineTransform) DiagramGraphUtil.getAffineTransform(graph, element,  G2DResource.getInstance(graph).HasTransform, true).clone();\r
             \r
+            // Find the gradient used to draw this style\r
             G2DResource g2d = G2DResource.getInstance(graph);\r
             Resource gradient = graph.getPossibleObject(experiment.getResource(), g2d.HasColorGradient);\r
             if(this.gradientResource == null || !this.gradientResource.equals(gradient)) {\r
@@ -158,12 +180,15 @@ public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, D
         observer.update();\r
     }\r
 \r
+    /**\r
+     * Apply style\r
+     */\r
     @Override\r
     public void applyStyleForNode(EvaluationContext observer, INode _node, Triple<AffineTransform, Double, ColorGradient> result) {\r
         Double multiplier;\r
         if (result != null && (multiplier = result.second) != null && !multiplier.isNaN()) {\r
             \r
-            \r
+            // Create a node that will show the style effect\r
             A node = ProfileVariables.claimChild(_node, "", "playbackColour", A.class, observer);\r
             if (node == null)\r
                 return;\r
@@ -174,28 +199,34 @@ public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, D
                 this.cg = result.third;\r
                 this.gradient = cg.getGradientArray(101);\r
             }\r
+            \r
+            // Get integer values for red, green and blue\r
             int i = (int)(multiplier * 100);\r
             int r = (int)(gradient[i * 3 + 0]  & 0xff);\r
             int g = (int)(gradient[i * 3 + 1]  & 0xff);\r
             int b = (int)(gradient[i * 3 + 2]  & 0xff);\r
-\r
+            // Get color with r, g and b\r
             java.awt.Color c = new java.awt.Color(r, g, b, 200);\r
 \r
-            int zIndex = -1;\r
+            // Create a node for the style\r
             INode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class);\r
+            Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(n), 0.0);\r
+            node.setFill(true);\r
+            node.setColor(c);\r
+            node.setStroke(null);\r
+            node.setValue("shape", expandedElementBounds);\r
+            node.setTransform(at);\r
+            \r
+            // Find z-index for the TextNode associated with the element and place the style node just below that text node \r
+            int zIndex = -1;\r
             if(n != null) {\r
                 at = ((TextNode)n).getTransform();\r
                 zIndex = ((TextNode)n).getZIndex() - 1;\r
             } else {\r
                 n = _node;\r
             }\r
-            Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(n), 0.0);\r
             node.setZIndex(zIndex);\r
-            node.setFill(true);\r
-            node.setColor(c);\r
-            node.setStroke(null);\r
-            node.setValue("shape", expandedElementBounds);\r
-            node.setTransform(at);\r
+\r
 \r
         } else {\r
             cleanupStyleForNode(_node);\r
@@ -208,7 +239,12 @@ public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, D
     }\r
     \r
     \r
-    \r
+    /**\r
+     * Dummy class for displaying the style\r
+     * \r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
     public static class A extends ShapeNode {\r
 \r
         private static final long serialVersionUID = -5273246617906214956L;\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewChartHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewChartHandler.java
new file mode 100644 (file)
index 0000000..3e3582f
--- /dev/null
@@ -0,0 +1,97 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.AdaptionUtils;\r
+\r
+/**\r
+ * Handler for creating a new {@link ChartNode} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewChartHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        \r
+       ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+        ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource model = node.data;        \r
+        \r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+            \r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(g);\r
+                G2DResource g2d = G2DResource.getInstance(g);\r
+\r
+                Resource title = GraphUtils.create2(g, jfree.TextTitle,\r
+                        l0.HasLabel, "Chart Title",\r
+                        jfree.HasPosition, jfree.Top);\r
+                \r
+                Resource jfreechart = GraphUtils.create2(g, jfree.Chart,\r
+                        l0.HasName, NameUtils.findFreshName(g, "Chart", model),\r
+                        l0.PartOf, model,\r
+                        l0.ConsistsOf, title,\r
+                        jfree.HasVisibleBorder, true,\r
+                        jfree.HasBorderWidth, 3);\r
+                g.claimLiteral(jfreechart, jfree.HasBorderColor, g2d.Color, new float[] {0,0,0,1});\r
+                \r
+                Resource domainAxis = GraphUtils.create2(g, jfree.NumberAxis,\r
+                        l0.HasLabel, "domain");\r
+                Resource rangeAxis = GraphUtils.create2(g, jfree.NumberAxis,\r
+                        l0.HasLabel, "range");\r
+                \r
+                Resource dataset = GraphUtils.create2(g, jfree.XYDataset,\r
+                        jfree.MapToDomainAxis, domainAxis,\r
+                        jfree.MapToRangeAxis, rangeAxis);\r
+                \r
+                GraphUtils.create2(g, jfree.XYPlot,\r
+                        l0.PartOf, jfreechart,\r
+                        jfree.HasDomainAxis, domainAxis,\r
+                        jfree.HasRangeAxis, rangeAxis,\r
+                        l0.ConsistsOf, dataset,\r
+                        l0.ConsistsOf, domainAxis,\r
+                        l0.ConsistsOf, rangeAxis);\r
+            }\r
+            \r
+        });\r
+        \r
+        \r
+        \r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultVariable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultVariable.java
deleted file mode 100644 (file)
index 57d5245..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.sysdyn.ui.project;\r
-\r
-import java.util.List;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.Datatypes;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.utils.OrderedSetUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.variable.ResourceVariable;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.operation.Layer0X;\r
-import org.simantics.sysdyn.SysdynResource;\r
-\r
-public class DefaultVariable extends ResourceVariable {\r
-\r
-       public DefaultVariable(Resource resource) {\r
-               super(resource);\r
-       }\r
-\r
-       @SuppressWarnings("unchecked")\r
-       @Override\r
-       public <T> T getValue(ReadGraph graph) throws DatabaseException {\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-               SysdynResource sr = SysdynResource.getInstance(graph);\r
-               Resource represents = graph.getPossibleObject(resource, L0X.Represents);\r
-               if(represents == null) return null;\r
-               //FIXME: doesn't support multiple expressions\r
-               Resource expressions = graph.getPossibleObject(represents, sr.HasExpressions);\r
-               if(expressions == null) return null;\r
-               List<Resource> expressionList = OrderedSetUtils.toList(graph, expressions);\r
-               Resource expression = expressionList.get(0);\r
-               if(expression == null) return null;\r
-               if(!graph.isInstanceOf(expression, sr.ParameterExpression)) return null;\r
-               String text = graph.getPossibleRelatedValue(expression, sr.HasEquation);\r
-               if(text == null) return null;\r
-               Double value = Double.parseDouble(text); \r
-               return (T)value;\r
-       }\r
-\r
-       @Override\r
-       public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
-               if(!Bindings.DOUBLE.equals(binding)) return null;\r
-               return getValue(graph);\r
-       }\r
-       \r
-       @Override\r
-       public void setValue(WriteGraph graph, Object object, Binding binding) throws DatabaseException {\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-               SysdynResource sr = SysdynResource.getInstance(graph);\r
-//             if(!Bindings.DOUBLE.equals(binding)) return;\r
-//             if(!MutableDoubleBinding.INSTANCE.equals(binding)) return;\r
-               Resource represents = graph.getPossibleObject(resource, L0X.Represents);\r
-               if(represents == null) return;\r
-               //FIXME: doesn't support multiple expressions\r
-               Resource expressions = graph.getPossibleObject(represents, sr.HasExpressions);\r
-               if(expressions == null) return;\r
-               List<Resource> expressionList = OrderedSetUtils.toList(graph, expressions);\r
-               Resource expression = expressionList.get(0);\r
-               if(expression == null) return;\r
-               if(!graph.isInstanceOf(expression, sr.ParameterExpression)) return;\r
-               graph.claimLiteral(expression, sr.HasEquation, object.toString(), Bindings.STRING);\r
-       }\r
-       \r
-       @SuppressWarnings("unchecked")\r
-       @Override\r
-       public <T> T getInterface(ReadGraph graph, Class<T> clazz)\r
-                       throws DatabaseException {\r
-               if(Datatype.class.equals(clazz)) return (T)Datatypes.DOUBLE;\r
-               return super.getInterface(graph, clazz);\r
-       }\r
-}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryVariable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryVariable.java
deleted file mode 100644 (file)
index b7b8539..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.sysdyn.ui.project;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.databoard.Accessors;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.accessor.Accessor;\r
-import org.simantics.databoard.accessor.RecordAccessor;\r
-import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
-import org.simantics.databoard.accessor.error.AccessorException;\r
-import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.variable.ResourceVariable;\r
-import org.simantics.db.layer0.variable.Variables;\r
-import org.simantics.simulation.ontology.SimulationResource;\r
-import org.simantics.sysdyn.manager.SysdynDataSet;\r
-import org.simantics.sysdyn.manager.SysdynModel;\r
-import org.simantics.sysdyn.manager.SysdynModelManager;\r
-import org.simantics.sysdyn.manager.SysdynResult;\r
-\r
-public class HistoryVariable extends ResourceVariable {\r
-\r
-       public HistoryVariable(Resource resource) {\r
-               super(resource);\r
-       }\r
-       \r
-//     @Override\r
-//     public <T> T getInterface(ReadGraph graph, Class<T> clazz) throws DatabaseException {\r
-//             if(Accessor.class.equals(clazz)) {\r
-//\r
-//                     SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-//                     Resource model = Variables.getModel(graph, this);\r
-//                     Resource configuration = graph.getPossibleObject(model, SIMU.HasConfiguration);\r
-//                     SysdynModel sm = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configuration);\r
-//                     SysdynResult sr = sm.getSysdynResult();\r
-//                     String rvi = Variables.getRVI(graph, this);\r
-//                     System.out.println("HistoryVariable rvi='" + rvi + "'");\r
-//                     rvi = rvi.substring(1).replace("/", ".");\r
-//                     SysdynDataSet ds = sr.getDataSet(rvi);\r
-//                     \r
-//                     try {\r
-//                             return (T)Accessors.getAccessor(Bindings.getBindingUnchecked(SysdynDataSet.class), ds);\r
-//                     } catch (RuntimeBindingConstructionException e) {\r
-//                             e.printStackTrace();\r
-//                     } catch (AccessorConstructionException e) {\r
-//                             e.printStackTrace();\r
-//                     }\r
-//                     return null;\r
-//                     \r
-//             }\r
-//             return super.getInterface(graph, clazz);\r
-//     }\r
-       \r
-       @SuppressWarnings("unchecked")\r
-       @Override\r
-       public <T> T getInterface(ReadGraph graph, Class<T> clazz) throws DatabaseException {\r
-               if(RecordAccessor.class.equals(clazz) || Accessor.class.equals(clazz)) {\r
-                       SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-                       Resource model = Variables.getModel(graph, this);\r
-                       Resource configuration = graph.getPossibleObject(model, SIMU.HasConfiguration);\r
-                       final SysdynModel sm = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configuration);\r
-                       SysdynResult sr = new SysdynResult(sm.getSimulationResult()); // TODO: copy or not to copy ...\r
-                       \r
-                       String tmp = Variables.getRVI(graph, this);\r
-                       System.out.println("HistoryVariable rvi='" + tmp + "'");\r
-                       final String rvi = tmp.substring(1).replace("/", ".");\r
-                       SysdynDataSet ds = sr.getDataSet(rvi);\r
-                       if(ds == null) ds = new SysdynDataSet("", "", new ArrayList<Double>(), new ArrayList<Double>()); // We need a dataset, so if not set, create it\r
-                       try {\r
-                               final RecordAccessor ac = (RecordAccessor)Accessors.getAccessor(Bindings.getBindingUnchecked(SysdynDataSet.class), ds);\r
-                               \r
-                               sm.addResultListener(new Runnable() { // FIXME: remove listener at some point..\r
-                                       @Override\r
-                                       public void run() {\r
-                                               SysdynResult sr = new SysdynResult(sm.getSimulationResult());\r
-                                               SysdynDataSet ds = sr.getDataSet(rvi);\r
-                                               if(ds == null) return;\r
-                                               try {\r
-                                                       if(ds.result == null) ds.result = "";\r
-                                                       ac.setValue(Bindings.getBindingUnchecked(SysdynDataSet.class), ds);\r
-                                               } catch (RuntimeBindingConstructionException e) {\r
-                                                       // TODO Auto-generated catch block\r
-                                                       e.printStackTrace();\r
-                                               } catch (AccessorException e) {\r
-                                                       // TODO Auto-generated catch block\r
-                                                       e.printStackTrace();\r
-                                               }\r
-                                       }});\r
-                               return (T)ac;\r
-                       } catch (RuntimeBindingConstructionException e) {\r
-                               e.printStackTrace();\r
-                       } catch (AccessorConstructionException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-                       return null;\r
-                       \r
-               }\r
-               return super.getInterface(graph, clazz);\r
-       }\r
-}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModelTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModelTab.java
deleted file mode 100644 (file)
index 77ea180..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.sysdyn.ui.properties;\r
-\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.ui.IWorkbenchSite;\r
-import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
-import org.simantics.db.management.ISessionContext;\r
-\r
-public class ModelTab extends LabelPropertyTabContributor {\r
-\r
-    @Override\r
-    public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
-        \r
-    }\r
-}\r
index c453dd7964c8ac843bd7dcd66550822666bf8d9e..d0f4851d2d2e338e40468a506f2efcba456e8fb5 100644 (file)
@@ -29,263 +29,313 @@ import org.simantics.modeling.ModelingResources;
 import org.simantics.selectionview.ComparableTabContributor;\r
 import org.simantics.selectionview.SelectionProcessor;\r
 import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
 import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder;\r
+import org.simantics.sysdyn.ui.trend.chart.properties.ChartAxisAndVariablesTab;\r
+import org.simantics.sysdyn.ui.trend.chart.properties.ChartTab;\r
+import org.simantics.sysdyn.ui.trend.chart.properties.GeneralChartPropertiesTab;\r
 import org.simantics.ui.utils.AdaptionUtils;\r
 \r
+/**\r
+ * SelectionProcessor for processing selections for property view in system dynamics\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class ResourceSelectionProcessor implements SelectionProcessor<Object, ReadGraph>  {\r
 \r
-       @Override\r
-       public Collection<?> process(Object selection, ReadGraph backend) {\r
-               Collection<ComparableTabContributor> tabs = new ArrayList<ComparableTabContributor>();\r
-               SysdynResource sr = SysdynResource.getInstance(backend);\r
-               DiagramResource dr = DiagramResource.getInstance(backend);\r
-               ModelingResources mr = ModelingResources.getInstance(backend);\r
-               SimulationResource simu = SimulationResource.getInstance(backend);\r
+    @Override\r
+    public Collection<?> process(Object selection, ReadGraph backend) {\r
+        Collection<ComparableTabContributor> tabs = new ArrayList<ComparableTabContributor>();\r
+        SysdynResource sr = SysdynResource.getInstance(backend);\r
+        DiagramResource dr = DiagramResource.getInstance(backend);\r
+        ModelingResources mr = ModelingResources.getInstance(backend);\r
+        SimulationResource simu = SimulationResource.getInstance(backend);\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(backend);\r
+\r
+        try {\r
+            // Many elements \r
+            if (selection instanceof ArrayList<?> && ((ArrayList<?>) selection).size() > 1) {\r
+                List<Resource> independentVariables = new ArrayList<Resource>();\r
+                Resource model = null;\r
+                for(Object o : (ArrayList<?>)selection) {\r
+                    Resource r = AdaptionUtils.adaptToSingle(o, Resource.class);\r
+                    if(r != null && backend.isInstanceOf(r, sr.IndependentVariable)) {\r
+                        if(model == null)\r
+                            model = backend.getSingleObject(r, Layer0.getInstance(backend).PartOf);\r
+                        if(model.equals( backend.getSingleObject(r, Layer0.getInstance(backend).PartOf)))\r
+                            independentVariables.add(r);\r
+                    }\r
+                }\r
+\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ArrayIndexesTab(),\r
+                        1,\r
+                        independentVariables,\r
+                        "Indexes"));\r
+\r
+                return tabs;\r
+            }\r
+\r
+\r
+            // Single element\r
+            Resource r = AdaptionUtils.adaptToSingle(selection, Resource.class);\r
+\r
+            if(r == null) {\r
+                // SharedFunctionsFolder has properties but no adapted resource\r
+                SharedFunctionsFolder sff = AdaptionUtils.adaptToSingle(selection, SharedFunctionsFolder.class);\r
+                if (sff != null) {\r
+                    return Collections.singleton(new ComparableTabContributor(\r
+                            new SharedFunctionLibrariesTab(),\r
+                            2,\r
+                            sff.data,\r
+                            "Shared Functions"));\r
+                }\r
 \r
-               try {\r
-                       // Many elements \r
-                       if (selection instanceof ArrayList<?> && ((ArrayList<?>) selection).size() > 1) {\r
-                               List<Resource> independentVariables = new ArrayList<Resource>();\r
-                               Resource model = null;\r
-                               for(Object o : (ArrayList<?>)selection) {\r
-                                       Resource r = AdaptionUtils.adaptToSingle(o, Resource.class);\r
-                                       if(r != null && backend.isInstanceOf(r, sr.IndependentVariable)) {\r
-                                               if(model == null)\r
-                                                       model = backend.getSingleObject(r, Layer0.getInstance(backend).PartOf);\r
-                                               if(model.equals( backend.getSingleObject(r, Layer0.getInstance(backend).PartOf)))\r
-                                                       independentVariables.add(r);\r
-                                       }\r
-                               }\r
+                return Collections.emptyList();\r
+            }\r
 \r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new ArrayIndexesTab(),\r
-                                               1,\r
-                                               independentVariables,\r
-                                               "Indexes"));\r
-                               \r
-                               return tabs;\r
-                       }\r
 \r
+            // if r == diagram element, change it to component\r
+            if (backend.isInstanceOf(r, dr.Element)) {\r
+                Resource component = backend.getPossibleObject(r, mr.ElementToComponent);\r
+                if (component != null) {\r
+                    r = component;\r
+                } else {\r
+                    Resource connection = backend.getPossibleObject(r, mr.DiagramConnectionToConnection);\r
+                    if(connection != null)\r
+                        r = connection;\r
+                }\r
+            }\r
+            \r
+            // Independent variable\r
+            if (backend.isInstanceOf(r, sr.IndependentVariable)) {\r
+                Resource activeExpression = backend.getPossibleObject(r, sr.HasActiveExpression);\r
+                Resource expression = null;\r
+                if(activeExpression != null)\r
+                    // if variable has active expression, display it\r
+                    expression = activeExpression;\r
+                else if (backend.hasStatement(r, sr.HasExpressions)){\r
+                    // else display the first expression of the variable\r
+                    Resource expressions = backend.getPossibleObject(r, sr.HasExpressions);\r
+                    List<Resource> expressionList = OrderedSetUtils.toList(backend, expressions);\r
+                    if(expressionList.isEmpty()) {\r
+                        System.err.println("expressionList is empty for " + r);\r
+                        return Collections.emptyList();\r
+                    }\r
+                    expression = expressionList.get(0);\r
+                }\r
+                tabs.add(new ComparableTabContributor(\r
+                        new EquationTab(),\r
+                        3,\r
+                        r,\r
+                        "Equation"));\r
+                if(expression != null && backend.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+                    // WithLookupExpression has its own extra tab for visual configuration\r
+                    tabs.add(new ComparableTabContributor(\r
+                            new LookupTableTab(),\r
+                            2,\r
+                            expression,\r
+                            "Lookup Table"));\r
+                }\r
 \r
-                       // Single element\r
-                       Resource r = AdaptionUtils.adaptToSingle(selection, Resource.class);\r
-                       \r
-                       if(r == null) {\r
-                               SharedFunctionsFolder sff = AdaptionUtils.adaptToSingle(selection, SharedFunctionsFolder.class);\r
-                               if (sff != null) {\r
-                                       return Collections.singleton(new ComparableTabContributor(\r
-                                                       new SharedFunctionLibrariesTab(),\r
-                                                       2,\r
-                                                       sff.data,\r
-                                       "Shared Functions"));\r
-                               }\r
-                               \r
-                               return Collections.emptyList();\r
-                       }\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ArrayIndexesTab(),\r
+                        1,\r
+                        r,\r
+                        "Indexes"));\r
 \r
+                tabs.add(new ComparableTabContributor(\r
+                        new VariableInformationTab(),\r
+                        0,\r
+                        r,\r
+                        "Additional Information"));\r
+                return tabs;\r
+            }\r
+            \r
+            // Input variable\r
+            if (backend.isInstanceOf(r, sr.Input)) {\r
+                tabs.add(new ComparableTabContributor(\r
+                        new InputVariableTab(),\r
+                        2,\r
+                        r,\r
+                        "Input"));\r
 \r
-                       if (backend.isInstanceOf(r, dr.Element)) {\r
-                               Resource component = backend.getPossibleObject(r, mr.ElementToComponent);\r
-                               if (component != null) {\r
-                                       r = component;\r
-                               } else {\r
-                                       Resource connection = backend.getPossibleObject(r, mr.DiagramConnectionToConnection);\r
-                                       if(connection != null)\r
-                                               r = connection;\r
-                               }\r
-                       }\r
-                       if (backend.isInstanceOf(r, sr.IndependentVariable)) {\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ArrayIndexesTab(),\r
+                        1,\r
+                        r,\r
+                        "Indexes"));\r
 \r
+                tabs.add(new ComparableTabContributor(\r
+                        new VariableInformationTab(),\r
+                        0,\r
+                        r,\r
+                        "Additional Information"));\r
+                return tabs;\r
+            }\r
+            \r
+            // Enumeration\r
+            if (backend.isInstanceOf(r, sr.Enumeration)) {\r
+                Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class);\r
+                if(s == null)\r
+                    s = r;\r
+                // give either variable or the actual resource\r
+                return Collections.singleton(new ComparableTabContributor(\r
+                        new EnumerationTab(),\r
+                        2,\r
+                        s,\r
+                        "Enumeration"));\r
+            }\r
+            \r
+            // Configuration and model. They both show the properties of the configuration\r
+            if ( backend.isInstanceOf(r, sr.Configuration) || backend.isInstanceOf(r, sr.SysdynModel)) {\r
+                if(!backend.isInstanceOf(r, sr.SysdynModel))\r
+                    r = backend.getPossibleObject(r, SimulationResource.getInstance(backend).IsConfigurationOf);\r
+                if (r != null)\r
+                    return Collections.singleton(\r
+                            new ComparableTabContributor(\r
+                                    new ConfigurationTab(),\r
+                                    0,\r
+                                    r,\r
+                                    "Model Properties"));\r
+            }\r
+            \r
+            // Module\r
+            if (backend.isInstanceOf(r, sr.Module)){\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ModuleTab(),\r
+                        3,\r
+                        r,\r
+                        "Module Properties"));\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ModuleInputTab(),\r
+                        2,\r
+                        r,\r
+                        "Inputs"));\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ModuleOutputTab(),\r
+                        1,\r
+                        r,\r
+                        "Outputs"));\r
+                return tabs;\r
+            }\r
+            \r
+            // Playback experiment\r
+            if (backend.isInstanceOf(r, sr.PlaybackExperiment))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new PlaybackExperimentTab(),\r
+                                0,\r
+                                r,\r
+                                "Experiment Properties"));\r
+            \r
+            // Default experiment\r
+            if (backend.isInstanceOf(r, simu.Experiment))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new ExperimentTab(),\r
+                                0,\r
+                                r,\r
+                                "Experiment Properties"));\r
+            \r
+            // Saved simulation result\r
+            if (backend.isInstanceOf(r, sr.Result))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new ResultTab(),\r
+                                0,\r
+                                r,\r
+                                "Result Properties"));\r
+            \r
+            // Dependency\r
+            if (backend.isInstanceOf(r, sr.Dependency))\r
+                if (backend.hasStatement(r, sr.RefersTo))\r
+                    return Collections.singleton(\r
+                            new ComparableTabContributor(\r
+                                    new ReferenceDependencyTab(),\r
+                                    0,\r
+                                    r,\r
+                                    "Reference Properties"));\r
+                else {\r
+                    Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
+                    return Collections.singleton(\r
+                            new ComparableTabContributor(\r
+                                    new DependencyTab(),\r
+                                    0,\r
+                                    diaConnection,\r
+                                    "Dependency Properties"));\r
+                }\r
+            \r
+            // Module symbol. Modules in modules-folder are actually symbol resources\r
+            if (backend.isInheritedFrom(r, sr.ModuleSymbol)) {\r
+                // Find the component resource\r
+                r =  backend.getPossibleObject(r, mr.SymbolToComponentType);\r
+                if(r != null)\r
+                    return Collections.singleton(\r
+                            new ComparableTabContributor(\r
+                                    new ModuleTypeTab(),\r
+                                    0,\r
+                                    r,\r
+                                    "Module Type Properties"));\r
+            }\r
 \r
-                               Resource activeExpression = backend.getPossibleObject(r, sr.HasActiveExpression);\r
-                               Resource expression = null;\r
-                               if(activeExpression != null)\r
-                                       expression = activeExpression;\r
-                               else if (backend.hasStatement(r, sr.HasExpressions)){\r
-                                       Resource expressions = backend.getPossibleObject(r, sr.HasExpressions);\r
-                                       List<Resource> expressionList = OrderedSetUtils.toList(backend, expressions);\r
-                                       if(expressionList.isEmpty()) {\r
-                                               System.err.println("expressionList is empty for " + r);\r
-                                               return Collections.emptyList();\r
-                                       }\r
-                                       expression = expressionList.get(0);\r
-                               }\r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new EquationTab(),\r
-                                               3,\r
-                                               r,\r
-                               "Equation"));\r
-                               if(expression != null && backend.isInstanceOf(expression, sr.WithLookupExpression)) {\r
-                                       tabs.add(new ComparableTabContributor(\r
-                                                       new LookupTableTab(),\r
-                                                       2,\r
-                                                       expression,\r
-                                       "Lookup Table"));\r
-                               }\r
+            // Function\r
+            if (backend.isInstanceOf(r, sr.SysdynModelicaFunction)) {\r
+                tabs.add(new ComparableTabContributor(\r
+                        new FunctionTab(),\r
+                        2,\r
+                        r,\r
+                        "Function"));\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ExternalFilesTab(),\r
+                        1,\r
+                        r,\r
+                        "External files"));\r
+                return tabs;\r
+            }\r
 \r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new ArrayIndexesTab(),\r
-                                               1,\r
-                                               r,\r
-                               "Indexes"));\r
+            // Function library\r
+            if (backend.isInstanceOf(r, sr.SysdynModelicaFunctionLibrary)) {\r
+                Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class);\r
+                if(s == null)\r
+                    s = r;\r
+                // give either variable or the actual resource\r
+                return Collections.singleton(new ComparableTabContributor(\r
+                        new FunctionLibraryTab(),\r
+                        2,\r
+                        s,\r
+                        "Function library"));\r
+            }\r
 \r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new VariableInformationTab(),\r
-                                               0,\r
-                                               r,\r
-                               "Additional Information"));\r
-                               return tabs;\r
-                       }\r
-                       if (backend.isInstanceOf(r, sr.Input)) {\r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new InputVariableTab(),\r
-                                               2,\r
-                                               r,\r
-                               "Input"));\r
-                               \r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new ArrayIndexesTab(),\r
-                                               1,\r
-                                               r,\r
-                               "Indexes"));\r
+            // Chart\r
+            if (backend.isInstanceOf(r, jfree.Chart)) {\r
+                tabs.add(new ComparableTabContributor(\r
+                        new GeneralChartPropertiesTab(),\r
+                        10,\r
+                        r,\r
+                        "General"));\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ChartAxisAndVariablesTab(),\r
+                        9,\r
+                        r,\r
+                        "Axis and Variables"));\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ChartTab(),\r
+                        1,\r
+                        r,\r
+                        "Chart"));\r
+                return tabs;\r
+            }\r
 \r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new VariableInformationTab(),\r
-                                               0,\r
-                                               r,\r
-                               "Additional Information"));\r
-                               return tabs;\r
-                       }\r
-                       if (backend.isInstanceOf(r, sr.Enumeration)) {\r
-                               Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class);\r
-                               if(s == null)\r
-                                       s = r;\r
-                               // give either variable or the actual resource\r
-                               return Collections.singleton(new ComparableTabContributor(\r
-                                               new EnumerationTab(),\r
-                                               2,\r
-                                               s,\r
-                               "Enumeration"));\r
-                       }\r
-                       if ( backend.isInstanceOf(r, sr.Configuration) || backend.isInstanceOf(r, sr.SysdynModel)) {\r
-                               if(!backend.isInstanceOf(r, sr.SysdynModel))\r
-                                       r = backend.getPossibleObject(r, SimulationResource.getInstance(backend).IsConfigurationOf);\r
-                               if (r != null)\r
-                                       return Collections.singleton(\r
-                                                       new ComparableTabContributor(\r
-                                                                       new ConfigurationTab(),\r
-                                                                       0,\r
-                                                                       r,\r
-                                                       "Model Properties"));\r
-                       }\r
-                       if (backend.isInstanceOf(r, sr.Module)){\r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new ModuleTab(),\r
-                                               3,\r
-                                               r,\r
-                               "Module Properties"));\r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new ModuleInputTab(),\r
-                                               2,\r
-                                               r,\r
-                               "Inputs"));\r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new ModuleOutputTab(),\r
-                                               1,\r
-                                               r,\r
-                               "Outputs"));\r
-                               return tabs;\r
-                       }\r
-                if (backend.isInstanceOf(r, sr.PlaybackExperiment))\r
-                       return Collections.singleton(\r
-                               new ComparableTabContributor(\r
-                                       new PlaybackExperimentTab(),\r
-                                       0,\r
-                                       r,\r
-                               "Experiment Properties"));\r
-                       if (backend.isInstanceOf(r, simu.Experiment))\r
-                               return Collections.singleton(\r
-                                               new ComparableTabContributor(\r
-                                                               new ExperimentTab(),\r
-                                                               0,\r
-                                                               r,\r
-                                               "Experiment Properties"));\r
-                       if (backend.isInstanceOf(r, sr.SysdynModel))\r
-                               return Collections.singleton(\r
-                                               new ComparableTabContributor(\r
-                                                               new ModelTab(),\r
-                                                               0,\r
-                                                               r,\r
-                                               "Model Properties"));\r
-                       if (backend.isInstanceOf(r, sr.Result))\r
-                               return Collections.singleton(\r
-                                               new ComparableTabContributor(\r
-                                                               new ResultTab(),\r
-                                                               0,\r
-                                                               r,\r
-                                               "Result Properties"));\r
-                       if (backend.isInstanceOf(r, sr.Dependency))\r
-                               if (backend.hasStatement(r, sr.RefersTo))\r
-                                       return Collections.singleton(\r
-                                                       new ComparableTabContributor(\r
-                                                                       new ReferenceDependencyTab(),\r
-                                                                       0,\r
-                                                                       r,\r
-                                                       "Reference Properties"));\r
-                               else {\r
-                                   Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
-                                       return Collections.singleton(\r
-                                                       new ComparableTabContributor(\r
-                                                                       new DependencyTab(),\r
-                                                                       0,\r
-                                                                       diaConnection,\r
-                                                       "Dependency Properties"));\r
-                               }\r
-                       if (backend.isInheritedFrom(r, sr.ModuleSymbol)) {\r
-                               r =  backend.getPossibleObject(r, mr.SymbolToComponentType);\r
-                               if(r != null)\r
-                                       return Collections.singleton(\r
-                                                       new ComparableTabContributor(\r
-                                                                       new ModuleTypeTab(),\r
-                                                                       0,\r
-                                                                       r,\r
-                                                       "Module Type Properties"));\r
-                       }\r
-                       \r
-                       if (backend.isInstanceOf(r, sr.SysdynModelicaFunction)) {\r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new FunctionTab(),\r
-                                               2,\r
-                                               r,\r
-                               "Function"));\r
-                               tabs.add(new ComparableTabContributor(\r
-                                               new ExternalFilesTab(),\r
-                                               1,\r
-                                               r,\r
-                               "External files"));\r
-                               return tabs;\r
-                       }\r
-                       \r
-                       if (backend.isInstanceOf(r, sr.SysdynModelicaFunctionLibrary)) {\r
-                               Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class);\r
-                               if(s == null)\r
-                                       s = r;\r
-                               // give either variable or the actual resource\r
-                               return Collections.singleton(new ComparableTabContributor(\r
-                                               new FunctionLibraryTab(),\r
-                                               2,\r
-                                               s,\r
-                               "Function library"));\r
-                       }\r
-                       \r
-               } catch (ServiceException e) {\r
-                       e.printStackTrace();\r
-               } catch (ManyObjectsForFunctionalRelationException e) {\r
-                       e.printStackTrace();\r
-               } catch (DatabaseException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               return Collections.emptyList();\r
-       }\r
+        } catch (ServiceException e) {\r
+            e.printStackTrace();\r
+        } catch (ManyObjectsForFunctionalRelationException e) {\r
+            e.printStackTrace();\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return Collections.emptyList();\r
+    }\r
 }\r
index 1bf12a70f68f4308145fad65bee4d6da11aa6e3a..08a5c6299005d9fa4d75cd7e233d751e72fe52db 100644 (file)
@@ -23,8 +23,6 @@ import org.eclipse.swt.dnd.DropTarget;
 import org.eclipse.swt.dnd.DropTargetAdapter;\r
 import org.eclipse.swt.dnd.DropTargetEvent;\r
 import org.eclipse.swt.dnd.Transfer;\r
-import org.eclipse.swt.events.MouseAdapter;\r
-import org.eclipse.swt.events.MouseEvent;\r
 import org.eclipse.swt.graphics.Point;\r
 import org.eclipse.swt.graphics.Rectangle;\r
 import org.eclipse.swt.widgets.Composite;\r
@@ -33,7 +31,13 @@ import org.eclipse.ui.IMemento;
 import org.eclipse.ui.IViewSite;\r
 import org.eclipse.ui.PartInitException;\r
 import org.eclipse.ui.part.ViewPart;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
 import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.ui.SimanticsUI;\r
 import org.simantics.ui.dnd.LocalObjectTransfer;\r
 \r
 /**\r
@@ -48,22 +52,19 @@ public class ChartPanel extends ViewPart {
 \r
     private Composite body;\r
     private ScrolledComposite sc;\r
-    \r
+\r
     private IDialogSettings settings;\r
-    private ArrayList<String> expandedCharts;\r
-    private ArrayList<String>  minimizedCharts;\r
-    \r
-//    private ArrayList<ChartPanelElement> elements;\r
-//    private ArrayList<Label> separators;\r
+    private ArrayList<Resource> expandedCharts;\r
+    private ArrayList<Resource> minimizedCharts;\r
 \r
     public static final String CHART_PANEL_SETTINGS = "CHART_PANEL_SETTINGS";\r
     public static final String EXPANDED_CHARTS = "ChartPanel.EXPANDED_CHARTS";\r
     public static final String MINIMIZED_CHARTS = "ChartPanel.MINIMIZED_CHARTS";\r
     public static final String CHART_PANEL_ORIENTATION = "CHART_PANEL_ORIENTATION";\r
-    \r
+\r
     public static final String CHART_PANEL_VERTICAL = "CHART_PANEL_ORIENTATION_VERTICAL";\r
     public static final String CHART_PANEL_HORIZONTAL = "CHART_PANEL_ORIENTATION_HORIZONTAL";\r
-    \r
+\r
     private boolean vertical = true;\r
 \r
     /**\r
@@ -72,36 +73,56 @@ public class ChartPanel extends ViewPart {
     @Override\r
     public void init(IViewSite site, IMemento memento) throws PartInitException {\r
         super.init(site, memento);\r
-        \r
-//        elements = new ArrayList<ChartPanelElement>();\r
-//        separators = new ArrayList<Label>();\r
-        \r
+\r
         settings = Activator.getDefault().getDialogSettings().getSection(CHART_PANEL_SETTINGS);\r
+\r
+        // Initialize settings if there are no settings\r
         if (settings == null) {\r
             settings = Activator.getDefault().getDialogSettings().addNewSection(CHART_PANEL_SETTINGS);\r
-            \r
-            String[] expandedUris = new String[] {"Module1.Variable1[index3]", "Module1.Variable2[index3]"};\r
+            String[] expandedUris = new String[] {};\r
             settings.put(EXPANDED_CHARTS, expandedUris);\r
-            \r
-            String[] minimizedUris = new String[] {"Module1.Variable3[index3]", "Module1.Variable4[index3]", "Module1.Variable5[index3]", "Module1.Variable6[index3]"};\r
+            String[] minimizedUris = new String[] {};\r
             settings.put(MINIMIZED_CHARTS, minimizedUris);\r
         }\r
-        \r
-        expandedCharts = new ArrayList<String>();\r
-        String[] expandedURIs = settings.getArray(EXPANDED_CHARTS);\r
-        for(String e : expandedURIs)\r
-            expandedCharts.add(e);\r
-        \r
-        minimizedCharts = new ArrayList<String>();\r
-        String[] minimizedURIs = settings.getArray(MINIMIZED_CHARTS);\r
-        for(String m : minimizedURIs)\r
-            minimizedCharts.add(m);\r
-        \r
+\r
+        // initialize chart lists\r
+        expandedCharts = new ArrayList<Resource>();\r
+        minimizedCharts = new ArrayList<Resource>();\r
+\r
+        // add chart resources to chart lists from settings\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new ReadRequest() {\r
+\r
+                @Override\r
+                public void run(ReadGraph graph) throws DatabaseException {\r
+                    JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                    Resource chart = null;\r
+                    String[] expandedURIs = settings.getArray(EXPANDED_CHARTS);\r
+                    for(String uri : expandedURIs) {\r
+                        chart = graph.getPossibleResource(uri);\r
+                        if(chart != null && graph.isInstanceOf(chart, jfree.Chart))\r
+                            expandedCharts.add(chart);\r
+                    }\r
+\r
+                    String[] minimizedURIs = settings.getArray(MINIMIZED_CHARTS);\r
+                    for(String uri : minimizedURIs) {\r
+                        chart = graph.getPossibleResource(uri);\r
+                        if(chart != null && graph.isInstanceOf(chart, jfree.Chart))\r
+                            minimizedCharts.add(chart);\r
+                    }\r
+                }\r
+            });\r
+        } catch (DatabaseException e1) {\r
+            e1.printStackTrace();\r
+        }\r
+\r
+        // set the orientation of the panel\r
         String orientation = settings.get(CHART_PANEL_ORIENTATION);\r
         if(CHART_PANEL_VERTICAL.equals(orientation))\r
             this.vertical = true;\r
         else if(CHART_PANEL_HORIZONTAL.equals(orientation))\r
             this.vertical = false;\r
+\r
     }\r
 \r
     /**\r
@@ -116,17 +137,18 @@ public class ChartPanel extends ViewPart {
         sc.setExpandHorizontal(true);\r
         sc.setExpandVertical(true);\r
         sc.getVerticalBar().setIncrement(sc.getVerticalBar().getIncrement()*3);\r
-        setupDropTarget(sc);\r
-        \r
+        sc.getHorizontalBar().setIncrement(sc.getHorizontalBar().getIncrement()*3);\r
+        setupDropTarget();\r
+\r
         body = new Composite(sc, SWT.NONE);\r
         GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(body);\r
         GridDataFactory.fillDefaults().grab(true, true).applyTo(body);\r
-        \r
+\r
         sc.setContent(body);\r
 \r
         createContents();\r
     }\r
-    \r
+\r
     /**\r
      * Display charts in this chart panel in the following order regardless of the orientation:\r
      * 1. Remove old content\r
@@ -138,28 +160,30 @@ public class ChartPanel extends ViewPart {
     private void createContents() {\r
         for(Control c : body.getChildren()) \r
             c.dispose();\r
-        \r
+\r
+        // Set the layout\r
         Composite composite = new Composite(body, SWT.NONE);\r
-        int separator;\r
         if(vertical) {\r
             GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(composite);\r
             GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
-            separator = SWT.VERTICAL;\r
         } else {\r
+            // Need to calculate horizontal elements for gridLayout\r
             int chartPanels = expandedCharts.size();\r
             int minimizedPanel = minimizedCharts.isEmpty() ? 0 : 1;\r
             int separators = 1 + expandedCharts.size() + minimizedCharts.size();\r
-            \r
+\r
             GridLayoutFactory.fillDefaults().spacing(0, 0).numColumns(chartPanels + minimizedPanel + separators).applyTo(composite);\r
             GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
-            separator = SWT.HORIZONTAL;\r
         }\r
 \r
-        new ChartPanelSeparator(composite, separator);\r
-        \r
-        for(String e : expandedCharts) {\r
+//        if(expandedCharts.isEmpty() && minimizedCharts.isEmpty()) {\r
+//            // TODO: the whole panel is a drop target \r
+//        } else { \r
+        new ChartPanelSeparator(composite, this, null, SWT.NONE);\r
+//        }\r
+\r
+        for(Resource e : expandedCharts) {\r
             new ChartPanelElement(composite, this, e, SWT.NONE);\r
-            new ChartPanelSeparator(composite, separator).addMouseListener(new SCFocusListener());\r
         }\r
 \r
         if(!minimizedCharts.isEmpty()) {\r
@@ -167,14 +191,13 @@ public class ChartPanel extends ViewPart {
             GridDataFactory.fillDefaults().grab(true, false).hint(ChartPanelHeader.HEADER_MINIMUM_WIDTH, SWT.DEFAULT).applyTo(minimized);\r
             GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(minimized);\r
 \r
-            for(String m : minimizedCharts) {\r
-                new ChartPanelHeader(minimized, this, m, SWT.BORDER);\r
-                new ChartPanelSeparator(minimized, SWT.VERTICAL).addMouseListener(new SCFocusListener());\r
+            for(Resource m : minimizedCharts) {\r
+                new ChartPanelElement(minimized, this, m, true, SWT.NONE);\r
             }\r
         }\r
 \r
         body.layout();\r
-        \r
+\r
         sc.setMinSize(body.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
         saveState();\r
     }\r
@@ -190,56 +213,61 @@ public class ChartPanel extends ViewPart {
         super.saveState(memento);\r
         saveState();\r
     }\r
-    \r
+\r
     /**\r
      * Save the current state of the view to IDialogSettings \r
      */\r
     private void saveState() {\r
-        if (settings != null) {\r
-            String[] expandedURIs = settings.getArray(EXPANDED_CHARTS);\r
-            if (expandedURIs == null) {\r
-                expandedURIs = new String[0];\r
-            }\r
-            expandedURIs = expandedCharts.toArray(new String[expandedCharts.size()]);\r
-            settings.put(EXPANDED_CHARTS, expandedURIs);\r
-            \r
-            String[] minimizedURIs = settings.getArray(MINIMIZED_CHARTS);\r
-            if (minimizedURIs == null) {\r
-                minimizedURIs = new String[0];\r
-            }\r
-            minimizedURIs = minimizedCharts.toArray(new String[minimizedCharts.size()]);\r
-            settings.put(MINIMIZED_CHARTS, minimizedURIs);\r
-            \r
-            if(vertical)\r
-                settings.put(CHART_PANEL_ORIENTATION, CHART_PANEL_VERTICAL);\r
-            else\r
-                settings.put(CHART_PANEL_ORIENTATION, CHART_PANEL_HORIZONTAL);\r
-          }\r
-        \r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new ReadRequest() {\r
+\r
+                @Override\r
+                public void run(ReadGraph graph) throws DatabaseException {\r
+                    if (settings != null) {\r
+                        String[] expandedURIs = new String[expandedCharts.size()];\r
+                        for(int i = 0; i < expandedCharts.size(); i++)\r
+                            expandedURIs[i] = graph.getURI(expandedCharts.get(i));\r
+                        settings.put(EXPANDED_CHARTS, expandedURIs);\r
+\r
+                        String[] minimizedURIs = new String[minimizedCharts.size()];\r
+                        for(int i = 0; i < minimizedCharts.size(); i++)\r
+                            minimizedURIs[i] = graph.getURI(minimizedCharts.get(i));\r
+                        settings.put(MINIMIZED_CHARTS, minimizedURIs);\r
+\r
+                        if(vertical)\r
+                            settings.put(CHART_PANEL_ORIENTATION, CHART_PANEL_VERTICAL);\r
+                        else\r
+                            settings.put(CHART_PANEL_ORIENTATION, CHART_PANEL_HORIZONTAL);\r
+                    }\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
     }\r
-    \r
+\r
     /**\r
      * Expand or minimize chart depending on the current status of that chart.\r
      * \r
      * @param chart The name of the chart to be expanded or minimized\r
      */\r
-    public void expandChart(String chart) {\r
+    public void expandChart(Resource chart) {\r
         boolean expand = false;\r
         if(minimizedCharts.contains(chart)) {\r
             minimizedCharts.remove(chart);\r
             expand = true;\r
         }\r
-        \r
+\r
         if(expandedCharts.contains(chart))\r
             expandedCharts.remove(chart);\r
-        \r
+\r
         if(expand)\r
             expandedCharts.add(expandedCharts.isEmpty() ? 0 : expandedCharts.size(), chart);\r
         else\r
             minimizedCharts.add(0, chart);\r
         refresh();\r
     }\r
-    \r
+\r
     /**\r
      * Set the orientation for this chart panel.\r
      * \r
@@ -252,50 +280,50 @@ public class ChartPanel extends ViewPart {
             this.vertical = false;\r
         refresh();\r
     }\r
-    \r
+\r
     /**\r
      * Removes a chart from this panel\r
      * \r
      * @param chart The name of the chart to be removed\r
      */\r
-    public void removeChart(String chart) {\r
+    public void removeChart(Resource chart) {\r
         if(this.expandedCharts.contains(chart))\r
             this.expandedCharts.remove(chart);\r
         else if(this.minimizedCharts.contains(chart))\r
             this.minimizedCharts.remove(chart);\r
         refresh();        \r
     }\r
-    \r
-    \r
+\r
+\r
     /**\r
      * Convenience method for refreshing the contents of the panel\r
      */\r
     private void refresh() {\r
         createContents();\r
     }\r
-    \r
-    \r
+\r
+\r
     /**\r
      * Sets up drag-scrolling for a scrolled composite \r
      * \r
      * @param control\r
      */\r
-    protected void setupDropTarget(final ScrolledComposite sc) {\r
+    protected void setupDropTarget() {\r
         DropTarget target = new DropTarget(sc, DND.DROP_NONE);\r
         target.setTransfer(new Transfer[] { LocalObjectTransfer.getTransfer() });\r
-        \r
+\r
         target.addDropListener(new DropTargetAdapter() {\r
-            \r
+\r
             private int activeMargin = 20;\r
             private int moveAmount = 1;\r
-            \r
+\r
             @Override\r
             public void dragOver(DropTargetEvent event) { \r
                 Point original = sc.getOrigin();\r
                 Point origin = sc.getOrigin();\r
                 Point pointer = sc.toControl(event.x, event.y);\r
                 Rectangle bounds = sc.getBounds();\r
-                \r
+\r
                 if(pointer.y < activeMargin)\r
                     origin.y = origin.y - moveAmount;\r
                 else if(bounds.height - pointer.y < activeMargin)\r
@@ -304,25 +332,50 @@ public class ChartPanel extends ViewPart {
                     origin.x = origin.x - moveAmount;\r
                 else if(bounds.width - pointer.x < activeMargin)\r
                     origin.x = origin.x + moveAmount;\r
-                \r
+\r
                 if(origin != original) {\r
                     sc.setOrigin (origin.x, origin.y);\r
                     sc.redraw();\r
                 }\r
             }\r
-            \r
+\r
         });\r
-        \r
+\r
+    }\r
+\r
+    public void dropChart(DropTargetEvent event, ChartPanelSeparator separator) {\r
+\r
+    }\r
+\r
+    public void dropChart(DropTargetEvent event, ChartPanelElement element) {\r
+\r
     }\r
-    \r
+\r
     /**\r
-     * Listener for directing focus to scrollableComposite\r
-     * @author Teemu Lempinen\r
-     *\r
+     * Is the panel vertically oriented\r
+     * @return Is the panel vertically oriented\r
      */\r
-    private class SCFocusListener extends MouseAdapter {\r
-        public void mouseDown(MouseEvent e) {\r
-            ChartPanel.this.setFocus();\r
+    public boolean isVertical() {\r
+        return vertical;\r
+    }\r
+\r
+    /**\r
+     * Adds chart after given element. If element == null, adds chart to the top.\r
+     * \r
+     * @param element Element whose after the chart will be placed. (null allowed)\r
+     */\r
+    public void addChart(Resource chartResource, ChartPanelElement element) {\r
+        if(element == null) {\r
+            expandedCharts.add(0, chartResource);\r
+        } else {\r
+            Resource elementResource = element.getChartResource();\r
+            if(element.isMinimized()) {\r
+                minimizedCharts.add(minimizedCharts.indexOf(elementResource) + 1, chartResource);\r
+            } else {\r
+                expandedCharts.add(expandedCharts.indexOf(elementResource) + 1, chartResource);\r
+            }\r
         }\r
+        refresh();\r
     }\r
+\r
 }\r
index 9dc99b808780e36025579a6a3d7ff8cad1c2ce6e..b686e578a25c00d6b648f55164ab0c0c3c67e2a1 100644 (file)
  *******************************************************************************/\r
 package org.simantics.sysdyn.ui.trend;\r
 \r
-import java.awt.Frame;\r
-import java.text.SimpleDateFormat;\r
-\r
 import org.eclipse.jface.layout.GridDataFactory;\r
 import org.eclipse.jface.layout.GridLayoutFactory;\r
 import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.awt.SWT_AWT;\r
+import org.eclipse.swt.events.MouseAdapter;\r
+import org.eclipse.swt.events.MouseEvent;\r
 import org.eclipse.swt.widgets.Composite;\r
-import org.jfree.chart.ChartFactory;\r
-import org.jfree.chart.JFreeChart;\r
-import org.jfree.chart.axis.DateAxis;\r
-import org.jfree.chart.plot.XYPlot;\r
-import org.jfree.data.time.Day;\r
-import org.jfree.data.time.TimeSeries;\r
-import org.jfree.data.time.TimeSeriesCollection;\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.ui.trend.chart.ChartComposite;\r
 \r
 /**\r
  * This class represents an expanded chart element in {@link ChartPanel}. It contains \r
@@ -39,61 +32,81 @@ public class ChartPanelElement extends Composite {
     public static int CHART_MINIMUM_WIDTH = 300;\r
     public static int CHART_MINIMUM_HEIGHT = 200;\r
     \r
+    private Resource chartResource;\r
+    private boolean minimized;\r
+    \r
     /**\r
-     * Creates a chart panel element into parent composite.\r
+     * Creates an expanded chart panel element into parent composite.\r
      * \r
      * @param parent The parent composite where the chart element is created\r
      * @param panel The {@link ChartPanel} containing the chart element\r
      * @param name The name of the chart\r
      * @param style The Style of the created chart element\r
      */\r
-    public ChartPanelElement(Composite parent, ChartPanel panel, String name, int style) {\r
+    public ChartPanelElement(Composite parent, ChartPanel panel, Resource chartResource, int style) {\r
+        this(parent, panel, chartResource, false, style);\r
+    }\r
+    \r
+    /**\r
+     *  Creates a chart panel element into parent composite.\r
+     * @param parent The parent composite where the chart element is created\r
+     * @param panel The {@link ChartPanel} containing the chart element\r
+     * @param name The name of the chart\r
+     * @param minimized Is the chart-section minimized\r
+     * @param style The Style of the created chart element\r
+     */\r
+    public ChartPanelElement(Composite parent, ChartPanel panel, Resource chartResource, boolean minimized, int style) {\r
         super(parent, style);\r
+        this.chartResource = chartResource;\r
+        this.minimized = minimized;\r
         \r
-        GridDataFactory.fillDefaults().grab(true, true).hint(CHART_MINIMUM_WIDTH,CHART_MINIMUM_HEIGHT).applyTo(this);\r
+        if(minimized)\r
+            GridDataFactory.fillDefaults().grab(true, false).applyTo(this);\r
+        else\r
+            GridDataFactory.fillDefaults().grab(true, true).hint(CHART_MINIMUM_WIDTH,CHART_MINIMUM_HEIGHT).applyTo(this);\r
+\r
         GridLayoutFactory.fillDefaults().spacing(0,0).applyTo(this);\r
         \r
         // Header\r
-        new ChartPanelHeader(this, panel, name, SWT.BORDER);\r
+        new ChartPanelHeader(this, panel, chartResource, SWT.BORDER);\r
         \r
-        // Chart\r
-        Composite swtComposite = new Composite(this,\r
-                SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
-        Frame frame = SWT_AWT.new_Frame(swtComposite);\r
-        GridDataFactory.fillDefaults().grab(true, true).applyTo(swtComposite);\r
-        setChart(frame);\r
+        if(!minimized) {\r
+            // Chart\r
+            new ChartComposite(this, chartResource, SWT.BORDER);\r
+        }\r
         \r
+        ChartPanelSeparator separator = new ChartPanelSeparator(parent, panel, this, SWT.NONE);\r
+        separator.addMouseListener(new SCFocusListener(panel));\r
     }\r
     \r
-    /** \r
-     * A dummy chart containing information about the population in India\r
-     * \r
-     * @param frame\r
+    /**\r
+     * Listener for directing focus to scrollableComposite\r
+     * @author Teemu Lempinen\r
+     *\r
      */\r
-    private void setChart(Frame frame) {\r
-        TimeSeries population = new TimeSeries("Indian Population");\r
-        population.add(new Day(1, 3, 1961), 439234771);\r
-        population.add(new Day(1, 3, 1971), 548159652);\r
-        population.add(new Day(1, 3, 1981), 683329097);\r
-        population.add(new Day(1, 3, 1991), 843387888);\r
-        population.add(new Day(1, 3, 2001), 1028610328);\r
-        population.add(new Day(1, 3, 2011), 1210193422);\r
-        TimeSeriesCollection dataset = new TimeSeriesCollection(population);\r
-        \r
-        // Create the chart\r
-        JFreeChart chart = ChartFactory.createTimeSeriesChart(\r
-            "Population of India", "Date", "Population", dataset,\r
-            true, true, false);\r
-        \r
-        //Get the plot and set date format\r
-        XYPlot plot = chart.getXYPlot();\r
-        DateAxis axis = (DateAxis) plot.getDomainAxis();\r
-          axis.setDateFormatOverride(new SimpleDateFormat("MMM-yyyy"));\r
-\r
-        // Render the frame\r
-        org.jfree.chart.ChartPanel panel = new org.jfree.chart.ChartPanel(chart);\r
-        panel.setSize(CHART_MINIMUM_WIDTH, CHART_MINIMUM_HEIGHT);\r
-        frame.add(panel);\r
+    private class SCFocusListener extends MouseAdapter {\r
+        ChartPanel panel;\r
+        public SCFocusListener(ChartPanel panel) {\r
+            this.panel = panel;\r
+        }\r
+        public void mouseDown(MouseEvent e) {\r
+            panel.setFocus();\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Returns the chart resource associated with this element\r
+     * @return chart resource\r
+     */\r
+    public Resource getChartResource() {\r
+        return this.chartResource;\r
+    }\r
+    \r
+    /**\r
+     * Returns the minimized state of this element\r
+     * @return is the element minimized\r
+     */\r
+    public boolean isMinimized() {\r
+        return this.minimized;\r
     }\r
-\r
 }\r
index b710fad8402a8b83455a40f6939e613860987f4d..3c69e4cc7aece08eced9a24515d5e04b94210dfa 100644 (file)
@@ -21,6 +21,13 @@ import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.Composite;\r
 import org.eclipse.swt.widgets.Control;\r
 import org.eclipse.swt.widgets.Label;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
 \r
 /**\r
  * Header of a chart element in {@link ChartPanel}. Only this header is\r
@@ -33,9 +40,10 @@ import org.eclipse.swt.widgets.Label;
 public class ChartPanelHeader extends Composite {\r
 \r
     public static int HEADER_MINIMUM_WIDTH = 250;\r
-    private String name; \r
     private ChartPanel panel;\r
-    \r
+    private Resource resource;\r
+    private Label name;\r
+\r
     /**\r
      * Chart panel header with minimize and close buttons.\r
      * \r
@@ -44,23 +52,66 @@ public class ChartPanelHeader extends Composite {
      * @param name The name of the chart\r
      * @param style he Style of the created chart element\r
      */\r
-    public ChartPanelHeader(Composite parent, ChartPanel panel, String name, int style) {\r
+    public ChartPanelHeader(Composite parent, ChartPanel panel, Resource chartResource, int style) {\r
         super(parent, style);\r
-        this.name = name;\r
+        this.resource = chartResource;\r
         this.panel = panel;\r
-        \r
+\r
         GridLayoutFactory.fillDefaults().numColumns(3).applyTo(this);\r
         GridDataFactory.fillDefaults().grab(true, false).applyTo(this);\r
-        \r
+\r
         // Label for the chart name (also minimize/expand)\r
-        Label label = new Label(this, SWT.NONE);\r
-        label.setText(name);\r
-        GridDataFactory.fillDefaults().grab(true, false).applyTo(label);\r
-        label.addMouseListener(new MinimizeListener(label));\r
-        label.setCursor(new Cursor(label.getDisplay(), SWT.CURSOR_HAND));\r
+        name = new Label(this, SWT.NONE);\r
+\r
+        try {\r
+            // name updater\r
+            SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+                @Override\r
+                public String perform(ReadGraph graph) throws DatabaseException {\r
+                    return graph.getPossibleRelatedValue(resource, Layer0.getInstance(graph).HasName);\r
+                }\r
+\r
+            }, new Listener<String>() {\r
+\r
+                @Override\r
+                public void execute(final String result) {\r
+                    if(result == null)\r
+                        return;\r
+                    \r
+                    name.getDisplay().asyncExec(new Runnable() {\r
+                        \r
+                        @Override\r
+                        public void run() {\r
+                            if(!name.isDisposed())\r
+                                name.setText(result);\r
+                        }\r
+                    });\r
+                }\r
+\r
+                @Override\r
+                public void exception(Throwable t) {\r
+                    t.printStackTrace();\r
+                }\r
+\r
+                @Override\r
+                public boolean isDisposed() {\r
+                    return name.isDisposed();\r
+                }\r
+\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+            name.setText("No name");\r
+        }\r
+\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(name);\r
+        name.addMouseListener(new MinimizeListener(name));\r
+        name.setCursor(new Cursor(name.getDisplay(), SWT.CURSOR_HAND));\r
 \r
         // Label for minimizing/expanding chart\r
-        label = new Label(this, SWT.NONE);\r
+        Label label = new Label(this, SWT.NONE);\r
         label.setText("^");\r
         GridDataFactory.fillDefaults().applyTo(label);\r
         label.addMouseListener(new MinimizeListener(label));\r
@@ -73,7 +124,7 @@ public class ChartPanelHeader extends Composite {
         label.addMouseListener(new RemoveChartListener(label));\r
         label.setCursor(new Cursor(label.getDisplay(), SWT.CURSOR_HAND));\r
     }\r
-    \r
+\r
     /**\r
      * Mouse listener to minimize chart button. Expands and minimizes \r
      * the chart of this header.\r
@@ -84,11 +135,11 @@ public class ChartPanelHeader extends Composite {
     private class MinimizeListener implements MouseListener {\r
 \r
         private Control control;\r
-        \r
+\r
         public MinimizeListener(Control control) {\r
             this.control = control;\r
         }\r
-        \r
+\r
         @Override\r
         public void mouseDoubleClick(MouseEvent e) {\r
         }\r
@@ -101,15 +152,15 @@ public class ChartPanelHeader extends Composite {
         public void mouseUp(MouseEvent e) {\r
             if(ChartPanelHeader.this.isDisposed())\r
                 return;\r
-            \r
+\r
             // Expand only if mouse was released inside the control\r
             Rectangle bounds = control.getBounds();\r
             bounds.x = 0;\r
             bounds.y = 0;\r
             if(bounds.contains(e.x, e.y))\r
-                panel.expandChart(name);\r
+                panel.expandChart(resource);\r
         }\r
-        \r
+\r
     }\r
 \r
     /**\r
@@ -121,7 +172,7 @@ public class ChartPanelHeader extends Composite {
     private class RemoveChartListener implements MouseListener {\r
 \r
         Control control;\r
-        \r
+\r
         public RemoveChartListener(Control control) {\r
             this.control = control;\r
         }\r
@@ -143,11 +194,11 @@ public class ChartPanelHeader extends Composite {
                 bounds.x = 0;\r
                 bounds.y = 0;\r
                 if(bounds.contains(e.x, e.y))\r
-                    panel.removeChart(name);\r
+                    panel.removeChart(resource);\r
             }\r
-                \r
-                \r
+\r
+\r
         }\r
-        \r
+\r
     }\r
 }\r
index 5b354ba0390a3d08c341cb65b036a24d5b706f19..c6f8e4ab7a838a1fb08c7a1f4d57477416cdd08f 100644 (file)
@@ -22,7 +22,9 @@ import org.eclipse.swt.dnd.Transfer;
 import org.eclipse.swt.widgets.Composite;\r
 import org.eclipse.swt.widgets.Control;\r
 import org.eclipse.swt.widgets.Display;\r
+import org.simantics.db.Resource;\r
 import org.simantics.ui.dnd.LocalObjectTransfer;\r
+import org.simantics.ui.utils.AdaptionUtils;\r
 \r
 /**\r
  * Class for separating charts in {@link ChartPanel}. Acts as a drop participant for adding\r
@@ -33,21 +35,26 @@ import org.simantics.ui.dnd.LocalObjectTransfer;
  */\r
 public class ChartPanelSeparator extends Composite {\r
 \r
+    private ChartPanelElement element;\r
+    private ChartPanel panel;\r
+    \r
     /**\r
      * Set up a small horizontal or vertical separator depending on SWT style\r
      * \r
      * @param parent\r
      * @param style\r
      */\r
-    public ChartPanelSeparator(Composite parent, int style) {\r
+    public ChartPanelSeparator(Composite parent, ChartPanel panel, ChartPanelElement element, int style) {\r
         super(parent, SWT.NONE);\r
-        if((style & SWT.VERTICAL) > 0) { \r
+        if(panel.isVertical() || (element != null && element.isMinimized())) { \r
             GridDataFactory.fillDefaults().grab(true, false).applyTo(this);\r
             GridLayoutFactory.fillDefaults().margins(0, 2).applyTo(this);\r
-        } else if((style & SWT.HORIZONTAL) > 0) {\r
+        } else {\r
             GridDataFactory.fillDefaults().grab(false, true).applyTo(this);\r
             GridLayoutFactory.fillDefaults().margins(2, 0).applyTo(this);\r
         }\r
+        this.panel = panel;\r
+        this.element = element;\r
         setupDropTarget(this);\r
     }\r
 \r
@@ -64,19 +71,31 @@ public class ChartPanelSeparator extends Composite {
             Composite composite = ChartPanelSeparator.this;\r
             Display display = composite.getDisplay();\r
             \r
+            /**\r
+             * Display effect on the composite when drag entered\r
+             */\r
             @Override\r
             public void dragEnter(DropTargetEvent event) {\r
-                event.detail = DND.DROP_COPY;\r
+                event.detail = DND.DROP_COPY; // TODO: calculate this. Is drop possible? What kind of drop?\r
                 composite.setBackground(display.getSystemColor(SWT.COLOR_BLACK));\r
             }\r
 \r
+            /**\r
+             * Revert effect when drag leaves\r
+             */\r
             @Override\r
             public void dragLeave(DropTargetEvent event) { \r
                 composite.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));\r
             }\r
 \r
+            /**\r
+             * Drop the data to chart panel\r
+             */\r
             @Override\r
             public void drop(DropTargetEvent event) {\r
+                Resource chartResource = AdaptionUtils.adaptToSingle(event.data, Resource.class);\r
+                if(chartResource != null)\r
+                    panel.addChart(chartResource, element);\r
             }\r
 \r
             @Override\r
index 1d80da29a1a28669df4df95c99a84c503ae85c66..2dbe66097d613c4b5e6f51ccca85aa1045af3d08 100644 (file)
@@ -28,8 +28,13 @@ import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.jfree.data.xy.AbstractXYDataset;\r
 import org.simantics.sysdyn.manager.SysdynDataSet;\r
 import org.simantics.sysdyn.ui.viewUtils.SysdynDatasetSelectionListener;\r
-import org.simantics.utils.ui.jface.ActiveSelectionProvider;\r
 \r
+/**\r
+ * Trend view that shows all active simulation results for selected variables.\r
+ *  \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class TrendView extends ViewPart {\r
 \r
        Frame frame;\r
@@ -38,6 +43,12 @@ public class TrendView extends ViewPart {
        SysdynDatasetSelectionListener sysdynDatasetSelectionListener;\r
        public static JFreeChart chart;\r
 \r
+       /**\r
+        * Dataset for jFreeChart\r
+        * \r
+        * @author Teemu Lempinen\r
+        *\r
+        */\r
        @SuppressWarnings("serial")\r
        class SysdynDatasets extends AbstractXYDataset {\r
 \r
@@ -50,17 +61,17 @@ public class TrendView extends ViewPart {
 \r
                @Override\r
                public Number getY(int series, int item) {\r
-                       return sets[series].values.get(item);\r
+                       return sets[series].values[item];\r
                }\r
 \r
                @Override\r
                public Number getX(int series, int item) {\r
-                       return sets[series].times.get(item);\r
+                       return sets[series].times[item];\r
                }\r
 \r
                @Override\r
                public int getItemCount(int series) {\r
-                       return sets[series].times.size();\r
+                       return sets[series].times.length;\r
                }\r
 \r
                @Override\r
@@ -81,13 +92,12 @@ public class TrendView extends ViewPart {
 \r
        @Override\r
        public void createPartControl(Composite parent) {\r
-               final ActiveSelectionProvider selectionProvider = new ActiveSelectionProvider();\r
-               getSite().setSelectionProvider(selectionProvider);\r
-\r
+           \r
                final Composite composite = new Composite(parent,\r
                                SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
                frame = SWT_AWT.new_Frame(composite);\r
 \r
+               // Create the chart\r
                SwingUtilities.invokeLater(new Runnable() {\r
 \r
                        @Override\r
@@ -107,6 +117,7 @@ public class TrendView extends ViewPart {
 \r
                });\r
 \r
+               // Add a dataset listener that updates datasets for the chart according to current selection \r
                sysdynDatasetSelectionListener = new SysdynDatasetSelectionListener() {\r
 \r
                        @Override\r
@@ -121,7 +132,6 @@ public class TrendView extends ViewPart {
                                });\r
                        }\r
                };\r
-               \r
                getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(sysdynDatasetSelectionListener);\r
 \r
        }\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ChartComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ChartComposite.java
new file mode 100644 (file)
index 0000000..f9c9a5d
--- /dev/null
@@ -0,0 +1,137 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import java.awt.Frame;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.awt.SWT_AWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.jfree.chart.ChartPanel;\r
+import org.jfree.chart.JFreeChart;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Simantics;\r
+import org.simantics.db.procedure.SyncListener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.RunnableWithObject;\r
+\r
+/**\r
+ * Composite containing a single chart defined by a JFreeChart.Chart\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartComposite extends Composite {\r
+\r
+    private Frame frame;\r
+    private ChartPanel panel;\r
+    private Composite composite;\r
+\r
+    /**\r
+     * A new ChartComposite with a definition in chartResourceURI\r
+     * @param parent Composite\r
+     * @param chartResourceURI URI for a JFreeChart.Chart definition\r
+     * @param style SWT style\r
+     */\r
+    public ChartComposite(Composite parent, final String chartResourceURI, int style) {\r
+        super(parent, style | SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
+\r
+        try {\r
+            Resource chartResource = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                @Override\r
+                public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                    return graph.getPossibleResource(chartResourceURI);\r
+                }\r
+\r
+            });\r
+            if(chartResource != null)\r
+                CreateContent(chartResource);\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * A new ChartComposite with a chartResource definition\r
+     * @param parent Composite\r
+     * @param chartResource JFreeChart.Chart resource\r
+     * @param style SWT style\r
+     */\r
+    public ChartComposite(Composite parent, final Resource chartResource, int style) {\r
+        super(parent, style | SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
+        CreateContent(chartResource);\r
+    }\r
+\r
+    /**\r
+     * Creates and displays the chart defined in chartResource\r
+     * @param chartResource\r
+     */\r
+    private void CreateContent(final Resource chartResource) {\r
+        composite = this;\r
+        GridLayoutFactory.fillDefaults().applyTo(composite);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        frame = SWT_AWT.new_Frame(composite);\r
+\r
+        try {\r
+            // Add a listener displaying the contents of the chart. Chart is re-drawn if the definition changes\r
+            Simantics.getSession().syncRequest(new Read<JFreeChart>() {\r
+\r
+                @Override\r
+                public JFreeChart perform(ReadGraph graph) throws DatabaseException {\r
+                    // Adapt chartResource to a chart (XY, pie, bar, ...)\r
+                    IJFreeChart c = graph.adapt(chartResource, IJFreeChart.class);\r
+                    return c.getChart();\r
+                }\r
+\r
+            } , new SyncListener<JFreeChart>() {\r
+\r
+                @Override\r
+                public boolean isDisposed() {\r
+                    return composite.isDisposed();\r
+                }\r
+\r
+                @Override\r
+                public void execute(ReadGraph graph, JFreeChart chart) throws DatabaseException {\r
+                    // Display the result chart\r
+                    composite.getDisplay().asyncExec(new RunnableWithObject(chart) {\r
+\r
+                        @Override\r
+                        public void run() {\r
+                            if(composite.isDisposed())\r
+                                return;\r
+                            if(panel != null)\r
+                                frame.remove(panel);\r
+                            composite.layout();\r
+                            panel = new ChartPanel((JFreeChart)getObject(), false, true, true, true, true);\r
+                            frame.add(panel);\r
+                            frame.validate();\r
+                        }\r
+                    });\r
+                }\r
+\r
+                @Override\r
+                public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {\r
+                    throwable.printStackTrace();\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IAxis.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IAxis.java
new file mode 100644 (file)
index 0000000..a544985
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import org.jfree.chart.axis.Axis;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+/**\r
+ * Interface for JFreeChart.Axis type resource\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public interface IAxis extends IJFreeChartComponent {\r
+    \r
+    /**\r
+     * Returns the axis\r
+     * \r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    public Axis getAxis();\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IDataset.java
new file mode 100644 (file)
index 0000000..cf53605
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import org.jfree.chart.renderer.AbstractRenderer;\r
+import org.jfree.data.general.Dataset;\r
+\r
+/**\r
+ * Interface for JFreeChart.Dataset type resource\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public interface IDataset extends IJFreeChartComponent {\r
+    \r
+    /**\r
+     * Returns the JFreeChart dataset represented by the associated resource\r
+     * \r
+     * @return JFreeChart dataset\r
+     */\r
+    public Dataset getDataset();\r
+    \r
+    \r
+    /**\r
+     * Returns the renderer for this dataset\r
+     * \r
+     * @return JFreeChart renderer\r
+     */\r
+    public AbstractRenderer getRenderer();\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChart.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChart.java
new file mode 100644 (file)
index 0000000..9c702c4
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import org.jfree.chart.JFreeChart;\r
+import org.simantics.db.exception.DatabaseException;\r
+/**\r
+ * Interface for JFreeChart.Chart type resource\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public interface IJFreeChart extends IJFreeChartComponent {\r
+\r
+    /**\r
+     * Returns the chart\r
+     * \r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    public JFreeChart getChart();\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChartComponent.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChartComponent.java
new file mode 100644 (file)
index 0000000..162c9e0
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+/**\r
+ * Interface for all components that are used to create JFreeCharts based on org.simantics.jfreechart ontology \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public interface IJFreeChartComponent {\r
+    \r
+    /**\r
+     * Dispose this component. Disposing a component may be useful \r
+     * if the component contains listeners that need to be disposed.\r
+     */\r
+    public void dispose();\r
+    \r
+    /**\r
+     * Returns the disposed state of the component\r
+     * @return\r
+     */\r
+    public boolean isDisposed();\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IPlot.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IPlot.java
new file mode 100644 (file)
index 0000000..7f92e86
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import org.jfree.chart.plot.Plot;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+/**\r
+ * Interface for JFreeChart.Plot type resource\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public interface IPlot extends IJFreeChartComponent {\r
+\r
+    /**\r
+     * Returns the plot\r
+     * \r
+     * @return Title\r
+     * @throws DatabaseException\r
+     */\r
+    public Plot getPlot();\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ITitle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ITitle.java
new file mode 100644 (file)
index 0000000..0728154
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import org.jfree.chart.title.Title;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+/**\r
+ * Interface for JFreeChart.Title type resource\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public interface ITitle extends IJFreeChartComponent {\r
+    \r
+    /**\r
+     * Returns the title\r
+     * \r
+     * @return Title\r
+     * @throws DatabaseException\r
+     */\r
+    public Title getTitle();\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/JFreeChart.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/JFreeChart.java
new file mode 100644 (file)
index 0000000..e25fd2c
--- /dev/null
@@ -0,0 +1,111 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.jfree.chart.title.LegendTitle;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+\r
+/**\r
+ * Class representing a complete JFreeChart.Chart\r
+ * \r
+ * This class supports all types of charts. The details of the chart are \r
+ * defined in plots and other adapted classes.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class JFreeChart implements IJFreeChart {\r
+\r
+    private org.jfree.chart.JFreeChart jfreechart;\r
+    private boolean disposed = false;\r
+\r
+    private ITitle title;\r
+    private Boolean legendVisible;\r
+    \r
+    private HashMap<Resource, IPlot> plots;\r
+    private IPlot firstPlot = null;\r
+\r
+    /**\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param chartResource Resource of type JFreeChart.Chart\r
+     */\r
+    public JFreeChart(ReadGraph graph, Resource chartResource) {\r
+        try {\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+            Resource titleResource = graph.syncRequest(new PossibleObjectWithType(chartResource, l0.ConsistsOf, jfree.Title));\r
+            title = graph.adapt(titleResource, ITitle.class);\r
+            legendVisible = graph.getPossibleRelatedValue(chartResource, jfree.HasVisibleLegend, Bindings.BOOLEAN);\r
+\r
+            plots = new HashMap<Resource, IPlot>();\r
+            for(Resource plotResource : graph.syncRequest(new ObjectsWithType(chartResource, l0.ConsistsOf, jfree.Plot))) {\r
+                IPlot plot = graph.adapt(plotResource, IPlot.class);\r
+                plots.put(plotResource, plot);\r
+                if(firstPlot == null)\r
+                    firstPlot = plot;\r
+            } \r
+\r
+\r
+        } catch(DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Returns a new chart using the information collected in the constructor\r
+     */\r
+    @Override\r
+    public org.jfree.chart.JFreeChart getChart() {\r
+        if(plots.size() == 0)\r
+            return null;\r
+        jfreechart = new org.jfree.chart.JFreeChart(firstPlot.getPlot());\r
+        \r
+        // setVisible does not work in TextTitle, have to use this workaround \r
+        org.jfree.chart.title.TextTitle  t = (org.jfree.chart.title.TextTitle)title.getTitle();\r
+        if(t.isVisible())\r
+            jfreechart.setTitle(t);\r
+        \r
+        if(legendVisible != null && !legendVisible) {\r
+            for(Object title : jfreechart.getSubtitles()) {\r
+                if(title instanceof LegendTitle)\r
+                    ((LegendTitle)title).setVisible(legendVisible);\r
+            }\r
+        }\r
+        return jfreechart;\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        disposed = true;\r
+\r
+        // Call dispose to title and plots to disable their possible listeners\r
+        title.dispose();\r
+        for(IPlot plot : plots.values())\r
+            plot.dispose();\r
+    }\r
+\r
+    @Override\r
+    public boolean isDisposed() {\r
+        return disposed;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/NumberAxis.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/NumberAxis.java
new file mode 100644 (file)
index 0000000..29ccc82
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import java.awt.Color;\r
+\r
+import org.jfree.chart.axis.Axis;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+\r
+/**\r
+ * Class representing a JFreeChart.NumberAxis\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NumberAxis implements IAxis {\r
+\r
+    private org.jfree.chart.axis.NumberAxis axis;\r
+    private String label;\r
+    private boolean disposed;\r
+    private Boolean tMarksVisible, tLabelsVisible;\r
+    private Color color;\r
+\r
+    /**\r
+     *\r
+     * @param graph ReadGraph\r
+     * @param axisResource resource of type JFreeChart.NumberAxis\r
+     */\r
+    public NumberAxis(ReadGraph graph, Resource axisResource) {\r
+\r
+        try {\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+            label = graph.getPossibleRelatedValue(axisResource, l0.HasLabel);\r
+            tMarksVisible = graph.getPossibleRelatedValue(axisResource, jfree.HasVisibleTickMarks, Bindings.BOOLEAN);\r
+            tLabelsVisible = graph.getPossibleRelatedValue(axisResource, jfree.HasVisibleTickLabels, Bindings.BOOLEAN);\r
+            Resource c = graph.getPossibleObject(axisResource, jfree.HasColor);\r
+            color = c == null ? null : G2DUtils.getColor(graph, c);\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+\r
+    @Override\r
+    public Axis getAxis() {\r
+        axis = new org.jfree.chart.axis.NumberAxis();\r
+        if(label != null)\r
+            axis.setLabel(label);\r
+        if(tMarksVisible != null && tMarksVisible == false)\r
+            axis.setTickMarksVisible(false);\r
+        if(tLabelsVisible != null && tLabelsVisible == false)\r
+            axis.setTickLabelsVisible(false);\r
+        if(color != null) {\r
+            axis.setAxisLinePaint(color);\r
+            axis.setLabelPaint(color);\r
+            axis.setTickLabelPaint(color);\r
+            axis.setTickMarkPaint(color);\r
+        }\r
+        return axis;\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        disposed = true;\r
+    }\r
+\r
+    @Override\r
+    public boolean isDisposed() {\r
+        return disposed;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/TextTitle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/TextTitle.java
new file mode 100644 (file)
index 0000000..a00fc62
--- /dev/null
@@ -0,0 +1,94 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import org.jfree.chart.title.Title;\r
+import org.jfree.ui.RectangleEdge;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+\r
+/**\r
+ * Class representing a JFreeChart.TextTitle\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class TextTitle implements ITitle {\r
+    \r
+    private org.jfree.chart.title.TextTitle textTitle;\r
+    private RectangleEdge position;\r
+    private String text;\r
+    private boolean disposed;\r
+    private Boolean visible;\r
+    \r
+    public TextTitle(ReadGraph graph, Resource titleResource) {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+        try {\r
+            text = graph.getPossibleRelatedValue(titleResource, l0.HasLabel, Bindings.STRING);\r
+            Resource pos = graph.getPossibleObject(titleResource, jfree.HasPosition);\r
+            position = getRectangleEdgePosition(graph, pos);\r
+            visible = graph.getPossibleRelatedValue(titleResource, jfree.IsVisible, Bindings.BOOLEAN);\r
+\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Get the RectangleEdge representation for Resource position (JFreeChart.Position)\r
+     * @param graph ReadGraph \r
+     * @param position Resource of type JFreeChart.Position\r
+     * @return RectangleEdge representation for Resource position\r
+     */\r
+    private RectangleEdge getRectangleEdgePosition(ReadGraph graph, Resource position) {\r
+        if(position == null)\r
+            return null;\r
+        \r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+        if(position.equals(jfree.Top))\r
+            return RectangleEdge.TOP;\r
+        else if(position.equals(jfree.Bottom))\r
+            return RectangleEdge.BOTTOM;\r
+        else if(position.equals(jfree.Left))\r
+            return RectangleEdge.LEFT;\r
+        else if(position.equals(jfree.Right))\r
+            return RectangleEdge.RIGHT;\r
+        else\r
+            return null;\r
+                    \r
+    }\r
+\r
+    @Override\r
+    public Title getTitle() {\r
+        textTitle = new org.jfree.chart.title.TextTitle(text);\r
+        if(position != null)\r
+            textTitle.setPosition(position);\r
+        if(visible != null)\r
+            textTitle.setVisible(visible);\r
+        return textTitle;\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        disposed = true;\r
+    }\r
+\r
+    @Override\r
+    public boolean isDisposed() {\r
+        return disposed;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYDataset.java
new file mode 100644 (file)
index 0000000..da285f4
--- /dev/null
@@ -0,0 +1,160 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.util.ArrayList;\r
+\r
+import org.jfree.chart.renderer.AbstractRenderer;\r
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;\r
+import org.jfree.data.general.Dataset;\r
+import org.jfree.data.xy.DefaultXYDataset;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.request.PossibleActiveExperiment;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.adapter.SysdynVariableProperties;\r
+\r
+/**\r
+ * Class representing a JFreeChart.XYDataset\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class XYDataset implements IDataset {\r
+\r
+    private DefaultXYDataset dataset;\r
+    private boolean disposed;\r
+    private ArrayList<TempSeries> series;\r
+    private XYLineAndShapeRenderer renderer;\r
+\r
+    public XYDataset(ReadGraph graph, final Resource datasetResource) {\r
+\r
+        try {\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+            // Find the model where the chart is located\r
+            Resource model = datasetResource;\r
+            do {\r
+                model = graph.getPossibleObject(model, l0.PartOf);\r
+            } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel));\r
+\r
+            // Find the variable realization of the current experiment\r
+            String realizationURI = null;\r
+            Resource realization = graph.syncRequest(new PossibleActiveExperiment(model));\r
+            if (realization == null) {\r
+                Layer0X L0X = Layer0X.getInstance(graph);\r
+                realization = graph.getPossibleObject(model, L0X.HasBaseRealization);\r
+            }\r
+            if (realization != null)\r
+                realizationURI = graph.getURI(realization);\r
+\r
+            if(realizationURI == null)\r
+                return; // No experiment -> No results\r
+\r
+            series = new ArrayList<TempSeries>();\r
+            // Get properties for all series\r
+            for(Resource r : graph.syncRequest(new ObjectsWithType(datasetResource, l0.ConsistsOf, jfree.Series))) {\r
+                String rvi = graph.getRelatedValue(r, jfree.HasVariableRVI);\r
+                \r
+                // Get label. If there is no label, rvi is used\r
+                String label = graph.getPossibleRelatedValue(r, l0.HasLabel);\r
+                if(label == null || label.isEmpty()) label = rvi.substring(1).replace('/', '.');\r
+                try {\r
+                    // Get visual properties\r
+                    Integer width = graph.getPossibleRelatedValue(r, jfree.HasLineWidth, Bindings.INTEGER);\r
+                    Resource c = graph.getPossibleObject(r, jfree.HasColor);\r
+                    Color color = c == null ? null : G2DUtils.getColor(graph, c);\r
+\r
+                    // Get a variable for the series\r
+                    Variable v = Variables.getVariable(graph, realizationURI + rvi);\r
+                    if(width == null) width = 1;\r
+                    double[] va = v.getPossiblePropertyValue(graph, SysdynVariableProperties.VALUES , Bindings.DOUBLE_ARRAY);\r
+                    double[] ta = v.getPossiblePropertyValue(graph, SysdynVariableProperties.TIMES , Bindings.DOUBLE_ARRAY);\r
+                    \r
+                    if(ta!=null && va!=null && (va.length == ta.length))\r
+                        // Add series if everything OK\r
+                        series.add(new TempSeries(label, new double[][] {ta, va}, width, color));\r
+                } catch (MissingVariableException e) {\r
+                    // Do nothing, if variable was not found. Move on to the next series\r
+                }\r
+\r
+            }\r
+\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Dataset getDataset() {\r
+\r
+        dataset = new DefaultXYDataset();\r
+        for(int i = 0; i < series.size(); i++) {\r
+            TempSeries s = series.get(i);\r
+            dataset.addSeries(s.name, s.values);\r
+            getRenderer().setSeriesStroke(i, new BasicStroke((float)s.width));\r
+            if(s.color != null)\r
+                getRenderer().setSeriesPaint(i, s.color);\r
+        }\r
+        return dataset;\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        disposed = true;\r
+    }\r
+\r
+    @Override\r
+    public boolean isDisposed() {\r
+        return disposed;\r
+    }\r
+\r
+    /**\r
+     * Auxiliary class containing all information needed to define a single series\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class TempSeries {\r
+        public double[][] values;\r
+        public String name;\r
+        public int width;\r
+        public Color color;\r
+\r
+        public TempSeries(String name, double[][] values, int width, Color color) {\r
+            this.name = name;\r
+            this.values = values;\r
+            this.width = width;\r
+            this.color = color;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public AbstractRenderer getRenderer() {\r
+        if(renderer == null)\r
+            renderer = new XYLineAndShapeRenderer(true, false);\r
+        return renderer;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYPlot.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYPlot.java
new file mode 100644 (file)
index 0000000..3e5cc12
--- /dev/null
@@ -0,0 +1,153 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+\r
+import org.jfree.chart.axis.ValueAxis;\r
+import org.jfree.chart.plot.Plot;\r
+import org.jfree.chart.renderer.xy.XYItemRenderer;\r
+import org.jfree.data.xy.XYDataset;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+\r
+/**\r
+ * Class representing a JFreeChart.XYPlot\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class XYPlot implements IPlot {\r
+\r
+    private org.jfree.chart.plot.XYPlot plot;\r
+    private ArrayList<IAxis> ranges;\r
+    private ArrayList<IAxis> domains;\r
+    private ArrayList<IDataset> datasets;\r
+    private HashMap<IDataset, IAxis> rangeMappings;\r
+    private HashMap<IDataset, IAxis> domainMappings;\r
+    private boolean disposed;\r
+    private Boolean visibleGrid;\r
+    \r
+    public XYPlot(ReadGraph graph, Resource plotResource) {\r
+\r
+        try {\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+            HashMap<Resource, IAxis> axisMap = new HashMap<Resource, IAxis>();\r
+            ranges = new ArrayList<IAxis>();\r
+            \r
+            // Get all range axis\r
+            for(Resource axisResource : graph.syncRequest(new ObjectsWithType(plotResource, jfree.HasRangeAxis, jfree.Axis))) {\r
+                IAxis axis = graph.adapt(axisResource, IAxis.class);\r
+                if(axis.getAxis() instanceof ValueAxis) {\r
+                    ranges.add(axis);\r
+                    axisMap.put(axisResource, axis);\r
+                }\r
+            }\r
+            \r
+            // Get all domain axis\r
+            // There usually is only one domain axis, but this supports also multiple domain axis\r
+            domains = new ArrayList<IAxis>();\r
+            for(Resource axisResource : graph.syncRequest(new ObjectsWithType(plotResource, jfree.HasDomainAxis, jfree.Axis))) {\r
+                IAxis axis = graph.adapt(axisResource, IAxis.class);\r
+                if(axis.getAxis() instanceof ValueAxis) {\r
+                    domains.add(axis);\r
+                    axisMap.put(axisResource, axis);\r
+                }\r
+            }\r
+\r
+            // Get all datasets and map them to axis\r
+            datasets = new ArrayList<IDataset>();\r
+            rangeMappings = new HashMap<IDataset, IAxis>();\r
+            domainMappings = new HashMap<IDataset, IAxis>();\r
+            for(Resource datasetResource : graph.syncRequest(new ObjectsWithType(plotResource, l0.ConsistsOf, jfree.Dataset))) {\r
+                IDataset dataset = graph.adapt(datasetResource, IDataset.class);\r
+                if(dataset.getDataset() instanceof XYDataset) {\r
+                    datasets.add(dataset);\r
+                    Resource axisResource = graph.getPossibleObject(datasetResource, jfree.MapToRangeAxis);\r
+                    IAxis axis;\r
+                    if(axisMap.containsKey(axisResource)) {\r
+                        axis = axisMap.get(axisResource);\r
+                        rangeMappings.put(dataset, axis);\r
+                    }\r
+                    \r
+                    axisResource = graph.getPossibleObject(datasetResource, jfree.MapToDomainAxis);\r
+                    if(axisMap.containsKey(axisResource)) {\r
+                        axis = axisMap.get(axisResource);\r
+                        domainMappings.put(dataset, axis);\r
+                    }\r
+                }\r
+            }\r
+            \r
+            // Visual properties\r
+            visibleGrid = graph.getPossibleRelatedValue(plotResource, jfree.HasVisibleGrid);\r
+            \r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Plot getPlot() {\r
+        \r
+        plot = new org.jfree.chart.plot.XYPlot(null, null, null, null);\r
+\r
+        for(int i = 0; i < ranges.size(); i++) {\r
+            plot.setRangeAxis(i, (ValueAxis)ranges.get(i).getAxis());\r
+        }\r
+        \r
+        for(int i = 0; i < domains.size(); i++) {\r
+            plot.setDomainAxis(i, (ValueAxis)domains.get(i).getAxis());\r
+        }\r
+        \r
+        for(int i = 0; i < datasets.size(); i++) {\r
+            IDataset dataset = datasets.get(i);\r
+            plot.setDataset(i, (XYDataset)dataset.getDataset());\r
+            plot.setRenderer(i, (XYItemRenderer)dataset.getRenderer());\r
+            plot.mapDatasetToRangeAxis(i, ranges.indexOf(rangeMappings.get(dataset)));\r
+            plot.mapDatasetToDomainAxis(i, domains.indexOf(domainMappings.get(dataset)));\r
+        }\r
+        \r
+        if(visibleGrid != null) {\r
+            plot.setRangeGridlinesVisible(visibleGrid);\r
+            plot.setDomainGridlinesVisible(visibleGrid);\r
+        }\r
+        return plot;\r
+    }\r
+    \r
+    @Override\r
+    public void dispose() {\r
+        disposed = true;\r
+        \r
+        // Dispose all axis and datasets\r
+        for(IAxis axis : ranges)\r
+            axis.dispose();\r
+        \r
+        for(IAxis axis : domains)\r
+            axis.dispose();\r
+        \r
+        for(IDataset dataset : datasets)\r
+            dataset.dispose();\r
+    }\r
+\r
+    @Override\r
+    public boolean isDisposed() {\r
+        return disposed;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/AxisChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/AxisChildRule.java
new file mode 100644 (file)
index 0000000..2ab462e
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.graphexplorer;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.model.children.ChildRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+\r
+/**\r
+ * ChildRule for finding the axis of a JFreeChart\r
+ *  \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class AxisChildRule implements ChildRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getChildren(ReadGraph graph, Object parent) throws DatabaseException {\r
+        ArrayList<Resource> result = new ArrayList<Resource>();\r
+        if(!(parent instanceof Resource))\r
+            return result;\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        /*\r
+         * 1. chart may have multiple plots\r
+         * 2. plot may have multiple axis\r
+         */\r
+        for(Resource plot : graph.syncRequest(new ObjectsWithType((Resource)parent, l0.ConsistsOf, jfree.Plot))) {\r
+            for(Resource axis : graph.syncRequest(new ObjectsWithType(plot, jfree.HasRangeAxis, jfree.Axis))) {\r
+                result.add(axis);\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getParents(ReadGraph graph, Object child) throws DatabaseException {\r
+        return new ArrayList<Resource>();\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/VariableChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/VariableChildRule.java
new file mode 100644 (file)
index 0000000..62babf6
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.graphexplorer;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.model.children.ChildRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+\r
+/**\r
+ * ChildRule for finding the series of an axis\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class VariableChildRule implements ChildRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getChildren(ReadGraph graph, Object parent) throws DatabaseException {\r
+        ArrayList<Resource> result = new ArrayList<Resource>();\r
+        if(!(parent instanceof Resource))\r
+            return result;\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        Resource axis = (Resource)parent;\r
+        /*\r
+         * 1. Axis belongs to a plot\r
+         * 2. Plot may have multiple datasets\r
+         * 3. Dataset is mapped to a single range axis\r
+         * 3. Dataset may have multiple seires\r
+         */\r
+        Resource plot = graph.getSingleObject(axis, jfree.HasRangeAxis_Inverse);\r
+        for(Resource dataset : graph.syncRequest(new ObjectsWithType(plot, l0.ConsistsOf, jfree.Dataset))) {\r
+            if(graph.hasStatement(dataset, jfree.MapToRangeAxis, axis)) {\r
+                for(Resource series : graph.syncRequest(new ObjectsWithType(dataset, l0.ConsistsOf, jfree.Series))) {\r
+                    result.add(series);\r
+                }\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getParents(ReadGraph graph, Object child) throws DatabaseException {\r
+        return new ArrayList<Resource>();\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisPropertyComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisPropertyComposite.java
new file mode 100644 (file)
index 0000000..46ff15e
--- /dev/null
@@ -0,0 +1,111 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+\r
+/**\r
+ * Composite for displaying axis properties in {@link ChartAxisAndVariablesTab}\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class AxisPropertyComposite extends Composite {\r
+\r
+    TrackedText name, units, min, max;\r
+    Button tlabels, tmarks;\r
+    \r
+    public AxisPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) {\r
+        super(parent, style);\r
+        \r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this);\r
+        \r
+        // Name \r
+        Label label = new Label(this, SWT.NONE);\r
+        label.setText("Name:");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        \r
+        name = new TrackedText(this, support, SWT.BORDER);\r
+        name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, ""));\r
+        name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel));\r
+        name.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager()));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget());\r
+        \r
+        \r
+        // Label (units)\r
+        label = new Label(this, SWT.NONE);\r
+        label.setText("Label: ");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        \r
+        units = new TrackedText(this, support, SWT.BORDER);\r
+        units.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); // FIXME: Units \r
+        units.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); // FIXME: Units \r
+        units.setColorProvider(new JFreeChartPropertyColorProvider(units.getResourceManager()));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(units.getWidget());\r
+        \r
+        \r
+        // Minimum and maximum values\r
+        label = new Label(this, SWT.NONE);\r
+        label.setText("Min:");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        Composite minmax = new Composite(this, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(minmax);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(minmax);\r
+        min = new TrackedText(minmax, support, SWT.BORDER);\r
+        min.setColorProvider(new JFreeChartPropertyColorProvider(min.getResourceManager()));\r
+\r
+        label = new Label(minmax, SWT.NONE);\r
+        label.setText("Max:");\r
+        max = new TrackedText(minmax, support, SWT.BORDER);\r
+        max.setColorProvider(new JFreeChartPropertyColorProvider(max.getResourceManager()));\r
+\r
+        \r
+        // Color\r
+        label = new Label(this, SWT.NONE);\r
+        label.setText("Color:");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        \r
+        Composite colorPicker = new ColorPicker(this, context, support, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker);\r
+        \r
+        // Tick mark and label visibility\r
+        label = new Label(this, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        tmarks = new Button(this, support, SWT.CHECK);\r
+        tmarks.setText("Tick marks visible");\r
+        tmarks.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.HasVisibleTickMarks, false, true));\r
+        tmarks.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.HasVisibleTickMarks));\r
+        GridDataFactory.fillDefaults().applyTo(tmarks.getWidget());\r
+\r
+        label = new Label(this, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        tlabels = new Button(this, support, SWT.CHECK);\r
+        tlabels.setText("Tick labels visible");\r
+        tlabels.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.HasVisibleTickLabels, false, true));\r
+        tlabels.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.HasVisibleTickLabels));\r
+        GridDataFactory.fillDefaults().applyTo(tlabels.getWidget());\r
+    }\r
+    \r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/BooleanPropertyFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/BooleanPropertyFactory.java
new file mode 100644 (file)
index 0000000..00a0954
--- /dev/null
@@ -0,0 +1,130 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.utils.datastructures.Quad;\r
+\r
+/**\r
+ * PropertyFactory for finding a boolean property. Supports also finding the \r
+ * property from a first occurrence of resource ConsistsOf type HasProperty   \r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class BooleanPropertyFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+\r
+    final private String propertyURI;\r
+    final private String typeURI;\r
+    final private Boolean inverse;\r
+    final private Boolean defaultValue;\r
+    \r
+    /**\r
+     * PropertyFactory for finding a boolean property with propertyURI\r
+     * \r
+     * @param propertyURI URI for the boolean property\r
+     */\r
+    public BooleanPropertyFactory(String propertyURI) {\r
+        this(null, propertyURI, false);\r
+    }\r
+    \r
+    /**\r
+     * PropertyFactory for finding a boolean property with propertyURI.\r
+     * \r
+     * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible)\r
+     * \r
+     * @param propertyURI URI for the boolean property\r
+     * @param inverse Invert the result?\r
+     */\r
+    public BooleanPropertyFactory(String propertyURI, boolean inverse) {\r
+        this(null, propertyURI, inverse);\r
+    }\r
+\r
+    /**\r
+     * PropertyFactory for finding a boolean property with propertyURI.\r
+     *  \r
+     * Finds the property for first ObjectWithType(resource, L0.ConsistsOf, type)\r
+     *  \r
+     * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible)\r
+     *  \r
+     * @param typeURI URI for a resource (resource ConsistsOf type) (null allowed)\r
+     * @param propertyURI URI for the boolean property\r
+     * @param inverse Invert the result?\r
+     */\r
+    public BooleanPropertyFactory(String typeURI, String propertyURI, boolean inverse) {\r
+        this(typeURI, propertyURI, inverse, false);\r
+    }\r
+    \r
+    /**\r
+     * PropertyFactory for finding a boolean property with propertyURI.\r
+     *  \r
+     * Finds the property for first ObjectWithType(resource, L0.ConsistsOf, type)\r
+     *  \r
+     * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible)\r
+     * \r
+     * @param typeURI URI for a resource (resource ConsistsOf type) (null allowed -> not used)\r
+     * @param propertyURI URI for the boolean property\r
+     * @param inverse Invert the result?\r
+     * @param defaultValue default value\r
+     */\r
+    public BooleanPropertyFactory(String typeURI, String propertyURI, boolean inverse, boolean defaultValue) {\r
+        this.propertyURI = propertyURI;\r
+        this.inverse = inverse;\r
+        this.typeURI = typeURI;\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    @Override\r
+    public Object getIdentity(Object inputContents) {\r
+        return new Quad<Resource, String, Object, Boolean>((Resource) inputContents, propertyURI, getClass(), defaultValue);\r
+    }\r
+\r
+    @Override\r
+    public Boolean perform(ReadGraph graph, Resource r) throws DatabaseException {\r
+        if(typeURI == null) {\r
+            // if no typeUri, use the default resource r\r
+            return getValue(graph, r);\r
+        } else {\r
+            // typeURI was defined, find the property for the first occurence of ConsistsOf type\r
+            Resource type =  graph.getResource(typeURI);\r
+            for(Resource o : graph.syncRequest(new ObjectsWithType(r, Layer0.getInstance(graph).ConsistsOf, type))) {\r
+                // Returns the value for the first occurrence\r
+                return getValue(graph, o);\r
+            }\r
+        }\r
+        // if nothing was found with typeURI\r
+        return false;\r
+    }\r
+    \r
+    /**\r
+     * Return the value for a Boolean literal possibly inverted (or default if resource != Boolean literal) \r
+     * \r
+     * @param graph ReadGraph\r
+     * @param resource Literal Boolean resource \r
+     * @return value of the parameter (or default or inverted)\r
+     * @throws DatabaseException\r
+     */\r
+    private Boolean getValue(ReadGraph graph, Resource resource) throws DatabaseException {\r
+        Boolean value = graph.getPossibleRelatedValue(resource, graph.getResource(propertyURI), Bindings.BOOLEAN);\r
+        if(value != null) {\r
+            return !inverse.equals(value);\r
+        } else {\r
+            return defaultValue;\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/BooleanSelectionListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/BooleanSelectionListener.java
new file mode 100644 (file)
index 0000000..718b9b2
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.Layer0;\r
+\r
+/**\r
+ * Class for setting a boolean value when a selection occurs. (check box buttons)\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class BooleanSelectionListener extends SelectionListenerImpl<Resource> {\r
+\r
+    final private String propertyURI;\r
+    final private String typeUri;\r
+    \r
+    /**\r
+     * Boolean selection listener for property with propertyURI\r
+     * \r
+     * @param context ISessionContext\r
+     * @param propertyURI uri of the boolean property\r
+     */\r
+    public BooleanSelectionListener(ISessionContext context, String propertyURI) {\r
+        this(context, null, propertyURI);\r
+    }\r
+\r
+    /**\r
+     * Boolean selection listener for property with propertyURI\r
+     * Sets the property for all ObjectWithType(resource, L0.ConsistsOf, type)\r
+     * \r
+     * @param context ISessionContext\r
+     * @param typeUri URI for a resource (resource ConsistsOf type) (null allowed -> not used)\r
+     * @param propertyURI uri of the boolean property\r
+     */\r
+    public BooleanSelectionListener(ISessionContext context, String typeUri, String propertyURI) {\r
+        super(context);\r
+        this.propertyURI = propertyURI;\r
+        this.typeUri = typeUri;\r
+    }\r
+\r
+    @Override\r
+    public void apply(WriteGraph graph, Resource chart) throws DatabaseException {\r
+        if(typeUri == null) {\r
+            setValue(graph, chart);\r
+        } else {\r
+            Resource type =  graph.getResource(typeUri);\r
+            for(Resource object : graph.syncRequest(new ObjectsWithType(chart, Layer0.getInstance(graph).ConsistsOf, type))) {\r
+                setValue(graph, object);\r
+            }\r
+        }\r
+            \r
+    }\r
+    \r
+    /**\r
+     * Set boolean value for Boolean literal resource (inverts the current value).\r
+     * @param graph ReadGraph\r
+     * @param resource Boolean literal resource\r
+     * @throws DatabaseException\r
+     */\r
+    private void setValue(WriteGraph graph, Resource resource) throws DatabaseException {\r
+        Resource property =  graph.getResource(propertyURI);\r
+        Boolean value = graph.getPossibleRelatedValue(resource, property, Bindings.BOOLEAN);\r
+        graph.claimLiteral(resource, property, Boolean.FALSE.equals(value));\r
+    }\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartAxisAndVariablesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartAxisAndVariablesTab.java
new file mode 100644 (file)
index 0000000..0781414
--- /dev/null
@@ -0,0 +1,192 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.ScrolledComposite;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.LabelPropertyTabContributor;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.AdaptionUtils;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+\r
+/**\r
+ * PropertyTab displaying properties of axis and variables of a chart\r
+ *  \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartAxisAndVariablesTab extends LabelPropertyTabContributor {\r
+\r
+    private GraphExplorerComposite explorer;\r
+    private ScrolledComposite propertyContainer;\r
+    private Button addAxis, addVariable, remove;\r
+    private WidgetSupportImpl additionalSupport;\r
+    \r
+    public ChartAxisAndVariablesTab() {\r
+        additionalSupport = new WidgetSupportImpl();\r
+    }\r
+\r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) {\r
+        Composite composite = new Composite(body, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);\r
+\r
+        // (Ontology-based) GraphExplorer displaying range axis and variables mapped to those axis\r
+        explorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE);\r
+        explorer.setBrowseContexts(SysdynResource.URIs.ChartAxisAndVariablesBrowseContext);\r
+        explorer.setInputSource(new SingleSelectionInputSource(\r
+                Resource.class));\r
+        explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning\r
+        explorer.finish();\r
+\r
+        ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                updateSelection(context);\r
+            }\r
+        });\r
+        GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer);\r
+\r
+        // Scrolled composite for displaying properties of a selection in explorer\r
+        propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL);\r
+        GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer);\r
+        GridLayoutFactory.fillDefaults().applyTo(propertyContainer);\r
+        propertyContainer.setExpandHorizontal(true);\r
+        propertyContainer.setExpandVertical(true);\r
+        \r
+        // Buttons for adding axis and variables and removing selected items from explorer\r
+        Composite buttonComposite = new Composite(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(buttonComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite);\r
+        \r
+        addAxis = new Button(buttonComposite, support, SWT.NONE);\r
+        addAxis.setText("Add axis");\r
+        addAxis.addSelectionListener(new NewAxisListener(context));\r
+\r
+        addVariable = new Button(buttonComposite, support, SWT.NONE);\r
+        addVariable.setText("Add variable");\r
+\r
+        remove = new Button(buttonComposite, support, SWT.NONE);\r
+        remove.setText("Remove");\r
+    }\r
+\r
+    /**\r
+     * Updates the content of propertyContainer  \r
+     * @param context\r
+     */\r
+    private void updateSelection(ISessionContext context) {\r
+        ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
+        IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection();\r
+        final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class);\r
+        if(resource == null)\r
+            return;\r
+\r
+        // Get the type of the selected node (axis or series)\r
+        String typeUri = null;\r
+        try {\r
+            typeUri = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+                @Override\r
+                public String perform(ReadGraph graph) throws DatabaseException {\r
+                    JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                    if(graph.isInstanceOf(resource, jfree.Axis))\r
+                        return graph.getURI(jfree.Axis);\r
+                    else if (graph.isInstanceOf(resource, jfree.Series))\r
+                        return graph.getURI(jfree.Series);\r
+                    return null;\r
+                }\r
+                \r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        \r
+        // Create a PropertyComposite for the selected node\r
+        if(typeUri != null) {\r
+            \r
+            for(Control child : propertyContainer.getChildren()) {\r
+                child.dispose();\r
+            }\r
+            \r
+            if(typeUri.equals(JFreeChartResource.URIs.Axis)) {\r
+                AxisPropertyComposite apc = new AxisPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE);\r
+                propertyContainer.setContent(apc);\r
+                Point size = apc.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+                propertyContainer.setMinSize(size);\r
+            } else if(typeUri.equals(JFreeChartResource.URIs.Series)) {\r
+                SeriesPropertyComposite spc = new SeriesPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE);\r
+                propertyContainer.setContent(spc);\r
+                Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+                propertyContainer.setMinSize(size);\r
+            }\r
+        }\r
+        \r
+        additionalSupport.fireInput(context, selection);\r
+    }\r
+    \r
+    /**\r
+     * SelectionListener for adding a new range axis to a plot\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class NewAxisListener extends SelectionListenerImpl<Resource> {\r
+\r
+        public NewAxisListener(ISessionContext context) {\r
+            super(context);\r
+        }\r
+\r
+        @Override\r
+        public void apply(WriteGraph graph, Resource chart) throws DatabaseException {\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            \r
+            Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.Plot));\r
+            \r
+            if(plot != null)\r
+                GraphUtils.create2(graph, jfree.NumberAxis,\r
+                    l0.HasLabel, NameUtils.findFreshLabel(graph, "range", plot),\r
+                    jfree.HasRangeAxis_Inverse, plot,\r
+                    l0.PartOf, plot);\r
+        }\r
+        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartTab.java
new file mode 100644 (file)
index 0000000..179dbe9
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.ui.properties.LabelPropertyTabContributor;\r
+import org.simantics.sysdyn.ui.trend.chart.ChartComposite;\r
+import org.simantics.ui.utils.AdaptionUtils;\r
+\r
+/**\r
+ * Tab for displaying a chart\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartTab extends LabelPropertyTabContributor implements Widget {\r
+\r
+    private Composite parent;\r
+\r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+        support.register(this);\r
+        this.parent = body;\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, final Object input) {\r
+        Resource chart = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+        new ChartComposite(parent, chart, SWT.BORDER);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ColorPicker.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ColorPicker.java
new file mode 100644 (file)
index 0000000..de914e3
--- /dev/null
@@ -0,0 +1,375 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Device;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.widgets.ColorDialog;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.AdaptionUtils;\r
+import org.simantics.utils.RunnableWithObject;\r
+import org.simantics.utils.datastructures.Triple;\r
+\r
+/**\r
+ * Composite for selecting a color for a chart component\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ColorPicker extends Composite implements Widget {\r
+\r
+    Button defaultColor, customColor, color;\r
+\r
+    /**\r
+     * Create a composite containing radio buttons for default or custom color. Color chooser button is active\r
+     * when the custom radio button is selected. Color chooser uses {@link ColorDialog} to select a color \r
+     * \r
+     * @param parent Composite\r
+     * @param context ISessionContext\r
+     * @param support WidgetSupport\r
+     * @param style SWT style\r
+     */\r
+    public ColorPicker(Composite parent, ISessionContext context, WidgetSupport support, int style) {\r
+        super(parent, style);\r
+        support.register(this);\r
+        \r
+        GridLayoutFactory.fillDefaults().numColumns(4).applyTo(this);\r
+\r
+        defaultColor = new Button(this, support, SWT.RADIO);\r
+        defaultColor.setText("default");\r
+        defaultColor.setSelectionFactory(new DefaultColorSelectionFactory(false));\r
+        defaultColor.addSelectionListener(new DefaultColorSelectionListener(context));\r
+        GridDataFactory.fillDefaults().applyTo(defaultColor.getWidget());\r
+\r
+        customColor = new Button(this, support, SWT.RADIO);\r
+        customColor.setText("custom");\r
+        customColor.setSelectionFactory(new DefaultColorSelectionFactory(true));\r
+        customColor.addSelectionListener(new DefaultColorSelectionListener(context));\r
+        \r
+        GridDataFactory.fillDefaults().applyTo(customColor.getWidget());\r
+\r
+        color = new Button(this, support, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(color.getWidget());\r
+        color.setImageFactory(new ColorImageFactoryFactory(color));\r
+        color.addSelectionListener(new ColorSelectionListener(context));\r
+        color.getWidget().setEnabled(false);\r
+    }\r
+\r
+    /**\r
+     * Method for finding the resource for which the color is selected. \r
+     * \r
+     * @param graph ReadGraph\r
+     * @param input input from WidgetSupport\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    protected Resource getResource(ReadGraph graph, Resource input) throws DatabaseException {\r
+        return input;\r
+    }\r
+    \r
+    /**\r
+     * Method for getting the relation with which the g2d.Color is related to a resource\r
+     * \r
+     * @param graph ReadGraph\r
+     * @return Color relation\r
+     * @throws DatabaseException\r
+     */\r
+    protected Resource getColorRelation(ReadGraph graph) throws DatabaseException {\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+        return jfree.HasColor;\r
+    }\r
+    \r
+    \r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+        \r
+        // Create a listener to define the enabled state of the color chooser button\r
+        context.getSession().asyncRequest(new Read<Boolean>() {\r
+\r
+            @Override\r
+            public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                // if there is a color definition, the color chooser is active\r
+                Boolean result = graph.hasStatement(getResource(graph, resource), getColorRelation(graph));\r
+                return result;\r
+            }\r
+            \r
+        }, new Listener<Boolean>() {\r
+\r
+            @Override\r
+            public void execute(Boolean result) {\r
+                if(!color.getWidget().isDisposed()) {\r
+                    color.getWidget().getDisplay().asyncExec(new RunnableWithObject(result) {\r
+                        @Override\r
+                        public void run() {\r
+                            if(!color.getWidget().isDisposed())\r
+                                color.getWidget().setEnabled((Boolean)getObject());\r
+                        }\r
+                    });\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public void exception(Throwable t) {\r
+                t.printStackTrace();\r
+            }\r
+\r
+            @Override\r
+            public boolean isDisposed() {\r
+                return color.getWidget().isDisposed();\r
+            }\r
+        });\r
+    }\r
+    \r
+    /**\r
+     * Get a colored image to be displayed in the color chooser button\r
+     * \r
+     * @param device SWT Device\r
+     * @param red Red 0-255\r
+     * @param green Green 0-255\r
+     * @param blue Blue 0-255\r
+     * @return\r
+     */\r
+    private Image getColorPickerImage(Device device, int red, int green, int blue) {\r
+        Image image = new Image(device, 20, 20);\r
+        GC gc = new GC (image);\r
+        gc.setBackground (new Color(device, red, green, blue));\r
+        gc.fillRectangle (image.getBounds ());\r
+        gc.dispose ();\r
+        return image;\r
+    }\r
+\r
+    /**\r
+     * ImageFactory returning an image for color button\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class ColorImageFactoryFactory extends ReadFactoryImpl<Resource, Image> {\r
+        \r
+        Button button;\r
+        \r
+        public ColorImageFactoryFactory(Button button) {\r
+            super();\r
+            this.button = button;\r
+        }\r
+        \r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Class<?>, Button>(inputContents, getClass(), button);\r
+        }\r
+\r
+        @Override\r
+        public Image perform(ReadGraph graph, Resource input) throws DatabaseException {\r
+            if(button.getWidget().isDisposed())\r
+                return null;\r
+            Display device = button.getWidget().getDisplay();\r
+            if(device == null)\r
+                return null;\r
+            RGB rgb = getColor(graph, getResource(graph, input));\r
+            return getColorPickerImage(device, rgb.red, rgb.green, rgb.blue);\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Get RGB from a color literal resource. If resource is not a color resource, return blue (RGB 0, 0, 255)\r
+     * @param graph ReadGraph\r
+     * @param input Color literal resource (float[4])\r
+     * @return RGB color\r
+     * @throws DatabaseException\r
+     */\r
+    private RGB getColor(ReadGraph graph, Resource input) throws DatabaseException{\r
+        float[] colorComponents = graph.getPossibleRelatedValue(input, getColorRelation(graph));\r
+        RGB rgb;\r
+        if(colorComponents == null)\r
+            rgb = new RGB(0, 0, 255);\r
+        else\r
+            rgb = new RGB((int)(colorComponents[0] * 255.0f), \r
+                    (int)(colorComponents[1] * 255.0f), \r
+                    (int)(colorComponents[2] * 255.0f));\r
+        return rgb;\r
+    }\r
+\r
+\r
+    /**\r
+     * SelectionListener for color button. \r
+     * \r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class ColorSelectionListener extends SelectionListenerImpl<Resource> {\r
+\r
+        private SelectionEvent e;\r
+        private RGB rgb;\r
+        \r
+        /**\r
+         * \r
+         * @param context ISessionContext\r
+         */\r
+        public ColorSelectionListener(ISessionContext context) {\r
+            super(context);\r
+        }\r
+\r
+        @Override\r
+        public void widgetSelected(SelectionEvent e) {\r
+            if(color.getWidget().isDisposed())\r
+                return;\r
+            // Save the event for coordinates\r
+            this.e = e;\r
+            super.widgetSelected(e);\r
+        }\r
+\r
+        @Override\r
+        public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+            if(color.getWidget().isDisposed())\r
+                return;\r
+            \r
+            final Resource resource = getResource(graph, input);\r
+            final Display display = color.getWidget().getDisplay();\r
+            final RGB oldRGB = getColor(graph, resource);\r
+            \r
+            display.asyncExec(new RunnableWithObject(oldRGB) {\r
+                public void run() {\r
+                    // Use color dialog to select a color\r
+                    Shell shell = new Shell(display);\r
+                    ColorDialog cd = new ColorDialog(shell);\r
+                    Point point = color.getWidget().toDisplay(e.x - 150, e.y - 150);\r
+                    cd.getParent().setLocation(point.x, point.y);\r
+                    cd.setText("Select color");\r
+                    cd.setRGB((RGB)getObject());\r
+                    rgb = cd.open();\r
+                    if(rgb == null)\r
+                        return;\r
+                    \r
+                    SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                        \r
+                        @Override\r
+                        public void perform(WriteGraph graph) throws DatabaseException {\r
+                            G2DResource g2d = G2DResource.getInstance(graph);\r
+                            float[] components = new float[] {(float)rgb.red / 255.0f,  (float)rgb.green / 255.0f, (float)rgb.blue / 255.0f, 1.0f};\r
+                            graph.claimLiteral(resource, getColorRelation(graph), g2d.Color, components);                            \r
+                        }\r
+                    });\r
+                    \r
+                }\r
+            });\r
+            \r
+            \r
+\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * SelectionFactory for default and custom color radio buttons\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class DefaultColorSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+\r
+        private Boolean isCustom;\r
+\r
+        /**\r
+         * \r
+         * @param isCustom Is this custom button?\r
+         */\r
+        public DefaultColorSelectionFactory(Boolean isCustom) {\r
+            super();\r
+            this.isCustom = isCustom;\r
+        }\r
+\r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Resource, Object, Boolean>((Resource) inputContents, getClass(), isCustom);\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource input) throws DatabaseException {\r
+            Resource r = graph.getPossibleObject(getResource(graph, input), getColorRelation(graph));\r
+            boolean result = false; // Default == not selected\r
+            if(r == null && !isCustom) {\r
+                // No color definition and default-button -> selected\r
+                result =  true;\r
+            } else if(r != null && isCustom) {\r
+                // color definition and custom button -> selected\r
+                result =  true;\r
+            }\r
+            return result;\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * SelectionListener for default and custom radio buttons\r
+     * \r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class DefaultColorSelectionListener extends SelectionListenerImpl<Resource> {\r
+\r
+        private SelectionEvent e;\r
+\r
+        public DefaultColorSelectionListener(ISessionContext context) {\r
+            super(context);\r
+        }\r
+\r
+        @Override\r
+        public void widgetSelected(SelectionEvent e) {\r
+            this.e = e; \r
+            super.widgetSelected(e);\r
+        }\r
+\r
+        @Override\r
+        public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+            Resource resource = getResource(graph, input);\r
+            if(customColor.getWidget().equals(e.widget)) {\r
+                // Custom selected. If there is no color already, create a default Blue color\r
+                G2DResource g2d = G2DResource.getInstance(graph);\r
+                if(graph.getPossibleObject(resource, getColorRelation(graph)) == null) {\r
+                    float[] components = java.awt.Color.BLUE.getColorComponents(new float[4]);\r
+                    components[3] = 1.0f;\r
+                    graph.claimLiteral(resource, getColorRelation(graph), g2d.Color, components);\r
+                }\r
+            } else {\r
+                // Default selected, remove color definition\r
+                graph.deny(resource, getColorRelation(graph));\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/GeneralChartPropertiesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/GeneralChartPropertiesTab.java
new file mode 100644 (file)
index 0000000..4cf681c
--- /dev/null
@@ -0,0 +1,225 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.ScrolledComposite;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.ui.properties.LabelPropertyTabContributor;\r
+\r
+/**\r
+ * PropertyTab displaying general properties and x-axis properties of a chart\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class GeneralChartPropertiesTab extends LabelPropertyTabContributor implements Widget {\r
+\r
+    private ScrolledComposite sc;\r
+    private Composite composite;\r
+    private org.simantics.browsing.ui.swt.widgets.TrackedText name, title;\r
+    private Text xlabel, xvariable, xmin, xmax;\r
+    private Combo type;\r
+    private Button hgrid, htitle, hlegend, hxlabel;\r
+\r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {    \r
+        support.register(this);\r
+\r
+        // Scrolled composite containing all of the properties in this tab\r
+        sc = new ScrolledComposite(body, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(sc);\r
+        GridLayoutFactory.fillDefaults().applyTo(sc);\r
+        sc.setExpandHorizontal(true);\r
+        sc.setExpandVertical(true);\r
+\r
+        composite = new Composite(sc, SWT.NONE);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);\r
+\r
+        // General properties\r
+        Group general = new Group(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(general);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(general);\r
+        general.setText("General");\r
+\r
+        // Name\r
+        Label label = new Label(general, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        label.setText("Name:");\r
+\r
+        Composite c = new Composite(general, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(c);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(c);\r
+\r
+        name = new org.simantics.browsing.ui.swt.widgets.TrackedText(c, support, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget());\r
+        name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
+        name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
+        name.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager()));\r
+\r
+        // Type\r
+        label = new Label(c, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        label.setText("Type:");\r
+\r
+        type = new Combo(c, SWT.BORDER | SWT.READ_ONLY);\r
+        type.setItems(new String[] {"Line", "Fancy", "Area", "3D"});\r
+        type.select(0);\r
+\r
+        // Title (Which is different than name)\r
+        label = new Label(general, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        label.setText("Title:");\r
+\r
+        title = new org.simantics.browsing.ui.swt.widgets.TrackedText(general, support, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(title.getWidget());\r
+        title.setTextFactory(new TitleFactory());\r
+        title.addModifyListener(new TitleModifier());\r
+        title.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager()));\r
+\r
+        // Group for hide options\r
+        Group hideGroup = new Group(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(hideGroup);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(hideGroup);\r
+        hideGroup.setText("Hide");\r
+\r
+        hgrid = new Button(hideGroup, support, SWT.CHECK);\r
+        hgrid.setText("Grid");\r
+        hgrid.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.HasVisibleGrid, true, true));\r
+        hgrid.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.HasVisibleGrid));\r
+        htitle = new Button(hideGroup, support, SWT.CHECK);\r
+        htitle.setText("Title");\r
+        htitle.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.IsVisible, true, true));\r
+        htitle.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.IsVisible));\r
+        hlegend = new Button(hideGroup, support, SWT.CHECK);\r
+        hlegend.setText("Legend");\r
+        hlegend.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.HasVisibleLegend, true, true));\r
+        hlegend.addSelectionListener(new BooleanSelectionListener(context, null, JFreeChartResource.URIs.HasVisibleLegend));\r
+        hxlabel = new Button(hideGroup, support, SWT.CHECK);\r
+        hxlabel.setText("X-label");\r
+\r
+        \r
+        // X-Axis properties\r
+        Group xgroup = new Group(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(xgroup);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(xgroup);\r
+        xgroup.setText("X-axis");\r
+\r
+        // Variable for x-axis (default: empty == time)\r
+        label = new Label(xgroup, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        label.setText("Variable:");\r
+\r
+        xvariable = new Text(xgroup, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(xvariable);\r
+\r
+        // Label for x-axis\r
+        label = new Label(xgroup, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        label.setText("Label:");\r
+\r
+        xlabel = new Text(xgroup, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(xlabel);\r
+\r
+        // Min and max values for x-axis\r
+        label = new Label(xgroup, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        label.setText("Min:");\r
+\r
+        Composite minmax = new Composite(xgroup, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(minmax);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(minmax);\r
+        xmin = new Text(minmax, SWT.BORDER);\r
+        xmin.setText("");\r
+\r
+        label = new Label(minmax, SWT.NONE);\r
+        label.setText("Max:");\r
+        xmax = new Text(minmax, SWT.BORDER);\r
+        xmax.setText("");\r
+\r
+        sc.setContent(composite);\r
+        Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+        sc.setMinSize(size);\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+\r
+    }\r
+\r
+    /**\r
+     * TextFactory for chart title\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class TitleFactory extends ReadFactoryImpl<Resource, String>   {\r
+        @Override\r
+        public String perform(ReadGraph graph, Resource chart) throws DatabaseException {\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+            Resource title = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.TextTitle));\r
+            if(title == null)\r
+                return "";\r
+            else {\r
+                String label = graph.getPossibleRelatedValue(title, l0.HasLabel, Bindings.STRING);\r
+                return label == null ? "" : label;\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * TitleModifier for chart title\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class TitleModifier extends TextModifyListenerImpl<Resource> {\r
+\r
+        @Override\r
+        public void applyText(WriteGraph graph, Resource chart, String text) throws DatabaseException {\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+            Resource title = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.TextTitle));\r
+            if(title == null) {\r
+                title = GraphUtils.create2(graph, jfree.TextTitle,\r
+                        jfree.HasPosition, jfree.Top);\r
+            }\r
+            graph.claimLiteral(title, l0.HasLabel, text);\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/JFreeChartPropertyColorProvider.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/JFreeChartPropertyColorProvider.java
new file mode 100644 (file)
index 0000000..d8dea9b
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.eclipse.jface.resource.ColorDescriptor;\r
+import org.eclipse.jface.resource.ResourceManager;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ITrackedColorProvider;\r
+\r
+/**\r
+ * ColorProvider providing coloring scheme for chart tab text widgets\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class JFreeChartPropertyColorProvider implements ITrackedColorProvider {\r
+    \r
+    private final ResourceManager resourceManager;\r
+    \r
+    private final ColorDescriptor highlightColor = ColorDescriptor.createFrom(new RGB(254, 255, 197));\r
+    private final ColorDescriptor inactiveColor = ColorDescriptor.createFrom(new RGB(255, 255, 255));\r
+    private final ColorDescriptor invalidInputColor = ColorDescriptor.createFrom(new RGB(255, 128, 128));\r
+\r
+    public JFreeChartPropertyColorProvider(ResourceManager resourceManager) {\r
+        this.resourceManager = resourceManager;\r
+    }\r
+    \r
+    @Override\r
+    public Color getEditingBackground() {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public Color getHoverBackground() {\r
+        return resourceManager.createColor(highlightColor);\r
+    }\r
+\r
+    @Override\r
+    public Color getInactiveBackground() {\r
+        return resourceManager.createColor(inactiveColor);\r
+    }\r
+\r
+    @Override\r
+    public Color getInvalidBackground() {\r
+        return resourceManager.createColor(invalidInputColor);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/SeriesPropertyComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/SeriesPropertyComposite.java
new file mode 100644 (file)
index 0000000..387b8dc
--- /dev/null
@@ -0,0 +1,170 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Spinner;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.utils.AdaptionUtils;\r
+\r
+/**\r
+ * Composite for displaying series properties in {@link ChartAxisAndVariablesTab}\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SeriesPropertyComposite extends Composite {\r
+\r
+    private TrackedText variable, label;\r
+    private TrackedSpinner width;\r
+\r
+    public SeriesPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) {\r
+        super(parent, style);\r
+        \r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this);\r
+\r
+        // Variable for the series\r
+        Label label = new Label(this, SWT.NONE);\r
+        label.setText("Variable:");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+\r
+        this.variable = new TrackedText(this, support, SWT.BORDER);\r
+        this.variable.setTextFactory(new StringPropertyFactory(JFreeChartResource.URIs.HasVariableRVI, ""));\r
+        this.variable.addModifyListener(new StringPropertyModifier(context, JFreeChartResource.URIs.HasVariableRVI));\r
+        this.variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager()));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget());\r
+\r
+        // Label to be displayed in chart for this series (usually same as the variable \r
+        label = new Label(this, SWT.NONE);\r
+        label.setText("Label:");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+\r
+        this.label = new TrackedText(this, support, SWT.BORDER);\r
+        this.label.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, ""));\r
+        this.label.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel));\r
+        this.label.setColorProvider(new JFreeChartPropertyColorProvider(this.label.getResourceManager()));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(this.label.getWidget());\r
+\r
+        // Color\r
+        label = new Label(this, SWT.NONE);\r
+        label.setText("Color:");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        \r
+        Composite colorPicker = new ColorPicker(this, context, support, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker);\r
+\r
+        // Line width\r
+        label = new Label(this, SWT.NONE);\r
+        label.setText("Line width:");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+\r
+        width = new TrackedSpinner(this, support, SWT.BORDER);\r
+        width.setSelectionFactory(new WidthSelectionFactory());\r
+        width.addModifyListener(new WidthModifyListener());\r
+        width.setMinimum(1);\r
+        width.setMaximum(10);\r
+\r
+    }\r
+\r
+\r
+    /**\r
+     * ModifyListener for the width {@link TrackedSpinner}\r
+     * \r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class WidthModifyListener implements TextModifyListener, Widget {\r
+\r
+        private ISessionContext context;\r
+        private Object lastInput = null;\r
+\r
+        @Override\r
+        public void modifyText(TrackedModifyEvent e) {\r
+            if(context == null)\r
+                return;\r
+\r
+            // Get the text value from spinner and associated resource (input)\r
+            Spinner spinner = (Spinner)e.getWidget();\r
+            final String textValue = spinner.getText();\r
+            final Object input = lastInput;\r
+\r
+            try {\r
+                context.getSession().syncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        // Apply with (textValue) to the series (input)\r
+                        Resource series = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+                        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                        try {\r
+                            // usually reliable, since the spinner does all the checks\r
+                            Integer value = Integer.parseInt(textValue); \r
+                            graph.claimLiteral(series, jfree.HasLineWidth, value, Bindings.INTEGER);\r
+                        } catch (NumberFormatException e) {\r
+                            e.printStackTrace();\r
+                        }\r
+                    }\r
+\r
+                });\r
+            } catch (DatabaseException e1) {\r
+                e1.printStackTrace();\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void setInput(ISessionContext context, Object parameter) {\r
+            this.context = context;\r
+            lastInput = parameter;\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Class for setting the value for width {@link TrackedSpinner}\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class WidthSelectionFactory extends ReadFactoryImpl<Resource, Integer>   {\r
+\r
+        @Override\r
+        public Integer perform(ReadGraph graph, Resource axis) throws DatabaseException {\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+            Integer width = graph.getPossibleRelatedValue(axis, jfree.HasLineWidth);\r
+            if(width == null)\r
+                // Default width == 1\r
+                width = 1;\r
+            return width;\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TrackedSpinner.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TrackedSpinner.java
new file mode 100644 (file)
index 0000000..b27ecd0
--- /dev/null
@@ -0,0 +1,179 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend.chart.properties;\r
+\r
+import org.eclipse.core.runtime.ListenerList;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Spinner;\r
+import org.simantics.browsing.ui.common.ErrorLogger;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactory;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.utils.ui.SWTUtils;\r
+\r
+/**\r
+ * Class for implementing Widget behavior for SWT Spinner in Simantics.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class TrackedSpinner implements Widget {\r
+\r
+    private Spinner         spinner;\r
+    private ListenerList    modifyListeners;\r
+    private ReadFactory<?, Integer> selectionFactory;\r
+\r
+\r
+    public TrackedSpinner(Composite parent, WidgetSupport support, int style) {\r
+        spinner = new Spinner(parent, style);\r
+        support.register(this);\r
+        \r
+        // Add a ModifyListener that uses all listeners in modifyListeners -list\r
+        spinner.addModifyListener(new ModifyListener() {\r
+            \r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                if (modifyListeners != null) {\r
+                    TrackedModifyEvent event = new TrackedModifyEvent(spinner, spinner.getText());\r
+                    for (Object o : modifyListeners.getListeners()) {\r
+                        ((TextModifyListener) o).modifyText(event);\r
+                    }\r
+                }                \r
+            }\r
+        });\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+\r
+        // Update all modifyListeners\r
+        if (modifyListeners != null) {\r
+            for (Object o : modifyListeners.getListeners()) {\r
+                if(o instanceof Widget) {\r
+                    ((Widget) o).setInput(context, input);\r
+                }\r
+            }\r
+        }\r
+\r
+        if (selectionFactory != null) {\r
+            // Get a value for the spinner\r
+            selectionFactory.listen(context, input, new Listener<Integer>() {\r
+                @Override\r
+                public void exception(Throwable t) {\r
+                    ErrorLogger.defaultLogError(t);\r
+                }\r
+                @Override\r
+                public void execute(final Integer selection) {\r
+                    SWTUtils.asyncExec(spinner, new Runnable() {\r
+                        @Override\r
+                        public void run() {\r
+                            if(isDisposed()) return;\r
+                            spinner.setSelection(selection);\r
+                        }\r
+                    });\r
+                }\r
+                @Override\r
+                public boolean isDisposed() {\r
+                    return spinner.isDisposed();\r
+                }\r
+            });\r
+        }\r
+\r
+    }\r
+    \r
+    /**\r
+     * Set a selection factory for the spinner\r
+     * \r
+     * @param selectionFactory ReadFactory<?, Integer> SelectionFactory\r
+     */\r
+    public void setSelectionFactory(ReadFactory<?, Integer> selectionFactory) {\r
+        this.selectionFactory = selectionFactory;\r
+    }\r
+    \r
+    /**\r
+     * Add a modifyListener for the spinner\r
+     * @param listener TextModifyListener\r
+     */\r
+    public synchronized void addModifyListener(TextModifyListener listener) {\r
+        if (modifyListeners == null) {\r
+            modifyListeners = new ListenerList(ListenerList.IDENTITY);\r
+        }\r
+        modifyListeners.add(listener);\r
+    }\r
+\r
+    /**\r
+     * Remove modifyListener from the spinner\r
+     * \r
+     * @param listener TextModifyListener\r
+     */\r
+    public synchronized void removeModifyListener(TextModifyListener listener) {\r
+        if (modifyListeners == null)\r
+            return;\r
+        modifyListeners.remove(listener);\r
+    }\r
+\r
+    /**\r
+     * Get the SWT Spinner of this TrackedSpinner widget\r
+     * @return\r
+     */\r
+    public Spinner getWidget() {\r
+        return spinner;\r
+    }\r
+    \r
+    /**\r
+     * Set minimum value \r
+     * @param value int minimum value\r
+     */\r
+    public void setMinimum(int value) {\r
+        spinner.setMinimum(value);\r
+    }\r
+    \r
+    /**\r
+     * Set maximum value\r
+     * @param value int maximum value\r
+     */\r
+    public void setMaximum(int value) {\r
+        spinner.setMaximum(value);\r
+    }\r
+    \r
+    /**\r
+     * Sets the receiver's selection, minimum value, maximum value, digits, increment and page increment all at once. \r
+     * \r
+     * @param selection the new selection value\r
+     * @param minimum the new minimum value\r
+     * @param maximum the new maximum value\r
+     * @param digits the new digits value\r
+     * @param increment the new increment value\r
+     * @param pageIncrement the new pageIncrement value\r
+     */\r
+    public void setValues(int selection, int  minimum, int  maximum, int digits, int increment, int pageIncrement) {\r
+        spinner.setValues(selection, minimum, maximum, digits, increment, pageIncrement);\r
+    }\r
+    \r
+    /**\r
+     * Sets the selection, which is the receiver's position, to the argument.\r
+     * If the argument is not within the range specified by minimum and maximum, \r
+     * it will be adjusted to fall within this range.\r
+     * \r
+     * @param value\r
+     */\r
+    public void setSelection(int value) {\r
+        spinner.setSelection(value);\r
+    }\r
+\r
+}\r
index 4eaefba7a98d8b9bf387f198115d1281ca1b1717..5ea14eea0863d5c76048b805c5de399609e7d628 100644 (file)
@@ -13,10 +13,10 @@ package org.simantics.sysdyn.ui.values;
 \r
 import java.util.ArrayList;\r
 import java.util.Collection;\r
-import java.util.List;\r
 \r
 import org.eclipse.jface.layout.GridDataFactory;\r
 import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ISelection;\r
 import org.eclipse.swt.SWT;\r
 import org.eclipse.swt.dnd.Clipboard;\r
 import org.eclipse.swt.dnd.TextTransfer;\r
@@ -35,6 +35,13 @@ import org.eclipse.ui.part.ViewPart;
 import org.simantics.sysdyn.manager.SysdynDataSet;\r
 import org.simantics.sysdyn.ui.viewUtils.SysdynDatasetSelectionListener;\r
 \r
+/**\r
+ * A view that shows the values of currently selected variables in a table. \r
+ * One column (first by default) is always time values.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class ValueView  extends ViewPart {\r
 \r
        private boolean disposed;\r
@@ -52,6 +59,7 @@ public class ValueView  extends ViewPart {
                GridLayoutFactory.fillDefaults().applyTo(baseComposite);\r
                GridDataFactory.fillDefaults().grab(true, true).applyTo(baseComposite);\r
 \r
+               // Result table\r
                table = new Table (baseComposite, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);\r
                GridDataFactory.fillDefaults().grab(true, true).applyTo(table);\r
                table.setLinesVisible (true);\r
@@ -61,6 +69,7 @@ public class ValueView  extends ViewPart {
                table.setLayoutData(data);\r
 \r
 \r
+               // Add selectionListener for updating the table\r
                selectionListener = new SysdynDatasetSelectionListener() {\r
 \r
                        @Override\r
@@ -77,6 +86,11 @@ public class ValueView  extends ViewPart {
                }; \r
                getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(selectionListener);\r
                \r
+               // Refreshes the table. There might be a selection already before the table is shown.\r
+               ISelection selection = getSite().getWorkbenchWindow().getSelectionService().getSelection();\r
+               if(selection != null)\r
+                   selectionListener.selectionChanged(getSite().getPart(), selection);\r
+               \r
                \r
                /*\r
                 * A primitive copy paste to support exporting data from table to excel\r
@@ -87,7 +101,6 @@ public class ValueView  extends ViewPart {
                 * value\tvalue\tvalue\n\r
                 * \r
                 */\r
-                \r
                KeyListener kl = new KeyListener() {\r
             \r
             @Override\r
@@ -99,12 +112,12 @@ public class ValueView  extends ViewPart {
             public void keyPressed(KeyEvent e) {\r
                 if (e.stateMask == SWT.CTRL && e.keyCode == 99)\r
                 {\r
-                    System.out.println("CTRL C is pressed");\r
                     \r
                     Clipboard cb = new Clipboard(e.display);\r
                     \r
                     TextTransfer textTransfer = TextTransfer.getInstance();\r
                     \r
+                    // Add names of the columns first. Selection is always full, print all columns\r
                     StringBuilder sb = new StringBuilder();\r
                     int columnCount = table.getColumnCount();\r
                     for(int i = 0; i < columnCount; i++) {\r
@@ -116,7 +129,7 @@ public class ValueView  extends ViewPart {
                             sb.append("\n");\r
                     }\r
                     \r
-                    \r
+                    // Print all selected rows. \r
                     for(TableItem ti : table.getSelection())\r
                         for(int i = 0; i < columnCount; i++) {\r
                             sb.append(ti.getText(i));\r
@@ -136,6 +149,11 @@ public class ValueView  extends ViewPart {
 \r
        }\r
 \r
+       /**\r
+        * Updates the table after selection has been changed\r
+        * \r
+        * @param activeDatasets\r
+        */\r
        private void updateTable(Collection<SysdynDataSet> activeDatasets) {\r
 \r
                if(activeDatasets.isEmpty() || !(activeDatasets instanceof ArrayList)) return;\r
@@ -153,13 +171,13 @@ public class ValueView  extends ViewPart {
                \r
                ArrayList<String> titleList = new ArrayList<String>();\r
                titleList.add("Time");\r
-               List<Double> times = null;\r
+               double[] times = new double[0];\r
                for (int i=0; i<datasets.size(); i++) {\r
                        String name = datasets.get(i).name;\r
                        if(datasets.get(i).result != null)\r
                                name += " : " + datasets.get(i).result;\r
                        titleList.add(name);\r
-                       if(times == null || datasets.get(i).values.size() > times.size()) {\r
+                       if(times == null || datasets.get(i).values.length > times.length) {\r
                                times = datasets.get(i).times;\r
                        }\r
                }\r
@@ -241,11 +259,11 @@ public class ValueView  extends ViewPart {
            \r
                // add results\r
                \r
-               for (int i=0; i<times.size(); i++) {\r
+               for (int i=0; i<times.length; i++) {\r
                        TableItem item = new TableItem (table, SWT.NONE);\r
-                       item.setText(0, times.get(i).toString());\r
+                       item.setText(0, String.valueOf(times[i]));\r
                        for(int j=0; j<datasets.size(); j++) {\r
-                               String approximation = approximate(times.get(i), i, datasets.get(j));\r
+                               String approximation = approximate(times[i], i, datasets.get(j));\r
                                item.setText (j + 1 /* time is at column 0 */, approximation);\r
                        }\r
                }\r
@@ -257,44 +275,57 @@ public class ValueView  extends ViewPart {
        }\r
 \r
        \r
+       /**\r
+        * Approximate a value for a table cell. There might not be a value for some specific time step\r
+        * due to different result sets. Approximation uses linear interpolation to calculate an approximate\r
+        * value for the desired time step. \r
+        * \r
+        * @param time Time step that is displayed\r
+        * @param index Index of the displayed time on its dataset\r
+        * @param dataset The dataset that contains the values that are displayed\r
+        * @return The exact value of an approximate if an exat value is not found\r
+        */\r
        private String approximate(Double time, int index, SysdynDataSet dataset) {\r
                \r
                // time out of datasets range\r
-               if(time > dataset.times.get(dataset.times.size() - 1) ||\r
-                               time < dataset.times.get(0)) {\r
+               if(time > dataset.times[dataset.times.length - 1] ||\r
+                               time < dataset.times[0]) {\r
                        return "---";\r
                }\r
                \r
                // Make sure the index is within times array\r
-               if(index >= dataset.times.size())\r
-                       index = dataset.times.size() - 1;\r
+               if(index >= dataset.times.length)\r
+                       index = dataset.times.length - 1;\r
 \r
                // times match, no approximation needed\r
-               if(dataset.times.contains(time)) {\r
-                       return dataset.values.get(dataset.times.indexOf(time)).toString();\r
+               double t;\r
+               for(int i = 0; i < dataset.times.length; i++) {\r
+                   t = dataset.times[i];\r
+                   if(t == time)\r
+                       return String.valueOf(dataset.values[i]);\r
                }\r
 \r
                // Search the position on datasets' timeline\r
                int dir = table.getSortDirection();\r
-               while(dataset.times.get(index) > time) {\r
+               while(dataset.times[index] > time) {\r
                        index = dir == SWT.UP ? index - 1 : index + 1;\r
                }\r
-               while(dataset.times.get(index) <= time)\r
+               while(dataset.times[index] <= time)\r
                        index = dir == SWT.UP ? index + 1 : index - 1;\r
                \r
                int a = dir == SWT.UP ? index - 1 : index;\r
                int b = dir == SWT.UP ? index : index - 1;\r
                \r
-               return dataset.values.get(a) + \r
-               (dataset.values.get(b) - dataset.values.get(a)) * \r
-               (time - dataset.times.get(a)) /\r
-               (dataset.times.get(b) - dataset.times.get(a)) + "*"; \r
+               // Calculate and return approximation\r
+               return dataset.values[a] + \r
+               (dataset.values[b] - dataset.values[a]) * \r
+               (time - dataset.times[a]) /\r
+               (dataset.times[b] - dataset.times[a]) + "*"; \r
        }\r
 \r
        @Override\r
        public void setFocus() {\r
-               // TODO Auto-generated method stub\r
-\r
+           \r
        }\r
 \r
        @Override\r
index 7ef3946c2c1466f928b558423476398bc54c5e64..f2b5f45f2440b0983ed4bcc1ce36a752d1ddc742 100644 (file)
@@ -47,6 +47,12 @@ import org.simantics.sysdyn.manager.SysdynModelManager;
 import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
 import org.simantics.sysdyn.manager.SysdynResult;\r
 \r
+/**\r
+ * \r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class HistoryVariable extends ChildVariable implements PropertyProvider {\r
 \r
     static Boolean DEBUG = false;\r
@@ -76,7 +82,7 @@ public class HistoryVariable extends ChildVariable implements PropertyProvider {
                            System.out.println("HistoryVariable rvi='" + tmp + "'");\r
                        final String rvi = tmp.substring(1).replace("/", ".");\r
                        SysdynDataSet ds = sr.getDataSet(rvi);\r
-                       if(ds == null) ds = new SysdynDataSet("", "", new ArrayList<Double>(), new ArrayList<Double>()); // We need a dataset, so if not set, create it\r
+                       if(ds == null) ds = new SysdynDataSet("", "", new double[0], new double[0]); // We need a dataset, so if not set, create it\r
                        try {\r
                                final RecordAccessor ac = (RecordAccessor)Accessors.getAccessor(Bindings.getBindingUnchecked(SysdynDataSet.class), ds);\r
                                \r
@@ -179,7 +185,10 @@ public class HistoryVariable extends ChildVariable implements PropertyProvider {
                if(rvi == null) {\r
                    rvi = Variables.getRVI(graph, this).substring(1).replace("/", ".");\r
                }\r
-               return graph.syncRequest(new PropertyRequest(this, name));\r
+               if(SysdynVariableProperties.TIMES.equals(name))\r
+                   return getProperty(name);\r
+               else\r
+                   return graph.syncRequest(new PropertyRequest(this, name));\r
            }\r
            return super.getPossibleExtraProperty(graph, name);\r
        }\r
@@ -227,16 +236,16 @@ public class HistoryVariable extends ChildVariable implements PropertyProvider {
             SysdynResult sr = new SysdynResult(model.getSimulationResult());\r
             SysdynDataSet ds = sr.getDataSet(rvi);\r
             if(ds == null)\r
-                return new ConstantPropertyVariable(this, name, new Double[0], Datatypes.DOUBLE_ARRAY);\r
+                return new ConstantPropertyVariable(this, name, new double[0], Datatypes.DOUBLE_ARRAY);\r
             else\r
-                return new ConstantPropertyVariable(this, name, ds.values.toArray(new Double[ds.values.size()]), Datatypes.DOUBLE_ARRAY);\r
+                return new ConstantPropertyVariable(this, name, ds.values, Datatypes.DOUBLE_ARRAY);\r
        } else if(SysdynVariableProperties.TIMES.equals(name)) {\r
             SysdynResult sr = new SysdynResult(model.getSimulationResult());\r
             SysdynDataSet ds = sr.getDataSet(rvi);\r
             if(ds == null)\r
-                return new ConstantPropertyVariable(this, name, new Double[0], Datatypes.DOUBLE_ARRAY);\r
+                return new ConstantPropertyVariable(this, name, new double[0], Datatypes.DOUBLE_ARRAY);\r
             else\r
-                return new ConstantPropertyVariable(this, name, ds.times.toArray(new Double[ds.times.size()]), Datatypes.DOUBLE_ARRAY);\r
+                return new ConstantPropertyVariable(this, name, ds.times, Datatypes.DOUBLE_ARRAY);\r
         }\r
         return null;\r
     }\r