1 package org.simantics.spreadsheet.graph;
3 import java.util.Collection;
4 import java.util.Collections;
5 import java.util.HashSet;
9 import org.simantics.databoard.binding.Binding;
10 import org.simantics.databoard.binding.mutable.Variant;
11 import org.simantics.layer0.Layer0;
12 import org.simantics.simulator.toolkit.db.StandardVariableNodeManager;
13 import org.simantics.simulator.variable.exceptions.NodeManagerException;
14 import org.simantics.spreadsheet.SpreadsheetCellStyle;
15 import org.simantics.spreadsheet.resource.SpreadsheetResource;
16 import org.simantics.spreadsheet.solver.SheetNode;
17 import org.simantics.spreadsheet.solver.SpreadsheetBook;
18 import org.simantics.spreadsheet.solver.SpreadsheetBook.SpreadsheetBookListener;
19 import org.simantics.spreadsheet.solver.SpreadsheetCell;
20 import org.simantics.spreadsheet.solver.SpreadsheetCellContent;
21 import org.simantics.spreadsheet.solver.SpreadsheetCellContentExpression;
22 import org.simantics.spreadsheet.solver.SpreadsheetCellEditable;
23 import org.simantics.spreadsheet.solver.SpreadsheetFormula;
24 import org.simantics.spreadsheet.solver.SpreadsheetSCLConstant;
25 import org.simantics.spreadsheet.solver.SpreadsheetTypeNode;
26 import org.simantics.structural.stubs.StructuralResource2;
28 @SuppressWarnings("rawtypes")
29 public class SpreadsheetNodeManager extends StandardVariableNodeManager<SheetNode, SpreadsheetBook> {
31 public SpreadsheetNodeManager(SpreadsheetRealm realm) {
32 super(realm, realm.getEngine());
33 realm.getEngine().registerListener(new SpreadsheetBookListener() {
36 public void cellsChanged(Collection<SpreadsheetCell> cells) {
37 realm.asyncExec(new Runnable() {
40 for(SpreadsheetCell cell : cells) {
41 refreshVariable(new SpreadsheetCellContent(cell));
42 Object content = cell.getContent();
43 if(content instanceof SpreadsheetFormula || content instanceof SpreadsheetSCLConstant)
44 refreshVariable(new SpreadsheetCellContentExpression(cell));
52 static final Set<String> COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component);
55 public Set<String> getClassifications(SheetNode node) throws NodeManagerException {
58 return COMPONENT_CLASS;
60 return Collections.emptySet();
64 public String getPropertyURI(SheetNode parent, SheetNode property) {
65 if(property instanceof SpreadsheetCellContent) {
66 return SpreadsheetResource.URIs.Cell_content;
67 } else if(property instanceof SpreadsheetTypeNode) {
68 return Layer0.URIs.typeURI;
69 } else if(property instanceof SpreadsheetCellContentExpression) {
70 return Layer0.URIs.SCLValue_expression;
71 } else if (property instanceof SpreadsheetCellStyle) {
72 return SpreadsheetResource.URIs.Cell_style;
73 } else if (property instanceof SpreadsheetCellEditable){
74 return SpreadsheetResource.URIs.Cell_editable;
80 //Custom setValue logic for SpreadsheetNodeManager - calls the setValueAndFireSelectedListeners
82 public void setValue(SheetNode node, Object value, Binding binding) throws NodeManagerException {
83 Set<SheetNode> dirtyNodeContents = findDirtyNodeContents(node);
84 super.setValueAndFireSelectedListeners(node, value, binding, dirtyNodeContents);
85 if(value instanceof SpreadsheetFormula) {
86 SpreadsheetCellContent scc = (SpreadsheetCellContent)node;
87 SpreadsheetCellContentExpression scce = new SpreadsheetCellContentExpression(scc.cell);
88 // We need to also refresh the expression variable in this case
89 refreshVariable(scce);
93 //Find the cells that are used by this cell and their SpreadsheetContents, so that they can be marked as dirty later
94 public Set<SheetNode> findDirtyNodeContents(SheetNode node){
95 Set<SheetNode> dirty = new HashSet<>();
97 SpreadsheetCell sscell = null;
98 if(node instanceof SpreadsheetCell) {
99 sscell = (SpreadsheetCell)node;
100 } else if (node instanceof SpreadsheetCellContent) {
101 sscell = ((SpreadsheetCellContent)node).cell;
105 Set<SpreadsheetCell> result = ((SpreadsheetRealm)super.getRealm()).getEngine().invalidate(sscell);
106 dirty.addAll(result);
109 Set<SheetNode> dirtyNodeContents = new HashSet<>();
110 for(SheetNode cell : dirty) {
111 Map<String, SheetNode> properties = cell.getProperties();
112 dirtyNodeContents.add((SpreadsheetCellContent)properties.get("content"));
115 return dirtyNodeContents;
120 protected Variant getEngineVariantOrCached(SheetNode node) throws NodeManagerException {
121 Variant variant = valueCache.get(node);
122 if(variant == null) {
123 Object value = realm.getEngine().getEngineValue(node);
124 Binding binding = realm.getEngine().getEngineBinding(node);
125 variant = new Variant(binding, value);
126 valueCache.put(node, variant);