]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetNodeManager.java
Spreadsheet changes
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / SpreadsheetNodeManager.java
1 package org.simantics.spreadsheet.graph;
2
3 import java.util.Collection;
4 import java.util.Collections;
5 import java.util.HashSet;
6 import java.util.Map;
7 import java.util.Set;
8
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.SpreadsheetTypeNode;
25 import org.simantics.structural.stubs.StructuralResource2;
26
27 @SuppressWarnings("rawtypes")
28 public class SpreadsheetNodeManager extends StandardVariableNodeManager<SheetNode, SpreadsheetBook> {
29
30     public SpreadsheetNodeManager(SpreadsheetRealm realm) {
31         super(realm, realm.getEngine());
32         realm.getEngine().registerListener(new SpreadsheetBookListener() {
33             
34             @Override
35             public void cellsChanged(Collection<SpreadsheetCell> cells) {
36                 realm.asyncExec(new Runnable() {
37                     @Override
38                     public void run() {
39                         for(SpreadsheetCell cell : cells) {
40                             System.err.println("Modification in cell " + cell);
41                             refreshVariable(new SpreadsheetCellContent(cell));
42                             refreshVariable(new SpreadsheetCellContentExpression(cell));
43                         }
44                     }
45                 });
46             }
47         });
48     }
49
50     static final Set<String> COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component);
51
52     @Override
53     public Set<String> getClassifications(SheetNode node) throws NodeManagerException {
54         checkThreadAccess();
55         if(isRoot(node))
56             return COMPONENT_CLASS;
57         else
58             return Collections.emptySet();
59     }
60
61     @Override
62     public String getPropertyURI(SheetNode parent, SheetNode property) {
63         if(property instanceof SpreadsheetCellContent) {
64             return SpreadsheetResource.URIs.Cell_content;
65         } else if(property instanceof SpreadsheetTypeNode) {
66             return Layer0.URIs.typeURI;
67         } else if(property instanceof SpreadsheetCellContentExpression) {
68             return Layer0.URIs.SCLValue_expression;
69         } else if (property instanceof SpreadsheetCellStyle) {
70             return SpreadsheetResource.URIs.Cell_style;
71         } else if (property instanceof SpreadsheetCellEditable){
72             return SpreadsheetResource.URIs.Cell_editable;
73         } else {
74             return null;
75         }
76     }
77     
78     //Custom setValue logic for SpreadsheetNodeManager - calls the setValueAndFireSelectedListeners
79     @Override
80     public void setValue(SheetNode node, Object value, Binding binding) throws NodeManagerException {
81         Set<SheetNode> dirtyNodeContents = findDirtyNodeContents(node);
82         super.setValueAndFireSelectedListeners(node, value, binding, dirtyNodeContents);
83         if(value instanceof SpreadsheetFormula) {
84             SpreadsheetCellContent scc = (SpreadsheetCellContent)node;
85             SpreadsheetCellContentExpression scce = new SpreadsheetCellContentExpression(scc.cell);
86             // We need to also refresh the expression variable in this case
87             refreshVariable(scce);
88         }
89     }
90     
91     //Find the cells that are used by this cell and their SpreadsheetContents, so that they can be marked as dirty later
92     public Set<SheetNode> findDirtyNodeContents(SheetNode node){
93         Set<SheetNode> dirty = new HashSet<>();
94         
95         SpreadsheetCell sscell = null;
96         if(node instanceof SpreadsheetCell) {
97                 sscell = (SpreadsheetCell)node;
98         } else if (node instanceof SpreadsheetCellContent) {
99                 sscell = ((SpreadsheetCellContent)node).cell;
100         }
101                         
102         if(sscell != null) {
103                 Set<SpreadsheetCell> result = ((SpreadsheetRealm)super.getRealm()).getEngine().invalidate(sscell);
104                 dirty.addAll(result);
105         }
106                         
107         Set<SheetNode> dirtyNodeContents = new HashSet<>();
108         for(SheetNode cell : dirty) {
109                 Map<String, SheetNode> properties = cell.getProperties();
110                 dirtyNodeContents.add((SpreadsheetCellContent)properties.get("content"));
111         }
112         
113         return dirtyNodeContents;
114     }
115     
116     
117     @Override
118     protected Variant getEngineVariantOrCached(SheetNode node) throws NodeManagerException {
119         Variant variant = valueCache.get(node);
120         if(variant == null) {
121             Object value = realm.getEngine().getEngineValue(node);
122             Binding binding = realm.getEngine().getEngineBinding(node);
123             variant = new Variant(binding, value);
124             valueCache.put(node, variant);
125         }
126         return variant;
127     }
128     
129 }