1 package org.simantics.spreadsheet.graph.function;
\r
3 import java.io.StringReader;
\r
4 import java.util.ArrayList;
\r
5 import java.util.Collection;
\r
6 import java.util.Collections;
\r
7 import java.util.HashMap;
\r
8 import java.util.HashSet;
\r
9 import java.util.List;
\r
10 import java.util.Map;
\r
11 import java.util.Set;
\r
12 import java.util.function.Consumer;
\r
14 import org.simantics.databoard.Bindings;
\r
15 import org.simantics.databoard.Databoard;
\r
16 import org.simantics.databoard.adapter.AdaptException;
\r
17 import org.simantics.databoard.binding.Binding;
\r
18 import org.simantics.databoard.binding.mutable.MutableVariant;
\r
19 import org.simantics.databoard.binding.mutable.Variant;
\r
20 import org.simantics.databoard.type.Datatype;
\r
21 import org.simantics.datatypes.literal.Font;
\r
22 import org.simantics.datatypes.literal.RGB;
\r
23 import org.simantics.datatypes.utils.BTreeContentBean;
\r
24 import org.simantics.db.ReadGraph;
\r
25 import org.simantics.db.Resource;
\r
26 import org.simantics.db.WriteGraph;
\r
27 import org.simantics.db.common.request.ObjectsWithType;
\r
28 import org.simantics.db.common.request.WriteRequest;
\r
29 import org.simantics.db.common.utils.Logger;
\r
30 import org.simantics.db.common.utils.NameUtils;
\r
31 import org.simantics.db.exception.DatabaseException;
\r
32 import org.simantics.db.layer0.StandardRealm;
\r
33 import org.simantics.db.layer0.exception.MissingVariableException;
\r
34 import org.simantics.db.layer0.function.StandardChildDomainChildren;
\r
35 import org.simantics.db.layer0.request.PossibleActiveRun;
\r
36 import org.simantics.db.layer0.util.Layer0Utils;
\r
37 import org.simantics.db.layer0.variable.ConstantChildVariable;
\r
38 import org.simantics.db.layer0.variable.ConstantPropertyVariableBuilder;
\r
39 import org.simantics.db.layer0.variable.ProxyChildVariable;
\r
40 import org.simantics.db.layer0.variable.ProxyVariables;
\r
41 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
\r
42 import org.simantics.db.layer0.variable.ValueAccessor;
\r
43 import org.simantics.db.layer0.variable.Variable;
\r
44 import org.simantics.db.layer0.variable.VariableMap;
\r
45 import org.simantics.db.layer0.variable.VariableMapImpl;
\r
46 import org.simantics.db.layer0.variable.Variables;
\r
47 import org.simantics.db.request.Write;
\r
48 import org.simantics.document.server.io.IColor;
\r
49 import org.simantics.document.server.io.IFont;
\r
50 import org.simantics.document.server.io.ITableCell;
\r
51 import org.simantics.layer0.Layer0;
\r
52 import org.simantics.scl.reflection.annotations.SCLValue;
\r
53 import org.simantics.simulator.variable.exceptions.NodeManagerException;
\r
54 import org.simantics.spreadsheet.CellEditor;
\r
55 import org.simantics.spreadsheet.ClientModel;
\r
56 import org.simantics.spreadsheet.Range;
\r
57 import org.simantics.spreadsheet.graph.ExcelFormula;
\r
58 import org.simantics.spreadsheet.graph.SheetNode;
\r
59 import org.simantics.spreadsheet.graph.SpreadsheetBook;
\r
60 import org.simantics.spreadsheet.graph.SpreadsheetCell;
\r
61 import org.simantics.spreadsheet.graph.SpreadsheetCellContent;
\r
62 import org.simantics.spreadsheet.graph.SpreadsheetFormula;
\r
63 import org.simantics.spreadsheet.graph.SpreadsheetGraphUtils;
\r
64 import org.simantics.spreadsheet.graph.SpreadsheetSCLConstant;
\r
65 import org.simantics.spreadsheet.graph.SpreadsheetSessionManager;
\r
66 import org.simantics.spreadsheet.graph.SpreadsheetStyle;
\r
67 import org.simantics.spreadsheet.graph.SpreadsheetStyle.SpreadsheetStyleBuilder;
\r
68 import org.simantics.spreadsheet.graph.celleditor.GraphCellEditorAdapter;
\r
69 import org.simantics.spreadsheet.graph.parser.ParseException;
\r
70 import org.simantics.spreadsheet.graph.parser.SheetFormulaParser;
\r
71 import org.simantics.spreadsheet.graph.parser.ast.AstValue;
\r
72 import org.simantics.spreadsheet.resource.SpreadsheetResource;
\r
73 import org.simantics.spreadsheet.util.SpreadsheetUtils;
\r
75 import gnu.trove.map.TMap;
\r
76 import gnu.trove.map.hash.THashMap;
\r
77 import it.unimi.dsi.fastutil.objects.ObjectArrayList;
\r
81 @SCLValue(type = "ReadGraph -> Resource -> a -> String")
\r
82 public static String cellLabel(ReadGraph graph, Resource resource, Object context) throws DatabaseException {
\r
83 if(context instanceof Resource) {
\r
84 return NameUtils.getSafeLabel(graph, ((Resource)context));
\r
85 } else if (context instanceof Variable) {
\r
86 Variable parent = ((Variable)context).getParent(graph);
\r
87 Variable content = parent.getPossibleProperty(graph, ClientModel.CONTENT);
\r
88 if(content != null) {
\r
89 Databoard db = graph.getService(Databoard.class);
\r
90 Variant variant = content.getValue(graph, db.VARIANT);
\r
91 return variant.getValue().toString();
\r
93 return parent.getName(graph);
\r
96 throw new DatabaseException("Unknown context " + context);
\r
100 private static Set<String> CLASSIFICATIONS = new HashSet<String>();
\r
101 private static ConstantPropertyVariableBuilder immutableBuilder = new ConstantPropertyVariableBuilder("immutable", true, Bindings.BOOLEAN);
\r
104 CLASSIFICATIONS.add(SpreadsheetResource.URIs.Attribute);
\r
107 @SCLValue(type = "ValueAccessor")
\r
108 public static ValueAccessor contentValueAccessor = new ValueAccessor() {
\r
111 public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {
\r
112 System.out.println("contentValueAccessor.context=" + context.getURI(graph));
\r
113 if(value instanceof String) {
\r
115 // Expressions are given as string
\r
116 String text = (String)value;
\r
117 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
118 if (text.startsWith("==")) {
\r
119 if(!Layer0Utils.setOrClearExpression(graph, context, text.substring(1), SHEET.SCLValue)) {
\r
120 org.simantics.db.layer0.function.All.standardSetValue3(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
\r
121 //StandardValueAccessor.setValue(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
\r
122 //org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
\r
127 Variable cell = context.getParent(graph);
\r
128 System.out.println("setValue : " + cell.getURI(graph));
\r
130 String formula = text.substring(1);
\r
132 if (ProxyVariables.isProxy(graph, context)) {
\r
134 SheetFormulaParser p = new SheetFormulaParser(new StringReader(formula));
\r
135 AstValue v = p.relation();
\r
136 SpreadsheetFormula sformula = new SpreadsheetFormula(v, formula);
\r
137 setValueToEngine(graph, cell, context, sformula, binding);
\r
138 } catch (ParseException e) {
\r
139 e.printStackTrace();
\r
144 Variant v = new Variant(ExcelFormula.BINDING, new ExcelFormula(formula));
\r
145 graph.claimLiteral(cell.getRepresents(graph), SHEET.Cell_content, SHEET.Cell_content_Inverse, Layer0.getInstance(graph).Variant, v, Bindings.VARIANT);
\r
149 if(ProxyVariables.isProxy(graph, context)) {
\r
151 Variable cell = context.getParent(graph);
\r
152 setValueToEngine(graph, cell, context, value, binding);
\r
156 // Values are given as Variant
\r
157 String expression = context.getPossiblePropertyValue(graph, "expression");
\r
158 if(expression != null) {
\r
159 Object current_ = context.getPossibleValue(graph);
\r
160 if(current_ instanceof Variable) {
\r
161 Variable current = (Variable)current_;
\r
162 Variant variant = (Variant)value;
\r
163 Datatype dt = current.getDatatype(graph);
\r
165 throw new DatabaseException();
\r
167 Binding variableBinding = Bindings.getBinding(dt);
\r
169 Object adapted = variant.getValue(variableBinding);
\r
170 current.setValue(graph, adapted, variableBinding);
\r
171 } catch (AdaptException e) {
\r
172 Logger.defaultLogError(e);
\r
176 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
177 Layer0Utils.clearExpression(graph, context, SHEET.SCLValue);
\r
179 org.simantics.db.layer0.function.All.standardSetValue3(graph, context, value, binding);
\r
180 //org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, value, binding);
\r
184 private void setValueToEngine(WriteGraph graph, Variable cell, Variable context, Object value, Binding binding) throws DatabaseException {
\r
185 Variable sheet = cell.getParent(graph);
\r
187 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
189 while(!sheet.getType(graph).equals(SHEET.Spreadsheet)) {
\r
190 sheet = sheet.getParent(graph);
\r
193 Range r = SpreadsheetUtils.decodeCellAbsolute(cell.getName(graph));
\r
195 Variable root = ProxyVariables.proxyVariableRoot(graph, context);
\r
197 String sessionName = root.getParent(graph).getURI(graph);
\r
198 StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
\r
199 SpreadsheetBook book = realm.getEngine();
\r
200 SpreadsheetCell sc = book.get(sheet.getName(graph), r.startRow, r.startColumn);
\r
201 sc.setContent(value);
\r
202 // book.accept(new InvalidateAll());
\r
203 List<SpreadsheetCell> changed = book.invalidate(sc);
\r
204 realm.asyncExec(new Runnable() {
\r
207 public void run() {
\r
209 SpreadsheetCellContent content = (SpreadsheetCellContent)sc.getProperties().get("content");
\r
210 realm.getNodeManager().setValue(content, value, binding);
\r
211 // for(SpreadsheetCell cell : changed) {
\r
212 // content = (SpreadsheetCellContent)cell.getProperties().get("content");
\r
213 // realm.getNodeManager().setValue(content, value, binding);
\r
215 } catch (NodeManagerException e) {
\r
216 Logger.defaultLogError(e);
\r
223 public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
\r
224 if(value instanceof String) setValue(graph, context, value, Bindings.STRING);
\r
225 else if(value instanceof Variant) setValue(graph, context, value, Bindings.VARIANT);
\r
226 else throw new DatabaseException("Unsupported value type " + value);
\r
230 public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
\r
231 return org.simantics.db.layer0.function.All.standardGetValue2(graph, context, binding);
\r
232 //return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context, binding);
\r
236 public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
\r
237 return org.simantics.db.layer0.function.All.standardGetValue1(graph, ((StandardGraphPropertyVariable)context));
\r
238 // return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context);
\r
242 public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
\r
243 return org.simantics.db.layer0.function.All.standardGetDatatype(graph, context);
\r
244 // return org.simantics.db.layer0.function.All.standardValueAccessor.getDatatype(graph, context);
\r
249 @SCLValue(type = "ValueAccessor")
\r
250 public static ValueAccessor contentDisplayValueAccessor = new ValueAccessor() {
\r
253 public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {
\r
254 if (!Bindings.STRING.equals(binding)) throw new IllegalArgumentException();
\r
255 if (!(value instanceof String)) throw new IllegalArgumentException();
\r
257 if (((String)value).startsWith("=")) {
\r
258 context.getParent(graph).setValue(graph, value, Bindings.STRING);
\r
260 context.getParent(graph).setValue(graph, new Variant(Bindings.STRING, value), Bindings.VARIANT);
\r
265 public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
\r
266 if (!(value instanceof String)) throw new IllegalArgumentException();
\r
268 if (((String)value).startsWith("=")) {
\r
269 context.getParent(graph).setValue(graph, value, Bindings.STRING);
\r
271 context.getParent(graph).setValue(graph, new Variant(Bindings.STRING, value), Bindings.VARIANT);
\r
276 public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
\r
277 return context.getParent(graph).getValue(graph, binding);
\r
281 public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
\r
282 return context.getParent(graph).getValue(graph);
\r
286 public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
\r
287 return context.getParent(graph).getDatatype(graph);
\r
292 @SCLValue(type = "VariableMap")
\r
293 public static VariableMap stringArrayChildren = new VariableMapImpl() {
\r
296 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
\r
298 TMap<String, Variable> map = new THashMap<String, Variable>();
\r
299 getVariables(graph, context, map);
\r
300 return map.get(name);
\r
305 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
\r
307 Resource resource = context.getRepresents(graph);
\r
309 SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
\r
311 String location = graph.getPossibleRelatedValue(resource, sr.Range_location, Bindings.STRING);
\r
312 if(location == null) return map;
\r
313 Integer width = graph.getPossibleRelatedValue(resource, sr.Range_widthBound, Bindings.INTEGER);
\r
314 if(width == null) return map;
\r
315 String[] array = graph.getPossibleRelatedValue(resource, sr.StringArrayRange_array, Bindings.STRING_ARRAY);
\r
316 if(array == null) return map;
\r
318 int rows = array.length / width;
\r
320 if(map == null) map = new HashMap<String,Variable>();
\r
322 for(int offset=0,i=0;i<rows;i++) {
\r
323 for(int j=0;j<width;j++) {
\r
325 String value = array[offset++];
\r
326 String valueLocation = SpreadsheetUtils.offset(location, i, j);
\r
328 ConstantPropertyVariableBuilder labelBuilder = new ConstantPropertyVariableBuilder(ClientModel.LABEL, value, Bindings.STRING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS);
\r
329 ConstantPropertyVariableBuilder typeBuilder = new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet());
\r
331 map.put(valueLocation, new ConstantChildVariable(context, valueLocation, labelBuilder, typeBuilder, immutableBuilder));
\r
342 @SCLValue(type = "VariableMap")
\r
343 public static VariableMap queryRangeChildren = new VariableMapImpl() {
\r
346 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
\r
348 TMap<String, Variable> map = new THashMap<String, Variable>();
\r
349 getVariables(graph, context, map);
\r
350 return map.get(name);
\r
355 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
\r
357 SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
\r
359 String location = "A1";
\r
363 Object object = context.getPropertyValue(graph, sr.ExpressionRange_cells);
\r
365 List<?> data = (List<?>)object;
\r
367 if(map == null) map = new HashMap<String,Variable>();
\r
369 for(Object o : data) {
\r
370 if(o instanceof ITableCell) {
\r
372 ITableCell cell = (ITableCell)o;
\r
374 String valueLocation = SpreadsheetUtils.offset(location, cell.getRow(), cell.getColumn());
\r
376 ArrayList<ConstantPropertyVariableBuilder> builders = new ArrayList<ConstantPropertyVariableBuilder>();
\r
378 builders.add(new ConstantPropertyVariableBuilder(ClientModel.CONTENT, Variant.ofInstance(cell.getText()), Bindings.VARIANT, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
\r
379 builders.add(new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet()));
\r
381 IFont font = cell.getFont();
\r
383 builders.add(new ConstantPropertyVariableBuilder(ClientModel.FONT, new Font(font.getFamily(), font.getHeight(), font.getStyle()), Font.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
\r
386 int align = cell.getAlign();
\r
387 builders.add(new ConstantPropertyVariableBuilder(ClientModel.ALIGN, align, Bindings.INTEGER, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
\r
389 IColor foreground = cell.getFGColor();
\r
390 if(foreground != null) {
\r
391 builders.add(new ConstantPropertyVariableBuilder(ClientModel.FOREGROUND, new RGB.Integer(foreground.red(), foreground.green(), foreground.blue()), RGB.Integer.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
\r
394 IColor background = cell.getBGColor();
\r
395 if(background != null) {
\r
396 builders.add(new ConstantPropertyVariableBuilder(ClientModel.BACKGROUND, new RGB.Integer(background.red(), background.green(), background.blue()), RGB.Integer.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
\r
399 map.put(valueLocation, new ConstantChildVariable(context, valueLocation, builders));
\r
404 } catch (DatabaseException e) {
\r
405 throw (DatabaseException)e;
\r
406 } catch (Throwable t) {
\r
407 throw new DatabaseException(t);
\r
417 @SCLValue(type = "VariableMap")
\r
418 public static VariableMap spreadsheetLinesChildren = new StandardChildDomainChildren() {
\r
421 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
\r
423 if(ProxyVariables.isProxy(graph, context))
\r
424 return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, null, name);
\r
426 return super.getVariable(graph, context, name);
\r
428 // TMap<String, Variable> map = new THashMap<String, Variable>();
\r
429 // getVariables(graph, context, map);
\r
430 // return map.get(name);
\r
435 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
\r
437 if(ProxyVariables.isProxy(graph, context))
\r
438 return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, Collections.emptyMap(), map);
\r
440 // Resource lines = context.getRepresents(graph);
\r
442 // BTree bt = new BTree(graph, lines, true);
\r
443 // List<Tuple2> entries = bt.entriesOfBTree(graph);
\r
444 // for(Tuple2 tuple : entries) {
\r
445 // Variant v = (Variant)tuple.get(0);
\r
446 // Resource line = (Resource)tuple.get(1);
\r
447 // String name = v.getValue().toString();
\r
448 // Variable child = org.simantics.db.layer0.function.All.getStandardChildDomainChildVariable(graph, context, line, name);
\r
449 // if(map == null) map = new THashMap<String,Variable>();
\r
450 // map.put(name, child);
\r
455 // return org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariables(graph, context, map);
\r
457 return super.getVariables(graph, context, map);
\r
463 @SCLValue(type = "VariableMap")
\r
464 public static VariableMap doubleArrayChildren = new VariableMapImpl() {
\r
467 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
\r
469 TMap<String, Variable> map = new THashMap<String, Variable>();
\r
470 getVariables(graph, context, map);
\r
471 return map.get(name);
\r
476 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
\r
478 Resource resource = context.getRepresents(graph);
\r
480 SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
\r
482 String location = graph.getPossibleRelatedValue(resource, sr.Range_location, Bindings.STRING);
\r
483 if(location == null) return map;
\r
484 Integer width = graph.getPossibleRelatedValue(resource, sr.Range_widthBound, Bindings.INTEGER);
\r
485 if(width == null) return map;
\r
486 double[] array = graph.getPossibleRelatedValue(resource, sr.DoubleArrayRange_array, Bindings.DOUBLE_ARRAY);
\r
487 if(array == null) return map;
\r
489 if(map == null) map = new HashMap<String,Variable>();
\r
491 int rows = array.length / width;
\r
493 for(int offset=0,i=0;i<rows;i++) {
\r
494 for(int j=0;j<width;j++) {
\r
496 double value = array[offset++];
\r
497 String valueLocation = SpreadsheetUtils.offset(location, i, j);
\r
499 ConstantPropertyVariableBuilder labelBuilder = new ConstantPropertyVariableBuilder(ClientModel.LABEL, String.valueOf(value), Bindings.STRING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS);
\r
500 ConstantPropertyVariableBuilder typeBuilder = new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet());
\r
502 map.put(valueLocation, new ConstantChildVariable(context, valueLocation, labelBuilder, typeBuilder, immutableBuilder));
\r
513 static class SpreadsheetProxyChildVariable extends ProxyChildVariable {
\r
515 public SpreadsheetProxyChildVariable(Variable base, Variable parent, Variable other, String name) {
\r
516 super(base, parent, other, name);
\r
520 public Variable create(Variable base, Variable parent, Variable other, String name) {
\r
521 return new SpreadsheetProxyChildVariable(base, parent, other, name);
\r
524 public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
\r
526 if(CONTEXT_END.equals(name)) {
\r
527 if(other instanceof ProxyChildVariable) {
\r
528 // The context is also a proxy - let it do the job
\r
529 return super.getPossibleChild(graph, name);
\r
531 return org.simantics.db.layer0.function.All.buildChildVariable(graph, this, base.getRepresents(graph), null);
\r
535 return super.getPossibleChild(graph, name);
\r
539 public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
\r
541 Collection<Variable> result = super.getChildren(graph);
\r
542 if(!(base instanceof ProxyChildVariable)) {
\r
543 Variable root = org.simantics.db.layer0.function.All.buildChildVariable(graph, this, base.getRepresents(graph), null);
\r
552 @SCLValue(type = "VariableMap")
\r
553 public static VariableMap spreadsheetChildren = new VariableMapImpl() {
\r
556 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
\r
558 if(ProxyChildVariable.CONTEXT_BEGIN.equals(name)) return getProxy(graph, context);
\r
559 return org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariable(graph, context, name);
\r
563 private Variable getProxy(ReadGraph graph, Variable context) throws DatabaseException {
\r
564 Variable root = Variables.getRootVariable(graph);
\r
565 return new SpreadsheetProxyChildVariable(context, context, root, ProxyChildVariable.CONTEXT_BEGIN);
\r
570 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map)
\r
571 throws DatabaseException {
\r
573 map = org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariables(graph, context, map);
\r
575 if(map == null) map = new HashMap<String,Variable>();
\r
576 map.put(ProxyChildVariable.CONTEXT_BEGIN, getProxy(graph, context));
\r
583 @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")
\r
584 public static CellEditor<Write> defaultSheetCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
\r
586 final Variable sheet = context_.getParent(graph);
\r
588 return new GraphCellEditorAdapter(null) {
\r
591 public <T> void edit(final Transaction<Write> transaction, final String location, final String property, final T value, final Binding binding, Consumer<?> callback) {
\r
593 SpreadsheetUtils.schedule(transaction, new WriteRequest() {
\r
596 public void perform(WriteGraph graph) throws DatabaseException {
\r
597 CellEditor<Write> editor = getPossibleCellEditor(graph, location, value == null ? null : new Variant(binding, value));
\r
598 if (editor == null)
\r
600 editor.edit(transaction, location, property, value, binding, callback);
\r
607 public void edit(final Transaction<Write> transaction, final String location, final Variant value, Consumer<?> callback) {
\r
608 SpreadsheetUtils.schedule(transaction, new WriteRequest() {
\r
611 public void perform(WriteGraph graph) throws DatabaseException {
\r
612 CellEditor<Write> editor = getPossibleCellEditor(graph, location, value);
\r
613 if (editor == null)
\r
615 editor.edit(transaction, location, value, callback);
\r
621 private CellEditor<Write> getPossibleCellEditor(WriteGraph graph, String location, Variant value) throws DatabaseException {
\r
622 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
623 Range range = SpreadsheetUtils.decodeCellAbsolute(location);
\r
625 List<Variable> cells = SpreadsheetGraphUtils.possibleConfigurationCellVariables(graph, sheet, range);
\r
626 if (cells.isEmpty()) {
\r
627 if (value == null) {
\r
630 cells = SpreadsheetGraphUtils.getOrCreateConfigurationCellVariables(graph, sheet, range);
\r
633 if (cells.size() != 1)
\r
634 throw new DatabaseException("Can edit only one cell at a time!");
\r
636 return cells.iterator().next().getPropertyValue(graph, SHEET.cellEditor);
\r
640 public void copy(final Transaction<Write> transaction, final String location, final MutableVariant variant, Consumer<?> callback) {
\r
642 SpreadsheetUtils.schedule(transaction, new WriteRequest() {
\r
645 public void perform(WriteGraph graph) throws DatabaseException {
\r
647 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
648 Variable variable = sheet.getPossibleChild(graph, location);
\r
649 if(variable != null) {
\r
650 CellEditor<Write> editor = variable.getPossiblePropertyValue(graph, SHEET.cellEditor);
\r
651 if(editor != null) {
\r
652 editor.copy(transaction, location, variant, null);
\r
665 @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")
\r
666 public static CellEditor<Write> variableCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
\r
668 final Variable cell = context_.getParent(graph);
\r
670 return new GraphCellEditorAdapter(cell) {
\r
673 public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, String property, T value, Binding binding) throws DatabaseException {
\r
674 cell.setPropertyValue(graph, property, value, binding);
\r
679 private static int encodeLineOrNode(ReadGraph graph, Resource r) throws DatabaseException {
\r
680 if(r == null) return 0;
\r
681 Layer0 L0 = Layer0.getInstance(graph);
\r
682 String name = graph.getRelatedValue(r, L0.HasName, Bindings.STRING);
\r
683 if(name.charAt(0) == 'R') {
\r
684 return -Integer.parseInt(name.substring(3));
\r
686 return Integer.parseInt(name);
\r
690 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
\r
691 public static int[] lineNodeKeys(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
\r
693 Resource node = context_.getParent(graph).getRepresents(graph);
\r
694 BTreeContentBean bean = BTreeContentBean.readPossible(graph, node);
\r
695 if(bean == null) return new int[0];
\r
696 // There are n keys and n+1 resources
\r
697 int[] result = new int[2*bean.n+1];
\r
698 for(int i=0;i<bean.n;i++) {
\r
699 result[2*i] = encodeLineOrNode(graph, bean.getChild(i));
\r
700 result[2*i+1] = (int)bean.getKey(i).getValue();
\r
702 result[2*bean.n] = encodeLineOrNode(graph, bean.getChild(bean.n));
\r
707 @SCLValue(type = "ReadGraph -> Resource -> Variable -> LineContentBean")
\r
708 public static LineContentBean defaultLineCells(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
\r
710 String contextUri = context_.getURI(graph);
\r
712 Variable line = context_.getParent(graph);
\r
714 Collection<Variable> children = line.getChildren(graph);
\r
715 ObjectArrayList<LineContentBeanCell> result = new ObjectArrayList<>();
\r
716 SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
\r
717 for (Variable child : children) {
\r
718 Resource repr = child.getRepresents(graph);
\r
720 Resource style = graph.getPossibleObject(repr, SR.Cell_HasStyle);
\r
721 Integer styleId = null;
\r
723 styleId = graph.getPossibleRelatedValue(style, SR.Style_id, Bindings.INTEGER);
\r
724 if (styleId == null) {
\r
725 System.err.println("Style " + style + " has no ID or either cell "+ repr + " has no style attached to it !!");
\r
726 styleId = SpreadsheetStyle.empty().getStyleId();
\r
729 LineContentBeanCell cell = new LineContentBeanCell(styleId);
\r
731 Variant variant = child.getPossiblePropertyValue(graph, SR.Cell_content);
\r
733 if(variant != null) {
\r
735 Variable var = child.getPossibleProperty(graph, SR.Cell_content);
\r
736 String expression = var.getPossiblePropertyValue(graph, "expression");
\r
737 if (expression != null) {
\r
738 cell.setContent(new Variant(SpreadsheetSCLConstant.BINDING, new SpreadsheetSCLConstant(expression, variant.getValue())));
\r
740 cell.setContent(variant);
\r
742 Range r = SpreadsheetUtils.decodeCellAbsolute(child.getName(graph));
\r
743 // result.add(cell);
\r
744 while(result.size() < r.startColumn + 1)
\r
745 result.add(new LineContentBeanCell());
\r
746 result.set(r.startColumn, cell);
\r
751 LineContentBean bean = new LineContentBean();
\r
752 bean.cells = result.toArray(new LineContentBeanCell[result.size()]);
\r
757 @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")
\r
758 public static CellEditor<Write> textCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
\r
760 System.out.println("Context URI : " + context_.getURI(graph));
\r
761 Variable cells = context_.getParent(graph);
\r
762 System.out.println("Cell URI : " + cells.getURI(graph));
\r
764 return new GraphCellEditorAdapter(cells) {
\r
766 public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, String property, T value, Binding binding) throws DatabaseException {
\r
768 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
769 if(ClientModel.CONTENT.equals(property)) {
\r
770 cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
\r
771 Variable runCell = null;
\r
772 Object transactionContext = transaction.getContext();
\r
773 if (transactionContext != null && transactionContext instanceof Variable) {
\r
774 Variable varContext = (Variable) transactionContext;
\r
775 Variable context = Variables.getContext(graph, varContext);
\r
777 runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);
\r
778 } catch (MissingVariableException e) {
\r
779 // Creating new cell, need synchronizing
\r
780 transaction.needSynchronization(cell.getParent(graph));
\r
783 if (runCell != null)
\r
784 runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
\r
785 } else if(ClientModel.CONTENT_EXPRESSION.equals(property)) {
\r
786 cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.STRING);
\r
787 Variable runCell = null;
\r
788 Object transactionContext = transaction.getContext();
\r
789 if (transactionContext != null && transactionContext instanceof Variable) {
\r
790 Variable varContext = (Variable) transactionContext;
\r
791 Variable context = Variables.getContext(graph, varContext);
\r
793 runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);
\r
794 } catch (MissingVariableException e) {
\r
795 //Creating new cell, need synchronizing
\r
796 transaction.needSynchronization(cell.getParent(graph));
\r
799 if (runCell != null)
\r
800 runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.STRING);
\r
801 } else if(ClientModel.BORDER.equals(property)) {
\r
802 Resource textCell = cell.getRepresents(graph);
\r
803 Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
\r
804 SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
\r
805 builder.border((Integer)value);
\r
806 finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
\r
807 } else if(ClientModel.ALIGN.equals(property)) {
\r
808 Resource textCell = cell.getRepresents(graph);
\r
809 Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
\r
810 SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
\r
811 builder.align((Integer)value);
\r
812 finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
\r
813 } else if(ClientModel.LOCKED.equals(property)) {
\r
814 cell.setPropertyValue(graph, SHEET.Cell_locked, value, Bindings.BOOLEAN);
\r
815 } else if(ClientModel.ROW_SPAN.equals(property)) {
\r
816 cell.setPropertyValue(graph, SHEET.Cell_rowSpan, value, Bindings.INTEGER);
\r
817 } else if(ClientModel.COLUMN_SPAN.equals(property)) {
\r
818 cell.setPropertyValue(graph, SHEET.Cell_columnSpan, value, Bindings.INTEGER);
\r
819 } else if(ClientModel.FONT.equals(property)) {
\r
820 Resource textCell = cell.getRepresents(graph);
\r
821 Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
\r
822 SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
\r
823 builder.font((Font)value);
\r
824 finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
\r
825 } else if(ClientModel.FOREGROUND.equals(property)) {
\r
826 Resource textCell = cell.getRepresents(graph);
\r
827 Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
\r
828 SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
\r
829 builder.foreground((RGB.Integer)value);
\r
830 finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
\r
831 } else if(ClientModel.BACKGROUND.equals(property)) {
\r
832 Resource textCell = cell.getRepresents(graph);
\r
833 Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
\r
834 SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
\r
835 builder.background((RGB.Integer)value);
\r
836 finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
\r
840 private void finishStyleUpdate(WriteGraph graph, SpreadsheetResource SHEET, Resource styleContainer, Resource textCell, SpreadsheetStyleBuilder builder, Transaction<?> transaction) throws DatabaseException {
\r
842 Variable bookVariable = Variables.getContext(graph, cell);
\r
843 Resource book = bookVariable.getRepresents(graph);
\r
844 Resource createdStyle = null;
\r
846 SpreadsheetStyle style = builder.build();
\r
847 int styleId = style.getStyleId();
\r
849 Collection<Resource> existingStyles = graph.syncRequest(new ObjectsWithType(book, Layer0.getInstance(graph).ConsistsOf, SHEET.Style));
\r
850 for (Resource eStyle : existingStyles) {
\r
851 int eStyleId = graph.getRelatedValue2(eStyle, SHEET.Style_id, Bindings.INTEGER);
\r
852 if (eStyleId == styleId) {
\r
853 createdStyle = eStyle;
\r
857 if (createdStyle == null) {
\r
858 style = builder.name("Style_" + existingStyles.size()).build();
\r
859 createdStyle = SpreadsheetGraphUtils.createStyle(graph, book, style);
\r
862 graph.deny(textCell, SHEET.Cell_HasStyle);
\r
863 Collection<Resource> cellsOfStyle = graph.getObjects(styleContainer, SHEET.Cell_StyleOf);
\r
864 if (cellsOfStyle.isEmpty()) {
\r
865 graph.deny(styleContainer);
\r
867 graph.claim(textCell, SHEET.Cell_HasStyle, createdStyle);
\r
869 // Variable runCell = null;
\r
870 // Object transactionContext = transaction.getContext();
\r
871 // if (transactionContext != null && transactionContext instanceof Variable) {
\r
872 // Variable varContext = (Variable) transactionContext;
\r
873 // Variable context = Variables.getContext(graph, varContext);
\r
875 // runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);
\r
876 // } catch (MissingVariableException e) {
\r
877 // //Creating new cell, need synchronizing
\r
878 // transaction.needSynchronization(cell.getParent(graph));
\r
881 // if (runCell != null) {
\r
882 // Datatype type = new RecordType();
\r
883 // Binding b = Bindings.getBinding(type);
\r
884 // runCell.setPropertyValue(graph, SHEET.Cell_style, style, b);
\r
888 private SpreadsheetStyleBuilder computeStyleBuilder(SpreadsheetResource SHEET, WriteGraph graph, Resource styleContainer) throws DatabaseException {
\r
889 RGB.Integer foreground = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_foreground, RGB.Integer.BINDING);
\r
890 RGB.Integer background = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_background, RGB.Integer.BINDING);
\r
891 Font font = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_font, Font.BINDING);
\r
892 Integer align = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_align, Bindings.INTEGER);
\r
893 Integer border = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_border, Bindings.INTEGER);
\r
895 return SpreadsheetStyle.newInstace().foreground(foreground).background(background).font(font).align(align).border(border);
\r
899 public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, Variant value) throws DatabaseException {
\r
900 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
902 // Handle possible deletes
\r
904 value = Variant.ofInstance("");
\r
906 if (!transaction.isOperationMode()) {
\r
907 cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
\r
910 Variable runCell = null;
\r
911 Object transactionContext = transaction.getContext();
\r
912 if (transactionContext != null && transactionContext instanceof Variable) {
\r
913 Variable varContext = (Variable) transactionContext;
\r
914 Variable context = Variables.getContext(graph, varContext);
\r
916 runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);
\r
917 } catch (MissingVariableException e) {
\r
918 // Creating cell for the first time so no runCell available at this time, needs synchronization
\r
919 transaction.needSynchronization(cell.getParent(graph));
\r
924 if (runCell != null) {
\r
925 System.out.println("All.edit " + runCell.getURI(graph));
\r
926 runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
\r
931 public <T> void copy(WriteGraph graph, Transaction<Write> transaction, String location, MutableVariant variant) throws DatabaseException {
\r
932 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
934 Variable runCell = null;
\r
935 Object transactionContext = transaction.getContext();
\r
936 if (transactionContext != null && transactionContext instanceof Variable) {
\r
937 Variable varContext = (Variable) transactionContext;
\r
938 Variable context = Variables.getContext(graph, varContext);
\r
939 runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);
\r
942 //Variant content = cell.getPropertyValue(graph, SHEET.Cell_content, Bindings.VARIANT);
\r
943 Object object = cell.getPropertyValue(graph, SHEET.Cell_content);
\r
944 Variant content = null;
\r
945 if (object instanceof Variant) {
\r
946 content = (Variant)object;
\r
947 } else if (object instanceof Double) {
\r
948 content = Variant.ofInstance((Double)object);
\r
949 } else if (object instanceof Float) {
\r
950 content = Variant.ofInstance((Float)object);
\r
951 } else if (object instanceof Integer) {
\r
952 content = Variant.ofInstance((Integer)object);
\r
953 } else if (object instanceof Long) {
\r
954 content = Variant.ofInstance((Long)object);
\r
955 } else if (object instanceof String) {
\r
956 content = Variant.ofInstance((String)object);
\r
957 } else if (object instanceof Variable) {
\r
958 content = Variant.ofInstance((Variable)object);
\r
960 throw new DatabaseException("");
\r
962 variant.setValue(content);
\r
969 @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")
\r
970 public static Variable spreadsheetInput(ReadGraph graph, Resource converter, Variable sheet) throws DatabaseException {
\r
971 return ProxyVariables.inputVariable(graph, sheet);
\r
974 @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")
\r
975 public static Variable spreadsheetSession(ReadGraph graph, Resource converter, Variable sheet) throws DatabaseException {
\r
976 return ProxyVariables.proxySessionVariable(graph, sheet);
\r
979 @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")
\r
980 public static Variable spreadsheetRunInput(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {
\r
981 Resource model = Variables.getModel(graph, property);
\r
982 Variable activeRun = graph.syncRequest(new PossibleActiveRun(model));
\r
983 if(activeRun != null) return activeRun;
\r
984 return Variables.getConfigurationContext(graph, model);
\r
987 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
\r
988 public static Object sclValue(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {
\r
989 return CompileSCLValueRequest.compileAndEvaluate(graph, context);
\r