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