fpspreadsheet: Avoid regression by new length units by accessing DefaultColWidth and DefaultRowHeights by means of setters/getters. Marked as deprecated though, "official" method is calling workbook's WriteDefaultColWidth/WriteDefaultRowHeight/ReadDefaultColWidth/ReadDefaultRowHeight which get the units as a parameter.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4574 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-03-19 15:18:49 +00:00
parent b3be7d1858
commit ae7cebf901
11 changed files with 148 additions and 56 deletions

View File

@ -1313,15 +1313,14 @@ begin
if AColIndex < 0 then // Row header column
begin
rLast := FWorksheet.GetLastRowIndex;
w := Length(IntToStr(rLast)) + 2;
w := FWorkbook.ConvertUnits(Length(IntToStr(rLast)) + 2, suChars, suPoints);
end else
begin
w := FWorksheet.DefaultColWidth;
w := FWorksheet.ReadDefaultColWidth(suPoints);
col := FWorksheet.FindCol(AColIndex);
if (col <> nil) and (col^.Width > 0) then
w := col^.Width;
w := FWorkbook.ConvertUnits(col^.Width, FWorkbook.Units, suPoints);
end;
w := FWorkbook.ConvertUnits(w, FWorkbook.Units, suPoints);
Result:= Format(' width="%.1fpt"', [w], FPointSeparatorSettings);
end;
@ -1392,11 +1391,10 @@ var
h: Single;
row: PRow;
begin
h := FWorksheet.DefaultRowHeight;
h := FWorksheet.ReadDefaultRowHeight(suPoints);
row := FWorksheet.FindRow(ARowIndex);
if row <> nil then
h := row^.Height;
h := FWorkbook.ConvertUnits(h, FWorkbook.Units, suPoints);
h := FWorkbook.ConvertUnits(row^.Height, FWorkbook.Units, suPoints);
Result := Format(' height="%.1fpt"', [h], FPointSeparatorSettings);
end;

View File

@ -1033,7 +1033,9 @@ var
colStyleIndex: Integer;
colStyle: TColumnStyleData;
i: Integer;
u: TsSizeUnits;
begin
u := FWorkbook.Units;
for i:=0 to FColumnList.Count-1 do
begin
colIndex := TColumnData(FColumnList[i]).Col;
@ -1042,8 +1044,8 @@ begin
// Add only column records to the worksheet if their width is different from
// the default column width. The column width stored in colStyle is already
// in workbook units (see ReadColumnStyles).
if not SameValue(colStyle.ColWidth, FWorksheet.DefaultColWidth, COLWIDTH_EPS) then
FWorksheet.WriteColWidth(colIndex, colStyle.ColWidth, FWorkbook.Units);
if not SameValue(colStyle.ColWidth, FWorksheet.ReadDefaultColWidth(u), COLWIDTH_EPS) then
FWorksheet.WriteColWidth(colIndex, colStyle.ColWidth, u);
end;
end;

View File

@ -135,8 +135,12 @@ type
FOnSelectCell: TsCellEvent;
{ Setter/Getter }
function GetFormatSettings: TFormatSettings;
function GetDefaultColWidth: Single;
function GetDefaultRowHeight: Single;
function GetFormatSettings: TFormatSettings;
procedure SetBiDiMode(AValue: TsBiDiMode);
procedure SetDefaultColWidth(AValue: Single);
procedure SetDefaultRowHeight(AValue: Single);
procedure SetName(const AName: String);
{ Callback procedures called when iterating through all cells }
@ -437,10 +441,14 @@ type
procedure DeleteRow(ARow: Cardinal);
procedure InsertCol(ACol: Cardinal);
procedure InsertRow(ARow: Cardinal);
function ReadDefaultColWidth(AUnits: TsSizeUnits): Single;
function ReadDefaultRowHeight(AUnits: TsSizeUnits): Single;
procedure RemoveAllRows;
procedure RemoveAllCols;
procedure RemoveCol(ACol: Cardinal);
procedure RemoveRow(ARow: Cardinal);
procedure WriteDefaultColWidth(AValue: Single; AUnits: TsSizeUnits);
procedure WriteDefaultRowHeight(AValue: Single; AUnits: TsSizeUnits);
procedure WriteRowInfo(ARow: Cardinal; AData: TRow);
procedure WriteRowHeight(ARow: Cardinal; AHeight: Single; AUnits: TsSizeUnits); overload;
procedure WriteRowHeight(ARow: Cardinal; AHeight: Single); overload; deprecated 'Use version with parameter AUnits';
@ -545,10 +553,11 @@ type
property Workbook: TsWorkbook read FWorkbook;
{@@ The default column width given in "character units" (width of the
character "0" in the default font) }
property DefaultColWidth: Single read FDefaultColWidth write FDefaultColWidth;
{@@ The default row height is given in "line count" (height of the
default font }
property DefaultRowHeight: Single read FDefaultRowHeight write FDefaultRowHeight;
property DefaultColWidth: Single read GetDefaultColWidth write SetDefaultColWidth;
deprecated 'Use Read/WriteDefaultColWidth';
{@@ The default row height is given in "line count" (height of the default font }
property DefaultRowHeight: Single read GetDefaultRowHeight write SetDefaultRowHeight;
deprecated 'Use Read/WriteDefaultColWidth';
// These are properties to interface to TsWorksheetGrid
property BiDiMode: TsBiDiMode read FBiDiMode write SetBiDiMode;
@ -6195,6 +6204,26 @@ begin
ChangedCell(ACell^.Row, ACell^.Col);
end;
function TsWorksheet.GetDefaultColWidth: Single;
begin
Result := ReadDefaultColWidth(suChars);
end;
procedure TsWorksheet.SetDefaultColWidth(AValue: Single);
begin
WriteDefaultColWidth(AValue, suChars);
end;
function TsWorksheet.GetDefaultRowHeight: Single;
begin
Result := ReadDefaultRowHeight(suLines);
end;
procedure TsWorksheet.SetDefaultRowHeight(AValue: Single);
begin
WriteDefaultRowHeight(AValue, suLines);
end;
function TsWorksheet.GetFormatSettings: TFormatSettings;
begin
Result := FWorkbook.FormatSettings;
@ -6724,6 +6753,24 @@ begin
end;
end;
{@@ ----------------------------------------------------------------------------
Reads the value of the default column width and converts it to the specified
units
-------------------------------------------------------------------------------}
function TsWorksheet.ReadDefaultColWidth(AUnits: TsSizeUnits): Single;
begin
Result := FWorkbook.ConvertUnits(FDefaultColWidth, FWorkbook.Units, AUnits);
end;
{@@ ----------------------------------------------------------------------------
Reads the value of the default row height and converts it to the specified
units
-------------------------------------------------------------------------------}
function TsWorksheet.ReadDefaultRowHeight(AUnits: TsSizeUnits): Single;
begin
Result := FWorkbook.ConvertUnits(FDefaultRowHeight, FWorkbook.Units, AUnits);
end;
{@@ ----------------------------------------------------------------------------
Removes all row records from the worksheet and frees the occupied memory.
Note: Cells are retained.
@ -6833,6 +6880,13 @@ begin
AElement^.Height := FWorkbook.ConvertUnits(AHeight, AUnits, FWorkbook.FUnits);
end;
{@@ ----------------------------------------------------------------------------
Sets the row height for a given row. The height is given in terms of
line count of the worksheet's default font.
Note that this method is deprecated and will be removed.
Use the variant in which the units of the new height can be specified.
-------------------------------------------------------------------------------}
procedure TsWorksheet.WriteRowHeight(ARow: Cardinal; AHeight: Single);
begin
WriteRowHeight(ARow, AHeight, suLines);
@ -6876,11 +6930,43 @@ begin
AElement^.Width := FWorkbook.ConvertUnits(AWidth, AUnits, FWorkbook.FUnits);
end;
{@@ ----------------------------------------------------------------------------
Sets the column width for a given column. The width is given in terms of
count of the "0" character using the worksheet's default font.
Note that this method is deprecated and will be removed.
Use the variant in which the units of the new width can be specified.
-------------------------------------------------------------------------------}
procedure TsWorksheet.WriteColWidth(ACol: Cardinal; AWidth: Single);
begin
WriteColWidth(ACol, AWidth, suChars);
end;
{@@ ----------------------------------------------------------------------------
Sets the default column widtht of the worksheet. The value will be stored
in workbook units.
@param AValue New value of the default column width
@param AUnits Units used by AValue
-------------------------------------------------------------------------------}
procedure TsWorksheet.WriteDefaultColWidth(AValue: Single; AUnits: TsSizeUnits);
begin
FDefaultColWidth := FWorkbook.ConvertUnits(AValue, AUnits, FWorkbook.Units);
end;
{@@ ----------------------------------------------------------------------------
Sets the default row height of the worksheet. The value will be stored
in workbook units.
@param AValue New value of the default row height
@param AUnits Units used by AValue
-------------------------------------------------------------------------------}
procedure TsWorksheet.WriteDefaultRowHeight(AValue: Single; AUnits: TsSizeUnits);
begin
FDefaultRowHeight := FWorkbook.ConvertUnits(AValue, AUnits, FWorkbook.Units);
end;
{------------------------------------------------------------------------------}
{ TsWorkbook }
{------------------------------------------------------------------------------}

View File

@ -3281,8 +3281,12 @@ begin
AStrings.Add('Last column=%d', [ASheet.GetLastColIndex]);
AStrings.Add('Active cell=%s', [GetCellString(ASheet.ActiveCellRow, ASheet.ActiveCellCol)]);
AStrings.Add('Selection=%s', [ASheet.GetSelectionAsString]);
AStrings.Add('Default column width=%.1f %s', [ASheet.DefaultColWidth, SizeUnitNames[ASheet.Workbook.Units]]);
AStrings.Add('Default row height=%.1f %s', [ASheet.DefaultRowHeight, SizeUnitNames[ASheet.Workbook.Units]]);
AStrings.Add('Default column width=%.1f %s', [
ASheet.ReadDefaultColWidth(ASheet.Workbook.Units),
SizeUnitNames[ASheet.Workbook.Units]]);
AStrings.Add('Default row height=%.1f %s', [
ASheet.ReadDefaultRowHeight(ASheet.Workbook.Units),
SizeUnitNames[ASheet.Workbook.Units]]);
AStrings.Add('Comments=%d items', [ASheet.Comments.Count]);
AStrings.Add('Hyperlinks=%d items', [ASheet.Hyperlinks.Count]);
AStrings.Add('MergedCells=%d items', [ASheet.MergedCells.Count]);
@ -3290,7 +3294,9 @@ begin
if ienPageLayout in FExpanded then
begin
AStrings.Add('(-) Page layout=');
AStrings.Add(' Orientation=%s', [GetEnumName(TypeInfo(TsPageOrientation), ord(ASheet.PageLayout.Orientation))]);
AStrings.Add(' Orientation=%s', [
GetEnumName(TypeInfo(TsPageOrientation),
ord(ASheet.PageLayout.Orientation))]);
AStrings.Add(' Page width=%.1f mm', [ASheet.PageLayout.PageWidth]);
AStrings.Add(' Page height=%.1f mm', [ASheet.PageLayout.PageHeight]);
AStrings.Add(' Left margin=%.1f mm', [ASheet.PageLayout.LeftMargin]);

View File

@ -4681,7 +4681,7 @@ begin
if lCol <> nil then
w := CalcColWidthFromSheet(lCol^.Width)
else
w := CalcColWidthFromSheet(Worksheet.DefaultColWidth);
w := CalcColWidthFromSheet(Worksheet.ReadDefaultColWidth(Workbook.Units));
end;
ColWidths[i] := w;
end;
@ -5501,7 +5501,7 @@ begin
if FHeaderCount > 0 then
ColWidths[0] := GetDefaultHeaderColWidth;
if Worksheet <> nil then
Worksheet.DefaultColWidth := CalcWorksheetColWidth(AValue);
Worksheet.WriteDefaultColWidth(CalcWorksheetColWidth(AValue), Workbook.Units);
end;
procedure TsCustomWorksheetGrid.SetDefRowHeight(AValue: Integer);
@ -5512,7 +5512,7 @@ begin
if FHeaderCount > 0 then
RowHeights[0] := GetDefaultRowHeight;
if Worksheet <> nil then
Worksheet.DefaultRowHeight := CalcWorksheetRowHeight(AValue);
Worksheet.WriteDefaultRowHeight(CalcWorksheetRowHeight(AValue), Workbook.Units);
end;
procedure TsCustomWorksheetGrid.SetFrozenCols(AValue: Integer);

View File

@ -311,7 +311,7 @@ var
c: Cardinal;
w: Single;
begin
if AWorksheet.Cols.Count <= 1 then
if AWorksheet.Cols.Count < 2 then
exit;
// Check whether all columns have the same column width
@ -322,7 +322,7 @@ begin
// At this point we know that all columns have the same width. We pass this
// to the DefaultColWidth and delete all column records.
AWorksheet.DefaultColWidth := w;
AWorksheet.WriteDefaultColWidth(w, FWorkbook.Units);
AWorksheet.RemoveAllCols;
end;
@ -349,7 +349,7 @@ begin
// At this point we know that all rows have the same height. We pass this
// to the DefaultRowHeight and delete all row records.
AWorksheet.DefaultRowHeight := h;
AWorksheet.WriteDefaultRowHeight(h, FWorkbook.Units);
AWorksheet.RemoveAllRows;
end;

View File

@ -377,7 +377,7 @@ begin
// calculate width in units of "characters"
colwidth := FWorkbook.ConvertUnits(w / 256, suChars, FWorkbook.Units);
// assign width to columns, but only if different from default column width.
if not SameValue(colwidth, FWorksheet.DefaultColWidth, EPS) then
if not SameValue(colwidth, FWorksheet.ReadDefaultColWidth(FWorkbook.Units), EPS) then
for c := c1 to c2 do
FWorksheet.WriteColWidth(c, colwidth, FWorkbook.Units);
end;
@ -387,8 +387,7 @@ var
hw: word;
begin
hw := WordLEToN(AStream.ReadWord);
FWorksheet.DefaultRowHeight := FWorkbook.ConvertUnits(
TwipsToPts(hw and $8000), suPoints, FWorkbook.Units);
FWorksheet.WriteDefaultRowHeight(TwipsToPts(hw and $8000), suPoints);
{
h := TwipsToPts(hw and $8000) / FWorkbook.GetDefaultFontSize;
if h > ROW_HEIGHT_CORRECTION then
@ -1788,9 +1787,8 @@ begin
{ Default height for unused rows, in twips = 1/20 of a point
Bits 0-14: Default height for unused rows, in twips
Bit 15 = 1: Row height not changed manually }
h := FWorkbook.ConvertUnits(AWorksheet.DefaultRowHeight, FWorkbook.Units, suPoints);
// h := (AWorksheet.DefaultRowHeight + ROW_HEIGHT_CORRECTION) * FWorkbook.GetDefaultFontSize;
AStream.WriteWord(WordToLE(PtsToTwips(h)));
h := AWorksheet.ReadDefaultRowHeight(suPoints); // h is in points
AStream.WriteWord(WordToLE(PtsToTwips(h))); // write as twips
end;
@ -1969,6 +1967,8 @@ end;
procedure TsSpreadBIFF2Writer.WriteRow(AStream: TStream; ASheet: TsWorksheet;
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow);
const
EPS = 1E-2;
var
containsXF: Boolean;
rowheight: Word;
@ -1996,10 +1996,8 @@ begin
AStream.WriteWord(WordToLE(Word(ALastColIndex) + 1));
{ Row height (in twips, 1/20 point) and info on custom row height }
if (ARow = nil) or (ARow^.Height = ASheet.DefaultRowHeight) then
rowheight := PtsToTwips(FWorkbook.ConvertUnits(
ASheet.DefaultRowHeight, FWorkbook.Units, suPoints))
// rowheight := PtsToTwips((ASheet.DefaultRowHeight + ROW_HEIGHT_CORRECTION) * h)
if (ARow = nil) or SameValue(ARow^.Height, ASheet.ReadDefaultRowHeight(FWorkbook.Units), EPS) then
rowheight := PtsToTwips(ASheet.ReadDefaultRowHeight(suPoints))
else
if (ARow^.Height = 0) then
rowheight := 0

View File

@ -691,8 +691,7 @@ var
begin
// read width in 1/256 of the width of "0" character
w := WordLEToN(AStream.ReadWord);
// calculate width in workbook units and use it as DefaultColWidth
ASheet.DefaultColWidth := FWorkbook.ConvertUnits(w / 256, suChars, FWorkbook.Units);
ASheet.WriteDefaultRowHeight(w / 256, suChars);
end;
{ Reads a STRING record which contains the result of string formula. }

View File

@ -1406,10 +1406,10 @@ begin
c2 := WordLEToN(AStream.ReadWord);
// read col width in 1/256 of the width of "0" character
w := WordLEToN(AStream.ReadWord);
// calculate width in units of "characters"
// calculate width in workbook units
colwidth := FWorkbook.ConvertUnits(w / 256, suChars, FWorkbook.Units);
// assign width to columns, but only if different from default column width
if not SameValue(colwidth, FWorksheet.DefaultColWidth, EPS) then
if not SameValue(colwidth, FWorksheet.ReadDefaultColWidth(FWorkbook.Units), EPS) then
for c := c1 to c2 do
FWorksheet.WriteColWidth(c, colwidth, FWorkbook.Units);
end;
@ -1516,7 +1516,7 @@ var
begin
// The file contains the column width in characters
w := WordLEToN(AStream.ReadWord);
FWorksheet.DefaultColWidth := FWorkbook.ConvertUnits(w, suChars, FWorkbook.Units);
FWorksheet.WriteDefaultColWidth(w, suChars);
end;
{@@ ----------------------------------------------------------------------------
@ -1532,8 +1532,7 @@ begin
// Height, in Twips (1/20 pt).
hw := WordLEToN(AStream.ReadWord);
FWorksheet.DefaultRowHeight := FWorkbook.ConvertUnits(
TwipsToPts(hw), suPoints, FWorkbook.Units);
FWorksheet.WriteDefaultRowHeight(TwipsToPts(hw), suPoints);
end;
{@@ ----------------------------------------------------------------------------
@ -3306,15 +3305,16 @@ end;
procedure TsSpreadBIFFWriter.WriteDefaultColWidth(AStream: TStream;
AWorksheet: TsWorksheet);
var
colwidth: Single;
w: Single;
begin
{ BIFF record header }
WriteBIFFHeader(AStream, INT_EXCEL_ID_DEFCOLWIDTH, 2);
{ Column width in characters, using the width of the zero character
from default font (first FONT record in the file). }
colwidth := FWorkbook.ConvertUnits(AWorksheet.DefaultColWidth, FWorkbook.Units, suChars);
AStream.WriteWord(round(colwidth));
w := AWorksheet.ReadDefaultColWidth(suChars);
{ It is written in units of 1/256 of the character width }
AStream.WriteWord(round(w * 256));
end;
{@@ ----------------------------------------------------------------------------
@ -3339,8 +3339,8 @@ begin
AStream.WriteWord(WordToLE($0001));
{ Default height for unused rows, in twips = 1/20 of a point }
h := FWorkbook.ConvertUnits(AWorksheet.DefaultRowHeight, FWorkbook.Units, suPoints);
AStream.WriteWord(WordToLE(PtsToTwips(h)));
h := AWorksheet.ReadDefaultRowHeight(suPoints); // h is in points
AStream.WriteWord(WordToLE(PtsToTwips(h))); // write as twips
end;
procedure TsSpreadBIFFWriter.WriteDefinedName(AStream: TStream;
@ -4235,6 +4235,8 @@ end;
-------------------------------------------------------------------------------}
procedure TsSpreadBIFFWriter.WriteRow(AStream: TStream; ASheet: TsWorksheet;
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow);
const
EPS = 1E-2;
var
w: Word;
dw: DWord;
@ -4285,8 +4287,8 @@ begin
AStream.WriteWord(WordToLE(Word(ALastColIndex) + 1));
{ Row height (in twips, 1/20 point) and info on custom row height }
if (ARow = nil) or (ARow^.Height = ASheet.DefaultRowHeight) then
rowheight := PtsToTwips(FWorkbook.ConvertUnits(ASheet.DefaultRowHeight, FWorkbook.Units, suPoints))
if (ARow = nil) or SameValue(ARow^.Height, ASheet.ReadDefaultRowHeight(FWorkbook.Units), EPS) then
rowheight := PtsToTwips(ASheet.ReadDefaultRowHeight(suPoints))
else
if (ARow^.Height = 0) then
rowheight := 0

View File

@ -685,8 +685,8 @@ begin
'ss:DefaultRowHeight="%.2f">' + LF,
[
AWorksheet.GetLastColIndex + 1, AWorksheet.GetLastRowIndex + 1,
FWorkbook.ConvertUnits(AWorksheet.DefaultColWidth, FWorkbook.Units, suPoints),
FWorkbook.ConvertUnits(AWorksheet.DefaultRowHeight, FWorkbook.Units, suPoints)
AWorksheet.ReadDefaultColWidth(suPoints),
AWorksheet.ReadDefaultRowHeight(suPoints)
],
FPointSeparatorSettings
));

View File

@ -1006,7 +1006,7 @@ begin
if s <> '' then col2 := StrToInt(s)-1 else col2 := col1;
s := GetAttrValue(colNode, 'width');
if (s <> '') and TryStrToFloat(s, w, FPointSeparatorSettings) then
if not SameValue(w, AWorksheet.DefaultColWidth, EPS) then
if not SameValue(w, AWorksheet.ReadDefaultColWidth(suChars), EPS) then
for col := col1 to col2 do
AWorksheet.WriteColWidth(col, w, suChars);
end;
@ -1810,11 +1810,11 @@ begin
s := GetAttrValue(ANode, 'defaultColWidth'); // is in characters
if (s <> '') and TryStrToFloat(s, w, FPointSeparatorSettings) then
AWorksheet.DefaultColWidth := FWorkbook.ConvertUnits(w, suChars, FWorkbook.Units);
AWorksheet.WriteDefaultColWidth(w, suChars);
s := GetAttrValue(ANode, 'defaultRowHeight'); // is in points
if (s <> '') and TryStrToFloat(s, h, FPointSeparatorSettings) then //begin
AWorksheet.DefaultRowHeight := FWorkbook.ConvertUnits(h, suPoints, FWorkbook.Units);
if (s <> '') and TryStrToFloat(s, h, FPointSeparatorSettings) then
AWorksheet.WriteDefaultRowHeight(h, suPoints);
end;
procedure TsSpreadOOXMLReader.ReadSheetList(ANode: TDOMNode; AList: TStrings);
@ -2468,10 +2468,11 @@ begin
for c:=0 to AWorksheet.GetLastColIndex do begin
col := AWorksheet.FindCol(c);
// The column width is needed in suChars here.
if col <> nil then
w := FWorkbook.ConvertUnits(col^.Width, FWorkbook.Units, suChars)
else
w := FWorkbook.ConvertUnits(AWorksheet.DefaultColWidth, FWorkbook.Units, suChars);
w := AWorksheet.ReadDefaultColWidth(suChars);
AppendToStream(AStream, Format(
'<col min="%d" max="%d" width="%.2f" customWidth="1" />',
[c+1, c+1, w], FPointSeparatorSettings)
@ -2996,8 +2997,8 @@ var
w, h: Single;
begin
// Excel has column width in characters, and row heights in pts.
w := FWorkbook.ConvertUnits(AWorksheet.DefaultColWidth, FWorkbook.Units, suChars);
h := FWorkbook.ConvertUnits(AWorksheet.DefaultRowHeight, FWorkbook.Units, suPoints);
w := AWorksheet.ReadDefaultColWidth(suChars);
h := AWorksheet.ReadDefaultRowHeight(suPoints);
AppendToStream(AStream, Format(
'<sheetFormatPr baseColWidth="%.2f" defaultRowHeight="%.2f" customHeight="true" />',
[w, h],