From: Miro Richard Eklund Date: Wed, 25 Jul 2018 09:33:33 +0000 (+0300) Subject: Spreadsheet updates cell values properly X-Git-Tag: v1.43.0~136^2~437 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=5915c1bbd6d0c6125aa3c815c7843339190f28e4 Spreadsheet updates cell values properly Cells referencing other cells weren't updated after change "8c8283a01e63980527d605936286747006bea601" (see in History view), in StandardNodeManager.java. I added a new setValue function that takes a list of Nodes that need to be updated (removes them from valueCache), which allows only specific cells to be updated when another cell is updated. I also removed invalidation code from Spreadsheet's "All.java" class and added them to the value updated in SpreadsheetNodeManager, which invalidates recursively the cells the use another cell. I also made sure that SpreadsheetCells jave the same properties through their life-cycle, rather than creating a properties map whenever the properties are called. gitlab #48 gitlab #54 gitlab #55 Change-Id: I125f644e014310937ed7697e9f44ec33825f9b0f --- diff --git a/bundles/org.simantics.simulator.toolkit/src/org/simantics/simulator/toolkit/StandardNodeManager.java b/bundles/org.simantics.simulator.toolkit/src/org/simantics/simulator/toolkit/StandardNodeManager.java index 8f1d1cf53..8a51fd330 100644 --- a/bundles/org.simantics.simulator.toolkit/src/org/simantics/simulator/toolkit/StandardNodeManager.java +++ b/bundles/org.simantics.simulator.toolkit/src/org/simantics/simulator/toolkit/StandardNodeManager.java @@ -322,6 +322,23 @@ public abstract class StandardNodeManager references) throws NodeManagerException { + if(references.size() > 0) { + for(Node n : references) { + valueCache.remove(n); + } + } + updateValueInner(node, value, binding); + fireNodeListenersSync(); + } + + //Update the value of the node helper method + private void updateValueInner(Node node, Object value, Binding binding) throws NodeManagerException { checkThreadAccess(); Binding targetBinding = realm.getEngine().getEngineBinding(node); if(binding.equals(targetBinding)) { @@ -341,7 +358,6 @@ public abstract class StandardNodeManager, S v.visit(this); } - public List invalidate(SpreadsheetCell cell) { + //Recursively find all SpreadsheetCells, invalidate them and return them all as a set + public Set invalidate(SpreadsheetCell cell) { + Set result = new HashSet<>(); + result.add(cell); + cell.invalidate(); + long refKey = cell.makeReferenceKey(); + AbstractLongSet refs = referenceMap.remove(refKey); + if(refs == null) return result; + for(long ref : refs) { + long sheet = ref >> 40; + long row = (ref >> 20) & 0xFFFFF; + long col = (ref) & 0xFFFFF; + SpreadsheetCell referer = get(sheets.get((int)sheet), (int)row, (int)col); + result.addAll(invalidate(referer)); + } + return result; + } + + @Deprecated + public List invalidateShallow(SpreadsheetCell cell) { ArrayList result = new ArrayList<>(); result.add(cell); cell.invalidate(); diff --git a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetCell.java b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetCell.java index b4e83ede1..0ee66cf07 100644 --- a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetCell.java +++ b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetCell.java @@ -31,12 +31,24 @@ public class SpreadsheetCell implements SpreadsheetElement, SheetNode { final private int column; int style; Object content; + final private Map properties; public SpreadsheetCell(SpreadsheetLine line, int column) { + this.properties = createProperties(); this.line = line; this.column = column; } + //All SpreadsheetCells have these properties - create them when object is created + private Map createProperties() { + Map p = new HashMap<>(); + p.put("typeURI", new SpreadsheetTypeNode(SpreadsheetResource.URIs.Cell)); + p.put("content", new SpreadsheetCellContent(this)); + p.put("style", new SpreadsheetCellStyle(this)); + p.put("editable", new SpreadsheetCellEditable(this)); + return p; + } + public boolean hasExpression() { return content instanceof SpreadsheetFormula || content instanceof SpreadsheetSCLConstant; } @@ -66,16 +78,9 @@ public class SpreadsheetCell implements SpreadsheetElement, SheetNode { @Override public Map getProperties() { - Map properties = new HashMap<>(); - if (GraphUI.DEBUG) System.out.println("SpreadsheetCell.getProperties: " + this + " " + content + " " + style); - - properties.put("typeURI", new SpreadsheetTypeNode(SpreadsheetResource.URIs.Cell)); - properties.put("content", new SpreadsheetCellContent(this)); - properties.put("style", new SpreadsheetCellStyle(this)); - properties.put("editable", new SpreadsheetCellEditable(this)); - return properties; + return properties; //Return this SpreadsheetCells's properties, rather than a new HashMap } public SpreadsheetBook getBook() { 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 56985d16c..caa6dc23f 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,8 +1,11 @@ package org.simantics.spreadsheet.graph; 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.layer0.Layer0; import org.simantics.simulator.toolkit.StandardNodeManager; import org.simantics.simulator.variable.exceptions.NodeManagerException; @@ -43,5 +46,36 @@ public class SpreadsheetNodeManager extends StandardNodeManager dirtyNodeContents = findDirtyNodeContents(node); + super.setValueAndFireSelectedListeners(node, value, binding, dirtyNodeContents); + } + + //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; + } } diff --git a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/All.java b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/All.java index 39e5778f9..98ef90231 100644 --- a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/All.java +++ b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/All.java @@ -200,7 +200,7 @@ public class All { SpreadsheetCell sc = book.get(sheet.getName(graph), r.startRow, r.startColumn); sc.setContent(value); // book.accept(new InvalidateAll()); - List changed = book.invalidate(sc); +// List changed = book.invalidate(sc); //Invalidation handled by SpreadsheetNodeManager realm.asyncExec(new Runnable() { @Override diff --git a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SelectionListener.java b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SelectionListener.java index d2eece5bd..8a8da732b 100644 --- a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SelectionListener.java +++ b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SelectionListener.java @@ -62,7 +62,16 @@ public class SelectionListener implements ListSelectionListener { final Object cell = table.getValueAt(selectedRows[0], selectedColumns[0]); if(cell != null) { - String expression = clientModel.getPossiblePropertyAt(SpreadsheetUtils.cellName(selectedRows[0], selectedColumns[0]), ClientModel.CONTENT_EXPRESSION); + + String expression = ""; + + Object expressionO = clientModel.getPossiblePropertyAt(SpreadsheetUtils.cellName(selectedRows[0], selectedColumns[0]), ClientModel.CONTENT_EXPRESSION); + if(expressionO instanceof String) { + expression = (String)expressionO; + } else if(expressionO instanceof Variant) { + expression = ((Variant)expressionO).toString(); + } + if(expression == null) { Variant content = SpreadsheetUtils.getSafeClientVariant(clientModel, SpreadsheetUtils.cellName(selectedRows[0], selectedColumns[0]), ClientModel.CONTENT); if(content != null) diff --git a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SpreadsheetModel.java b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SpreadsheetModel.java index 93f455702..5339796bd 100644 --- a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SpreadsheetModel.java +++ b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SpreadsheetModel.java @@ -2,6 +2,7 @@ package org.simantics.spreadsheet.ui; import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Frame; @@ -691,6 +692,9 @@ public class SpreadsheetModel { etl = new ExpressionTextListener(expression, serverInterface.getAdapter(CellEditor.class)); expression.addFocusListener(etl); expression.addKeyListener(etl); + + //Large default size so that the expression field is clearly visible + expression.setPreferredSize(new Dimension(600, 32)); sheets.addItemListener(sheetsListener); diff --git a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/TextTableCellEditor.java b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/TextTableCellEditor.java index 2c84b6ad1..24fade56a 100644 --- a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/TextTableCellEditor.java +++ b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/TextTableCellEditor.java @@ -136,7 +136,14 @@ class TextTableCellEditor extends DefaultCellEditor implements SpreadsheetCellEd String str = (String)getCellEditorValue(); String cellName = SpreadsheetUtils.cellName(row, column); - String expression = clientModel.getPossiblePropertyAt(cellName, ClientModel.CONTENT_EXPRESSION); + Object expressionO = clientModel.getPossiblePropertyAt(cellName, ClientModel.CONTENT_EXPRESSION); + String expression = null; + if(expressionO instanceof String) { + expression = (String)expressionO; + } else if(expressionO instanceof Variant) { + expression = ((Variant)expressionO).getValue().toString(); + } + if(expression == null) { Variant content = SpreadsheetUtils.getSafeClientVariant(clientModel, cellName, ClientModel.CONTENT); if(content != null)