/// <summary> /// Recalculate a cell's value from it's formula /// </summary> private ResultSet RefreshCell(int x, int y, bool formulaChanged) { var gc = bigGrid1.Items[x, y] as GridCell ?? new GridCell(); var rs = new ResultSet {Result = gc.Value}; if (formulaChanged) {// Clear out old refs and add new ones: rs = RecalculateFromCell(x, y); var data = new SheetDataTableAdapters.DependsAdapter(); ulong key = bigGrid1.Items.GetUniqueKey(x, y); data.ClearDependenciesForHash((long)key); foreach (var refr in rs.References) { data.AddDependency((long)key, (long)bigGrid1.Items.GetUniqueKey(refr.X, refr.Y)); } UpdateCell(gc, x, y); return rs; } Stack<string> rpn = null; try { rpn = calculator.InfixToPostfix(gc.Formula ?? ""); } catch (Exception ex) { gc.Value = "Formula Error: " + ex.Message; } if (rpn != null && rpn.Count > 0) { // formula is non-empty try { rs = calculator.EvaluatePostfix(rpn, y, x); gc.Value = rs.Result; } catch (Exception ex) { gc.Value = "Calculation Error: " + ex.Message; } } UpdateCell(gc,x,y); return rs; }
/// <summary> /// Recalculate dependent cell's values /// </summary> private ResultSet RecalculateFromCell(int x, int y) { // TODO: self-reference protection! ulong key = bigGrid1.Items.GetUniqueKey(x, y); // First, get our own values: ResultSet rs = RefreshCell(x, y, false); var adapter = new SheetDataTableAdapters.DependsAdapter(); foreach (var dep_row in adapter.GetDependsOf((long)key)) { if (dep_row.Depends != ((long)key)) throw new Exception("Nasty mismatch in dependency table"); int[] coords = bigGrid1.Items.HashToIndex((ulong)dep_row.Hash); RecalculateFromCell(coords[0], coords[1]); } return rs; }