]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Cleanup code in EquationTab and fix StockExpression class 87/4387/3
authorJani Mäkinen <jani.makinen@semantum.fi>
Wed, 19 Aug 2020 12:39:06 +0000 (15:39 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 25 Aug 2020 10:51:27 +0000 (13:51 +0300)
gitlab #49

Change-Id: I4bac3bc28865f02951d480087af50964994d6310

bundles/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java
bundles/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionWidget.java
bundles/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java

index 8b62d3ae19a4d77c73fc72f81ef3bfa788873e98..3ba3a3a664f4bf92a24d1967f56583088646194c 100644 (file)
@@ -259,9 +259,9 @@ public class EquationTab extends AdjustableTab implements Widget {
                        return;
 
                DataContainer<Boolean> isListenerActive = lastActiveInput;
-               Resource expression = null;
+
                try {
-                       expression = Simantics.getSession().syncRequest(new ResourceRead<Resource>(variable) {
+                       Simantics.getSession().syncRequest(new ResourceRead<Resource>(variable) {
 
                                @Override
                                public Resource perform(ReadGraph graph) throws DatabaseException {
@@ -280,83 +280,18 @@ public class EquationTab extends AdjustableTab implements Widget {
 
                                @Override
                                public void exception(Throwable t) {
-                                       LOGGER.error("getActiveExpression failed", t);
+                                       LOGGER.error("Error while reading active expression", t);
                                }
 
                                @Override
                                public boolean isDisposed() {
-                                       return !isListenerActive.get();
+                                       return !isListenerActive.get() || composite.isDisposed();
                                }});
+
                } catch (DatabaseException e) {
                        LOGGER.error("getActiveExpression failed", e);
                }
 
-               // The variable has no expressions -> creating a new ordered set expressions and the active expression
-               if(expression == null && variable != null) {
-                       try {
-                               expression = Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
-
-                                       @Override
-                                       public Resource perform(WriteGraph graph)
-                                                       throws DatabaseException {
-                                               if(!graph.hasStatement(variable)) {
-                                                       /* Trying to create empty experiment for removed variable due to
-                                                        * async setInput
-                                                        */
-                                                       return null;
-                                               }
-
-                                               SysdynResource sr = SysdynResource.getInstance(graph);
-                                               Layer0 l0 = Layer0.getInstance(graph);
-                                               Resource expressions = ListUtils.create(graph, Collections.<Resource>emptyList());
-                                               graph.claim(variable, sr.Variable_expressionList, expressions);
-                                               final Resource expression = graph.newResource();
-
-                                               if(graph.isInstanceOf(variable, sr.Auxiliary) ||
-                                                               graph.isInstanceOf(variable, sr.Valve)) {
-                                                       graph.claim(expression, l0.InstanceOf, null, sr.NormalExpression);
-                                                       graph.claimLiteral(expression, sr.Expression_equation, "");
-                                               }
-                                               else if(graph.isInstanceOf(variable, sr.Stock)) {
-                                                       graph.claim(expression, l0.InstanceOf, null, sr.StockExpression);
-                                                       graph.claimLiteral(expression, sr.StockExpression_initialEquation, "");
-                                               }
-                                               ArrayList<Resource> addition = new ArrayList<Resource>(1);
-                                               addition.add(expression);
-                                               ListUtils.insertBack(graph, expressions, addition);
-
-                                               graph.claim(variable, l0.ConsistsOf, expression);
-
-                                               VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
-                                               final Session session = graph.getSession();
-                                               session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {
-                                                       @Override
-                                                       public void perform(WriteGraph graph) throws DatabaseException {
-                                                               VirtualGraph runtime = graph.getService(VirtualGraph.class);
-                                                               session.asyncRequest(new WriteRequest(runtime) {
-                                                                       @Override
-                                                                       public void perform(WriteGraph graph) throws DatabaseException {
-                                                                               SysdynResource sr = SysdynResource.getInstance(graph);
-                                                                               if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))
-                                                                                       graph.deny(variable, sr.IndependentVariable_activeExpression);
-                                                                               graph.claim(variable, sr.IndependentVariable_activeExpression, expression);
-                                                                       }
-                                                               }
-                                                                               );
-                                                       }
-                                               });
-                                               return expression;
-                                       }
-                               });
-                       } catch (DatabaseException e) {
-                               LOGGER.error("getActiveExpression failed", e);
-                       }
-
-                       if(expression == null)
-                               return;
-               }
-
-               // Now the variable should have an expression
                Simantics.getSession().asyncRequest(new Read<Pair<Boolean, Boolean>>() {
 
                        /**
@@ -398,7 +333,8 @@ public class EquationTab extends AdjustableTab implements Widget {
                        @Override
                        public void execute(AsyncReadGraph graph,
                                        final Pair<Boolean, Boolean> result) {
-                               newExpression.getWidget().getDisplay().asyncExec(new Runnable() {
+
+                               site.getShell().getDisplay().asyncExec(new Runnable() {
 
                                        @Override
                                        public void run() {
@@ -413,18 +349,78 @@ public class EquationTab extends AdjustableTab implements Widget {
 
                        @Override
                        public void exception(AsyncReadGraph graph, Throwable throwable) {
-                               LOGGER.error("Unexpected failure", throwable);
+                               LOGGER.error("Error while reading sysdyn variable", throwable);
                        }
 
                        @Override
                        public boolean isDisposed() {
-                               return newExpression.getWidget().isDisposed() || deleteExpression.getWidget().isDisposed();
+                               return !isListenerActive.get() || newExpression.getWidget().isDisposed() || deleteExpression.getWidget().isDisposed();
                        }
                });
 
-               // Set input to widgets using expressionSupport
-               StructuredSelection ss = new StructuredSelection(new ExpressionWidgetInput(var, expression));
-               expressionSupport.fireInput(context, ss);
+       }
+
+       private Resource ensureExpression(Resource variable) {
+               // The variable has no expressions -> creating a new ordered set expressions and the active expression
+               try {
+                       return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
+
+                               @Override
+                               public Resource perform(WriteGraph graph)
+                                               throws DatabaseException {
+                                       if(!graph.hasStatement(variable)) {
+                                               /* Trying to create empty experiment for removed variable due to 
+                                                * async setInput
+                                                */
+                                               return null; 
+                                       }
+
+                                       SysdynResource sr = SysdynResource.getInstance(graph);
+                                       Layer0 l0 = Layer0.getInstance(graph);
+                                       Resource expressions = ListUtils.create(graph, Collections.<Resource>emptyList());
+                                       graph.claim(variable, sr.Variable_expressionList, expressions);
+                                       final Resource expression = graph.newResource();
+
+                                       if(graph.isInstanceOf(variable, sr.Auxiliary) ||
+                                                       graph.isInstanceOf(variable, sr.Valve)) {
+                                               graph.claim(expression, l0.InstanceOf, null, sr.NormalExpression);
+                                               graph.claimLiteral(expression, sr.Expression_equation, "");
+                                       }
+                                       else if(graph.isInstanceOf(variable, sr.Stock)) {
+                                               graph.claim(expression, l0.InstanceOf, null, sr.StockExpression);
+                                               graph.claimLiteral(expression, sr.StockExpression_initialEquation, "");
+                                       }
+                                       ArrayList<Resource> addition = new ArrayList<Resource>(1);
+                                       addition.add(expression);
+                                       ListUtils.insertBack(graph, expressions, addition);
+
+                                       graph.claim(variable, l0.ConsistsOf, expression);
+
+                                       VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
+                                       final Session session = graph.getSession();
+                                       session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {
+                                               @Override
+                                               public void perform(WriteGraph graph) throws DatabaseException {
+                                                       VirtualGraph runtime = graph.getService(VirtualGraph.class);
+                                                       session.asyncRequest(new WriteRequest(runtime) {
+                                                               @Override
+                                                               public void perform(WriteGraph graph) throws DatabaseException {
+                                                                       SysdynResource sr = SysdynResource.getInstance(graph);
+                                                                       if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))
+                                                                               graph.deny(variable, sr.IndependentVariable_activeExpression);
+                                                                       graph.claim(variable, sr.IndependentVariable_activeExpression, expression);
+                                                               }
+                                                       }
+                                                                       );
+                                               }
+                                       });
+                                       return expression;
+                               }
+                       });
+               } catch (DatabaseException e) {
+                       e.printStackTrace();
+               }       
+               return null;
        }
 
        /**
@@ -749,137 +745,14 @@ public class EquationTab extends AdjustableTab implements Widget {
                }
        }
 
-       private void updateExpression(Resource expression, Resource variable, ISessionContext context, Variable var) {
+       private void updateExpression(Resource currentExpression, Resource variable, ISessionContext context, Variable var) {
                // The variable has no expressions -> creating a new ordered set expressions and the active expression
+               Resource expression = currentExpression;
                if(expression == null && variable != null) {
-                       try {
-                               expression = Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
-
-                                       @Override
-                                       public Resource perform(WriteGraph graph)
-                                                       throws DatabaseException {
-                                               if(!graph.hasStatement(variable)) {
-                                                       /* Trying to create empty experiment for removed variable due to
-                                                        * async setInput
-                                                        */
-                                                       return null;
-                                               }
-
-                                               SysdynResource sr = SysdynResource.getInstance(graph);
-                                               Layer0 l0 = Layer0.getInstance(graph);
-                                               Resource expressions = ListUtils.create(graph, Collections.<Resource>emptyList());
-                                               graph.claim(variable, sr.Variable_expressionList, expressions);
-                                               final Resource expression = graph.newResource();
-
-                                               if(graph.isInstanceOf(variable, sr.Auxiliary) ||
-                                                               graph.isInstanceOf(variable, sr.Valve)) {
-                                                       graph.claim(expression, l0.InstanceOf, null, sr.NormalExpression);
-                                                       graph.claimLiteral(expression, sr.Expression_equation, "");
-                                               }
-                                               else if(graph.isInstanceOf(variable, sr.Stock)) {
-                                                       graph.claim(expression, l0.InstanceOf, null, sr.StockExpression);
-                                                       graph.claimLiteral(expression, sr.StockExpression_initialEquation, "");
-                                               }
-                                               ArrayList<Resource> addition = new ArrayList<Resource>(1);
-                                               addition.add(expression);
-                                               ListUtils.insertBack(graph, expressions, addition);
-
-                                               graph.claim(variable, l0.ConsistsOf, expression);
-
-                                               VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
-                                               final Session session = graph.getSession();
-                                               session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {
-                                                       @Override
-                                                       public void perform(WriteGraph graph) throws DatabaseException {
-                                                               VirtualGraph runtime = graph.getService(VirtualGraph.class);
-                                                               session.asyncRequest(new WriteRequest(runtime) {
-                                                                       @Override
-                                                                       public void perform(WriteGraph graph) throws DatabaseException {
-                                                                               SysdynResource sr = SysdynResource.getInstance(graph);
-                                                                               if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))
-                                                                                       graph.deny(variable, sr.IndependentVariable_activeExpression);
-                                                                               graph.claim(variable, sr.IndependentVariable_activeExpression, expression);
-                                                                       }
-                                                               }
-                                                                               );
-                                                       }
-                                               });
-                                               return expression;
-                                       }
-                               });
-                       } catch (DatabaseException e) {
-                               LOGGER.error("Unexpected failure", e);
-                       }
-
-                       if(expression == null)
-                               return;
+                       expression = ensureExpression(variable);
                }
-
-               // Now the variable should have an expression
-               Simantics.getSession().asyncRequest(new Read<Pair<Boolean, Boolean>>() {
-
-                       /**
-                        * Find out if user can add a new expression or delete the current expression
-                        */
-                       @Override
-                       public Pair<Boolean, Boolean> perform(ReadGraph graph) throws DatabaseException {
-                               SysdynResource sr = SysdynResource.getInstance(graph);
-                               Resource expressions = graph.getPossibleObject(variable, sr.Variable_expressionList);
-                               if(expressions == null) {
-                                       return new Pair<Boolean, Boolean>(false, false);
-                               }
-                               List<Resource> expressionList = ListUtils.toList(graph, expressions);
-                               if(expressionList.isEmpty()) {
-                                       return new Pair<Boolean, Boolean>(false, false);
-                               }
-
-                               boolean canAdd = true;
-                               boolean canDelete = false;
-                               // If there are multiple expressions, one can be removed
-                               if(expressionList.size() > 1)
-                                       canDelete = true;
-                               String defaultRange = ArrayExpressionCombo.getDefaultRange(graph, variable);
-
-                               /* If the variable is an array variable, a range has been set to all expressions and none of
-                                * the ranges is the default range, an expression can be added
-                                */ 
-                               for(Resource expression : expressionList) {
-                                       String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange);
-                                       if(range == null || range.equals("") || range.equals(defaultRange)) {
-                                               canAdd = false;
-                                               break;
-                                       }
-                               }
-                               return new Pair<Boolean, Boolean>(canAdd, canDelete);
-                       }
-               }, new AsyncListener<Pair<Boolean, Boolean>>() {
-
-                       @Override
-                       public void execute(AsyncReadGraph graph,
-                                       final Pair<Boolean, Boolean> result) {
-                               newExpression.getWidget().getDisplay().asyncExec(new Runnable() {
-
-                                       @Override
-                                       public void run() {
-                                               if(!newExpression.getWidget().isDisposed())
-                                                       newExpression.getWidget().setEnabled(result.first);
-                                               if(!deleteExpression.getWidget().isDisposed())
-                                                       deleteExpression.getWidget().setEnabled(result.second);
-                                       }
-                               });
-
-                       }
-
-                       @Override
-                       public void exception(AsyncReadGraph graph, Throwable throwable) {
-                               LOGGER.error("Unexpected failure", throwable);
-                       }
-
-                       @Override
-                       public boolean isDisposed() {
-                               return newExpression.getWidget().isDisposed() || deleteExpression.getWidget().isDisposed();
-                       }
-               });
+               if(expression == null)
+                       return;
 
                // Set input to widgets using expressionSupport
                StructuredSelection ss = new StructuredSelection(new ExpressionWidgetInput(var, expression));
index 4b38a52ada7d3aba05f877aab8d1b7c95acbcdbf..81616660b6a997d56357e82facaf16e27b009927 100644 (file)
@@ -232,7 +232,8 @@ public class ExpressionWidget implements Widget {
      */
        public void validateFields() {
                if(this.variableTable == null) return;
-        
+               if(expr == null) return;
+
                try {
                    // Find the variable for this experession
                        Resource variable = Simantics.getSession().syncRequest(new Read<Resource>() {
index 14f87e966c5bbb535a650126c394ea38df230d1e..f64b138d5c824c89be6b0d3884d6c2cfd4b19462 100644 (file)
@@ -42,6 +42,7 @@ import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;\r
 import org.simantics.db.common.CommentMetadata;\r
 import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.ResourceRead;\r
 import org.simantics.db.common.request.WriteRequest;\r
 import org.simantics.db.common.utils.ListUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
@@ -54,155 +55,177 @@ import org.simantics.sysdyn.manager.SysdynModel;
 import org.simantics.sysdyn.manager.SysdynModelManager;\r
 import org.simantics.sysdyn.representation.Stock;\r
 import org.simantics.sysdyn.representation.Valve;\r
+import org.simantics.sysdyn.ui.properties.EquationTab;\r
 import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.Triple;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
 \r
 public class StockExpression implements IExpression {\r
 \r
-    private final ExpressionWidgetInput input;\r
-    private ExpressionField integralExpression, initialExpression;\r
-    private ExpressionField lastSelectedText;\r
-    private TextViewerUndoManager undoManager;\r
-    \r
-    public StockExpression(ExpressionWidgetInput input) {\r
-        this.input = input;\r
-    }\r
-    \r
-    @Override\r
-    public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\r
-        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent);\r
-        String initialEquation = data.get("initialEquation") != null ? (String)data.get("initialEquation") : "";\r
-        String integralEquation = data.get("integral") != null ? (String)data.get("integral") : getDefaultIntegral(input.expression);\r
-\r
-\r
-        Label label = new Label(parent, SWT.NONE);\r
-        label.setText("Integral");\r
-\r
-        Composite integralComposite = new Composite(parent, SWT.NONE);\r
-        GridDataFactory.fillDefaults().grab(true, true).applyTo(integralComposite);\r
-        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(integralComposite);\r
-        \r
-        integralExpression = new ExpressionField(integralComposite, SWT.BORDER, allowedVariables, true, input);\r
-        integralExpression.setExpression(integralEquation);\r
-        GridDataFactory.fillDefaults().grab(true, true).applyTo(integralExpression);\r
-        integralExpression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
-\r
-            @Override\r
-            public void focusLost(FocusEvent e) {\r
-                lastSelectedText = integralExpression;\r
-            }\r
-        });\r
-        \r
-        undoManager = new TextViewerUndoManager(100);\r
-        integralExpression.getSourceViewer().setUndoManager(undoManager);\r
-        undoManager.connect(integralExpression.getSourceViewer());\r
-        \r
-        Button defaultButton = new Button(integralComposite, SWT.PUSH);\r
-        defaultButton.setText("Use default");\r
-        defaultButton.addListener(SWT.Selection, new Listener() {\r
-\r
-               @Override\r
-               public void handleEvent(Event event) {\r
-                       switch (event.type) {\r
-                       case SWT.Selection:\r
-                               StockExpression.this.integralExpression.setExpression(getDefaultIntegral(input.expression));\r
-                               Simantics.getSession().asyncRequest(new WriteRequest() {\r
-\r
-                                       @Override\r
-                                       public void perform(WriteGraph graph)\r
-                                                       throws DatabaseException {\r
-                                               // Delete the possible integral expression from the database to note \r
-                                               // that we are in the "default" mode.\r
-                                               graph.markUndoPoint();\r
-                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
-                                               graph.deny(input.expression, sr.StockExpression_useCustomIntegral);\r
-                                               graph.claimLiteral(input.expression, sr.StockExpression_integralEquation, getDefaultIntegral(graph, input.expression));\r
-                                               \r
-                                       CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-                                       graph.addMetadata(cm.add("Use default"));\r
-                                               \r
-                                       }\r
-                               });\r
-                               break;\r
-                       }\r
-               }\r
-\r
-        });\r
-\r
-        label = new Label(parent, SWT.NONE);\r
-        label.setText("Initial\nValue");\r
-\r
-        initialExpression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
-        initialExpression.setExpression(initialEquation);\r
-        GridDataFactory.fillDefaults().grab(true, true).applyTo(initialExpression);\r
-        initialExpression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
-\r
-            @Override\r
-            public void focusLost(FocusEvent e) {\r
-                lastSelectedText = initialExpression;\r
-            }\r
-        });\r
-\r
-        lastSelectedText = initialExpression;\r
-    }\r
-\r
-    @Override\r
-    public void focus() {\r
-        this.lastSelectedText.focus();\r
-    }\r
-\r
-    @Override\r
-    public List<ExpressionField> getExpressionFields() {\r
-        return Arrays.asList(this.integralExpression, this.initialExpression);\r
-    }\r
-\r
-    @Override\r
-    public void readData(final Resource expression, final Map<String, Object> data) {\r
-        Pair<String, String> equations = null;\r
-        if (expression != null && data.get("initialEquation") == null) {\r
-               try {\r
-                   equations = Simantics.getSession().syncRequest(new Read<Pair<String, String>>() {\r
-       \r
-                       @Override\r
-                       public Pair<String, String> perform(ReadGraph graph) throws DatabaseException {\r
-                           SysdynResource sr = SysdynResource.getInstance(graph);\r
-                           if (graph.isInstanceOf(expression, sr.StockExpression)) {\r
-                               String initialEquation = graph.getPossibleRelatedValue(expression, sr.StockExpression_initialEquation);\r
-                               String integralEquation = graph.getPossibleRelatedValue(expression, sr.StockExpression_integralEquation);\r
-                               initialEquation = (initialEquation != null) ? initialEquation : "";\r
-                               return new Pair<String, String>(integralEquation, initialEquation);\r
-                           } else {\r
-                               return new Pair<String, String>(null, "");\r
-                           }\r
-                       }\r
-       \r
-                   });\r
-               } catch (DatabaseException e1) {\r
-                   e1.printStackTrace();\r
-               }\r
-               data.put("initialEquation", equations.second);\r
-        }\r
-\r
-        if (equations.first == null) {\r
-               try {\r
+       private static final Logger LOGGER = LoggerFactory.getLogger(StockExpression.class);\r
+       private final ExpressionWidgetInput input;\r
+       private ExpressionField integralExpression, initialExpression;\r
+       private ExpressionField lastSelectedText;\r
+       private TextViewerUndoManager undoManager;\r
+\r
+       public StockExpression(ExpressionWidgetInput input) {\r
+               this.input = input;\r
+       }\r
+\r
+       @Override\r
+       public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\r
+               GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent);\r
+               String initialEquation = data.get("initialEquation") != null ? (String)data.get("initialEquation") : "";\r
+               String integralEquation = data.get("integral") != null ? (String)data.get("integral") : getDefaultIntegral(input.expression);\r
+\r
+\r
+               Label label = new Label(parent, SWT.NONE);\r
+               label.setText("Integral");\r
+\r
+               Composite integralComposite = new Composite(parent, SWT.NONE);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(integralComposite);\r
+               GridLayoutFactory.fillDefaults().numColumns(2).applyTo(integralComposite);\r
+\r
+               integralExpression = new ExpressionField(integralComposite, SWT.BORDER, allowedVariables, true, input);\r
+               integralExpression.setExpression(integralEquation);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(integralExpression);\r
+               integralExpression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+                       @Override\r
+                       public void focusLost(FocusEvent e) {\r
+                               lastSelectedText = integralExpression;\r
+                       }\r
+               });\r
+\r
+               undoManager = new TextViewerUndoManager(100);\r
+               integralExpression.getSourceViewer().setUndoManager(undoManager);\r
+               undoManager.connect(integralExpression.getSourceViewer());\r
+\r
+               Button defaultButton = new Button(integralComposite, SWT.PUSH);\r
+               defaultButton.setText("Use default");\r
+               defaultButton.addListener(SWT.Selection, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(Event event) {\r
+                               switch (event.type) {\r
+                               case SWT.Selection:\r
+                                       StockExpression.this.integralExpression.setExpression(getDefaultIntegral(input.expression));\r
+                                       Simantics.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                                               @Override\r
+                                               public void perform(WriteGraph graph)\r
+                                                               throws DatabaseException {\r
+                                                       // Delete the possible integral expression from the database to note \r
+                                                       // that we are in the "default" mode.\r
+                                                       graph.markUndoPoint();\r
+                                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                                       graph.deny(input.expression, sr.StockExpression_useCustomIntegral);\r
+                                                       graph.claimLiteral(input.expression, sr.StockExpression_integralEquation, getDefaultIntegral(graph, input.expression));\r
+\r
+                                                       CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
+                                                       graph.addMetadata(cm.add("Use default"));\r
+\r
+                                               }\r
+                                       });\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+               });\r
+\r
+               label = new Label(parent, SWT.NONE);\r
+               label.setText("Initial\nValue");\r
+\r
+               initialExpression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
+               initialExpression.setExpression(initialEquation);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(initialExpression);\r
+               initialExpression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+                       @Override\r
+                       public void focusLost(FocusEvent e) {\r
+                               lastSelectedText = initialExpression;\r
+                       }\r
+               });\r
+\r
+               lastSelectedText = initialExpression;\r
+       }\r
+\r
+       @Override\r
+       public void focus() {\r
+               this.lastSelectedText.focus();\r
+       }\r
+\r
+       @Override\r
+       public List<ExpressionField> getExpressionFields() {\r
+               return Arrays.asList(this.integralExpression, this.initialExpression);\r
+       }\r
+\r
+       @Override\r
+       public void readData(final Resource expression, final Map<String, Object> data) {\r
+               if(expression == null) {\r
+                       LOGGER.warn("StockExpression is null");\r
+                       return;\r
+               }\r
+               if(!expression.equals(data.get("expression"))) {\r
+                       data.clear();\r
+               }\r
+\r
+               Object getInitialEquation = data.get("initialEquation");\r
+               Object integralEquation = data.get("integral");\r
+               Boolean useCustomIntegral = (Boolean) data.get("useCustomIntegral");\r
+               if (getInitialEquation == null || integralEquation == null || useCustomIntegral == null) {\r
+                       try {\r
+                               Triple<String, String, Boolean> equations = Simantics.getSession().syncRequest(new ResourceRead<Triple<String, String, Boolean>>(expression) {\r
+\r
+                                       @Override\r
+                                       public Triple<String, String, Boolean> perform(ReadGraph graph) throws DatabaseException {\r
+                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                               boolean useCustomIntegral = graph.hasStatement(resource, sr.StockExpression_useCustomIntegral);\r
+                                               if (graph.isInstanceOf(expression, sr.StockExpression)) {\r
+                                                       String initialEquation = graph.getPossibleRelatedValue(expression, sr.StockExpression_initialEquation);\r
+                                                       String integralEquation = graph.getPossibleRelatedValue(expression, sr.StockExpression_integralEquation);\r
+                                                       initialEquation = (initialEquation != null) ? initialEquation : "";\r
+                                                       return new Triple<String, String, Boolean>(integralEquation, initialEquation, useCustomIntegral);\r
+                                               } else {\r
+                                                       return new Triple<String, String, Boolean>(null, "", useCustomIntegral);\r
+                                               }\r
+                                       }\r
+                               });\r
+                               data.put("integral", equations.first);\r
+                               data.put("initialEquation", equations.second);\r
+                               data.put("useCustomIntegral", equations.third);\r
+                               integralEquation = equations.first;\r
+                               getInitialEquation = equations.second;\r
+                               useCustomIntegral = equations.third;\r
+                       } catch (DatabaseException e1) {\r
+                               e1.printStackTrace();\r
+                       }\r
+               }\r
+               if (integralEquation == null) {\r
+                       try {\r
                                Simantics.getSession().syncRequest(new WriteRequest() {\r
 \r
                                        @Override\r
                                        public void perform(WriteGraph graph) throws DatabaseException {\r
                                                SysdynResource sr = SysdynResource.getInstance(graph);\r
-                                       graph.claimLiteral(input.expression, sr.StockExpression_integralEquation, getDefaultIntegral(graph, input.expression));\r
-                                       graph.markUndoPoint();\r
-                               CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-                               graph.addMetadata(cm.add("Set expression"));\r
+                                               graph.claimLiteral(input.expression, sr.StockExpression_integralEquation, getDefaultIntegral(graph, input.expression));\r
+                                               graph.markUndoPoint();\r
+                                               CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
+                                               graph.addMetadata(cm.add("Set expression"));\r
                                        }\r
-\r
                                });\r
                        } catch (DatabaseException e) {\r
                                // TODO Auto-generated catch block\r
                                e.printStackTrace();\r
                        }\r
-               \r
-               data.put("integral", getDefaultIntegral(expression));\r
-        } else {\r
+\r
+                       data.put("integral", getDefaultIntegral(expression));\r
+               } else if(!useCustomIntegral) {\r
+                       data.put("integral", getDefaultIntegral(expression));\r
+               }\r
+               /*\r
+\r
                try {\r
                        final String integral = equations.first;\r
                                Simantics.getSession().syncRequest(new ReadRequest() {\r
@@ -222,172 +245,172 @@ public class StockExpression implements IExpression {
                                data.put("integral", equations.first);\r
                                e.printStackTrace();\r
                        }\r
-        }\r
-\r
-    }\r
-\r
-    @Override\r
-    public void replaceSelection(String var) {\r
-        if(lastSelectedText != null) {\r
-            IDocument doc = lastSelectedText.getDocument();\r
-            try {\r
-                Point selection = lastSelectedText.getSelection();\r
-                doc.replace(selection.x, selection.y, var);\r
-                lastSelectedText.setSelection(selection.x + var.length());\r
-            } catch (BadLocationException e) {\r
-                e.printStackTrace();\r
-            }\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void save(final Resource expression, final Map<String, Object> data) {\r
-       final String currentInitial = this.initialExpression.getExpression();\r
-       final String currentIntegral = this.integralExpression.getExpression();\r
-       if (currentIntegral == null) {\r
-               this.integralExpression.setExpression(getDefaultIntegral(expression));\r
-        }\r
-        if(!currentInitial.equals(data.get("initialEquation"))\r
-                       || currentIntegral == null\r
-                       || !currentIntegral.equals(data.get("integral"))) {\r
-            Simantics.getSession().asyncRequest(new WriteRequest() {\r
-\r
-                @Override\r
-                public void perform(WriteGraph g)\r
-                throws DatabaseException {\r
-                    SysdynResource sr = SysdynResource.getInstance(g);\r
-                    Layer0 l0 = Layer0.getInstance(g);\r
-                    \r
-                    if(!g.isInstanceOf(expression, sr.StockExpression)) {\r
-                        Resource variable = g.getPossibleObject(expression, l0.PartOf);\r
-                        Resource expressionList = g.getPossibleObject(variable, sr.Variable_expressionList);\r
-                       Resource temp = g.newResource();\r
-                       ListUtils.replace(g, expressionList, expression, temp);\r
-                       \r
-                       for(Resource predicate : g.getPredicates(expression)) {\r
-                           g.deny(expression, predicate);\r
-                       }\r
-                       g.claim(expression, l0.InstanceOf, null, sr.StockExpression);\r
-\r
-                        ListUtils.replace(g, expressionList, temp, expression);\r
-\r
-                       RemoverUtil.remove(g, temp);\r
-\r
-                       g.claim(expression, l0.PartOf, variable);\r
-                    }\r
-                    g.claimLiteral(expression, sr.StockExpression_initialEquation, currentInitial);\r
-                    \r
-                    if (!currentIntegral.equals(g.getPossibleRelatedValue(expression, sr.StockExpression_integralEquation, Bindings.STRING))) {\r
-                       // If the value is not same as default, enable the custom tag\r
-                       g.claim(expression, sr.StockExpression_useCustomIntegral, expression);\r
-                    }\r
-                    g.claimLiteral(expression, sr.StockExpression_integralEquation, currentIntegral);\r
-                    \r
-                    updateData(data);\r
-                    \r
-                    g.markUndoPoint();\r
-                    \r
-                    Layer0Utils.addCommentMetadata(g, "Saved Stock Expression " + currentIntegral + " " + expression.toString() + " with Initial Value " + currentInitial);\r
-                }\r
-\r
-            });\r
-        }\r
-        this.initialExpression.setExpression(currentInitial);\r
-        this.integralExpression.setExpression(currentIntegral);\r
-    }\r
-\r
-    @Override\r
-    public void updateData(Map<String, Object> data) {\r
-       if(this.initialExpression != null && this.initialExpression.getExpression() != null)\r
-            data.put("initialEquation", this.initialExpression.getExpression());\r
-       if(this.integralExpression != null && this.integralExpression.getExpression() != null)\r
-            data.put("integral", this.integralExpression.getExpression());\r
-    }\r
-\r
-    \r
-    private static String getDefaultIntegral(ReadGraph graph, Resource expression) throws DatabaseException {\r
-        SysdynResource sr = SysdynResource.getInstance(graph);\r
-        Layer0 l0 = Layer0.getInstance(graph);\r
-    \r
-           // find the variable\r
-           Resource variable = graph.getPossibleObject(expression, l0.PartOf);\r
-           if(variable == null)\r
-               return "";\r
-           \r
+                */\r
+               data.put("expression", expression);\r
+       }\r
+\r
+       @Override\r
+       public void replaceSelection(String var) {\r
+               if(lastSelectedText != null) {\r
+                       IDocument doc = lastSelectedText.getDocument();\r
+                       try {\r
+                               Point selection = lastSelectedText.getSelection();\r
+                               doc.replace(selection.x, selection.y, var);\r
+                               lastSelectedText.setSelection(selection.x + var.length());\r
+                       } catch (BadLocationException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void save(final Resource expression, final Map<String, Object> data) {\r
+               final String currentInitial = this.initialExpression.getExpression();\r
+               final String currentIntegral = this.integralExpression.getExpression();\r
+               if (currentIntegral == null) {\r
+                       this.integralExpression.setExpression(getDefaultIntegral(expression));\r
+               }\r
+               if(!currentInitial.equals(data.get("initialEquation"))\r
+                               || currentIntegral == null\r
+                               || !currentIntegral.equals(data.get("integral"))) {\r
+                       Simantics.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                               @Override\r
+                               public void perform(WriteGraph g)\r
+                                               throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(g);\r
+                                       Layer0 l0 = Layer0.getInstance(g);\r
+\r
+                                       if(!g.isInstanceOf(expression, sr.StockExpression)) {\r
+                                               Resource variable = g.getPossibleObject(expression, l0.PartOf);\r
+                                               Resource expressionList = g.getPossibleObject(variable, sr.Variable_expressionList);\r
+                                               Resource temp = g.newResource();\r
+                                               ListUtils.replace(g, expressionList, expression, temp);\r
+\r
+                                               for(Resource predicate : g.getPredicates(expression)) {\r
+                                                       g.deny(expression, predicate);\r
+                                               }\r
+                                               g.claim(expression, l0.InstanceOf, null, sr.StockExpression);\r
+\r
+                                               ListUtils.replace(g, expressionList, temp, expression);\r
+\r
+                                               RemoverUtil.remove(g, temp);\r
+\r
+                                               g.claim(expression, l0.PartOf, variable);\r
+                                       }\r
+                                       g.claimLiteral(expression, sr.StockExpression_initialEquation, currentInitial);\r
+\r
+                                       if (!currentIntegral.equals(g.getPossibleRelatedValue(expression, sr.StockExpression_integralEquation, Bindings.STRING))) {\r
+                                               // If the value is not same as default, enable the custom tag\r
+                                               g.claim(expression, sr.StockExpression_useCustomIntegral, expression);\r
+                                       }\r
+                                       g.claimLiteral(expression, sr.StockExpression_integralEquation, currentIntegral);\r
+\r
+                                       updateData(data);\r
+\r
+                                       g.markUndoPoint();\r
+\r
+                                       Layer0Utils.addCommentMetadata(g, "Saved Stock Expression " + currentIntegral + " " + expression.toString() + " with Initial Value " + currentInitial);\r
+                               }\r
+\r
+                       });\r
+               }\r
+               this.initialExpression.setExpression(currentInitial);\r
+               this.integralExpression.setExpression(currentIntegral);\r
+       }\r
+\r
+       @Override\r
+       public void updateData(Map<String, Object> data) {\r
+               if(this.initialExpression != null && this.initialExpression.getExpression() != null)\r
+                       data.put("initialEquation", this.initialExpression.getExpression());\r
+               if(this.integralExpression != null && this.integralExpression.getExpression() != null)\r
+                       data.put("integral", this.integralExpression.getExpression());\r
+       }\r
+\r
+\r
+       private static String getDefaultIntegral(ReadGraph graph, Resource expression) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+               // find the variable\r
+               Resource variable = graph.getPossibleObject(expression, l0.PartOf);\r
+               if(variable == null)\r
+                       return "";\r
+\r
                SysdynModelManager sdm = SysdynModelManager.getInstance(graph.getSession());\r
                SysdynModel model = sdm.getModel(graph, graph.getSingleObject(variable, l0.PartOf));\r
                model.update(graph);\r
-               \r
+\r
                Stock stock = (Stock)model.getElement(variable);\r
-           \r
+\r
                String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange);\r
                if(range == null)\r
                        range = "";\r
-       \r
-           StringBuilder builder = new StringBuilder();\r
-           builder.append("");\r
-           for(Valve in : stock.getIncomingValves()) {\r
-               builder.append(" + " + in.getName() + range);\r
-           }\r
-           for(Valve out : stock.getOutgoingValves()) {\r
-               builder.append(" - " + out.getName() + range);\r
-           }\r
-           if (builder.indexOf(" + ") == 0)\r
-               builder.delete(0, 3);\r
-           \r
-           return builder.toString().trim();   \r
-    }\r
-    \r
-    \r
-    private static String getDefaultIntegral(final Resource expression) {\r
-       \r
-        String integral = "";\r
-        if(expression == null)\r
-               return integral;\r
-        try {\r
-            integral = Simantics.getSession().syncRequest(new Read<String>() {\r
-\r
-                @Override\r
-                public String perform(ReadGraph graph) throws DatabaseException {\r
-                       return getDefaultIntegral(graph, expression);\r
-                }\r
-\r
-            });\r
-        } catch (DatabaseException e) {\r
-            e.printStackTrace();\r
-        }\r
-        return integral;\r
-    }\r
-\r
-    @Override\r
-    public void addKeyListener(KeyListener listener) {\r
-        this.initialExpression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
-        this.integralExpression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
-\r
-    }\r
-\r
-    @Override\r
-    public void addModifyListener(ModifyListener listener) {\r
-        this.initialExpression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
-        this.integralExpression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
-\r
-    }\r
-\r
-    @Override\r
-    public void addFocusListener(FocusListener listener) {\r
-        this.initialExpression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
-        this.integralExpression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
-    }\r
-    \r
+\r
+               StringBuilder builder = new StringBuilder();\r
+               builder.append("");\r
+               for(Valve in : stock.getIncomingValves()) {\r
+                       builder.append(" + " + in.getName() + range);\r
+               }\r
+               for(Valve out : stock.getOutgoingValves()) {\r
+                       builder.append(" - " + out.getName() + range);\r
+               }\r
+               if (builder.indexOf(" + ") == 0)\r
+                       builder.delete(0, 3);\r
+\r
+               return builder.toString().trim();       \r
+       }\r
+\r
+\r
+       private static String getDefaultIntegral(final Resource expression) {\r
+\r
+               String integral = "";\r
+               if(expression == null)\r
+                       return integral;\r
+               try {\r
+                       integral = Simantics.getSession().syncRequest(new Read<String>() {\r
+\r
+                               @Override\r
+                               public String perform(ReadGraph graph) throws DatabaseException {\r
+                                       return getDefaultIntegral(graph, expression);\r
+                               }\r
+\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return integral;\r
+       }\r
+\r
+       @Override\r
+       public void addKeyListener(KeyListener listener) {\r
+               this.initialExpression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+               this.integralExpression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+\r
+       }\r
+\r
+       @Override\r
+       public void addModifyListener(ModifyListener listener) {\r
+               this.initialExpression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+               this.integralExpression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+\r
+       }\r
+\r
+       @Override\r
+       public void addFocusListener(FocusListener listener) {\r
+               this.initialExpression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+               this.integralExpression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+       }\r
+\r
        @Override\r
        public void addVerifyKeyListener(VerifyKeyListener listener) {\r
                this.initialExpression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
                this.integralExpression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
        }\r
 \r
-    @Override\r
-    public IUndoManager getUndoManager() {\r
-        return undoManager;\r
-    }\r
+       @Override\r
+       public IUndoManager getUndoManager() {\r
+               return undoManager;\r
+       }\r
 \r
 }\r