fpspreadsheet: Introduce enum field "Options" of TRow and TCol records to replace boolean "Hidden". Prepare for new "PageBreak" option.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7068 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2019-07-23 14:41:55 +00:00
parent 47e9e05399
commit 6fb1f76bc2
8 changed files with 156 additions and 45 deletions

View File

@ -6270,7 +6270,7 @@ begin
GetRowStyleAndHeight(ASheet, ARowIndex, stylename, h);
// Row hidden?
if (round(h) = 0) or (Assigned(row) and row^.Hidden) then
if (round(h) = 0) or (Assigned(row) and (croHidden in row^.Options)) then
rowHiddenStr := ' table:visibility="collapse"'
else
rowHiddenStr := '';
@ -6412,7 +6412,7 @@ begin
// Determine how often this row is repeated
row := sheet.FindRow(ARowIndex);
isHidden1 := (round(h) = 0) or ((row <> nil) and row^.Hidden);
isHidden1 := (round(h) = 0) or ((row <> nil) and (croHidden in row^.Options));
rowHiddenStr := IfThen(isHidden1, ' table:visibility="collapse"', '');
// Rows with format are not repeated - too complicated...
@ -6428,7 +6428,7 @@ begin
break;
row := sheet.FindRow(r);
isHidden := (row <> nil) and
(row^.Hidden or ((row^.RowHeightType=rhtCustom) and (row^.Height = 0)));
((croHidden in row^.Options) or ((row^.RowHeightType=rhtCustom) and (row^.Height = 0)));
if ((row <> nil) and (row^.FormatIndex > 0)) or (isHidden <> isHidden1) then
break;
h1 := sheet.GetRowHeight(r, FWorkbook.Units);

View File

@ -489,6 +489,11 @@ type
procedure WriteColWidth(ACol: Cardinal; AWidth: Single;
AColWidthType: TsColWidthType = cwtCustom); overload; deprecated 'Use version with parameter AUnits';
procedure AddPageBreakToCol(ACol: Cardinal);
procedure AddPageBreakToRow(ARow: Cardinal);
procedure RemovePageBreakFromCol(ACol: Cardinal);
procedure RemovePageBreakFromRow(ARow: Cardinal);
// Sorting
function DefaultCompareCells(ACell1, ACell2: PCell; ASortKey: TsSortKey): Integer;
procedure Sort(const ASortParams: TsSortParams;
@ -7742,7 +7747,7 @@ var
c: PCol;
begin
c := FindCol(ACol);
Result := Assigned(c) and c^.Hidden;
Result := Assigned(c) and (croHidden in c^.Options);
end;
{@@ ----------------------------------------------------------------------------
@ -7753,7 +7758,7 @@ var
r: PRow;
begin
r := FindRow(ARow);
Result := Assigned(r) and r^.Hidden;
Result := Assigned(r) and (croHidden in r^.Options);
end;
{@@ ----------------------------------------------------------------------------
@ -7764,8 +7769,8 @@ var
c: PCol;
begin
c := GetCol(ACol);
if not c^.Hidden then begin
c^.Hidden := true;
if not (croHidden in c^.Options) then begin
Include(c^.Options, croHidden);
ChangedCell(0, ACol);
end;
end;
@ -7778,8 +7783,8 @@ var
r: PRow;
begin
r := GetRow(ARow);
if not r^.Hidden then begin
r^.Hidden := true;
if not (croHidden in r^.Options) then begin
Include(r^.Options, croHidden);
ChangedCell(ARow, 0);
end;
end;
@ -7792,8 +7797,8 @@ var
c: PCol;
begin
c := FindCol(ACol);
if Assigned(c) and c^.Hidden then begin
c^.Hidden := false;
if Assigned(c) and (croHidden in c^.Options) then begin
Exclude(c^.Options, croHidden);
ChangedCell(0, ACol);
end;
end;
@ -7806,8 +7811,8 @@ var
r: PRow;
begin
r := FindRow(ARow);
if Assigned(r) and r^.Hidden then begin
r^.Hidden := false;
if Assigned(r) and (croHidden in r^.Options) then begin
Exclude(r^.Options, croHidden);
ChangedCell(ARow, 0);
end;
end;
@ -8225,7 +8230,7 @@ begin
lRow^.Height := AData.Height;
lRow^.RowHeightType := AData.RowHeightType;
lRow^.FormatIndex := AData.FormatIndex;
lRow^.Hidden := AData.Hidden;
lRow^.Options := AData.Options;
ChangedRow(ARow);
end;
@ -8302,7 +8307,7 @@ begin
lCol^.Width := AData.Width;
lCol^.ColWidthType := AData.ColWidthType;
lCol^.FormatIndex := AData.FormatIndex;
lCol^.Hidden := AData.Hidden;
lCol^.Options := AData.Options;
ChangedCol(ACol);
end;
@ -8386,6 +8391,69 @@ begin
FDefaultRowHeight := FWorkbook.ConvertUnits(AValue, AUnits, FWorkbook.Units);
end;
{@@ ----------------------------------------------------------------------------
Sets the PageBreak flag for the column record with the specified column index.
This means that, when printed, a page break will occur before this column.
Note that FPS currently does not support printing by itself.
-------------------------------------------------------------------------------}
procedure TsWorksheet.AddPageBreakToCol(ACol: Cardinal);
var
lCol: PCol;
begin
lCol := AddCol(ACol);
Include(lCol^.Options, croPageBreak);
ChangedCol(ACol);
end;
{@@ ----------------------------------------------------------------------------
Sets the PageBreak flag for the row record with the specified row index.
This means that, when printed, a page break will occur before this row.
Note that FPS currently does not support printing by itself.
-------------------------------------------------------------------------------}
procedure TsWorksheet.AddPageBreakToRow(ARow: Cardinal);
var
lRow: PRow;
begin
lRow := AddRow(ARow);
Include(lRow^.Options, croPageBreak);
ChangedRow(ARow);
end;
{@@ ----------------------------------------------------------------------------
Removes the PageBreak flag for the column record with the specified column
index.
This means that, during printing, page break handling of this column will be
automatic.
Note that FPS currently does not support printing by itself.
-------------------------------------------------------------------------------}
procedure TsWorksheet.RemovePageBreakFromCol(ACol: Cardinal);
var
lCol: PCol;
begin
lCol := FindCol(ACol);
if lCol <> nil then begin
Exclude(lCol^.Options, croPageBreak);
ChangedCol(ACol);
end;
end;
{@@ ----------------------------------------------------------------------------
Removes the PageBreak flag for the row record with the specified row index.
This means that, during printing, page break handling of this row will be
automatic.
Note that FPS currently does not support printing by itself.
-------------------------------------------------------------------------------}
procedure TsWorksheet.RemovePageBreakFromRow(ARow: Cardinal);
var
lRow: PRow;
begin
lRow := FindRow(ARow);
if lRow <> nil then begin
Exclude(lRow^.Options, croPageBreak);
ChangedRow(ARow);
end;
end;
{==============================================================================}
{ TsWorkbook }

View File

@ -404,7 +404,7 @@ begin
break;
if sheet.FindNextCellInCol(0, lCol^.Col) <> nil then
break;
if lCol^.Hidden then
if (lCol^.Options <> []) then
break;
sheet.RemoveCol(lCol^.Col);
dec(c);
@ -431,10 +431,11 @@ begin
// to the DefaultColWidth ...
sheet.WriteDefaultColWidth(w, FWorkbook.Units);
// ...and delete all column records with non-default format
// ...and delete all visible column records with default format
for c := sheet.Cols.Count-1 downto 0 do begin
lCol := PCol(sheet.Cols[c]);
if (lCol^.FormatIndex = 0) and (not lCol^.Hidden) then sheet.RemoveCol(lCol^.Col);
if (lCol^.FormatIndex = 0) and not (croHidden in lCol^.Options) then
sheet.RemoveCol(lCol^.Col);
end;
end;
end;
@ -481,7 +482,7 @@ begin
// ... and delete all visible row records with default format.
for r := sheet.Rows.Count-1 downto 0 do begin
lRow := PRow(sheet.Rows[r]);
if (lRow^.FormatIndex = 0) and (not lRow^.Hidden) then
if (lRow^.FormatIndex = 0) and not (croHidden in lRow^.Options) then
sheet.RemoveRow(lRow^.Row);
end;
end;

View File

@ -774,6 +774,12 @@ type
in the grid, or by changed by code) }
TsColWidthtype = (cwtDefault, cwtCustom);
{@@ Column or row options
croHidden - Column or row is hidden
croPageBreak - Enforces a pagebreak before this column/row during printing }
TsColRowOption = (croHidden, croPageBreak);
TsColRowOptions = set of TsColRowOption;
{@@ The record TRow contains information about a spreadsheet row:
@param Row The index of the row (beginning with 0)
@param Height The height of the row (expressed in the units defined
@ -782,14 +788,15 @@ type
automatic height
@param FormatIndex Row default format, index into the workbook's
FCellFormatList
@param Hidden Indicates that the row is hidden
Only rows with non-default height or non-default format have a row record. }
@param Options @See TsColRowOption
Only rows with non-default height or non-default format or non-default
Options have a row record. }
TRow = record
Row: Cardinal;
Height: Single;
RowHeightType: TsRowHeightType;
FormatIndex: Integer;
Hidden: Boolean;
Options: TsColRowOptions;
end;
{@@ Pointer to a TRow record }
@ -802,14 +809,15 @@ type
@param ColWidthType Specifies whether the column has default or custom width
@param FormatIndex Column default format, index into the workbook's
FCellFormatlist
@param Hidden Indicates that the column is hidden
Only columns with non-default width or non-default format have a column record. }
@param Options @see TsColRowOptions
Only columns with non-default width or non-default format or non-default
Options have a column record. }
TCol = record
Col: Cardinal;
Width: Single;
ColWidthType: TsColWidthType;
FormatIndex: Integer;
Hidden: Boolean;
Options: TsColRowOptions;
end;
{@@ Pointer to a TCol record }

View File

@ -1674,6 +1674,7 @@ var
fmt: PsCellFormat;
book: TsWorkbook;
sheet: TsWorksheet;
col: PCol;
begin
book := FWorkbook as TsWorkbook;
sheet := FWorksheet as TsWorksheet;
@ -1689,24 +1690,36 @@ begin
{ Calculate width in workbook units }
lCol.Width := book.ConvertUnits(w / 256, suChars, FWorkbook.Units);
if SameValue(lCol.Width, sheet.ReadDefaultColWidth(FWorkbook.Units), EPS) then
lCol.ColWidthType := cwtDefault else
lCol.ColWidthType := cwtDefault
else
lCol.ColWidthType := cwtCustom;
{ Read xf record index }
xf := WordLEToN(AStream.ReadWord);
idx := FCellFormatList.FindIndexOfID(xf);
if idx > -1 then begin
if idx > -1 then
begin
fmt := FCellFormatList.Items[idx];
lCol.FormatIndex := book.AddCellFormat(fmt^);
end else
lCol.FormatIndex := 0;
{ Get current value of column options to keep already set PageBreak option }
col := TsWorksheet(FWorksheet).FindCol(c);
if col <> nil then
lCol.Options := col^.Options
else
lCol.Options := [];
{ Read column visibility }
flags := WordLEToN(AStream.ReadWord);
lCol.Hidden := (flags and $0001 <> 0);
if flags and $0001 = $0001 then
Include(lCol.Options, croHidden)
else
Exclude(lCol.Options, croHidden);
{ Assign width and format to columns, but only if different from defaults }
if (lCol.FormatIndex > 0) or (lCol.ColWidthType = cwtCustom) or lCol.Hidden then
if (lCol.FormatIndex > 0) or (lCol.ColWidthType = cwtCustom) or (lCol.Options <> []) then
for c := c1 to c2 do
sheet.WriteColInfo(c, lCol);
end;
@ -2544,6 +2557,7 @@ type
var
rowrec: TRowRecord;
lRow: TRow;
row: PRow;
h: word;
hpts: Single;
hdef: Single;
@ -2583,12 +2597,21 @@ begin
// Find the format with ID xf
lRow.FormatIndex := XFToFormatIndex(xf);
{ Get current value of row Options to keep Pagebreak already written }
row := TsWorksheet(FWorksheet).FindRow(rowRec.RowIndex);
if row <> nil then
lRow.Options := row^.Options
else
lRow.Options := [];
{ Row visibility }
lRow.Hidden := rowRec.Flags and $00000020 <> 0;
if rowRec.Flags and $00000020 <> 0 then
Include(lRow.Options, croHidden)
else
Exclude(lRow.Options, croHidden);
// We only create a row record for fpspreadsheet if the row has a
// non-standard height (i.e. different from default row height) or format.
if isNonDefaultHeight or hasFormat or lRow.Hidden then
if isNonDefaultHeight or hasFormat or (lRow.Options <> []) then
TsWorksheet(FWorksheet).WriteRowInfo(rowrec.RowIndex, lRow);
end;
@ -3988,7 +4011,7 @@ begin
w := round(width * 256);
optn := 0;
if ACol^.Hidden then optn := optn + $0001;
if (croHidden in ACol^.Options) then optn := optn + $0001;
// outline, collapsed flags are not used
rec.ColWidth := WordToLE(w);
@ -4851,7 +4874,7 @@ begin
{ Option flags }
dw := $00000100; // bit 8 is always 1
if Assigned(ARow) and ARow^.Hidden then dw := dw or $00000020;
if Assigned(ARow) and (croHidden in ARow^.Options) then dw := dw or $00000020;
if spaceabove then dw := dw or $10000000;
if spacebelow then dw := dw or $20000000;
if (ARow <> nil) and (ARow^.RowHeightType = rhtCustom) then // Custom row height

View File

@ -1187,10 +1187,12 @@ begin
end else
lCol.FormatIndex := 0;
lCol.Options := [];
s := GetAttrValue(colNode, 'hidden');
lCol.Hidden := StrIsTrue(s);
if StrIsTrue(s) then
Include(lCol.Options, croHidden);
if (lCol.ColWidthType = cwtCustom) or (lCol.FormatIndex > 0) or lCol.Hidden then
if (lCol.ColWidthType = cwtCustom) or (lCol.FormatIndex > 0) or (lCol.Options <> []) then
for col := col1 to Min(col2, FLastCol) do
sheet.WriteColInfo(col, lCol);
end;
@ -2015,11 +2017,13 @@ begin
end;
{ Row visibility }
lRow.Options := [];
s := GetAttrvalue(ANode, 'hidden');
lRow.Hidden := StrIsTrue(s);
if StrIsTrue(s) then
Include(lRow.Options, croHidden);
{ Write out }
if (lRow.RowHeightType <> rhtDefault) or (lRow.FormatIndex <> 0) or lRow.Hidden then
if (lRow.RowHeightType <> rhtDefault) or (lRow.FormatIndex <> 0) or (lRow.Options <> []) then
(AWorksheet as TsWorksheet).WriteRowInfo(r, lRow);
end;
@ -3059,7 +3063,7 @@ begin
end;
if lCol^.FormatIndex > 0 then
customStyle := Format('style="%d" ', [lCol^.FormatIndex]);
if lCol^.Hidden then hiddenStr := ' hidden="1"';
if (croHidden in lCol^.Options) then hiddenStr := ' hidden="1"';
end;
AppendToStream(AStream, Format(
'<col min="%d" max="%d" width="%.2f" %s%s%s />',
@ -3514,7 +3518,7 @@ begin
s := s + ' customHeight="1"';
if row^.FormatIndex > 0 then
s := s + Format(' s="%d" customFormat="1"', [row^.FormatIndex]);
if row^.Hidden then
if (croHidden in row^.Options) then
s := s + ' hidden="1"';
end;
AppendToStream(AStream, Format(
@ -3581,7 +3585,7 @@ begin
s := s + ' customHeight="1"';
if row^.FormatIndex > 0 then
s := s + Format(' s="%d" customFormat="1"', [row^.FormatIndex]);
if row^.Hidden then
if (croHidden in row^.Options) then
s := s + ' hidden="1"';
end;
AppendToStream(AStream, Format(

View File

@ -3792,7 +3792,10 @@ begin
]));
UpdateFormatProperties(lCol^.FormatIndex, AStrings);
AStrings.Add(Format('Hidden=%s', [
BoolToStr(lCol^.Hidden, true)
BoolToStr(croHidden in lCol^.Options, true)
]));
AStrings.Add(Format('PageBreak=%s', [
BoolToStr(croPageBreak in lCol^.Options, true)
]));
end else
begin
@ -3837,7 +3840,10 @@ begin
]));
UpdateFormatProperties(lRow^.FormatIndex, AStrings);
AStrings.Add(Format('Hidden=%s', [
BoolToStr(lRow^.Hidden, true)
BoolToStr(croHidden in lRow^.Options, true)
]));
AStrings.Add(Format('PageBreak=%s', [
BoolToStr(croPageBreak in lRow^.Options, true)
]));
end else
begin

View File

@ -5753,7 +5753,7 @@ begin
if Worksheet <> nil then
begin
lCol := Worksheet.FindCol(ACol - FHeaderCount);
if (lCol <> nil) and lCol^.Hidden then
if (lCol <> nil) and (croHidden in lCol^.Options) then
w := 0
else begin
if (lCol <> nil) and (lCol^.ColWidthType = cwtCustom) then
@ -5809,8 +5809,9 @@ begin
begin
sr := ARow - FHeaderCount; // worksheet row index
lRow := Worksheet.FindRow(sr);
if (lRow <> nil) then begin
if lRow^.Hidden then
if (lRow <> nil) then
begin
if (croHidden in lRow^.Options) then
h := 0
else begin
case lRow^.RowHeightType of