+ public static Variant extRefActiveVariable(ReadGraph graph, Variable var) throws DatabaseException {
+ return new Variant(Bindings.VOID, new ExternalRefActiveVariable(graph, var));
+ }
+
+ static class ExternalRefActiveVariable implements ExternalRef {
+
+ final private String uri;
+
+ public ExternalRefActiveVariable(ReadGraph graph, Variable variable) throws DatabaseException {
+ this.uri = variable.getURI(graph);
+ }
+
+ @Override
+ public void listen(Object context, ExternalRefListener listener) {
+ Simantics.getSession().asyncRequest(new BinaryRead<String, String, Variant>((String)context, uri) {
+
+ @Override
+ public Variant perform(ReadGraph graph) throws DatabaseException {
+ Variable contextVariable = Variables.getVariable(graph, parameter);
+ Variable configVariable = Variables.getVariable(graph, parameter2);
+ Variable activeVariable = Variables.switchPossibleContext(graph, configVariable, contextVariable.getRepresents(graph));
+ if(activeVariable == null) return Variant.ofInstance("Could not resolve " + configVariable.getURI(graph) + " for " + contextVariable.getURI(graph));
+ return activeVariable.getVariantValue(graph);
+ }
+ }, new Listener<Variant>() {
+
+ @Override
+ public void execute(Variant result) {
+ listener.newValue(result);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Error while evaluating variable value, context = " + context + " uri=" + uri, t);
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return listener.isDisposed();
+ }
+
+ });
+ }
+
+ @Override
+ public void modify(Object context, Variant newValue) {
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ Variable contextVariable = Variables.getVariable(graph, (String)context);
+ Variable configVariable = Variables.getVariable(graph,uri);
+ Variable activeVariable = Variables.switchPossibleContext(graph, configVariable, contextVariable.getRepresents(graph));
+ if(activeVariable == null) return;
+ activeVariable.setValue(graph, newValue.getValue(), newValue.getBinding());
+ }
+ });
+
+ }
+
+ }
+
+ public static CellEditor cellEditor(ReadGraph graph, Resource sheet) throws DatabaseException {
+ SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
+ Variable sheetVariable = Variables.getVariable(graph, sheet);
+ return sheetVariable.getPropertyValue(graph, SHEET.cellEditor);
+ }
+
+ public static final String SPREADSHEET_TRANSACTION = "spreadsheetTransaction";
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static Object syncExec(CellEditor editor, OperationMode mode, Function fun) throws InterruptedException {
+
+ Transaction tr = editor.startTransaction(mode);
+
+ SCLContext context = SCLContext.getCurrent();
+ Transaction oldTransaction = (Transaction)context.put(SPREADSHEET_TRANSACTION, tr);
+
+ Object result = null;
+
+ try {
+
+ result = fun.apply(Tuple0.INSTANCE);
+
+ } finally {
+
+ tr.commit();
+
+ context.put(SPREADSHEET_TRANSACTION, oldTransaction);
+
+ }
+
+ return result;
+
+ }
+
+ public static int cellColumn(ReadGraph graph, Variable cell) {
+ if(cell instanceof StandardGraphChildVariable) {
+ StandardGraphChildVariable sgcv = (StandardGraphChildVariable)cell;
+ SpreadsheetCell sc = (SpreadsheetCell)sgcv.node.node;
+ return sc.getColumn();
+ }
+ throw new IllegalStateException("Expected StandardGraphChildVariable, got " + cell.getClass().getName());
+ }
+
+ private static SpreadsheetCell getCellFromVariable(Variable cell) {
+ StandardGraphChildVariable std = (StandardGraphChildVariable)cell;
+ return (SpreadsheetCell)std.node.node;
+ }
+
+ private static SpreadsheetLine getLineFromVariable(Variable cell) {
+ StandardGraphChildVariable std = (StandardGraphChildVariable)cell;
+ return (SpreadsheetLine)std.node.node;
+ }
+
+ public static Variable linesVariable(ReadGraph graph, Variable sheetVariable) throws DatabaseException {
+ while(!"Lines".equals(sheetVariable.getName(graph)))
+ sheetVariable = sheetVariable.getParent(graph);
+ return sheetVariable;
+ }
+
+ public static Variable offsetCell(ReadGraph graph, Variable cellVariable, int x, int y) throws DatabaseException {
+
+ Variable lineVariable = cellVariable.getParent(graph);
+ Variable offsetLine = offsetRow(graph, lineVariable, y);
+ if(offsetLine == null) return null;
+ SpreadsheetCell cell = getCellFromVariable(cellVariable);
+ return rowCell(graph, offsetLine, cell.column + x);
+
+ }
+
+ public static Variable offsetRow(ReadGraph graph, Variable lineVariable, int offset) throws DatabaseException {
+
+ if(offset == 0) return lineVariable;
+
+ SpreadsheetLine line = getLineFromVariable(lineVariable);
+ SpreadsheetLine offsetLine = line.possibleOffset(offset);
+ if(offsetLine == null) return null;
+
+ Variable linesVariable = linesVariable(graph, lineVariable);
+ String path = offsetLine.getLinesPath();
+ return linesVariable.browsePossible(graph, path);
+
+ }
+
+ public static Variable rowCell(ReadGraph graph, Variable lineVariable, int column) throws DatabaseException {
+
+ SpreadsheetLine line = getLineFromVariable(lineVariable);
+
+ return lineVariable.getPossibleChild(graph, Spreadsheets.cellName(line.row, column));
+
+ }
+
+ public static SpreadsheetBook spreadsheetBook(Variable variable) {
+ if(variable instanceof StandardGraphChildVariable) {
+ VariableNode<?> node = ((StandardGraphChildVariable)variable).node;
+ if(node != null) {
+ if(node.node instanceof SpreadsheetBook)
+ return (SpreadsheetBook) node.node;
+ }
+ }
+ return null;
+ }
+