--- /dev/null
+package org.simantics.spreadsheet.graph.function;\r
+\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.function.Consumer;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Databoard;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.mutable.MutableVariant;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.datatypes.literal.Font;\r
+import org.simantics.datatypes.literal.RGB;\r
+import org.simantics.datatypes.utils.BTreeContentBean;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.StandardRealm;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.function.StandardChildDomainChildren;\r
+import org.simantics.db.layer0.request.PossibleActiveRun;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.variable.ConstantChildVariable;\r
+import org.simantics.db.layer0.variable.ConstantPropertyVariableBuilder;\r
+import org.simantics.db.layer0.variable.ProxyChildVariable;\r
+import org.simantics.db.layer0.variable.ProxyVariables;\r
+import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;\r
+import org.simantics.db.layer0.variable.ValueAccessor;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.VariableMap;\r
+import org.simantics.db.layer0.variable.VariableMapImpl;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.request.Write;\r
+import org.simantics.document.server.io.IColor;\r
+import org.simantics.document.server.io.IFont;\r
+import org.simantics.document.server.io.ITableCell;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.simulator.variable.exceptions.NodeManagerException;\r
+import org.simantics.spreadsheet.CellEditor;\r
+import org.simantics.spreadsheet.ClientModel;\r
+import org.simantics.spreadsheet.Range;\r
+import org.simantics.spreadsheet.graph.ExcelFormula;\r
+import org.simantics.spreadsheet.graph.SheetNode;\r
+import org.simantics.spreadsheet.graph.SpreadsheetBook;\r
+import org.simantics.spreadsheet.graph.SpreadsheetCell;\r
+import org.simantics.spreadsheet.graph.SpreadsheetCellContent;\r
+import org.simantics.spreadsheet.graph.SpreadsheetFormula;\r
+import org.simantics.spreadsheet.graph.SpreadsheetGraphUtils;\r
+import org.simantics.spreadsheet.graph.SpreadsheetSCLConstant;\r
+import org.simantics.spreadsheet.graph.SpreadsheetSessionManager;\r
+import org.simantics.spreadsheet.graph.SpreadsheetStyle;\r
+import org.simantics.spreadsheet.graph.SpreadsheetStyle.SpreadsheetStyleBuilder;\r
+import org.simantics.spreadsheet.graph.celleditor.GraphCellEditorAdapter;\r
+import org.simantics.spreadsheet.graph.parser.ParseException;\r
+import org.simantics.spreadsheet.graph.parser.SheetFormulaParser;\r
+import org.simantics.spreadsheet.graph.parser.ast.AstValue;\r
+import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
+import org.simantics.spreadsheet.util.SpreadsheetUtils;\r
+\r
+import gnu.trove.map.TMap;\r
+import gnu.trove.map.hash.THashMap;\r
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;\r
+\r
+public class All {\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> a -> String")\r
+ public static String cellLabel(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+ if(context instanceof Resource) {\r
+ return NameUtils.getSafeLabel(graph, ((Resource)context)); \r
+ } else if (context instanceof Variable) {\r
+ Variable parent = ((Variable)context).getParent(graph);\r
+ Variable content = parent.getPossibleProperty(graph, ClientModel.CONTENT);\r
+ if(content != null) {\r
+ Databoard db = graph.getService(Databoard.class);\r
+ Variant variant = content.getValue(graph, db.VARIANT);\r
+ return variant.getValue().toString();\r
+ } else {\r
+ return parent.getName(graph);\r
+ }\r
+ } else {\r
+ throw new DatabaseException("Unknown context " + context);\r
+ }\r
+ }\r
+\r
+ private static Set<String> CLASSIFICATIONS = new HashSet<String>();\r
+ private static ConstantPropertyVariableBuilder immutableBuilder = new ConstantPropertyVariableBuilder("immutable", true, Bindings.BOOLEAN); \r
+ \r
+ static {\r
+ CLASSIFICATIONS.add(SpreadsheetResource.URIs.Attribute);\r
+ }\r
+\r
+ @SCLValue(type = "ValueAccessor")\r
+ public static ValueAccessor contentValueAccessor = new ValueAccessor() {\r
+ \r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
+ System.out.println("contentValueAccessor.context=" + context.getURI(graph));\r
+ if(value instanceof String) {\r
+ \r
+ // Expressions are given as string\r
+ String text = (String)value;\r
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+ if (text.startsWith("==")) {\r
+ if(!Layer0Utils.setOrClearExpression(graph, context, text.substring(1), SHEET.SCLValue)) {\r
+ org.simantics.db.layer0.function.All.standardSetValue3(graph, context, Variant.ofInstance(value), Bindings.VARIANT);\r
+ //StandardValueAccessor.setValue(graph, context, Variant.ofInstance(value), Bindings.VARIANT);\r
+ //org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, Variant.ofInstance(value), Bindings.VARIANT);\r
+ }\r
+ return;\r
+ } else {\r
+ \r
+ Variable cell = context.getParent(graph);\r
+ System.out.println("setValue : " + cell.getURI(graph));\r
+ \r
+ String formula = text.substring(1);\r
+ \r
+ if (ProxyVariables.isProxy(graph, context)) {\r
+ try {\r
+ SheetFormulaParser p = new SheetFormulaParser(new StringReader(formula));\r
+ AstValue v = p.relation();\r
+ SpreadsheetFormula sformula = new SpreadsheetFormula(v, formula);\r
+ setValueToEngine(graph, cell, context, sformula, binding);\r
+ } catch (ParseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return;\r
+ }\r
+ \r
+ Variant v = new Variant(ExcelFormula.BINDING, new ExcelFormula(formula));\r
+ graph.claimLiteral(cell.getRepresents(graph), SHEET.Cell_content, SHEET.Cell_content_Inverse, Layer0.getInstance(graph).Variant, v, Bindings.VARIANT);\r
+ }\r
+ } else {\r
+ \r
+ if(ProxyVariables.isProxy(graph, context)) {\r
+ \r
+ Variable cell = context.getParent(graph);\r
+ setValueToEngine(graph, cell, context, value, binding);\r
+ return;\r
+ }\r
+ \r
+ // Values are given as Variant\r
+ String expression = context.getPossiblePropertyValue(graph, "expression");\r
+ if(expression != null) {\r
+ Object current_ = context.getPossibleValue(graph);\r
+ if(current_ instanceof Variable) {\r
+ Variable current = (Variable)current_;\r
+ Variant variant = (Variant)value;\r
+ Datatype dt = current.getDatatype(graph);\r
+ if (dt == null) {\r
+ throw new DatabaseException();\r
+ }\r
+ Binding variableBinding = Bindings.getBinding(dt);\r
+ try {\r
+ Object adapted = variant.getValue(variableBinding);\r
+ current.setValue(graph, adapted, variableBinding);\r
+ } catch (AdaptException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ return;\r
+ }\r
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+ Layer0Utils.clearExpression(graph, context, SHEET.SCLValue);\r
+ }\r
+ org.simantics.db.layer0.function.All.standardSetValue3(graph, context, value, binding);\r
+ //org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, value, binding);\r
+ }\r
+ }\r
+ \r
+ private void setValueToEngine(WriteGraph graph, Variable cell, Variable context, Object value, Binding binding) throws DatabaseException {\r
+ Variable sheet = cell.getParent(graph);\r
+\r
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+\r
+ while(!sheet.getType(graph).equals(SHEET.Spreadsheet)) {\r
+ sheet = sheet.getParent(graph);\r
+ }\r
+ \r
+ Range r = SpreadsheetUtils.decodeCellAbsolute(cell.getName(graph));\r
+ \r
+ Variable root = ProxyVariables.proxyVariableRoot(graph, context);\r
+ \r
+ String sessionName = root.getParent(graph).getURI(graph);\r
+ StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);\r
+ SpreadsheetBook book = realm.getEngine();\r
+ SpreadsheetCell sc = book.get(sheet.getName(graph), r.startRow, r.startColumn);\r
+ sc.setContent(value);\r
+// book.accept(new InvalidateAll());\r
+ List<SpreadsheetCell> changed = book.invalidate(sc);\r
+ realm.asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ try {\r
+ SpreadsheetCellContent content = (SpreadsheetCellContent)sc.getProperties().get("content");\r
+ realm.getNodeManager().setValue(content, value, binding);\r
+// for(SpreadsheetCell cell : changed) {\r
+// content = (SpreadsheetCellContent)cell.getProperties().get("content");\r
+// realm.getNodeManager().setValue(content, value, binding);\r
+// }\r
+ } catch (NodeManagerException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ }\r
+ });\r
+ }\r
+ \r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
+ if(value instanceof String) setValue(graph, context, value, Bindings.STRING);\r
+ else if(value instanceof Variant) setValue(graph, context, value, Bindings.VARIANT);\r
+ else throw new DatabaseException("Unsupported value type " + value);\r
+ }\r
+ \r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
+ return org.simantics.db.layer0.function.All.standardGetValue2(graph, context, binding);\r
+ //return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context, binding);\r
+ }\r
+ \r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
+ return org.simantics.db.layer0.function.All.standardGetValue1(graph, ((StandardGraphPropertyVariable)context));\r
+// return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context);\r
+ }\r
+\r
+ @Override\r
+ public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {\r
+ return org.simantics.db.layer0.function.All.standardGetDatatype(graph, context);\r
+// return org.simantics.db.layer0.function.All.standardValueAccessor.getDatatype(graph, context);\r
+ }\r
+ \r
+ };\r
+\r
+ @SCLValue(type = "ValueAccessor")\r
+ public static ValueAccessor contentDisplayValueAccessor = new ValueAccessor() {\r
+ \r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
+ if (!Bindings.STRING.equals(binding)) throw new IllegalArgumentException();\r
+ if (!(value instanceof String)) throw new IllegalArgumentException();\r
+ \r
+ if (((String)value).startsWith("=")) {\r
+ context.getParent(graph).setValue(graph, value, Bindings.STRING);\r
+ } else {\r
+ context.getParent(graph).setValue(graph, new Variant(Bindings.STRING, value), Bindings.VARIANT);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
+ if (!(value instanceof String)) throw new IllegalArgumentException();\r
+ \r
+ if (((String)value).startsWith("=")) {\r
+ context.getParent(graph).setValue(graph, value, Bindings.STRING);\r
+ } else {\r
+ context.getParent(graph).setValue(graph, new Variant(Bindings.STRING, value), Bindings.VARIANT);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
+ return context.getParent(graph).getValue(graph, binding);\r
+ }\r
+ \r
+ @Override\r
+ public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
+ return context.getParent(graph).getValue(graph);\r
+ }\r
+\r
+ @Override\r
+ public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {\r
+ return context.getParent(graph).getDatatype(graph);\r
+ }\r
+ \r
+ };\r
+\r
+ @SCLValue(type = "VariableMap")\r
+ public static VariableMap stringArrayChildren = new VariableMapImpl() {\r
+ \r
+ @Override\r
+ public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+ \r
+ TMap<String, Variable> map = new THashMap<String, Variable>();\r
+ getVariables(graph, context, map);\r
+ return map.get(name); \r
+ \r
+ }\r
+\r
+ @Override\r
+ public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+ \r
+ Resource resource = context.getRepresents(graph);\r
+ \r
+ SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);\r
+ \r
+ String location = graph.getPossibleRelatedValue(resource, sr.Range_location, Bindings.STRING);\r
+ if(location == null) return map;\r
+ Integer width = graph.getPossibleRelatedValue(resource, sr.Range_widthBound, Bindings.INTEGER);\r
+ if(width == null) return map;\r
+ String[] array = graph.getPossibleRelatedValue(resource, sr.StringArrayRange_array, Bindings.STRING_ARRAY);\r
+ if(array == null) return map;\r
+ \r
+ int rows = array.length / width;\r
+ \r
+ if(map == null) map = new HashMap<String,Variable>();\r
+ \r
+ for(int offset=0,i=0;i<rows;i++) {\r
+ for(int j=0;j<width;j++) {\r
+ \r
+ String value = array[offset++];\r
+ String valueLocation = SpreadsheetUtils.offset(location, i, j);\r
+\r
+ ConstantPropertyVariableBuilder labelBuilder = new ConstantPropertyVariableBuilder(ClientModel.LABEL, value, Bindings.STRING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS);\r
+ ConstantPropertyVariableBuilder typeBuilder = new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet());\r
+ \r
+ map.put(valueLocation, new ConstantChildVariable(context, valueLocation, labelBuilder, typeBuilder, immutableBuilder));\r
+ \r
+ }\r
+ }\r
+ \r
+ return map;\r
+ \r
+ }\r
+ \r
+ };\r
+\r
+ @SCLValue(type = "VariableMap")\r
+ public static VariableMap queryRangeChildren = new VariableMapImpl() {\r
+ \r
+ @Override\r
+ public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+ \r
+ TMap<String, Variable> map = new THashMap<String, Variable>();\r
+ getVariables(graph, context, map);\r
+ return map.get(name); \r
+ \r
+ }\r
+\r
+ @Override\r
+ public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+ \r
+ SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);\r
+ \r
+ String location = "A1";\r
+ \r
+ try {\r
+ \r
+ Object object = context.getPropertyValue(graph, sr.ExpressionRange_cells);\r
+ \r
+ List<?> data = (List<?>)object;\r
+ \r
+ if(map == null) map = new HashMap<String,Variable>();\r
+ \r
+ for(Object o : data) {\r
+ if(o instanceof ITableCell) {\r
+\r
+ ITableCell cell = (ITableCell)o;\r
+ \r
+ String valueLocation = SpreadsheetUtils.offset(location, cell.getRow(), cell.getColumn());\r
+\r
+ ArrayList<ConstantPropertyVariableBuilder> builders = new ArrayList<ConstantPropertyVariableBuilder>();\r
+ \r
+ builders.add(new ConstantPropertyVariableBuilder(ClientModel.CONTENT, Variant.ofInstance(cell.getText()), Bindings.VARIANT, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));\r
+ builders.add(new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet()));\r
+ \r
+ IFont font = cell.getFont();\r
+ if(font != null) {\r
+ builders.add(new ConstantPropertyVariableBuilder(ClientModel.FONT, new Font(font.getFamily(), font.getHeight(), font.getStyle()), Font.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));\r
+ }\r
+\r
+ int align = cell.getAlign();\r
+ builders.add(new ConstantPropertyVariableBuilder(ClientModel.ALIGN, align, Bindings.INTEGER, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));\r
+ \r
+ IColor foreground = cell.getFGColor();\r
+ if(foreground != null) {\r
+ builders.add(new ConstantPropertyVariableBuilder(ClientModel.FOREGROUND, new RGB.Integer(foreground.red(), foreground.green(), foreground.blue()), RGB.Integer.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));\r
+ }\r
+\r
+ IColor background = cell.getBGColor();\r
+ if(background != null) {\r
+ builders.add(new ConstantPropertyVariableBuilder(ClientModel.BACKGROUND, new RGB.Integer(background.red(), background.green(), background.blue()), RGB.Integer.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));\r
+ }\r
+\r
+ map.put(valueLocation, new ConstantChildVariable(context, valueLocation, builders));\r
+\r
+ }\r
+ }\r
+ \r
+ } catch (DatabaseException e) {\r
+ throw (DatabaseException)e;\r
+ } catch (Throwable t) {\r
+ throw new DatabaseException(t);\r
+ } finally {\r
+ }\r
+\r
+ return map;\r
+ \r
+ }\r
+ \r
+ };\r
+\r
+ @SCLValue(type = "VariableMap")\r
+ public static VariableMap spreadsheetLinesChildren = new StandardChildDomainChildren() {\r
+ \r
+ @Override\r
+ public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+ \r
+ if(ProxyVariables.isProxy(graph, context))\r
+ return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, null, name);\r
+ \r
+ return super.getVariable(graph, context, name);\r
+ \r
+// TMap<String, Variable> map = new THashMap<String, Variable>();\r
+// getVariables(graph, context, map);\r
+// return map.get(name);\r
+\r
+ }\r
+\r
+ @Override\r
+ public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+\r
+ if(ProxyVariables.isProxy(graph, context))\r
+ return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, Collections.emptyMap(), map);\r
+\r
+// Resource lines = context.getRepresents(graph);\r
+// \r
+// BTree bt = new BTree(graph, lines, true);\r
+// List<Tuple2> entries = bt.entriesOfBTree(graph);\r
+// for(Tuple2 tuple : entries) {\r
+// Variant v = (Variant)tuple.get(0);\r
+// Resource line = (Resource)tuple.get(1);\r
+// String name = v.getValue().toString();\r
+// Variable child = org.simantics.db.layer0.function.All.getStandardChildDomainChildVariable(graph, context, line, name);\r
+// if(map == null) map = new THashMap<String,Variable>();\r
+// map.put(name, child);\r
+// }\r
+// \r
+// return map;\r
+\r
+// return org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariables(graph, context, map);\r
+\r
+ return super.getVariables(graph, context, map);\r
+ \r
+ }\r
+ \r
+ };\r
+ \r
+ @SCLValue(type = "VariableMap")\r
+ public static VariableMap doubleArrayChildren = new VariableMapImpl() {\r
+ \r
+ @Override\r
+ public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+ \r
+ TMap<String, Variable> map = new THashMap<String, Variable>();\r
+ getVariables(graph, context, map);\r
+ return map.get(name); \r
+ \r
+ }\r
+\r
+ @Override\r
+ public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+ \r
+ Resource resource = context.getRepresents(graph);\r
+ \r
+ SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);\r
+ \r
+ String location = graph.getPossibleRelatedValue(resource, sr.Range_location, Bindings.STRING);\r
+ if(location == null) return map;\r
+ Integer width = graph.getPossibleRelatedValue(resource, sr.Range_widthBound, Bindings.INTEGER);\r
+ if(width == null) return map;\r
+ double[] array = graph.getPossibleRelatedValue(resource, sr.DoubleArrayRange_array, Bindings.DOUBLE_ARRAY);\r
+ if(array == null) return map;\r
+ \r
+ if(map == null) map = new HashMap<String,Variable>();\r
+ \r
+ int rows = array.length / width;\r
+ \r
+ for(int offset=0,i=0;i<rows;i++) {\r
+ for(int j=0;j<width;j++) {\r
+ \r
+ double value = array[offset++];\r
+ String valueLocation = SpreadsheetUtils.offset(location, i, j);\r
+\r
+ ConstantPropertyVariableBuilder labelBuilder = new ConstantPropertyVariableBuilder(ClientModel.LABEL, String.valueOf(value), Bindings.STRING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS);\r
+ ConstantPropertyVariableBuilder typeBuilder = new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet());\r
+ \r
+ map.put(valueLocation, new ConstantChildVariable(context, valueLocation, labelBuilder, typeBuilder, immutableBuilder));\r
+ \r
+ }\r
+ }\r
+\r
+ return map;\r
+ \r
+ }\r
+ \r
+ };\r
+\r
+ static class SpreadsheetProxyChildVariable extends ProxyChildVariable {\r
+\r
+ public SpreadsheetProxyChildVariable(Variable base, Variable parent, Variable other, String name) {\r
+ super(base, parent, other, name);\r
+ }\r
+ \r
+ @Override\r
+ public Variable create(Variable base, Variable parent, Variable other, String name) {\r
+ return new SpreadsheetProxyChildVariable(base, parent, other, name);\r
+ }\r
+ \r
+ public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {\r
+ \r
+ if(CONTEXT_END.equals(name)) {\r
+ if(other instanceof ProxyChildVariable) {\r
+ // The context is also a proxy - let it do the job\r
+ return super.getPossibleChild(graph, name);\r
+ } else {\r
+ return org.simantics.db.layer0.function.All.buildChildVariable(graph, this, base.getRepresents(graph), null);\r
+ }\r
+ }\r
+ \r
+ return super.getPossibleChild(graph, name);\r
+ \r
+ }\r
+ \r
+ public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {\r
+\r
+ Collection<Variable> result = super.getChildren(graph);\r
+ if(!(base instanceof ProxyChildVariable)) {\r
+ Variable root = org.simantics.db.layer0.function.All.buildChildVariable(graph, this, base.getRepresents(graph), null);\r
+ result.add(root);\r
+ }\r
+ return result;\r
+ \r
+ } \r
+ \r
+ }\r
+\r
+ @SCLValue(type = "VariableMap")\r
+ public static VariableMap spreadsheetChildren = new VariableMapImpl() {\r
+\r
+ @Override\r
+ public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+ \r
+ if(ProxyChildVariable.CONTEXT_BEGIN.equals(name)) return getProxy(graph, context);\r
+ return org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariable(graph, context, name);\r
+ \r
+ }\r
+\r
+ private Variable getProxy(ReadGraph graph, Variable context) throws DatabaseException {\r
+ Variable root = Variables.getRootVariable(graph);\r
+ return new SpreadsheetProxyChildVariable(context, context, root, ProxyChildVariable.CONTEXT_BEGIN);\r
+ }\r
+\r
+\r
+ @Override\r
+ public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map)\r
+ throws DatabaseException {\r
+ \r
+ map = org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariables(graph, context, map);\r
+ \r
+ if(map == null) map = new HashMap<String,Variable>();\r
+ map.put(ProxyChildVariable.CONTEXT_BEGIN, getProxy(graph, context));\r
+ return map;\r
+ }\r
+\r
+ };\r
+\r
+ \r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")\r
+ public static CellEditor<Write> defaultSheetCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {\r
+\r
+ final Variable sheet = context_.getParent(graph);\r
+ \r
+ return new GraphCellEditorAdapter(null) {\r
+\r
+ @Override\r
+ public <T> void edit(final Transaction<Write> transaction, final String location, final String property, final T value, final Binding binding, Consumer<?> callback) {\r
+\r
+ SpreadsheetUtils.schedule(transaction, new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ CellEditor<Write> editor = getPossibleCellEditor(graph, location, value == null ? null : new Variant(binding, value));\r
+ if (editor == null)\r
+ return;\r
+ editor.edit(transaction, location, property, value, binding, callback);\r
+ }\r
+ });\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void edit(final Transaction<Write> transaction, final String location, final Variant value, Consumer<?> callback) {\r
+ SpreadsheetUtils.schedule(transaction, new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ CellEditor<Write> editor = getPossibleCellEditor(graph, location, value);\r
+ if (editor == null)\r
+ return;\r
+ editor.edit(transaction, location, value, callback);\r
+ }\r
+ });\r
+ \r
+ }\r
+ \r
+ private CellEditor<Write> getPossibleCellEditor(WriteGraph graph, String location, Variant value) throws DatabaseException {\r
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+ Range range = SpreadsheetUtils.decodeCellAbsolute(location);\r
+ \r
+ List<Variable> cells = SpreadsheetGraphUtils.possibleConfigurationCellVariables(graph, sheet, range);\r
+ if (cells.isEmpty()) {\r
+ if (value == null) {\r
+ return null;\r
+ } else {\r
+ cells = SpreadsheetGraphUtils.getOrCreateConfigurationCellVariables(graph, sheet, range);\r
+ }\r
+ }\r
+ if (cells.size() != 1)\r
+ throw new DatabaseException("Can edit only one cell at a time!");\r
+ \r
+ return cells.iterator().next().getPropertyValue(graph, SHEET.cellEditor);\r
+ }\r
+\r
+ @Override\r
+ public void copy(final Transaction<Write> transaction, final String location, final MutableVariant variant, Consumer<?> callback) {\r
+\r
+ SpreadsheetUtils.schedule(transaction, new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+\r
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+ Variable variable = sheet.getPossibleChild(graph, location);\r
+ if(variable != null) {\r
+ CellEditor<Write> editor = variable.getPossiblePropertyValue(graph, SHEET.cellEditor);\r
+ if(editor != null) {\r
+ editor.copy(transaction, location, variant, null);\r
+ }\r
+ }\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+ \r
+ };\r
+ \r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")\r
+ public static CellEditor<Write> variableCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {\r
+\r
+ final Variable cell = context_.getParent(graph);\r
+ \r
+ return new GraphCellEditorAdapter(cell) {\r
+\r
+ @Override\r
+ public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, String property, T value, Binding binding) throws DatabaseException {\r
+ cell.setPropertyValue(graph, property, value, binding);\r
+ }\r
+ };\r
+ }\r
+ \r
+ private static int encodeLineOrNode(ReadGraph graph, Resource r) throws DatabaseException {\r
+ if(r == null) return 0;\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ String name = graph.getRelatedValue(r, L0.HasName, Bindings.STRING);\r
+ if(name.charAt(0) == 'R') {\r
+ return -Integer.parseInt(name.substring(3));\r
+ } else {\r
+ return Integer.parseInt(name);\r
+ }\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
+ public static int[] lineNodeKeys(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {\r
+\r
+ Resource node = context_.getParent(graph).getRepresents(graph);\r
+ BTreeContentBean bean = BTreeContentBean.readPossible(graph, node);\r
+ if(bean == null) return new int[0];\r
+ // There are n keys and n+1 resources\r
+ int[] result = new int[2*bean.n+1];\r
+ for(int i=0;i<bean.n;i++) {\r
+ result[2*i] = encodeLineOrNode(graph, bean.getChild(i));\r
+ result[2*i+1] = (int)bean.getKey(i).getValue();\r
+ }\r
+ result[2*bean.n] = encodeLineOrNode(graph, bean.getChild(bean.n));\r
+ return result;\r
+ \r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> LineContentBean")\r
+ public static LineContentBean defaultLineCells(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {\r
+ \r
+ String contextUri = context_.getURI(graph);\r
+ \r
+ Variable line = context_.getParent(graph);\r
+ \r
+ Collection<Variable> children = line.getChildren(graph);\r
+ ObjectArrayList<LineContentBeanCell> result = new ObjectArrayList<>();\r
+ SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);\r
+ for (Variable child : children) {\r
+ Resource repr = child.getRepresents(graph);\r
+ \r
+ Resource style = graph.getPossibleObject(repr, SR.Cell_HasStyle);\r
+ Integer styleId = null;\r
+ if (style != null)\r
+ styleId = graph.getPossibleRelatedValue(style, SR.Style_id, Bindings.INTEGER);\r
+ if (styleId == null) {\r
+ System.err.println("Style " + style + " has no ID or either cell "+ repr + " has no style attached to it !!");\r
+ styleId = SpreadsheetStyle.empty().getStyleId();\r
+ }\r
+\r
+ LineContentBeanCell cell = new LineContentBeanCell(styleId);\r
+ \r
+ Variant variant = child.getPossiblePropertyValue(graph, SR.Cell_content);\r
+ \r
+ if(variant != null) {\r
+ \r
+ Variable var = child.getPossibleProperty(graph, SR.Cell_content);\r
+ String expression = var.getPossiblePropertyValue(graph, "expression");\r
+ if (expression != null) {\r
+ cell.setContent(new Variant(SpreadsheetSCLConstant.BINDING, new SpreadsheetSCLConstant(expression, variant.getValue())));\r
+ } else {\r
+ cell.setContent(variant);\r
+ }\r
+ Range r = SpreadsheetUtils.decodeCellAbsolute(child.getName(graph));\r
+// result.add(cell);\r
+ while(result.size() < r.startColumn + 1)\r
+ result.add(new LineContentBeanCell());\r
+ result.set(r.startColumn, cell);\r
+ \r
+ }\r
+\r
+ }\r
+ LineContentBean bean = new LineContentBean();\r
+ bean.cells = result.toArray(new LineContentBeanCell[result.size()]);\r
+ return bean;\r
+ \r
+ }\r
+ \r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")\r
+ public static CellEditor<Write> textCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {\r
+\r
+ System.out.println("Context URI : " + context_.getURI(graph));\r
+ Variable cells = context_.getParent(graph);\r
+ System.out.println("Cell URI : " + cells.getURI(graph));\r
+ \r
+ return new GraphCellEditorAdapter(cells) {\r
+\r
+ public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, String property, T value, Binding binding) throws DatabaseException {\r
+ \r
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+ if(ClientModel.CONTENT.equals(property)) {\r
+ cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);\r
+ Variable runCell = null;\r
+ Object transactionContext = transaction.getContext();\r
+ if (transactionContext != null && transactionContext instanceof Variable) {\r
+ Variable varContext = (Variable) transactionContext;\r
+ Variable context = Variables.getContext(graph, varContext);\r
+ try {\r
+ runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);\r
+ } catch (MissingVariableException e) {\r
+ // Creating new cell, need synchronizing\r
+ transaction.needSynchronization(cell.getParent(graph));\r
+ }\r
+ }\r
+ if (runCell != null)\r
+ runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);\r
+ } else if(ClientModel.CONTENT_EXPRESSION.equals(property)) {\r
+ cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.STRING);\r
+ Variable runCell = null;\r
+ Object transactionContext = transaction.getContext();\r
+ if (transactionContext != null && transactionContext instanceof Variable) {\r
+ Variable varContext = (Variable) transactionContext;\r
+ Variable context = Variables.getContext(graph, varContext);\r
+ try {\r
+ runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);\r
+ } catch (MissingVariableException e) {\r
+ //Creating new cell, need synchronizing\r
+ transaction.needSynchronization(cell.getParent(graph));\r
+ }\r
+ }\r
+ if (runCell != null)\r
+ runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.STRING);\r
+ } else if(ClientModel.BORDER.equals(property)) {\r
+ Resource textCell = cell.getRepresents(graph);\r
+ Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);\r
+ SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);\r
+ builder.border((Integer)value);\r
+ finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);\r
+ } else if(ClientModel.ALIGN.equals(property)) {\r
+ Resource textCell = cell.getRepresents(graph);\r
+ Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);\r
+ SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);\r
+ builder.align((Integer)value);\r
+ finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);\r
+ } else if(ClientModel.LOCKED.equals(property)) {\r
+ cell.setPropertyValue(graph, SHEET.Cell_locked, value, Bindings.BOOLEAN); \r
+ } else if(ClientModel.ROW_SPAN.equals(property)) {\r
+ cell.setPropertyValue(graph, SHEET.Cell_rowSpan, value, Bindings.INTEGER);\r
+ } else if(ClientModel.COLUMN_SPAN.equals(property)) {\r
+ cell.setPropertyValue(graph, SHEET.Cell_columnSpan, value, Bindings.INTEGER);\r
+ } else if(ClientModel.FONT.equals(property)) {\r
+ Resource textCell = cell.getRepresents(graph);\r
+ Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);\r
+ SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);\r
+ builder.font((Font)value);\r
+ finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);\r
+ } else if(ClientModel.FOREGROUND.equals(property)) {\r
+ Resource textCell = cell.getRepresents(graph);\r
+ Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);\r
+ SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);\r
+ builder.foreground((RGB.Integer)value);\r
+ finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);\r
+ } else if(ClientModel.BACKGROUND.equals(property)) {\r
+ Resource textCell = cell.getRepresents(graph);\r
+ Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);\r
+ SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);\r
+ builder.background((RGB.Integer)value);\r
+ finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);\r
+ }\r
+ }\r
+ \r
+ private void finishStyleUpdate(WriteGraph graph, SpreadsheetResource SHEET, Resource styleContainer, Resource textCell, SpreadsheetStyleBuilder builder, Transaction<?> transaction) throws DatabaseException {\r
+ \r
+ Variable bookVariable = Variables.getContext(graph, cell);\r
+ Resource book = bookVariable.getRepresents(graph);\r
+ Resource createdStyle = null;\r
+ \r
+ SpreadsheetStyle style = builder.build();\r
+ int styleId = style.getStyleId();\r
+\r
+ Collection<Resource> existingStyles = graph.syncRequest(new ObjectsWithType(book, Layer0.getInstance(graph).ConsistsOf, SHEET.Style));\r
+ for (Resource eStyle : existingStyles) {\r
+ int eStyleId = graph.getRelatedValue2(eStyle, SHEET.Style_id, Bindings.INTEGER);\r
+ if (eStyleId == styleId) {\r
+ createdStyle = eStyle;\r
+ break;\r
+ }\r
+ }\r
+ if (createdStyle == null) {\r
+ style = builder.name("Style_" + existingStyles.size()).build();\r
+ createdStyle = SpreadsheetGraphUtils.createStyle(graph, book, style);\r
+ }\r
+ \r
+ graph.deny(textCell, SHEET.Cell_HasStyle);\r
+ Collection<Resource> cellsOfStyle = graph.getObjects(styleContainer, SHEET.Cell_StyleOf);\r
+ if (cellsOfStyle.isEmpty()) {\r
+ graph.deny(styleContainer);\r
+ }\r
+ graph.claim(textCell, SHEET.Cell_HasStyle, createdStyle);\r
+ \r
+// Variable runCell = null;\r
+// Object transactionContext = transaction.getContext();\r
+// if (transactionContext != null && transactionContext instanceof Variable) {\r
+// Variable varContext = (Variable) transactionContext;\r
+// Variable context = Variables.getContext(graph, varContext);\r
+// try {\r
+// runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);\r
+// } catch (MissingVariableException e) {\r
+// //Creating new cell, need synchronizing\r
+// transaction.needSynchronization(cell.getParent(graph));\r
+// }\r
+// }\r
+// if (runCell != null) {\r
+// Datatype type = new RecordType();\r
+// Binding b = Bindings.getBinding(type);\r
+// runCell.setPropertyValue(graph, SHEET.Cell_style, style, b);\r
+// }\r
+ }\r
+\r
+ private SpreadsheetStyleBuilder computeStyleBuilder(SpreadsheetResource SHEET, WriteGraph graph, Resource styleContainer) throws DatabaseException {\r
+ RGB.Integer foreground = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_foreground, RGB.Integer.BINDING);\r
+ RGB.Integer background = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_background, RGB.Integer.BINDING);\r
+ Font font = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_font, Font.BINDING);\r
+ Integer align = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_align, Bindings.INTEGER);\r
+ Integer border = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_border, Bindings.INTEGER);\r
+ \r
+ return SpreadsheetStyle.newInstace().foreground(foreground).background(background).font(font).align(align).border(border);\r
+ }\r
+\r
+ @Override\r
+ public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, Variant value) throws DatabaseException {\r
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+ \r
+ // Handle possible deletes\r
+ if (value == null)\r
+ value = Variant.ofInstance("");\r
+ \r
+ if (!transaction.isOperationMode()) {\r
+ cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);\r
+// return;\r
+ }\r
+ Variable runCell = null;\r
+ Object transactionContext = transaction.getContext();\r
+ if (transactionContext != null && transactionContext instanceof Variable) {\r
+ Variable varContext = (Variable) transactionContext;\r
+ Variable context = Variables.getContext(graph, varContext);\r
+ try {\r
+ runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);\r
+ } catch (MissingVariableException e) {\r
+ // Creating cell for the first time so no runCell available at this time, needs synchronization\r
+ transaction.needSynchronization(cell.getParent(graph));\r
+ }\r
+ \r
+ }\r
+\r
+ if (runCell != null) {\r
+ System.out.println("All.edit " + runCell.getURI(graph));\r
+ runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public <T> void copy(WriteGraph graph, Transaction<Write> transaction, String location, MutableVariant variant) throws DatabaseException {\r
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+ \r
+ Variable runCell = null;\r
+ Object transactionContext = transaction.getContext();\r
+ if (transactionContext != null && transactionContext instanceof Variable) {\r
+ Variable varContext = (Variable) transactionContext;\r
+ Variable context = Variables.getContext(graph, varContext);\r
+ runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);\r
+ }\r
+ \r
+ //Variant content = cell.getPropertyValue(graph, SHEET.Cell_content, Bindings.VARIANT);\r
+ Object object = cell.getPropertyValue(graph, SHEET.Cell_content);\r
+ Variant content = null;\r
+ if (object instanceof Variant) {\r
+ content = (Variant)object;\r
+ } else if (object instanceof Double) {\r
+ content = Variant.ofInstance((Double)object);\r
+ } else if (object instanceof Float) {\r
+ content = Variant.ofInstance((Float)object);\r
+ } else if (object instanceof Integer) {\r
+ content = Variant.ofInstance((Integer)object);\r
+ } else if (object instanceof Long) {\r
+ content = Variant.ofInstance((Long)object);\r
+ } else if (object instanceof String) {\r
+ content = Variant.ofInstance((String)object);\r
+ } else if (object instanceof Variable) {\r
+ content = Variant.ofInstance((Variable)object);\r
+ } else {\r
+ throw new DatabaseException("");\r
+ }\r
+ variant.setValue(content);\r
+ }\r
+ \r
+ };\r
+ \r
+ }\r
+ \r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")\r
+ public static Variable spreadsheetInput(ReadGraph graph, Resource converter, Variable sheet) throws DatabaseException {\r
+ return ProxyVariables.inputVariable(graph, sheet);\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")\r
+ public static Variable spreadsheetSession(ReadGraph graph, Resource converter, Variable sheet) throws DatabaseException {\r
+ return ProxyVariables.proxySessionVariable(graph, sheet);\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")\r
+ public static Variable spreadsheetRunInput(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {\r
+ Resource model = Variables.getModel(graph, property);\r
+ Variable activeRun = graph.syncRequest(new PossibleActiveRun(model));\r
+ if(activeRun != null) return activeRun;\r
+ return Variables.getConfigurationContext(graph, model);\r
+ }\r
+ \r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
+ public static Object sclValue(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {\r
+ return CompileSCLValueRequest.compileAndEvaluate(graph, context);\r
+ }\r
+\r
+}
\ No newline at end of file