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;
out ACurrencySymbol: String): Boolean;
function GetEffectiveCellFormatIndex(ACell: PCell): Integer;
function GetPointerToEffectiveCellFormat(ARow, ACol: Cardinal): PsCellFormat; overload;
function GetPointerToEffectiveCellFormat(ACell: PCell): PsCellFormat; overload;
function GetEffectiveCellFormatIndex(ARow, ACol: Cardinal): Integer; overload;
function GetEffectiveCellFormatIndex(ACell: PCell): Integer; overload;
function GetPointerToEffectiveCellFormat(ARow, ACol: Cardinal): PsCellFormat; //overload;
// function GetPointerToEffectiveCellFormat(ACell: PCell): PsCellFormat; overload;
function ReadUsedFormatting(ACell: PCell): TsUsedFormattingFields;
function ReadBackground(ACell: PCell): TsFillPattern;
@ -1950,7 +1951,7 @@ var
srcFormula, destFormula: PsFormula;
rpn: TsRPNFormula;
elem: TsFormulaElement;
i, j: Integer;
i: Integer;
begin
if (AFromCell = nil) or (AToCell = nil) then
exit;
@ -3008,15 +3009,35 @@ end;
If it is default, look for the row format. If it is default, look for
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;
begin
Result := 0;
if ACell <> nil then
if ACell <> nil then begin
Result := ACell^.FormatIndex;
if Result = 0 then
Result := GetRowFormatIndex(ACell^.Row);
if Result = 0 then
Result := GetColFormatIndex(ACell^.Col);
if Result = 0 then
Result := GetRowFormatIndex(ACell^.Row);
if Result = 0 then
Result := GetColFormatIndex(ACell^.Col);
end;
end;
{@@ ----------------------------------------------------------------------------
@ -3046,7 +3067,7 @@ begin
end;
Result := FWorkbook.GetPointerToCellFormat(fmtIndex);
end;
(*
{@@ ----------------------------------------------------------------------------
Mainly like GetPointerToEffectiveCellFormat(ARow, ACol), but avoids looking
for the cell if ACell <> nil
@ -3060,7 +3081,7 @@ begin
else
fmtIndex := 0;
Result := FWorkbook.GetPointerToCellFormat(fmtIndex);
end;
end; *)
{@@ ----------------------------------------------------------------------------
Reads the set of used formatting fields of a cell.

View File

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