-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());
+ new Exception().printStackTrace();
+ realm.getEngine().registerListener(new SpreadsheetBookListener() {
+
+ @Override
+ public void cellsChanged(Collection<SpreadsheetCell> cells) {
+ realm.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ for(SpreadsheetCell cell : cells) {
+ System.err.println("Modification in cell " + cell.getName());
+ 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;
+ }
+
+}