diff --git a/components/fpspreadsheet/examples/excel5demo/excel5write.lpr b/components/fpspreadsheet/examples/excel5demo/excel5write.lpr
index 0f950117c..716730d87 100644
--- a/components/fpspreadsheet/examples/excel5demo/excel5write.lpr
+++ b/components/fpspreadsheet/examples/excel5demo/excel5write.lpr
@@ -33,7 +33,7 @@ begin
// Create the spreadsheet
MyWorkbook := TsWorkbook.Create;
- MyWorksheet := MyWorkbook.AddWorksheet(Str_Worksheet1);
+ MyWorksheet := MyWorkbook.AddWorksheet(UTF8ToAnsi(Str_Worksheet1));
MyWorksheet.Options := MyWorksheet.Options + [soHasFrozenPanes];
MyWorksheet.LeftPaneWidth := 1;
diff --git a/components/fpspreadsheet/examples/excel8demo/excel8write.lpr b/components/fpspreadsheet/examples/excel8demo/excel8write.lpr
index 248df45ec..95276f26b 100644
--- a/components/fpspreadsheet/examples/excel8demo/excel8write.lpr
+++ b/components/fpspreadsheet/examples/excel8demo/excel8write.lpr
@@ -56,9 +56,10 @@ begin
MyWorksheet.LeftPaneWidth := 20*72*2; // 72 pt = inch --> 2 inches = 5 cm
}
// Write some cells
- MyWorksheet.WriteNumber(0, 1, 2.0);// B1
- MyWorksheet.WriteNumber(0, 2, 3.0);// C1
- MyWorksheet.WriteNumber(0, 3, 4.0);// D1
+ MyWorksheet.WriteNumber(0, 0, 1.0); // A1
+ MyWorksheet.WriteNumber(0, 1, 2.0); // B1
+ MyWorksheet.WriteNumber(0, 2, 3.0); // C1
+ MyWorksheet.WriteNumber(0, 3, 4.0); // D1
MyWorksheet.WriteUTF8Text(4, 2, Str_Total);// C5
MyWorksheet.WriteNumber(4, 3, 10); // D5
diff --git a/components/fpspreadsheet/examples/fpsgrid/fpsgrid.lpi b/components/fpspreadsheet/examples/fpsgrid/fpsgrid.lpi
index 3be3feee6..ed788ad24 100644
--- a/components/fpspreadsheet/examples/fpsgrid/fpsgrid.lpi
+++ b/components/fpspreadsheet/examples/fpsgrid/fpsgrid.lpi
@@ -48,6 +48,9 @@
+
+
+
@@ -79,6 +82,9 @@
+
+
+
@@ -137,6 +143,9 @@
+
+
+
diff --git a/components/fpspreadsheet/examples/spready/mainform.lfm b/components/fpspreadsheet/examples/spready/mainform.lfm
index 12c90740b..d24057e00 100644
--- a/components/fpspreadsheet/examples/spready/mainform.lfm
+++ b/components/fpspreadsheet/examples/spready/mainform.lfm
@@ -967,10 +967,6 @@ object Form1: TForm1
}
end
end
- object MnuWordwrap: TMenuItem
- Action = AcWordwrap
- AutoCheck = True
- end
object MnuNumberFormat: TMenuItem
Caption = 'Number format'
object MenuItem33: TMenuItem
@@ -1014,6 +1010,9 @@ object Form1: TForm1
Action = AcNFShortDateTime
AutoCheck = True
end
+ object MenuItem60: TMenuItem
+ Caption = '-'
+ end
object MenuItem52: TMenuItem
Action = AcNFShortDate
AutoCheck = True
@@ -1030,6 +1029,9 @@ object Form1: TForm1
Action = AcNFCustomMY
AutoCheck = True
end
+ object MenuItem61: TMenuItem
+ Caption = '-'
+ end
object MenuItem56: TMenuItem
Action = AcNFShortTime
AutoCheck = True
@@ -1046,6 +1048,17 @@ object Form1: TForm1
Action = AcNFLongTimeAM
AutoCheck = True
end
+ object MenuItem62: TMenuItem
+ Caption = '-'
+ end
+ object MenuItem63: TMenuItem
+ Action = AcNFTimeInterval
+ AutoCheck = True
+ end
+ end
+ object MnuWordwrap: TMenuItem
+ Action = AcWordwrap
+ AutoCheck = True
end
end
end
diff --git a/components/fpspreadsheet/examples/spready/mainform.pas b/components/fpspreadsheet/examples/spready/mainform.pas
index 68810ce75..885e2d36a 100644
--- a/components/fpspreadsheet/examples/spready/mainform.pas
+++ b/components/fpspreadsheet/examples/spready/mainform.pas
@@ -142,6 +142,10 @@ type
MenuItem57: TMenuItem;
MenuItem58: TMenuItem;
MenuItem59: TMenuItem;
+ MenuItem60: TMenuItem;
+ MenuItem61: TMenuItem;
+ MenuItem62: TMenuItem;
+ MenuItem63: TMenuItem;
MnuFmtDateTimeMSZ: TMenuItem;
MnuTimeInterval: TMenuItem;
MnuShortTimeAM: TMenuItem;
@@ -281,6 +285,8 @@ uses
fpcanvas, fpsutils, fpsnumformatparser;
const
+ DROPDOWN_COUNT = 24;
+
HORALIGN_TAG = 100;
VERTALIGN_TAG = 110;
TEXTROT_TAG = 130;
@@ -305,6 +311,7 @@ const
TB_INNER_BORDER = $0800;
// Use a combination of these bits for the "Tag" of the Border actions - see FormCreate.
+
{ TForm1 }
procedure TForm1.AcEditExecute(Sender: TObject);
@@ -695,6 +702,8 @@ begin
FormatToolbar.Height := FontCombobox.Height + 2*FontCombobox.Top;
FormatToolbar.ButtonHeight := FormatToolbar.Height - 4;
+ CbBackgroundCOlor.Height := FontCombobox.Height;
+
// Populate font combobox
FontCombobox.Items.Assign(Screen.Fonts);
@@ -714,6 +723,10 @@ begin
AcBorderOuter.Tag := LEFT_BORDER_THIN + RIGHT_BORDER_THIN + TOP_BORDER_THIN + BOTTOM_BORDER_THIN;
AcBorderOuterMedium.Tag := LEFT_BORDER_THICK + RIGHT_BORDER_THICK + TOP_BORDER_THICK + BOTTOM_BORDER_THICK;
AcBorderAll.Tag := AcBorderOuter.Tag + AcBorderInner.Tag;
+
+ FontCombobox.DropDownCount := DROPDOWN_COUNT;
+ FontSizeCombobox.DropDownCount := DROPDOWN_COUNT;
+ CbBackgroundColor.DropDownCount := DROPDOWN_COUNT;
end;
procedure TForm1.LoadFile(const AFileName: String);
diff --git a/components/fpspreadsheet/examples/spready/spready.lpi b/components/fpspreadsheet/examples/spready/spready.lpi
index 431986deb..e116128ee 100644
--- a/components/fpspreadsheet/examples/spready/spready.lpi
+++ b/components/fpspreadsheet/examples/spready/spready.lpi
@@ -47,6 +47,9 @@
+
+
+
@@ -78,6 +81,9 @@
+
+
+
@@ -136,6 +142,9 @@
+
+
+
diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas
index 4cea0f812..a4c6a2c8a 100755
--- a/components/fpspreadsheet/fpspreadsheet.pas
+++ b/components/fpspreadsheet/fpspreadsheet.pas
@@ -301,6 +301,7 @@ const
// Will be removed sooner or later...
scRGBColor = $FFFF;
+ scTransparent = $FFFE;
scNotDefined = $FFFF;
type
@@ -472,7 +473,7 @@ type
FOnChangeCell: TsCellEvent;
FOnChangeFont: TsCellEvent;
function GetFormatSettings: TFormatSettings;
- procedure RemoveCallback(data, arg: pointer);
+ procedure RemoveCallback(data, arg: pointer);
protected
procedure ChangedCell(ARow, ACol: Cardinal);
@@ -2307,12 +2308,33 @@ begin
ChangedCell(ARow, ACol);
end;
+{@@
+ Writes data defined as a string into a cell. Depending on the structure of the
+ string, the worksheet tries to guess whether it is a number, a date/time or
+ a text and calls the corresponding writing method.
+
+ @param ARow Row index of the cell
+ @param ACol Column index of the cell
+ @param AValue Value to be written into the cell given as a string. Depending
+ on the structure of the string, however, the value is written
+ as a number, a date/time or a text.
+}
procedure TsWorksheet.WriteCellValueAsString(ARow, ACol: Cardinal;
AValue: String);
begin
WriteCellValueAsString(GetCell(ARow, ACol), AValue);
end;
+{@@
+ Writes data defined as a string into a cell. Depending on the structure of the
+ string, the worksheet tries to guess whether it is a number, a date/time or
+ a text and calls the corresponding writing method.
+
+ @param ACell Poiner to the cell
+ @param AValue Value to be written into the cell given as a string. Depending
+ on the structure of the string, however, the value is written
+ as a number, a date/time or a text.
+}
procedure TsWorksheet.WriteCellValueAsString(ACell: PCell; AValue: String);
var
isPercent: Boolean;
@@ -2716,12 +2738,18 @@ procedure TsWorksheet.WriteNumberFormat(ACell: PCell;
begin
if ACell = nil then
exit;
- Include(ACell^.UsedFormattingFields, uffNumberFormat);
+
ACell^.NumberFormat := ANumberFormat;
- if (AFormatString = '') then
- ACell^.NumberFormatStr := BuildNumberFormatString(ANumberFormat, Workbook.FormatSettings)
- else
- ACell^.NumberFormatStr := AFormatString;
+ if ANumberFormat <> nfGeneral then begin
+ Include(ACell^.UsedFormattingFields, uffNumberFormat);
+ if (AFormatString = '') then
+ ACell^.NumberFormatStr := BuildNumberFormatString(ANumberFormat, Workbook.FormatSettings)
+ else
+ ACell^.NumberFormatStr := AFormatString;
+ end else begin
+ Exclude(ACell^.UsedFormattingFields, uffNumberFormat);
+ ACell^.NumberFormatStr := '';
+ end;
ChangedCell(ACell^.Row, ACell^.Col);
end;
@@ -2932,7 +2960,8 @@ end;
@param ARow Row index of the cell
@param ACol Column index of the cell
@param AColor Index of the new background color into the workbook's
- color palette.
+ color palette. Use the color index scTransparent to
+ erase an existing background color.
}
procedure TsWorksheet.WriteBackgroundColor(ARow, ACol: Cardinal;
AColor: TsColor);
@@ -2940,8 +2969,12 @@ var
ACell: PCell;
begin
ACell := GetCell(ARow, ACol);
- ACell^.UsedFormattingFields := ACell^.UsedFormattingFields + [uffBackgroundColor];
- ACell^.BackgroundColor := AColor;
+ if AColor = scTransparent then
+ Exclude(ACell^.UsedFormattingFields, uffBackgroundColor)
+ else begin
+ Include(ACell^.UsedFormattingFields, uffBackgroundColor);
+ ACell^.BackgroundColor := AColor;
+ end;
ChangedCell(ARow, ACol);
end;
@@ -3086,7 +3119,7 @@ var
lCell: PCell;
begin
lCell := GetCell(ARow, ACol);
- lCell^.UsedFormattingFields := lCell^.UsedFormattingFields + [uffHorAlign];
+ Include(lCell^.UsedFormattingFields, uffHorAlign);
lCell^.HorAlignment := AValue;
ChangedCell(ARow, ACol);
end;
@@ -3104,7 +3137,7 @@ var
lCell: PCell;
begin
lCell := GetCell(ARow, ACol);
- lCell^.UsedFormattingFields := lCell^.UsedFormattingFields + [uffVertAlign];
+ Include(lCell^.UsedFormattingFields, uffVertAlign);
lCell^.VertAlignment := AValue;
ChangedCell(ARow, ACol);
end;
diff --git a/components/fpspreadsheet/fpspreadsheetgrid.pas b/components/fpspreadsheet/fpspreadsheetgrid.pas
index 3b675d6ba..756d1a2ae 100644
--- a/components/fpspreadsheet/fpspreadsheetgrid.pas
+++ b/components/fpspreadsheet/fpspreadsheetgrid.pas
@@ -113,6 +113,7 @@ type
procedure DrawCellBorders; overload;
procedure DrawCellBorders(ACol, ARow: Integer; ARect: TRect); overload;
procedure DrawFocusRect(aCol,aRow:Integer; ARect:TRect); override;
+ procedure DrawFrozenPaneBorders(ARect: TRect);
procedure DrawSelection;
procedure DrawTextInCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); override;
function GetBorderStyle(ACol, ARow, ADeltaCol, ADeltaRow: Integer;
@@ -478,6 +479,11 @@ end;
{ TsCustomWorksheetGrid }
+{@@
+ Constructor of the grid. Activates the display of column and row headers
+ and creates an internal "CellFont". Creates a given number of empty rows
+ and columns.
+}
constructor TsCustomWorksheetGrid.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
@@ -487,6 +493,9 @@ begin
FCellFont := TFont.Create;
end;
+{@@
+ Destructor of the grid: Destroys the workbook and the internal CellFont
+}
destructor TsCustomWorksheetGrid.Destroy;
begin
FreeAndNil(FWorkbook);
@@ -494,15 +503,24 @@ begin
inherited Destroy;
end;
-{ Suppresses unnecessary repaints. }
+{@@
+ The BeginUpdate/EndUpdate pair suppresses unnecessary painting of the grid.
+ Call BeginUpdate to stop refreshing the grid, and call EndUpdate to release
+ the lock and to repaint the grid again.
+}
procedure TsCustomWorksheetGrid.BeginUpdate;
begin
inc(FLockCount);
end;
-{ Converts the column width, given in "characters" of the default font, to pixels
- All chars are assumed to have the same width defined by the "0".
- Therefore, this calculation is only approximate. }
+{@@
+ Converts the column width, given in "characters" of the default font, to pixels
+ All chars are assumed to have the same width defined by the width of the
+ "0" character. Therefore, this calculation is only approximate.
+
+ @param AWidth Width of a column given as "character count".
+ @return Column width in pixels.
+}
function TsCustomWorksheetGrid.CalcColWidth(AWidth: Single): Integer;
var
w0: Integer;
@@ -512,9 +530,14 @@ begin
Result := Round(AWidth * w0);
end;
-{ Finds the max cell height per row and uses this to define the RowHeights[].
- Returns DefaultRowHeight if the row does not contain any cells.
- ARow is a grid row index. }
+{@@
+ Finds the maximum cell height per row and uses this to define the RowHeights[].
+ Returns DefaultRowHeight if the row does not contain any cells, or if the
+ worksheet does not have a TRow record for this particular row.
+ ARow is a grid row index.
+
+ @param ARow Index of the row, in grid units
+}
function TsCustomWorksheetGrid.CalcAutoRowHeight(ARow: Integer): Integer;
var
c: Integer;
@@ -529,7 +552,14 @@ begin
Result := h;
end;
-{ Converts the row height (from a worksheet row), given in lines, to pixels }
+{@@
+ Converts the row height (from a worksheet row record), given in lines, to
+ pixels as needed by the grid
+
+ @param AHeight Row height expressed as default font line count from the
+ worksheet
+ @result Row height in pixels
+}
function TsCustomWorksheetGrid.CalcRowHeight(AHeight: Single): Integer;
var
h_pts: Single;
@@ -538,15 +568,32 @@ begin
Result := PtsToPX(h_pts, Screen.PixelsPerInch) + 4;
end;
+{@@
+ Handler for the event OnChangeCell fired by the worksheet when the contents
+ of formatting of a cell has changed.
+ As a consequence, the grid may have to update the cell.
+ Row/Col coordinates are in worksheet units here!
+
+ @param ASender Sender of the event OnChangeFont (the worksheet)
+ @param ARow Row index of the changed cell, in worksheet units!
+ @param ACol Column index of the changed cell, in worksheet units!
+}
procedure TsCustomWorksheetGrid.ChangedCellHandler(ASender: TObject; ARow, ACol:Cardinal);
begin
Unused(ASender, ARow, ACol);
if FLockCount = 0 then Invalidate;
end;
-{ Handler for the event that the font has changed in a given cell.
- As a consequence, the row height may have to be adapted.
- Row/Col coordinates are in worksheet units here! }
+{@@
+ Handler for the event OnChangeFont fired by the worksheet when the font has
+ changed in a cell.
+ As a consequence, the grid may have to update the row height.
+ Row/Col coordinates are in worksheet units here!
+
+ @param ASender Sender of the event OnChangeFont (the worksheet)
+ @param ARow Row index of the cell with the changed font, in worksheet units!
+ @param ACol Column index of the cell with the changed font, in worksheet units!
+}
procedure TsCustomWorksheetGrid.ChangedFontHandler(ASender: TObject; ARow, ACol: Cardinal);
var
lRow: PRow;
@@ -564,7 +611,12 @@ begin
end;
end;
-{ Converts a spreadsheet font to a font used for painting (TCanvas.Font). }
+{@@
+ Converts a spreadsheet font to a font used for painting (TCanvas.Font).
+
+ @param sFont Font as used by fpspreadsheet (input)
+ @param AFont Font as used by TCanvas for painting (output)
+}
procedure TsCustomWorksheetGrid.Convert_sFont_to_Font(sFont: TsFont; AFont: TFont);
begin
if Assigned(AFont) and Assigned(sFont) then begin
@@ -579,7 +631,12 @@ begin
end;
end;
-{ Converts a font used for painting (TCanvas.Font) to a spreadsheet font }
+{@@
+ Converts a font used for painting (TCanvas.Font) to a spreadsheet font
+
+ @param AFont Font as used by TCanvas for painting (input)
+ @param sFont Font as used by fpspreadsheet (output)
+}
procedure TsCustomWorksheetGrid.Convert_Font_to_sFont(AFont: TFont; sFont: TsFont);
begin
if Assigned(AFont) and Assigned(sFont) then begin
@@ -594,8 +651,20 @@ begin
end;
end;
-{ Is overridden to show "frozen" cells in the same style as normal cells.
- "Frozen" cells are internally "fixed" cells of the grid. }
+{@@
+ This is one of the main painting methods inherited from TsCustomGrid. It is
+ overridden here to achieve the feature of "frozen" cells which should be
+ painted in the same style as normal cells.
+
+ Internally, "frozen" cells are "fixed" cells of the grid. Therefore, it is
+ not possible to select any cell within the frozen panes - in contrast to the
+ standard spreadsheet applications.
+
+ @param ACol Column index of the cell being drawn
+ @param ARow Row index of the cell beging drawn
+ @param ARect Rectangle, in grid pixels, covered by the cell
+ @param AState Grid drawing state, as defined by TsCustomGrid
+}
procedure TsCustomWorksheetGrid.DefaultDrawCell(aCol, aRow: Integer; var aRect: TRect;
AState: TGridDrawState);
var
@@ -614,7 +683,6 @@ begin
end;
if wasFixed then begin
- wasFixed := true; // ?????
AState := AState - [gdFixed];
Canvas.Brush.Color := clWindow;
end;
@@ -627,8 +695,14 @@ begin
end;
end;
-{ Adjusts the grid's canvas before painting a given cell. Considers, e.g.
- background color, horizontal alignment, vertical alignment, etc. }
+{@@
+ Adjusts the grid's canvas before painting a given cell. Considers, e.g.
+ background color, horizontal alignment, vertical alignment, etc.
+
+ @param ACol Column index of the cell being painted
+ @param ARow Row index of the cell being painted
+ @param AState Grid drawing state -- see TsCustomGrid.
+}
procedure TsCustomWorksheetGrid.DoPrepareCanvas(ACol, ARow: Integer;
AState: TGridDrawState);
var
@@ -711,10 +785,13 @@ begin
inherited DoPrepareCanvas(ACol, ARow, AState);
end;
-{ Is overridden in order to paint the cell borders and the selection rectangle.
- Both features can extend into the neighbor cells and thus are clipped at the
- cell borders by the standard painting mechanism. In DrawAllRows, clipping at
- cell borders is no longer active. }
+{@@
+ This method is inherited from TsCustomGrid, but is overridden here in order
+ to paint the cell borders and the selection rectangle.
+ Both features can extend into the neighbor cells and thus would be clipped
+ at the cell borders by the standard painting mechanism. At the time when
+ DrawAllRows is called, however, clipping at cell borders is no longer active.
+}
procedure TsCustomWorksheetGrid.DrawAllRows;
var
cliprect: TRect;
@@ -731,6 +808,9 @@ begin
ColRowToOffset(True, True, FixedCols-1, tmp, cliprect.Left);
if FixedRows > 0 then
ColRowToOffset(False, True, FixedRows-1, tmp, cliprect.Top);
+
+ DrawFrozenPaneBorders(clipRect);
+
rgn := CreateRectRgn(cliprect.Left, cliprect.top, cliprect.Right, cliprect.Bottom);
SelectClipRgn(Canvas.Handle, Rgn);
@@ -743,7 +823,9 @@ begin
end;
end;
-{ Draws the borders of all cells. }
+{@@
+ Draws the borders of all cells. Calls DrawCellBorder for each individual cell.
+}
procedure TsCustomWorksheetGrid.DrawCellBorders;
var
cell: PCell;
@@ -764,10 +846,16 @@ begin
end;
end;
-{ Draws the border lines around a given cell. Note that when this procedure is
+{@@
+ Draws the border lines around a given cell. Note that when this procedure is
called the output is clipped by the cell rectangle, but thick and double
border styles extend into the neighbor cell. Therefore, these border lines
- are drawn in parts. }
+ are drawn in parts.
+
+ @param ACol Column Index
+ @param ARow Row index
+ @param ARect Rectangle in pixels occupied by the cell.
+}
procedure TsCustomWorksheetGrid.DrawCellBorders(ACol, ARow: Integer; ARect: TRect);
procedure DrawBorderLine(ACoord: Integer; ARect: TRect; IsHor: Boolean;
@@ -858,7 +946,29 @@ begin
// Nothing do to
end;
-{ Draws the selection rectangle, 3 pixels wide as in Excel. }
+{@@
+ Draws a solid line along the borders of frozen panes.
+
+ @param ARect This rectangle indicates the area with movable cells. If the
+ grid has frozen panes a black line is drawn along the upper
+ and/or left edge of this rectangle.
+}
+procedure TsCustomWorksheetGrid.DrawFrozenPaneBorders(ARect: TRect);
+begin
+ if (soHasFrozenPanes in FWorksheet.Options) then begin
+ Canvas.Pen.Style := psSolid;
+ Canvas.Pen.Color := clBlack;
+ Canvas.Pen.Width := 1;
+ if FFrozenRows > 0 then
+ Canvas.Line(ARect.Left, ARect.Top, ARect.Right, ARect.Top);
+ if FFrozenCols > 0 then
+ Canvas.Line(ARect.Left, ARect.Top, ARect.Left, ARect.Bottom);
+ end;
+end;
+
+{@@
+ Draws the selection rectangle, 3 pixels wide as in Excel.
+}
procedure TsCustomWorksheetGrid.DrawSelection;
var
P1, P2: TPoint;
@@ -884,9 +994,16 @@ begin
Canvas.Rectangle(P1.X, P1.Y, P2.X, P2.Y);
end;
-{ Draws the cell text. Calls "GetCellText" to determine the text in the cell.
+{@@
+ Draws the cell text. Calls "GetCellText" to determine the text in the cell.
Takes care of horizontal and vertical text alignment, text rotation and
- text wrapping }
+ text wrapping
+
+ @param ACol Column index of the cell
+ @param ARow Row index of the cell
+ @param ARect Rectangle in pixels occupied by the cell.
+ @param AState Drawing state of the grid -- see TCustomGrid
+}
procedure TsCustomWorksheetGrid.DrawTextInCell(ACol, ARow: Integer; ARect: TRect;
AState: TGridDrawState);
var
@@ -970,6 +1087,12 @@ begin
txtRot, wrapped, false);
end;
+{@@
+ Is called when editing of a cell is completed. Determines the worksheet cell
+ and writes the text into the worksheet. Tries to keep the format of the cell,
+ but if it is a new cell, or the content type has changed, tries to figure out
+ the content type (number, date/time, text).
+}
procedure TsCustomWorksheetGrid.EditingDone;
var
oldText: String;
@@ -989,14 +1112,24 @@ begin
FEditing := false;
end;
+{@@
+ The BeginUpdate/EndUpdate pair suppresses unnecessary painting of the grid.
+ Call BeginUpdate to stop refreshing the grid, and call EndUpdate to release
+ the lock and to repaint the grid again.
+}
procedure TsCustomWorksheetGrid.EndUpdate;
begin
dec(FLockCount);
if FLockCount = 0 then Invalidate;
end;
-{ Copies the borders of a cell to its neighbors. This avoids the nightmare of
- changing borders due to border conflicts of adjacent cells. }
+{@@
+ Copies the borders of a cell to its neighbors. This avoids the nightmare of
+ changing borders due to border conflicts of adjacent cells.
+
+ @param ACol Column index of the cell
+ @param ARow Row index of the cell
+}
procedure TsCustomWorksheetGrid.FixNeighborCellBorders(ACol, ARow: Integer);
procedure SetNeighborBorder(NewRow, NewCol: Integer;
@@ -1032,10 +1165,14 @@ begin
end;
end;
-{ The "colors" used by the spreadsheet are indexes into the workbook's color
+{@@
+ The "colors" used by the spreadsheet are indexes into the workbook's color
palette. If the user wants to set a color to a particular rgb value this is
not possible in general. The method FindNearestPaletteIndex finds the bast
- matching color in the palette. }
+ matching color in the palette.
+
+ @param AColor Color index into the workbook's palette
+}
function TsCustomWorksheetGrid.FindNearestPaletteIndex(AColor: TColor): TsColor;
procedure ColorToHSL(RGB: TColor; out H, S, L : double);
@@ -1121,6 +1258,14 @@ begin
end;
end;
+{@@
+ Returns the background color of a cell. The color is given as an index into
+ the workbook's color palette.
+
+ @param ACol Column index of the cell
+ @param ARow Row index of the cell
+ @result Color index of the cell's background color.
+}
function TsCustomWorksheetGrid.GetBackgroundColor(ACol, ARow: Integer): TsColor;
var
cell: PCell;
@@ -1133,6 +1278,17 @@ begin
end;
end;
+{@@
+ Returns the background color of a cell range defined by a rectangle. The color
+ is given as an index into the workbook's color palette. If the colors are
+ different from cell to cell the value scUndefined is returned.
+
+ @param ARect Cell range defined as a rectangle: Left/Top refers to the cell
+ in the left/top corner of the selection, Right/Bottom to the
+ right/bottom corner.
+ @return Color index common to all cells within the selection. If the cells'
+ background colors are different the value scUndefined is returned.
+}
function TsCustomWorksheetGrid.GetBackgroundColors(ARect: TGridRect): TsColor;
var
c, r: Integer;
@@ -1150,6 +1306,13 @@ begin
end;
end;
+{@@
+ Returns the cell borders which are drawn around a given cell.
+
+ @param ACol Column index of the cell
+ @param ARow Row index of the cell
+ @return Set with flags indicating where borders are drawn (top/left/right/bottom)
+}
function TsCustomWorksheetGrid.GetCellBorder(ACol, ARow: Integer): TsCellBorders;
var
cell: PCell;
@@ -1162,6 +1325,14 @@ begin
end;
end;
+{@@
+ Returns the cell borders which are drawn around a given rectangular cell range.
+
+ @param ARect Rectangle defining the range of cell.
+ @return Set with flags indicating where borders are drawn (top/left/right/bottom)
+ If the individual cells within the range have different borders an
+ empty set is returned.
+}
function TsCustomWorksheetGrid.GetCellBorders(ARect: TGridRect): TsCellBorders;
var
c, r: Integer;
diff --git a/components/fpspreadsheet/xlsbiff2.pas b/components/fpspreadsheet/xlsbiff2.pas
index 1990e5c26..5052664bb 100755
--- a/components/fpspreadsheet/xlsbiff2.pas
+++ b/components/fpspreadsheet/xlsbiff2.pas
@@ -803,9 +803,9 @@ begin
// Background color not supported, only shaded background
if xf.HorAlign_Border_Background and $80 <> 0 then
- lData.BackgroundColor := 1 // shaded background = "true"
+ lData.BackgroundColor := 1 // encodes "shaded background = true"
else
- ldata.BackgroundColor := 0; // shaded background = "false"
+ ldata.BackgroundColor := 0; // encodes "shaded background = false"
// Add the decoded data to the list
FXFList.Add(lData);
diff --git a/components/fpspreadsheet/xlsbiff5.pas b/components/fpspreadsheet/xlsbiff5.pas
index 94ed26cc8..9cf17347f 100755
--- a/components/fpspreadsheet/xlsbiff5.pas
+++ b/components/fpspreadsheet/xlsbiff5.pas
@@ -382,7 +382,8 @@ begin
begin
len := Length(Boundsheets);
SetLength(Boundsheets, len + 1);
- Boundsheets[len] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i).Name);
+ Boundsheets[len] := WriteBoundsheet(AStream, UTF8ToAnsi(Workbook.GetWorksheetByIndex(i).Name));
+ // BIFF8 does not support unicode --> Need UTF8ToAnsi !
end;
WriteEOF(AStream);
@@ -1419,6 +1420,7 @@ var
xf: TXFRecord;
b: Byte;
dw: DWord;
+ fill: Word;
begin
AStream.ReadBuffer(xf, SizeOf(xf));
@@ -1489,8 +1491,14 @@ begin
lData.BorderStyles[cbNorth].Color := (xf.Border_Background_2 and MASK_XF_BORDER_TOP_COLOR) shr 9;
lData.BorderStyles[cbSouth].Color := (xf.Border_Background_1 and MASK_XF_BORDER_BOTTOM_COLOR) shr 25;
+ // Background fill style
+ fill := (xf.Border_Background_1 and MASK_XF_BKGR_FILLPATTERN) shr 16;
+
// Background color
- lData.BackgroundColor := xf.Border_Background_1 AND MASK_XF_BKGR_PATTERN_COLOR;
+ if fill = 0 then
+ lData.BackgroundColor := scTransparent
+ else
+ lData.BackgroundColor := xf.Border_Background_1 and MASK_XF_BKGR_PATTERN_COLOR;
// Add the XF to the list
FXFList.Add(lData);
diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas
index 17a48fa77..f1ad4d31c 100755
--- a/components/fpspreadsheet/xlsbiff8.pas
+++ b/components/fpspreadsheet/xlsbiff8.pas
@@ -266,6 +266,9 @@ const
MASK_XF_BORDER_TOP_COLOR = $0000007F;
MASK_XF_BORDER_BOTTOM_COLOR = $00003F80;
+ { XF CELL BACKGROUND PATTERN }
+ MASK_XF_BACKGROUND_PATTERN = $FC000000;
+
TEXT_ROTATIONS: Array[TsTextRotation] of Byte = (
XF_ROTATION_HORIZONTAL,
XF_ROTATION_90DEG_CW,
@@ -1833,6 +1836,7 @@ var
xf: TXFRecord;
b: Byte;
dw: DWord;
+ fill: Integer;
begin
AStream.ReadBuffer(xf, SizeOf(xf));
@@ -1902,9 +1906,15 @@ begin
lData.BorderStyles[cbNorth].Color := (xf.Border_Background_2 and MASK_XF_BORDER_TOP_COLOR);
lData.BorderStyles[cbSouth].Color := (xf.Border_Background_2 and MASK_XF_BORDER_BOTTOM_COLOR) shr 7;
- // Background color;
+ // Background fill pattern
+ fill := (xf.Border_Background_2 and MASK_XF_BACKGROUND_PATTERN) shr 26;
+
+ // Background color
xf.Border_Background_3 := DWordLEToN(xf.Border_Background_3);
- lData.BackgroundColor := xf.Border_Background_3 AND $007F;
+ if fill <> 0 then
+ lData.BackgroundColor := xf.Border_Background_3 and $007F
+ else
+ lData.BackgroundColor := scTransparent; // this means "no fill"
// Add the XF to the list
FXFList.Add(lData);
diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas
index 46b3a9efb..f1a96195e 100644
--- a/components/fpspreadsheet/xlscommon.pas
+++ b/components/fpspreadsheet/xlscommon.pas
@@ -840,10 +840,11 @@ begin
Exclude(lCell^.UsedFormattingFields, uffBorder);
// Background color
- if XFData.BackgroundColor <> 0 then begin
+ if XFData.BackgroundColor <> scTransparent then begin
Include(lCell^.UsedFormattingFields, uffBackgroundColor);
lCell^.BackgroundColor := XFData.BackgroundColor;
- end;
+ end else
+ Exclude(lCell^.UsedFormattingFields, uffBackgroundColor);
end;
end;