You've already forked lazarus-ccr
fpspreadsheet: Add test case for copy format. Fix default vertical text alignment issue of biff5 and biff8.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3817 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -1321,8 +1321,8 @@ function GetFileFormatName(AFormat: TsSpreadsheetFormat): String;
|
|||||||
procedure MakeLEPalette(APalette: PsPalette; APaletteSize: Integer);
|
procedure MakeLEPalette(APalette: PsPalette; APaletteSize: Integer);
|
||||||
function SameCellBorders(ACell1, ACell2: PCell): Boolean;
|
function SameCellBorders(ACell1, ACell2: PCell): Boolean;
|
||||||
|
|
||||||
procedure InitCell(out ACell: TCell); overload;
|
procedure InitCell(var ACell: TCell); overload;
|
||||||
procedure InitCell(ARow, ACol: Cardinal; out ACell: TCell); overload;
|
procedure InitCell(ARow, ACol: Cardinal; var ACell: TCell); overload;
|
||||||
|
|
||||||
function HasFormula(ACell: PCell): Boolean;
|
function HasFormula(ACell: PCell): Boolean;
|
||||||
|
|
||||||
@ -1573,12 +1573,13 @@ end;
|
|||||||
Initalizes a new cell.
|
Initalizes a new cell.
|
||||||
@return New cell record
|
@return New cell record
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure InitCell(out ACell: TCell);
|
procedure InitCell(var ACell: TCell);
|
||||||
begin
|
begin
|
||||||
ACell.FormulaValue := '';
|
ACell.FormulaValue := '';
|
||||||
ACell.UTF8StringValue := '';
|
ACell.UTF8StringValue := '';
|
||||||
ACell.NumberFormatStr := '';
|
ACell.NumberFormatStr := '';
|
||||||
FillChar(ACell, SizeOf(ACell), 0);
|
FillChar(ACell, SizeOf(ACell), 0);
|
||||||
|
ACell.BorderStyles := DEFAULT_BORDERSTYLES;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -1589,7 +1590,7 @@ end;
|
|||||||
@param ACol Column index of the new cell
|
@param ACol Column index of the new cell
|
||||||
@return New cell record with row and column fields preset to passed values.
|
@return New cell record with row and column fields preset to passed values.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure InitCell(ARow, ACol: Cardinal; out ACell: TCell);
|
procedure InitCell(ARow, ACol: Cardinal; var ACell: TCell);
|
||||||
begin
|
begin
|
||||||
InitCell(ACell);
|
InitCell(ACell);
|
||||||
ACell.Row := ARow;
|
ACell.Row := ARow;
|
||||||
@ -2287,14 +2288,9 @@ begin
|
|||||||
if (Result = nil) then
|
if (Result = nil) then
|
||||||
begin
|
begin
|
||||||
New(Result);
|
New(Result);
|
||||||
FillChar(Result^, SizeOf(TCell), #0);
|
InitCell(ARow, ACol, Result^);
|
||||||
|
|
||||||
Result^.Row := ARow;
|
|
||||||
Result^.Col := ACol;
|
|
||||||
Result^.ContentType := cctEmpty;
|
|
||||||
Result^.BorderStyles := DEFAULT_BORDERSTYLES;
|
|
||||||
|
|
||||||
Cells.Add(Result);
|
Cells.Add(Result);
|
||||||
|
|
||||||
if FFirstColIndex = $FFFFFFFF then FFirstColIndex := GetFirstColIndex(true)
|
if FFirstColIndex = $FFFFFFFF then FFirstColIndex := GetFirstColIndex(true)
|
||||||
else FFirstColIndex := Min(FFirstColIndex, ACol);
|
else FFirstColIndex := Min(FFirstColIndex, ACol);
|
||||||
if FFirstRowIndex = $FFFFFFFF then FFirstRowIndex := GetFirstRowIndex(true)
|
if FFirstRowIndex = $FFFFFFFF then FFirstRowIndex := GetFirstRowIndex(true)
|
||||||
|
@ -14,7 +14,7 @@ uses
|
|||||||
testsutility;
|
testsutility;
|
||||||
|
|
||||||
var
|
var
|
||||||
SourceCells: Array[0..6] of TCell;
|
SourceCells: Array[0..9] of TCell;
|
||||||
|
|
||||||
procedure InitCopyData;
|
procedure InitCopyData;
|
||||||
|
|
||||||
@ -32,48 +32,68 @@ type
|
|||||||
|
|
||||||
published
|
published
|
||||||
procedure Test_CopyValuesToEmptyCells;
|
procedure Test_CopyValuesToEmptyCells;
|
||||||
// procedure Test_Copy_Format;
|
procedure Test_CopyValuesToOccupiedCells;
|
||||||
// procedure Test_Copy_Formula;
|
|
||||||
|
procedure Test_CopyFormatsToEmptyCells;
|
||||||
|
procedure Test_CopyFormatsToOccupiedCells;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
TypInfo, Math, fpsutils;
|
TypInfo, fpsutils;
|
||||||
|
|
||||||
const
|
const
|
||||||
CopyTestSheet = 'Copy';
|
CopyTestSheet = 'Copy';
|
||||||
|
|
||||||
function InitNumber(ANumber: Double): TCell;
|
function InitNumber(ANumber: Double; ABkColor: TsColor): TCell;
|
||||||
begin
|
begin
|
||||||
InitCell(Result);
|
InitCell(Result);
|
||||||
Result.ContentType := cctNumber;
|
Result.ContentType := cctNumber;
|
||||||
Result.Numbervalue := ANumber;
|
Result.Numbervalue := ANumber;
|
||||||
|
if (ABkColor <> scNotDefined) and (ABkColor <> scTransparent) then
|
||||||
|
begin
|
||||||
|
Result.UsedFormattingFields := Result.UsedFormattingFields + [uffBackgroundColor];
|
||||||
|
Result.BackgroundColor := ABkColor;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function InitString(AString: String): TCell;
|
function InitString(AString: String; ABkColor: TsColor): TCell;
|
||||||
begin
|
begin
|
||||||
InitCell(Result);
|
InitCell(Result);
|
||||||
Result.ContentType := cctUTF8String;
|
Result.ContentType := cctUTF8String;
|
||||||
Result.UTF8StringValue := AString;
|
Result.UTF8StringValue := AString;
|
||||||
|
if (ABkColor <> scNotDefined) and (ABkColor <> scTransparent) then
|
||||||
|
begin
|
||||||
|
Result.UsedFormattingFields := Result.UsedFormattingFields + [uffBackgroundColor];
|
||||||
|
Result.BackgroundColor := ABkColor;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function InitFormula(AFormula: String; ANumberResult: Double): TCell;
|
function InitFormula(AFormula: String; ANumberResult: Double; ABkColor: TsColor): TCell;
|
||||||
begin
|
begin
|
||||||
InitCell(Result);
|
InitCell(Result);
|
||||||
Result.FormulaValue := AFormula;
|
Result.FormulaValue := AFormula;
|
||||||
Result.NumberValue := ANumberResult;
|
Result.NumberValue := ANumberResult;
|
||||||
Result.ContentType := cctNumber;
|
Result.ContentType := cctNumber;
|
||||||
|
if (ABkColor <> scNotDefined) and (ABkColor <> scTransparent) then
|
||||||
|
begin
|
||||||
|
Result.UsedFormattingFields := Result.UsedFormattingFields + [uffBackgroundColor];
|
||||||
|
Result.BackgroundColor := ABkColor;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure InitCopyData;
|
procedure InitCopyData;
|
||||||
begin
|
begin
|
||||||
SourceCells[0] := InitNumber(1.0); // will be in A1
|
SourceCells[0] := InitNumber(1.0, scTransparent); // will be in A1
|
||||||
SourceCells[1] := InitNumber(2.0);
|
SourceCells[1] := InitNumber(2.0, scTransparent);
|
||||||
SourceCells[2] := InitNumber(3.0);
|
SourceCells[2] := InitNumber(3.0, scYellow);
|
||||||
SourceCells[3] := InitString('Lazarus');
|
SourceCells[3] := InitString('Lazarus', scRed);
|
||||||
SourceCells[4] := InitFormula('A1+1', 2.0);
|
SourceCells[4] := InitFormula('A1+1', 2.0, scTransparent);
|
||||||
InitCell(SourceCells[5]); // empty but existing
|
SourceCells[5] := InitFormula('$A1+1', 2.0, scTransparent);
|
||||||
|
SourceCells[6] := InitFormula('A$1+1', 2.0, scTransparent);
|
||||||
|
SourceCells[7] := InitFormula('$A$1+1', 2.0, scGray);
|
||||||
|
InitCell(SourceCells[8]); // empty but existing
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -112,28 +132,60 @@ begin
|
|||||||
|
|
||||||
MyWorkSheet:= MyWorkBook.AddWorksheet(CopyTestSheet);
|
MyWorkSheet:= MyWorkBook.AddWorksheet(CopyTestSheet);
|
||||||
|
|
||||||
// Create two identical columns A and B
|
// Prepare the worksheet in which cells are copied:
|
||||||
for row := 0 to High(SourceCells) do
|
// Store the SourceCells to column A and B; in B shifted down by 1 cell
|
||||||
|
{ A B
|
||||||
|
1 1.0
|
||||||
|
2 2.0 1.0
|
||||||
|
3 3.0 (yellow) 2.0
|
||||||
|
4 Lazarus (red) 3.0
|
||||||
|
5 A1+1 Lazarus
|
||||||
|
6 $A1+1 A1+1
|
||||||
|
7 A$1+1 $A1+1
|
||||||
|
8 $A$1+1 (gray) A$1+1
|
||||||
|
9 (empty) $A$1+1 (gray)
|
||||||
|
10 (empty)
|
||||||
|
}
|
||||||
for col := 0 to 1 do
|
for col := 0 to 1 do
|
||||||
|
for row := 0 to High(SourceCells) do
|
||||||
begin
|
begin
|
||||||
|
// Why is there a row index of "row + col" below? The first column has the
|
||||||
|
// data starting at the top, in cell A1. In the second column each row
|
||||||
|
// index is incremented by 1, i.e. the data are shifted down by 1 cell.
|
||||||
case SourceCells[row].ContentType of
|
case SourceCells[row].ContentType of
|
||||||
cctNumber:
|
cctNumber:
|
||||||
cell := MyWorksheet.WriteNumber(row, col, SourceCells[row].NumberValue);
|
cell := MyWorksheet.WriteNumber(row+col, col, SourceCells[row].NumberValue);
|
||||||
cctUTF8String:
|
cctUTF8String:
|
||||||
cell := Myworksheet.WriteUTF8Text(row, col, SourceCells[row].UTF8StringValue);
|
cell := Myworksheet.WriteUTF8Text(row+col, col, SourceCells[row].UTF8StringValue);
|
||||||
cctEmpty:
|
cctEmpty:
|
||||||
cell := MyWorksheet.WriteBlank(row, col);
|
cell := MyWorksheet.WriteBlank(row+col, col);
|
||||||
end;
|
end;
|
||||||
if SourceCells[row].FormulaValue <> '' then
|
if SourceCells[row].FormulaValue <> '' then
|
||||||
Myworksheet.WriteFormula(row, col, SourceCells[row].FormulaValue);
|
Myworksheet.WriteFormula(row+col, col, SourceCells[row].FormulaValue);
|
||||||
|
if (uffBackgroundColor in SourceCells[row].UsedFormattingFields) then
|
||||||
|
MyWorksheet.WriteBackgroundColor(cell, SourceCells[row].BackgroundColor);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
MyWorksheet.CalcFormulas;
|
MyWorksheet.CalcFormulas;
|
||||||
|
|
||||||
|
// Now perform the "copy" operations
|
||||||
case ATestKind of
|
case ATestKind of
|
||||||
1: // copy the source cell values to the empty column C
|
1, 2:
|
||||||
|
// copy the source cell VALUES to the empty column C (ATestKind = 1)
|
||||||
|
// or occupied column B (ATestKind = 2)
|
||||||
|
begin
|
||||||
|
if ATestKind = 1 then col := 2 else col := 1;
|
||||||
for row := 0 to High(SourceCells) do
|
for row := 0 to High(SourceCells) do
|
||||||
Myworksheet.CopyValue(MyWorksheet.FindCell(row, 0), row, 2);
|
Myworksheet.CopyValue(MyWorksheet.FindCell(row, 0), row, col);
|
||||||
|
end;
|
||||||
|
3, 4:
|
||||||
|
// copy the source cell FORMATS to the empty column C (ATestKind = 1)
|
||||||
|
// or occupied column B (ATestKind = 2)
|
||||||
|
begin
|
||||||
|
if ATestKind = 1 then col := 2 else col := 1;
|
||||||
|
for row := 0 to High(SourceCells) do
|
||||||
|
MyWorksheet.CopyFormat(MyWorksheet.FindCell(row, 0), row, col);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Write to file
|
// Write to file
|
||||||
@ -150,42 +202,187 @@ begin
|
|||||||
MyWorksheet := MyWorkbook.GetFirstWorksheet;
|
MyWorksheet := MyWorkbook.GetFirstWorksheet;
|
||||||
|
|
||||||
case ATestKind of
|
case ATestKind of
|
||||||
1: // Copied values in first colum to empty third column
|
1, 2:
|
||||||
|
// Copied VALUES in first colum to empty third column (ATestKind = 1) or
|
||||||
|
// occuopied second column (ATestKind = 2)
|
||||||
// The formula cell should contain the result of A1+1 (only value copied)
|
// The formula cell should contain the result of A1+1 (only value copied)
|
||||||
begin
|
begin
|
||||||
col := 2;
|
if ATestKind = 1 then col := 2 else col := 1;
|
||||||
// Number cells
|
for row := 0 to Length(SourceCells) do
|
||||||
for row := 0 to High(SourceCells) do
|
|
||||||
begin
|
begin
|
||||||
cell := MyWorksheet.FindCell(row, col);
|
cell := MyWorksheet.FindCell(row, col);
|
||||||
|
|
||||||
|
if row < Length(SourceCells) then
|
||||||
|
begin
|
||||||
|
// Check content type
|
||||||
if (SourceCells[row].ContentType in [cctNumber, cctUTF8String, cctEmpty]) then
|
if (SourceCells[row].ContentType in [cctNumber, cctUTF8String, cctEmpty]) then
|
||||||
CheckEquals(
|
CheckEquals(
|
||||||
GetEnumName(TypeInfo(TCellContentType), Integer(SourceCells[row].ContentType)),
|
GetEnumName(TypeInfo(TCellContentType), Integer(SourceCells[row].ContentType)),
|
||||||
GetEnumName(TypeInfo(TCellContentType), Integer(cell^.ContentType)),
|
GetEnumName(TypeInfo(TCellContentType), Integer(cell^.ContentType)),
|
||||||
'Content type mismatch, cell '+CellNotation(MyWorksheet, row, col));
|
'Content type mismatch, cell '+CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check values
|
||||||
case SourceCells[row].ContentType of
|
case SourceCells[row].ContentType of
|
||||||
cctNumber:
|
cctNumber:
|
||||||
CheckEquals(
|
CheckEquals(
|
||||||
SourceCells[row].NumberValue,
|
SourceCells[row].NumberValue,
|
||||||
cell^.NumberValue,
|
cell^.NumberValue,
|
||||||
'Number value mismatch, cell ' + CellNotation(MyWorksheet, row, col));
|
'Number value mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
cctUTF8String:
|
cctUTF8String:
|
||||||
CheckEquals(
|
CheckEquals(
|
||||||
SourceCells[row].UTF8StringValue,
|
SourceCells[row].UTF8StringValue,
|
||||||
cell^.UTF8StringValue,
|
cell^.UTF8StringValue,
|
||||||
'String value mismatch, cell ' + CellNotation(MyWorksheet, row, col));
|
'String value mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Check formula results
|
||||||
if HasFormula(@SourceCells[row]) then
|
if HasFormula(@SourceCells[row]) then
|
||||||
CheckEquals(
|
CheckEquals(
|
||||||
SourceCells[0].NumberValue + 1,
|
SourceCells[0].NumberValue + 1,
|
||||||
cell^.NumberValue,
|
cell^.NumberValue,
|
||||||
'Result of copied formula mismatch, cell ' + CellNotation(MyWorksheet, row, col));
|
'Result of copied formula mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Check format: it should not be changed when copying only values
|
||||||
|
case ATestKind of
|
||||||
|
1: // Copy to empty column --> no formatting
|
||||||
|
CheckEquals(
|
||||||
|
true, // true = "the cell has default formatting"
|
||||||
|
(cell = nil) or (cell^.UsedFormattingFields = []),
|
||||||
|
'Default format mismatch, cell ' + CellNotation(MyWorksheet, row,col)
|
||||||
|
);
|
||||||
|
2: // Copy to occupied column --> format like source, but shifted down 1 cvell
|
||||||
|
if row = 0 then // this cell should not be formatted
|
||||||
|
CheckEquals(
|
||||||
|
true,
|
||||||
|
cell^.UsedFormattingFields = [],
|
||||||
|
'Formatting fields mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
CheckEquals(
|
||||||
|
true,
|
||||||
|
SourceCells[row-1].UsedFormattingFields = cell^.UsedFormattingFields,
|
||||||
|
'Formatting fields mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
if (uffBackgroundColor in cell^.UsedFormattingFields) then
|
||||||
|
CheckEquals(
|
||||||
|
SourceCells[row-1].BackgroundColor,
|
||||||
|
cell^.BackgroundColor,
|
||||||
|
'Background color mismatch, cell '+ CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ ------------------------------------------------ }
|
||||||
|
|
||||||
|
3: // FORMATs copied from first column to empty third column
|
||||||
|
begin
|
||||||
|
col := 2;
|
||||||
|
for row :=0 to Length(SourceCells)-1 do
|
||||||
|
begin
|
||||||
|
cell := MyWorksheet.FindCell(row, col);
|
||||||
|
|
||||||
|
// There should not be any content because the column was empty and
|
||||||
|
// we had copied only formats
|
||||||
|
CheckEquals(
|
||||||
|
true, // true = "the cell has no content"
|
||||||
|
(cell = nil) or (cell^.ContentType = cctEmpty),
|
||||||
|
'No content mismatch, cell ' + CellNotation(MyWorksheet, row,col)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check the format: it should be identical to that in column A
|
||||||
|
if cell <> nil then
|
||||||
|
begin
|
||||||
|
CheckEquals(
|
||||||
|
true,
|
||||||
|
SourceCells[row].UsedFormattingFields = cell^.UsedFormattingFields,
|
||||||
|
'Formatting fields mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
if (uffBackgroundColor in cell^.UsedFormattingFields) then
|
||||||
|
CheckEquals(
|
||||||
|
SourceCells[row].BackgroundColor,
|
||||||
|
cell^.BackgroundColor,
|
||||||
|
'Background color mismatch, cell '+ CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ ---------------------------- }
|
||||||
|
|
||||||
|
4: // FORMATs copied from 1st to second column.
|
||||||
|
begin
|
||||||
|
col := 1;
|
||||||
|
|
||||||
|
// Check values: they should be unchanged, i.e. identical to column A,
|
||||||
|
// but there is a vertical offset by 1 cell
|
||||||
|
cell := MyWorksheet.FindCell(0, col);
|
||||||
|
CheckEquals(
|
||||||
|
true, // true = "the cell has no content"
|
||||||
|
(cell = nil) or (cell^.ContentType = cctEmpty),
|
||||||
|
'No content mismatch, cell ' + CellNotation(MyWorksheet, row,col)
|
||||||
|
);
|
||||||
|
for row := 1 to Length(SourceCells) do
|
||||||
|
begin
|
||||||
|
cell := MyWorksheet.FindCell(row, col);
|
||||||
|
// Check content type
|
||||||
|
if (SourceCells[row-1].ContentType in [cctNumber, cctUTF8String, cctEmpty]) then
|
||||||
|
CheckEquals(
|
||||||
|
GetEnumName(TypeInfo(TCellContentType), Integer(SourceCells[row-1].ContentType)),
|
||||||
|
GetEnumName(TypeInfo(TCellContentType), Integer(cell^.ContentType)),
|
||||||
|
'Content type mismatch, cell '+CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
// Check values
|
||||||
|
case SourceCells[row-1].ContentType of
|
||||||
|
cctNumber:
|
||||||
|
CheckEquals(
|
||||||
|
SourceCells[row-1].NumberValue,
|
||||||
|
cell^.NumberValue,
|
||||||
|
'Number value mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
cctUTF8String:
|
||||||
|
CheckEquals(
|
||||||
|
SourceCells[row-1].UTF8StringValue,
|
||||||
|
cell^.UTF8StringValue,
|
||||||
|
'String value mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
// Check formula results
|
||||||
|
if HasFormula(@SourceCells[row-1]) then
|
||||||
|
CheckEquals(
|
||||||
|
SourceCells[0].NumberValue + 1,
|
||||||
|
cell^.NumberValue,
|
||||||
|
'Result of copied formula mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Now check formatting - it should be equal to first column
|
||||||
|
for row := 0 to Length(SourceCells)-1 do
|
||||||
|
begin
|
||||||
|
cell := MyWorksheet.FindCell(row, col);
|
||||||
|
CheckEquals(
|
||||||
|
true,
|
||||||
|
SourceCells[row].UsedFormattingFields = cell^.UsedFormattingFields,
|
||||||
|
'Formatting fields mismatch, cell ' + CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (uffBackgroundColor in cell^.UsedFormattingFields) then
|
||||||
|
CheckEquals(
|
||||||
|
SourceCells[row].BackgroundColor,
|
||||||
|
cell^.BackgroundColor,
|
||||||
|
'Background color mismatch, cell '+ CellNotation(MyWorksheet, row, col)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
MyWorkbook.Free;
|
MyWorkbook.Free;
|
||||||
@ -200,6 +397,24 @@ begin
|
|||||||
Test_Copy(1);
|
Test_Copy(1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Copy given cell values to occupied cells }
|
||||||
|
procedure TSpreadCopyTests.Test_CopyValuesToOccupiedCells;
|
||||||
|
begin
|
||||||
|
Test_Copy(2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Copy given cell formats to empty cells }
|
||||||
|
procedure TSpreadCopyTests.Test_CopyFormatsToEmptyCells;
|
||||||
|
begin
|
||||||
|
Test_Copy(3);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Copy given cell formats to occupied cells }
|
||||||
|
procedure TSpreadCopyTests.Test_CopyFormatsToOccupiedCells;
|
||||||
|
begin
|
||||||
|
Test_Copy(4);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
RegisterTest(TSpreadCopyTests);
|
RegisterTest(TSpreadCopyTests);
|
||||||
|
@ -639,8 +639,8 @@ begin
|
|||||||
if MyCell = nil then
|
if MyCell = nil then
|
||||||
fail('Error in test code. Failed to get cell.');
|
fail('Error in test code. Failed to get cell.');
|
||||||
vertAlign := TsVertAlignment(row);
|
vertAlign := TsVertAlignment(row);
|
||||||
if (vertAlign = vaDefault) and (AFormat in [sfExcel5, sfExcel8]) then
|
if (vertAlign = vaBottom) and (AFormat in [sfExcel5, sfExcel8]) then
|
||||||
vertAlign := vaBottom;
|
vertAlign := vaDefault;
|
||||||
CheckEquals(
|
CheckEquals(
|
||||||
GetEnumName(TypeInfo(TsVertAlignment), Integer(vertAlign)),
|
GetEnumName(TypeInfo(TsVertAlignment), Integer(vertAlign)),
|
||||||
GetEnumName(TypeInfo(TsVertAlignment), Integer(MyCell^.VertAlignment)),
|
GetEnumName(TypeInfo(TsVertAlignment), Integer(MyCell^.VertAlignment)),
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
<Unit1>
|
<Unit1>
|
||||||
<Filename Value="datetests.pas"/>
|
<Filename Value="datetests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="datetests"/>
|
||||||
</Unit1>
|
</Unit1>
|
||||||
<Unit2>
|
<Unit2>
|
||||||
<Filename Value="stringtests.pas"/>
|
<Filename Value="stringtests.pas"/>
|
||||||
@ -60,6 +61,7 @@
|
|||||||
<Unit4>
|
<Unit4>
|
||||||
<Filename Value="manualtests.pas"/>
|
<Filename Value="manualtests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="manualtests"/>
|
||||||
</Unit4>
|
</Unit4>
|
||||||
<Unit5>
|
<Unit5>
|
||||||
<Filename Value="testsutility.pas"/>
|
<Filename Value="testsutility.pas"/>
|
||||||
@ -68,6 +70,7 @@
|
|||||||
<Unit6>
|
<Unit6>
|
||||||
<Filename Value="internaltests.pas"/>
|
<Filename Value="internaltests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="internaltests"/>
|
||||||
</Unit6>
|
</Unit6>
|
||||||
<Unit7>
|
<Unit7>
|
||||||
<Filename Value="formattests.pas"/>
|
<Filename Value="formattests.pas"/>
|
||||||
@ -106,6 +109,7 @@
|
|||||||
<Unit15>
|
<Unit15>
|
||||||
<Filename Value="errortests.pas"/>
|
<Filename Value="errortests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="errortests"/>
|
||||||
</Unit15>
|
</Unit15>
|
||||||
<Unit16>
|
<Unit16>
|
||||||
<Filename Value="virtualmodetests.pas"/>
|
<Filename Value="virtualmodetests.pas"/>
|
||||||
@ -114,11 +118,11 @@
|
|||||||
<Unit17>
|
<Unit17>
|
||||||
<Filename Value="insertdeletetests.pas"/>
|
<Filename Value="insertdeletetests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="insertdeletetests"/>
|
||||||
</Unit17>
|
</Unit17>
|
||||||
<Unit18>
|
<Unit18>
|
||||||
<Filename Value="celltypetests.pas"/>
|
<Filename Value="celltypetests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="celltypetests"/>
|
|
||||||
</Unit18>
|
</Unit18>
|
||||||
<Unit19>
|
<Unit19>
|
||||||
<Filename Value="sortingtests.pas"/>
|
<Filename Value="sortingtests.pas"/>
|
||||||
|
@ -1380,7 +1380,15 @@ begin
|
|||||||
// Vertical text alignment
|
// Vertical text alignment
|
||||||
b := (xf.Align_TextBreak AND MASK_XF_VERT_ALIGN) shr 4;
|
b := (xf.Align_TextBreak AND MASK_XF_VERT_ALIGN) shr 4;
|
||||||
if (b + 1 <= ord(high(TsVertAlignment))) then
|
if (b + 1 <= ord(high(TsVertAlignment))) then
|
||||||
lData.VertAlignment := tsVertAlignment(b + 1) // + 1 due to vaDefault
|
begin
|
||||||
|
lData.VertAlignment := tsVertAlignment(b + 1); // + 1 due to vaDefault
|
||||||
|
// Unfortunately BIFF does not provide a "default" vertical alignment code.
|
||||||
|
// Without the following correction "non-formatted" cells would always have
|
||||||
|
// the uffVertAlign FormattingField set which contradicts the statement of
|
||||||
|
// not being formatted.
|
||||||
|
if lData.VertAlignment = vaBottom then
|
||||||
|
lData.VertAlignment := vaDefault;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
lData.VertAlignment := vaDefault;
|
lData.VertAlignment := vaDefault;
|
||||||
|
|
||||||
@ -1403,22 +1411,26 @@ begin
|
|||||||
// The case of "no line" is not included in the TsLineStyle enumeration.
|
// The case of "no line" is not included in the TsLineStyle enumeration.
|
||||||
// --> correct by subtracting 1!
|
// --> correct by subtracting 1!
|
||||||
dw := xf.Border_Background_1 and MASK_XF_BORDER_BOTTOM;
|
dw := xf.Border_Background_1 and MASK_XF_BORDER_BOTTOM;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
Include(lData.Borders, cbSouth);
|
Include(lData.Borders, cbSouth);
|
||||||
lData.BorderStyles[cbSouth].LineStyle := TsLineStyle(dw shr 22 - 1);
|
lData.BorderStyles[cbSouth].LineStyle := TsLineStyle(dw shr 22 - 1);
|
||||||
end;
|
end;
|
||||||
dw := xf.Border_Background_2 and MASK_XF_BORDER_LEFT;
|
dw := xf.Border_Background_2 and MASK_XF_BORDER_LEFT;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
Include(lData.Borders, cbWest);
|
Include(lData.Borders, cbWest);
|
||||||
lData.BorderStyles[cbWest].LineStyle := TsLineStyle(dw shr 3 - 1);
|
lData.BorderStyles[cbWest].LineStyle := TsLineStyle(dw shr 3 - 1);
|
||||||
end;
|
end;
|
||||||
dw := xf.Border_Background_2 and MASK_XF_BORDER_RIGHT;
|
dw := xf.Border_Background_2 and MASK_XF_BORDER_RIGHT;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
Include(lData.Borders, cbEast);
|
Include(lData.Borders, cbEast);
|
||||||
lData.BorderStyles[cbEast].LineStyle := TsLineStyle(dw shr 6 - 1);
|
lData.BorderStyles[cbEast].LineStyle := TsLineStyle(dw shr 6 - 1);
|
||||||
end;
|
end;
|
||||||
dw := xf.Border_Background_2 and MASK_XF_BORDER_TOP;
|
dw := xf.Border_Background_2 and MASK_XF_BORDER_TOP;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
Include(lData.Borders, cbNorth);
|
Include(lData.Borders, cbNorth);
|
||||||
lData.BorderStyles[cbNorth].LineStyle := TsLineStyle(dw - 1);
|
lData.BorderStyles[cbNorth].LineStyle := TsLineStyle(dw - 1);
|
||||||
end;
|
end;
|
||||||
|
@ -1966,7 +1966,15 @@ begin
|
|||||||
// Vertical text alignment
|
// Vertical text alignment
|
||||||
b := (xf.Align_TextBreak AND MASK_XF_VERT_ALIGN) shr 4;
|
b := (xf.Align_TextBreak AND MASK_XF_VERT_ALIGN) shr 4;
|
||||||
if (b + 1 <= ord(high(TsVertAlignment))) then
|
if (b + 1 <= ord(high(TsVertAlignment))) then
|
||||||
lData.VertAlignment := tsVertAlignment(b + 1) // + 1 due to vaDefault
|
begin
|
||||||
|
lData.VertAlignment := tsVertAlignment(b + 1); // + 1 due to vaDefault
|
||||||
|
// Unfortunately BIFF does not provide a "default" vertical alignment code.
|
||||||
|
// Without the following correction "non-formatted" cells would always have
|
||||||
|
// the uffVertAlign FormattingField set which contradicts the statement of
|
||||||
|
// not being formatted.
|
||||||
|
if lData.VertAlignment = vaBottom then
|
||||||
|
lData.VertAlignment := vaDefault;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
lData.VertAlignment := vaDefault;
|
lData.VertAlignment := vaDefault;
|
||||||
|
|
||||||
@ -1988,27 +1996,32 @@ begin
|
|||||||
|
|
||||||
// the 4 masked bits encode the line style of the border line. 0 = no line
|
// the 4 masked bits encode the line style of the border line. 0 = no line
|
||||||
dw := xf.Border_Background_1 and MASK_XF_BORDER_LEFT;
|
dw := xf.Border_Background_1 and MASK_XF_BORDER_LEFT;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
Include(lData.Borders, cbWest);
|
Include(lData.Borders, cbWest);
|
||||||
lData.BorderStyles[cbWest].LineStyle := FixLineStyle(dw);
|
lData.BorderStyles[cbWest].LineStyle := FixLineStyle(dw);
|
||||||
end;
|
end;
|
||||||
dw := xf.Border_Background_1 and MASK_XF_BORDER_RIGHT;
|
dw := xf.Border_Background_1 and MASK_XF_BORDER_RIGHT;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
Include(lData.Borders, cbEast);
|
Include(lData.Borders, cbEast);
|
||||||
lData.BorderStyles[cbEast].LineStyle := FixLineStyle(dw shr 4);
|
lData.BorderStyles[cbEast].LineStyle := FixLineStyle(dw shr 4);
|
||||||
end;
|
end;
|
||||||
dw := xf.Border_Background_1 and MASK_XF_BORDER_TOP;
|
dw := xf.Border_Background_1 and MASK_XF_BORDER_TOP;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
Include(lData.Borders, cbNorth);
|
Include(lData.Borders, cbNorth);
|
||||||
lData.BorderStyles[cbNorth].LineStyle := FixLineStyle(dw shr 8);
|
lData.BorderStyles[cbNorth].LineStyle := FixLineStyle(dw shr 8);
|
||||||
end;
|
end;
|
||||||
dw := xf.Border_Background_1 and MASK_XF_BORDER_BOTTOM;
|
dw := xf.Border_Background_1 and MASK_XF_BORDER_BOTTOM;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
Include(lData.Borders, cbSouth);
|
Include(lData.Borders, cbSouth);
|
||||||
lData.BorderStyles[cbSouth].LineStyle := FixLineStyle(dw shr 12);
|
lData.BorderStyles[cbSouth].LineStyle := FixLineStyle(dw shr 12);
|
||||||
end;
|
end;
|
||||||
dw := xf.Border_Background_2 and MASK_XF_BORDER_DIAGONAL;
|
dw := xf.Border_Background_2 and MASK_XF_BORDER_DIAGONAL;
|
||||||
if dw <> 0 then begin
|
if dw <> 0 then
|
||||||
|
begin
|
||||||
lData.BorderStyles[cbDiagUp].LineStyle := FixLineStyle(dw shr 21);
|
lData.BorderStyles[cbDiagUp].LineStyle := FixLineStyle(dw shr 21);
|
||||||
lData.BorderStyles[cbDiagDown].LineStyle := lData.BorderStyles[cbDiagUp].LineStyle;
|
lData.BorderStyles[cbDiagDown].LineStyle := lData.BorderStyles[cbDiagUp].LineStyle;
|
||||||
if xf.Border_Background_1 and MASK_XF_BORDER_SHOW_DIAGONAL_UP <> 0 then
|
if xf.Border_Background_1 and MASK_XF_BORDER_SHOW_DIAGONAL_UP <> 0 then
|
||||||
|
@ -321,7 +321,6 @@ type
|
|||||||
function GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
|
function GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
|
||||||
procedure GetLastColCallback(ACell: PCell; AStream: TStream);
|
procedure GetLastColCallback(ACell: PCell; AStream: TStream);
|
||||||
function GetLastColIndex(AWorksheet: TsWorksheet): Word;
|
function GetLastColIndex(AWorksheet: TsWorksheet): Word;
|
||||||
// function FormulaElementKindToExcelTokenID(AElementKind: TFEKind; out ASecondaryID: Word): Word;
|
|
||||||
// Helper function for writing a string with 8-bit length }
|
// Helper function for writing a string with 8-bit length }
|
||||||
function WriteString_8BitLen(AStream: TStream; AString: String): Integer; virtual;
|
function WriteString_8BitLen(AStream: TStream; AString: String): Integer; virtual;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user