fpspreadsheet: Fix crash in Worksheet.GetEffectiveCellFormatIndex and add overloaded version.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6494 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2018-06-13 21:54:35 +00:00
parent 29f1533516
commit 1d35a3b0c9
2 changed files with 63 additions and 22 deletions

View File

@ -161,9 +161,10 @@ type
function GetNumberFormatAttributes(ACell: PCell; out ADecimals: Byte; function GetNumberFormatAttributes(ACell: PCell; out ADecimals: Byte;
out ACurrencySymbol: String): Boolean; out ACurrencySymbol: String): Boolean;
function GetEffectiveCellFormatIndex(ACell: PCell): Integer; function GetEffectiveCellFormatIndex(ARow, ACol: Cardinal): Integer; overload;
function GetPointerToEffectiveCellFormat(ARow, ACol: Cardinal): PsCellFormat; overload; function GetEffectiveCellFormatIndex(ACell: PCell): Integer; overload;
function GetPointerToEffectiveCellFormat(ACell: PCell): PsCellFormat; overload; function GetPointerToEffectiveCellFormat(ARow, ACol: Cardinal): PsCellFormat; //overload;
// function GetPointerToEffectiveCellFormat(ACell: PCell): PsCellFormat; overload;
function ReadUsedFormatting(ACell: PCell): TsUsedFormattingFields; function ReadUsedFormatting(ACell: PCell): TsUsedFormattingFields;
function ReadBackground(ACell: PCell): TsFillPattern; function ReadBackground(ACell: PCell): TsFillPattern;
@ -1950,7 +1951,7 @@ var
srcFormula, destFormula: PsFormula; srcFormula, destFormula: PsFormula;
rpn: TsRPNFormula; rpn: TsRPNFormula;
elem: TsFormulaElement; elem: TsFormulaElement;
i, j: Integer; i: Integer;
begin begin
if (AFromCell = nil) or (AToCell = nil) then if (AFromCell = nil) or (AToCell = nil) then
exit; exit;
@ -3008,15 +3009,35 @@ end;
If it is default, look for the row format. If it is default, look for If it is default, look for the row format. If it is default, look for
the column format. (see "excelfileformat", p. 89) the column format. (see "excelfileformat", p. 89)
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function TsWorksheet.GetEffectiveCellFormatIndex(ARow, ACol: Cardinal): Integer;
var
cell: PCell;
begin
cell := FindCell(ARow, ACol);
if (cell <> nil) then
Result := GetEffectiveCellFormatIndex(cell)
// Result := cell^.FormatIndex
else
begin
// Col and row formats are needed explicitely only in case of empty cells.
// Because if a cells exists the col/row format already has been copied
// to the cell.
Result := GetRowFormatIndex(ARow);
if Result = 0 then
Result := GetColFormatIndex(ACol);
end;
end;
function TsWorksheet.GetEffectiveCellFormatIndex(ACell: PCell): Integer; function TsWorksheet.GetEffectiveCellFormatIndex(ACell: PCell): Integer;
begin begin
Result := 0; Result := 0;
if ACell <> nil then if ACell <> nil then begin
Result := ACell^.FormatIndex; Result := ACell^.FormatIndex;
if Result = 0 then if Result = 0 then
Result := GetRowFormatIndex(ACell^.Row); Result := GetRowFormatIndex(ACell^.Row);
if Result = 0 then if Result = 0 then
Result := GetColFormatIndex(ACell^.Col); Result := GetColFormatIndex(ACell^.Col);
end;
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@ -3046,7 +3067,7 @@ begin
end; end;
Result := FWorkbook.GetPointerToCellFormat(fmtIndex); Result := FWorkbook.GetPointerToCellFormat(fmtIndex);
end; end;
(*
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Mainly like GetPointerToEffectiveCellFormat(ARow, ACol), but avoids looking Mainly like GetPointerToEffectiveCellFormat(ARow, ACol), but avoids looking
for the cell if ACell <> nil for the cell if ACell <> nil
@ -3060,7 +3081,7 @@ begin
else else
fmtIndex := 0; fmtIndex := 0;
Result := FWorkbook.GetPointerToCellFormat(fmtIndex); Result := FWorkbook.GetPointerToCellFormat(fmtIndex);
end; end; *)
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Reads the set of used formatting fields of a cell. Reads the set of used formatting fields of a cell.

View File

@ -1632,6 +1632,7 @@ var
w, w0: Integer; w, w0: Integer;
fmt: PsCellFormat; fmt: PsCellFormat;
fc: Integer; fc: Integer;
idx: Integer;
begin begin
Result := false; Result := false;
cell := FDrawingCell; cell := FDrawingCell;
@ -1641,7 +1642,9 @@ begin
exit; exit;
// fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex); // fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
fmt := Worksheet.GetPointerToEffectiveCellFormat(cell); idx := Worksheet.GetEffectiveCellFormatIndex(cell);
fmt := Workbook.GetPointerToCellFormat(idx);
// fmt := Worksheet.GetPointerToEffectiveCellFormat(cell);
if (uffWordWrap in fmt^.UsedFormattingFields) then // ... word-wrap if (uffWordWrap in fmt^.UsedFormattingFields) then // ... word-wrap
exit; exit;
if (uffTextRotation in fmt^.UsedFormattingFields) and // ... vertical text if (uffTextRotation in fmt^.UsedFormattingFields) and // ... vertical text
@ -2542,6 +2545,7 @@ const
var var
bs: TsCellBorderStyle; bs: TsCellBorderStyle;
fmt: PsCellFormat; fmt: PsCellFormat;
idx: Integer;
r1, c1, r2, c2: Cardinal; r1, c1, r2, c2: Cardinal;
begin begin
if Assigned(Worksheet) then begin if Assigned(Worksheet) then begin
@ -2570,7 +2574,9 @@ begin
DrawBorderLine(ARect.Bottom-1, ARect, drawHor, bs); DrawBorderLine(ARect.Bottom-1, ARect, drawHor, bs);
if ACell <> nil then begin if ACell <> nil then begin
fmt := Worksheet.GetPointerToEffectiveCellFormat(ACell); idx := Worksheet.GetEffectiveCellFormatIndex(ACell);
fmt := Workbook.GetPointerToCellFormat(idx);
// fmt := Worksheet.GetPointerToEffectiveCellFormat(ACell);
// Diagonal up // Diagonal up
if cbDiagUp in fmt^.Border then begin if cbDiagUp in fmt^.Border then begin
bs := fmt^.Borderstyles[cbDiagUp]; bs := fmt^.Borderstyles[cbDiagUp];
@ -3116,6 +3122,7 @@ var
lCell: PCell; lCell: PCell;
fmt: PsCellFormat; fmt: PsCellFormat;
numfmt: TsNumFormatParams; numfmt: TsNumFormatParams;
idx: Integer;
numFmtColor: TColor; numFmtColor: TColor;
sidx: Integer; // number format section index sidx: Integer; // number format section index
RTL: Boolean; RTL: Boolean;
@ -3152,8 +3159,9 @@ begin
if txt = '' then if txt = '' then
exit; exit;
// fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex); idx := Worksheet.GetEffectiveCellFormatIndex(lCell);
fmt := Worksheet.GetPointerToEffectiveCellFormat(lCell); fmt := Workbook.GetPointerToCellFormat(idx);
// fmt := Worksheet.GetPointerToEffectiveCellFormat(lCell);
wrapped := (uffWordWrap in fmt^.UsedFormattingFields) or (fmt^.TextRotation = rtStacked); wrapped := (uffWordWrap in fmt^.UsedFormattingFields) or (fmt^.TextRotation = rtStacked);
RTL := IsRightToLeft; RTL := IsRightToLeft;
if (uffBiDi in fmt^.UsedFormattingFields) then if (uffBiDi in fmt^.UsedFormattingFields) then
@ -3349,11 +3357,14 @@ procedure TsCustomWorksheetGrid.FixNeighborCellBorders(ACell: PCell);
var var
fmt: PsCellFormat; fmt: PsCellFormat;
idx: Integer;
begin begin
if (Worksheet = nil) or (ACell = nil) then if (Worksheet = nil) or (ACell = nil) then
exit; exit;
fmt := Worksheet.GetPointerToEffectiveCellFormat(ACell); idx := Worksheet.GetEffectiveCellFormatIndex(ACell);
fmt := Workbook.GetPointerToCellFormat(idx);
// fmt := Worksheet.GetPointerToEffectiveCellFormat(ACell);
with ACell^ do with ACell^ do
begin begin
// fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex); // fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
@ -3740,6 +3751,7 @@ var
cellR: TRect; cellR: TRect;
r1,c1,r2,c2: Cardinal; r1,c1,r2,c2: Cardinal;
fmt: PsCellFormat; fmt: PsCellFormat;
idx: Integer;
fntIndex: Integer; fntIndex: Integer;
txtRot: TsTextRotation; txtRot: TsTextRotation;
RTL: Boolean; RTL: Boolean;
@ -3773,8 +3785,9 @@ begin
DoPrepareCanvas(ACol, ARow, []); DoPrepareCanvas(ACol, ARow, []);
// fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex); idx := Worksheet.GetEffectiveCellFormatIndex(lCell);
fmt := Worksheet.GetPointerToEffectiveCellFormat(lCell); fmt := Workbook.GetPointerToCellFormat(idx);
// fmt := Worksheet.GetPointerToEffectiveCellFormat(lCell);
if (uffFont in fmt^.UsedFormattingFields) then if (uffFont in fmt^.UsedFormattingFields) then
fntIndex := fmt^.FontIndex else fntIndex := DEFAULT_FONTINDEX; fntIndex := fmt^.FontIndex else fntIndex := DEFAULT_FONTINDEX;
if (uffTextRotation in fmt^.UsedFormattingFields) then if (uffTextRotation in fmt^.UsedFormattingFields) then
@ -4372,6 +4385,7 @@ var
i: Integer; i: Integer;
tmp: Integer = 0; tmp: Integer = 0;
cell: PCell; cell: PCell;
idx: Integer;
fmt: PsCellFormat; fmt: PsCellFormat;
rct, clip_rct, commentcell_rct, temp_rct: TRect; rct, clip_rct, commentcell_rct, temp_rct: TRect;
gds: TGridDrawState; gds: TGridDrawState;
@ -4404,7 +4418,9 @@ begin
then then
Continue; Continue;
// Overflow possible from non-merged, non-right-aligned, horizontal label cells // Overflow possible from non-merged, non-right-aligned, horizontal label cells
fmt := Worksheet.GetPointerToEffectiveCellFormat(cell); idx := Worksheet.GetEffectiveCellFormatIndex(cell);
fmt := Workbook.GetPointerToCellFormat(idx);
// fmt := Worksheet.GetPointerToEffectiveCellFormat(cell);
if (not Worksheet.IsMerged(cell)) and if (not Worksheet.IsMerged(cell)) and
(cell^.ContentType = cctUTF8String) and (cell^.ContentType = cctUTF8String) and
not (uffTextRotation in fmt^.UsedFormattingFields) and not (uffTextRotation in fmt^.UsedFormattingFields) and
@ -4431,7 +4447,9 @@ begin
then then
continue; continue;
// Overflow possible from non-merged, horizontal, non-left-aligned label cells // Overflow possible from non-merged, horizontal, non-left-aligned label cells
fmt := Worksheet.GetPointerToEffectiveCellFormat(cell); idx := Worksheet.GetEffectiveCellFormatIndex(cell);
fmt := Workbook.GetPointerToCellFormat(idx);
// fmt := Worksheet.GetPointerToEffectiveCellFormat(cell);
if (not Worksheet.IsMerged(cell)) and if (not Worksheet.IsMerged(cell)) and
(cell^.ContentType = cctUTF8String) and (cell^.ContentType = cctUTF8String) and
not (uffTextRotation in fmt^.UsedFormattingFields) and not (uffTextRotation in fmt^.UsedFormattingFields) and
@ -6583,6 +6601,7 @@ procedure TsCustomWorksheetGrid.SetCellValue(ACol, ARow: Integer; AValue: Varian
var var
cell: PCell = nil; cell: PCell = nil;
fmt: PsCellFormat = nil; fmt: PsCellFormat = nil;
idx: Integer;
nfp: TsNumFormatParams; nfp: TsNumFormatParams;
r, c: Cardinal; r, c: Cardinal;
s, plain: String; s, plain: String;
@ -6624,8 +6643,9 @@ begin
// If it is a date/time format write a date/time cell... // If it is a date/time format write a date/time cell...
if cell <> nil then if cell <> nil then
begin begin
// fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex); idx := Worksheet.GetEffectiveCellFormatIndex(cell);
fmt := Worksheet.GetPointerToEffectiveCellFormat(cell); fmt := Workbook.GetPointerToCellFormat(idx);
// fmt := Worksheet.GetPointerToEffectiveCellFormat(cell);
if fmt <> nil then if fmt <> nil then
nfp := Workbook.GetNumberFormat(fmt^.NumberFormatIndex); nfp := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
if (fmt <> nil) and IsDateTimeFormat(nfp) then if (fmt <> nil) and IsDateTimeFormat(nfp) then