]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetCell.java
7d04e9b6e21c607bb80b30bce98ed10ac8a5489c
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / SpreadsheetCell.java
1 package org.simantics.spreadsheet.graph;\r
2 \r
3 import java.util.Collections;\r
4 import java.util.HashMap;\r
5 import java.util.List;\r
6 import java.util.Map;\r
7 import java.util.Optional;\r
8 \r
9 import org.simantics.spreadsheet.graph.formula.FormulaError2;\r
10 import org.simantics.spreadsheet.graph.formula.SpreadsheetEvaluationEnvironment;\r
11 import org.simantics.spreadsheet.graph.parser.ast.AstValue;\r
12 import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
13 import org.simantics.spreadsheet.util.SpreadsheetUtils;\r
14 \r
15 public class SpreadsheetCell implements SpreadsheetElement, SheetNode {\r
16 \r
17         private static final long serialVersionUID = 6616793596542239339L;\r
18 \r
19         public static SpreadsheetCell EMPTY;\r
20         \r
21         static {\r
22             EMPTY = new SpreadsheetCell(null, -1);\r
23             EMPTY.setContent("");\r
24             EMPTY.setStyle(SpreadsheetStyle.empty().getStyleId());\r
25         }\r
26         \r
27         private boolean inProgress = false;\r
28         private int iterations = 0;\r
29         \r
30         final private SpreadsheetLine line;\r
31         final private int column;\r
32         int style;\r
33         Object content;\r
34         \r
35         public SpreadsheetCell(SpreadsheetLine line, int column) {\r
36                 this.line = line;\r
37                 this.column = column;\r
38         }\r
39 \r
40     public boolean hasExpression() {\r
41                 return content instanceof SpreadsheetFormula || content instanceof SpreadsheetSCLConstant; \r
42         }\r
43         \r
44         public void setContent(Object newContent) {\r
45 //       if(newContent != null) {\r
46 //            if (!(newContent instanceof Serializable)) {\r
47 //                throw new AssertionError("content not instanceof Serializable but it is " + newContent.getClass().getSimpleName());\r
48 //            }\r
49 //        }\r
50             if (GraphUI.DEBUG)\r
51                 System.out.println("SpreadsheetCell.setContent "+ this + " " + newContent);\r
52                 this.content = newContent;\r
53         }\r
54 \r
55         @Override\r
56         public String getName() {\r
57                 return SpreadsheetUtils.cellName(line.row, column);\r
58         }\r
59 \r
60         @Override\r
61         public Map<?, ?> getChildren() {\r
62                 return Collections.emptyMap();\r
63         }\r
64         \r
65         private static String[] keys = { "typeURI", "content" };\r
66         \r
67         @Override\r
68         public Map<String, SheetNode> getProperties() {\r
69             Map<String, SheetNode> properties = new HashMap<>();\r
70             \r
71             if (GraphUI.DEBUG)\r
72                 System.out.println("SpreadsheetCell.getProperties: " + this + " " + content + " " + style);\r
73             \r
74             properties.put("typeURI", new SpreadsheetTypeNode(SpreadsheetResource.URIs.Cell));\r
75             properties.put("content", new SpreadsheetCellContent(this));\r
76         properties.put("style", new SpreadsheetCellStyle(this));\r
77         properties.put("editable", new SpreadsheetCellEditable(this));\r
78             return properties;\r
79         }\r
80         \r
81         public SpreadsheetBook getBook() {\r
82                 return line.getEngine().getBook();\r
83         }\r
84 \r
85         public SpreadsheetEngine getEngine() {\r
86                 return line.getEngine();\r
87         }\r
88 \r
89         public <T> T evaluate(SpreadsheetEvaluationEnvironment env) {\r
90                 return evaluate(env, null);\r
91         }\r
92 \r
93         public <T> T evaluate(SpreadsheetEvaluationEnvironment env, CellValueVisitor caller) {\r
94 //          System.err.println(getEngine().getName() + ":" + getName() + ": evaluate");\r
95                 if(caller != null)\r
96                         caller.addReference(makeReferenceKey());\r
97                 if(content instanceof SpreadsheetFormula) {\r
98                         SpreadsheetFormula f = (SpreadsheetFormula)content;\r
99                         if(f.result == null) {\r
100                                 CellValueVisitor visitor = new CellValueVisitor(env, this);\r
101                                 AstValue value = ((SpreadsheetFormula)content).value;\r
102                                 if(this.inProgress == true) this.iterations++;\r
103                                 \r
104                                 if(env.iterationEnabled == false){\r
105                                         if(this.inProgress == false){\r
106                                                 this.inProgress = true;\r
107                                                 f.result = value.accept(visitor);\r
108                                         }\r
109                                         else f.result = FormulaError2.CIRCULAR_REF.getString();\r
110                                 }\r
111                                 else if(iterations<env.iterationLimit){\r
112                                         this.inProgress = true;\r
113                                         f.result = value.accept(visitor);\r
114                                 }\r
115                                 else f.result = 0.0;\r
116                                 \r
117                                 env.getBook().registerReferences(makeReferenceKey(), visitor.getReferences());\r
118                         }\r
119                         this.inProgress = false;\r
120                         return (T)f.result;\r
121                 } else if (content instanceof SpreadsheetSCLConstant) {\r
122                     SpreadsheetSCLConstant sclConstant = (SpreadsheetSCLConstant) content;\r
123                     return (T) sclConstant.content;\r
124                 } else {\r
125                         this.inProgress = false;\r
126                         return (T)content;\r
127                 }\r
128         }\r
129         \r
130         public long makeReferenceKey() {\r
131                 SpreadsheetBook book = getBook();\r
132                 SpreadsheetEngine engine = getEngine();\r
133                 long engineIndex = book.getEngineIndex(engine);\r
134                 long row = line.row;\r
135                 long col = column;\r
136                 return (engineIndex << 40) + (row << 20) + col; \r
137         }\r
138         \r
139         public void invalidate() {\r
140                 getEngine().rangeCache = null;\r
141                 if(content instanceof SpreadsheetFormula) {\r
142                         SpreadsheetFormula f = (SpreadsheetFormula)content;\r
143                         f.result = null;\r
144                 }\r
145         }\r
146 \r
147         @Override\r
148         public void accept(SpreadsheetVisitor v) {\r
149                 v.visit(this);\r
150         }\r
151 \r
152     @Override\r
153     public Optional<SpreadsheetElement> getParent() {\r
154         return Optional.of(line);\r
155     }\r
156 \r
157     @Override\r
158     public List<SpreadsheetElement> getSpreadsheetChildren() {\r
159         return Collections.emptyList();\r
160     }\r
161 \r
162     @Override\r
163     public void remove(SpreadsheetElement child) {\r
164         // TODO Auto-generated method stub\r
165         \r
166     }\r
167 \r
168     @Override\r
169     public int hashCode() {\r
170         final int prime = 31;\r
171         int result = 1;\r
172         result = prime * result + column;\r
173         result = prime * result + ((line == null) ? 0 : line.hashCode());\r
174         return result;\r
175     }\r
176 \r
177     @Override\r
178     public boolean equals(Object obj) {\r
179         if (this == obj)\r
180             return true;\r
181         if (obj == null)\r
182             return false;\r
183         if (getClass() != obj.getClass())\r
184             return false;\r
185         SpreadsheetCell other = (SpreadsheetCell) obj;\r
186         if (column != other.column)\r
187             return false;\r
188         if (line == null) {\r
189             if (other.line != null)\r
190                 return false;\r
191         } else if (!line.equals(other.line))\r
192             return false;\r
193         return true;\r
194     }\r
195 \r
196     public void setStyle(int styleId) {\r
197         this.style = styleId;\r
198     }\r
199 \r
200     public int getStyle() {\r
201         return style;\r
202     }\r
203 \r
204     public Object getContent() {\r
205         return content;\r
206     }\r
207     \r
208     public static SpreadsheetCell empty(SpreadsheetLine line, int column) {\r
209         SpreadsheetCell cell =  new SpreadsheetCell(line, column);\r
210         cell.setContent("");\r
211         cell.setStyle(SpreadsheetStyle.empty().getStyleId());\r
212         return cell;\r
213     }\r
214 \r
215 }\r