{*******************************************************************} { } { Developer Express Visual Component Library } { ExpressPrinting System 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, cxPC, cxControls, cxContainer, cxEdit, cxLabel, cxCheckBox, Menus, cxLookAndFeelPainters, cxTextEdit, cxButtons, cxGraphics, cxMaskEdit, cxDropDownEdit, cxColorComboBox, dxPSReportRenderCanvas, cxLookAndFeels; 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(ACanvas: TdxPSReportRenderCustomCanvas): TRect; override; function GetBorderEdgeBounds(ASide: TdxCellSide; const AOuterRect: TRect): TRect; override; function GetBorderBrush(ASide: TdxCellSide): TBrush; function GetBorderEdgeClass(ASide: TdxCellSide): TdxPSCellBorderClass; override; function GetEffectiveBounds(ACanvas: TdxPSReportRenderCustomCanvas; AStage: TdxPSRenderStages): TRect; override; function GetTextBounds(ACanvas: TdxPSReportRenderCustomCanvas): TRect; override; function IsDrawn(ACanvas: TdxPSReportRenderCustomCanvas; 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(ACanvas: TdxPSReportRenderCustomCanvas): 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(ACanvas: TdxPSReportRenderCustomCanvas; 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 procedure ClipItemBounds(ACanvas: TdxPSReportRenderCustomCanvas; AOuterRect: TRect); procedure DrawBorder(ACanvas: TdxPSReportRenderCustomCanvas; const R: TRect; ASide: TdxCellSide); public function Item: TdxReportCellSSString; reintroduce; overload; procedure DrawBorders(ACanvas: TdxPSReportRenderCustomCanvas; const R: TRect); 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(ACanvas: TdxPSReportRenderCustomCanvas; 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: TcxPageControl; tshOptions: TcxTabSheet; Image5: TImage; imgGrid: TImage; tshColor: TcxTabSheet; tshFont: TcxTabSheet; tshBehaviors: TcxTabSheet; Image3: TImage; Image1: TImage; lblPreview: TcxLabel; stTransparent: TcxLabel; stFixedTransparent: TcxLabel; lblShow: TcxLabel; lblMiscellaneous: TcxLabel; lblGridLinesColor: TcxLabel; lblOnEveryPage: TcxLabel; lblSelection: TcxLabel; chbxRowAutoHeight: TcxCheckBox; chbxShowRowAndColumnHeadings: TcxCheckBox; chbxShowGridlines: TcxCheckBox; chbxSuppressSourceFormats: TcxCheckBox; chbxTransparent: TcxCheckBox; chbxFixedTransparent: TcxCheckBox; chbxOnlySelected: TcxCheckBox; chbxFixedRowsOnEveryPage: TcxCheckBox; btnFont: TcxButton; btnFixedFont: TcxButton; edFont: TcxTextEdit; edFixedFont: TcxTextEdit; ccbxLineColor: TcxColorComboBox; lblColor: TcxLabel; ccbxColor: TcxColorComboBox; ccbxFixedColor: TcxColorComboBox; lblFixedColor: TcxLabel; cxLabel1: TcxLabel; procedure chbxFixedRowsOnEveryPageClick(Sender: TObject); procedure chbxOnlySelectedClick(Sender: TObject); procedure btnFixedFontClick(Sender: TObject); procedure chbxRowAutoHeightClick(Sender: TObject); procedure chbxOptionsViewChanged(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 FPreviewBox: TCustomControl; function GetReportLink: TCustomdxSpreadSheetReportLink; procedure CreateControls; procedure SetReportLink(Value: TCustomdxSpreadSheetReportLink); 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(ACanvas: TdxPSReportRenderCustomCanvas; AFont: TFont; const S: string): Integer; begin ACanvas.SaveState; try ACanvas.Font := AFont; Result := ACanvas.TextSize(S).cx; finally ACanvas.RestoreState; end; 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( ACanvas: TdxPSReportRenderCustomCanvas; AStage: TdxPSRenderStages); begin if (rsFirstPass in AStage) and IsBackgroundDrawn then DrawBackground(ACanvas); if rsSecondPass in AStage then begin if IsTextDrawn then DrawText(ACanvas); if IsBordersDrawn then DrawBorders(ACanvas); 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(ACanvas: TdxPSReportRenderCustomCanvas): TRect; var LineThickness: Integer; begin Result := inherited GetBackgroundBounds(ACanvas); 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); ACanvas.FixupRect(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): TBrush; var AItem: TdxPSEdgePatternItem; begin AItem := dxPSEdgePatternFactory.Items[TdxPSEdgePatternClass(BorderEdgeClasses[ASide]), IsPrinting]; Result := AItem.Brushes[dxCellEdgeSideOrientation[ASide]]; end; function TdxReportCellSSString.GetBorderEdgeClass(ASide: TdxCellSide): TdxPSCellBorderClass; begin Result := Borders[ASide].Pattern; if Result = nil then Result := TdxPSSolidEdgePattern; end; function TdxReportCellSSString.GetEffectiveBounds( ACanvas: TdxPSReportRenderCustomCanvas; AStage: TdxPSRenderStages): TRect; begin if rsFirstPass in AStage then Result := inherited GetEffectiveBounds(ACanvas, AStage) else UnionRect(Result, GetOuterBounds(ACanvas), GetTextBounds(ACanvas)); end; function TdxReportCellSSString.GetTextBounds(ACanvas: TdxPSReportRenderCustomCanvas): TRect; begin Result := inherited GetTextBounds(ACanvas); if TextExtentLeft <> 0 then Result.Left := TextExtentLeft; if TextExtentRight <> 0 then Result.Right := TextExtentRight; end; function TdxReportCellSSString.IsDrawn(ACanvas: TdxPSReportRenderCustomCanvas; AStage: TdxPSRenderStages; const ARect: TRect): Boolean; var R: TRect; begin Result := IntersectRect(R, GetAbsoluteInnerBounds(ACanvas), 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(ACanvas: TdxPSReportRenderCustomCanvas): TRect; begin Result := GetInnerBounds(ACanvas); 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; procedure TdxPSCellPatternsBorderPainter.ClipItemBounds( ACanvas: TdxPSReportRenderCustomCanvas; AOuterRect: TRect); 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; ACanvas.IntersectClipRgn(AOuterRect) end; procedure TdxPSCellPatternsBorderPainter.DrawBorder( ACanvas: TdxPSReportRenderCustomCanvas; const R: TRect; ASide: TdxCellSide); var ARegion: TcxRegionHandle; begin if Item.IsDoubleLineBorderPattern(ASide) then ARegion := Item.GetDoubleBorderRgn(ASide, R) else ARegion := CreateRectRgnIndirect(R); ACanvas.FillRegion(ARegion, Item.BordersBkColor, Item.Borders[ASide].Color, nil, Item.GetBorderBrush(ASide)); DeleteObject(ARegion); end; procedure TdxPSCellPatternsBorderPainter.DrawBorders( ACanvas: TdxPSReportRenderCustomCanvas; const R: TRect); var ABorder: TdxPSCellBorder; ABorderRect: TRect; ABrushOrg: TPoint; ASide: TdxCellSide; ATempRect: TRect; begin ACanvas.SaveClipRgn; try if Item.IsNearMostTopOrLeft then ClipItemBounds(ACanvas, R); for ASide := Low(TdxCellSide) to High(TdxCellSide) do if ASide in Item.CellSides then begin ABorderRect := Item.GetBorderEdgeBounds(ASide, R); if ACanvas.IsRectVisible(ABorderRect) then begin ABrushOrg := ACanvas.BrushOrg; try ABorder := Item.Borders[ASide]; if (ABorder.Pattern <> nil) and ABorder.Pattern.RequiredBrushOrigin then begin ATempRect := ABorderRect; ACanvas.LogicalToDeviceCoordinates(ATempRect); ACanvas.BrushOrg := Point(ATempRect.Left mod 2, ATempRect.Top mod 2); end; ACanvas.FixupRect(ABorderRect); DrawBorder(ACanvas, ABorderRect, ASide); finally ACanvas.BrushOrg := ABrushOrg; end; end; end; finally ACanvas.RestoreClipRgn; 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( ACanvas: TdxPSReportRenderCustomCanvas; 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(ScreenCanvas, AItem.Font, AItem.Text); case AItem.TextAlignX of 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; taLeft: AItem.TextExtentRight := CalcTextRightExtent(TextWidth + 3 * dxTextSpace, Col, Row); taRight: AItem.TextExtentLeft := CalcTextLeftExtent(TextWidth + 3 * dxTextSpace, Col, Row); end; end; var Col, Row: Integer; Item: TdxReportCellSSString; begin ScreenCanvas.SaveState; try 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; finally ScreenCanvas.RestoreState; end; 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; ccbxColor.ColorValue := ReportLink.Color; chbxFixedTransparent.Checked := ReportLink.FixedTransparent; ccbxFixedColor.ColorValue := ReportLink.FixedColor; ccbxLineColor.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; ccbxColor.Enabled := not chbxTransparent.Checked; lblColor.Enabled := ccbxColor.Enabled; ccbxFixedColor.Enabled := not chbxFixedTransparent.Checked; lblFixedColor.Enabled := ccbxFixedColor.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; begin FPreviewBox := TdxPSPaintPanel.Create(pnlPreview); with TdxPSPaintPanel(FPreviewBox) do begin Parent := pnlPreview; Align := alClient; EdgeInner := esNone; EdgeOuter := esNone; OnPaint := pbxPreviewPaint; end; 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 := TcxCheckBox(Sender).Checked; Modified := True; end; procedure TfmdxSpreadSheetDesignWindow.chbxOnlySelectedClick(Sender: TObject); begin if LockControlsUpdate then Exit; ReportLink.OnlySelected := TcxCheckBox(Sender).checked; Modified := True; end; procedure TfmdxSpreadSheetDesignWindow.ccbxColorChange(Sender: TObject); var Color: TColor; begin if LockControlsUpdate then Exit; Color := TcxColorComboBox(Sender).ColorValue; case TcxColorComboBox(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: TcxTextEdit; begin if TcxButton(Sender).Tag = 0 then Result := edFont else Result := edFixedFont; end; begin if LockControlsUpdate then Exit; with dxPSGlbl.FontDialog do begin case TcxButton(Sender).Tag of 0: Font := ReportLink.Font; 1: Font := ReportLink.FixedFont; end; if Execute then begin case TcxButton(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 := TcxCheckBox(Sender).Checked; Modified := True; end; procedure TfmdxSpreadSheetDesignWindow.chbxOptionsViewChanged(Sender: TObject); var AOption: TdxPSSpreadSheetReportLinkOptionView; begin if not LockControlsUpdate then begin case TcxCheckBox(Sender).Tag of 0: AOption := ssovRowAndColumnHeadings; 1: AOption := ssovGridLines; 2: AOption := ssovSuppressSourceFormats; else Exit; end; if TcxCheckBox(Sender).Checked then ReportLink.OptionsView := ReportLink.OptionsView + [AOption] else ReportLink.OptionsView := ReportLink.OptionsView - [AOption]; Modified := True; UpdatePreview; end; end; procedure TfmdxSpreadSheetDesignWindow.chbxFixedTransparentClick( Sender: TObject); begin if not LockControlsUpdate then begin case TcxCheckBox(Sender).Tag of 0: ReportLink.Transparent := TcxCheckBox(Sender).checked; 1: ReportLink.FixedTransparent := TcxCheckBox(Sender).checked; end; Modified := True; UpdatePreview; end; 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 ActivateComboBoxControl(Self, TcxLabel(Sender).FocusControl); end; procedure TfmdxSpreadSheetDesignWindow.pgctrlMainChange(Sender: TObject); begin lblPreview.Parent := TcxPageControl(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.