2014-11-08 23:41:35 +00:00
|
|
|
{ fpspreadsheetgrid }
|
2010-05-01 18:10:38 +00:00
|
|
|
|
2014-11-08 23:41:35 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2015-01-06 17:42:54 +00:00
|
|
|
Grid component which can load and write data from/to FPSpreadsheet documents.
|
2014-11-08 23:41:35 +00:00
|
|
|
Can either be used alone or in combination with a TsWorkbookSource component.
|
|
|
|
The latter case requires less written code.
|
2010-05-01 18:10:38 +00:00
|
|
|
|
2014-04-20 20:31:36 +00:00
|
|
|
AUTHORS: Felipe Monteiro de Carvalho, Werner Pamler
|
2014-11-08 23:41:35 +00:00
|
|
|
|
|
|
|
LICENSE: See the file COPYING.modifiedLGPL.txt, included in the Lazarus
|
|
|
|
distribution, for details about the license.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
unit fpspreadsheetgrid;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
2015-03-13 14:33:55 +00:00
|
|
|
{$I fps.inc}
|
2014-05-08 22:44:52 +00:00
|
|
|
|
|
|
|
{ To do:
|
|
|
|
- When Lazarus 1.4 comes out remove the workaround for the RGB2HLS bug in
|
|
|
|
FindNearestPaletteIndex.
|
2014-06-06 08:48:22 +00:00
|
|
|
- Arial bold is not shown as such if loaded from ods
|
2015-04-18 14:58:38 +00:00
|
|
|
- Background color of first cell is ignored.
|
|
|
|
|
|
|
|
- Enter 1234567890 into a cell. reduce col width with mouse. Immediately
|
|
|
|
before display becomes #### there is 11E09 in the cell - it should be 1E09.
|
|
|
|
Cell not correctly erased? }
|
2009-10-06 19:25:18 +00:00
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2015-02-23 18:50:29 +00:00
|
|
|
Classes, SysUtils, LResources,
|
|
|
|
Forms, Controls, Graphics, Dialogs, Grids, ExtCtrls,
|
2015-01-17 22:57:23 +00:00
|
|
|
fpstypes, fpspreadsheet, fpspreadsheetctrls;
|
2009-10-06 19:25:18 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
|
|
|
|
{ TsCustomWorksheetGrid }
|
|
|
|
|
2015-02-22 23:38:28 +00:00
|
|
|
TsHyperlinkClickEvent = procedure(Sender: TObject;
|
|
|
|
const AHyperlink: TsHyperlink) of object;
|
|
|
|
|
2014-12-16 18:28:41 +00:00
|
|
|
{@@ TsCustomWorksheetGrid is the ancestor of TsWorksheetGrid and is able to
|
2014-11-16 21:59:52 +00:00
|
|
|
display spreadsheet data along with their formatting. }
|
2015-01-06 17:42:54 +00:00
|
|
|
TsCustomWorksheetGrid = class(TCustomDrawGrid, IsSpreadsheetControl)
|
2009-10-06 19:25:18 +00:00
|
|
|
private
|
2014-04-29 21:58:48 +00:00
|
|
|
{ Private declarations }
|
2014-11-03 15:34:57 +00:00
|
|
|
FWorkbookSource: TsWorkbookSource;
|
|
|
|
FOwnedWorkbook: TsWorkbook;
|
|
|
|
FOwnsWorkbook: Boolean;
|
|
|
|
FOwnedWorksheet: TsWorksheet;
|
2014-05-03 21:27:31 +00:00
|
|
|
FHeaderCount: Integer;
|
2014-05-28 21:26:38 +00:00
|
|
|
FInitColCount: Integer;
|
|
|
|
FInitRowCount: Integer;
|
2014-05-04 18:07:54 +00:00
|
|
|
FFrozenCols: Integer;
|
|
|
|
FFrozenRows: Integer;
|
2014-05-07 22:44:00 +00:00
|
|
|
FEditText: String;
|
2014-05-08 15:54:29 +00:00
|
|
|
FOldEditText: String;
|
2014-05-07 22:44:00 +00:00
|
|
|
FLockCount: Integer;
|
2015-03-16 00:05:56 +00:00
|
|
|
FLockSetup: Integer;
|
2014-05-07 22:44:00 +00:00
|
|
|
FEditing: Boolean;
|
2014-05-11 16:16:59 +00:00
|
|
|
FCellFont: TFont;
|
2014-08-13 14:05:29 +00:00
|
|
|
FAutoCalc: Boolean;
|
2014-09-14 20:40:58 +00:00
|
|
|
FTextOverflow: Boolean;
|
2014-05-23 23:13:49 +00:00
|
|
|
FReadFormulas: Boolean;
|
2014-09-10 19:54:06 +00:00
|
|
|
FDrawingCell: PCell;
|
2014-09-25 10:36:17 +00:00
|
|
|
FTextOverflowing: Boolean;
|
2014-11-18 10:19:33 +00:00
|
|
|
FEnhEditMode: Boolean;
|
2015-02-23 18:50:29 +00:00
|
|
|
FHyperlinkTimer: TTimer;
|
2015-03-02 21:20:00 +00:00
|
|
|
FHyperlinkCell: PCell; // Selected cell if it stores a hyperlink
|
2015-02-22 23:38:28 +00:00
|
|
|
FOnClickHyperlink: TsHyperlinkClickEvent;
|
2014-05-03 20:12:44 +00:00
|
|
|
function CalcAutoRowHeight(ARow: Integer): Integer;
|
2014-04-19 19:29:13 +00:00
|
|
|
function CalcColWidth(AWidth: Single): Integer;
|
2014-04-20 14:57:23 +00:00
|
|
|
function CalcRowHeight(AHeight: Single): Integer;
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure ChangedCellHandler(ASender: TObject; ARow, ACol: Cardinal);
|
2014-05-08 21:52:04 +00:00
|
|
|
procedure ChangedFontHandler(ASender: TObject; ARow, ACol: Cardinal);
|
2015-03-05 10:35:32 +00:00
|
|
|
procedure FixNeighborCellBorders(ACell: PCell);
|
2014-06-25 08:22:37 +00:00
|
|
|
function GetBorderStyle(ACol, ARow, ADeltaCol, ADeltaRow: Integer;
|
2015-03-05 10:35:32 +00:00
|
|
|
ACell: PCell; out ABorderStyle: TsCellBorderStyle): Boolean;
|
2014-05-11 10:39:14 +00:00
|
|
|
|
|
|
|
// Setter/Getter
|
2014-05-11 11:56:20 +00:00
|
|
|
function GetBackgroundColor(ACol, ARow: Integer): TsColor;
|
|
|
|
function GetBackgroundColors(ARect: TGridRect): TsColor;
|
2014-05-11 09:20:52 +00:00
|
|
|
function GetCellBorder(ACol, ARow: Integer): TsCellBorders;
|
|
|
|
function GetCellBorders(ARect: TGridRect): TsCellBorders;
|
|
|
|
function GetCellBorderStyle(ACol, ARow: Integer; ABorder: TsCellBorder): TsCellBorderStyle;
|
|
|
|
function GetCellBorderStyles(ARect: TGridRect; ABorder: TsCellBorder): TsCellBorderStyle;
|
2014-05-11 16:16:59 +00:00
|
|
|
function GetCellFont(ACol, ARow: Integer): TFont;
|
|
|
|
function GetCellFonts(ARect: TGridRect): TFont;
|
|
|
|
function GetCellFontColor(ACol, ARow: Integer): TsColor;
|
|
|
|
function GetCellFontColors(ARect: TGridRect): TsColor;
|
|
|
|
function GetCellFontName(ACol, ARow: Integer): String;
|
|
|
|
function GetCellFontNames(ARect: TGridRect): String;
|
|
|
|
function GetCellFontSize(ACol, ARow: Integer): Single;
|
|
|
|
function GetCellFontSizes(ARect: TGridRect): Single;
|
|
|
|
function GetCellFontStyle(ACol, ARow: Integer): TsFontStyles;
|
|
|
|
function GetCellFontStyles(ARect: TGridRect): TsFontStyles;
|
2014-05-10 12:32:05 +00:00
|
|
|
function GetHorAlignment(ACol, ARow: Integer): TsHorAlignment;
|
|
|
|
function GetHorAlignments(ARect: TGridRect): TsHorAlignment;
|
2014-05-03 21:27:31 +00:00
|
|
|
function GetShowGridLines: Boolean;
|
|
|
|
function GetShowHeaders: Boolean;
|
2014-05-11 10:39:14 +00:00
|
|
|
function GetTextRotation(ACol, ARow: Integer): TsTextRotation;
|
|
|
|
function GetTextRotations(ARect: TGridRect): TsTextRotation;
|
2014-05-10 12:32:05 +00:00
|
|
|
function GetVertAlignment(ACol, ARow: Integer): TsVertAlignment;
|
|
|
|
function GetVertAlignments(ARect: TGridRect): TsVertAlignment;
|
2014-11-03 15:34:57 +00:00
|
|
|
function GetWorkbook: TsWorkbook;
|
|
|
|
function GetWorksheet: TsWorksheet;
|
2014-05-11 09:20:52 +00:00
|
|
|
function GetWordwrap(ACol, ARow: Integer): Boolean;
|
|
|
|
function GetWordwraps(ARect: TGridRect): Boolean;
|
2014-08-13 14:05:29 +00:00
|
|
|
procedure SetAutoCalc(AValue: Boolean);
|
2014-05-11 11:56:20 +00:00
|
|
|
procedure SetBackgroundColor(ACol, ARow: Integer; AValue: TsColor);
|
|
|
|
procedure SetBackgroundColors(ARect: TGridRect; AValue: TsColor);
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure SetCellBorder(ACol, ARow: Integer; AValue: TsCellBorders);
|
|
|
|
procedure SetCellBorders(ARect: TGridRect; AValue: TsCellBorders);
|
|
|
|
procedure SetCellBorderStyle(ACol, ARow: Integer; ABorder: TsCellBorder; AValue: TsCellBorderStyle);
|
|
|
|
procedure SetCellBorderStyles(ARect: TGridRect; ABorder: TsCellBorder; AValue: TsCellBorderStyle);
|
2014-05-11 16:16:59 +00:00
|
|
|
procedure SetCellFont(ACol, ARow: Integer; AValue: TFont);
|
|
|
|
procedure SetCellFonts(ARect: TGridRect; AValue: TFont);
|
|
|
|
procedure SetCellFontColor(ACol, ARow: Integer; AValue: TsColor);
|
|
|
|
procedure SetCellFontColors(ARect: TGridRect; AValue: TsColor);
|
|
|
|
procedure SetCellFontName(ACol, ARow: Integer; AValue: String);
|
|
|
|
procedure SetCellFontNames(ARect: TGridRect; AValue: String);
|
|
|
|
procedure SetCellFontStyle(ACol, ARow: Integer; AValue: TsFontStyles);
|
|
|
|
procedure SetCellFontStyles(ARect: TGridRect; AValue: TsFontStyles);
|
|
|
|
procedure SetCellFontSize(ACol, ARow: Integer; AValue: Single);
|
|
|
|
procedure SetCellFontSizes(ARect: TGridRect; AValue: Single);
|
2014-05-04 18:07:54 +00:00
|
|
|
procedure SetFrozenCols(AValue: Integer);
|
|
|
|
procedure SetFrozenRows(AValue: Integer);
|
2014-05-10 12:32:05 +00:00
|
|
|
procedure SetHorAlignment(ACol, ARow: Integer; AValue: TsHorAlignment);
|
|
|
|
procedure SetHorAlignments(ARect: TGridRect; AValue: TsHorAlignment);
|
2014-12-11 12:09:43 +00:00
|
|
|
procedure SetReadFormulas(AValue: Boolean);
|
2014-05-03 21:27:31 +00:00
|
|
|
procedure SetShowGridLines(AValue: Boolean);
|
|
|
|
procedure SetShowHeaders(AValue: Boolean);
|
2014-05-11 10:39:14 +00:00
|
|
|
procedure SetTextRotation(ACol, ARow: Integer; AValue: TsTextRotation);
|
|
|
|
procedure SetTextRotations(ARect: TGridRect; AValue: TsTextRotation);
|
2014-05-10 12:32:05 +00:00
|
|
|
procedure SetVertAlignment(ACol, ARow: Integer; AValue: TsVertAlignment);
|
|
|
|
procedure SetVertAlignments(ARect: TGridRect; AValue: TsVertAlignment);
|
2014-11-03 15:34:57 +00:00
|
|
|
procedure SetWorkbookSource(AValue: TsWorkbookSource);
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure SetWordwrap(ACol, ARow: Integer; AValue: boolean);
|
|
|
|
procedure SetWordwraps(ARect: TGridRect; AValue: boolean);
|
2014-05-08 22:44:52 +00:00
|
|
|
|
2015-02-23 18:50:29 +00:00
|
|
|
procedure HyperlinkTimerElapsed(Sender: TObject);
|
|
|
|
|
2009-10-06 19:25:18 +00:00
|
|
|
protected
|
|
|
|
{ Protected declarations }
|
2014-10-03 16:09:54 +00:00
|
|
|
procedure AutoAdjustColumn(ACol: Integer); override;
|
|
|
|
procedure AutoAdjustRow(ARow: Integer); virtual;
|
2014-09-14 16:16:23 +00:00
|
|
|
function CellOverflow(ACol, ARow: Integer; AState: TGridDrawState;
|
|
|
|
out ACol1, ACol2: Integer; var ARect: TRect): Boolean;
|
2014-08-13 14:05:29 +00:00
|
|
|
procedure CreateNewWorkbook;
|
2014-10-03 16:09:54 +00:00
|
|
|
procedure DblClick; override;
|
2015-01-12 11:42:23 +00:00
|
|
|
procedure DefineProperties(Filer: TFiler); override;
|
2015-01-11 16:23:47 +00:00
|
|
|
procedure DoOnResize; override;
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure DoPrepareCanvas(ACol, ARow: Integer; AState: TGridDrawState); override;
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure DrawAllRows; override;
|
|
|
|
procedure DrawCellBorders; overload;
|
2015-03-05 10:35:32 +00:00
|
|
|
procedure DrawCellBorders(ACol, ARow: Integer; ARect: TRect; ACell: PCell); overload;
|
2015-01-29 12:39:52 +00:00
|
|
|
procedure DrawCellGrid(ACol,ARow: Integer; ARect: TRect; AState: TGridDrawState); override;
|
2015-01-30 14:48:51 +00:00
|
|
|
procedure DrawCommentMarker(ARect: TRect);
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure DrawFocusRect(aCol,aRow:Integer; ARect:TRect); override;
|
2014-06-23 13:49:12 +00:00
|
|
|
procedure DrawFrozenPaneBorders(ARect: TRect);
|
2014-09-10 19:54:06 +00:00
|
|
|
procedure DrawRow(aRow: Integer); override;
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure DrawSelection;
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure DrawTextInCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); override;
|
2015-02-23 18:50:29 +00:00
|
|
|
procedure ExecuteHyperlink;
|
2014-04-30 19:09:54 +00:00
|
|
|
function GetCellHeight(ACol, ARow: Integer): Integer;
|
2015-01-30 14:48:51 +00:00
|
|
|
function GetCellHintText(ACol, ARow: Integer): String; override;
|
2014-04-19 19:29:13 +00:00
|
|
|
function GetCellText(ACol, ARow: Integer): String;
|
2014-05-07 22:44:00 +00:00
|
|
|
function GetEditText(ACol, ARow: Integer): String; override;
|
2014-05-11 09:20:52 +00:00
|
|
|
function HasBorder(ACell: PCell; ABorder: TsCellBorder): Boolean;
|
2014-10-03 16:09:54 +00:00
|
|
|
procedure HeaderSized(IsColumn: Boolean; AIndex: Integer); override;
|
2014-05-22 21:54:24 +00:00
|
|
|
procedure InternalDrawTextInCell(AText, AMeasureText: String; ARect: TRect;
|
|
|
|
AJustification: Byte; ACellHorAlign: TsHorAlignment;
|
|
|
|
ACellVertAlign: TsVertAlignment; ATextRot: TsTextRotation;
|
|
|
|
ATextWrap, ReplaceTooLong: Boolean);
|
2014-05-08 15:54:29 +00:00
|
|
|
procedure KeyDown(var Key : Word; Shift : TShiftState); override;
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure Loaded; override;
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure LoadFromWorksheet(AWorksheet: TsWorksheet);
|
2014-11-19 08:48:07 +00:00
|
|
|
procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
|
2014-10-06 13:37:24 +00:00
|
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
2015-02-23 18:50:29 +00:00
|
|
|
procedure MouseUp(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
|
2014-05-09 22:00:53 +00:00
|
|
|
procedure MoveSelection; override;
|
2014-11-03 15:34:57 +00:00
|
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
|
|
// function SelectCell(AGridCol, AGridRow: Integer): Boolean; override;
|
2014-05-08 15:54:29 +00:00
|
|
|
procedure SelectEditor; override;
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure SetEditText(ACol, ARow: Longint; const AValue: string); override;
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure Setup;
|
2014-10-23 14:31:29 +00:00
|
|
|
procedure Sort(AColSorting: Boolean; AIndex, AIndxFrom, AIndxTo:Integer); override;
|
2015-03-16 09:45:58 +00:00
|
|
|
procedure TopLeftChanged; override;
|
2014-12-11 15:53:24 +00:00
|
|
|
function TrimToCell(ACell: PCell): String;
|
2014-07-26 17:05:21 +00:00
|
|
|
procedure UpdateColWidths(AStartIndex: Integer = 0);
|
|
|
|
procedure UpdateRowHeights(AStartIndex: Integer = 0);
|
2014-12-11 12:09:43 +00:00
|
|
|
{@@ Automatically recalculate formulas whenever a cell value changes. }
|
2014-08-13 14:05:29 +00:00
|
|
|
property AutoCalc: Boolean read FAutoCalc write SetAutoCalc default false;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Displays column and row headers in the fixed col/row style of the grid.
|
|
|
|
Deprecated. Use ShowHeaders instead. }
|
2014-05-03 21:27:31 +00:00
|
|
|
property DisplayFixedColRow: Boolean read GetShowHeaders write SetShowHeaders default true;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ This number of columns at the left is "frozen", i.e. it is not possible to
|
|
|
|
scroll these columns }
|
2014-05-04 18:07:54 +00:00
|
|
|
property FrozenCols: Integer read FFrozenCols write SetFrozenCols;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ This number of rows at the top is "frozen", i.e. it is not possible to
|
|
|
|
scroll these rows. }
|
2014-05-04 18:07:54 +00:00
|
|
|
property FrozenRows: Integer read FFrozenRows write SetFrozenRows;
|
2014-12-11 12:09:43 +00:00
|
|
|
{@@ Activates reading of RPN formulas. Should be turned off when
|
|
|
|
non-implemented formulas crashe reading of the spreadsheet file. }
|
|
|
|
property ReadFormulas: Boolean read FReadFormulas write SetReadFormulas;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Shows/hides vertical and horizontal grid lines }
|
2014-05-03 21:27:31 +00:00
|
|
|
property ShowGridLines: Boolean read GetShowGridLines write SetShowGridLines default true;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Shows/hides column and row headers in the fixed col/row style of the grid. }
|
2014-05-03 21:27:31 +00:00
|
|
|
property ShowHeaders: Boolean read GetShowHeaders write SetShowHeaders default true;
|
2014-09-14 20:40:58 +00:00
|
|
|
{@@ Activates text overflow (cells reaching into neighbors) }
|
|
|
|
property TextOverflow: Boolean read FTextOverflow write FTextOverflow default false;
|
2015-02-22 23:38:28 +00:00
|
|
|
{@@ Event called when an external hyperlink is clicked }
|
|
|
|
property OnClickHyperlink: TsHyperlinkClickEvent read FOnClickHyperlink write FOnClickHyperlink;
|
2014-05-08 22:44:52 +00:00
|
|
|
|
2009-10-06 19:25:18 +00:00
|
|
|
public
|
2014-04-29 21:58:48 +00:00
|
|
|
{ public methods }
|
2009-10-06 19:25:18 +00:00
|
|
|
constructor Create(AOwner: TComponent); override;
|
2014-04-19 19:29:13 +00:00
|
|
|
destructor Destroy; override;
|
2015-02-23 18:50:29 +00:00
|
|
|
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure BeginUpdate;
|
2014-06-20 15:58:22 +00:00
|
|
|
procedure DefaultDrawCell(ACol, ARow: Integer; var ARect: TRect; AState: TGridDrawState); override;
|
2014-10-03 22:02:09 +00:00
|
|
|
procedure DeleteCol(AGridCol: Integer); reintroduce;
|
|
|
|
procedure DeleteRow(AGridRow: Integer); reintroduce;
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure EditingDone; override;
|
|
|
|
procedure EndUpdate;
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure GetSheets(const ASheets: TStrings);
|
2014-10-06 10:43:10 +00:00
|
|
|
function GetGridCol(ASheetCol: Cardinal): Integer; inline;
|
|
|
|
function GetGridRow(ASheetRow: Cardinal): Integer; inline;
|
|
|
|
function GetWorksheetCol(AGridCol: Integer): Cardinal; inline;
|
|
|
|
function GetWorksheetRow(AGridRow: Integer): Cardinal; inline;
|
2014-07-26 17:05:21 +00:00
|
|
|
procedure InsertCol(AGridCol: Integer);
|
|
|
|
procedure InsertRow(AGridRow: Integer);
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure LoadFromSpreadsheetFile(AFileName: string;
|
|
|
|
AFormat: TsSpreadsheetFormat; AWorksheetIndex: Integer = 0); overload;
|
|
|
|
procedure LoadFromSpreadsheetFile(AFileName: string;
|
|
|
|
AWorksheetIndex: Integer = 0); overload;
|
2014-06-24 11:45:16 +00:00
|
|
|
procedure NewWorkbook(AColCount, ARowCount: Integer);
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure SaveToSpreadsheetFile(AFileName: string;
|
|
|
|
AOverwriteExisting: Boolean = true); overload;
|
|
|
|
procedure SaveToSpreadsheetFile(AFileName: string; AFormat: TsSpreadsheetFormat;
|
|
|
|
AOverwriteExisting: Boolean = true); overload;
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure SelectSheetByIndex(AIndex: Integer);
|
2014-05-08 12:12:06 +00:00
|
|
|
|
2014-09-09 15:51:56 +00:00
|
|
|
procedure MergeCells;
|
|
|
|
procedure UnmergeCells;
|
|
|
|
|
2014-05-08 12:12:06 +00:00
|
|
|
{ Utilities related to Workbooks }
|
|
|
|
procedure Convert_sFont_to_Font(sFont: TsFont; AFont: TFont);
|
|
|
|
procedure Convert_Font_to_sFont(AFont: TFont; sFont: TsFont);
|
|
|
|
function FindNearestPaletteIndex(AColor: TColor): TsColor;
|
|
|
|
|
2015-01-06 17:42:54 +00:00
|
|
|
{ Interfacing with WorkbookSource}
|
2014-11-03 15:34:57 +00:00
|
|
|
procedure ListenerNotification(AChangedItems: TsNotificationItems;
|
|
|
|
AData: Pointer = nil);
|
2015-01-06 17:42:54 +00:00
|
|
|
procedure RemoveWorkbookSource;
|
2014-11-03 15:34:57 +00:00
|
|
|
|
2014-04-29 21:58:48 +00:00
|
|
|
{ public properties }
|
2014-11-03 15:34:57 +00:00
|
|
|
{@@ Link to the workbook }
|
|
|
|
property WorkbookSource: TsWorkbookSource read FWorkbookSource write SetWorkbookSource;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Currently selected worksheet of the workbook }
|
2014-11-03 15:34:57 +00:00
|
|
|
property Worksheet: TsWorksheet read GetWorksheet;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Workbook displayed in the grid }
|
2014-11-03 15:34:57 +00:00
|
|
|
property Workbook: TsWorkbook read GetWorkbook;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Count of header lines - for conversion between grid- and workbook-based
|
2014-06-24 11:45:16 +00:00
|
|
|
row and column indexes. Either 1 if row and column headers are shown or 0 if not}
|
2014-05-07 22:44:00 +00:00
|
|
|
property HeaderCount: Integer read FHeaderCount;
|
2014-05-10 12:32:05 +00:00
|
|
|
|
|
|
|
{ maybe these should become published ... }
|
2014-06-25 08:22:37 +00:00
|
|
|
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Background color of the cell at the given column and row. Expressed as
|
|
|
|
index into the workbook's color palette. }
|
2014-05-11 11:56:20 +00:00
|
|
|
property BackgroundColor[ACol, ARow: Integer]: TsColor
|
|
|
|
read GetBackgroundColor write SetBackgroundColor;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Common background color of the cells covered by the given rectangle.
|
2014-06-24 11:45:16 +00:00
|
|
|
Expressed as index into the workbook's color palette. }
|
2014-05-11 11:56:20 +00:00
|
|
|
property BackgroundColors[ARect: TGridRect]: TsColor
|
|
|
|
read GetBackgroundColors write SetBackgroundColors;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Set of flags indicating at which cell border a border line is drawn. }
|
2014-05-11 09:20:52 +00:00
|
|
|
property CellBorder[ACol, ARow: Integer]: TsCellBorders
|
|
|
|
read GetCellBorder write SetCellBorder;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Set of flags indicating at which border of a range of cells a border
|
|
|
|
line is drawn }
|
2014-05-11 09:20:52 +00:00
|
|
|
property CellBorders[ARect: TGridRect]: TsCellBorders
|
|
|
|
read GetCellBorders write SetCellBorders;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Style of the border line at the given border of the cell at column ACol
|
|
|
|
and row ARow. Requires the cellborder flag of the border to be set
|
|
|
|
for the border line to be shown }
|
2014-05-11 09:20:52 +00:00
|
|
|
property CellBorderStyle[ACol, ARow: Integer; ABorder: TsCellBorder]: TsCellBorderStyle
|
|
|
|
read GetCellBorderStyle write SetCellBorderStyle;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Style of the border line at the given border of the cells within the
|
2014-06-24 16:10:01 +00:00
|
|
|
range of colum/row indexes defined by the rectangle. Requires the cellborder
|
2014-06-24 11:45:16 +00:00
|
|
|
flag of the border to be set for the border line to be shown }
|
2014-05-11 09:20:52 +00:00
|
|
|
property CellBorderStyles[ARect: TGridRect; ABorder: TsCellBorder]: TsCellBorderStyle
|
|
|
|
read GetCellBorderStyles write SetCellBorderStyles;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Font to be used for text in the cell at column ACol and row ARow. }
|
2014-05-11 16:16:59 +00:00
|
|
|
property CellFont[ACol, ARow: Integer]: TFont
|
|
|
|
read GetCellFont write SetCellFont;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Font to be used for the cells in the column/row index range
|
2014-06-24 11:45:16 +00:00
|
|
|
given by the rectangle }
|
2014-05-11 16:16:59 +00:00
|
|
|
property CellFonts[ARect: TGridRect]: TFont
|
|
|
|
read GetCellFonts write SetCellFonts;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Name of the font used for the cell on column ACol and row ARow }
|
2014-05-11 16:16:59 +00:00
|
|
|
property CellFontName[ACol, ARow: Integer]: String
|
|
|
|
read GetCellFontName write SetCellFontName;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Name of the font used for the cells within the range
|
2014-06-24 11:45:16 +00:00
|
|
|
of column/row indexes defined by the rectangle. }
|
2014-05-11 16:16:59 +00:00
|
|
|
property CellFontNames[ARect: TGridRect]: String
|
|
|
|
read GetCellFontNames write SetCellFontNames;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Style of the font (bold, italic, ...) used for text in the
|
2014-06-24 11:45:16 +00:00
|
|
|
cell at column ACol and row ARow. }
|
2014-05-11 16:16:59 +00:00
|
|
|
property CellFontStyle[ACol, ARow: Integer]: TsFontStyles
|
|
|
|
read GetCellFontStyle write SetCellFontStyle;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Style of the font (bold, italic, ...) used for the cells within
|
2014-06-24 11:45:16 +00:00
|
|
|
the range of column/row indexes defined by the rectangle. }
|
2014-05-11 16:16:59 +00:00
|
|
|
property CellFontStyles[ARect: TGridRect]: TsFontStyles
|
|
|
|
read GetCellFontStyles write SetCellFontStyles;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Size of the font (in points) used for the cell at column ACol
|
2014-06-24 11:45:16 +00:00
|
|
|
and row ARow }
|
2014-05-11 16:16:59 +00:00
|
|
|
property CellFontSize[ACol, ARow: Integer]: Single
|
|
|
|
read GetCellFontSize write SetCellFontSize;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Size of the font (in points) used for the cells within the
|
2014-06-24 11:45:16 +00:00
|
|
|
range of column/row indexes defined by the rectangle. }
|
2014-05-11 16:16:59 +00:00
|
|
|
property CellFontSizes[ARect: TGridRect]: Single
|
|
|
|
read GetCellFontSizes write SetCellFontSizes;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Parameter for horizontal text alignment within the cell at column ACol
|
|
|
|
and row ARow }
|
2014-05-10 12:32:05 +00:00
|
|
|
property HorAlignment[ACol, ARow: Integer]: TsHorAlignment
|
|
|
|
read GetHorAlignment write SetHorAlignment;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Parameter for the horizontal text alignments in all cells within the
|
|
|
|
range cf column/row indexes defined by the rectangle. }
|
2014-05-10 12:32:05 +00:00
|
|
|
property HorAlignments[ARect: TGridRect]: TsHorAlignment
|
|
|
|
read GetHorAlignments write SetHorAlignments;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Rotation of the text in the cell at column ACol and row ARow. }
|
2014-05-11 10:39:14 +00:00
|
|
|
property TextRotation[ACol, ARow: Integer]: TsTextRotation
|
|
|
|
read GetTextRotation write SetTextRotation;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Rotation of the text in the cells within the range of column/row indexes
|
2014-06-24 16:10:01 +00:00
|
|
|
defined by the rectangle. }
|
2014-05-11 10:39:14 +00:00
|
|
|
property TextRotations[ARect: TGridRect]: TsTextRotation
|
|
|
|
read GetTextRotations write SetTextRotations;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Parameter for vertical text alignment in the cell at column ACol and
|
|
|
|
row ARow. }
|
2014-05-10 12:32:05 +00:00
|
|
|
property VertAlignment[ACol, ARow: Integer]: TsVertAlignment
|
|
|
|
read GetVertAlignment write SetVertAlignment;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Parameter for vertical text alignment in the cells having column/row
|
|
|
|
indexes defined by the rectangle. }
|
2014-05-10 12:32:05 +00:00
|
|
|
property VertAlignments[ARect: TGridRect]: TsVertAlignment
|
|
|
|
read GetVertAlignments write SetVertAlignments;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ If true, word-wrapping of text within the cell at column ACol and row ARow
|
2014-06-24 11:45:16 +00:00
|
|
|
is activated. }
|
2014-05-11 09:20:52 +00:00
|
|
|
property Wordwrap[ACol, ARow: Integer]: Boolean
|
|
|
|
read GetWordwrap write SetWordwrap;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ If true, word-wrapping of text within all cells within the range defined
|
|
|
|
by the rectangle is activated. }
|
2014-05-11 09:20:52 +00:00
|
|
|
property Wordwraps[ARect: TGridRect]: Boolean
|
|
|
|
read GetWordwraps write SetWordwraps;
|
2014-11-05 23:45:48 +00:00
|
|
|
|
|
|
|
// inherited
|
2015-03-13 14:33:55 +00:00
|
|
|
{$IFNDEF FPS_NO_GRID_MULTISELECT}
|
2014-11-05 23:45:48 +00:00
|
|
|
{@@ Allow multiple selections}
|
|
|
|
property RangeSelectMode default rsmMulti;
|
|
|
|
{$ENDIF}
|
2009-10-06 19:25:18 +00:00
|
|
|
end;
|
|
|
|
|
2014-12-31 16:50:31 +00:00
|
|
|
|
2010-05-01 18:10:38 +00:00
|
|
|
{ TsWorksheetGrid }
|
|
|
|
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@
|
|
|
|
TsWorksheetGrid is a grid which displays spreadsheet data along with
|
2014-06-24 16:10:01 +00:00
|
|
|
formatting. As it is linked to an instance of TsWorkbook, it provides
|
2014-06-24 22:47:15 +00:00
|
|
|
methods for reading data from or writing to spreadsheet files. It has the
|
2014-10-19 21:20:57 +00:00
|
|
|
same funtionality as TsCustomWorksheetGrid, but has published all properties.
|
2014-06-24 11:45:16 +00:00
|
|
|
}
|
2009-10-06 19:25:18 +00:00
|
|
|
TsWorksheetGrid = class(TsCustomWorksheetGrid)
|
|
|
|
published
|
2014-04-30 19:09:54 +00:00
|
|
|
// inherited from TsCustomWorksheetGrid
|
2014-12-11 12:09:43 +00:00
|
|
|
{@@ Automatically recalculates the worksheet if a cell value changes. }
|
2014-08-13 14:05:29 +00:00
|
|
|
property AutoCalc;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Displays column and row headers in the fixed col/row style of the grid.
|
|
|
|
Deprecated. Use ShowHeaders instead. }
|
2014-05-03 21:27:31 +00:00
|
|
|
property DisplayFixedColRow; deprecated 'Use ShowHeaders';
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ This number of columns at the left is "frozen", i.e. it is not possible to
|
2014-06-24 16:10:01 +00:00
|
|
|
scroll these columns. }
|
2014-05-04 18:07:54 +00:00
|
|
|
property FrozenCols;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ This number of rows at the top is "frozen", i.e. it is not possible to
|
|
|
|
scroll these rows. }
|
2014-05-04 18:07:54 +00:00
|
|
|
property FrozenRows;
|
2014-12-11 12:09:43 +00:00
|
|
|
{@@ Activates reading of RPN formulas. Should be turned off when
|
|
|
|
non-implemented formulas crashe reading of the spreadsheet file. }
|
2014-05-23 23:13:49 +00:00
|
|
|
property ReadFormulas;
|
2014-06-24 16:10:01 +00:00
|
|
|
{@@ Shows/hides vertical and horizontal grid lines. }
|
2014-05-03 21:27:31 +00:00
|
|
|
property ShowGridLines;
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Shows/hides column and row headers in the fixed col/row style of the grid. }
|
2014-05-03 21:27:31 +00:00
|
|
|
property ShowHeaders;
|
2014-09-14 20:40:58 +00:00
|
|
|
{@@ Activates text overflow (cells reaching into neighbors) }
|
|
|
|
property TextOverflow;
|
2014-11-03 15:34:57 +00:00
|
|
|
{@@ Link to the workbook }
|
2014-12-11 12:09:43 +00:00
|
|
|
property WorkbookSource;
|
2014-04-30 19:09:54 +00:00
|
|
|
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property Align;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property AlternateColor;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property Anchors;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property AutoAdvance;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property AutoEdit;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property AutoFillColumns;
|
|
|
|
//property BiDiMode;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property BorderSpacing;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property BorderStyle;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2015-01-30 14:48:51 +00:00
|
|
|
property CellHintPriority;
|
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property Color;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property ColCount;
|
2014-04-19 19:29:13 +00:00
|
|
|
//property Columns;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property Constraints;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property DefaultColWidth;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property DefaultDrawing;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property DefaultRowHeight;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property DragCursor;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property DragKind;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property DragMode;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property Enabled;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2014-09-14 20:40:58 +00:00
|
|
|
property ExtendedSelect default true;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property FixedColor;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property Flat;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property Font;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property GridLineWidth;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property HeaderHotZones;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property HeaderPushZones;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property MouseWheelOption;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from TCustomGrid. Select the option goEditing to make the grid editable! }
|
2009-10-06 19:25:18 +00:00
|
|
|
property Options;
|
|
|
|
//property ParentBiDiMode;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property ParentColor default false;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property ParentFont;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property ParentShowHint;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property PopupMenu;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property RowCount;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property ScrollBars;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property ShowHint;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property TabOrder;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property TabStop;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property TitleFont;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property TitleImageList;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property TitleStyle;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property UseXORFeatures;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property Visible;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property VisibleColCount;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property VisibleRowCount;
|
|
|
|
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnBeforeSelection;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnChangeBounds;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnClick;
|
2015-02-22 23:38:28 +00:00
|
|
|
{@@ inherited from TCustomWorksheetGrid}
|
|
|
|
property OnClickHyperlink;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnColRowDeleted;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnColRowExchanged;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnColRowInserted;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnColRowMoved;
|
2014-10-23 14:31:29 +00:00
|
|
|
(*
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2014-10-23 14:31:29 +00:00
|
|
|
property OnCompareCells; // apply userdefined sorting to worksheet directly!
|
|
|
|
*)
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnDragDrop;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnDragOver;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnDblClick;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnDrawCell;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnEditButtonClick;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnEditingDone;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnEndDock;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnEndDrag;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnEnter;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnExit;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnGetEditMask;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnGetEditText;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnHeaderClick;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnHeaderSized;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnKeyDown;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnKeyPress;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnKeyUp;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnMouseDown;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnMouseMove;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnMouseUp;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnMouseWheel;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnMouseWheelDown;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnMouseWheelUp;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnPickListSelect;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnPrepareCanvas;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnResize;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnSelectEditor;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnSelection;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnSelectCell;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnSetEditText;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnShowHint;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnStartDock;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnStartDrag;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnTopLeftChanged;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnUTF8KeyPress;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnValidateEntry;
|
2014-06-25 08:22:37 +00:00
|
|
|
{@@ inherited from ancestors}
|
2009-10-06 19:25:18 +00:00
|
|
|
property OnContextPopup;
|
|
|
|
end;
|
|
|
|
|
2015-01-06 17:42:54 +00:00
|
|
|
procedure Register;
|
2009-10-06 19:25:18 +00:00
|
|
|
|
|
|
|
implementation
|
|
|
|
|
2014-04-19 19:29:13 +00:00
|
|
|
uses
|
2015-04-18 14:58:38 +00:00
|
|
|
Types, LCLType, LCLIntf, LCLProc, Math, StrUtils,
|
2015-02-23 18:50:29 +00:00
|
|
|
fpCanvas, fpsStrings, fpsUtils, fpsVisualUtils;
|
2014-04-21 21:43:43 +00:00
|
|
|
|
2014-05-22 21:54:24 +00:00
|
|
|
const
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Translation of the fpspreadsheet type of horizontal text alignment to that
|
|
|
|
used in the graphics unit. }
|
2014-05-22 21:54:24 +00:00
|
|
|
HOR_ALIGNMENTS: array[haLeft..haRight] of TAlignment = (
|
|
|
|
taLeftJustify, taCenter, taRightJustify
|
|
|
|
);
|
2014-06-24 11:45:16 +00:00
|
|
|
{@@ Translation of the fpspreadsheet type of vertical text alignment to that
|
|
|
|
used in the graphics unit. }
|
2014-05-22 21:54:24 +00:00
|
|
|
VERT_ALIGNMENTS: array[TsVertAlignment] of TTextLayout = (
|
|
|
|
tlBottom, tlTop, tlCenter, tlBottom
|
|
|
|
);
|
|
|
|
|
2015-02-23 18:50:29 +00:00
|
|
|
{@@ Default number of columns prepared for a new empty worksheet }
|
|
|
|
DEFAULT_COL_COUNT = 26;
|
|
|
|
{@@ Default number of rows prepared for a new empty worksheet }
|
|
|
|
DEFAULT_ROW_COUNT = 100;
|
|
|
|
{@@ Interval how long the mouse buttons has to be held down on a
|
|
|
|
hyperlink cell until the associated hyperlink is executed. }
|
|
|
|
HYPERLINK_TIMER_INTERVAL = 500;
|
2014-11-07 14:42:09 +00:00
|
|
|
|
2014-04-21 21:43:43 +00:00
|
|
|
var
|
2015-02-17 23:32:00 +00:00
|
|
|
{@@ Auxiliary bitmap containing the previously used non-trivial fill pattern }
|
|
|
|
FillPatternBitmap: TBitmap = nil;
|
|
|
|
FillPatternStyle: TsFillStyle;
|
|
|
|
FillPatternFgColor: TColor;
|
|
|
|
FillPatternBgColor: TColor;
|
2014-04-21 21:43:43 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2015-02-17 23:32:00 +00:00
|
|
|
Helper procedure which creates bitmaps used for fill patterns in cell
|
|
|
|
backgrounds.
|
|
|
|
The parameters are buffered in FillPatternXXXX variables to avoid unnecessary
|
|
|
|
creation of the same bitmaps again and again.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2015-02-17 23:32:00 +00:00
|
|
|
procedure CreateFillPattern(var ABitmap: TBitmap; AStyle: TsFillStyle;
|
|
|
|
AFgColor, ABgColor: TColor);
|
|
|
|
|
|
|
|
procedure SolidFill(AColor: TColor);
|
|
|
|
begin
|
|
|
|
ABitmap.Canvas.Brush.Color := AColor;
|
|
|
|
ABitmap.Canvas.FillRect(0, 0, ABitmap.Width, ABitmap.Height);
|
2014-04-21 21:43:43 +00:00
|
|
|
end;
|
2015-02-17 23:32:00 +00:00
|
|
|
|
|
|
|
var
|
|
|
|
x,y: Integer;
|
|
|
|
begin
|
|
|
|
if (FillPatternStyle = AStyle) and (FillPatternBgColor = ABgColor) and
|
|
|
|
(FillPatternFgColor = AFgColor) and (ABitmap <> nil)
|
|
|
|
then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
FreeAndNil(ABitmap);
|
|
|
|
ABitmap := TBitmap.Create;
|
|
|
|
with ABitmap do begin
|
|
|
|
if AStyle = fsGray6 then SetSize(8, 4) else SetSize(4, 4);
|
|
|
|
case AStyle of
|
|
|
|
fsNoFill:
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
fsSolidFill:
|
|
|
|
SolidFill(AFgColor);
|
|
|
|
fsGray75:
|
|
|
|
begin
|
|
|
|
SolidFill(AFgColor);
|
|
|
|
Canvas.Pixels[0, 0] := ABgColor;
|
|
|
|
Canvas.Pixels[2, 1] := ABgColor;
|
|
|
|
Canvas.Pixels[0, 2] := ABgColor;
|
|
|
|
Canvas.Pixels[2, 3] := ABgColor;
|
|
|
|
end;
|
|
|
|
fsGray50:
|
|
|
|
begin
|
|
|
|
SolidFill(AFgColor);
|
|
|
|
for y := 0 to 3 do for
|
|
|
|
x := 0 to 3 do
|
|
|
|
if odd(x+y) then Canvas.Pixels[x,y] := ABgColor;
|
|
|
|
end;
|
|
|
|
fsGray25:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
Canvas.Pixels[0, 0] := AFgColor;
|
|
|
|
Canvas.Pixels[2, 1] := AFgColor;
|
|
|
|
Canvas.Pixels[0, 2] := AFgColor;
|
|
|
|
Canvas.Pixels[2, 3] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsGray12:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
Canvas.Pixels[0, 0] := AFgColor;
|
|
|
|
Canvas.Pixels[2, 2] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsGray6:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
Canvas.Pixels[0, 0] := AFgColor;
|
|
|
|
Canvas.Pixels[4, 2] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsStripeHor:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for y := 0 to 1 do
|
|
|
|
for x := 0 to 3 do
|
|
|
|
Canvas.Pixels[x,y] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsStripeVert:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for y := 0 to 3 do
|
|
|
|
for x := 0 to 1 do
|
|
|
|
Canvas.Pixels[x,y] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsStripeDiagUp:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for y := 0 to 3 do
|
|
|
|
for x := 0 to 1 do
|
|
|
|
Canvas.Pixels[(x+y) mod 4, 3-y] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsStripeDiagDown:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for y := 0 to 3 do
|
|
|
|
for x := 0 to 1 do
|
|
|
|
Canvas.Pixels[(x+y) mod 4, y] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsThinStripeHor:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for x := 0 to 3 do Canvas.Pixels[x, 0] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsThinStripeVert:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for y := 0 to 3 do Canvas.Pixels[0, y] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsThinStripeDiagUp:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for x := 0 to 3 do Canvas.Pixels[3-x, x] := AFgColor;
|
|
|
|
end;
|
|
|
|
fsThinStripeDiagDown, fsThinHatchDiag:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for x := 0 to 3 do Canvas.Pixels[x, x] := AFgColor;
|
|
|
|
if AStyle = fsThinHatchDiag then begin
|
|
|
|
Canvas.Pixels[0, 2] := AFgColor;
|
|
|
|
Canvas.Pixels[2, 0] := AFgColor;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
fsHatchDiag:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for x := 0 to 1 do
|
|
|
|
for y := 0 to 1 do begin
|
|
|
|
Canvas.Pixels[x,y] := AFgColor;
|
|
|
|
Canvas.Pixels[x+2, y+2] := AFgColor;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
fsThickHatchDiag:
|
|
|
|
begin
|
|
|
|
SolidFill(AFgColor);
|
|
|
|
for x := 2 to 3 do Canvas.Pixels[x, 0] := ABgColor;
|
|
|
|
for x := 0 to 1 do Canvas.Pixels[x, 2] := ABgColor;
|
|
|
|
end;
|
|
|
|
fsThinHatchHor:
|
|
|
|
begin
|
|
|
|
SolidFill(ABgColor);
|
|
|
|
for x := 0 to 3 do begin
|
|
|
|
Canvas.Pixels[x, 0] := AFgColor;
|
|
|
|
Canvas.Pixels[0, x] := AFgColor;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end; // case
|
|
|
|
end;
|
|
|
|
|
|
|
|
FillPatternStyle := AStyle;
|
|
|
|
FillPatternBgColor := ABgColor;
|
|
|
|
FillPatternFgColor := AFgColor;
|
2014-04-21 21:43:43 +00:00
|
|
|
end;
|
2014-04-19 19:29:13 +00:00
|
|
|
|
2015-02-17 23:32:00 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Helper procedure which draws a densely dotted horizontal line. In Excel
|
|
|
|
this is called a "hair line".
|
|
|
|
|
|
|
|
@param x1, x2 x coordinates of the end points of the line
|
|
|
|
@param y y coordinate of the horizontal line
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure DrawHairLineHor(ACanvas: TCanvas; x1, x2, y: Integer);
|
|
|
|
var
|
|
|
|
clr: TColor;
|
|
|
|
x: Integer;
|
|
|
|
begin
|
|
|
|
if odd(x1) then inc(x1);
|
|
|
|
x := x1;
|
|
|
|
clr := ACanvas.Pen.Color;
|
|
|
|
while (x <= x2) do begin
|
|
|
|
ACanvas.Pixels[x, y] := clr;
|
|
|
|
inc(x, 2);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Helper procedure which draws a densely dotted vertical line. In Excel
|
|
|
|
this is called a "hair line".
|
|
|
|
|
|
|
|
@param x x coordinate of the vertical line
|
|
|
|
@param y1, y2 y coordinates of the end points of the line
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure DrawHairLineVert(ACanvas: TCanvas; x, y1, y2: Integer);
|
|
|
|
var
|
|
|
|
clr: TColor;
|
|
|
|
y: Integer;
|
|
|
|
begin
|
|
|
|
if odd(y1) then inc(y1);
|
|
|
|
y := y1;
|
|
|
|
clr := ACanvas.Pen.Color;
|
|
|
|
while (y <= y2) do begin
|
|
|
|
ACanvas.Pixels[x, y] := clr;
|
|
|
|
inc(y, 2);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Calculates a background color for selected cells. The procedures takes the
|
|
|
|
original background color and dims or brightens it by adding the value ADelta
|
2014-06-24 16:10:01 +00:00
|
|
|
to the RGB components.
|
2014-06-24 11:45:16 +00:00
|
|
|
|
|
|
|
@param c Color to be modified
|
2014-06-24 16:10:01 +00:00
|
|
|
@param ADelta Value to be added to the RGB components of the inpur color
|
2014-06-24 11:45:16 +00:00
|
|
|
@result Modified color.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-09 22:00:53 +00:00
|
|
|
function CalcSelectionColor(c: TColor; ADelta: Byte) : TColor;
|
2014-05-08 22:44:52 +00:00
|
|
|
type
|
|
|
|
TRGBA = record R,G,B,A: Byte end;
|
|
|
|
begin
|
|
|
|
c := ColorToRGB(c);
|
2014-05-09 22:00:53 +00:00
|
|
|
TRGBA(Result).A := 0;
|
|
|
|
if TRGBA(c).R < 128
|
|
|
|
then TRGBA(Result).R := TRGBA(c).R + ADelta
|
|
|
|
else TRGBA(Result).R := TRGBA(c).R - ADelta;
|
|
|
|
if TRGBA(c).G < 128
|
|
|
|
then TRGBA(Result).G := TRGBA(c).G + ADelta
|
|
|
|
else TRGBA(Result).G := TRGBA(c).G - ADelta;
|
|
|
|
if TRGBA(c).B < 128
|
|
|
|
then TRGBA(Result).B := TRGBA(c).B + ADelta
|
|
|
|
else TRGBA(Result).B := TRGBA(c).B - ADelta;
|
2014-05-08 22:44:52 +00:00
|
|
|
end;
|
2014-12-31 16:50:31 +00:00
|
|
|
|
2010-05-01 18:10:38 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{*******************************************************************************
|
|
|
|
* TsCustomWorksheetGrid *
|
|
|
|
*******************************************************************************}
|
2009-10-06 19:25:18 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
Constructor of the grid. Activates the display of column and row headers
|
2014-06-24 11:45:16 +00:00
|
|
|
and creates an internal "CellFont". Creates a pre-defined number of empty rows
|
2014-06-23 13:49:12 +00:00
|
|
|
and columns.
|
2014-06-24 11:45:16 +00:00
|
|
|
|
|
|
|
@param AOwner Owner of the grid
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-19 19:29:13 +00:00
|
|
|
constructor TsCustomWorksheetGrid.Create(AOwner: TComponent);
|
2009-10-06 19:25:18 +00:00
|
|
|
begin
|
2014-04-19 19:29:13 +00:00
|
|
|
inherited Create(AOwner);
|
2014-09-13 18:59:18 +00:00
|
|
|
AutoAdvance := aaDown;
|
|
|
|
ExtendedSelect := true;
|
2014-05-03 21:27:31 +00:00
|
|
|
FHeaderCount := 1;
|
2015-02-23 18:50:29 +00:00
|
|
|
FInitColCount := DEFAULT_COL_COUNT;
|
|
|
|
FInitRowCount := DEFAULT_ROW_COUNT;
|
2014-05-11 16:16:59 +00:00
|
|
|
FCellFont := TFont.Create;
|
2015-02-23 18:50:29 +00:00
|
|
|
FHyperlinkTimer := TTimer.Create(self);
|
|
|
|
FHyperlinkTimer.Interval := HYPERLINK_TIMER_INTERVAL;
|
|
|
|
FHyperlinkTimer.OnTimer := @HyperlinkTimerElapsed;
|
2014-11-03 15:34:57 +00:00
|
|
|
FOwnsWorkbook := true;
|
2015-03-13 14:33:55 +00:00
|
|
|
{$IFNDEF FPS_NO_GRID_MULTISELECT}
|
2015-02-23 18:50:29 +00:00
|
|
|
RangeSelectMode := rsmMulti;
|
2014-11-05 23:45:48 +00:00
|
|
|
{$ENDIF}
|
2014-04-19 19:29:13 +00:00
|
|
|
end;
|
2009-10-06 19:25:18 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 16:10:01 +00:00
|
|
|
Destructor of the grid: Destroys the workbook and the internal CellFont.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-19 19:29:13 +00:00
|
|
|
destructor TsCustomWorksheetGrid.Destroy;
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if FWorkbookSource <> nil then FWorkbookSource.RemoveListener(self);
|
|
|
|
if FOwnsWorkbook then FreeAndNil(FOwnedWorkbook);
|
2014-05-11 16:16:59 +00:00
|
|
|
FreeAndNil(FCellFont);
|
2014-04-19 19:29:13 +00:00
|
|
|
inherited Destroy;
|
|
|
|
end;
|
2009-10-06 19:25:18 +00:00
|
|
|
|
2014-10-03 16:09:54 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Is called when goDblClickAutoSize is in the grid's options and a double click
|
|
|
|
has occured at the border of a column header. Sets optimum column with.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.AutoAdjustColumn(ACol: Integer);
|
|
|
|
var
|
|
|
|
gRow: Integer; // row in grid coordinates
|
|
|
|
r: Cardinal;
|
|
|
|
lastRow: Cardinal;
|
|
|
|
w, maxw: Integer;
|
|
|
|
txt: String;
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet = nil then
|
2014-10-03 16:09:54 +00:00
|
|
|
exit;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
lastRow := Worksheet.GetLastOccupiedRowIndex;
|
2014-10-03 16:09:54 +00:00
|
|
|
maxw := -1;
|
|
|
|
for r := 0 to lastRow do
|
|
|
|
begin
|
|
|
|
gRow := GetGridRow(r);
|
|
|
|
txt := GetCellText(ACol, gRow);
|
|
|
|
PrepareCanvas(ACol, gRow, []);
|
|
|
|
w := Canvas.TextWidth(txt);
|
|
|
|
if (txt <> '') and (w > maxw) then maxw := w;
|
|
|
|
end;
|
|
|
|
if maxw > -1 then
|
|
|
|
maxw := maxw + 2*constCellPadding
|
|
|
|
else
|
|
|
|
maxw := DefaultColWidth;
|
|
|
|
ColWidths[ACol] := maxW;
|
|
|
|
HeaderSized(true, ACol);
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Is called when goDblClickAutoSize is in the grid's options and a double click
|
|
|
|
has occured at the border of a row header. Sets optimum row height.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.AutoAdjustRow(ARow: Integer);
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then
|
2014-10-03 16:09:54 +00:00
|
|
|
RowHeights[ARow] := CalcAutoRowHeight(ARow)
|
|
|
|
else
|
|
|
|
RowHeights[ARow] := DefaultRowHeight;
|
|
|
|
HeaderSized(false, ARow);
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure TsCustomWorksheetGrid.BeginUpdate;
|
|
|
|
begin
|
|
|
|
inc(FLockCount);
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 16:10:01 +00:00
|
|
|
Converts the column width, given in "characters" of the default font, to pixels.
|
2014-06-23 13:49:12 +00:00
|
|
|
All chars are assumed to have the same width defined by the width of the
|
|
|
|
"0" character. Therefore, this calculation is only approximate.
|
|
|
|
|
2014-09-14 16:16:23 +00:00
|
|
|
@param AWidth Width of a column given as "character count".
|
2014-06-23 13:49:12 +00:00
|
|
|
@return Column width in pixels.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-19 19:29:13 +00:00
|
|
|
function TsCustomWorksheetGrid.CalcColWidth(AWidth: Single): Integer;
|
|
|
|
var
|
|
|
|
w0: Integer;
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
Convert_sFont_to_Font(Workbook.GetFont(0), Canvas.Font);
|
2014-04-19 19:29:13 +00:00
|
|
|
w0 := Canvas.TextWidth('0');
|
|
|
|
Result := Round(AWidth * w0);
|
2009-10-06 19:25:18 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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.
|
|
|
|
|
2014-06-24 11:45:16 +00:00
|
|
|
@param ARow Index of the row, in grid units
|
|
|
|
@return Row height
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-03 20:12:44 +00:00
|
|
|
function TsCustomWorksheetGrid.CalcAutoRowHeight(ARow: Integer): Integer;
|
|
|
|
var
|
|
|
|
c: Integer;
|
|
|
|
h: Integer;
|
2014-04-20 14:57:23 +00:00
|
|
|
begin
|
2014-05-03 20:12:44 +00:00
|
|
|
h := 0;
|
2014-05-03 21:27:31 +00:00
|
|
|
for c := FHeaderCount to ColCount-1 do
|
2014-05-03 20:12:44 +00:00
|
|
|
h := Max(h, GetCellHeight(c, ARow));
|
|
|
|
if h = 0 then
|
|
|
|
Result := DefaultRowHeight
|
|
|
|
else
|
|
|
|
Result := h;
|
2014-04-20 14:57:23 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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
|
2014-06-24 16:10:01 +00:00
|
|
|
@result Row height in pixels.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-03 20:12:44 +00:00
|
|
|
function TsCustomWorksheetGrid.CalcRowHeight(AHeight: Single): Integer;
|
2014-05-31 21:04:53 +00:00
|
|
|
var
|
|
|
|
h_pts: Single;
|
2014-04-30 19:09:54 +00:00
|
|
|
begin
|
2014-05-31 21:04:53 +00:00
|
|
|
h_pts := AHeight * (Workbook.GetFont(0).Size + ROW_HEIGHT_CORRECTION);
|
|
|
|
Result := PtsToPX(h_pts, Screen.PixelsPerInch) + 4;
|
2014-04-30 19:09:54 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Looks for overflowing cells: if the text of the given cell is longer than
|
2014-09-14 16:16:23 +00:00
|
|
|
the cell width the function calculates the column indexes and the rectangle
|
|
|
|
to show the complete text.
|
|
|
|
Ony for non-wordwrapped label cells and for horizontal orientation.
|
|
|
|
Function returns false if text overflow needs not to be considered.
|
2014-09-25 10:36:17 +00:00
|
|
|
|
|
|
|
@param ACol, ARow Column and row indexes (in grid coordinates) of the cell
|
|
|
|
to be drawn
|
|
|
|
@param AState GridDrawState of the cell (normal, fixed, selected etc)
|
|
|
|
@param ACol1,ACol2 (output) Index of the first and last column covered by the
|
|
|
|
overflowing text
|
|
|
|
@param ARect (output) Pixel rectangle enclosing the cell and its neighbors
|
|
|
|
affected
|
|
|
|
@return TRUE if text overflow into neighbor cells is to be considered,
|
|
|
|
FALSE if not.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-09-14 16:16:23 +00:00
|
|
|
function TsCustomWorksheetGrid.CellOverflow(ACol, ARow: Integer;
|
|
|
|
AState: TGridDrawState; out ACol1, ACol2: Integer; var ARect: TRect): Boolean;
|
|
|
|
var
|
|
|
|
txt: String;
|
|
|
|
len: Integer;
|
|
|
|
cell: PCell;
|
|
|
|
txtalign: TsHorAlignment;
|
|
|
|
r: Cardinal;
|
|
|
|
w, w0: Integer;
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt: PsCellFormat;
|
2014-09-14 16:16:23 +00:00
|
|
|
begin
|
|
|
|
Result := false;
|
|
|
|
cell := FDrawingCell;
|
2014-09-25 10:36:17 +00:00
|
|
|
|
|
|
|
// Nothing to do in these cases (like in Excel):
|
2015-02-28 23:46:08 +00:00
|
|
|
if (cell = nil) or not (cell^.ContentType in [cctUTF8String]) then // ... non-label cells
|
2014-09-14 16:16:23 +00:00
|
|
|
exit;
|
2015-01-23 21:54:23 +00:00
|
|
|
|
|
|
|
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
|
|
|
|
|
|
|
if (uffWordWrap in fmt^.UsedFormattingFields) then // ... word-wrap
|
2014-09-14 16:16:23 +00:00
|
|
|
exit;
|
2015-01-23 21:54:23 +00:00
|
|
|
if (uffTextRotation in fmt^.UsedFormattingFields) and // ... vertical text
|
|
|
|
(fmt^.TextRotation <> trHorizontal)
|
2014-09-14 16:16:23 +00:00
|
|
|
then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
txt := cell^.UTF8Stringvalue;
|
2015-01-23 21:54:23 +00:00
|
|
|
if (uffHorAlign in fmt^.UsedFormattingFields) then
|
|
|
|
txtalign := fmt^.HorAlignment
|
2014-09-14 16:16:23 +00:00
|
|
|
else
|
|
|
|
txtalign := haDefault;
|
|
|
|
PrepareCanvas(ACol, ARow, AState);
|
2014-09-24 12:45:59 +00:00
|
|
|
len := Canvas.TextWidth(txt) + 2*constCellPadding;
|
2014-09-14 16:16:23 +00:00
|
|
|
ACol1 := ACol;
|
|
|
|
ACol2 := ACol;
|
|
|
|
r := GetWorksheetRow(ARow);
|
|
|
|
case txtalign of
|
|
|
|
haLeft, haDefault:
|
|
|
|
// overflow to the right
|
|
|
|
while (len > ARect.Right - ARect.Left) and (ACol2 < ColCount-1) do
|
|
|
|
begin
|
|
|
|
result := true;
|
|
|
|
inc(ACol2);
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(r, GetWorksheetCol(ACol2));
|
2014-09-14 16:16:23 +00:00
|
|
|
if (cell <> nil) and (cell^.ContentType <> cctEmpty) then
|
|
|
|
begin
|
|
|
|
dec(ACol2);
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
ARect.Right := ARect.Right + ColWidths[ACol2];
|
|
|
|
end;
|
|
|
|
haRight:
|
|
|
|
// overflow to the left
|
|
|
|
while (len > ARect.Right - ARect.Left) and (ACol1 > FixedCols) do
|
|
|
|
begin
|
|
|
|
result := true;
|
|
|
|
dec(ACol1);
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(r, GetWorksheetCol(ACol1));
|
2014-09-14 16:16:23 +00:00
|
|
|
if (cell <> nil) and (cell^.ContentType <> cctEmpty) then
|
|
|
|
begin
|
|
|
|
inc(ACol1);
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
ARect.Left := ARect.Left - ColWidths[ACol1];
|
|
|
|
end;
|
|
|
|
haCenter:
|
|
|
|
begin
|
|
|
|
len := len div 2;
|
|
|
|
w0 := (ARect.Right - ARect.Left) div 2;
|
|
|
|
w := w0;
|
|
|
|
// right part
|
|
|
|
while (len > w) and (ACol2 < ColCount-1) do
|
|
|
|
begin
|
|
|
|
Result := true;
|
|
|
|
inc(ACol2);
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(r, GetWorksheetCol(ACol2));
|
2014-09-14 16:16:23 +00:00
|
|
|
if (cell <> nil) and (cell^.ContentType <> cctEmpty) then
|
|
|
|
begin
|
|
|
|
dec(ACol2);
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
ARect.Right := ARect.Right + ColWidths[ACol2];
|
|
|
|
inc(w, ColWidths[ACol2]);
|
|
|
|
end;
|
|
|
|
// left part
|
|
|
|
w := w0;
|
|
|
|
while (len > w) and (ACol1 > FixedCols) do
|
|
|
|
begin
|
|
|
|
Result := true;
|
|
|
|
dec(ACol1);
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(r, GetWorksheetCol(ACol1));
|
2014-09-14 16:16:23 +00:00
|
|
|
if (cell <> nil) and (cell^.Contenttype <> cctEmpty) then
|
|
|
|
begin
|
|
|
|
inc(ACol1);
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
ARect.Left := ARect.left - ColWidths[ACol1];
|
|
|
|
inc(w, ColWidths[ACol1]);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
Handler for the event OnChangeCell fired by the worksheet when the contents
|
2014-06-24 16:10:01 +00:00
|
|
|
or formatting of a cell have changed.
|
2014-06-23 13:49:12 +00:00
|
|
|
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!
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure TsCustomWorksheetGrid.ChangedCellHandler(ASender: TObject; ARow, ACol:Cardinal);
|
|
|
|
begin
|
2014-06-20 15:58:22 +00:00
|
|
|
Unused(ASender, ARow, ACol);
|
2014-05-07 22:44:00 +00:00
|
|
|
if FLockCount = 0 then Invalidate;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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!
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.ChangedFontHandler(ASender: TObject;
|
|
|
|
ARow, ACol: Cardinal);
|
2014-05-08 21:52:04 +00:00
|
|
|
var
|
|
|
|
lRow: PRow;
|
2014-10-06 10:43:10 +00:00
|
|
|
gr: Integer; // row index in grid units
|
2014-05-08 21:52:04 +00:00
|
|
|
begin
|
2014-06-20 15:58:22 +00:00
|
|
|
Unused(ASender, ACol);
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Worksheet <> nil) then begin
|
|
|
|
lRow := Worksheet.FindRow(ARow);
|
2014-05-08 21:52:04 +00:00
|
|
|
if lRow = nil then begin
|
|
|
|
// There is no row record --> row height changes according to font height
|
|
|
|
// Otherwise the row height would be fixed according to the value in the row record.
|
2014-10-06 10:43:10 +00:00
|
|
|
gr := GetGridRow(ARow); // convert row index to grid units
|
|
|
|
RowHeights[gr] := CalcAutoRowHeight(gr);
|
2014-05-08 21:52:04 +00:00
|
|
|
end;
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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)
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-08 12:12:06 +00:00
|
|
|
procedure TsCustomWorksheetGrid.Convert_sFont_to_Font(sFont: TsFont; AFont: TFont);
|
|
|
|
begin
|
2014-11-21 15:47:54 +00:00
|
|
|
fpsVisualUtils.Convert_sFont_to_Font(Workbook, sFont, AFont);
|
2014-05-08 12:12:06 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 16:10:01 +00:00
|
|
|
Converts a font used for painting (TCanvas.Font) to a spreadsheet font.
|
2014-06-23 13:49:12 +00:00
|
|
|
|
|
|
|
@param AFont Font as used by TCanvas for painting (input)
|
|
|
|
@param sFont Font as used by fpspreadsheet (output)
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.Convert_Font_to_sFont(AFont: TFont;
|
|
|
|
sFont: TsFont);
|
2014-05-08 12:12:06 +00:00
|
|
|
begin
|
2014-11-14 23:27:49 +00:00
|
|
|
fpsVisualUtils.Convert_Font_to_sFont(Workbook, AFont, sFont);
|
2014-05-08 12:12:06 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.DefaultDrawCell(aCol, aRow: Integer;
|
|
|
|
var aRect: TRect; AState: TGridDrawState);
|
2014-05-04 18:07:54 +00:00
|
|
|
var
|
|
|
|
wasFixed: Boolean;
|
|
|
|
begin
|
|
|
|
wasFixed := false;
|
|
|
|
if (gdFixed in AState) then
|
|
|
|
if ShowHeaders then begin
|
|
|
|
if ((ARow < FixedRows) and (ARow > 0) and (ACol > 0)) or
|
|
|
|
((ACol < FixedCols) and (ACol > 0) and (ARow > 0))
|
|
|
|
then
|
|
|
|
wasFixed := true;
|
|
|
|
end else begin
|
|
|
|
if (ARow < FixedRows) or (ACol < FixedCols) then
|
|
|
|
wasFixed := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if wasFixed then begin
|
|
|
|
AState := AState - [gdFixed];
|
|
|
|
Canvas.Brush.Color := clWindow;
|
2014-06-23 14:13:46 +00:00
|
|
|
DoPrepareCanvas(ACol, ARow, AState);
|
2014-05-04 18:07:54 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
inherited DefaultDrawCell(ACol, ARow, ARect, AState);
|
|
|
|
|
|
|
|
if wasFixed then begin
|
|
|
|
DrawCellGrid(ACol, ARow, ARect, AState);
|
|
|
|
AState := AState + [gdFixed];
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-09-16 15:03:17 +00:00
|
|
|
Deletes the column specified.
|
2014-09-21 16:50:56 +00:00
|
|
|
|
|
|
|
@param AGridCol Grid index of the column to be deleted
|
|
|
|
-------------------------------------------------------------------------------}
|
2014-09-16 15:03:17 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DeleteCol(AGridCol: Integer);
|
|
|
|
begin
|
|
|
|
if AGridCol < FHeaderCount then
|
|
|
|
exit;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.DeleteCol(GetWorksheetCol(AGridCol));
|
2014-09-16 15:03:17 +00:00
|
|
|
UpdateColWidths(AGridCol);
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-09-16 15:03:17 +00:00
|
|
|
Deletes the row specified.
|
2014-09-21 16:50:56 +00:00
|
|
|
|
|
|
|
@param AGridRow Grid index of the row to be deleted
|
|
|
|
-------------------------------------------------------------------------------}
|
2014-09-16 15:03:17 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DeleteRow(AGridRow: Integer);
|
|
|
|
begin
|
|
|
|
if AGridRow < FHeaderCount then
|
|
|
|
exit;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.DeleteRow(GetWorksheetRow(AGridRow));
|
2014-09-16 15:03:17 +00:00
|
|
|
UpdateRowHeights(AGridRow);
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-08-13 14:05:29 +00:00
|
|
|
Creates a new empty workbook into which a file will be loaded. Destroys the
|
|
|
|
previously used workbook.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-08-13 14:05:29 +00:00
|
|
|
procedure TsCustomWorksheetGrid.CreateNewWorkbook;
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if FOwnsWorkbook then
|
|
|
|
FreeAndNil(FOwnedWorkbook);
|
|
|
|
|
|
|
|
if FWorkbookSource <> nil then
|
|
|
|
FWorkbookSource.CreateNewWorkbook
|
2014-08-29 15:32:43 +00:00
|
|
|
else
|
2014-11-03 15:34:57 +00:00
|
|
|
begin
|
|
|
|
FOwnedWorkbook := TsWorkbook.Create;
|
|
|
|
FOwnsWorkbook := true;
|
|
|
|
if FReadFormulas then
|
|
|
|
FOwnedWorkbook.Options := FOwnedWorkbook.Options + [boReadFormulas]
|
|
|
|
else
|
|
|
|
FOwnedWorkbook.Options := FOwnedWorkbook.Options - [boReadFormulas];
|
|
|
|
SetAutoCalc(FAutoCalc);
|
|
|
|
end;
|
2014-08-13 14:05:29 +00:00
|
|
|
end;
|
|
|
|
|
2014-10-03 16:09:54 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Is called when a Double-click occurs. Overrides the inherited method to
|
|
|
|
react on double click on cell border in row headers to auto-adjust the
|
|
|
|
row heights
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.DblClick;
|
|
|
|
var
|
|
|
|
oldHeight: Integer;
|
|
|
|
gRow: Integer;
|
|
|
|
begin
|
|
|
|
SelectActive := False;
|
|
|
|
FGridState := gsNormal;
|
|
|
|
if (goRowSizing in Options) and (Cursor = crVSplit) and (FHeaderCount > 0) then
|
|
|
|
begin
|
|
|
|
if (goDblClickAutoSize in Options) then
|
|
|
|
begin
|
|
|
|
gRow := GCache.MouseCell.y;
|
|
|
|
if CellRect(0, gRow).Bottom - GCache.ClickMouse.y > 0 then dec(gRow);
|
|
|
|
oldHeight := RowHeights[gRow];
|
|
|
|
AutoAdjustRow(gRow);
|
|
|
|
if oldHeight <> RowHeights[gRow] then
|
|
|
|
Cursor := crDefault; //ChangeCursor;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
inherited DblClick;
|
|
|
|
end;
|
|
|
|
|
2015-01-12 11:42:23 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DefineProperties(Filer: TFiler);
|
|
|
|
begin
|
|
|
|
// Don't call inherited, this is where to ColWidths/RwoHeights are stored in
|
|
|
|
// the lfm file - we don't need them, we get them from the workbook!
|
2015-01-13 19:02:57 +00:00
|
|
|
Unused(Filer);
|
2015-01-12 11:42:23 +00:00
|
|
|
end;
|
|
|
|
|
2015-01-11 16:23:47 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DoOnResize;
|
|
|
|
begin
|
|
|
|
if (csDesigning in ComponentState) and (Worksheet = nil) then
|
|
|
|
NewWorkbook(FInitColCount, FInitRowCount);
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 16:10:01 +00:00
|
|
|
Adjusts the grid's canvas before painting a given cell. Considers
|
2014-06-23 13:49:12 +00:00
|
|
|
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.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DoPrepareCanvas(ACol, ARow: Integer;
|
|
|
|
AState: TGridDrawState);
|
|
|
|
var
|
|
|
|
ts: TTextStyle;
|
|
|
|
lCell: PCell;
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt: PsCellFormat;
|
2014-04-19 19:29:13 +00:00
|
|
|
r, c: Integer;
|
2014-04-22 23:10:32 +00:00
|
|
|
fnt: TsFont;
|
|
|
|
style: TFontStyles;
|
2014-05-08 22:44:52 +00:00
|
|
|
isSelected: Boolean;
|
2015-02-17 23:32:00 +00:00
|
|
|
fgcolor, bgcolor: TColor;
|
2015-04-18 14:58:38 +00:00
|
|
|
numFmt: TsNumFormatParams;
|
|
|
|
sidx: Integer;
|
|
|
|
clr: Integer;
|
2009-10-06 19:25:18 +00:00
|
|
|
begin
|
2014-05-08 22:44:52 +00:00
|
|
|
GetSelectedState(AState, isSelected);
|
2014-05-03 20:12:44 +00:00
|
|
|
Canvas.Font.Assign(Font);
|
2014-04-21 21:43:43 +00:00
|
|
|
Canvas.Brush.Bitmap := nil;
|
2014-05-09 22:00:53 +00:00
|
|
|
Canvas.Brush.Color := Color;
|
2014-04-19 19:29:13 +00:00
|
|
|
ts := Canvas.TextStyle;
|
2015-02-17 23:32:00 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
if ShowHeaders then
|
|
|
|
begin
|
2014-04-19 19:29:13 +00:00
|
|
|
// Formatting of row and column headers
|
2014-09-21 16:50:56 +00:00
|
|
|
if ARow = 0 then
|
|
|
|
begin
|
2014-04-20 20:31:36 +00:00
|
|
|
ts.Alignment := taCenter;
|
|
|
|
ts.Layout := tlCenter;
|
|
|
|
end else
|
2014-09-21 16:50:56 +00:00
|
|
|
if ACol = 0 then
|
|
|
|
begin
|
2014-04-19 19:29:13 +00:00
|
|
|
ts.Alignment := taRightJustify;
|
2014-04-20 20:31:36 +00:00
|
|
|
ts.Layout := tlCenter;
|
|
|
|
end;
|
2014-06-02 08:52:37 +00:00
|
|
|
if ShowHeaders and ((ACol = 0) or (ARow = 0)) then
|
|
|
|
Canvas.Brush.Color := FixedColor
|
2014-04-19 19:29:13 +00:00
|
|
|
end;
|
2015-02-17 23:32:00 +00:00
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Worksheet <> nil) and (ARow >= FHeaderCount) and (ACol >= FHeaderCount) then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-05-03 21:27:31 +00:00
|
|
|
r := ARow - FHeaderCount;
|
|
|
|
c := ACol - FHeaderCount;
|
2015-02-17 23:32:00 +00:00
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
lCell := Worksheet.FindCell(r, c);
|
2014-09-21 16:50:56 +00:00
|
|
|
if lCell <> nil then
|
|
|
|
begin
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
2015-04-18 14:58:38 +00:00
|
|
|
numFmt := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
2015-02-17 23:32:00 +00:00
|
|
|
|
2014-04-20 21:51:12 +00:00
|
|
|
// Background color
|
2015-02-17 23:32:00 +00:00
|
|
|
if (uffBackground in fmt^.UsedFormattingFields) then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Workbook.FileFormat = sfExcel2 then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2015-02-17 23:32:00 +00:00
|
|
|
CreateFillPattern(FillPatternBitmap, fsGray50, clBlack, Color);
|
2014-04-21 21:43:43 +00:00
|
|
|
Canvas.Brush.Style := bsImage;
|
2015-02-17 23:32:00 +00:00
|
|
|
Canvas.Brush.Bitmap := FillPatternBitmap;
|
2014-09-21 16:50:56 +00:00
|
|
|
end else
|
|
|
|
begin
|
2015-02-17 23:32:00 +00:00
|
|
|
case fmt^.Background.Style of
|
|
|
|
fsNoFill:
|
|
|
|
Canvas.Brush.Style := bsClear;
|
|
|
|
fsSolidFill:
|
|
|
|
begin
|
|
|
|
Canvas.Brush.Style := bsSolid;
|
|
|
|
Canvas.Brush.Color := Workbook.GetPaletteColor(fmt^.Background.FgColor);
|
|
|
|
end;
|
|
|
|
else
|
|
|
|
if fmt^.Background.BgColor = scTransparent
|
|
|
|
then bgcolor := Color
|
|
|
|
else bgcolor := Workbook.GetPaletteColor(fmt^.Background.BgColor);
|
|
|
|
if fmt^.Background.FgColor = scTransparent
|
|
|
|
then fgcolor := Color
|
|
|
|
else fgcolor := Workbook.GetPaletteColor(fmt^.Background.FgColor);
|
|
|
|
CreateFillPattern(FillPatternBitmap, fmt^.Background.Style, fgColor, bgColor);
|
|
|
|
Canvas.Brush.Style := bsImage;
|
|
|
|
Canvas.Brush.Bitmap := FillPatternBitmap;
|
|
|
|
end;
|
2014-04-21 21:43:43 +00:00
|
|
|
end;
|
2014-09-21 16:50:56 +00:00
|
|
|
end else
|
|
|
|
begin
|
2014-04-20 21:51:12 +00:00
|
|
|
Canvas.Brush.Style := bsSolid;
|
|
|
|
Canvas.Brush.Color := Color;
|
|
|
|
end;
|
2015-02-17 23:32:00 +00:00
|
|
|
|
2014-04-22 23:10:32 +00:00
|
|
|
// Font
|
2015-03-01 11:40:04 +00:00
|
|
|
if Worksheet.HasHyperlink(lCell) then
|
2015-02-22 23:38:28 +00:00
|
|
|
fnt := Workbook.GetHyperlinkFont
|
|
|
|
else
|
|
|
|
fnt := Workbook.GetDefaultFont;
|
2015-01-23 21:54:23 +00:00
|
|
|
if (uffFont in fmt^.UsedFormattingFields) then
|
|
|
|
fnt := Workbook.GetFont(fmt^.FontIndex);
|
2015-02-22 23:38:28 +00:00
|
|
|
|
|
|
|
if fnt <> nil then
|
|
|
|
begin
|
|
|
|
Canvas.Font.Name := fnt.FontName;
|
|
|
|
Canvas.Font.Size := round(fnt.Size);
|
|
|
|
Canvas.Font.Color := Workbook.GetPaletteColor(fnt.Color);
|
|
|
|
style := [];
|
|
|
|
if fssBold in fnt.Style then Include(style, fsBold);
|
|
|
|
if fssItalic in fnt.Style then Include(style, fsItalic);
|
|
|
|
if fssUnderline in fnt.Style then Include(style, fsUnderline);
|
|
|
|
if fssStrikeout in fnt.Style then Include(style, fsStrikeout);
|
|
|
|
Canvas.Font.Style := style;
|
2014-04-22 23:10:32 +00:00
|
|
|
end;
|
2015-04-26 16:24:19 +00:00
|
|
|
// Read text color from number format if available
|
2015-04-18 14:58:38 +00:00
|
|
|
if not IsNaN(lCell^.NumberValue) and (numFmt <> nil) then
|
|
|
|
begin
|
|
|
|
sidx := 0;
|
|
|
|
if (Length(numFmt.Sections) > 1) and (lCell^.NumberValue < 0) then
|
|
|
|
sidx := 1
|
|
|
|
else
|
|
|
|
if (Length(numFmt.Sections) > 2) and (lCell^.NumberValue = 0) then
|
|
|
|
sidx := 2;
|
2015-04-21 09:35:58 +00:00
|
|
|
if (nfkHasColor in numFmt.Sections[sidx].Kind) then
|
2015-04-18 14:58:38 +00:00
|
|
|
begin
|
2015-04-21 09:35:58 +00:00
|
|
|
clr := numFmt.Sections[sidx].Color;
|
2015-04-18 14:58:38 +00:00
|
|
|
Canvas.Font.Color := Workbook.GetPaletteColor(clr);
|
|
|
|
end;
|
|
|
|
end;
|
2014-04-29 21:58:48 +00:00
|
|
|
// Wordwrap, text alignment and text rotation are handled by "DrawTextInCell".
|
2014-04-19 19:29:13 +00:00
|
|
|
end;
|
|
|
|
end;
|
2014-05-08 22:44:52 +00:00
|
|
|
|
|
|
|
if IsSelected then
|
2014-05-09 22:00:53 +00:00
|
|
|
Canvas.Brush.Color := CalcSelectionColor(Canvas.Brush.Color, 16);
|
2014-05-08 22:44:52 +00:00
|
|
|
|
2014-04-19 19:29:13 +00:00
|
|
|
Canvas.TextStyle := ts;
|
2014-05-04 18:07:54 +00:00
|
|
|
|
2014-04-19 19:29:13 +00:00
|
|
|
inherited DoPrepareCanvas(ACol, ARow, AState);
|
2009-10-06 19:25:18 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
This method is inherited from TsCustomGrid, but is overridden here in order
|
|
|
|
to paint the cell borders and the selection rectangle.
|
2014-06-24 16:10:01 +00:00
|
|
|
Both features can extend into the neighboring cells and thus would be clipped
|
2014-06-23 13:49:12 +00:00
|
|
|
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.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawAllRows;
|
|
|
|
var
|
|
|
|
cliprect: TRect;
|
|
|
|
rgn: HRGN;
|
2014-06-20 15:58:22 +00:00
|
|
|
tmp: Integer = 0;
|
2014-05-11 09:20:52 +00:00
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
Canvas.SaveHandleState;
|
|
|
|
try
|
2014-06-02 08:52:37 +00:00
|
|
|
// Avoid painting into the header cells
|
2014-05-11 09:20:52 +00:00
|
|
|
cliprect := ClientRect;
|
|
|
|
if FixedCols > 0 then
|
|
|
|
ColRowToOffset(True, True, FixedCols-1, tmp, cliprect.Left);
|
|
|
|
if FixedRows > 0 then
|
|
|
|
ColRowToOffset(False, True, FixedRows-1, tmp, cliprect.Top);
|
2014-06-23 13:49:12 +00:00
|
|
|
DrawFrozenPaneBorders(clipRect);
|
|
|
|
|
2014-05-11 09:20:52 +00:00
|
|
|
rgn := CreateRectRgn(cliprect.Left, cliprect.top, cliprect.Right, cliprect.Bottom);
|
|
|
|
SelectClipRgn(Canvas.Handle, Rgn);
|
|
|
|
DrawCellBorders;
|
|
|
|
DrawSelection;
|
|
|
|
DeleteObject(rgn);
|
|
|
|
finally
|
|
|
|
Canvas.RestoreHandleState;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
Draws the borders of all cells. Calls DrawCellBorder for each individual cell.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawCellBorders;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
2015-03-16 09:45:58 +00:00
|
|
|
gc, gr: Integer;
|
|
|
|
sr1, sc1, sr2, sc2: Cardinal;
|
2014-05-11 09:20:52 +00:00
|
|
|
rect: TRect;
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet = nil then
|
2014-09-21 16:50:56 +00:00
|
|
|
exit;
|
2014-05-11 09:20:52 +00:00
|
|
|
|
2015-03-16 09:45:58 +00:00
|
|
|
sr1 := GetWorksheetRow(GCache.VisibleGrid.Top);
|
|
|
|
sc1 := GetWorksheetCol(GCache.VisibleGrid.Left);
|
|
|
|
sr2 := GetWorksheetRow(GCache.VisibleGrid.Bottom);
|
|
|
|
sc2 := GetWorksheetCol(GCache.VisibleGrid.Right);
|
|
|
|
|
|
|
|
for cell in Worksheet.Cells.GetRangeEnumerator(sr1, sc1, sr2, sc2) do
|
|
|
|
if (uffBorder in Worksheet.ReadUsedFormatting(cell)) then
|
|
|
|
begin
|
|
|
|
gc := GetGridCol(cell^.Col);
|
|
|
|
gr := GetGridRow(cell^.Row);
|
|
|
|
rect := CellRect(gc, gr);
|
|
|
|
DrawCellBorders(gc, gr, rect, cell);
|
|
|
|
end;
|
|
|
|
|
|
|
|
{
|
|
|
|
gr := TopLeft.Y;
|
|
|
|
gc := TopLeft.X;
|
2015-03-04 17:30:59 +00:00
|
|
|
for cell in Worksheet.Cells do
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2015-01-23 21:54:23 +00:00
|
|
|
if (uffBorder in Worksheet.ReadUsedFormatting(cell)) then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2015-03-16 09:45:58 +00:00
|
|
|
gc := GetGridCol(cell^.Col);
|
|
|
|
gr := GetGridRow(cell^.Row);
|
|
|
|
rect := CellRect(gc, gr);
|
|
|
|
DrawCellBorders(gc, gr, rect, cell);
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
end;
|
2015-03-16 09:45:58 +00:00
|
|
|
}
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
Draws the border lines around a given cell. Note that when this procedure is
|
2014-05-09 22:00:53 +00:00
|
|
|
called the output is clipped by the cell rectangle, but thick and double
|
2014-06-24 16:10:01 +00:00
|
|
|
border styles extend into the neighboring cell. Therefore, these border lines
|
2014-06-23 13:49:12 +00:00
|
|
|
are drawn in parts.
|
|
|
|
|
|
|
|
@param ACol Column Index
|
|
|
|
@param ARow Row index
|
|
|
|
@param ARect Rectangle in pixels occupied by the cell.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2015-03-05 10:35:32 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawCellBorders(ACol, ARow: Integer;
|
|
|
|
ARect: TRect; ACell: PCell);
|
2014-07-30 22:51:59 +00:00
|
|
|
const
|
|
|
|
drawHor = 0;
|
|
|
|
drawVert = 1;
|
|
|
|
drawDiagUp = 2;
|
|
|
|
drawDiagDown = 3;
|
2014-05-03 17:00:00 +00:00
|
|
|
|
2014-07-30 22:51:59 +00:00
|
|
|
procedure DrawBorderLine(ACoord: Integer; ARect: TRect; ADrawDirection: Byte;
|
2014-05-09 22:00:53 +00:00
|
|
|
ABorderStyle: TsCellBorderStyle);
|
2014-05-03 17:00:00 +00:00
|
|
|
const
|
2014-05-11 09:20:52 +00:00
|
|
|
// TsLineStyle = (lsThin, lsMedium, lsDashed, lsDotted, lsThick, lsDouble, lsHair);
|
2014-05-03 17:00:00 +00:00
|
|
|
PEN_STYLES: array[TsLineStyle] of TPenStyle =
|
2014-05-11 09:20:52 +00:00
|
|
|
(psSolid, psSolid, psDash, psDot, psSolid, psSolid, psSolid);
|
|
|
|
PEN_WIDTHS: array[TsLineStyle] of Integer =
|
|
|
|
(1, 2, 1, 1, 3, 1, 1);
|
|
|
|
var
|
|
|
|
width3: Boolean; // line is 3 pixels wide
|
2014-07-30 22:51:59 +00:00
|
|
|
deltax, deltay: Integer;
|
|
|
|
angle: Double;
|
2014-05-09 22:00:53 +00:00
|
|
|
begin
|
|
|
|
Canvas.Pen.Style := PEN_STYLES[ABorderStyle.LineStyle];
|
2014-05-11 09:20:52 +00:00
|
|
|
Canvas.Pen.Width := PEN_WIDTHS[ABorderStyle.LineStyle];
|
2014-11-03 15:34:57 +00:00
|
|
|
Canvas.Pen.Color := Workbook.GetPaletteColor(ABorderStyle.Color);
|
2014-05-11 09:20:52 +00:00
|
|
|
Canvas.Pen.EndCap := pecSquare;
|
|
|
|
width3 := (ABorderStyle.LineStyle in [lsThick, lsDouble]);
|
|
|
|
|
2014-07-30 22:51:59 +00:00
|
|
|
// Workaround until efficient drawing procedures for diagonal "hair" lines
|
|
|
|
// is available
|
|
|
|
if (ADrawDirection in [drawDiagUp, drawDiagDown]) and
|
|
|
|
(ABorderStyle.LineStyle = lsHair)
|
|
|
|
then
|
|
|
|
ABorderStyle.LineStyle := lsDotted;
|
|
|
|
|
2014-05-11 09:20:52 +00:00
|
|
|
// Tuning the rectangle to avoid issues at the grid borders and to get nice corners
|
|
|
|
if (ABorderStyle.LineStyle in [lsMedium, lsThick, lsDouble]) then begin
|
2014-09-21 16:50:56 +00:00
|
|
|
if ACol = ColCount-1 then
|
|
|
|
begin
|
2014-07-30 22:51:59 +00:00
|
|
|
if (ADrawDirection = drawVert) and (ACoord = ARect.Right-1) and width3
|
|
|
|
then dec(ACoord);
|
2014-05-11 09:20:52 +00:00
|
|
|
dec(ARect.Right);
|
|
|
|
end;
|
2014-09-21 16:50:56 +00:00
|
|
|
if ARow = RowCount-1 then
|
|
|
|
begin
|
2014-07-30 22:51:59 +00:00
|
|
|
if (ADrawDirection = drawHor) and (ACoord = ARect.Bottom-1) and width3
|
|
|
|
then dec(ACoord);
|
2014-05-11 09:20:52 +00:00
|
|
|
dec(ARect.Bottom);
|
|
|
|
end;
|
|
|
|
end;
|
2014-09-21 16:50:56 +00:00
|
|
|
if ABorderStyle.LineStyle in [lsMedium, lsThick] then
|
|
|
|
begin
|
2014-07-30 22:51:59 +00:00
|
|
|
if (ADrawDirection = drawHor) then
|
|
|
|
dec(ARect.Right, 1)
|
|
|
|
else if (ADrawDirection = drawVert) then
|
|
|
|
dec(ARect.Bottom, 1);
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
// Painting
|
|
|
|
case ABorderStyle.LineStyle of
|
|
|
|
lsThin, lsMedium, lsThick, lsDotted, lsDashed:
|
2014-07-30 22:51:59 +00:00
|
|
|
case ADrawDirection of
|
|
|
|
drawHor : Canvas.Line(ARect.Left, ACoord, ARect.Right, ACoord);
|
|
|
|
drawVert : Canvas.Line(ACoord, ARect.Top, ACoord, ARect.Bottom);
|
|
|
|
drawDiagUp : Canvas.Line(ARect.Left, ARect.Bottom, ARect.Right, ARect.Top);
|
|
|
|
drawDiagDown: Canvas.Line(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
|
|
|
|
end;
|
2014-05-11 09:20:52 +00:00
|
|
|
|
|
|
|
lsHair:
|
2014-07-30 22:51:59 +00:00
|
|
|
case ADrawDirection of
|
|
|
|
drawHor : DrawHairLineHor(Canvas, ARect.Left, ARect.Right, ACoord);
|
|
|
|
drawVert : DrawHairLineVert(Canvas, ACoord, ARect.Top, ARect.Bottom);
|
|
|
|
drawDiagUp : ;
|
|
|
|
drawDiagDown: ;
|
|
|
|
end;
|
2014-05-11 09:20:52 +00:00
|
|
|
|
|
|
|
lsDouble:
|
2014-07-30 22:51:59 +00:00
|
|
|
case ADrawDirection of
|
|
|
|
drawHor:
|
|
|
|
begin
|
|
|
|
Canvas.Line(ARect.Left, ACoord-1, ARect.Right, ACoord-1);
|
|
|
|
Canvas.Line(ARect.Left, ACoord+1, ARect.Right, ACoord+1);
|
|
|
|
Canvas.Pen.Color := Color;
|
|
|
|
Canvas.Line(ARect.Left, ACoord, ARect.Right, ACoord);
|
|
|
|
end;
|
|
|
|
drawVert:
|
|
|
|
begin
|
|
|
|
Canvas.Line(ACoord-1, ARect.Top, ACoord-1, ARect.Bottom);
|
|
|
|
Canvas.Line(ACoord+1, ARect.Top, ACoord+1, ARect.Bottom);
|
|
|
|
Canvas.Pen.Color := Color;
|
|
|
|
Canvas.Line(ACoord, ARect.Top, ACoord, ARect.Bottom);
|
|
|
|
end;
|
|
|
|
drawDiagUp:
|
|
|
|
begin
|
|
|
|
if ARect.Right = ARect.Left then
|
|
|
|
angle := pi/2
|
|
|
|
else
|
|
|
|
angle := arctan((ARect.Bottom-ARect.Top) / (ARect.Right-ARect.Left));
|
|
|
|
deltax := Max(1, round(1.0 / sin(angle)));
|
|
|
|
deltay := Max(1, round(1.0 / cos(angle)));
|
|
|
|
Canvas.Line(ARect.Left, ARect.Bottom-deltay-1, ARect.Right-deltax, ARect.Top-1);
|
|
|
|
Canvas.Line(ARect.Left+deltax, ARect.Bottom-1, ARect.Right, ARect.Top+deltay-1);
|
|
|
|
end;
|
|
|
|
drawDiagDown:
|
|
|
|
begin
|
|
|
|
if ARect.Right = ARect.Left then
|
|
|
|
angle := pi/2
|
|
|
|
else
|
|
|
|
angle := arctan((ARect.Bottom-ARect.Top) / (ARect.Right-ARect.Left));
|
|
|
|
deltax := Max(1, round(1.0 / sin(angle)));
|
|
|
|
deltay := Max(1, round(1.0 / cos(angle)));
|
|
|
|
Canvas.Line(ARect.Left, ARect.Top+deltay-1, ARect.Right-deltax, ARect.Bottom-1);
|
|
|
|
Canvas.Line(ARect.Left+deltax, ARect.Top-1, ARect.Right, ARect.Bottom-deltay-1);
|
|
|
|
end;
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
2014-05-09 22:00:53 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
bs: TsCellBorderStyle;
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt: PsCellFormat;
|
2014-05-09 22:00:53 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
2014-05-09 22:00:53 +00:00
|
|
|
// Left border
|
2015-03-05 10:35:32 +00:00
|
|
|
if GetBorderStyle(ACol, ARow, -1, 0, ACell, bs) then
|
2014-07-30 22:51:59 +00:00
|
|
|
DrawBorderLine(ARect.Left-1, ARect, drawVert, bs);
|
2014-05-09 22:00:53 +00:00
|
|
|
// Right border
|
2015-03-05 10:35:32 +00:00
|
|
|
if GetBorderStyle(ACol, ARow, +1, 0, ACell, bs) then
|
2014-07-30 22:51:59 +00:00
|
|
|
DrawBorderLine(ARect.Right-1, ARect, drawVert, bs);
|
2014-05-09 22:00:53 +00:00
|
|
|
// Top border
|
2015-03-05 10:35:32 +00:00
|
|
|
if GetBorderstyle(ACol, ARow, 0, -1, ACell, bs) then
|
2014-07-30 22:51:59 +00:00
|
|
|
DrawBorderLine(ARect.Top-1, ARect, drawHor, bs);
|
2014-05-09 22:00:53 +00:00
|
|
|
// Bottom border
|
2015-03-05 10:35:32 +00:00
|
|
|
if GetBorderStyle(ACol, ARow, 0, +1, ACell, bs) then
|
2014-07-30 22:51:59 +00:00
|
|
|
DrawBorderLine(ARect.Bottom-1, ARect, drawHor, bs);
|
|
|
|
|
2015-03-05 10:35:32 +00:00
|
|
|
if ACell <> nil then begin
|
|
|
|
fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
2014-07-30 22:51:59 +00:00
|
|
|
// Diagonal up
|
2015-01-23 21:54:23 +00:00
|
|
|
if cbDiagUp in fmt^.Border then begin
|
|
|
|
bs := fmt^.Borderstyles[cbDiagUp];
|
2014-07-30 22:51:59 +00:00
|
|
|
DrawBorderLine(0, ARect, drawDiagUp, bs);
|
|
|
|
end;
|
|
|
|
// Diagonal down
|
2015-01-23 21:54:23 +00:00
|
|
|
if cbDiagDown in fmt^.Border then begin
|
|
|
|
bs := fmt^.BorderStyles[cbDiagDown];
|
2014-07-30 22:51:59 +00:00
|
|
|
DrawborderLine(0, ARect, drawDiagDown, bs);
|
|
|
|
end;
|
|
|
|
end;
|
2014-05-09 22:00:53 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2015-01-29 12:39:52 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Method inherited method from TCustomGrid. Is overridden here to avoid painting
|
|
|
|
of the border of frozen cells in black under some circumstances.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.DrawCellGrid(ACol, ARow: Integer; ARect: TRect;
|
|
|
|
AState: TGridDrawState);
|
|
|
|
begin
|
|
|
|
if (TitleStyle <> tsNative) and (gdFixed in AState) and
|
|
|
|
{DisplayFixedColRow and} ((FFrozenCols > 0) or (FFrozenRows > 0)) then
|
|
|
|
begin
|
|
|
|
// Draw default cell borders only in the header cols/rows.
|
|
|
|
// If there are frozen cells they would get a black border, so we don't
|
|
|
|
// draw their borders here - they are drawn by "DrawRow" anyway.
|
|
|
|
if ((ACol=0) or (ARow = 0)) and DisplayFixedColRow then
|
|
|
|
inherited;
|
|
|
|
end else
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2015-01-30 14:48:51 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Draws the red rectangle in the upper right corner of a cell to indicate that
|
|
|
|
this cell contains a popup comment
|
|
|
|
-------------------------------------------------------------------------------}
|
2015-01-30 17:46:06 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawCommentMarker(ARect: TRect);
|
2015-01-30 14:48:51 +00:00
|
|
|
const
|
2015-02-05 11:23:06 +00:00
|
|
|
COMMENT_SIZE = 7;
|
2015-01-30 14:48:51 +00:00
|
|
|
var
|
|
|
|
P: Array[0..3] of TPoint;
|
|
|
|
begin
|
|
|
|
Canvas.Brush.Color := clRed;
|
|
|
|
Canvas.Brush.Style := bsSolid;
|
|
|
|
Canvas.Pen.Style := psClear;
|
|
|
|
P[0] := Point(ARect.Right, ARect.Top);
|
|
|
|
P[1] := Point(ARect.Right - COMMENT_SIZE, ARect.Top);
|
|
|
|
P[2] := Point(ARect.Right, ARect.Top + COMMENT_SIZE);
|
|
|
|
P[3] := P[0];
|
|
|
|
Canvas.Polygon(P);
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 16:10:01 +00:00
|
|
|
This procedure is responsible for painting the focus rectangle. We don't want
|
|
|
|
the red dashed rectangle here, but prefer the thick Excel-like black border
|
2015-03-02 21:20:00 +00:00
|
|
|
line. This new focus rectangle is drawn by the method DrawSelection because
|
|
|
|
the thick Excel border reaches into adjacent cells.
|
2014-06-24 11:45:16 +00:00
|
|
|
|
|
|
|
@param ACol Grid column index of the focused cell
|
|
|
|
@param ARow Grid row index of the focused cell
|
|
|
|
@param ARect Rectangle in pixels covered by the focused cell
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawFocusRect(aCol, aRow: Integer; ARect: TRect);
|
|
|
|
begin
|
2014-06-20 15:58:22 +00:00
|
|
|
Unused(ACol, ARow, ARect);
|
2014-05-11 09:20:52 +00:00
|
|
|
// Nothing do to
|
2014-05-09 22:00:53 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
Draws a solid line along the borders of frozen panes.
|
|
|
|
|
2015-01-29 12:39:52 +00:00
|
|
|
@param ARect This rectangle indicates the area containing scrollable cells.
|
2014-06-24 16:10:01 +00:00
|
|
|
If the grid has frozen panes, a black line is drawn along the
|
2014-06-24 11:45:16 +00:00
|
|
|
upper and/or left edge of this rectangle (depending on the
|
|
|
|
value of FrozenRows and FrozenCols).
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-06-23 13:49:12 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawFrozenPaneBorders(ARect: TRect);
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if WorkSheet = nil then
|
2014-09-10 19:54:06 +00:00
|
|
|
exit;
|
2014-11-03 15:34:57 +00:00
|
|
|
if (soHasFrozenPanes in Worksheet.Options) then begin
|
2014-06-23 13:49:12 +00:00
|
|
|
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;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Draws a complete row of cells. Is mostly duplicated from Grids.pas, but adds
|
2014-09-25 10:36:17 +00:00
|
|
|
code for merged cells and overflow text, the section on drawing the default
|
|
|
|
focus rectangle is removed.
|
|
|
|
|
|
|
|
@param ARow Index of the row to be drawn (index in grid coordinates)
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-09-10 19:54:06 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawRow(ARow: Integer);
|
|
|
|
var
|
|
|
|
gds: TGridDrawState;
|
2015-03-16 17:40:16 +00:00
|
|
|
sr, sr1,sc1,sr2,sc2, scLastUsed: Cardinal; // sheet row/column
|
2014-09-14 20:40:58 +00:00
|
|
|
gr, gc, gcNext, gcLast, gc1, gc2, gcLastUsed: Integer; // grid row/column
|
2014-09-25 10:36:17 +00:00
|
|
|
i: Integer;
|
2015-02-05 17:50:23 +00:00
|
|
|
rct, saved_rct, temp_rct, commentcell_rct: TRect;
|
2014-09-10 19:54:06 +00:00
|
|
|
clipArea: Trect;
|
|
|
|
cell: PCell;
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt: PsCellFormat;
|
2014-10-06 10:43:10 +00:00
|
|
|
tmp: Integer = 0;
|
2014-09-10 19:54:06 +00:00
|
|
|
|
|
|
|
function IsPushCellActive: boolean;
|
|
|
|
begin
|
|
|
|
with GCache do
|
2014-09-14 16:16:23 +00:00
|
|
|
result := (PushedCell.X <> -1) and (PushedCell.Y <> -1);
|
2014-09-10 19:54:06 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
function VerticalIntersect(const aRect,bRect: TRect): boolean;
|
|
|
|
begin
|
|
|
|
result := (aRect.Top < bRect.Bottom) and (aRect.Bottom > bRect.Top);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function HorizontalIntersect(const aRect,bRect: TRect): boolean;
|
|
|
|
begin
|
|
|
|
result := (aRect.Left < bRect.Right) and (aRect.Right > bRect.Left);
|
|
|
|
end;
|
|
|
|
|
2014-09-25 10:36:17 +00:00
|
|
|
procedure DoDrawCell(_col, _row: Integer; _clipRect, _cellRect: TRect);
|
2014-09-10 19:54:06 +00:00
|
|
|
var
|
|
|
|
Rgn: HRGN;
|
|
|
|
begin
|
|
|
|
with GCache do begin
|
|
|
|
if (_col = HotCell.x) and (_row = HotCell.y) and not IsPushCellActive() then begin
|
|
|
|
Include(gds, gdHot);
|
|
|
|
HotCellPainted := True;
|
|
|
|
end;
|
|
|
|
if ClickCellPushed and (_col = PushedCell.x) and (_row = PushedCell.y) then begin
|
|
|
|
Include(gds, gdPushed);
|
|
|
|
end;
|
|
|
|
end;
|
2014-10-03 16:09:54 +00:00
|
|
|
|
2014-09-10 19:54:06 +00:00
|
|
|
Canvas.SaveHandleState;
|
|
|
|
try
|
2014-09-25 10:36:17 +00:00
|
|
|
Rgn := CreateRectRgn(_clipRect.Left, _clipRect.Top, _clipRect.Right, _clipRect.Bottom);
|
2014-09-10 19:54:06 +00:00
|
|
|
SelectClipRgn(Canvas.Handle, Rgn);
|
2014-09-25 10:36:17 +00:00
|
|
|
DrawCell(_col, _row, _cellRect, gds);
|
2014-09-10 19:54:06 +00:00
|
|
|
DeleteObject(Rgn);
|
|
|
|
finally
|
|
|
|
Canvas.RestoreHandleState;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
|
|
// Upper and Lower bounds for this row
|
2014-09-14 16:16:23 +00:00
|
|
|
rct := Rect(0, 0, 0, 0);
|
2014-09-10 19:54:06 +00:00
|
|
|
ColRowToOffSet(False, True, ARow, rct.Top, rct.Bottom);
|
|
|
|
saved_rct := rct;
|
|
|
|
|
|
|
|
// is this row within the ClipRect?
|
|
|
|
clipArea := Canvas.ClipRect;
|
|
|
|
if (rct.Top >= rct.Bottom) or not VerticalIntersect(rct, clipArea) then begin
|
|
|
|
{$IFDEF DbgVisualChange}
|
|
|
|
DebugLn('Drawrow: Skipped row: ', IntToStr(aRow));
|
|
|
|
{$ENDIF}
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
2015-03-16 17:40:16 +00:00
|
|
|
scLastused := Worksheet.GetLastColIndex;
|
2014-09-14 16:16:23 +00:00
|
|
|
sr := GetWorksheetRow(ARow);
|
|
|
|
|
2014-09-10 19:54:06 +00:00
|
|
|
// Draw columns in this row
|
2014-09-14 16:16:23 +00:00
|
|
|
with GCache.VisibleGrid do
|
|
|
|
begin
|
2015-03-16 17:40:16 +00:00
|
|
|
gcLast := Right;
|
2014-09-14 16:16:23 +00:00
|
|
|
gc := Left;
|
|
|
|
|
|
|
|
// Because of possible cell overflow from cells left of the visible range
|
|
|
|
// we have to seek to the left for the first occupied text cell
|
|
|
|
// and start painting from here.
|
2014-11-03 15:34:57 +00:00
|
|
|
if FTextOverflow and (sr <> Cardinal(-1)) and Assigned(Worksheet) then
|
2014-09-14 16:16:23 +00:00
|
|
|
while (gc > FixedCols) do
|
|
|
|
begin
|
|
|
|
dec(gc);
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(sr, GetWorksheetCol(gc));
|
2014-09-14 16:16:23 +00:00
|
|
|
// Empty cell --> proceed with next cell to the left
|
|
|
|
if (cell = nil) or (cell^.ContentType = cctEmpty) or
|
2015-02-28 23:46:08 +00:00
|
|
|
((cell^.ContentType = cctUTF8String) and (cell^.UTF8StringValue = ''))
|
2014-09-14 16:16:23 +00:00
|
|
|
then
|
|
|
|
Continue;
|
|
|
|
// Overflow possible from non-merged, non-right-aligned, horizontal label cells
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
2015-02-22 23:38:28 +00:00
|
|
|
if (not Worksheet.IsMerged(cell)) and
|
2015-02-28 23:46:08 +00:00
|
|
|
(cell^.ContentType = cctUTF8String) and
|
2015-01-23 21:54:23 +00:00
|
|
|
not (uffTextRotation in fmt^.UsedFormattingFields) and
|
|
|
|
(uffHorAlign in fmt^.UsedFormattingFields) and (fmt^.HorAlignment <> haRight)
|
2014-09-14 16:16:23 +00:00
|
|
|
then
|
|
|
|
Break;
|
|
|
|
// All other cases --> no overflow --> return to initial left cell
|
|
|
|
gc := Left;
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Now find the last column. Again text can overflow into the visible area
|
|
|
|
// from cells to the right.
|
|
|
|
gcLast := Right;
|
2014-11-03 15:34:57 +00:00
|
|
|
if FTextOverflow and (sr <> Cardinal(-1)) and Assigned(Worksheet) then
|
2014-09-15 07:33:55 +00:00
|
|
|
begin
|
2015-03-16 17:40:16 +00:00
|
|
|
gcLastUsed := GetGridCol(scLastUsed);
|
2014-09-14 20:40:58 +00:00
|
|
|
while (gcLast < ColCount-1) and (gcLast < gcLastUsed) do begin
|
2014-09-14 16:16:23 +00:00
|
|
|
inc(gcLast);
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(sr, GetWorksheetCol(gcLast));
|
2014-09-14 16:16:23 +00:00
|
|
|
// Empty cell --> proceed with next cell to the right
|
|
|
|
if (cell = nil) or (cell^.ContentType = cctEmpty) or
|
2015-02-28 23:46:08 +00:00
|
|
|
((cell^.ContentType = cctUTF8String) and (cell^.UTF8StringValue = ''))
|
2014-09-14 16:16:23 +00:00
|
|
|
then
|
|
|
|
continue;
|
|
|
|
// Overflow possible from non-merged, horizontal, non-left-aligned label cells
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
2015-02-22 23:38:28 +00:00
|
|
|
if (not Worksheet.IsMerged(cell)) and
|
2015-02-28 23:46:08 +00:00
|
|
|
(cell^.ContentType = cctUTF8String) and
|
2015-01-23 21:54:23 +00:00
|
|
|
not (uffTextRotation in fmt^.UsedFormattingFields) and
|
|
|
|
(uffHorAlign in fmt^.UsedFormattingFields) and (fmt^.HorAlignment <> haLeft)
|
2014-09-14 16:16:23 +00:00
|
|
|
then
|
|
|
|
Break;
|
|
|
|
// All other cases --> no overflow --> return to initial right column
|
|
|
|
gcLast := Right;
|
2014-09-14 20:40:58 +00:00
|
|
|
Break;
|
2014-09-14 16:16:23 +00:00
|
|
|
end;
|
2014-09-15 07:33:55 +00:00
|
|
|
end;
|
2014-09-14 16:16:23 +00:00
|
|
|
|
2014-09-24 12:45:59 +00:00
|
|
|
// Here begins the drawing loop of all cells in the row
|
2014-09-14 20:40:58 +00:00
|
|
|
while (gc <= gcLast) do begin
|
2014-09-14 16:16:23 +00:00
|
|
|
gr := ARow;
|
2014-09-10 19:54:06 +00:00
|
|
|
rct := saved_rct;
|
|
|
|
// FDrawingCell is the cell which is currently being painted. We store
|
|
|
|
// it to avoid excessive calls to "FindCell".
|
|
|
|
FDrawingCell := nil;
|
2014-09-14 16:16:23 +00:00
|
|
|
gcNext := gc + 1;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) and (gr >= FixedRows) and (gc >= FixedCols) then
|
2014-09-10 19:54:06 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(gr), GetWorksheetCol(gc));
|
2015-02-22 00:12:16 +00:00
|
|
|
if (cell = nil) or (not Worksheet.IsMerged(cell)) then
|
2014-09-15 20:54:39 +00:00
|
|
|
begin
|
2014-09-10 19:54:06 +00:00
|
|
|
// single cell
|
2014-09-14 16:16:23 +00:00
|
|
|
FDrawingCell := cell;
|
2015-02-15 11:45:08 +00:00
|
|
|
if Worksheet.HasComment(cell) then
|
2015-02-05 17:50:23 +00:00
|
|
|
commentcell_rct := CellRect(gc, gr)
|
|
|
|
else
|
|
|
|
commentcell_rct := Rect(0,0,0,0);
|
2014-09-25 10:36:17 +00:00
|
|
|
// Special treatment of overflowing cells
|
2014-09-14 20:40:58 +00:00
|
|
|
if FTextOverflow then
|
2014-09-14 16:16:23 +00:00
|
|
|
begin
|
2014-09-14 20:40:58 +00:00
|
|
|
gds := GetGridDrawState(gc, gr);
|
|
|
|
ColRowToOffset(true, true, gc, rct.Left, rct.Right);
|
|
|
|
if CellOverflow(gc, gr, gds, gc1, gc2, rct) then
|
|
|
|
begin
|
2014-09-25 10:36:17 +00:00
|
|
|
// Draw individual cells of the overflown range
|
|
|
|
ColRowToOffset(true, true, gc1, rct.Left, tmp); // rct is the clip rect
|
|
|
|
ColRowToOffset(true, true, gc2, tmp, rct.Right);
|
|
|
|
FDrawingCell := nil;
|
|
|
|
temp_rct := rct;
|
|
|
|
for i := gc1 to gc2 do begin
|
|
|
|
ColRowToOffset(true, true, i, temp_rct.Left, temp_rct.Right);
|
|
|
|
if HorizontalIntersect(temp_rct, clipArea) and (i <> gc) then
|
|
|
|
begin
|
|
|
|
gds := GetGridDrawState(i, gr);
|
|
|
|
DoDrawCell(i, gr, rct, temp_rct);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
// Repaint the base cell text (it was partly overwritten before)
|
|
|
|
FDrawingCell := cell;
|
|
|
|
FTextOverflowing := true;
|
|
|
|
ColRowToOffset(true, true, gc, temp_rct.Left, temp_rct.Right);
|
|
|
|
if HorizontalIntersect(temp_rct, clipArea) then
|
|
|
|
begin
|
|
|
|
gds := GetGridDrawState(gc, gr);
|
|
|
|
DoDrawCell(gc, gr, rct, temp_rct);
|
2015-02-15 11:45:08 +00:00
|
|
|
if Worksheet.HasComment(FDrawingCell) then
|
2015-02-05 17:50:23 +00:00
|
|
|
DrawCommentMarker(temp_rct);
|
2014-09-25 10:36:17 +00:00
|
|
|
end;
|
|
|
|
FTextOverflowing := false;
|
|
|
|
|
|
|
|
gcNext := gc2 + 1;
|
|
|
|
gc := gcNext;
|
|
|
|
continue;
|
2014-09-14 20:40:58 +00:00
|
|
|
end;
|
2014-09-14 16:16:23 +00:00
|
|
|
end;
|
|
|
|
end
|
2014-09-10 19:54:06 +00:00
|
|
|
else
|
|
|
|
begin
|
|
|
|
// merged cells
|
2014-11-03 15:34:57 +00:00
|
|
|
FDrawingCell := Worksheet.FindMergeBase(cell);
|
|
|
|
Worksheet.FindMergedRange(FDrawingCell, sr1, sc1, sr2, sc2);
|
2014-09-14 16:16:23 +00:00
|
|
|
gr := GetGridRow(sr1);
|
2015-02-15 11:45:08 +00:00
|
|
|
if Worksheet.HasComment(FDrawingCell) then
|
2015-02-05 17:50:23 +00:00
|
|
|
commentcell_rct := CellRect(GetGridCol(sc2), gr)
|
|
|
|
else
|
|
|
|
commentcell_rct := Rect(0,0,0,0);
|
2014-09-14 16:16:23 +00:00
|
|
|
ColRowToOffSet(False, True, gr, rct.Top, tmp);
|
2014-10-06 10:43:10 +00:00
|
|
|
ColRowToOffSet(False, True, gr + integer(sr2) - integer(sr1), tmp, rct.Bottom);
|
2014-09-14 16:16:23 +00:00
|
|
|
gc := GetGridCol(sc1);
|
|
|
|
gcNext := gc + (sc2 - sc1) + 1;
|
2014-09-10 19:54:06 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-14 16:16:23 +00:00
|
|
|
ColRowToOffset(true, true, gc, rct.Left, tmp);
|
|
|
|
ColRowToOffset(true, true, gcNext-1, tmp, rct.Right);
|
2014-09-10 19:54:06 +00:00
|
|
|
|
2014-09-11 09:49:16 +00:00
|
|
|
if (rct.Left < rct.Right) and HorizontalIntersect(rct, clipArea) then
|
|
|
|
begin
|
2014-09-14 16:16:23 +00:00
|
|
|
gds := GetGridDrawState(gc, gr);
|
2014-09-25 10:36:17 +00:00
|
|
|
DoDrawCell(gc, gr, rct, rct);
|
2015-01-30 14:48:51 +00:00
|
|
|
// Draw comment marker
|
2015-02-05 17:50:23 +00:00
|
|
|
if (commentcell_rct.Left <> 0) and (commentcell_rct.Right <> 0) and
|
|
|
|
(commentcell_rct.Top <> 0) and (commentcell_rct.Bottom <> 0)
|
|
|
|
then
|
|
|
|
DrawCommentMarker(commentcell_rct);
|
2014-09-11 09:49:16 +00:00
|
|
|
end;
|
2014-09-10 19:54:06 +00:00
|
|
|
|
2014-09-14 16:16:23 +00:00
|
|
|
gc := gcNext;
|
2014-09-10 19:54:06 +00:00
|
|
|
end;
|
2014-09-25 10:36:17 +00:00
|
|
|
end; // with GCache.VisibleGrid ...
|
2014-09-10 19:54:06 +00:00
|
|
|
|
2015-01-29 12:39:52 +00:00
|
|
|
// Draw fixed columns
|
2014-09-14 16:16:23 +00:00
|
|
|
gr := ARow;
|
|
|
|
for gc := 0 to FixedCols-1 do begin
|
2014-09-10 19:54:06 +00:00
|
|
|
gds := [gdFixed];
|
2014-09-14 16:16:23 +00:00
|
|
|
ColRowToOffset(True, True, gc, rct.Left, rct.Right);
|
2014-09-10 19:54:06 +00:00
|
|
|
// is this column within the ClipRect?
|
|
|
|
if (rct.Left < rct.Right) and HorizontalIntersect(rct, clipArea) then
|
2014-09-14 20:40:58 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
|
|
|
FDrawingCell := Worksheet.FindCell(GetWorksheetRow(gr), GetWorksheetCol(gc))
|
2014-09-15 07:33:55 +00:00
|
|
|
else
|
|
|
|
FDrawingCell := nil;
|
2014-09-25 10:36:17 +00:00
|
|
|
DoDrawCell(gc, gr, rct, rct);
|
2014-09-14 20:40:58 +00:00
|
|
|
end;
|
2014-09-10 19:54:06 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Draws the selection rectangle around selected cells, 3 pixels wide as in Excel.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawSelection;
|
|
|
|
var
|
|
|
|
P1, P2: TPoint;
|
2015-03-02 21:20:00 +00:00
|
|
|
cell: PCell;
|
|
|
|
r1,c1,r2,c2: Cardinal;
|
2014-05-09 22:00:53 +00:00
|
|
|
begin
|
2015-03-02 21:20:00 +00:00
|
|
|
// Selected cell
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(Selection.Top), GetWorksheetCol(Selection.Left));
|
|
|
|
if Worksheet.IsMerged(cell) then
|
|
|
|
begin
|
|
|
|
Worksheet.FindMergedRange(cell, r1,c1,r2,c2);
|
|
|
|
P1 := CellRect(GetGridCol(c1), GetGridRow(r1)).TopLeft;
|
|
|
|
P2 := CellRect(GetGridCol(c2), GetGridRow(r2)).BottomRight;
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
P1 := CellRect(Selection.Left, Selection.Top).TopLeft;
|
|
|
|
P2 := CellRect(Selection.Right, Selection.Bottom).BottomRight;
|
|
|
|
end;
|
2014-05-11 09:20:52 +00:00
|
|
|
// Cosmetics at the edges of the grid to avoid spurious rests
|
|
|
|
if Selection.Top > TopRow then dec(P1.Y) else inc(P1.Y);
|
|
|
|
if Selection.Left > LeftCol then dec(P1.X) else inc(P1.X);
|
|
|
|
if Selection.Right = ColCount-1 then dec(P2.X);
|
|
|
|
if Selection.Bottom = RowCount-1 then dec(P2.Y);
|
|
|
|
// Set up the canvas
|
|
|
|
Canvas.Pen.Style := psSolid;
|
|
|
|
Canvas.Pen.Width := 3;
|
|
|
|
Canvas.Pen.JoinStyle := pjsMiter;
|
|
|
|
if UseXORFeatures then begin
|
|
|
|
Canvas.Pen.Color := clWhite;
|
|
|
|
Canvas.Pen.Mode := pmXOR;
|
|
|
|
end else
|
|
|
|
Canvas.Pen.Color := clBlack;
|
|
|
|
Canvas.Brush.Style := bsClear;
|
|
|
|
// Paint
|
|
|
|
Canvas.Rectangle(P1.X, P1.Y, P2.X, P2.Y);
|
2014-05-07 22:44:00 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Draws the cell text. Calls "GetCellText" to determine the text for the cell.
|
2014-04-29 21:58:48 +00:00
|
|
|
Takes care of horizontal and vertical text alignment, text rotation and
|
2014-06-24 16:10:01 +00:00
|
|
|
text wrapping.
|
2014-06-23 13:49:12 +00:00
|
|
|
|
2014-06-24 11:45:16 +00:00
|
|
|
@param ACol Grid column index of the cell
|
|
|
|
@param ARow Grid row index of the cell
|
2014-06-24 16:10:01 +00:00
|
|
|
@param ARect Rectangle in pixels occupied by the cell
|
2014-06-23 13:49:12 +00:00
|
|
|
@param AState Drawing state of the grid -- see TCustomGrid
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure TsCustomWorksheetGrid.DrawTextInCell(ACol, ARow: Integer; ARect: TRect;
|
|
|
|
AState: TGridDrawState);
|
2014-04-29 21:58:48 +00:00
|
|
|
var
|
|
|
|
ts: TTextStyle;
|
|
|
|
txt: String;
|
2014-05-11 09:20:52 +00:00
|
|
|
wrapped: Boolean;
|
2014-04-29 21:58:48 +00:00
|
|
|
horAlign: TsHorAlignment;
|
|
|
|
vertAlign: TsVertAlignment;
|
2014-05-22 21:54:24 +00:00
|
|
|
txtRot: TsTextRotation;
|
2014-04-29 21:58:48 +00:00
|
|
|
lCell: PCell;
|
2014-05-22 21:54:24 +00:00
|
|
|
justif: Byte;
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt: PsCellFormat;
|
2014-04-19 19:29:13 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Worksheet = nil) then
|
2014-04-29 21:58:48 +00:00
|
|
|
exit;
|
2014-09-14 16:16:23 +00:00
|
|
|
|
2014-09-11 09:49:16 +00:00
|
|
|
if (ACol < FHeaderCount) or (ARow < FHeaderCount) then
|
|
|
|
lCell := nil
|
|
|
|
else
|
|
|
|
lCell := FDrawingCell;
|
2014-09-25 10:36:17 +00:00
|
|
|
|
2014-05-22 21:54:24 +00:00
|
|
|
// Header
|
2014-09-21 16:50:56 +00:00
|
|
|
if lCell = nil then
|
|
|
|
begin
|
|
|
|
if ShowHeaders and ((ACol = 0) or (ARow = 0)) then
|
|
|
|
begin
|
2014-04-29 21:58:48 +00:00
|
|
|
ts.Alignment := taCenter;
|
|
|
|
ts.Layout := tlCenter;
|
2014-04-30 19:09:54 +00:00
|
|
|
ts.Opaque := false;
|
2014-04-29 21:58:48 +00:00
|
|
|
Canvas.TextStyle := ts;
|
|
|
|
end;
|
|
|
|
inherited DrawCellText(aCol, aRow, aRect, aState, GetCellText(ACol,ARow));
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
2014-05-22 21:54:24 +00:00
|
|
|
// Cells
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
|
|
|
wrapped := (uffWordWrap in fmt^.UsedFormattingFields) or (fmt^.TextRotation = rtStacked);
|
|
|
|
txtRot := fmt^.TextRotation;
|
|
|
|
vertAlign := fmt^.VertAlignment;
|
2014-05-28 09:04:42 +00:00
|
|
|
if vertAlign = vaDefault then vertAlign := vaBottom;
|
2015-01-23 21:54:23 +00:00
|
|
|
if fmt^.HorAlignment <> haDefault then
|
|
|
|
horAlign := fmt^.HorAlignment
|
2014-09-21 16:50:56 +00:00
|
|
|
else
|
|
|
|
begin
|
2014-05-22 21:54:24 +00:00
|
|
|
if (lCell^.ContentType in [cctNumber, cctDateTime]) then
|
2014-04-29 21:58:48 +00:00
|
|
|
horAlign := haRight
|
|
|
|
else
|
|
|
|
horAlign := haLeft;
|
|
|
|
end;
|
|
|
|
|
|
|
|
InflateRect(ARect, -constCellPadding, -constCellPadding);
|
|
|
|
|
2014-09-14 16:16:23 +00:00
|
|
|
// txt := GetCellText(ACol, ARow);
|
|
|
|
txt := GetCellText(GetGridRow(lCell^.Col), GetGridCol(lCell^.Row));
|
2014-06-23 09:15:56 +00:00
|
|
|
if txt = '' then
|
|
|
|
exit;
|
2014-04-29 21:58:48 +00:00
|
|
|
|
2014-06-23 09:15:56 +00:00
|
|
|
case txtRot of
|
|
|
|
trHorizontal:
|
|
|
|
case horAlign of
|
|
|
|
haLeft : justif := 0;
|
|
|
|
haCenter : justif := 1;
|
|
|
|
haRight : justif := 2;
|
2014-04-29 21:58:48 +00:00
|
|
|
end;
|
2014-06-23 09:15:56 +00:00
|
|
|
rtStacked,
|
|
|
|
rt90DegreeClockwiseRotation:
|
|
|
|
case vertAlign of
|
|
|
|
vaTop : justif := 0;
|
|
|
|
vaCenter: justif := 1;
|
|
|
|
vaBottom: justif := 2;
|
|
|
|
end;
|
|
|
|
rt90DegreeCounterClockwiseRotation:
|
|
|
|
case vertAlign of
|
|
|
|
vaTop : justif := 2;
|
|
|
|
vaCenter: justif := 1;
|
|
|
|
vaBottom: justif := 0;
|
2014-04-29 21:58:48 +00:00
|
|
|
end;
|
|
|
|
end;
|
2014-06-23 09:15:56 +00:00
|
|
|
InternalDrawTextInCell(txt, txt, ARect, justif, horAlign, vertAlign,
|
|
|
|
txtRot, wrapped, false);
|
2014-04-19 19:29:13 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 16:10:01 +00:00
|
|
|
This procedure is called when editing of a cell is completed. It 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).
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure TsCustomWorksheetGrid.EditingDone;
|
|
|
|
var
|
|
|
|
oldText: String;
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
2014-09-21 16:50:56 +00:00
|
|
|
if (not EditorShowing) and FEditing then
|
|
|
|
begin
|
2014-05-07 22:44:00 +00:00
|
|
|
oldText := GetCellText(Col, Row);
|
2014-09-21 16:50:56 +00:00
|
|
|
if oldText <> FEditText then
|
|
|
|
begin
|
2015-03-02 21:20:00 +00:00
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(Row), GetWorksheetCol(Col));
|
|
|
|
if Worksheet.IsMerged(cell) then
|
|
|
|
cell := Worksheet.FindMergeBase(cell);
|
2014-11-18 10:19:33 +00:00
|
|
|
if (FEditText <> '') and (FEditText[1] = '=') then
|
|
|
|
Worksheet.WriteFormula(cell, Copy(FEditText, 2, Length(FEditText)), true)
|
|
|
|
else
|
|
|
|
Worksheet.WriteCellValueAsString(cell, FEditText);
|
2014-05-07 22:44:00 +00:00
|
|
|
FEditText := '';
|
|
|
|
end;
|
|
|
|
inherited EditingDone;
|
|
|
|
end;
|
|
|
|
FEditing := false;
|
2014-11-18 10:19:33 +00:00
|
|
|
FEnhEditMode := false;
|
2014-05-07 22:44:00 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-07 22:44:00 +00:00
|
|
|
procedure TsCustomWorksheetGrid.EndUpdate;
|
|
|
|
begin
|
|
|
|
dec(FLockCount);
|
|
|
|
if FLockCount = 0 then Invalidate;
|
|
|
|
end;
|
|
|
|
|
2015-02-23 18:50:29 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Executes a hyperlink stored in the FHyperlinkCell
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.ExecuteHyperlink;
|
|
|
|
var
|
|
|
|
hyperlink: TsHyperlink;
|
2015-02-28 23:46:08 +00:00
|
|
|
target, bookmark: String;
|
2015-02-23 18:50:29 +00:00
|
|
|
sheetname: String;
|
|
|
|
sheet: TsWorksheet;
|
|
|
|
r, c: Cardinal;
|
|
|
|
begin
|
|
|
|
if FHyperlinkCell = nil then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
hyperlink := Worksheet.ReadHyperlink(FHyperlinkCell);
|
2015-03-02 12:23:52 +00:00
|
|
|
SplitHyperlink(hyperlink.Target, target, bookmark);
|
2015-02-28 23:46:08 +00:00
|
|
|
if target = '' then begin
|
|
|
|
// Goes to a cell within the current workbook
|
|
|
|
if ParseSheetCellString(bookmark, sheetname, r, c) then
|
|
|
|
begin
|
|
|
|
if sheetname <> '' then
|
2015-02-23 18:50:29 +00:00
|
|
|
begin
|
2015-02-28 23:46:08 +00:00
|
|
|
sheet := Workbook.GetWorksheetByName(sheetname);
|
|
|
|
if sheet = nil then
|
|
|
|
raise Exception.CreateFmt(rsWorksheetNotFound, [sheetname]);
|
|
|
|
Workbook.SelectWorksheet(sheet);
|
|
|
|
end;
|
|
|
|
Worksheet.SelectCell(r, c);
|
|
|
|
end else
|
|
|
|
raise Exception.CreateFmt(rsNoValidHyperlinkInternal, [hyperlink.Target]);
|
|
|
|
end else
|
|
|
|
// Fires the OnClickHyperlink event which should open a file or a URL
|
|
|
|
if Assigned(FOnClickHyperlink) then FOnClickHyperlink(self, hyperlink);
|
2015-02-23 18:50:29 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
Copies the borders of a cell to its neighbors. This avoids the nightmare of
|
|
|
|
changing borders due to border conflicts of adjacent cells.
|
|
|
|
|
2015-03-05 10:35:32 +00:00
|
|
|
@param ACell Pointer to the cell
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2015-03-05 10:35:32 +00:00
|
|
|
procedure TsCustomWorksheetGrid.FixNeighborCellBorders(ACell: PCell);
|
|
|
|
//Col, ARow: Integer);
|
2014-05-11 09:20:52 +00:00
|
|
|
|
2015-03-05 10:35:32 +00:00
|
|
|
procedure SetNeighborBorder(NewRow, NewCol: Cardinal;
|
2014-05-11 09:20:52 +00:00
|
|
|
ANewBorder: TsCellBorder; const ANewBorderStyle: TsCellBorderStyle;
|
|
|
|
AInclude: Boolean);
|
|
|
|
var
|
|
|
|
neighbor: PCell;
|
|
|
|
border: TsCellBorders;
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
neighbor := Worksheet.FindCell(NewRow, NewCol);
|
2014-09-21 16:50:56 +00:00
|
|
|
if neighbor <> nil then
|
|
|
|
begin
|
2015-01-23 21:54:23 +00:00
|
|
|
border := Worksheet.ReadCelLBorders(neighbor);
|
2014-09-21 16:50:56 +00:00
|
|
|
if AInclude then
|
|
|
|
begin
|
2014-05-11 09:20:52 +00:00
|
|
|
Include(border, ANewBorder);
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.WriteBorderStyle(NewRow, NewCol, ANewBorder, ANewBorderStyle);
|
2014-05-11 09:20:52 +00:00
|
|
|
end else
|
|
|
|
Exclude(border, ANewBorder);
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.WriteBorders(NewRow, NewCol, border);
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt: PsCellFormat;
|
2014-05-11 09:20:52 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet = nil then
|
2014-09-21 16:50:56 +00:00
|
|
|
exit;
|
|
|
|
|
2015-03-05 10:35:32 +00:00
|
|
|
// cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
if (Worksheet <> nil) and (ACell <> nil) then
|
|
|
|
with ACell^ do
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2015-03-05 10:35:32 +00:00
|
|
|
fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
2015-01-23 21:54:23 +00:00
|
|
|
SetNeighborBorder(Row, Col-1, cbEast, fmt^.BorderStyles[cbWest], cbWest in fmt^.Border);
|
|
|
|
SetNeighborBorder(Row, Col+1, cbWest, fmt^.BorderStyles[cbEast], cbEast in fmt^.Border);
|
|
|
|
SetNeighborBorder(Row-1, Col, cbSouth, fmt^.BorderStyles[cbNorth], cbNorth in fmt^.Border);
|
|
|
|
SetNeighborBorder(Row+1, Col, cbNorth, fmt^.BorderStyles[cbSouth], cbSouth in fmt^.Border);
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
The "colors" used by the spreadsheet are indexes into the workbook's color
|
2014-06-24 16:10:01 +00:00
|
|
|
palette. If the user wants to set a color to a particular RGB value this is
|
2014-05-08 12:12:06 +00:00
|
|
|
not possible in general. The method FindNearestPaletteIndex finds the bast
|
2014-06-23 13:49:12 +00:00
|
|
|
matching color in the palette.
|
|
|
|
|
|
|
|
@param AColor Color index into the workbook's palette
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-08 12:12:06 +00:00
|
|
|
function TsCustomWorksheetGrid.FindNearestPaletteIndex(AColor: TColor): TsColor;
|
|
|
|
begin
|
2014-11-14 23:27:49 +00:00
|
|
|
Result := fpsVisualUtils.FindNearestPaletteIndex(Workbook, AColor);
|
2014-05-08 12:12:06 +00:00
|
|
|
end;
|
2014-11-14 23:27:49 +00:00
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
(*
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Notification by the workbook link that a cell has been modified. --> Repaint.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.CellChanged(ACell: PCell);
|
|
|
|
begin
|
|
|
|
Unused(ACell);
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Notification by the workbook link that another cell has been selected
|
|
|
|
--> select the cell in the grid
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.CellSelected(ASheetRow, ASheetCol: Cardinal);
|
|
|
|
var
|
|
|
|
grow, gcol: Integer;
|
|
|
|
begin
|
|
|
|
if (FWorkbookLink <> nil) then
|
|
|
|
begin
|
|
|
|
grow := GetGridRow(ASheetRow);
|
|
|
|
gcol := GetGridCol(ASheetCol);
|
|
|
|
if (grow <> Row) or (gcol <> Col) then begin
|
|
|
|
Row := grow;
|
|
|
|
Col := gcol;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Notification by the workbook link that a new workbook is available.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.WorkbookChanged;
|
|
|
|
begin
|
|
|
|
WorksheetChanged;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Notification by the workbook link that a new worksheet has been selected from
|
|
|
|
the current workbook. Is also called internally from WorkbookChanged.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.WorksheetChanged;
|
|
|
|
begin
|
|
|
|
if Worksheet <> nil then begin
|
|
|
|
//Worksheet.OnChangeCell := @ChangedCellHandler;
|
|
|
|
//Worksheet.OnChangeFont := @ChangedFontHandler;
|
|
|
|
ShowHeaders := (soShowHeaders in Worksheet.Options);
|
|
|
|
ShowGridLines := (soShowGridLines in Worksheet.Options);
|
|
|
|
if (soHasFrozenPanes in Worksheet.Options) then begin
|
|
|
|
FrozenCols := Worksheet.LeftPaneWidth;
|
|
|
|
FrozenRows := Worksheet.TopPaneHeight;
|
|
|
|
end else begin
|
|
|
|
FrozenCols := 0;
|
|
|
|
FrozenRows := 0;
|
|
|
|
end;
|
|
|
|
Row := FrozenRows;
|
|
|
|
Col := FrozenCols;
|
|
|
|
end;
|
|
|
|
Setup;
|
|
|
|
end;
|
|
|
|
*)
|
2014-05-08 12:12:06 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
Returns the background color of a cell. The color is given as an index into
|
|
|
|
the workbook's color palette.
|
|
|
|
|
2014-06-24 11:45:16 +00:00
|
|
|
@param ACol Grid column index of the cell
|
|
|
|
@param ARow Grid row index of the cell
|
2014-06-23 13:49:12 +00:00
|
|
|
@result Color index of the cell's background color.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 11:56:20 +00:00
|
|
|
function TsCustomWorksheetGrid.GetBackgroundColor(ACol, ARow: Integer): TsColor;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
Result := scNotDefined;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
Result := Worksheet.ReadBackgroundColor(cell);
|
2014-05-11 11:56:20 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 11:56:20 +00:00
|
|
|
function TsCustomWorksheetGrid.GetBackgroundColors(ARect: TGridRect): TsColor;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
clr: TsColor;
|
|
|
|
begin
|
|
|
|
Result := GetBackgroundColor(ARect.Left, ARect.Top);
|
|
|
|
clr := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
2014-09-21 16:50:56 +00:00
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
begin
|
2014-05-11 11:56:20 +00:00
|
|
|
Result := GetBackgroundColor(c, r);
|
2014-09-21 16:50:56 +00:00
|
|
|
if Result <> clr then
|
|
|
|
begin
|
2014-05-11 11:56:20 +00:00
|
|
|
Result := scNotDefined;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
Returns the cell borders which are drawn around a given cell.
|
|
|
|
|
2014-06-24 11:45:16 +00:00
|
|
|
@param ACol Grid column index of the cell
|
|
|
|
@param ARow Grid row index of the cell
|
2014-06-23 13:49:12 +00:00
|
|
|
@return Set with flags indicating where borders are drawn (top/left/right/bottom)
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
function TsCustomWorksheetGrid.GetCellBorder(ACol, ARow: Integer): TsCellBorders;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
Result := [];
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
Result := Worksheet.ReadCellBorders(cell);
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-23 13:49:12 +00:00
|
|
|
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.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
function TsCustomWorksheetGrid.GetCellBorders(ARect: TGridRect): TsCellBorders;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
b: TsCellBorders;
|
|
|
|
begin
|
|
|
|
Result := GetCellBorder(ARect.Left, ARect.Top);
|
|
|
|
b := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
2014-09-21 16:50:56 +00:00
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
begin
|
2014-05-11 09:20:52 +00:00
|
|
|
Result := GetCellBorder(c, r);
|
2014-09-21 16:50:56 +00:00
|
|
|
if Result <> b then
|
|
|
|
begin
|
2014-05-11 09:20:52 +00:00
|
|
|
Result := [];
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Returns the style of the cell border line drawn along the edge specified
|
|
|
|
by the parameter ABorder of a cell. The style is defined by line style and
|
|
|
|
line color.
|
|
|
|
|
|
|
|
@param ACol Grid column index of the cell
|
|
|
|
@param ARow Grid row index of the cell
|
|
|
|
@param ABorder Identifier of the border at which the line will be drawn
|
|
|
|
(see TsCellBorder)
|
|
|
|
@return CellBorderStyle record containing information on line style and
|
2014-06-24 16:10:01 +00:00
|
|
|
line color.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
function TsCustomWorksheetGrid.GetCellBorderStyle(ACol, ARow: Integer;
|
|
|
|
ABorder: TsCellBorder): TsCellBorderStyle;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
Result := DEFAULT_BORDERSTYLES[ABorder];
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
Result := Worksheet.ReadCellBorderStyle(cell, ABorder);
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Returns the style of the cell border line drawn along the edge specified
|
|
|
|
by the parameter ABorder of a range of cells defined by the rectangle of
|
|
|
|
column and row indexes. The style is defined by linestyle and line color.
|
|
|
|
|
|
|
|
@param ARect Rectangle whose edges define the limits of the grid row and
|
2014-06-24 16:10:01 +00:00
|
|
|
column indexes of the cells.
|
2014-06-24 11:45:16 +00:00
|
|
|
@param ABorder Identifier of the border where the line will be drawn
|
|
|
|
(see TsCellBorder)
|
|
|
|
@return CellBorderStyle record containing information on line style and
|
2014-06-24 16:10:01 +00:00
|
|
|
line color.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
function TsCustomWorksheetGrid.GetCellBorderStyles(ARect: TGridRect;
|
|
|
|
ABorder: TsCellBorder): TsCellBorderStyle;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
bs: TsCellBorderStyle;
|
|
|
|
begin
|
|
|
|
Result := GetCellBorderStyle(ARect.Left, ARect.Top, ABorder);
|
|
|
|
bs := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
2014-09-21 16:50:56 +00:00
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
begin
|
2014-05-11 09:20:52 +00:00
|
|
|
Result := GetCellBorderStyle(c, r, ABorder);
|
2014-09-21 16:50:56 +00:00
|
|
|
if (Result.LineStyle <> bs.LineStyle) or (Result.Color <> bs.Color) then
|
|
|
|
begin
|
2014-05-11 09:20:52 +00:00
|
|
|
Result := DEFAULT_BORDERSTYLES[ABorder];
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
2014-05-08 12:12:06 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Returns the font to be used when painting text in a cell.
|
|
|
|
|
|
|
|
@param ACol Grid column index of the cell
|
|
|
|
@param ARow Grid row index of the cell
|
|
|
|
@return Font usable when painting on a canvas.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 16:16:59 +00:00
|
|
|
function TsCustomWorksheetGrid.GetCellFont(ACol, ARow: Integer): TFont;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
fnt: TsFont;
|
|
|
|
begin
|
|
|
|
Result := nil;
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Workbook <> nil) then
|
2014-10-19 21:20:57 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
fnt := Workbook.GetDefaultFont;
|
2015-01-23 21:54:23 +00:00
|
|
|
if (Worksheet <> nil) then
|
2014-10-19 21:20:57 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
fnt := Worksheet.ReadCellFont(cell);
|
2014-10-19 21:20:57 +00:00
|
|
|
end;
|
|
|
|
Convert_sFont_to_Font(fnt, FCellFont);
|
|
|
|
Result := FCellFont;
|
|
|
|
end;
|
2014-05-11 16:16:59 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Returns the font to be used when painting text in the cells defined by the
|
|
|
|
rectangle of row/column indexes.
|
|
|
|
|
|
|
|
@param ARect Rectangle whose edges define the limits of the grid row and
|
2014-06-24 16:10:01 +00:00
|
|
|
column indexes of the cells.
|
2014-06-24 11:45:16 +00:00
|
|
|
@return Font usable when painting on a canvas.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 16:16:59 +00:00
|
|
|
function TsCustomWorksheetGrid.GetCellFonts(ARect: TGridRect): TFont;
|
|
|
|
var
|
2015-03-05 10:35:32 +00:00
|
|
|
// c, r: Integer;
|
|
|
|
r1,c1,r2,c2: Cardinal;
|
2014-05-11 16:16:59 +00:00
|
|
|
sFont, sDefFont: TsFont;
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
Result := GetCellFont(ARect.Left, ARect.Top);
|
2014-11-03 15:34:57 +00:00
|
|
|
sDefFont := Workbook.GetDefaultFont; // Default font
|
2015-03-05 10:35:32 +00:00
|
|
|
r1 := GetWorksheetRow(ARect.Top);
|
|
|
|
c1 := GetWorksheetCol(ARect.Left);
|
|
|
|
r2 := GetWorksheetRow(ARect.Bottom);
|
|
|
|
c2 := GetWorksheetRow(ARect.Right);
|
|
|
|
for cell in Worksheet.Cells.GetRangeEnumerator(r1, c1, r2, c2) do
|
|
|
|
begin
|
|
|
|
sFont := Worksheet.ReadCellFont(cell);
|
|
|
|
if (sFont.FontName <> sDefFont.FontName) and (sFont.Size <> sDefFont.Size)
|
|
|
|
and (sFont.Style <> sDefFont.Style) and (sFont.Color <> sDefFont.Color)
|
|
|
|
then
|
|
|
|
begin
|
|
|
|
Convert_sFont_to_Font(sDefFont, FCellFont);
|
|
|
|
Result := FCellFont;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{
|
2014-05-11 16:16:59 +00:00
|
|
|
for c := ARect.Left to ARect.Right do
|
2014-09-21 16:50:56 +00:00
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(r), GetWorksheetCol(c));
|
2014-09-21 16:50:56 +00:00
|
|
|
if cell <> nil then
|
|
|
|
begin
|
2015-01-23 21:54:23 +00:00
|
|
|
sFont := Worksheet.ReadCellFont(cell);
|
2014-05-11 16:16:59 +00:00
|
|
|
if (sFont.FontName <> sDefFont.FontName) and (sFont.Size <> sDefFont.Size)
|
|
|
|
and (sFont.Style <> sDefFont.Style) and (sFont.Color <> sDefFont.Color)
|
2014-09-21 16:50:56 +00:00
|
|
|
then
|
|
|
|
begin
|
2014-05-11 16:16:59 +00:00
|
|
|
Convert_sFont_to_Font(sDefFont, FCellFont);
|
|
|
|
Result := FCellFont;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
2015-03-05 10:35:32 +00:00
|
|
|
}
|
2014-05-11 16:16:59 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Returns the height (in pixels) of the cell at ACol/ARow (of the grid).
|
|
|
|
|
|
|
|
@param ACol Grid column index of the cell
|
|
|
|
@param ARow Grid row index of the cell
|
|
|
|
@result Height of the cell in pixels. Wrapped text is handled correctly.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-30 19:09:54 +00:00
|
|
|
function TsCustomWorksheetGrid.GetCellHeight(ACol, ARow: Integer): Integer;
|
|
|
|
var
|
|
|
|
lCell: PCell;
|
|
|
|
s: String;
|
2014-05-11 09:20:52 +00:00
|
|
|
wrapped: Boolean;
|
2014-04-30 19:09:54 +00:00
|
|
|
txtR: TRect;
|
|
|
|
cellR: TRect;
|
|
|
|
flags: Cardinal;
|
2014-09-13 18:59:18 +00:00
|
|
|
r1,c1,r2,c2: Cardinal;
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt: PsCellFormat;
|
2014-04-30 19:09:54 +00:00
|
|
|
begin
|
|
|
|
Result := 0;
|
2014-05-03 21:27:31 +00:00
|
|
|
if ShowHeaders and ((ACol = 0) or (ARow = 0)) then
|
2014-04-30 19:09:54 +00:00
|
|
|
exit;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet = nil then
|
2014-04-30 19:09:54 +00:00
|
|
|
exit;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
lCell := Worksheet.FindCell(ARow-FHeaderCount, ACol-FHeaderCount);
|
2014-09-21 16:50:56 +00:00
|
|
|
if lCell <> nil then
|
|
|
|
begin
|
2015-02-22 00:12:16 +00:00
|
|
|
if Worksheet.IsMerged(lCell) then
|
2014-09-15 20:54:39 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.FindMergedRange(lCell, r1, c1, r2, c2);
|
2014-09-13 18:59:18 +00:00
|
|
|
if r1 <> r2 then
|
|
|
|
// If the merged range encloses several rows we skip automatic row height
|
|
|
|
// determination since only the height of the first row of the block
|
|
|
|
// (containing the merge base cell) would change which is very confusing.
|
|
|
|
exit;
|
|
|
|
end;
|
2014-04-30 19:09:54 +00:00
|
|
|
s := GetCellText(ACol, ARow);
|
|
|
|
if s = '' then
|
|
|
|
exit;
|
|
|
|
DoPrepareCanvas(ACol, ARow, []);
|
2015-01-23 21:54:23 +00:00
|
|
|
fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
|
|
|
wrapped := (uffWordWrap in fmt^.UsedFormattingFields)
|
|
|
|
or (fmt^.TextRotation = rtStacked);
|
2014-04-30 19:09:54 +00:00
|
|
|
// *** multi-line text ***
|
2014-09-21 16:50:56 +00:00
|
|
|
if wrapped then
|
|
|
|
begin
|
2014-04-30 19:09:54 +00:00
|
|
|
// horizontal
|
2015-01-23 21:54:23 +00:00
|
|
|
if ( (uffTextRotation in fmt^.UsedFormattingFields) and
|
|
|
|
(fmt^.TextRotation in [trHorizontal, rtStacked]))
|
|
|
|
or not (uffTextRotation in fmt^.UsedFormattingFields)
|
2014-09-21 16:50:56 +00:00
|
|
|
then
|
|
|
|
begin
|
2014-04-30 19:09:54 +00:00
|
|
|
cellR := CellRect(ACol, ARow);
|
|
|
|
InflateRect(cellR, -constCellPadding, -constCellPadding);
|
|
|
|
txtR := Bounds(cellR.Left, cellR.Top, cellR.Right-cellR.Left, cellR.Bottom-cellR.Top);
|
|
|
|
flags := DT_WORDBREAK and not DT_SINGLELINE;
|
|
|
|
LCLIntf.DrawText(Canvas.Handle, PChar(s), Length(s), txtR,
|
|
|
|
DT_CALCRECT or flags);
|
|
|
|
Result := txtR.Bottom - txtR.Top + 2*constCellPadding;
|
|
|
|
end;
|
|
|
|
// rotated wrapped text:
|
|
|
|
// do not consider this because wrapping affects cell height.
|
|
|
|
end else
|
|
|
|
// *** single-line text ***
|
|
|
|
begin
|
|
|
|
// not rotated
|
2015-01-23 21:54:23 +00:00
|
|
|
if ( not (uffTextRotation in fmt^.UsedFormattingFields) or
|
|
|
|
(fmt^.TextRotation = trHorizontal) )
|
2014-04-30 19:09:54 +00:00
|
|
|
then
|
|
|
|
Result := Canvas.TextHeight(s) + 2*constCellPadding
|
|
|
|
else
|
|
|
|
// rotated by +/- 90°
|
2015-01-23 21:54:23 +00:00
|
|
|
if (uffTextRotation in fmt^.UsedFormattingFields) and
|
|
|
|
(fmt^.TextRotation in [rt90DegreeClockwiseRotation, rt90DegreeCounterClockwiseRotation])
|
2014-04-30 19:09:54 +00:00
|
|
|
then
|
|
|
|
Result := Canvas.TextWidth(s) + 2*constCellPadding;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2015-01-30 14:48:51 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
This function defines the text to be displayed as a cell hint. By default, it
|
2015-02-28 23:46:08 +00:00
|
|
|
is the comment and/or the hyperlink attached to a cell; it can further be
|
|
|
|
modified by using the OnGetCellHint event.
|
2015-01-30 14:48:51 +00:00
|
|
|
Option goCellHints must be active for the cell hint feature to work.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
function TsCustomWorksheetGrid.GetCellHintText(ACol, ARow: Integer): String;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
2015-02-28 23:46:08 +00:00
|
|
|
hyperlink: PsHyperlink;
|
|
|
|
comment: String;
|
2015-01-30 14:48:51 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-02-28 23:46:08 +00:00
|
|
|
if cell = nil then
|
|
|
|
Result := ''
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
// Read comment
|
|
|
|
comment := Worksheet.ReadComment(cell);
|
|
|
|
// Read hyperlink info
|
2015-03-01 11:40:04 +00:00
|
|
|
if Worksheet.HasHyperlink(cell) then begin
|
2015-02-28 23:46:08 +00:00
|
|
|
hyperlink := Worksheet.FindHyperlink(cell);
|
|
|
|
if hyperlink <> nil then
|
|
|
|
begin
|
|
|
|
if hyperlink^.ToolTip <> '' then
|
|
|
|
Result := hyperlink^.ToolTip
|
|
|
|
else
|
|
|
|
Result := Format('Hyperlink: %s' + LineEnding + rsStdHyperlinkTooltip,
|
|
|
|
[hyperlink^.Target]
|
|
|
|
);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
// Combine comment and hyperlink
|
|
|
|
if (Result <> '') and (comment <> '') then
|
|
|
|
Result := comment + LineEnding + LineEnding + Result
|
|
|
|
else
|
|
|
|
if (Result = '') and (comment <> '') then
|
|
|
|
Result := comment;
|
|
|
|
end;
|
|
|
|
|
2015-01-30 14:48:51 +00:00
|
|
|
if Assigned(OnGetCellHint) then
|
|
|
|
OnGetCellHint(self, ACol, ARow, Result);
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
This function returns the text to be shown in a grid cell. The text is looked
|
|
|
|
up in the corresponding cell of the worksheet by calling its ReadAsUTF8Text
|
|
|
|
method. In case of "stacked" text rotation, line endings are inserted after
|
|
|
|
each character.
|
|
|
|
|
|
|
|
@param ACol Grid column index of the cell
|
|
|
|
@param ARow Grid row index of the cell
|
|
|
|
@return Text to be displayed in the cell.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-19 19:29:13 +00:00
|
|
|
function TsCustomWorksheetGrid.GetCellText(ACol, ARow: Integer): String;
|
|
|
|
var
|
2015-03-02 21:20:00 +00:00
|
|
|
cell: PCell;
|
2014-04-29 21:58:48 +00:00
|
|
|
r, c, i: Integer;
|
|
|
|
s: String;
|
2014-04-19 19:29:13 +00:00
|
|
|
begin
|
|
|
|
Result := '';
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
if ShowHeaders then
|
|
|
|
begin
|
2014-05-03 21:27:31 +00:00
|
|
|
// Headers
|
2014-04-19 19:29:13 +00:00
|
|
|
if (ARow = 0) and (ACol = 0) then
|
|
|
|
exit;
|
2014-09-21 16:50:56 +00:00
|
|
|
if (ARow = 0) then
|
|
|
|
begin
|
2015-02-22 23:38:28 +00:00
|
|
|
Result := GetColString(ACol - FHeaderCount);
|
2014-04-19 19:29:13 +00:00
|
|
|
exit;
|
2009-10-06 19:25:18 +00:00
|
|
|
end
|
|
|
|
else
|
2014-09-21 16:50:56 +00:00
|
|
|
if (ACol = 0) then
|
|
|
|
begin
|
2014-04-19 19:29:13 +00:00
|
|
|
Result := IntToStr(ARow);
|
|
|
|
exit;
|
2009-10-06 19:25:18 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-05-03 21:27:31 +00:00
|
|
|
r := ARow - FHeaderCount;
|
|
|
|
c := ACol - FHeaderCount;
|
2015-03-02 21:20:00 +00:00
|
|
|
cell := Worksheet.FindCell(r, c);
|
|
|
|
if cell <> nil then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2015-03-02 21:20:00 +00:00
|
|
|
Result := TrimToCell(cell);
|
|
|
|
if Worksheet.ReadTextRotation(cell) = rtStacked then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-04-29 21:58:48 +00:00
|
|
|
s := Result;
|
|
|
|
Result := '';
|
2014-09-21 16:50:56 +00:00
|
|
|
for i:=1 to Length(s) do
|
|
|
|
begin
|
2014-05-28 09:04:42 +00:00
|
|
|
Result := Result + s[i];
|
|
|
|
if i < Length(s) then Result := Result + LineEnding;
|
|
|
|
end;
|
2014-04-29 21:58:48 +00:00
|
|
|
end;
|
|
|
|
end;
|
2014-04-19 19:29:13 +00:00
|
|
|
end;
|
|
|
|
end;
|
2009-10-06 19:25:18 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-24 11:45:16 +00:00
|
|
|
Determines the text to be passed to the cell editor. The text is determined
|
2014-06-24 16:10:01 +00:00
|
|
|
from the underlying worksheet cell, but it is possible to intercept this by
|
2014-06-24 11:45:16 +00:00
|
|
|
adding a handler for the OnGetEditText event.
|
|
|
|
|
|
|
|
@param ACol Grid column index of the cell being edited
|
|
|
|
@param ARow Grid row index of the grid cell being edited
|
|
|
|
@return Text to be passed to the cell editor.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-11-18 10:19:33 +00:00
|
|
|
function TsCustomWorksheetGrid.GetEditText(ACol, ARow: Integer): string;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-07 22:44:00 +00:00
|
|
|
begin
|
2014-11-18 10:19:33 +00:00
|
|
|
if FEnhEditMode then // Initiated by "F2"
|
|
|
|
begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-03-02 21:20:00 +00:00
|
|
|
if Worksheet.IsMerged(cell) then
|
|
|
|
cell := Worksheet.FindMergeBase(cell);
|
2014-11-18 10:19:33 +00:00
|
|
|
Result := Worksheet.ReadFormulaAsString(cell, true);
|
|
|
|
if Result <> '' then
|
|
|
|
begin
|
|
|
|
if Result[1] <> '=' then Result := '=' + Result;
|
|
|
|
end else
|
2014-11-19 08:48:07 +00:00
|
|
|
if cell <> nil then
|
2014-11-18 10:19:33 +00:00
|
|
|
case cell^.ContentType of
|
|
|
|
cctNumber:
|
|
|
|
Result := FloatToStr(cell^.NumberValue);
|
|
|
|
cctDateTime:
|
|
|
|
if cell^.DateTimeValue < 1.0 then
|
|
|
|
Result := FormatDateTime('tt', cell^.DateTimeValue)
|
|
|
|
else
|
|
|
|
Result := FormatDateTime('c', cell^.DateTimeValue);
|
|
|
|
else
|
|
|
|
Result := Worksheet.ReadAsUTF8Text(cell);
|
2014-11-19 08:48:07 +00:00
|
|
|
end
|
|
|
|
else
|
|
|
|
Result := '';
|
2014-11-18 10:19:33 +00:00
|
|
|
end else
|
|
|
|
Result := GetCellText(aCol, aRow);
|
2015-03-02 21:20:00 +00:00
|
|
|
if Assigned(OnGetEditText) then
|
|
|
|
OnGetEditText(Self, aCol, aRow, Result);
|
2014-05-07 22:44:00 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Determines the style of the border between a cell and its neighbor given by
|
2014-05-09 22:00:53 +00:00
|
|
|
ADeltaCol and ADeltaRow (one of them must be 0, the other one can only be +/-1).
|
2014-09-15 20:54:39 +00:00
|
|
|
ACol and ARow are in grid units.
|
|
|
|
Result is FALSE if there is no border line.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-09 22:00:53 +00:00
|
|
|
function TsCustomWorksheetGrid.GetBorderStyle(ACol, ARow, ADeltaCol, ADeltaRow: Integer;
|
2015-03-05 10:35:32 +00:00
|
|
|
ACell: PCell; out ABorderStyle: TsCellBorderStyle): Boolean;
|
2014-05-09 22:00:53 +00:00
|
|
|
var
|
2015-03-05 10:35:32 +00:00
|
|
|
//cell,
|
|
|
|
neighborcell: PCell;
|
2014-05-09 22:00:53 +00:00
|
|
|
border, neighborborder: TsCellBorder;
|
2015-03-05 10:35:32 +00:00
|
|
|
// r, c: Cardinal;
|
2014-05-09 22:00:53 +00:00
|
|
|
begin
|
|
|
|
Result := true;
|
2014-09-21 16:50:56 +00:00
|
|
|
if (ADeltaCol = -1) and (ADeltaRow = 0) then
|
|
|
|
begin
|
2014-05-09 22:00:53 +00:00
|
|
|
border := cbWest;
|
|
|
|
neighborborder := cbEast;
|
|
|
|
end else
|
2014-09-21 16:50:56 +00:00
|
|
|
if (ADeltaCol = +1) and (ADeltaRow = 0) then
|
|
|
|
begin
|
2014-05-09 22:00:53 +00:00
|
|
|
border := cbEast;
|
|
|
|
neighborborder := cbWest;
|
|
|
|
end else
|
2014-09-21 16:50:56 +00:00
|
|
|
if (ADeltaCol = 0) and (ADeltaRow = -1) then
|
|
|
|
begin
|
2014-05-09 22:00:53 +00:00
|
|
|
border := cbNorth;
|
|
|
|
neighborborder := cbSouth;
|
|
|
|
end else
|
2014-09-21 16:50:56 +00:00
|
|
|
if (ADeltaCol = 0) and (ADeltaRow = +1) then
|
|
|
|
begin
|
2014-05-09 22:00:53 +00:00
|
|
|
border := cbSouth;
|
|
|
|
neighborBorder := cbNorth;
|
|
|
|
end else
|
2014-09-15 20:54:39 +00:00
|
|
|
raise Exception.Create('[TsCustomWorksheetGrid] Incorrect col/row for GetBorderStyle.');
|
|
|
|
|
2015-03-05 10:35:32 +00:00
|
|
|
// r := GetWorksheetRow(ARow);
|
|
|
|
// c := GetWorksheetCol(ACol);
|
|
|
|
//cell := Worksheet.FindCell(r, c);
|
2014-09-15 20:54:39 +00:00
|
|
|
if (ARow - FHeaderCount + ADeltaRow < 0) or (ACol - FHeaderCount + ADeltaCol < 0) then
|
2014-07-30 22:51:59 +00:00
|
|
|
neighborcell := nil
|
|
|
|
else
|
2014-11-03 15:34:57 +00:00
|
|
|
neighborcell := Worksheet.FindCell(ARow - FHeaderCount + ADeltaRow, ACol - FHeaderCount + ADeltaCol);
|
2014-09-15 20:54:39 +00:00
|
|
|
|
2014-05-09 22:00:53 +00:00
|
|
|
// Only cell has border, but neighbor has not
|
2015-03-05 10:35:32 +00:00
|
|
|
if HasBorder(ACell, border) and not HasBorder(neighborCell, neighborBorder) then
|
2014-09-15 20:54:39 +00:00
|
|
|
begin
|
2015-03-05 10:35:32 +00:00
|
|
|
if Worksheet.InSameMergedRange(ACell, neighborcell) then
|
2014-09-15 20:54:39 +00:00
|
|
|
result := false
|
|
|
|
else
|
2015-03-05 10:35:32 +00:00
|
|
|
ABorderStyle := Worksheet.ReadCellBorderStyle(ACell, border)
|
2014-09-15 20:54:39 +00:00
|
|
|
end
|
2014-05-09 22:00:53 +00:00
|
|
|
else
|
|
|
|
// Only neighbor has border, cell has not
|
2015-03-05 10:35:32 +00:00
|
|
|
if not HasBorder(ACell, border) and HasBorder(neighborCell, neighborBorder) then
|
2014-09-15 20:54:39 +00:00
|
|
|
begin
|
2015-03-05 10:35:32 +00:00
|
|
|
if Worksheet.InSameMergedRange(ACell, neighborcell) then
|
2014-09-15 20:54:39 +00:00
|
|
|
result := false
|
|
|
|
else
|
2015-02-22 00:12:16 +00:00
|
|
|
ABorderStyle := Worksheet.ReadCellBorderStyle(neighborcell, neighborborder);
|
2014-09-15 20:54:39 +00:00
|
|
|
end
|
2014-05-09 22:00:53 +00:00
|
|
|
else
|
|
|
|
// Both cells have shared border -> use top or left border
|
2015-03-05 10:35:32 +00:00
|
|
|
if HasBorder(ACell, border) and HasBorder(neighborCell, neighborBorder) then
|
2014-09-15 20:54:39 +00:00
|
|
|
begin
|
2015-03-05 10:35:32 +00:00
|
|
|
if Worksheet.InSameMergedRange(ACell, neighborcell) then
|
2014-09-15 20:54:39 +00:00
|
|
|
result := false
|
|
|
|
else
|
2014-05-09 22:00:53 +00:00
|
|
|
if (border in [cbNorth, cbWest]) then
|
2015-02-22 00:12:16 +00:00
|
|
|
ABorderStyle := Worksheet.ReadCellBorderStyle(neighborcell, neighborborder)
|
2014-05-09 22:00:53 +00:00
|
|
|
else
|
2015-03-05 10:35:32 +00:00
|
|
|
ABorderStyle := Worksheet.ReadCellBorderStyle(ACell, border);
|
2014-05-09 22:00:53 +00:00
|
|
|
end else
|
|
|
|
Result := false;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Converts a column index of the worksheet to a column index usable in the grid.
|
|
|
|
This is required because worksheet indexes always start at zero while
|
|
|
|
grid indexes also have to account for the column/row headers.
|
|
|
|
|
|
|
|
@param ASheetCol Worksheet column index
|
|
|
|
@return Grid column index
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-06-05 21:57:23 +00:00
|
|
|
function TsCustomWorksheetGrid.GetGridCol(ASheetCol: Cardinal): Integer;
|
|
|
|
begin
|
2014-09-15 20:54:39 +00:00
|
|
|
Result := Integer(ASheetCol) + FHeaderCount
|
2014-06-05 21:57:23 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Converts a row index of the worksheet to a row index usable in the grid.
|
|
|
|
This is required because worksheet indexes always start at zero while
|
|
|
|
grid indexes also have to account for the column/row headers.
|
|
|
|
|
|
|
|
@param ASheetRow Worksheet row index
|
|
|
|
@return Grid row index
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-06-05 21:57:23 +00:00
|
|
|
function TsCustomWorksheetGrid.GetGridRow(ASheetRow: Cardinal): Integer;
|
|
|
|
begin
|
2014-09-15 20:54:39 +00:00
|
|
|
Result := Integer(ASheetRow) + FHeaderCount;
|
2014-06-05 21:57:23 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Returns a list of worksheets contained in the file. Useful for assigning to
|
|
|
|
user controls like TabControl, Combobox etc. in order to select a sheet.
|
|
|
|
|
|
|
|
@param ASheets List of strings containing the names of the worksheets of
|
|
|
|
the workbook
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure TsCustomWorksheetGrid.GetSheets(const ASheets: TStrings);
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
ASheets.Clear;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Workbook) then
|
|
|
|
for i:=0 to Workbook.GetWorksheetCount-1 do
|
|
|
|
ASheets.Add(Workbook.GetWorksheetByIndex(i).Name);
|
2014-04-19 19:29:13 +00:00
|
|
|
end;
|
2009-10-06 19:25:18 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Calculates the index of the worksheet column that is displayed in the
|
2014-05-08 21:52:04 +00:00
|
|
|
given column of the grid. If the sheet headers are turned on, both numbers
|
2014-06-25 08:22:37 +00:00
|
|
|
differ by 1, otherwise they are equal. Saves an "if" in cases.
|
|
|
|
|
|
|
|
@param AGridCol Index of a grid column
|
|
|
|
@return Index of a the corresponding worksheet column
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-07 22:44:00 +00:00
|
|
|
function TsCustomWorksheetGrid.GetWorksheetCol(AGridCol: Integer): cardinal;
|
|
|
|
begin
|
2014-09-14 16:16:23 +00:00
|
|
|
if (FHeaderCount > 0) and (AGridCol = 0) then
|
|
|
|
Result := Cardinal(-1)
|
|
|
|
else
|
|
|
|
Result := AGridCol - FHeaderCount;
|
2014-05-07 22:44:00 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Calculates the index of the worksheet row that is displayed in the
|
2014-05-08 21:52:04 +00:00
|
|
|
given row of the grid. If the sheet headers are turned on, both numbers
|
2014-06-25 08:22:37 +00:00
|
|
|
differ by 1, otherwise they are equal. Saves an "if" in some cases.
|
|
|
|
|
|
|
|
@param AGridRow Index of a grid row
|
|
|
|
@resturn Index of the corresponding worksheet row.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-07 22:44:00 +00:00
|
|
|
function TsCustomWorksheetGrid.GetWorksheetRow(AGridRow: Integer): Cardinal;
|
|
|
|
begin
|
2014-09-14 16:16:23 +00:00
|
|
|
if (FHeaderCount > 0) and (AGridRow = 0) then
|
|
|
|
Result := Cardinal(-1)
|
|
|
|
else
|
|
|
|
Result := AGridRow - FHeaderCount;
|
2014-05-07 22:44:00 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Returns true if the cell has the given border.
|
2014-06-25 08:22:37 +00:00
|
|
|
|
|
|
|
@param ACell Pointer to cell considered
|
|
|
|
@param ABorder Indicator for border to be checked for visibility
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-11 09:20:52 +00:00
|
|
|
function TsCustomWorksheetGrid.HasBorder(ACell: PCell; ABorder: TsCellBorder): Boolean;
|
|
|
|
begin
|
2015-01-23 21:54:23 +00:00
|
|
|
if Worksheet = nil then
|
|
|
|
result := false
|
|
|
|
else
|
|
|
|
Result := ABorder in Worksheet.ReadCellBorders(ACell);
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Inherited from TCustomGrid. Is called when column widths or row heights
|
|
|
|
have changed. Stores the new column width or row height in the worksheet.
|
|
|
|
|
|
|
|
@param IsColumn Specifies whether the changed parameter is a column width
|
|
|
|
(true) or a row height (false)
|
|
|
|
@param Index Index of the changed column or row
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-10-03 16:09:54 +00:00
|
|
|
procedure TsCustomWorksheetGrid.HeaderSized(IsColumn: Boolean; AIndex: Integer);
|
2014-05-08 21:52:04 +00:00
|
|
|
var
|
|
|
|
w0: Integer;
|
2014-05-31 21:04:53 +00:00
|
|
|
h, h_pts: Single;
|
2014-05-08 21:52:04 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet = nil then
|
2014-05-08 21:52:04 +00:00
|
|
|
exit;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
Convert_sFont_to_Font(Workbook.GetDefaultFont, Canvas.Font);
|
2014-05-08 21:52:04 +00:00
|
|
|
if IsColumn then begin
|
|
|
|
// The grid's column width is in "pixels", the worksheet's column width is
|
|
|
|
// in "characters".
|
|
|
|
w0 := Canvas.TextWidth('0');
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.WriteColWidth(GetWorksheetCol(AIndex), ColWidths[AIndex] / w0);
|
2014-05-08 21:52:04 +00:00
|
|
|
end else begin
|
|
|
|
// The grid's row heights are in "pixels", the worksheet's row heights are
|
2014-05-31 21:04:53 +00:00
|
|
|
// in "lines"
|
2014-10-03 16:09:54 +00:00
|
|
|
h_pts := PxToPts(RowHeights[AIndex] - 4, Screen.PixelsPerInch); // in points
|
2014-11-03 15:34:57 +00:00
|
|
|
h := h_pts / (Workbook.GetFont(0).Size + ROW_HEIGHT_CORRECTION);
|
|
|
|
Worksheet.WriteRowHeight(GetWorksheetRow(AIndex), h);
|
2014-05-08 21:52:04 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2015-02-23 18:50:29 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Clicking into cells with hyperlinks poses a user-interface problem:
|
|
|
|
normally the cell should go into edit mode. But with hyperlinks a click should
|
|
|
|
also execute the hyperlink. How to distinguish both cases?
|
|
|
|
In order to keep both features for hyperlinks we follow a strategy similar to
|
|
|
|
Excel: a short click selects the cell for editing as usual; a longer click
|
|
|
|
opens the hyperlink by means of a timer ("FHyperlinkTimer") (in Excel, in
|
|
|
|
fact, the behavior is opposite, but this one here is easier to implement.)
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.HyperlinkTimerElapsed(Sender: TObject);
|
|
|
|
begin
|
|
|
|
if FHyperlinkTimer.Enabled then begin
|
|
|
|
FHyperlinkTimer.Enabled := false;
|
|
|
|
FGridState := gsNormal; // this prevents selecting a cell block
|
|
|
|
EditorMode := false; // this prevents editing the clicked cell
|
|
|
|
ExecuteHyperlink; // Execute the hyperlink
|
|
|
|
FHyperlinkCell := nil;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-07-26 17:05:21 +00:00
|
|
|
Inserts an empty column before the column specified
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-07-26 17:05:21 +00:00
|
|
|
procedure TsCustomWorksheetGrid.InsertCol(AGridCol: Integer);
|
|
|
|
var
|
|
|
|
c: Cardinal;
|
|
|
|
begin
|
|
|
|
if AGridCol < FHeaderCount then
|
|
|
|
exit;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
if LongInt(Worksheet.GetLastColIndex) + 1 + FHeaderCount >= FInitColCount then
|
2014-07-26 17:05:21 +00:00
|
|
|
ColCount := ColCount + 1;
|
|
|
|
c := AGridCol - FHeaderCount;
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.InsertCol(c);
|
2014-07-26 17:05:21 +00:00
|
|
|
|
|
|
|
UpdateColWidths(AGridCol);
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-07-26 17:05:21 +00:00
|
|
|
Inserts an empty row before the row specified
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-07-26 17:05:21 +00:00
|
|
|
procedure TsCustomWorksheetGrid.InsertRow(AGridRow: Integer);
|
|
|
|
var
|
|
|
|
r: Cardinal;
|
|
|
|
begin
|
|
|
|
if AGridRow < FHeaderCount then
|
|
|
|
exit;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
if LongInt(Worksheet.GetlastRowIndex) + 1 + FHeaderCount >= FInitRowCount then
|
2014-07-26 17:05:21 +00:00
|
|
|
RowCount := RowCount + 1;
|
|
|
|
r := AGridRow - FHeaderCount;
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.InsertRow(r);
|
2014-07-26 17:05:21 +00:00
|
|
|
|
|
|
|
UpdateRowHeights(AGridRow);
|
|
|
|
end;
|
2014-05-22 21:54:24 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Internal general text drawing method.
|
|
|
|
|
|
|
|
@param AText Text to be drawn
|
|
|
|
@param AMeasureText Text used for checking if the text fits into the
|
|
|
|
text rectangle. If too large and ReplaceTooLong = true,
|
|
|
|
a series of # is drawn.
|
|
|
|
@param ARect Rectangle in which the text is drawn
|
|
|
|
@param AJustification Determines whether the text is drawn at the "start" (0),
|
|
|
|
"center" (1) or "end" (2) of the drawing rectangle.
|
|
|
|
Start/center/end are seen along the text drawing
|
|
|
|
direction.
|
|
|
|
@param ACellHorAlign Is the HorAlignment property stored in the cell
|
|
|
|
@param ACellVertAlign Is the VertAlignment property stored in the cell
|
|
|
|
@param ATextRot Determines the rotation angle of the text.
|
|
|
|
@param ATextWrap Determines if the text can wrap into multiple lines
|
|
|
|
@param ReplaceTooLang If true too-long texts are replaced by a series of
|
|
|
|
# chars filling the cell.
|
|
|
|
|
|
|
|
@Note The reason to separate AJustification from ACellHorAlign and ACelVertAlign is
|
2014-05-28 09:04:42 +00:00
|
|
|
the output of nfAccounting formatted numbers where the numbers are always
|
2014-06-23 09:15:56 +00:00
|
|
|
right-aligned, and the currency symbol is left-aligned.
|
2014-06-25 08:22:37 +00:00
|
|
|
THIS FEATURE IS CURRENTLY NO LONGER SUPPORTED.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-22 21:54:24 +00:00
|
|
|
procedure TsCustomWorksheetGrid.InternalDrawTextInCell(AText, AMeasureText: String;
|
|
|
|
ARect: TRect; AJustification: Byte; ACellHorAlign: TsHorAlignment;
|
|
|
|
ACellVertAlign: TsVertAlignment; ATextRot: TsTextRotation;
|
|
|
|
ATextWrap, ReplaceTooLong: Boolean);
|
|
|
|
var
|
|
|
|
ts: TTextStyle;
|
|
|
|
flags: Cardinal;
|
|
|
|
txt: String;
|
|
|
|
txtRect: TRect;
|
|
|
|
P: TPoint;
|
|
|
|
w, h, h0, hline: Integer;
|
|
|
|
i: Integer;
|
|
|
|
L: TStrings;
|
|
|
|
wrapped: Boolean;
|
2014-10-06 10:43:10 +00:00
|
|
|
pLeft: Integer = 0;
|
|
|
|
pRight: Integer = 0;
|
2014-05-22 21:54:24 +00:00
|
|
|
begin
|
|
|
|
wrapped := ATextWrap or (ATextRot = rtStacked);
|
|
|
|
if AMeasureText = '' then txt := AText else txt := AMeasureText;
|
|
|
|
flags := DT_WORDBREAK and not DT_SINGLELINE or DT_CALCRECT;
|
|
|
|
txtRect := ARect;
|
|
|
|
|
|
|
|
if (ATextRot in [trHorizontal, rtStacked]) then begin
|
|
|
|
// HORIZONAL TEXT DRAWING DIRECTION
|
|
|
|
Canvas.Font.Orientation := 0;
|
|
|
|
ts := Canvas.TextStyle;
|
|
|
|
ts.Opaque := false;
|
2014-09-25 10:36:17 +00:00
|
|
|
ts.Clipping := not FTextOverflowing;
|
2014-05-22 21:54:24 +00:00
|
|
|
if wrapped then begin
|
|
|
|
ts.Wordbreak := true;
|
|
|
|
ts.SingleLine := false;
|
|
|
|
LCLIntf.DrawText(Canvas.Handle, PChar(txt), Length(txt), txtRect, flags);
|
|
|
|
w := txtRect.Right - txtRect.Left;
|
|
|
|
h := txtRect.Bottom - txtRect.Top;
|
|
|
|
end else begin
|
|
|
|
ts.WordBreak := false;
|
|
|
|
ts.SingleLine := false;
|
|
|
|
w := Canvas.TextWidth(AMeasureText);
|
|
|
|
h := Canvas.TextHeight('Tg');
|
|
|
|
end;
|
|
|
|
|
|
|
|
if ATextRot = rtStacked then begin
|
|
|
|
// Stacked
|
|
|
|
ts.Alignment := HOR_ALIGNMENTS[ACellHorAlign];
|
|
|
|
if h > ARect.Bottom - ARect.Top then begin
|
|
|
|
if ReplaceTooLong then begin
|
|
|
|
txt := '#';
|
|
|
|
repeat
|
|
|
|
txt := txt + '#';
|
|
|
|
LCLIntf.DrawText(Canvas.Handle, PChar(txt), Length(txt), txtRect, flags);
|
|
|
|
until txtRect.Bottom - txtRect.Top > ARect.Bottom - ARect.Top;
|
|
|
|
AText := copy(txt, 1, Length(txt)-1);
|
|
|
|
end;
|
|
|
|
ts.Layout := tlTop;
|
|
|
|
end else
|
|
|
|
case AJustification of
|
|
|
|
0: ts.Layout := tlTop;
|
|
|
|
1: ts.Layout := tlCenter;
|
|
|
|
2: ts.Layout := tlBottom;
|
|
|
|
end;
|
|
|
|
Canvas.TextStyle := ts;
|
|
|
|
Canvas.TextRect(ARect, ARect.Left, ARect.Top, AText);
|
|
|
|
end else begin
|
|
|
|
// Horizontal
|
|
|
|
if h > ARect.Bottom - ARect.Top then
|
|
|
|
ts.Layout := tlTop
|
|
|
|
else
|
|
|
|
ts.Layout := VERT_ALIGNMENTS[ACellVertAlign];
|
2014-09-14 16:16:23 +00:00
|
|
|
|
|
|
|
// too long text
|
|
|
|
if w > ARect.Right - ARect.Left then
|
|
|
|
if ReplaceTooLong then
|
|
|
|
begin
|
|
|
|
txt := '';
|
|
|
|
repeat
|
|
|
|
txt := txt + '#';
|
|
|
|
LCLIntf.DrawText(Canvas.Handle, PChar(txt), Length(txt), txtRect, flags);
|
|
|
|
until txtRect.Right - txtRect.Left > ARect.Right - ARect.Left;
|
|
|
|
AText := Copy(txt, 1, Length(txt)-1);
|
|
|
|
w := Canvas.TextWidth(AText);
|
|
|
|
end;
|
|
|
|
|
|
|
|
P := ARect.TopLeft;
|
|
|
|
case AJustification of
|
|
|
|
0: ts.Alignment := taLeftJustify;
|
2015-02-22 00:12:16 +00:00
|
|
|
1: if (FDrawingCell <> nil) and not Worksheet.IsMerged(FDrawingCell) then
|
2014-09-14 16:16:23 +00:00
|
|
|
begin
|
|
|
|
// Special treatment for overflowing cells: they must be centered
|
|
|
|
// at their original column, not in the total enclosing rectangle.
|
2014-10-06 10:43:10 +00:00
|
|
|
ColRowToOffset(true, true, integer(FDrawingCell^.Col) + FHeaderCount, pLeft, pRight);
|
2014-09-14 16:16:23 +00:00
|
|
|
P.X := (pLeft + pRight - w) div 2;
|
|
|
|
P.y := ARect.Top;
|
|
|
|
ts.Alignment := taLeftJustify;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
ts.Alignment := taCenter;
|
|
|
|
2: ts.Alignment := taRightJustify;
|
|
|
|
end;
|
2014-05-22 21:54:24 +00:00
|
|
|
Canvas.TextStyle := ts;
|
2014-09-14 16:16:23 +00:00
|
|
|
Canvas.TextRect(ARect, P.X, P.Y, AText);
|
2014-05-22 21:54:24 +00:00
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
// ROTATED TEXT DRAWING DIRECTION
|
2014-06-24 16:10:01 +00:00
|
|
|
// Since there is no good API for multiline rotated text, we draw the text
|
2014-05-22 21:54:24 +00:00
|
|
|
// line by line.
|
|
|
|
L := TStringList.Create;
|
|
|
|
try
|
|
|
|
txtRect := Bounds(ARect.Left, ARect.Top, ARect.Bottom - ARect.Top, ARect.Right - ARect.Left);
|
|
|
|
hline := Canvas.TextHeight('Tg');
|
|
|
|
if wrapped then begin
|
|
|
|
// Extract wrapped lines
|
|
|
|
L.Text := WrapText(Canvas, txt, txtRect.Right - txtRect.Left);
|
|
|
|
// Calculate size of wrapped text
|
|
|
|
flags := DT_WORDBREAK and not DT_SINGLELINE or DT_CALCRECT;
|
|
|
|
LCLIntf.DrawText(Canvas.Handle, PChar(L.Text), Length(L.Text), txtRect, flags);
|
|
|
|
w := txtRect.Right - txtRect.Left;
|
|
|
|
h := txtRect.Bottom - txtRect.Top;
|
|
|
|
h0 := hline;
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
L.Text := txt;
|
|
|
|
w := Canvas.TextWidth(txt);
|
|
|
|
h := hline;
|
|
|
|
h0 := 0;
|
|
|
|
end;
|
2014-05-28 09:04:42 +00:00
|
|
|
// w and h are seen along the text direction, not x/y!
|
2014-05-22 21:54:24 +00:00
|
|
|
|
|
|
|
if w > ARect.Bottom - ARect.Top then begin
|
|
|
|
if ReplaceTooLong then begin
|
|
|
|
txt := '#';
|
|
|
|
repeat
|
|
|
|
txt := txt + '#';
|
|
|
|
until Canvas.TextWidth(txt) > ARect.Bottom - ARect.Top;
|
|
|
|
L.Text := Copy(txt, 1, Length(txt)-1);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
ts := Canvas.TextStyle;
|
|
|
|
ts.SingleLine := true; // Draw text line by line
|
|
|
|
ts.Clipping := false;
|
|
|
|
ts.Layout := tlTop;
|
|
|
|
ts.Alignment := taLeftJustify;
|
|
|
|
ts.Opaque := false;
|
|
|
|
|
|
|
|
if ATextRot = rt90DegreeClockwiseRotation then begin
|
|
|
|
// Clockwise
|
|
|
|
Canvas.Font.Orientation := -900;
|
|
|
|
case ACellHorAlign of
|
|
|
|
haLeft : P.X := Min(ARect.Right-1, ARect.Left + h - h0);
|
|
|
|
haCenter : P.X := Min(ARect.Right-1, (ARect.Left + ARect.Right + h) div 2);
|
|
|
|
haRight : P.X := ARect.Right - 1;
|
|
|
|
end;
|
|
|
|
for i:= 0 to L.Count-1 do begin
|
|
|
|
w := Canvas.TextWidth(L[i]);
|
|
|
|
case AJustification of
|
|
|
|
0: P.Y := ARect.Top; // corresponds to "top"
|
|
|
|
1: P.Y := Max(ARect.Top, (Arect.Top + ARect.Bottom - w) div 2); // "center"
|
2014-05-28 09:04:42 +00:00
|
|
|
2: P.Y := Max(ARect.Top, ARect.Bottom - w); // "bottom"
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
2014-05-22 21:54:24 +00:00
|
|
|
Canvas.TextRect(ARect, P.X, P.Y, L[i], ts);
|
|
|
|
dec(P.X, hline);
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
// Counter-clockwise
|
|
|
|
Canvas.Font.Orientation := +900;
|
|
|
|
case ACellHorAlign of
|
|
|
|
haLeft : P.X := ARect.Left;
|
|
|
|
haCenter : P.X := Max(ARect.Left, (ARect.Left + ARect.Right - h + h0) div 2);
|
|
|
|
haRight : P.X := MAx(ARect.Left, ARect.Right - h + h0);
|
|
|
|
end;
|
|
|
|
for i:= 0 to L.Count-1 do begin
|
|
|
|
w := Canvas.TextWidth(L[i]);
|
|
|
|
case AJustification of
|
|
|
|
0: P.Y := ARect.Bottom; // like "Bottom"
|
|
|
|
1: P.Y := Min(ARect.Bottom, (ARect.Top + ARect.Bottom + w) div 2); // "Center"
|
|
|
|
2: P.Y := Min(ARect.Bottom, ARect.Top + w); // like "top"
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
2014-05-22 21:54:24 +00:00
|
|
|
Canvas.TextRect(ARect, P.X, P.Y, L[i], ts);
|
|
|
|
inc(P.X, hline);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
L.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Standard key handling method inherited from TCustomGrid. Is overridden to
|
|
|
|
catch the ESC key during editing in order to restore the old cell text
|
2014-05-22 21:54:24 +00:00
|
|
|
|
2014-06-25 08:22:37 +00:00
|
|
|
@param Key Key which has been pressed
|
|
|
|
@param Shift Additional shift keys which are pressed
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-05-08 15:54:29 +00:00
|
|
|
procedure TsCustomWorksheetGrid.KeyDown(var Key : Word; Shift : TShiftState);
|
|
|
|
begin
|
2014-11-18 10:19:33 +00:00
|
|
|
if (Key = VK_F2) then
|
|
|
|
FEnhEditMode := true
|
|
|
|
else
|
2014-05-08 15:54:29 +00:00
|
|
|
if (Key = VK_ESCAPE) and FEditing then begin
|
|
|
|
SetEditText(Col, Row, FOldEditText);
|
|
|
|
EditorHide;
|
2014-06-17 22:00:23 +00:00
|
|
|
exit;
|
2014-05-08 15:54:29 +00:00
|
|
|
end;
|
2014-06-17 22:00:23 +00:00
|
|
|
inherited;
|
2014-05-08 15:54:29 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2014-06-25 08:22:37 +00:00
|
|
|
Standard method inherited from TCustomGrid. Is overridden to create an
|
|
|
|
empty workbook
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2014-04-19 19:29:13 +00:00
|
|
|
procedure TsCustomWorksheetGrid.Loaded;
|
|
|
|
begin
|
|
|
|
inherited;
|
2015-01-05 23:32:49 +00:00
|
|
|
if FWorkbookSource = nil then
|
2015-01-11 16:23:47 +00:00
|
|
|
// CreateNewWorkbook;
|
2015-01-05 23:32:49 +00:00
|
|
|
NewWorkbook(FInitColCount, FInitRowCount);
|
2014-04-19 19:29:13 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Loads the worksheet into the grid and displays its contents.
|
2014-05-08 15:54:29 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
@param AWorksheet Worksheet to be displayed in the grid
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.LoadFromWorksheet(AWorksheet: TsWorksheet);
|
2014-08-13 14:05:29 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if FWorkbookSource <> nil then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
FOwnedWorksheet := AWorksheet;
|
|
|
|
if FOwnedWorksheet <> nil then begin
|
2015-03-16 00:05:56 +00:00
|
|
|
inc(FLockSetup);
|
2014-11-03 15:34:57 +00:00
|
|
|
FOwnedWorksheet.OnChangeCell := @ChangedCellHandler;
|
|
|
|
FOwnedWorksheet.OnChangeFont := @ChangedFontHandler;
|
|
|
|
ShowHeaders := (soShowHeaders in Worksheet.Options);
|
|
|
|
ShowGridLines := (soShowGridLines in Worksheet.Options);
|
|
|
|
if (soHasFrozenPanes in Worksheet.Options) then begin
|
|
|
|
FrozenCols := FOwnedWorksheet.LeftPaneWidth;
|
|
|
|
FrozenRows := FOwnedWorksheet.TopPaneHeight;
|
2014-09-21 16:50:56 +00:00
|
|
|
end else begin
|
|
|
|
FrozenCols := 0;
|
|
|
|
FrozenRows := 0;
|
|
|
|
end;
|
|
|
|
Row := FrozenRows;
|
|
|
|
Col := FrozenCols;
|
2015-03-16 00:05:56 +00:00
|
|
|
dec(FLockSetup);
|
2014-08-13 14:05:29 +00:00
|
|
|
end;
|
2014-09-21 16:50:56 +00:00
|
|
|
Setup;
|
2014-08-13 14:05:29 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Creates a new workbook and loads the given file into it. The file is assumed
|
|
|
|
to have the given file format. Shows the sheet with the given sheet index.
|
|
|
|
|
|
|
|
@param AFileName Name of the file to be loaded
|
|
|
|
@param AFormat Spreadsheet file format assumed for the file
|
|
|
|
@param AWorksheetIndex Index of the worksheet to be displayed in the grid
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.LoadFromSpreadsheetFile(AFileName: string;
|
|
|
|
AFormat: TsSpreadsheetFormat; AWorksheetIndex: Integer);
|
2014-05-11 11:56:20 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if FOwnsWorkbook then
|
|
|
|
FreeAndNil(FOwnedWorkbook);
|
|
|
|
|
|
|
|
if FWorkbookSource <> nil then
|
|
|
|
FWorkbookSource.LoadFromSpreadsheetFile(AFileName, AFormat, AWorksheetIndex)
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
CreateNewWorkbook;
|
|
|
|
Workbook.ReadFromFile(AFileName, AFormat);
|
|
|
|
LoadFromWorksheet(Workbook.GetWorksheetByIndex(AWorksheetIndex));
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
2014-05-11 11:56:20 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Creates a new workbook and loads the given file into it. The file format
|
|
|
|
is determined automatically. Shows the sheet with the given sheet index.
|
|
|
|
|
|
|
|
@param AFileName Name of the file to be loaded
|
|
|
|
@param AWorksheetIndex Index of the worksheet to be shown in the grid
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.LoadFromSpreadsheetFile(AFileName: string;
|
|
|
|
AWorksheetIndex: Integer);
|
2014-05-11 11:56:20 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if FOwnsWorkbook then
|
|
|
|
FreeAndNil(FOwnedWorkbook);
|
|
|
|
|
|
|
|
if FWorkbookSource <> nil then
|
|
|
|
FWorkbookSource.LoadFromSpreadsheetFile(AFileName, AWorksheetIndex)
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
CreateNewWorkbook;
|
|
|
|
Workbook.ReadFromFile(AFilename);
|
|
|
|
LoadFromWorksheet(Workbook.GetWorksheetByIndex(AWorksheetIndex));
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Notification message received from the WorkbookLink telling which item of the
|
|
|
|
spreadsheet has changed.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.ListenerNotification(AChangedItems: TsNotificationItems;
|
|
|
|
AData: Pointer = nil);
|
|
|
|
var
|
|
|
|
grow, gcol: Integer;
|
|
|
|
begin
|
|
|
|
Unused(AData);
|
|
|
|
|
|
|
|
// Nothing to do for "workbook changed" because this is always combined with
|
|
|
|
// "worksheet changed".
|
|
|
|
|
|
|
|
// Worksheet changed
|
|
|
|
if (lniWorksheet in AChangedItems) then
|
|
|
|
begin
|
|
|
|
if (Worksheet <> nil) then
|
|
|
|
begin
|
2015-03-16 00:05:56 +00:00
|
|
|
inc(FLockSetup);
|
2014-11-03 15:34:57 +00:00
|
|
|
ShowHeaders := (soShowHeaders in Worksheet.Options);
|
|
|
|
ShowGridLines := (soShowGridLines in Worksheet.Options);
|
|
|
|
if (soHasFrozenPanes in Worksheet.Options) then begin
|
|
|
|
FrozenCols := Worksheet.LeftPaneWidth;
|
|
|
|
FrozenRows := Worksheet.TopPaneHeight;
|
|
|
|
end else begin
|
|
|
|
FrozenCols := 0;
|
|
|
|
FrozenRows := 0;
|
|
|
|
end;
|
2015-03-16 00:05:56 +00:00
|
|
|
dec(FLockSetup);
|
2014-11-03 15:34:57 +00:00
|
|
|
end;
|
|
|
|
Setup;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Cell value or format changed
|
|
|
|
if (lniCell in AChangedItems) then
|
|
|
|
Invalidate;
|
|
|
|
|
|
|
|
// Selection changed
|
|
|
|
if (lniSelection in AChangedItems) and (Worksheet <> nil) then
|
|
|
|
begin
|
2014-11-04 21:56:24 +00:00
|
|
|
grow := GetGridRow(Worksheet.ActiveCellRow);
|
|
|
|
gcol := GetGridCol(Worksheet.ActiveCellCol);
|
2014-11-03 15:34:57 +00:00
|
|
|
if (grow <> Row) or (gcol <> Col) then
|
|
|
|
MoveExtend(false, gcol, grow);
|
2014-05-11 11:56:20 +00:00
|
|
|
end;
|
2014-11-17 22:18:40 +00:00
|
|
|
|
|
|
|
// Abort selection because of an error
|
|
|
|
if (lniAbortSelection in AChangedItems) and (Worksheet <> nil) then
|
|
|
|
begin
|
|
|
|
MouseUp(mbLeft, [], GCache.ClickMouse.X, GCache.ClickMouse.Y);
|
|
|
|
// HOW TO DO THIS???? SelectActive not working...
|
|
|
|
end;
|
2014-11-27 15:20:29 +00:00
|
|
|
|
|
|
|
// Row height (after font change).
|
|
|
|
if (lniRow in AChangedItems) and (Worksheet <> nil) then
|
|
|
|
begin
|
2015-01-09 22:25:20 +00:00
|
|
|
grow := GetGridRow({%H-}PtrInt(AData));
|
2014-11-27 15:20:29 +00:00
|
|
|
RowHeights[grow] := CalcAutoRowHeight(grow);
|
|
|
|
end;
|
2014-05-11 11:56:20 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Merges the selected cells to a single large cell
|
|
|
|
Only the upper left cell can have content and formatting (which is extended
|
|
|
|
into the other cells).
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.MergeCells;
|
2014-05-11 09:20:52 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.MergeCells(
|
2014-09-21 16:50:56 +00:00
|
|
|
GetWorksheetRow(Selection.Top),
|
|
|
|
GetWorksheetCol(Selection.Left),
|
|
|
|
GetWorksheetRow(Selection.Bottom),
|
|
|
|
GetWorksheetCol(Selection.Right)
|
|
|
|
);
|
|
|
|
end;
|
|
|
|
|
2014-11-19 08:48:07 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2015-02-22 23:38:28 +00:00
|
|
|
Standard mouse down handler. Is overridden here to handle hyperlinks and to
|
|
|
|
enter "enhanced edit mode" which removes formatting from the values and
|
|
|
|
presents formulas for editing.
|
2014-11-19 08:48:07 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.MouseDown(Button: TMouseButton;
|
|
|
|
Shift: TShiftState; X, Y: Integer);
|
2015-02-23 18:50:29 +00:00
|
|
|
{todo: extend such that the hyperlink is handled only when the text is clicked (tough because of overflow cells!) }
|
2015-02-22 23:38:28 +00:00
|
|
|
var
|
|
|
|
mouseCell: TPoint;
|
|
|
|
cell: PCell;
|
2015-02-23 18:50:29 +00:00
|
|
|
r, c: Cardinal;
|
2014-11-19 08:48:07 +00:00
|
|
|
begin
|
|
|
|
inherited;
|
2015-02-22 23:38:28 +00:00
|
|
|
|
2015-02-23 18:50:29 +00:00
|
|
|
{ Prepare processing of the hyperlink: triggers a timer, the hyperlink is
|
|
|
|
executed when the timer has expired (see HyperlinkTimerElapsed). }
|
|
|
|
if (ssLeft in Shift) then
|
2015-02-22 23:38:28 +00:00
|
|
|
begin
|
|
|
|
mouseCell := MouseToCell(Point(X, Y));
|
|
|
|
r := GetWorksheetRow(mouseCell.Y);
|
|
|
|
c := GetWorksheetCol(mouseCell.X);
|
|
|
|
cell := Worksheet.FindCell(r, c);
|
2015-02-23 18:50:29 +00:00
|
|
|
if Worksheet.IsMerged(cell) then
|
|
|
|
cell := Worksheet.FindMergeBase(cell);
|
2015-03-01 11:40:04 +00:00
|
|
|
if Worksheet.HasHyperlink(cell) then
|
2015-02-22 23:38:28 +00:00
|
|
|
begin
|
2015-02-23 18:50:29 +00:00
|
|
|
FHyperlinkCell := cell;
|
|
|
|
FHyperlinkTimer.Enabled := true;
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
FHyperlinkCell := nil;
|
|
|
|
FHyperlinkTimer.Enabled := false;
|
2015-02-22 23:38:28 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-11-19 08:48:07 +00:00
|
|
|
FEnhEditMode := true;
|
|
|
|
end;
|
|
|
|
|
2014-10-06 13:37:24 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Standard mouse move handler. Is overridden because, if TextOverflow is active,
|
|
|
|
overflown cell may be erased when the mouse leaves them; repaints entire
|
|
|
|
grid instead.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
|
|
var
|
|
|
|
prevMouseCell: TPoint;
|
|
|
|
begin
|
|
|
|
prevMouseCell := GCache.MouseCell;
|
|
|
|
inherited;
|
|
|
|
if FTextOverflow and
|
|
|
|
((prevMouseCell.X <> GCache.MouseCell.X) or (prevMouseCell.Y <> GCache.MouseCell.Y))
|
|
|
|
then
|
|
|
|
InvalidateGrid;
|
2015-02-23 18:50:29 +00:00
|
|
|
|
|
|
|
if FHyperlinkTimer.Enabled and (ssLeft in Shift) then
|
|
|
|
FHyperlinkTimer.Enabled := false;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.MouseUp(Button: TMouseButton;
|
|
|
|
Shift:TShiftState; X,Y:Integer);
|
|
|
|
begin
|
|
|
|
if FHyperlinkTimer.Enabled then begin
|
|
|
|
FHyperlinkTimer.Enabled := false;
|
|
|
|
FHyperlinkCell := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
inherited;
|
2014-10-06 13:37:24 +00:00
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Standard method inherited from TCustomGrid.
|
2014-12-16 18:28:41 +00:00
|
|
|
Notifies the WorkbookSource of the changed selected cell.
|
2014-09-21 16:50:56 +00:00
|
|
|
Repaints the grid after moving selection to avoid spurious rests of the
|
|
|
|
old thick selection border.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.MoveSelection;
|
2014-11-05 23:45:48 +00:00
|
|
|
var
|
|
|
|
sel: TsCellRangeArray;
|
2015-03-13 14:33:55 +00:00
|
|
|
{$IFNDEF FPS_NO_GRID_MULTISELECT}
|
2014-11-05 23:45:48 +00:00
|
|
|
i: Integer;
|
|
|
|
{$ENDIF}
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-05 23:45:48 +00:00
|
|
|
if Worksheet <> nil then
|
|
|
|
begin
|
2015-03-13 14:33:55 +00:00
|
|
|
{$IFNDEF FPS_NO_GRID_MULTISELECT}
|
2014-11-05 23:45:48 +00:00
|
|
|
if HasMultiSelection then
|
|
|
|
begin
|
|
|
|
SetLength(sel, SelectedRangeCount);
|
|
|
|
for i:=0 to High(sel) do
|
|
|
|
with SelectedRange[i] do
|
|
|
|
begin
|
|
|
|
sel[i].Row1 := GetWorksheetRow(Top);
|
|
|
|
sel[i].Col1 := GetWorksheetCol(Left);
|
|
|
|
sel[i].Row2 := GetWorksheetRow(Bottom);
|
|
|
|
sel[i].Col2 := GetWorksheetCol(Right);
|
|
|
|
end;
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
SetLength(sel, 1);
|
|
|
|
sel[0].Row1 := GetWorksheetRow(Selection.Top);
|
|
|
|
sel[0].Col1 := GetWorksheetCol(Selection.Left);
|
|
|
|
sel[0].Row2 := GetWorksheetRow(Selection.Bottom);
|
|
|
|
sel[0].Col2 := GetWorksheetRow(Selection.Right);
|
|
|
|
end;
|
|
|
|
{$ELSE}
|
|
|
|
SetLength(sel, 1);
|
|
|
|
sel[0].Row1 := GetWorksheetRow(Selection.Top);
|
|
|
|
sel[0].Col1 := GetWorksheetCol(Selection.Left);
|
|
|
|
sel[0].Row2 := GetWorksheetRow(Selection.Bottom);
|
|
|
|
sel[0].Col2 := GetWorksheetRow(Selection.Right);
|
|
|
|
{$ENDIF}
|
|
|
|
Worksheet.SetSelection(sel);
|
|
|
|
|
|
|
|
Worksheet.SelectCell(GetWorksheetRow(Row), GetWorksheetCol(Col));
|
|
|
|
end;
|
2014-09-21 16:50:56 +00:00
|
|
|
//Refresh;
|
|
|
|
inherited;
|
|
|
|
Refresh;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Creates a new empty workbook with the specified number of columns and rows.
|
|
|
|
|
|
|
|
@param AColCount Number of columns
|
|
|
|
@param ARowCount Number of rows
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.NewWorkbook(AColCount, ARowCount: Integer);
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if FOwnsWorkbook then
|
|
|
|
FreeAndNil(FOwnedWorkbook);
|
|
|
|
|
|
|
|
if FWorkbookSource <> nil then
|
|
|
|
FWorkbookSource.CreateNewWorkbook
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
CreateNewWorkbook;
|
|
|
|
FOwnedWorksheet := FOwnedWorkbook.AddWorksheet('Sheet1');
|
|
|
|
FOwnedWorksheet.OnChangeCell := @ChangedCellHandler;
|
|
|
|
FOwnedWorksheet.OnChangeFont := @ChangedFontHandler;
|
|
|
|
FInitColCount := AColCount;
|
|
|
|
FInitRowCount := ARowCount;
|
|
|
|
Setup;
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Standard component notification: The grid is notified that the WorkbookLink
|
|
|
|
is being removed.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.Notification(AComponent: TComponent;
|
|
|
|
Operation: TOperation);
|
|
|
|
begin
|
|
|
|
inherited Notification(AComponent, Operation);
|
|
|
|
if (Operation = opRemove) and (AComponent = FWorkbookSource) then
|
|
|
|
SetWorkbookSource(nil);
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
2015-01-06 17:42:54 +00:00
|
|
|
Removes the link of the WorksheetGrid to the WorkbookSource.
|
|
|
|
Required before destruction.
|
2014-09-21 16:50:56 +00:00
|
|
|
-------------------------------------------------------------------------------}
|
2015-01-06 17:42:54 +00:00
|
|
|
procedure TsCustomWorksheetGrid.RemoveWorkbookSource;
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2015-01-06 17:42:54 +00:00
|
|
|
SetWorkbookSource(nil);
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Writes the workbook represented by the grid to a spreadsheet file.
|
|
|
|
|
|
|
|
@param AFileName Name of the file to which the workbook is to be
|
|
|
|
saved.
|
|
|
|
@param AFormat Spreadsheet file format in which the file is to be
|
|
|
|
saved.
|
|
|
|
@param AOverwriteExisting If the file already exists, it is overwritten in
|
|
|
|
the case of AOverwriteExisting = true, or an
|
|
|
|
exception is raised if AOverwriteExisting = false
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.SaveToSpreadsheetFile(AFileName: String;
|
|
|
|
AFormat: TsSpreadsheetFormat; AOverwriteExisting: Boolean = true);
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Workbook <> nil then
|
|
|
|
Workbook.WriteToFile(AFileName, AFormat, AOverwriteExisting);
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Saves the workbook into a file with the specified file name. If this file
|
|
|
|
name already exists the file is overwritten if AOverwriteExisting is true.
|
|
|
|
|
2015-03-16 17:40:16 +00:00
|
|
|
@param AFileName Name of the file to which the workbook is to be
|
|
|
|
saved
|
|
|
|
If the file format is not known it is written
|
|
|
|
as BIFF8/XLS.
|
|
|
|
@param AOverwriteExisting If this file already exists it is overwritten if
|
|
|
|
AOverwriteExisting = true, or an exception is
|
|
|
|
raised if AOverwriteExisting = false.
|
|
|
|
-------------------------------------------------------------------------------}
|
2014-09-21 16:50:56 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SaveToSpreadsheetFile(AFileName: String;
|
|
|
|
AOverwriteExisting: Boolean = true);
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Workbook <> nil then
|
|
|
|
Workbook.WriteToFile(AFileName, AOverwriteExisting);
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
2014-12-31 16:50:31 +00:00
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Standard method inherited from TCustomGrid: Is called when editing starts.
|
|
|
|
Is overridden here to store the old text just in case that the user presses
|
|
|
|
ESC to cancel editing.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.SelectEditor;
|
|
|
|
begin
|
|
|
|
FOldEditText := GetCellText(Col, Row);
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Loads the workbook into the grid and selects the sheet with the given index.
|
|
|
|
"Selected" means here that the sheet is loaded into the grid.
|
|
|
|
|
|
|
|
@param AIndex Index of the worksheet to be shown in the grid
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.SelectSheetByIndex(AIndex: Integer);
|
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Workbook <> nil then
|
|
|
|
LoadFromWorksheet(Workbook.GetWorksheetByIndex(AIndex));
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Standard method inherited from TCustomGrid. Fetches the text that is
|
|
|
|
currently in the editor. It is not yet transferred to the worksheet because
|
|
|
|
input will be checked only at the end of editing.
|
|
|
|
|
|
|
|
@param ACol Grid column index of the cell being edited
|
|
|
|
@param ARow Grid row index of the cell being edited
|
|
|
|
@param AValue String which is currently in the cell editor
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.SetEditText(ACol, ARow: Longint; const AValue: string);
|
|
|
|
begin
|
|
|
|
FEditText := AValue;
|
|
|
|
FEditing := true;
|
|
|
|
inherited SetEditText(aCol, aRow, aValue);
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Helper method for setting up the rows and columns after a new workbook is
|
|
|
|
loaded or created. Sets up the grid's column and row count, as well as the
|
|
|
|
initial column widths and row heights.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.Setup;
|
|
|
|
begin
|
2015-01-23 21:54:23 +00:00
|
|
|
if csLoading in ComponentState then
|
|
|
|
exit;
|
|
|
|
|
2015-03-16 00:05:56 +00:00
|
|
|
if FLockSetup > 0 then
|
|
|
|
exit;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Worksheet = nil) or (Worksheet.GetCellCount = 0) then begin
|
2014-09-21 16:50:56 +00:00
|
|
|
if ShowHeaders then begin
|
|
|
|
ColCount := FInitColCount + 1; //2;
|
|
|
|
RowCount := FInitRowCount + 1; //2;
|
|
|
|
FixedCols := 1;
|
|
|
|
FixedRows := 1;
|
|
|
|
ColWidths[0] := Canvas.TextWidth(' 999999 ');
|
|
|
|
end else begin
|
|
|
|
FixedCols := 0;
|
|
|
|
FixedRows := 0;
|
|
|
|
ColCount := FInitColCount; //0;
|
|
|
|
RowCount := FInitRowCount; //0;
|
|
|
|
end;
|
|
|
|
end else
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then begin
|
|
|
|
Convert_sFont_to_Font(Workbook.GetDefaultFont, Font);
|
2015-02-08 22:22:40 +00:00
|
|
|
Canvas.Font.Assign(Font);
|
2014-11-03 15:34:57 +00:00
|
|
|
ColCount := Max(integer(Worksheet.GetLastColIndex) + 1 + FHeaderCount, FInitColCount);
|
|
|
|
RowCount := Max(integer(Worksheet.GetLastRowIndex) + 1 + FHeaderCount, FInitRowCount);
|
2014-09-21 16:50:56 +00:00
|
|
|
FixedCols := FFrozenCols + FHeaderCount;
|
|
|
|
FixedRows := FFrozenRows + FHeaderCount;
|
|
|
|
if ShowHeaders then begin
|
|
|
|
ColWidths[0] := Canvas.TextWidth(' 999999 ');
|
|
|
|
RowHeights[0] := DefaultRowHeight;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
UpdateColWidths;
|
|
|
|
UpdateRowHeights;
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Setter to define the link to the workbook.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.SetWorkbookSource(AValue: TsWorkbookSource);
|
|
|
|
begin
|
|
|
|
if AValue = FWorkbookSource then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
if FOwnsWorkbook then
|
|
|
|
FreeAndNil(FOwnedWorkbook);
|
|
|
|
|
|
|
|
if FWorkbookSource <> nil then
|
|
|
|
FWorkbookSource.RemoveListener(self);
|
|
|
|
FWorkbookSource := AValue;
|
|
|
|
if FWorkbookSource <> nil then
|
|
|
|
FWorkbookSource.AddListener(self);
|
|
|
|
|
|
|
|
FOwnsWorkbook := (FWorkbookSource = nil);
|
|
|
|
ListenerNotification([lniWorksheet, lniSelection]);
|
|
|
|
end;
|
|
|
|
|
2014-10-23 14:31:29 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Sorts the grid by calling the corresponding method of the worksheet.
|
|
|
|
Sorting extends across the entire worksheet.
|
|
|
|
Sort direction is determined by the property "SortOrder". Other sorting
|
|
|
|
criteria are "case-sensitive" and "numbers first".
|
|
|
|
|
|
|
|
@param AColSorting If true the grid is sorted from top to bottom and the
|
|
|
|
next parameter, "Index", refers to a column. Otherweise
|
|
|
|
sorting goes from left to right and "Index" refers to a row.
|
|
|
|
@param AIndex Index of the column (if ColSorting=true) or row (ColSorting = false)
|
|
|
|
which is sorted.
|
|
|
|
@param AIndxFrom Sorting starts at this row (ColSorting=true) / column (ColSorting=false)
|
|
|
|
@param AIndxTo Sorting ends at this row (ColSorting=true) / column (ColSorting=false)
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.Sort(AColSorting: Boolean;
|
|
|
|
AIndex, AIndxFrom, AIndxTo:Integer);
|
|
|
|
var
|
|
|
|
sortParams: TsSortParams;
|
|
|
|
begin
|
|
|
|
sortParams := InitSortParams(AColSorting, 1);
|
|
|
|
sortParams.Keys[0].ColRowIndex := AIndex - HeaderCount;
|
|
|
|
if SortOrder = soDescending then
|
|
|
|
sortParams.Keys[0].Options := [ssoDescending];
|
|
|
|
if AColSorting then
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Sort(
|
2014-10-23 14:31:29 +00:00
|
|
|
sortParams,
|
2014-11-03 15:34:57 +00:00
|
|
|
AIndxFrom-HeaderCount, 0, AIndxTo-HeaderCount, Worksheet.GetLastColIndex
|
2014-10-23 14:31:29 +00:00
|
|
|
)
|
|
|
|
else
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Sort(
|
2014-10-23 14:31:29 +00:00
|
|
|
sortParams,
|
2014-11-03 15:34:57 +00:00
|
|
|
0, AIndxFrom-HeaderCount, Worksheet.GetLastRowIndex, AIndxTo-HeaderCount
|
2014-10-23 14:31:29 +00:00
|
|
|
);
|
|
|
|
end;
|
|
|
|
|
2015-03-16 09:45:58 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Inherited method called whenever to grid is scrolled, i.e. the top/left cell
|
|
|
|
changes.
|
|
|
|
Is overridden to calculate the row heights of the currently visible grid
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.TopLeftChanged;
|
|
|
|
begin
|
|
|
|
UpdateRowHeights;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2014-12-11 15:53:24 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Modifies the text that is show for cells which are too narrow to hold the
|
|
|
|
entire text. The method follows the behavior of Excel and Open/LibreOffice:
|
|
|
|
If the specified cell contains a non-formatted number, then it is formatted
|
|
|
|
such that the text fits into the cell. If the text is still too long or
|
|
|
|
the cell does not contain a label then the cell is filled by '#' characters.
|
|
|
|
Label cell texts are not modified, they can overflow into the adjacent cells.
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
function TsCustomWorksheetGrid.TrimToCell(ACell: PCell): String;
|
|
|
|
var
|
|
|
|
cellSize, txtSize: Integer;
|
|
|
|
decs: Integer;
|
|
|
|
p: Integer;
|
|
|
|
isRotated: Boolean;
|
|
|
|
isStacked: Boolean;
|
2015-02-05 18:06:52 +00:00
|
|
|
fmt: PsCellFormat;
|
2015-04-18 14:58:38 +00:00
|
|
|
numFmt: TsNumFormatParams;
|
|
|
|
nfs: String;
|
|
|
|
isGeneralFmt: Boolean;
|
2014-12-11 15:53:24 +00:00
|
|
|
begin
|
|
|
|
Result := Worksheet.ReadAsUTF8Text(ACell);
|
2015-02-28 23:46:08 +00:00
|
|
|
if (Result = '') or ((ACell <> nil) and (ACell^.ContentType = cctUTF8String))
|
2014-12-11 15:53:24 +00:00
|
|
|
then
|
|
|
|
exit;
|
|
|
|
|
2015-02-05 18:06:52 +00:00
|
|
|
fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
2015-04-18 14:58:38 +00:00
|
|
|
isRotated := (fmt^.TextRotation <> trHorizontal);
|
|
|
|
isStacked := (fmt^.TextRotation = rtStacked);
|
|
|
|
numFmt := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
|
|
|
isGeneralFmt := (numFmt = nil);
|
2014-12-11 15:53:24 +00:00
|
|
|
|
|
|
|
// Determine space available in cell
|
|
|
|
if isRotated then
|
|
|
|
cellSize := RowHeights[GetGridRow(ACell^.Row)]
|
|
|
|
else
|
|
|
|
cellSize := ColWidths[GetGridCol(ACell^.Col)] - 2*ConstCellPadding;
|
|
|
|
|
|
|
|
// Determine space needed for text
|
|
|
|
if isStacked then
|
|
|
|
txtSize := Length(Result) * Canvas.TextHeight('A')
|
|
|
|
else
|
|
|
|
txtSize := Canvas.TextWidth(Result);
|
|
|
|
|
|
|
|
// Nothing to do if text fits into cell
|
|
|
|
if txtSize <= cellSize then
|
|
|
|
exit;
|
|
|
|
|
2015-04-18 14:58:38 +00:00
|
|
|
if (ACell^.ContentType = cctNumber) and isGeneralFmt then
|
2014-12-11 15:53:24 +00:00
|
|
|
begin
|
|
|
|
// Determine number of decimal places
|
|
|
|
p := pos(Workbook.FormatSettings.DecimalSeparator, Result);
|
|
|
|
if p = 0 then
|
|
|
|
decs := 0
|
|
|
|
else
|
|
|
|
decs := Length(Result) - p;
|
|
|
|
|
|
|
|
// Use floating point format, but reduce number of decimal places until
|
|
|
|
// text fits in
|
|
|
|
while decs > 0 do
|
|
|
|
begin
|
|
|
|
dec(decs);
|
|
|
|
Result := Format('%.*f', [decs, ACell^.NumberValue], Workbook.FormatSettings);
|
|
|
|
if isStacked then
|
|
|
|
txtSize := Length(Result) * Canvas.TextHeight('A')
|
|
|
|
else
|
|
|
|
txtSize := Canvas.TextWidth(Result);
|
|
|
|
if txtSize <= cellSize then
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// There seem to be too many integer digits. Switch to exponential format.
|
|
|
|
decs := 13;
|
|
|
|
while decs > 0 do
|
|
|
|
begin
|
|
|
|
dec(decs);
|
2015-04-18 14:58:38 +00:00
|
|
|
nfs := '0.' + DupeString('0', decs) + 'E-00';
|
|
|
|
Result := FormatFloat(nfs, ACell^.NumberValue, Workbook.FormatSettings);
|
|
|
|
// Result := Format('%.*e', [decs, ACell^.NumberValue], Workbook.FormatSettings);
|
2014-12-11 15:53:24 +00:00
|
|
|
if isStacked then
|
|
|
|
txtSize := Length(Result) * Canvas.TextHeight('A')
|
|
|
|
else
|
|
|
|
txtSize := Canvas.TextWidth(Result);
|
|
|
|
if txtSize <= cellSize then
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Still text too long or non-number --> Fill with # characters.
|
|
|
|
Result := '';
|
|
|
|
txtSize := 0;
|
|
|
|
while txtSize < cellSize do
|
|
|
|
begin
|
|
|
|
Result := Result + '#';
|
|
|
|
if isStacked then
|
|
|
|
txtSize := Length(Result) * Canvas.TextHeight('#')
|
|
|
|
else
|
|
|
|
txtSize := Canvas.TextWidth(Result);
|
|
|
|
end;
|
|
|
|
|
|
|
|
// We added one character too many
|
|
|
|
Delete(Result, Length(Result), 1);
|
|
|
|
end;
|
|
|
|
|
2015-01-06 17:42:54 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Splits a merged cell block into single cells
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.UnmergeCells;
|
|
|
|
begin
|
|
|
|
Worksheet.UnmergeCells(
|
|
|
|
GetWorksheetRow(Selection.Top),
|
|
|
|
GetWorksheetCol(Selection.Left)
|
|
|
|
);
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Updates column widths according to the data in the TCol records
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.UpdateColWidths(AStartIndex: Integer = 0);
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
lCol: PCol;
|
|
|
|
w: Integer;
|
|
|
|
begin
|
|
|
|
if AStartIndex = 0 then AStartIndex := FHeaderCount;
|
|
|
|
for i := AStartIndex to ColCount-1 do begin
|
|
|
|
w := DefaultColWidth;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
lCol := Worksheet.FindCol(i - FHeaderCount);
|
2014-09-21 16:50:56 +00:00
|
|
|
if lCol <> nil then
|
|
|
|
w := CalcColWidth(lCol^.Width)
|
2015-02-08 22:22:40 +00:00
|
|
|
else
|
|
|
|
w := CalcColWidth(Worksheet.DefaultColWidth);
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
ColWidths[i] := w;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Updates row heights by using the data from the TRow records or by auto-
|
|
|
|
calculating the row height from the max of the cell heights
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure TsCustomWorksheetGrid.UpdateRowHeights(AStartIndex: Integer = 0);
|
2015-03-17 11:42:57 +00:00
|
|
|
const
|
|
|
|
DELTA = 10;
|
2014-09-21 16:50:56 +00:00
|
|
|
var
|
2015-03-17 11:42:57 +00:00
|
|
|
r, r1, r2: Integer;
|
2014-09-21 16:50:56 +00:00
|
|
|
lRow: PRow;
|
|
|
|
h: Integer;
|
|
|
|
begin
|
2015-04-18 14:58:38 +00:00
|
|
|
Unused(AStartIndex);
|
|
|
|
|
2015-03-16 09:45:58 +00:00
|
|
|
{
|
2015-03-16 00:05:56 +00:00
|
|
|
BeginUpdate;
|
2014-09-21 16:50:56 +00:00
|
|
|
if AStartIndex <= 0 then AStartIndex := FHeaderCount;
|
|
|
|
for i := AStartIndex to RowCount-1 do begin
|
|
|
|
h := CalcAutoRowHeight(i);
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
lRow := Worksheet.FindRow(i - FHeaderCount);
|
2014-09-21 16:50:56 +00:00
|
|
|
if (lRow <> nil) then
|
|
|
|
h := CalcRowHeight(lRow^.Height);
|
|
|
|
end;
|
|
|
|
RowHeights[i] := h;
|
|
|
|
end;
|
2015-03-16 00:05:56 +00:00
|
|
|
EndUpdate;
|
2015-03-16 09:45:58 +00:00
|
|
|
}
|
2015-03-17 11:42:57 +00:00
|
|
|
r1 := Max(FHeaderCount, GCache.VisibleGrid.Top - DELTA);
|
|
|
|
r2 := Min(RowCount-1, GCache.VisibleGrid.Bottom + DELTA);
|
|
|
|
for r:=r1 to r2 do
|
|
|
|
begin
|
2015-03-16 09:45:58 +00:00
|
|
|
if Worksheet <> nil then
|
|
|
|
begin
|
2015-03-17 11:42:57 +00:00
|
|
|
lRow := Worksheet.FindRow(r - FHeaderCount);
|
2015-03-16 09:45:58 +00:00
|
|
|
if (lRow <> nil) then
|
2015-03-17 11:42:57 +00:00
|
|
|
h := CalcRowHeight(lRow^.Height)
|
|
|
|
else
|
|
|
|
h := CalcAutoRowHeight(r);
|
|
|
|
end else
|
|
|
|
h := DefaultRowHeight;
|
|
|
|
RowHeights[r] := h;
|
2015-03-16 09:45:58 +00:00
|
|
|
end;
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{*******************************************************************************
|
|
|
|
* Setter / getter methods *
|
|
|
|
*******************************************************************************}
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetCellFontColor(ACol, ARow: Integer): TsColor;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
fnt: TsFont;
|
|
|
|
begin
|
|
|
|
Result := scNotDefined;
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Workbook <> nil) and (Worksheet <> nil) then begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
fnt := Worksheet.ReadCellFont(cell);
|
|
|
|
Result := fnt.Color;
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetCellFontColors(ARect: TGridRect): TsColor;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
clr: TsColor;
|
|
|
|
begin
|
|
|
|
Result := GetCellFontColor(ARect.Left, ARect.Top);
|
|
|
|
clr := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do begin
|
|
|
|
Result := GetCellFontColor(c, r);
|
|
|
|
if (Result <> clr) then begin
|
|
|
|
Result := scNotDefined;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetCellFontName(ACol, ARow: Integer): String;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
fnt: TsFont;
|
|
|
|
begin
|
|
|
|
Result := '';
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Workbook <> nil) and (Worksheet <> nil) then begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
fnt := Worksheet.ReadCellFont(cell);
|
2015-03-03 00:06:15 +00:00
|
|
|
if fnt <> nil then
|
|
|
|
Result := fnt.FontName;
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetCellFontNames(ARect: TGridRect): String;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
s: String;
|
|
|
|
begin
|
|
|
|
Result := GetCellFontName(ARect.Left, ARect.Top);
|
|
|
|
s := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do begin
|
|
|
|
Result := GetCellFontName(c, r);
|
|
|
|
if (Result <> '') and (Result <> s) then begin
|
|
|
|
Result := '';
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetCellFontSize(ACol, ARow: Integer): Single;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
fnt: TsFont;
|
|
|
|
begin
|
|
|
|
Result := -1.0;
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Workbook <> nil) and (Worksheet <> nil) then begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
fnt := Worksheet.ReadCellFont(cell);
|
|
|
|
Result := fnt.Size;
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetCellFontSizes(ARect: TGridRect): Single;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
sz: Single;
|
|
|
|
begin
|
|
|
|
Result := GetCellFontSize(ARect.Left, ARect.Top);
|
|
|
|
sz := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do begin
|
|
|
|
Result := GetCellFontSize(c, r);
|
|
|
|
if (Result <> -1) and not SameValue(Result, sz, 1E-3) then begin
|
|
|
|
Result := -1.0;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetCellFontStyle(ACol, ARow: Integer): TsFontStyles;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
fnt: TsFont;
|
|
|
|
begin
|
|
|
|
Result := [];
|
2014-11-03 15:34:57 +00:00
|
|
|
if (Workbook <> nil) and (Worksheet <> nil) then begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
fnt := Worksheet.ReadCellFont(cell);
|
|
|
|
Result := fnt.Style;
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetCellFontStyles(ARect: TGridRect): TsFontStyles;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
style: TsFontStyles;
|
|
|
|
begin
|
|
|
|
Result := GetCellFontStyle(ARect.Left, ARect.Top);
|
|
|
|
style := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do begin
|
|
|
|
Result := GetCellFontStyle(c, r);
|
|
|
|
if Result <> style then begin
|
|
|
|
Result := [];
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetHorAlignment(ACol, ARow: Integer): TsHorAlignment;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
Result := haDefault;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
Result := Worksheet.ReadHorAlignment(cell);
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetHorAlignments(ARect: TGridRect): TsHorAlignment;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
horalign: TsHorAlignment;
|
|
|
|
begin
|
|
|
|
Result := GetHorAlignment(ARect.Left, ARect.Top);
|
|
|
|
horalign := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do begin
|
|
|
|
Result := GetHorAlignment(c, r);
|
|
|
|
if Result <> horalign then begin
|
|
|
|
Result := haDefault;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetShowGridLines: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (Options * [goHorzLine, goVertLine] <> []);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetShowHeaders: Boolean;
|
|
|
|
begin
|
|
|
|
Result := FHeaderCount <> 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetTextRotation(ACol, ARow: Integer): TsTextRotation;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
Result := trHorizontal;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
Result := Worksheet.ReadTextRotation(cell);
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetTextRotations(ARect: TGridRect): TsTextRotation;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
textrot: TsTextRotation;
|
|
|
|
begin
|
|
|
|
Result := GetTextRotation(ARect.Left, ARect.Top);
|
|
|
|
textrot := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do begin
|
|
|
|
Result := GetTextRotation(c, r);
|
|
|
|
if Result <> textrot then begin
|
|
|
|
Result := trHorizontal;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetVertAlignment(ACol, ARow: Integer): TsVertAlignment;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
Result := vaDefault;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
Result := Worksheet.ReadVertAlignment(cell);
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetVertAlignments(ARect: TGridRect): TsVertAlignment;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
vertalign: TsVertAlignment;
|
|
|
|
begin
|
|
|
|
Result := GetVertalignment(ARect.Left, ARect.Top);
|
|
|
|
vertalign := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do begin
|
|
|
|
Result := GetVertAlignment(c, r);
|
|
|
|
if Result <> vertalign then begin
|
|
|
|
Result := vaDefault;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
function TsCustomWorksheetGrid.GetWorkbook: TsWorkbook;
|
|
|
|
begin
|
|
|
|
if FWorkbookSource <> nil then
|
|
|
|
Result := FWorkbookSource.Workbook
|
|
|
|
else
|
|
|
|
Result := FOwnedWorkbook;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetWorksheet: TsWorksheet;
|
|
|
|
begin
|
|
|
|
if FWorkbookSource <> nil then
|
2014-11-05 23:45:48 +00:00
|
|
|
Result := FWorkbooksource.Worksheet
|
2014-11-03 15:34:57 +00:00
|
|
|
else
|
|
|
|
Result := FOwnedWorksheet;
|
|
|
|
end;
|
|
|
|
|
2014-09-21 16:50:56 +00:00
|
|
|
function TsCustomWorksheetGrid.GetWordwrap(ACol, ARow: Integer): Boolean;
|
|
|
|
var
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
Result := false;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
|
|
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
2015-01-23 21:54:23 +00:00
|
|
|
Result := Worksheet.ReadWordwrap(cell);
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsCustomWorksheetGrid.GetWordwraps(ARect: TGridRect): Boolean;
|
|
|
|
var
|
|
|
|
c, r: Integer;
|
|
|
|
wrapped: Boolean;
|
|
|
|
begin
|
|
|
|
Result := GetWordwrap(ARect.Left, ARect.Top);
|
|
|
|
wrapped := Result;
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do begin
|
|
|
|
Result := GetWordwrap(c, r);
|
|
|
|
if Result <> wrapped then begin
|
|
|
|
Result := false;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetAutoCalc(AValue: Boolean);
|
|
|
|
begin
|
|
|
|
FAutoCalc := AValue;
|
2014-11-03 15:34:57 +00:00
|
|
|
|
|
|
|
if Assigned(FWorkbookSource) then
|
|
|
|
begin
|
|
|
|
if FAutoCalc then
|
|
|
|
FWorkbookSource.Options := FWorkbookSource.Options + [boAutoCalc]
|
|
|
|
else
|
2014-12-11 12:09:43 +00:00
|
|
|
FWorkbookSource.Options := FWorkbookSource.Options - [boAutoCalc];
|
2014-11-03 15:34:57 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
if Assigned(Workbook) then
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
|
|
|
if FAutoCalc then
|
2014-11-03 15:34:57 +00:00
|
|
|
Workbook.Options := Workbook.Options + [boAutoCalc]
|
2014-09-21 16:50:56 +00:00
|
|
|
else
|
2014-11-03 15:34:57 +00:00
|
|
|
Workbook.Options := Workbook.Options - [boAutoCalc];
|
2014-09-21 16:50:56 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetBackgroundColor(ACol, ARow: Integer;
|
|
|
|
AValue: TsColor);
|
|
|
|
var
|
2015-01-23 21:54:23 +00:00
|
|
|
cell: PCell;
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
2014-09-21 16:50:56 +00:00
|
|
|
BeginUpdate;
|
|
|
|
try
|
2015-01-23 21:54:23 +00:00
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteBackgroundColor(cell, AValue);
|
2014-09-21 16:50:56 +00:00
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetBackgroundColors(ARect: TGridRect;
|
|
|
|
AValue: TsColor);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetBackgroundColor(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellBorder(ACol, ARow: Integer;
|
|
|
|
AValue: TsCellBorders);
|
|
|
|
var
|
2015-01-23 21:54:23 +00:00
|
|
|
cell: PCell;
|
2014-09-21 16:50:56 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
2014-05-11 09:20:52 +00:00
|
|
|
BeginUpdate;
|
|
|
|
try
|
2015-01-23 21:54:23 +00:00
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteBorders(cell, AValue);
|
2015-03-05 10:35:32 +00:00
|
|
|
FixNeighborCellBorders(cell);
|
2014-05-11 09:20:52 +00:00
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellBorders(ARect: TGridRect;
|
|
|
|
AValue: TsCellBorders);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetCellBorder(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellBorderStyle(ACol, ARow: Integer;
|
|
|
|
ABorder: TsCellBorder; AValue: TsCellBorderStyle);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-11 09:20:52 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
2014-05-11 09:20:52 +00:00
|
|
|
BeginUpdate;
|
|
|
|
try
|
2015-01-23 21:54:23 +00:00
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteBorderStyle(cell, ABorder, AValue);
|
2015-03-05 10:35:32 +00:00
|
|
|
FixNeighborCellBorders(cell);
|
2014-05-11 09:20:52 +00:00
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellBorderStyles(ARect: TGridRect;
|
|
|
|
ABorder: TsCellBorder; AValue: TsCellBorderStyle);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetCellBorderStyle(c, r, ABorder, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-05-11 16:16:59 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetCellFont(ACol, ARow: Integer; AValue: TFont);
|
|
|
|
var
|
|
|
|
fnt: TsFont;
|
2015-01-23 21:54:23 +00:00
|
|
|
cell: PCell;
|
2014-05-11 16:16:59 +00:00
|
|
|
begin
|
|
|
|
FCellFont.Assign(AValue);
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then begin
|
2014-05-11 16:16:59 +00:00
|
|
|
fnt := TsFont.Create;
|
|
|
|
try
|
|
|
|
Convert_Font_To_sFont(FCellFont, fnt);
|
2015-01-23 21:54:23 +00:00
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteFont(cell, fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
2014-05-11 16:16:59 +00:00
|
|
|
finally
|
|
|
|
fnt.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFonts(ARect: TGridRect;
|
|
|
|
AValue: TFont);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetCellFont(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFontColor(ACol, ARow: Integer; AValue: TsColor);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-11 16:16:59 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2015-01-23 21:54:23 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteFontColor(cell, AValue);
|
|
|
|
end;
|
2014-05-11 16:16:59 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFontColors(ARect: TGridRect; AValue: TsColor);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetCellFontColor(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFontName(ACol, ARow: Integer; AValue: String);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-11 16:16:59 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2015-01-23 21:54:23 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteFontName(cell, AValue);
|
|
|
|
end;
|
2014-05-11 16:16:59 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFontNames(ARect: TGridRect; AValue: String);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetCellFontName(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFontSize(ACol, ARow: Integer;
|
|
|
|
AValue: Single);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-11 16:16:59 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2015-01-23 21:54:23 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteFontSize(cell, AValue);
|
|
|
|
end;
|
2014-05-11 16:16:59 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFontSizes(ARect: TGridRect;
|
|
|
|
AValue: Single);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetCellFontSize(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFontStyle(ACol, ARow: Integer;
|
|
|
|
AValue: TsFontStyles);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-11 16:16:59 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2015-01-23 21:54:23 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteFontStyle(cell, AValue);
|
|
|
|
end;
|
2014-05-11 16:16:59 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetCellFontStyles(ARect: TGridRect;
|
|
|
|
AValue: TsFontStyles);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetCellFontStyle(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-05-04 18:07:54 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetFrozenCols(AValue: Integer);
|
|
|
|
begin
|
|
|
|
FFrozenCols := AValue;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then begin
|
|
|
|
Worksheet.LeftPaneWidth := FFrozenCols;
|
2014-06-21 12:19:19 +00:00
|
|
|
if (FFrozenCols > 0) or (FFrozenRows > 0) then
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Options := Worksheet.Options + [soHasFrozenPanes]
|
2014-06-21 12:19:19 +00:00
|
|
|
else
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Options := Worksheet.Options - [soHasFrozenPanes];
|
2014-06-21 12:19:19 +00:00
|
|
|
end;
|
2014-05-04 18:07:54 +00:00
|
|
|
Setup;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetFrozenRows(AValue: Integer);
|
|
|
|
begin
|
|
|
|
FFrozenRows := AValue;
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then begin
|
|
|
|
Worksheet.TopPaneHeight := FFrozenRows;
|
2014-06-21 12:19:19 +00:00
|
|
|
if (FFrozenCols > 0) or (FFrozenRows > 0) then
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Options := Worksheet.Options + [soHasFrozenPanes]
|
2014-06-21 12:19:19 +00:00
|
|
|
else
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Options := Worksheet.Options - [soHasFrozenPanes];
|
2014-06-21 12:19:19 +00:00
|
|
|
end;
|
2014-05-04 18:07:54 +00:00
|
|
|
Setup;
|
|
|
|
end;
|
|
|
|
|
2014-05-10 12:32:05 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetHorAlignment(ACol, ARow: Integer;
|
|
|
|
AValue: TsHorAlignment);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-10 12:32:05 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2015-01-23 21:54:23 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteHorAlignment(cell, AValue);
|
|
|
|
end;
|
2014-05-10 12:32:05 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetHorAlignments(ARect: TGridRect;
|
|
|
|
AValue: TsHorAlignment);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetHorAlignment(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-12-11 12:09:43 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetReadFormulas(AValue: Boolean);
|
|
|
|
begin
|
|
|
|
FReadFormulas := AValue;
|
|
|
|
|
|
|
|
if Assigned(FWorkbookSource) then
|
|
|
|
begin
|
|
|
|
if FReadFormulas then
|
|
|
|
FWorkbookSource.Options := FWorkbookSource.Options + [boReadFormulas]
|
|
|
|
else
|
|
|
|
FWorkbookSource.Options := FWorkbookSource.Options - [boReadFormulas];
|
|
|
|
end;
|
|
|
|
|
|
|
|
if Assigned(Workbook) then
|
|
|
|
begin
|
|
|
|
if FReadFormulas then
|
|
|
|
Workbook.Options := Workbook.Options + [boReadFormulas]
|
|
|
|
else
|
|
|
|
Workbook.Options := Workbook.Options - [boReadFormulas];
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-05-08 15:54:29 +00:00
|
|
|
{ Shows / hides the worksheet's grid lines }
|
2014-05-03 21:27:31 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetShowGridLines(AValue: Boolean);
|
2014-04-19 19:29:13 +00:00
|
|
|
begin
|
2014-05-11 09:20:52 +00:00
|
|
|
if AValue = GetShowGridLines then
|
|
|
|
Exit;
|
|
|
|
|
2014-05-03 21:27:31 +00:00
|
|
|
if AValue then
|
|
|
|
Options := Options + [goHorzLine, goVertLine]
|
|
|
|
else
|
|
|
|
Options := Options - [goHorzLine, goVertLine];
|
2014-05-11 16:22:48 +00:00
|
|
|
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then
|
2014-05-11 16:22:48 +00:00
|
|
|
if AValue then
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Options := Worksheet.Options + [soShowGridLines]
|
2014-05-11 16:22:48 +00:00
|
|
|
else
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Options := Worksheet.Options - [soShowGridLines];
|
2014-05-03 21:27:31 +00:00
|
|
|
end;
|
|
|
|
|
2014-05-08 15:54:29 +00:00
|
|
|
{ Shows / hides the worksheet's row and column headers. }
|
2014-05-03 21:27:31 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetShowHeaders(AValue: Boolean);
|
|
|
|
begin
|
|
|
|
if AValue = GetShowHeaders then Exit;
|
2014-05-11 16:22:48 +00:00
|
|
|
|
2014-05-03 21:27:31 +00:00
|
|
|
FHeaderCount := ord(AValue);
|
2014-11-03 15:34:57 +00:00
|
|
|
if Worksheet <> nil then
|
2014-05-11 16:22:48 +00:00
|
|
|
if AValue then
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Options := Worksheet.Options + [soShowHeaders]
|
2014-05-11 16:22:48 +00:00
|
|
|
else
|
2014-11-03 15:34:57 +00:00
|
|
|
Worksheet.Options := Worksheet.Options - [soShowHeaders];
|
2014-05-11 16:22:48 +00:00
|
|
|
|
2014-04-19 19:29:13 +00:00
|
|
|
Setup;
|
|
|
|
end;
|
2009-10-06 19:25:18 +00:00
|
|
|
|
2014-05-11 10:39:14 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetTextRotation(ACol, ARow: Integer;
|
|
|
|
AValue: TsTextRotation);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-11 10:39:14 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2015-01-23 21:54:23 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteTextRotation(cell, AValue);
|
|
|
|
end;
|
2014-05-11 10:39:14 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetTextRotations(ARect: TGridRect;
|
|
|
|
AValue: TsTextRotation);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetTextRotation(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-05-10 12:32:05 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetVertAlignment(ACol, ARow: Integer;
|
|
|
|
AValue: TsVertAlignment);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-10 12:32:05 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2015-01-23 21:54:23 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteVertAlignment(cell, AValue);
|
|
|
|
end;
|
2014-05-10 12:32:05 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetVertAlignments(ARect: TGridRect;
|
|
|
|
AValue: TsVertAlignment);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetVertAlignment(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-05-11 09:20:52 +00:00
|
|
|
procedure TsCustomWorksheetGrid.SetWordwrap(ACol, ARow: Integer;
|
|
|
|
AValue: Boolean);
|
2015-01-23 21:54:23 +00:00
|
|
|
var
|
|
|
|
cell: PCell;
|
2014-05-11 09:20:52 +00:00
|
|
|
begin
|
2014-11-03 15:34:57 +00:00
|
|
|
if Assigned(Worksheet) then
|
2015-01-23 21:54:23 +00:00
|
|
|
begin
|
|
|
|
cell := Worksheet.GetCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
|
|
|
Worksheet.WriteWordwrap(cell, AValue);
|
|
|
|
end;
|
2014-05-11 09:20:52 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsCustomWorksheetGrid.SetWordwraps(ARect: TGridRect;
|
|
|
|
AValue: Boolean);
|
|
|
|
var
|
|
|
|
c,r: Integer;
|
|
|
|
begin
|
|
|
|
BeginUpdate;
|
|
|
|
try
|
|
|
|
for c := ARect.Left to ARect.Right do
|
|
|
|
for r := ARect.Top to ARect.Bottom do
|
|
|
|
SetWordwrap(c, r, AValue);
|
|
|
|
finally
|
|
|
|
EndUpdate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-05-08 12:12:06 +00:00
|
|
|
|
2015-01-06 17:42:54 +00:00
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
|
|
Registers the worksheet grid in the Lazarus component palette,
|
|
|
|
page "FPSpreadsheet".
|
|
|
|
-------------------------------------------------------------------------------}
|
|
|
|
procedure Register;
|
|
|
|
begin
|
|
|
|
RegisterComponents('FPSpreadsheet', [TsWorksheetGrid]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2014-04-21 21:43:43 +00:00
|
|
|
initialization
|
2014-05-31 21:04:53 +00:00
|
|
|
fpsutils.ScreenPixelsPerInch := Screen.PixelsPerInch;
|
2015-02-17 23:32:00 +00:00
|
|
|
FillPatternStyle := fsNoFill;
|
2014-04-21 21:43:43 +00:00
|
|
|
|
2015-01-12 11:42:23 +00:00
|
|
|
RegisterPropertyToSkip(TsCustomWorksheetGrid, 'ColWidths', 'taken from worksheet', '');
|
|
|
|
RegisterPropertyToSkip(TsCustomWorksheetGrid, 'RowHeights', 'taken from worksheet', '');
|
|
|
|
|
2014-04-21 21:43:43 +00:00
|
|
|
finalization
|
2015-02-17 23:32:00 +00:00
|
|
|
FreeAndNil(FillPatternBitmap);
|
2014-04-21 21:43:43 +00:00
|
|
|
|
2009-10-06 19:25:18 +00:00
|
|
|
end.
|