You've already forked lazarus-ccr
fpspreadsheet: Fix iterative 3d formula correction terminating prematurely.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6449 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user