X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.spreadsheet.graph%2Fsrc%2Forg%2Fsimantics%2Fspreadsheet%2Fgraph%2FSpreadsheetNodeManager.java;h=64d002f831d81c7198406b877ef21b7cb46cd3e9;hb=e5871be84f8ba53a1c80be728bcfb67231c29279;hp=416cc19269a7ceff31146ce943dc3ac5628af3b1;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetNodeManager.java b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetNodeManager.java index 416cc1926..64d002f83 100644 --- a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetNodeManager.java +++ b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetNodeManager.java @@ -1,47 +1,131 @@ -package org.simantics.spreadsheet.graph; - -import java.util.Collections; -import java.util.Set; - -import org.simantics.db.layer0.StandardNodeManager; -import org.simantics.layer0.Layer0; -import org.simantics.simulator.variable.exceptions.NodeManagerException; -import org.simantics.spreadsheet.resource.SpreadsheetResource; -import org.simantics.structural.stubs.StructuralResource2; - -@SuppressWarnings("rawtypes") -public class SpreadsheetNodeManager extends StandardNodeManager { - - public SpreadsheetNodeManager(SpreadsheetRealm realm) { - super(realm, realm.getEngine()); - } - - static final Set COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component); - - @Override - public Set getClassifications(SheetNode node) throws NodeManagerException { - checkThreadAccess(); - if(isRoot(node)) - return COMPONENT_CLASS; - else - return Collections.emptySet(); - } - - @Override - public String getPropertyURI(SheetNode parent, SheetNode property) { - if(property instanceof SpreadsheetCellContent) { - return SpreadsheetResource.URIs.Cell_content; - } else if(property instanceof SpreadsheetTypeNode) { - return Layer0.URIs.typeURI; - } else if(property instanceof SpreadsheetCellContentExpression) { - return Layer0.URIs.SCLValue_expression; - } else if (property instanceof SpreadsheetCellStyle) { - return SpreadsheetResource.URIs.Cell_style; - } else if (property instanceof SpreadsheetCellEditable){ - return SpreadsheetResource.URIs.Cell_editable; - } else { - return null; - } - } - -} +package org.simantics.spreadsheet.graph; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.layer0.Layer0; +import org.simantics.simulator.toolkit.db.StandardVariableNodeManager; +import org.simantics.simulator.variable.exceptions.NodeManagerException; +import org.simantics.spreadsheet.SpreadsheetCellStyle; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.spreadsheet.solver.SheetNode; +import org.simantics.spreadsheet.solver.SpreadsheetBook; +import org.simantics.spreadsheet.solver.SpreadsheetBook.SpreadsheetBookListener; +import org.simantics.spreadsheet.solver.SpreadsheetCell; +import org.simantics.spreadsheet.solver.SpreadsheetCellContent; +import org.simantics.spreadsheet.solver.SpreadsheetCellContentExpression; +import org.simantics.spreadsheet.solver.SpreadsheetCellEditable; +import org.simantics.spreadsheet.solver.SpreadsheetFormula; +import org.simantics.spreadsheet.solver.SpreadsheetSCLConstant; +import org.simantics.spreadsheet.solver.SpreadsheetTypeNode; +import org.simantics.structural.stubs.StructuralResource2; + +@SuppressWarnings("rawtypes") +public class SpreadsheetNodeManager extends StandardVariableNodeManager { + + public SpreadsheetNodeManager(SpreadsheetRealm realm) { + super(realm, realm.getEngine()); + realm.getEngine().registerListener(new SpreadsheetBookListener() { + + @Override + public void cellsChanged(Collection cells) { + realm.asyncExec(new Runnable() { + @Override + public void run() { + for(SpreadsheetCell cell : cells) { + refreshVariable(new SpreadsheetCellContent(cell)); + Object content = cell.getContent(); + if(content instanceof SpreadsheetFormula || content instanceof SpreadsheetSCLConstant) + refreshVariable(new SpreadsheetCellContentExpression(cell)); + } + } + }); + } + }); + } + + static final Set COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component); + + @Override + public Set getClassifications(SheetNode node) throws NodeManagerException { + checkThreadAccess(); + if(isRoot(node)) + return COMPONENT_CLASS; + else + return Collections.emptySet(); + } + + @Override + public String getPropertyURI(SheetNode parent, SheetNode property) { + if(property instanceof SpreadsheetCellContent) { + return SpreadsheetResource.URIs.Cell_content; + } else if(property instanceof SpreadsheetTypeNode) { + return Layer0.URIs.typeURI; + } else if(property instanceof SpreadsheetCellContentExpression) { + return Layer0.URIs.SCLValue_expression; + } else if (property instanceof SpreadsheetCellStyle) { + return SpreadsheetResource.URIs.Cell_style; + } else if (property instanceof SpreadsheetCellEditable){ + return SpreadsheetResource.URIs.Cell_editable; + } else { + return null; + } + } + + //Custom setValue logic for SpreadsheetNodeManager - calls the setValueAndFireSelectedListeners + @Override + public void setValue(SheetNode node, Object value, Binding binding) throws NodeManagerException { + Set dirtyNodeContents = findDirtyNodeContents(node); + super.setValueAndFireSelectedListeners(node, value, binding, dirtyNodeContents); + if(value instanceof SpreadsheetFormula) { + SpreadsheetCellContent scc = (SpreadsheetCellContent)node; + SpreadsheetCellContentExpression scce = new SpreadsheetCellContentExpression(scc.cell); + // We need to also refresh the expression variable in this case + refreshVariable(scce); + } + } + + //Find the cells that are used by this cell and their SpreadsheetContents, so that they can be marked as dirty later + public Set findDirtyNodeContents(SheetNode node){ + Set dirty = new HashSet<>(); + + SpreadsheetCell sscell = null; + if(node instanceof SpreadsheetCell) { + sscell = (SpreadsheetCell)node; + } else if (node instanceof SpreadsheetCellContent) { + sscell = ((SpreadsheetCellContent)node).cell; + } + + if(sscell != null) { + Set result = ((SpreadsheetRealm)super.getRealm()).getEngine().invalidate(sscell); + dirty.addAll(result); + } + + Set dirtyNodeContents = new HashSet<>(); + for(SheetNode cell : dirty) { + Map properties = cell.getProperties(); + dirtyNodeContents.add((SpreadsheetCellContent)properties.get("content")); + } + + return dirtyNodeContents; + } + + + @Override + protected Variant getEngineVariantOrCached(SheetNode node) throws NodeManagerException { + Variant variant = valueCache.get(node); + if(variant == null) { + Object value = realm.getEngine().getEngineValue(node); + Binding binding = realm.getEngine().getEngineBinding(node); + variant = new Variant(binding, value); + valueCache.put(node, variant); + } + return variant; + } + +}