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