]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetNodeManager.java
Adopt spreadsheet changes made in Balas development
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / SpreadsheetNodeManager.java
index 416cc19269a7ceff31146ce943dc3ac5628af3b1..64d002f831d81c7198406b877ef21b7cb46cd3e9 100644 (file)
-package org.simantics.spreadsheet.graph;\r
-\r
-import java.util.Collections;\r
-import java.util.Set;\r
-\r
-import org.simantics.db.layer0.StandardNodeManager;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.simulator.variable.exceptions.NodeManagerException;\r
-import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-\r
-@SuppressWarnings("rawtypes")\r
-public class SpreadsheetNodeManager extends StandardNodeManager<SheetNode, SpreadsheetBook> {\r
-       \r
-    public SpreadsheetNodeManager(SpreadsheetRealm realm) {\r
-        super(realm, realm.getEngine());\r
-    }\r
-\r
-    static final Set<String> COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component);\r
-            \r
-    @Override\r
-    public Set<String> getClassifications(SheetNode node) throws NodeManagerException {\r
-        checkThreadAccess();\r
-        if(isRoot(node))\r
-            return COMPONENT_CLASS;\r
-        else\r
-            return Collections.emptySet();\r
-    }\r
-    \r
-    @Override\r
-    public String getPropertyURI(SheetNode parent, SheetNode property) {\r
-       if(property instanceof SpreadsheetCellContent) {\r
-            return SpreadsheetResource.URIs.Cell_content;\r
-       } else if(property instanceof SpreadsheetTypeNode) {\r
-            return Layer0.URIs.typeURI;\r
-       } else if(property instanceof SpreadsheetCellContentExpression) {\r
-            return Layer0.URIs.SCLValue_expression;\r
-       } else if (property instanceof SpreadsheetCellStyle) {\r
-           return SpreadsheetResource.URIs.Cell_style;\r
-       } else if (property instanceof SpreadsheetCellEditable){\r
-           return SpreadsheetResource.URIs.Cell_editable;\r
-       } else {\r
-               return null;\r
-       }\r
-    }\r
-    \r
-}\r
+package org.simantics.spreadsheet.graph;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.layer0.Layer0;
+import org.simantics.simulator.toolkit.db.StandardVariableNodeManager;
+import org.simantics.simulator.variable.exceptions.NodeManagerException;
+import org.simantics.spreadsheet.SpreadsheetCellStyle;
+import org.simantics.spreadsheet.resource.SpreadsheetResource;
+import org.simantics.spreadsheet.solver.SheetNode;
+import org.simantics.spreadsheet.solver.SpreadsheetBook;
+import org.simantics.spreadsheet.solver.SpreadsheetBook.SpreadsheetBookListener;
+import org.simantics.spreadsheet.solver.SpreadsheetCell;
+import org.simantics.spreadsheet.solver.SpreadsheetCellContent;
+import org.simantics.spreadsheet.solver.SpreadsheetCellContentExpression;
+import org.simantics.spreadsheet.solver.SpreadsheetCellEditable;
+import org.simantics.spreadsheet.solver.SpreadsheetFormula;
+import org.simantics.spreadsheet.solver.SpreadsheetSCLConstant;
+import org.simantics.spreadsheet.solver.SpreadsheetTypeNode;
+import org.simantics.structural.stubs.StructuralResource2;
+
+@SuppressWarnings("rawtypes")
+public class SpreadsheetNodeManager extends StandardVariableNodeManager<SheetNode, SpreadsheetBook> {
+
+    public SpreadsheetNodeManager(SpreadsheetRealm realm) {
+        super(realm, realm.getEngine());
+        realm.getEngine().registerListener(new SpreadsheetBookListener() {
+            
+            @Override
+            public void cellsChanged(Collection<SpreadsheetCell> cells) {
+                realm.asyncExec(new Runnable() {
+                    @Override
+                    public void run() {
+                        for(SpreadsheetCell cell : cells) {
+                            refreshVariable(new SpreadsheetCellContent(cell));
+                            Object content = cell.getContent();
+                            if(content instanceof SpreadsheetFormula || content instanceof SpreadsheetSCLConstant)
+                                refreshVariable(new SpreadsheetCellContentExpression(cell));
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    static final Set<String> COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component);
+
+    @Override
+    public Set<String> getClassifications(SheetNode node) throws NodeManagerException {
+        checkThreadAccess();
+        if(isRoot(node))
+            return COMPONENT_CLASS;
+        else
+            return Collections.emptySet();
+    }
+
+    @Override
+    public String getPropertyURI(SheetNode parent, SheetNode property) {
+        if(property instanceof SpreadsheetCellContent) {
+            return SpreadsheetResource.URIs.Cell_content;
+        } else if(property instanceof SpreadsheetTypeNode) {
+            return Layer0.URIs.typeURI;
+        } else if(property instanceof SpreadsheetCellContentExpression) {
+            return Layer0.URIs.SCLValue_expression;
+        } else if (property instanceof SpreadsheetCellStyle) {
+            return SpreadsheetResource.URIs.Cell_style;
+        } else if (property instanceof SpreadsheetCellEditable){
+            return SpreadsheetResource.URIs.Cell_editable;
+        } else {
+            return null;
+        }
+    }
+    
+    //Custom setValue logic for SpreadsheetNodeManager - calls the setValueAndFireSelectedListeners
+    @Override
+    public void setValue(SheetNode node, Object value, Binding binding) throws NodeManagerException {
+       Set<SheetNode> dirtyNodeContents = findDirtyNodeContents(node);
+       super.setValueAndFireSelectedListeners(node, value, binding, dirtyNodeContents);
+       if(value instanceof SpreadsheetFormula) {
+           SpreadsheetCellContent scc = (SpreadsheetCellContent)node;
+           SpreadsheetCellContentExpression scce = new SpreadsheetCellContentExpression(scc.cell);
+           // We need to also refresh the expression variable in this case
+           refreshVariable(scce);
+       }
+    }
+    
+    //Find the cells that are used by this cell and their SpreadsheetContents, so that they can be marked as dirty later
+    public Set<SheetNode> findDirtyNodeContents(SheetNode node){
+       Set<SheetNode> dirty = new HashSet<>();
+       
+       SpreadsheetCell sscell = null;
+       if(node instanceof SpreadsheetCell) {
+               sscell = (SpreadsheetCell)node;
+       } else if (node instanceof SpreadsheetCellContent) {
+               sscell = ((SpreadsheetCellContent)node).cell;
+       }
+                       
+       if(sscell != null) {
+               Set<SpreadsheetCell> result = ((SpreadsheetRealm)super.getRealm()).getEngine().invalidate(sscell);
+               dirty.addAll(result);
+       }
+                       
+       Set<SheetNode> dirtyNodeContents = new HashSet<>();
+       for(SheetNode cell : dirty) {
+               Map<String, SheetNode> properties = cell.getProperties();
+               dirtyNodeContents.add((SpreadsheetCellContent)properties.get("content"));
+       }
+       
+       return dirtyNodeContents;
+    }
+    
+    
+    @Override
+    protected Variant getEngineVariantOrCached(SheetNode node) throws NodeManagerException {
+        Variant variant = valueCache.get(node);
+        if(variant == null) {
+            Object value = realm.getEngine().getEngineValue(node);
+            Binding binding = realm.getEngine().getEngineBinding(node);
+            variant = new Variant(binding, value);
+            valueCache.put(node, variant);
+        }
+        return variant;
+    }
+    
+}