diff --git a/components/fpspreadsheet/source/common/fpsclasses.pas b/components/fpspreadsheet/source/common/fpsclasses.pas index 92c1cddbd..d4a06ac74 100644 --- a/components/fpspreadsheet/source/common/fpsclasses.pas +++ b/components/fpspreadsheet/source/common/fpsclasses.pas @@ -252,23 +252,23 @@ end; { Call-back function for formulas when rows/cols are inserted/deleted } -function FixDeletedCol(AExprNode: TsExprNode; AData: Pointer): Boolean; +procedure FixDeletedCol(AExprNode: TsExprNode; AData: Pointer; + var MustRebuildFormulas: Boolean); var colIndex: Cardinal; rng: TsCellRange; begin - Result := false; colIndex := PtrInt(AData); if AExprNode is TsCellExprNode then begin if not TsCellExprNode(AExprNode).Has3dLink then if TsCellExprNode(AExprNode).Col > colIndex then begin TsCellExprNode(AExprNode).Col := TsCellexprNode(AExprNode).Col - 1; - Result := true; + MustRebuildFormulas := true; end else if TsCellExprNode(AExprNode).Col = colIndex then begin TsCellExprNode(AExprNode).Error := errIllegalRef; - Result := true; + MustRebuildFormulas := true; end; end else if AExprNode is TsCellRangeExprNode then @@ -277,15 +277,15 @@ begin rng := TsCellRangeExprNode(AExprNode).Range; if (rng.Col1 = colIndex) and (rng.Col2 = colIndex) then begin TsCellRangeExprNode(AExprNode).Error := errIllegalRef; - Result := true; + MustRebuildFormulas := true; end else begin if rng.Col1 > colIndex then begin dec(rng.Col1); - Result := true; + MustRebuildFormulas := true; end; if rng.Col2 >= colIndex then begin dec(rng.Col2); - Result := true; + MustRebuildFormulas := true; end; TsCellRangeExprNode(AExprNode).Range := rng; end; @@ -293,23 +293,23 @@ begin end; end; -function FixDeletedRow(AExprNode: TsExprNode; AData: Pointer): Boolean; +procedure FixDeletedRow(AExprNode: TsExprNode; AData: Pointer; + var MustRebuildFormulas: Boolean); var rowIndex: Cardinal; rng: TsCellRange; begin - Result := false; rowIndex := PtrInt(AData); if AExprNode is TsCellExprNode then begin if not TsCellExprNode(AExprNode).Has3dLink then if TsCellExprNode(AExprNode).Row > rowIndex then begin TsCellExprNode(AExprNode).Row := TsCellExprNode(AExprNode).Row - 1; - Result := true; + MustRebuildFormulas := true; end else if TsCellExprNode(AExprNode).Row = rowIndex then begin TsCelLExprNode(AExprNode).Error := errIllegalRef; - Result := true; + MustRebuildFormulas := true; end; end else if AExprNode is TsCellRangeExprNode then @@ -318,16 +318,16 @@ begin rng := TsCellRangeExprNode(AExprNode).Range; if (rng.Row1 = rowIndex) and (rng.Row2 = rowIndex) then begin TsCellRangeExprNode(AExprNode).Error := errIllegalRef; - Result := true; + MustRebuildFormulas := true; end else begin if rng.Row1 > rowIndex then begin dec(rng.Row1); - Result := true; + MustRebuildFormulas := true; end; if rng.Row2 >= rowIndex then begin dec(rng.Row2); - Result := true; + MustRebuildFormulas := true; end; TsCellRangeExprNode(AExprNode).Range := rng; end; @@ -335,19 +335,19 @@ begin end; end; -function FixInsertedCol(AExprNode: TsExprNode; AData: Pointer): Boolean; +procedure FixInsertedCol(AExprNode: TsExprNode; AData: Pointer; + var MustRebuildFormulas: Boolean); var colIndex: Cardinal; rng: TsCellRange; begin - Result := false; colIndex := PtrInt(AData); if AExprNode is TsCellExprNode then begin if not TsCellExprNode(AExprNode).Has3dLink then if TsCellExprNode(AExprNode).Col >= colIndex then begin TsCellExprNode(AExprNode).Col := TsCellexprNode(AExprNode).Col + 1; - Result := true; + MustRebuildFormulas := true; end; end else if AExprNode is TsCellRangeExprNode then @@ -357,24 +357,24 @@ begin if rng.Col1 >= colIndex then inc(rng.Col1); if rng.Col2 >= colIndex then inc(rng.Col2); TsCellRangeExprNode(AExprNode).Range := rng; - Result := true; + MustRebuildFormulas := true; end; end; end; -function FixInsertedRow(AExprNode: TsExprNode; AData: Pointer): Boolean; +procedure FixInsertedRow(AExprNode: TsExprNode; AData: Pointer; + var MustRebuildFormulas: Boolean); var rowIndex: Cardinal; rng: TsCellRange; begin - Result := false; rowIndex := PtrInt(AData); if AExprNode is TsCellExprNode then begin if not TsCellexprNode(AExprNode).Has3dLink then if TsCellExprNode(AExprNode).Row >= rowIndex then begin TsCellExprNode(AExprNode).Row := TsCellExprNode(AExprNode).Row + 1; - Result := true; + MustRebuildFormulas := true; end; end else if AExprNode is TsCellRangeExprNode then @@ -384,7 +384,7 @@ begin if rng.Row1 >= rowIndex then inc(rng.Row1); if rng.Row2 >= rowIndex then inc(rng.Row2); TsCellRangeExprNode(AExprNode).Range := rng; - Result := true; + MustRebuildFormulas := true; end; end; end; diff --git a/components/fpspreadsheet/source/common/fpsexprparser.pas b/components/fpspreadsheet/source/common/fpsexprparser.pas index 3a46351bc..199bfc65e 100644 --- a/components/fpspreadsheet/source/common/fpsexprparser.pas +++ b/components/fpspreadsheet/source/common/fpsexprparser.pas @@ -106,9 +106,11 @@ type PsExpressionResult = ^TsExpressionResult; TsExprParameterArray = array of TsExpressionResult; - { Function executed when iterating through all nodes (Parser.IterateNodes). - The function returns true if the text formula has to be rebuilt. } - TsExprNodeFunc = function(ANode: TsExprNode; AData: Pointer): Boolean; + { Proceudre executed when iterating through all nodes (Parser.IterateNodes). + The procedure sets the parameter MustRebuildFormula to true if the + text formula has to be rebuilt. } + TsExprNodeProc = procedure(ANode: TsExprNode; AData: Pointer; + var MustRebuildFormulas: Boolean); { TsExprNode } TsExprNode = class(TObject) @@ -122,7 +124,8 @@ type function AsString: string; virtual; abstract; procedure Check; virtual; //abstract; function Has3DLink: Boolean; virtual; - function IterateNodes(AFunc: TsExprNodeFunc; AData: Pointer): Boolean; virtual; + procedure IterateNodes(AProc: TsExprNodeProc; AData: Pointer; + var MustRebuildFormulas: Boolean); virtual; function NodeType: TsResultType; virtual; abstract; function NodeValue: TsExpressionResult; property Parser: TsExpressionParser read FParser; @@ -141,7 +144,8 @@ type constructor Create(AParser: TsExpressionParser; ALeft, ARight: TsExprNode); destructor Destroy; override; function Has3DLink: Boolean; override; - function IterateNodes(AFunc: TsExprNodeFunc; AData: Pointer): boolean; override; + procedure IterateNodes(AProc: TsExprNodeProc; AData: Pointer; + var MustRebuildFormulas: boolean); override; property Left: TsExprNode read FLeft; property Right: TsExprNode read FRight; end; @@ -563,7 +567,8 @@ type function AsString: String; override; procedure Check; override; function Has3DLink: Boolean; override; - function IterateNodes(AFunc: TsExprNodeFunc; AData: Pointer): Boolean; override; + procedure IterateNodes(AProc: TsExprNodeProc; AData: Pointer; + var MustRebuildFormulas: Boolean); override; property ArgumentNodes: TsExprArgumentArray read FArgumentNodes; property ArgumentParams: TsExprParameterArray read FArgumentParams; end; @@ -618,7 +623,8 @@ type function GetSheetName: String; function GetWorkbook: TsBasicWorkbook; function Has3DLink: Boolean; override; - function IterateNodes(AFunc: TsExprNodeFunc; AData: Pointer): Boolean; override; + procedure IterateNodes(AProc: TsExprNodeProc; AData: Pointer; + var MustRebuildFormulas: Boolean); override; function NodeType: TsResultType; override; procedure SetSheetIndex(AIndex: Integer); property Col: Cardinal read FCol write FCol; // Be careful when modifying Col and Row @@ -654,7 +660,8 @@ type function GetSheetIndex(AIndex: TsCellRangeIndex): Integer; function GetWorkbook: TsBasicWorkbook; function Has3DLink: Boolean; override; - function IterateNodes(AFunc: TsExprNodeFunc; AData: Pointer): Boolean; override; + procedure IterateNodes(AProc: TsExprNodeProc; AData: Pointer; + var MustRebuildFormulas: Boolean); override; function NodeType: TsResultType; override; procedure SetSheetIndex(AIndex: TsCellRangeIndex; AValue: Integer); property Error: TsErrorValue read FError write FError; @@ -780,7 +787,7 @@ type function Evaluate: TsExpressionResult; procedure EvaluateExpression(out AResult: TsExpressionResult); function Has3DLinks: Boolean; - function IterateNodes(AFunc: TsExprNodeFunc; AData: Pointer): boolean; + function IterateNodes(AProc: TsExprNodeProc; AData: Pointer): boolean; procedure PrepareCopyMode(ASourceCell, ADestCell: PCell); function ResultType: TsResultType; @@ -1979,10 +1986,11 @@ begin Result := FExprNode.Has3DLink; end; -function TsExpressionParser.IterateNodes(AFunc: TsExprNodeFunc; +function TsExpressionParser.IterateNodes(AProc: TsExprNodeProc; AData: Pointer): Boolean; begin - Result := FExprNode.IterateNodes(AFunc, AData); + Result := false; + FExprNode.IterateNodes(AProc, AData, Result); end; procedure TsExpressionParser.SetDialect(const AValue: TsFormulaDialect); @@ -2767,9 +2775,10 @@ begin Result := false; end; -function TsExprNode.IterateNodes(AFunc: TsExprNodeFunc; AData: Pointer): Boolean; +procedure TsExprNode.IterateNodes(AProc: TsExprNodeProc; AData: Pointer; + var MustRebuildFormulas: Boolean); begin - Unused(AFunc, AData); + Unused(AProc, AData, MustRebuildFormulas); // to be overridden by descendant classes end; @@ -2823,10 +2832,14 @@ begin Result := FLeft.Has3DLink or FRight.Has3DLink; end; -function TsBinaryOperationExprNode.IterateNodes(AFunc: TsExprNodeFunc; - AData: Pointer): Boolean; +procedure TsBinaryOperationExprNode.IterateNodes(AProc: TsExprNodeProc; + AData: Pointer; var MustRebuildFormulas: Boolean); +var + rebuildLeft, rebuildRight: Boolean; begin - Result := FLeft.IterateNodes(AFunc, AData) or FRight.IterateNodes(AFunc, AData); + FLeft.IterateNodes(AProc, AData, rebuildLeft); + FRight.IterateNodes(AProc, AData, rebuildRight); + MustRebuildFormulas := MustRebuildFormulas or rebuildLeft or rebuildRight; end; function TsBinaryOperationExprNode.HasError(out AResult: TsExpressionResult): Boolean; @@ -3780,14 +3793,13 @@ begin Result := false; end; -function TsFunctionExprNode.IterateNodes(AFunc: TsExprNodeFunc; - AData: Pointer): Boolean; +procedure TsFunctionExprNode.IterateNodes(AProc: TsExprNodeProc; + AData: Pointer; var MustRebuildFormulas: Boolean); var i: Integer; begin - Result := false; for i:=0 to High(FArgumentParams) do - Result := Result or FArgumentNodes[i].IterateNodes(AFunc, AData); + FArgumentNodes[i].IterateNodes(AProc, AData, MustRebuildFormulas); end; @@ -4037,10 +4049,10 @@ begin Result := rtCell; end; -function TsCellExprNode.IterateNodes(AFunc: TsExprNodeFunc; - AData: Pointer): Boolean; +procedure TsCellExprNode.IterateNodes(AProc: TsExprNodeProc; + AData: Pointer; var MustRebuildFormulas: Boolean); begin - Result := AFunc(self, AData); + AProc(self, AData, MustRebuildFormulas); end; procedure TsCellExprNode.SetSheetIndex(AIndex: Integer); @@ -4293,10 +4305,10 @@ begin Result := F3dRange; end; -function TsCellRangeExprNode.IterateNodes(AFunc: TsExprNodeFunc; - AData: Pointer): Boolean; +procedure TsCellRangeExprNode.IterateNodes(AProc: TsExprNodeProc; + AData: Pointer; var MustRebuildFormulas: Boolean); begin - Result := AFunc(self, AData); + AProc(self, AData, MustRebuildFormulas); end; function TsCellRangeExprNode.NodeType: TsResultType; diff --git a/components/fpspreadsheet/source/common/fpspreadsheet.pas b/components/fpspreadsheet/source/common/fpspreadsheet.pas index e3fce9bac..c9b79d483 100644 --- a/components/fpspreadsheet/source/common/fpspreadsheet.pas +++ b/components/fpspreadsheet/source/common/fpspreadsheet.pas @@ -1137,6 +1137,7 @@ end; {@@ ---------------------------------------------------------------------------- Destructor of the TsWorksheet class. Releases all memory, but does not delete from the workbook's worksheetList !!! + NOTE: Don't call directly. Always use Workbook.RemoveWorksheet to remove a worksheet from a workbook. -------------------------------------------------------------------------------} @@ -9599,7 +9600,8 @@ end; { AData points to the deleted worksheet } -function FixWorksheetDeletedCallback(ANode: TsExprNode; AData: Pointer): Boolean; +procedure FixWorksheetDeletedCallback(ANode: TsExprNode; AData: Pointer; + var MustRebuildFormulas: Boolean); var deletedindex: Integer; deletedSheet: TsWorksheet; @@ -9607,7 +9609,6 @@ var rngNode: TsCellRangeExprNode; index, index1, index2: Integer; begin - Result := false; if ANode is TsCellExprNode then begin cellNode := TsCellExprNode(ANode); @@ -9616,11 +9617,11 @@ begin index := cellNode.GetSheetIndex; if deletedindex < index then begin cellNode.SetSheetIndex(index-1); - Result := true; + MustRebuildFormulas := true; end else if deletedIndex = index then begin cellNode.Error := errIllegalRef; - Result := true; + MustRebuildFormulas := true; end; end else if ANode is TsCellRangeExprNode then @@ -9633,23 +9634,23 @@ begin if deletedIndex < index1 then begin rngNode.SetSheetIndex(1, index1-1); rngNode.SetSheetIndex(2, index2-1); - Result := true; + MustRebuildFormulas := true; end else if (deletedIndex > index1) and (deletedIndex < index2) then begin rngNode.SetSheetIndex(2, index2-1); - Result := true; + MustRebuildFormulas := true; end else if (deletedIndex = index1) and (index1 <> index2) then begin rngNode.SetSheetIndex(2, index2-1); - Result := true; + MustRebuildFormulas := true; end else if (deletedIndex = index2) and (index1 <> index2) then begin rngNode.SetSheetIndex(2, index2-1); - Result := true; + MustRebuildFormulas := true; end else if (deletedIndex = index1) and (deletedIndex = index2) then begin rngNode.Error := errIllegalRef; - Result := true; + MustRebuildFormulas := true; end; end; end; diff --git a/components/fpspreadsheet/source/common/xlsbiff8.pas b/components/fpspreadsheet/source/common/xlsbiff8.pas index a213f9662..b05175da8 100644 --- a/components/fpspreadsheet/source/common/xlsbiff8.pas +++ b/components/fpspreadsheet/source/common/xlsbiff8.pas @@ -2559,11 +2559,13 @@ begin AStream.WriteWord(0); end; -function DoCollectSheetsWith3dRefs(ANode: TsExprNode; AData: Pointer): Boolean; +procedure DoCollectSheetsWith3dRefs(ANode: TsExprNode; AData: Pointer; + var MustRebuildFormulas: Boolean); var sheetlist: TsBIFF8ExternSheetList; sheetIdx, sheetIdx1, sheetIdx2: Integer; begin + Unused(MustRebuildFormulas); sheetlist := TsBIFF8ExternSheetList(AData); if (ANode is TsCellExprNode) and TsCellExprNode(ANode).Has3DLink then begin @@ -2577,7 +2579,6 @@ begin for sheetIdx := sheetIdx1 to sheetIdx2 do sheetList.AddSheets('', nil, sheetIdx1, sheetIdx2); end; - Result := false; end; {@@ ---------------------------------------------------------------------------- diff --git a/components/fpspreadsheet/source/common/xlscommon.pas b/components/fpspreadsheet/source/common/xlscommon.pas index 02c3c5521..ca5e3c1a2 100644 --- a/components/fpspreadsheet/source/common/xlscommon.pas +++ b/components/fpspreadsheet/source/common/xlscommon.pas @@ -3463,12 +3463,14 @@ begin end; end; -function DoCollectSheetsWith3dRefs(ANode: TsExprNode; AData: Pointer): Boolean; +procedure DoCollectSheetsWith3dRefs(ANode: TsExprNode; AData: Pointer; + var MustRebuildFormulas: Boolean); var sheetlist: TsBIFFExternSheetList; sheetIdx, sheetIdx1, sheetIdx2: Integer; workbook: TsWorkbook; begin + Unused(MustRebuildFormulas); sheetlist := TsBIFFExternSheetList(AData); if (ANode is TsCellExprNode) and TsCellExprNode(ANode).Has3DLink then sheetList.AddSheet(TsCellExprNode(ANode).GetSheetName, ebkInternal) @@ -3481,7 +3483,6 @@ begin for sheetIdx := sheetIdx1 to sheetIdx2 do sheetList.AddSheet(workbook.GetWorksheetByIndex(sheetIdx).Name, ebkInternal); end; - Result := false; // No need to rebuild the text formula end; {@@ ----------------------------------------------------------------------------