Componentes.Terceros.DevExp.../internal/x.46/2/ExpressPrinting System/Sources/dxPScxSSLnk.pas

3067 lines
102 KiB
ObjectPascal

{*******************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressPrinting System(tm) COMPONENT SUITE }
{ }
{ Copyright (C) 1998-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSPRINTINGSYSTEM AND }
{ ALL ACCOMPANYING VCL CONTROLS AS PART OF AN }
{ EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{*******************************************************************}
unit dxPScxSSLnk;
interface
{$I cxVer.inc}
{$IFDEF CBUILDER5}
(*$HPPEMIT '#define HRGN unsigned'*)
{$ELSE}
(*$HPPEMIT '#define HRGN int'*)
{$ENDIF}
uses
Windows, Classes, Graphics, Controls, StdCtrls, ExtCtrls, ComCtrls, Dialogs,
cxSSTypes, cxSSData, cxSSStyles, cxSSheet, cxExcelConst, dxPSCore, dxPSForm,
dxPSGlbl, dxPSBaseGridLnk, dxPSExcelEdgePatterns, dxPSExcelFillPatterns,
dxPSEdgePatterns, dxPSFillPatterns, cxDrawTextUtils;
type
PdxPSCellBorder = ^TdxPSCellBorder;
TdxPSCellBorder = record
Color: TColor;
Pattern: TdxPSEdgePatternClass;
end;
PdxPSCellBorders = ^TdxPSCellBorders;
TdxPSCellBorders = array[TdxCellSide] of TdxPSCellBorder;
TdxPSCellBorderCorner = (cbcTopLeft, cbcTopRight, cbcBottomRight, cbcBottomLeft);
TdxPSCellBorderCorners = set of TdxPSCellBorderCorner;
TdxPSCellBorderEnd = (cbsTopLeft, cbsBottomRight);
TdxPSCellBorderEnds = set of TdxPSCellBorderEnd;
TdxPSCellBorderSub = 0..3;
TdxPSCellCorner = (ccTopLeft, ccTopRight, ccBottomRight, ccBottomLeft);
TdxPSCellPatternsBorderPainter = class;
TdxPSGridCellsAdapter = class;
TdxReportCellSSString = class(TdxReportCellString)
private
FBorders: TdxPSCellBorders;
FBorderSlants: DWORD;
FBorderSubs: DWORD;
FContentBkColor: TColor;
FContentPattern: TdxPSFillPatternClass;
FRealCol: Integer;
FRealRow: Integer;
FTextExtentLeft: Integer;
FTextExtentRight: Integer;
function GetBorder(ASide: TdxCellSide): TdxPSCellBorder;
function GetBordersBkColor: TColor;
function GetBorderSlant(ASide: TdxCellSide; ACorner: TdxPSCellBorderCorner): Integer;
function GetBorderSlantOffset(ASide: TdxCellSide; ACorner: TdxPSCellBorderCorner): TDWORDBits;
function GetBorderSub(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd): TdxPSCellBorderSub;
function GetBorderSubMask(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd): DWORD;
function GetBorderSubOffset(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd): TDWORDBits;
function GetClipContent: Boolean;
function GetCol: Integer;
function GetFill: Boolean;
function GetIsFixed: Boolean;
function GetIsMerged: Boolean;
function GetIsNearMostLeft: Boolean;
function GetIsNearMostTop: Boolean;
function GetIsNearMostTopOrLeft: Boolean;
function GetIsVirtual: Boolean;
function GetRow: Integer;
procedure SetBorder(ASide: TdxCellSide; Value: TdxPSCellBorder);
procedure SetBorderSlant(ASide: TdxCellSide; ACorner: TdxPSCellBorderCorner; Value: Integer);
procedure SetBorderSub(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd; Value: TdxPSCellBorderSub);
procedure SetClipConent(Value: Boolean);
procedure SetFill(Value: Boolean);
procedure SetIsFixed(Value: Boolean);
procedure SetIsMerged(Value: Boolean);
procedure SetIsNearMostLeft(Value: Boolean);
procedure SetIsNearMostTop(Value: Boolean);
procedure SetIsVirtual(Value: Boolean);
protected
procedure CalcBorderSubs(AnAdapter: TdxPSGridCellsAdapter);
procedure CalcDoubleBorderSlants(AnAdapter: TdxPSGridCellsAdapter);
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); override;
function GetBackgroundBounds(DC: HDC): TRect; override;
function GetBorderEdgeBounds(ASide: TdxCellSide; const AOuterRect: TRect): TRect; override;
function GetBorderBrush(ASide: TdxCellSide): HBRUSH;
function GetBorderEdgeClass(ASide: TdxCellSide): TdxPSCellBorderClass; override;
function GetEffectiveBounds(DC: HDC; AStage: TdxPSRenderStages): TRect; override;
function GetTextBounds(DC: HDC): TRect; override;
function IsDrawn(DC: HDC; AStage: TdxPSRenderStages; const ARect: TRect): Boolean; override;
function GetBorderPainterClass: TdxPSCellBorderPainterClass; override;
procedure InitBorderPainter(ABordersPainter: TdxPSCellBorderPainter); override;
function GetContentBkColor: TColor; override;
function GetContentPattern: TdxPSFillPatternClass; override;
procedure SetContentBkColor(Value: TColor); override;
procedure SetContentPattern(Value: TdxPSFillPatternClass); override;
procedure ReadBorders(AReader: TdxPSDataReader);
procedure ReadData(AReader: TdxPSDataReader); override;
procedure WriteBorders(AWriter: TdxPSDataWriter);
procedure WriteData(AWriter: TdxPSDataWriter); override;
function GetAbsoluteInnerBounds(DC: HDC): TRect;
function GetDoubleBorderRgn(ASide: TdxCellSide; const R: TRect): HRGN;
function IsDoubleLineBorderPattern(ABorder: TdxPSCellBorder): Boolean; overload;
function IsDoubleLineBorderPattern(ASide: TdxCellSide): Boolean; overload;
function NullBorder: TdxPSCellBorder;
public
constructor Create(AParent: TdxReportCell); override;
procedure Assign(Source: TPersistent); override;
procedure SetBorders(AColor: TColor; APattern: TdxPSEdgePatternClass);
procedure DrawContent(DC: HDC; AStage: TdxPSRenderStages); override;
property Borders[ASide: TdxCellSide]: TdxPSCellBorder read GetBorder write SetBorder;
property BordersBkColor: TColor read GetBordersBkColor;
property BorderSlants[ASide: TdxCellSide; ACorner: TdxPSCellBorderCorner]: Integer read GetBorderSlant write SetBorderSlant;
property BorderSubs[ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd]: TdxPSCellBorderSub read GetBorderSub write SetBorderSub;
property ClipContent: Boolean read GetClipContent write SetClipConent;
property Col: Integer read GetCol;
property Fill: Boolean read GetFill write SetFill;
property IsFixed: Boolean read GetIsFixed write SetIsFixed;
property IsMerged: Boolean read GetIsMerged write SetIsMerged;
property IsNearMostLeft: Boolean read GetIsNearMostLeft write SetIsNearMostLeft;
property IsNearMostTop: Boolean read GetIsNearMostTop write SetIsNearMostTop;
property IsNearMostTopOrLeft: Boolean read GetIsNearMostTopOrLeft;
property IsVirtual: Boolean read GetIsVirtual write SetIsVirtual;
property RealCol: Integer read FRealCol write FRealCol;
property RealRow: Integer read FRealRow write FRealRow;
property Row: Integer read GetRow;
property TextExtentLeft: Integer read FTextExtentLeft write FTextExtentLeft;
property TextExtentRight: Integer read FTextExtentRight write FTextExtentRight;
end;
TdxPSCellPatternsBorderPainter = class(TdxPSCellBorderPainter)
private
FGridAdapter: TdxPSGridCellsAdapter;
protected
function ClipItemBounds(DC: HDC; AOuterRect: TRect): HRGN;
procedure DrawBorder(DC: HDC; const R: TRect; AForeColor, ABkColor: TColor; ABrush: HBRUSH); overload;
procedure DrawBorder(DC: HDC; ABorderRgn: HRGN; AForeColor, ABkColor: TColor; ABrush: HBRUSH); overload;
public
function Item: TdxReportCellSSString; reintroduce; overload;
procedure Paint(DC: HDC); override;
property GridAdapter: TdxPSGridCellsAdapter read FGridAdapter;
end;
TdxPSGridCellsAdapter = class
private
FReportCells: TdxReportCells;
function GetCell(Col, Row: Integer): TdxReportCellSSString;
function GetColCount: Integer;
function GetColOffset(Index: Integer): Integer;
function GetColWidth(Index: Integer): Integer;
function GetRow(Index: Integer): TdxReportCell;
function GetRowCount: Integer;
function GetRowHeight(Index: Integer): Integer;
function GetRowIndex(Index: Integer): Integer;
function GetRowOffset(Index: Integer): Integer;
public
constructor Create(AReportCells: TdxReportCells);
function GetNeighborCell(AItem: TdxReportCellSSString; ASide: TdxCellSide): TdxReportCellSSString;
property Cells[Col, Row: Integer]: TdxReportCellSSString read GetCell; default;
property ColCount: Integer read GetColCount;
property ColOffsets[Index: Integer]: Integer read GetColOffset;
property ColWidths[Index: Integer]: Integer read GetColWidth;
property RowCount: Integer read GetRowCount;
property RowHeights[Index: Integer]: Integer read GetRowHeight;
property RowIndexes[Index: Integer]: Integer read GetRowIndex;
property RowOffsets[Index: Integer]: Integer read GetRowOffset;
property Rows[Index: Integer]: TdxReportCell read GetRow;
end;
TdxPSSSStringGridCellDataMap = class(TdxPSTextGridCellDataMap)
protected
class procedure InitializeCellData(ACol, ARow: Integer; ADataItem: TAbstractdxReportCellData;
AReportLink: TAbstractdxGridReportLink); override;
class function DataClass: TdxReportCellDataClass; override;
end;
TdxPSSpreadSheetReportLinkOptionView = (ssovRowAndColumnHeadings, ssovGridLines, ssovSuppressSourceFormats);
TdxPSSpreadSheetReportLinkOptionsView = set of TdxPSSpreadSheetReportLinkOptionView;
TCustomdxSpreadSheetReportLink = class(TAbstractdxGridReportLink)
private
FAppendingExtraColumns: Boolean;
FColCount: Integer;
FCellObjects: TList;
FExtraColumnCount: Integer;
FGridAdapter: TdxPSGridCellsAdapter;
FOptionsView: TdxPSSpreadSheetReportLinkOptionsView;
FPrintArea: TRect;
FProcessingMerges: Boolean;
FRowCount: Integer;
FTempFont: TFont;
function GetBookSheet: TcxSSBookSheet;
function GetCustomSpreadSheetBook: TcxCustomSpreadSheetBook;
function GetMeaningColCount: Integer;
function GetMeaningRowCount: Integer;
function GetMergedCells: TcxSSMergedCellsStorage;
procedure SetOptionsView(Value: TdxPSSpreadSheetReportLinkOptionsView);
procedure SetPrintArea(Value: TRect);
function GetSSCellObject(ACol, ARow: Integer): TcxSSCellObject;
function GetSSCellStyle(ACol, ARow: Integer): TcxSSCellStyle;
function GetSSColorPalette: PcxExcelPalette;
function GetSSDataStorage: TcxSSDataStorage;
function GetSSDefaultCellSideColor(ASide: TdxCellSide): TColor;
function GetSSDefaultStyle: TcxSSCellStyle;
function GetFlatIndex(ACol, ARow: Integer): Integer;
function GetRealColor(AColorIndex: Integer; ADefaultColor: TColor): TColor;
function IsSSDefaultStyle(AStyle: TcxSSCellStyle): Boolean;
protected
FSourceHeaderFontIndex: Integer;
function CannotActivateReportErrorString: string; override;
procedure DoChangeComponent; override;
procedure InternalRestoreDefaults; override;
procedure InternalRestoreFromOriginal; override;
function IsScaleGridLines: Boolean; override;
function NeedTwoPassRendering: Boolean; override;
function GetDataItemClass(ACol: Integer; ARow: Integer = 0): TdxReportCellDataClass; override;
function GetColCount: Integer; override;
function GetFixedColCount: Integer; override;
function GetFixedRowCount: Integer; override;
function GetRowCount: Integer; override;
function GetCellSides(ACol, ARow: Integer): TdxCellSides; override;
function GetCellText(ACol, ARow: Integer): string; override;
function GetCellTextAlignY(ACol, ARow: Integer): TcxTextAlignY; override;
function GetMinRowHeight(DC: HDC; AFont: TFont): Integer; override;
function GetSelectionRect: TRect; override;
function GetSourceCellColor(ACol, ARow: Integer): TColor; override;
function GetSourceCellContentBkColor(ACol, ARow: Integer): TColor; override;
function GetSourceCellContentPattern(ACol, ARow: Integer): TdxPSFillPatternClass; override;
function GetSourceCellEdge3DSoft(ACol, ARow: Integer): Boolean; override;
function GetSourceCellEdgeMode(ACol, ARow: Integer): TdxCellEdgeMode; override;
function GetSourceCellFontIndex(ACol, ARow: Integer): Integer; override;
function GetSourceCellMultiline(ACol, ARow: Integer): Boolean; override;
function GetSourceCellTextAlignX(ACol, ARow: Integer): TcxTextAlignX; override;
function GetSourceCellTextAlignY(ACol, ARow: Integer): TcxTextAlignY; override;
function GetSourceCellTransparent(ACol, ARow: Integer): Boolean; override;
function GetSourceColWidth(ACol: Integer): Integer; override;
function GetSourceRowHeight(ARow: Integer): Integer; override;
function HasSelection: Boolean; override;
function IsDrawBorder: Boolean; override;
function IsDrawHorzLines: Boolean; override;
function IsDrawVertLines: Boolean; override;
function IsProcessedCol(ACol: Integer): Boolean; override;
function IsProcessedRow(ARow: Integer): Boolean; override;
procedure AfterConstruct(AReportCells: TdxReportCells); override;
procedure PrepareConstruct(AReportCells: TdxReportCells); override;
procedure UnprepareConstruct(AReportCells: TdxReportCells); override;
procedure AddMerges(AReportCells: TdxReportCells);
procedure AppendAdditionalColumns(AnAdapter: TdxPSGridCellsAdapter);
procedure CalcTextExtents(AnAdapter: TdxPSGridCellsAdapter);
procedure DeleteCellObjects;
procedure DeleteUnneededCellSides(AnAdapter: TdxPSGridCellsAdapter);
procedure FixupRowWidths(AnAdapter: TdxPSGridCellsAdapter);
function HasMerges: Boolean;
function IsEmptyCell(const ACell: TcxSSCellRec): Boolean;
function OnlyEdgeIsAssigned(const ACell: TcxSSCellRec; AEdge: TcxSSEdgeBorder): Boolean;
function OnlyLeftEdgeIsAssigned(ACell: TcxSSCellRec): Boolean;
function OnlyTopEdgeIsAssigned(ACell: TcxSSCellRec): Boolean;
procedure PostProcessItems(AnAdapter: TdxPSGridCellsAdapter);
procedure SetupCellBorders(ACol, ARow: Integer; ADataItem: TAbstractdxReportCellData); virtual;
procedure CheckPrintAreaBounds(var R: TRect);
function GetColumnOffset(ACol: Integer): Integer;
function GetRowOffset(ARow: Integer): Integer;
function IsMergedBorder(ACol, ARow: Integer; ASide: TdxCellSide): Boolean;
function IsMergedCell(ACol, ARow: Integer): Boolean; virtual;
function IsNearMostLeftCell(ACol, ARow: Integer): Boolean; virtual;
function IsNearMostTopCell(ACol, ARow: Integer): Boolean; virtual;
function IsShowGridLines: Boolean;
function IsShowRowAndColumnHeadings: Boolean;
function IsSuppressSourceFormats: Boolean;
property ColCount: Integer read GetColCount;
property ExtraColumnCount: Integer read FExtraColumnCount;
property MeaningColCount: Integer read GetMeaningColCount;
property MeaningRowCount: Integer read GetMeaningRowCount;
property MergedCells: TcxSSMergedCellsStorage read GetMergedCells;
property RowCount: Integer read GetRowCount;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure ClearPrintArea;
function DataProviderPresent: Boolean; override;
function DataToPrintExist: Boolean; virtual;
function PrintAreaExists: Boolean; virtual;
property BookSheet: TcxSSBookSheet read GetBookSheet;
property CustomSpreadSheetBook: TcxCustomSpreadSheetBook read GetCustomSpreadSheetBook;
property PrintArea: TRect read FPrintArea write SetPrintArea;
published
property Color;
property Effects3D;
property FixedColor;
property FixedFont;
property FixedTransparent;
property Font;
property GridLineColor;
property HeadersOnEveryPage;
property OnlySelected;
property OptionsView: TdxPSSpreadSheetReportLinkOptionsView read FOptionsView write SetOptionsView
default [ssovRowAndColumnHeadings];
property RowAutoHeight;
property ScaleFonts;
property Soft3D;
property Transparent;
property UseCustomPageBreaks;
property UseHorzDelimiters;
property UseVertDelimiters;
property OnGetCustomPageBreaks;
property OnInitializeItem;
end;
TdxSpreadSheetBookReportLink = class(TCustomdxSpreadSheetReportLink)
private
function GetSpreadSheetBook: TcxSpreadSheetBook;
public
property SpreadSheetBook: TcxSpreadSheetBook read GetSpreadSheetBook;
end;
TdxSpreadSheetReportLink = class(TCustomdxSpreadSheetReportLink)
private
function GetSpreadSheet: TcxSpreadSheet;
public
property SpreadSheet: TcxSpreadSheet read GetSpreadSheet;
end;
TfmdxSpreadSheetDesignWindow = class(TStandarddxReportLinkDesignWindow)
pnlPreview: TPanel;
pgctrlMain: TPageControl;
tshOptions: TTabSheet;
pnlOptions: TPanel;
lblShow: TLabel;
Bevel11: TBevel;
lblMiscellaneous: TLabel;
Bevel4: TBevel;
Image5: TImage;
imgGrid: TImage;
chbxRowAutoHeight: TCheckBox;
tshColor: TTabSheet;
pnlColor: TPanel;
lblGridLinesColor: TLabel;
bvlLineColorHolder: TBevel;
gbxFixedTransparent: TGroupBox;
lblFixedColor: TLabel;
bvlFixedColorHolder: TBevel;
gbxTransparent: TGroupBox;
lblColor: TLabel;
bvlColorHolder: TBevel;
chbxTransparent: TCheckBox;
chbxFixedTransparent: TCheckBox;
tshFont: TTabSheet;
pnlFont: TPanel;
btnFont: TButton;
edFont: TEdit;
btnFixedFont: TButton;
edFixedFont: TEdit;
tshBehaviors: TTabSheet;
Panel1: TPanel;
Image3: TImage;
lblSelection: TLabel;
Bevel3: TBevel;
lblOnEveryPage: TLabel;
Image1: TImage;
Bevel10: TBevel;
chbxOnlySelected: TCheckBox;
chbxFixedRowsOnEveryPage: TCheckBox;
chbxShowRowAndColumnHeadings: TCheckBox;
chbxShowGridLines: TCheckBox;
chbxSuppressSourceFormats: TCheckBox;
lblPreview: TStaticText;
stTransparent: TStaticText;
stFixedTransparent: TStaticText;
procedure chbxFixedRowsOnEveryPageClick(Sender: TObject);
procedure chbxOnlySelectedClick(Sender: TObject);
procedure btnFixedFontClick(Sender: TObject);
procedure chbxRowAutoHeightClick(Sender: TObject);
procedure chbxSuppressSourceFormatsClick(Sender: TObject);
procedure chbxShowRowAndColumnHeadingsClick(Sender: TObject);
procedure chbxShowGridLinesClick(Sender: TObject);
procedure chbxFixedTransparentClick(Sender: TObject);
procedure ccbxColorChange(Sender: TObject);
procedure pbxPreviewPaint(Sender: TObject);
procedure lblColorClick(Sender: TObject);
procedure pgctrlMainChange(Sender: TObject);
procedure stTransparentClick(Sender: TObject);
procedure stFixedTransparentClick(Sender: TObject);
private
FccbxColor: TCustomComboBox;
FccbxFixedColor: TCustomComboBox;
FccbxGridLineColor: TCustomComboBox;
FPreviewBox: TCustomControl;
function GetReportLink: TCustomdxSpreadSheetReportLink;
procedure SetReportLink(Value: TCustomdxSpreadSheetReportLink);
procedure CreateControls;
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
protected
procedure DoInitialize; override;
{$IFDEF DELPHI7}
function GetPreviewHost: TCustomPanel; override;
{$ENDIF}
procedure LoadStrings; override;
procedure PaintPreview(ACanvas: TCanvas; R: TRect); override;
procedure UpdateControlsState; override;
procedure UpdatePreview; override;
public
constructor Create(AOwner: TComponent); override;
property ReportLink: TCustomdxSpreadSheetReportLink read GetReportLink write SetReportLink;
end;
const
dxPSEmptySSPrintArea: TRect = (Left: -1; Top: -1; Right: -1; Bottom: -1);
dxPSCellSideMap: array[TcxSSEdgeBorder] of TdxCellSide = (csLeft, csTop, csRight, csBottom);
cxSSEdgeBorderMap: array[TdxCellSide] of TcxSSEdgeBorder = (eLeft, eTop, eRight, eBottom);
dxCellEdgeSideOrientation: array[TdxCellSide] of TdxPSCellEdgePatternOrientation =
(cepoVertical, cepoHorizontal, cepoVertical, cepoHorizontal);
dxPSEdgePatternClassMap: array[TcxSSEdgeLineStyle] of TdxPSEdgePatternClass =
(TdxPSSolidEdgePattern, TdxPSSolidEdgePattern, TdxPSMediumSolidEdgePattern,
TdxPSDashedEdgePattern, TdxPSDottedEdgePattern, TdxPSThickSolidEdgePattern,
TdxPSDoubleLineSolidEdgePattern, TdxPSHairEdgePattern, TdxPSMediumDashedEdgePattern,
TdxPSDashDotEdgePattern, TdxPSMediumDashDotEdgePattern, TdxPSDashDotDotEdgePattern,
TdxPSMediumDashDotDotEdgePattern, TdxPSSlantedDashDotEdgePattern, TdxPSSolidEdgePattern);
dxPSFillPatternClassMap: array[TcxSSFillStyle] of TdxPSFillPatternClass =
(TdxPSSolidFillPattern, TdxPSGray75FillPattern, TdxPSGray50FillPattern,
TdxPSGray25FillPattern, TdxPSGray125FillPattern, TdxPSGray625FillPattern,
TdxPSHorizontalStripeFillPattern, TdxPSVerticalStripeFillPattern,
TdxPSDiagonalStripeFillPattern, TdxPSReverseDiagonalStripeFillPattern,
TdxPSDiagonalCrossHatchFillPattern, TdxPSThickCrossHatchFillPattern,
TdxPSThinHorizontalStripeFillPattern, TdxPSThinVerticalStripeFillPattern,
TdxPSThinDiagonalStripeFillPattern, TdxPSThinReverseDiagonalStripeFillPattern,
TdxPSThinHorizontalCrossHatchFillPattern, TdxPSThinDiagonalCrossHatchFillPattern);
dxPSTextAlignXMap: array[TcxDisplayTextAlignment] of TcxTextAlignX =
(taLeft, taCenterX, taRight, taLeft, taDistributeX);
dxPSTextAlignYMap: array[TcxVertTextAlign] of TcxTextAlignY =
(taTop, taCenterY, taBottom, taDistributeY);
implementation
{$R *.DFM}
uses
SysUtils, Forms, cxSSUtils, cxClasses, dxPSRes, dxPSUtl, dxExtCtrls, dxPrnDev;
const
{ Since we don't use following Format Bits in TdxReportCellSSString we are allowed to safely override them }
dxFormatClipContent = dxPSGlbl.dxFormatMakeSpaceForEmptyImage;
dxFormatFill = dxPSGlbl.dxFormatCheckEnabled;
dxFormatFixed = dxPSGlbl.dxFormatCheckBold;
dxFormatMerged = dxPSGlbl.dxFormatImageTransparent;
dxFormatNearMostLeft = dxPSGlbl.dxFormatCheckFlat;
dxFormatNearMostTop = dxPSGlbl.dxFormatCheckChecked;
dxFormatVirtual = dxPSGlbl.dxFormatImageTransparent;
SubEndMask = $00000003;
SubBitsPerEnd = 2;
SubBitsPerSide = SubBitsPerEnd * (Integer(High(TdxPSCellBorderEnd)) + 1);
SlantBitsPerSide = 4;
SlantMask = $00000001;
{ from SS }
SystemColorStart = 55;
type
TcxCustomSpreadSheetBookAccess = class(TcxCustomSpreadSheetBook);
TcxSSBookSheetAccess = class(TcxSSBookSheet);
TcxSSDataStorageAccess = class(TcxSSDataStorage);
TcxSSCellStyleAccess = class(TcxSSCellStyle);
function AreBackgroundsEqual(AStyle1, AStyle2: TcxSSCellStyleRec): Boolean;
begin
Result :=
(AStyle1.BrushStyle = AStyle2.BrushStyle) and
(AStyle1.BrushBkColor = AStyle2.BrushBkColor) and
(AStyle1.BrushFgColor = AStyle2.BrushFgColor);
end;
function AreEdgesEqual(AEdge1, AEdge2: TcxSSEdgeStyleRec): Boolean;
begin
Result := (AEdge1.Color = AEdge2.Color) and (AEdge1.Style = AEdge2.Style);
end;
function AreBordersEqual(ABorders1, ABorders2: TcxSSBordersStyle;
AExclusion: TcxSSEdgeBorders = []): Boolean;
var
Edge: TcxSSEdgeBorder;
begin
for Edge := eLeft to eBottom do
begin
if Edge in AExclusion then
Result := not AreEdgesEqual(ABorders1[Edge], ABorders2[Edge])
else
Result := AreEdgesEqual(ABorders1[Edge], ABorders2[Edge]);
if not Result then Break;
end;
end;
function AreStylesEqual(AStyle1, AStyle2: TcxSSCellStyleRec;
AExclusion: TcxSSEdgeBorders = []): Boolean;
begin
Result := AreBackgroundsEqual(AStyle1, AStyle2) and
AreBordersEqual(AStyle1.Borders, AStyle2.Borders, AExclusion);
end;
function IsCellDataEmpty(const ACell: TcxSSCellRec): Boolean;
begin
Result := (ACell.Text = '') and (ACell.DateTime = 0);
end;
function ExposeBookSheet(ASpreadSheet: TcxSSBookSheet): TcxSSBookSheetAccess;
begin
Result := TcxSSBookSheetAccess(ASpreadSheet);
end;
function ExposeDataStorage(ADataStorage: TcxSSDataStorage): TcxSSDataStorageAccess;
begin
Result := TcxSSDataStorageAccess(ADataStorage);
end;
function ExposeSpreadSheetBook(ASpreadSheetBook: TcxCustomSpreadSheetBook): TcxCustomSpreadSheetBookAccess;
begin
Result := TcxCustomSpreadSheetBookAccess(ASpreadSheetBook);
end;
function ExposeActiveSpreadSheet(ASpreadSheetBook: TcxCustomSpreadSheetBook): TcxSSBookSheetAccess;
begin
Result := ExposeBookSheet(ExposeSpreadSheetBook(ASpreadSheetBook).ActiveSheet);
end;
function ExposeStyle(AStyle: TcxSSCellStyle): TcxSSCellStyleAccess;
begin
Result := TcxSSCellStyleAccess(AStyle);
end;
function GetTextWidth(DC: HDC; AFont: HFONT; const S: string): Integer;
var
Size: TSize;
begin
AFont := SelectObject(DC, AFont);
GetTextExtentPoint32(DC, PChar(S), Length(S), Size);
SelectObject(DC, AFont);
Result := Size.cx;
end;
{ TdxReportCellSSString }
constructor TdxReportCellSSString.Create(AParent: TdxReportCell);
begin
inherited Create(AParent);
PreventLeftTextExceed := False;
TextAlignY := taBottom;
end;
procedure TdxReportCellSSString.Assign(Source: TPersistent);
begin
inherited Assign(Source);
if Source is TdxReportCellSSString then
begin
FBorders := TdxReportCellSSString(Source).FBorders;
FBorderSlants := TdxReportCellSSString(Source).FBorderSlants;
FBorderSubs := TdxReportCellSSString(Source).FBorderSubs;
FContentBkColor := TdxReportCellSSString(Source).FContentBkColor;
FContentPattern := TdxReportCellSSString(Source).FContentPattern;
FRealCol := TdxReportCellSSString(Source).FRealCol;
FRealRow := TdxReportCellSSString(Source).FRealRow;
FTextExtentLeft := TdxReportCellSSString(Source).FTextExtentLeft;
FTextExtentRight := TdxReportCellSSString(Source).FTextExtentRight;
end;
end;
procedure TdxReportCellSSString.SetBorders(AColor: TColor; APattern: TdxPSEdgePatternClass);
var
Side: TdxCellSide;
ABorder: TdxPSCellBorder;
begin
for Side := csLeft to csBottom do
begin
ABorder := Borders[Side];
ABorder.Color := AColor;
ABorder.Pattern := APattern;
Borders[Side] := ABorder;
end;
end;
procedure TdxReportCellSSString.DrawContent(DC: HDC; AStage: TdxPSRenderStages);
begin
if rsFirstPass in AStage then
if IsBackgroundDrawn then DrawBackground(DC);
if rsSecondPass in AStage then
begin
if IsTextDrawn then DrawText(DC);
if IsBordersDrawn then DrawBorders(DC);
end;
end;
procedure TdxReportCellSSString.CalcBorderSubs(AnAdapter: TdxPSGridCellsAdapter);
function GetNeighborCell(ASide: TdxCellSide): TdxReportCellSSString;
begin
Result := AnAdapter.GetNeighborCell(Self, ASide);
end;
function GetNeighborCellBorder(ASide, ABorderSide: TdxCellSide): TdxPSCellBorder;
var
Neighbor: TdxReportCellSSString;
begin
Neighbor := GetNeighborCell(ASide);
if Neighbor <> nil then
Result := Neighbor.Borders[ABorderSide]
else
Result := NullBorder;
end;
function GetNeighborCellBorderSalient(ASide, ABorderSide: TdxCellSide;
ASalient: TdxPSCellBorderSalientType): Integer;
var
Neighbor: TdxReportCellSSString;
begin
Neighbor := GetNeighborCell(ASide);
if Neighbor <> nil then
Result := Neighbor.BorderEdgeSalients[ABorderSide, ASalient]
else
Result := 0;
end;
procedure GetBordersAtCorner(ACorner: TdxPSCellCorner; out ABorders: TdxPSCellBorders);
begin
case ACorner of
ccTopLeft:
begin
ABorders[csLeft] := GetNeighborCellBorder(csLeft, csTop);
ABorders[csTop] := GetNeighborCellBorder(csTop, csLeft);
ABorders[csRight] := Borders[csTop];
ABorders[csBottom] := Borders[csLeft];
end;
ccTopRight:
begin
ABorders[csLeft] := Borders[csTop];
ABorders[csTop] := GetNeighborCellBorder(csTop, csRight);
ABorders[csRight] := GetNeighborCellBorder(csRight, csTop);
ABorders[csBottom] := Borders[csRight];
end;
ccBottomRight:
begin
ABorders[csLeft] := Borders[csBottom];
ABorders[csTop] := Borders[csRight];
ABorders[csRight] := GetNeighborCellBorder(csRight, csBottom);
ABorders[csBottom] := GetNeighborCellBorder(csBottom, csRight);
end;
ccBottomLeft:
begin
ABorders[csLeft] := GetNeighborCellBorder(csLeft, csBottom);
ABorders[csTop] := Borders[csLeft];
ABorders[csRight] := Borders[csBottom];
ABorders[csBottom] := GetNeighborCellBorder(csBottom, csLeft);
end;
end;
end;
function DontNeedCornerSubsCalculation(ACorner: TdxPSCellCorner; ABorders: TdxPSCellBorders): Boolean;
var
BorderCount, DblCount: Integer;
Color: TColor;
Side: TdxCellSide;
Border: TdxPSCellBorder;
begin
BorderCount := 0;
DblCount := 0;
Color := clBlack;
Result := False;
for Side := csLeft to csBottom do
begin
Border := ABorders[Side];
if Border.Pattern = nil then Continue;
Inc(BorderCount);
if IsDoubleLineBorderPattern(Border) then
Inc(DblCount);
if (DblCount <> 0) and (DblCount <> BorderCount) then
Exit;
if BorderCount = 1 then
Color := Border.Color
else
if Color <> Border.Color then
Exit;
end;
Result := True;
end;
function GetFavoriteSides(ACorner: TdxPSCellCorner; const ABorders: TdxPSCellBorders): TdxCellSides;
const
CornerSideMaps: array[TdxPSCellCorner, TdxCellSide] of TdxCellSides =
(([], [], [csTop], [csLeft]),
([csTop], [], [], [csRight]),
([csBottom], [csRight], [], []),
([], [csLeft], [csBottom], []));
var
StartSide, FavoriteSide, Side: TdxCellSide;
DblCount: Integer;
DblCandidates: TdxCellSides;
Border, FavoriteBorder: TdxPSCellBorder;
begin
StartSide := csLeft;
while (StartSide < csBottom) and (ABorders[StartSide].Pattern = nil) do
Inc(StartSide);
FavoriteSide := StartSide;
FavoriteBorder := ABorders[FavoriteSide];
DblCount := 0;
DblCandidates := [];
for Side := StartSide to csBottom do
begin
Border := ABorders[Side];
if Border.Pattern = nil then Continue;
if IsDoubleLineBorderPattern(Border) then
begin
Inc(DblCount);
DblCandidates := DblCandidates + CornerSideMaps[ACorner, Side];
end;
if Side > StartSide then
if not IsDoubleLineBorderPattern(Border) and
(IsDoubleLineBorderPattern(FavoriteBorder) or
(Border.Pattern.Thickness > FavoriteBorder.Pattern.Thickness) or
((Border.Pattern.Thickness = FavoriteBorder.Pattern.Thickness) and
(Border.Color < FavoriteBorder.Color))) then
begin
FavoriteBorder := Border;
FavoriteSide := Side;
end;
end;
if DblCount > 1 then
Result := DblCandidates
else
Result := CornerSideMaps[ACorner, FavoriteSide];
end;
function CalcBorderSub(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd): Integer;
const
ConcurSides: array[TdxCellSide, TdxPSCellBorderEnd] of TdxCellSide =
((csTop, csBottom),
(csLeft, csRight),
(csTop, csBottom),
(csLeft, csRight));
var
ConcurSide: TdxCellSide;
begin
ConcurSide := ConcurSides[ASide, AEnd];
Result := BorderEdgeSalients[ConcurSide, bstOuter] +
Max(BorderEdgeSalients[ConcurSide, bstInner], GetNeighborCellBorderSalient(ASide, ConcurSide, bstInner));
end;
const
BorderEnds: array[TdxPSCellCorner, TdxCellSide] of TdxPSCellBorderEnd =
((cbsTopLeft, cbsTopLeft, cbsTopLeft, cbsTopLeft),
(cbsTopLeft, cbsBottomRight, cbsTopLeft, cbsTopLeft),
(cbsBottomRight, cbsBottomRight, cbsBottomRight, cbsBottomRight),
(cbsBottomRight, cbsTopLeft, cbsTopLeft, cbsTopLeft));
CornerSides: array[TdxPSCellCorner] of TdxCellSides =
([csLeft, csTop],
[csTop, csRight],
[csRight, csBottom],
[csBottom, csLeft]);
var
Corner: TdxPSCellCorner;
Borders: TdxPSCellBorders;
UnfavorableSides: TdxCellSides;
Side: TdxCellSide;
BorderEnd: TdxPSCellBorderEnd;
begin
for Corner := ccTopLeft to ccBottomLeft do
begin
GetBordersAtCorner(Corner, Borders);
if DontNeedCornerSubsCalculation(Corner, Borders) then
Continue;
UnfavorableSides := CornerSides[Corner] - GetFavoriteSides(Corner, Borders);
for Side := csLeft to csBottom do
if Side in UnfavorableSides then
begin
BorderEnd := BorderEnds[Corner, Side];
BorderSubs[Side, BorderEnd] := CalcBorderSub(Side, BorderEnd);
end;
end;
end;
procedure TdxReportCellSSString.CalcDoubleBorderSlants(AnAdapter: TdxPSGridCellsAdapter);
var
Neighbor: TdxReportCellSSString;
begin
if IsDoubleLineBorderPattern(csLeft) then
begin
Neighbor := AnAdapter.GetNeighborCell(Self, csLeft);
BorderSlants[csLeft, cbcTopLeft] := Ord((Neighbor <> nil) and Neighbor.IsDoubleLineBorderPattern(csTop));
BorderSlants[csLeft, cbcTopRight] := Ord(IsDoubleLineBorderPattern(csTop));
BorderSlants[csLeft, cbcBottomRight] := Ord(IsDoubleLineBorderPattern(csBottom));
BorderSlants[csLeft, cbcBottomLeft] := Ord((Neighbor <> nil) and Neighbor.IsDoubleLineBorderPattern(csBottom));
end;
if IsDoubleLineBorderPattern(csTop) then
begin
Neighbor := AnAdapter.GetNeighborCell(Self, csTop);
BorderSlants[csTop, cbcTopLeft] := Ord((Neighbor <> nil) and Neighbor.IsDoubleLineBorderPattern(csLeft));
BorderSlants[csTop, cbcTopRight] := Ord((Neighbor <> nil) and Neighbor.IsDoubleLineBorderPattern(csRight));
BorderSlants[csTop, cbcBottomRight] := Ord(IsDoubleLineBorderPattern(csRight));
BorderSlants[csTop, cbcBottomLeft] := Ord(IsDoubleLineBorderPattern(csLeft));
end;
if IsDoubleLineBorderPattern(csRight) then
begin
Neighbor := AnAdapter.GetNeighborCell(Self, csRight);
BorderSlants[csRight, cbcTopLeft] := Ord(IsDoubleLineBorderPattern(csTop));
BorderSlants[csRight, cbcTopRight] := Ord((Neighbor <> nil) and Neighbor.IsDoubleLineBorderPattern(csTop));
BorderSlants[csRight, cbcBottomRight] := Ord((Neighbor <> nil) and Neighbor.IsDoubleLineBorderPattern(csBottom));
BorderSlants[csRight, cbcBottomLeft] := Ord(IsDoubleLineBorderPattern(csBottom));
end;
if IsDoubleLineBorderPattern(csBottom) then
begin
Neighbor := AnAdapter.GetNeighborCell(Self, csBottom);
BorderSlants[csBottom, cbcTopLeft] := Ord(IsDoubleLineBorderPattern(csLeft));
BorderSlants[csBottom, cbcTopRight] := Ord(IsDoubleLineBorderPattern(csRight));
BorderSlants[csBottom, cbcBottomRight] := Ord((Neighbor <> nil) and Neighbor.IsDoubleLineBorderPattern(csRight));
BorderSlants[csBottom, cbcBottomLeft] := Ord((Neighbor <> nil) and Neighbor.IsDoubleLineBorderPattern(csLeft));
end;
end;
procedure TdxReportCellSSString.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
begin
inherited ConvertCoords(APixelsNumerator, APixelsDenominator);
TextExtentLeft := MulDiv(TextExtentLeft, APixelsNumerator, APixelsDenominator);
TextExtentRight := MulDiv(TextExtentRight, APixelsNumerator, APixelsDenominator);
end;
function TdxReportCellSSString.GetBackgroundBounds(DC: HDC): TRect;
var
LineThickness: Integer;
begin
Result := inherited GetBackgroundBounds(DC);
if not IsFixed then
begin
LineThickness := Self.LineThickness;
if BorderEdgeSalients[csLeft, bstOuter] > 0 then Dec(Result.Left, LineThickness);
if BorderEdgeSalients[csTop, bstOuter] > 0 then Dec(Result.Top, LineThickness);
if BorderEdgeSalients[csRight, bstOuter] > 0 then Inc(Result.Right, LineThickness);
if BorderEdgeSalients[csBottom, bstOuter] > 0 then Inc(Result.Bottom, LineThickness);
FixupRect(DC, Result);
end;
end;
function TdxReportCellSSString.GetBorderEdgeBounds(ASide: TdxCellSide; const AOuterRect: TRect): TRect;
begin
Result := inherited GetBorderEdgeBounds(ASide, AOuterRect);
with Result do
if ASide in csLeftRight then
begin
Inc(Top, LineThickness * BorderSubs[ASide, cbsTopLeft]);
Dec(Bottom, LineThickness * BorderSubs[ASide, cbsBottomRight]);
end
else
begin
Inc(Left, LineThickness * BorderSubs[ASide, cbsTopLeft]);
Dec(Right, LineThickness * BorderSubs[ASide, cbsBottomRight]);
end;
end;
function TdxReportCellSSString.GetBorderBrush(ASide: TdxCellSide): HBRUSH;
begin
Result := dxPSEdgePatternFactory.Items[TdxPSEdgePatternClass(BorderEdgeClasses[ASide]), IsPrinting].Brushes[dxCellEdgeSideOrientation[ASide]].Handle;
end;
function TdxReportCellSSString.GetBorderEdgeClass(ASide: TdxCellSide): TdxPSCellBorderClass;
begin
Result := Borders[ASide].Pattern;
if Result = nil then
Result := TdxPSSolidEdgePattern;
end;
function TdxReportCellSSString.GetEffectiveBounds(DC: HDC; AStage: TdxPSRenderStages): TRect;
begin
if rsFirstPass in AStage then
Result := inherited GetEffectiveBounds(DC, AStage)
else
UnionRect(Result, GetOuterBounds(DC), GetTextBounds(DC));
end;
function TdxReportCellSSString.GetTextBounds(DC: HDC): TRect;
begin
Result := inherited GetTextBounds(DC);
if TextExtentLeft <> 0 then
Result.Left := TextExtentLeft;
if TextExtentRight <> 0 then
Result.Right := TextExtentRight;
end;
function TdxReportCellSSString.IsDrawn(DC: HDC; AStage: TdxPSRenderStages; const ARect: TRect): Boolean;
var
R: TRect;
begin
Result := IntersectRect(R, GetAbsoluteInnerBounds(DC), ARect);
end;
function TdxReportCellSSString.GetBorderPainterClass: TdxPSCellBorderPainterClass;
begin
if IsFixed then
Result := inherited GetBorderPainterClass
else
Result := TdxPSCellPatternsBorderPainter;
end;
procedure TdxReportCellSSString.InitBorderPainter(ABordersPainter: TdxPSCellBorderPainter);
begin
inherited InitBorderPainter(ABordersPainter);
if not IsFixed then
TdxPSCellPatternsBorderPainter(ABordersPainter).FGridAdapter :=
TCustomdxSpreadSheetReportLink(ReportCells.ReportLink).FGridAdapter;
end;
function TdxReportCellSSString.GetContentBkColor: TColor;
begin
Result := FContentBkColor;
end;
function TdxReportCellSSString.GetContentPattern: TdxPSFillPatternClass;
begin
Result := FContentPattern;
end;
procedure TdxReportCellSSString.SetContentBkColor(Value: TColor);
begin
FContentBkColor := Value;
end;
procedure TdxReportCellSSString.SetContentPattern(Value: TdxPSFillPatternClass);
begin
FContentPattern := Value;
end;
procedure TdxReportCellSSString.ReadBorders(AReader: TdxPSDataReader);
var
Side: TdxCellSide;
Border: TdxPSCellBorder;
begin
for Side := csLeft to csBottom do
begin
Border.Color := AReader.ReadInteger;
Border.Pattern := TdxPSEdgePatternClass(AReader.ReadCellBorderClass);
Borders[Side] := Border;
end;
end;
procedure TdxReportCellSSString.ReadData(AReader: TdxPSDataReader);
begin
inherited ReadData(AReader);
with AReader do
begin
ReadBorders(AReader);
FBorderSlants := ReadInteger;
FBorderSubs := ReadInteger;
RealCol := ReadInteger;
RealRow := ReadInteger;
TextExtentLeft := ReadInteger;
TextExtentRight := ReadInteger;
end;
end;
procedure TdxReportCellSSString.WriteBorders(AWriter: TdxPSDataWriter);
var
Side: TdxCellSide;
begin
for Side := csLeft to csBottom do
begin
AWriter.WriteInteger(Borders[Side].Color);
AWriter.WriteClassName(Borders[Side].Pattern);
end;
end;
procedure TdxReportCellSSString.WriteData(AWriter: TdxPSDataWriter);
begin
inherited WriteData(AWriter);
with AWriter do
begin
WriteBorders(AWriter);
WriteInteger(FBorderSlants);
WriteInteger(FBorderSubs);
WriteInteger(RealCol);
WriteInteger(RealRow);
WriteInteger(TextExtentLeft);
WriteInteger(TextExtentRight);
end;
end;
function TdxReportCellSSString.GetAbsoluteInnerBounds(DC: HDC): TRect;
begin
Result := GetInnerBounds(DC);
if Parent <> nil then
with Parent.AbsoluteOrigin do
OffsetRect(Result, X, Y);
end;
function TdxReportCellSSString.GetDoubleBorderRgn(ASide: TdxCellSide; const R: TRect): HRGN;
const
VertexCount = 4;
type
PdxPSCellEdgeCoords = ^TdxPSCellEdgeCoords;
TdxPSCellEdgeCoords = record
case Byte of
0: (TopLeft, TopRight, BottomRight, BottomLeft: TPoint);
1: (Points: array[0..VertexCount - 1] of TPoint);
end;
var
EdgeCoords: TdxPSCellEdgeCoords;
Thickness: Integer;
begin
with EdgeCoords do
begin
TopLeft := R.TopLeft;
TopRight := Point(R.Right, R.Top);
BottomRight := R.BottomRight;
BottomLeft := Point(R.Left, R.Bottom);
end;
Thickness := LineThickness * (TdxPSDoubleLineSolidEdgePattern.Thickness - 1);
with EdgeCoords do
case ASide of
csLeft:
begin
Inc(TopLeft.Y, Thickness * BorderSlants[ASide, cbcTopLeft]);
Inc(TopRight.Y, Thickness * BorderSlants[ASide, cbcTopRight]);
Dec(BottomRight.Y, Thickness * BorderSlants[ASide, cbcBottomRight]);
Dec(BottomLeft.Y, Thickness * BorderSlants[ASide, cbcBottomLeft]);
end;
csTop:
begin
Inc(TopLeft.X, Thickness * BorderSlants[ASide, cbcTopLeft]);
Dec(TopRight.X, Thickness * BorderSlants[ASide, cbcTopRight]);
Dec(BottomRight.X, Thickness * BorderSlants[ASide, cbcBottomRight]);
Inc(BottomLeft.X, Thickness * BorderSlants[ASide, cbcBottomLeft]);
end;
csRight:
begin
Inc(TopLeft.Y, Thickness * BorderSlants[ASide, cbcTopLeft]);
Inc(TopRight.Y, Thickness * BorderSlants[ASide, cbcTopRight]);
Dec(BottomRight.Y, Thickness * BorderSlants[ASide, cbcBottomRight]);
Dec(BottomLeft.Y, Thickness * BorderSlants[ASide, cbcBottomLeft]);
end;
csBottom:
begin
Inc(TopLeft.X, Thickness * BorderSlants[ASide, cbcTopLeft]);
Dec(TopRight.X, Thickness * BorderSlants[ASide, cbcTopRight]);
Dec(BottomRight.X, Thickness * BorderSlants[ASide, cbcBottomRight]);
Inc(BottomLeft.X, Thickness * BorderSlants[ASide, cbcBottomLeft]);
end;
end;
Result := CreatePolygonRgn(EdgeCoords.Points, SizeOf(TdxPSCellEdgeCoords) div SizeOf(TPoint), Windows.WINDING);
end;
function TdxReportCellSSString.IsDoubleLineBorderPattern(ABorder: TdxPSCellBorder): Boolean;
begin
with ABorder do
Result := (Pattern <> nil) and Pattern.InheritsFrom(TdxPSDoubleLineSolidEdgePattern);
end;
function TdxReportCellSSString.IsDoubleLineBorderPattern(ASide: TdxCellSide): Boolean;
begin
Result := (ASide in CellSides) and IsDoubleLineBorderPattern(Self.Borders[ASide]);
end;
function TdxReportCellSSString.NullBorder: TdxPSCellBorder;
begin
FillChar(Result, SizeOf(TdxPSCellBorder), 0);
end;
function TdxReportCellSSString.GetBorder(ASide: TdxCellSide): TdxPSCellBorder;
begin
Result := FBorders[ASide];
end;
function TdxReportCellSSString.GetBordersBkColor: TColor;
begin
if Transparent then
Result := ColorToRGB(clWindow)
else
Result := Color;
end;
function TdxReportCellSSString.GetBorderSlant(ASide: TdxCellSide; ACorner: TdxPSCellBorderCorner): Integer;
begin
Result := (FBorderSlants shr GetBorderSlantOffset(ASide, ACorner)) and SlantMask;
end;
function TdxReportCellSSString.GetBorderSlantOffset(ASide: TdxCellSide; ACorner: TdxPSCellBorderCorner): TDWORDBits;
begin
Result := Integer(ASide) * SlantBitsPerSide + Integer(ACorner);
end;
function TdxReportCellSSString.GetBorderSub(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd): TdxPSCellBorderSub;
begin
Result := (FBorderSubs shr GetBorderSubOffset(ASide, AEnd)) and SubEndMask;
end;
function TdxReportCellSSString.GetBorderSubMask(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd): DWORD;
begin
Result := 0 or (SubEndMask shl GetBorderSubOffset(ASide, AEnd));
end;
function TdxReportCellSSString.GetBorderSubOffset(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd): TDWORDBits;
begin
Result := Integer(ASide) * SubBitsPerSide + SubBitsPerEnd * Integer(AEnd);
end;
function TdxReportCellSSString.GetClipContent: Boolean;
begin
Result := (Format and dxFormatClipContent) = dxFormatClipContent;
end;
function TdxReportCellSSString.GetCol: Integer;
begin
Result := Index;
end;
function TdxReportCellSSString.GetFill: Boolean;
begin
Result := (Format and dxFormatFill) = dxFormatFill;
end;
function TdxReportCellSSString.GetIsFixed: Boolean;
begin
Result := (Format and dxFormatFixed) = dxFormatFixed;
end;
function TdxReportCellSSString.GetIsMerged: Boolean;
begin
Result := (Format and dxFormatMerged) = dxFormatMerged;
end;
function TdxReportCellSSString.GetIsNearMostLeft: Boolean;
begin
Result := (Format and dxFormatNearMostLeft) = dxFormatNearMostLeft;
end;
function TdxReportCellSSString.GetIsNearMostTop: Boolean;
begin
Result := (Format and dxFormatNearMostTop) = dxFormatNearMostTop;
end;
function TdxReportCellSSString.GetIsNearMostTopOrLeft: Boolean;
begin
Result := GetIsNearMostLeft or GetIsNearMostTop;
end;
function TdxReportCellSSString.GetIsVirtual: Boolean;
begin
Result := GetFormatBit(dxFormatVirtual);
end;
function TdxReportCellSSString.GetRow: Integer;
begin
Result := Parent.Index;
end;
procedure TdxReportCellSSString.SetBorder(ASide: TdxCellSide; Value: TdxPSCellBorder);
begin
FBorders[ASide] := Value;
end;
procedure TdxReportCellSSString.SetBorderSlant(ASide: TdxCellSide;
ACorner: TdxPSCellBorderCorner; Value: Integer);
var
Mask: DWORD;
begin
Mask := 1 shl GetBorderSlantOffset(ASide, ACorner);
FBorderSlants := FBorderSlants and not Mask;
if Value <> 0 then
FBorderSlants := FBorderSlants or Mask;
end;
procedure TdxReportCellSSString.SetBorderSub(ASide: TdxCellSide; AEnd: TdxPSCellBorderEnd;
Value: TdxPSCellBorderSub);
begin
FBorderSubs := FBorderSubs and not GetBorderSubMask(ASide, AEnd) or
(Value shl GetBorderSubOffset(ASide, AEnd));
end;
procedure TdxReportCellSSString.SetClipConent(Value: Boolean);
const
dxClipContent: array[Boolean] of DWORD = (0, dxFormatClipContent);
begin
Format := Format and not dxFormatClipContent or dxClipContent[Value];
end;
procedure TdxReportCellSSString.SetFill(Value: Boolean);
const
dxFill: array[Boolean] of DWORD = (0, dxFormatFill);
begin
Format := Format and not dxFormatFill or dxFill[Value];
end;
procedure TdxReportCellSSString.SetIsFixed(Value: Boolean);
const
dxFixed: array[Boolean] of DWORD = (0, dxFormatFixed);
begin
Format := Format and not dxFormatFixed or dxFixed[Value];
end;
procedure TdxReportCellSSString.SetIsMerged(Value: Boolean);
const
dxMerged: array[Boolean] of DWORD = (0, dxFormatMerged);
begin
Format := Format and not dxFormatMerged or dxMerged[Value];
end;
procedure TdxReportCellSSString.SetIsNearMostLeft(Value: Boolean);
const
dxIsNearMostLeft: array[Boolean] of DWORD = (0, dxFormatNearMostLeft);
begin
Format := Format and not dxFormatNearMostLeft or dxIsNearMostLeft[Value];
end;
procedure TdxReportCellSSString.SetIsNearMostTop(Value: Boolean);
const
dxIsNearMostTop: array[Boolean] of DWORD = (0, dxFormatNearMostTop);
begin
Format := Format and not dxFormatNearMostTop or dxIsNearMostTop[Value];
end;
procedure TdxReportCellSSString.SetIsVirtual(Value: Boolean);
begin
SetFormatBit(dxFormatVirtual, Value);
end;
{ TdxPSCellPatternsBorderPainter }
function TdxPSCellPatternsBorderPainter.Item: TdxReportCellSSString;
begin
Result := inherited Item as TdxReportCellSSString;
end;
function TdxPSCellPatternsBorderPainter.ClipItemBounds(DC: HDC; AOuterRect: TRect): HRGN;
begin
with Item do
begin
if IsNearMostTop then
Inc(AOuterRect.Top, LineThickness * BorderEdgeSalients[csTop, bstOuter]);
if IsNearMostLeft then
Inc(AOuterRect.Left, LineThickness * BorderEdgeSalients[csLeft, bstOuter]);
end;
Result := Renderer.IntersectClipRect(AOuterRect);
end;
procedure TdxPSCellPatternsBorderPainter.DrawBorder(DC: HDC; const R: TRect;
AForeColor, ABkColor: TColor; ABrush: HBRUSH);
begin
ABkColor := SetBkColor(DC, ABkColor);
AForeColor := SetTextColor(DC, AForeColor);
FillRect(DC, R, ABrush);
SetTextColor(DC, AForeColor);
SetBkColor(DC, ABkColor);
end;
procedure TdxPSCellPatternsBorderPainter.DrawBorder(DC: HDC; ABorderRgn: HRGN;
AForeColor, ABkColor: TColor; ABrush: HBRUSH);
begin
ABkColor := SetBkColor(DC, ABkColor);
AForeColor := SetTextColor(DC, AForeColor);
FillRgn(DC, ABorderRgn, ABrush);
SetTextColor(DC, AForeColor);
SetBkColor(DC, ABkColor);
end;
procedure TdxPSCellPatternsBorderPainter.Paint(DC: HDC);
var
R: TRect;
Rgn: HRGN;
Side: TdxCellSide;
BorderRect: TRect;
BorderBr: HBRUSH;
BrushOrg: TPoint;
BorderRgn: HRGN;
Border: TdxPSCellBorder;
begin
with Item do
begin
R := GetOuterBounds(DC);
Rgn := 0;
if IsNearMostTopOrLeft then Rgn := ClipItemBounds(DC, R);
for Side := csLeft to csBottom do
if Side in CellSides then
begin
BorderRect := GetBorderEdgeBounds(Side, R);
if RectVisible(DC, BorderRect) then
begin
BorderBr := GetBorderBrush(Side);
Border := Borders[Side];
GetBrushOrgEx(DC, BrushOrg);
if (Border.Pattern <> nil) and Border.Pattern.RequiredBrushOrigin then
begin
UnrealizeObject(BorderBrush);
BrushOrg := BorderRect.TopLeft;
LPToDP(DC, BrushOrg, 1);
SetBrushOrgEx(DC, BrushOrg.X mod 2{Border.Pattern.Thickness}, BrushOrg.Y mod 2{Border.Pattern.Thickness}, nil);
end;
FixupRect(DC, BorderRect);
if IsDoubleLineBorderPattern(Side) then
begin
BorderRgn := GetDoubleBorderRgn(Side, BorderRect);
DrawBorder(DC, BorderRgn, Border.Color, BordersBkColor, BorderBr);
DeleteObject(BorderRgn);
end
else
DrawBorder(DC, BorderRect, Border.Color, BordersBkColor, BorderBr);
if (Border.Pattern <> nil) and Border.Pattern.RequiredBrushOrigin then
SetBrushOrgEx(DC, BrushOrg.X, BrushOrg.Y, nil);
end;
end;
if IsNearMostTopOrLeft then Renderer.RestoreClipRgn(Rgn);
end;
end;
{ TdxPSGridCellsAdapter }
constructor TdxPSGridCellsAdapter.Create(AReportCells: TdxReportCells);
begin
inherited Create;
FReportCells := AReportCells;
end;
function TdxPSGridCellsAdapter.GetNeighborCell(AItem: TdxReportCellSSString;
ASide: TdxCellSide): TdxReportCellSSString;
begin
Result := nil;
case ASide of
csLeft:
if AItem.Col > 0 then
Result := Cells[AItem.Col - 1, AItem.Row];
csTop:
if AItem.Row > 0 then
Result := Cells[AItem.Col, AItem.Row - 1];
csRight:
if AItem.Col + 1 < ColCount then
Result := Cells[AItem.Col + 1, AItem.Row];
csBottom:
if AItem.Row + 1 < RowCount then
Result := Cells[AItem.Col, AItem.Row + 1];
end;
end;
function TdxPSGridCellsAdapter.GetCell(Col, Row: Integer): TdxReportCellSSString;
begin
Result := FReportCells.Cells[Row].DataItems[Col] as TdxReportCellSSString;
end;
function TdxPSGridCellsAdapter.GetColCount: Integer;
begin
with FReportCells do
if Cells.CellCount > 0 then
Result := Cells[0].DataItemCount
else
Result := 0;
end;
function TdxPSGridCellsAdapter.GetColOffset(Index: Integer): Integer;
begin
if Index < ColCount then
Result := Cells[Index, 0].Left
else
Result := Cells[ColCount - 1, 0].Left + Cells[ColCount - 1, 0].Width;
end;
function TdxPSGridCellsAdapter.GetColWidth(Index: Integer): Integer;
begin
Result := Cells[Index, 0].Width;
end;
function TdxPSGridCellsAdapter.GetRow(Index: Integer): TdxReportCell;
begin
Result := FReportCells.Cells[Index];
end;
function TdxPSGridCellsAdapter.GetRowCount: Integer;
begin
Result := FReportCells.Cells.CellCount;
end;
function TdxPSGridCellsAdapter.GetRowHeight(Index: Integer): Integer;
begin
Result := Cells[0, Index].Height;
end;
function TdxPSGridCellsAdapter.GetRowIndex(Index: Integer): Integer;
begin
Result := Rows[Index].Data;
end;
function TdxPSGridCellsAdapter.GetRowOffset(Index: Integer): Integer;
begin
if Index < RowCount then
Result := Cells[0, Index].Top
else
Result := Cells[0, RowCount - 1].Top + Cells[0, RowCount - 1].Height;
end;
{ TdxPSSSStringGridCellDataMap }
class procedure TdxPSSSStringGridCellDataMap.InitializeCellData(ACol, ARow: Integer;
ADataItem: TAbstractdxReportCellData; AReportLink: TAbstractdxGridReportLink);
begin
inherited;
with TCustomdxSpreadSheetReportLink(AReportLink) do
begin
TdxReportCellSSString(ADataItem).Fill := not IsFixedCell(ACol, ARow) and
(GetSSCellObject(ACol, ARow).DisplayTextAlignment = dtaFILL);
TdxReportCellSSString(ADataItem).IsFixed := IsFixedCell(ACol, ARow);
TdxReportCellSSString(ADataItem).IsMerged := IsMergedCell(ACol, ARow);
TdxReportCellSSString(ADataItem).IsNearMostLeft := IsNearMostLeftCell(ACol, ARow);
TdxReportCellSSString(ADataItem).IsNearMostTop := IsNearMostTopCell(ACol, ARow);
TdxReportCellSSString(ADataItem).RealCol := ACol;
TdxReportCellSSString(ADataItem).RealRow := ARow;
SetupCellBorders(ACol, ARow, ADataItem);
end;
end;
class function TdxPSSSStringGridCellDataMap.DataClass: TdxReportCellDataClass;
begin
Result := TdxReportCellSSString;
end;
{ TCustomdxSpreadSheetReportLink }
constructor TCustomdxSpreadSheetReportLink.Create(AOwner: TComponent);
begin
inherited;
FColCount := -1;
FRowCount := -1;
FCellObjects := TList.Create;
FGridAdapter := TdxPSGridCellsAdapter.Create(nil);
FTempFont := TFont.Create;
end;
destructor TCustomdxSpreadSheetReportLink.Destroy;
begin
FTempFont.Free;
FGridAdapter.Free;
DeleteCellObjects;
FCellObjects.Free;
inherited;
end;
procedure TCustomdxSpreadSheetReportLink.Assign(Source: TPersistent);
begin
inherited;
if Source is TCustomdxSpreadSheetReportLink then
with TCustomdxSpreadSheetReportLink(Source) do
begin
Self.OptionsView := OptionsView;
Self.PrintArea := PrintArea;
end;
end;
procedure TCustomdxSpreadSheetReportLink.ClearPrintArea;
begin
PrintArea := dxPSEmptySSPrintArea;
end;
function TCustomdxSpreadSheetReportLink.DataProviderPresent: Boolean;
begin
Result := inherited DataProviderPresent and DataToPrintExist;
end;
function TCustomdxSpreadSheetReportLink.DataToPrintExist: Boolean;
begin
Result := (MeaningColCount > 0) and (MeaningRowCount > 0);
end;
function TCustomdxSpreadSheetReportLink.PrintAreaExists: Boolean;
begin
Result := not EqualRect(PrintArea, dxPSEmptySSPrintArea);
end;
function TCustomdxSpreadSheetReportLink.CannotActivateReportErrorString: string;
begin
if not inherited DataProviderPresent then
Result := inherited CannotActivateReportErrorString
else
Result := cxGetResourceString(@sdxDataToPrintDoesNotExist);
end;
procedure TCustomdxSpreadSheetReportLink.DoChangeComponent;
begin
ClearPrintArea;
inherited;
end;
procedure TCustomdxSpreadSheetReportLink.InternalRestoreDefaults;
begin
inherited;
EndEllipsis := False;
Soft3D := True;
FPrintArea := dxPSEmptySSPrintArea;
OptionsView := [ssovRowAndColumnHeadings];
end;
procedure TCustomdxSpreadSheetReportLink.InternalRestoreFromOriginal;
begin
inherited;
FixedFont := ExposeSpreadSheetBook(CustomSpreadSheetBook).HeaderFont;
end;
function TCustomdxSpreadSheetReportLink.IsScaleGridLines: Boolean;
begin
Result := False;
end;
function TCustomdxSpreadSheetReportLink.NeedTwoPassRendering: Boolean;
begin
Result := True;
end;
function TCustomdxSpreadSheetReportLink.GetDataItemClass(ACol: Integer; ARow: Integer = 0): TdxReportCellDataClass;
begin
Result := TdxReportCellSSString;
end;
function TCustomdxSpreadSheetReportLink.GetColCount: Integer;
var
BeginCol, BeginRow, EndRow: Integer;
begin
if FColCount <= 0 then
if HasSelection then
begin
GetSelectedRange(BeginCol, FColCount, BeginRow, EndRow);
Inc(FColCount);
end
else
FColCount := MeaningColCount + 1;
Result := FColCount;
end;
function TCustomdxSpreadSheetReportLink.GetFixedColCount: Integer;
begin
Result := 1;
end;
function TCustomdxSpreadSheetReportLink.GetFixedRowCount: Integer;
begin
Result := 1;
end;
function TCustomdxSpreadSheetReportLink.GetRowCount: Integer;
var
BeginCol, EndCol, BeginRow: Integer;
begin
if FRowCount <= 0 then
if HasSelection then
begin
GetSelectedRange(BeginCol, EndCol, BeginRow, FRowCount);
Inc(FRowCount);
end
else
FRowCount := MeaningRowCount + 1;
Result := FRowCount;
end;
function TCustomdxSpreadSheetReportLink.GetCellSides(ACol, ARow: Integer): TdxCellSides;
function AreNeigborhoodsTransparent(ASide: TdxCellSide): Boolean;
begin
case ASide of
csLeft:
Result := IsNearMostLeftCell(ACol, ARow) or
(GetCellTransparent(ACol - 1, ARow) and GetCellTransparent(ACol, ARow));
csTop:
Result := IsNearMostTopCell(ACol, ARow) or
(GetCellTransparent(ACol, ARow - 1) and GetCellTransparent(ACol, ARow));
csRight:
Result := ((ACol = GetColCount - 1) {and not FAppendingExtraColumns}) or
(GetCellTransparent(ACol + 1, ARow) and GetCellTransparent(ACol, ARow));
else // csBottom
Result := ((ARow = GetRowCount - 1) {and not FAppendingExtraColumns}) or
(GetCellTransparent(ACol, ARow + 1) and GetCellTransparent(ACol, ARow));
end;
end;
var
Style: TcxSSCellStyle;
Side: TdxCellSide;
BorderStyle: TcxSSEdgeLineStyle;
begin
if IsFixedCell(ACol, ARow) or IsSuppressSourceFormats then
Result := inherited GetCellSides(ACol, ARow)
else
begin
Result := csAll;
Style := GetSSCellStyle(ACol, ARow);
for Side := Low(TdxCellSide) to High(TdxCellSide) do
begin
if Style <> nil then
BorderStyle := Style.Borders.Edges[cxSSEdgeBorderMap[Side]].Style
else
BorderStyle := lsDefault;
if (BorderStyle in [lsNone, lsDefault]) and
(not IsShowGridLines or not AreNeigborhoodsTransparent(Side) or
(IsMergedCell(ACol, ARow) and not IsMergedBorder(ACol, ARow, Side))) then
Exclude(Result, Side);
end;
end;
end;
function TCustomdxSpreadSheetReportLink.GetCellText(ACol, ARow: Integer): string;
begin
if IsFixedCell(ACol, ARow) then
begin
if (ACol = 0) and (ARow <> 0) then
Result := TcxSSUtils.RowNameByIndex(ARow - 1, CustomSpreadSheetBook.R1C1ReferenceStyle);
if (ARow = 0) and (ACol <> 0) then
Result := TcxSSUtils.ColumnNameByIndex(ACol - 1, CustomSpreadSheetBook.R1C1ReferenceStyle);
end
else
if (FProcessingMerges or not IsMergedCell(ACol, ARow)) and not FAppendingExtraColumns then
Result := GetSSCellObject(ACol, ARow).DisplayText
else
Result := '';
end;
function TCustomdxSpreadSheetReportLink.GetCellTextAlignY(ACol, ARow: Integer): TcxTextAlignY;
begin
if (DrawMode <> gdmBorrowSource) and not IsFixedCell(ACol, ARow) then
Result := taBottom
else
Result := inherited GetCellTextAlignY(ACol, ARow);
end;
function TCustomdxSpreadSheetReportLink.GetMinRowHeight(DC: HDC; AFont: TFont): Integer;
begin
Result := 1;
end;
function TCustomdxSpreadSheetReportLink.GetSelectionRect: TRect;
begin
if OnlySelected then
Result := ExposeBookSheet(BookSheet).SelectionRect
else
Result := PrintArea;
OffsetRect(Result, 1, 1);
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellColor(ACol, ARow: Integer): TColor;
begin
if IsFixedCell(ACol, ARow) then
Result := ColorToRGB(ExposeSpreadSheetBook(CustomSpreadSheetBook).HeaderColor)
else
if GetSourceCellContentPattern(ACol, ARow).InheritsFrom(TdxPSSolidFillPattern) then
Result := GetRealColor(GetSSCellStyle(ACol, ARow).Brush.BackgroundColor, clWindow)
else
Result := GetRealColor(GetSSCellStyle(ACol, ARow).Brush.ForegroundColor, clWindow);
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellContentBkColor(ACol, ARow: Integer): TColor;
begin
if IsFixedCell(ACol, ARow) then
Result := ColorToRGB(ExposeSpreadSheetBook(CustomSpreadSheetBook).HeaderColor)
else
Result := GetRealColor(GetSSCellStyle(ACol, ARow).Brush.BackgroundColor, clWindow);
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellContentPattern(ACol, ARow: Integer): TdxPSFillPatternClass;
begin
if IsFixedCell(ACol, ARow) then
Result := TdxPSSolidFillPattern
else
Result := dxPSFillPatternClassMap[GetSSCellStyle(ACol, ARow).Brush.Style];
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellEdge3DSoft(ACol, ARow: Integer): Boolean;
begin
Result := True;
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellEdgeMode(ACol, ARow: Integer): TdxCellEdgeMode;
const
FixedEdgeModes: array[Boolean] of TdxCellEdgeMode = (cem3DEffects, cemPattern);
begin
if IsFixedCell(ACol, ARow) then
Result := FixedEdgeModes[ExposeSpreadSheetBook(CustomSpreadSheetBook).PainterType = ptOfficeXPStyle]
else
Result := cemPattern;
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellFontIndex(ACol, ARow: Integer): Integer;
procedure SetupFont(AFontRec: PcxSSFontRec; AFont: TFont);
begin
with AFont do
begin
Name := AFontRec.Name;
Color := GetRealColor(AFontRec.FontColor, Self.Font.Color);
Style := AFontRec.Style;
Charset := AFontRec.Charset;
Size := AFontRec.Size;
end;
if not dxIsTrueTypeFont(AFont) then AFont.Name := Self.Font.Name;
end;
begin
if not IsFixedCell(ACol, ARow) then
begin
SetupFont(ExposeStyle(GetSSCellStyle(ACol, ARow)).StylePtr^.FontPtr, FTempFont);
Result := AddFontToPool(FTempFont);
end
else
Result := FSourceHeaderFontIndex;
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellMultiline(ACol, ARow: Integer): Boolean;
begin
Result := not IsFixedCell(ACol, ARow) and GetSSCellStyle(ACol, ARow).WordBreak;
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellTextAlignX(ACol, ARow: Integer): TcxTextAlignX;
begin
if IsFixedCell(ACol, ARow) then
Result := taCenterX
else
Result := dxPSTextAlignXMap[GetSSCellObject(ACol, ARow).DisplayTextAlignment];
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellTextAlignY(ACol, ARow: Integer): TcxTextAlignY;
begin
if IsFixedCell(ACol, ARow) then
Result := taBottom
else
Result := dxPSTextAlignYMap[GetSSCellStyle(ACol, ARow).VertTextAlign];
end;
function TCustomdxSpreadSheetReportLink.GetSourceCellTransparent(ACol, ARow: Integer): Boolean;
begin
if not IsFixedCell(ACol, ARow) then
begin
Result := inherited GetSourceCellTransparent(ACol, ARow);
if Result then
Result := (GetSSCellStyle(ACol, ARow).Brush.Style = fsSolid) and (GetSourceCellColor(ACol, ARow) = ColorToRGB(clWindow));
end
else
Result := FixedTransparent;
end;
function TCustomdxSpreadSheetReportLink.GetSourceColWidth(ACol: Integer): Integer;
begin
with ExposeSpreadSheetBook(CustomSpreadSheetBook) do
if IsFixedCol(ACol) then
Result := RowHeaderWidth
else
Result := ActiveSheet.Cols.Size[ACol - 1];
Result := MulDiv(Result, Screen.PixelsPerInch, 96);
end;
function TCustomdxSpreadSheetReportLink.GetSourceRowHeight(ARow: Integer): Integer;
begin
with ExposeSpreadSheetBook(CustomSpreadSheetBook) do
if IsFixedRow(ARow) then
Result := ColHeaderHeight
else
begin
Result := ActiveSheet.Rows.Size[ARow - 1];
Result := MulDiv(Result, 96, Screen.PixelsPerInch);
end;
if Result > 3 then Inc(Result, 3);
Result := MulDiv(Result, Screen.PixelsPerInch, 96);
end;
function TCustomdxSpreadSheetReportLink.HasSelection: Boolean;
begin
Result := inherited HasSelection or PrintAreaExists;
end;
function TCustomdxSpreadSheetReportLink.IsDrawBorder: Boolean;
begin
Result := True;//ssovGridLines in OptionsView;
end;
function TCustomdxSpreadSheetReportLink.IsDrawHorzLines: Boolean;
begin
Result := ssovGridLines in OptionsView;
end;
function TCustomdxSpreadSheetReportLink.IsDrawVertLines: Boolean;
begin
Result := ssovGridLines in OptionsView;
end;
function TCustomdxSpreadSheetReportLink.IsProcessedCol(ACol: Integer): Boolean;
begin
Result := inherited IsProcessedCol(ACol);
if Result then
if IsFixedCol(ACol) then
Result := IsShowRowAndColumnHeadings
else
Result := ExposeSpreadSheetBook(CustomSpreadSheetBook).ActiveSheet.Cols.Visible[ACol - 1];
end;
function TCustomdxSpreadSheetReportLink.IsProcessedRow(ARow: Integer): Boolean;
begin
Result := inherited IsProcessedRow(ARow);
if Result then
if IsFixedRow(ARow) then
Result := IsShowRowAndColumnHeadings
else
with ExposeSpreadSheetBook(CustomSpreadSheetBook) do
Result := ActiveSheet.Rows.Visible[ARow - 1];
end;
procedure TCustomdxSpreadSheetReportLink.AfterConstruct(AReportCells: TdxReportCells);
begin
FColCount := -1;
FRowCount := -1;
FGridAdapter.FReportCells := nil;
DeleteCellObjects;
inherited;
end;
procedure TCustomdxSpreadSheetReportLink.PrepareConstruct(AReportCells: TdxReportCells);
begin
FExtraColumnCount := 0;
FCellObjects.Count := ColCount * RowCount - 1;
FGridAdapter.FReportCells := AReportCells;
FSourceHeaderFontIndex := AddFontToPool(ExposeSpreadSheetBook(CustomSpreadSheetBook).HeaderFont);
inherited;
end;
procedure TCustomdxSpreadSheetReportLink.UnprepareConstruct(AReportCells: TdxReportCells);
begin
if not AbortBuilding then
begin
if HasMerges then AddMerges(AReportCells);
CalcTextExtents(FGridAdapter);
if not HasSelection then
AppendAdditionalColumns(FGridAdapter);
DeleteUnneededCellSides(FGridAdapter);
PostProcessItems(FGridAdapter);
FixupRowWidths(FGridAdapter);
end;
inherited;
end;
procedure TCustomdxSpreadSheetReportLink.AddMerges(AReportCells: TdxReportCells);
function IntersectRect(R1, R2: TRect): Boolean;
begin
Inc(R1.Right);
Inc(R1.Bottom);
Inc(R2.Right);
Inc(R2.Bottom);
Result := Windows.IntersectRect(R1, R1, R2);
end;
var
SelRect, R: TRect;
LeftOffset, TopOffset, I, ACol, ARow: Integer;
Overlay, Cell: TdxReportCell;
DataClass: TdxReportCellDataClass;
DataItem: TAbstractdxReportCellData;
begin
FProcessingMerges := True;
try
SelRect := Rect(0, 0, 0, 0);
LeftOffset := 0;
TopOffset := 0;
if HasSelection then
begin
SelRect := GetSelectionRect;
LeftOffset := GetColumnOffset(SelRect.Left);
TopOffset := GetRowOffset(SelRect.Top);
if IsShowRowAndColumnHeadings then
begin
Dec(LeftOffset, ColumnWidths[0]);
if not HeadersOnEveryPage then Dec(TopOffset, RowHeights[0]);
end;
end
else
if not IsShowRowAndColumnHeadings then
begin
Inc(LeftOffset, ColumnWidths[0]);
Inc(TopOffset, RowHeights[0]);
end
else
if HeadersOnEveryPage then Inc(TopOffset, RowHeights[0]);
Overlay := AReportCells.AddOverlay;
for I := 0 to MergedCells.Count - 1 do
begin
R := MergedCells.MergedAsRect[I];
OffsetRect(R, 1, 1);
if HasSelection and not IntersectRect(R, SelRect) then
Continue;
ACol := R.Left;
ARow := R.Top;
R.Left := GetColumnOffset(R.Left);
R.Top := GetRowOffset(R.Top);
R.Right := GetColumnOffset(R.Right + 1);
R.Bottom := GetRowOffset(R.Bottom + 1);
OffsetRect(R, -LeftOffset, -TopOffset);
Cell := TdxReportCell.Create(Overlay);
Cell.BoundsRect := R;
Cell.Transparent := True;
Cell.CellSides := [];
DataClass := GetDataItemClass(ACol);
if DataClass <> nil then
begin
DataItem := DataClass.Create(Cell);
OffsetRect(R, -R.Left, -R.Top);
DataItem.BoundsRect := R;
AssignData(ACol, ARow, DataItem);
DataItem.CellSides := [];
//DataItem.Transparent := False;//True;
end;
end;
finally
FProcessingMerges := False;
end;
end;
procedure TCustomdxSpreadSheetReportLink.CheckPrintAreaBounds(var R: TRect);
begin
if not EqualRect(R, dxPSEmptySSPrintArea) then
with R do
begin
if Left < 0 then Left :=0;
if Top < 0 then Top := 0;
if Right < Left then Right := Left;
if Bottom < Top then Bottom := Top;
end;
end;
function TCustomdxSpreadSheetReportLink.GetColumnOffset(ACol: Integer): Integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to ACol - 1 do
Inc(Result, ColumnWidths[I]);
end;
function TCustomdxSpreadSheetReportLink.GetRowOffset(ARow: Integer): Integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to ARow - 1 do
Inc(Result, RowHeights[I]);
end;
function TCustomdxSpreadSheetReportLink.IsMergedBorder(ACol, ARow: Integer;
ASide: TdxCellSide): Boolean;
function CellInRect(const R: TRect; X, Y: Integer): Boolean;
begin
Result := (X >= R.Left) and (X <= R.Right) and (Y >= R.Top) and (Y <= R.Bottom);
end;
var
I: Integer;
R: TRect;
begin
Result := IsMergedCell(ACol, ARow);
if Result then
for I := 0 to MergedCells.Count - 1 do
begin
R := MergedCells.MergedAsRect[I];
OffsetRect(R, 1, 1);
if CellInRect(R, ACol, ARow) then
begin
case ASide of
csLeft:
Result := ACol = R.Left;
csTop:
Result := ARow = R.Top;
csRight:
Result := ACol = R.Right;
csBottom:
Result := ARow = R.Bottom;
end;
if Result then Exit;
end;
//Result := (ACol = R.Left) or (ACol = R.Right) or (ARow = R.Top) or (ARow = R.Bottom);
end;
end;
function TCustomdxSpreadSheetReportLink.IsMergedCell(ACol, ARow: Integer): Boolean;
begin
Result := not IsFixedCell(ACol, ARow) and ExposeStyle(GetSSCellStyle(ACol, ARow)).Merge;
end;
function TCustomdxSpreadSheetReportLink.IsNearMostLeftCell(ACol, ARow: Integer): Boolean;
var
R: TRect;
begin
if IsShowRowAndColumnHeadings then
begin
if HasSelection then
begin
R := GetSelectionRect;
Dec(R.Left);
Dec(ACol, R.Left);
end;
Result := ACol = 1
end
else
Result := False;//ACol = 0;
end;
function TCustomdxSpreadSheetReportLink.IsNearMostTopCell(ACol, ARow: Integer): Boolean;
var
R: TRect;
begin
if IsShowRowAndColumnHeadings then
begin
if HasSelection then
begin
R := GetSelectionRect;
Dec(R.Top);
Dec(ARow, R.Top);
end;
Result := ARow = 1
end
else
Result := False;//ARow = 0;
end;
function TCustomdxSpreadSheetReportLink.IsShowGridLines: Boolean;
begin
Result := ssovGridLines in OptionsView;
end;
function TCustomdxSpreadSheetReportLink.IsShowRowAndColumnHeadings: Boolean;
begin
Result := ssovRowAndColumnHeadings in OptionsView;
end;
function TCustomdxSpreadSheetReportLink.IsSuppressSourceFormats: Boolean;
begin
Result := ssovSuppressSourceFormats in OptionsView;
end;
procedure TCustomdxSpreadSheetReportLink.AppendAdditionalColumns(AnAdapter: TdxPSGridCellsAdapter);
function DoCalcExtraColumnCount(AnAdapter: TdxPSGridCellsAdapter;
ADefaultColumnWidth: Integer): Integer;
var
Col, Row, Index, CurrentColumnOffset: Integer;
Item: TdxReportCellSSString;
begin
Result := AnAdapter.ColCount;
for Row := 0 to AnAdapter.RowCount - 1 do
for Col := 0 to AnAdapter.ColCount - 1 do
begin
Item := AnAdapter[Col, Row];
if Item.TextExtentRight <> 0 then
begin
Index := Col;
CurrentColumnOffset := AnAdapter.ColOffsets[Index];
while Item.TextExtentRight > CurrentColumnOffset do
begin
Inc(Index);
if Index <= AnAdapter.ColCount then
CurrentColumnOffset := AnAdapter.ColOffsets[Index]
else
Inc(CurrentColumnOffset, ADefaultColumnWidth);
end;
if Index > Result then Result := Index;
end;
end;
Dec(Result, AnAdapter.ColCount);
end;
function FindNearestVisibleColIndex(AStartIndex: Integer): Integer;
begin
Result := AStartIndex;
with ExposeSpreadSheetBook(CustomSpreadSheetBook).ActiveSheet.Cols do
while not Visible[Result - 1] do
Inc(Result);
end;
procedure DoAppendExtraColumns(AnAdapter: TdxPSGridCellsAdapter;
AExtraColumnCount, ADefaultColumnWidth: Integer);
var
L, Row, Col, StartRealCol, RealCol: Integer;
Item: TdxReportCellSSString;
Cell: TdxReportCell;
R: TRect;
begin
L := AnAdapter.ColOffsets[AnAdapter.ColCount];
StartRealCol := AnAdapter.Cells[AnAdapter.ColCount - 1, 0].RealCol;
for Row := 0 to AnAdapter.RowCount - 1 do
begin
Item := nil;
Cell := AnAdapter.Rows[Row];
R := Bounds(L, 0, 0, Cell.Height);
RealCol := StartRealCol;
for Col := 0 to AExtraColumnCount - 1 do
begin
R.Left := R.Right;
R.Right := R.Left + ADefaultColumnWidth;
Item := TdxReportCellSSString.Create(Cell);
Item.BoundsRect := R;
Item.IsVirtual := True;
RealCol := FindNearestVisibleColIndex(RealCol + 1);
AssignData(RealCol, AnAdapter.RowIndexes[Row], Item);
if Item.IsFixed then
Item.Text := TcxSSUtils.ColumnNameByIndex(RealCol - 1, CustomSpreadSheetBook.R1C1ReferenceStyle);
end;
Cell.Width := Item.BoundsRect.Right;
end;
end;
var
DefaultColumnWidth: Integer;
begin
FAppendingExtraColumns := True;
try
DefaultColumnWidth := ExposeSpreadSheetBook(CustomSpreadSheetBook).DefaultColWidth;
FExtraColumnCount := DoCalcExtraColumnCount(FGridAdapter, DefaultColumnWidth);
if ExtraColumnCount <> 0 then
DoAppendExtraColumns(FGridAdapter, ExtraColumnCount, DefaultColumnWidth);
finally
FAppendingExtraColumns := False;
end;
end;
procedure TCustomdxSpreadSheetReportLink.PostProcessItems(AnAdapter: TdxPSGridCellsAdapter);
var
Col, Row: Integer;
begin
for Col := 0 to AnAdapter.ColCount - 1 do
for Row := 0 to AnAdapter.RowCount - 1 do
with AnAdapter.Cells[Col, Row] do
if not IsFixed and not IsVirtual then
begin
CalcBorderSubs(AnAdapter);
CalcDoubleBorderSlants(AnAdapter);
end;
end;
procedure TCustomdxSpreadSheetReportLink.CalcTextExtents(AnAdapter: TdxPSGridCellsAdapter);
function NeedCalcItemTextExtents(AItem: TdxReportCellSSString): Boolean;
begin
with AItem do
Result := not IsMerged and not IsFixed and not Multiline and not Fill and
(Text <> '') and (TextAlignX in [taLeft, taCenterX, taRight]);
end;
procedure DoCalcItemTextExtents(AItem: TdxReportCellSSString; Col, Row: Integer);
function CalcTextRightExtent(ATextWidth, ACol, ARow: Integer): Integer;
var
OriginalColumnOffset, CurrentColumnOffset, EndOfTextOffset, I: Integer;
Item: TdxReportCellSSString;
begin
OriginalColumnOffset := AnAdapter.ColOffsets[ACol];
EndOfTextOffset := OriginalColumnOffset + ATextWidth;
Result := 0;
CurrentColumnOffset := AnAdapter.ColOffsets[ACol + 1];
for I := ACol + 1 to AnAdapter.ColCount do
begin
CurrentColumnOffset := AnAdapter.ColOffsets[I];
if CurrentColumnOffset > EndOfTextOffset then
Break;
if I < AnAdapter.ColCount then
Item := AnAdapter[I, ARow]
else
Item := nil;
if (Item <> nil) and (Item.IsMerged or (Item.Text <> '')) then
begin
Result := CurrentColumnOffset;
Break;
end
end;
if Result = 0 then
begin
Result := EndOfTextOffset;
if (Result > CurrentColumnOffset) and HasSelection then
Result := CurrentColumnOffset + dxTextSpace;
if Result < AnAdapter.ColOffsets[ACol + 1] then Result := 0;
end;
end;
function CalcTextLeftExtent(ATextWidth, ACol, ARow: Integer): Integer;
var
TextLeftEdge, I, CurrentColumnOffset: Integer;
Item: TdxReportCellSSString;
begin
TextLeftEdge := AnAdapter.ColOffsets[ACol + 1] - ATextWidth;
if TextLeftEdge < 0 then TextLeftEdge := 0;
Result := 0;
for I := ACol downto 0 do
begin
if I > 0 then
Item := AnAdapter[I - 1, ARow]
else
Item := nil;
CurrentColumnOffset := AnAdapter.ColOffsets[I];
if CurrentColumnOffset < TextLeftEdge then
Break;
if (Item = nil) or Item.IsFixed or Item.IsMerged or (Item.Text <> '') then
begin
Result := CurrentColumnOffset;
Break;
end
end;
if Result = 0 then
begin
Result := TextLeftEdge;
if Result > AnAdapter.ColOffsets[ACol] then Result := 0;
end;
end;
var
TextWidth: Integer;
begin
TextWidth := GetTextWidth(ScreenDC, AItem.Font.Handle, AItem.Text);
case AItem.TextAlignX of
taLeft:
AItem.TextExtentRight := CalcTextRightExtent(TextWidth + 3 * dxTextSpace, Col, Row);
taCenterX:
begin
Dec(TextWidth, (TextWidth - AItem.Width) div 2);
AItem.TextExtentRight := CalcTextRightExtent(TextWidth + 1 * dxTextSpace, Col, Row);
AItem.TextExtentLeft := CalcTextLeftExtent(TextWidth + 1 * dxTextSpace, Col, Row);
end;
taRight:
AItem.TextExtentLeft := CalcTextLeftExtent(TextWidth + 3 * dxTextSpace, Col, Row);
end;
end;
var
Font: HFONT;
Col, Row: Integer;
Item: TdxReportCellSSString;
begin
Font := GetCurrentObject(ScreenDC, OBJ_FONT);
for Col := 0 to AnAdapter.ColCount - 1 do
for Row := 0 to AnAdapter.RowCount - 1 do
begin
Item := AnAdapter[Col, Row];
if NeedCalcItemTextExtents(Item) then DoCalcItemTextExtents(Item, Col, Row);
end;
SelectObject(ScreenDC, Font);
end;
procedure TCustomdxSpreadSheetReportLink.DeleteCellObjects;
var
I: Integer;
begin
for I := 0 to FCellObjects.Count - 1 do
TObject(FCellObjects[I]).Free;
FCellObjects.Clear;
end;
procedure TCustomdxSpreadSheetReportLink.DeleteUnneededCellSides(AnAdapter: TdxPSGridCellsAdapter);
procedure DoDeleteUnneededCellSidesFromRightSide(AItem: TdxReportCellSSString; ACol: Integer);
var
TextRightExtent, Col, CurrentColumnOffset: Integer;
begin
TextRightExtent := AItem.TextExtentRight;
for Col := ACol + 1 to AnAdapter.ColCount - 1 do
begin
CurrentColumnOffset := AnAdapter.ColOffsets[Col];
if CurrentColumnOffset < TextRightExtent then
begin
AItem.CellSides := AItem.CellSides - [csRight];
AItem := TdxReportCellSSString(AItem.GetNextSibling);
if AItem = nil then
Break;
AItem.CellSides := AItem.CellSides - [csLeft];
end;
end;
end;
procedure DoDeleteUnneededCellSidesFromLeftSide(AItem: TdxReportCellSSString; ACol: Integer);
var
TextLeftExtent, Col, CurrentColumnOffset: Integer;
begin
TextLeftExtent := AItem.TextExtentLeft;
for Col := ACol downto 0 do
begin
CurrentColumnOffset := AnAdapter.ColOffsets[Col];
if CurrentColumnOffset > TextLeftExtent then
begin
AItem.CellSides := AItem.CellSides - [csLeft];
AItem := TdxReportCellSSString(AItem.GetPrevSibling);
if (AItem = nil) or AItem.IsFixed then
Break;
AItem.CellSides := AItem.CellSides - [csRight];
end;
end;
end;
var
Col, Row: Integer;
Item: TdxReportCellSSString;
begin
for Row := 0 to AnAdapter.RowCount - 1 do
for Col := 0 to AnAdapter.ColCount - 1 do
begin
Item := AnAdapter[Col, Row];
if Item.TextExtentRight <> 0 then
DoDeleteUnneededCellSidesFromRightSide(Item, Col);
if Item.TextExtentLeft <> 0 then
DoDeleteUnneededCellSidesFromLeftSide(Item, Col);
end;
end;
procedure TCustomdxSpreadSheetReportLink.FixupRowWidths(AnAdapter: TdxPSGridCellsAdapter);
var
MaxWidth, I: Integer;
begin
with AnAdapter do
begin
MaxWidth := 0;
for I := 0 to ColCount - 1 do
Inc(MaxWidth, ColWidths[I]);
for I := 0 to RowCount - 1 do
Rows[I].Width := MaxWidth;
end;
end;
function TCustomdxSpreadSheetReportLink.HasMerges: Boolean;
begin
Result := MergedCells.Count <> 0;
end;
function TCustomdxSpreadSheetReportLink.IsEmptyCell(const ACell: TcxSSCellRec): Boolean;
var
DefaultStyle: TcxSSCellStyleRec;
begin
DefaultStyle := ExposeDataStorage(GetSSDataStorage).DefaultCellRec.StylePtr^;
Result := IsCellDataEmpty(ACell) and AreStylesEqual(DefaultStyle, ACell.StylePtr^);
end;
function TCustomdxSpreadSheetReportLink.OnlyEdgeIsAssigned(const ACell: TcxSSCellRec;
AEdge: TcxSSEdgeBorder): Boolean;
var
DefaultStyle: TcxSSCellStyleRec;
begin
DefaultStyle := ExposeDataStorage(GetSSDataStorage).DefaultCellRec.StylePtr^;
Result := IsCellDataEmpty(ACell) and AreStylesEqual(DefaultStyle, ACell.StylePtr^, [AEdge]);
end;
function TCustomdxSpreadSheetReportLink.OnlyLeftEdgeIsAssigned(ACell: TcxSSCellRec): Boolean;
begin
Result := OnlyEdgeIsAssigned(ACell, eLeft);
end;
function TCustomdxSpreadSheetReportLink.OnlyTopEdgeIsAssigned(ACell: TcxSSCellRec): Boolean;
begin
Result := OnlyEdgeIsAssigned(ACell, eTop);
end;
procedure TCustomdxSpreadSheetReportLink.SetupCellBorders(ACol, ARow: Integer;
ADataItem: TAbstractdxReportCellData);
var
DefaultAutoColor, DefaultColor: TColor;
Style: TcxSSCellStyle;
Side: TdxCellSide;
Border: TdxPSCellBorder;
begin
if not IsFixedCell(ACol, ARow) then
begin
DefaultAutoColor := ColorToRGB(clWindowText);
DefaultColor := ColorToRGB(ExposeSpreadSheetBook(CustomSpreadSheetBook).GridColor);
if IsSuppressSourceFormats then
Style := nil
else
Style := GetSSCellStyle(ACol, ARow);
for Side := csLeft to csBottom do
if Side in ADataItem.CellSides then
begin
if Style <> nil then
begin
with Style.Borders.Edges[cxSSEdgeBorderMap[Side]] do
begin
Border.Pattern := dxPSEdgePatternClassMap[Style];
if Style = lsDefault then
Border.Color := GetRealColor(Color, DefaultColor)
else
Border.Color := GetRealColor(Color, DefaultAutoColor);
end;
if IsSSDefaultStyle(Style) then
Border.Color := GetRealColor(GetSSDefaultCellSideColor(Side), DefaultColor);
end
else
if not IsMergedCell(ACol, ARow) then
begin
Border.Color := GetRealColor(GetSSDefaultCellSideColor(Side), ColorToRGB(GridLineColor));
Border.Pattern := TdxPSSolidEdgePattern;
end
else
Border.Pattern := nil;
TdxReportCellSSString(ADataItem).Borders[Side] := Border;
end;
end
end;
function TCustomdxSpreadSheetReportLink.GetBookSheet: TcxSSBookSheet;
begin
if CustomSpreadSheetBook = nil then
Result := nil
else
Result := ExposeSpreadSheetBook(CustomSpreadSheetBook).ActiveSheet;
end;
function TCustomdxSpreadSheetReportLink.GetCustomSpreadSheetBook: TcxCustomSpreadSheetBook;
begin
Result := TcxCustomSpreadSheetBook(Component);
end;
function TCustomdxSpreadSheetReportLink.GetMeaningColCount: Integer;
var
Storage: TcxSSDataStorageAccess;
Col, Row, CandidateCol: Integer;
Cell: TcxSSCellRec;
R: TRect;
begin
Result := -1;
CandidateCol := 0;
Storage := ExposeDataStorage(GetSSDataStorage);
for Row := 0 to Storage.Capacity.cY - 1 do
begin
for Col := Storage.Capacity.cX - 1 downto 0 do
begin
Cell := Storage.Cells[Col, Row];
if not IsEmptyCell(Cell) then
begin
CandidateCol := Col;
if (CandidateCol > 0) and OnlyLeftEdgeIsAssigned(Cell) then Dec(CandidateCol);
Break;
end;
end;
if CandidateCol > Result then Result := CandidateCol;
end;
for Col := 0 to MergedCells.Count - 1 do
begin
R := Storage.MergedCells.MergedAsRect[Col];
if R.Right > Result then Result := R.Right;
end;
if Result > -1 then Inc(Result);
end;
function TCustomdxSpreadSheetReportLink.GetMeaningRowCount: Integer;
var
Storage: TcxSSDataStorageAccess;
CandidateRow, Col, Row: Integer;
Cell: TcxSSCellRec;
IsBreaked: Boolean;
R: TRect;
begin
Storage := ExposeDataStorage(GetSSDataStorage);
CandidateRow := -1;
for Row := Storage.Capacity.cY - 1 downto 0 do
begin
IsBreaked := False;
for Col := 0 to Storage.Capacity.cX - 1 do
begin
Cell := Storage.Cells[Col, Row];
if not IsEmptyCell(Cell) then
begin
CandidateRow := Row;
if (CandidateRow = 0) or not OnlyTopEdgeIsAssigned(Cell) then
begin
IsBreaked := True;
Break;
end;
end;
end;
if CandidateRow <> -1 then
begin
if not IsBreaked then Dec(CandidateRow);
Break;
end;
end;
Result := CandidateRow;
for Col := 0 to Storage.MergedCells.Count - 1 do
begin
R := Storage.MergedCells.MergedAsRect[Col];
if R.Bottom > Result then Result := R.Bottom;
end;
Result := Min(Result, Storage.MaxRow + 1);
if Result > -1 then Inc(Result);
end;
function TCustomdxSpreadSheetReportLink.GetMergedCells: TcxSSMergedCellsStorage;
begin
Result := ExposeDataStorage(ExposeBookSheet(BookSheet).DataStorage).MergedCells;
end;
procedure TCustomdxSpreadSheetReportLink.SetOptionsView(Value: TdxPSSpreadSheetReportLinkOptionsView);
begin
if FOptionsView <> Value then
begin
FOptionsView := Value;
if ssovSuppressSourceFormats in FOptionsView then
DrawMode := gdmStrict
else
DrawMode := gdmBorrowSource;
LinkModified(True);
end;
end;
procedure TCustomdxSpreadSheetReportLink.SetPrintArea(Value: TRect);
begin
CheckPrintAreaBounds(Value);
if not EqualRect(Value, FPrintArea) then
begin
FPrintArea := Value;
LinkModified(True);
end;
end;
function TCustomdxSpreadSheetReportLink.GetSSCellObject(ACol, ARow: Integer): TcxSSCellObject;
var
Index: Integer;
begin
Index := GetFlatIndex(ACol - 1, ARow - 1);
if Index > FCellObjects.Count - 1 then // ExtraColumns
Result := nil
else
Result := FCellObjects.List^[Index];
if Result = nil then
begin
Result := ExposeActiveSpreadSheet(CustomSpreadSheetBook).GetCellObject(ACol - 1, ARow - 1);
if Index > FCellObjects.Count - 1 then
FCellObjects.Count := Index + 1;
FCellObjects.List^[Index] := Result;
end;
end;
function TCustomdxSpreadSheetReportLink.GetSSCellStyle(ACol, ARow: Integer): TcxSSCellStyle;
var
CellObject: TcxSSCellObject;
begin
if not FAppendingExtraColumns then
begin
CellObject := GetSSCellObject(ACol, ARow);
if (CellObject <> nil) and CellObject.StyleExist then
Result := CellObject.Style
else
Result := GetSSDefaultStyle;
end
else
Result := GetSSDefaultStyle;
end;
function TCustomdxSpreadSheetReportLink.GetSSColorPalette: PcxExcelPalette;
begin
Result := ExposeSpreadSheetBook(CustomSpreadSheetBook).Palette;
end;
function TCustomdxSpreadSheetReportLink.GetSSDataStorage: TcxSSDataStorage;
begin
Result := ExposeBookSheet(BookSheet).DataStorage;
end;
function TCustomdxSpreadSheetReportLink.GetSSDefaultCellSideColor(ASide: TdxCellSide): TColor;
begin
with ExposeSpreadSheetBook(CustomSpreadSheetBook), DefaultStyle.Borders do
if ASide in csLeftRight then
if VerticalBorders.Style <> lsDefault then
Result := VerticalBorders.Color
else
Result := ColorToRGB(GridColor)
else
if HorizontalBorders.Style <> lsDefault then
Result := HorizontalBorders.Color
else
Result := ColorToRGB(GridColor);
end;
function TCustomdxSpreadSheetReportLink.GetSSDefaultStyle: TcxSSCellStyle;
begin
Result := ExposeSpreadSheetBook(CustomSpreadSheetBook).StyleCache.DefaultStyle;
end;
function TCustomdxSpreadSheetReportLink.GetFlatIndex(ACol, ARow: Integer): Integer;
begin
Result := ARow * (ColCount - 1) + ACol;
end;
function TCustomdxSpreadSheetReportLink.GetRealColor(AColorIndex: Integer; ADefaultColor: TColor): TColor;
begin
if AColorIndex > SystemColorStart then
Result := ADefaultColor
else
Result := GetSSColorPalette^[AColorIndex];
Result := ColorToRGB(Result);
end;
function TCustomdxSpreadSheetReportLink.IsSSDefaultStyle(AStyle: TcxSSCellStyle): Boolean;
begin
Result := AStyle = GetSSDefaultStyle;
end;
{ TdxSpreadSheetBookReportLink }
function TdxSpreadSheetBookReportLink.GetSpreadSheetBook: TcxSpreadSheetBook;
begin
Result := TcxSpreadSheetBook(Component);
end;
{ TdxSpreadSheetReportLink }
function TdxSpreadSheetReportLink.GetSpreadSheet: TcxSpreadSheet;
begin
Result := TcxSpreadSheet(Component);
end;
{ TfmdxSpreadSheetDesignWindow }
constructor TfmdxSpreadSheetDesignWindow.Create(AOwner: TComponent);
begin
HelpContext := dxhccxSpreadSheetReportLinkDesigner;
inherited;
CreateControls;
pgctrlMain.ActivePage := pgctrlMain.Pages[0];
end;
procedure TfmdxSpreadSheetDesignWindow.DoInitialize;
begin
inherited;
chbxShowRowAndColumnHeadings.Checked := ssovRowAndColumnHeadings in ReportLink.OptionsView;
chbxShowGridLines.Checked := ssovGridLines in ReportLink.OptionsView;
// chbxAutoWidth.Checked := ReportLink.AutoWidth;
chbxRowAutoHeight.Checked := ReportLink.RowAutoHeight;
chbxSuppressSourceFormats.Checked := ssovSuppressSourceFormats in ReportLink.OptionsView;
chbxTransparent.Checked := ReportLink.Transparent;
TdxPSColorCombo(FccbxColor).ColorValue := ReportLink.Color;
chbxFixedTransparent.Checked := ReportLink.FixedTransparent;
TdxPSColorCombo(FccbxFixedColor).ColorValue := ReportLink.FixedColor;
TdxPSColorCombo(FccbxGridLineColor).ColorValue := ReportLink.GridLineColor;
FontInfoToText(ReportLink.Font, edFont);
FontInfoToText(ReportLink.FixedFont, edFixedFont);
chbxFixedRowsOnEveryPage.Checked := ReportLink.HeadersOnEveryPage;
chbxOnlySelected.Checked := ReportLink.OnlySelected;
end;
{$IFDEF DELPHI7}
function TfmdxSpreadSheetDesignWindow.GetPreviewHost: TCustomPanel;
begin
Result := pnlPreview;
end;
{$ENDIF}
procedure TfmdxSpreadSheetDesignWindow.LoadStrings;
begin
inherited;
tshOptions.Caption := cxGetResourceString(@sdxOptions);
tshFont.Caption := cxGetResourceString(@sdxFonts);
tshColor.Caption := cxGetResourceString(@sdxColors);
tshBehaviors.Caption := cxGetResourceString(@sdxBehaviors);
lblPreview.Caption := DropAmpersand(cxGetResourceString(@sdxPreview));
lblShow.Caption := cxGetResourceString(@sdxShow);
chbxShowRowAndColumnHeadings.Caption := cxGetResourceString(@sdxShowRowAndColumnHeadings);
chbxShowGridLines.Caption := cxGetResourceString(@sdxShowGridLines);
lblMiscellaneous.Caption := cxGetResourceString(@sdxMiscellaneous);
//chbxAutoWidth.Caption := cxGetResourceString(@sdxAutoWidth);
chbxRowAutoHeight.Caption := cxGetResourceString(@sdxRowAutoHeight);
chbxSuppressSourceFormats.Caption := cxGetResourceString(@sdxSuppressSourceFormats);
stTransparent.Caption := ' ' + cxGetResourceString(@sdxTransparent) + ' ';
lblColor.Caption := cxGetResourceString(@sdxColor);
stFixedTransparent.Caption := ' ' + cxGetResourceString(@sdxFixedTransparent) + ' ';
lblFixedColor.Caption := cxGetResourceString(@sdxFixedColor);
lblGridLinesColor.Caption := cxGetResourceString(@sdxGridLinesColor);
btnFont.Caption := cxGetResourceString(@sdxBtnFont);
btnFixedFont.Caption := cxGetResourceString(@sdxBtnFixedFont);
lblOnEveryPage.Caption := cxGetResourceString(@sdxOnEveryPage);
chbxFixedRowsOnEveryPage.Caption := cxGetResourceString(@sdxRepeatHeaderRowAtTop);
lblSelection.Caption := cxGetResourceString(@sdxSelection);
chbxOnlySelected.Caption := cxGetResourceString(@sdxOnlySelected);
end;
procedure TfmdxSpreadSheetDesignWindow.PaintPreview(ACanvas: TCanvas; R: TRect);
begin
inherited;
dxPSBaseGridLnk.dxPSDrawGridPreview(ACanvas, R, ReportLink,
ReportLink.IsShowRowAndColumnHeadings, ReportLink.IsShowRowAndColumnHeadings);
end;
procedure TfmdxSpreadSheetDesignWindow.UpdateControlsState;
begin
inherited;
FccbxColor.Enabled := not chbxTransparent.Checked;
lblColor.Enabled := FccbxColor.Enabled;
FccbxFixedColor.Enabled := not chbxFixedTransparent.Checked;
lblFixedColor.Enabled := FccbxFixedColor.Enabled;
chbxFixedRowsOnEveryPage.Enabled := not ReportLink.IsAggregated;
end;
procedure TfmdxSpreadSheetDesignWindow.UpdatePreview;
begin
FPreviewBox.Invalidate;
end;
function TfmdxSpreadSheetDesignWindow.GetReportLink: TCustomdxSpreadSheetReportLink;
begin
Result := inherited ReportLink as TCustomdxSpreadSheetReportLink;
end;
procedure TfmdxSpreadSheetDesignWindow.SetReportLink(Value: TCustomdxSpreadSheetReportLink);
begin
inherited ReportLink := Value;
end;
procedure TfmdxSpreadSheetDesignWindow.CreateControls;
function CreateColorCombo(AHost: TBevel; ALabel: TLabel; ATag: Integer; AnAutoColor: TColor): TdxPSColorCombo;
begin
Result := TdxPSColorCombo.Create(Self);
with Result do
begin
BoundsRect := AHost.BoundsRect;
Tag := ATag;
Parent := AHost.Parent;
ColorTypes := [ctPure];
ShowColorName := True;
ShowAutoColor := True;
AutoColor := AnAutoColor;
OnChange := ccbxColorChange;
end;
ALabel.FocusControl := Result;
end;
function CreatePreviewBox(AParent: TWinControl) : TdxPSPaintPanel;
begin
Result := TdxPSPaintPanel.Create(Self);
with Result do
begin
Parent := AParent;
Align := alClient;
EdgeInner := esNone;
EdgeOuter := esNone;
OnPaint := pbxPreviewPaint;
end;
end;
begin
FccbxColor := CreateColorCombo(bvlColorHolder, lblColor, 0, dxDefaultColor);
FccbxFixedColor := CreateColorCombo(bvlFixedColorHolder, lblFixedColor, 1, dxDefaultFixedColor);
FccbxGridLineColor := CreateColorCombo(bvlLineColorHolder, lblGridLinesColor, 2, dxDefaultGridLineColor);
FPreviewBox := CreatePreviewBox(pnlPreview);
end;
procedure TfmdxSpreadSheetDesignWindow.CMDialogChar(var Message: TCMDialogChar);
var
I: Integer;
begin
inherited;
with pgctrlMain do
for I := 0 to PageCount - 1 do
if IsAccel(Message.CharCode, Pages[I].Caption) then
begin
Message.Result := 1;
ActivePage := Pages[I];
Exit;
end;
end;
procedure TfmdxSpreadSheetDesignWindow.pbxPreviewPaint(Sender: TObject);
begin
with TdxPSPaintPanel(Sender) do
PaintPreview(Canvas, ClientRect);
end;
procedure TfmdxSpreadSheetDesignWindow.chbxFixedRowsOnEveryPageClick(Sender: TObject);
begin
if LockControlsUpdate then Exit;
ReportLink.HeadersOnEveryPage := TCheckBox(Sender).Checked;
Modified := True;
end;
procedure TfmdxSpreadSheetDesignWindow.chbxOnlySelectedClick(Sender: TObject);
begin
if LockControlsUpdate then Exit;
ReportLink.OnlySelected := TCheckBox(Sender).checked;
Modified := True;
end;
procedure TfmdxSpreadSheetDesignWindow.ccbxColorChange(Sender: TObject);
var
Color: TColor;
begin
if LockControlsUpdate then Exit;
Color := TdxPSColorCombo(Sender).ColorValue;
case TdxPSColorCombo(Sender).Tag of
0: ReportLink.Color := Color;
1: ReportLink.FixedColor := Color;
2: ReportLink.GridLineColor := Color;
end;
Modified := True;
UpdatePreview;
end;
procedure TfmdxSpreadSheetDesignWindow.btnFixedFontClick(Sender: TObject);
function GetEdit: TEdit;
begin
if TButton(Sender).Tag = 0 then
Result := edFont
else
Result := edFixedFont;
end;
begin
if LockControlsUpdate then Exit;
with dxPSGlbl.FontDialog do
begin
case TButton(Sender).Tag of
0: Font := ReportLink.Font;
1: Font := ReportLink.FixedFont;
end;
if Execute then
begin
case TButton(Sender).Tag of
0: ReportLink.Font := Font;
1: ReportLink.FixedFont := Font;
end;
FontInfoToText(Font, GetEdit);
Modified := True;
UpdatePreview;
end;
end;
end;
procedure TfmdxSpreadSheetDesignWindow.chbxRowAutoHeightClick(
Sender: TObject);
begin
if LockControlsUpdate then Exit;
ReportLink.RowAutoHeight := TCheckBox(Sender).Checked;
Modified := True;
end;
procedure TfmdxSpreadSheetDesignWindow.chbxSuppressSourceFormatsClick(
Sender: TObject);
begin
if LockControlsUpdate then Exit;
with ReportLink do
if TCheckBox(Sender).Checked then
OptionsView := OptionsView + [ssovSuppressSourceFormats]
else
OptionsView := OptionsView - [ssovSuppressSourceFormats];
Modified := True;
UpdatePreview;
end;
procedure TfmdxSpreadSheetDesignWindow.chbxShowRowAndColumnHeadingsClick(
Sender: TObject);
begin
if LockControlsUpdate then Exit;
with ReportLink do
if TCheckBox(Sender).Checked then
OptionsView := OptionsView + [ssovRowAndColumnHeadings]
else
OptionsView := OptionsView - [ssovRowAndColumnHeadings];
Modified := True;
UpdatePreview;
end;
procedure TfmdxSpreadSheetDesignWindow.chbxShowGridLinesClick(
Sender: TObject);
begin
if LockControlsUpdate then Exit;
with ReportLink do
if TCheckBox(Sender).Checked then
OptionsView := OptionsView + [ssovGridLines]
else
OptionsView := OptionsView - [ssovGridLines];
Modified := True;
UpdatePreview;
end;
procedure TfmdxSpreadSheetDesignWindow.chbxFixedTransparentClick(
Sender: TObject);
begin
if LockControlsUpdate then Exit;
case TCheckBox(Sender).Tag of
0: ReportLink.Transparent := TCheckBox(Sender).checked;
1: ReportLink.FixedTransparent := TCheckBox(Sender).checked;
end;
Modified := True;
UpdatePreview;
end;
procedure TfmdxSpreadSheetDesignWindow.stTransparentClick(Sender: TObject);
begin
if chbxTransparent.CanFocus then ActiveControl := chbxTransparent;
chbxTransparent.Checked := not chbxTransparent.Checked;
end;
procedure TfmdxSpreadSheetDesignWindow.stFixedTransparentClick(Sender: TObject);
begin
if chbxFixedTransparent.CanFocus then ActiveControl := chbxFixedTransparent;
chbxFixedTransparent.Checked := not chbxFixedTransparent.Checked;
end;
procedure TfmdxSpreadSheetDesignWindow.lblColorClick(Sender: TObject);
begin
ActiveControl := TLabel(Sender).FocusControl;
TCustomComboBox(ActiveControl).DroppedDown := True;
end;
procedure TfmdxSpreadSheetDesignWindow.pgctrlMainChange(Sender: TObject);
begin
lblPreview.Parent := TPageControl(Sender).ActivePage;
end;
procedure RegisterItems;
begin
TdxReportCellSSString.Register;
end;
procedure UnregisterItems;
begin
TdxReportCellSSString.Unregister;
end;
procedure RegisterAssistants;
begin
TdxPSSSStringGridCellDataMap.Register;
end;
procedure UnregisterAssistants;
begin
TdxPSSSStringGridCellDataMap.Unregister;
end;
initialization
RegisterAssistants;
RegisterItems;
dxPSRegisterReportLink(TdxSpreadSheetBookReportLink, TcxSpreadSheetBook, TfmdxSpreadSheetDesignWindow);
dxPSRegisterReportLink(TdxSpreadSheetReportLink, TcxSpreadSheet, TfmdxSpreadSheetDesignWindow);
finalization
dxPSUnregisterReportLink(TdxSpreadSheetReportLink, TcxSpreadSheet, TfmdxSpreadSheetDesignWindow);
dxPSUnregisterReportLink(TdxSpreadSheetBookReportLink, TcxSpreadSheetBook, TfmdxSpreadSheetDesignWindow);
UnregisterItems;
UnregisterAssistants;
end.