internal void MarkAsDirty(CalcService service, bool recalculateAll = false, bool recursiveToIntersectant = true, bool recursiveToDependency = true, bool recursiveToSharedFormula = true) { if (!this.IsDirty && !this._isProcessingDirty) { int num; int num2; int num3; int num4; bool flag; this._isProcessingDirty = true; if ((this.DirtyItem == null) && !this._isTempNode) { CalcLocalIdentity objA = this.Id as CalcLocalIdentity; if (object.ReferenceEquals(objA, null)) { return; } this.DirtyItem = new DirtyItem(service, this.Source, objA, this); } CalcGraph graph = service.GetCalculationManager(this.Source, null, true).Graph; CalcReferenceHelper.Id2Range(this.Source, this.Id, out num, out num2, out num3, out num4, out flag); CalcRangeIdentity id = this.Id as CalcRangeIdentity; List <CalcNode> searchingDepends = new List <CalcNode>(); List <CalcNode> list2 = new List <CalcNode>(); if (recursiveToIntersectant && !object.ReferenceEquals(id, null)) { List <CalcNode> list3 = new List <CalcNode>(); for (int i = 0; i < num3; i++) { for (int j = 0; j < num4; j++) { CalcNode node = graph.GetNode(new CalcCellIdentity(num + i, num2 + j)); if (!object.ReferenceEquals(node, null) && node.IsDirty) { list2.Add(node); } if ((!object.ReferenceEquals(node, null) && !node._isWattingForProcess) && (!node._isProcessingDirty && !node.IsDirty)) { node._isWattingForProcess = true; list3.Add(node); } } } foreach (CalcNode node2 in list3) { node2.MarkAsDirty(service, recalculateAll, false, true, true); node2._isWattingForProcess = false; } } DirtyItem dependForehand = null; List <CalcNode> pendingDependDirtyNode = new List <CalcNode>(); if ((this.Dependents != null) && (this.Dependents.Count > 0)) { searchingDepends.AddRange(this.Dependents.Values); } List <SharedFormulaDirtyItem> sharedDirtyItmes = new List <SharedFormulaDirtyItem>(); if (flag || !recalculateAll) { foreach (CalcNode node3 in graph.GetAllDependentRangeNodes(num, num2, num3, num4)) { if ((node3 != this) && ((recalculateAll || !graph.IsSharedFormula(node3.Id as CalcRangeIdentity)) || ((node3.Dependents != null) && (node3.Dependents.Count != 0)))) { if (!recalculateAll && recursiveToDependency) { ExpandSharedFormulaDependency(service, graph, list2, sharedDirtyItmes, node3, this.Id as CalcLocalIdentity); } else if (recalculateAll) { list2.Add(node3); } } } if (recursiveToSharedFormula && this._isTempNode) { foreach (CalcNode node4 in graph.GetAllDependentSharedNodes(num, num2, num3, num4)) { list2.Add(node4); } } } if (recursiveToIntersectant) { searchingDepends.AddRange(list2); list2.Clear(); } dependForehand = SerchDependForehand(dependForehand, searchingDepends, list2, pendingDependDirtyNode, sharedDirtyItmes); if (recursiveToSharedFormula && !this._isTempNode) { if (dependForehand != null) { service.InsertToDirtyBefore(this.DirtyItem, dependForehand); } else { service.AddDirtyItem(this.DirtyItem); } } if (recursiveToDependency) { foreach (CalcNode node5 in pendingDependDirtyNode) { node5._isWattingForProcess = true; } foreach (CalcNode node6 in pendingDependDirtyNode) { node6.MarkAsDirty(service, recalculateAll, true, true, true); node6._isWattingForProcess = false; } foreach (SharedFormulaDirtyItem item2 in sharedDirtyItmes) { if (!item2.Node.IsDirty) { service.AddDirtyItem(item2); } List <CalcNode> list6 = new List <CalcNode>(); foreach (CalcLocalIdentity identity3 in item2.DirtySubIds2) { if (!item2.DirtySubIds.Contains(identity3)) { item2.DirtySubIds.Add(identity3); CalcNode item = graph.GetNode(identity3); if (item == null) { item = CreateTempNode(this.Source, identity3); } item._isWattingForProcess = true; list6.Add(item); } } foreach (CalcNode node8 in list6) { node8.MarkAsDirty(service, recalculateAll, true, true, false); node8._isWattingForProcess = false; } } } else if (recalculateAll) { foreach (CalcNode node9 in searchingDepends) { this.SetPredencyItem(service, node9); } foreach (CalcNode node10 in list2) { if (IsContains(node10.Id as CalcLocalIdentity, this.Id as CalcLocalIdentity)) { this.SetPredencyItem(service, node10); } } } this._isProcessingDirty = false; } }
internal bool EvaluateFormula(CalcCalculationManager mgr, DirtyItem dirtyItem) { CalcLocalIdentity id = dirtyItem.Id as CalcLocalIdentity; if (object.ReferenceEquals(id, null)) { return(false); } CalcExpression objA = mgr.GetExpression(id); if (object.ReferenceEquals(objA, null)) { return(false); } ICalcSource source = mgr.Source; Dictionary <CalcLocalIdentity, CalcExpression> dictionary = new Dictionary <CalcLocalIdentity, CalcExpression>(); if ((id is CalcRangeIdentity) && mgr.Graph.IsSharedFormula(id as CalcRangeIdentity)) { List <CalcLocalIdentity> dirtySubIds = new List <CalcLocalIdentity>(); SharedFormulaDirtyItem item = dirtyItem as SharedFormulaDirtyItem; if ((item != null) && !item.IsFullRangeDirty) { dirtySubIds = (dirtyItem as SharedFormulaDirtyItem).DirtySubIds; } else { dirtySubIds.Add(id); } foreach (CalcLocalIdentity identity3 in dirtySubIds) { int num; int num2; int num3; int num4; bool flag; CalcRangeIdentity identity4 = identity3 as CalcRangeIdentity; CalcReferenceHelper.Id2Range(source, identity3, out num, out num2, out num3, out num4, out flag); for (int i = num; i < (num + num3); i++) { for (int j = num2; j < (num2 + num4); j++) { if ((identity4 != null) && (identity4.IsFullRow || identity4.IsFullColumn)) { new FullBandMappingVisitor(identity4.IsFullRow, identity4.IsFullRow ? i : j).Visit(objA, 0, 0); } CalcCellIdentity identity5 = new CalcCellIdentity(i, j); CalcExpression expression = mgr.GetExpression(identity5); if (((expression != null) && (expression == objA)) && !mgr.Graph.IsIsIntersectantWithArrayFormula(identity5)) { dictionary[identity5] = objA; } } } } } else { dictionary.Add(id, objA); } foreach (KeyValuePair <CalcLocalIdentity, CalcExpression> pair in dictionary) { id = pair.Key; object obj2 = mgr.Evaluator.Evaluate(pair.Value, source.GetEvaluatorContext(id)); while (!(id is CalcRangeIdentity) && ((obj2 is CalcReference) || (obj2 is CalcArray))) { if (obj2 is CalcReference) { obj2 = ExtractValueFromReference(id, obj2); } if (obj2 is CalcArray) { obj2 = (obj2 as CalcArray).GetValue(0); } } source.SetValue(id, obj2); } return(true); }