package org.simantics.spreadsheet.graph.function; import java.util.ArrayList; import java.util.Collection; import org.simantics.databoard.Bindings; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.ConstantChildVariable; import org.simantics.db.layer0.variable.ConstantPropertyVariable; import org.simantics.db.layer0.variable.ConstantPropertyVariableBuilder; import org.simantics.db.layer0.variable.ProxyChildVariable; import org.simantics.db.layer0.variable.StandardGraphChildVariable; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.VariableNode; import org.simantics.db.layer0.variable.Variables; import org.simantics.spreadsheet.Range; import org.simantics.spreadsheet.SheetVariables; import org.simantics.spreadsheet.Spreadsheets; import org.simantics.spreadsheet.common.matrix.VariantMatrix; import org.simantics.spreadsheet.graph.Ranges; import org.simantics.spreadsheet.resource.SpreadsheetResource; import org.simantics.spreadsheet.util.SpreadsheetUtils; public class SpreadsheetRootVariable extends StandardGraphChildVariable { public SpreadsheetRootVariable(Variable parent, VariableNode node, Resource resource) { super(parent, node, resource); } @Override public String getName(ReadGraph graph) throws DatabaseException { return ProxyChildVariable.CONTEXT_END; } @SuppressWarnings("deprecation") @Override public Variable getNameVariable(ReadGraph graph) throws DatabaseException { return new ConstantPropertyVariable(this, Variables.NAME, ProxyChildVariable.CONTEXT_END, Bindings.STRING); } @Override public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException { Variable var = super.getPossibleChild(graph, name); if(var == null) var = getPossibleRangeChild(graph, this, name); if(var == null) var = getPossibleDeepChild(graph, this, name); return var; } private Variable getPossibleDeepChild(ReadGraph graph, Variable context, String name) throws DatabaseException { SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph); for(Variable range : graph.syncRequest(new Ranges(context), TransientCacheListener.>instance())) { String location = range.getPropertyValue(graph, SHEET.Range_location, Bindings.STRING); Integer widthBound = range.getPropertyValue(graph, SHEET.Range_widthBound, Bindings.INTEGER); Integer heightBound = range.getPropertyValue(graph, SHEET.Range_heightBound, Bindings.INTEGER); if(SpreadsheetUtils.isInBounds(location, name, widthBound, heightBound)) { Variable cell = range.getPossibleChild(graph, name); if(cell != null) return cell; } } return null; } private Variable getPossibleRangeChild(ReadGraph graph, Variable context, String name) throws DatabaseException { final String[] propertyNames = { SheetVariables.CONTENT, SheetVariables.RANGE_CELL_NAMES, Variables.LABEL, "immutable" }; final Binding[] bindings = { Bindings.VARIANT, null, Bindings.STRING, Bindings.BOOLEAN}; if(name.contains(":")) { Range range = Spreadsheets.decodeRange(name, 0, 0); VariantMatrix matrix = new VariantMatrix(range.height(),range.width()); String rangeNames[][] = new String[range.height()][range.width()]; for(int x=range.startColumn;x<=range.endColumn;x++) { for(int y=range.startRow;y<=range.endRow;y++) { String location = Spreadsheets.cellName(y,x); Variable child = context.getPossibleChild(graph, location); Variant value = null; if(child != null) value = child.getPossiblePropertyValue(graph, SheetVariables.CONTENT, Bindings.VARIANT); matrix.set(y-range.startRow, x-range.startColumn, value); rangeNames[y-range.startRow][x-range.startColumn] = location; } } Object[] values = new Object[] { Variant.ofInstance(matrix), rangeNames, null, name, Boolean.FALSE }; ArrayList list = new ArrayList(); for(int i = 0; i < propertyNames.length; i++) { list.add(new ConstantPropertyVariableBuilder(propertyNames[i], values[i], bindings[i])); } return new ConstantChildVariable(context, name, list); } else { return null; } } }