You've already forked lazarus-ccr
fpspreadsheet: Initial commit with row and column formats. Display in grid seems to work. Reading implemented for biff8 and biff5.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5249 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -41,32 +41,6 @@ type
|
||||
TsWorksheet = class;
|
||||
TsWorkbook = class;
|
||||
|
||||
{@@ 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 by
|
||||
the workbook)
|
||||
@param RowHeightType Specifies default, automatic or custom row height }
|
||||
TRow = record
|
||||
Row: Cardinal;
|
||||
Height: Single;
|
||||
RowHeightType: TsRowHeightType;
|
||||
end;
|
||||
|
||||
{@@ Pointer to a TRow record }
|
||||
PRow = ^TRow;
|
||||
|
||||
{@@ The record TCol contains information about a spreadsheet column:
|
||||
@param Col The index of the column (beginning with 0)
|
||||
@param Width The width of the column (expressed in the units defined in the workbook)
|
||||
Only columns with non-default widths have a column record. }
|
||||
TCol = record
|
||||
Col: Cardinal;
|
||||
Width: Single;
|
||||
end;
|
||||
|
||||
{@@ Pointer to a TCol record }
|
||||
PCol = ^TCol;
|
||||
|
||||
{@@ Worksheet user interface options:
|
||||
@param soShowGridLines Show or hide the grid lines in the spreadsheet
|
||||
@param soShowHeaders Show or hide the column or row headers of the spreadsheet
|
||||
@ -200,6 +174,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 ReadUsedFormatting(ACell: PCell): TsUsedFormattingFields;
|
||||
function ReadBackground(ACell: PCell): TsFillPattern;
|
||||
function ReadBackgroundColor(ACell: PCell): TsColor;
|
||||
@ -438,10 +416,12 @@ type
|
||||
function GetCellCountInRow(ARow: Cardinal): Cardinal;
|
||||
function GetCellCountInCol(ACol: Cardinal): Cardinal;
|
||||
function GetRow(ARow: Cardinal): PRow;
|
||||
function GetRowFormatIndex(ARow: Cardinal): Integer;
|
||||
function GetRowHeight(ARow: Cardinal; AUnits: TsSizeUnits): Single; overload;
|
||||
function GetRowHeight(ARow: Cardinal): Single; overload; deprecated 'Use version with parameter AUnits.';
|
||||
function GetRowHeightType(ARow: Cardinal): TsRowHeightType;
|
||||
function GetCol(ACol: Cardinal): PCol;
|
||||
function GetColFormatIndex(ACol: Cardinal): Integer;
|
||||
function GetColWidth(ACol: Cardinal; AUnits: TsSizeUnits): Single; overload;
|
||||
function GetColWidth(ACol: Cardinal): Single; overload; deprecated 'Use version with parameter AUnits.';
|
||||
procedure DeleteCol(ACol: Cardinal);
|
||||
@ -457,11 +437,13 @@ type
|
||||
procedure WriteDefaultColWidth(AValue: Single; AUnits: TsSizeUnits);
|
||||
procedure WriteDefaultRowHeight(AValue: Single; AUnits: TsSizeUnits);
|
||||
procedure WriteRowInfo(ARow: Cardinal; AData: TRow);
|
||||
procedure WriteRowFormatIndex(ARow: Cardinal; AFormatIndex: Integer);
|
||||
procedure WriteRowHeight(ARow: Cardinal; AHeight: Single; AUnits: TsSizeUnits;
|
||||
ARowHeightType: TsRowHeightType = rhtCustom); overload;
|
||||
procedure WriteRowHeight(ARow: Cardinal; AHeight: Single;
|
||||
ARowHeightType: TsRowHeightType = rhtCustom); overload; deprecated 'Use version with parameter AUnits';
|
||||
procedure WriteColInfo(ACol: Cardinal; AData: TCol);
|
||||
procedure WriteColFormatIndex(ACol: Cardinal; AFormatIndex: Integer);
|
||||
procedure WriteColWidth(ACol: Cardinal; AWidth: Single; AUnits: TsSizeUnits); overload;
|
||||
procedure WriteColWidth(ACol: Cardinal; AWidth: Single); overload; deprecated 'Use version with parameter AUnits';
|
||||
|
||||
@ -2873,6 +2855,70 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Returns the index of the effective cell format to be used at the specified
|
||||
cell.
|
||||
|
||||
"Effective" cell format means: At first, look for the cell format.
|
||||
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(ACell: PCell): Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
if ACell <> nil then
|
||||
Result := ACell^.FormatIndex;
|
||||
if Result = 0 then
|
||||
Result := GetRowFormatIndex(ACell^.Row);
|
||||
if Result = 0 then
|
||||
Result := GetColFormatIndex(ACell^.Col);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Returns a pointer to the effective cell format to be used at the cell in
|
||||
ARow and ACol.
|
||||
|
||||
"Effective" cell format means: At first, look for the cell format.
|
||||
If it is default, look for the row format. If it is default, look for
|
||||
the column format. (see "excelfileformat", p. 89)
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorksheet.GetPointerToEffectiveCellFormat(ARow, ACol: Cardinal): PsCellFormat;
|
||||
var
|
||||
cell: PCell;
|
||||
fmtIndex: Integer;
|
||||
begin
|
||||
cell := FindCell(ARow, ACol);
|
||||
if (cell <> nil) and (cell^.FormatIndex > 0) then
|
||||
fmtIndex := cell^.FormatIndex
|
||||
else begin
|
||||
fmtIndex := GetRowFormatIndex(ARow);
|
||||
if fmtIndex = 0 then
|
||||
fmtIndex := GetColFormatIndex(ACol);
|
||||
end;
|
||||
Result := FWorkbook.GetPointerToCellFormat(fmtIndex);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Mainly like GetPointerToEffectiveCellFormat(ARow, ACol), but avoids looking
|
||||
for the cell if ACell <> nil
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorksheet.GetPointerToEffectiveCellFormat(ACell: PCell): PsCellFormat;
|
||||
var
|
||||
fmtIndex: Integer;
|
||||
begin
|
||||
fmtIndex := 0;
|
||||
if (ACell <> nil) then begin
|
||||
if (ACell^.FormatIndex > 0) then
|
||||
fmtIndex := ACell^.FormatIndex
|
||||
else begin
|
||||
fmtIndex := GetRowFormatIndex(ACell^.Row);
|
||||
if fmtIndex = 0 then
|
||||
fmtIndex := GetColFormatIndex(ACell^.Col);
|
||||
end;
|
||||
end;
|
||||
Result := FWorkbook.GetPointerToCellFormat(fmtIndex);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the set of used formatting fields of a cell.
|
||||
|
||||
@ -4545,6 +4591,7 @@ var
|
||||
isMixed: Boolean;
|
||||
rtParams: TsRichTextParams;
|
||||
plain: String;
|
||||
fmtIndex: Integer;
|
||||
begin
|
||||
if ACell = nil then
|
||||
exit;
|
||||
@ -4564,8 +4611,10 @@ begin
|
||||
WriteNumberFormat(ACell, nfText);
|
||||
end;
|
||||
|
||||
fmt := Workbook.GetCellFormat(ACell^.FormatIndex);
|
||||
fmtIndex := GetEffectiveCellFormatIndex(ACell);
|
||||
fmt := Workbook.GetCellFormat(fmtIndex);
|
||||
numFmtParams := Workbook.GetNumberFormat(fmt.NumberFormatIndex);
|
||||
ACell^.FormatIndex := fmtIndex;
|
||||
|
||||
isPercent := Pos('%', AValue) = Length(AValue);
|
||||
if isPercent then Delete(AValue, Length(AValue), 1);
|
||||
@ -6430,6 +6479,28 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Returns the index to the cell format to be used for a given column.
|
||||
If there is no column record then the default format (index 0) is used.
|
||||
|
||||
@param ACol Index of the column considered
|
||||
@return Index of the format into the workbook's FCellFormatList. This format
|
||||
will be used for formatting a cell if itself does not have a
|
||||
non-zero format index, and if there is no row format either.
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorksheet.GetColFormatIndex(ACol: Cardinal): Integer;
|
||||
var
|
||||
col: PCol;
|
||||
begin
|
||||
Result := 0; // Default format has index 0
|
||||
if ACol <> UNASSIGNED_ROW_COL_INDEX then
|
||||
begin
|
||||
col := FindCol(ACol);
|
||||
if col <> nil then
|
||||
Result := col^.FormatIndex
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Returns the width of the given column. If there is no column record then
|
||||
the default column width is returned.
|
||||
@ -6460,6 +6531,28 @@ begin
|
||||
Result := GetColWidth(ACol, suChars);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Returns the index to the cell format to be used for a given row.
|
||||
If there is no row record then the default format (index 0) is returned.
|
||||
|
||||
@param ARow Index of the row considered
|
||||
@return Index of the format into the workbook's FCellFormatList. This format
|
||||
will be used for formatting a cell if itself does not have a
|
||||
non-zero format index.
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorksheet.GetRowFormatIndex(ARow: Cardinal): Integer;
|
||||
var
|
||||
row: PRow;
|
||||
begin
|
||||
Result := 0; // Default format has index 0
|
||||
if ARow <> UNASSIGNED_ROW_COL_INDEX then
|
||||
begin
|
||||
row := FindRow(ARow);
|
||||
if row <> nil then
|
||||
Result := row^.FormatIndex
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Returns the height of the given row. If there is no row record then the
|
||||
default row height is returned
|
||||
@ -6905,24 +6998,40 @@ end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes a row record for the row at a given index to the spreadsheet.
|
||||
Currently the row record contains only the row height (and the row index,
|
||||
of course).
|
||||
The row record contains info on the row height and the row format index.
|
||||
|
||||
Creates a new row record if it does not yet exist.
|
||||
|
||||
@param ARow Index of the row record which will be created or modified
|
||||
@param AData Data to be written. Expected to be already in the units
|
||||
defined for the workbook
|
||||
Note that the row height value can be negative to indicate
|
||||
that this is an auto-calculated value (i.e. the value can
|
||||
change for example when the font size changes).
|
||||
@param AData Data to be written. Row height expected to be already in the
|
||||
units defined for the workbook.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorksheet.WriteRowInfo(ARow: Cardinal; AData: TRow);
|
||||
var
|
||||
AElement: PRow;
|
||||
lRow: PRow;
|
||||
begin
|
||||
AElement := GetRow(ARow);
|
||||
AElement^.Height := AData.Height;
|
||||
lRow := GetRow(ARow);
|
||||
lRow^.Height := AData.Height;
|
||||
lRow^.RowHeightType := AData.RowHeightType;
|
||||
lRow^.FormatIndex := AData.FormatIndex;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Sets the cell format index for a specific row.
|
||||
Creates a new row record if it does not yet exist.
|
||||
|
||||
@param ARow Index of the row to be considered
|
||||
@param AFormatIndex Index into the workbook's FCellFormatList. This format
|
||||
will be used if a cell has default format index (0).
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorksheet.WriteRowFormatIndex(ARow: Cardinal; AFormatIndex:Integer);
|
||||
var
|
||||
lRow: PRow;
|
||||
begin
|
||||
if ARow = UNASSIGNED_ROW_COL_INDEX then
|
||||
exit;
|
||||
lRow := GetRow(ARow);
|
||||
lRow^.FormatIndex := AFormatIndex;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -6938,13 +7047,13 @@ end;
|
||||
procedure TsWorksheet.WriteRowHeight(ARow: Cardinal; AHeight: Single;
|
||||
AUnits: TsSizeUnits; ARowHeightType: TsRowHeightType = rhtCustom);
|
||||
var
|
||||
AElement: PRow;
|
||||
lRow: PRow;
|
||||
begin
|
||||
if ARow = UNASSIGNED_ROW_COL_INDEX then
|
||||
exit;
|
||||
AElement := GetRow(ARow);
|
||||
AElement^.Height := FWorkbook.ConvertUnits(AHeight, AUnits, FWorkbook.FUnits);
|
||||
AElement^.RowHeightType := ARowHeightType;
|
||||
lRow := GetRow(ARow);
|
||||
lRow^.Height := FWorkbook.ConvertUnits(AHeight, AUnits, FWorkbook.FUnits);
|
||||
lRow^.RowHeightType := ARowHeightType;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -6961,22 +7070,42 @@ begin
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes a column record for the column at a given index to the spreadsheet.
|
||||
Currently the column record contains only the column width (and the column
|
||||
index, of course).
|
||||
Writes a column record for the column at a specific index to the spreadsheet.
|
||||
The column record contains info on the column width and the format index.
|
||||
|
||||
Creates a new column record if it does not yet exist.
|
||||
|
||||
@param ACol Index of the column record which will be created or modified
|
||||
@param AData Data to be written (essentially column width). The column
|
||||
width is already in the units defined for the workbook.
|
||||
@param AData Data to be written. The column width must already be in
|
||||
the units defined for the workbook.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorksheet.WriteColInfo(ACol: Cardinal; AData: TCol);
|
||||
var
|
||||
AElement: PCol;
|
||||
lCol: PCol;
|
||||
begin
|
||||
AElement := GetCol(ACol);
|
||||
AElement^.Width := AData.Width;
|
||||
lCol := GetCol(ACol);
|
||||
lCol^.Width := AData.Width;
|
||||
lCol^.ColWidthType := AData.ColWidthType;
|
||||
lCol^.FormatIndex := AData.FormatIndex;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Sets the cell format index for a specific column.
|
||||
Creates a new column record if it does not yet exist.
|
||||
|
||||
@param ACol Index of the column to be considered
|
||||
@param AFormatIndex Index into the workbook's FCellFormatList. This format
|
||||
will be used if a cell has default format index (0) and
|
||||
if there is no specific default row format.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorksheet.WriteColFormatIndex(ACol: Cardinal; AFormatIndex:Integer);
|
||||
var
|
||||
lCol: PCol;
|
||||
begin
|
||||
if ACol = UNASSIGNED_ROW_COL_INDEX then
|
||||
exit;
|
||||
lCol := GetCol(ACol);
|
||||
lCol^.FormatIndex := AFormatIndex;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -6990,12 +7119,12 @@ end;
|
||||
procedure TsWorksheet.WriteColWidth(ACol: Cardinal; AWidth: Single;
|
||||
AUnits: TsSizeUnits);
|
||||
var
|
||||
AElement: PCol;
|
||||
lCol: PCol;
|
||||
begin
|
||||
if ACol = UNASSIGNED_ROW_COL_INDEX then
|
||||
exit;
|
||||
AElement := GetCol(ACol);
|
||||
AElement^.Width := FWorkbook.ConvertUnits(AWidth, AUnits, FWorkbook.FUnits);
|
||||
lCol := GetCol(ACol);
|
||||
lCol^.Width := FWorkbook.ConvertUnits(AWidth, AUnits, FWorkbook.FUnits);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
|
@ -498,7 +498,7 @@ type
|
||||
TsWorksheetGrid = class(TsCustomWorksheetGrid)
|
||||
published
|
||||
// inherited from TsCustomWorksheetGrid
|
||||
{@@ Automatically recalculates the worksheet if a cell value changes. }
|
||||
{@@ Automatically recalculates the worksheet formulas if a cell value changes. }
|
||||
property AutoCalc;
|
||||
{@@ Automatically expand grid dimensions }
|
||||
property AutoExpand default [aeData, aeNavigation];
|
||||
@ -1307,8 +1307,8 @@ begin
|
||||
if (cell = nil) or not (cell^.ContentType in [cctUTF8String]) then // ... non-label cells
|
||||
exit;
|
||||
|
||||
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||
|
||||
// fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(cell);
|
||||
if (uffWordWrap in fmt^.UsedFormattingFields) then // ... word-wrap
|
||||
exit;
|
||||
if (uffTextRotation in fmt^.UsedFormattingFields) and // ... vertical text
|
||||
@ -1717,10 +1717,13 @@ begin
|
||||
r := ARow - FHeaderCount;
|
||||
c := ACol - FHeaderCount;
|
||||
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(r, c);
|
||||
lCell := Worksheet.FindCell(r, c);
|
||||
if lCell <> nil then
|
||||
begin
|
||||
fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
||||
|
||||
//if lCell <> nil then
|
||||
//begin
|
||||
|
||||
// fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
||||
// numFmt := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
||||
|
||||
// Background color
|
||||
@ -1760,7 +1763,7 @@ begin
|
||||
end;
|
||||
|
||||
// Font
|
||||
if Worksheet.HasHyperlink(lCell) then
|
||||
if (lcell <> nil) and Worksheet.HasHyperlink(lCell) then
|
||||
fnt := Workbook.GetHyperlinkFont
|
||||
else
|
||||
fnt := Workbook.GetDefaultFont;
|
||||
@ -1771,7 +1774,7 @@ begin
|
||||
Canvas.Font.Height := Round(ZoomFactor * Canvas.Font.Height);
|
||||
|
||||
// Wordwrap, text alignment and text rotation are handled by "DrawTextInCell".
|
||||
end;
|
||||
//end;
|
||||
end;
|
||||
|
||||
if IsSelected then
|
||||
@ -1997,7 +2000,8 @@ begin
|
||||
DrawBorderLine(ARect.Bottom-1, ARect, drawHor, bs);
|
||||
|
||||
if ACell <> nil then begin
|
||||
fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(ACell);
|
||||
// fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
||||
{
|
||||
if Worksheet.IsMergeBase(ACell) then
|
||||
begin
|
||||
@ -2212,7 +2216,8 @@ begin
|
||||
then
|
||||
Continue;
|
||||
// Overflow possible from non-merged, non-right-aligned, horizontal label cells
|
||||
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||
// fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(cell);
|
||||
if (not Worksheet.IsMerged(cell)) and
|
||||
(cell^.ContentType = cctUTF8String) and
|
||||
not (uffTextRotation in fmt^.UsedFormattingFields) and
|
||||
@ -2239,7 +2244,8 @@ begin
|
||||
then
|
||||
continue;
|
||||
// Overflow possible from non-merged, horizontal, non-left-aligned label cells
|
||||
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||
// fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(cell);
|
||||
if (not Worksheet.IsMerged(cell)) and
|
||||
(cell^.ContentType = cctUTF8String) and
|
||||
not (uffTextRotation in fmt^.UsedFormattingFields) and
|
||||
@ -2496,15 +2502,7 @@ begin
|
||||
ts.Layout := tlCenter;
|
||||
ts.Opaque := false;
|
||||
Canvas.TextStyle := ts;
|
||||
{
|
||||
writeLn('HEADER');
|
||||
writeln(Format('1 - col=%d, row=%d, font size=%d', [acol, arow, canvas.font.size]));
|
||||
}
|
||||
inherited DrawCellText(aCol, aRow, aRect, aState, GetCellText(ACol,ARow));
|
||||
{
|
||||
writeln(GetCellText(ACol, ARow));
|
||||
writeln(Format('2 - col=%d, row=%d, font size=%d', [acol, arow, canvas.font.size]));
|
||||
}
|
||||
exit;
|
||||
end;
|
||||
|
||||
@ -2516,7 +2514,8 @@ begin
|
||||
if txt = '' then
|
||||
exit;
|
||||
|
||||
fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
||||
// fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(lCell);
|
||||
wrapped := (uffWordWrap in fmt^.UsedFormattingFields) or (fmt^.TextRotation = rtStacked);
|
||||
RTL := IsRightToLeft;
|
||||
if (uffBiDi in fmt^.UsedFormattingFields) then
|
||||
@ -2702,9 +2701,10 @@ begin
|
||||
if (Worksheet = nil) or (ACell = nil) then
|
||||
exit;
|
||||
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(ACell);
|
||||
with ACell^ do
|
||||
begin
|
||||
fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
||||
// fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
||||
if Col > 0 then
|
||||
SetNeighborBorder(Row, Col-1, cbEast, fmt^.BorderStyles[cbWest], cbWest in fmt^.Border);
|
||||
SetNeighborBorder(Row, Col+1, cbWest, fmt^.BorderStyles[cbEast], cbEast in fmt^.Border);
|
||||
@ -3121,7 +3121,8 @@ begin
|
||||
|
||||
DoPrepareCanvas(ACol, ARow, []);
|
||||
|
||||
fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
||||
// fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(lCell);
|
||||
if (uffFont in fmt^.UsedFormattingFields) then
|
||||
fntIndex := fmt^.FontIndex else fntIndex := DEFAULT_FONTINDEX;
|
||||
if (uffTextRotation in fmt^.UsedFormattingFields) then
|
||||
@ -4670,7 +4671,8 @@ begin
|
||||
if (Result = '') or ((ACell <> nil) and (ACell^.ContentType = cctUTF8String)) then
|
||||
exit;
|
||||
|
||||
fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
||||
// fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(ACell^.Row, ACell^.Col);
|
||||
isRotated := (fmt^.TextRotation <> trHorizontal);
|
||||
isStacked := (fmt^.TextRotation = rtStacked);
|
||||
numFmt := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
||||
@ -5646,8 +5648,10 @@ begin
|
||||
// If it is a date/time format write a date/time cell...
|
||||
if cell <> nil then
|
||||
begin
|
||||
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||
if fmt <> nil then nfp := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
||||
// fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||
fmt := Worksheet.GetPointerToEffectiveCellFormat(cell);
|
||||
if fmt <> nil then
|
||||
nfp := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
||||
if (fmt <> nil) and IsDateTimeFormat(nfp) then
|
||||
Worksheet.WriteDateTime(r, c, VarToDateTime(AValue)) else
|
||||
Worksheet.WriteNumber(r, c, AValue);
|
||||
|
@ -674,7 +674,7 @@ type
|
||||
Worksheet: Pointer; // Must be cast to TsWorksheet when used (avoids circular unit reference)
|
||||
{ Status flags }
|
||||
Flags: TsCellFlags;
|
||||
{ Index of format record in the workbook's FCellFormatList }
|
||||
{ Index of format record in the workbook's CellFormatList }
|
||||
FormatIndex: Integer;
|
||||
{ Cell content }
|
||||
UTF8StringValue: String; // Strings cannot be part of a variant record
|
||||
@ -693,6 +693,57 @@ type
|
||||
{@@ Pointer to a TCell record }
|
||||
PCell = ^TCell;
|
||||
|
||||
{@@ Types of row heights
|
||||
rhtDefault - default row height
|
||||
rhtAuto - automatically determined row height, depends on font size,
|
||||
text rotation, rich-text parameters, word-wrap
|
||||
rhtCustom - user-determined row height (dragging the row header borders in
|
||||
the grid, or changed by code) }
|
||||
TsRowHeightType = (rhtDefault, rhtCustom, rhtAuto);
|
||||
|
||||
{@@ Types of column widths
|
||||
cwtDefault - default column width
|
||||
cwtCustom - userdefined column width (dragging the column header border
|
||||
in the grid, or by changed by code) }
|
||||
TsColWidthtype = (cwtDefault, cwtCustom);
|
||||
|
||||
{@@ 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
|
||||
by the workbook)
|
||||
@param RowHeightType Specifies whether the row has default, custom, or
|
||||
automatic height
|
||||
@param FormatIndex Row default format, index into the workbook's
|
||||
FCellFormatList
|
||||
Only rows with non-default height or non-default format have a row record. }
|
||||
TRow = record
|
||||
Row: Cardinal;
|
||||
Height: Single;
|
||||
RowHeightType: TsRowHeightType;
|
||||
FormatIndex: Integer;
|
||||
end;
|
||||
|
||||
{@@ Pointer to a TRow record }
|
||||
PRow = ^TRow;
|
||||
|
||||
{@@ The record TCol contains information about a spreadsheet column:
|
||||
@param Col The index of the column (beginning with 0)
|
||||
@param Width The width of the column (expressed in the units defined
|
||||
in the workbook)
|
||||
@param ColWidthType Specifies whether the column has default or custom width
|
||||
@param FormatIndex Column default format, index into the workbook's
|
||||
FCellFormatlist
|
||||
Only columns with non-default width or non-default format have a column record. }
|
||||
TCol = record
|
||||
Col: Cardinal;
|
||||
Width: Single;
|
||||
ColWidthType: TsColWidthType;
|
||||
FormatIndex: Integer;
|
||||
end;
|
||||
|
||||
{@@ Pointer to a TCol record }
|
||||
PCol = ^TCol;
|
||||
|
||||
{@@ Embedded image }
|
||||
TsImage = record
|
||||
Row, Col: Cardinal; // cell for top/left edge of the image (anchor)
|
||||
@ -725,15 +776,6 @@ type
|
||||
{@@ Array with all possible images in a header or a footer }
|
||||
TsHeaderFooterImages = array[TsHeaderFooterSectionIndex] of TsHeaderFooterImage;
|
||||
|
||||
const
|
||||
{@@ Indexes to be used for the various headers and footers }
|
||||
HEADER_FOOTER_INDEX_FIRST = 0;
|
||||
HEADER_FOOTER_INDEX_ODD = 1;
|
||||
HEADER_FOOTER_INDEX_EVEN = 2;
|
||||
HEADER_FOOTER_INDEX_ALL = 1;
|
||||
|
||||
|
||||
type
|
||||
{@@ Search option }
|
||||
TsSearchOption = (soCompareEntireCell, soMatchCase, soRegularExpr, soAlongRows,
|
||||
soBackward, soWrapDocument, soEntireDocument);
|
||||
@ -770,18 +812,18 @@ type
|
||||
TsStreamParam = (spClipboard, spWindowsClipboardHTML);
|
||||
TsStreamParams = set of TsStreamParam;
|
||||
|
||||
{@@ Types of row heights
|
||||
rhtDefault - default row height
|
||||
rhtAuto - automatically determined row height, depends on font size,
|
||||
text rotation, rich-text parameters, word-wrap
|
||||
rhtCustom - user-determined row height (dragging the row header borders in
|
||||
the grid }
|
||||
TsRowHeightType = (rhtDefault, rhtAuto, rhtCustom);
|
||||
|
||||
const
|
||||
RowHeightTypeNames: array[TsRowHeightType] of string = (
|
||||
'Default', 'Auto', 'Custom');
|
||||
|
||||
ColWidthTypeNames: array[TsColWidthType] of string = (
|
||||
'Default', 'Custom');
|
||||
|
||||
{@@ Indexes to be used for the various headers and footers }
|
||||
HEADER_FOOTER_INDEX_FIRST = 0;
|
||||
HEADER_FOOTER_INDEX_ODD = 1;
|
||||
HEADER_FOOTER_INDEX_EVEN = 2;
|
||||
HEADER_FOOTER_INDEX_ALL = 1;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -386,6 +386,7 @@ type
|
||||
|
||||
procedure AddBuiltinNumFormats; override;
|
||||
procedure ApplyCellFormatting(ACell: PCell; XFIndex: Word); virtual;
|
||||
|
||||
(*
|
||||
procedure ApplyRichTextFormattingRuns(ACell: PCell;
|
||||
ARuns: TsRichTextFormattingRuns);
|
||||
@ -1001,6 +1002,7 @@ begin
|
||||
ACell^.FormatIndex := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
(*
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Converts the rich-text formatting run data as read from the file to the
|
||||
@ -1401,19 +1403,37 @@ const
|
||||
var
|
||||
c, c1, c2: Cardinal;
|
||||
w: Word;
|
||||
colwidth: Double;
|
||||
xf: Word;
|
||||
lCol: TCol;
|
||||
idx: Integer;
|
||||
fmt: PsCellFormat;
|
||||
begin
|
||||
// read column start and end index of column range
|
||||
{ Read column start and end index of column range }
|
||||
c1 := WordLEToN(AStream.ReadWord);
|
||||
c2 := WordLEToN(AStream.ReadWord);
|
||||
// read col width in 1/256 of the width of "0" character
|
||||
|
||||
{ Read col width in 1/256 of the width of "0" character }
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
// 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.ReadDefaultColWidth(FWorkbook.Units), EPS) then
|
||||
|
||||
{ Calculate width in workbook units }
|
||||
lCol.Width := FWorkbook.ConvertUnits(w / 256, suChars, FWorkbook.Units);
|
||||
if SameValue(lCol.Width, FWorksheet.ReadDefaultColWidth(FWorkbook.Units), EPS) then
|
||||
lCol.ColWidthType := cwtDefault else
|
||||
lCol.ColWidthType := cwtCustom;
|
||||
|
||||
{ Read xf record index }
|
||||
xf := WordLEToN(AStream.ReadWord);
|
||||
idx := FCellFormatList.FindIndexOfID(xf);
|
||||
if idx > -1 then begin
|
||||
fmt := FCellFormatList.Items[idx];
|
||||
lCol.FormatIndex := FWorkbook.AddCellFormat(fmt^);
|
||||
end else
|
||||
lCol.FormatIndex := 0;
|
||||
|
||||
{ Assign width and format to columns, but only if different from defaults }
|
||||
if (lCol.FormatIndex > 0) or (lCol.ColWidthType = cwtCustom) then
|
||||
for c := c1 to c2 do
|
||||
FWorksheet.WriteColWidth(c, colwidth, FWorkbook.Units);
|
||||
FWorksheet.WriteColInfo(c, lCol);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -2086,33 +2106,56 @@ type
|
||||
end;
|
||||
var
|
||||
rowrec: TRowRecord;
|
||||
lRow: PRow;
|
||||
lRow: TRow;
|
||||
h: word;
|
||||
hpts: Single;
|
||||
hdef: Single;
|
||||
isNonDefaultHeight: Boolean;
|
||||
isAutoSizeHeight: Boolean;
|
||||
hasFormat: Boolean;
|
||||
flags: DWord;
|
||||
xf: Word;
|
||||
idx: Integer;
|
||||
fmt: PsCellFormat;
|
||||
begin
|
||||
rowrec.RowIndex := 0; // to silence the compiler...
|
||||
AStream.ReadBuffer(rowrec, SizeOf(TRowRecord));
|
||||
rowrec.RowIndex := WordLEToN(rowrec.RowIndex);
|
||||
flags := DWordLEToN(rowrec.Flags);
|
||||
|
||||
{ Row height }
|
||||
h := WordLEToN(rowrec.Height) and $7FFF; // mask off "custom" bit
|
||||
hpts := FWorkbook.ConvertUnits(TwipsToPts(h), suPoints, FWorkbook.Units);
|
||||
hdef := FWorksheet.ReadDefaultRowHeight(FWorkbook.Units);
|
||||
|
||||
isNonDefaultHeight := not SameValue(hpts, hdef, ROWHEIGHT_EPS);
|
||||
isAutoSizeHeight := WordLEToN(rowrec.Flags) and $00000040 = 0;
|
||||
// If this bis is set then font size and row height do NOT match, i.e. NO autosize
|
||||
isAutoSizeHeight := flags and $00000040 = 0;
|
||||
// If this bit is set then font size and row height do NOT match, i.e. NO autosize
|
||||
if isAutoSizeHeight then
|
||||
lRow.RowHeightType := rhtAuto else
|
||||
lRow.RowHeightType := rhtCustom;
|
||||
lRow.Height := hpts;
|
||||
|
||||
{ Row format }
|
||||
lRow.FormatIndex := 0;
|
||||
hasFormat := flags and $00000080 <> 0;
|
||||
// If this bit is set then the record contains an xf index.
|
||||
if hasFormat then begin
|
||||
xf := (flags and $0FFF0000) shr 16;
|
||||
if xf = 15 then hasFormat := false;
|
||||
end;
|
||||
if hasFormat then begin
|
||||
// Find the format with ID xf
|
||||
idx := FCellFormatList.FindIndexOfID(xf);
|
||||
if idx > -1 then begin
|
||||
fmt := FCellFormatList.Items[idx];
|
||||
lRow.FormatIndex := FWorkbook.AddCellFormat(fmt^);
|
||||
end;
|
||||
end;
|
||||
|
||||
// We only create a row record for fpspreadsheet if the row has a
|
||||
// non-standard height (i.e. different from default row height).
|
||||
if isNonDefaultHeight then begin
|
||||
lRow := FWorksheet.GetRow(WordLEToN(rowrec.RowIndex));
|
||||
if isAutoSizeHeight then
|
||||
lRow^.RowHeightType := rhtAuto else
|
||||
lRow^.RowHeightType := rhtCustom;
|
||||
lRow^.Height := hpts;
|
||||
end;
|
||||
// non-standard height (i.e. different from default row height) or format.
|
||||
if isNonDefaultHeight or hasFormat then
|
||||
FWorksheet.WriteRowInfo(rowrec.RowIndex, lRow);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user