git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@8 05c56307-c608-d34a-929d-697000501d7a
25961 lines
804 KiB
ObjectPascal
25961 lines
804 KiB
ObjectPascal
{*******************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressPrinting System(tm) COMPONENT SUITE }
|
|
{ }
|
|
{ Copyright (C) 1998-2007 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 dxPSCore;
|
|
|
|
interface
|
|
|
|
{$I cxVer.inc}
|
|
|
|
{$IFNDEF DELPHI6}
|
|
{$IFNDEF BCB}
|
|
{$L+} // to avoid internal error in Delphi5
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
(*$HPPEMIT '#include <ole2.hpp>*)
|
|
{$IFDEF CBUILDER5}
|
|
(*$HPPEMIT '#define HRGN unsigned'*)
|
|
{$ELSE}
|
|
(*$HPPEMIT '#define HRGN int'*)
|
|
{$ENDIF}
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, StdCtrls, ExtCtrls,
|
|
ActiveX, Menus, Forms, ImgList, {$IFDEF DELPHI5} Contnrs, {$ENDIF} cxClasses,
|
|
dxBase, dxPSGlbl, dxPSSngltn, dxPSEngn, dxPSESys, dxPSForm, dxBkgnd, dxPrnPg,
|
|
dxPgsDlg, dxPrnDlg, dxWrap, dxPSTextOut, dxPSFillPatterns;
|
|
|
|
type
|
|
EdxPrintEngine = class(Exception);
|
|
EdxReportLink = class(EdxPrintEngine);
|
|
EdxPSExplorer = class(EdxPrintEngine);
|
|
EdxComponentPrinter = class(EdxPrintEngine);
|
|
|
|
EdxInvalidStorageVersion = class(EdxComponentPrinter)
|
|
private
|
|
FVersion: UINT;
|
|
public
|
|
constructor Create(AVersion: UINT);
|
|
property Version: UINT read FVersion write FVersion;
|
|
end;
|
|
|
|
TCustomdxPSExplorerContextCommand = class;
|
|
|
|
IdxPSExplorerContextCommandBuilder = interface
|
|
['{EE36E842-FD6A-4A89-A343-A32828AEFE3D}']
|
|
procedure AddExplorerContextCommand(ACommand: TCustomdxPSExplorerContextCommand);
|
|
procedure UpdateExplorerContextCommands;
|
|
end;
|
|
|
|
IdxPSExplorerContextCommands = interface
|
|
['{DC3A582D-7E33-410F-A235-680A846824D3}']
|
|
procedure BuildCommandSet(ABuilder: IdxPSExplorerContextCommandBuilder);
|
|
end;
|
|
|
|
IdxPSExplorerContextCommands2 = interface
|
|
['{E4D68CF3-AD07-4220-B892-92C8F9B3F966}']
|
|
procedure FinalizeCommand(ACommand: TCustomdxPSExplorerContextCommand);
|
|
procedure InitializeCommand(ACommand: TCustomdxPSExplorerContextCommand);
|
|
end;
|
|
|
|
IdxReportLinkController = interface
|
|
['{120F53E4-1B09-46EF-B42D-04AB8BBCC374}']
|
|
function GetControlSiteBounds(AControl: TControl): TRect;
|
|
end;
|
|
|
|
TdxPSReportDocument = class;
|
|
TdxPSReportRenderer = class;
|
|
TdxReportLinkClass = class of TBasedxReportLink;
|
|
TBasedxReportLink = class;
|
|
TdxCompositionReportLink = class;
|
|
TCustomdxComponentPrinter = class;
|
|
TCustomdxPSExplorerTreeContainer = class;
|
|
TAbstractdxReportLinkDesigner = class;
|
|
TAbstractdxPreviewWindowDesigner = class;
|
|
TAbstractdxReportLinkDesignWindow = class;
|
|
TdxReportLinkDesignWindowClass = class of TAbstractdxReportLinkDesignWindow;
|
|
TBasedxPreviewWindow = class;
|
|
|
|
TdxReportVisualItemClass = class of TdxReportVisualItem;
|
|
TdxReportVisualItem = class;
|
|
TdxReportCellDataClass = class of TAbstractdxReportCellData;
|
|
TAbstractdxReportCellData = class;
|
|
TdxReportCellClass = class of TdxReportCell;
|
|
TdxReportCell = class;
|
|
TdxReportCellsClass = class of TdxReportCells;
|
|
TdxReportCells = class;
|
|
|
|
TdxPSCellBorderClass = class of TdxPSCustomCellBorder;
|
|
TdxPSCustomCellBorder = class;
|
|
TdxPSCellBorderPainterClass = class of TdxPSCellBorderPainter;
|
|
TdxPSCellBorderPainter = class;
|
|
|
|
TdxPSReportGroupLookAndFeelClass = class of TdxPSReportGroupLookAndFeel;
|
|
TdxPSReportGroupLookAndFeel = class;
|
|
TdxPSReportGroupLookAndFeelPainterClass = class of TdxPSReportGroupLookAndFeelPainter;
|
|
TdxPSReportGroupLookAndFeelPainter = class;
|
|
|
|
|
|
{ Data Reader\Writer }
|
|
|
|
TdxPSDataReaderClass = class of TdxPSDataReader;
|
|
|
|
TdxPSDataReader = class(TReader)
|
|
protected
|
|
class function SupportsStorageVersion(AVersion: Integer): Boolean; virtual;
|
|
public
|
|
class procedure Register; virtual;
|
|
class procedure Unregister; virtual;
|
|
|
|
function ReadCellBorderClass: TdxPSCellBorderClass;
|
|
function ReadClass: TClass;
|
|
function ReadFillPatternClass: TdxPSFillPatternClass;
|
|
function ReadFont(AFont: TFont): TFont;
|
|
function ReadGraphicClass: TGraphicClass;
|
|
procedure ReadImage(AnImage: TGraphic);
|
|
procedure ReadImageList(AnImageList: TCustomImageList);
|
|
function ReadLinkClass: TdxReportLinkClass;
|
|
function ReadLookAndFeelClass: TdxPSReportGroupLookAndFeelClass;
|
|
function ReadPoint: TPoint;
|
|
function ReadPSVersion: TdxPSVersion;
|
|
function ReadRect: TRect;
|
|
procedure SkipBytes(Count: {$IFDEF DELPHI6} Int64 {$ELSE} Integer {$ENDIF});
|
|
end;
|
|
|
|
TdxPSDataWriterClass = class of TdxPSDataWriter;
|
|
|
|
TdxPSDataWriter = class(TWriter)
|
|
protected
|
|
class function SupportsStorageVersion(AVersion: Integer): Boolean; virtual;
|
|
public
|
|
class procedure Register; virtual;
|
|
class procedure Unregister; virtual;
|
|
|
|
procedure WriteClassName(AClass: TClass); overload;
|
|
procedure WriteClassName(AnObject: TObject); overload;
|
|
procedure WriteFont(AFont: TFont);
|
|
procedure WriteImage(AnImage: TGraphic);
|
|
procedure WriteImageList(AnImageList: TCustomImageList);
|
|
procedure WritePoint(const Pt: TPoint);
|
|
procedure WritePSVersion(const AVersion: TdxPSVersion);
|
|
procedure WriteRect(const R: TRect);
|
|
end;
|
|
|
|
{ Report Renderers }
|
|
|
|
TdxWindowScalePair = record
|
|
Numerator: Integer;
|
|
Denominator: Integer;
|
|
end;
|
|
|
|
TdxContinuedIndexPair = class
|
|
public
|
|
StartIndex: Integer;
|
|
EndIndex: Integer;
|
|
end;
|
|
|
|
TdxPageOverlayIndexes = class(TList)
|
|
private
|
|
function GetItem(Index: Integer): Integer;
|
|
procedure SetItem(Index, Value: Integer);
|
|
public
|
|
function Add(AValue: Integer): Integer;
|
|
property Items[Index: Integer]: Integer read GetItem write SetItem; default;
|
|
end;
|
|
|
|
TdxPSReportRenderInfo = class;
|
|
|
|
TdxPSPageRenderInfoClass = class of TdxPSPageRenderInfo;
|
|
|
|
TdxPSPageRenderInfo = class
|
|
private
|
|
FIndexPairs: TList;
|
|
FIsEmptyPage: Boolean;
|
|
FIsEmptyPageCalculated: Boolean;
|
|
FOverlays: TList;
|
|
FPageIndex: Integer;
|
|
FRenderInfo: TdxPSReportRenderInfo;
|
|
function GetColIndex: Integer;
|
|
function GetFooterBounds: TRect;
|
|
function GetHeaderBounds: TRect;
|
|
function GetIndexPair(Index: Integer): TdxContinuedIndexPair;
|
|
function GetIndexPairCount: Integer;
|
|
function GetIsBottomPage: Boolean;
|
|
function GetIsEmptyPage: Boolean;
|
|
function GetIsTopPage: Boolean;
|
|
function GetOverlay(Index: Integer): TdxPageOverlayIndexes;
|
|
function GetOverlayCount: Integer;
|
|
function GetPrinterPage: TdxPrinterPage;
|
|
function GetReportCells: TdxReportCells;
|
|
function GetReportLink: TBasedxReportLink;
|
|
function GetRowIndex: Integer;
|
|
function GetTitleBounds: TRect;
|
|
function GetTitleHeight: Integer;
|
|
procedure SetIndexPair(Index: Integer; Value: TdxContinuedIndexPair);
|
|
|
|
procedure FreeAndNilIndexPairs;
|
|
procedure FreeAndNilOverlays;
|
|
protected
|
|
function AreRectsIntersected(const R1, R2: TRect): Boolean;
|
|
|
|
procedure CalculateBounds; virtual;
|
|
function CalculateIndexPairCount: Integer; virtual;
|
|
procedure CalculateIndexPairs; virtual;
|
|
function CalculateIsEmptyPage: Boolean; virtual;
|
|
procedure CalculateOffsets;
|
|
procedure CalculateOverlayIndexes;
|
|
|
|
property IsEmptyPageCalculated: Boolean read FIsEmptyPageCalculated write FIsEmptyPageCalculated;
|
|
public
|
|
ContentBounds: TRect;
|
|
DataOffset: TPoint;
|
|
DetailBounds: TRect;
|
|
TitleOffset: TPoint;
|
|
constructor Create(ARenderInfo: TdxPSReportRenderInfo; APageIndex: Integer); virtual;
|
|
destructor Destroy; override;
|
|
procedure Calculate; virtual;
|
|
|
|
function HasDetails: Boolean; virtual;
|
|
function HasFooter: Boolean; virtual;
|
|
function HasHeader: Boolean; virtual;
|
|
function HasTitle: Boolean; virtual;
|
|
|
|
property ColIndex: Integer read GetColIndex;
|
|
property FooterBounds: TRect read GetFooterBounds;
|
|
property HeaderBounds: TRect read GetHeaderBounds;
|
|
property IndexPairCount: Integer read GetIndexPairCount;
|
|
property IndexPairs[Index: Integer]: TdxContinuedIndexPair read GetIndexPair write SetIndexPair;
|
|
property IsBottomPage: Boolean read GetIsBottomPage;
|
|
property IsEmptyPage: Boolean read GetIsEmptyPage;
|
|
property IsTopPage: Boolean read GetIsTopPage;
|
|
property OverlayCount: Integer read GetOverlayCount;
|
|
property Overlays[Index: Integer]: TdxPageOverlayIndexes read GetOverlay;
|
|
property PageIndex: Integer read FPageIndex;
|
|
property PrinterPage: TdxPrinterPage read GetPrinterPage;
|
|
property RenderInfo: TdxPSReportRenderInfo read FRenderInfo;
|
|
property ReportCells: TdxReportCells read GetReportCells;
|
|
property ReportLink: TBasedxReportLink read GetReportLink;
|
|
property RowIndex: Integer read GetRowIndex;
|
|
property TitleBounds: TRect read GetTitleBounds;
|
|
property TitleHeight: Integer read GetTitleHeight;
|
|
end;
|
|
|
|
TdxPSReportRenderInfoClass = class of TdxPSReportRenderInfo;
|
|
|
|
TdxPSReportRenderInfo = class
|
|
private
|
|
FBaseContentFont: TFont;
|
|
FDelimitersX: TList;
|
|
FDelimitersY: TList;
|
|
FEmptyPageCount: Integer;
|
|
FGridLinesColor: TColor;
|
|
FHardDelimitersY: TList;
|
|
//FIsTitleHeightCalculated: Boolean;
|
|
FLockCounter: Integer;
|
|
FPageDelimitersX: TList;
|
|
FPageDelimitersY: TList;
|
|
FPageRenderInfos: TList;
|
|
FReportLink: TBasedxReportLink;
|
|
//FTitleHeight: Integer;
|
|
function GetBreakPagesByHardDelimiters: Boolean;
|
|
function GetDelimiterX(Index: Integer): Integer;
|
|
function GetDelimiterXCount: Integer;
|
|
function GetDelimiterY(Index: Integer): Integer;
|
|
function GetDelimiterYCount: Integer;
|
|
function GetEmptyPageCount: Integer;
|
|
function GetFooterHeight: Integer;
|
|
function GetHeaderHeight: Integer;
|
|
function GetLocked: Boolean;
|
|
function GetPageDelimiterX(Index: Integer): Integer;
|
|
function GetPageDelimiterXCount: Integer;
|
|
function GetPageDelimiterY(Index: Integer): Integer;
|
|
function GetPageDelimiterYCount: Integer;
|
|
function GetPageRenderInfo(Index: Integer): TdxPSPageRenderInfo;
|
|
function GetPageRenderInfoCount: Integer;
|
|
function GetPrinterPage: TdxPrinterPage;
|
|
function GetReportCells: TdxReportCells;
|
|
function GetReportHeight: Integer;
|
|
function GetReportWidth: Integer;
|
|
function GetScaleFactor: Integer;
|
|
function GetTitleAdjustOnReportScale: Boolean;
|
|
function GetTitleFont: TFont;
|
|
function GetTitleText: string;
|
|
function GetUseHardVertDelimiters: Boolean;
|
|
function GetUseHorzDelimiters: Boolean;
|
|
function GetUseVertDelimiters: Boolean;
|
|
function GetTitleHeight: Integer;
|
|
procedure SetBaseContentFont(Value: TFont);
|
|
|
|
function IsNonEmptyPage(const ABounds: TRect): Boolean;
|
|
protected
|
|
function CalculateEmptyPageCount: Integer; virtual;
|
|
procedure CalculateHeaderAndFooterBounds; virtual;
|
|
function CalculatePageContentHeight(APageIndex: Integer): Integer; virtual;
|
|
function CalculatePageContentWidth(APageIndex: Integer): Integer; virtual;
|
|
procedure CalculatePageCount; virtual;
|
|
procedure CalculatePageDelimiters; virtual;
|
|
function CalculatePageDetailBounds(APageCol, APageRow: Integer): TRect; virtual;
|
|
procedure CalculatePageHeaderAndFooterBounds; virtual;
|
|
procedure CalculatePageRenderInfos; virtual;
|
|
procedure CalculatePageRealAndVirtualIndexes(APageIndex: Integer; out AVirtualPageIndex, ARealPageIndex: Integer); virtual;
|
|
//function CalculateTitleHeight: Integer; virtual;
|
|
procedure CalculateTitleBounds; virtual;
|
|
procedure DoCalculate; virtual;
|
|
|
|
function GetNonEmptyPageCount: Integer; virtual;
|
|
function GetPageColCount: Integer; virtual;
|
|
function GetPageRowCount: Integer; virtual;
|
|
function GetPageSize: TPoint; virtual;
|
|
function GetPaintSize: TPoint; virtual;
|
|
function GetUnitsPerInch: Integer; virtual;
|
|
function GetWindowScalePair: TdxWindowScalePair; virtual;
|
|
procedure SetUnitsPerInch(Value: Integer); virtual;
|
|
|
|
procedure ClearPageRenderInfos;
|
|
function CreatePageRenderInfo(APageIndex: Integer): TdxPSPageRenderInfo; virtual;
|
|
procedure FreeAndNilPageRenderInfos;
|
|
function GetPageRenderInfoClass: TdxPSPageRenderInfoClass; virtual;
|
|
procedure Refresh; virtual;
|
|
|
|
function HasPageTitle(APageIndex: Integer): Boolean;
|
|
function IsHardDelimiter(AValue: Integer): Boolean;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure ReadDelimiters(AReader: TdxPSDataReader);
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
procedure WriteDelimiters(AWriter: TdxPSDataWriter);
|
|
|
|
procedure AddPageDelimiterX(AValue: Integer);
|
|
procedure AddPageDelimiterY(AValue: Integer);
|
|
procedure PageDelimiterXClear;
|
|
procedure PageDelimiterYClear;
|
|
|
|
procedure AddStandardDelimiters;
|
|
procedure EliminateDuplicatesAndSortDelimiters(AList: TList);
|
|
procedure GetDelimiters;
|
|
procedure MakeDelimiters;
|
|
procedure MakeHardDelimiters;
|
|
procedure TrancateDelimiters(AList: TList; AValue: Integer);
|
|
|
|
function LoMetricRectToInternalUnits(const R: TRect): TRect;
|
|
function LoMetricValueToInternalUnits(Value: Integer): Integer; virtual;
|
|
function RealPageIndexToVirtualPageIndex(APageIndex: Integer; ATakeIntoAccountEmptyPages: Boolean): Integer; virtual;
|
|
function VirtualPageIndexToRealPageIndex(APageIndex: Integer): Integer; virtual;
|
|
|
|
property DelimiterXList: TList read FDelimitersX;
|
|
property DelimiterYList: TList read FDelimitersY;
|
|
property HardDelimiterYList: TList read FHardDelimitersY;
|
|
public
|
|
CanUseHFOnEveryPageMode: Boolean;
|
|
FooterBounds: TRect;
|
|
HeaderBounds: TRect;
|
|
PageFooterBounds: TRect;
|
|
PageHeaderBounds: TRect;
|
|
TitleBounds: TRect;
|
|
VirtualPageCount: Integer;
|
|
|
|
constructor Create(AReportLink: TBasedxReportLink); virtual;
|
|
destructor Destroy; override;
|
|
|
|
procedure Calculate;
|
|
function CalculateTitleHeight: Integer; virtual;
|
|
function CanRenderPage(AVirtualPageIndex: Integer): Boolean; virtual;
|
|
function IsDrawPageFootNoteOnPage(APageIndex: Integer): Boolean; virtual;
|
|
function IsDrawPageTitleOnPage(APageIndex: Integer): Boolean; virtual;
|
|
|
|
procedure Lock;
|
|
procedure Unlock;
|
|
|
|
property BaseContentFont: TFont read FBaseContentFont write SetBaseContentFont;
|
|
property BreakPagesByHardDelimiters: Boolean read GetBreakPagesByHardDelimiters;
|
|
property DelimitersX[Index: Integer]: Integer read GetDelimiterX;
|
|
property DelimiterXCount: Integer read GetDelimiterXCount;
|
|
property DelimitersY[Index: Integer]: Integer read GetDelimiterY;
|
|
property DelimiterYCount: Integer read GetDelimiterYCount;
|
|
property EmptyPageCount: Integer read GetEmptyPageCount;
|
|
property FooterHeight: Integer read GetFooterHeight;
|
|
property GridLinesColor: TColor read FGridLinesColor write FGridLinesColor;
|
|
property HeaderHeight: Integer read GetHeaderHeight;
|
|
property Locked: Boolean read GetLocked;
|
|
property NonEmptyPageCount: Integer read GetNonEmptyPageCount;
|
|
property PageColCount: Integer read GetPageColCount;
|
|
property PageDelimitersX[Index: Integer]: Integer read GetPageDelimiterX;
|
|
property PageDelimiterXCount: Integer read GetPageDelimiterXCount;
|
|
property PageDelimitersY[Index: Integer]: Integer read GetPageDelimiterY;
|
|
property PageDelimiterYCount: Integer read GetPageDelimiterYCount;
|
|
property PageRenderInfoCount: Integer read GetPageRenderInfoCount;
|
|
property PageRenderInfos[Index: Integer]: TdxPSPageRenderInfo read GetPageRenderInfo;
|
|
property PageRowCount: Integer read GetPageRowCount;
|
|
property PageSize: TPoint read GetPageSize;
|
|
property PaintSize: TPoint read GetPaintSize;
|
|
property PrinterPage: TdxPrinterPage read GetPrinterPage;
|
|
property ReportCells: TdxReportCells read GetReportCells;
|
|
property ReportHeight: Integer read GetReportHeight;
|
|
property ReportLink: TBasedxReportLink read FReportLink;
|
|
property ReportWidth: Integer read GetReportWidth;
|
|
property ScaleFactor: Integer read GetScaleFactor;
|
|
property TitleAdjustOnReportScale: Boolean read GetTitleAdjustOnReportScale;
|
|
property TitleFont: TFont read GetTitleFont;
|
|
property TitleHeight: Integer read GetTitleHeight;
|
|
property TitleText: string read GetTitleText;
|
|
property UnitsPerInch: Integer read GetUnitsPerInch write SetUnitsPerInch;
|
|
property UseHardVertDelimiters: Boolean read GetUseHardVertDelimiters;
|
|
property UseHorzDelimiters: Boolean read GetUseHorzDelimiters;
|
|
property UseVertDelimiters: Boolean read GetUseVertDelimiters;
|
|
property WindowScalePair: TdxWindowScalePair read GetWindowScalePair;
|
|
end;
|
|
|
|
TdxCellCheckPos = (ccpLeft, ccpCenter, ccpRight);
|
|
TdxCellEdgeKind = (cekInner, cekOuter);
|
|
TdxCellEdgeMode = (cemPattern, cem3DEffects);
|
|
TdxCellEdgeStyle = (cesRaised, cesSunken);
|
|
TdxCellSide = (csLeft, csTop, csRight, csBottom);
|
|
TdxCellSides = set of TdxCellSide;
|
|
TdxCellSortOrder = (csoNone, csoUp, csoDown);
|
|
TdxCellUpDown = csoUp..csoDown;
|
|
TdxCheckButtonEdgeStyle = (cbesNone, cbes3D, cbesSoft3D, cbesBoldFlat, cbesUltraFlat, cbesSingle);
|
|
TdxGraphicDrawMode = (gdmNone, gdmCenter, gdmStretch, gdmStretchProportional, gdmCenterAndStretchProportional);
|
|
TdxImageLayout = (ilImageTopLeft, ilImageTopCenter, ilImageTopRight, ilImageCenterLeft,
|
|
ilImageCenterCenter, ilImageCenterRight, ilImageBottomLeft, ilImageBottomCenter, ilImageBottomRight);
|
|
|
|
TdxCellImageBuffering = (cibDefault, cibNone, cibAlways);
|
|
{$IFDEF BCB}
|
|
TdxCellImageActualBuffering = TdxCellImageBuffering;
|
|
{$ELSE}
|
|
TdxCellImageActualBuffering = cibNone..cibAlways;
|
|
{$ENDIF}
|
|
|
|
TdxPSCellBorderSalientType = (bstOuter, bstInner);
|
|
|
|
TdxPSTreeLineMode = (tlmNone, tlmVertical, tlmCross, tlmTopRightCorner, tlmBottomRightCorner);
|
|
TdxPSTreeLinePart = (tlpTop, tlpRight, tlpBottom);
|
|
TdxPSTreeLineParts = set of TdxPSTreeLinePart;
|
|
TdxPSTreeLineStyle = (tlsSolid, tlsDot);
|
|
|
|
TdxPSCellBorderPainter = class
|
|
private
|
|
FItem: TdxReportVisualItem;
|
|
FRenderer: TdxPSReportRenderer;
|
|
function GetLineThickness: Integer;
|
|
protected
|
|
class function GetBorderBounds(const R: TRect; ASide: TdxCellSide; ALineThickness: Integer): TRect; virtual;
|
|
class function GetBottomShadowBounds(const R: TRect; AShadowDepth: Integer): TRect;
|
|
class function GetBottomShadowRestSpaceBounds(const R: TRect; AShadowDepth: Integer): TRect;
|
|
class function GetRightShadowBounds(const R: TRect; AShadowDepth: Integer): TRect;
|
|
class function GetRightShadowRestSpaceBounds(const R: TRect; AShadowDepth: Integer): TRect;
|
|
class procedure InflateRect(var R: TRect; ASides: TdxCellSides; ALineThickness: Integer);
|
|
public
|
|
constructor Create(ARenderer: TdxPSReportRenderer); virtual;
|
|
|
|
class procedure DrawFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
ATLBrush, ABRBrush: HBRUSH; ALineThickness: Integer; AThickness: Integer = 1);
|
|
class procedure DrawShadow(DC: HDC; const R: TRect; AShadowDepth: Integer;
|
|
AShadowBrush, ARestSpaceBrush: HBRUSH);
|
|
procedure Paint(DC: HDC); virtual;
|
|
|
|
function BorderClass: TdxPSCellBorderClass; overload; virtual;
|
|
function Item: TdxReportVisualItem; overload; virtual;
|
|
function Renderer: TdxPSReportRenderer; overload; virtual;
|
|
|
|
property LineThickness: Integer read GetLineThickness;
|
|
end;
|
|
|
|
TdxPSCustomCellBorder = class(TPersistent)
|
|
protected
|
|
class function Edge3DSoft: Boolean; virtual;
|
|
class function Edge3DStyle: TdxCellEdgeStyle; virtual;
|
|
class function EdgeMode: TdxCellEdgeMode; virtual;
|
|
|
|
class function GetBorderEdgeSalient(ASide: TdxCellSide; ASalient: TdxPSCellBorderSalientType): Integer; virtual;
|
|
class function GetPainterClass: TdxPSCellBorderPainterClass; virtual;
|
|
public
|
|
class procedure Register; virtual;
|
|
class procedure Unregister; virtual;
|
|
|
|
class function Solid: Boolean; virtual;
|
|
class function Thickness: Integer; virtual;
|
|
end;
|
|
|
|
TdxPSCellNullBorderPainter = class(TdxPSCellBorderPainter)
|
|
public
|
|
procedure Paint(DC: HDC); override;
|
|
end;
|
|
|
|
TdxPSCellNullBorder = class(TdxPSCustomCellBorder)
|
|
protected
|
|
class function GetPainterClass: TdxPSCellBorderPainterClass; override;
|
|
public
|
|
class function Thickness: Integer; override;
|
|
end;
|
|
|
|
TdxPSCellFlatBorder = class(TdxPSCustomCellBorder)
|
|
protected
|
|
class function GetPainterClass: TdxPSCellBorderPainterClass; override;
|
|
end;
|
|
|
|
TdxPSCellBoldFlatBorder = class(TdxPSCellFlatBorder)
|
|
public
|
|
class function Thickness: Integer; override;
|
|
end;
|
|
|
|
TdxPSCellUltraFlatBorder = class(TdxPSCellFlatBorder)
|
|
public
|
|
class function Thickness: Integer; override;
|
|
end;
|
|
|
|
TdxPSCell3DBorderClass = class of TdxPSCustomCell3DBorder;
|
|
|
|
TdxPSCell3DBorderPainter = class(TdxPSCellBorderPainter)
|
|
public
|
|
class procedure Draw3DFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush: HBRUSH;
|
|
ALineThickness: Integer); overload; virtual;
|
|
class procedure Draw3DFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
ACellBorders: TdxPSCell3DBorderClass; ALineThickness: Integer); overload; virtual;
|
|
procedure Paint(DC: HDC); override;
|
|
|
|
function BorderClass: TdxPSCell3DBorderClass; reintroduce; overload;
|
|
end;
|
|
|
|
TdxPSCustomCell3DBorder = class(TdxPSCustomCellBorder)
|
|
protected
|
|
class function EdgeMode: TdxCellEdgeMode; override;
|
|
|
|
class function GetBorderEdgeSalient(ASide: TdxCellSide; ASalient: TdxPSCellBorderSalientType): Integer; override;
|
|
class function GetPainterClass: TdxPSCellBorderPainterClass; override;
|
|
public
|
|
class function Solid: Boolean; override;
|
|
class function Thickness: Integer; override;
|
|
|
|
class function BottomRightInnerBrush: HBRUSH; virtual;
|
|
class function BottomRightInnerColor: TColor; virtual;
|
|
class function BottomRightOuterBrush: HBRUSH; virtual;
|
|
class function BottomRightOuterColor: TColor; virtual;
|
|
class function TopLeftInnerBrush: HBRUSH; virtual;
|
|
class function TopLeftInnerColor: TColor; virtual;
|
|
class function TopLeftOuterBrush: HBRUSH; virtual;
|
|
class function TopLeftOuterColor: TColor; virtual;
|
|
end;
|
|
|
|
TdxPSCellRaisedBorder = class(TdxPSCustomCell3DBorder)
|
|
protected
|
|
class function Edge3DSoft: Boolean; override;
|
|
class function Edge3DStyle: TdxCellEdgeStyle; override;
|
|
public
|
|
class function BottomRightInnerBrush: HBRUSH; override;
|
|
class function BottomRightInnerColor: TColor; override;
|
|
class function BottomRightOuterBrush: HBRUSH; override;
|
|
class function BottomRightOuterColor: TColor; override;
|
|
class function TopLeftInnerBrush: HBRUSH; override;
|
|
class function TopLeftInnerColor: TColor; override;
|
|
class function TopLeftOuterBrush: HBRUSH; override;
|
|
class function TopLeftOuterColor: TColor; override;
|
|
end;
|
|
|
|
TdxPSCellRaisedSoftBorder = class(TdxPSCellRaisedBorder)
|
|
protected
|
|
class function Edge3DSoft: Boolean; override;
|
|
public
|
|
class function BottomRightInnerBrush: HBRUSH; override;
|
|
class function BottomRightInnerColor: TColor; override;
|
|
end;
|
|
|
|
TdxPSCellSunkenBorder = class(TdxPSCustomCell3DBorder)
|
|
protected
|
|
class function Edge3DSoft: Boolean; override;
|
|
class function Edge3DStyle: TdxCellEdgeStyle; override;
|
|
public
|
|
class function BottomRightInnerBrush: HBRUSH; override;
|
|
class function BottomRightInnerColor: TColor; override;
|
|
class function BottomRightOuterBrush: HBRUSH; override;
|
|
class function BottomRightOuterColor: TColor; override;
|
|
class function TopLeftInnerBrush: HBRUSH; override;
|
|
class function TopLeftInnerColor: TColor; override;
|
|
class function TopLeftOuterBrush: HBRUSH; override;
|
|
class function TopLeftOuterColor: TColor; override;
|
|
end;
|
|
|
|
TdxPSCellSunkenSoftBorder = class(TdxPSCellSunkenBorder)
|
|
protected
|
|
class function Edge3DSoft: Boolean; override;
|
|
public
|
|
class function BottomRightInnerBrush: HBRUSH; override;
|
|
class function BottomRightInnerColor: TColor; override;
|
|
class function TopLeftInnerBrush: HBRUSH; override;
|
|
class function TopLeftInnerColor: TColor; override;
|
|
end;
|
|
|
|
TdxPSCellTwistedBorderPainter = class(TdxPSCell3DBorderPainter)
|
|
public
|
|
{$IFDEF BCB}
|
|
class procedure Draw3DFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
ACellBorders: TdxPSCell3DBorderClass; ALineThickness: Integer); override;
|
|
{$ENDIF}
|
|
class procedure Draw3DFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush: HBRUSH; ALineThickness: Integer); override;
|
|
end;
|
|
|
|
TdxPSCellTwistedBorder = class(TdxPSCustomCell3DBorder)
|
|
protected
|
|
class function GetPainterClass: TdxPSCellBorderPainterClass; override;
|
|
end;
|
|
|
|
TdxPSCellEtchedBorder = class(TdxPSCellTwistedBorder)
|
|
public
|
|
class function BottomRightInnerBrush: HBRUSH; override;
|
|
class function BottomRightInnerColor: TColor; override;
|
|
class function BottomRightOuterBrush: HBRUSH; override;
|
|
class function BottomRightOuterColor: TColor; override;
|
|
class function TopLeftInnerBrush: HBRUSH; override;
|
|
class function TopLeftInnerColor: TColor; override;
|
|
class function TopLeftOuterBrush: HBRUSH; override;
|
|
class function TopLeftOuterColor: TColor; override;
|
|
end;
|
|
|
|
TdxPSCellBumpedBorder = class(TdxPSCellTwistedBorder)
|
|
public
|
|
class function BottomRightInnerBrush: HBRUSH; override;
|
|
class function BottomRightInnerColor: TColor; override;
|
|
class function BottomRightOuterBrush: HBRUSH; override;
|
|
class function BottomRightOuterColor: TColor; override;
|
|
class function TopLeftInnerBrush: HBRUSH; override;
|
|
class function TopLeftInnerColor: TColor; override;
|
|
class function TopLeftOuterBrush: HBRUSH; override;
|
|
class function TopLeftOuterColor: TColor; override;
|
|
end;
|
|
|
|
TdxPSColorBorderPainter = class(TdxPSCellBorderPainter)
|
|
protected
|
|
function GetSideColor(ASide: TdxCellSide): TColor; virtual;
|
|
public
|
|
procedure Paint(DC: HDC); override;
|
|
property SideColor[ASide: TdxCellSide]: TColor read GetSideColor;
|
|
end;
|
|
|
|
TdxPSColorBorder = class(TdxPSCellUltraFlatBorder{TdxPSCustomCellBorder})
|
|
protected
|
|
class function GetPainterClass: TdxPSCellBorderPainterClass; override;
|
|
end;
|
|
|
|
TdxPSBackgroundBitmapPool = class
|
|
private
|
|
FItems: TList;
|
|
function GetCount: Integer;
|
|
function GetItem(Index: Integer): TBitmap;
|
|
protected
|
|
procedure ReadData(AReader: TdxPSDataReader);
|
|
procedure WriteData(AWriter: TdxPSDataWriter);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TdxPSBackgroundBitmapPool);
|
|
|
|
function Add(ABitmap: TBitmap): Integer;
|
|
procedure Clear;
|
|
procedure Delete(AnIndex: Integer);
|
|
function Find(ABitmap: TBitmap; out AnIndex: Integer): Boolean;
|
|
|
|
property Count: Integer read GetCount;
|
|
property Items[Index: Integer]: TBitmap read GetItem; default;
|
|
end;
|
|
|
|
TdxPSBrushPoolItem = class
|
|
private
|
|
FBrush: HBRUSH;
|
|
FColor: TColor;
|
|
function GetBrush: HBRUSH;
|
|
public
|
|
constructor Create(AColor: TColor);
|
|
destructor Destroy; override;
|
|
|
|
property Brush: HBRUSH read GetBrush;
|
|
property Color: TColor read FColor;
|
|
end;
|
|
|
|
TdxPSReportBrushPool = class
|
|
private
|
|
FItems: TList;
|
|
function GetBrush(AColor: TColor): HBRUSH;
|
|
function GetCount: Integer;
|
|
function GetItem(Index: Integer): TdxPSBrushPoolItem;
|
|
protected
|
|
function Add(AColor: TColor): Integer;
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
|
|
procedure Clear;
|
|
function IndexOf(AColor: TColor): Integer;
|
|
|
|
property Brushes[AColor: TColor]: HBRUSH read GetBrush; default;
|
|
property Count: Integer read GetCount;
|
|
property Items[Index: Integer]: TdxPSBrushPoolItem read GetItem;
|
|
end;
|
|
|
|
TdxPSReportRendererClass = class of TdxPSReportRenderer;
|
|
|
|
TdxPSFontPoolItem = class
|
|
private
|
|
FFont: TFont;
|
|
FOriginalSize: Integer;
|
|
procedure SetFont(Value: TFont);
|
|
public
|
|
constructor Create(AFont: TFont);
|
|
destructor Destroy; override;
|
|
|
|
property Font: TFont read FFont write SetFont;
|
|
property OriginalSize: Integer read FOriginalSize write FOriginalSize;
|
|
end;
|
|
|
|
TdxPSReportFontPool = class
|
|
private
|
|
FItems: TList;
|
|
function GetCount: Integer;
|
|
function GetFont(Index: Integer): TFont;
|
|
function GetItem(Index: Integer): TdxPSFontPoolItem;
|
|
protected
|
|
FLocked: Boolean;
|
|
function CreateFont(AFont: TFont): Integer;
|
|
procedure FontChanged(Sender: TObject);
|
|
procedure PrepareFonts(UPI: Integer);
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader);
|
|
procedure WriteData(AWriter: TdxPSDataWriter);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
|
|
function Add(AFont: TFont): Integer;
|
|
procedure Clear;
|
|
function IndexOf(AFont: TFont): Integer;
|
|
|
|
property Count: Integer read GetCount;
|
|
property Fonts[Index: Integer]: TFont read GetFont; default;
|
|
property Items[Index: Integer]: TdxPSFontPoolItem read GetItem;
|
|
end;
|
|
|
|
TdxPSCachedGraphicInfo = class
|
|
protected
|
|
Renderer: TdxPSReportRenderer;
|
|
SourceGraphic, PreparedGraphic: TGraphic;
|
|
UnitsPerInch: Integer;
|
|
UnitsPerPixel: Integer;
|
|
ViewPortRect: TRect;
|
|
ZoomFactor: Integer;
|
|
procedure SaveModeInfo;
|
|
public
|
|
constructor Create(ARenderer: TdxPSReportRenderer); virtual;
|
|
function Check(ASourceGraphic: TGraphic; ABitmap: TBitmap; var APreparedGraphic: TGraphic): Boolean;
|
|
end;
|
|
|
|
TdxPSRenderStage = (rsFirstPass, rsSecondPass);
|
|
TdxPSRenderStages = set of TdxPSRenderStage;
|
|
|
|
TdxPSReportRenderer = class
|
|
private
|
|
FBorderColor: TColor;
|
|
FBorderPainters: TList;
|
|
FBrushPool: TdxPSReportBrushPool;
|
|
FCachedGraphicInfo: TdxPSCachedGraphicInfo;
|
|
FCanvas: TCanvas;
|
|
FCheckBitmap: TBitmap;
|
|
FDC: HDC;
|
|
FDrawBitmap: TBitmap;
|
|
FDrawMask: TBitmap;
|
|
FGroupLookAndFeelPainters: TList;
|
|
FHFStrings: TStrings;
|
|
FIsRendering: Boolean;
|
|
FLineThickness: Integer;
|
|
FMarlettFont10: TFont;
|
|
FMarlettFont8: TFont;
|
|
FPPI: Integer;
|
|
FPrevMode: Integer;
|
|
FPrevWindowExt: TSize;
|
|
FPrevWindowOrg: TPoint;
|
|
FPrevViewPortExt: TSize;
|
|
FPrevViewPortOrg: TPoint;
|
|
FRenderingPageIndex: Integer; // virtual index
|
|
FRenderStage: TdxPSRenderStages;
|
|
FReportLink: TBasedxReportLink;
|
|
FSaveColor: TColor;
|
|
FSaveFont: TFont;
|
|
FSavePixelsPerInch: Integer;
|
|
FSymbolFont: TFont;
|
|
FUnitsPerPixel: Integer;
|
|
FViewPortRect: TRect;
|
|
FZoomFactor: Integer;
|
|
function GetBorderPainterItem(Index: Integer): TdxPSCellBorderPainter;
|
|
function GetBorderPainterCount: Integer;
|
|
function GetGroupLookAndFeelPainter(Index: Integer): TdxPSReportGroupLookAndFeelPainter;
|
|
function GetGroupLookAndFeelPainterCount: Integer;
|
|
function GetHalfLineThickness: Integer;
|
|
function GetIsPrinting: Boolean;
|
|
function GetPageRenderInfo: TdxPSPageRenderInfo;
|
|
function GetRenderInfo: TdxPSReportRenderInfo;
|
|
function GetReportCells: TdxReportCells;
|
|
protected
|
|
function CustomDrawReportItem(AnItem: TAbstractdxReportCellData): Boolean;
|
|
procedure Get3DBorderBrushes(AnItem: TdxReportVisualItem; var AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush: HBRUSH);
|
|
procedure Get3DBorderColors(AnItem: TdxReportVisualItem; var AOuterTLColor, AOuterBRColor, AInnerTLColor, AInnerBRColor: TColor);
|
|
|
|
function GetUnitsPerInch: Integer; virtual;
|
|
|
|
function CreateBorderPainter(AClass: TdxPSCellBorderPainterClass): TdxPSCellBorderPainter;
|
|
function FindBorderPainter(AClass: TdxPSCellBorderPainterClass): TdxPSCellBorderPainter;
|
|
procedure FreeAndNilBorderPainters;
|
|
|
|
function CreateReportGroupLookAndFeelPainter(AClass: TdxPSReportGroupLookAndFeelPainterClass): TdxPSReportGroupLookAndFeelPainter;
|
|
function FindReportGroupLookAndFeelPainter(AClass: TdxPSReportGroupLookAndFeelPainterClass): TdxPSReportGroupLookAndFeelPainter;
|
|
procedure FreeAndNilReportGroupLookAndFeelPainters;
|
|
|
|
procedure PrepareCanvasForCustomDraw(AFont: TFont; AColor: TColor);
|
|
procedure PrepareFonts;
|
|
procedure PrepareGDIObjects; virtual;
|
|
procedure PrepareLogicalCoordinates; virtual;
|
|
procedure PrepareLogicalUnits; virtual;
|
|
function PreparedPageIndex(APageIndex: Integer): Integer;
|
|
procedure PrepareRenderPage; virtual;
|
|
procedure PrepareWindow; virtual;
|
|
procedure PrepareViewPort; virtual;
|
|
procedure RenderCell(ACell: TdxReportCell; const OriginRect: TRect);
|
|
procedure RenderDelimiters;
|
|
procedure RenderEntirePage(ARealPageIndex: Integer); virtual;
|
|
procedure RenderPageContent; virtual;
|
|
procedure RenderPageContentPart(ACell: TdxReportCell;StartIndex, EndIndex: Integer; const OriginRect: TRect);
|
|
procedure RenderPageOverlay(AnOverlayIndex: Integer; AnOverlay: TdxPageOverlayIndexes; const OriginRect: TRect); virtual;
|
|
procedure RenderPageBackground(ARealPageIndex: Integer); virtual;
|
|
procedure RenderPageFooter(ARealPageIndex: Integer); virtual;
|
|
procedure RenderPageHeader(ARealPageIndex: Integer); virtual;
|
|
procedure RenderPageHeaderOrFooter(HF: TCustomdxPageObject; APageIndex: Integer; ARect: TRect); virtual;
|
|
procedure RenderPageHeaderOrFooterContent(HF: TCustomdxPageObject; APageIndex: Integer; ARect: TRect;
|
|
ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean); virtual;
|
|
procedure RenderPageHeaderOrFooterContentPart(ATitlePart: TdxPageTitlePart; AStrings: TStrings;
|
|
ATextAlignY: TdxTextAlignY; ALineHeight, ADestWidth, ADestHeight: Integer; const ARect: TRect);
|
|
procedure RenderPageTitleContent(const AText: string; ARect: TRect; ATextAlignX: TdxTextAlignX;
|
|
ATextAlignY: TdxTextAlignY; AColor: TColor; AFont: TFont; ATransparent: Boolean); virtual;
|
|
procedure RenderPageTitle; virtual;
|
|
procedure RestoreMapMode; virtual;
|
|
procedure SaveMapMode; virtual;
|
|
procedure UnprepareCanvasForCustomDraw;
|
|
procedure UnprepareGDIObjects; virtual;
|
|
procedure UnprepareLogicalUnits; virtual;
|
|
procedure UnprepareRenderPage; virtual;
|
|
|
|
property BorderPainterCount: Integer read GetBorderPainterCount;
|
|
property BorderPainters[Index: Integer]: TdxPSCellBorderPainter read GetBorderPainterItem;
|
|
property BrushPool: TdxPSReportBrushPool read FBrushPool;
|
|
property CachedGraphicInfo: TdxPSCachedGraphicInfo read FCachedGraphicInfo;
|
|
property GroupLookAndFeelPainterCount: Integer read GetGroupLookAndFeelPainterCount;
|
|
property GroupLookAndFeelPainters[Index: Integer]: TdxPSReportGroupLookAndFeelPainter read GetGroupLookAndFeelPainter;
|
|
public
|
|
constructor Create(AReportLink: TBasedxReportLink); virtual;
|
|
destructor Destroy; override;
|
|
|
|
function CalcTextHeight(DC: HDC; const AText: string; AWordBreak: Boolean;
|
|
AFont: TFont = nil; ABaseWidth: Integer = -1): Integer;
|
|
function CalcTextLineCount(DC: HDC; const AText: string; AFont: TFont = nil;
|
|
ABaseWidth: Integer = -1): Integer;
|
|
function CalcTextPatternHeight(DC: HDC; AFont: TFont = nil): Integer;
|
|
function CalcTextRect(DC: HDC; const AText: string; var ARect: TRect;
|
|
AWordBreak: Boolean; AFont: TFont = nil): Integer; overload;
|
|
function CalcTextRect(DC: HDC; const AText: string; var ARect: TRect;
|
|
AFormat: DWORD; AFont: TFont = nil): Integer; overload;
|
|
function CalcTextWidth(DC: HDC; const AText: string; AFont: TFont = nil): Integer;
|
|
|
|
procedure DrawCheckBox(DC: HDC; var R: TRect; AChecked, AEnabled, AIsRadio: Boolean;
|
|
AEdgeStyle: TdxCheckButtonEdgeStyle; ABorderColor: TColor = clWindowText); virtual;
|
|
procedure DrawEdge(DC: HDC; var R: TRect; AEdgeMode: TdxCellEdgeMode;
|
|
AEdge3DEdge: TdxCellEdgeStyle; ASides: TdxCellSides; ASoft: Boolean;
|
|
ABorderColor: TColor = -1); virtual;
|
|
procedure DrawEllipse(DC: HDC; R: TRect; AForeColor, ABackColor: TColor;
|
|
APattern: TdxPSFillPatternClass; ABorderColor: TColor;
|
|
ABorderThickness: Integer = 1); virtual;
|
|
procedure DrawExpandButton(DC: HDC; var R: TRect;
|
|
AExpanded, ADrawBorder, AEdge3D, AEdge3DSoft, AShadow, AFillInterior: Boolean;
|
|
ABorderColor, AInteriorColor: TColor); virtual;
|
|
procedure DrawGlyph(DC: HDC; const R: TRect; AGlyph: Byte); // Draw indvidual glyph from Font (used to render SortMark, ExpandButton, CheckBox Glyphs and so on)
|
|
procedure DrawGraphic(DC: HDC; var R: TRect; const AClipRect: TRect;
|
|
AImageList: TCustomImageList; AImageIndex: Integer; AGraphic: TGraphic;
|
|
AGraphicTransparent, ATransparent: Boolean; AColor: TColor); virtual;
|
|
procedure DrawGraphicEx(DC: HDC; R: TRect; const AClipRect: TRect;
|
|
AImageList: TCustomImageList; AImageIndex: Integer; AGraphic: TGraphic;
|
|
AGraphicTransparent, ATransparent: Boolean; AColor, ABkColor: TColor;
|
|
APattern: TdxPSFillPatternClass; AnActualImageBuffering: TdxCellImageActualBuffering = cibAlways); virtual;
|
|
procedure DrawRectangle(DC: HDC; R: TRect; AForeColor, ABackColor: TColor;
|
|
AContentPattern: TdxPSFillPatternClass; ABorderColor: TColor;
|
|
ABorderThickness: Integer = 1); virtual;
|
|
procedure DrawRoundRect(DC: HDC; R: TRect; AnEllipseWidth, AnEllipseHeight: Integer;
|
|
AForeColor, ABackColor: TColor; AContentPattern: TdxPSFillPatternClass;
|
|
ABorderColor: TColor; ABorderThickness: Integer = 1); virtual;
|
|
procedure DrawSortMark(DC: HDC; var R: TRect; ASortOrder: TdxCellSortOrder; AMono: Boolean); virtual;
|
|
procedure DrawText(DC: HDC; var R: TRect; AMaxLineCount: Integer;
|
|
ALeftIndent, ARightIndent: Integer; const AText: string; AFont: TFont;
|
|
ABkColor: TColor; ATextAlignX: TdxTextAlignX; ATextAlignY: TdxTextAlignY;
|
|
AFillBackground, AMultiline, AEndEllipsis: Boolean; APreventLeftTextExceed: Boolean = True;
|
|
APreventTopTextExceed: Boolean = True; AHidePrefix: Boolean = True);
|
|
procedure DrawTextEx(DC: HDC; var R: TRect; AMaxLineCount: Integer;
|
|
ALeftIndent, ARightIndent: Integer; const AText: string; AFont: TFont; AFormat: DWORD);
|
|
function MakeTextFormat(ATextAlignX: TdxTextAlignX; ATextAlignY: TdxTextAlignY;
|
|
AMultiline, AEndEllipsis, APreventLeftTextExceed, APreventTopTextExceed, AHidePrefix: Boolean): DWORD;
|
|
procedure FillEllipse(DC: HDC; const R: TRect; AColor: TColor); virtual;
|
|
procedure FillEllipseEx(DC: HDC; const R: TRect; AForeColor, ABackColor: TColor; APattern: TdxPSFillPatternClass); virtual;
|
|
procedure FillRect(DC: HDC; const R: TRect; AColor: TColor); virtual;
|
|
procedure FillRectEx(DC: HDC; const R: TRect; AForeColor, ABackColor: TColor; APattern: TdxPSFillPatternClass); virtual;
|
|
procedure FillRoundRect(DC: HDC; const R: TRect;
|
|
AnEllipseWidth, AnEllipseHeight: Integer; AColor: TColor); virtual;
|
|
procedure FillRoundRectEx(DC: HDC; const R: TRect; AnEllipseWidth, AnEllipseHeight: Integer;
|
|
AForeColor, ABackColor: TColor; APattern: TdxPSFillPatternClass); virtual;
|
|
procedure FillRgn(DC: HDC; Rgn: HRGN; AColor: TColor); virtual;
|
|
procedure FillRgnEx(DC: HDC; Rgn: HRGN; AForeColor, ABackColor: TColor; APattern: TdxPSFillPatternClass); virtual;
|
|
procedure FrameEllipse(DC: HDC; R: TRect; AColor: TColor; AThickness: Integer = 1);
|
|
procedure FrameRect(DC: HDC; R: TRect; AColor: TColor; ASides: TdxCellSides = [csLeft..csBottom];
|
|
AThickness: Integer = 1); virtual;
|
|
procedure FrameRoundRect(DC: HDC; R: TRect; AnEllipseWidth, AnEllipseHeight: Integer;
|
|
AColor: TColor; AThickness: Integer = 1); virtual;
|
|
|
|
function GetBorderPainter(AClass: TdxPSCellBorderPainterClass): TdxPSCellBorderPainter;
|
|
function GetBrushByColor(AColor: TColor): HBRUSH;
|
|
function GetPatternBrush(APattern: TdxPSFillPatternClass; AColor: TColor): HBRUSH;
|
|
function GetReportGroupLookAndFeelPainter(AClass: TdxPSReportGroupLookAndFeelPainterClass): TdxPSReportGroupLookAndFeelPainter;
|
|
|
|
function ExcludeClipRect(const R: TRect): Integer;
|
|
function GetClipRgn: HRGN;
|
|
function IntersectClipRect(const R: TRect): HRGN;
|
|
procedure RestoreClipRgn(var Rgn: HRGN);
|
|
|
|
procedure RenderPage(ACanvas: TCanvas; const APageBounds: TRect;
|
|
APageIndex, AContinuousPageIndex, AZoomFactor: Integer); virtual;
|
|
|
|
property BorderColor: TColor read FBorderColor;
|
|
property Canvas: TCanvas read FCanvas write FCanvas;
|
|
property DC: HDC read FDC write FDC;
|
|
property HalfLineThickness: Integer read GetHalfLineThickness;
|
|
property IsPrinting: Boolean read GetIsPrinting;
|
|
property IsRendering: Boolean read FIsRendering;
|
|
property LineThickness: Integer read FLineThickness write FLineThickness;
|
|
property MarlettFont10: TFont read FMarlettFont10;
|
|
property MarlettFont8: TFont read FMarlettFont8;
|
|
property PageRenderInfo: TdxPSPageRenderInfo read GetPageRenderInfo;
|
|
property PPI: Integer read FPPI write FPPI; // PixelsPerInch for current DC
|
|
property RenderInfo: TdxPSReportRenderInfo read GetRenderInfo;
|
|
property RenderingPageIndex: Integer read FRenderingPageIndex; // virtual
|
|
property RenderStage: TdxPSRenderStages read FRenderStage;
|
|
property ReportCells: TdxReportCells read GetReportCells;
|
|
property ReportLink: TBasedxReportLink read FReportLink;
|
|
property SymbolFont: TFont read FSymbolFont;
|
|
property UnitsPerInch: Integer read GetUnitsPerInch;
|
|
property UnitsPerPixel: Integer read FUnitsPerPixel write FUnitsPerPixel;
|
|
property ViewPortRect: TRect read FViewPortRect;
|
|
property ZoomFactor: Integer read FZoomFactor;
|
|
end;
|
|
|
|
{ Report Items }
|
|
|
|
TdxReportItemClass = class of TdxReportItem;
|
|
|
|
TdxReportItem = class(TPersistent)
|
|
private
|
|
FData: Integer;
|
|
FParent: TdxReportCell;
|
|
function GetIndex: Integer;
|
|
function GetReportCells: TdxReportCells; virtual;
|
|
procedure SetIndex(Value: Integer);
|
|
procedure SetParent(Value: TdxReportCell);
|
|
protected
|
|
function AsCell: TdxReportCell;
|
|
function GetTopLevelParent: TdxReportCell;
|
|
class function IsCell: Boolean; virtual;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
class function Serializable: Boolean; virtual;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); virtual;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
class function ReportItemClass: TdxReportItemClass;
|
|
|
|
class procedure Register; virtual;
|
|
class procedure Unregister; virtual;
|
|
|
|
function Clone(AParent: TdxReportCell): TdxReportItem;
|
|
function GetNextSibling: TdxReportItem;
|
|
function GetPrevSibling: TdxReportItem;
|
|
function HasParent: Boolean;
|
|
function IsFirstItem: Boolean;
|
|
function IsLastItem: Boolean;
|
|
|
|
property Data: Integer read FData write FData;
|
|
property Index: Integer read GetIndex write SetIndex;
|
|
property Parent: TdxReportCell read FParent write SetParent;
|
|
property ReportCells: TdxReportCells read GetReportCells;
|
|
property TopLevelParent: TdxReportCell read GetTopLevelParent;
|
|
end;
|
|
|
|
TdxReportVisualItem = class(TdxReportItem)
|
|
private
|
|
FBackgroundBitmapIndex: Integer;
|
|
FBorderClass: TdxPSCellBorderClass;
|
|
FBorderColor: TColor;
|
|
FBoundsRect: TRect;
|
|
FCellSideColors: array[TdxCellSide] of TColor;
|
|
FColor: TColor;
|
|
FFontIndex: Integer;
|
|
FFormat: DWORD;
|
|
function GetAbsoluteOrigin: TPoint;
|
|
function GetAbsoluteRect: TRect;
|
|
function GetBackgroundBitmap: TBitmap;
|
|
function GetBackgroundBitmapHeight: Integer;
|
|
function GetBackgroundBitmapPool: TdxPSBackgroundBitmapPool;
|
|
function GetBackgroundBitmapTileOrigin: TPoint;
|
|
function GetBackgroundBitmapTileStartIndexX: Integer;
|
|
function GetBackgroundBitmapTileStartIndexY: Integer;
|
|
function GetBackgroundBitmapTileStopIndexX: Integer;
|
|
function GetBackgroundBitmapTileStopIndexY: Integer;
|
|
function GetBackgroundBitmapWidth: Integer;
|
|
function GetBorderBrush: HBRUSH;
|
|
function GetBorderColor: TColor;
|
|
function GetCellSides: TdxCellSides;
|
|
function GetCellSideColors(ASide: TdxCellSide): TColor;
|
|
function GetContentBrush: HBRUSH;
|
|
function GetEdge3DSoft: Boolean;
|
|
function GetEdge3DStyle: TdxCellEdgeStyle;
|
|
function GetEdgeMode: TdxCellEdgeMode;
|
|
function GetExcludeFromClipRgn: Boolean;
|
|
function GetFont: TFont;
|
|
function GetHeight: Integer;
|
|
function GetIsPrinting: Boolean;
|
|
function GetLeft: Integer;
|
|
function GetLineThickness: Integer;
|
|
function GetOrigin: TPoint;
|
|
function GetParentBrush: HBRUSH;
|
|
function GetParentColor: TColor;
|
|
function GetRenderer: TdxPSReportRenderer;
|
|
function GetShadowBrush: HBRUSH;
|
|
function GetShowShadow: Boolean;
|
|
function GetTop: Integer;
|
|
function GetTransparent: Boolean;
|
|
function GetWidth: Integer;
|
|
function GetVisible: Boolean;
|
|
procedure SetBackgroundBitmapIndex(Value: Integer);
|
|
procedure SetBorderClass(Value: TdxPSCellBorderClass);
|
|
procedure SetBoundsRect(const Value: TRect);
|
|
procedure SetCellSides(Value: TdxCellSides);
|
|
procedure SetCellSideColors(ASide: TdxCellSide; AValue: TColor);
|
|
procedure SetColor(Value: TColor);
|
|
procedure SetEdge3DSoft(Value: Boolean);
|
|
procedure SetEdge3DStyle(Value: TdxCellEdgeStyle);
|
|
procedure SetEdgeMode(Value: TdxCellEdgeMode);
|
|
procedure SetExcludeFromClipRgn(Value: Boolean);
|
|
procedure SetFont(Value: TFont);
|
|
procedure SetFormat(Value: DWORD);
|
|
procedure SetHeight(Value: Integer);
|
|
procedure SetLeft(Value: Integer);
|
|
procedure SetOrigin(const Value: TPoint);
|
|
procedure SetShowShadow(Value: Boolean);
|
|
procedure SetTop(Value: Integer);
|
|
procedure SetTransparent(Value: Boolean);
|
|
procedure SetWidth(Value: Integer);
|
|
procedure SetVisible(Value: Boolean);
|
|
protected
|
|
procedure BoundsChanged; virtual;
|
|
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); virtual;
|
|
procedure DoExcludeFromClipRgn(DC: HDC; const R: TRect; var AResult: Integer);
|
|
|
|
function GetBackgroundBitmapTileBounds(Col, Row: Integer): TRect; virtual;
|
|
function GetBackgroundBounds(DC: HDC): TRect; virtual;
|
|
function GetBorderClass: TdxPSCellBorderClass; virtual;
|
|
function GetBorderEdgeBounds(ASide: TdxCellSide; const AOuterRect: TRect): TRect; virtual;
|
|
function GetBorderEdgeClass(ASide: TdxCellSide): TdxPSCellBorderClass; virtual;
|
|
function GetBorderEdgeSalient(ASide: TdxCellSide; ASalient: TdxPSCellBorderSalientType): Integer; virtual;
|
|
function GetBorderEdgeThickness(ASide: TdxCellSide): Integer; virtual;
|
|
function GetBorderBounds(DC: HDC): TRect; virtual;
|
|
|
|
function GetBorderOuterBoundsRelativeTo(DC: HDC; const R: TRect): TRect;
|
|
function GetInnerBoundsRelativeTo(DC: HDC; const R: TRect): TRect;
|
|
function GetOuterBoundsRelativeTo(DC: HDC; const R: TRect): TRect;
|
|
|
|
function GetBorderPainter: TdxPSCellBorderPainter;
|
|
function GetBorderPainterClass: TdxPSCellBorderPainterClass; virtual;
|
|
procedure InitBorderPainter(ABorderPainter: TdxPSCellBorderPainter); virtual;
|
|
function HasBorderColoration: Boolean; virtual;
|
|
|
|
function GetFormatBit(ABit: DWORD): Boolean;
|
|
procedure SetFormatBit(ABit: DWORD; Value: Boolean);
|
|
|
|
function GetContentBkColor: TColor; virtual;
|
|
function GetContentPattern: TdxPSFillPatternClass; virtual;
|
|
function GetShadowColor: TColor; virtual;
|
|
function GetShadowDepth: Integer; virtual;
|
|
procedure SetContentBkColor(Value: TColor); virtual;
|
|
procedure SetContentPattern(Value: TdxPSFillPatternClass); virtual;
|
|
procedure SetFontIndex(Value: Integer); virtual;
|
|
procedure SetShadowColor(Value: TColor); virtual;
|
|
procedure SetShadowDepth(Value: Integer); virtual;
|
|
|
|
function IsBackgroundBitmapDrawn: Boolean; virtual;
|
|
function IsBackgroundDrawn: Boolean; virtual;
|
|
function IsBordersDrawn: Boolean; virtual;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
property BackgroundBitmapHeight: Integer read GetBackgroundBitmapHeight;
|
|
property BackgroundBitmapTileBounds[Col, Row: Integer]: TRect read GetBackgroundBitmapTileBounds;
|
|
property BackgroundBitmapTileOrigin: TPoint read GetBackgroundBitmapTileOrigin;
|
|
property BackgroundBitmapTileStartIndexX: Integer read GetBackgroundBitmapTileStartIndexX;
|
|
property BackgroundBitmapTileStartIndexY: Integer read GetBackgroundBitmapTileStartIndexY;
|
|
property BackgroundBitmapTileStopIndexX: Integer read GetBackgroundBitmapTileStopIndexX;
|
|
property BackgroundBitmapTileStopIndexY: Integer read GetBackgroundBitmapTileStopIndexY;
|
|
property BackgroundBitmapWidth: Integer read GetBackgroundBitmapWidth;
|
|
|
|
property Format: DWORD read FFormat write SetFormat;
|
|
property IsPrinting: Boolean read GetIsPrinting;
|
|
property LineThickness: Integer read GetLineThickness;
|
|
property Renderer: TdxPSReportRenderer read GetRenderer;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure AdjustContent(DC: HDC); virtual;
|
|
|
|
procedure DrawBackground(DC: HDC); virtual;
|
|
procedure DrawBackgroundBitmap(DC: HDC); virtual;
|
|
procedure DrawBackgroundBitmapTile(DC: HDC; const Rect: TRect); virtual;
|
|
procedure DrawBackgroundRect(DC: HDC; const R: TRect);
|
|
procedure DrawBorders(DC: HDC); virtual;
|
|
|
|
function GetBorderOuterBounds(DC: HDC): TRect; virtual;
|
|
function GetInnerBounds(DC: HDC): TRect; virtual;
|
|
function GetOuterBounds(DC: HDC): TRect; virtual;
|
|
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); virtual;
|
|
|
|
function CalculateLineCount(DC: HDC): Integer; virtual;
|
|
|
|
function MeasureBordersHeight(DC: HDC): Integer; virtual;
|
|
function MeasureBordersWidth(DC: HDC): Integer; virtual;
|
|
function MeasureContentHeight(DC: HDC): Integer; virtual;
|
|
function MeasureContentWidth(DC: HDC): Integer; virtual;
|
|
function MeasureFontHeight(DC: HDC): Integer; virtual;
|
|
function MeasureHeight(DC: HDC): Integer; virtual;
|
|
function MeasureWidth(DC: HDC): Integer; virtual;
|
|
|
|
// for backward compatibility
|
|
class function MapBorderClass(AEdgeMode: TdxCellEdgeMode; AEdgeStyle: TdxCellEdgeStyle; ASoft: Boolean): TdxPSCellBorderClass;
|
|
|
|
property AbsoluteOrigin: TPoint read GetAbsoluteOrigin;
|
|
property AbsoluteRect: TRect read GetAbsoluteRect;
|
|
property BackgroundBitmap: TBitmap read GetBackgroundBitmap;
|
|
property BackgroundBitmapIndex: Integer read FBackgroundBitmapIndex write SetBackgroundBitmapIndex;
|
|
property BackgroundBitmapPool: TdxPSBackgroundBitmapPool read GetBackgroundBitmapPool;
|
|
property BorderBrush: HBRUSH read GetBorderBrush;
|
|
property BorderClass: TdxPSCellBorderClass read GetBorderClass write SetBorderClass;
|
|
property BorderColor: TColor read GetBorderColor write FBorderColor; // clDefault;
|
|
property BorderEdgeClasses[Side: TdxCellSide]: TdxPSCellBorderClass read GetBorderEdgeClass;
|
|
property BorderEdgeSalients[Side: TdxCellSide; Salient: TdxPSCellBorderSalientType]: Integer read GetBorderEdgeSalient;
|
|
property BorderEdgeThicknesses[Side: TdxCellSide]: Integer read GetBorderEdgeThickness;
|
|
property BorderPainter: TdxPSCellBorderPainter read GetBorderPainter;
|
|
property BorderPainterClass: TdxPSCellBorderPainterClass read GetBorderPainterClass;
|
|
property BoundsRect: TRect read FBoundsRect write SetBoundsRect;
|
|
property CellSides: TdxCellSides read GetCellSides write SetCellSides; {csAll}
|
|
property CellSideColors[ASide: TdxCellSide]: TColor read GetCellSideColors write SetCellSideColors;
|
|
property Color: TColor read FColor write SetColor;
|
|
property ContentBkColor: TColor read GetContentBkColor write SetContentBkColor;
|
|
property ContentBrush: HBRUSH read GetContentBrush;
|
|
property ContentPattern: TdxPSFillPatternClass read GetContentPattern write SetContentPattern;
|
|
property Edge3DSoft: Boolean read GetEdge3DSoft write SetEdge3DSoft; // obsolete - use BorderClass instead
|
|
property Edge3DStyle: TdxCellEdgeStyle read GetEdge3DStyle write SetEdge3DStyle; // obsolete - use BorderClass instead
|
|
property EdgeMode: TdxCellEdgeMode read GetEdgeMode write SetEdgeMode; // obsolete - use BorderClass instead
|
|
property ExcludeFromClipRgn: Boolean read GetExcludeFromClipRgn write SetExcludeFromClipRgn;
|
|
property Font: TFont read GetFont write SetFont;
|
|
property FontIndex: Integer read FFontIndex write SetFontIndex;
|
|
property Height: Integer read GetHeight write SetHeight;
|
|
property Left: Integer read GetLeft write SetLeft;
|
|
property Origin: TPoint read GetOrigin write SetOrigin;
|
|
property ParentBrush: HBRUSH read GetParentBrush;
|
|
property ParentColor: TColor read GetParentColor;
|
|
property ShadowBrush: HBRUSH read GetShadowBrush;
|
|
property ShadowColor: TColor read GetShadowColor write SetShadowColor;
|
|
property ShadowDepth: Integer read GetShadowDepth write SetShadowDepth;
|
|
property ShowShadow: Boolean read GetShowShadow write SetShowShadow;
|
|
property Top: Integer read GetTop write SetTop;
|
|
property Transparent: Boolean read GetTransparent write SetTransparent;
|
|
property Width: Integer read GetWidth write SetWidth;
|
|
property Visible: Boolean read GetVisible write SetVisible;
|
|
end;
|
|
|
|
TdxReportCell = class(TdxReportVisualItem)
|
|
private
|
|
FCellList: TList;
|
|
FDataList: TList;
|
|
FReportCells: TdxReportCells;
|
|
function GetAbsoluteIndex: Integer;
|
|
function GetCellCount: Integer;
|
|
function GetCell(Index: Integer): TdxReportCell;
|
|
function GetClipChildren: Boolean;
|
|
function GetDataItemCount: Integer;
|
|
function GetDataItem(Index: Integer): TAbstractdxReportCellData;
|
|
function GetIsTopLevel: Boolean;
|
|
function GetLevel: Integer;
|
|
function GetReportCells: TdxReportCells; override;
|
|
procedure CellListNeeded;
|
|
procedure CellListRelease;
|
|
procedure DataListNeeded;
|
|
procedure DataListRelease;
|
|
procedure InsertCell(AnItem: TdxReportCell);
|
|
procedure InsertDataItem(AnItem: TdxReportItem);
|
|
procedure InsertItem(AnItem: TdxReportItem);
|
|
procedure MoveCell(ACurIndex, ANewIndex: Integer);
|
|
procedure MoveDataItem(ACurIndex, ANewIndex: Integer);
|
|
procedure MoveItem(AnItem: TdxReportItem; ACurIndex, ANewIndex: Integer);
|
|
procedure RemoveCell(AnItem: TdxReportCell);
|
|
procedure RemoveDataItem(AnItem: TdxReportItem);
|
|
procedure RemoveItem(AnItem: TdxReportItem);
|
|
procedure SetClipChildren(Value: Boolean);
|
|
protected
|
|
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); override;
|
|
function GetBackgroundBitmapTileBounds(Col, Row: Integer): TRect; override;
|
|
function GetBackgroundBounds(DC: HDC): TRect; override;
|
|
function GetBorderBounds(DC: HDC): TRect; override;
|
|
class function IsCell: Boolean; override;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
procedure ReadCells(AReader: TdxPSDataReader); virtual;
|
|
procedure ReadDataItems(AReader: TdxPSDataReader); virtual;
|
|
procedure ReadProperties(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteCells(AWriter: TdxPSDataWriter); virtual;
|
|
procedure WriteDataItems(AWriter: TdxPSDataWriter); virtual;
|
|
procedure WriteProperties(AWriter: TdxPSDataWriter); virtual;
|
|
public
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure DrawContent(DC: HDC; DrawRect: TRect; const OriginRect: TRect; AStage: TdxPSRenderStages); virtual;
|
|
procedure DrawItself(DC: HDC; AStage: TdxPSRenderStages); virtual;
|
|
procedure DrawNestedCells(DC: HDC; DrawRect: TRect; const OriginRect: TRect; AStage: TdxPSRenderStages); virtual;
|
|
procedure DrawNestedDataItems(DC: HDC; const OriginRect: TRect; AStage: TdxPSRenderStages); virtual;
|
|
function ExcludeNestedItems(DC: HDC; const OriginRect: TRect): Integer; virtual;
|
|
|
|
function GetBorderOuterBounds(DC: HDC): TRect; override;
|
|
function GetInnerBounds(DC: HDC): TRect; override;
|
|
function GetOuterBounds(DC: HDC): TRect; override;
|
|
|
|
function MeasureHeight(DC: HDC): Integer; override;
|
|
function MeasureWidth(DC: HDC): Integer; override;
|
|
|
|
function AddCell: TdxReportCell;
|
|
function AddDataItem(AClass: TdxReportCellDataClass): TAbstractdxReportCellData;
|
|
procedure AllocateSpaceForCells(ACapacity: Integer);
|
|
procedure AllocateSpaceForDatas(ACapacity: Integer);
|
|
procedure ClearAll;
|
|
procedure ClearCells;
|
|
procedure ClearDataItems;
|
|
procedure DeleteCell(Index: Integer);
|
|
procedure DeleteDataItem(Index: Integer);
|
|
function FirstCell: TdxReportCell;
|
|
function HasChildren: Boolean;
|
|
function IndexOf(AnItem: TdxReportItem): Integer;
|
|
function LastCell: TdxReportCell;
|
|
|
|
property AbsoluteIndex: Integer read GetAbsoluteIndex;
|
|
property CellCount: Integer read GetCellCount;
|
|
property Cells[Index: Integer]: TdxReportCell read GetCell; default;
|
|
property ClipChildren: Boolean read GetClipChildren write SetClipChildren;
|
|
property DataItemCount: Integer read GetDataItemCount;
|
|
property DataItems[Index: Integer]: TAbstractdxReportCellData read GetDataItem;
|
|
property IsTopLevel: Boolean read GetIsTopLevel;
|
|
property Level: Integer read GetLevel;
|
|
end;
|
|
|
|
TdxReportGroup = class;
|
|
|
|
TdxPSReportGroupLookAndFeelPainter = class
|
|
private
|
|
FGroup: TdxReportGroup;
|
|
FLookAndFeel: TdxPSReportGroupLookAndFeel;
|
|
FRenderer: TdxPSReportRenderer;
|
|
protected
|
|
procedure DrawBorders(DC: HDC); virtual;
|
|
procedure DrawCaptionText(DC: HDC); virtual;
|
|
procedure Initialize(ALookAndFeel: TdxPSReportGroupLookAndFeel; AGroup: TdxReportGroup); virtual;
|
|
|
|
function Group: TdxReportGroup; overload; virtual;
|
|
function LookAndFeel: TdxPSReportGroupLookAndFeel; overload; virtual;
|
|
public
|
|
constructor Create(ARenderer: TdxPSReportRenderer); virtual;
|
|
procedure Paint(DC: HDC); virtual;
|
|
property Renderer: TdxPSReportRenderer read FRenderer;
|
|
end;
|
|
|
|
TdxPSReportGroupLookAndFeel = class(TPersistent)
|
|
private
|
|
FCaptionHeight: Integer;
|
|
FCaptionFontIndex: Integer;
|
|
FCaptionIndent: Integer;
|
|
FColor: TColor;
|
|
FData: Pointer;
|
|
FFontIndex: Integer;
|
|
FReportCells: TdxReportCells;
|
|
function GetCaptionFont: TFont;
|
|
function GetFont: TFont;
|
|
function GetRenderer: TdxPSReportRenderer;
|
|
procedure SetCaptionFont(Value: TFont);
|
|
procedure SetCaptionFontIndex(Value: Integer);
|
|
procedure SetFont(Value: TFont);
|
|
procedure SetFontIndex(Value: Integer);
|
|
protected
|
|
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); virtual;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
|
|
function GetBorderEdgeThickness(AGroup: TdxReportGroup; ASide: TdxCellSide): Integer; virtual;
|
|
function GetBorderThickness: Integer; virtual;
|
|
function GetColor: TColor; virtual;
|
|
procedure SetBorderThickness(Value: Integer); virtual;
|
|
|
|
function GetCaptionAreaHeight: Integer; virtual;
|
|
function GetCaptionBounds(AGroup: TdxReportGroup): TRect; virtual;
|
|
function GetCaptionColor: TColor; virtual;
|
|
function GetCaptionHeight: Integer; virtual;
|
|
function GetCaptionIndent: Integer; virtual;
|
|
function GetCaptionLeftRestSpaceBounds(AGroup: TdxReportGroup): TRect; virtual;
|
|
function GetCaptionRightRestSpaceBounds(AGroup: TdxReportGroup): TRect; virtual;
|
|
function GetCaptionTextBounds(AGroup: TdxReportGroup): TRect; virtual;
|
|
|
|
function GetPainter: TdxPSReportGroupLookAndFeelPainter;
|
|
class function GetPainterClass: TdxPSReportGroupLookAndFeelPainterClass; virtual;
|
|
|
|
property BorderThickness: Integer read GetBorderThickness write SetBorderThickness;
|
|
property CaptionAreaHeight: Integer read GetCaptionAreaHeight;
|
|
property CaptionColor: TColor read GetCaptionColor;
|
|
property CaptionHeight: Integer read GetCaptionHeight;
|
|
property CaptionIndent: Integer read GetCaptionIndent;
|
|
property Renderer: TdxPSReportRenderer read GetRenderer;
|
|
property ReportCells: TdxReportCells read FReportCells;
|
|
public
|
|
constructor Create(AReportCells: TdxReportCells); virtual;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
class function BorderClass: TdxPSCellBorderClass; virtual;
|
|
class function DefaultBorderSides: TdxCellSides; virtual;
|
|
class function Name: string; virtual;
|
|
|
|
class procedure Register; virtual;
|
|
class procedure Unregister; virtual;
|
|
|
|
procedure Paint(DC: HDC; AGroup: TdxReportGroup);
|
|
procedure Prepare(DC: HDC); virtual;
|
|
|
|
property CaptionFont: TFont read GetCaptionFont write SetCaptionFont;
|
|
property CaptionFontIndex: Integer read FCaptionFontIndex write SetCaptionFontIndex;
|
|
property Color: TColor read GetColor write FColor;
|
|
property Data: Pointer read FData write FData;
|
|
property Font: TFont read GetFont write SetFont;
|
|
property FontIndex: Integer read FFontIndex write SetFontIndex;
|
|
end;
|
|
|
|
TdxPSReportGroupNullLookAndFeel = class;
|
|
|
|
TdxPSReportGroupNullLookAndFeelPainter = class(TdxPSReportGroupLookAndFeelPainter)
|
|
public
|
|
procedure Paint(DC: HDC); override;
|
|
end;
|
|
|
|
TdxPSReportGroupNullLookAndFeel = class(TdxPSReportGroupLookAndFeel)
|
|
protected
|
|
function GetBorderThickness: Integer; override;
|
|
function GetCaptionHeight: Integer; override;
|
|
class function GetPainterClass: TdxPSReportGroupLookAndFeelPainterClass; override;
|
|
public
|
|
class function BorderClass: TdxPSCellBorderClass; override;
|
|
class function DefaultBorderSides: TdxCellSides; override;
|
|
class function Name: string; override;
|
|
end;
|
|
|
|
TdxPSReportGroupStandardLookAndFeel = class;
|
|
|
|
TdxPSReportGroupStandardLookAndFeelPainter = class(TdxPSReportGroupLookAndFeelPainter)
|
|
protected
|
|
procedure DrawBorders(DC: HDC); override;
|
|
procedure DrawCaptionRestSpace(DC: HDC); virtual;
|
|
function LookAndFeel: TdxPSReportGroupStandardLookAndFeel; reintroduce; overload;
|
|
public
|
|
procedure Paint(DC: HDC); override;
|
|
end;
|
|
|
|
TdxPSReportGroupStandardLookAndFeel = class(TdxPSReportGroupLookAndFeel)
|
|
protected
|
|
class function GetPainterClass: TdxPSReportGroupLookAndFeelPainterClass; override;
|
|
public
|
|
class function BorderClass: TdxPSCellBorderClass; override;
|
|
class function Name: string; override;
|
|
|
|
property CaptionAreaHeight;
|
|
property CaptionFont;
|
|
property CaptionFontIndex;
|
|
end;
|
|
|
|
TdxPSReportGroupOfficeLookAndFeel = class(TdxPSReportGroupStandardLookAndFeel)
|
|
protected
|
|
function GetCaptionIndent: Integer; override;
|
|
public
|
|
class function DefaultBorderSides: TdxCellSides; override;
|
|
class function Name: string; override;
|
|
end;
|
|
|
|
TdxPSReportGroupWebLookAndFeel = class;
|
|
|
|
TdxPSReportGroupWebLookAndFeelPainter = class(TdxPSReportGroupLookAndFeelPainter)
|
|
protected
|
|
procedure DrawBorders(DC: HDC); override;
|
|
procedure DrawCaptionSeparator(DC: HDC); virtual;
|
|
function LookAndFeel: TdxPSReportGroupWebLookAndFeel; reintroduce; overload;
|
|
public
|
|
procedure Paint(DC: HDC); override;
|
|
end;
|
|
|
|
TdxPSReportGroupWebLookAndFeel = class(TdxPSReportGroupLookAndFeel)
|
|
private
|
|
FBorderColor: TColor;
|
|
FBorderThickness: Integer;
|
|
FCaptionColor: TColor;
|
|
FCaptionSeparatorColor: TColor;
|
|
FCaptionSeparatorThickness: Integer;
|
|
procedure SetCaptionSeparatorThickness(Value: Integer);
|
|
protected
|
|
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); override;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
function GetBorderEdgeThickness(AGroup: TdxReportGroup; ASide: TdxCellSide): Integer; override;
|
|
function GetBorderThickness: Integer; override;
|
|
procedure SetBorderThickness(Value: Integer); override;
|
|
|
|
function GetBorderColor: TColor; virtual;
|
|
function GetCaptionColor: TColor; override;
|
|
function GetCaptionSeparatorColor: TColor; virtual;
|
|
|
|
function GetCaptionAreaHeight: Integer; override;
|
|
function GetCaptionBounds(AGroup: TdxReportGroup): TRect; override;
|
|
function GetCaptionLeftRestSpaceBounds(AGroup: TdxReportGroup): TRect; override;
|
|
function GetCaptionRightRestSpaceBounds(AGroup: TdxReportGroup): TRect; override;
|
|
function GetCaptionSeparatorBounds(AGroup: TdxReportGroup): TRect; virtual;
|
|
function GetCaptionTextBounds(AGroup: TdxReportGroup): TRect; override;
|
|
|
|
class function GetPainterClass: TdxPSReportGroupLookAndFeelPainterClass; override;
|
|
public
|
|
constructor Create(AReportCells: TdxReportCells); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
class function BorderClass: TdxPSCellBorderClass; override;
|
|
class function Name: string; override;
|
|
|
|
property BorderColor: TColor read GetBorderColor write FBorderColor;
|
|
property BorderThickness;
|
|
property CaptionAreaHeight;
|
|
property CaptionColor write FCaptionColor;
|
|
property CaptionFont;
|
|
property CaptionSeparatorColor: TColor read GetCaptionSeparatorColor write FCaptionSeparatorColor;
|
|
property CaptionSeparatorThickness: Integer read FCaptionSeparatorThickness write SetCaptionSeparatorThickness;
|
|
end;
|
|
|
|
TdxReportGroup = class(TdxReportCell)
|
|
private
|
|
FCaptionText: string;
|
|
FCaptionTextWidth: Integer;
|
|
FLookAndFeel: TdxPSReportGroupLookAndFeel;
|
|
//FStreamedLookAndFeelIndex: Integer;
|
|
function GetCaptionAlignment: TdxTextAlignX;
|
|
function GetCaptionTextWidth: Integer;
|
|
function GetCaptionTransparent: Boolean;
|
|
function GetLookAndFeel: TdxPSReportGroupLookAndFeel;
|
|
function GetLookAndFeelIndex: Integer;
|
|
function GetShowCaption: Boolean;
|
|
function GetUseOwnBorderClass: Boolean;
|
|
procedure SetCaptionAlignment(Value: TdxTextAlignX);
|
|
procedure SetCaptionTransparent(Value: Boolean);
|
|
procedure SetLookAndFeel(Value: TdxPSReportGroupLookAndFeel);
|
|
procedure SetShowCaption(Value: Boolean);
|
|
procedure SetUseOwnBorderClass(Value: Boolean);
|
|
protected
|
|
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); override;
|
|
procedure InternalDrawBorders(DC: HDC); virtual;
|
|
|
|
function GetBorderClass: TdxPSCellBorderClass; override;
|
|
function GetBorderEdgeSalient(ASide: TdxCellSide; ASalient: TdxPSCellBorderSalientType): Integer; override;
|
|
function GetBorderEdgeThickness(ASide: TdxCellSide): Integer; override;
|
|
function InternalGetBorderEdgeThickness(ASide: TdxCellSide): Integer;
|
|
|
|
function IsBordersDrawn: Boolean; override;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
property CaptionTextWidth: Integer read GetCaptionTextWidth;
|
|
property LookAndFeelIndex: Integer read GetLookAndFeelIndex;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure DrawBorders(DC: HDC); override;
|
|
|
|
procedure CalculateCaptionTextWidth(DC: HDC);
|
|
function GetBorderOuterBounds(DC: HDC): TRect; override;
|
|
|
|
property CaptionAlignment: TdxTextAlignX read GetCaptionAlignment write SetCaptionAlignment;
|
|
property CaptionText: string read FCaptionText write FCaptionText;
|
|
property CaptionTransparent: Boolean read GetCaptionTransparent write SetCaptionTransparent;
|
|
property LookAndFeel: TdxPSReportGroupLookAndFeel read GetLookAndFeel write SetLookAndFeel;
|
|
property ShowCaption: Boolean read GetShowCaption write SetShowCaption;
|
|
property UseOwnBorderClass: Boolean read GetUseOwnBorderClass write SetUseOwnBorderClass;
|
|
end;
|
|
|
|
TdxReportCells = class(TPersistent)
|
|
private
|
|
FBorderColor: TColor;
|
|
FBorderWidth: Integer;
|
|
FCells: TdxReportCell;
|
|
FExpandButtonBorderColor: TColor;
|
|
FFooterCells: TdxReportCell;
|
|
FGroupBorderColor: TColor;
|
|
FGroupCaptionColor: TColor;
|
|
FGroupCaptionSeparatorColor: TColor;
|
|
FGroupColor: TColor;
|
|
FHeaderCells: TdxReportCell;
|
|
FImageLists: TList;
|
|
FLookAndFeel: TdxPSReportGroupLookAndFeel;
|
|
FLookAndFeels: TList;
|
|
FOverlays: TList;
|
|
FOwnImageLists: Boolean;
|
|
FShadowColor: TColor;
|
|
FShadowDepth: Integer;
|
|
FReportLink: TBasedxReportLink;
|
|
FTreeLineColor: TColor;
|
|
FTreeLineStyle: TdxPSTreeLineStyle;
|
|
function GetAreFooterCellsAllocated: Boolean;
|
|
function GetAreHeaderCellsAllocated: Boolean;
|
|
function GetBoundsRect: TRect;
|
|
function GetCount: Integer;
|
|
function GetFont: TFont;
|
|
function GetFooterBoundsRect: TRect;
|
|
function GetFooterCellCount: Integer;
|
|
function GetFooterCells: TdxReportCell;
|
|
function GetHeaderBoundsRect: TRect;
|
|
function GetHeaderCellCount: Integer;
|
|
function GetHeaderCells: TdxReportCell;
|
|
function GetImageList(Index: Integer): TCustomImageList;
|
|
function GetImageListCount: Integer;
|
|
function GetLookAndFeel(Index: Integer): TdxPSReportGroupLookAndFeel;
|
|
function GetLookAndFeelCount: Integer;
|
|
function GetOverlay(Index: Integer): TdxReportCell;
|
|
function GetOverlayCount: Integer;
|
|
function GetRenderer: TdxPSReportRenderer;
|
|
procedure SetBorderColor(Value: TColor);
|
|
procedure SetShadowColor(Value: TColor);
|
|
procedure SetShadowDepth(Value: Integer);
|
|
procedure SetTreeLineColor(Value: TColor);
|
|
|
|
procedure CreateFooterCells;
|
|
procedure CreateHeaderCells;
|
|
protected
|
|
procedure AfterReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure AfterWriteData(AWriter: TdxPSDataWriter); virtual;
|
|
procedure BeforeReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure BeforeWriteData(AWriter: TdxPSDataWriter); virtual;
|
|
|
|
procedure ReadCells(AReader: TdxPSDataReader);
|
|
procedure ReadHeaderCells(AReader: TdxPSDataReader);
|
|
procedure ReadFooterCells(AReader: TdxPSDataReader);
|
|
procedure ReadImageLists(AReader: TdxPSDataReader);
|
|
procedure ReadLookAndFeels(AReader: TdxPSDataReader);
|
|
procedure ReadOverlayCells(AReader: TdxPSDataReader);
|
|
procedure ReadProperties(AReader: TdxPSDataReader);
|
|
|
|
procedure WriteCells(AWriter: TdxPSDataWriter);
|
|
procedure WriteFooterCells(AWriter: TdxPSDataWriter);
|
|
procedure WriteHeaderCells(AWriter: TdxPSDataWriter);
|
|
procedure WriteImageLists(AWriter: TdxPSDataWriter);
|
|
procedure WriteLookAndFeels(AWriter: TdxPSDataWriter);
|
|
procedure WriteOverlayCells(AWriter: TdxPSDataWriter);
|
|
procedure WriteProperties(AWriter: TdxPSDataWriter);
|
|
|
|
function CalculateOverlaysHeight: Integer;
|
|
function CalculateOverlaysWidth: Integer;
|
|
function CalculateTotalHeight: Integer;
|
|
function CalculateTotalWidth: Integer;
|
|
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); virtual;
|
|
function GetCellTopLevelParent(AnItem: TdxReportItem): TdxReportCell; virtual;
|
|
|
|
procedure FreeAndNilReportGroupLookAndFeels;
|
|
procedure PrepareReportGroupsLookAndFeels(DC: HDC);
|
|
|
|
procedure AddImageList(AnImageList: TCustomImageList);
|
|
procedure ClearImageLists;
|
|
procedure FreeAndNilImageLists;
|
|
procedure GetImageLists;
|
|
|
|
property ImageListCount: Integer read GetImageListCount;
|
|
property OwnImageLists: Boolean read FOwnImageLists write FOwnImageLists;
|
|
property Renderer: TdxPSReportRenderer read GetRenderer;
|
|
public
|
|
constructor Create(AReportLink: TBasedxReportLink); virtual;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure ClearItems;
|
|
|
|
procedure ClearLookAndFeels;
|
|
function CreateGroupLookAndFeel(AClass: TdxPSReportGroupLookAndFeelClass; ACheckExisting: Boolean = True): TdxPSReportGroupLookAndFeel;
|
|
function FindGroupLookAndFeelByClass(AClass: TdxPSReportGroupLookAndFeelClass): TdxPSReportGroupLookAndFeel;
|
|
function FindGroupLookAndFeelByData(AData: Pointer): TdxPSReportGroupLookAndFeel;
|
|
function IndexOfImageList(AnImageList: TCustomImageList): Integer;
|
|
function IndexOfReportGroupLookAndFeel(ALookAndFeel: TdxPSReportGroupLookAndFeel): Integer;
|
|
|
|
procedure DoProgress(const APercentDone: Double);
|
|
|
|
function AddOverlay: TdxReportCell;
|
|
procedure AppendOverlays(Source: TdxReportCells; AnOffsetX: Integer = 0; AnOffsetY: Integer = 0);
|
|
procedure AssignOverlays(Source: TdxReportCells; AnOffsetX: Integer = 0; AnOffsetY: Integer = 0);
|
|
procedure ClearOverlays;
|
|
procedure DeleteOverlay(AnOverlay: TdxReportCell);
|
|
procedure FreeAndNilOverlays;
|
|
function HasOverlays: Boolean;
|
|
function IndexOfOverlay(AnOverlay: TdxReportCell): Integer;
|
|
|
|
function GetFontByIndex(AnIndex: Integer): TFont;
|
|
function GetIndexByFont(AFont: TFont): Integer;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
|
|
property AreFooterCellsAllocated: Boolean read GetAreFooterCellsAllocated;
|
|
property AreHeaderCellsAllocated: Boolean read GetAreHeaderCellsAllocated;
|
|
property BorderColor: TColor read FBorderColor write SetBorderColor;
|
|
property BorderWidth: Integer read FBorderWidth write FBorderWidth;
|
|
property BoundsRect: TRect read GetBoundsRect;
|
|
property Cells: TdxReportCell read FCells;
|
|
property Count: Integer read GetCount;
|
|
property ExpandButtonBorderColor: TColor read FExpandButtonBorderColor write FExpandButtonBorderColor default clBlack;
|
|
property Font: TFont read GetFont;
|
|
property FooterBoundsRect: TRect read GetFooterBoundsRect;
|
|
property FooterCellCount: Integer read GetFooterCellCount;
|
|
property FooterCells: TdxReportCell read GetFooterCells;
|
|
property GroupBorderColor: TColor read FGroupBorderColor write FGroupBorderColor;
|
|
property GroupCaptionColor: TColor read FGroupCaptionColor write FGroupCaptionColor;
|
|
property GroupCaptionSeparatorColor: TColor read FGroupCaptionSeparatorColor write FGroupCaptionSeparatorColor;
|
|
property GroupColor: TColor read FGroupColor write FGroupColor;
|
|
property HeaderBoundsRect: TRect read GetHeaderBoundsRect;
|
|
property HeaderCellCount: Integer read GetHeaderCellCount;
|
|
property HeaderCells: TdxReportCell read GetHeaderCells;
|
|
property ImageLists[Index: Integer]: TCustomImageList read GetImageList;
|
|
property LookAndFeel: TdxPSReportGroupLookAndFeel read FLookAndFeel write FLookAndFeel;
|
|
property LookAndFeelCount: Integer read GetLookAndFeelCount;
|
|
property LookAndFeels[Index: Integer]: TdxPSReportGroupLookAndFeel read GetLookAndFeel;
|
|
property OverlayCount: Integer read GetOverlayCount;
|
|
property Overlays[Index: Integer]: TdxReportCell read GetOverlay;
|
|
property ReportLink: TBasedxReportLink read FReportLink;
|
|
property ShadowColor: TColor read FShadowColor write SetShadowColor;
|
|
property ShadowDepth: Integer read FShadowDepth write SetShadowDepth;
|
|
property TreeLineColor: TColor read FTreeLineColor write SetTreeLineColor;
|
|
property TreeLineStyle: TdxPSTreeLineStyle read FTreeLineStyle write FTreeLineStyle default tlsDot;
|
|
end;
|
|
|
|
TAbstractdxReportCellData = class(TdxReportVisualItem)
|
|
private
|
|
function GetBreakByChars: Boolean;
|
|
function GetEndEllipsis: Boolean;
|
|
function GetHidePrefix: Boolean;
|
|
function GetMultiline: Boolean;
|
|
function GetPreventLeftTextExceed: Boolean;
|
|
function GetPreventTopTextExceed: Boolean;
|
|
function GetSortOrder: TdxCellSortOrder;
|
|
function GetTextAlignX: TdxTextAlignX;
|
|
function GetTextAlignY: TdxTextAlignY;
|
|
procedure SetBreakByChars(Value: Boolean);
|
|
procedure SetEndEllipsis(Value: Boolean);
|
|
procedure SetHidePrefix(Value: Boolean);
|
|
procedure SetMultiline(Value: Boolean);
|
|
procedure SetPreventLeftTextExceed(Value: Boolean);
|
|
procedure SetPreventTopTextExceed(Value: Boolean);
|
|
procedure SetSortOrder(Value: TdxCellSortOrder);
|
|
procedure SetTextAlignX(Value: TdxTextAlignX);
|
|
procedure SetTextAlignY(Value: TdxTextAlignY);
|
|
protected
|
|
function CustomDraw(DC: HDC): Boolean; virtual;
|
|
function GetAbsoluteEffectiveBounds(DC: HDC; AStage: TdxPSRenderStages): TRect; virtual;
|
|
function GetDefaultDTFormat: DWORD; virtual;
|
|
function GetEffectiveBounds(DC: HDC; AStage: TdxPSRenderStages): TRect; virtual;
|
|
function GetDTFormat: DWORD; virtual;
|
|
function IsCustomDrawn: Boolean; virtual;
|
|
function IsDrawingNeeded(DC: HDC; AStage: TdxPSRenderStages; const ARect: TRect): Boolean; virtual;
|
|
function IsDrawn(DC: HDC; AStage: TdxPSRenderStages; const ARect: TRect): Boolean; virtual;
|
|
|
|
property BreakByChars: Boolean read GetBreakByChars write SetBreakByChars default True;
|
|
property EndEllipsis: Boolean read GetEndEllipsis write SetEndEllipsis default False;
|
|
property HidePrefix: Boolean read GetHidePrefix write SetHidePrefix default False;
|
|
property Multiline: Boolean read GetMultiline write SetMultiline default False;
|
|
property PreventLeftTextExceed: Boolean read GetPreventLeftTextExceed write SetPreventLeftTextExceed;
|
|
property PreventTopTextExceed: Boolean read GetPreventTopTextExceed write SetPreventTopTextExceed;
|
|
property SortOrder: TdxCellSortOrder read GetSortOrder write SetSortOrder default csoNone;
|
|
property TextAlignX: TdxTextAlignX read GetTextAlignX write SetTextAlignX default taLeft;
|
|
property TextAlignY: TdxTextAlignY read GetTextAlignY write SetTextAlignY default taCenterY;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
|
|
procedure DrawContent(DC: HDC; AStage: TdxPSRenderStages); virtual;
|
|
function GetCustomDrawID: Integer; virtual;
|
|
|
|
function MeasureContentHeight(DC: HDC): Integer; override;
|
|
function MeasureContentWidth(DC: HDC): Integer; override;
|
|
|
|
property DefaultDTFormat: DWORD read GetDefaultDTFormat;
|
|
property DTFormat: DWORD read GetDTFormat;
|
|
end;
|
|
|
|
TdxReportCellBoxClass = class of TdxReportCellBox;
|
|
|
|
TdxReportCellBox = class(TAbstractdxReportCellData);
|
|
|
|
TdxReportCellTextClass = class of TdxReportCellText;
|
|
|
|
TdxReportCellText = class(TAbstractdxReportCellData)
|
|
private
|
|
FIndent: Cardinal;
|
|
function GetAdjustFont: Boolean;
|
|
function GetIndent: Integer;
|
|
procedure SetAdjustFont(Value: Boolean);
|
|
procedure SetIndent(Value: Integer);
|
|
protected
|
|
function GetText: string; virtual; abstract;
|
|
procedure SetText(const Value: string); virtual; abstract;
|
|
|
|
function GetSortMarkBounds(DC: HDC): TRect; virtual;
|
|
function GetTextBounds(DC: HDC): TRect; virtual;
|
|
function IsSortMarkDrawn: Boolean; virtual;
|
|
function IsTextDrawn: Boolean; virtual;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
property AdjustFont: Boolean read GetAdjustFont write SetAdjustFont;
|
|
property Indent: Integer read GetIndent write SetIndent;
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure DrawContent(DC: HDC; AStage: TdxPSRenderStages); override;
|
|
procedure DrawSortMark(DC: HDC); virtual;
|
|
procedure DrawText(DC: HDC); virtual;
|
|
|
|
function CalculateLineCount(DC: HDC): Integer; override;
|
|
function MeasureContentHeight(DC: HDC): Integer; override;
|
|
function MeasureContentWidth(DC: HDC): Integer; override;
|
|
function MeasureFontHeight(DC: HDC): Integer; override;
|
|
|
|
property EndEllipsis;
|
|
property HidePrefix;
|
|
property Multiline;
|
|
property SortOrder;
|
|
property Text: string read GetText write SetText;
|
|
end;
|
|
|
|
TdxReportCellStringClass = class of TdxReportCellString;
|
|
|
|
TdxReportCellString = class(TdxReportCellText)
|
|
private
|
|
FText: string;
|
|
protected
|
|
function GetText: string; override;
|
|
procedure SetText(const Value: string); override;
|
|
public
|
|
property AdjustFont;
|
|
property Indent;
|
|
property PreventLeftTextExceed;
|
|
property PreventTopTextExceed;
|
|
property TextAlignX;
|
|
property TextAlignY;
|
|
end;
|
|
|
|
TdxReportCellImageContainer = class(TdxReportCellString)
|
|
private
|
|
function GetImageTransparent: Boolean;
|
|
procedure SetImageTransparent(Value: Boolean);
|
|
protected
|
|
function GetImageAreaBounds(DC: HDC): TRect; virtual;
|
|
function GetImageBounds(DC: HDC): TRect; virtual;
|
|
procedure GetImageSizes(var AImageWidth, AImageHeight: Integer); virtual;
|
|
function HasImage: Boolean; virtual;
|
|
function IsImageBackgroundDrawn: Boolean; virtual;
|
|
function IsImageDrawn: Boolean; virtual;
|
|
function IsTextBackgroundDrawn: Boolean; virtual;
|
|
property ImageTransparent: Boolean read GetImageTransparent write SetImageTransparent default True;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure DrawContent(DC: HDC; AStage: TdxPSRenderStages); override;
|
|
procedure DrawImage(DC: HDC); virtual;
|
|
procedure DrawImageBackground(DC: HDC); virtual;
|
|
procedure DrawTextBackground(DC: HDC); virtual;
|
|
end;
|
|
|
|
TdxCustomReportCellCheckClass = class of TdxCustomReportCellCheck;
|
|
|
|
TdxCustomReportCellCheck = class(TdxReportCellImageContainer)
|
|
private
|
|
function GetBoldBorder: Boolean;
|
|
function GetButtonEdgeStyle: TdxCheckButtonEdgeStyle;
|
|
function GetChecked: Boolean;
|
|
function GetCheckPos: TdxCellCheckPos;
|
|
function GetEnabled: Boolean;
|
|
function GetFlatBorder: Boolean;
|
|
function GetState: TCheckBoxState;
|
|
procedure SetBoldBorder(Value: Boolean);
|
|
procedure SetButtonEdgeStyle(Value: TdxCheckButtonEdgeStyle);
|
|
procedure SetCheckPos(Value: TdxCellCheckPos);
|
|
procedure SetEnabled(Value: Boolean);
|
|
procedure SetFlatBorder(Value: Boolean);
|
|
protected
|
|
function GetCheckBounds(DC: HDC): TRect; virtual;
|
|
function GetImageAreaBounds(DC: HDC): TRect; override;
|
|
function GetImageBounds(DC: HDC): TRect; override;
|
|
procedure GetImageSizes(var AImageWidth, AImageHeight: Integer); override;
|
|
function GetTextBounds(DC: HDC): TRect; override;
|
|
function HasImage: Boolean; override;
|
|
function IsImageBackgroundDrawn: Boolean; override;
|
|
class function IsRadio: Boolean; virtual;
|
|
procedure SetChecked(Value: Boolean); virtual;
|
|
|
|
property BoldBorder: Boolean read GetBoldBorder write SetBoldBorder; // obsolete
|
|
property FlatBorder: Boolean read GetFlatBorder write SetFlatBorder; // obsolete
|
|
property State: TCheckBoxState read GetState;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
|
|
procedure DrawCheck(DC: HDC); virtual;
|
|
procedure DrawImage(DC: HDC); override;
|
|
|
|
function MeasureContentHeight(DC: HDC): Integer; override;
|
|
function MeasureContentWidth(DC: HDC): Integer; override;
|
|
|
|
property ButtonEdgeStyle: TdxCheckButtonEdgeStyle read GetButtonEdgeStyle write SetButtonEdgeStyle default cbesUltraFlat;
|
|
property Checked: Boolean read GetChecked write SetChecked default False;
|
|
property CheckPos: TdxCellCheckPos read GetCheckPos write SetCheckPos default ccpCenter;
|
|
property Enabled: Boolean read GetEnabled write SetEnabled default True;
|
|
end;
|
|
|
|
TdxReportCellCheck = class(TdxCustomReportCellCheck)
|
|
public
|
|
property BoldBorder;
|
|
property FlatBorder;
|
|
property State;
|
|
end;
|
|
|
|
TdxCustomReportCellRadio = class(TdxReportCellCheck)
|
|
protected
|
|
class function IsRadio: Boolean; override;
|
|
end;
|
|
|
|
TdxReportCellRadio = class(TdxCustomReportCellRadio)
|
|
end;
|
|
|
|
TdxCustomReportCellCheckImage = class(TdxReportCellCheck)
|
|
private
|
|
function GetGlyphPartialBounds: TRect;
|
|
protected
|
|
procedure GetImageSizes(var AImageWidth, AImageHeight: Integer); override;
|
|
|
|
function GetGlyph: TBitmap; virtual;
|
|
function GetGlyphCount: Integer; virtual;
|
|
function GetGlyphIndex: Integer; virtual;
|
|
procedure SetGlyph(Value: TBitmap); virtual;
|
|
procedure SetGlyphCount(Value: Integer); virtual;
|
|
|
|
function HasGlyph: Boolean; virtual;
|
|
procedure ReleaseGlyph; virtual;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
property Glyph: TBitmap read GetGlyph write SetGlyph;
|
|
property GlyphCount: Integer read GetGlyphCount write SetGlyphCount;
|
|
property GlyphIndex: Integer read GetGlyphIndex;
|
|
property GlyphPartialBounds: TRect read GetGlyphPartialBounds;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure DrawCheck(DC: HDC); override;
|
|
procedure DrawCheckGlyph(DC: HDC); virtual;
|
|
end;
|
|
|
|
TdxReportCellCheckImage = class(TdxCustomReportCellCheckImage)
|
|
private
|
|
FGlyph: TBitmap;
|
|
protected
|
|
function GetGlyphCount: Integer; override;
|
|
function GetGlyph: TBitmap; override;
|
|
procedure SetGlyph(Value: TBitmap); override;
|
|
procedure SetGlyphCount(Value: Integer); override;
|
|
|
|
function HasGlyph: Boolean; override;
|
|
procedure ReleaseGlyph; override;
|
|
public
|
|
property Glyph;
|
|
property GlyphCount;
|
|
property GlyphIndex;
|
|
property GlyphPartialBounds;
|
|
end;
|
|
|
|
TdxCustomReportButtonGroupClass = class of TdxCustomReportButtonGroup;
|
|
|
|
TdxCustomReportButtonGroup = class(TdxReportGroup)
|
|
private
|
|
FColumnCount: Integer;
|
|
FInterColumnsMinSpace: Integer;
|
|
FInterRowsMinSpace: Integer;
|
|
FIndents: TRect;
|
|
FItemSize: TSize;
|
|
function GetButtonEdgeStyle: TdxCheckButtonEdgeStyle;
|
|
function GetCheckPos: TdxCellCheckPos;
|
|
function GetItem(Index: Integer): TdxCustomReportCellCheck;
|
|
function GetItemColumn(Index: Integer): Integer;
|
|
function GetItemCount: Integer;
|
|
function GetItemRow(Index: Integer): Integer;
|
|
function GetRowCount: Integer;
|
|
procedure SetButtonEdgeStyle(Value: TdxCheckButtonEdgeStyle);
|
|
procedure SetCheckPos(Value: TdxCellCheckPos);
|
|
procedure SetColumnCount(Value: Integer);
|
|
procedure SetInterColumnsMinSpace(Value: Integer);
|
|
procedure SetInterRowsMinSpace(Value: Integer);
|
|
procedure SetIndents(Value: TRect);
|
|
protected
|
|
FLocked: Boolean;
|
|
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); override;
|
|
procedure SetFontIndex(Value: Integer); override;
|
|
|
|
procedure ReadDataItems(AReader: TdxPSDataReader); override;
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
class function GetItemClass: TdxCustomReportCellCheckClass; virtual;
|
|
procedure InitializeItem(AnItem: TdxCustomReportCellCheck); virtual;
|
|
|
|
property ItemSize: TSize read FItemSize;
|
|
property Locked: Boolean read FLocked write FLocked;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure AdjustContent(DC: HDC); override;
|
|
|
|
function MeasureContentHeight(DC: HDC): Integer; override;
|
|
function MeasureContentWidth(DC: HDC): Integer; override;
|
|
|
|
function Add(const AText: string = ''): TdxCustomReportCellCheck;
|
|
procedure Clear;
|
|
procedure Delete(Index: Integer);
|
|
function FindItem(const ACaption: string): Integer;
|
|
|
|
property ButtonEdgeStyle: TdxCheckButtonEdgeStyle read GetButtonEdgeStyle write SetButtonEdgeStyle default cbesUltraFlat;
|
|
property CheckPos: TdxCellCheckPos read GetCheckPos write SetCheckPos default ccpCenter;
|
|
property ColumnCount: Integer read FColumnCount write SetColumnCount;
|
|
property Indents: TRect read FIndents write SetIndents;
|
|
property InterColumnsMinSpace: Integer read FInterColumnsMinSpace write SetInterColumnsMinSpace;
|
|
property InterRowsMinSpace: Integer read FInterRowsMinSpace write SetInterRowsMinSpace;
|
|
property ItemColumns[Index: Integer]: Integer read GetItemColumn;
|
|
property ItemCount: Integer read GetItemCount;
|
|
property ItemRows[Index: Integer]: Integer read GetItemRow;
|
|
property Items[Index: Integer]: TdxCustomReportCellCheck read GetItem;
|
|
property RowCount: Integer read GetRowCount;
|
|
end;
|
|
|
|
TdxReportRadioGroup = class(TdxCustomReportButtonGroup)
|
|
private
|
|
function GetItem(Index: Integer): TdxCustomReportCellRadio;
|
|
function GetItemIndex: Integer;
|
|
procedure SetItemIndex(Value: Integer);
|
|
protected
|
|
class function GetItemClass: TdxCustomReportCellCheckClass; override;
|
|
public
|
|
function Add(const AText: string = ''): TdxCustomReportCellRadio;
|
|
property ItemIndex: Integer read GetItemIndex write SetItemIndex;
|
|
property Items[Index: Integer]: TdxCustomReportCellRadio read GetItem;
|
|
end;
|
|
|
|
TdxReportCheckGroup = class(TdxCustomReportButtonGroup)
|
|
private
|
|
FGlyph: TBitmap;
|
|
FGlyphCount: Integer;
|
|
function GetGlyph: TBitmap;
|
|
function GetItem(Index: Integer): TdxCustomReportCellCheckImage;
|
|
function GetItemChecked(Index: Integer): Boolean;
|
|
function GetItemEnabled(Index: Integer): Boolean;
|
|
function GetItemState(Index: Integer): TCheckBoxState;
|
|
procedure SetGlyph(Value: TBitmap);
|
|
procedure SetGlyphCount(Value: Integer);
|
|
procedure SetItemChecked(Index: Integer; Value: Boolean);
|
|
procedure SetItemEnabled(Index: Integer; Value: Boolean);
|
|
protected
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
class function GetItemClass: TdxCustomReportCellCheckClass; override;
|
|
procedure InitializeItem(AnItem: TdxCustomReportCellCheck); override;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
function Add(const AText: string = ''): TdxCustomReportCellCheckImage;
|
|
function HasGlyph: Boolean;
|
|
procedure ReleaseGlyph;
|
|
|
|
property Glyph: TBitmap read GetGlyph write SetGlyph;
|
|
property GlyphCount: Integer read FGlyphCount write SetGlyphCount;
|
|
property Items[Index: Integer]: TdxCustomReportCellCheckImage read GetItem;
|
|
property ItemsChecked[Index: Integer]: Boolean read GetItemChecked write SetItemChecked;
|
|
property ItemsEnabled[Index: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
|
|
property ItemsState[Index: Integer]: TCheckBoxState read GetItemState;
|
|
end;
|
|
|
|
TCustomdxReportCellImageContainer = class(TdxReportCellImageContainer)
|
|
private
|
|
FImage: TGraphic;
|
|
FImageIndex: Integer;
|
|
FImageList: TCustomImageList;
|
|
procedure SetImage(Value: TGraphic);
|
|
protected
|
|
function GetActualImageBuffering: TdxCellImageActualBuffering; virtual;
|
|
function GetImageBuffering: TdxCellImageBuffering; virtual;
|
|
procedure GetImageSizes(var AImageWidth, AImageHeight: Integer); override;
|
|
function HasImage: Boolean; override;
|
|
procedure SetImageBuffering(Value: TdxCellImageBuffering); virtual;
|
|
|
|
function GetImageListIndex: Integer;
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
property ActualImageBuffering: TdxCellImageActualBuffering read GetActualImageBuffering;
|
|
property ImageBuffering: TdxCellImageBuffering read GetImageBuffering write SetImageBuffering;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
function CreateImage(AGraphicClass: TGraphicClass): TGraphic; virtual;
|
|
procedure DrawImage(DC: HDC); override;
|
|
|
|
property Image: TGraphic read FImage write SetImage;
|
|
property ImageIndex: Integer read FImageIndex write FImageIndex;
|
|
property ImageList: TCustomImageList read FImageList write FImageList;
|
|
property ImageTransparent;
|
|
end;
|
|
|
|
TdxReportCellImageClass = class of TdxReportCellImage;
|
|
|
|
TdxReportCellImage = class(TCustomdxReportCellImageContainer)
|
|
private
|
|
function GetImageLayout: TdxImageLayout;
|
|
function GetIsTextDrawnForCenteredImage: Boolean;
|
|
function GetIsTextShiftedForHorizontallyCenteredImage: Boolean;
|
|
function GetMakeSpaceForEmptyImage: Boolean;
|
|
procedure SetImageLayout(Value: TdxImageLayout);
|
|
procedure SetIsTextDrawnForCenteredImage(Value: Boolean);
|
|
procedure SetIsTextShiftedForHorizontallyCenteredImage(Value: Boolean);
|
|
procedure SetMakeSpaceForEmptyImage(Value: Boolean);
|
|
protected
|
|
function GetHalfContentWidth(DC: HDC): Integer;
|
|
function GetImageAreaBounds(DC: HDC): TRect; override;
|
|
function GetImageBounds(DC: HDC): TRect; override;
|
|
function GetTextBounds(DC: HDC): TRect; override;
|
|
function IsImageBackgroundDrawn: Boolean; override;
|
|
function IsTextDrawn: Boolean; override;
|
|
function IsTextBackgroundDrawn: Boolean; override;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
function MeasureContentHeight(DC: HDC): Integer; override;
|
|
function MeasureContentWidth(DC: HDC): Integer; override;
|
|
|
|
property ImageLayout: TdxImageLayout read GetImageLayout write SetImageLayout default ilImageCenterLeft;
|
|
property ImageTransparent;
|
|
property IsTextDrawnForCenteredImage: Boolean read GetIsTextDrawnForCenteredImage write SetIsTextDrawnForCenteredImage default False;
|
|
property IsTextShiftedForHorizontallyCenteredImage: Boolean read GetIsTextShiftedForHorizontallyCenteredImage write SetIsTextShiftedForHorizontallyCenteredImage default True;
|
|
property MakeSpaceForEmptyImage: Boolean read GetMakeSpaceForEmptyImage write SetMakeSpaceForEmptyImage default True;
|
|
end;
|
|
|
|
TdxReportCellGraphicClass = class of TdxReportCellGraphic;
|
|
|
|
TdxReportCellGraphic = class(TCustomdxReportCellImageContainer)
|
|
private
|
|
function GetCenter: Boolean;
|
|
function GetDrawMode: TdxGraphicDrawMode;
|
|
function GetStretch: Boolean;
|
|
procedure SetCenter(Value: Boolean);
|
|
procedure SetDrawMode(Value: TdxGraphicDrawMode);
|
|
procedure SetStretch(Value: Boolean);
|
|
protected
|
|
function GetImageBounds(DC: HDC): TRect; override;
|
|
function GetImageBuffering: TdxCellImageBuffering; override;
|
|
function GetTextBounds(DC: HDC): TRect; override;
|
|
procedure SetImageBuffering(Value: TdxCellImageBuffering); override;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
//procedure Assign(Source: TPersistent); override;
|
|
|
|
function MeasureFontHeight(DC: HDC): Integer; override;
|
|
function MeasureContentHeight(DC: HDC): Integer; override;
|
|
function MeasureContentWidth(DC: HDC): Integer; override;
|
|
|
|
property Center: Boolean read GetCenter write SetCenter;
|
|
property DrawMode: TdxGraphicDrawMode read GetDrawMode write SetDrawMode default gdmNone;
|
|
property ImageBuffering;
|
|
property ImageTransparent;
|
|
property Stretch: Boolean read GetStretch write SetStretch;
|
|
end;
|
|
|
|
TdxReportCellExpandButtonAlignHorz = (bahLeft, bahCenter, bahRight);
|
|
TdxReportCellExpandButtonAlignVert = (bavTop, bavCenter, bavBottom);
|
|
|
|
TdxReportCellExpandButtonClass = class of TdxReportCellExpandButton;
|
|
|
|
TdxReportCellExpandButton = class(TAbstractdxReportCellData)
|
|
private
|
|
FButtonInteriorColor: TColor;
|
|
FButtonSize: Integer;
|
|
function GetActualButtonSize: Integer;
|
|
function GetButtonBorder3D: Boolean;
|
|
function GetButtonBorder3DSoft: Boolean;
|
|
function GetButtonBorderShadow: Boolean;
|
|
function GetButtonExpanded: Boolean;
|
|
function GetButtonTransparent: Boolean;
|
|
function GetKeepOddSize: Boolean;
|
|
function GetShowButton: Boolean;
|
|
function GetShowButtonBorder: Boolean;
|
|
function GetTreeLineMode: TdxPSTreeLineMode;
|
|
procedure SetButtonBorder3D(Value: Boolean);
|
|
procedure SetButtonBorder3DSoft(Value: Boolean);
|
|
procedure SetButtonBorderShadow(Value: Boolean);
|
|
procedure SetButtonExpanded(Value: Boolean);
|
|
procedure SetButtonTransparent(Value: Boolean);
|
|
procedure SetKeepOddSize(Value: Boolean);
|
|
procedure SetShowButton(Value: Boolean);
|
|
procedure SetShowButtonBorder(Value: Boolean);
|
|
procedure SetTreeLineMode(Value: TdxPSTreeLineMode);
|
|
protected
|
|
procedure ConvertCoords(APixelsNumerator, APixelsDenominator: Integer); override;
|
|
|
|
function AreTreeLinesDrawn: Boolean;
|
|
function CalculateButtonBounds: TRect; virtual;
|
|
|
|
function GetButtonAlignHorz: TdxReportCellExpandButtonAlignHorz; virtual;
|
|
function GetButtonAlignVert: TdxReportCellExpandButtonAlignVert; virtual;
|
|
function GetButtonIndents: TRect; virtual;
|
|
procedure SetButtonAlignHorz(Value: TdxReportCellExpandButtonAlignHorz); virtual;
|
|
procedure SetButtonAlignVert(Value: TdxReportCellExpandButtonAlignVert); virtual;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
public
|
|
constructor Create(AParent: TdxReportCell); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure DrawContent(DC: HDC; AStage: TdxPSRenderStages); override;
|
|
procedure DrawExpandButton(DC: HDC); virtual;
|
|
procedure DrawTreeLines(DC: HDC); virtual;
|
|
|
|
function GetButtonBounds(DC: HDC): TRect; virtual;
|
|
|
|
property ActualButtonSize: Integer read GetActualButtonSize;
|
|
property ButtonAlignHorz: TdxReportCellExpandButtonAlignHorz read GetButtonAlignHorz write SetButtonAlignHorz default bahCenter;
|
|
property ButtonAlignVert: TdxReportCellExpandButtonAlignVert read GetButtonAlignVert write SetButtonAlignVert default bavCenter;
|
|
property ButtonBorder3D: Boolean read GetButtonBorder3D write SetButtonBorder3D default False;
|
|
property ButtonBorder3DSoft: Boolean read GetButtonBorder3DSoft write SetButtonBorder3DSoft default False;
|
|
property ButtonBorderShadow: Boolean read GetButtonBorderShadow write SetButtonBorderShadow default False;
|
|
property ButtonExpanded: Boolean read GetButtonExpanded write SetButtonExpanded default False;
|
|
property ButtonIndents: TRect read GetButtonIndents;
|
|
property ButtonInteriorColor: TColor read FButtonInteriorColor write FButtonInteriorColor default clNone;
|
|
property ButtonSize: Integer read FButtonSize write FButtonSize default 9;
|
|
property ButtonTransparent: Boolean read GetButtonTransparent write SetButtonTransparent default True;
|
|
property KeepOddSize: Boolean read GetKeepOddSize write SetKeepOddSize default True;
|
|
property ShowButton: Boolean read GetShowButton write SetShowButton default False;
|
|
property ShowButtonBorder: Boolean read GetShowButtonBorder write SetShowButtonBorder default True;
|
|
property TreeLineMode: TdxPSTreeLineMode read GetTreeLineMode write SetTreeLineMode default tlmNone;
|
|
end;
|
|
|
|
TdxReportCellExpandButtonEx = class(TdxReportCellExpandButton)
|
|
private
|
|
FFormatEx: DWORD;
|
|
protected
|
|
function GetButtonAlignHorz: TdxReportCellExpandButtonAlignHorz; override;
|
|
function GetButtonAlignVert: TdxReportCellExpandButtonAlignVert; override;
|
|
function GetButtonIndents: TRect; override;
|
|
procedure SetButtonAlignHorz(Value: TdxReportCellExpandButtonAlignHorz); override;
|
|
procedure SetButtonAlignVert(Value: TdxReportCellExpandButtonAlignVert); override;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); override;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); override;
|
|
|
|
property FormatEx: DWORD read FFormatEx write FFormatEx;
|
|
end;
|
|
|
|
{ Explorer }
|
|
|
|
TdxPSExplorerRefreshStage = (ersBefore, ersAfter);
|
|
|
|
TCustomdxPSExplorerItemStateInfo = record
|
|
Count: Integer;
|
|
UniqueIDSize: Integer;
|
|
// UniqueID: TBytes follows by UniqueIDSize with Length UniqueIDSize
|
|
end;
|
|
|
|
TCustomdxPSExplorer = class;
|
|
TCustomdxPSExplorerItem = class;
|
|
TdxPSExplorerFolder = class;
|
|
TdxPSExplorerItem = class;
|
|
|
|
|
|
IdxPSExplorerTreeContainerHost = interface
|
|
['{4E52E062-EDCF-4A58-8212-45EAE673F506}']
|
|
function GetFlat: Boolean;
|
|
function GetReportLink: TBasedxReportLink;
|
|
function GetTreeContainerParent: TWinControl;
|
|
|
|
procedure UpdateState;
|
|
|
|
property Flat: Boolean read GetFlat;
|
|
property ReportLink: TBasedxReportLink read GetReportLink;
|
|
property TreeContainerParent: TWinControl read GetTreeContainerParent;
|
|
end;
|
|
|
|
|
|
TdxPSExplorerChangeNotifier = class
|
|
private
|
|
FExplorer: TCustomdxPSExplorer;
|
|
procedure SetExplorer(Value: TCustomdxPSExplorer);
|
|
protected
|
|
procedure ExplorerRefresh(AStage: TdxPSExplorerRefreshStage); virtual; abstract;
|
|
procedure FolderPopulated(AFolder: TdxPSExplorerFolder); virtual; abstract;
|
|
procedure ItemAdded(AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
procedure ItemDataLoaded(AnItem: TdxPSExplorerItem); virtual; abstract;
|
|
procedure ItemDataUnloaded(AnItem: TdxPSExplorerItem); virtual; abstract;
|
|
procedure ItemDeleted(AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
procedure ItemParentChanged(AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
procedure ItemPropertiesChanged(AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
procedure ItemRenamed(AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
public
|
|
constructor Create(AnExplorer: TCustomdxPSExplorer);
|
|
destructor Destroy; override;
|
|
|
|
property Explorer: TCustomdxPSExplorer read FExplorer write SetExplorer;
|
|
end;
|
|
|
|
TdxPSExplorerChangeNotifierAdapter = class(TdxPSExplorerChangeNotifier)
|
|
protected
|
|
procedure ExplorerRefresh(AStage: TdxPSExplorerRefreshStage); override;
|
|
procedure FolderPopulated(AFolder: TdxPSExplorerFolder); override;
|
|
procedure ItemAdded(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure ItemDataLoaded(AnItem: TdxPSExplorerItem); override;
|
|
procedure ItemDataUnloaded(AnItem: TdxPSExplorerItem); override;
|
|
procedure ItemDeleted(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure ItemParentChanged(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure ItemPropertiesChanged(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure ItemRenamed(AnItem: TCustomdxPSExplorerItem); override;
|
|
end;
|
|
|
|
TdxPSExplorerTreeChangeNotifier = class(TdxPSExplorerChangeNotifierAdapter)
|
|
private
|
|
FTreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
protected
|
|
procedure ExplorerRefresh(AStage: TdxPSExplorerRefreshStage); override;
|
|
procedure FolderPopulated(AFolder: TdxPSExplorerFolder); override;
|
|
procedure ItemAdded(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure ItemDataLoaded(AnItem: TdxPSExplorerItem); override;
|
|
procedure ItemDataUnloaded(AnItem: TdxPSExplorerItem); override;
|
|
procedure ItemDeleted(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure ItemParentChanged(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure ItemPropertiesChanged(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure ItemRenamed(AnItem: TCustomdxPSExplorerItem); override;
|
|
public
|
|
constructor Create(ATreeContainer: TCustomdxPSExplorerTreeContainer; ARegister: Boolean = True);
|
|
property TreeContainer: TCustomdxPSExplorerTreeContainer read FTreeContainer;
|
|
end;
|
|
|
|
TCustomdxPSExplorerTreeContainerClass = class of TCustomdxPSExplorerTreeContainer;
|
|
|
|
TCustomdxPSExplorerTreeContainer = class
|
|
private
|
|
FControl: TWinControl;
|
|
FChangeNotifier: TdxPSExplorerTreeChangeNotifier;
|
|
FExplorer: TCustomdxPSExplorer;
|
|
FHost: IdxPSExplorerTreeContainerHost;
|
|
protected
|
|
{ Next virtual (abstract) methods must be overriden in descendants }
|
|
procedure AddItem(AParent: TdxPSExplorerFolder; AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
procedure Clear; virtual; abstract;
|
|
procedure DeleteItem(AnItem: TCustomdxPSExplorerItem); virtual;
|
|
procedure InvalidateItem(AnItem: TCustomdxPSExplorerItem); virtual;
|
|
procedure MoveItem(AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
procedure RenameItem(AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
|
|
function GetCreationParent: TdxPSExplorerFolder; virtual; abstract;
|
|
function GetFocusedItem: TCustomdxPSExplorerItem; virtual; abstract;
|
|
function GetIsEditing: Boolean; virtual; abstract;
|
|
function GetIsFolderSelected: Boolean; virtual; abstract;
|
|
function GetIsItemSelected: Boolean; virtual; abstract;
|
|
function GetIsRootSelected: Boolean; virtual; abstract;
|
|
function GetSelectedFolder: TdxPSExplorerFolder; virtual; abstract;
|
|
function GetSelectedItem: TCustomdxPSExplorerItem; virtual; abstract;
|
|
function GetSelectedItemText: string; virtual; abstract;
|
|
procedure SetFocusedItem(Value: TCustomdxPSExplorerItem); virtual; abstract;
|
|
procedure SetSelectedItem(Value: TCustomdxPSExplorerItem); virtual; abstract;
|
|
procedure SetSelectedItemText(const Value: string); virtual; abstract;
|
|
|
|
procedure RestoreState; virtual;
|
|
procedure SaveState; virtual;
|
|
|
|
procedure CreateTreeContainer;
|
|
procedure InitializeTreeContainer; virtual;
|
|
procedure ProcessKeyDown(var Key: Word; Shift: TShiftState); virtual;
|
|
procedure ProcessKeyPress(var Key: Char); virtual;
|
|
|
|
property ChangeNotifier: TdxPSExplorerTreeChangeNotifier read FChangeNotifier;
|
|
property Host: IdxPSExplorerTreeContainerHost read FHost;
|
|
public
|
|
constructor Create(AnExplorer: TCustomdxPSExplorer; AHost: IdxPSExplorerTreeContainerHost); virtual;
|
|
destructor Destroy; override;
|
|
|
|
class function ControlClass: TWinControlClass; virtual;
|
|
class procedure Register;
|
|
class procedure Unregister;
|
|
|
|
procedure BeginUpdate; virtual;
|
|
procedure EndUpdate; virtual;
|
|
|
|
{ Follow virtual (abstract) methods must be overriden in descendants }
|
|
function BeginEdit(AnImmediate: Boolean = True): Boolean; virtual; abstract;
|
|
procedure EndEdit(ACancel: Boolean); virtual; abstract;
|
|
|
|
procedure CollapseItem(AnItem: TCustomdxPSExplorerItem; ARecursive: Boolean = False); virtual; abstract;
|
|
procedure ExpandItem(AnItem: TCustomdxPSExplorerItem; ARecursive: Boolean = False); virtual; abstract;
|
|
procedure MakeItemVisible(AnItem: TCustomdxPSExplorerItem); virtual; abstract;
|
|
|
|
function CanCreateFolder: Boolean; virtual;
|
|
function CanCreateItem: Boolean; virtual;
|
|
function CanDeleteSelection: Boolean; virtual;
|
|
function CanLoadSelectedItemData: Boolean; virtual;
|
|
function CanRefresh: Boolean; virtual;
|
|
function CanRenameSelectedItem: Boolean; virtual;
|
|
function CanShowPropertySheetsForSelectedItem: Boolean; virtual;
|
|
function CanUnloadItemData: Boolean; virtual;
|
|
function CreateItem: TdxPSExplorerItem; virtual;
|
|
procedure DeleteSelection(AShowMessage: Boolean = True); virtual;
|
|
function IsSelectedItemCurrentlyLoaded: Boolean;
|
|
procedure LoadSelectedItemData; virtual;
|
|
procedure RenameSelectedItem; virtual;
|
|
function ShowSelectedItemPropertySheets: Boolean;
|
|
procedure UnloadItemData; virtual;
|
|
|
|
{ Follow abstract methods must be overriden in descendants }
|
|
function GetDropTarget(X, Y: Integer): TdxPSExplorerFolder; virtual; abstract;
|
|
function GetItemAt(X, Y: Integer): TCustomdxPSExplorerItem; virtual; abstract;
|
|
|
|
function CanFocus: Boolean; virtual;
|
|
procedure SetFocus; virtual;
|
|
|
|
procedure RefreshSorting(ANode: TObject); overload; virtual;
|
|
procedure RefreshSorting(AFolder: TdxPSExplorerFolder); overload; virtual;
|
|
|
|
property Control: TWinControl read FControl;
|
|
property CreationParent: TdxPSExplorerFolder read GetCreationParent;
|
|
property Explorer: TCustomdxPSExplorer read FExplorer;
|
|
property FocusedItem: TCustomdxPSExplorerItem read GetFocusedItem write SetFocusedItem;
|
|
property IsEditing: Boolean read GetIsEditing;
|
|
property IsFolderSelected: Boolean read GetIsFolderSelected;
|
|
property IsItemSelected: Boolean read GetIsItemSelected;
|
|
property IsRootSelected: Boolean read GetIsRootSelected;
|
|
property SelectedFolder: TdxPSExplorerFolder read GetSelectedFolder;
|
|
property SelectedItem: TCustomdxPSExplorerItem read GetSelectedItem write SetSelectedItem;
|
|
property SelectedItemText: string read GetSelectedItemText write SetSelectedItemText;
|
|
end;
|
|
|
|
TdxPSExplorerTreeBuilderClass = class of TdxPSExplorerTreeBuilder;
|
|
|
|
TdxPSExplorerTreeBuilder = class
|
|
protected
|
|
class procedure BuildTree(AnExplorer: TCustomdxPSExplorer;
|
|
ATreeContainer: TCustomdxPSExplorerTreeContainer); virtual;
|
|
class procedure CreateFolderNode(ATreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
AParent, AFolder: TdxPSExplorerFolder); virtual;
|
|
class procedure CreateItemNode(ATreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
AParent: TdxPSExplorerFolder; AnItem: TCustomdxPSExplorerItem); virtual;
|
|
class procedure PopulateTreeFolder(ATreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
AFolder: TdxPSExplorerFolder); virtual;
|
|
public
|
|
class procedure Register;
|
|
class procedure Unregister;
|
|
end;
|
|
|
|
TdxPSStreamMode = (smRead, smWrite, smReadWrite);
|
|
|
|
TCustomdxPSExplorerItemPropertySheetsClass = class of TCustomdxPSExplorerItemPropertySheets;
|
|
|
|
TCustomdxPSExplorerItemPropertySheets = class(TCustomdxPSForm)
|
|
private
|
|
FExplorerItem: TCustomdxPSExplorerItem;
|
|
class function FormClass: TCustomdxPSExplorerItemPropertySheetsClass;
|
|
protected
|
|
procedure Done; virtual;
|
|
procedure Initialize; virtual;
|
|
public
|
|
constructor CreateEx(AnExplorerItem: TCustomdxPSExplorerItem); virtual;
|
|
|
|
class function Execute(AnExplorerItem: TCustomdxPSExplorerItem): Boolean;
|
|
function ExplorerItem: TCustomdxPSExplorerItem; overload; virtual;
|
|
end;
|
|
|
|
TCustomdxPSExplorerItemComparator = class
|
|
public
|
|
class function CompareItems(AnItem1, AnItem2: Pointer): Integer;
|
|
end;
|
|
|
|
TCustomdxPSExplorerItemHelper = class
|
|
public
|
|
class function GetHasChildren(AFolder: TdxPSExplorerFolder): Boolean; virtual;
|
|
class function GetImageIndex(AnItem: TCustomdxPSExplorerItem): Integer; virtual;
|
|
class function GetSelectedIndex(AnItem: TCustomdxPSExplorerItem): Integer; virtual;
|
|
class procedure SetHasChildren(AFolder: TdxPSExplorerFolder; Value: Boolean); virtual;
|
|
end;
|
|
|
|
TCustomdxPSExplorerItemClass = class of TCustomdxPSExplorerItem;
|
|
|
|
TCustomdxPSExplorerItem = class
|
|
private
|
|
FExplorer: TCustomdxPSExplorer;
|
|
FName: string;
|
|
FParent: TdxPSExplorerFolder;
|
|
FWindowHandle: HWND;
|
|
procedure SetParent(Value: TdxPSExplorerFolder);
|
|
protected
|
|
function CompareTo(AnItem: TCustomdxPSExplorerItem): Integer; virtual;
|
|
|
|
function DoDelete: Boolean; virtual;
|
|
function DoMove(AParent: TdxPSExplorerFolder): Boolean; virtual;
|
|
function DoRename(var ANewName: string): Boolean; virtual;
|
|
|
|
function GetDisplayName: string; virtual;
|
|
function GetImageIndex: Integer; virtual;
|
|
function GetInfoTip: string; virtual;
|
|
function GetNewName(AReportLink: TBasedxReportLink): string; virtual;
|
|
function GetSelectedIndex: Integer; virtual;
|
|
|
|
procedure InternalDelete; virtual;
|
|
procedure InternalMove(AParent: TdxPSExplorerFolder); virtual;
|
|
procedure InternalRename(const AName: string); virtual;
|
|
procedure SetName(const Value: string); virtual;
|
|
|
|
function GetItemStateInfo: TCustomdxPSExplorerItemStateInfo; virtual;
|
|
procedure WriteState(AStream: TStream); virtual;
|
|
|
|
procedure WndProc(var Message: TMessage); virtual;
|
|
public
|
|
constructor Create(AnExplorer: TCustomdxPSExplorer; AParent: TdxPSExplorerFolder); virtual;
|
|
destructor Destroy; override;
|
|
|
|
function Explorer: TCustomdxPSExplorer; overload; virtual;
|
|
|
|
function CanAccept(AnItem: TCustomdxPSExplorerItem): Boolean; virtual;
|
|
function CanDelete: Boolean; virtual;
|
|
function CanMove: Boolean; virtual;
|
|
function CanMoveTo(AParent: TCustomdxPSExplorerItem): Boolean; overload; virtual;
|
|
function CanRename: Boolean; virtual;
|
|
function CanRenameTo(const AName: string): Boolean; virtual;
|
|
procedure Delete; virtual;
|
|
function GetUniqueID(out AnUniqueID: TBytes): Integer; virtual; // returns Length of needed memory
|
|
function HasAsParent(AnItem: TCustomdxPSExplorerItem): Boolean;
|
|
function IsNameChanged(const ANewName: string): Boolean; virtual;
|
|
|
|
class function HasPropertySheets: Boolean;
|
|
class function PropertySheetsClass: TCustomdxPSExplorerItemPropertySheetsClass; virtual;
|
|
function ShowPropertySheets: Boolean;
|
|
|
|
function CannotRenameMessageText(const AOldName, ANewName: string): string; virtual;
|
|
function DeleteMessageText: string; virtual;
|
|
function OverwriteMessageText(Dest: TCustomdxPSExplorerItem): string; virtual;
|
|
|
|
property DisplayName: string read GetDisplayName;
|
|
property InfoTip: string read GetInfoTip;
|
|
property Name: string read FName write SetName;
|
|
property Parent: TdxPSExplorerFolder read FParent write SetParent;
|
|
end;
|
|
|
|
TdxPSExplorerFolderHelper = class(TCustomdxPSExplorerItemHelper)
|
|
public
|
|
class function GetHasChildren(AFolder: TdxPSExplorerFolder): Boolean; override;
|
|
class procedure SetHasChildren(AFolder: TdxPSExplorerFolder; Value: Boolean); override;
|
|
end;
|
|
|
|
TdxPSExplorerFolderClass = class of TdxPSExplorerFolder;
|
|
|
|
TdxPSExplorerFolder = class(TCustomdxPSExplorerItem)
|
|
private
|
|
FFolders: TList;
|
|
FHasChildren: Boolean;
|
|
FItems: TList;
|
|
function GetFolder(Index: Integer): TdxPSExplorerFolder;
|
|
function GetFolderCount: Integer;
|
|
function GetHasChildren: Boolean;
|
|
function GetIsRoot: Boolean;
|
|
function GetItem(Index: Integer): TdxPSExplorerItem;
|
|
function GetItemCount: Integer;
|
|
function GetItemList(AnItem: TCustomdxPSExplorerItem): TList; overload;
|
|
function GetItemList(AnItemClass: TCustomdxPSExplorerItemClass): TList; overload;
|
|
procedure SetHasChildren(Value: Boolean);
|
|
protected
|
|
function CompareTo(AnItem: TCustomdxPSExplorerItem): Integer; override;
|
|
function GetImageIndex: Integer; override;
|
|
function GetNewName(AReportLink: TBasedxReportLink): string; override;
|
|
function GetSelectedIndex: Integer; override;
|
|
|
|
function GetItemStateInfo: TCustomdxPSExplorerItemStateInfo; override;
|
|
procedure WriteState(AStream: TStream); override;
|
|
|
|
procedure LoadData; virtual;
|
|
|
|
procedure Add(AnItem: TCustomdxPSExplorerItem);
|
|
procedure Remove(AnItem: TCustomdxPSExplorerItem);
|
|
|
|
procedure FreeAndNilFolders;
|
|
procedure FreeAndNilItems;
|
|
|
|
property HasChildren: Boolean read GetHasChildren write SetHasChildren;
|
|
public
|
|
constructor Create(AnExplorer: TCustomdxPSExplorer; AParent: TdxPSExplorerFolder); override;
|
|
destructor Destroy; override;
|
|
|
|
function CanAccept(AnItem: TCustomdxPSExplorerItem): Boolean; override;
|
|
function CanRenameTo(const AName: string): Boolean; override;
|
|
function CreateFolder: TdxPSExplorerFolder; virtual;
|
|
function CreateItem(AReportLink: TBasedxReportLink): TdxPSExplorerItem; virtual;
|
|
procedure Populate;
|
|
|
|
procedure Delete; override;
|
|
procedure DeleteFolders; virtual;
|
|
procedure DeleteItems; virtual;
|
|
|
|
function HasFolders: Boolean; virtual;
|
|
function HasItems: Boolean; virtual;
|
|
function HasLoadedItem: Boolean; virtual;
|
|
|
|
function FolderByName(const AName: string): TdxPSExplorerFolder; virtual;
|
|
function ItemByName(const AName: string): TdxPSExplorerItem; virtual;
|
|
|
|
function CannotRenameMessageText(const AOldName, ANewName: string): string; override;
|
|
function DeleteMessageText: string; override;
|
|
function OverwriteMessageText(Dest: TCustomdxPSExplorerItem): string; override;
|
|
|
|
property FolderCount: Integer read GetFolderCount;
|
|
property Folders[Index: Integer]: TdxPSExplorerFolder read GetFolder; default;
|
|
property IsRoot: Boolean read GetIsRoot;
|
|
property ItemCount: Integer read GetItemCount;
|
|
property Items[Index: Integer]: TdxPSExplorerItem read GetItem;
|
|
end;
|
|
|
|
TdxPSExplorerItemClass = class of TdxPSExplorerItem;
|
|
|
|
TdxPSExplorerItem = class(TCustomdxPSExplorerItem)
|
|
private
|
|
FHasInvalidData: Boolean;
|
|
FReportDocument: TdxPSReportDocument;
|
|
function GetIsCurrentlyLoaded: Boolean;
|
|
procedure SetHasInvalidData(Value: Boolean);
|
|
protected
|
|
function CompareTo(AnItem: TCustomdxPSExplorerItem): Integer; override;
|
|
function DoDelete: Boolean; override;
|
|
function GetFormCaption: string; virtual;
|
|
function GetImageIndex: Integer; override;
|
|
function GetInfoTip: string; override;
|
|
function GetNewName(AReportLink: TBasedxReportLink): string; override;
|
|
function GetSelectedIndex: Integer; override;
|
|
procedure InternalDelete; override;
|
|
|
|
procedure DocumentChanged(Sender: TObject); virtual;
|
|
procedure SaveDocument; virtual;
|
|
|
|
procedure SetReportData(AReportLink: TBasedxReportLink); virtual;
|
|
|
|
property FormCaption: string read GetFormCaption;
|
|
public
|
|
constructor Create(AnExplorer: TCustomdxPSExplorer; AParent: TdxPSExplorerFolder); override;
|
|
destructor Destroy; override;
|
|
|
|
function CanLoadData: Boolean; virtual;
|
|
function CanRenameTo(const AName: string): Boolean; override;
|
|
|
|
function CannotRenameMessageText(const AOldName, ANewName: string): string; override;
|
|
function DataLoadErrorText: string; virtual;
|
|
function DeleteMessageText: string; override;
|
|
function OverwriteMessageText(Dest: TCustomdxPSExplorerItem): string; override;
|
|
|
|
function CreateDataStream(AMode: TdxPSStreamMode): TStream; virtual;
|
|
procedure RetrieveReportData(AReportLink: TBasedxReportLink); virtual;
|
|
|
|
function IsLoading: Boolean; virtual;
|
|
procedure Load(AReportLink: TBasedxReportLink);
|
|
procedure Unload;
|
|
|
|
class function PropertySheetsClass: TCustomdxPSExplorerItemPropertySheetsClass; override;
|
|
|
|
property HasInvalidData: Boolean read FHasInvalidData write SetHasInvalidData;
|
|
property IsCurrentlyLoaded: Boolean read GetIsCurrentlyLoaded;
|
|
property ReportDocument: TdxPSReportDocument read FReportDocument;
|
|
end;
|
|
|
|
TCustomdxPSExplorerContextCommandClass = class of TCustomdxPSExplorerContextCommand;
|
|
|
|
TCustomdxPSExplorerContextCommand = class(TPersistent)
|
|
private
|
|
FBitmap: TBitmap;
|
|
FCaption: string;
|
|
FData: Integer;
|
|
FExplorer: TCustomdxPSExplorer;
|
|
FHint: string;
|
|
FShortCut: TShortCut;
|
|
procedure SetBitmap(Value: TBitmap);
|
|
public
|
|
constructor Create(AnExplorer: TCustomdxPSExplorer); virtual;
|
|
destructor Destroy; override;
|
|
|
|
function Enabled: Boolean; virtual;
|
|
procedure Execute; virtual;
|
|
|
|
function Explorer: TCustomdxPSExplorer; overload; virtual;
|
|
|
|
property Bitmap: TBitmap read FBitmap write SetBitmap;
|
|
property Caption: string read FCaption write FCaption;
|
|
property Data: Integer read FData Write FData;
|
|
property Hint: string read FHint write FHint;
|
|
property ShortCut: TShortCut read FShortCut write FShortCut;
|
|
end;
|
|
|
|
TdxPSExplorerContextCommandSeparator = class(TCustomdxPSExplorerContextCommand)
|
|
public
|
|
constructor Create(AnExplorer: TCustomdxPSExplorer); override;
|
|
function Enabled: Boolean; override;
|
|
end;
|
|
|
|
TdxPSExplorerRefreshContextCommand = class(TCustomdxPSExplorerContextCommand)
|
|
public
|
|
constructor Create(AnExplorer: TCustomdxPSExplorer); override;
|
|
procedure Execute; override;
|
|
end;
|
|
|
|
TdxPSExplorerState = (esItemCreating, esFolderCreating, esLoading, esRefreshing);
|
|
TdxPSExplorerStates = set of TdxPSExplorerState;
|
|
|
|
TdxPSExplorerItemDataLoadErrorEvent = procedure(Sender: TCustomdxPSExplorer;
|
|
AnItem: TdxPSExplorerItem; var AShowErrorMessage: Boolean; var AText: string) of object;
|
|
|
|
TdxPSExplorerClass = class of TCustomdxPSExplorer;
|
|
|
|
TCustomdxPSExplorer = class(TComponent, {$IFNDEF DELPHI6} IUnknown, {$ENDIF}
|
|
IdxPSExplorerContextCommands, IdxPSExplorerContextCommands2)
|
|
private
|
|
FActiveFolder: TdxPSExplorerFolder;
|
|
FCommands: TList;
|
|
FFilterLinkClass: TComponentClass;
|
|
FLoadedItem: TdxPSExplorerItem;
|
|
FLoadingCounter: Integer;
|
|
FLockCounter: Integer;
|
|
FNotifiers: TList;
|
|
FRefreshCounter: Integer;
|
|
FRoot: TdxPSExplorerFolder;
|
|
FState: TdxPSExplorerStates;
|
|
FStateStream: TStream;
|
|
FOnItemDataLoadError: TdxPSExplorerItemDataLoadErrorEvent;
|
|
function GetCommand(Index: Integer): TCustomdxPSExplorerContextCommand;
|
|
function GetCommandCount: Integer;
|
|
function GetFilterLink: string;
|
|
function GetNotifier(Index: Integer): TdxPSExplorerChangeNotifier;
|
|
function GetNotifierCount: Integer;
|
|
function GetRoot: TdxPSExplorerFolder;
|
|
procedure SetFilterLink(const Value: string);
|
|
protected
|
|
{$IFNDEF DELPHI6}
|
|
{ IUnknown }
|
|
function QueryInterface(const IID: TGUID; out Obj): HRESULT; override;
|
|
function _Addref: Integer; stdcall;
|
|
function _Release: Integer; stdcall;
|
|
{$ENDIF}
|
|
|
|
{ IdxPSExplorerContextCommands }
|
|
procedure BuildCommandSet(ABuilder: IdxPSExplorerContextCommandBuilder); virtual;
|
|
{ IdxPSExplorerContextCommands2 }
|
|
procedure FinalizeCommand(ACommand: TCustomdxPSExplorerContextCommand); virtual;
|
|
procedure InitializeCommand(ACommand: TCustomdxPSExplorerContextCommand); virtual;
|
|
|
|
function AddCommand(ACommandClass: TCustomdxPSExplorerContextCommandClass): TCustomdxPSExplorerContextCommand;
|
|
function AddCommandSeparator: TdxPSExplorerContextCommandSeparator;
|
|
procedure ClearCommands;
|
|
function CreateCommand(ACommandClass: TCustomdxPSExplorerContextCommandClass): TCustomdxPSExplorerContextCommand;
|
|
function CreateCommandSeparator: TdxPSExplorerContextCommandSeparator;
|
|
function FindCommand(ACommandClass: TCustomdxPSExplorerContextCommandClass): TCustomdxPSExplorerContextCommand;
|
|
procedure FreeAndNilCommands;
|
|
|
|
class function AcceptItemNameChar(AnItem: TCustomdxPSExplorerItem; Ch: Char): Boolean; virtual;
|
|
function CreateItemDataStream(AnItem: TdxPSExplorerItem; AMode: TdxPSStreamMode): TStream; virtual; abstract;
|
|
class function GetFolderClass: TdxPSExplorerFolderClass; virtual;
|
|
class function GetItemClass: TdxPSExplorerItemClass; virtual;
|
|
class function GetRootFolderClass: TdxPSExplorerFolderClass; virtual;
|
|
function GetRootDisplayName: string; virtual;
|
|
procedure LoadData(AFolder: TdxPSExplorerFolder);
|
|
|
|
function CanDelete(AnItem: TCustomdxPSExplorerItem): Boolean; virtual;
|
|
function CanMove(AnItem: TCustomdxPSExplorerItem): Boolean; virtual;
|
|
function CanMoveTo(AnItem, AParent: TCustomdxPSExplorerItem): Boolean; virtual;
|
|
function CanRename(AnItem: TCustomdxPSExplorerItem): Boolean; virtual;
|
|
function CanRenameTo(AnItem: TCustomdxPSExplorerItem; const AName: string): Boolean; virtual;
|
|
procedure Delete(AnItem: TCustomdxPSExplorerItem); virtual;
|
|
procedure MoveTo(AnItem: TCustomdxPSExplorerItem; AParent: TdxPSExplorerFolder); virtual;
|
|
procedure PopulateFolder(AFolder: TdxPSExplorerFolder); virtual;
|
|
procedure RenameTo(AnItem: TCustomdxPSExplorerItem; AName: string); virtual;
|
|
|
|
procedure AfterRefresh;
|
|
procedure BeforeRefresh;
|
|
procedure DoRefresh; virtual;
|
|
procedure RootNeeded;
|
|
|
|
procedure DoItemDataLoadError(AnItem: TdxPSExplorerItem); dynamic;
|
|
procedure DoLoadData(AFolder: TdxPSExplorerFolder); virtual; abstract;
|
|
procedure InternalSetLoadedItem(Value: TdxPSExplorerItem);
|
|
|
|
procedure PopulateTreeFolder(ATreeContainer: TCustomdxPSExplorerTreeContainer; AFolder: TdxPSExplorerFolder);
|
|
|
|
procedure LoadState;
|
|
procedure SaveState;
|
|
|
|
procedure NotifyFolderPopulated(AFolder: TdxPSExplorerFolder);
|
|
procedure NotifyItemAdded(AnItem: TCustomdxPSExplorerItem);
|
|
procedure NotifyItemDataLoaded(AnItem: TdxPSExplorerItem);
|
|
procedure NotifyItemDataUnloaded(AnItem: TdxPSExplorerItem);
|
|
procedure NotifyItemDeleted(AnItem: TCustomdxPSExplorerItem);
|
|
procedure NotifyItemParentChanged(AnItem: TCustomdxPSExplorerItem);
|
|
procedure NotifyItemPropertiesChanged(AnItem: TCustomdxPSExplorerItem);
|
|
procedure NotifyItemRenamed(AnItem: TCustomdxPSExplorerItem);
|
|
procedure NotifyRefresh(AStage: TdxPSExplorerRefreshStage);
|
|
|
|
function AreNotificationsLocked: Boolean;
|
|
function IndexOfNotifier(ANotifier: TdxPSExplorerChangeNotifier): Integer;
|
|
procedure LockNotifications;
|
|
procedure ReleaseAndNilNotifiers;
|
|
procedure UnlockNotifications;
|
|
|
|
procedure BeginLoading;
|
|
procedure EndLoading;
|
|
function IsLoading: Boolean;
|
|
|
|
property CommandCount: Integer read GetCommandCount;
|
|
property Commands[Index: Integer]: TCustomdxPSExplorerContextCommand read GetCommand;
|
|
property NotifierCount: Integer read GetNotifierCount;
|
|
property Notifiers[Index: Integer]: TdxPSExplorerChangeNotifier read GetNotifier;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
function LoadedItem: TdxPSExplorerItem; overload; virtual;
|
|
|
|
function CanCreateFolder: Boolean; virtual;
|
|
function CanCreateItem: Boolean; virtual;
|
|
function CreateNewFolder(AParent: TdxPSExplorerFolder): TdxPSExplorerFolder; virtual;
|
|
function CreateNewItem(AParent: TdxPSExplorerFolder; AReportLink: TBasedxReportLink): TdxPSExplorerItem; virtual;
|
|
|
|
procedure BuildTree(ATreeContainer: TCustomdxPSExplorerTreeContainer);
|
|
function CreateTree(const AHost: IdxPSExplorerTreeContainerHost): TCustomdxPSExplorerTreeContainer;
|
|
|
|
function FindCustomItemByUniqueID(const AnUniqueID: TBytes): TCustomdxPSExplorerItem; virtual;
|
|
procedure LoadItemData(AnItem: TdxPSExplorerItem; AReportLink: TBasedxReportLink); overload;
|
|
procedure UnloadItemData(AnItem: TdxPSExplorerItem); overload;
|
|
procedure Refresh; virtual;
|
|
|
|
procedure RegisterNotifier(ANotifier: TdxPSExplorerChangeNotifier);
|
|
procedure UnregisterNotifier(ANotifier: TdxPSExplorerChangeNotifier);
|
|
|
|
property ActiveFolder: TdxPSExplorerFolder read FActiveFolder Write FActiveFolder;
|
|
property FilterLinkClass: TComponentClass read FFilterLinkClass write FFilterLinkClass;
|
|
property Root: TdxPSExplorerFolder read GetRoot;
|
|
property State: TdxPSExplorerStates read FState;
|
|
published
|
|
property FilterLink: string read GetFilterLink write SetFilterLink;
|
|
property OnItemDataLoadError: TdxPSExplorerItemDataLoadErrorEvent read FOnItemDataLoadError write FOnItemDataLoadError;
|
|
end;
|
|
|
|
TdxReportFootNoteMode = (fnmNone, fnmOnLastPage, fnmOnEveryBottomPage);
|
|
TdxReportTitleMode = (tmNone, tmOnFirstPage, tmOnEveryTopPage);
|
|
|
|
TdxReportTitle = class(TPersistent)
|
|
private
|
|
FAdjustOnReportScale: Boolean;
|
|
FColor: TColor;
|
|
FDefaultFont: TFont;
|
|
FFont: TFont;
|
|
FLockCalcViewInfos: Boolean;
|
|
FMode: TdxReportTitleMode;
|
|
FReportLink: TBasedxReportLink;
|
|
FText: string;
|
|
FTextAlignX: TdxTextAlignX;
|
|
FTextAlignY: TdxTextAlignY;
|
|
FTransparent: Boolean;
|
|
FUpdateCount: Integer;
|
|
function IsFontStored: Boolean;
|
|
procedure SetAdjustOnReportScale(Value: Boolean);
|
|
procedure SetColor(Value: TColor);
|
|
procedure SetFont(Value: TFont);
|
|
procedure SetMode(Value: TdxReportTitleMode);
|
|
procedure SetText(const Value: string);
|
|
procedure SetTextAlignX(Value: TdxTextAlignX);
|
|
procedure SetTextAlignY(Value: TdxTextAlignY);
|
|
procedure SetTransparent(Value: Boolean);
|
|
|
|
procedure CalculateRenderInfos;
|
|
procedure FontChanged(Sender: TObject);
|
|
protected
|
|
procedure DoRestoreDefaults; virtual;
|
|
procedure InitializeDefaultFont(AFont: TFont); virtual;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
|
|
property LockCalcViewInfos: Boolean read FLockCalcViewInfos;
|
|
public
|
|
constructor Create(AReportLink: TBasedxReportLink);
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure BeginUpdate;
|
|
procedure CancelUpdate;
|
|
procedure EndUpdate;
|
|
|
|
function DefaultFont: TFont; virtual;
|
|
procedure RestoreDefaults;
|
|
|
|
property ReportLink: TBasedxReportLink read FReportLink;
|
|
published
|
|
property AdjustOnReportScale: Boolean read FAdjustOnReportScale write SetAdjustOnReportScale default False;
|
|
property Color: TColor read FColor write SetColor default clWhite;
|
|
property Font: TFont read FFont write SetFont stored IsFontStored;
|
|
property Mode: TdxReportTitleMode read FMode write SetMode default tmOnEveryTopPage;
|
|
property Text: string read FText write SetText;
|
|
property TextAlignX: TdxTextAlignX read FTextAlignX write SetTextAlignX default taCenterX;
|
|
property TextAlignY: TdxTextAlignY read FTextAlignY write SetTextAlignY default taCenterY;
|
|
property Transparent: Boolean read FTransparent write SetTransparent default True;
|
|
end;
|
|
|
|
TdxPSReportDocumentClass = class of TdxPSReportDocument;
|
|
|
|
TdxPSReportDocument = class(TPersistent)
|
|
private
|
|
FCaption: string;
|
|
FCreationDate: TDateTime;
|
|
FCreator: string;
|
|
FDescription: string;
|
|
FIsCaptionAssigned: Boolean;
|
|
FIsCreatorAssigned: Boolean;
|
|
FIsDescriptionAssigned: Boolean;
|
|
FPreview: TMetafile;
|
|
FReportLink: TBasedxReportLink;
|
|
FUpdateCount: Integer;
|
|
FOnChanged: TNotifyEvent;
|
|
function GetCaption: string;
|
|
function GetCreator: string;
|
|
function GetDescription: string;
|
|
function IsCaptionStored: Boolean;
|
|
function IsCreatorStored: Boolean;
|
|
function IsDesciptionStored: Boolean;
|
|
procedure SetCaption(const Value: string);
|
|
procedure SetCreationDate(const Value: TDateTime);
|
|
procedure SetCreator(const Value: string);
|
|
procedure SetDescription(const Value: string);
|
|
|
|
procedure ReadIsCaptionAssigned(Reader: TReader);
|
|
procedure ReadIsCreatorAssigned(Reader: TReader);
|
|
procedure ReadIsDescriptionAssigned(Reader: TReader);
|
|
procedure WriteIsCaptionAssigned(Writer: TWriter);
|
|
procedure WriteIsCreatorAssigned(Writer: TWriter);
|
|
procedure WriteIsDescriptionAssigned(Writer: TWriter);
|
|
protected
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
|
|
procedure Changed; virtual;
|
|
procedure DoAssign(Source: TdxPSReportDocument); virtual;
|
|
procedure DoRestoreDefaults; virtual;
|
|
function GetInfoTip: string; virtual;
|
|
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
|
|
property UpdateCount: Integer read FUpdateCount write FUpdateCount;
|
|
public
|
|
constructor Create(AReportLink: TBasedxReportLink); virtual;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
procedure BeginUpdate;
|
|
procedure CancelUpdate;
|
|
procedure EndUpdate;
|
|
function IsUpdateLocked: Boolean;
|
|
|
|
function DefaultCaption: string; virtual;
|
|
function DefaultCreator: string; virtual;
|
|
function DefaultDescription: string; virtual;
|
|
|
|
procedure RestoreDefaults;
|
|
procedure RetrievePreview; virtual;
|
|
|
|
property InfoTip: string read GetInfoTip;
|
|
property Preview: TMetafile read FPreview;
|
|
property ReportLink: TBasedxReportLink read FReportLink;
|
|
|
|
property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
|
|
published
|
|
property Caption: string read GetCaption write SetCaption stored IsCaptionStored;
|
|
property CreationDate: TDateTime read FCreationDate write SetCreationDate;
|
|
property Creator: string read GetCreator write SetCreator stored IsCreatorStored;
|
|
property Description: string read GetDescription write SetDescription stored IsDesciptionStored;
|
|
end;
|
|
|
|
TdxPSDataStorageOffsetTableClass = class of TdxPSDataStorageOffsetTable;
|
|
|
|
TdxPSDataStorageOffsetTable = class
|
|
protected
|
|
procedure DoAssign(Source: TdxPSDataStorageOffsetTable); virtual;
|
|
public
|
|
Information: Longint;
|
|
Document: Longint;
|
|
Title: Longint;
|
|
Data: Longint;
|
|
Reserved1: Longint;
|
|
Reserved2: Longint;
|
|
Reserved3: Longint;
|
|
Reserved4: Longint;
|
|
constructor Create(ATemplate: TdxPSDataStorageOffsetTable = nil); virtual;
|
|
procedure Assign(Source: TdxPSDataStorageOffsetTable); virtual;
|
|
procedure Clear; virtual;
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
end;
|
|
PdxPSDataStorageOffsetTable = TdxPSDataStorageOffsetTable; // for backward compatibility
|
|
|
|
TdxPSDataStorageInfoClass = class of TdxPSDataStorageInfo;
|
|
|
|
TdxPSDataStorageInfo = class
|
|
public
|
|
StorageVersion: Integer;
|
|
PrintingSystemVersion: TdxPSVersion;
|
|
LinkClassName: string[255];
|
|
ComponentClassName: string[255];
|
|
LinkClass: TdxReportLinkClass;
|
|
ComponentClass: TComponentClass;
|
|
constructor Create(AReportLink: TBasedxReportLink); virtual;
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
end;
|
|
PdxPSDataStorageInfo = TdxPSDataStorageInfo; // for backward compatibility
|
|
|
|
TdxAssignedFormatValue = (fvDate, fvTime, fvPageNumber);
|
|
TdxAssignedFormatValues = set of TdxAssignedFormatValue;
|
|
|
|
TdxReportLinkState = (rlsDataLoading, rlsDataSaving);
|
|
TdxReportLinkStates = set of TdxReportLinkState;
|
|
|
|
TdxReportLinkDataSource = (rldsComponent, rldsExternalStorage);
|
|
|
|
TdxCustomDrawReportLinkTitleEvent = procedure(Sender: TBasedxReportLink;
|
|
ACanvas: TCanvas; ARect: TRect; ANom, ADenom: Integer;
|
|
var ATextAlignX: TdxTextAlignX; var ATextAlignY: TdxTextAlignY;
|
|
var AColor: TColor; AFont: TFont; var ADone: Boolean) of object;
|
|
|
|
TdxCustomDrawReportLinkHFEvent = procedure(Sender: TObject; ACanvas: TCanvas;
|
|
APageIndex: Integer; var ARect: TRect; ANom, ADenom: Integer;
|
|
var ADefaultDrawText, ADefaultDrawBackground: Boolean) of object;
|
|
|
|
TdxFilterStyleEvent = procedure(Sender: TBasedxReportLink;
|
|
AStyle: TBasedxPrintStyle; var ASupported: Boolean) of object;
|
|
|
|
TdxMeasureReportLinkTitleEvent = procedure(Sender: TBasedxReportLink;
|
|
var AHeight: Integer) of object;
|
|
|
|
TdxPSGetImageListProc = procedure(AnImageList: TCustomImageList) of object;
|
|
|
|
|
|
IdxPSNativeWin32ControlHandleSupport = interface
|
|
['{4B649281-A283-4CAC-98D4-08E779A7F9C8}']
|
|
function GetNativeHandle: {$IFDEF BCB}Integer {$ELSE}HWND {$ENDIF};
|
|
procedure SetNativeHandle(Value: {$IFDEF BCB}Integer {$ELSE}HWND {$ENDIF});
|
|
property NativeHandle: {$IFDEF BCB}Integer {$ELSE}HWND {$ENDIF} read GetNativeHandle write SetNativeHandle;
|
|
end;
|
|
|
|
|
|
TBasedxReportLink = class(TComponent {$IFNDEF DELPHI6}, IUnknown {$ENDIF})
|
|
private
|
|
FActive: Boolean;
|
|
FAssignedFormatValues: TdxAssignedFormatValues;
|
|
FBuiltIn: Boolean;
|
|
FComponent: TComponent;
|
|
FComponentPrinter: TCustomdxComponentPrinter;
|
|
FController: TBasedxReportLink;
|
|
FCurrentPage: Integer;
|
|
FData: Pointer;
|
|
FDateFormat: Integer;
|
|
FDataSource: TdxReportLinkDataSource;
|
|
FDataStream: TStream;
|
|
FDefaultFont: TFont;
|
|
FDesignerCaption: string;
|
|
FDesignerHelpContext: THelpContext;
|
|
FDesignWindow: TAbstractdxReportLinkDesignWindow;
|
|
FFont: TFont;
|
|
FFootersOnEveryPage: Boolean;
|
|
FHeadersOnEveryPage: Boolean;
|
|
FInternalStreaming: Boolean;
|
|
FIsDesignerCaptionAssigned: Boolean;
|
|
FIsInvalidReport: Boolean;
|
|
FPageNumberFormat: TdxPageNumberFormat;
|
|
FPrinterPage: TdxPrinterPage;
|
|
FRebuildNeeded: Boolean;
|
|
FRenderer: TdxPSReportRenderer;
|
|
FRenderInfo: TdxPSReportRenderInfo;
|
|
FReportCells: TdxReportCells;
|
|
FReportDocument: TdxPSReportDocument;
|
|
FReportTitle: TdxReportTitle;
|
|
FSavedReportDocument: TdxPSReportDocument;
|
|
FSavedReportTitle: TdxReportTitle;
|
|
FScaleFonts: Boolean;
|
|
FShowDesigner: Boolean;
|
|
FShowEmptyPages: Boolean;
|
|
FShowPageFooter: Boolean;
|
|
FShowPageHeader: Boolean;
|
|
FState: TdxReportLinkStates;
|
|
FStartPageIndex: Integer;
|
|
FStorageName: string;
|
|
FStyleManager: TdxPrintStyleManager;
|
|
FSubscriber: TdxEventSubscriber;
|
|
FTimeFormat: Integer;
|
|
FTransparent: Boolean;
|
|
FUseHorzDelimiters: Boolean;
|
|
FUseVertDelimiters: Boolean;
|
|
|
|
FBackgroundBitmapPool: TdxPSBackgroundBitmapPool;
|
|
FFontPool: TdxPSReportFontPool;
|
|
FPainting: Boolean;
|
|
FPrepared: Boolean;
|
|
FStreamedActive: Boolean;
|
|
|
|
FOnChangeComponent: TNotifyEvent;
|
|
FOnCustomDrawPageFooter: TdxCustomDrawReportLinkHFEvent;
|
|
FOnCustomDrawPageHeader: TdxCustomDrawReportLinkHFEvent;
|
|
FOnCustomDrawReportLinkTitle: TdxCustomDrawReportLinkTitleEvent;
|
|
FOnDataSourceChanged: TNotifyEvent;
|
|
FOnDestroy: TNotifyEvent;
|
|
FOnFilterStyle: TdxFilterStyleEvent;
|
|
FOnMeasureReportLinkTitle: TdxMeasureReportLinkTitleEvent;
|
|
|
|
function GetAbortBuilding: Boolean;
|
|
function GetCaption: string;
|
|
function GetCurrentPrintStyle: TBasedxPrintStyle;
|
|
function GetDateFormat: Integer;
|
|
function GetDateTime: TDateTime;
|
|
function GetDescription: string;
|
|
function GetDesignerCaption: string;
|
|
function GetFontPool: TdxPSReportFontPool;
|
|
function GetHasDesignWindow: Boolean;
|
|
function GetHasPreviewWindow: Boolean;
|
|
function GetIndex: Integer;
|
|
function GetIsAggregated: Boolean;
|
|
function GetIsBuilding: Boolean;
|
|
function GetIsCurrentLink: Boolean;
|
|
function GetPageHeight: Integer;
|
|
function GetPageNumberFormat: TdxPageNumberFormat;
|
|
function GetPageWidth: Integer;
|
|
function GetPreviewWindow: TBasedxPreviewWindow;
|
|
function GetRealPrinterPage: TdxPrinterPage;
|
|
function GetReportTitleMode: TdxReportTitleMode;
|
|
function GetReportTitleText: string;
|
|
function GetRenderer: TdxPSReportRenderer;
|
|
function GetRenderInfo: TdxPSReportRenderInfo;
|
|
function GetRenderStage: TdxPSRenderStages;
|
|
function GetShowEmptyPages: Boolean;
|
|
function GetShowPageFooter: Boolean;
|
|
function GetShowPageHeader: Boolean;
|
|
///function GetShrinkToPageHeight: Boolean;
|
|
function GetShrinkToPageWidth: Boolean;
|
|
function GetStartPageIndex: Integer;
|
|
function GetTimeFormat: Integer;
|
|
function GetVirtualPageCount: Integer;
|
|
function IsDateFormatStored: Boolean;
|
|
function IsDesignerCaptionStored: Boolean;
|
|
function IsPageNumberFormatStored: Boolean;
|
|
function IsTimeFormatStored: Boolean;
|
|
procedure SetAbortBuilding(Value: Boolean);
|
|
procedure SetAssignedFormatValues(Value: TdxAssignedFormatValues);
|
|
procedure SetCaption(const Value: string);
|
|
procedure SetComponentPrinter(Value: TCustomdxComponentPrinter);
|
|
procedure SetCurrentPage(Value: Integer);
|
|
procedure SetDateFormat(Value: Integer);
|
|
procedure SetDataSource(Value: TdxReportLinkDataSource);
|
|
procedure SetDateTime(const Value: TDateTime);
|
|
procedure SetDesignerCaption(const Value: string);
|
|
procedure SetDescription(const Value: string);
|
|
procedure SetIndex(Value: Integer);
|
|
procedure SetIsCurrentLink(Value: Boolean);
|
|
procedure SetPageNumberFormat(Value: TdxPageNumberFormat);
|
|
procedure SetPrinterPage(Value: TdxPrinterPage);
|
|
procedure SetRealPrinterPage(Value: TdxPrinterPage);
|
|
procedure SetReportDocument(Value: TdxPSReportDocument);
|
|
procedure SetReportTitle(Value: TdxReportTitle);
|
|
procedure SetReportTitleMode(Value: TdxReportTitleMode);
|
|
procedure SetReportTitleText(const Value: string);
|
|
procedure SetShowEmptyPages(Value: Boolean);
|
|
procedure SetShowPageFooter(Value: Boolean);
|
|
procedure SetShowPageHeader(Value: Boolean);
|
|
//procedure SetShrinkToPageHeight(Value: Boolean);
|
|
procedure SetShrinkToPageWidth(Value: Boolean);
|
|
procedure SetStartPageIndex(Value: Integer);
|
|
procedure SetStorageName(const Value: string);
|
|
procedure SetStyleManager(Value: TdxPrintStyleManager);
|
|
procedure SetTimeFormat(Value: Integer);
|
|
procedure SetUseHorzDelimiters(Value: Boolean);
|
|
procedure SetUseVertDelimiters(Value: Boolean);
|
|
|
|
procedure AssignFormats(AnItem: TdxAssignedFormatValue; AValue: Boolean);
|
|
function CurrentComposition: TdxCompositionReportLink;
|
|
procedure PaintPage(ACanvas: TCanvas; const APageBounds: TRect;
|
|
APageIndex, AContinuousPageIndex, AZoomFactor: Integer); virtual;
|
|
function ValidateMargins: Boolean;
|
|
|
|
procedure DefineStylesClick(Sender: TObject);
|
|
procedure StyleClick(Sender: TObject);
|
|
|
|
procedure ReadBuiltIn(Reader: TReader);
|
|
procedure ReadComponentName(AReader: TReader);
|
|
procedure ReadIsDesignerCaptionAssigned(Reader: TReader);
|
|
procedure ReadStyleManagerName(AReader: TReader);
|
|
procedure WriteBuiltIn(Writer: TWriter);
|
|
procedure WriteComponentName(AWriter: TWriter);
|
|
procedure WriteIsDesignerCaptionAssigned(Writer: TWriter);
|
|
procedure WriteStyleManagerName(AWriter: TWriter);
|
|
protected
|
|
FColor: TColor;
|
|
FFontIndex: Integer;
|
|
{$IFNDEF DELPHI6}
|
|
{ IUnknown }
|
|
function QueryInterface(const IID: TGUID; out Obj): HRESULT; override;
|
|
function _Addref: Integer; stdcall;
|
|
function _Release: Integer; stdcall;
|
|
{$ENDIF}
|
|
procedure AssignTo(Dest: TPersistent); override;
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure ReadState(Reader: TReader); override;
|
|
procedure SetName(const NewName: TComponentName); override;
|
|
procedure SetParentComponent(AParent: TComponent); override;
|
|
|
|
{ Render Info}
|
|
procedure CalculateRenderInfos;
|
|
procedure ClearGDIPools;
|
|
function CreateRenderInfo: TdxPSReportRenderInfo; virtual;
|
|
procedure FreeRenderInfos;
|
|
function GetRenderInfoClass: TdxPSReportRenderInfoClass; virtual;
|
|
|
|
function CreateRenderer: TdxPSReportRenderer; virtual;
|
|
procedure FreeRenderer;
|
|
function GetRendererClass: TdxPSReportRendererClass; virtual;
|
|
|
|
procedure InitializeDefaultFont(AFont: TFont); virtual;
|
|
procedure InternalGetDelimiters(ADelimitersHorz, ADelimitersVert: TList);
|
|
|
|
function IsEntirePageCustomDrawn: Boolean;
|
|
function IsHeaderOrFooterCustomDrawn(AHFObject: TCustomdxPageObject): Boolean;
|
|
function IsTitleCustomDrawn: Boolean;
|
|
|
|
function NeedCalcEmptyPages: Boolean;
|
|
function PageReady(APageIndex: Integer): Boolean; {obsolete: always returns True}
|
|
procedure PrepareFonts(UPI: Integer);
|
|
|
|
procedure PrepareLongOperation;
|
|
procedure UnprepareLongOperation;
|
|
|
|
function CreateReportDocument: TdxPSReportDocument;
|
|
procedure DocumentChanged(Sender: TObject); virtual;
|
|
class function GetReportDocumentClass: TdxPSReportDocumentClass; virtual;
|
|
|
|
function CreateReportCells: TdxReportCells; virtual;
|
|
function GetReportCellsClass: TdxReportCellsClass; virtual;
|
|
|
|
{ Read/Write Data }
|
|
class function CreateDataReader(AStream: TStream): TdxPSDataReader;
|
|
class function CreateDataWriter(AStream: TStream): TdxPSDataWriter;
|
|
class function GetDataReaderClass: TdxPSDataReaderClass; virtual;
|
|
class function GetDataWriterClass: TdxPSDataWriterClass; virtual;
|
|
procedure InternalLoadDataFromStream(AStream: TStream);
|
|
procedure InternalReadData(AReader: TdxPSDataReader); virtual;
|
|
procedure InternalWriteData(AWriter: TdxPSDataWriter); virtual;
|
|
function IsRebuildNeededAndAllowed(ACheckPreviewMode: Boolean): Boolean;
|
|
|
|
function RetrieveStorageInfo: TdxPSDataStorageInfo; virtual;
|
|
procedure ReadData(AReader: TdxPSDataReader); virtual;
|
|
class function ReadOffsetTable(AReader: TdxPSDataReader): TdxPSDataStorageOffsetTable; virtual;
|
|
class procedure ReadReportDocument(AReader: TdxPSDataReader; AReportDocument: TdxPSReportDocument); virtual;
|
|
class function ReadStorageInfo(AReader: TdxPSDataReader): TdxPSDataStorageInfo; virtual;
|
|
class procedure SkipStorageInfo(AReader: TdxPSDataReader);
|
|
procedure ReadTitle(AReader: TdxPSDataReader); virtual;
|
|
procedure WriteData(AWriter: TdxPSDataWriter); virtual;
|
|
class procedure WriteOffsetTable(AWriter: TdxPSDataWriter; AnOffsetTable: TdxPSDataStorageOffsetTable); virtual;
|
|
class procedure WriteReportDocument(AWriter: TdxPSDataWriter; AReportDocument: TdxPSReportDocument); virtual;
|
|
class procedure WriteStorageInfo(AWriter: TdxPSDataWriter; AStorageInfo: TdxPSDataStorageInfo); virtual;
|
|
procedure WriteTitle(AWriter: TdxPSDataWriter); virtual;
|
|
|
|
{ Read/Write Link Data}
|
|
procedure ReadBackgroundBitmapPool(AReader: TdxPSDataReader);
|
|
procedure ReadFontPool(AReader: TdxPSDataReader);
|
|
procedure ReadRenderInfo(AReader: TdxPSDataReader);
|
|
procedure ReadReportData(AReader: TdxPSDataReader);
|
|
procedure WriteBackgroundBitmapPool(AWriter: TdxPSDataWriter);
|
|
procedure WriteFontPool(AWriter: TdxPSDataWriter);
|
|
procedure WriteRenderInfo(AWriter: TdxPSDataWriter);
|
|
procedure WriteReportData(AWriter: TdxPSDataWriter);
|
|
|
|
{ properties read/write virtual methods }
|
|
function GetAllowContinuousPageIndexes: Boolean; virtual;
|
|
function GetAlwaysBufferedGraphics: Boolean; virtual;
|
|
function GetContinuousPageIndexes: Boolean; virtual;
|
|
function GetEmptyPagesCanExist: Boolean; virtual;
|
|
function GetRealScaleFactor: Integer; virtual;
|
|
function GetReportHeight: Integer; virtual;
|
|
function GetReportWidth: Integer; virtual;
|
|
function IsFontStored: Boolean; virtual;
|
|
procedure SetActive(Value: Boolean); virtual;
|
|
procedure SetColor(Value: TColor); virtual;
|
|
procedure SetComponent(Value: TComponent); virtual;
|
|
procedure SetContinuousPageIndexes(Value: Boolean); virtual;
|
|
procedure SetFont(Value: TFont); virtual;
|
|
procedure SetFootersOnEveryPage(Value: Boolean); virtual;
|
|
procedure SetHeadersOnEveryPage(Value: Boolean); virtual;
|
|
procedure SetTransparent(Value: Boolean); virtual;
|
|
|
|
procedure FontChanged(Sender: TObject); virtual;
|
|
procedure LinkModified(Value: Boolean); virtual;
|
|
|
|
procedure AfterDesignReport(ADone: Boolean); virtual;
|
|
procedure BeforeDesignReport; virtual;
|
|
|
|
procedure AfterPrinting; virtual;
|
|
procedure BeforePrinting; virtual;
|
|
|
|
function CalculateActualScaleFactor: Integer; virtual;
|
|
function CannotActivateReportErrorString: string; virtual;
|
|
procedure ConstructReport(AReportCells: TdxReportCells); virtual;
|
|
procedure ConvertCoords; virtual;
|
|
|
|
procedure CustomDraw(AnItem: TAbstractdxReportCellData; ACanvas: TCanvas;
|
|
ABoundsRect, AClientRect: TRect; var ADone: Boolean); virtual;
|
|
function GetDesignerClass: TdxReportLinkDesignWindowClass; virtual;
|
|
procedure DoApplyInDesigner; virtual;
|
|
procedure DoCreateReport; virtual;
|
|
procedure DoCreateReportData;
|
|
procedure DoDataProviderDontPresent; dynamic;
|
|
procedure DoDestroyReport; virtual;
|
|
procedure DoPageParamsChanged; virtual;
|
|
procedure CopyDataStreamFrom(AStream: TStream);
|
|
procedure FinalizeDataStream; virtual;
|
|
function GetBreakPagesByHardDelimiters: Boolean; virtual;
|
|
function GetCriticalSize(AReportCells: TdxReportCells): Integer; virtual;
|
|
procedure GetImageLists(AProc: TdxPSGetImageListProc); virtual;
|
|
function GetPageCount: Integer; virtual;
|
|
function GetRebuildOnPageParamsChange(AUpdateCodes: TdxPrinterPageUpdateCodes): Boolean; virtual;
|
|
function GetUseHardVertDelimiters: Boolean; virtual;
|
|
function GetVisiblePageCount: Integer; virtual;
|
|
procedure InternalActivate; virtual;
|
|
procedure InternalRestoreDefaults; virtual;
|
|
procedure InternalRestoreFromOriginal; virtual;
|
|
function IsDrawFootersOnEveryPage: Boolean; virtual;
|
|
function IsDrawHeadersOnEveryPage: Boolean; virtual;
|
|
function IsScaleGridLines: Boolean; virtual;
|
|
function IsSupportedCustomDraw(Item: TAbstractdxReportCellData): Boolean; virtual;
|
|
procedure MakeDelimiters(AReportCells: TdxReportCells; AHorzDelimiters, AVertDelimiters: TList); virtual;
|
|
procedure MakeHardDelimiters(AReportCells: TdxReportCells; AVertDelimiters: TList); virtual;
|
|
procedure PageParamsChanged(Sender: TdxPrinterPage; AStyle: TBasedxPrintStyle;
|
|
AUpdateCodes: TdxPrinterPageUpdateCodes); virtual;
|
|
function PossibleCustomDraw(AnItem: TAbstractdxReportCellData): Boolean; virtual;
|
|
procedure PrepareReportGroupsLookAndFeels;
|
|
procedure RetrievePageAsImage(APageIndex: Integer; AGraphicClass: TGraphicClass; AGraphic: TGraphic);
|
|
procedure RetrievePageAsImageCallBack(AComponentPrinter: TCustomdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; AIndex, APageIndex: Integer; const AGraphic: TGraphic;
|
|
AData: Pointer; var AContinue: Boolean);
|
|
procedure ShowEmptyPagesChanged; virtual;
|
|
procedure ShowPageFooterChanged; virtual;
|
|
procedure ShowPageHeaderChanged; virtual;
|
|
procedure StdProcessDataSourceDontPresent; virtual;
|
|
procedure TunePixelsNumerator(AReportCells: TdxReportCells); virtual;
|
|
|
|
procedure ComponentUnsupportedError(AComponent: TComponent);
|
|
|
|
procedure DoChangeComponent; dynamic;
|
|
procedure DoCustomDrawEntirePage(ACanvas: TCanvas; R: TRect; ARealPageIndex: Integer); virtual;
|
|
procedure DoCustomDrawPageHeaderOrFooter(AHFObject: TCustomdxPageObject;
|
|
ACanvas: TCanvas; APageIndex: Integer; R: TRect;
|
|
var ADefaultDrawText, ADefaultDrawBackground: Boolean); virtual;
|
|
procedure DoParentCustomDrawPageHeaderOrFooter(
|
|
AHFObject: TCustomdxPageObject; ACanvas: TCanvas; APageIndex: Integer;
|
|
R: TRect; var ADefaultDrawText, ADefaultDrawBackground: Boolean;
|
|
APixelsNumerator: Integer); virtual;
|
|
procedure DoParentCustomDrawReportTitle(ACanvas: TCanvas; R: TRect;
|
|
var ATextAlignX: TdxTextAlignX; var ATextAlignY: TdxTextAlignY;
|
|
var AColor: TColor; AFont: TFont; var ADone: Boolean;
|
|
APixelsNumerator: Integer); virtual;
|
|
procedure DoCustomDrawPageTitle(ACanvas: TCanvas; R: TRect;
|
|
var ATextAlignX: TdxTextAlignX; var ATextAlignY: TdxTextAlignY;
|
|
var AColor: TColor; AFont: TFont; var ADone: Boolean); virtual;
|
|
|
|
procedure DoDataSourceChanged; dynamic;
|
|
procedure DoDestroy; dynamic;
|
|
procedure DoMeasureReportLinkTitle(var AHeight: Integer); virtual;
|
|
procedure DoProgress(const APercentDone: Double); dynamic;
|
|
function IsComposable(AComposition: TdxCompositionReportLink): Boolean; virtual;
|
|
function IsSupportedStyle(APrintStyle: TBasedxPrintStyle): Boolean; virtual;
|
|
function NeedTwoPassRendering: Boolean; virtual;
|
|
|
|
procedure DesignerModified;
|
|
procedure DesignerUpdate(TheAll: Boolean);
|
|
function IsDesigning: Boolean;
|
|
function IsDestroying: Boolean;
|
|
function IsLoading: Boolean;
|
|
|
|
property AllowContinuousPageIndexes: Boolean read GetAllowContinuousPageIndexes;
|
|
property AlwaysBufferedGraphics: Boolean read GetAlwaysBufferedGraphics;
|
|
property BackgroundBitmapPool: TdxPSBackgroundBitmapPool read FBackgroundBitmapPool;
|
|
property BreakPagesByHardDelimiters: Boolean read GetBreakPagesByHardDelimiters;
|
|
property Color: TColor read FColor write SetColor default clWhite;
|
|
property ContinuousPageIndexes: Boolean read GetContinuousPageIndexes write SetContinuousPageIndexes default False;
|
|
//property Controller: TBasedxReportLink read FController write FController;
|
|
property DataStream: TStream read FDataStream;
|
|
property Font: TFont read FFont write SetFont stored IsFontStored;
|
|
property FontPool: TdxPSReportFontPool read GetFontPool;
|
|
property FootersOnEveryPage: Boolean read FFootersOnEveryPage write SetFootersOnEveryPage default False;
|
|
property HeadersOnEveryPage: Boolean read FHeadersOnEveryPage write SetHeadersOnEveryPage default False;
|
|
property InternalStreaming: Boolean read FInternalStreaming write FInternalStreaming;
|
|
property IsBuilding: Boolean read GetIsBuilding;
|
|
property IsInvalidReport: Boolean read FIsInvalidReport; //stored in external storage
|
|
property PageHeight: Integer read GetPageHeight;
|
|
property PageWidth: Integer read GetPageWidth;
|
|
property Renderer: TdxPSReportRenderer read GetRenderer;
|
|
property RenderInfo: TdxPSReportRenderInfo read GetRenderInfo;
|
|
property ScaleFonts: Boolean read FScaleFonts write FScaleFonts default True;
|
|
property State: TdxReportLinkStates read FState;
|
|
property Transparent: Boolean read FTransparent write SetTransparent default True;
|
|
property UseHardVertDelimiters: Boolean read GetUseHardVertDelimiters;
|
|
property UseHorzDelimiters: Boolean read FUseHorzDelimiters write SetUseHorzDelimiters default True;
|
|
property UseVertDelimiters: Boolean read FUseVertDelimiters write SetUseVertDelimiters default True;
|
|
property VirtualPageCount: Integer read GetVirtualPageCount;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure BeforeDestruction; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function GetParentComponent: TComponent; override;
|
|
function HasParent: Boolean; override;
|
|
|
|
procedure LoadFromRegistry(const APath: string);
|
|
procedure SaveToRegistry(const APath: string);
|
|
|
|
class function Aggregable: Boolean; virtual;
|
|
class function CanBeUsedAsStub: Boolean; virtual; // when data loaded from external storage
|
|
class function Serializable: Boolean; virtual;
|
|
|
|
function DefaultDateFormat: Integer; virtual;
|
|
function DefaultDesignerCaption: string; virtual;
|
|
function DefaultFont: TFont; virtual;
|
|
function DefaultPageNumberFormat: TdxPageNumberFormat; virtual;
|
|
function DefaultTimeFormat: Integer; virtual;
|
|
|
|
procedure RestoreDefaults; virtual;
|
|
procedure RestoreFromOriginal; virtual;
|
|
|
|
function CheckToDesign: Boolean;
|
|
function DataProviderPresent: Boolean; virtual;
|
|
function DesignerExists(AComponentClass: TComponentClass): Boolean; virtual;
|
|
function DesignReport: Boolean;
|
|
procedure DestroyReport; virtual;
|
|
procedure GetPageColRowCount(out APageColCount, APageRowCount: Integer); virtual;
|
|
procedure Initialize; virtual;
|
|
function IsEmptyPage(AVirtualPageIndex: Integer): Boolean; virtual;
|
|
function IsEmptyReport: Boolean; virtual;
|
|
procedure RebuildReport; virtual;
|
|
{ Use this routine when you attempt to assign ReportLink to Component that actually is in a DLL }
|
|
{ Don't use this routine in regular cases, i.e. ReportLink is in the same executable file }
|
|
procedure SetComponentUnconditionally(Value: TComponent);
|
|
|
|
class procedure GetSupportedComponentList(AList: TdxClassList);
|
|
class function IsSupportedCompClass(AComponentClass: TClass): Boolean; virtual;
|
|
class function LinkClass: TdxReportLinkClass;
|
|
class function Supports(AnObject: TObject{TComponent}): Boolean; overload;
|
|
class function Supports(AClass: TClass): Boolean; overload;
|
|
|
|
function Print(AShowDialog: Boolean; APPrintDlgData: PdxPrintDlgData): Boolean;
|
|
procedure PrintEx(APageNums: TdxPageNumbers; ACopies: Integer; ACollate: Boolean);
|
|
procedure PrintPages(const APageIndexes: array of Integer);
|
|
procedure PrintPagesEx(const APageIndexes: array of Integer; APageNums: TdxPageNumbers;
|
|
ACopyCount: Integer; ACollate: Boolean);
|
|
|
|
procedure Preview(Modal: Boolean = True);
|
|
function PreviewExists: Boolean;
|
|
|
|
procedure BuildPageSetupMenu(ARootItem: TComponent; AData: Pointer;
|
|
AIncludeDefineItem: Boolean = True);
|
|
procedure DefinePrintStylesDlg;
|
|
procedure GetFilteredStyles(AStrings: TStrings);
|
|
function PageSetup: Boolean;
|
|
function PageSetupEx(AActivePageIndex: Integer; AShowPreviewBtn, AShowPrintBtn: Boolean;
|
|
out APreviewBtnClicked, APrintBtnClicked: Boolean): Boolean; overload;
|
|
function PageSetupEx(AActivePageIndex: Integer;
|
|
APreviewBtnClicked, APrintBtnClicked: PBoolean): Boolean; overload; {$IFDEF DELPHI6} deprecated; {$ENDIF}
|
|
|
|
function ShowDateTimeFormatsDlg: Boolean;
|
|
function ShowPageNumberFormatsDlg: Boolean;
|
|
function ShowTitlePropertiesDlg: Boolean;
|
|
|
|
function SupportsScaling: Boolean; virtual;
|
|
|
|
function CanChangeTitle: Boolean;
|
|
function SupportsTitle: Boolean; virtual;
|
|
|
|
function CanLoadData: Boolean; virtual;
|
|
function CanSaveData: Boolean; virtual;
|
|
function CanUnloadData: Boolean; virtual;
|
|
function GetNewReportStorageName: string; virtual;
|
|
procedure LoadDataFromFile(const AName: string); virtual;
|
|
procedure LoadDataFromStream(AStream: TStream); virtual;
|
|
procedure SaveDataToFile(const AName: string); virtual;
|
|
procedure SaveDataToStream(AStream: TStream); virtual;
|
|
|
|
class function ExtractComponentClass(AStream: TStream; ARaiseException: Boolean = False): TComponentClass;
|
|
class function ExtractLinkClass(AStream: TStream; ARaiseException: Boolean = False): TdxReportLinkClass;
|
|
class function ExtractOffsetTable(AStream: TStream; ARaiseException: Boolean = False): TdxPSDataStorageOffsetTable;
|
|
class function ExtractReportDocument(AStream: TStream; ARaiseException: Boolean = False): TdxPSReportDocument;
|
|
class function ExtractStorageInfo(AStream: TStream; ARaiseException: Boolean = False): TdxPSDataStorageInfo;
|
|
class function ExtractStorageVersion(AStream: TStream; ARaiseException: Boolean = False): Integer;
|
|
class procedure FinalizeStorageInfo(var AStorageInfo: TdxPSDataStorageInfo);
|
|
class function PossibleDataStorage(AStream: TStream; ARaiseException: Boolean = False): Boolean; overload;
|
|
class function PossibleDataStorage(const AFileName: string; ARaiseException: Boolean = False): Boolean; overload;
|
|
|
|
function AddBackgroundBitmapToPool(ABitmap: TBitmap): Integer;
|
|
function AddFontToPool(AFont: TFont): Integer;
|
|
|
|
function CreateGroupLookAndFeel(AClass: TdxPSReportGroupLookAndFeelClass; ACheckExisting: Boolean = True): TdxPSReportGroupLookAndFeel;
|
|
function FindGroupLookAndFeelByClass(AClass: TdxPSReportGroupLookAndFeelClass): TdxPSReportGroupLookAndFeel;
|
|
function IndexOfReportGroupLookAndFeel(ALookAndFeel: TdxPSReportGroupLookAndFeel): Integer;
|
|
|
|
procedure DrawPageHeader(APageIndex: Integer; ARect: TRect;
|
|
ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
procedure DrawPageFooter(APageIndex: Integer; ARect: TRect;
|
|
ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
|
|
procedure DrawCheckBox(Canvas: TCanvas; var R: TRect; Checked, Enabled, FlatBorder: Boolean;
|
|
BoldBorder: Boolean = False); overload; virtual;
|
|
procedure DrawCheckBox(Canvas: TCanvas; var R: TRect; Checked, Enabled, IsRadio: Boolean;
|
|
EdgeStyle: TdxCheckButtonEdgeStyle; BorderColor: TColor = clWindowText); overload; virtual;
|
|
procedure drawEdge(Canvas: TCanvas; var R: TRect; EdgeMode: TdxCellEdgeMode;
|
|
InnerEdge, OuterEdge: TdxCellEdgeStyle; Sides: TdxCellSides = [csLeft..csBottom];
|
|
Soft: Boolean = True); virtual;
|
|
procedure DrawEllipse(Canvas: TCanvas; R: TRect; ForeColor, BkColor: TColor;
|
|
Pattern: TdxPSFillPatternClass; BorderColor: TColor; BorderThickness: Integer = 1); virtual;
|
|
procedure DrawExpandButton(Canvas: TCanvas; var R: TRect;
|
|
Expanded, DrawBorder, Edge3D, Edge3DSoft, Shadow, FillInterior: Boolean;
|
|
BorderColor, InteriorColor: TColor); virtual;
|
|
procedure DrawGlyph(DC: HDC; const R: TRect; AGlyph: Byte);
|
|
procedure DrawGraphic(Canvas: TCanvas; var R: TRect; const ClipRect: TRect;
|
|
ImageList: TCustomImageList; ImageIndex: Integer; Graphic: TGraphic;
|
|
GraphicTransparent, Transparent: Boolean; BkColor: TColor); virtual;
|
|
procedure DrawGraphicEx(Canvas: TCanvas; var R: TRect; const ClipRect: TRect;
|
|
ImageList: TCustomImageList; ImageIndex: Integer; Graphic: TGraphic;
|
|
GraphicTransparent, Transparent: Boolean; BkColor, ForeColor: TColor;
|
|
Pattern: TdxPSFillPatternClass; AnActualImageBuffering: TdxCellImageActualBuffering = cibAlways); virtual;
|
|
procedure DrawRectangle(Canvas: TCanvas; R: TRect; ForeColor, BkColor: TColor;
|
|
ContentPattern: TdxPSFillPatternClass; BorderColor: TColor;
|
|
BorderThickness: Integer = 1); virtual;
|
|
procedure DrawRoundRect(Canvas: TCanvas; R: TRect; CornerWidth, CornerHeight: Integer;
|
|
ForeColor, BkColor: TColor; ContentPattern: TdxPSFillPatternClass;
|
|
BorderColor: TColor; BorderThickness: Integer = 1); virtual;
|
|
procedure DrawSortMark(Canvas: TCanvas; var R: TRect; SortOrder: TdxCellSortOrder; Mono: Boolean); virtual;
|
|
procedure drawText(Canvas: TCanvas; var R: TRect; AIndent: Integer;
|
|
const Text: string; Font: TFont; BkColor: TColor; TextAlignX: TdxTextAlignX;
|
|
TextAlignY: TdxTextAlignY; FillBackground, Multiline, EndEllipsis: Boolean); virtual;
|
|
procedure drawTextEx(Canvas: TCanvas; var R: TRect; MaxLineCount: Integer;
|
|
LeftIndent, RightIndent: Integer; const Text: string; Font: TFont;
|
|
BkColor: TColor; TextAlignX: TdxTextAlignX; TextAlignY: TdxTextAlignY;
|
|
FillBackground, Multiline, EndEllipsis, PreventLeftTextExceed, PreventTopTextExceed: Boolean); virtual;
|
|
procedure FillEllipse(Canvas: TCanvas; const R: TRect; Color: TColor); virtual;
|
|
procedure FillEllipseEx(Canvas: TCanvas; const R: TRect; ForeColor, BkColor: TColor; Pattern: TdxPSFillPatternClass); virtual;
|
|
procedure FillRectEx(Canvas: TCanvas; const R: TRect; ForeColor, BkColor: TColor; Pattern: TdxPSFillPatternClass); virtual;
|
|
procedure FillRoundRect(Canvas: TCanvas; const R: TRect; CornerWidth, CornerHeight: Integer; Color: TColor); virtual;
|
|
procedure FillRoundRectEx(Canvas: TCanvas; const R: TRect; CornerWidth, CornerHeight: Integer;
|
|
ForeColor, BkColor: TColor; Pattern: TdxPSFillPatternClass); virtual;
|
|
procedure FillRgnEx(Canvas: TCanvas; Rgn: HRGN; ForeColor, BkColor: TColor; Pattern: TdxPSFillPatternClass); virtual;
|
|
procedure FrameEllipse(Canvas: TCanvas; R: TRect; Color: TColor; Thickness: Integer = 1);
|
|
procedure frameRect(Canvas: TCanvas; R: TRect; Color: TColor; Sides: TdxCellSides = [csLeft..csBottom];
|
|
Thickness: Integer = 1);
|
|
procedure FrameRoundRect(Canvas: TCanvas; R: TRect; CornerWidth, CornerHeight: Integer;
|
|
Color: TColor; Thickness: Integer = 1); virtual;
|
|
|
|
{ for internal use only }
|
|
function RealPageIndexToVirtualPageIndex(APageIndex: Integer;
|
|
ATakeIntoAccountEmptyPages: Boolean): Integer; virtual;
|
|
function VirtualPageIndexToRealPageIndex(APageIndex: Integer): Integer; virtual;
|
|
|
|
property AbortBuilding: Boolean read GetAbortBuilding write SetAbortBuilding;
|
|
property BuiltIn: Boolean read FBuiltIn write FBuiltIn;
|
|
property ComponentPrinter: TCustomdxComponentPrinter read FComponentPrinter write SetComponentPrinter;
|
|
property Controller: TBasedxReportLink read FController write FController;
|
|
property CurrentPage: Integer read FCurrentPage write SetCurrentPage;
|
|
property CurrentPrintStyle: TBasedxPrintStyle read GetCurrentPrintStyle;
|
|
property Data: Pointer read FData write FData;
|
|
property DataSource: TdxReportLinkDataSource read FDataSource write SetDataSource;
|
|
property DesignWindow: TAbstractdxReportLinkDesignWindow read FDesignWindow;
|
|
property EmptyPagesCanExist: Boolean read GetEmptyPagesCanExist;
|
|
property HasDesignWindow: Boolean read GetHasDesignWindow;
|
|
property HasPreviewWindow: Boolean read GetHasPreviewWindow;
|
|
property IsAggregated: Boolean read GetIsAggregated;
|
|
property PageCount: Integer read GetPageCount;
|
|
property PreviewWindow: TBasedxPreviewWindow read GetPreviewWindow;
|
|
property RealPrinterPage: TdxPrinterPage read GetRealPrinterPage write SetRealPrinterPage;
|
|
property RealScaleFactor: Integer read GetRealScaleFactor;
|
|
property RebuildNeeded: Boolean read FRebuildNeeded;
|
|
property RenderStage: TdxPSRenderStages read GetRenderStage;
|
|
property ReportCells: TdxReportCells read FReportCells;
|
|
property ReportHeight: Integer read GetReportHeight;
|
|
property ReportWidth: Integer read GetReportWidth;
|
|
property ShowEmptyPages: Boolean read GetShowEmptyPages write SetShowEmptyPages default False;
|
|
property VisiblePageCount: Integer read GetVisiblePageCount;
|
|
published
|
|
property Active: Boolean read FActive write SetActive default False;
|
|
property Caption: string read GetCaption write SetCaption stored False;
|
|
property Component: TComponent read FComponent write SetComponent;
|
|
property Description: string read GetDescription write SetDescription stored False;
|
|
property DateFormat: Integer read GetDateFormat write SetDateFormat stored IsDateFormatStored default 0;
|
|
property DateTime: TDateTime read GetDateTime write SetDateTime stored False;
|
|
property DesignerCaption: string read GetDesignerCaption write SetDesignerCaption stored IsDesignerCaptionStored;
|
|
property DesignerHelpContext: THelpContext read FDesignerHelpContext write FDesignerHelpContext default 0;
|
|
property Index: Integer read GetIndex write SetIndex stored False;
|
|
property IsCurrentLink: Boolean read GetIsCurrentLink write SetIsCurrentLink stored False;
|
|
property PageNumberFormat: TdxPageNumberFormat read GetPageNumberFormat write SetPageNumberFormat stored IsPageNumberFormatStored;
|
|
property PrinterPage: TdxPrinterPage read FPrinterPage write SetPrinterPage;
|
|
property ReportDocument: TdxPSReportDocument read FReportDocument write SetReportDocument;
|
|
property ReportTitle: TdxReportTitle read FReportTitle write SetReportTitle;
|
|
property ReportTitleMode: TdxReportTitleMode read GetReportTitleMode write SetReportTitleMode stored False default tmOnEveryTopPage;
|
|
property ReportTitleText: string read GetReportTitleText write SetReportTitleText stored False;
|
|
property ShowDesigner: Boolean read FShowDesigner write FShowDesigner stored False;
|
|
property ShowPageFooter: Boolean read GetShowPageFooter write SetShowPageFooter default True;
|
|
property ShowPageHeader: Boolean read GetShowPageHeader write SetShowPageHeader default True;
|
|
//property ShrinkToPageHeight: Boolean read GetShrinkToPageHeight write SetShrinkToPageHeight default False;
|
|
property ShrinkToPageWidth: Boolean read GetShrinkToPageWidth write SetShrinkToPageWidth default False;
|
|
property StartPageIndex: Integer read GetStartPageIndex write SetStartPageIndex default 1;
|
|
property StorageName: string read FStorageName write SetStorageName;
|
|
property StyleManager: TdxPrintStyleManager read FStyleManager write SetStyleManager;
|
|
property TimeFormat: Integer read GetTimeFormat write SetTimeFormat stored IsTimeFormatStored default 0;
|
|
property AssignedFormatValues: TdxAssignedFormatValues read FAssignedFormatValues write SetAssignedFormatValues default []; //must be last
|
|
|
|
property OnChangeComponent: TNotifyEvent read FOnChangeComponent write FOnChangeComponent;
|
|
property OnCustomDrawPageFooter: TdxCustomDrawReportLinkHFEvent read FOnCustomDrawPageFooter write FOnCustomDrawPageFooter;
|
|
property OnCustomDrawPageHeader: TdxCustomDrawReportLinkHFEvent read FOnCustomDrawPageHeader write FOnCustomDrawPageHeader;
|
|
property OnCustomDrawReportLinkTitle: TdxCustomDrawReportLinkTitleEvent read FOnCustomDrawReportLinkTitle write FOnCustomDrawReportLinkTitle;
|
|
property OnDataSourceChanged: TNotifyEvent read FOnDataSourceChanged write FOnDataSourceChanged;
|
|
property OnDestroy: TNotifyEvent read FOnDestroy write FOnDestroy;
|
|
property OnFilterStyle: TdxFilterStyleEvent read FOnFilterStyle write FOnFilterStyle;
|
|
property OnMeasureReportLinkTitle: TdxMeasureReportLinkTitleEvent read FOnMeasureReportLinkTitle write FOnMeasureReportLinkTitle;
|
|
end;
|
|
|
|
TdxCompositionLinkItem = class(TCollectionItem)
|
|
private
|
|
FBuiltIn: Boolean;
|
|
FReportLink: TBasedxReportLink;
|
|
FLoadingReportLinkName: string;
|
|
procedure SetReportLink(Value: TBasedxReportLink);
|
|
procedure ReadData(Reader: TReader);
|
|
procedure ReadLinkName(Reader: TReader);
|
|
procedure WriteData(Writer: TWriter);
|
|
procedure WriteLinkName(Writer: TWriter);
|
|
protected
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
procedure SetIndex(Value: Integer); override;
|
|
function Composition: TdxCompositionReportLink;
|
|
public
|
|
constructor Create(Collection: TCollection); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
property BuiltIn: Boolean read FBuiltIn write FBuiltIn;
|
|
published
|
|
property ReportLink: TBasedxReportLink read FReportLink write SetReportLink;
|
|
end;
|
|
|
|
TdxCompositionLinkItems = class(TCollection)
|
|
private
|
|
FComposition: TdxCompositionReportLink;
|
|
FDontNeedRebuild: Boolean;
|
|
function GetItem(Index: Integer): TdxCompositionLinkItem;
|
|
procedure SetItem(Index: Integer; Value: TdxCompositionLinkItem);
|
|
protected
|
|
procedure CorrectLinksAfterLoadings;
|
|
function GetOwner: TPersistent; override;
|
|
procedure Update(Item: TCollectionItem); override;
|
|
public
|
|
constructor Create(AComposition: TdxCompositionReportLink);
|
|
|
|
function Add: TdxCompositionLinkItem;
|
|
function AddLink(AReportLink: TBasedxReportLink): TdxCompositionLinkItem;
|
|
procedure DeleteItemsByLink(AReportLink: TBasedxReportLink);
|
|
procedure DeleteNonBuiltIns;
|
|
procedure GetLinkEntries(AReportLink: TBasedxReportLink; AList: TList); // returns list of Items
|
|
function IndexOfLink(AReportLink: TBasedxReportLink): Integer; // returns first entry for AReportLink in Items
|
|
function IsLinkComposable(AReportLink: TBasedxReportLink): Boolean;
|
|
function LinkExists(AReportLink: TBasedxReportLink): Boolean;
|
|
function NextAssignedItem(AnItem: TdxCompositionLinkItem): TdxCompositionLinkItem;
|
|
function NonBuiltInsExists: Boolean;
|
|
function PrevAssignedItem(AnItem: TdxCompositionLinkItem): TdxCompositionLinkItem;
|
|
|
|
property Composition: TdxCompositionReportLink read FComposition;
|
|
property Items[Index: Integer]: TdxCompositionLinkItem read GetItem write SetItem; default;
|
|
end;
|
|
|
|
TdxPSCompositionReportRenderInfo = class(TdxPSReportRenderInfo)
|
|
private
|
|
FNonEmptyPageCount: Integer;
|
|
FPageColCount: Integer;
|
|
FPageRowCount: Integer;
|
|
FStartIndexes: TList;
|
|
function GetReportLink: TdxCompositionReportLink;
|
|
function GetStartIndex(Index: Integer): Integer;
|
|
function GetStartIndexCount: Integer;
|
|
procedure SetStartIndex(Index: Integer; Value: Integer);
|
|
protected
|
|
function CalculateNonEmptyPageCount: Integer; virtual;
|
|
function CalculatePageColCount: Integer; virtual;
|
|
function CalculatePageRowCount: Integer; virtual;
|
|
|
|
procedure DoCalculate; override;
|
|
procedure Refresh; override;
|
|
|
|
function GetNonEmptyPageCount: Integer; override;
|
|
function GetPageColCount: Integer; override;
|
|
function GetPageRowCount: Integer; override;
|
|
|
|
function RealPageIndexToVirtualPageIndex(APageIndex: Integer; ATakeIntoAccountEmptyPages: Boolean): Integer; override;
|
|
function VirtualPageIndexToRealPageIndex(APageIndex: Integer): Integer; override;
|
|
|
|
procedure GetCompositionLinkItemByPageIndexAndFixIndex(APageIndex: Integer;
|
|
var APageIndexRelativeToLink: Integer; var AnItem: TdxCompositionLinkItem);
|
|
public
|
|
constructor Create(AReportLink: TBasedxReportLink); override;
|
|
destructor Destroy; override;
|
|
|
|
property ReportLink: TdxCompositionReportLink read GetReportLink;
|
|
property StartIndexCount: Integer read GetStartIndexCount;
|
|
property StartIndexes[Index: Integer]: Integer read GetStartIndex write SetStartIndex;
|
|
end;
|
|
|
|
TdxPSCompositionReportRenderer = class(TdxPSReportRenderer)
|
|
private
|
|
function GetRenderInfo: TdxPSCompositionReportRenderInfo;
|
|
function GetReportLink: TdxCompositionReportLink;
|
|
public
|
|
procedure RenderPage(ACanvas: TCanvas; const APageBounds: TRect;
|
|
APageIndex, AContinuousPageIndex, AZoomFactor: Integer); override;
|
|
|
|
property RenderInfo: TdxPSCompositionReportRenderInfo read GetRenderInfo;
|
|
property ReportLink: TdxCompositionReportLink read GetReportLink;
|
|
end;
|
|
|
|
TdxPSReportCompositionDocument = class(TdxPSReportDocument)
|
|
private
|
|
function GetReportLink: TdxCompositionReportLink;
|
|
public
|
|
function DefaultDescription: string; override;
|
|
property ReportLink: TdxCompositionReportLink read GetReportLink;
|
|
end;
|
|
|
|
TdxCompositionReportLinkEvent = procedure(Sender: TdxCompositionReportLink;
|
|
AItem: TdxCompositionLinkItem) of object;
|
|
|
|
TdxCompositionState = (csRebuildReportLink);
|
|
TdxCompositionStates = set of TdxCompositionState;
|
|
|
|
TdxCompositionOption = (coCanEdit, coShowDescription);
|
|
TdxCompositionOptions = set of TdxCompositionOption;
|
|
|
|
TdxCompositionReportLink = class(TBasedxReportLink)
|
|
private
|
|
FCompositionState: TdxCompositionStates;
|
|
FContinuousPageIndexes: Boolean;
|
|
FDesignerOptions: TdxCompositionOptions;
|
|
FInvalidatedLinks: TList;
|
|
FItems: TdxCompositionLinkItems;
|
|
FOnAfterBuildReport: TdxCompositionReportLinkEvent;
|
|
FOnBeforeBuildReport: TdxCompositionReportLinkEvent;
|
|
function GetRenderer: TdxPSCompositionReportRenderer;
|
|
function GetRenderInfo: TdxPSCompositionReportRenderInfo;
|
|
function GetReportDocument: TdxPSReportCompositionDocument;
|
|
procedure SetItems(Value: TdxCompositionLinkItems);
|
|
procedure SetReportDocument(Value: TdxPSReportCompositionDocument);
|
|
|
|
procedure ActivateLink(AReportLink: TBasedxReportLink);
|
|
procedure UpdateComposition(AUpdateCodes: TdxPrinterPageUpdateCodes);
|
|
protected
|
|
procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
|
|
|
|
procedure ConstructReport(AReportCells: TdxReportCells); override;
|
|
procedure DoCreateReport; override;
|
|
function GetRendererClass: TdxPSReportRendererClass; override;
|
|
function GetRenderInfoClass: TdxPSReportRenderInfoClass; override;
|
|
procedure InternalRestoreDefaults; override;
|
|
procedure InternalRestoreFromOriginal; override;
|
|
procedure ShowEmptyPagesChanged; override;
|
|
procedure ShowPageFooterChanged; override;
|
|
procedure ShowPageHeaderChanged; override;
|
|
procedure StdProcessDataSourceDontPresent; override;
|
|
|
|
function GetAllowContinuousPageIndexes: Boolean; override;
|
|
function GetContinuousPageIndexes: Boolean; override;
|
|
function GetEmptyPagesCanExist: Boolean; override;
|
|
function GetRebuildOnPageParamsChange(AUpdateCodes: TdxPrinterPageUpdateCodes): Boolean; override;
|
|
function GetReportHeight: Integer; override;
|
|
function GetReportWidth: Integer; override;
|
|
procedure SetContinuousPageIndexes(Value: Boolean); override;
|
|
|
|
procedure DoAfterBuildReport(AItem: TdxCompositionLinkItem); dynamic;
|
|
procedure DoBeforeBuildReport(AItem: TdxCompositionLinkItem); dynamic;
|
|
|
|
class function GetReportDocumentClass: TdxPSReportDocumentClass; override;
|
|
|
|
property Renderer: TdxPSCompositionReportRenderer read GetRenderer;
|
|
property RenderInfo: TdxPSCompositionReportRenderInfo read GetRenderInfo;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
function DefaultDesignerCaption: string; override;
|
|
|
|
{ for internal use only }
|
|
function RealPageIndexToVirtualPageIndex(APageIndex: Integer;
|
|
ATakeIntoAccountEmptyPages: Boolean): Integer; override;
|
|
function VirtualPageIndexToRealPageIndex(APageIndex: Integer): Integer; override;
|
|
|
|
class function CanBeUsedAsStub: Boolean; override;
|
|
class function Serializable: Boolean; override;
|
|
function DataProviderPresent: Boolean; override;
|
|
function IsEmptyPage(AVirtualPageIndex: Integer): Boolean; override;
|
|
function SupportsTitle: Boolean; override;
|
|
|
|
procedure GetItems(AStrings: TStrings; AExcludeUnassigned: Boolean);
|
|
|
|
property CompositionState: TdxCompositionStates read FCompositionState;
|
|
property ReportDocument: TdxPSReportCompositionDocument read GetReportDocument write SetReportDocument;
|
|
published
|
|
property ContinuousPageIndexes default True;
|
|
property DesignerOptions: TdxCompositionOptions read FDesignerOptions write FDesignerOptions
|
|
default [coCanEdit, coShowDescription];
|
|
property Items: TdxCompositionLinkItems read FItems write SetItems;
|
|
|
|
property OnAfterBuildReport: TdxCompositionReportLinkEvent read FOnAfterBuildReport write FOnAfterBuildReport;
|
|
property OnBeforeBuildReport: TdxCompositionReportLinkEvent read FOnBeforeBuildReport write FOnBeforeBuildReport;
|
|
end;
|
|
|
|
{ Report PropertySheets }
|
|
|
|
TdxReportLinkDesignWindowState = (dwsInitialize);
|
|
TdxReportLinkDesignWindowStates = set of TdxReportLinkDesignWindowState;
|
|
|
|
TAbstractdxReportLinkDesignWindow = class(TCustomdxPSForm)
|
|
private
|
|
FApplyed: Boolean;
|
|
FModified: Boolean;
|
|
FPrevKeyPreview: Boolean;
|
|
FReportLink: TBasedxReportLink;
|
|
function GetComponent: TComponent;
|
|
function GetIsDesigning: Boolean;
|
|
function IsCaptionStored: Boolean;
|
|
procedure SetModified(Value: Boolean);
|
|
procedure WMHelp(var message: TWMHelp); message WM_HELP;
|
|
protected
|
|
FState: TdxReportLinkDesignWindowStates;
|
|
procedure CreateWnd; override;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
|
|
procedure AfterRebuildReport; virtual;
|
|
procedure BeforeRebuildReport; virtual;
|
|
|
|
procedure Initialize; virtual;
|
|
procedure LoadStrings; virtual;
|
|
procedure UpdateControlsState; virtual;
|
|
|
|
property Applyed: Boolean read FApplyed write FApplyed;
|
|
property Component: TComponent read GetComponent;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
function Execute: Boolean; virtual;
|
|
|
|
property IsDesigning: Boolean read GetIsDesigning;
|
|
property Modified: Boolean read FModified write SetModified;
|
|
property ReportLink: TBasedxReportLink read FReportLink write FReportLink;
|
|
property State: TdxReportLinkDesignWindowStates read FState;
|
|
published
|
|
property Caption stored IsCaptionStored;
|
|
end;
|
|
|
|
TStandarddxReportLinkDesignWindow = class(TAbstractdxReportLinkDesignWindow)
|
|
private
|
|
FAtLeastOneTimeApplied: Boolean;
|
|
FUpdateControlsCount: Integer;
|
|
procedure SetAtLeastOneTimeApplied(Value: Boolean);
|
|
|
|
procedure CreateStdButtons;
|
|
procedure PlaceStdButtons;
|
|
procedure RegroupStdButtons;
|
|
protected
|
|
{$IFDEF DELPHI7}
|
|
FPrevPreviewHostWindowProc: TWndMethod;
|
|
{$ENDIF}
|
|
procedure Resize; override;
|
|
|
|
function CanApply: Boolean; virtual;
|
|
procedure DoApply; virtual;
|
|
procedure Initialize; override;
|
|
procedure LoadStrings; override;
|
|
procedure UpdateControlsState; override;
|
|
|
|
procedure ApplyClick(Sender: TObject); virtual;
|
|
procedure RestoreDefaultsClick(Sender: TObject); virtual;
|
|
procedure RestoreOriginalClick(Sender: TObject); virtual;
|
|
procedure TitlePropertiesClick(Sender: TObject); virtual;
|
|
|
|
procedure DoInitialize; virtual;
|
|
{$IFDEF DELPHI7}
|
|
function GetPreviewHost: TCustomPanel; virtual;
|
|
procedure PreviewHostWindowProc(var Message: TMessage); virtual;
|
|
{$ENDIF}
|
|
procedure PaintPreview(ACanvas: TCanvas; R: TRect); virtual;
|
|
procedure UpdatePreview; virtual;
|
|
|
|
property AtLeastOneTimeApplied: Boolean read FAtLeastOneTimeApplied write SetAtLeastOneTimeApplied;
|
|
{$IFDEF DELPHI7}
|
|
property PreviewHost: TCustomPanel read GetPreviewHost;
|
|
{$ENDIF}
|
|
property UpdateControlsCount: Integer read FUpdateControlsCount;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
{$IFDEF DELPHI7}
|
|
destructor Destroy; override;
|
|
{$ENDIF}
|
|
|
|
procedure BeginUpdateControls; virtual;
|
|
procedure EndUpdateControls; virtual;
|
|
function LockControlsUpdate: Boolean;
|
|
published
|
|
btnApply: TButton;
|
|
btnCancel: TButton;
|
|
btnHelp: TButton;
|
|
btnOK: TButton;
|
|
btnRestoreDefaults: TButton;
|
|
btnRestoreOriginal: TButton;
|
|
btnTitleProperties: TButton;
|
|
end;
|
|
|
|
{ Print Styles }
|
|
|
|
TdxPSPrintStyle = class(TBasedxPrintStyle)
|
|
private
|
|
FOnAfterGenerating: TNotifyEvent;
|
|
FOnAfterPrinting: TNotifyEvent;
|
|
FOnBeforeGenerating: TNotifyEvent;
|
|
FOnBeforePrinting: TNotifyEvent;
|
|
procedure AfterGenerating;
|
|
procedure BeforeGenerating;
|
|
protected
|
|
procedure AddStdHFFunctions; virtual;
|
|
|
|
procedure DoAfterGenerating; virtual;
|
|
procedure DoAfterPrinting; override;
|
|
procedure DoBeforeGenerating; virtual;
|
|
procedure DoBeforePrinting; override;
|
|
|
|
procedure InitializeDefaultStyleGlyph(ABitmap: TBitmap); override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
|
|
function DefaultPageFooterText(APart: TdxPageTitlePart): string; override;
|
|
function DefaultStyleCaption: string; override;
|
|
published
|
|
property OnAfterGenerating: TNotifyEvent read FOnAfterGenerating write FOnAfterGenerating;
|
|
property OnAfterPrinting: TNotifyEvent read FOnAfterPrinting write FOnAfterPrinting;
|
|
property OnBeforeGenerating: TNotifyEvent read FOnBeforeGenerating write FOnBeforeGenerating;
|
|
property OnBeforePrinting: TNotifyEvent read FOnBeforePrinting write FOnBeforePrinting;
|
|
end;
|
|
|
|
{ Preview Window}
|
|
|
|
TdxPreviewEnableOption = (peoCanChangeMargins, peoHelp, peoPageBackground, peoPageSetup,
|
|
peoPreferences, peoPrint, peoReportDesign);
|
|
TdxPreviewEnableOptions = set of TdxPreviewEnableOption;
|
|
TdxPreviewVisibleOption = (pvoHelp, pvoPageBackground, pvoPageSetup, pvoPreferences,
|
|
pvoPrint, pvoReportDesign, pvoPrintStyles, pvoReportFileOperations, pvoPageMargins);
|
|
TdxPreviewVisibleOptions = set of TdxPreviewVisibleOption;
|
|
TdxPSPreviewState = (prsNone, prsEditHeaders, prsEditFooters);
|
|
TdxPSThumbnailsSize = (tsSmall, tsLarge);
|
|
|
|
{$IFDEF OLEDRAGANDDROP}
|
|
{$ENDIF}
|
|
|
|
TdxPreviewWindowClass = class of TBasedxPreviewWindow;
|
|
|
|
TBasedxPreviewWindow = class(TCustomdxPSForm, {$IFNDEF DELPHI6} IUnknown, {$ENDIF}
|
|
IdxPSExplorerContextCommandBuilder {$IFDEF OLEDRAGANDDROP}, IDropTarget{$ENDIF})
|
|
private
|
|
{$IFDEF OLEDRAGANDDROP}
|
|
FDraggedFileName: string;
|
|
{$ENDIF}
|
|
function GetReportLink: TBasedxReportLink;
|
|
protected
|
|
{$IFNDEF DELPHI6}
|
|
{ IUnknown }
|
|
function QueryInterface(const IID: TGUID; out Obj): HRESULT; override;
|
|
function _Addref: Integer; stdcall;
|
|
function _Release: Integer; stdcall;
|
|
{$ENDIF}
|
|
{$IFDEF OLEDRAGANDDROP}
|
|
{ IDropTarget }
|
|
function IDropTarget.DragEnter = IDropTarget_DragEnter;
|
|
function IDropTarget.DragOver = IDropTarget_DragOver;
|
|
function IDropTarget.DragLeave = IDropTarget_DragLeave;
|
|
function IDropTarget.Drop = IDropTarget_Drop;
|
|
|
|
function IDropTarget_DragEnter(const DataObj: IDataObject; grfKeyState: Longint;
|
|
Pt: TPoint; var dwEffect: Longint): HRESULT; stdcall;
|
|
function IDropTarget_DragOver(grfKeyState: Longint; Pt: TPoint;
|
|
var dwEffect: Longint): HRESULT; stdcall;
|
|
function IDropTarget_DragLeave: HRESULT; stdcall;
|
|
function IDropTarget_Drop(const DataObj: IDataObject; grfKeyState: Longint; Pt: TPoint;
|
|
var dwEffect: Longint): HRESULT; stdcall;
|
|
{$ENDIF}
|
|
|
|
procedure AddExplorerContextCommand(ACommand: TCustomdxPSExplorerContextCommand); virtual;
|
|
procedure UpdateExplorerContextCommands; virtual;
|
|
|
|
function GetActivePageIndex: Integer; virtual; abstract;
|
|
function GetBackground: TdxBackground; virtual; abstract;
|
|
function GetComponentPrinter: TCustomdxComponentPrinter; virtual; abstract;
|
|
function GetExplorerTree: TCustomdxPSExplorerTreeContainer; virtual;
|
|
function GetHFEditPart: TdxPageTitlePart; virtual;
|
|
function GetPageCount: Integer; virtual; abstract;
|
|
function GetPreviewEnableOptions: TdxPreviewEnableOptions; virtual; abstract;
|
|
function GetPreviewVisibleOptions: TdxPreviewVisibleOptions; virtual; abstract;
|
|
function GetSaveZoomPosition: Boolean; virtual; abstract;
|
|
function GetShowExplorer: Boolean; virtual;
|
|
function GetShowThumbnails: Boolean; virtual;
|
|
function GetState: TdxPSPreviewState; virtual;
|
|
function GetThumbnailsSize: TdxPSThumbnailsSize; virtual; abstract;
|
|
function GetVisiblePageSize: TPoint; virtual; abstract;
|
|
function GetZoomFactor: Integer; virtual; abstract;
|
|
procedure SetActivePageIndex(Value: Integer); virtual; abstract;
|
|
procedure SetBackground(const Value: TdxBackground); virtual; abstract;
|
|
procedure SetComponentPrinter(const Value: TCustomdxComponentPrinter); virtual; abstract;
|
|
procedure SetHFEditPart(const Value: TdxPageTitlePart); virtual; abstract;
|
|
procedure SetPageCount(Value: Integer); virtual; abstract;
|
|
procedure SetPreviewEnableOptions(const Value: TdxPreviewEnableOptions); virtual; abstract;
|
|
procedure SetPreviewVisibleOptions(const Value: TdxPreviewVisibleOptions); virtual; abstract;
|
|
procedure SetSaveZoomPosition(Value: Boolean); virtual; abstract;
|
|
procedure SetShowExplorer(Value: Boolean); virtual;
|
|
procedure SetShowThumbnails(Value: Boolean); virtual;
|
|
procedure SetState(const Value: TdxPSPreviewState); virtual; abstract;
|
|
procedure SetThumbnailsSize(const Value: TdxPSThumbnailsSize); virtual; abstract;
|
|
procedure SetZoomFactor(Value: Integer); virtual; abstract;
|
|
|
|
procedure BeginUpdate; virtual;
|
|
procedure CancelUpdate; virtual;
|
|
procedure EndUpdate; virtual;
|
|
function Locked: Boolean; virtual;
|
|
procedure UpdateCaption;
|
|
|
|
procedure CreationComplete; virtual;
|
|
procedure PaintPage(Sender: TObject; ACanvas: TCanvas; ARect: TRect; APageIndex: Integer); virtual;
|
|
procedure PaintThumbnailPage(Sender: TObject; ACanvas: TCanvas; ARect: TRect; APageIndex: Integer); virtual;
|
|
|
|
{$IFDEF OLEDRAGANDDROP}
|
|
function CanDrop: Boolean; virtual;
|
|
function DoCanAccept: Boolean; virtual;
|
|
procedure DoDrop; virtual;
|
|
property DraggedFileName: string read FDraggedFileName;
|
|
{$ENDIF}
|
|
public
|
|
destructor Destroy; override;
|
|
|
|
procedure GoToFirstPage; virtual; abstract;
|
|
procedure GoToLastPage; virtual; abstract;
|
|
procedure GoToNextPage; virtual; abstract;
|
|
procedure GoToPrevPage; virtual; abstract;
|
|
|
|
procedure InitContent; virtual;
|
|
procedure InvalidateContent; virtual;
|
|
procedure InvalidatePage(APageIndex: Integer); virtual;
|
|
procedure InvalidateAllPages; virtual;
|
|
procedure InvalidatePagesContent; virtual;
|
|
procedure InvalidatePagesHeaderContent; virtual;
|
|
procedure InvalidatePagesFooterContent; virtual;
|
|
|
|
procedure RebuildReport; virtual;
|
|
|
|
procedure UpdateControls; virtual;
|
|
|
|
property ActivePageIndex: Integer read GetActivePageIndex write SetActivePageIndex;
|
|
property Background: TdxBackground read GetBackground write SetBackground;
|
|
property ComponentPrinter: TCustomdxComponentPrinter read GetComponentPrinter write SetComponentPrinter;
|
|
property EnableOptions: TdxPreviewEnableOptions read GetPreviewEnableOptions write SetPreviewEnableOptions;
|
|
property ExplorerTree: TCustomdxPSExplorerTreeContainer read GetExplorerTree;
|
|
property HFEditPart: TdxPageTitlePart read GetHFEditPart write SetHFEditPart;
|
|
property PageCount: Integer read GetPageCount write SetPageCount;
|
|
property ReportLink: TBasedxReportLink read GetReportLink;
|
|
property SaveZoomPosition: Boolean read GetSaveZoomPosition write SetSaveZoomPosition;
|
|
property ShowExplorer: Boolean read GetShowExplorer write SetShowExplorer;
|
|
property ShowThumbnails: Boolean read GetShowThumbnails write SetShowThumbnails;
|
|
property State: TdxPSPreviewState read GetState write SetState;
|
|
property ThumbnailsSize: TdxPSThumbnailsSize read GetThumbnailsSize write SetThumbnailsSize;
|
|
property VisibleOptions: TdxPreviewVisibleOptions read GetPreviewVisibleOptions write SetPreviewVisibleOptions;
|
|
property VisiblePageSize: TPoint read GetVisiblePageSize;
|
|
property ZoomFactor: Integer read GetZoomFactor write SetZoomFactor;
|
|
end;
|
|
|
|
TdxPreviewOptions = class;
|
|
|
|
TdxComponentPrinterThumbnailsOptions = class(TPersistent)
|
|
private
|
|
FDefaultFont: TFont;
|
|
FFont: TFont;
|
|
FPreviewOptions: TdxPreviewOptions;
|
|
FShowPageNumbers: Boolean;
|
|
procedure SetFont(Value: TFont);
|
|
procedure SetShowPageNumbers(Value: Boolean);
|
|
protected
|
|
procedure InitializeDefaultFont(AFont: TFont); virtual;
|
|
function IsFontStored: Boolean; virtual;
|
|
public
|
|
constructor Create(APreviewOptions: TdxPreviewOptions); virtual;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
function DefaultFont: TFont; virtual;
|
|
procedure RestoreDefaults; virtual;
|
|
|
|
property PreviewOptions: TdxPreviewOptions read FPreviewOptions;
|
|
published
|
|
property Font: TFont read FFont write SetFont stored IsFontStored;
|
|
property ShowPageNumbers: Boolean read FShowPageNumbers write SetShowPageNumbers default True;
|
|
end;
|
|
|
|
TdxPreviewOptions = class(TdxBaseObject)
|
|
private
|
|
FCaption: string;
|
|
FComponentPrinter: TCustomdxComponentPrinter;
|
|
FDefaultIcon: TIcon;
|
|
FEnableOptions: TdxPreviewEnableOptions;
|
|
FIcon: TIcon;
|
|
FHelpContext: THelpContext;
|
|
FIsBoundsAssigned: Boolean;
|
|
FIsCaptionAssigned: Boolean;
|
|
FIsIconAssigned: Boolean;
|
|
FRect: TRect;
|
|
FSavePosition: Boolean;
|
|
FSaveZoomPosition: Boolean;
|
|
FShowExplorer: Boolean;
|
|
FThumbnailsOptions: TdxComponentPrinterThumbnailsOptions;
|
|
FVisibleOptions: TdxPreviewVisibleOptions;
|
|
FWindowState: TWindowState;
|
|
function GetCaption: string;
|
|
function GetHelpFile: string;
|
|
function GetIcon: TIcon;
|
|
function GetPosition(index: Integer): Integer;
|
|
function GetRect: TRect;
|
|
function GetRegistryPath: string;
|
|
function IsBoundsStored: Boolean;
|
|
function IsCaptionStored: Boolean;
|
|
function IsIconStored: Boolean;
|
|
procedure SetCaption(const Value: string);
|
|
procedure SetEnableOptions(Value: TdxPreviewEnableOptions);
|
|
procedure SetHelpContext(Value: THelpContext);
|
|
procedure SetHelpFile(const Value: string);
|
|
procedure SetIcon(Value: TIcon);
|
|
procedure SetPosition(Index: Integer; Value: Integer);
|
|
procedure SetRect(Value: TRect);
|
|
procedure SetRegistryPath(const Value: string);
|
|
procedure SetShowExplorer(Value: Boolean);
|
|
procedure SetThumbnailsOptions(Value: TdxComponentPrinterThumbnailsOptions);
|
|
procedure SetVisibleOptions(Value: TdxPreviewVisibleOptions);
|
|
procedure SetWindowState(Value: TWindowState);
|
|
|
|
function HasPreviewWindow: Boolean;
|
|
function PreviewWindow: TBasedxPreviewWindow;
|
|
|
|
procedure ReadBoundsRect(Stream: TStream);
|
|
procedure ReadIsCaptionAssigned(Reader: TReader);
|
|
procedure ReadIsIconAssigned(Reader: TReader);
|
|
procedure WriteBoundsRect(Stream: TStream);
|
|
procedure WriteIsCaptionAssigned(Writer: TWriter);
|
|
procedure WriteIsIconAssigned(Writer: TWriter);
|
|
protected
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
|
|
procedure DoAssign(Source: TdxBaseObject); override;
|
|
procedure DoRestoreDefaults; override;
|
|
|
|
function GetIsIconAssigned: Boolean;
|
|
procedure IconChanged(Sender: TObject); virtual;
|
|
procedure InitializeDefaultIcon(AnIcon: TIcon); virtual;
|
|
procedure RefreshIsIconAssigned;
|
|
public
|
|
constructor Create; override;
|
|
destructor Destroy; override;
|
|
|
|
function DefaultCaption: string; virtual;
|
|
function DefaultIcon: TIcon; virtual;
|
|
function DefaultRect: TRect; virtual;
|
|
|
|
procedure RestoreOriginalIcon;
|
|
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
|
|
property ComponentPrinter: TCustomdxComponentPrinter read FComponentPrinter;
|
|
property IsIconAssigned: Boolean read FIsIconAssigned;
|
|
property Rect: TRect read GetRect write SetRect;
|
|
published
|
|
property EnableOptions: TdxPreviewEnableOptions read FEnableOptions write SetEnableOptions
|
|
default [peoCanChangeMargins, peoPageBackground, peoPageSetup, peoPreferences, peoPrint, peoReportDesign];
|
|
property Caption: string read GetCaption write SetCaption stored IsCaptionStored;
|
|
property Height: Integer index 0 read GetPosition write SetPosition stored False;
|
|
property HelpFile: string read GetHelpFile write SetHelpFile stored False;
|
|
property HelpContext: THelpContext read FHelpContext write SetHelpContext default 0;
|
|
property Icon: TIcon read GetIcon write SetIcon stored IsIconStored;
|
|
property Left: Integer index 1 read GetPosition write SetPosition stored False;
|
|
property RegistryPath: string read GetRegistryPath write SetRegistryPath stored False;
|
|
property SavePosition: Boolean read FSavePosition write FSavePosition stored False default True;
|
|
property SaveZoomPosition: Boolean read FSaveZoomPosition write FSaveZoomPosition default True;
|
|
property ShowExplorer: Boolean read FShowExplorer write SetShowExplorer default False;
|
|
property ThumbnailsOptions: TdxComponentPrinterThumbnailsOptions read FThumbnailsOptions write SetThumbnailsOptions;
|
|
property Top: Integer index 2 read GetPosition write SetPosition stored False;
|
|
property VisibleOptions: TdxPreviewVisibleOptions read FVisibleOptions write SetVisibleOptions
|
|
default [pvoPageSetup, pvoPageBackground, pvoPreferences, pvoPrint, pvoReportDesign, pvoPrintStyles,
|
|
pvoReportFileOperations, pvoPageMargins];
|
|
property Width: Integer index 3 read GetPosition write SetPosition stored False;
|
|
property WindowState: TWindowState read FWindowState write SetWindowState default wsNormal;
|
|
end;
|
|
|
|
{ ComponentPrinter }
|
|
|
|
TdxBeforeDesignReportEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
ADesignWindow: TAbstractdxReportLinkDesignWindow) of object;
|
|
|
|
TdxCustomDrawPageEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
ACanvas: TCanvas; APageIndex: Integer; ARect: TRect; ANom, ADenom: Integer) of object;
|
|
|
|
TdxCustomDrawReportTitleEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
ACanvas: TCanvas; ARect: TRect; ANom, ADenom: Integer;
|
|
var TextAlignX: TdxTextAlignX; var TextAlignY: TdxTextAlignY;
|
|
var AColor: TColor; AFont: TFont; var ADone: Boolean) of object;
|
|
|
|
TdxCustomDrawPageHFEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
ACanvas: TCanvas; APageIndex: Integer; var ARect: TRect; ANom, ADenom: Integer;
|
|
var ADefaultDrawText, ADefaultDrawBackground: Boolean) of object;
|
|
|
|
TdxDesignReportEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
var ADone: Boolean) of object;
|
|
|
|
TdxGenerateReportProgressEvent = procedure(Sender: TObject;
|
|
AReportLink: TBasedxReportLink; APercentDone: Double {'##0.00'}) of object;
|
|
|
|
TdxGetPrintTitleEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
var ATitle: string) of object;
|
|
|
|
TdxPrintDlgDataEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
var APrintDlgData: TdxPrintDlgData) of object;
|
|
|
|
TdxMeasureReportTitleEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
var AHeight: Integer) of object;
|
|
|
|
TdxNewPageEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
APageIndex: Integer) of object;
|
|
|
|
TdxPageSetupEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
ADone: Boolean) of object;
|
|
|
|
TdxPreviewEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink) of object;
|
|
|
|
TdxPrintDeviceProblemEvent = procedure(Sender: TObject; var ADone: Boolean) of object;
|
|
|
|
TdxReportLinkNotifyEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink) of object;
|
|
|
|
TdxStartPrintEvent = procedure(Sender: TObject; AReportLink: TBasedxReportLink;
|
|
APageCount: Integer) of object;
|
|
|
|
TdxCPOption = (cpoAutoRebuildBeforePreview, cpoAutoRebuildBeforePrint,
|
|
cpoGenerateReportProgressEvent, cpoShowHourGlass, cpoDropStorageModeAfterPreview);
|
|
TdxCPOptions = set of TdxCPOption;
|
|
|
|
TdxCPState = (cpsBuilding, cpsDesigning, cpsPreviewing, cpsPrinting, cpsPrintDialog,
|
|
cpsPageSetupDialog, cpsDefineStylesDialog, cpsCustomizing, cpsLoading, cpsSaving,
|
|
cpsExplore);
|
|
TdxCPStates = set of TdxCPState;
|
|
|
|
TdxPSBuildStage = (bsStart, bsProgress, bsEnd);
|
|
TdxPSPrintStage = (psStart, psProgress, psEnd);
|
|
|
|
TdxPSComponentPrinterExplorerChangeNotifier = class(TdxPSExplorerChangeNotifierAdapter)
|
|
private
|
|
FComponentPrinter: TCustomdxComponentPrinter;
|
|
protected
|
|
procedure ItemDataUnloaded(AnItem: TdxPSExplorerItem); override;
|
|
public
|
|
constructor Create(AComponentPrinter: TCustomdxComponentPrinter);
|
|
property ComponentPrinter: TCustomdxComponentPrinter read FComponentPrinter;
|
|
end;
|
|
|
|
TCustomdxComponentPrinter = class(TComponent)
|
|
private
|
|
FAbortBuilding: Boolean;
|
|
FAbortPrinting: Boolean;
|
|
FAutoUpdateDateTime: Boolean;
|
|
FBeepAfterLongOperations: Boolean;
|
|
FCurrentLink: TBasedxReportLink;
|
|
FDateFormat: Integer;
|
|
FExplorer: TCustomdxPSExplorer;
|
|
FExplorerChangeNotifier: TdxPSComponentPrinterExplorerChangeNotifier;
|
|
FExplorerStubLink: TBasedxReportLink;
|
|
FInternalStreaming: Boolean;
|
|
FLongOperationTime: Integer;
|
|
FOptions: TdxCPOptions;
|
|
FPageNumberFormat: TdxPageNumberFormat;
|
|
FPreviewOptions: TdxPreviewOptions;
|
|
FPreviewWindow: TBasedxPreviewWindow;
|
|
FPreviewWindowDesigner: TAbstractdxPreviewWindowDesigner;
|
|
FPrintFileList: TStrings;
|
|
FPrintTitle: string;
|
|
FReportLinkDesigner: TAbstractdxReportLinkDesigner;
|
|
FReportLinks: TList;
|
|
FState: TdxCPStates;
|
|
FTimeFormat: Integer;
|
|
FVersion: Integer;
|
|
|
|
FOnAddReportLink: TdxReportLinkNotifyEvent;
|
|
FOnAfterPreview: TdxPreviewEvent;
|
|
FOnBeforeDesignReport: TdxBeforeDesignReportEvent;
|
|
FOnBeforePreview: TdxPreviewEvent;
|
|
FOnChangeComponent: TdxReportLinkNotifyEvent;
|
|
FOnChangeCurrentLink: TNotifyEvent;
|
|
FOnCustomDrawPage: TdxCustomDrawPageEvent;
|
|
FOnCustomDrawPageFooter: TdxCustomDrawPageHFEvent;
|
|
FOnCustomDrawPageHeader: TdxCustomDrawPageHFEvent;
|
|
FOnCustomDrawReportTitle: TdxCustomDrawReportTitleEvent;
|
|
FOnDeleteReportLink: TdxReportLinkNotifyEvent;
|
|
FOnDesignReport: TdxDesignReportEvent;
|
|
FOnEndGenerateReport: TdxReportLinkNotifyEvent;
|
|
FOnEndPrint: TdxReportLinkNotifyEvent;
|
|
FOnFinalizePrintDlgData: TdxPrintDlgDataEvent;
|
|
FOnGenerateReportProgress: TdxGenerateReportProgressEvent;
|
|
FOnGetPrintTitle: TdxGetPrintTitleEvent;
|
|
FOnInitializePrintDlgData: TdxPrintDlgDataEvent;
|
|
FOnMeasureReportTitle: TdxMeasureReportTitleEvent;
|
|
FOnNewPage: TdxNewPageEvent;
|
|
FOnPageSetup: TdxPageSetupEvent;
|
|
FOnPrintDeviceBusy: TdxPrintDeviceProblemEvent;
|
|
FOnPrintDeviceError: TdxPrintDeviceProblemEvent;
|
|
FOnStartGenerateReport: TdxReportLinkNotifyEvent;
|
|
FOnStartPrint: TdxStartPrintEvent;
|
|
|
|
FEndTime: DWORD;
|
|
FHFTextEntryChooseSubscriber: TdxEventSubscriber;
|
|
FLongOperationCounter: Integer;
|
|
FMemoryStream: TStream;
|
|
FModalPreview: Boolean;
|
|
FPrintAll: Boolean;
|
|
FSaveCollate: Boolean;
|
|
FSaveCopies: Integer;
|
|
FSavePageIndex: Integer;
|
|
FSavePrintToFile: Boolean;
|
|
FStartTime: DWORD;
|
|
FWindowHandle: HWND;
|
|
function GetCurrentLinkIndex: Integer;
|
|
function GetExplorerRealStubLink: TBasedxReportLink;
|
|
function GetIsExplorerMode: Boolean;
|
|
function GetLinkCount: Integer;
|
|
function GetPreviewCaption: string;
|
|
function GetReportLink(index: Integer): TBasedxReportLink;
|
|
procedure SetAbortBuilding(Value: Boolean);
|
|
procedure SetAbortPrinting(Value: Boolean);
|
|
procedure SetAutoUpdateDateTime(Value: Boolean);
|
|
procedure SetCurrentLink(Value: TBasedxReportLink);
|
|
procedure SetCurrentLinkIndex(Value: Integer);
|
|
procedure SetDateFormat(Value: Integer);
|
|
procedure SetExplorer(Value: TCustomdxPSExplorer);
|
|
procedure SetExplorerStubLink(Value: TBasedxReportLink);
|
|
procedure SetLongOperationTime(Value: Integer);
|
|
procedure SetPageNumberFormat(Value: TdxPageNumberFormat);
|
|
procedure SetPreviewOptions(Value: TdxPreviewOptions);
|
|
procedure SetupPreviewProperties(APreviewWindow: TBasedxPreviewWindow);
|
|
procedure SetPrintFileList(Value: TStrings);
|
|
procedure SetReportLink(index: Integer; Value: TBasedxReportLink);
|
|
procedure SetTimeFormat(Value: Integer);
|
|
|
|
function BeginPrintPages(const Source: string; out APageIndexes: TIntegers): Boolean;
|
|
procedure EndPrintPages(var APageIndexes: TIntegers);
|
|
|
|
function CreatePreviewWindow(AReportLink: TBasedxReportLink): TBasedxPreviewWindow;
|
|
procedure DestroyPreviewWindow;
|
|
|
|
procedure FinalizeDefaultPrintDlgData(AReportLink: TBasedxReportLink; var APrintDlgData: TdxPrintDlgData); virtual;
|
|
procedure InitializeDefaultPrintDlgData(AReportLink: TBasedxReportLink; out APrintDlgData: TdxPrintDlgData); virtual;
|
|
|
|
procedure InitDevModeFromPrinterPageSettings(APrinterPage: TdxPrinterPage);
|
|
|
|
function PrintDialog(AReportLink: TBasedxReportLink; var APrintDlgData: TdxPrintDlgData): Boolean;
|
|
function PrintPagesAsStringEx(const APages: string; APageNums: TdxPageNumbers;
|
|
ACopyCount: Integer; ACollate: Boolean; AReportLink: TBasedxReportLink = nil): Boolean;
|
|
procedure PrnDlgPageSetup(Sender: TObject; var ADone: Boolean;
|
|
APreviewBtnClicked, APrintBtnClicked: PBoolean);
|
|
|
|
procedure RaiseBuildingEvent(AReportLink: TBasedxReportLink;
|
|
const APercentCompleted: Double; AStage: TdxPSBuildStage);
|
|
procedure RaisePrintingEvent(AReportLink: TBasedxReportLink;
|
|
APageIndex, APageCount: Integer; AStage: TdxPSPrintStage);
|
|
|
|
procedure ActivateLink(AReportLink: TBasedxReportLink);
|
|
function CheckLink(Value: TBasedxReportLink): TBasedxReportLink;
|
|
function CreateLink(ALinkClass: TdxReportLinkClass;
|
|
AComponent: TComponent; AOwner: TComponent): TBasedxReportLink;
|
|
procedure DeactivateLink(AReportLink: TBasedxReportLink);
|
|
procedure InsertLink(Value: TBasedxReportLink);
|
|
procedure MoveLink(ACurIndex, ANewIndex: Integer);
|
|
procedure RemoveLink(Value: TBasedxReportLink);
|
|
procedure ResyncCurrentLink(AIndex: Integer);
|
|
|
|
procedure OnHFTextEntryChosen(Sender: TObject; const AEntry: string);
|
|
|
|
{ design-time support }
|
|
procedure DesignerModified;
|
|
procedure DesignerUpdate(AnItem: TBasedxReportLink);
|
|
function IsDesigning: Boolean;
|
|
function IsDestroying: Boolean;
|
|
function IsLoading: Boolean;
|
|
|
|
procedure ShowExistingPreviewWindow;
|
|
procedure WndProc(var Message: TMessage);
|
|
protected
|
|
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
|
|
procedure Loaded; override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure SetChildOrder(Child: TComponent; Order: Integer); override;
|
|
procedure SetName(const NewName: TComponentName); override;
|
|
|
|
procedure DoAddReportLink(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoAfterPreview(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoBeforeDesignReport(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoBeforeDestroyReport(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoBeforePreview(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoChangeComponent(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoChangeCurrentLink; dynamic;
|
|
procedure DoCustomDrawEntirePage(AReportLink: TBasedxReportLink; ACanvas: TCanvas;
|
|
APageIndex: Integer; ARect: TRect; ANom, ADenom: Integer); virtual;
|
|
procedure DoCustomDrawPageHeaderOrFooter(AReportLink: TBasedxReportLink;
|
|
AHFObject: TCustomdxPageObject; ACanvas: TCanvas; APageIndex: Integer;
|
|
R: TRect; var ADefaultDrawText, ADefaultDrawBackground: Boolean;
|
|
APixelsNumerator: Integer = 0); virtual;
|
|
procedure DoCustomDrawReportTitle(AReportLink: TBasedxReportLink; ACanvas: TCanvas;
|
|
ARect: TRect; var ATextAlignX: TdxTextAlignX; var ATextAlignY: TdxTextAlignY;
|
|
var AColor: TColor; AFont: TFont; var ADone: Boolean;
|
|
APixelsNumerator: Integer = 0); virtual;
|
|
procedure DoDeleteReportLink(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoDesignReport(AReportLink: TBasedxReportLink; ADone: Boolean); dynamic;
|
|
procedure DoEndPrint(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoFinalizePrintDlgData(AReportLink: TBasedxReportLink; var APrintDlgData: TdxPrintDlgData); dynamic;
|
|
procedure DoInitializePrintDlgData(AReportLink: TBasedxReportLink; var APrintDlgData: TdxPrintDlgData); dynamic;
|
|
procedure DoMeasureReportTitle(AReportLink: TBasedxReportLink; var AHeight: Integer); virtual;
|
|
procedure DoNewPage(AReportLink: TBasedxReportLink; APageIndex: Integer); dynamic;
|
|
procedure DoPageParamsChanged(AReportLink: TBasedxReportLink);
|
|
procedure DoPageSetup(AReportLink: TBasedxReportLink; ADone: Boolean); dynamic;
|
|
procedure DoPrintDeviceBusy; dynamic;
|
|
procedure DoPrintDeviceError; dynamic;
|
|
procedure DoProgress(AReportLink: TBasedxReportLink; const PercentDone: Double); dynamic;
|
|
procedure DoStartPrint(AReportLink: TBasedxReportLink; FullPageCount: Integer); dynamic;
|
|
procedure DoStartUpdateReport(AReportLink: TBasedxReportLink); dynamic;
|
|
procedure DoEndUpdateReport(AReportLink: TBasedxReportLink); dynamic;
|
|
function GetPrintTitle(AReportLink: TBasedxReportLink): string; dynamic;
|
|
procedure StdProcessPrintDeviceBusy; virtual;
|
|
procedure StdProcessPrintDeviceError; virtual;
|
|
|
|
function IsCustomPrintDlgData: Boolean;
|
|
|
|
function IsForegroundPreviewWindow: Boolean;
|
|
function IsGenerateReportProgressEvent: Boolean;
|
|
function IsRebuildBeforeOutput(AForceRebuild: Boolean): Boolean;
|
|
function IsRebuildBeforePreview: Boolean;
|
|
function IsRebuildBeforePrint: Boolean;
|
|
function IsShowHourGlass: Boolean;
|
|
|
|
procedure PaintThumbnailPage(ACanvas: TCanvas; APageIndex: Integer;
|
|
const APageBounds, AContentBounds: TRect; AReportLink: TBasedxReportLink = nil);
|
|
procedure PaintThumbnailPageIndex(ACanvas: TCanvas; const R: TRect; APageIndex: Integer);
|
|
|
|
procedure FormatChanged(AReportLink: TBasedxReportLink);
|
|
procedure PreparePageSetup;
|
|
procedure PrepareBuildReport(AReportLink: TBasedxReportLink);
|
|
procedure PrepareLongOperation;
|
|
procedure PreparePrintDevice;
|
|
procedure PrepareReport(AReportLink: TBasedxReportLink);
|
|
procedure PrintPage(AReportLink: TBasedxReportLink; APageIndex: Integer); virtual;
|
|
procedure UnprepareBuildReport(AReportLink: TBasedxReportLink);
|
|
procedure UnprepareLongOperation;
|
|
procedure UnpreparePageSetup;
|
|
procedure UnpreparePrintDevice;
|
|
procedure UnprepareReport(AReportLink: TBasedxReportLink);
|
|
|
|
{ Stream loading }
|
|
procedure AfterLoadFromStream(AStream: TStream);
|
|
procedure BeforeLoadFromStream(AStream: TStream);
|
|
procedure ErrorLoadFromStream(AStream: TStream);
|
|
procedure LoadItselfFromStream(AStream: TStream);
|
|
procedure LoadLinksFromStream(AStream: TStream);
|
|
procedure LoadVersionFromStream(AStream: TStream; var AVersion: Integer);
|
|
procedure PrepareLoadFromStream(AStream: TStream);
|
|
procedure UnprepareLoadFromStream(AStream: TStream);
|
|
{ Stream saving}
|
|
procedure PrepareSaveToStream(AStream: TStream);
|
|
procedure SaveItselfToStream(AStream: TStream);
|
|
procedure SaveLinksToStream(AStream: TStream);
|
|
procedure SaveVersionToStream(AStream: TStream);
|
|
procedure UnprepareSaveToStream(AStream: TStream);
|
|
|
|
property ExplorerChangeNotifier: TdxPSComponentPrinterExplorerChangeNotifier read FExplorerChangeNotifier;
|
|
property PreviewCaption: string read GetPreviewCaption;
|
|
property OnAfterPreview: TdxPreviewEvent read FOnAfterPreview write FOnAfterPreview;
|
|
property OnBeforeDesignReport: TdxBeforeDesignReportEvent read FOnBeforeDesignReport write FOnBeforeDesignReport;
|
|
property OnBeforePreview: TdxPreviewEvent read FOnBeforePreview write FOnBeforePreview;
|
|
property OnChangeComponent: TdxReportLinkNotifyEvent read FOnChangeComponent write FOnChangeComponent;
|
|
property OnChangeCurrentLink: TNotifyEvent read FOnChangeCurrentLink write FOnChangeCurrentLink;
|
|
property OnCustomDrawPageHeader: TdxCustomDrawPageHFEvent read FOnCustomDrawPageHeader write FOnCustomDrawPageHeader;
|
|
property OnCustomDrawPageFooter: TdxCustomDrawPageHFEvent read FOnCustomDrawPageFooter write FOnCustomDrawPageFooter;
|
|
property OnCustomDrawReportTitle: TdxCustomDrawReportTitleEvent read FOnCustomDrawReportTitle write FOnCustomDrawReportTitle;
|
|
property OnDesignReport: TdxDesignReportEvent read FOnDesignReport write FOnDesignReport;
|
|
property OnMeasureReportTitle: TdxMeasureReportTitleEvent read FOnMeasureReportTitle write FOnMeasureReportTitle;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
function AddComposition: TdxCompositionReportLink;
|
|
function AddEmptyLink(ALinkClass: TdxReportLinkClass): TBasedxReportLink;
|
|
function AddEmptyLinkEx(ALinkClass: TdxReportLinkClass; AOwner: TComponent): TBasedxReportLink;
|
|
function AddLink(AComponent: TComponent): TBasedxReportLink;
|
|
function AddLinkEx(AComponent: TComponent; AOwner: TComponent): TBasedxReportLink;
|
|
procedure AssignReportLinks(Source: TCustomdxComponentPrinter);
|
|
function CreateLinkFromFile(const AFileName: string): TBasedxReportLink;
|
|
function CreateLinkFromStream(AStream: TStream): TBasedxReportLink;
|
|
procedure DeleteAllLinks;
|
|
procedure DeleteLink(AIndex: Integer);
|
|
procedure DestroyReport(AReportLink: TBasedxReportLink = nil);
|
|
function FindLinkByComponent(Value: TComponent; ACanCreate: Boolean = False): TBasedxReportLink;
|
|
procedure GetLinks(AList: TList);
|
|
function IndexOfLink(AReportLink: TBasedxReportLink): Integer; overload;
|
|
function IndexOfLink(const AName: string): Integer; overload;
|
|
function IndexOfLinkByName(const AName: string): Integer;
|
|
function LinkByName(const AName: string): TBasedxReportLink;
|
|
procedure RebuildReport(AReportLink: TBasedxReportLink = nil);
|
|
|
|
class function GetNewLinkName(AReportLink: TBasedxReportLink): string;
|
|
class function IsSupportedCompClass(AComponentClass: TClass): Boolean; overload;
|
|
class function IsSupportedCompClass(AComponent: TObject{TComponent}): Boolean; overload;
|
|
|
|
{ composition support }
|
|
function CurrentCompositionByLink(AReportLink: TBasedxReportLink): TdxCompositionReportLink;
|
|
procedure GetCompositionsByLink(AReportLink: TBasedxReportLink; ACompositions: TList);
|
|
procedure GetItems(AComposition: TdxCompositionReportLink; AStrings: TStrings; AExcludeAssigned: Boolean);
|
|
function IsLinkInComposition(AReportLink: TBasedxReportLink; AComposition: TdxCompositionReportLink): Boolean;
|
|
function IsLinkInCurrentComposition(AReportLink: TBasedxReportLink): Boolean;
|
|
|
|
procedure Explore;
|
|
|
|
function DesignerExists(AReportLink: TBasedxReportLink = nil): Boolean;
|
|
function DesignerExistsByComponent(AComponent: TComponent): Boolean;
|
|
function DesignReport(AReportLink: TBasedxReportLink = nil): Boolean;
|
|
|
|
procedure DrawPageFooter(AReportLink: TBasedxReportLink; APageIndex: Integer;
|
|
ARect: TRect; ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
procedure DrawPageHeader(AReportLink: TBasedxReportLink; APageIndex: Integer;
|
|
ARect: TRect; ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
|
|
procedure GetPageColRowCount(out ACol, ARow: Integer; AReportLink: TBasedxReportLink = nil);
|
|
function GetPageCount(AReportLink: TBasedxReportLink = nil): Integer;
|
|
|
|
function PageSetup(AReportLink: TBasedxReportLink = nil): Boolean;
|
|
function PageSetupEx(AActivePageIndex: Integer; AShowPreviewBtn, AShowPrintBtn: Boolean;
|
|
out APreviewBtnClicked, APrintBtnClicked: Boolean; AReportLink: TBasedxReportLink = nil): Boolean; overload;
|
|
function PageSetupEx(AActivePageIndex: Integer; APreviewBtnClicked, APrintBtnClicked: PBoolean;
|
|
AReportLink: TBasedxReportLink = nil): Boolean; overload; {$IFDEF DELPHI6} deprecated; {$ENDIF}
|
|
|
|
procedure PaintPage(ACanvas: TCanvas; APageIndex: Integer;
|
|
const APageBounds, AContentBounds: TRect; AReportLink: TBasedxReportLink = nil);
|
|
|
|
procedure Preview(AModal: Boolean = True; AReportLink: TBasedxReportLink = nil);
|
|
function PreviewExists: Boolean;
|
|
|
|
function Print(AShowDialog: Boolean; APPrintDlgData: PdxPrintDlgData;
|
|
AReportLink: TBasedxReportLink = nil): Boolean;
|
|
procedure PrintEx(APageNums: TdxPageNumbers; ACopies: Integer; ACollate: Boolean;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
procedure PrintPages(const APageIndexes: array of Integer;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
procedure PrintPagesEx(const APageIndexes: array of Integer;
|
|
APageNums: TdxPageNumbers; ACopyCount: Integer; ACollate: Boolean;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
|
|
procedure LoadFromFile(const AName: string);
|
|
procedure LoadFromStream(AStream: TStream);
|
|
procedure SaveToFile(const AName: string);
|
|
procedure SaveToStream(AStream: TStream);
|
|
|
|
property AbortBuilding: Boolean read FAbortBuilding write SetAbortBuilding;
|
|
property AbortPrinting: Boolean read FAbortPrinting write SetAbortPrinting;
|
|
property AutoUpdateDateTime: Boolean read FAutoUpdateDateTime write SetAutoUpdateDateTime default True;
|
|
property BeepAfterLongOperations: Boolean read FBeepAfterLongOperations write FBeepAfterLongOperations default True;
|
|
property CurrentLink: TBasedxReportLink read FCurrentLink write SetCurrentLink;
|
|
property CurrentLinkIndex: Integer read GetCurrentLinkIndex write SetCurrentLinkIndex;
|
|
property DateFormat: Integer read FDateFormat write SetDateFormat default 0;
|
|
property Explorer: TCustomdxPSExplorer read FExplorer write SetExplorer;
|
|
property ExplorerRealStubLink: TBasedxReportLink read GetExplorerRealStubLink;
|
|
property ExplorerStubLink: TBasedxReportLink read FExplorerStubLink write SetExplorerStubLink;
|
|
property IsExplorerMode: Boolean read GetIsExplorerMode;
|
|
property LinkCount: Integer read GetLinkCount;
|
|
property LongOperationTime: Integer read FLongOperationTime write SetLongOperationTime default 5000; {ms}
|
|
property Options: TdxCPOptions read FOptions write FOptions
|
|
default [Low(TdxCPOption)..High(TdxCPOption)]; {dxDefaultCPOptions}
|
|
property PageNumberFormat: TdxPageNumberFormat read FPageNumberFormat write SetPageNumberFormat default pnfNumeral;
|
|
property PreviewOptions: TdxPreviewOptions read FPreviewOptions write SetPreviewOptions;
|
|
property PreviewWindow: TBasedxPreviewWindow read FPreviewWindow;
|
|
property PrintFileList: TStrings read FPrintFileList write SetPrintFileList;
|
|
property PrintTitle: string read FPrintTitle write FPrintTitle;
|
|
property ReportLink[Index: Integer]: TBasedxReportLink read GetReportLink write SetReportLink; default;
|
|
property State: TdxCPStates read FState;
|
|
property TimeFormat: Integer read FTimeFormat write SetTimeFormat default 0;
|
|
property Version: Integer read FVersion write FVersion;
|
|
|
|
property PreviewWindowDesigner: TAbstractdxPreviewWindowDesigner read FPreviewWindowDesigner;
|
|
property ReportLinkDesigner: TAbstractdxReportLinkDesigner read FReportLinkDesigner;
|
|
|
|
property OnAddReportLink: TdxReportLinkNotifyEvent read FOnAddReportLink write FOnAddReportLink;
|
|
property OnCustomDrawPage: TdxCustomDrawPageEvent read FOnCustomDrawPage write FOnCustomDrawPage;
|
|
property OnDeleteReportLink: TdxReportLinkNotifyEvent read FOnDeleteReportLink write FOnDeleteReportLink;
|
|
property OnEndGenerateReport: TdxReportLinkNotifyEvent read FOnEndGenerateReport write FOnEndGenerateReport;
|
|
property OnEndPrint: TdxReportLinkNotifyEvent read FOnEndPrint write FOnEndPrint;
|
|
property OnFinalizePrintDlgData: TdxPrintDlgDataEvent read FOnFinalizePrintDlgData write FOnFinalizePrintDlgData;
|
|
property OnGenerateReportProgress: TdxGenerateReportProgressEvent read FOnGenerateReportProgress write FOnGenerateReportProgress;
|
|
property OnGetPrintTitle: TdxGetPrintTitleEvent read FOnGetPrintTitle write FOnGetPrintTitle;
|
|
property OnInitializePrintDlgData: TdxPrintDlgDataEvent read FOnInitializePrintDlgData write FOnInitializePrintDlgData;
|
|
property OnNewPage: TdxNewPageEvent read FOnNewPage write FOnNewPage;
|
|
property OnPageSetup: TdxPageSetupEvent read FOnPageSetup write FOnPageSetup;
|
|
property OnPrintDeviceBusy: TdxPrintDeviceProblemEvent read FOnPrintDeviceBusy write FOnPrintDeviceBusy;
|
|
property OnPrintDeviceError: TdxPrintDeviceProblemEvent read FOnPrintDeviceError write FOnPrintDeviceError;
|
|
property OnStartGenerateReport: TdxReportLinkNotifyEvent read FOnStartGenerateReport write FOnStartGenerateReport;
|
|
property OnStartPrint: TdxStartPrintEvent read FOnStartPrint write FOnStartPrint;
|
|
end;
|
|
|
|
TdxEnumPagesAsImagesProc = procedure(AComponentPrinter: TCustomdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; AIndex, APageIndex: Integer;
|
|
const AGraphic: TGraphic; AData: Pointer;
|
|
var AContinue: Boolean) of object;
|
|
|
|
TdxExportProgressEvent = procedure(Sender: TCustomdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; APageCount, AIndex, APageIndex: Integer;
|
|
AData: Pointer) of object;
|
|
|
|
TdxExportPrepareGraphicEvent = procedure(Sender: TCustomdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; const AGraphic: TGraphic;
|
|
AData: Pointer) of object;
|
|
|
|
TdxExportGetPageFileNameEvent = procedure(Sender: TCustomdxComponentPrinter;
|
|
AIndex, APageIndex: Integer; var AFileName: string) of object;
|
|
|
|
TdxOnFilterComponentEvent = procedure(Sender: TObject; var AComponent: TComponent;
|
|
var ACaption, ADescription: string; var Accept: Boolean) of object;
|
|
|
|
TdxOnGetSupportedComponentsEvent = procedure(Sender: TObject; AComponents: TStrings) of object;
|
|
|
|
TdxCPCustomizeDlgOption = (cdoShowDescription);
|
|
TdxCPCustomizeDlgOptions = set of TdxCPCustomizeDlgOption;
|
|
|
|
TdxComponentPrinter = class(TCustomdxComponentPrinter)
|
|
private
|
|
FCustomizeDlgOptions: TdxCPCustomizeDlgOptions;
|
|
FOverWriteAll: Boolean;
|
|
FOverWriteExistingFiles: Boolean;
|
|
FOverWriteFile: Boolean;
|
|
FOnExportGetPageFileName: TdxExportGetPageFileNameEvent;
|
|
FOnExportPrepareGraphic: TdxExportPrepareGraphicEvent;
|
|
FOnExportProgress: TdxExportProgressEvent;
|
|
FOnFilterComponent: TdxOnFilterComponentEvent;
|
|
FOnGetSupportedComponents: TdxOnGetSupportedComponentsEvent;
|
|
procedure WritePageAsImageToDisk(AComponentPrinter: TCustomdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; AIndex, APageIndex: Integer;
|
|
const AGraphic: TGraphic; AData: Pointer;
|
|
var AContinue: Boolean);
|
|
protected
|
|
procedure Loaded; override;
|
|
function DoFilterComponent(AComponent: TComponent; var ACaption, ADescription: string): Boolean; dynamic;
|
|
procedure GetDefaultExportPageFileName(AIndex, APageIndex: Integer; var AFileName: string); dynamic;
|
|
procedure GetExportPageFileName(AIndex, APageIndex: Integer; var AFileName: string); dynamic;
|
|
function GetSupportedComponents(AComponents: TStrings): Boolean; dynamic;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
procedure ShowCustomizeDlg;
|
|
|
|
procedure LoadFromRegistry(const APath: string);
|
|
procedure SaveToRegistry(const APath: string);
|
|
|
|
procedure EnumPagesAsImages(const APageIndexes: array of Integer;
|
|
AGraphicClass: TGraphicClass; ADrawBackground: Boolean;
|
|
ACallBackProc: TdxEnumPagesAsImagesProc; ACallBackData, AProgressData,
|
|
APrepareData: Pointer;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
procedure SavePagesAsImagesToDisk(const APageIndexes: array of Integer;
|
|
AGraphicClass: TGraphicClass; ADrawBackground: Boolean; const AFileMask: string;
|
|
AProgressData, APrepareData: Pointer;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
published
|
|
property AutoUpdateDateTime;
|
|
property BeepAfterLongOperations;
|
|
property CurrentLink;
|
|
property CustomizeDlgOptions: TdxCPCustomizeDlgOptions read FCustomizeDlgOptions write FCustomizeDlgOptions
|
|
default [cdoShowDescription];
|
|
property DateFormat;
|
|
property Explorer;
|
|
property ExplorerStubLink;
|
|
property LongOperationTime;
|
|
property Options;
|
|
property OverWriteExistingFiles: Boolean read FOverWriteExistingFiles write FOverWriteExistingFiles default False;
|
|
property PageNumberFormat;
|
|
property PreviewOptions;
|
|
property PrintTitle;
|
|
property TimeFormat;
|
|
property Version;
|
|
|
|
property OnAddReportLink;
|
|
property OnAfterPreview;
|
|
property OnBeforeDesignReport;
|
|
property OnBeforePreview;
|
|
property OnChangeComponent;
|
|
property OnChangeCurrentLink;
|
|
property OnCustomDrawPage;
|
|
property OnCustomDrawPageFooter;
|
|
property OnCustomDrawPageHeader;
|
|
property OnCustomDrawReportTitle;
|
|
property OnDeleteReportLink;
|
|
property OnDesignReport;
|
|
property OnEndGenerateReport;
|
|
property OnEndPrint;
|
|
property OnExportGetPageFileName: TdxExportGetPageFileNameEvent read FOnExportGetPageFileName write FOnExportGetPageFileName;
|
|
property OnExportPrepareGraphic: TdxExportPrepareGraphicEvent read FOnExportPrepareGraphic write FOnExportPrepareGraphic;
|
|
property OnExportProgress: TdxExportProgressEvent read FOnExportProgress write FOnExportProgress;
|
|
property OnFilterComponent: TdxOnFilterComponentEvent read FOnFilterComponent write FOnFilterComponent;
|
|
property OnFinalizePrintDlgData;
|
|
property OnGetPrintTitle;
|
|
property OnGenerateReportProgress;
|
|
property OnGetSupportedComponents: TdxOnGetSupportedComponentsEvent read FOnGetSupportedComponents write FOnGetSupportedComponents;
|
|
property OnInitializePrintDlgData;
|
|
property OnMeasureReportTitle;
|
|
property OnNewPage;
|
|
property OnPageSetup;
|
|
property OnPrintDeviceBusy;
|
|
property OnPrintDeviceError;
|
|
property OnStartGenerateReport;
|
|
property OnStartPrint;
|
|
end;
|
|
|
|
TAbstractdxPreviewWindowDesigner = class
|
|
private
|
|
FComponentPrinter: TCustomdxComponentPrinter;
|
|
protected
|
|
procedure Activate; virtual; abstract;
|
|
procedure Modified; virtual; abstract;
|
|
public
|
|
constructor Create(AComponentPrinter: TCustomdxComponentPrinter);
|
|
destructor Destroy; override;
|
|
|
|
property ComponentPrinter: TCustomdxComponentPrinter read FComponentPrinter;
|
|
end;
|
|
|
|
TAbstractdxReportLinkDesigner = class
|
|
private
|
|
FComponentPrinter: TCustomdxComponentPrinter;
|
|
protected
|
|
procedure Modified; virtual; abstract;
|
|
procedure Update(Item: TBasedxReportLink); virtual; abstract;
|
|
public
|
|
constructor Create(AComponentPrinter: TCustomdxComponentPrinter);
|
|
destructor Destroy; override;
|
|
|
|
procedure BeginUpdate; virtual; abstract;
|
|
procedure CancelUpdate; virtual; abstract;
|
|
procedure EndUpdate; virtual; abstract;
|
|
|
|
property ComponentPrinter: TCustomdxComponentPrinter read FComponentPrinter;
|
|
end;
|
|
|
|
{ This si a routine for fast PrintPreview and(or) Printing an individual component.
|
|
You MUST add "unit" contained "Link" that supports the "AComponent" into the uses
|
|
clause of the your unit }
|
|
|
|
function dxPrintComponent(AComponent: TComponent; APrintPreview: Boolean = True;
|
|
APrintDialog: Boolean = False; const AReportTitle: string = '';
|
|
const APrintTitle: string = ''): Boolean;
|
|
|
|
{ Enum Pages as Images routines }
|
|
|
|
procedure dxPSEnumReportPages(AComponentPrinter: TdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; const APageIndexes: array of Integer;
|
|
AGraphicClass: TGraphicClass; AnExportBackground: Boolean;
|
|
ACallBackProc: TdxEnumPagesAsImagesProc;
|
|
ACallBackData: Pointer;
|
|
AProgressProc: TdxExportProgressEvent;
|
|
AProgressData: Pointer;
|
|
APrepareGraphicProc: TdxExportPrepareGraphicEvent;
|
|
APrepareData: Pointer);
|
|
|
|
{ ReportLinks registration routines }
|
|
|
|
procedure dxPSRegisterReportLink(ALinkClass: TdxReportLinkClass;
|
|
AComponentClass: TComponentClass; ADesignerClass: TdxReportLinkDesignWindowClass);
|
|
procedure dxPSUnregisterReportLink(ALinkClass: TdxReportLinkClass;
|
|
AComponentClass: TComponentClass; ADesignerClass: TdxReportLinkDesignWindowClass);
|
|
procedure dxPSUnregisterReportLinks(const ALinkClasses: array of TdxReportLinkClass);
|
|
|
|
function dxPSDesignerClassByCompClass(AComponentClass: TClass): TdxReportLinkDesignWindowClass; overload;
|
|
function dxPSDesignerClassByCompClass(AComponent: TObject{TComponent}): TdxReportLinkDesignWindowClass; overload;
|
|
|
|
function dxPSDesignerClassByLinkClass(ALinkClass: TClass): TdxReportLinkDesignWindowClass; overload;
|
|
function dxPSDesignerClassByLinkClass(ALink: TObject{TBasedxReportLink}): TdxReportLinkDesignWindowClass; overload;
|
|
|
|
function dxPSLinkClassByCompClass(AComponentClass: TClass): TdxReportLinkClass; overload;
|
|
function dxPSLinkClassByCompClass(AComponent: TObject{TComponent}): TdxReportLinkClass; overload;
|
|
|
|
procedure dxPSGetActiveReportLinksList(AClassList: TdxClassList);
|
|
procedure dxPSGetReportLinksList(AClassList: TdxClassList);
|
|
procedure dxPSGetLinkSupportedComponentsList(AClassList: TdxClassList; ALinkClass: TClass); overload;
|
|
procedure dxPSGetLinkSupportedComponentsList(AClassList: TdxClassList; ALink: TObject{TBasedxReportLink}); overload;
|
|
procedure dxPSGetSupportedComponentsList(AClassList: TdxClassList);
|
|
|
|
function dxPSIsSupportedCompClass(AComponentClass: TClass): Boolean; overload;
|
|
function dxPSIsSupportedCompClass(AComponent: TObject{TComponent}): Boolean; overload;
|
|
|
|
{ PreviewWindow registration routines }
|
|
|
|
function dxPSGetPreviewWindowClassByClassName(const AClassName: string): TdxPreviewWindowClass;
|
|
procedure dxPSGetPreviewWindowList(AStrings: TStrings);
|
|
procedure dxPSRegisterPreviewWindow(APreviewWindowClass: TdxPreviewWindowClass);
|
|
procedure dxPSUnregisterPreviewWindow(APreviewWindowClass: TdxPreviewWindowClass = nil);
|
|
|
|
{ Units convertation routines }
|
|
|
|
function OnePixel: Integer;
|
|
function PixelsNumerator: Integer;
|
|
function PixelsDenominator: Integer;
|
|
|
|
{ Helpers }
|
|
|
|
procedure FixupRect(DC: HDC; var R: TRect);
|
|
procedure Get3DBorderBrushes(AEdgeStyle: TdxCellEdgeStyle; ASoft: Boolean;
|
|
var AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush: HBRUSH);
|
|
procedure Get3DBorderColors(AEdgeStyle: TdxCellEdgeStyle; ASoft: Boolean;
|
|
var AOuterTLColor, AOuterBRColor, AInnerTLColor, AInnerBRColor: TColor);
|
|
|
|
function dxPSExplorerImages: TCustomImageList;
|
|
|
|
procedure dxPSStartWait;
|
|
procedure dxPSStopWait;
|
|
|
|
const
|
|
CM_FREEEXPLORERITEM = WM_USER + 1;
|
|
|
|
cemSingle = cemPattern; // obsolete: declared only for backward compatibility
|
|
cesNone = cesRaised; // obsolete: declared only for backward compatibility
|
|
|
|
csAll = [csLeft..csBottom];
|
|
csTopLeft = [csLeft, csTop];
|
|
csBottomRight = [csRight, csBottom];
|
|
csLeftRight = [csLeft, csRight];
|
|
csTopBottom = [csTop, csBottom];
|
|
|
|
tlpAll: TdxPSTreeLineParts = [tlpTop, tlpRight, tlpBottom];
|
|
|
|
dxAlignment: array[TdxTextAlignX] of TAlignment = (taLeftJustify, taCenter, taRightJustify, taCenter, taCenter);
|
|
dxCalcFormat: array[Boolean] of UINT =
|
|
(DXTO_CALCRECT or DXTO_AUTOINDENTS {or DXTO_EXPANDTABS} or DXTO_CHARBREAK or DXTO_SINGLELINE,
|
|
DXTO_CALCRECT or DXTO_AUTOINDENTS or DXTO_EXPANDTABS or DXTO_CHARBREAK or DXTO_WORDBREAK);
|
|
|
|
dxDrawTextTextAlignX: array[TdxTextAlignX] of UINT = (DT_LEFT, DT_CENTER, DT_RIGHT, DT_CENTER, DT_CENTER);
|
|
dxDrawTextTextAlignY: array[TdxTextAlignY] of UINT = (DT_TOP, DT_VCENTER, DT_BOTTOM, DT_TOP);
|
|
|
|
dxImageLayout: array[TAlignment] of TdxImageLayout = (ilImageCenterLeft, ilImageCenterRight, ilImageCenterCenter);
|
|
dxMultilineTextAlignY: array[Boolean] of TdxTextAlignY = (taCenterY, taTop);
|
|
dxTextAlignX: array[TAlignment] of TdxTextAlignX = (taLeft, taRight, taCenterX);
|
|
dxTextAlignY: array[TTextLayout] of TdxTextAlignY = (taTop, taCenterY, taBottom);
|
|
|
|
//TdxCellEdgeStyle = (cesRaised, cesSunken)
|
|
dxCellBorderClassMap: array[TdxCellEdgeStyle, Boolean] of TdxPSCellBorderClass =
|
|
((TdxPSCellRaisedBorder, TdxPSCellRaisedSoftBorder),
|
|
(TdxPSCellSunkenBorder, TdxPSCellSunkenSoftBorder));
|
|
dxDefaultCPOptions =
|
|
[cpoAutoRebuildBeforePreview, cpoAutoRebuildBeforePrint,
|
|
cpoGenerateReportProgressEvent, cpoShowHourGlass, cpoDropStorageModeAfterPreview];
|
|
dxDefaultPreviewEnableOptions =
|
|
[peoCanChangeMargins, peoPageBackground, peoPageSetup, peoPreferences,
|
|
peoPrint, peoReportDesign];
|
|
dxDefaultPreviewVisibleOptions =
|
|
[pvoPageBackground, pvoPageSetup, pvoPreferences, pvoPrint, pvoReportDesign,
|
|
pvoPrintStyles, pvoReportFileOperations, pvoPageMargins];
|
|
|
|
dxThumbnailsZoomFactors: array[TdxPSThumbnailsSize] of Integer = (5, 10);
|
|
|
|
dxDefaultBkColor = clWhite;
|
|
dxDefaultBreakByChars = True;
|
|
dxDefaultCellSides = csAll;
|
|
dxDefaultCheckFlatBorder = True;
|
|
dxDefaultCheckPos = ccpCenter;
|
|
dxDefaultColor = clWhite;
|
|
dxDefaultContentColor = dxDefaultColor;
|
|
dxDefaultCrossSignCrossSize = 9; // pixels
|
|
dxDefaultEdgeMode = cemPattern;
|
|
dxDefaultEdge3DSoft = True;
|
|
dxDefaultEdge3DStyle = cesRaised;
|
|
dxDefaultEndEllipsis = False;
|
|
dxDefaultExpandButtonBorderColor = clBlack;
|
|
dxDefaultFixedColor = clBtnFace; //clSilver;
|
|
dxDefaultFixedTransparent = False;
|
|
dxDefaultFont: array[0..LF_FACESIZE - 1] of Char = 'Times New Roman';
|
|
dxDefaultGridLineColor = clBlack;
|
|
dxDefaultGroupBorderColor = clBtnFace;
|
|
dxDefaultGroupCaptionColor = clBtnFace;
|
|
dxDefaultGroupCaptionSeparatorColor = clBtnFace;
|
|
dxDefaultGroupColor = clBtnFace;
|
|
dxDefaultHidePrefix = False;
|
|
dxDefaultMultiline = False;
|
|
dxDefaultShadowColor = clBlack;
|
|
dxDefaultShadowDepth = 3;
|
|
dxDefaultSortOrder = csoNone;
|
|
dxDefaultPreventLeftTextExceed = True;
|
|
dxDefaultPreventTopTextExceed = True;
|
|
dxDefaultReportGroupCaptionIndent = 5;
|
|
dxDefaultReportGroupLookAndFeel: TdxPSReportGroupLookAndFeelClass = TdxPSReportGroupStandardLookAndFeel;
|
|
dxDefaultTextAlignX = taLeft;
|
|
dxDefaultTextAlignY = taCenterY;
|
|
dxDefaultTransparent = True;
|
|
dxDefaultTreeLineColor = clGray;
|
|
|
|
dxPSDefaultFontCharSet = DEFAULT_CHARSET;
|
|
dxPSDefaultFontColor = clBlack;
|
|
dxPSDefaultFontName = 'Times New Roman';
|
|
dxPSDefaultFontSize = 8;
|
|
dxPSDefaultFontStyle = [];
|
|
|
|
dxPSDefaultPreviewThumbnailsFontColor = clBlue;
|
|
dxPSDefaultPreviewThumbnailsFontName = 'Tahoma';
|
|
dxPSDefaultPreviewThumbnailsFontSize = 48;
|
|
dxPSDefaultPreviewThumbnailsFontStyle = [];
|
|
|
|
dxPSDefaultReportTitleFontColor = clBlack;
|
|
dxPSDefaultReportTitleFontName = dxPSDefaultFontName;
|
|
dxPSDefaultReportTitleFontSize = 14;
|
|
dxPSDefaultReportTitleFontStyle = [fsBold];
|
|
|
|
dxRadioGroupInterColumnsMinSpace = 1;
|
|
dxRadioGroupInterRowsMinSpace = 1;
|
|
dxRadioGroupBoundsIndent = 2;
|
|
|
|
dxTextSpace = 2;
|
|
|
|
dxPSReportFileLongExtension = 'ExpressPrinting System-Report'; //Don't Localize
|
|
dxPSReportFileShortExtension = 'rps'; //Don't Localize
|
|
|
|
dxSortMarkRgnSize = 16;
|
|
dxSortMarkWidth = 8;
|
|
dxSortMarkHeight = 7;
|
|
|
|
sdxDocumentCaptionSeparator = '-';
|
|
|
|
var
|
|
FUnitsPerInch: Integer = 4800;
|
|
FDontPrintTransparentImages: Boolean = False; // affects only on Printout
|
|
|
|
iiExplorerFolderCollapsed: Integer = -1;
|
|
iiExplorerFolderExpanded: Integer = -1;
|
|
iiExplorerItem: Integer = -1;
|
|
iiExplorerItemHasInvalidData: Integer = -1;
|
|
iiDriveTypes: array[TdxDriveType] of Integer = (-1, -1, -1, -1, -1, -1, -1);
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF DELPHI7}
|
|
Themes,
|
|
UxTheme,
|
|
{$ENDIF}
|
|
{$IFDEF DELPHI6}
|
|
Variants,
|
|
{$ENDIF}
|
|
{$IFNDEF CBUILDER6}
|
|
dxPSCPDsg,
|
|
{$ENDIF}
|
|
{$IFDEF USEJPEGIMAGE}
|
|
Jpeg,
|
|
{$ENDIF}
|
|
TypInfo, Registry, Consts, CommCtrl, Dialogs, ShlObj, ShellAPI, dxPSRes,
|
|
dxPSImgs, dxPSUtl, dxPSEvnt, dxPSEdgePatterns, dxfmDTFmt, dxfmPNFmt, dxPSfmTtl,
|
|
dxfmChFN, dxPrnDev, dxPSPgsMnuBld, dxPSfmReportProperties, dxPSXplorerTreeView,
|
|
dxPSCompsProvider, dxPSfmCompositionDsg, dxPSPrVwStd;
|
|
|
|
function OffsetWindowOrgEx(DC: HDC; X, Y: Integer; Pt: PPoint): BOOL; stdcall; external gdi32 name 'OffsetWindowOrgEx';
|
|
|
|
const
|
|
FExplorerImages: TCustomImageList = nil;
|
|
|
|
// Image Indexes of Drive Types in ExplorerImages
|
|
DriveTypeImageIndexMap: array[TdxDriveType] of Integer = (-1, -1, 7, 8, 9, 11, 12);
|
|
|
|
// Page "Update Codes" that force us to Rebuild Report or Recalculate ViewInfos
|
|
SignificantPrinterPageUpdateCodes: TdxPrinterPageUpdateCodes = [ucMarginLeft, ucMarginTop, ucMarginRight, ucMarginBottom, ucScale];
|
|
|
|
MaxGlyphCount = 6; // Max Glyph count used in TdxCustomReportCellCheckImage
|
|
PtPerInch = 72; // Typographic Point per Inch
|
|
|
|
// Consts used in TCustomdxReportCellImageContainer to recognize Image kind saved in Stream
|
|
imstImageList = 0;
|
|
imstShellLargeImageList = 1;
|
|
imstShellSmallImageList = 2;
|
|
imstImage = 3;
|
|
|
|
// New ItemLink Name Template
|
|
sdxNewLinkNameTemplate = 'Link%d'; // Don't Localize
|
|
|
|
// Const used to store/load various Report Data to/from Windows Registry or Stream(File)
|
|
sdxNil = 'nil'; // Don't Localize
|
|
sdxFilePort = 'FILE:'; // Don't Localize
|
|
|
|
sdxAssignedDateFormat = 'OwnDateFormat'; // Don't Localize
|
|
sdxAssignedTimeFormat = 'OwnTimeFormat'; // Don't Localize
|
|
sdxAssignedPageNumberFormat = 'OwnPageNumberFormat'; // Don't Localize
|
|
sdxAutoUpdateDateTime = 'AutoUpdateDateTime'; // Don't Localize
|
|
sdxDateFormat = 'DateFormat'; // Don't Localize
|
|
sdxPageNumberFormat = 'PageNumberFormat'; // Don't Localize
|
|
sdxPrintDlgFilesRegistryPath = '\PrintDialogFiles'; // Don't Localize
|
|
sdxStartPageIndex = 'StartPageIndex'; // Don't Localize
|
|
sdxTimeFormat = 'TimeFormat'; // Don't Localize
|
|
dxFormatTextAdjustFont = Integer($80000000);
|
|
|
|
var
|
|
FPixelsDenominator: Integer;
|
|
FPixelsNumerator: Integer;
|
|
|
|
FSaveCursor: TCursor;
|
|
FWaitCounter: Integer = 0;
|
|
|
|
type
|
|
{$IFDEF DELPHI7}
|
|
TCustomPanelAccess = class(TCustomPanel);
|
|
{$ENDIF}
|
|
|
|
TdxLinkList = class;
|
|
|
|
TdxReportLinkRegItem = class
|
|
private
|
|
FLinkList: TdxLinkList;
|
|
protected
|
|
property LinkList: TdxLinkList read FLinkList;
|
|
public
|
|
ComponentClass: TComponentClass;
|
|
DesignerClass: TdxReportLinkDesignWindowClass;
|
|
LinkClass: TdxReportLinkClass;
|
|
constructor Create(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass);
|
|
destructor Destroy; override;
|
|
|
|
function IsEqual(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass = nil;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass = nil): Boolean;
|
|
function IsLastLinkClass: Boolean;
|
|
end;
|
|
|
|
TdxLinkList = class({$IFDEF DELPHI5}TObjectList{$ELSE}TList{$ENDIF})
|
|
private
|
|
function GetItem(Index: Integer): TdxReportLinkRegItem;
|
|
protected
|
|
function GetLinkClassCount(ALinkClass: TdxReportLinkClass): Integer;
|
|
public
|
|
procedure Add(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass);
|
|
{$IFNDEF DELPHI5}
|
|
procedure Clear; override;
|
|
procedure Delete(Index: Integer);
|
|
{$ENDIF}
|
|
|
|
function Find(out AnIndex: Integer; ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass = nil;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass = nil): Boolean; overload;
|
|
function Find(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass = nil;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass = nil): Boolean; overload;
|
|
|
|
function FindDesignerByLink(ALinkClass: TClass): TdxReportLinkDesignWindowClass; overload;
|
|
function FindDesignerByLink(ALink: TObject{TBasedxReportLink}): TdxReportLinkDesignWindowClass; overload;
|
|
|
|
function FindLinkByComponent(AComponentClass: TClass): TdxReportLinkClass; overload;
|
|
function FindLinkByComponent(AComponent: TObject{TComponent}): TdxReportLinkClass; overload;
|
|
|
|
procedure GetLinks(AClassList: TdxClassList; AnExcludeInactive: Boolean = True);
|
|
procedure GetSupportedComponents(AClassList: TdxClassList; ALinkClass: TClass = nil); overload;
|
|
procedure GetSupportedComponents(AClassList: TdxClassList; ALink: TObject{TBasedxReportLink}); overload;
|
|
|
|
procedure UnregisterLink(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass = nil;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass = nil);
|
|
procedure UnregisterLinks(const ALinkClasses: array of TdxReportLinkClass);
|
|
|
|
property Items[Index: Integer]: TdxReportLinkRegItem read GetItem;
|
|
end;
|
|
|
|
const
|
|
FLinkList: TdxLinkList = nil;
|
|
FPreviewWindowList: TdxClassList = nil;
|
|
|
|
type
|
|
TdxPSExplorerTreeContainerFactory = class(TdxCustomClassFactory)
|
|
private
|
|
function GetActiveTreeContainerClass: TCustomdxPSExplorerTreeContainerClass;
|
|
public
|
|
class function Instance: TdxPSExplorerTreeContainerFactory; reintroduce; overload;
|
|
property ActiveTreeContainerClass: TCustomdxPSExplorerTreeContainerClass read GetActiveTreeContainerClass;
|
|
end;
|
|
|
|
TdxPSExplorerTreeBuilderFactory = class(TdxCustomClassFactory)
|
|
private
|
|
// because of CLR :-(
|
|
function GetActiveBuilderClass: TdxPSExplorerTreeBuilderClass;
|
|
public
|
|
class function Instance: TdxPSExplorerTreeBuilderFactory; reintroduce; overload;
|
|
property ActiveBuilderClass: TdxPSExplorerTreeBuilderClass read GetActiveBuilderClass;
|
|
end;
|
|
|
|
TdxPSReaderFactory = class(TdxCustomClassFactory)
|
|
private
|
|
function GetActualReaderClass: TdxPSDataReaderClass;
|
|
function GetReaderClass(Version: Integer): TdxPSDataReaderClass;
|
|
public
|
|
class function Instance: TdxPSReaderFactory; reintroduce; overload;
|
|
|
|
property ActualReaderClass: TdxPSDataReaderClass read GetActualReaderClass;
|
|
property ReaderClasses[Version: Integer]: TdxPSDataReaderClass read GetReaderClass; default;
|
|
end;
|
|
|
|
TdxPSWriterFactory = class(TdxCustomClassFactory)
|
|
private
|
|
function GetActualWriterClass: TdxPSDataWriterClass;
|
|
function GetWriterClass(Version: Integer): TdxPSDataWriterClass;
|
|
public
|
|
class function Instance: TdxPSWriterFactory; reintroduce; overload;
|
|
|
|
property ActualWriterClass: TdxPSDataWriterClass read GetActualWriterClass;
|
|
property WriterClasses[Version: Integer]: TdxPSDataWriterClass read GetWriterClass; default;
|
|
end;
|
|
|
|
|
|
{ TdxReportLinkRegItem }
|
|
|
|
constructor TdxReportLinkRegItem.Create(ALinkClass: TdxReportLinkClass;
|
|
AComponentClass: TComponentClass; ADesignerClass: TdxReportLinkDesignWindowClass);
|
|
begin
|
|
inherited Create;
|
|
LinkClass := ALinkClass;
|
|
ComponentClass := AComponentClass;
|
|
DesignerClass := ADesignerClass;
|
|
if GetClass(LinkClass.ClassName) = nil then
|
|
RegisterClass(LinkClass);
|
|
end;
|
|
|
|
destructor TdxReportLinkRegItem.Destroy;
|
|
begin
|
|
if IsLastLinkClass and (GetClass(LinkClass.ClassName) <> nil) then
|
|
UnregisterClass(LinkClass);
|
|
inherited;
|
|
end;
|
|
|
|
function TdxReportLinkRegItem.IsEqual(ALinkClass: TdxReportLinkClass;
|
|
AComponentClass: TComponentClass = nil; ADesignerClass: TdxReportLinkDesignWindowClass = nil): Boolean;
|
|
begin
|
|
Result := (LinkClass = ALinkClass) and
|
|
((ComponentClass = nil) or (ComponentClass = AComponentClass)) and
|
|
((DesignerClass = nil) or (DesignerClass = ADesignerClass));
|
|
end;
|
|
|
|
function TdxReportLinkRegItem.IsLastLinkClass: Boolean;
|
|
begin
|
|
Result := LinkList.GetLinkClassCount(LinkClass) = 1;
|
|
end;
|
|
|
|
{ TdxLinkList }
|
|
|
|
procedure TdxLinkList.Add(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass);
|
|
var
|
|
Item: TdxReportLinkRegItem;
|
|
begin
|
|
if not Find(ALinkClass, AComponentClass, ADesignerClass) then
|
|
begin
|
|
Item := TdxReportLinkRegItem.Create(ALinkClass, AComponentClass, ADesignerClass);
|
|
Item.FLinkList := Self;
|
|
Insert(0, Item);
|
|
end;
|
|
end;
|
|
|
|
{$IFNDEF DELPHI5}
|
|
procedure TdxLinkList.Clear;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
Items[I].Free;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxLinkList.Delete(Index: Integer);
|
|
begin
|
|
Items[Index].Free;
|
|
inherited;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function TdxLinkList.Find(out AnIndex: Integer; ALinkClass: TdxReportLinkClass;
|
|
AComponentClass: TComponentClass = nil; ADesignerClass: TdxReportLinkDesignWindowClass = nil): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AnIndex := -1;
|
|
for I := 0 to FLinkList.Count - 1 do
|
|
if Items[I].IsEqual(ALinkClass, AComponentClass, ADesignerClass) then
|
|
begin
|
|
AnIndex := I;
|
|
Break;
|
|
end;
|
|
Result := AnIndex <> -1;
|
|
end;
|
|
|
|
function TdxLinkList.Find(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass = nil;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass = nil): Boolean;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Result := Find(Index, ALinkClass, AComponentClass, ADesignerClass);
|
|
end;
|
|
|
|
function TdxLinkList.FindDesignerByLink(ALinkClass: TClass): TdxReportLinkDesignWindowClass;
|
|
var
|
|
I: Integer;
|
|
Item: TdxReportLinkRegItem;
|
|
begin
|
|
if ALinkClass <> nil then
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Item := Items[I];
|
|
if Item.LinkClass = ALinkClass then
|
|
begin
|
|
Result := Item.DesignerClass;
|
|
Exit;
|
|
end;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxLinkList.FindDesignerByLink(ALink: TObject{TBasedxReportLink}): TdxReportLinkDesignWindowClass;
|
|
begin
|
|
if ALink <> nil then
|
|
Result := FindDesignerByLink(ALink.ClassType)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxLinkList.FindLinkByComponent(AComponentClass: TClass): TdxReportLinkClass;
|
|
var
|
|
I: Integer;
|
|
Item: TdxReportLinkRegItem;
|
|
begin
|
|
Result := nil;
|
|
if AComponentClass <> nil then
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Item := Items[I];
|
|
if AComponentClass.InheritsFrom(Item.ComponentClass) then
|
|
begin
|
|
Result := Item.LinkClass;
|
|
if AComponentClass = Item.ComponentClass then Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxLinkList.FindLinkByComponent(AComponent: TObject{TComponent}): TdxReportLinkClass;
|
|
begin
|
|
if AComponent <> nil then
|
|
Result := FindLinkByComponent(AComponent.ClassType)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxLinkList.GetLinks(AClassList: TdxClassList; AnExcludeInactive: Boolean = True);
|
|
var
|
|
Buffer: TdxClassList;
|
|
I: Integer;
|
|
Item: TdxReportLinkRegItem;
|
|
ComponentClass: TComponentClass;
|
|
LinkClass: TdxReportLinkClass;
|
|
begin
|
|
Buffer := TdxClassList.Create;
|
|
try
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Item := Items[I];
|
|
ComponentClass := Item.ComponentClass;
|
|
if not AnExcludeInactive or (ComponentClass = nil) or (Buffer.IndexOf(ComponentClass) = -1) then
|
|
begin
|
|
LinkClass := Item.LinkClass;
|
|
if AClassList.IndexOf(LinkClass) = -1 then
|
|
AClassList.Add(LinkClass);
|
|
if AnExcludeInactive and (ComponentClass <> nil) then
|
|
Buffer.Add(ComponentClass);
|
|
end;
|
|
end;
|
|
finally
|
|
Buffer.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLinkList.GetSupportedComponents(AClassList: TdxClassList; ALinkClass: TClass = nil);
|
|
var
|
|
I: Integer;
|
|
Item: TdxReportLinkRegItem;
|
|
ComponentClass: TComponentClass;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Item := Items[I];
|
|
if (ALinkClass = nil) or (Item.LinkClass = ALinkClass) then
|
|
begin
|
|
ComponentClass := Item.ComponentClass;
|
|
if AClassList.IndexOf(ComponentClass) = -1 then
|
|
AClassList.Add(ComponentClass);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLinkList.GetSupportedComponents(AClassList: TdxClassList; ALink: TObject{TBasedxReportLink});
|
|
var
|
|
LinkClass: TClass;
|
|
begin
|
|
if ALink <> nil then
|
|
LinkClass := ALink.ClassType
|
|
else
|
|
LinkClass := nil;
|
|
GetSupportedComponents(AClassList, LinkClass);
|
|
end;
|
|
|
|
procedure TdxLinkList.UnregisterLink(ALinkClass: TdxReportLinkClass;
|
|
AComponentClass: TComponentClass = nil; ADesignerClass: TdxReportLinkDesignWindowClass = nil);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
if Find(Index, ALinkClass, AComponentClass, ADesignerClass) then
|
|
Delete(Index);
|
|
end;
|
|
|
|
procedure TdxLinkList.UnregisterLinks(const ALinkClasses: array of TdxReportLinkClass);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := Low(ALinkClasses) to High(ALinkClasses) do
|
|
UnregisterLink(ALinkClasses[I]);
|
|
end;
|
|
|
|
function TdxLinkList.GetLinkClassCount(ALinkClass: TdxReportLinkClass): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to Count - 1 do
|
|
if Items[I].LinkClass = ALinkClass then Inc(Result);
|
|
end;
|
|
|
|
function TdxLinkList.GetItem(Index: Integer): TdxReportLinkRegItem;
|
|
begin
|
|
Result := inherited Items[Index] as TdxReportLinkRegItem;
|
|
end;
|
|
|
|
{ TdxPSExplorerTreeContainerFactory }
|
|
|
|
function dxPSExplorerTreeContainerFactory: TdxPSExplorerTreeContainerFactory;
|
|
begin
|
|
Result := TdxPSExplorerTreeContainerFactory.Instance;
|
|
end;
|
|
|
|
class function TdxPSExplorerTreeContainerFactory.Instance: TdxPSExplorerTreeContainerFactory;
|
|
begin
|
|
Result := inherited Instance as TdxPSExplorerTreeContainerFactory;
|
|
end;
|
|
|
|
function TdxPSExplorerTreeContainerFactory.GetActiveTreeContainerClass: TCustomdxPSExplorerTreeContainerClass;
|
|
begin
|
|
Result := TCustomdxPSExplorerTreeContainerClass(Items[0]);
|
|
end;
|
|
|
|
{ TdxPSExplorerTreeBuilderFactory }
|
|
|
|
function dxPSExplorerTreeBuilderFactory: TdxPSExplorerTreeBuilderFactory;
|
|
begin
|
|
Result := TdxPSExplorerTreeBuilderFactory.Instance;
|
|
end;
|
|
|
|
function dxPSExplorerTreeBuilderFactory_ActiveBuilderClass: TdxPSExplorerTreeBuilderClass;
|
|
begin
|
|
Result := dxPSExplorerTreeBuilderFactory.ActiveBuilderClass;
|
|
end;
|
|
|
|
class function TdxPSExplorerTreeBuilderFactory.Instance: TdxPSExplorerTreeBuilderFactory;
|
|
begin
|
|
Result := inherited Instance as TdxPSExplorerTreeBuilderFactory;
|
|
end;
|
|
|
|
// because of CLR :-(
|
|
function TdxPSExplorerTreeBuilderFactory.GetActiveBuilderClass: TdxPSExplorerTreeBuilderClass;
|
|
begin
|
|
Result := TdxPSExplorerTreeBuilderClass(Items[Count - 1]);
|
|
end;
|
|
|
|
{ TdxPSReaderFactory }
|
|
|
|
function dxPSReaderFactory: TdxPSReaderFactory;
|
|
begin
|
|
Result := TdxPSReaderFactory.Instance;
|
|
end;
|
|
|
|
class function TdxPSReaderFactory.Instance: TdxPSReaderFactory;
|
|
begin
|
|
Result := inherited Instance as TdxPSReaderFactory
|
|
end;
|
|
|
|
function TdxPSReaderFactory.GetActualReaderClass: TdxPSDataReaderClass;
|
|
begin
|
|
Result := ReaderClasses[dxPSGlbl.dxPSStorageVersion];
|
|
end;
|
|
|
|
function TdxPSReaderFactory.GetReaderClass(Version: Integer): TdxPSDataReaderClass;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := Count - 1 to 0 do
|
|
begin
|
|
Result := TdxPSDataReaderClass(Items[I]);
|
|
if Result.SupportsStorageVersion(Version) then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
{ TdxPSWriterFactory }
|
|
|
|
function dxPSWriterFactory: TdxPSWriterFactory;
|
|
begin
|
|
Result := TdxPSWriterFactory.Instance;
|
|
end;
|
|
|
|
class function TdxPSWriterFactory.Instance: TdxPSWriterFactory;
|
|
begin
|
|
Result := inherited Instance as TdxPSWriterFactory;
|
|
end;
|
|
|
|
function TdxPSWriterFactory.GetActualWriterClass: TdxPSDataWriterClass;
|
|
begin
|
|
Result := WriterClasses[dxPSGlbl.dxPSStorageVersion];
|
|
end;
|
|
|
|
function TdxPSWriterFactory.GetWriterClass(Version: Integer): TdxPSDataWriterClass;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := Count - 1 to 0 do
|
|
begin
|
|
Result := TdxPSDataWriterClass(Items[I]);
|
|
if Result.SupportsStorageVersion(Version) then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
{ units convertation routines }
|
|
|
|
function OnePixel: Integer;
|
|
begin
|
|
Result := FPixelsNumerator div FPixelsDenominator;
|
|
if Result = 0 then Result := 1;
|
|
end;
|
|
|
|
function PixelsNumerator: Integer;
|
|
begin
|
|
Result := FPixelsNumerator;
|
|
end;
|
|
|
|
function PixelsDenominator: Integer;
|
|
begin
|
|
Result := FPixelsDenominator;
|
|
end;
|
|
|
|
{ Helpers }
|
|
|
|
procedure FixupRect(DC: HDC; var R: TRect);
|
|
begin
|
|
if DC <> 0 then
|
|
begin
|
|
LPtoDP(DC, R, 2);
|
|
DPtoLP(DC, R, 2);
|
|
end;
|
|
end;
|
|
|
|
const
|
|
InnerBorderBRColors: array[TdxCellEdgeStyle, Boolean] of Integer =
|
|
((COLOR_BTNSHADOW, COLOR_BTNFACE), (COLOR_BTNSHADOW, COLOR_BTNFACE));
|
|
InnerBorderTLColors: array[TdxCellEdgeStyle, Boolean] of Integer =
|
|
((COLOR_BTNHIGHLIGHT, COLOR_BTNHIGHLIGHT), (COLOR_BTNSHADOW, COLOR_BTNFACE));
|
|
|
|
OuterBorderBRColors: array[TdxCellEdgeStyle, Boolean] of Integer =
|
|
((COLOR_WINDOWTEXT, COLOR_WINDOWTEXT), (COLOR_BTNHIGHLIGHT, COLOR_BTNHIGHLIGHT));
|
|
OuterBorderTLColors: array[TdxCellEdgeStyle, Boolean] of Integer =
|
|
((COLOR_WINDOWTEXT, COLOR_WINDOWTEXT), (COLOR_WINDOWTEXT, COLOR_WINDOWTEXT));
|
|
|
|
procedure Get3DBorderBrushes(AEdgeStyle: TdxCellEdgeStyle; ASoft: Boolean;
|
|
var AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush: HBRUSH);
|
|
begin
|
|
AOuterTLBrush := GetSysColorBrush(OuterBorderTLColors[AEdgeStyle, ASoft]);
|
|
AOuterBRBrush := GetSysColorBrush(OuterBorderBRColors[AEdgeStyle, ASoft]);
|
|
AInnerTLBrush := GetSysColorBrush(InnerBorderTLColors[AEdgeStyle, ASoft]);
|
|
AInnerBRBrush := GetSysColorBrush(InnerBorderBRColors[AEdgeStyle, ASoft]);
|
|
end;
|
|
|
|
procedure Get3DBorderColors(AEdgeStyle: TdxCellEdgeStyle; ASoft: Boolean;
|
|
var AOuterTLColor, AOuterBRColor, AInnerTLColor, AInnerBRColor: TColor);
|
|
begin
|
|
AOuterTLColor := GetSysColor(OuterBorderTLColors[AEdgeStyle, ASoft]);
|
|
AOuterBRColor := GetSysColor(OuterBorderBRColors[AEdgeStyle, ASoft]);
|
|
AInnerTLColor := GetSysColor(InnerBorderTLColors[AEdgeStyle, ASoft]);
|
|
AInnerBRColor := GetSysColor(InnerBorderBRColors[AEdgeStyle, ASoft]);
|
|
end;
|
|
|
|
function dxPSExplorerImages: TCustomImageList;
|
|
|
|
function AddShellIconByIndex(AnIndex: Integer): Integer;
|
|
var
|
|
Icon: TIcon;
|
|
begin
|
|
if AnIndex <> -1 then
|
|
begin
|
|
Icon := TIcon.Create;
|
|
try
|
|
dxPSUtl.ShellSmallImages.GetIcon(AnIndex, Icon);
|
|
Result := FExplorerImages.AddIcon(Icon);
|
|
finally
|
|
Icon.Free;
|
|
end
|
|
end
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
function LoadIcon(AnExtraFlags: UINT): Integer;
|
|
const
|
|
Flags = SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SYSICONINDEX;
|
|
var
|
|
FileInfo: TSHFileInfo;
|
|
begin
|
|
FillChar(FileInfo, SizeOf(FileInfo), 0);
|
|
FileInfo.dwAttributes := SFGAO_FOLDER;
|
|
try
|
|
SHGetFileInfo('', FILE_ATTRIBUTE_DIRECTORY, FileInfo, SizeOf(FileInfo), Flags or AnExtraFlags);
|
|
finally
|
|
DestroyIcon(FileInfo.hIcon);
|
|
end;
|
|
Result := AddShellIconByIndex(FileInfo.iIcon);
|
|
end;
|
|
|
|
function LoadBitmap(const AResName: string): Integer;
|
|
var
|
|
Bitmap: TBitmap;
|
|
begin
|
|
Bitmap := TBitmap.Create;
|
|
try
|
|
Bitmap_LoadFromResourceName(Bitmap, AResName);
|
|
FExplorerImages.AddMasked(Bitmap, clFuchsia);
|
|
Result := FExplorerImages.Count - 1;
|
|
finally
|
|
Bitmap.Free;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
I: TdxDriveType;
|
|
begin
|
|
if FExplorerImages = nil then
|
|
begin
|
|
FExplorerImages := TImageList.Create(nil);
|
|
FExplorerImages.Handle := ImageList_Duplicate(dxPSUtl.ShellSmallImages.Handle);
|
|
FExplorerImages.Clear;
|
|
|
|
iiExplorerFolderCollapsed := LoadIcon(0);
|
|
iiExplorerFolderExpanded := LoadIcon(SHGFI_OPENICON);
|
|
iiExplorerItem := LoadBitmap(IDB_DXPSEXPLORERITEM_SMALL);
|
|
iiExplorerItemHasInvalidData := LoadBitmap(IDB_DXPSEXPLORERITEM_INVALID);
|
|
|
|
for I := Low(TdxDriveType) to High(TdxDriveType) do
|
|
//iiDriveTypes[I] := AddShellIconByIndex(DriveTypeImageIndexMap[I]);
|
|
end;
|
|
Result := FExplorerImages;
|
|
end;
|
|
|
|
procedure dxPSStartWait;
|
|
begin
|
|
if FWaitCounter = 0 then
|
|
begin
|
|
FSaveCursor := Screen.Cursor;
|
|
Screen.Cursor := crHourGlass;
|
|
end;
|
|
Inc(FWaitCounter);
|
|
end;
|
|
|
|
procedure dxPSStopWait;
|
|
begin
|
|
if FWaitCounter <> 0 then
|
|
begin
|
|
Dec(FWaitCounter);
|
|
if FWaitCounter = 0 then Screen.Cursor := FSaveCursor;
|
|
end;
|
|
end;
|
|
|
|
{ ReportLinks Registration and Utilities}
|
|
|
|
function dxPSIndexOfRegItem(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass): Integer;
|
|
begin
|
|
if FLinkList <> nil then
|
|
FLinkList.Find(Result, ALinkClass, AComponentClass, ADesignerClass)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure dxPSRegisterReportLink(ALinkClass: TdxReportLinkClass; AComponentClass: TComponentClass;
|
|
ADesignerClass: TdxReportLinkDesignWindowClass);
|
|
begin
|
|
if (ALinkClass = nil) or
|
|
((AComponentClass <> nil) and (dxPSIndexOfRegItem(ALinkClass, AComponentClass, ADesignerClass) <> -1)) then
|
|
Exit;
|
|
|
|
if FLinkList = nil then
|
|
FLinkList := TdxLinkList.Create;
|
|
FLinkList.Add(ALinkClass, AComponentClass, ADesignerClass);
|
|
end;
|
|
|
|
procedure dxPSUnregisterReportLink(ALinkClass: TdxReportLinkClass;
|
|
AComponentClass: TComponentClass; ADesignerClass: TdxReportLinkDesignWindowClass);
|
|
begin
|
|
if FLinkList <> nil then
|
|
FLinkList.UnregisterLink(ALinkClass, AComponentClass, ADesignerClass);
|
|
end;
|
|
|
|
procedure dxPSUnregisterReportLinks(const ALinkClasses: array of TdxReportLinkClass);
|
|
begin
|
|
if FLinkList <> nil then
|
|
FLinkList.UnregisterLinks(ALinkClasses);
|
|
end;
|
|
|
|
procedure dxPSUnregisterAllReportLinks;
|
|
begin
|
|
if FLinkList <> nil then
|
|
begin
|
|
FLinkList.Clear;
|
|
FreeAndNil(FLinkList);
|
|
end;
|
|
end;
|
|
|
|
function dxPSDesignerClassByCompClass(AComponentClass: TClass): TdxReportLinkDesignWindowClass;
|
|
var
|
|
LinkClass: TdxReportLinkClass;
|
|
begin
|
|
LinkClass := dxPSLinkClassByCompClass(AComponentClass);
|
|
Result := dxPSDesignerClassByLinkClass(LinkClass);
|
|
end;
|
|
|
|
function dxPSDesignerClassByCompClass(AComponent: TObject{TComponent}): TdxReportLinkDesignWindowClass;
|
|
begin
|
|
if AComponent <> nil then
|
|
Result := dxPSDesignerClassByCompClass(AComponent.ClassType)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function dxPSLinkClassByCompClass(AComponentClass: TClass): TdxReportLinkClass;
|
|
begin
|
|
if FLinkList <> nil then
|
|
Result := FLinkList.FindLinkByComponent(AComponentClass)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function dxPSLinkClassByCompClass(AComponent: TObject{TComponent}): TdxReportLinkClass;
|
|
begin
|
|
if FLinkList <> nil then
|
|
Result := FLinkList.FindLinkByComponent(AComponent)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function dxPSDesignerClassByLinkClass(ALinkClass: TClass): TdxReportLinkDesignWindowClass;
|
|
begin
|
|
if FLinkList <> nil then
|
|
Result := FLinkList.FindDesignerByLink(ALinkClass)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function dxPSDesignerClassByLinkClass(ALink: TObject{TBasedxReportLink}): TdxReportLinkDesignWindowClass;
|
|
begin
|
|
if ALink <> nil then
|
|
Result := FLinkList.FindDesignerByLink(ALink)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure dxPSGetActiveReportLinksList(AClassList: TdxClassList);
|
|
begin
|
|
if FLinkList <> nil then
|
|
FLinkList.GetLinks(AClassList, True);
|
|
end;
|
|
|
|
procedure dxPSGetReportLinksList(AClassList: TdxClassList);
|
|
begin
|
|
if FLinkList <> nil then
|
|
FLinkList.GetLinks(AClassList, False);
|
|
end;
|
|
|
|
procedure dxPSGetLinkSupportedComponentsList(AClassList: TdxClassList; ALinkClass: TClass);
|
|
begin
|
|
if FLinkList <> nil then
|
|
FLinkList.GetSupportedComponents(AClassList, ALinkClass);
|
|
end;
|
|
|
|
procedure dxPSGetLinkSupportedComponentsList(AClassList: TdxClassList; ALink: TObject{TBasedxReportLink});
|
|
begin
|
|
if FLinkList <> nil then
|
|
FLinkList.GetSupportedComponents(AClassList, ALink);
|
|
end;
|
|
|
|
procedure dxPSGetSupportedComponentsList(AClassList: TdxClassList);
|
|
begin
|
|
if FLinkList <> nil then
|
|
FLinkList.GetSupportedComponents(AClassList);
|
|
end;
|
|
|
|
function dxPSIsSupportedCompClass(AComponentClass: TClass): Boolean;
|
|
begin
|
|
Result := dxPSLinkClassByCompClass(AComponentClass) <> nil;
|
|
end;
|
|
|
|
function dxPSIsSupportedCompClass(AComponent: TObject{TComponent}): Boolean;
|
|
begin
|
|
Result := dxPSLinkClassByCompClass(AComponent) <> nil;
|
|
end;
|
|
|
|
{ PreviewWindows Registration and Utilities}
|
|
|
|
function GetPreviewClass: TdxPreviewWindowClass;
|
|
begin
|
|
Result := nil;
|
|
if (FPreviewWindowList <> nil) and (FPreviewWindowList.Count <> 0) then
|
|
Result := TdxPreviewWindowClass(FPreviewWindowList.Last);
|
|
end;
|
|
|
|
function dxPSIndexOfPreviewWindowClass(APreviewWindowClass: TdxPreviewWindowClass): Integer;
|
|
begin
|
|
if FPreviewWindowList <> nil then
|
|
for Result := 0 to FPreviewWindowList.Count - 1 do
|
|
if TdxPreviewWindowClass(FPreviewWindowList[Result]) = APreviewWindowClass then
|
|
Exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
function dxPSGetPreviewWindowClassByClassName(const AClassName: string): TdxPreviewWindowClass;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if FPreviewWindowList <> nil then
|
|
for I := 0 to FPreviewWindowList.Count - 1 do
|
|
begin
|
|
Result := TdxPreviewWindowClass(FPreviewWindowList[I]);
|
|
if (Result <> nil) and Result.ClassNameIs(AClassName) then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure dxPSGetPreviewWindowList(AStrings: TStrings);
|
|
var
|
|
I: Integer;
|
|
PreviewWindowClass: TdxPreviewWindowClass;
|
|
begin
|
|
if FPreviewWindowList <> nil then
|
|
begin
|
|
AStrings.BeginUpdate;
|
|
try
|
|
for I := 0 to FPreviewWindowList.Count - 1 do
|
|
begin
|
|
PreviewWindowClass := TdxPreviewWindowClass(FPreviewWindowList[I]);
|
|
if PreviewWindowClass <> nil then
|
|
AStrings.AddObject(PreviewWindowClass.ClassName, TObject(PreviewWindowClass));
|
|
end;
|
|
finally
|
|
AStrings.EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure dxPSRegisterPreviewWindow(APreviewWindowClass: TdxPreviewWindowClass);
|
|
begin
|
|
if FPreviewWindowList = nil then
|
|
FPreviewWindowList := TdxClassList.Create;
|
|
FPreviewWindowList.Add(APreviewWindowClass);
|
|
end;
|
|
|
|
procedure dxPSUnregisterPreviewWindow(APreviewWindowClass: TdxPreviewWindowClass = nil);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
if FPreviewWindowList <> nil then
|
|
begin
|
|
if APreviewWindowClass = nil then
|
|
Index := FPreviewWindowList.Count - 1
|
|
else
|
|
Index := dxPSIndexOfPreviewWindowClass(APreviewWindowClass);
|
|
|
|
if Index <> -1 then
|
|
begin
|
|
FPreviewWindowList.Delete(Index);
|
|
if FPreviewWindowList.Count = 0 then FreeAndNil(FPreviewWindowList);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure dxPSUnregisterAllPreviewWindows;
|
|
begin
|
|
while FPreviewWindowList <> nil do dxPSUnregisterPreviewWindow(nil);
|
|
end;
|
|
|
|
function dxPrintComponent(AComponent: TComponent;
|
|
APrintPreview: Boolean = True; APrintDialog: Boolean = False;
|
|
const AReportTitle: string = ''; const APrintTitle: string = ''): Boolean;
|
|
var
|
|
ComponentPrinter: TdxComponentPrinter;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
try
|
|
ComponentPrinter := TdxComponentPrinter.Create(nil);
|
|
try
|
|
ComponentPrinter.PrintTitle := APrintTitle;
|
|
ReportLink := ComponentPrinter.AddLink(AComponent);
|
|
Result := ReportLink <> nil;
|
|
if Result then
|
|
try
|
|
ReportLink.ReportTitleText := AReportTitle;
|
|
if APrintPreview then
|
|
ReportLink.Preview(True)
|
|
else
|
|
ReportLink.Print(APrintDialog, nil);
|
|
finally
|
|
ReportLink.Free;
|
|
end
|
|
finally
|
|
ComponentPrinter.Free;
|
|
end;
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
type
|
|
TdxPSRunTimeComponentsProvider = class(TAbstractdxPSComponentsProvider)
|
|
public
|
|
procedure GetComponents(AComponentPrinter: TdxComponentPrinter; AReportLink: TBasedxReportLink;
|
|
AComponents: TStrings; AnOptions: TdxPSGetComponentOptions); override;
|
|
end;
|
|
|
|
procedure TdxPSRunTimeComponentsProvider.GetComponents(AComponentPrinter: TdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; AComponents: TStrings; AnOptions: TdxPSGetComponentOptions);
|
|
|
|
procedure ProcessComponent(AComponent: TComponent);
|
|
var
|
|
Caption: string;
|
|
Description: string;
|
|
Item: TdxComponentItem;
|
|
begin
|
|
Caption := AComponent.Name;
|
|
Description := '';
|
|
if (AComponentPrinter.FindLinkByComponent(AComponent) = nil) and
|
|
(((AReportLink = nil) and dxPSIsSupportedCompClass(AComponent)) or
|
|
((AReportLink <> nil) and AReportLink.Supports(AComponent))) and
|
|
AComponentPrinter.DoFilterComponent(AComponent, Caption, Description) then
|
|
begin
|
|
Item := dxPSCreateComponentItem(AComponent, Caption, Description);
|
|
AComponents.AddObject(Item.Caption, Item);
|
|
end;
|
|
end;
|
|
|
|
var
|
|
Owner: TComponent;
|
|
I: Integer;
|
|
begin
|
|
if not AComponentPrinter.GetSupportedComponents(AComponents) then
|
|
begin
|
|
//Item := dxPSCreateComponentItem(nil, 'Composition', '');
|
|
//AComponents.AddObject(Item.Caption, Item);
|
|
|
|
Owner := AComponentPrinter.Owner;
|
|
if Owner <> nil then
|
|
begin
|
|
ProcessComponent(Owner);
|
|
for I := 0 to Owner.ComponentCount - 1 do
|
|
ProcessComponent(Owner.Components[I]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ EdxInvalidStorageVersion }
|
|
|
|
constructor EdxInvalidStorageVersion.Create(AVersion: UINT);
|
|
begin
|
|
FVersion := AVersion;
|
|
inherited CreateFmt(cxGetResourceString(@sdxInvalidStorageVersion), [Version]);
|
|
end;
|
|
|
|
{ TdxPSDataReader }
|
|
|
|
class procedure TdxPSDataReader.Register;
|
|
begin
|
|
dxPSReaderFactory.Register(Self);
|
|
end;
|
|
|
|
class procedure TdxPSDataReader.Unregister;
|
|
begin
|
|
dxPSReaderFactory.Unregister(Self);
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadClass: TClass;
|
|
begin
|
|
Result := GetClass(ReadString);
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadCellBorderClass: TdxPSCellBorderClass;
|
|
begin
|
|
Result := TdxPSCellBorderClass(ReadClass);
|
|
if Result = nil then
|
|
Result := TdxPSCellUltraFlatBorder;
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadFillPatternClass: TdxPSFillPatternClass;
|
|
begin
|
|
Result := TdxPSFillPatternClass(ReadClass);
|
|
if Result = nil then
|
|
Result := TdxPSSolidFillPattern;
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadFont(AFont: TFont): TFont;
|
|
begin
|
|
Result := AFont;
|
|
if Result = nil then Result := TFont.Create;
|
|
|
|
with Result do
|
|
begin
|
|
Charset := TFontCharset(ReadInteger);
|
|
Color := ReadInteger;
|
|
Name := ReadString;
|
|
Pitch := TFontPitch(ReadInteger);
|
|
Size := ReadInteger;
|
|
Style := TFontStyles(Byte(ReadInteger));
|
|
end;
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadGraphicClass: TGraphicClass;
|
|
begin
|
|
Result := TGraphicClass(ReadClass);
|
|
end;
|
|
|
|
procedure TdxPSDataReader.ReadImage(AnImage: TGraphic);
|
|
var
|
|
MemoryStream: TMemoryStream;
|
|
HasMask: Boolean;
|
|
Mask: TBitmap;
|
|
begin
|
|
MemoryStream := TMemoryStream.Create;
|
|
try
|
|
MemoryStream.Size := {$IFDEF DELPHI6} Self.ReadInt64 {$ELSE} Self.ReadInteger {$ENDIF};
|
|
if MemoryStream.Size <> 0 then
|
|
begin
|
|
Self.Read(MemoryStream.Memory^, MemoryStream.Size);
|
|
MemoryStream.Position := 0;
|
|
AnImage.LoadFromStream(MemoryStream);
|
|
|
|
MemoryStream.Read(HasMask , SizeOf(HasMask));
|
|
if HasMask then
|
|
begin
|
|
Mask := TBitmap.Create;
|
|
try
|
|
Mask.LoadFromStream(MemoryStream);
|
|
TBitmap(AnImage).MaskHandle := Mask.ReleaseHandle;
|
|
finally
|
|
Mask.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
MemoryStream.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TdxPSDataReader.ReadImageList(AnImageList: TCustomImageList);
|
|
var
|
|
MemoryStream: TMemoryStream;
|
|
Adapter: IStream;
|
|
begin
|
|
MemoryStream := TMemoryStream.Create;
|
|
try
|
|
MemoryStream.Size := {$IFDEF DELPHI6} Self.ReadInt64 {$ELSE} Self.ReadInteger {$ENDIF};
|
|
if MemoryStream.Size <> 0 then
|
|
begin
|
|
Self.Read(MemoryStream.Memory^, MemoryStream.Size);
|
|
MemoryStream.Position := 0;
|
|
Adapter := TStreamAdapter.Create(MemoryStream);
|
|
AnImageList.Handle := CommCtrl.ImageList_Read(Adapter);
|
|
end;
|
|
finally
|
|
MemoryStream.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TdxPSDataReader.ReadLinkClass: TdxReportLinkClass;
|
|
begin
|
|
Result := TdxReportLinkClass(ReadClass);
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadLookAndFeelClass: TdxPSReportGroupLookAndFeelClass;
|
|
begin
|
|
Result := TdxPSReportGroupLookAndFeelClass(ReadClass);
|
|
if Result = nil then
|
|
Result := TdxPSReportGroupNullLookAndFeel;
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadPoint: TPoint;
|
|
begin
|
|
Read(Result, SizeOf(Result));
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadPSVersion: TdxPSVersion;
|
|
begin
|
|
Read(Result, SizeOf(Result));
|
|
end;
|
|
|
|
function TdxPSDataReader.ReadRect: TRect;
|
|
begin
|
|
Read(Result, SizeOf(Result));
|
|
end;
|
|
|
|
procedure TdxPSDataReader.SkipBytes(Count: {$IFDEF DELPHI6} Int64 {$ELSE} Integer {$ENDIF});
|
|
var
|
|
Buffer: TBytes;
|
|
begin
|
|
SetLength(Buffer, Count);
|
|
Read(Buffer, Length(Buffer));
|
|
end;
|
|
|
|
class function TdxPSDataReader.SupportsStorageVersion(AVersion: Integer): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{ TdxPSDataWriter }
|
|
|
|
class procedure TdxPSDataWriter.Register;
|
|
begin
|
|
dxPSWriterFactory.Register(Self);
|
|
end;
|
|
|
|
class procedure TdxPSDataWriter.Unregister;
|
|
begin
|
|
dxPSWriterFactory.Unregister(Self);
|
|
end;
|
|
|
|
procedure TdxPSDataWriter.WriteClassName(AClass: TClass);
|
|
begin
|
|
if AClass <> nil then
|
|
WriteString(AClass.ClassName)
|
|
else
|
|
WriteString(sdxNil);
|
|
end;
|
|
|
|
procedure TdxPSDataWriter.WriteClassName(AnObject: TObject);
|
|
begin
|
|
if AnObject <> nil then
|
|
WriteClassName(AnObject.ClassType)
|
|
else
|
|
WriteString(sdxNil);
|
|
end;
|
|
|
|
procedure TdxPSDataWriter.WriteFont(AFont: TFont);
|
|
begin
|
|
with AFont do
|
|
begin
|
|
WriteInteger(Charset);
|
|
WriteInteger(Color);
|
|
WriteString(Name);
|
|
WriteInteger(Integer(Pitch));
|
|
WriteInteger(Size);
|
|
WriteInteger(Integer(Byte(Style)));
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSDataWriter.WriteImage(AnImage: TGraphic);
|
|
var
|
|
MemoryStream: TMemoryStream;
|
|
HasMask: Boolean;
|
|
Mask: TBitmap;
|
|
begin
|
|
MemoryStream:= TMemoryStream.Create;
|
|
try
|
|
AnImage.SaveToStream(MemoryStream);
|
|
|
|
HasMask := (AnImage is TBitmap) and (TBitmap(AnImage).MaskHandle <> 0);
|
|
MemoryStream.Write(HasMask, SizeOf(HasMask));
|
|
if HasMask then
|
|
begin
|
|
Mask := TBitmap.Create;
|
|
try
|
|
Mask.Monochrome := True;
|
|
Mask.Handle := TBitmap(AnImage).MaskHandle;
|
|
Mask.SaveToStream(MemoryStream);
|
|
finally
|
|
Mask.Free;
|
|
end;
|
|
end;
|
|
|
|
Self.WriteInteger(MemoryStream.Size);
|
|
Self.Write(MemoryStream.Memory^, MemoryStream.Size);
|
|
finally
|
|
MemoryStream.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TdxPSDataWriter.WriteImageList(AnImageList: TCustomImageList);
|
|
var
|
|
MemoryStream: TMemoryStream;
|
|
Adapter: IStream;
|
|
begin
|
|
MemoryStream := TMemoryStream.Create;
|
|
try
|
|
Adapter := TStreamAdapter.Create(MemoryStream);
|
|
CommCtrl.ImageList_Write(AnImageList.Handle, Adapter);
|
|
|
|
Self.WriteInteger(MemoryStream.Size);
|
|
Self.Write(MemoryStream.Memory^, MemoryStream.Size);
|
|
finally
|
|
MemoryStream.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TdxPSDataWriter.WritePoint(const Pt: TPoint);
|
|
begin
|
|
Write(Pt, SizeOf(Pt));
|
|
end;
|
|
|
|
procedure TdxPSDataWriter.WritePSVersion(const AVersion: TdxPSVersion);
|
|
begin
|
|
Write(AVersion, SizeOf(AVersion));
|
|
end;
|
|
|
|
procedure TdxPSDataWriter.WriteRect(const R: TRect);
|
|
begin
|
|
Write(R, SizeOf(R));
|
|
end;
|
|
|
|
|
|
class function TdxPSDataWriter.SupportsStorageVersion(AVersion: Integer): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{ TdxPageOverlayIndexes }
|
|
|
|
function TdxPageOverlayIndexes.Add(AValue: Integer): Integer;
|
|
begin
|
|
Result := inherited Add(TObject(AValue));
|
|
end;
|
|
|
|
function TdxPageOverlayIndexes.GetItem(Index: Integer): Integer;
|
|
begin
|
|
Result := Integer(inherited Items[Index]);
|
|
end;
|
|
|
|
procedure TdxPageOverlayIndexes.SetItem(Index, Value: Integer);
|
|
begin
|
|
inherited Items[Index] := TObject(Value);
|
|
end;
|
|
|
|
{ TdxPSPageRenderInfo }
|
|
|
|
constructor TdxPSPageRenderInfo.Create(ARenderInfo: TdxPSReportRenderInfo;
|
|
APageIndex: Integer);
|
|
begin
|
|
inherited Create;
|
|
FPageIndex := APageIndex;
|
|
FRenderInfo := ARenderInfo;
|
|
FIndexPairs := TList.Create;
|
|
FOverlays := TList.Create;
|
|
end;
|
|
|
|
destructor TdxPSPageRenderInfo.Destroy;
|
|
begin
|
|
FreeAndNilOverlays;
|
|
FreeAndNilIndexPairs;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSPageRenderInfo.Calculate;
|
|
begin
|
|
CalculateBounds;
|
|
CalculateOffsets;
|
|
FIndexPairs.Count := CalculateIndexPairCount;
|
|
CalculateIndexPairs;
|
|
CalculateOverlayIndexes;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.HasDetails: Boolean;
|
|
begin
|
|
Result := not IsRectEmpty(DetailBounds);
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.HasFooter: Boolean;
|
|
begin
|
|
Result := not IsRectEmpty(FooterBounds) and (RenderInfo.CanUseHFOnEveryPageMode or IsBottomPage);
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.HasHeader: Boolean;
|
|
begin
|
|
Result := not IsRectEmpty(HeaderBounds) and (RenderInfo.CanUseHFOnEveryPageMode or IsTopPage);
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.HasTitle: Boolean;
|
|
begin
|
|
Result := RenderInfo.IsDrawPageTitleOnPage(PageIndex);
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.AreRectsIntersected(const R1, R2: TRect): Boolean;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if R1.Top = R1.Bottom then
|
|
Result := (R1.Top >= R2.Top) and (R1.Top <= R2.Bottom) // bear in mind that R.Top = R.Bottom
|
|
else
|
|
Result := Windows.IntersectRect(R, R1, R2);
|
|
end;
|
|
|
|
procedure TdxPSPageRenderInfo.CalculateBounds;
|
|
var
|
|
H: Integer;
|
|
begin
|
|
DetailBounds := RenderInfo.CalculatePageDetailBounds(ColIndex, RowIndex);
|
|
|
|
ContentBounds := DetailBounds;
|
|
Inc(ContentBounds.Bottom, HeaderBounds.Bottom - HeaderBounds.Top);
|
|
Inc(ContentBounds.Bottom, FooterBounds.Bottom - FooterBounds.Top);
|
|
|
|
H := MulDiv(RenderInfo.PaintSize.Y, 100, RenderInfo.ScaleFactor);
|
|
if HasTitle then
|
|
Dec(H, TitleHeight);
|
|
|
|
with ContentBounds do
|
|
if Bottom - Top > H then
|
|
Bottom := Top + H;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.CalculateIndexPairCount: Integer;
|
|
var
|
|
EndIndex, TopSide, StartIndex: Integer;
|
|
R: TRect;
|
|
begin
|
|
if (RenderInfo.EmptyPageCount > 0) or ReportLink.NeedCalcEmptyPages then
|
|
begin
|
|
EndIndex := {AStartIndex } -1;
|
|
Result := 0;
|
|
TopSide := DetailBounds.Top;
|
|
while (TopSide < DetailBounds.Bottom) and (EndIndex < ReportCells.Count) do
|
|
begin
|
|
Inc(Result);
|
|
StartIndex := EndIndex + 1;
|
|
repeat
|
|
R := ReportCells.Cells[StartIndex].AbsoluteRect;
|
|
Inc(StartIndex);
|
|
until (StartIndex = ReportCells.Count) or AreRectsIntersected(R, DetailBounds);
|
|
Dec(StartIndex);
|
|
|
|
EndIndex := StartIndex;
|
|
repeat
|
|
R := ReportCells.Cells[EndIndex].AbsoluteRect;
|
|
Inc(EndIndex);
|
|
until (EndIndex = ReportCells.Count) or not AreRectsIntersected(R, DetailBounds);
|
|
Dec(EndIndex);
|
|
if EndIndex <> ReportCells.Count - 1 then
|
|
Dec(EndIndex);
|
|
if EndIndex < StartIndex then
|
|
EndIndex := StartIndex;
|
|
|
|
TopSide := R.Bottom;
|
|
end;
|
|
end
|
|
else
|
|
Result := 1;
|
|
end;
|
|
|
|
procedure TdxPSPageRenderInfo.CalculateIndexPairs;
|
|
var
|
|
EndIndex, I, StartIndex: Integer;
|
|
R: TRect;
|
|
Intersected: Boolean;
|
|
begin
|
|
if IndexPairCount <> 0 then
|
|
begin
|
|
EndIndex := {AStartIndex } -1;
|
|
for I := 0 to IndexPairCount - 1 do
|
|
begin
|
|
StartIndex := EndIndex + 1;
|
|
repeat
|
|
R := ReportCells.Cells[StartIndex].AbsoluteRect;
|
|
Inc(StartIndex);
|
|
until (StartIndex = ReportCells.Count) or AreRectsIntersected(R, DetailBounds);
|
|
Dec(StartIndex);
|
|
EndIndex := StartIndex;
|
|
// fix 2.1
|
|
Intersected := True;
|
|
while (EndIndex < ReportCells.Count) and Intersected do
|
|
begin
|
|
R := ReportCells.Cells[EndIndex].AbsoluteRect;
|
|
Intersected := AreRectsIntersected(R, DetailBounds);
|
|
Inc(EndIndex);
|
|
end;
|
|
//Dec(EndIndex, 1 + Ord(EndIndex <> ReportCells.Count));
|
|
Dec(EndIndex);
|
|
if EndIndex <> ReportCells.Count - 1 then
|
|
Dec(EndIndex);
|
|
if EndIndex < StartIndex then
|
|
EndIndex := StartIndex;
|
|
|
|
IndexPairs[I].StartIndex := StartIndex;
|
|
IndexPairs[I].EndIndex := EndIndex;
|
|
end;
|
|
end
|
|
else
|
|
DetailBounds := NullRect; //TODO: TdxPSPageRenderInfo.CalculateIndexPairs
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.CalculateIsEmptyPage: Boolean;
|
|
begin
|
|
Result := not RenderInfo.IsNonEmptyPage(DetailBounds);
|
|
end;
|
|
|
|
procedure TdxPSPageRenderInfo.CalculateOffsets;
|
|
var
|
|
FullRect: TRect;
|
|
MarginsOffset: TPoint;
|
|
DataSize, PaintSize: Integer;
|
|
begin
|
|
FullRect := ContentBounds;
|
|
OffsetRect(FullRect, -FullRect.Left, -FullRect.Top);
|
|
FullRect := ScaleRect(FullRect, RenderInfo.ScaleFactor, 100, RenderInfo.ScaleFactor, 100);
|
|
|
|
MarginsOffset := PrinterPage.MarginsLoMetric.TopLeft;
|
|
|
|
// horz.
|
|
DataOffset.X := RenderInfo.LoMetricValueToInternalUnits(MarginsOffset.X);
|
|
if HasTitle then
|
|
TitleOffset.X := DataOffset.X;
|
|
if RenderInfo.PrinterPage.CenterOnPageH then
|
|
begin
|
|
DataSize := FullRect.Right - FullRect.Left;
|
|
PaintSize := RenderInfo.PaintSize.X;
|
|
if DataSize < RenderInfo.PaintSize.X then
|
|
Inc(DataOffset.X, MulDiv((PaintSize - DataSize) div 2, 100, RenderInfo.ScaleFactor));
|
|
end;
|
|
|
|
// vert.
|
|
DataOffset.Y := RenderInfo.LoMetricValueToInternalUnits(MarginsOffset.Y);
|
|
if HasTitle then
|
|
begin
|
|
TitleOffset.Y := DataOffset.Y;
|
|
Inc(DataOffset.Y, RenderInfo.TitleHeight);
|
|
end;
|
|
if RenderInfo.PrinterPage.CenterOnPageV then
|
|
begin
|
|
DataSize := FullRect.Bottom - FullRect.Top;
|
|
PaintSize := RenderInfo.PaintSize.Y;
|
|
if HasTitle then
|
|
Dec(PaintSize, RenderInfo.TitleBounds.Bottom - RenderInfo.TitleBounds.Top);
|
|
if DataSize < PaintSize then
|
|
Inc(DataOffset.Y, MulDiv((PaintSize - DataSize) div 2, 100, RenderInfo.ScaleFactor));
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSPageRenderInfo.CalculateOverlayIndexes;
|
|
|
|
function CreateOverlayIndexes(AnOverlay: TdxReportCell): TdxPageOverlayIndexes;
|
|
var
|
|
I: Integer;
|
|
R: TRect;
|
|
begin
|
|
Result := TdxPageOverlayIndexes.Create;
|
|
|
|
for I := 0 to AnOverlay.CellCount - 1 do
|
|
if IntersectRect(R, AnOverlay[I].AbsoluteRect, DetailBounds) then
|
|
Result.Add(I);
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (ReportCells = nil) or not ReportCells.HasOverlays then Exit;
|
|
|
|
FOverlays.Count := ReportCells.OverlayCount;
|
|
for I := 0 to ReportCells.OverlayCount - 1 do
|
|
FOverlays[I] := CreateOverlayIndexes(ReportCells.Overlays[I]);
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetColIndex: Integer;
|
|
begin
|
|
Result := PageIndex mod RenderInfo.PageColCount;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetFooterBounds: TRect;
|
|
begin
|
|
Result := RenderInfo.FooterBounds;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetHeaderBounds: TRect;
|
|
begin
|
|
Result := RenderInfo.HeaderBounds;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetIndexPair(Index: Integer): TdxContinuedIndexPair;
|
|
begin
|
|
Result := TdxContinuedIndexPair(FIndexPairs[Index]);
|
|
if Result = nil then
|
|
begin
|
|
Result := TdxContinuedIndexPair.Create;
|
|
FIndexPairs[Index] := Result;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetIndexPairCount: Integer;
|
|
begin
|
|
Result := FIndexPairs.Count;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetIsBottomPage: Boolean;
|
|
begin
|
|
Result := PageIndex >= RenderInfo.PageRenderInfoCount - RenderInfo.PageColCount;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetIsEmptyPage: Boolean;
|
|
begin
|
|
if not FIsEmptyPageCalculated then
|
|
begin
|
|
FIsEmptyPageCalculated := True;
|
|
FIsEmptyPage := CalculateIsEmptyPage;
|
|
end;
|
|
Result := FIsEmptyPage;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetIsTopPage: Boolean;
|
|
begin
|
|
Result := PageIndex < RenderInfo.PageColCount;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetOverlay(Index: Integer): TdxPageOverlayIndexes;
|
|
begin
|
|
Result := TdxPageOverlayIndexes(FOverlays[Index]);
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetOverlayCount: Integer;
|
|
begin
|
|
Result := FOverlays.Count;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetPrinterPage: TdxPrinterPage;
|
|
begin
|
|
Result := RenderInfo.PrinterPage;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetReportCells: TdxReportCells;
|
|
begin
|
|
Result := ReportLink.FReportCells;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetReportLink: TBasedxReportLink;
|
|
begin
|
|
Result := RenderInfo.ReportLink;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetRowIndex: Integer;
|
|
begin
|
|
Result := PageIndex div RenderInfo.PageColCount;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetTitleBounds: TRect;
|
|
begin
|
|
Result := RenderInfo.TitleBounds;
|
|
end;
|
|
|
|
function TdxPSPageRenderInfo.GetTitleHeight: Integer;
|
|
begin
|
|
with TitleBounds do
|
|
Result := Bottom - Top;
|
|
end;
|
|
|
|
procedure TdxPSPageRenderInfo.SetIndexPair(Index: Integer; Value: TdxContinuedIndexPair);
|
|
begin
|
|
FIndexPairs[Index] := Value;
|
|
end;
|
|
|
|
procedure TdxPSPageRenderInfo.FreeAndNilIndexPairs;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to IndexPairCount - 1 do
|
|
IndexPairs[I].Free;
|
|
FreeAndNil(FIndexPairs);
|
|
end;
|
|
|
|
procedure TdxPSPageRenderInfo.FreeAndNilOverlays;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to OverlayCount - 1 do
|
|
Overlays[I].Free;
|
|
FreeAndNil(FOverlays);
|
|
end;
|
|
|
|
{ TdxPSReportRenderInfo }
|
|
|
|
constructor TdxPSReportRenderInfo.Create(AReportLink: TBasedxReportLink);
|
|
begin
|
|
inherited Create;
|
|
FReportLink := AReportLink;
|
|
FBaseContentFont := TFont.Create;
|
|
FDelimitersX := TList.Create;
|
|
FDelimitersY := TList.Create;
|
|
FHardDelimitersY := TList.Create;
|
|
FPageDelimitersX := TList.Create;
|
|
FPageDelimitersY := TList.Create;
|
|
FPageRenderInfos := TList.Create;
|
|
end;
|
|
|
|
destructor TdxPSReportRenderInfo.Destroy;
|
|
begin
|
|
FreeAndNilPageRenderInfos;
|
|
FreeAndNil(FBaseContentFont);
|
|
FreeAndNil(FPageDelimitersY);
|
|
FreeAndNil(FPageDelimitersX);
|
|
FreeAndNil(FHardDelimitersY);
|
|
FreeAndNil(FDelimitersY);
|
|
FreeAndNil(FDelimitersX);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.Calculate;
|
|
begin
|
|
if not Locked then
|
|
begin
|
|
Lock;
|
|
try
|
|
Refresh;
|
|
DoCalculate;
|
|
finally
|
|
Unlock;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.CanRenderPage(AVirtualPageIndex: Integer): Boolean;
|
|
begin
|
|
Result := not (ReportLink.ShowEmptyPages and PageRenderInfos[AVirtualPageIndex].IsEmptyPage);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.IsDrawPageFootNoteOnPage(APageIndex: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
{case ReportLink.ReportTitleMode of
|
|
fnmNone:
|
|
Result := False;
|
|
fnmOnLastPage:
|
|
Result := APageIndex = PageCount - 1;
|
|
else
|
|
Result := APageIndex < PageCount - PageColCount;
|
|
end;}
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.IsDrawPageTitleOnPage(APageIndex: Integer): Boolean;
|
|
begin
|
|
case ReportLink.ReportTitleMode of
|
|
tmNone:
|
|
Result := False;
|
|
tmOnFirstPage:
|
|
Result := APageIndex = 0;
|
|
else
|
|
Result := APageIndex < PageColCount;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.Lock;
|
|
begin
|
|
Inc(FLockCounter);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.Unlock;
|
|
begin
|
|
if FLockCounter <> 0 then Dec(FLockCounter);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.CalculateEmptyPageCount: Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to PageRenderInfoCount - 1 do
|
|
if PageRenderInfos[I].IsEmptyPage then Inc(Result);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.CalculateHeaderAndFooterBounds;
|
|
begin
|
|
if ReportCells <> nil then
|
|
begin
|
|
if ReportLink.IsDrawFootersOnEveryPage or (ReportLink.DataSource = rldsExternalStorage) then
|
|
FooterBounds := ReportCells.FooterBoundsRect;
|
|
if ReportLink.IsDrawHeadersOnEveryPage or (ReportLink.DataSource = rldsExternalStorage) then
|
|
HeaderBounds := ReportCells.HeaderBoundsRect;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.CalculatePageContentHeight(APageIndex: Integer): Integer;
|
|
var
|
|
HeaderH, FooterH, TitleH: Integer;
|
|
begin
|
|
Result := PaintSize.Y;
|
|
|
|
HeaderH := MulDiv(HeaderHeight, ScaleFactor, 100);
|
|
FooterH := MulDiv(FooterHeight, ScaleFactor, 100);
|
|
TitleH := 0;
|
|
if IsDrawPageTitleOnPage(APageIndex) then
|
|
TitleH := MulDiv(TitleHeight, ScaleFactor, 100);
|
|
if APageIndex = 0 then
|
|
CanUseHFOnEveryPageMode := Result > HeaderH + FooterH + TitleH;
|
|
|
|
if Result < HeaderH + FooterH + TitleH then
|
|
FooterH := 0;
|
|
if (Result < HeaderH + TitleH) and (APageIndex > FPageDelimitersX.Count - 1) then
|
|
HeaderH := 0;
|
|
|
|
Dec(Result, HeaderH + FooterH + TitleH);
|
|
// if Result < 0 then Result := 0;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.CalculatePageContentWidth(APageIndex: Integer): Integer;
|
|
begin
|
|
Result := PaintSize.X;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.CalculatePageCount;
|
|
begin
|
|
VirtualPageCount := PageColCount * PageRowCount;
|
|
FPageRenderInfos.Capacity := VirtualPageCount;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.CalculatePageDelimiters;
|
|
var
|
|
I, PageIndex, Offset, PageContentWidth, PagePaintHeight, CurDelimiter,
|
|
Delimiter, HardDelimiterIndex: Integer;
|
|
begin
|
|
// Horz.
|
|
I := 0;
|
|
PageIndex := 0;
|
|
CurDelimiter := 0;
|
|
|
|
AddPageDelimiterX(0);
|
|
while I < DelimiterXCount do
|
|
begin
|
|
PageContentWidth := CalculatePageContentWidth(PageIndex);
|
|
Offset := PageDelimitersX[PageIndex];
|
|
while (I < DelimiterXCount) and
|
|
(MulDiv(DelimitersX[I] - Offset, ScaleFactor, 100) <= PageContentWidth) do
|
|
Inc(I);
|
|
if I < DelimiterXCount then
|
|
begin
|
|
Dec(I);
|
|
CurDelimiter := DelimitersX[I];
|
|
if Offset - CurDelimiter >= 0 then
|
|
CurDelimiter := Offset + MulDiv(PageContentWidth, 100, ScaleFactor);
|
|
AddPageDelimiterX(CurDelimiter);
|
|
Inc(PageIndex);
|
|
end;
|
|
end;
|
|
|
|
I := PageDelimitersX[PageDelimiterXCount - 1];
|
|
if I <> ReportWidth then
|
|
begin
|
|
Inc(I, ReportWidth);
|
|
if PageDelimiterXCount > 1 then Dec(I, CurDelimiter);
|
|
AddPageDelimiterX(I);
|
|
end;
|
|
if PageDelimiterXCount = 1 then PageDelimiterXClear;
|
|
|
|
// Vert.
|
|
I := 0;
|
|
PageIndex := 0;
|
|
AddPageDelimiterY(0);
|
|
while I < DelimiterYCount do
|
|
begin
|
|
PagePaintHeight := CalculatePageContentHeight(PageIndex);
|
|
if PagePaintHeight <= 0 then
|
|
begin
|
|
AddPageDelimiterY(0);
|
|
Inc(PageIndex);
|
|
Continue;
|
|
end;
|
|
Offset := PageDelimitersY[PageIndex];
|
|
HardDelimiterIndex := -1;
|
|
while I < DelimiterYCount do
|
|
begin
|
|
Delimiter := DelimitersY[I];
|
|
if MulDiv(Delimiter - Offset, ScaleFactor, 100) > PagePaintHeight then
|
|
Break;
|
|
if IsHardDelimiter(Delimiter) then
|
|
begin
|
|
HardDelimiterIndex := I;
|
|
if BreakPagesByHardDelimiters then Break;
|
|
end;
|
|
Inc(I);
|
|
end;
|
|
|
|
if I < DelimiterYCount then
|
|
begin
|
|
if HardDelimiterIndex <> -1 then
|
|
I := HardDelimiterIndex
|
|
else
|
|
Dec(I);
|
|
CurDelimiter := DelimitersY[I];
|
|
if HardDelimiterIndex <> -1 then
|
|
Inc(I);
|
|
if Offset - CurDelimiter >= 0 then
|
|
CurDelimiter := Offset + MulDiv(PagePaintHeight, 100, ScaleFactor);
|
|
AddPageDelimiterY(CurDelimiter);
|
|
Inc(PageIndex);
|
|
end;
|
|
end;
|
|
|
|
I := PageDelimitersY[PageDelimiterYCount - 1];
|
|
if I <> ReportHeight then
|
|
begin
|
|
Inc(I, ReportHeight);
|
|
if PageDelimiterYCount > 1 then Dec(I, CurDelimiter);
|
|
AddPageDelimiterY(I);
|
|
end;
|
|
if PageDelimiterYCount = 1 then PageDelimiterYClear;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.CalculatePageDetailBounds(APageCol, APageRow: Integer): TRect;
|
|
begin
|
|
Result := MakeRect(PageDelimitersX[APageCol], PageDelimitersY[APageRow],
|
|
PageDelimitersX[APageCol + 1], PageDelimitersY[APageRow + 1]);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.CalculatePageHeaderAndFooterBounds;
|
|
begin
|
|
if ReportLink.ShowPageHeader then
|
|
PageHeaderBounds := LoMetricRectToInternalUnits(PrinterPage.HeaderRectLoMetric);
|
|
if ReportLink.ShowPageFooter then
|
|
PageFooterBounds := LoMetricRectToInternalUnits(PrinterPage.FooterRectLoMetric);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.CalculatePageRenderInfos;
|
|
var
|
|
I: Integer;
|
|
PageRenderInfo: TdxPSPageRenderInfo;
|
|
begin
|
|
for I := 0 to VirtualPageCount - 1 do
|
|
begin
|
|
PageRenderInfo := CreatePageRenderInfo(I);
|
|
PageRenderInfo.Calculate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.CalculatePageRealAndVirtualIndexes(APageIndex: Integer;
|
|
out AVirtualPageIndex, ARealPageIndex: Integer);
|
|
begin
|
|
AVirtualPageIndex := RealPageIndexToVirtualPageIndex(APageIndex, False);
|
|
ARealPageIndex := VirtualPageIndexToRealPageIndex(APageIndex);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.CalculateTitleHeight: Integer;
|
|
const
|
|
CalcFormat: UINT = DT_CALCRECT or DT_EDITCONTROL or DT_WORDBREAK;
|
|
var
|
|
L, PrevFontHeight: Integer;
|
|
DC: HDC;
|
|
PrevFont: HFONT;
|
|
R: TRect;
|
|
begin
|
|
Result := 0;
|
|
PrevFontHeight := TitleFont.Height;
|
|
if TitleAdjustOnReportScale then
|
|
TitleFont.Height := MulDiv(PrevFontHeight, ScaleFactor, 100);
|
|
try
|
|
L := Length(TitleText);
|
|
if L <> 0 then
|
|
begin
|
|
DC := GetDC(0);
|
|
try
|
|
PrevFont := SelectObject(DC, TitleFont.Handle);
|
|
R := PrinterPage.PaintRectPixels;
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
Result := 4 + Windows.DrawText(DC, PChar(TitleText), L, R, CalcFormat);
|
|
SelectObject(DC, PrevFont);
|
|
finally
|
|
ReleaseDC(0, DC);
|
|
end;
|
|
end;
|
|
ReportLink.DoMeasureReportLinkTitle(Result);
|
|
finally
|
|
if TitleAdjustOnReportScale then
|
|
TitleFont.Height := PrevFontHeight
|
|
end;
|
|
R := PrinterPage.PaintRectPixels;
|
|
L := (R.Bottom - R.Top) div 2;
|
|
if Result > L then Result := L;
|
|
if Result < 0 then Result := 0;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.CalculateTitleBounds;
|
|
begin
|
|
TitleBounds.Right := MulDiv(PaintSize.X, 100, ScaleFactor);
|
|
TitleBounds.Bottom := MulDiv(CalculateTitleHeight,
|
|
100 * PixelsNumerator, ScaleFactor * PixelsDenominator);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.DoCalculate;
|
|
begin
|
|
if ReportCells <> nil then
|
|
begin
|
|
BaseContentFont := ReportCells.Font;
|
|
GridLinesColor := ReportCells.BorderColor;
|
|
end;
|
|
|
|
CalculateTitleBounds;
|
|
CalculateHeaderAndFooterBounds;
|
|
CalculatePageDelimiters;
|
|
CalculatePageCount;
|
|
CalculatePageHeaderAndFooterBounds;
|
|
CalculatePageRenderInfos;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetNonEmptyPageCount: Integer;
|
|
begin
|
|
Result := VirtualPageCount - EmptyPageCount;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageColCount: Integer;
|
|
begin
|
|
Result := PageDelimiterXCount - 1;
|
|
if Result < 0 then Result := 0;
|
|
if (Result = 0) and (ReportCells <> nil) and (ReportCells.HeaderCellCount <> 0) and (ReportCells.FooterCellCount <> 0) then
|
|
Result := 1;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageRowCount: Integer;
|
|
begin
|
|
Result := PageDelimiterYCount - 1;
|
|
if Result < 0 then Result := 0;
|
|
if (Result = 0) and (ReportCells <> nil) and (ReportCells.HeaderCellCount <> 0) and (ReportCells.FooterCellCount <> 0) then
|
|
Result := 1;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageSize: TPoint;
|
|
begin
|
|
with PrinterPage.RealPageSizeLoMetric do
|
|
begin
|
|
Result.X := MulDiv(X, UnitsPerInch, 254);
|
|
Result.Y := MulDiv(Y, UnitsPerInch, 254);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPaintSize: TPoint;
|
|
begin
|
|
with PrinterPage.PaintRectLoMetric do
|
|
begin
|
|
Result.X := MulDiv(Right - Left, UnitsPerInch, 254);
|
|
Result.Y := MulDiv(Bottom - Top, UnitsPerInch, 254);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetUnitsPerInch: Integer;
|
|
begin
|
|
Result := FUnitsPerInch;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetWindowScalePair: TdxWindowScalePair;
|
|
begin
|
|
Result.Numerator := 100;
|
|
Result.Denominator := ScaleFactor;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.SetUnitsPerInch(Value: Integer);
|
|
begin
|
|
FUnitsPerInch := Value;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.ClearPageRenderInfos;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to PageRenderInfoCount - 1 do
|
|
PageRenderInfos[I].Free;
|
|
FPageRenderInfos.Clear;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.CreatePageRenderInfo(APageIndex: Integer): TdxPSPageRenderInfo;
|
|
begin
|
|
Result := GetPageRenderInfoClass.Create(Self, APageIndex);
|
|
FPageRenderInfos.Add(Result);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.FreeAndNilPageRenderInfos;
|
|
begin
|
|
ClearPageRenderInfos;
|
|
FreeAndNil(FPageRenderInfos);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageRenderInfoClass: TdxPSPageRenderInfoClass;
|
|
begin
|
|
Result := TdxPSPageRenderInfo;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.Refresh;
|
|
begin
|
|
ClearPageRenderInfos;
|
|
FPageDelimitersX.Clear;
|
|
FPageDelimitersY.Clear;
|
|
|
|
CanUseHFOnEveryPageMode := True;
|
|
|
|
//FIsTitleHeightCalculated := False;
|
|
FEmptyPageCount := -1;
|
|
VirtualPageCount := 0;
|
|
|
|
FooterBounds := NullRect;
|
|
HeaderBounds := NullRect;
|
|
PageFooterBounds := NullRect;
|
|
PageHeaderBounds := NullRect;
|
|
TitleBounds := NullRect;
|
|
FPixelsNumerator := Self.UnitsPerInch;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.HasPageTitle(APageIndex: Integer): Boolean;
|
|
begin
|
|
Result := not IsRectEmpty(TitleBounds) and IsDrawPageTitleOnPage(APageIndex);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.IsHardDelimiter(AValue: Integer): Boolean;
|
|
begin
|
|
Result := FHardDelimitersY.IndexOf(TObject(AValue)) <> -1;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
ReadDelimiters(AReader);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.ReadDelimiters(AReader: TdxPSDataReader);
|
|
|
|
procedure ReadList(AList: TList);
|
|
begin
|
|
AList.Clear;
|
|
AList.Count := AReader.ReadInteger;
|
|
AReader.Read(AList.List^, AList.Count * SizeOf(Pointer));
|
|
end;
|
|
|
|
begin
|
|
ReadList(FDelimitersX);
|
|
ReadList(FDelimitersY);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
WriteDelimiters(AWriter);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.WriteDelimiters(AWriter: TdxPSDataWriter);
|
|
|
|
procedure WriteList(AList: TList);
|
|
begin
|
|
AWriter.WriteInteger(AList.Count);
|
|
AWriter.Write(AList.List^, AList.Count * SizeOf(Pointer));
|
|
end;
|
|
|
|
begin
|
|
WriteList(FDelimitersX);
|
|
WriteList(FDelimitersY);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.AddPageDelimiterX(AValue: Integer);
|
|
begin
|
|
FPageDelimitersX.Add(TObject(AValue));
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.AddPageDelimiterY(AValue: Integer);
|
|
begin
|
|
FPageDelimitersY.Add(TObject(AValue));
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.PageDelimiterXClear;
|
|
begin
|
|
FPageDelimitersX.Clear;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.PageDelimiterYClear;
|
|
begin
|
|
FPageDelimitersY.Clear;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.AddStandardDelimiters;
|
|
begin
|
|
DelimiterXList.Add(TObject(Integer(0)));
|
|
DelimiterXList.Add(TObject(Integer(ReportWidth)));
|
|
DelimiterYList.Add(TObject(Integer(0)));
|
|
DelimiterYList.Add(TObject(Integer(ReportHeight)));
|
|
end;
|
|
|
|
function CompareProc(Item1, Item2: Pointer ): Integer;
|
|
begin
|
|
Result := Integer(Item1) - Integer(Item2);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.EliminateDuplicatesAndSortDelimiters(AList: TList);
|
|
var
|
|
Duplicates: TList;
|
|
I: Integer;
|
|
V: Pointer;
|
|
begin
|
|
Duplicates := TList.Create;
|
|
try
|
|
for I := 0 to AList.Count - 1 do
|
|
begin
|
|
V := AList[I];
|
|
if Duplicates.IndexOf(V) = -1 then Duplicates.Add(V);
|
|
end;
|
|
Duplicates.Sort(CompareProc);
|
|
AList.Clear;
|
|
AList.Count := Duplicates.Count;
|
|
V := AList.List;
|
|
Move(Duplicates.List^, V^, Duplicates.Count * SizeOf(Pointer));
|
|
finally
|
|
Duplicates.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.GetDelimiters;
|
|
begin
|
|
DelimiterXList.Clear;
|
|
DelimiterYList.Clear;
|
|
HardDelimiterYList.Clear;
|
|
|
|
if UseHorzDelimiters or UseVertDelimiters then
|
|
begin
|
|
MakeDelimiters;
|
|
if UseHardVertDelimiters then
|
|
begin
|
|
MakeHardDelimiters;
|
|
EliminateDuplicatesAndSortDelimiters(HardDelimiterYList);
|
|
TrancateDelimiters(HardDelimiterYList, ReportLink.ReportHeight);
|
|
end;
|
|
end;
|
|
|
|
AddStandardDelimiters;
|
|
|
|
EliminateDuplicatesAndSortDelimiters(DelimiterXList);
|
|
TrancateDelimiters(DelimiterXList, ReportLink.ReportWidth);
|
|
EliminateDuplicatesAndSortDelimiters(DelimiterYList);
|
|
TrancateDelimiters(DelimiterYList, ReportLink.ReportHeight);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.MakeDelimiters;
|
|
begin
|
|
ReportLink.MakeDelimiters(ReportCells, DelimiterXList, DelimiterYList);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.MakeHardDelimiters;
|
|
begin
|
|
ReportLink.MakeHardDelimiters(ReportCells, HardDelimiterYList);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.PageParamsChanged(Sender: TdxPrinterPage;
|
|
AStyle: TBasedxPrintStyle; AUpdateCodes: TdxPrinterPageUpdateCodes);
|
|
begin
|
|
if (RealPrinterPage = Sender) and IsCurrentLink and
|
|
(SignificantPrinterPageUpdateCodes * AUpdateCodes <> []) then
|
|
begin
|
|
if Active then
|
|
if GetRebuildOnPageParamsChange(AUpdateCodes) then
|
|
RebuildReport
|
|
else
|
|
CalculateRenderInfos;
|
|
DoPageParamsChanged;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.PossibleCustomDraw(AnItem: TAbstractdxReportCellData): Boolean;
|
|
begin
|
|
Result := (DataSource = rldsComponent) and IsSupportedCustomDraw(AnItem);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.PrepareReportGroupsLookAndFeels;
|
|
var
|
|
DC: HDC;
|
|
begin
|
|
if ReportCells <> nil then
|
|
begin
|
|
DC := GetDC(0);
|
|
try
|
|
ReportCells.PrepareReportGroupsLookAndFeels(DC);
|
|
finally
|
|
ReleaseDC(0, DC);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.TrancateDelimiters(AList: TList; AValue: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
I := AList.Count - 1;
|
|
while (I > -1) and (Integer(AList[I]) > AValue) do
|
|
begin
|
|
AList.Delete(I);
|
|
Dec(I);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.LoMetricRectToInternalUnits(const R: TRect): TRect;
|
|
begin
|
|
with Result do
|
|
begin
|
|
Left := LoMetricValueToInternalUnits(R.Left);
|
|
Top := LoMetricValueToInternalUnits(R.Top);
|
|
Right := LoMetricValueToInternalUnits(R.Right);
|
|
Bottom := LoMetricValueToInternalUnits(R.Bottom);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.LoMetricValueToInternalUnits(Value: Integer): Integer;
|
|
begin
|
|
Result := MulDiv(Value, 100 * UnitsPerInch, 254 * ScaleFactor);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.RealPageIndexToVirtualPageIndex(APageIndex: Integer;
|
|
ATakeIntoAccountEmptyPages: Boolean): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := APageIndex;
|
|
if (EmptyPageCount > 0) and (not ReportLink.ShowEmptyPages or ATakeIntoAccountEmptyPages) then
|
|
begin
|
|
I := 0;
|
|
while (I < VirtualPageCount) and (I <> Result) do
|
|
begin
|
|
if PageRenderInfos[I].IsEmptyPage then Inc(Result);
|
|
Inc(I);
|
|
end;
|
|
while (Result < VirtualPageCount) and PageRenderInfos[Result].IsEmptyPage do
|
|
Inc(Result);
|
|
if Result = VirtualPageCount then Dec(Result);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.VirtualPageIndexToRealPageIndex(APageIndex: Integer): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := APageIndex;
|
|
if (EmptyPageCount = 0) or not ReportLink.ShowEmptyPages then
|
|
Exit;
|
|
for I := 0 to APageIndex do
|
|
if PageRenderInfos[I].IsEmptyPage then Dec(Result);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPrinterPage: TdxPrinterPage;
|
|
begin
|
|
Result := ReportLink.RealPrinterPage;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetReportCells: TdxReportCells;
|
|
begin
|
|
Result := ReportLink.FReportCells;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetReportHeight: Integer;
|
|
begin
|
|
Result := ReportLink.ReportHeight;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetReportWidth: Integer;
|
|
begin
|
|
Result := ReportLink.ReportWidth;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetScaleFactor: Integer;
|
|
begin
|
|
Result := ReportLink.RealScaleFactor;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetTitleAdjustOnReportScale: Boolean;
|
|
begin
|
|
Result := ReportLink.ReportTitle.AdjustOnReportScale;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetTitleFont: TFont;
|
|
begin
|
|
Result := ReportLink.ReportTitle.Font;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetTitleText: string;
|
|
begin
|
|
Result := ReportLink.ReportTitleText;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetBreakPagesByHardDelimiters: Boolean;
|
|
begin
|
|
Result := UseHardVertDelimiters and ReportLink.BreakPagesByHardDelimiters;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetDelimiterX(Index: Integer): Integer;
|
|
begin
|
|
Result := Integer(FDelimitersX.List^[Index]);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetDelimiterXCount: Integer;
|
|
begin
|
|
Result := FDelimitersX.Count;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetDelimiterY(Index: Integer): Integer;
|
|
begin
|
|
Result := Integer(FDelimitersY.List^[Index]);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetDelimiterYCount: Integer;
|
|
begin
|
|
Result := FDelimitersY.Count;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetEmptyPageCount: Integer;
|
|
begin
|
|
if FEmptyPageCount = -1 then
|
|
if ReportLink.NeedCalcEmptyPages then
|
|
FEmptyPageCount := CalculateEmptyPageCount
|
|
else
|
|
FEmptyPageCount := 0;
|
|
Result := FEmptyPageCount;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetFooterHeight: Integer;
|
|
begin
|
|
with FooterBounds do
|
|
Result := Bottom - Top;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetHeaderHeight: Integer;
|
|
begin
|
|
with HeaderBounds do
|
|
Result := Bottom - Top;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetLocked: Boolean;
|
|
begin
|
|
Result := FLockCounter <> 0;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageDelimiterX(Index: Integer): Integer;
|
|
begin
|
|
Result := Integer(FPageDelimitersX.List^[Index]);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageDelimiterXCount: Integer;
|
|
begin
|
|
Result := FPageDelimitersX.Count;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageDelimiterY(Index: Integer): Integer;
|
|
begin
|
|
Result := Integer(FPageDelimitersY.List^[Index]);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageDelimiterYCount: Integer;
|
|
begin
|
|
Result := FPageDelimitersY.Count;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageRenderInfo(Index: Integer): TdxPSPageRenderInfo;
|
|
begin
|
|
Result := TdxPSPageRenderInfo(FPageRenderInfos[Index]);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetPageRenderInfoCount: Integer;
|
|
begin
|
|
Result := FPageRenderInfos.Count;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetUseHardVertDelimiters: Boolean;
|
|
begin
|
|
Result := ReportLink.UseHardVertDelimiters;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetUseHorzDelimiters: Boolean;
|
|
begin
|
|
Result := ReportLink.UseHorzDelimiters;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetUseVertDelimiters: Boolean;
|
|
begin
|
|
Result := ReportLink.UseVertDelimiters;
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.GetTitleHeight: Integer;
|
|
begin
|
|
with TitleBounds do
|
|
Result := Bottom - Top;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderInfo.SetBaseContentFont(Value: TFont);
|
|
begin
|
|
BaseContentFont.Assign(Value);
|
|
end;
|
|
|
|
function TdxPSReportRenderInfo.IsNonEmptyPage(const ABounds: TRect): Boolean;
|
|
var
|
|
I: Integer;
|
|
R: TRect;
|
|
begin
|
|
Result := False;
|
|
if ReportCells <> nil then
|
|
for I := 0 to ReportCells.Count - 1 do
|
|
begin
|
|
R := ReportCells.Cells[I].AbsoluteRect;
|
|
Result := IntersectRect(R, R, ABounds);
|
|
if Result then Exit;
|
|
end;
|
|
end;
|
|
|
|
{ TdxPSCellBorderPainter }
|
|
|
|
constructor TdxPSCellBorderPainter.Create(ARenderer: TdxPSReportRenderer);
|
|
begin
|
|
inherited Create;
|
|
FRenderer := ARenderer;
|
|
end;
|
|
|
|
class procedure TdxPSCellBorderPainter.DrawFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
ATLBrush, ABRBrush: HBRUSH; ALineThickness: Integer; AThickness: Integer = 1);
|
|
var
|
|
I: Integer;
|
|
Side: TdxCellSide;
|
|
BorderBounds: TRect;
|
|
begin
|
|
for I := 0 to AThickness - 1 do
|
|
begin
|
|
for Side := csLeft to csBottom do
|
|
if Side in ASides then
|
|
begin
|
|
BorderBounds := GetBorderBounds(R, Side, ALineThickness);
|
|
if RectVisible(DC, BorderBounds) then
|
|
if Side in csTopLeft then
|
|
Windows.FillRect(DC, BorderBounds, ATLBrush)
|
|
else
|
|
Windows.FillRect(DC, BorderBounds, ABRBrush);
|
|
end;
|
|
InflateRect(R, ASides, ALineThickness);
|
|
end;
|
|
end;
|
|
|
|
class procedure TdxPSCellBorderPainter.DrawShadow(DC: HDC; const R: TRect;
|
|
AShadowDepth: Integer; AShadowBrush, ARestSpaceBrush: HBRUSH);
|
|
begin
|
|
Windows.FillRect(DC, GetBottomShadowBounds(R, AShadowDepth), AShadowBrush);
|
|
Windows.FillRect(DC, GetBottomShadowRestSpaceBounds(R, AShadowDepth), ARestSpaceBrush);
|
|
Windows.FillRect(DC, GetRightShadowBounds(R, AShadowDepth), AShadowBrush);
|
|
Windows.FillRect(DC, GetRightShadowRestSpaceBounds(R, AShadowDepth), ARestSpaceBrush);
|
|
end;
|
|
|
|
procedure TdxPSCellBorderPainter.Paint(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
with Item do
|
|
begin
|
|
R := GetBorderOuterBounds(DC);
|
|
DrawFrame(DC, R, CellSides, BorderBrush, BorderBrush, LineThickness, BorderClass.Thickness);
|
|
if ShowShadow and (ShadowDepth <> 0) then
|
|
DrawShadow(DC, R, ShadowDepth, ShadowBrush, ParentBrush);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSCellBorderPainter.BorderClass: TdxPSCellBorderClass;
|
|
begin
|
|
Result := Item.BorderClass;
|
|
end;
|
|
|
|
function TdxPSCellBorderPainter.Item: TdxReportVisualItem;
|
|
begin
|
|
Result := FItem;
|
|
end;
|
|
|
|
function TdxPSCellBorderPainter.Renderer: TdxPSReportRenderer;
|
|
begin
|
|
Result := FRenderer;
|
|
end;
|
|
|
|
class function TdxPSCellBorderPainter.GetBorderBounds(const R: TRect;
|
|
ASide: TdxCellSide; ALineThickness: Integer): TRect;
|
|
begin
|
|
Result := R;
|
|
with Result do
|
|
case ASide of
|
|
csLeft:
|
|
Right := Left + ALineThickness;
|
|
csTop:
|
|
Bottom := Top + ALineThickness;
|
|
csRight:
|
|
Left := Right - ALineThickness;
|
|
csBottom:
|
|
Top := Bottom - ALineThickness;
|
|
end;
|
|
end;
|
|
|
|
class function TdxPSCellBorderPainter.GetBottomShadowBounds(const R: TRect;
|
|
AShadowDepth: Integer): TRect;
|
|
begin
|
|
with Result do
|
|
begin
|
|
Left := R.Left + AShadowDepth;
|
|
Top := R.Bottom;
|
|
Right := R.Right + AShadowDepth;
|
|
Bottom := Top + AShadowDepth;
|
|
end;
|
|
end;
|
|
|
|
class function TdxPSCellBorderPainter.GetBottomShadowRestSpaceBounds(const R: TRect;
|
|
AShadowDepth: Integer): TRect;
|
|
begin
|
|
with Result do
|
|
begin
|
|
Left := R.Left;
|
|
Top := R.Bottom;
|
|
Right := Left + AShadowDepth;
|
|
Bottom := Top + AShadowDepth;
|
|
end;
|
|
end;
|
|
|
|
class function TdxPSCellBorderPainter.GetRightShadowBounds(const R: TRect;
|
|
AShadowDepth: Integer): TRect;
|
|
begin
|
|
with Result do
|
|
begin
|
|
Left := R.Right;
|
|
Top := R.Top + AShadowDepth;
|
|
Right := Left + AShadowDepth;
|
|
Bottom := Bottom;
|
|
end;
|
|
end;
|
|
|
|
class function TdxPSCellBorderPainter.GetRightShadowRestSpaceBounds(const R: TRect;
|
|
AShadowDepth: Integer): TRect;
|
|
begin
|
|
with Result do
|
|
begin
|
|
Left := R.Right;
|
|
Top := R.Top;
|
|
Right := Left + AShadowDepth;
|
|
Bottom := Top + AShadowDepth;
|
|
end;
|
|
end;
|
|
|
|
class procedure TdxPSCellBorderPainter.InflateRect(var R: TRect; ASides: TdxCellSides;
|
|
ALineThickness: Integer);
|
|
begin
|
|
if csLeft in ASides then Inc(R.Left, ALineThickness);
|
|
if csTop in ASides then Inc(R.Top, ALineThickness);
|
|
if csRight in ASides then Dec(R.Right, ALineThickness);
|
|
if csBottom in ASides then Dec(R.Bottom, ALineThickness);
|
|
end;
|
|
|
|
function TdxPSCellBorderPainter.GetLineThickness: Integer;
|
|
begin
|
|
Result := Renderer.LineThickness;
|
|
end;
|
|
|
|
{ TdxPSCustomCellBorder }
|
|
|
|
class procedure TdxPSCustomCellBorder.Register;
|
|
begin
|
|
if GetClass(ClassName) = nil then RegisterClass(Self);
|
|
end;
|
|
|
|
class procedure TdxPSCustomCellBorder.Unregister;
|
|
begin
|
|
end;
|
|
|
|
class function TdxPSCustomCellBorder.Solid: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
class function TdxPSCustomCellBorder.Thickness: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
class function TdxPSCustomCellBorder.Edge3DSoft: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
class function TdxPSCustomCellBorder.Edge3DStyle: TdxCellEdgeStyle;
|
|
begin
|
|
Result := cesRaised;
|
|
end;
|
|
|
|
class function TdxPSCustomCellBorder.EdgeMode: TdxCellEdgeMode;
|
|
begin
|
|
Result := cemPattern;
|
|
end;
|
|
|
|
class function TdxPSCustomCellBorder.GetBorderEdgeSalient(ASide: TdxCellSide;
|
|
ASalient: TdxPSCellBorderSalientType): Integer;
|
|
begin
|
|
if ASalient = bstOuter then
|
|
if ASide in csTopLeft then
|
|
Result := 1 + Thickness div 2
|
|
else
|
|
Result := (Thickness - 1) div 2
|
|
else
|
|
if ASide in csTopLeft then
|
|
Result := (Thickness - 1) div 2
|
|
else
|
|
Result := 1 + Thickness div 2
|
|
end;
|
|
|
|
class function TdxPSCustomCellBorder.GetPainterClass: TdxPSCellBorderPainterClass;
|
|
begin
|
|
Result := TdxPSCellBorderPainter;
|
|
end;
|
|
|
|
{ TdxPSCellNullBorderPainter }
|
|
|
|
procedure TdxPSCellNullBorderPainter.Paint(DC: HDC);
|
|
begin
|
|
with Item do
|
|
if ShowShadow and (ShadowDepth <> 0) then
|
|
DrawShadow(DC, GetBorderOuterBounds(DC), ShadowDepth, ShadowBrush, ParentBrush);
|
|
end;
|
|
|
|
{ TdxPSNullCellEdge }
|
|
|
|
class function TdxPSCellNullBorder.GetPainterClass: TdxPSCellBorderPainterClass;
|
|
begin
|
|
Result := TdxPSCellNullBorderPainter;
|
|
end;
|
|
|
|
class function TdxPSCellNullBorder.Thickness: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
{ TdxPSCellFlatBorder }
|
|
|
|
class function TdxPSCellFlatBorder.GetPainterClass: TdxPSCellBorderPainterClass;
|
|
begin
|
|
Result := inherited GetPainterClass;//TdxPSCellFlatBorderPainter; //TODO:
|
|
end;
|
|
|
|
{ TdxPSCellBoldFlatBorder }
|
|
|
|
class function TdxPSCellBoldFlatBorder.Thickness: Integer;
|
|
begin
|
|
Result := 2;
|
|
end;
|
|
|
|
{ TdxPSCellUltraFlatBorder }
|
|
|
|
class function TdxPSCellUltraFlatBorder.Thickness: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
{ TdxPSCell3DBorderPainter }
|
|
|
|
class procedure TdxPSCell3DBorderPainter.Draw3DFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush: HBRUSH; ALineThickness: Integer);
|
|
begin
|
|
DrawFrame(DC, R, ASides, AOuterTLBrush, AOuterBRBrush, ALineThickness);
|
|
InflateRect(R, ASides, ALineThickness);
|
|
DrawFrame(DC, R, ASides, AInnerTLBrush, AInnerBRBrush, ALineThickness);
|
|
end;
|
|
|
|
class procedure TdxPSCell3DBorderPainter.Draw3DFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
ACellBorders: TdxPSCell3DBorderClass; ALineThickness: Integer);
|
|
begin
|
|
with ACellBorders do
|
|
Draw3DFrame(DC, R, ASides, TopLeftOuterBrush, BottomRightOuterBrush,
|
|
TopLeftInnerBrush, BottomRightInnerBrush, ALineThickness);
|
|
end;
|
|
|
|
procedure TdxPSCell3DBorderPainter.Paint(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
with Item do
|
|
begin
|
|
R := GetBorderOuterBounds(DC);
|
|
Draw3DFrame(DC, R, CellSides, Self.BorderClass, LineThickness);
|
|
if ShowShadow and (ShadowDepth <> 0) then
|
|
DrawShadow(DC, R, ShadowDepth, ShadowBrush, ParentBrush);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSCell3DBorderPainter.BorderClass: TdxPSCell3DBorderClass;
|
|
begin
|
|
Result := TdxPSCell3DBorderClass(inherited BorderClass);
|
|
end;
|
|
|
|
{ TdxPSCustomCell3DBorder }
|
|
|
|
class function TdxPSCustomCell3DBorder.Solid: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.Thickness: Integer;
|
|
begin
|
|
Result := 2;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.BottomRightInnerBrush: HBRUSH;
|
|
begin
|
|
Result := NULL_BRUSH;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.BottomRightInnerColor: TColor;
|
|
begin
|
|
Result := clNone;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.BottomRightOuterBrush: HBRUSH;
|
|
begin
|
|
Result := NULL_BRUSH;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.BottomRightOuterColor: TColor;
|
|
begin
|
|
Result := clNone;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.TopLeftInnerBrush: HBRUSH;
|
|
begin
|
|
Result := NULL_BRUSH;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.TopLeftInnerColor: TColor;
|
|
begin
|
|
Result := clNone;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.TopLeftOuterBrush: HBRUSH;
|
|
begin
|
|
Result := NULL_BRUSH;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.TopLeftOuterColor: TColor;
|
|
begin
|
|
Result := clNone;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.EdgeMode: TdxCellEdgeMode;
|
|
begin
|
|
Result := cem3DEffects;
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.GetBorderEdgeSalient(ASide: TdxCellSide;
|
|
ASalient: TdxPSCellBorderSalientType): Integer;
|
|
begin
|
|
if ASalient = bstOuter then
|
|
if ASide in csTopLeft then
|
|
Result := Thickness div 2
|
|
else
|
|
Result := (Thickness - 1) div 2
|
|
else
|
|
if ASide in csTopLeft then
|
|
Result := (Thickness - 1) div 2
|
|
else
|
|
Result := Thickness div 2
|
|
end;
|
|
|
|
class function TdxPSCustomCell3DBorder.GetPainterClass: TdxPSCellBorderPainterClass;
|
|
begin
|
|
Result := TdxPSCell3DBorderPainter;
|
|
end;
|
|
|
|
{ TdxPSCellRaisedBorder }
|
|
|
|
class function TdxPSCellRaisedBorder.BottomRightInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNSHADOW);
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.BottomRightInnerColor: TColor;
|
|
begin
|
|
Result := clBtnShadow;
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.BottomRightOuterBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_WINDOWTEXT);
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.BottomRightOuterColor: TColor;
|
|
begin
|
|
Result := clWindowText;
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.TopLeftInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNHIGHLIGHT);
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.TopLeftInnerColor: TColor;
|
|
begin
|
|
Result := clBtnHighlight;
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.TopLeftOuterBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_WINDOWTEXT);
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.TopLeftOuterColor: TColor;
|
|
begin
|
|
Result := clWindowText;
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.Edge3DSoft: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
class function TdxPSCellRaisedBorder.Edge3DStyle: TdxCellEdgeStyle;
|
|
begin
|
|
Result := cesRaised;
|
|
end;
|
|
|
|
{ TdxPSCellRaisedSoftBorder }
|
|
|
|
class function TdxPSCellRaisedSoftBorder.BottomRightInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNFACE);
|
|
end;
|
|
|
|
class function TdxPSCellRaisedSoftBorder.BottomRightInnerColor: TColor;
|
|
begin
|
|
Result := clBtnFace;
|
|
end;
|
|
|
|
class function TdxPSCellRaisedSoftBorder.Edge3DSoft: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{ TdxPSCellSunkenBorder }
|
|
|
|
class function TdxPSCellSunkenBorder.BottomRightInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNFACE);
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.BottomRightInnerColor: TColor;
|
|
begin
|
|
Result := clBtnFace;
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.BottomRightOuterBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNHIGHLIGHT);
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.BottomRightOuterColor: TColor;
|
|
begin
|
|
Result := clBtnHighlight;
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.TopLeftInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNSHADOW);
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.TopLeftInnerColor: TColor;
|
|
begin
|
|
Result := clBtnShadow;
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.TopLeftOuterBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_WINDOWTEXT);
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.TopLeftOuterColor: TColor;
|
|
begin
|
|
Result := clWindowText;
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.Edge3DSoft: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
class function TdxPSCellSunkenBorder.Edge3DStyle: TdxCellEdgeStyle;
|
|
begin
|
|
Result := cesSunken;
|
|
end;
|
|
|
|
{ TdxPSCellSunkenSoftBorder }
|
|
|
|
class function TdxPSCellSunkenSoftBorder.BottomRightInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNFACE);
|
|
end;
|
|
|
|
class function TdxPSCellSunkenSoftBorder.BottomRightInnerColor: TColor;
|
|
begin
|
|
Result := clBtnFace;
|
|
end;
|
|
|
|
class function TdxPSCellSunkenSoftBorder.TopLeftInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNFACE);
|
|
end;
|
|
|
|
class function TdxPSCellSunkenSoftBorder.TopLeftInnerColor: TColor;
|
|
begin
|
|
Result := clBtnFace;
|
|
end;
|
|
|
|
class function TdxPSCellSunkenSoftBorder.Edge3DSoft: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{ TdxPSCellEtchedBorderPainter }
|
|
|
|
{$IFDEF BCB}
|
|
class procedure TdxPSCellTwistedBorderPainter.Draw3DFrame(DC: HDC; R: TRect;
|
|
ASides: TdxCellSides; ACellBorders: TdxPSCell3DBorderClass; ALineThickness: Integer);
|
|
begin
|
|
inherited;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
class procedure TdxPSCellTwistedBorderPainter.Draw3DFrame(DC: HDC; R: TRect; ASides: TdxCellSides;
|
|
AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush: HBRUSH; ALineThickness: Integer);
|
|
begin
|
|
Inc(R.Left, ALineThickness);
|
|
Inc(R.Top, ALineThickness);
|
|
DrawFrame(DC, R, ASides, AInnerTLBrush, AInnerBRBrush, ALineThickness);
|
|
Windows.OffsetRect(R, -ALineThickness, -ALineThickness);
|
|
DrawFrame(DC, R, ASides, AOuterTLBrush, AOuterBRBrush, ALineThickness);
|
|
end;
|
|
|
|
{ TdxPSCellTwistedBorder }
|
|
|
|
class function TdxPSCellTwistedBorder.GetPainterClass: TdxPSCellBorderPainterClass;
|
|
begin
|
|
Result := TdxPSCellTwistedBorderPainter;
|
|
end;
|
|
|
|
{ TdxPSCellEtchedBorder }
|
|
|
|
class function TdxPSCellEtchedBorder.BottomRightInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNHIGHLIGHT);
|
|
end;
|
|
|
|
class function TdxPSCellEtchedBorder.BottomRightInnerColor: TColor;
|
|
begin
|
|
Result := clBtnHighLight;
|
|
end;
|
|
|
|
class function TdxPSCellEtchedBorder.BottomRightOuterBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_WINDOWTEXT);
|
|
end;
|
|
|
|
class function TdxPSCellEtchedBorder.BottomRightOuterColor: TColor;
|
|
begin
|
|
Result := clWindowText;
|
|
end;
|
|
|
|
class function TdxPSCellEtchedBorder.TopLeftInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNHIGHLIGHT);
|
|
end;
|
|
|
|
class function TdxPSCellEtchedBorder.TopLeftInnerColor: TColor;
|
|
begin
|
|
Result := clBtnHighLight;
|
|
end;
|
|
|
|
class function TdxPSCellEtchedBorder.TopLeftOuterBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_WINDOWTEXT);
|
|
end;
|
|
|
|
class function TdxPSCellEtchedBorder.TopLeftOuterColor: TColor;
|
|
begin
|
|
Result := clWindowText;
|
|
end;
|
|
|
|
{ TdxPSCellBumpedBorder }
|
|
|
|
class function TdxPSCellBumpedBorder.BottomRightInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_WINDOWTEXT);
|
|
end;
|
|
|
|
class function TdxPSCellBumpedBorder.BottomRightInnerColor: TColor;
|
|
begin
|
|
Result := clWindowText;
|
|
end;
|
|
|
|
class function TdxPSCellBumpedBorder.BottomRightOuterBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNHIGHLIGHT);
|
|
end;
|
|
|
|
class function TdxPSCellBumpedBorder.BottomRightOuterColor: TColor;
|
|
begin
|
|
Result := clBtnHighLight;
|
|
end;
|
|
|
|
class function TdxPSCellBumpedBorder.TopLeftInnerBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_WINDOWTEXT);
|
|
end;
|
|
|
|
class function TdxPSCellBumpedBorder.TopLeftInnerColor: TColor;
|
|
begin
|
|
Result := clWindowText;
|
|
end;
|
|
|
|
class function TdxPSCellBumpedBorder.TopLeftOuterBrush: HBRUSH;
|
|
begin
|
|
Result := GetSysColorBrush(COLOR_BTNHIGHLIGHT);
|
|
end;
|
|
|
|
class function TdxPSCellBumpedBorder.TopLeftOuterColor: TColor;
|
|
begin
|
|
Result := clBtnHighLight;
|
|
end;
|
|
|
|
{ TdxPSCellBorderPainter }
|
|
|
|
procedure TdxPSColorBorderPainter.Paint(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
Side: TdxCellSide;
|
|
BorderBounds: TRect;
|
|
begin
|
|
with Item do
|
|
begin
|
|
R := GetBorderOuterBounds(DC);
|
|
// SelectClipRgn(DC, 0);
|
|
if RectVisible(DC, R) then
|
|
begin
|
|
for Side := csBottom downto csLeft do
|
|
if Side in CellSides then
|
|
begin
|
|
BorderBounds := Self.GetBorderBounds(R, Side, Renderer.LineThickness);
|
|
Windows.FillRect(DC, BorderBounds,
|
|
Renderer.GetBrushByColor(SideColor[Side]));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSColorBorderPainter.GetSideColor(ASide: TdxCellSide): TColor;
|
|
begin
|
|
Result := FItem.FCellSideColors[ASide];
|
|
end;
|
|
|
|
{ TdxPSColorBorder }
|
|
|
|
class function TdxPSColorBorder.GetPainterClass: TdxPSCellBorderPainterClass;
|
|
begin
|
|
Result := TdxPSColorBorderPainter;
|
|
end;
|
|
|
|
{ TdxPSBackgroundBitmapPool }
|
|
|
|
constructor TdxPSBackgroundBitmapPool.Create;
|
|
begin
|
|
inherited Create;
|
|
FItems := TList.Create;
|
|
end;
|
|
|
|
destructor TdxPSBackgroundBitmapPool.Destroy;
|
|
begin
|
|
Clear;
|
|
FreeAndNil(FItems);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxPSBackgroundBitmapPool.Assign(Source: TdxPSBackgroundBitmapPool);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Clear;
|
|
for I := 0 to Source.Count - 1 do
|
|
Add(Source.Items[I]);
|
|
end;
|
|
|
|
function TdxPSBackgroundBitmapPool.Add(ABitmap: TBitmap): Integer;
|
|
begin
|
|
if not Find(ABitmap, Result) then Result := FItems.Add(ABitmap);
|
|
end;
|
|
|
|
procedure TdxPSBackgroundBitmapPool.Clear;
|
|
begin
|
|
FItems.Clear;
|
|
end;
|
|
|
|
procedure TdxPSBackgroundBitmapPool.Delete(AnIndex: Integer);
|
|
begin
|
|
FItems.Delete(AnIndex);
|
|
end;
|
|
|
|
function TdxPSBackgroundBitmapPool.Find(ABitmap: TBitmap; out AnIndex: Integer): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AnIndex := -1;
|
|
for I := 0 to Count - 1 do
|
|
if dxPSUtl.dxAreGraphicsEqual(Items[I], ABitmap) then
|
|
begin
|
|
AnIndex := I;
|
|
Break;
|
|
end;
|
|
Result := AnIndex <> -1;
|
|
end;
|
|
|
|
procedure TdxPSBackgroundBitmapPool.ReadData(AReader: TdxPSDataReader);
|
|
var
|
|
Bitmap: TBitmap;
|
|
begin
|
|
AReader.ReadListBegin;
|
|
try
|
|
while not AReader.EndOfList do
|
|
begin
|
|
Bitmap := TBitmap.Create;
|
|
try
|
|
AReader.ReadImage(Bitmap);
|
|
Add(Bitmap);
|
|
except
|
|
Bitmap.Free;
|
|
raise;
|
|
end;
|
|
end;
|
|
finally
|
|
AReader.ReadListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSBackgroundBitmapPool.WriteData(AWriter: TdxPSDataWriter);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AWriter.WriteListBegin;
|
|
try
|
|
for I := 0 to Count - 1 do
|
|
AWriter.WriteImage(Items[I]);
|
|
finally
|
|
AWriter.WriteListEnd;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSBackgroundBitmapPool.GetCount: Integer;
|
|
begin
|
|
Result := FItems.Count;
|
|
end;
|
|
|
|
function TdxPSBackgroundBitmapPool.GetItem(Index: Integer): TBitmap;
|
|
begin
|
|
if Index <> -1 then
|
|
Result := TBitmap(FItems[Index])
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
{ TdxPSBrushPoolItem }
|
|
|
|
constructor TdxPSBrushPoolItem.Create(AColor: TColor);
|
|
begin
|
|
inherited Create;
|
|
FBrush := NULL_BRUSH;
|
|
FColor := ColorToRGB(AColor);
|
|
end;
|
|
|
|
destructor TdxPSBrushPoolItem.Destroy;
|
|
begin
|
|
if FBrush <> NULL_BRUSH then
|
|
begin
|
|
DeleteObject(FBrush);
|
|
FBrush := NULL_BRUSH;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
function TdxPSBrushPoolItem.GetBrush: HBRUSH;
|
|
begin
|
|
if FBrush = NULL_BRUSH then
|
|
FBrush := CreateSolidBrush(Color);
|
|
Result := FBrush;
|
|
end;
|
|
|
|
{ TdxPSReportBrushPool }
|
|
|
|
constructor TdxPSReportBrushPool.Create;
|
|
begin
|
|
inherited Create;
|
|
FItems := TList.Create;
|
|
end;
|
|
|
|
destructor TdxPSReportBrushPool.Destroy;
|
|
begin
|
|
Clear;
|
|
FreeAndNil(FItems);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSReportBrushPool.Clear;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
Items[I].Free;
|
|
FItems.Clear;
|
|
end;
|
|
|
|
function TdxPSReportBrushPool.IndexOf(AColor: TColor): Integer;
|
|
begin
|
|
AColor := ColorToRGB(AColor);
|
|
for Result := 0 to Count - 1 do
|
|
if Items[Result].Color = AColor then Exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
function TdxPSReportBrushPool.Add(AColor: TColor): Integer;
|
|
begin
|
|
Result := Count;
|
|
FItems.Add(TdxPSBrushPoolItem.Create(AColor));
|
|
end;
|
|
|
|
function TdxPSReportBrushPool.GetBrush(AColor: TColor): HBRUSH;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Index := IndexOf(AColor);
|
|
if Index = -1 then
|
|
Index := Add(AColor);
|
|
Result := Items[Index].Brush;
|
|
end;
|
|
|
|
function TdxPSReportBrushPool.GetCount: Integer;
|
|
begin
|
|
Result := FItems.Count;
|
|
end;
|
|
|
|
function TdxPSReportBrushPool.GetItem(Index: Integer): TdxPSBrushPoolItem;
|
|
begin
|
|
Result := TdxPSBrushPoolItem(FItems[Index]);
|
|
end;
|
|
|
|
{ TdxPSFontPoolItem }
|
|
|
|
constructor TdxPSFontPoolItem.Create(AFont: TFont);
|
|
begin
|
|
inherited Create;
|
|
FFont := TFont.Create;
|
|
Font := AFont;
|
|
OriginalSize := Font.Size;
|
|
end;
|
|
|
|
destructor TdxPSFontPoolItem.Destroy;
|
|
begin
|
|
FreeAndNil(FFont);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSFontPoolItem.SetFont(Value: TFont);
|
|
begin
|
|
Font.Assign(Value);
|
|
end;
|
|
|
|
{ TdxPSReportFontPool }
|
|
|
|
constructor TdxPSReportFontPool.Create;
|
|
begin
|
|
inherited Create;
|
|
FItems := TList.Create;
|
|
end;
|
|
|
|
destructor TdxPSReportFontPool.Destroy;
|
|
begin
|
|
Clear;
|
|
FreeAndNil(FItems);
|
|
inherited;
|
|
end;
|
|
|
|
function TdxPSReportFontPool.Add(AFont: TFont): Integer;
|
|
begin
|
|
Result := IndexOf(AFont);
|
|
if Result = -1 then
|
|
Result := CreateFont(AFont);
|
|
end;
|
|
|
|
procedure TdxPSReportFontPool.Clear;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
Items[I].Free;
|
|
FItems.Clear;
|
|
end;
|
|
|
|
function TdxPSReportFontPool.IndexOf(AFont: TFont): Integer;
|
|
begin
|
|
for Result := 0 to Count - 1 do
|
|
if dxAreFontsEqual(Fonts[Result], AFont) then Exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
function TdxPSReportFontPool.CreateFont(AFont: TFont): Integer;
|
|
var
|
|
Item: TdxPSFontPoolItem;
|
|
begin
|
|
Result := Count;
|
|
Item := TdxPSFontPoolItem.Create(AFont);
|
|
FItems.Add(Item);
|
|
Item.Font.OnChange := FontChanged;
|
|
end;
|
|
|
|
procedure TdxPSReportFontPool.FontChanged(Sender: TObject);
|
|
begin
|
|
if not FLocked then Add(TFont(Sender));
|
|
end;
|
|
|
|
procedure TdxPSReportFontPool.PrepareFonts(UPI: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
FLocked := True;
|
|
try
|
|
for I := 0 to Count - 1 do
|
|
with Items[I] do
|
|
Font.Height := -MulDiv(OriginalSize, UPI, PtPerInch);
|
|
finally
|
|
FLocked := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportFontPool.ReadData(AReader: TdxPSDataReader);
|
|
var
|
|
Font: TFont;
|
|
begin
|
|
Clear;
|
|
Font := TFont.Create;
|
|
try
|
|
AReader.ReadListBegin;
|
|
try
|
|
while not AReader.EndOfList do
|
|
begin
|
|
AReader.ReadFont(Font);
|
|
Font.Size := AReader.ReadInteger;
|
|
Add(Font);
|
|
end;
|
|
finally
|
|
AReader.ReadListEnd;
|
|
end;
|
|
finally
|
|
Font.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportFontPool.WriteData(AWriter: TdxPSDataWriter);
|
|
var
|
|
I: Integer;
|
|
Item: TdxPSFontPoolItem;
|
|
begin
|
|
AWriter.WriteListBegin;
|
|
try
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Item := Items[I];
|
|
AWriter.WriteFont(Item.Font);
|
|
AWriter.WriteInteger(Item.OriginalSize);
|
|
end;
|
|
finally
|
|
AWriter.WriteListEnd;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportFontPool.GetCount: Integer;
|
|
begin
|
|
Result := FItems.Count;
|
|
end;
|
|
|
|
function TdxPSReportFontPool.GetFont(Index: Integer): TFont;
|
|
begin
|
|
Result := Items[Index].Font;
|
|
end;
|
|
|
|
function TdxPSReportFontPool.GetItem(Index: Integer): TdxPSFontPoolItem;
|
|
begin
|
|
Result := TdxPSFontPoolItem(FItems[Index]);
|
|
end;
|
|
|
|
{ TdxPSCachedGraphicInfo }
|
|
|
|
constructor TdxPSCachedGraphicInfo.Create(ARenderer: TdxPSReportRenderer);
|
|
begin
|
|
Renderer := ARenderer;
|
|
end;
|
|
|
|
function TdxPSCachedGraphicInfo.Check(
|
|
ASourceGraphic: TGraphic; ABitmap: TBitmap; var APreparedGraphic: TGraphic): Boolean;
|
|
begin
|
|
Result := ASourceGraphic <> nil;
|
|
if Result then
|
|
begin
|
|
Result := (ASourceGraphic = SourceGraphic) and (UnitsPerInch = Renderer.UnitsPerInch) and
|
|
(UnitsPerPixel = Renderer.UnitsPerPixel) and (ZoomFactor = Renderer.ZoomFactor) and
|
|
(ABitmap.Width = ASourceGraphic.Width) and (ABitmap.Height = ASourceGraphic.Height);
|
|
if Result then
|
|
APreparedGraphic := PreparedGraphic
|
|
else
|
|
begin
|
|
PreparedGraphic := APreparedGraphic;
|
|
SourceGraphic := ASourceGraphic;
|
|
SaveModeInfo;
|
|
end;
|
|
APreparedGraphic := ABitmap;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSCachedGraphicInfo.SaveModeInfo;
|
|
begin
|
|
UnitsPerInch := Renderer.UnitsPerInch;
|
|
UnitsPerPixel := Renderer.UnitsPerPixel;
|
|
ZoomFactor := Renderer.ZoomFactor;
|
|
end;
|
|
|
|
{ TdxPSReportRenderer }
|
|
|
|
constructor TdxPSReportRenderer.Create(AReportLink: TBasedxReportLink);
|
|
|
|
function CreateBitmap: TBitmap;
|
|
begin
|
|
Result := TBitmap.Create;
|
|
with Result do
|
|
try
|
|
{ Delphi4 bug ? - we have to assign image sizes manually at the first time of creating one }
|
|
Height := 16;
|
|
Width := 16;
|
|
HandleType := bmDIB;
|
|
except
|
|
Result.Free;
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
function CreateFont(const AName: string; ASize: Integer): TFont;
|
|
begin
|
|
Result := TFont.Create;
|
|
Result.Name := AName;
|
|
Result.Size := ASize;
|
|
Result.Charset := DEFAULT_CHARSET;
|
|
dxPSUtl.SetFontAsNonAntialiased(Result);
|
|
end;
|
|
|
|
begin
|
|
inherited Create;
|
|
FCachedGraphicInfo := TdxPSCachedGraphicInfo.Create(Self);
|
|
FBorderPainters := TList.Create;
|
|
FBrushPool := TdxPSReportBrushPool.Create;
|
|
FReportLink := AReportLink;
|
|
FCheckBitmap := CreateBitmap;
|
|
FDrawBitmap := CreateBitmap;
|
|
FDrawMask := CreateBitmap;
|
|
FGroupLookAndFeelPainters := TList.Create;
|
|
FHFStrings := TStringList.Create;
|
|
FLineThickness := 1;
|
|
FMarlettFont10 := CreateFont('Marlett', 10);
|
|
FMarlettFont8 := CreateFont('Marlett', 8);
|
|
FSymbolFont := CreateFont('Symbol', 7);
|
|
FSaveFont := TFont.Create;
|
|
end;
|
|
|
|
destructor TdxPSReportRenderer.Destroy;
|
|
begin
|
|
FreeAndNil(FSaveFont);
|
|
FreeAndNil(FSymbolFont);
|
|
FreeAndNil(FMarlettFont10);
|
|
FreeAndNil(FMarlettFont8);
|
|
FreeAndNil(FHFStrings);
|
|
FreeAndNilReportGroupLookAndFeelPainters;
|
|
FreeAndNil(FDrawMask);
|
|
FreeAndNil(FDrawBitmap);
|
|
FreeAndNil(FCheckBitmap);
|
|
FreeAndNil(FBrushPool);
|
|
FreeAndNil(FCachedGraphicInfo);
|
|
FreeAndNilBorderPainters;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.CustomDrawReportItem(AnItem: TAbstractdxReportCellData): Boolean;
|
|
var
|
|
R: TRect;
|
|
ARgn: HRGN;
|
|
begin
|
|
Result := False;
|
|
R := AnItem.GetOuterBounds(DC);
|
|
ARgn := GetClipRgn;
|
|
Windows.IntersectClipRect(DC, R.Left, R.Top, R.Right, R.Bottom);
|
|
ReportLink.CustomDraw(AnItem, Canvas, R, AnItem.BoundsRect, Result);
|
|
RestoreClipRgn(ARgn);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.Get3DBorderBrushes(AnItem: TdxReportVisualItem;
|
|
var AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush: HBRUSH);
|
|
begin
|
|
dxPSCore.Get3DBorderBrushes(AnItem.Edge3DStyle, AnItem.Edge3DSoft,
|
|
AOuterTLBrush, AOuterBRBrush, AInnerTLBrush, AInnerBRBrush);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.Get3DBorderColors(AnItem: TdxReportVisualItem;
|
|
var AOuterTLColor, AOuterBRColor, AInnerTLColor, AInnerBRColor: TColor);
|
|
begin
|
|
dxPSCore.Get3DBorderColors(AnItem.Edge3DStyle, AnItem.Edge3DSoft,
|
|
AOuterTLColor, AOuterBRColor, AInnerTLColor, AInnerBRColor);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageTitleContent(const AText: string; ARect: TRect;
|
|
ATextAlignX: TdxTextAlignX; ATextAlignY: TdxTextAlignY; AColor: TColor; AFont: TFont;
|
|
ATransparent: Boolean);
|
|
const
|
|
cFormat: DWORD = DXTO_AUTOINDENTS or DXTO_EXPANDTABS or DXTO_PATTERNEDTEXT or DXTO_CHARBREAK;
|
|
var
|
|
PrevFontSize, UPI: Integer;
|
|
Rgn: HRGN;
|
|
Done: Boolean;
|
|
Format: DWORD;
|
|
begin
|
|
PrevFontSize := AFont.Size;
|
|
UPI := UnitsPerInch;
|
|
if not ReportLink.ReportTitle.AdjustOnReportScale then
|
|
UPI := MulDiv(UPI, 100, ReportLink.RealScaleFactor);
|
|
AFont.Size := MulDiv(PrevFontSize, UPI, Screen.PixelsPerInch); //PPI);
|
|
|
|
Rgn := IntersectClipRect(ARect);
|
|
try
|
|
Done := False;
|
|
if ReportLink.IsTitleCustomDrawn then
|
|
begin
|
|
PrepareCanvasForCustomDraw(AFont, AColor);
|
|
ReportLink.DoCustomDrawPageTitle(Canvas, ARect, ATextAlignX, ATextAlignY, AColor, AFont, Done);
|
|
SetBkMode(DC, Windows.TRANSPARENT);
|
|
end;
|
|
|
|
if not Done then
|
|
begin
|
|
if not ATransparent then
|
|
FillRect(DC, ARect, AColor);
|
|
Format := cFormat or MakeTextFormat(ATextAlignX, ATextAlignY, True, False, True, True, True);
|
|
DrawTextEx(DC, ARect, 0, 0, 0, AText, AFont, Format);
|
|
end;
|
|
|
|
if ReportLink.IsTitleCustomDrawn then UnprepareCanvasForCustomDraw;
|
|
finally
|
|
RestoreClipRgn(Rgn);
|
|
end;
|
|
AFont.Size := PrevFontSize;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.CalcTextHeight(DC: HDC; const AText: string;
|
|
AWordBreak: Boolean; AFont: TFont = nil; ABaseWidth: Integer = -1): Integer;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if ABaseWidth = -1 then ABaseWidth := 5;
|
|
R := MakeRect(0, 0, ABaseWidth, 5);
|
|
Result := CalcTextRect(DC, AText, R, AWordBreak, AFont);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.CalcTextLineCount(DC: HDC; const AText: string;
|
|
AFont: TFont = nil; ABaseWidth: Integer = -1): Integer;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if AText <> '' then
|
|
begin
|
|
if ABaseWidth = -1 then
|
|
ABaseWidth := 2 * dxTextSpace + 1;
|
|
R := MakeRect(0, 0, ABaseWidth, 5);
|
|
Result := dxTextOut(DC, AText, R, dxCalcFormat[True] or DXTO_CALCROWCOUNT, AFont, 0, 0, 0);
|
|
end
|
|
else
|
|
Result := 0
|
|
end;
|
|
|
|
function TdxPSReportRenderer.CalcTextPatternHeight(DC: HDC; AFont: TFont = nil): Integer;
|
|
begin
|
|
Result := CalcTextHeight(DC, 'Wg', False, AFont, -1);
|
|
end;
|
|
|
|
|
|
function TdxPSReportRenderer.CalcTextRect(DC: HDC; const AText: string;
|
|
var ARect: TRect; AWordBreak: Boolean; AFont: TFont = nil): Integer;
|
|
const
|
|
CalcFormats: array[Boolean] of UINT =
|
|
(DXTO_CALCROWCOUNT or DXTO_AUTOINDENTS or DXTO_CHARBREAK or DXTO_SINGLELINE,
|
|
DXTO_CALCROWCOUNT or DXTO_AUTOINDENTS or DXTO_EXPANDTABS or DXTO_CHARBREAK or DXTO_WORDBREAK);
|
|
begin
|
|
Result := CalcTextRect(DC, AText, ARect, CalcFormats[AWordBreak], AFont);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.CalcTextRect(DC: HDC; const AText: string;
|
|
var ARect: TRect; AFormat: DWORD; AFont: TFont = nil): Integer;
|
|
var
|
|
ATextParams: TdxTextParams;
|
|
ATextRows: TdxTextRows;
|
|
AFontHandle: HFont;
|
|
begin
|
|
if (AText <> '') and (AText[1] <> #0) then
|
|
begin
|
|
if AFont <> nil then
|
|
AFontHandle := SelectObject(DC, AFont.Handle)
|
|
else
|
|
AFontHandle := 0;
|
|
ARect.Bottom := MaxInt;
|
|
InflateRect(ARect, -dxTextSpace * LineThickness, 0);
|
|
ATextParams := dxCalcTextParams(DC, AFormat);
|
|
ATextRows := dxMakeTextRows(DC, AText, ARect, ATextParams);
|
|
ARect.Bottom := ARect.Top + ATextRows.Count * ATextParams.FullRowHeight +
|
|
3 * LineThickness * dxTextSpace;
|
|
ATextRows.Free;
|
|
if AFontHandle <> 0 then
|
|
SelectObject(DC, AFontHandle);
|
|
Result := ARect.Bottom - ARect.Top;
|
|
end
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
|
|
(*
|
|
// todo: old version
|
|
function TdxPSReportRenderer.CalcTextRect(DC: HDC; const AText: string;
|
|
var ARect: TRect; AFormat: DWORD; AFont: TFont = nil): Integer;
|
|
begin
|
|
if AText <> '' then
|
|
begin
|
|
dxTextOut(DC, AText, ARect, AFormat or DXTO_CALCRECT, AFont, 0, 0, 0);
|
|
Result := ARect.Bottom - ARect.Top;
|
|
end
|
|
else
|
|
Result := 0;
|
|
end;
|
|
*)
|
|
|
|
function TdxPSReportRenderer.CalcTextWidth(DC: HDC; const AText: string;
|
|
AFont: TFont = nil): Integer;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := MakeRect(0, 0, 5 * LineThickness, 5 * LineThickness);
|
|
dxTextOut(DC, AText, R, dxCalcFormat[False], AFont, 0, 0, 0);
|
|
Result := R.Right - R.Left;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawCheckBox(DC: HDC; var R: TRect;
|
|
AChecked, AEnabled, AIsRadio: Boolean; AEdgeStyle: TdxCheckButtonEdgeStyle;
|
|
ABorderColor: TColor = clWindowText);
|
|
const
|
|
Enabled: array[Boolean] of UINT = (DFCS_BUTTON3STATE or DFCS_INACTIVE, 0);
|
|
Checked: array[Boolean] of UINT = (0, DFCS_CHECKED);
|
|
//FlatBorder: array[Boolean] of UINT = (0, DFCS_FLAT);
|
|
Radio: array[Boolean] of UINT = (0, DFCS_BUTTONRADIO);
|
|
InteriorIndexes: array[Boolean] of UINT = (CheckInteriorIndex, RadioInteriorIndex);
|
|
MarkIndexes: array[Boolean] of UINT = (CheckMarkIndex, RadioBeanIndex);
|
|
TopLeftArcInnerIndexes: array[Boolean] of UINT = (CheckTopLeftArcInnerIndex, RadioTopLeftArcInnerIndex);
|
|
BottomRightArcInnerIndexes: array[Boolean] of UINT = (CheckBottomRightArcInnerIndex, RadioBottomRightArcInnerIndex);
|
|
TopLeftArcOuterIndexes: array[Boolean] of UINT = (CheckTopLeftArcOuterIndex, RadioTopLeftArcOuterIndex);
|
|
BottomRightArcOuterIndexes: array[Boolean] of UINT = (CheckBottomRightArcOuterIndex, RadioBottomRightArcOuterIndex);
|
|
var
|
|
F: HFONT;
|
|
C: TColor;
|
|
begin
|
|
if AEdgeStyle <> cbes3D then
|
|
begin
|
|
// todo: commented for AB9777
|
|
// if AIsRadio then OffsetRect(R, 0, LineThickness);
|
|
|
|
F := SelectObject(DC, MarlettFont10.Handle);
|
|
C := GetTextColor(DC);
|
|
|
|
if AEnabled then
|
|
SetTextColor(DC, ColorToRGB(clWindow))
|
|
else
|
|
SetTextColor(DC, ColorToRGB(clBtnFace));
|
|
dxPSUtl.DrawGlyph(DC, R, InteriorIndexes[AIsRadio]);
|
|
//actually it's a mask, that means we should paint by halftone brush over here
|
|
|
|
if AChecked then
|
|
begin
|
|
SetTextColor(DC, ColorToRGB(clWindowText));
|
|
dxPSUtl.DrawGlyph(DC, R, MarkIndexes[AIsRadio]);
|
|
end;
|
|
|
|
if AEdgeStyle <> cbesNone then
|
|
begin
|
|
case AEdgeStyle of
|
|
cbesSoft3D:
|
|
SetTextColor(DC, ColorToRGB(clBtnFace));
|
|
cbesSingle,
|
|
cbesBoldFlat:
|
|
SetTextColor(DC, ColorToRGB(ABorderColor));
|
|
cbesUltraFlat:
|
|
SetTextColor(DC, ColorToRGB(clWindowText));
|
|
end;
|
|
|
|
dxPSUtl.DrawGlyph(DC, R, TopLeftArcInnerIndexes[AIsRadio]);
|
|
dxPSUtl.DrawGlyph(DC, R, BottomRightArcInnerIndexes[AIsRadio]);
|
|
|
|
if AEdgeStyle in [cbesSoft3D, cbesBoldFlat] then
|
|
begin
|
|
if AEdgeStyle = cbesSoft3D then
|
|
SetTextColor(DC, ColorToRGB(clBtnShadow));
|
|
dxPSUtl.DrawGlyph(DC, R, TopLeftArcOuterIndexes[AIsRadio]);
|
|
if AEdgeStyle = cbesSoft3D then
|
|
SetTextColor(DC, ColorToRGB(clBtnHighlight));
|
|
dxPSUtl.DrawGlyph(DC, R, BottomRightArcOuterIndexes[AIsRadio]);
|
|
end;
|
|
|
|
SelectObject(DC, F);
|
|
SetTextColor(DC, C);
|
|
end;
|
|
end
|
|
else
|
|
DrawFrameControl(DC, R, DFC_BUTTON, DFCS_TRANSPARENT or Radio[AIsRadio] or Enabled[AEnabled] or Checked[AChecked]);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawEdge(DC: HDC; var R: TRect; AEdgeMode: TdxCellEdgeMode;
|
|
AEdge3DEdge: TdxCellEdgeStyle; ASides: TdxCellSides; ASoft: Boolean; ABorderColor: TColor = -1);
|
|
var
|
|
Brush: HBRUSH;
|
|
CellBorders: TdxPSCell3DBorderClass;
|
|
begin
|
|
case AEdgeMode of
|
|
cemPattern:
|
|
begin
|
|
if ABorderColor = -1 then ABorderColor := RenderInfo.GridLinesColor;
|
|
Brush := GetBrushByColor(ABorderColor);
|
|
TdxPSCellBorderPainter.DrawFrame(DC, R, ASides, Brush, Brush, LineThickness);
|
|
end;
|
|
cem3DEffects:
|
|
begin
|
|
CellBorders := TdxPSCell3DBorderClass(TdxReportVisualItem.MapBorderClass(AEdgeMode, AEdge3DEdge, ASoft));
|
|
TdxPSCell3DBorderPainter.Draw3DFrame(DC, R, ASides, CellBorders, LineThickness);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawEllipse(DC: HDC; R: TRect;
|
|
AForeColor, ABackColor: TColor; APattern: TdxPSFillPatternClass;
|
|
ABorderColor: TColor; ABorderThickness: Integer = 1);
|
|
begin
|
|
FrameEllipse(DC, R, ABorderColor, ABorderThickness);
|
|
InflateRect(R, -ABorderThickness * LineThickness, -ABorderThickness * LineThickness);
|
|
FillEllipseEx(DC, R, AForeColor, ABackColor, APattern);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawExpandButton(DC: HDC; var R: TRect;
|
|
AExpanded, ADrawBorder, AEdge3D, AEdge3DSoft, AShadow, AFillInterior: Boolean;
|
|
ABorderColor, AInteriorColor: TColor);
|
|
|
|
procedure DrawGlyph(DC: HDC; const R: TRect; AGlyph: Byte);
|
|
var
|
|
Ch: Char;
|
|
Size: TSize;
|
|
X, Y: Integer;
|
|
begin
|
|
Ch := Chr(AGlyph);
|
|
GetTextExtentPoint32(DC, @Ch, 1, Size);
|
|
with R do
|
|
begin
|
|
X := Left + (Right - Left - Size.cX) div 2;
|
|
Y := Top + (Bottom - Top - Size.cY) div 2;
|
|
end;
|
|
ExtTextOut(DC, X, Y, 0, @R, @Ch, 1, nil);
|
|
end;
|
|
|
|
const
|
|
InnerBottomRight3DColors: array[Boolean] of TColor = (clBtnShadow, clBtnFace);
|
|
OuterFlatColors: array[Boolean] of TColor = (clWindowText, clBtnShadow);
|
|
CrossHireIndexes: array[Boolean] of Byte = (dxPSUtl.PlusSignIndex, dxPSUtl.MinusSignIndex);
|
|
var
|
|
F: HFONT;
|
|
C: TColor;
|
|
begin
|
|
SetBkMode(DC, TRANSPARENT);
|
|
F := GetCurrentObject(DC, OBJ_FONT);
|
|
C := GetTextColor(DC);
|
|
|
|
SelectObject(DC, MarlettFont8.Handle);
|
|
if ADrawBorder then
|
|
begin
|
|
if AEdge3D then
|
|
begin
|
|
SetTextColor(DC, ColorToRGB(ABorderColor));
|
|
DrawGlyph(DC, R, dxPSUtl.CheckTopLeftArcOuterIndex);
|
|
DrawGlyph(DC, R, dxPSUtl.CheckBottomRightArcOuterIndex);
|
|
end;
|
|
|
|
if AFillInterior then
|
|
begin
|
|
SetTextColor(DC, ColorToRGB(AInteriorColor));
|
|
DrawGlyph(DC, R, dxPSUtl.CheckInteriorIndex);
|
|
end;
|
|
|
|
if not AEdge3D then
|
|
begin
|
|
SetTextColor(DC, ColorToRGB(ABorderColor));//OuterFlatColors[AEdge3DSoft]));
|
|
DrawGlyph(DC, R, dxPSUtl.CheckTopLeftArcInnerIndex);
|
|
DrawGlyph(DC, R, dxPSUtl.CheckBottomRightArcInnerIndex);
|
|
if AShadow then
|
|
begin
|
|
OffsetRect(R, LineThickness, LineThickness);
|
|
SetTextColor(DC, ColorToRGB(clBtnShadow));
|
|
DrawGlyph(DC, R, dxPSUtl.CheckBottomRightArcInnerIndex);
|
|
OffsetRect(R, -LineThickness, -LineThickness);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
SetTextColor(DC, ColorToRGB(clBtnHighlight));
|
|
DrawGlyph(DC, R, dxPSUtl.CheckTopLeftArcInnerIndex);
|
|
SetTextColor(DC, ColorToRGB(InnerBottomRight3DColors[AEdge3DSoft]));
|
|
DrawGlyph(DC, R, dxPSUtl.CheckBottomRightArcInnerIndex);
|
|
end;
|
|
end;
|
|
|
|
// cross-hire
|
|
SelectObject(DC, SymbolFont.Handle);
|
|
SetTextColor(DC, ColorToRGB(clWindowText));
|
|
OffsetRect(R, 0, -LineThickness);
|
|
DrawGlyph(DC, R, CrossHireIndexes[AExpanded]);
|
|
|
|
SetTextColor(DC, C);
|
|
SelectObject(DC, F);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawGlyph(DC: HDC; const R: TRect; AGlyph: Byte);
|
|
begin
|
|
dxPSUtl.DrawGlyph(DC, R, AGlyph);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawGraphic(DC: HDC; var R: TRect; const AClipRect: TRect;
|
|
AImageList: TCustomImageList; AImageIndex: Integer; AGraphic: TGraphic;
|
|
AGraphicTransparent, ATransparent: Boolean; AColor: TColor);
|
|
begin
|
|
DrawGraphicEx(DC, R, AClipRect, AImageList, AImageIndex, AGraphic,
|
|
AGraphicTransparent, ATransparent, AColor, clWindow, TdxPSSolidFillPattern, cibAlways);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawGraphicEx(DC: HDC; R: TRect; const AClipRect: TRect;
|
|
AImageList: TCustomImageList; AImageIndex: Integer; AGraphic: TGraphic;
|
|
AGraphicTransparent, ATransparent: Boolean; AColor, ABkColor: TColor;
|
|
APattern: TdxPSFillPatternClass; AnActualImageBuffering: TdxCellImageActualBuffering = cibAlways);
|
|
|
|
procedure GetImage(ABitmap: TBitmap; AImageList: TCustomImageList;
|
|
AImageIndex: Integer; AType: TImageType);
|
|
|
|
{$IFNDEF DELPHI6}
|
|
function GetColor(Value: TColor): DWORD;
|
|
begin
|
|
Result := ColorToRGB(Value);
|
|
case Result of
|
|
clNone: Result := CLR_NONE;
|
|
clDefault: Result := CLR_DEFAULT;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFNDEF DELPHI6}
|
|
const
|
|
DrawingStyles: array[TDrawingStyle] of Longint =
|
|
(ILD_FOCUS, ILD_SELECTED, ILD_NORMAL, ILD_TRANSPARENT);
|
|
Images: array[TImageType] of Longint = (0, ILD_MASK);
|
|
{$ENDIF}
|
|
begin
|
|
ABitmap.Handle := 0;
|
|
ABitmap.Height := AImageList.Height;
|
|
ABitmap.Width := AImageList.Width;
|
|
ABitmap.Transparent := True;
|
|
{$IFNDEF DELPHI6}
|
|
with AImageList do
|
|
if HandleAllocated then
|
|
ImageList_DrawEx(Handle, AImageIndex, ABitmap.Canvas.Handle, 0, 0, 0, 0,
|
|
GetColor(BkColor), GetColor(BlendColor),
|
|
DrawingStyles[DrawingStyle] or Images[ImageType]);
|
|
{$ELSE}
|
|
AImageList.Draw(ABitmap.Canvas, 0, 0, AImageIndex, dsNormal, AType);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
var
|
|
Tmp: TBitmap;
|
|
G: TGraphic;
|
|
Rgn, Rgn2, RestRgn: HRGN;
|
|
SaveTransparent: Boolean;
|
|
begin
|
|
Rgn := 0;
|
|
if (R.Right - R.Left > AClipRect.Right - AClipRect.Left) or
|
|
(R.Bottom - R.Top > AClipRect.Bottom - AClipRect.Top) then
|
|
Rgn := IntersectClipRect(AClipRect);
|
|
|
|
if not ATransparent then
|
|
if not AGraphicTransparent then
|
|
begin
|
|
RestRgn := CreateRectRgnIndirect(AClipRect);
|
|
Rgn2 := CreateRectRgnIndirect(R);
|
|
if CombineRgn(RestRgn, RestRgn, Rgn2, RGN_DIFF) > NULLREGION then
|
|
FillRgnEx(DC, RestRgn, AColor, ABkColor, APattern);
|
|
DeleteObject(Rgn2);
|
|
DeleteObject(RestRgn);
|
|
end
|
|
else
|
|
FillRectEx(DC, AClipRect, AColor, ABkColor, APattern);
|
|
|
|
if AnActualImageBuffering = cibAlways then {v3.2}
|
|
//if ReportLink.AlwaysBufferedGraphics then
|
|
begin
|
|
if AImageList <> nil then
|
|
begin
|
|
GetImage(FDrawBitmap, AImageList, AImageIndex, itImage);
|
|
{!!!} FDrawBitmap.HandleType := bmDIB;
|
|
GetImage(FDrawMask, AImageList, AImageIndex, itMask);
|
|
{!!!} FDrawMask.HandleType := bmDIB;
|
|
FDrawBitmap.MaskHandle := FDrawMask.Handle;
|
|
end
|
|
else
|
|
begin
|
|
if not CachedGraphicInfo.Check(AGraphic, FDrawBitmap, G) then
|
|
with FDrawBitmap do
|
|
begin
|
|
Handle := 0;
|
|
Width := AGraphic.Width;
|
|
Height := AGraphic.Height;
|
|
HandleType := bmDIB;
|
|
//if AGraphic is TBitmap then
|
|
// MaskHandle := TBitmap(AGraphic).MaskHandle;
|
|
Canvas.Draw(0, 0, AGraphic);
|
|
end;
|
|
end;
|
|
G := FDrawBitmap;
|
|
end
|
|
else
|
|
G := AGraphic;
|
|
|
|
if (G <> nil) and not G.Empty then
|
|
begin
|
|
SaveTransparent := G.Transparent;
|
|
G.Transparent := (not IsPrinting or not FDontPrintTransparentImages) and
|
|
AGraphicTransparent and not (G is TIcon);
|
|
|
|
if not IsRectEmpty(R) then
|
|
begin
|
|
if IsPrinting and (AImageList <> nil) then
|
|
begin
|
|
Tmp := TBitmap.Create;
|
|
try
|
|
Tmp.HandleType := bmDIB; // !!!
|
|
Tmp.Width := FDrawBitmap.Width;
|
|
Tmp.Height := FDrawBitmap.Height;
|
|
StretchBlt(Tmp.Canvas.Handle, 0, 0, Tmp.Width, Tmp.Height, FCanvas.Handle,
|
|
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top, srcCopy);
|
|
AImageList.Draw(Tmp.Canvas, 0, 0, AImageIndex{$IFDEF DELPHI6}, dsTransparent, itImage{$ENDIF});
|
|
FCanvas.StretchDraw(R, Tmp);
|
|
finally
|
|
Tmp.Free;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if G is TBitmap then // save mask handle - delphi bug SC - DB19634
|
|
FDrawMask.Handle := TBitmap(G).MaskHandle;
|
|
FCanvas.StretchDraw(R, G{FDrawBitmap});
|
|
end;
|
|
end;
|
|
if AGraphicTransparent and not (G is TIcon) then
|
|
G.Transparent := SaveTransparent;
|
|
end;
|
|
|
|
if Rgn <> 0 then RestoreClipRgn(Rgn);
|
|
FDrawMask.Handle := 0;
|
|
FDrawBitmap.MaskHandle := 0;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawRectangle(DC: HDC; R: TRect;
|
|
AForeColor, ABackColor: TColor; AContentPattern: TdxPSFillPatternClass;
|
|
ABorderColor: TColor; ABorderThickness: Integer = 1);
|
|
begin
|
|
FrameRect(DC, R, ABorderColor, csAll, ABorderThickness);
|
|
InflateRect(R, -ABorderThickness * LineThickness, -ABorderThickness * LineThickness);
|
|
FillRectEx(DC, R, AForeColor, ABackColor, AContentPattern);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawRoundRect(DC: HDC; R: TRect;
|
|
AnEllipseWidth, AnEllipseHeight: Integer; AForeColor, ABackColor: TColor;
|
|
AContentPattern: TdxPSFillPatternClass; ABorderColor: TColor;
|
|
ABorderThickness: Integer = 1);
|
|
begin
|
|
FrameRoundRect(DC, R, AnEllipseWidth, AnEllipseHeight, ABorderColor, ABorderThickness);
|
|
|
|
AnEllipseHeight :=
|
|
MulDiv(AnEllipseHeight, R.Bottom - R.Top - 2 * ABorderThickness * LineThickness, R.Bottom - R.Top);
|
|
AnEllipseWidth :=
|
|
MulDiv(AnEllipseWidth, R.Right - R.Left - 2 * ABorderThickness * LineThickness, R.Right - R.Left);
|
|
InflateRect(R, -ABorderThickness * LineThickness, -ABorderThickness * LineThickness);
|
|
|
|
FillRoundRectEx(DC, R, AnEllipseWidth, AnEllipseHeight, AForeColor, ABackColor, AContentPattern);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawSortMark(DC: HDC; var R: TRect;
|
|
ASortOrder: TdxCellSortOrder; AMono: Boolean);
|
|
const
|
|
GlyphIndexes: array[TdxCellSortOrder] of Byte = (0, SortUpMarkIndex, SortDownMarkIndex);
|
|
var
|
|
F: HFONT;
|
|
C: TColor;
|
|
Ch: Char;
|
|
Size: TSize;
|
|
begin
|
|
if ASortOrder <> csoNone then
|
|
begin
|
|
F := SelectObject(DC, MarlettFont10.Handle);
|
|
C := SetTextColor(DC, ColorTORGB(clWindowText));
|
|
Ch := Chr(GlyphIndexes[ASortOrder]);
|
|
GetTextExtentPoint32(DC, @Ch, 1, Size);
|
|
with R do
|
|
R := Bounds(Left + (Right - Left - Size.cX) div 2, Top + (Bottom - Top - Size.cY) div 2, Size.cX, Size.cY);
|
|
dxPSUtl.DrawGlyph(DC, R, GlyphIndexes[ASortOrder]);
|
|
SelectObject(DC, F);
|
|
SetTextColor(DC, C);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawText(DC: HDC; var R: TRect; AMaxLineCount: Integer;
|
|
ALeftIndent, ARightIndent: Integer; const AText: string; AFont: TFont;
|
|
ABkColor: TColor; ATextAlignX: TdxTextAlignX; ATextAlignY: TdxTextAlignY;
|
|
AFillBackground, AMultiline, AEndEllipsis: Boolean; APreventLeftTextExceed: Boolean = True;
|
|
APreventTopTextExceed: Boolean = True; AHidePrefix: Boolean = True);
|
|
var
|
|
Format: DWORD;
|
|
begin
|
|
if AFillBackground then FillRect(DC, R, ABkColor);
|
|
Format := DXTO_AUTOINDENTS or DXTO_EXPANDTABS or DXTO_PATTERNEDTEXT or DXTO_CHARBREAK or
|
|
MakeTextFormat(ATextAlignX, ATextAlignY, AMultiline, AEndEllipsis,
|
|
APreventLeftTextExceed, APreventTopTextExceed, AHidePrefix);
|
|
|
|
DrawTextEx(DC, R, AMaxLineCount, ALeftIndent, ARightIndent, AText, AFont, Format);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.DrawTextEx(DC: HDC; var R: TRect; AMaxLineCount: Integer;
|
|
ALeftIndent, ARightIndent: Integer; const AText: string; AFont: TFont; AFormat: DWORD);
|
|
begin
|
|
dxTextOut(DC, AText, R, AFormat, AFont, AMaxLineCount,
|
|
MulDiv(ALeftIndent, PPI, 96), MulDiv(ARightIndent, PPI, 96));
|
|
end;
|
|
|
|
function TdxPSReportRenderer.MakeTextFormat(ATextAlignX: TdxTextAlignX;
|
|
ATextAlignY: TdxTextAlignY; AMultiline, AEndEllipsis, APreventLeftTextExceed,
|
|
APreventTopTextExceed, AHidePrefix: Boolean): DWORD;
|
|
const
|
|
dxEndEllipsis: array[Boolean] of UINT = (0, DXTO_END_ELLIPSIS);
|
|
dxHidePrefix: array[Boolean] of UINT = (0, DXTO_HIDEPREFIX);
|
|
dxPreventLeftExceed: array[Boolean] of UINT = (0, DXTO_PREVENT_LEFT_EXCEED);
|
|
dxPreventTopExceed: array[Boolean] of UINT = (0, DXTO_PREVENT_TOP_EXCEED);
|
|
dxWordBreak: array[Boolean] of UINT = (DXTO_SINGLELINE, DXTO_WORDBREAK);
|
|
begin
|
|
Result := dxMakeFormat(ATextAlignX, ATextAlignY) or
|
|
dxEndEllipsis[AEndEllipsis] or
|
|
dxHidePrefix[AHidePrefix] or
|
|
dxPreventLeftExceed[APreventLeftTextExceed] or
|
|
dxPreventTopExceed[APreventTopTextExceed] or
|
|
dxWordBreak[AMultiline];
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FillEllipse(DC: HDC; const R: TRect; AColor: TColor);
|
|
begin
|
|
FillEllipseEx(DC, R, AColor, clWhite, TdxPSSolidFillPattern);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FillEllipseEx(DC: HDC; const R: TRect;
|
|
AForeColor, ABackColor: TColor; APattern: TdxPSFillPatternClass);
|
|
var
|
|
Pen: HPEN;
|
|
Rgn: HRGN;
|
|
begin
|
|
Pen := SelectObject(DC, GetStockObject(NULL_PEN));
|
|
Rgn := CreateEllipticRgnIndirect(R);
|
|
FillRgnEx(DC, Rgn, AForeColor, ABackColor, APattern);
|
|
DeleteObject(Rgn);
|
|
SelectObject(DC, Pen);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FillRect(DC: HDC; const R: TRect; AColor: TColor);
|
|
begin
|
|
FillRectEx(DC, R, AColor, clWhite, TdxPSSolidFillPattern);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FillRectEx(DC: HDC; const R: TRect; AForeColor, ABackColor: TColor;
|
|
APattern: TdxPSFillPatternClass);
|
|
var
|
|
BrushOrg: TPoint;
|
|
begin
|
|
if APattern = nil then Exit;
|
|
|
|
GetBrushOrgEx(DC, BrushOrg);
|
|
if APattern.RequiredBrushOrigin then
|
|
begin
|
|
BrushOrg := R.TopLeft;
|
|
Windows.LPToDP(DC, BrushOrg, 1);
|
|
SetBrushOrgEx(DC, BrushOrg.X mod APattern.Dimensions.cX, BrushOrg.Y mod APattern.Dimensions.cY, @BrushOrg);
|
|
end;
|
|
|
|
if not APattern.Solid then
|
|
begin
|
|
ABackColor := SetBkColor(DC, ColorToRGB(ABackColor));
|
|
AForeColor := SetTextColor(DC, ColorToRGB(AForeColor));
|
|
end;
|
|
|
|
Windows.FillRect(DC, R, GetPatternBrush(APattern, ColorToRGB(AForeColor)));
|
|
|
|
if not APattern.Solid then
|
|
begin
|
|
SetBkColor(DC, ABackColor);
|
|
SetTextColor(DC, AForeColor);
|
|
end;
|
|
|
|
if APattern.RequiredBrushOrigin then
|
|
SetBrushOrgEx(DC, BrushOrg.X, BrushOrg.Y, nil);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FillRoundRect(DC: HDC; const R: TRect;
|
|
AnEllipseWidth, AnEllipseHeight: Integer; AColor: TColor);
|
|
begin
|
|
FillRoundRectEx(DC, R, AnEllipseWidth, AnEllipseHeight, AColor, clWhite, TdxPSSolidFillPattern);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FillRoundRectEx(DC: HDC; const R: TRect;
|
|
AnEllipseWidth, AnEllipseHeight: Integer; AForeColor, ABackColor: TColor;
|
|
APattern: TdxPSFillPatternClass);
|
|
var
|
|
Pen: HPEN;
|
|
Rgn: HRGN;
|
|
begin
|
|
Pen := SelectObject(DC, GetStockObject(NULL_PEN));
|
|
with R do
|
|
Rgn := CreateRoundRectRgn(Left, Top, Right, Bottom, AnEllipseWidth, AnEllipseHeight);
|
|
FillRgnEx(DC, Rgn, AForeColor, ABackColor, APattern);
|
|
DeleteObject(Rgn);
|
|
SelectObject(DC, Pen);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FillRgn(DC: HDC; Rgn: HRGN; AColor: TColor);
|
|
begin
|
|
FillRgnEx(DC, Rgn, AColor, clWhite, TdxPSSolidFillPattern);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FillRgnEx(DC: HDC; Rgn: HRGN; AForeColor, ABackColor: TColor;
|
|
APattern: TdxPSFillPatternClass);
|
|
var
|
|
BrushOrg: TPoint;
|
|
R: TRect;
|
|
begin
|
|
if APattern = nil then Exit;
|
|
|
|
GetBrushOrgEx(DC, BrushOrg);
|
|
if APattern.RequiredBrushOrigin and (GetRgnBox(Rgn, R) <> NULLREGION) then
|
|
begin
|
|
BrushOrg := R.TopLeft;
|
|
Windows.LPToDP(DC, BrushOrg, 1);
|
|
SetBrushOrgEx(DC, BrushOrg.X mod APattern.Dimensions.cX, BrushOrg.Y mod APattern.Dimensions.cY, @BrushOrg);
|
|
end;
|
|
|
|
if not APattern.Solid then
|
|
begin
|
|
AForeColor := SetTextColor(DC, ColorToRGB(AForeColor));
|
|
ABackColor := SetBkColor(DC, ColorToRGB(ABackColor));
|
|
end;
|
|
|
|
Windows.FillRgn(DC, Rgn, GetPatternBrush(APattern, AForeColor));
|
|
|
|
if not APattern.Solid then
|
|
begin
|
|
SetBkColor(DC, ABackColor);
|
|
SetTextColor(DC, AForeColor);
|
|
end;
|
|
|
|
if APattern.RequiredBrushOrigin then
|
|
SetBrushOrgEx(DC, BrushOrg.X, BrushOrg.Y, nil);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FrameEllipse(DC: HDC; R: TRect; AColor: TColor;
|
|
AThickness: Integer = 1);
|
|
var
|
|
OuterRgn, InnerRgn: HRGN;
|
|
begin
|
|
OuterRgn := CreateEllipticRgnIndirect(R);
|
|
InflateRect(R, -AThickness * LineThickness, -AThickness * LineThickness);
|
|
InnerRgn := CreateEllipticRgnIndirect(R);
|
|
CombineRgn(OuterRgn, OuterRgn, InnerRgn, RGN_DIFF);
|
|
FillRgn(DC, OuterRgn, AColor);
|
|
DeleteObject(InnerRgn);
|
|
DeleteObject(OuterRgn);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FrameRect(DC: HDC; R: TRect; AColor: TColor;
|
|
ASides: TdxCellSides = [csLeft..csBottom]; AThickness: Integer = 1);
|
|
var
|
|
Brush: HBRUSH;
|
|
I: Integer;
|
|
begin
|
|
Brush := SelectObject(DC, GetPatternBrush(TdxPSSolidFillPattern, AColor));
|
|
AColor := SetTextColor(DC, ColorToRGB(AColor));
|
|
for I := 0 to AThickness - 1 do
|
|
begin
|
|
with R do
|
|
begin
|
|
if csLeft in ASides then
|
|
PatBlt(DC, Left, Top, LineThickness, Bottom - Top, PATCOPY);
|
|
if csTop in ASides then
|
|
PatBlt(DC, Left, Top, Right - Left, LineThickness, PATCOPY);
|
|
if csRight in ASides then
|
|
PatBlt(DC, Right - LineThickness, Top, LineThickness, Bottom - Top, PATCOPY);
|
|
if csBottom in ASides then
|
|
PatBlt(DC, Left, Bottom - LineThickness, Right - Left, LineThickness, PATCOPY);
|
|
|
|
end;
|
|
InflateRect(R, -LineThickness, -LineThickness);
|
|
end;
|
|
SetTextColor(DC, AColor);
|
|
SelectObject(DC, Brush);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FrameRoundRect(DC: HDC; R: TRect;
|
|
AnEllipseWidth, AnEllipseHeight: Integer; AColor: TColor;
|
|
AThickness: Integer = 1);
|
|
var
|
|
OuterRgn, InnerRgn: HRGN;
|
|
begin
|
|
with R do
|
|
OuterRgn := CreateRoundRectRgn(Left, Top, Right, Bottom, AnEllipseWidth, AnEllipseHeight);
|
|
AnEllipseHeight := MulDiv(AnEllipseHeight, R.Bottom - R.Top - 2 * AThickness * LineThickness, R.Bottom - R.Top);
|
|
AnEllipseWidth := MulDiv(AnEllipseWidth, R.Right - R.Left - 2 * AThickness * LineThickness, R.Right - R.Left);
|
|
InflateRect(R, -AThickness * LineThickness, -AThickness * LineThickness);
|
|
with R do
|
|
InnerRgn := CreateRoundRectRgn(Left, Top, Right, Bottom, AnEllipseWidth, AnEllipseHeight);
|
|
CombineRgn(OuterRgn, OuterRgn, InnerRgn, RGN_DIFF);
|
|
FillRgn(DC, OuterRgn, AColor);
|
|
DeleteObject(InnerRgn);
|
|
DeleteObject(OuterRgn);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetBorderPainter(AClass: TdxPSCellBorderPainterClass): TdxPSCellBorderPainter;
|
|
begin
|
|
Result := FindBorderPainter(AClass);
|
|
if Result = nil then
|
|
Result := CreateBorderPainter(AClass);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetBrushByColor(AColor: TColor): HBRUSH;
|
|
begin
|
|
{if IsSysColor(AColor) then //TODO: GetSysColorBrush
|
|
Result := GetSysColorBrush(AColor)
|
|
else}
|
|
if (AColor = clNone) or (AColor = clDefault) then
|
|
Result := GetStockObject(NULL_BRUSH)
|
|
else
|
|
Result := BrushPool.Brushes[AColor];
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetPatternBrush(APattern: TdxPSFillPatternClass; AColor: TColor): HBRUSH;
|
|
begin
|
|
if APattern.Solid then
|
|
Result := BrushPool.Brushes[AColor]
|
|
else
|
|
Result := dxPSFillPatternFactory.Items[APattern, IsPrinting].Brush.Handle;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetReportGroupLookAndFeelPainter(AClass: TdxPSReportGroupLookAndFeelPainterClass): TdxPSReportGroupLookAndFeelPainter;
|
|
begin
|
|
Result := FindReportGroupLookAndFeelPainter(AClass);
|
|
if Result = nil then
|
|
Result := CreateReportGroupLookAndFeelPainter(AClass);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.ExcludeClipRect(const R: TRect): Integer;
|
|
begin
|
|
with R do
|
|
Result := Windows.ExcludeClipRect(DC, Left, Top, Right, Bottom);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetClipRgn: HRGN;
|
|
begin
|
|
Result := CreateRectRgn(0, 0, 0, 0);
|
|
if Windows.GetClipRgn(DC, Result) <> 1 then
|
|
begin
|
|
DeleteObject(Result);
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.IntersectClipRect(const R: TRect): HRGN;
|
|
begin
|
|
Result := dxPSUtl.IntersectClipRect(DC, R);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RestoreClipRgn(var Rgn: HRGN);
|
|
begin
|
|
dxPSUtl.RestoreClipRgn(DC, Rgn);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPage(ACanvas: TCanvas; const APageBounds: TRect;
|
|
APageIndex, AContinuousPageIndex, AZoomFactor: Integer);
|
|
var
|
|
VirtualPageIndex, RealPageIndex: Integer;
|
|
Composition: TdxCompositionReportLink;
|
|
begin
|
|
RenderInfo.CalculatePageRealAndVirtualIndexes(APageIndex, VirtualPageIndex, RealPageIndex);
|
|
|
|
if not RenderInfo.CanRenderPage(VirtualPageIndex) then Exit;
|
|
|
|
Composition := ReportLink.CurrentComposition;
|
|
if (Composition = nil) or not Composition.ContinuousPageIndexes then
|
|
AContinuousPageIndex := RealPageIndex
|
|
else
|
|
if Composition <> nil then
|
|
AContinuousPageIndex := Composition.VirtualPageIndexToRealPageIndex(AContinuousPageIndex);
|
|
|
|
dxHFFormatObject.CurrentPage := PreparedPageIndex(AContinuousPageIndex) + 1;
|
|
|
|
FCanvas := ACanvas;
|
|
FDC := FCanvas.Handle;
|
|
FPPI := GetDeviceCaps(DC, LOGPIXELSX);
|
|
FViewPortRect := APageBounds;
|
|
FZoomFactor := AZoomFactor;
|
|
FRenderingPageIndex := VirtualPageIndex;
|
|
PrepareRenderPage;
|
|
try
|
|
RenderPageBackground(RealPageIndex);
|
|
RenderPageHeader(RealPageIndex);
|
|
RenderPageFooter(RealPageIndex);
|
|
if RenderInfo.HasPageTitle(RealPageIndex) then RenderPageTitle;
|
|
if ReportLink.NeedTwoPassRendering then
|
|
begin
|
|
FRenderStage := [rsFirstPass];
|
|
RenderPageContent;
|
|
FRenderStage := [rsSecondPass];
|
|
RenderPageContent;
|
|
end
|
|
else
|
|
begin
|
|
FRenderStage := [rsFirstPass, rsSecondPass];
|
|
RenderPageContent;
|
|
end;
|
|
finally
|
|
FRenderStage := [];
|
|
UnprepareRenderPage;
|
|
end;
|
|
RenderEntirePage(RealPageIndex);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderDelimiters;
|
|
var
|
|
I, Delimiter: Integer;
|
|
R: TRect;
|
|
begin
|
|
for I := 0 to RenderInfo.DelimiterXCount - 1 do
|
|
begin
|
|
Delimiter := RenderInfo.DelimitersX[I];
|
|
R := MakeBounds(Delimiter, 0, 2 * LineThickness, 20 * LineThickness);
|
|
//OffsetRect(R, 0, -PageRenderInfo.DataOffset.Y);
|
|
FillRect(DC, R, GetSysColorBrush(COLOR_HIGHLIGHT));
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageBackground(ARealPageIndex: Integer);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if IsPrinting then
|
|
with ReportLink.RealPrinterPage.Background do
|
|
begin
|
|
R := RenderInfo.PageHeaderBounds;
|
|
R.Bottom := RenderInfo.PageFooterBounds.Top;
|
|
if (Mode = bmNone) or ((Mode = bmPicture) and (PictureMode in [ppmCenter, ppmProportional])) then
|
|
Windows.FillRect(DC, R, GetStockObject(WHITE_BRUSH));
|
|
PaintEx(Canvas, R, PixelsNumerator * 100, PixelsDenominator * RenderInfo.ScaleFactor);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageFooter(ARealPageIndex: Integer);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := RenderInfo.PageFooterBounds;
|
|
if not IsRectEmpty(R) and (IsPrinting or RectVisible(DC, R)) then
|
|
RenderPageHeaderOrFooter(ReportLink.RealPrinterPage.PageFooter, ARealPageIndex, R);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageHeader(ARealPageIndex: Integer);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := RenderInfo.PageHeaderBounds;
|
|
if not IsRectEmpty(R) and (IsPrinting or RectVisible(DC, R)) then
|
|
RenderPageHeaderOrFooter(ReportLink.RealPrinterPage.PageHeader, ARealPageIndex, R);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageHeaderOrFooter(HF: TCustomdxPageObject;
|
|
APageIndex: Integer; ARect: TRect);
|
|
const
|
|
TitleParts: array[Boolean] of TdxPageTitleParts = ([], [tpLeft..tpRight]);
|
|
var
|
|
PrevFontHeight: Integer;
|
|
Rgn: HRGN;
|
|
DefaultDrawText, DefaultDrawBackground: Boolean;
|
|
PrevFont: HFONT;
|
|
PrevFontColor: COLORREF;
|
|
begin
|
|
PrevFontHeight := HF.Font.Height;
|
|
HF.Font.Height := -MulDiv(HF.Font.Size, MulDiv(UnitsPerInch, 100, ReportLink.RealScaleFactor), PtPerInch);
|
|
|
|
SetBkMode(DC, TRANSPARENT);
|
|
|
|
Rgn := IntersectClipRect(ARect);
|
|
try
|
|
DefaultDrawText := True;
|
|
DefaultDrawBackground := True;
|
|
|
|
PrevFont := SelectObject(DC, HF.Font.Handle);
|
|
PrevFontColor := SetTextColor(DC, ColorToRGB(HF.Font.Color));
|
|
|
|
if ReportLink.IsHeaderOrFooterCustomDrawn(HF) then
|
|
begin
|
|
//PrepareCanvasForCustomDraw(@HF.Font, nil);
|
|
ReportLink.DoCustomDrawPageHeaderOrFooter(HF, Canvas, APageIndex, ARect, DefaultDrawText, DefaultDrawBackground);
|
|
SetBkMode(DC, TRANSPARENT);
|
|
end;
|
|
|
|
if DefaultDrawText or DefaultDrawBackground then
|
|
RenderPageHeaderOrFooterContent(HF, APageIndex, ARect, TitleParts[DefaultDrawText], DefaultDrawBackground);
|
|
|
|
//if ReportLink.IsHeaderOrFooterCustomDrawn(HF) then UnprepareCanvasForCustomDraw;
|
|
|
|
SetTextColor(DC, PrevFontColor);
|
|
SelectObject(DC, PrevFont);
|
|
finally
|
|
RestoreClipRgn(Rgn);
|
|
end;
|
|
HF.Font.Height := PrevFontHeight;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageHeaderOrFooterContentPart(ATitlePart: TdxPageTitlePart;
|
|
AStrings: TStrings; ATextAlignY: TdxTextAlignY; ALineHeight, ADestWidth, ADestHeight: Integer;
|
|
const ARect: TRect);
|
|
const
|
|
uFormat = DT_SINGLELINE or DT_VCENTER or DT_NOCLIP or DT_EDITCONTROL;
|
|
var
|
|
FullHeight: Integer;
|
|
R: TRect;
|
|
I: Integer;
|
|
S: string;
|
|
TextSize: TSize;
|
|
begin
|
|
if ATextAlignY = taTop then
|
|
FullHeight := ARect.Top
|
|
else
|
|
begin
|
|
FullHeight := AStrings.Count * ALineHeight;
|
|
if ATextAlignY = taCenterY then
|
|
FullHeight := ARect.Top + (ADestHeight - FullHeight) div 2
|
|
else {taBottom}
|
|
FullHeight := ARect.Top + ADestHeight - FullHeight;
|
|
end;
|
|
if FullHeight < ARect.Top then
|
|
FullHeight := ARect.Top;
|
|
R := MakeRect(ARect.Left, FullHeight, ARect.Right, FullHeight + ALineHeight);
|
|
|
|
for I := 0 to AStrings.Count - 1 do
|
|
begin
|
|
S := AStrings[I];
|
|
if S <> '' then
|
|
begin
|
|
GetTextExtentPoint32(DC, PChar(S), Length(S), TextSize);
|
|
if ADestWidth > TextSize.cX then
|
|
case ATitlePart of
|
|
tpLeft:
|
|
R.Right := R.Left + TextSize.cX;
|
|
tpCenter:
|
|
begin
|
|
R.Left := ARect.Left + (ADestWidth - TextSize.cX) div 2;
|
|
R.Right := R.Left + TextSize.cX;
|
|
end;
|
|
tpRight:
|
|
R.Left := R.Right - TextSize.cX;
|
|
end;
|
|
if RectVisible(DC, R) then
|
|
begin
|
|
Windows.DrawText(DC, PChar(S), Length(S), R, uFormat or DT_LEFT);
|
|
ExcludeClipRect(R);
|
|
end;
|
|
R.Right := ARect.Right;
|
|
end;
|
|
OffsetRect(R, 0, ALineHeight);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageHeaderOrFooterContent(HF: TCustomdxPageObject;
|
|
APageIndex: Integer; ARect: TRect; ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
var
|
|
TextSize: TSize;
|
|
LineHeight, DestWidth, DestHeight: Integer;
|
|
TextAlignY: TdxTextAlignY;
|
|
begin
|
|
if ADrawBackground then
|
|
HF.Background.PaintEx(Canvas, ARect, PixelsNumerator * 100, PixelsDenominator * RenderInfo.ScaleFactor);
|
|
|
|
if ATitleParts = [] then
|
|
Exit;
|
|
|
|
GetTextExtentPoint32(DC, 'Hg', 2, TextSize);
|
|
LineHeight := TextSize.cY;
|
|
DestWidth := ARect.Right - ARect.Left;
|
|
DestHeight := ARect.Bottom - ARect.Top;
|
|
|
|
if tpLeft in ATitleParts then
|
|
begin
|
|
if ReportLink.RealPrinterPage.ReverseTitlesOnEvenPages and Odd(APageIndex) then
|
|
begin
|
|
FHFStrings.Text := dxProcessHFString(HF.RightTitle.Text);
|
|
TextAlignY := HF.TextAlignY[tpRight];
|
|
end
|
|
else
|
|
begin
|
|
FHFStrings.Text := dxProcessHFString(HF.LeftTitle.Text);
|
|
TextAlignY := HF.TextAlignY[tpLeft];
|
|
end;
|
|
RenderPageHeaderOrFooterContentPart(tpLeft, FHFStrings, TextAlignY,
|
|
LineHeight, DestWidth, DestHeight, ARect);
|
|
end;
|
|
|
|
if tpRight in ATitleParts then
|
|
begin
|
|
if ReportLink.RealPrinterPage.ReverseTitlesOnEvenPages and Odd(APageIndex) then
|
|
begin
|
|
FHFStrings.Text := dxProcessHFString(HF.LeftTitle.Text);
|
|
TextAlignY := HF.TextAlignY[tpLeft];
|
|
end
|
|
else
|
|
begin
|
|
FHFStrings.Text := dxProcessHFString(HF.RightTitle.Text);
|
|
TextAlignY := HF.TextAlignY[tpRight];
|
|
end;
|
|
RenderPageHeaderOrFooterContentPart(tpRight, FHFStrings, TextAlignY,
|
|
LineHeight, DestWidth, DestHeight, ARect);
|
|
end;
|
|
|
|
if tpCenter in ATitleParts then
|
|
begin
|
|
FHFStrings.Text := dxProcessHFString(HF.CenterTitle.Text);
|
|
TextAlignY := HF.TextAlignY[tpCenter];
|
|
RenderPageHeaderOrFooterContentPart(tpCenter, FHFStrings, TextAlignY,
|
|
LineHeight, DestWidth, DestHeight, ARect);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageTitle;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := RenderInfo.TitleBounds;
|
|
OffsetWindowOrgEx(DC, -PageRenderInfo.TitleOffset.X, -PageRenderInfo.TitleOffset.Y, nil);
|
|
if RectVisible(DC, R) then
|
|
with ReportLink.ReportTitle do
|
|
RenderPageTitleContent(Text, R, TextAlignX, TextAlignY, Color, Font, Transparent);
|
|
OffsetWindowOrgEx(DC, PageRenderInfo.TitleOffset.X, PageRenderInfo.TitleOffset.Y, nil);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderCell(ACell: TdxReportCell; const OriginRect: TRect);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if ACell.Visible then
|
|
begin
|
|
R := ACell.BoundsRect;
|
|
{ Transform R into the coordinate space of page }
|
|
OffsetRect(R, -OriginRect.Left, -OriginRect.Top);
|
|
if (R.Left <> 0) or (R.Top <> 0) then
|
|
OffsetWindowOrgEx(DC, -R.Left, -R.Top, nil);
|
|
ACell.DrawContent(DC, MakeRect(0, 0, R.Right - R.Left, R.Bottom - R.Top), OriginRect, RenderStage);
|
|
if (R.Left <> 0) or (R.Top <> 0) then
|
|
OffsetWindowOrgEx(DC, R.Left, R.Top, nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderEntirePage(ARealPageIndex: Integer);
|
|
var
|
|
Rgn: HRGN;
|
|
begin
|
|
if ReportLink.IsEntirePageCustomDrawn then
|
|
begin
|
|
Rgn := IntersectClipRect(ViewPortRect);
|
|
try
|
|
ReportLink.DoCustomDrawEntirePage(Canvas, ViewPortRect, ARealPageIndex);
|
|
finally
|
|
RestoreClipRgn(Rgn);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageContent;
|
|
var
|
|
R: TRect;
|
|
Rgn: HRGN;
|
|
PrevFont: HFONT;
|
|
PrevFontColor: COLORREF;
|
|
I, H, StartIndex, EndIndex: Integer;
|
|
PrevWindowOrg: TPoint;
|
|
begin
|
|
OffsetWindowOrgEx(DC, -PageRenderInfo.DataOffset.X - LineThickness,
|
|
-PageRenderInfo.DataOffset.Y - LineThickness, @PrevWindowOrg);
|
|
R := PageRenderInfo.ContentBounds;
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
// InflateRect(R, LineThickness, LineThickness); // for double
|
|
Dec(R.Left, LineThickness);
|
|
Dec(R.Top, LineThickness);
|
|
|
|
Rgn := dxPSUtl.IntersectClipRect(DC, R, True);
|
|
SetBkMode(DC, Windows.TRANSPARENT);
|
|
with RenderInfo.BaseContentFont do
|
|
begin
|
|
PrevFont := SelectObject(DC, Handle);
|
|
PrevFontColor := SetTextColor(DC, ColorToRGB(Color));
|
|
end;
|
|
|
|
with PageRenderInfo do
|
|
begin
|
|
if HasHeader then
|
|
begin
|
|
R := HeaderBounds;
|
|
OffsetRect(R, DetailBounds.Left, 0);
|
|
with ReportCells do
|
|
RenderPageContentPart(HeaderCells, 0, HeaderCells.CellCount - 1, R);
|
|
ExcludeClipRect(HeaderBounds);
|
|
OffsetWindowOrgEx(DC, 0, -(HeaderBounds.Bottom - HeaderBounds.Top), nil);
|
|
end;
|
|
|
|
if HasDetails then
|
|
begin
|
|
EndIndex := 0;
|
|
for I := 0 to IndexPairCount - 1 do
|
|
begin
|
|
StartIndex := IndexPairs[I].StartIndex;
|
|
EndIndex := IndexPairs[I].EndIndex;
|
|
RenderPageContentPart(ReportCells.Cells, StartIndex, EndIndex, DetailBounds);
|
|
end;
|
|
for I := 0 to OverlayCount - 1 do
|
|
RenderPageOverlay(I, Overlays[I], DetailBounds);
|
|
|
|
H := 0;
|
|
if not IsBottomPage then
|
|
H := DetailBounds.Bottom
|
|
else
|
|
if ReportCells.Cells.CellCount > EndIndex then
|
|
H := ReportCells.Cells[EndIndex].BoundsRect.Bottom;
|
|
Dec(H, DetailBounds.Top);
|
|
OffsetWindowOrgEx(DC, 0, -H, nil);
|
|
end;
|
|
|
|
if HasFooter then
|
|
begin
|
|
R := FooterBounds;
|
|
OffsetRect(R, DetailBounds.Left, 0);
|
|
with ReportCells do
|
|
RenderPageContentPart(FooterCells, 0, FooterCells.CellCount - 1, R);
|
|
end;
|
|
end;
|
|
RestoreClipRgn(Rgn);
|
|
SetBkMode(DC, Windows.OPAQUE);
|
|
SetTextColor(DC, PrevFontColor);
|
|
SelectObject(DC, PrevFont);
|
|
SetWindowOrgEx(DC, PrevWindowOrg.X, PrevWindowOrg.Y, nil);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageContentPart(ACell: TdxReportCell;
|
|
StartIndex, EndIndex: Integer; const OriginRect: TRect);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := StartIndex to EndIndex do
|
|
RenderCell(ACell[I], OriginRect);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RenderPageOverlay(AnOverlayIndex: Integer;
|
|
AnOverlay: TdxPageOverlayIndexes; const OriginRect: TRect);
|
|
var
|
|
OverlayCell: TdxReportCell;
|
|
I: Integer;
|
|
begin
|
|
OverlayCell := ReportCells.Overlays[AnOverlayIndex];
|
|
for I := 0 to AnOverlay.Count - 1 do
|
|
RenderCell(OverlayCell.Cells[AnOverlay[I]], OriginRect);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetUnitsPerInch: Integer;
|
|
begin
|
|
Result := RenderInfo.UnitsPerInch;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.CreateBorderPainter(AClass: TdxPSCellBorderPainterClass): TdxPSCellBorderPainter;
|
|
begin
|
|
Result := AClass.Create(Self);
|
|
FBorderPainters.Add(Result);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.FindBorderPainter(AClass: TdxPSCellBorderPainterClass): TdxPSCellBorderPainter;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to BorderPainterCount - 1 do
|
|
begin
|
|
Result := BorderPainters[I];
|
|
if Result.ClassType = AClass then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FreeAndNilBorderPainters;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to BorderPainterCount - 1 do
|
|
BorderPainters[I].Free;
|
|
FreeAndNil(FBorderPainters);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.CreateReportGroupLookAndFeelPainter(AClass: TdxPSReportGroupLookAndFeelPainterClass): TdxPSReportGroupLookAndFeelPainter;
|
|
begin
|
|
Result := AClass.Create(Self);
|
|
FGroupLookAndFeelPainters.Add(Result);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.FindReportGroupLookAndFeelPainter(AClass: TdxPSReportGroupLookAndFeelPainterClass): TdxPSReportGroupLookAndFeelPainter;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to GroupLookAndFeelPainterCount - 1 do
|
|
begin
|
|
Result := GroupLookAndFeelPainters[I];
|
|
if Result.ClassType = AClass then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.FreeAndNilReportGroupLookAndFeelPainters;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to GroupLookAndFeelPainterCount - 1 do
|
|
GroupLookAndFeelPainters[I].Free;
|
|
FreeAndNil(FGroupLookAndFeelPainters);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetBorderPainterItem(Index: Integer): TdxPSCellBorderPainter;
|
|
begin
|
|
Result := TdxPSCellBorderPainter(FBorderPainters[Index]);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetBorderPainterCount: Integer;
|
|
begin
|
|
Result := FBorderPainters.Count;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetGroupLookAndFeelPainter(Index: Integer): TdxPSReportGroupLookAndFeelPainter;
|
|
begin
|
|
Result := TdxPSReportGroupLookAndFeelPainter(FGroupLookAndFeelPainters[Index]);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetGroupLookAndFeelPainterCount: Integer;
|
|
begin
|
|
Result := FGroupLookAndFeelPainters.Count;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetHalfLineThickness: Integer;
|
|
begin
|
|
Result := LineThickness div 2;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetIsPrinting: Boolean;
|
|
begin
|
|
Result := IsPrinterDC(DC);
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetPageRenderInfo: TdxPSPageRenderInfo;
|
|
begin
|
|
Result := RenderInfo.PageRenderInfos[RenderingPageIndex];
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetRenderInfo: TdxPSReportRenderInfo;
|
|
begin
|
|
Result := FReportLink.RenderInfo;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.GetReportCells: TdxReportCells;
|
|
begin
|
|
Result := ReportLink.FReportCells;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.PrepareCanvasForCustomDraw(AFont: TFont; AColor: TColor);
|
|
begin
|
|
FSavePixelsPerInch := Canvas.Font.PixelsPerInch;
|
|
FSaveFont.Assign(Canvas.Font);
|
|
if (AFont <> nil) then
|
|
begin
|
|
Canvas.Font.PixelsPerInch := AFont.PixelsPerInch;
|
|
Canvas.Font := AFont;
|
|
end;
|
|
FSaveColor := Canvas.Brush.Color;
|
|
Canvas.Brush.Color := AColor;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.UnprepareCanvasForCustomDraw;
|
|
begin
|
|
Canvas.Brush.Color := FSaveColor;
|
|
Canvas.Brush.Style := bsClear;
|
|
Canvas.Font.PixelsPerInch := FSavePixelsPerInch;
|
|
Canvas.Font := FSaveFont;
|
|
SetBkMode(DC, Windows.TRANSPARENT);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.PrepareFonts;
|
|
var
|
|
UPI: Integer;
|
|
begin
|
|
UPI := RenderInfo.UnitsPerInch;
|
|
if not ReportLink.ScaleFonts and (ReportLink.RealScaleFactor <> 100) then
|
|
UPI := MulDiv(UPI, 100, ReportLink.RealScaleFactor);
|
|
ReportLink.PrepareFonts(UPI);
|
|
MarlettFont10.Height := -MulDiv(10, UnitsPerInch, PtPerInch);
|
|
dxPSUtl.SetFontAsNonAntialiased(MarlettFont10);
|
|
MarlettFont8.Height := -MulDiv(8, UnitsPerInch, PtPerInch);
|
|
dxPSUtl.SetFontAsNonAntialiased(MarlettFont8);
|
|
SymbolFont.Height := -MulDiv(7, UnitsPerInch, PtPerInch);
|
|
dxPSUtl.SetFontAsNonAntialiased(SymbolFont);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.PrepareGDIObjects;
|
|
begin
|
|
FBorderColor := ColorToRGB(RenderInfo.GridLinesColor);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.PrepareLogicalCoordinates;
|
|
begin
|
|
SetMapMode(DC, MM_ISOTROPIC);
|
|
PrepareWindow;
|
|
PrepareViewPort;
|
|
// MoveToEx(DC, 0, 0, nil);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.PrepareLogicalUnits;
|
|
var
|
|
R: TRect;
|
|
UnitsPerPt: Integer;
|
|
begin
|
|
R := MakeRect(0, 0, 1, 1);
|
|
DPToLP(DC, R, 2);
|
|
UnitsPerPixel := R.Right - R.Left;
|
|
//if Odd(FUnitsPerPixel) then Dec(FUnitsPerPixel);
|
|
if UnitsPerPixel = 0 then UnitsPerPixel := 1;
|
|
|
|
UnitsPerPt := MulDiv(UnitsPerPixel, PPI, PtPerInch);
|
|
|
|
if not IsPrinting then
|
|
begin
|
|
LineThickness := 1 * UnitsPerPixel;
|
|
if (ZoomFactor > 100) and ReportLink.IsScaleGridLines then
|
|
LineThickness := LineThickness * (ZoomFactor div 100);
|
|
end
|
|
else
|
|
LineThickness := MulDiv(UnitsPerPt, 1, 2);
|
|
|
|
FPixelsNumerator := RenderInfo.UnitsPerInch;
|
|
end;
|
|
|
|
function TdxPSReportRenderer.PreparedPageIndex(APageIndex: Integer): Integer;
|
|
var
|
|
RowIndex, ColIndex: Integer;
|
|
begin
|
|
if RenderInfo.PrinterPage.PageOrder = poDownThenOver then
|
|
begin
|
|
RowIndex := APageIndex div RenderInfo.PageColCount;
|
|
ColIndex := APageIndex mod RenderInfo.PageColCount;
|
|
Result := RowIndex + ColIndex * RenderInfo.PageRowCount;
|
|
end
|
|
else
|
|
Result := APageIndex;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.PrepareRenderPage;
|
|
begin
|
|
RenderInfo.Lock;
|
|
SaveMapMode;
|
|
PrepareLogicalCoordinates;
|
|
PrepareLogicalUnits;
|
|
PrepareFonts;
|
|
PrepareGDIObjects;
|
|
FIsRendering := True;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.PrepareWindow;
|
|
begin
|
|
with RenderInfo do
|
|
begin
|
|
SetWindowExtEx(DC, PageSize.X, PageSize.Y, nil);
|
|
ScaleWindowExtEx(DC, WindowScalePair.Numerator, WindowScalePair.Denominator,
|
|
WindowScalePair.Numerator, WindowScalePair.Denominator, nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.PrepareViewPort;
|
|
begin
|
|
with ViewPortRect do
|
|
begin
|
|
SetViewPortExtEx(DC, Right - Left, Bottom - Top, nil);
|
|
SetViewPortOrgEx(DC, Left, Top, nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.RestoreMapMode;
|
|
begin
|
|
SetMapMode(DC, FPrevMode);
|
|
SetWindowExtEx(DC, FPrevWindowExt.cX, FPrevWindowExt.cY, nil);
|
|
SetViewPortOrgEx(DC, FPrevViewPortOrg.X, FPrevViewPortOrg.Y, nil);
|
|
SetViewPortExtEx(DC, FPrevViewPortExt.cX, FPrevViewPortExt.cY, nil);
|
|
SetWindowOrgEx(DC, FPrevWindowOrg.X, FPrevWindowOrg.Y, nil);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.SaveMapMode;
|
|
begin
|
|
FPrevMode := GetMapMode(DC);
|
|
GetWindowExtEx(DC, FPrevWindowExt);
|
|
GetWindowOrgEx(DC, FPrevWindowOrg);
|
|
GetViewPortExtEx(DC, FPrevViewPortExt);
|
|
GetViewPortOrgEx(DC, FPrevViewPortOrg);
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.UnprepareLogicalUnits;
|
|
begin
|
|
LineThickness := 1;
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.UnprepareGDIObjects;
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSReportRenderer.UnprepareRenderPage;
|
|
begin
|
|
FIsRendering := False;
|
|
UnprepareLogicalUnits;
|
|
UnprepareGDIObjects;
|
|
RestoreMapMode;
|
|
RenderInfo.Unlock;
|
|
end;
|
|
|
|
{ TdxReportItem }
|
|
|
|
constructor TdxReportItem.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create;
|
|
Parent := AParent;
|
|
end;
|
|
|
|
destructor TdxReportItem.Destroy;
|
|
begin
|
|
SetParent(nil);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxReportItem.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxReportItem then
|
|
Data := TdxReportItem(Source).Data
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
class function TdxReportItem.ReportItemClass: TdxReportItemClass;
|
|
begin
|
|
Result := TdxReportItemClass(GetTypeData(ClassInfo)^.ClassType);
|
|
end;
|
|
|
|
class procedure TdxReportItem.Register;
|
|
begin
|
|
if GetClass(ClassName) = nil then RegisterClass(Self);
|
|
end;
|
|
|
|
class procedure TdxReportItem.Unregister;
|
|
begin
|
|
UnregisterClass(Self);
|
|
end;
|
|
|
|
function TdxReportItem.Clone(AParent: TdxReportCell): TdxReportItem;
|
|
begin
|
|
Result := ReportItemClass.Create(AParent);
|
|
try
|
|
Result.Assign(Self);
|
|
except
|
|
Result.Free;
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportItem.GetNextSibling: TdxReportItem;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Result := nil;
|
|
if not HasParent then Exit;
|
|
Index := Parent.IndexOf(Self);
|
|
|
|
if IsCell then
|
|
begin
|
|
if Index < Parent.CellCount - 1 then
|
|
Result := TdxReportItem(Parent.FCellList[Index + 1]);
|
|
end
|
|
else
|
|
if Index < Parent.DataItemCount - 1 then
|
|
Result := TdxReportItem(Parent.FDataList[Index + 1]);
|
|
end;
|
|
|
|
function TdxReportItem.GetPrevSibling: TdxReportItem;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Result := nil;
|
|
if not HasParent then Exit;
|
|
Index := Parent.IndexOf(Self);
|
|
if Index < 1 then Exit;
|
|
|
|
if IsCell then
|
|
Result := TdxReportItem(Parent.FCellList[Index - 1])
|
|
else
|
|
Result := TdxReportItem(Parent.FDataList[Index - 1]);
|
|
end;
|
|
|
|
function TdxReportItem.HasParent: Boolean;
|
|
begin
|
|
Result := Parent <> nil;
|
|
end;
|
|
|
|
function TdxReportItem.IsFirstItem: Boolean;
|
|
begin
|
|
Result := GetPrevSibling = nil;
|
|
end;
|
|
|
|
function TdxReportItem.IsLastItem: Boolean;
|
|
begin
|
|
Result := GetNextSibling = nil;
|
|
end;
|
|
|
|
function TdxReportItem.AsCell: TdxReportCell;
|
|
begin
|
|
if IsCell then
|
|
Result := TdxReportCell(Self)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxReportItem.GetTopLevelParent: TdxReportCell;
|
|
begin
|
|
if ReportCells <> nil then
|
|
Result := ReportCells.GetCellTopLevelParent(Self)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
class function TdxReportItem.IsCell: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TdxReportItem.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
Data := AReader.ReadInteger;
|
|
end;
|
|
|
|
procedure TdxReportItem.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
AWriter.WriteInteger(Data);
|
|
end;
|
|
|
|
class function TdxReportItem.Serializable: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TdxReportItem.GetIndex: Integer;
|
|
begin
|
|
if Parent <> nil then
|
|
Result := Parent.IndexOf(Self)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
function TdxReportItem.GetReportCells: TdxReportCells;
|
|
begin
|
|
if Parent <> nil then
|
|
Result := Parent.ReportCells
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxReportItem.SetIndex(Value: Integer);
|
|
var
|
|
CurIndex: Integer;
|
|
begin
|
|
if Parent = nil then Exit;
|
|
if Value < 0 then Value := 0;
|
|
|
|
if IsCell then
|
|
begin
|
|
if Value > Parent.CellCount - 1 then
|
|
Value := Parent.CellCount - 1
|
|
end
|
|
else
|
|
if Value > Parent.DataItemCount - 1 then
|
|
Value := Parent.DataItemCount - 1;
|
|
CurIndex := GetIndex;
|
|
if CurIndex <> Value then
|
|
Parent.MoveItem(Self, CurIndex, Value);
|
|
end;
|
|
|
|
procedure TdxReportItem.SetParent(Value: TdxReportCell);
|
|
begin
|
|
if Parent <> Value then
|
|
begin
|
|
if Parent <> nil then Parent.RemoveItem(Self);
|
|
if Value <> nil then Value.InsertItem(Self);
|
|
end;
|
|
end;
|
|
|
|
{ TdxReportVisualItem }
|
|
|
|
constructor TdxReportVisualItem.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited;
|
|
FBackgroundBitmapIndex := -1;
|
|
if HasBorderColoration then
|
|
FBorderClass := TdxPSColorBorder
|
|
else
|
|
FBorderClass := TdxPSCellUltraFlatBorder;
|
|
FBorderColor := clDefault;
|
|
CellSides := dxDefaultCellSides; // csAll
|
|
FColor := dxDefaultContentColor; // clWhite
|
|
ShowShadow := False;
|
|
Transparent := dxDefaultTransparent; // True
|
|
Visible := True;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.Assign(Source: TPersistent);
|
|
begin
|
|
inherited;
|
|
if Source is TdxReportVisualItem then
|
|
with TdxReportVisualItem(Source) do
|
|
begin
|
|
Self.BackgroundBitmapIndex := BackgroundBitmapIndex;
|
|
Self.BorderClass := BorderClass;
|
|
Self.BorderColor := BorderColor;
|
|
Self.BoundsRect := BoundsRect;
|
|
Self.Color := Color;
|
|
Self.ContentBkColor := ContentBkColor;
|
|
Self.ContentPattern := ContentPattern;
|
|
Self.FontIndex := FontIndex;
|
|
Self.Format := Format;
|
|
Self.ShadowColor := ShadowColor;
|
|
Self.ShadowDepth := ShadowDepth;
|
|
Self.FCellSideColors := FCellSideColors;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.AdjustContent(DC: HDC);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.DrawBackground(DC: HDC);
|
|
begin
|
|
DrawBackgroundRect(DC, GetBackgroundBounds(DC));
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.DrawBackgroundBitmap(DC: HDC);
|
|
var
|
|
Rgn: HRGN;
|
|
I, J: Integer;
|
|
R: TRect;
|
|
begin
|
|
Rgn := Renderer.IntersectClipRect(GetBackgroundBounds(DC));
|
|
try
|
|
for I := BackgroundBitmapTileStartIndexX to BackgroundBitmapTileStopIndexX do
|
|
for J := BackgroundBitmapTileStartIndexY to BackgroundBitmapTileStopIndexY do
|
|
begin
|
|
R := BackgroundBitmapTileBounds[I, J];
|
|
if RectVisible(DC, R) then DrawBackgroundBitmapTile(DC, R);
|
|
end;
|
|
finally
|
|
Renderer.RestoreClipRgn(Rgn);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.DrawBackgroundBitmapTile(DC: HDC; const Rect: TRect);
|
|
begin
|
|
Renderer.DrawGraphicEx(DC, Rect, GetBackgroundBounds(DC), nil, -1, BackgroundBitmap,
|
|
False, False, clNone, clNone, nil, cibAlways);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.DrawBackgroundRect(DC: HDC; const R: TRect);
|
|
begin
|
|
if not IsRectEmpty(R) then
|
|
Renderer.FillRectEx(DC, R, Color, ContentBkColor, ContentPattern);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.DrawBorders(DC: HDC);
|
|
begin
|
|
BorderPainter.Paint(DC);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderOuterBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := GetBorderOuterBoundsRelativeTo(DC, GetOuterBounds(DC));
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetInnerBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := GetInnerBoundsRelativeTo(DC, BoundsRect);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetOuterBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := GetOuterBoundsRelativeTo(DC, BoundsRect);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
begin
|
|
if (ALeft <> Left) or (ATop <> Top) or (AWidth <> Width) or (AHeight <> Height) then
|
|
begin
|
|
FBoundsRect.Left := ALeft;
|
|
FBoundsRect.Top := ATop;
|
|
FBoundsRect.Right := ALeft + AWidth;
|
|
FBoundsRect.Bottom := ATop + AHeight;
|
|
BoundsChanged;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportVisualItem.CalculateLineCount(DC: HDC): Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TdxReportVisualItem.MeasureBordersHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := 0;
|
|
if csTop in CellSides then
|
|
Inc(Result, GetBorderEdgeThickness(csTop) - 1);
|
|
if csBottom in CellSides then
|
|
Inc(Result, GetBorderEdgeThickness(csBottom) - 1);
|
|
if ShowShadow then
|
|
Inc(Result, ShadowDepth);
|
|
end;
|
|
|
|
function TdxReportVisualItem.MeasureBordersWidth(DC: HDC): Integer;
|
|
begin
|
|
Result := 0;
|
|
if csLeft in CellSides then
|
|
Inc(Result, GetBorderEdgeThickness(csLeft) - 1);
|
|
if csRight in CellSides then
|
|
Inc(Result, GetBorderEdgeThickness(csRight) - 1);
|
|
if ShowShadow then
|
|
Inc(Result, ShadowDepth);
|
|
end;
|
|
|
|
function TdxReportVisualItem.MeasureContentHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportVisualItem.MeasureContentWidth(DC: HDC): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportVisualItem.MeasureFontHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := Height;
|
|
end;
|
|
|
|
function TdxReportVisualItem.MeasureHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := MeasureBordersHeight(DC) + MeasureContentHeight(DC);
|
|
end;
|
|
|
|
function TdxReportVisualItem.MeasureWidth(DC: HDC): Integer;
|
|
begin
|
|
Result := MeasureBordersWidth(DC) + MeasureContentWidth(DC);
|
|
end;
|
|
|
|
class function TdxReportVisualItem.MapBorderClass(AEdgeMode: TdxCellEdgeMode;
|
|
AEdgeStyle: TdxCellEdgeStyle; ASoft: Boolean): TdxPSCellBorderClass;
|
|
begin
|
|
if AEdgeMode = cem3DEffects then
|
|
Result := dxCellBorderClassMap[AEdgeStyle, ASoft]
|
|
else
|
|
Result := TdxPSCellUltraFlatBorder;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.BoundsChanged;
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
|
|
begin
|
|
with FBoundsRect do
|
|
begin
|
|
Left := MulDiv(Left, APixelsNumerator, APixelsDenominator);
|
|
Right := MulDiv(Right, APixelsNumerator, APixelsDenominator);
|
|
Top := MulDiv(Top, APixelsNumerator, APixelsDenominator);
|
|
Bottom := MulDiv(Bottom, APixelsNumerator, APixelsDenominator);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.DoExcludeFromClipRgn(DC: HDC; const R: TRect;
|
|
var AResult: Integer);
|
|
var
|
|
R2: TRect;
|
|
begin
|
|
if ExcludeFromClipRgn and not Transparent and Visible and IntersectRect(R2, GetAbsoluteRect, R) then
|
|
begin
|
|
R2 := GetOuterBounds(DC);
|
|
if not IsRectEmpty(R2) then
|
|
AResult := Renderer.ExcludeClipRect(R2);
|
|
end;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapTileBounds(Col, Row: Integer): TRect;
|
|
begin
|
|
Result := MakeBounds(Left + BackgroundBitmapWidth * Col, Top + BackgroundBitmapHeight * Row,
|
|
BackgroundBitmapWidth, BackgroundBitmapHeight);
|
|
with BackgroundBitmapTileOrigin do
|
|
OffsetRect(Result, X, Y);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := GetInnerBounds(DC);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderClass: TdxPSCellBorderClass;
|
|
begin
|
|
Result := FBorderClass;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderEdgeClass(ASide: TdxCellSide): TdxPSCellBorderClass;
|
|
begin
|
|
Result := BorderClass;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderEdgeBounds(ASide: TdxCellSide; const AOuterRect: TRect): TRect;
|
|
begin
|
|
Result := AOuterRect;
|
|
with Result do
|
|
case ASide of
|
|
csLeft:
|
|
Right := Left + LineThickness * BorderEdgeThicknesses[csLeft];
|
|
csTop:
|
|
Bottom := Top + LineThickness * BorderEdgeThicknesses[csTop];
|
|
csRight:
|
|
Left := Right - LineThickness * BorderEdgeThicknesses[csRight];
|
|
csBottom:
|
|
Top := Bottom - LineThickness * BorderEdgeThicknesses[csBottom];
|
|
end;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderEdgeSalient(ASide: TdxCellSide; ASalient: TdxPSCellBorderSalientType): Integer;
|
|
begin
|
|
Result := BorderEdgeClasses[ASide].GetBorderEdgeSalient(ASide, ASalient);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderEdgeThickness(ASide: TdxCellSide): Integer;
|
|
begin
|
|
Result := BorderEdgeClasses[ASide].Thickness;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := FBoundsRect;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderOuterBoundsRelativeTo(DC: HDC; const R: TRect): TRect;
|
|
begin
|
|
Result := R;
|
|
if ShowShadow then
|
|
begin
|
|
Dec(Result.Right, ShadowDepth);
|
|
Dec(Result.Bottom, ShadowDepth);
|
|
end;
|
|
//FixupRect(DC, Result);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetInnerBoundsRelativeTo(DC: HDC; const R: TRect): TRect;
|
|
var
|
|
LineThickness: Integer;
|
|
begin
|
|
Result := GetOuterBoundsRelativeTo(DC, R);
|
|
LineThickness := Self.LineThickness;
|
|
|
|
with Result do
|
|
begin
|
|
if csLeft in CellSides then
|
|
Inc(Left, LineThickness * BorderEdgeThicknesses[csLeft]);
|
|
if csTop in CellSides then
|
|
Inc(Top, LineThickness * BorderEdgeThicknesses[csTop]);
|
|
if csRight in CellSides then
|
|
Dec(Right, LineThickness * BorderEdgeThicknesses[csRight]);
|
|
if csBottom in CellSides then
|
|
Dec(Bottom, LineThickness * BorderEdgeThicknesses[csBottom]);
|
|
|
|
if ShowShadow then
|
|
begin
|
|
Dec(Right, ShadowDepth);
|
|
Dec(Bottom, ShadowDepth);
|
|
end;
|
|
end;
|
|
FixupRect(DC, Result);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetOuterBoundsRelativeTo(DC: HDC; const R: TRect): TRect;
|
|
var
|
|
LineThickness: Integer;
|
|
begin
|
|
Result := R;
|
|
LineThickness := Self.LineThickness;
|
|
|
|
with Result do
|
|
begin
|
|
if csLeft in CellSides then
|
|
Dec(Left, LineThickness * BorderEdgeSalients[csLeft, bstOuter]);
|
|
if csTop in CellSides then
|
|
Dec(Top, LineThickness * BorderEdgeSalients[csTop, bstOuter]);
|
|
if csRight in CellSides then
|
|
Inc(Right, LineThickness * BorderEdgeSalients[csRight, bstOuter]);
|
|
if csBottom in CellSides then
|
|
Inc(Bottom, LineThickness * BorderEdgeSalients[csBottom, bstOuter]);
|
|
end;
|
|
FixupRect(DC, Result);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderPainter: TdxPSCellBorderPainter;
|
|
begin
|
|
Result := Renderer.GetBorderPainter(BorderPainterClass);
|
|
InitBorderPainter(Result);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderPainterClass: TdxPSCellBorderPainterClass;
|
|
begin
|
|
Result := BorderClass.GetPainterClass;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.InitBorderPainter(ABorderPainter: TdxPSCellBorderPainter);
|
|
begin
|
|
ABorderPainter.FItem := Self;
|
|
end;
|
|
|
|
function TdxReportVisualItem.HasBorderColoration: Boolean;
|
|
begin
|
|
Result := False; // todo MSN;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetFormatBit(ABit: DWORD): Boolean;
|
|
begin
|
|
Result := Format and ABit = ABit;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetFormatBit(ABit: DWORD; Value: Boolean);
|
|
begin
|
|
Format := Format and not ABit;
|
|
if Value then
|
|
Format := Format or ABit;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetContentBkColor: TColor;
|
|
begin
|
|
Result := Color;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetContentPattern: TdxPSFillPatternClass;
|
|
begin
|
|
Result := TdxPSSolidFillPattern;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetShadowColor: TColor;
|
|
begin
|
|
if ReportCells <> nil then
|
|
Result := ReportCells.ShadowColor
|
|
else
|
|
Result := dxDefaultShadowColor;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetShadowDepth: Integer;
|
|
begin
|
|
if ReportCells <> nil then
|
|
Result := ReportCells.ShadowDepth
|
|
else
|
|
Result := dxDefaultShadowDepth;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetContentBkColor(Value: TColor);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetContentPattern(Value: TdxPSFillPatternClass);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetFontIndex(Value: Integer);
|
|
begin
|
|
if Value < -1 then Value := -1;
|
|
FFontIndex := Value;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetShadowColor(Value: TColor);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetShadowDepth(Value: Integer);
|
|
begin
|
|
end;
|
|
|
|
function TdxReportVisualItem.IsBackgroundBitmapDrawn: Boolean;
|
|
begin
|
|
Result := (BackgroundBitmapIndex <> -1) and not BackgroundBitmap.Empty;
|
|
end;
|
|
|
|
function TdxReportVisualItem.IsBackgroundDrawn: Boolean;
|
|
begin
|
|
Result := not Transparent;
|
|
end;
|
|
|
|
function TdxReportVisualItem.IsBordersDrawn: Boolean;
|
|
begin
|
|
Result := (CellSides <> []) or ShowShadow;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited ReadData(AReader);
|
|
with AReader do
|
|
begin
|
|
BackgroundBitmapIndex := ReadInteger;
|
|
BoundsRect := ReadRect;
|
|
BorderClass := ReadCellBorderClass;
|
|
if HasBorderColoration then
|
|
TRect(FCellSideColors) := ReadRect;
|
|
BorderColor := ReadInteger;
|
|
Color := ReadInteger;
|
|
ContentBkColor := ReadInteger;
|
|
ContentPattern := ReadFillPatternClass;
|
|
FontIndex := ReadInteger;
|
|
Read(FFormat, SizeOf(Format));
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited WriteData(AWriter);
|
|
with AWriter do
|
|
begin
|
|
WriteInteger(BackgroundBitmapIndex);
|
|
WriteRect(BoundsRect);
|
|
WriteClassName(BorderClass);
|
|
if HasBorderColoration then
|
|
WriteRect(TRect(FCellSideColors));
|
|
WriteInteger(BorderColor);
|
|
WriteInteger(Color);
|
|
WriteInteger(ContentBkColor);
|
|
WriteClassName(ContentPattern);
|
|
WriteInteger(FontIndex);
|
|
Write(Format, SizeOf(Format));
|
|
end;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetAbsoluteOrigin: TPoint;
|
|
var
|
|
Item: TdxReportVisualItem;
|
|
Origin: TPoint;
|
|
begin
|
|
Result := NullPoint;
|
|
Item := Self;
|
|
while Item <> nil do
|
|
begin
|
|
Origin := Item.GetOrigin;
|
|
Inc(Result.X, Origin.X);
|
|
Inc(Result.Y, Origin.Y);
|
|
Item := Item.Parent;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetAbsoluteRect: TRect;
|
|
begin
|
|
with Result do
|
|
begin
|
|
TopLeft := AbsoluteOrigin;
|
|
Right := Left + Width;
|
|
Bottom := Top + Height;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmap: TBitmap;
|
|
begin
|
|
Result := BackgroundBitmapPool[BackgroundBitmapIndex];
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapHeight: Integer;
|
|
begin
|
|
Result := BackgroundBitmap.Height * Renderer.UnitsPerPixel;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapPool: TdxPSBackgroundBitmapPool;
|
|
begin
|
|
if (ReportCells <> nil) and (ReportCells.ReportLink <> nil) then
|
|
Result := ReportCells.ReportLink.BackgroundBitmapPool
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapTileOrigin: TPoint;
|
|
begin
|
|
Result := AbsoluteOrigin;
|
|
Result.X := -Result.X;
|
|
Result.Y := -Result.Y;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapTileStartIndexX: Integer;
|
|
begin
|
|
Result := Abs(BackgroundBitmapTileOrigin.X) div BackgroundBitmapWidth;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapTileStartIndexY: Integer;
|
|
begin
|
|
Result := Abs(BackgroundBitmapTileOrigin.Y) div BackgroundBitmapHeight;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapTileStopIndexX: Integer;
|
|
begin
|
|
Result := (Width + Abs(BackgroundBitmapTileOrigin.X)) div BackgroundBitmapWidth;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapTileStopIndexY: Integer;
|
|
begin
|
|
Result := (Height + Abs(BackgroundBitmapTileOrigin.Y)) div BackgroundBitmapHeight;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBackgroundBitmapWidth: Integer;
|
|
begin
|
|
Result := BackgroundBitmap.Width * Renderer.UnitsPerPixel;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderBrush: HBRUSH;
|
|
begin
|
|
Result := Renderer.GetBrushByColor(BorderColor);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetBorderColor: TColor;
|
|
begin
|
|
Result := FBorderColor;
|
|
if Result = clDefault then Result := ReportCells.BorderColor;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetCellSides: TdxCellSides;
|
|
begin
|
|
Result := TdxCellSides(Byte(Format and dxPSGlbl.dxFormatRect));
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetCellSideColors(ASide: TdxCellSide): TColor;
|
|
begin
|
|
Result := FCellSideColors[ASide];
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetContentBrush: HBRUSH;
|
|
begin
|
|
Result := dxPSFillPatternFactory.Items[ContentPattern, IsPrinting].Brush.Handle;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetEdge3DSoft: Boolean;
|
|
begin
|
|
Result := BorderClass.Edge3DSoft;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetEdge3DStyle: TdxCellEdgeStyle;
|
|
begin
|
|
Result := BorderClass.Edge3DStyle;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetEdgeMode: TdxCellEdgeMode;
|
|
begin
|
|
Result := BorderClass.EdgeMode;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetExcludeFromClipRgn: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExcludeFromClipRgn);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetFont: TFont;
|
|
begin
|
|
if (FontIndex <> -1) and (ReportCells <> nil) then
|
|
Result := ReportCells.GetFontByIndex(FontIndex)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetHeight: Integer;
|
|
begin
|
|
with BoundsRect do
|
|
Result := Bottom - Top;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetIsPrinting: Boolean;
|
|
begin
|
|
Result := Renderer.IsPrinting;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetLeft: Integer;
|
|
begin
|
|
Result := BoundsRect.Left;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetLineThickness: Integer;
|
|
begin
|
|
Result := Renderer.LineThickness;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetOrigin: TPoint;
|
|
begin
|
|
Result := BoundsRect.TopLeft;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetParentBrush: HBRUSH;
|
|
begin
|
|
Result := Renderer.GetBrushByColor(ParentColor);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetParentColor: TColor;
|
|
var
|
|
ItemParent: TdxReportCell;
|
|
begin
|
|
ItemParent := Parent;
|
|
while (ItemParent <> nil) and ItemParent.Transparent do
|
|
ItemParent := ItemParent.Parent;
|
|
|
|
if ItemParent <> nil then
|
|
Result := ItemParent.Color
|
|
else
|
|
Result := clNone;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetRenderer: TdxPSReportRenderer;
|
|
begin
|
|
Result := ReportCells.Renderer;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetShadowBrush: HBRUSH;
|
|
begin
|
|
Result := Renderer.GetBrushByColor(ShadowColor);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetShowShadow: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatShowShadow);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetTop: Integer;
|
|
begin
|
|
Result := BoundsRect.Top;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetTransparent: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatTransparent);
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetWidth: Integer;
|
|
begin
|
|
with BoundsRect do
|
|
Result := Right - Left;
|
|
end;
|
|
|
|
function TdxReportVisualItem.GetVisible: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatVisible);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetBackgroundBitmapIndex(Value: Integer);
|
|
begin
|
|
if Value < -1 then Value := -1;
|
|
FBackgroundBitmapIndex := Value;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetBorderClass(Value: TdxPSCellBorderClass);
|
|
begin
|
|
if Value = nil then Value := TdxPSCellUltraFlatBorder;
|
|
FBorderClass := Value;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetBoundsRect(const Value: TRect);
|
|
begin
|
|
with Value do
|
|
SetBounds(Left, Top, Right - Left, Bottom - Top);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetCellSides(Value: TdxCellSides);
|
|
begin
|
|
if CellSides <> Value then
|
|
Format := Format and not dxPSGlbl.dxFormatRect or Byte(Value);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetCellSideColors(
|
|
ASide: TdxCellSide; AValue: TColor);
|
|
begin
|
|
FCellSideColors[ASide] := AValue;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetColor(Value: TColor);
|
|
begin
|
|
FColor := ColorToRGB(Value);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetEdge3DSoft(Value: Boolean);
|
|
begin
|
|
BorderClass := MapBorderClass(EdgeMode, Edge3DStyle, Value);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetEdge3DStyle(Value: TdxCellEdgeStyle);
|
|
begin
|
|
BorderClass := MapBorderClass(EdgeMode, Value, Edge3DSoft);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetEdgeMode(Value: TdxCellEdgeMode);
|
|
begin
|
|
BorderClass := MapBorderClass(Value, Edge3DStyle, Edge3DSoft);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetExcludeFromClipRgn(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExcludeFromClipRgn, Value);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetFont(Value: TFont);
|
|
begin
|
|
if ReportCells <> nil then
|
|
FontIndex := ReportCells.GetIndexByFont(Value);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetFormat(Value: DWORD);
|
|
begin
|
|
FFormat := Value;
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetHeight(Value: Integer);
|
|
begin
|
|
SetBounds(Left, Top, Width, Value);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetLeft(Value: Integer);
|
|
begin
|
|
SetBounds(Value, Top, Width, Height);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetOrigin(const Value: TPoint);
|
|
begin
|
|
SetBounds(Value.X, Value.Y, Width, Height);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetShowShadow(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatShowShadow, Value);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetTop(Value: Integer);
|
|
begin
|
|
SetBounds(Left, Value, Width, Height);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetTransparent(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatTransparent, Value);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetWidth(Value: Integer);
|
|
begin
|
|
SetBounds(Left, Top, Value, Height);
|
|
end;
|
|
|
|
procedure TdxReportVisualItem.SetVisible(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatVisible, Value);
|
|
end;
|
|
|
|
{ TdxReportCell }
|
|
|
|
destructor TdxReportCell.Destroy;
|
|
begin
|
|
SetParent(nil);
|
|
ClearDataItems;
|
|
ClearCells;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxReportCell.Assign(Source: TPersistent);
|
|
|
|
procedure DoAssign(ASource, ADest: TdxReportCell);
|
|
var
|
|
I: Integer;
|
|
DestCell: TdxReportCell;
|
|
begin
|
|
for I := 0 to ASource.CellCount - 1 do
|
|
begin
|
|
DestCell := TdxReportCell.Create(ADest);
|
|
DestCell.Assign(ASource.Cells[I]);
|
|
end;
|
|
|
|
for I := 0 to ASource.DataItemCount - 1 do
|
|
ASource.DataItems[I].Clone(ADest);
|
|
end;
|
|
|
|
begin
|
|
if (Source is TdxReportCell) and (Source <> Self) then
|
|
begin
|
|
ClearAll;
|
|
inherited;
|
|
DoAssign(TdxReportCell(Source), Self);
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxReportCell.DrawContent(DC: HDC; DrawRect: TRect; const OriginRect: TRect;
|
|
AStage: TdxPSRenderStages);
|
|
var
|
|
R: TRect;
|
|
ContentRgn, Rgn: HRGN;
|
|
begin
|
|
if ClipChildren then
|
|
begin
|
|
R := DrawRect;
|
|
Dec(R.Left, BorderClass.Thickness * LineThickness); // BorderClass.Thickness - v3.2
|
|
Dec(R.Top, BorderClass.Thickness * LineThickness); // BorderClass.Thickness - v3.2
|
|
ContentRgn := Renderer.IntersectClipRect(R);
|
|
end
|
|
else
|
|
ContentRgn := Renderer.GetClipRgn;
|
|
|
|
try
|
|
Rgn := Renderer.GetClipRgn;
|
|
if ExcludeNestedItems(DC, OriginRect) <> NULLREGION then
|
|
begin
|
|
DrawItself(DC, AStage);
|
|
DrawNestedDataItems(DC, OriginRect, AStage);
|
|
end;
|
|
Renderer.RestoreClipRgn(Rgn);
|
|
|
|
DrawNestedCells(DC, DrawRect, OriginRect, AStage);
|
|
//DrawNestedDataItems(DC, OriginRect, AStage);
|
|
finally
|
|
Renderer.RestoreClipRgn(ContentRgn);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.DrawItself(DC: HDC; AStage: TdxPSRenderStages);
|
|
begin
|
|
if rsFirstPass in AStage then
|
|
begin
|
|
if IsBackgroundBitmapDrawn then
|
|
DrawBackgroundBitmap(DC)
|
|
else
|
|
if IsBackgroundDrawn then
|
|
DrawBackground(DC);
|
|
|
|
if IsBordersDrawn then DrawBorders(DC);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.DrawNestedCells(DC: HDC; DrawRect: TRect; const OriginRect: TRect;
|
|
AStage: TdxPSRenderStages);
|
|
var
|
|
I: Integer;
|
|
R: TRect;
|
|
begin
|
|
for I := 0 to CellCount - 1 do
|
|
with Cells[I] do
|
|
if Visible then
|
|
begin
|
|
DrawRect := BoundsRect;
|
|
if {RectVisible(DC, DrawRect) and }IntersectRect(R, GetAbsoluteRect, OriginRect) then
|
|
with BoundsRect do
|
|
begin
|
|
if (Left <> 0) or (Top <> 0) then OffsetWindowOrgEx(DC, -Left, -Top, nil);
|
|
OffsetRect(DrawRect, -Left, -Top);
|
|
DrawContent(DC, DrawRect, OriginRect, AStage);
|
|
if (Left <> 0) or (Top <> 0) then OffsetWindowOrgEx(DC, Left, Top, nil);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.DrawNestedDataItems(DC: HDC; const OriginRect: TRect; AStage: TdxPSRenderStages);
|
|
|
|
function PrepareCustomDraw(AnItem: TAbstractdxReportCellData): TAbstractdxReportCellData;
|
|
begin
|
|
Result := TAbstractdxReportCellData(AnItem.Clone(nil));
|
|
Renderer.PrepareCanvasForCustomDraw(AnItem.Font, AnItem.Color);
|
|
end;
|
|
|
|
procedure UnprepareCustomDraw(AnItem: TAbstractdxReportCellData; var ASavedItem: TAbstractdxReportCellData);
|
|
begin
|
|
if AnItem.FontIndex = -1 then
|
|
with ReportCells.GetFontByIndex(ASavedItem.FontIndex) do
|
|
begin
|
|
SelectObject(DC, Handle);
|
|
SetTextColor(DC, ColorToRGB(Color));
|
|
end;
|
|
AnItem.Assign(ASavedItem);
|
|
FreeAndNil(ASavedItem);
|
|
Renderer.UnprepareCanvasForCustomDraw;
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
Item, SavedItem: TAbstractdxReportCellData;
|
|
IsCustomDrawn: Boolean;
|
|
begin
|
|
for I := DataItemCount - 1 downto 0 do
|
|
begin
|
|
Item := DataItems[I];
|
|
if Item.IsDrawingNeeded(DC, AStage, OriginRect) then
|
|
begin
|
|
SavedItem := nil;
|
|
IsCustomDrawn := Item.IsCustomDrawn;
|
|
if IsCustomDrawn then SavedItem := PrepareCustomDraw(Item);
|
|
try
|
|
if not Item.CustomDraw(DC) then Item.DrawContent(DC, AStage);
|
|
finally
|
|
if IsCustomDrawn then UnprepareCustomDraw(Item, SavedItem);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCell.ExcludeNestedItems(DC: HDC; const OriginRect: TRect): Integer;
|
|
|
|
procedure ExcludeNestedCells(DC: HDC; const OriginRect: TRect; var AResult: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to CellCount - 1 do
|
|
with Cells[I] do
|
|
begin
|
|
DoExcludeFromClipRgn(DC, OriginRect, AResult);
|
|
if AResult = NULLREGION then Break;
|
|
end;
|
|
end;
|
|
|
|
procedure ExcludeNestedDataItems(DC: HDC; const OriginRect: TRect; var AResult: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to DataItemCount - 1 do
|
|
with DataItems[I] do
|
|
begin
|
|
DoExcludeFromClipRgn(DC, OriginRect, AResult);
|
|
if AResult = NULLREGION then Break;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Result := SIMPLEREGION;
|
|
ExcludeNestedCells(DC, OriginRect, Result);
|
|
if Result <> NULLREGION then
|
|
ExcludeNestedDataItems(DC, OriginRect, Result);
|
|
end;
|
|
|
|
function TdxReportCell.GetBorderOuterBounds(DC: HDC): TRect;
|
|
begin
|
|
// Result := GetOuterBounds(DC);
|
|
Result := BoundsRect;
|
|
OffsetRect(Result, -Result.Left, -Result.Top);
|
|
Result := GetBorderOuterBoundsRelativeTo(DC, GetOuterBoundsRelativeTo(DC, Result));
|
|
end;
|
|
|
|
function TdxReportCell.GetInnerBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := BoundsRect;
|
|
OffsetRect(Result, -Result.Left, -Result.Top);
|
|
Result := GetInnerBoundsRelativeTo(DC, Result);
|
|
end;
|
|
|
|
function TdxReportCell.GetOuterBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := BoundsRect;
|
|
OffsetRect(Result, -Result.Left, -Result.Top);
|
|
Result := GetOuterBoundsRelativeTo(DC, Result);
|
|
end;
|
|
|
|
function TdxReportCell.MeasureHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := Height;
|
|
end;
|
|
|
|
function TdxReportCell.MeasureWidth(DC: HDC): Integer;
|
|
begin
|
|
Result := Width;
|
|
end;
|
|
|
|
procedure TdxReportCell.InsertCell(AnItem: TdxReportCell);
|
|
begin
|
|
CellListNeeded;
|
|
FCellList.Add(AnItem);
|
|
AnItem.FReportCells := FReportCells;
|
|
end;
|
|
|
|
procedure TdxReportCell.InsertDataItem(AnItem: TdxReportItem);
|
|
begin
|
|
DataListNeeded;
|
|
FDataList.Add(AnItem);
|
|
end;
|
|
|
|
procedure TdxReportCell.InsertItem(AnItem: TdxReportItem);
|
|
begin
|
|
if AnItem.IsCell then
|
|
InsertCell(AnItem.AsCell)
|
|
else
|
|
InsertDataItem(AnItem);
|
|
AnItem.FParent := Self;
|
|
end;
|
|
|
|
procedure TdxReportCell.MoveCell(ACurIndex, ANewIndex: Integer);
|
|
begin
|
|
FCellList.Move(ACurIndex, ANewIndex);
|
|
end;
|
|
|
|
procedure TdxReportCell.MoveDataItem(ACurIndex, ANewIndex: Integer);
|
|
begin
|
|
FDataList.Move(ACurIndex, ANewIndex);
|
|
end;
|
|
|
|
procedure TdxReportCell.MoveItem(AnItem: TdxReportItem; ACurIndex, ANewIndex: Integer);
|
|
begin
|
|
if AnItem.IsCell then
|
|
MoveCell(ACurIndex, ANewIndex)
|
|
else
|
|
MoveDataItem(ACurIndex, ANewIndex);
|
|
end;
|
|
|
|
procedure TdxReportCell.RemoveCell(AnItem: TdxReportCell);
|
|
begin
|
|
if FCellList <> nil then
|
|
begin
|
|
FCellList.Remove(AnItem);
|
|
CellListRelease;
|
|
end
|
|
end;
|
|
|
|
procedure TdxReportCell.RemoveDataItem(AnItem: TdxReportItem);
|
|
begin
|
|
if FDataList <> nil then
|
|
begin
|
|
FDataList.Remove(AnItem);
|
|
DataListRelease;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.RemoveItem(AnItem: TdxReportItem);
|
|
begin
|
|
if AnItem.IsCell then
|
|
RemoveCell(AnItem.AsCell)
|
|
else
|
|
RemoveDataItem(AnItem);
|
|
AnItem.FParent := nil;
|
|
end;
|
|
|
|
procedure TdxReportCell.SetClipChildren(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatClipChildren, Value);
|
|
end;
|
|
|
|
function TdxReportCell.GetAbsoluteIndex: Integer;
|
|
var
|
|
Cell: TdxReportCell;
|
|
begin
|
|
Cell := Self;
|
|
Result := 0;
|
|
while Cell <> nil do
|
|
begin
|
|
Inc(Result, Cell.Index);
|
|
Cell := Cell.Parent;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCell.GetLevel: Integer;
|
|
var
|
|
Cell: TdxReportCell;
|
|
begin
|
|
Result := 0;
|
|
Cell := Parent;
|
|
while Cell <> nil do
|
|
begin
|
|
Inc(Result);
|
|
Cell := Cell.Parent;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.AllocateSpaceForCells(ACapacity: Integer);
|
|
begin
|
|
CellListNeeded;
|
|
if ACapacity > FCellList.Capacity then FCellList.Capacity := ACapacity;
|
|
end;
|
|
|
|
procedure TdxReportCell.AllocateSpaceForDatas(ACapacity: Integer);
|
|
begin
|
|
DataListNeeded;
|
|
if ACapacity > FDataList.Capacity then FDataList.Capacity := ACapacity;
|
|
end;
|
|
|
|
function TdxReportCell.GetReportCells: TdxReportCells;
|
|
begin
|
|
Result := FReportCells;
|
|
end;
|
|
|
|
procedure TdxReportCell.CellListNeeded;
|
|
begin
|
|
if FCellList = nil then FCellList := TList.Create;
|
|
end;
|
|
|
|
procedure TdxReportCell.CellListRelease;
|
|
begin
|
|
if CellCount = 0 then FreeAndNil(FCellList);
|
|
end;
|
|
|
|
procedure TdxReportCell.DataListNeeded;
|
|
begin
|
|
if FDataList = nil then FDataList := TList.Create;
|
|
end;
|
|
|
|
procedure TdxReportCell.DataListRelease;
|
|
begin
|
|
if DataItemCount = 0 then FreeAndNil(FDataList);
|
|
end;
|
|
|
|
procedure TdxReportCell.ClearAll;
|
|
begin
|
|
ClearCells;
|
|
ClearDataItems;
|
|
end;
|
|
|
|
procedure TdxReportCell.ClearCells;
|
|
begin
|
|
if FCellList <> nil then
|
|
begin
|
|
while CellCount > 0 do Cells[CellCount - 1].Free;
|
|
CellListRelease;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.ClearDataItems;
|
|
begin
|
|
if FDataList <> nil then
|
|
begin
|
|
while DataItemCount > 0 do DataItems[DataItemCount - 1].Free;
|
|
DataListRelease;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCell.GetCell(Index: Integer): TdxReportCell;
|
|
begin
|
|
Result := TdxReportCell(FCellList[Index]);
|
|
end;
|
|
|
|
function TdxReportCell.GetClipChildren: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatClipChildren);
|
|
end;
|
|
|
|
function TdxReportCell.GetCellCount: Integer;
|
|
begin
|
|
if FCellList <> nil then
|
|
Result := FCellList.Count
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportCell.GetDataItem(Index: Integer): TAbstractdxReportCellData;
|
|
begin
|
|
Result := TAbstractdxReportCellData(FDataList[Index]);
|
|
end;
|
|
|
|
function TdxReportCell.GetIsTopLevel: Boolean;
|
|
begin
|
|
Result := Level = 1;
|
|
end;
|
|
|
|
function TdxReportCell.GetDataItemCount: Integer;
|
|
begin
|
|
if FDataList <> nil then
|
|
Result := FDataList.Count
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportCell.IndexOf(AnItem: TdxReportItem): Integer;
|
|
begin
|
|
Result := -1;
|
|
if AnItem.IsCell then
|
|
begin
|
|
if FCellList <> nil then
|
|
Result := FCellList.IndexOf(AnItem)
|
|
end
|
|
else
|
|
if FDataList <> nil then
|
|
Result := FDataList.IndexOf(AnItem);
|
|
end;
|
|
|
|
class function TdxReportCell.IsCell: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TdxReportCell.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited ReadData(AReader);
|
|
ReadProperties(AReader);
|
|
ReadCells(AReader);
|
|
ReadDataItems(AReader);
|
|
end;
|
|
|
|
procedure TdxReportCell.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited WriteData(AWriter);
|
|
WriteProperties(AWriter);
|
|
WriteCells(AWriter);
|
|
WriteDataItems(AWriter);
|
|
end;
|
|
|
|
procedure TdxReportCell.ReadCells(AReader: TdxPSDataReader);
|
|
|
|
procedure LoadCell;
|
|
var
|
|
CellClassName: string;
|
|
CellClass: TdxReportCellClass;
|
|
Cell: TdxReportCell;
|
|
begin
|
|
CellClassName := AReader.ReadString;
|
|
CellClass := TdxReportCellClass(GetClass(CellClassName));
|
|
if CellClass = nil then
|
|
Assert(CellClass <> nil);
|
|
if CellClass <> nil then
|
|
begin
|
|
Cell := CellClass.Create(Self);
|
|
Cell.ReadData(AReader);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
ClearCells;
|
|
AReader.ReadListBegin;
|
|
try
|
|
while not AReader.EndOfList do LoadCell;
|
|
finally
|
|
AReader.ReadListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.ReadDataItems(AReader: TdxPSDataReader);
|
|
|
|
procedure LoadDataItem;
|
|
var
|
|
DataItemClassName: string;
|
|
DataItemClass: TdxReportCellDataClass;
|
|
DataItem: TAbstractdxReportCellData;
|
|
begin
|
|
try
|
|
DataItemClassName := AReader.ReadString;
|
|
DataItemClass := TdxReportCellDataClass(GetClass(DataItemClassName));
|
|
Assert(DataItemClass <> nil);
|
|
except
|
|
ShowMessage(DataItemClassName);
|
|
raise;
|
|
end;
|
|
if DataItemClass <> nil then
|
|
begin
|
|
DataItem := DataItemClass.Create(Self);
|
|
DataItem.ReadData(AReader);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
ClearDataItems;
|
|
AReader.ReadListBegin;
|
|
try
|
|
while not AReader.EndOfList do
|
|
LoadDataItem;
|
|
finally
|
|
AReader.ReadListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.ReadProperties(AReader: TdxPSDataReader);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportCell.WriteCells(AWriter: TdxPSDataWriter);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AWriter.WriteListBegin;
|
|
try
|
|
for I := 0 to CellCount - 1 do
|
|
with Cells[I] do
|
|
if Serializable then
|
|
begin
|
|
AWriter.WriteString(ClassName);
|
|
WriteData(AWriter);
|
|
end;
|
|
finally
|
|
AWriter.WriteListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.WriteDataItems(AWriter: TdxPSDataWriter);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AWriter.WriteListBegin;
|
|
try
|
|
for I := 0 to DataItemCount - 1 do
|
|
with DataItems[I] do
|
|
if Serializable then
|
|
begin
|
|
AWriter.WriteString(ClassName);
|
|
WriteData(AWriter);
|
|
end;
|
|
finally
|
|
AWriter.WriteListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCell.WriteProperties(AWriter: TdxPSDataWriter);
|
|
begin
|
|
end;
|
|
|
|
function TdxReportCell.AddCell: TdxReportCell;
|
|
begin
|
|
Result := TdxReportCell.Create(Self);
|
|
end;
|
|
|
|
function TdxReportCell.AddDataItem(AClass: TdxReportCellDataClass): TAbstractdxReportCellData;
|
|
begin
|
|
Result := AClass.Create(Self);
|
|
end;
|
|
|
|
procedure TdxReportCell.DeleteCell(Index: Integer);
|
|
var
|
|
Cell: TdxReportCell;
|
|
begin
|
|
Cell := Cells[Index];
|
|
Cell.Parent := nil;
|
|
end;
|
|
|
|
procedure TdxReportCell.DeleteDataItem(Index: Integer);
|
|
var
|
|
DataItem: TAbstractdxReportCellData;
|
|
begin
|
|
DataItem := DataItems[Index];
|
|
DataItem.Parent := nil;
|
|
end;
|
|
|
|
function TdxReportCell.LastCell: TdxReportCell;
|
|
begin
|
|
if CellCount > 0 then
|
|
Result := TdxReportCell(FCellList.Last)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxReportCell.FirstCell: TdxReportCell;
|
|
begin
|
|
if CellCount > 0 then
|
|
Result := TdxReportCell(FCellList.First)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxReportCell.HasChildren: Boolean;
|
|
begin
|
|
Result := CellCount > 0;
|
|
end;
|
|
|
|
procedure TdxReportCell.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to DataItemCount - 1 do
|
|
DataItems[I].ConvertCoords(PixelsNumerator, PixelsDenominator);
|
|
for I := 0 to CellCount - 1 do
|
|
Cells[I].ConvertCoords(PixelsNumerator, PixelsDenominator);
|
|
inherited;
|
|
end;
|
|
|
|
function TdxReportCell.GetBackgroundBitmapTileBounds(Col, Row: Integer): TRect;
|
|
begin
|
|
Result := inherited GetBackgroundBitmapTileBounds(Col, Row);
|
|
OffsetRect(Result, -Left, -Top);
|
|
end;
|
|
|
|
function TdxReportCell.GetBackgroundBounds(DC: HDC): TRect;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := BoundsRect;
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
Result := GetInnerBoundsRelativeTo(DC, R);
|
|
end;
|
|
|
|
function TdxReportCell.GetBorderBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := inherited GetBorderBounds(DC);
|
|
OffsetRect(Result, -Result.Left, -Result.Top);
|
|
end;
|
|
|
|
{ TdxPSReportGroupLookAndFeelPainter }
|
|
|
|
constructor TdxPSReportGroupLookAndFeelPainter.Create(ARenderer: TdxPSReportRenderer);
|
|
begin
|
|
inherited Create;
|
|
FRenderer := ARenderer;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeelPainter.Paint(DC: HDC);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeelPainter.DrawBorders(DC: HDC);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeelPainter.DrawCaptionText(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := LookAndFeel.GetCaptionTextBounds(Group);
|
|
if RectVisible(DC, R) then
|
|
Renderer.DrawText(DC, R, 1, 0, 0, Group.CaptionText, LookAndFeel.CaptionFont,
|
|
LookAndFeel.GetCaptionColor, Group.CaptionAlignment, taCenterY, not Group.CaptionTransparent,
|
|
False, False, False, False, True);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeelPainter.Initialize(ALookAndFeel: TdxPSReportGroupLookAndFeel;
|
|
AGroup: TdxReportGroup);
|
|
begin
|
|
FGroup := AGroup;
|
|
FLookAndFeel := ALookAndFeel;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeelPainter.Group: TdxReportGroup;
|
|
begin
|
|
Result := FGroup;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeelPainter.LookAndFeel: TdxPSReportGroupLookAndFeel;
|
|
begin
|
|
Result := FLookAndFeel;
|
|
end;
|
|
|
|
{ TdxPSReportGroupLookAndFeel }
|
|
|
|
constructor TdxPSReportGroupLookAndFeel.Create(AReportCells: TdxReportCells);
|
|
begin
|
|
inherited Create;
|
|
FReportCells := AReportCells;
|
|
FCaptionFontIndex := -1;
|
|
FCaptionHeight := 0;
|
|
FCaptionIndent := dxDefaultReportGroupCaptionIndent;
|
|
FColor := dxDefaultGroupColor;
|
|
FFontIndex := -1;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxPSReportGroupLookAndFeel then
|
|
with TdxPSReportGroupLookAndFeel(Source) do
|
|
begin
|
|
Self.CaptionFontIndex := CaptionFontIndex;
|
|
Self.FCaptionIndent := CaptionIndent;
|
|
Self.Color := Color;
|
|
Self.FontIndex := FontIndex;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
class function TdxPSReportGroupLookAndFeel.BorderClass: TdxPSCellBorderClass;
|
|
begin
|
|
Result := TdxPSCellEtchedBorder;
|
|
end;
|
|
|
|
class function TdxPSReportGroupLookAndFeel.DefaultBorderSides: TdxCellSides;
|
|
begin
|
|
Result := csAll;
|
|
end;
|
|
|
|
class function TdxPSReportGroupLookAndFeel.Name: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
class procedure TdxPSReportGroupLookAndFeel.Register;
|
|
begin
|
|
if GetClass(ClassName) = nil then RegisterClass(Self);
|
|
end;
|
|
|
|
class procedure TdxPSReportGroupLookAndFeel.Unregister;
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.Paint(DC: HDC; AGroup: TdxReportGroup);
|
|
begin
|
|
with GetPainter do
|
|
begin
|
|
Initialize(Self, AGroup);
|
|
Paint(DC);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.Prepare(DC: HDC);
|
|
begin
|
|
FCaptionHeight := 2 * Renderer.CalcTextPatternHeight(DC, CaptionFont) div 2;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
|
|
begin
|
|
FCaptionHeight := MulDiv(FCaptionHeight, APixelsNumerator, APixelsDenominator);
|
|
FCaptionIndent := MulDiv(FCaptionIndent, APixelsNumerator, APixelsDenominator);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
FCaptionHeight := AReader.ReadInteger;
|
|
CaptionFontIndex := AReader.ReadInteger;
|
|
FCaptionIndent := AReader.ReadInteger;
|
|
Color := AReader.ReadInteger;
|
|
Data := Pointer(AReader.ReadInteger);
|
|
FontIndex := AReader.ReadInteger;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
AWriter.WriteInteger(CaptionHeight);
|
|
AWriter.WriteInteger(CaptionFontIndex);
|
|
AWriter.WriteInteger(CaptionIndent);
|
|
AWriter.WriteInteger(Color);
|
|
AWriter.WriteInteger(Integer(Data));
|
|
AWriter.WriteInteger(FontIndex);
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetBorderEdgeThickness(AGroup: TdxReportGroup;
|
|
ASide: TdxCellSide): Integer;
|
|
begin
|
|
if ASide = csTop then
|
|
begin
|
|
Result := BorderThickness;
|
|
if Renderer.IsRendering and (Renderer.LineThickness <> 0) then
|
|
Result := Result * Renderer.LineThickness;
|
|
if AGroup.ShowCaption then
|
|
Inc(Result, CaptionAreaHeight);
|
|
if Renderer.IsRendering and (Renderer.LineThickness <> 0) then
|
|
Result := Result div Renderer.LineThickness;
|
|
end
|
|
else
|
|
Result := AGroup.InternalGetBorderEdgeThickness(ASide);
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetBorderThickness: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetColor: TColor;
|
|
begin
|
|
Result := FColor;
|
|
if Result = clDefault then Result := ReportCells.GroupColor;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.SetBorderThickness(Value: Integer);
|
|
begin
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionAreaHeight: Integer;
|
|
begin
|
|
Result := CaptionHeight;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionBounds(AGroup: TdxReportGroup): TRect;
|
|
begin
|
|
Result := AGroup.BoundsRect;
|
|
Result.Bottom := Result.Top + CaptionHeight;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionColor: TColor;
|
|
begin
|
|
Result := Color;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionHeight: Integer;
|
|
begin
|
|
Result := FCaptionHeight;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionIndent: Integer;
|
|
begin
|
|
Result := FCaptionIndent;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionLeftRestSpaceBounds(AGroup: TdxReportGroup): TRect;
|
|
begin
|
|
if not AGroup.Transparent then
|
|
begin
|
|
Result := GetCaptionBounds(AGroup);
|
|
Result.Right := GetCaptionTextBounds(AGroup).Left;
|
|
end
|
|
else
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionRightRestSpaceBounds(AGroup: TdxReportGroup): TRect;
|
|
begin
|
|
if not AGroup.Transparent then
|
|
begin
|
|
Result := GetCaptionBounds(AGroup);
|
|
Result.Left := GetCaptionTextBounds(AGroup).Right;
|
|
end
|
|
else
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionTextBounds(AGroup: TdxReportGroup): TRect;
|
|
var
|
|
TextWidth: Integer;
|
|
begin
|
|
Result := NullRect;
|
|
if AGroup.ShowCaption then
|
|
begin
|
|
TextWidth := AGroup.CaptionTextWidth;
|
|
if TextWidth <> 0 then
|
|
begin
|
|
Result := AGroup.BoundsRect;
|
|
OffsetRect(Result, -Result.Left, -Result.Top);
|
|
InflateRect(Result, -CaptionIndent, 0);
|
|
|
|
if not IsRectEmpty(Result) then
|
|
with Result do
|
|
begin
|
|
case AGroup.CaptionAlignment of
|
|
taLeft:
|
|
Right := Left + TextWidth;
|
|
taCenterX:
|
|
begin
|
|
Inc(Left, (Right - Left - TextWidth) div 2);
|
|
Right := Left + TextWidth;
|
|
end;
|
|
taRight:
|
|
Left := Right - TextWidth;
|
|
end;
|
|
Bottom := Top + CaptionHeight;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetPainter: TdxPSReportGroupLookAndFeelPainter;
|
|
begin
|
|
Result := Renderer.GetReportGroupLookAndFeelPainter(GetPainterClass);
|
|
end;
|
|
|
|
class function TdxPSReportGroupLookAndFeel.GetPainterClass: TdxPSReportGroupLookAndFeelPainterClass;
|
|
begin
|
|
Result := nil; // Actually method must be declared as "abstract" but "C++" syntax does not allow us to use "static virtual abstract" methods
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetCaptionFont: TFont;
|
|
begin
|
|
if CaptionFontIndex <> -1 then
|
|
Result := ReportCells.GetFontByIndex(CaptionFontIndex)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetFont: TFont;
|
|
begin
|
|
if FontIndex <> -1 then
|
|
Result := ReportCells.GetFontByIndex(FontIndex)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxPSReportGroupLookAndFeel.GetRenderer: TdxPSReportRenderer;
|
|
begin
|
|
Result := ReportCells.Renderer;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.SetCaptionFont(Value: TFont);
|
|
begin
|
|
CaptionFontIndex := ReportCells.GetIndexByFont(Value);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.SetCaptionFontIndex(Value: Integer);
|
|
begin
|
|
if Value < -1 then Value := -1;
|
|
FCaptionFontIndex := Value;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.SetFont(Value: TFont);
|
|
begin
|
|
FontIndex := ReportCells.GetIndexByFont(Value);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupLookAndFeel.SetFontIndex(Value: Integer);
|
|
begin
|
|
if Value < -1 then Value := -1;
|
|
FFontIndex := Value;
|
|
end;
|
|
|
|
{ TdxPSReportGroupNullLookAndFeelPainter }
|
|
|
|
procedure TdxPSReportGroupNullLookAndFeelPainter.Paint(DC: HDC);
|
|
begin
|
|
end;
|
|
|
|
{ TdxPSReportGroupNullLookAndFeel }
|
|
|
|
class function TdxPSReportGroupNullLookAndFeel.BorderClass: TdxPSCellBorderClass;
|
|
begin
|
|
Result := TdxPSCellUltraFlatBorder;
|
|
end;
|
|
|
|
class function TdxPSReportGroupNullLookAndFeel.DefaultBorderSides: TdxCellSides;
|
|
begin
|
|
Result := [];
|
|
end;
|
|
|
|
class function TdxPSReportGroupNullLookAndFeel.Name: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxReportGroupNullLookAndFeel);
|
|
end;
|
|
|
|
function TdxPSReportGroupNullLookAndFeel.GetBorderThickness: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TdxPSReportGroupNullLookAndFeel.GetCaptionHeight: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
class function TdxPSReportGroupNullLookAndFeel.GetPainterClass: TdxPSReportGroupLookAndFeelPainterClass;
|
|
begin
|
|
Result := TdxPSReportGroupNullLookAndFeelPainter;
|
|
end;
|
|
|
|
{ TdxPSReportGroupStandardLookAndFeelPainter }
|
|
|
|
procedure TdxPSReportGroupStandardLookAndFeelPainter.Paint(DC: HDC);
|
|
var
|
|
Rgn: HRGN;
|
|
begin
|
|
DrawCaptionRestSpace(DC);
|
|
DrawCaptionText(DC);
|
|
if Group.IsBordersDrawn then
|
|
begin
|
|
Rgn := Renderer.ExcludeClipRect(LookAndFeel.GetCaptionTextBounds(Group));
|
|
DrawBorders(DC);
|
|
Renderer.RestoreClipRgn(Rgn);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupStandardLookAndFeelPainter.DrawBorders(DC: HDC);
|
|
begin
|
|
Group.InternalDrawBorders(DC);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupStandardLookAndFeelPainter.DrawCaptionRestSpace(DC: HDC);
|
|
|
|
procedure DrawCaptionPart(const R: TRect);
|
|
begin
|
|
if RectVisible(DC, R) then
|
|
Renderer.FillRect(DC, R, LookAndFeel.Color);
|
|
end;
|
|
|
|
begin
|
|
DrawCaptionPart(LookAndFeel.GetCaptionLeftRestSpaceBounds(Group));
|
|
DrawCaptionPart(LookAndFeel.GetCaptionRightRestSpaceBounds(Group));
|
|
end;
|
|
|
|
function TdxPSReportGroupStandardLookAndFeelPainter.LookAndFeel: TdxPSReportGroupStandardLookAndFeel;
|
|
begin
|
|
Result := inherited LookAndFeel as TdxPSReportGroupStandardLookAndFeel;
|
|
end;
|
|
|
|
{ TdxPSReportGroupStandardLookAndFeel }
|
|
|
|
class function TdxPSReportGroupStandardLookAndFeel.BorderClass: TdxPSCellBorderClass;
|
|
begin
|
|
Result := TdxPSCellEtchedBorder;
|
|
end;
|
|
|
|
class function TdxPSReportGroupStandardLookAndFeel.Name: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxReportGroupStandardLookAndFeel);
|
|
end;
|
|
|
|
class function TdxPSReportGroupStandardLookAndFeel.GetPainterClass: TdxPSReportGroupLookAndFeelPainterClass;
|
|
begin
|
|
Result := TdxPSReportGroupStandardLookAndFeelPainter;
|
|
end;
|
|
|
|
{ TdxPSReportGroupOfficeLookAndFeel }
|
|
|
|
class function TdxPSReportGroupOfficeLookAndFeel.DefaultBorderSides: TdxCellSides;
|
|
begin
|
|
Result := [csTop];
|
|
end;
|
|
|
|
class function TdxPSReportGroupOfficeLookAndFeel.Name: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxReportGroupOfficeLookAndFeel);
|
|
end;
|
|
|
|
function TdxPSReportGroupOfficeLookAndFeel.GetCaptionIndent: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
{ TdxPSReportGroupWebLookAndFeelPainter }
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeelPainter.Paint(DC: HDC);
|
|
begin
|
|
DrawBorders(DC);
|
|
DrawCaptionText(DC);
|
|
DrawCaptionSeparator(DC);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeelPainter.DrawBorders(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := Group.BoundsRect;
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
Renderer.FrameRect(DC, R, LookAndFeel.BorderColor, Group.CellSides, LookAndFeel.BorderThickness);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeelPainter.DrawCaptionSeparator(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := LookAndFeel.GetCaptionSeparatorBounds(Group);
|
|
if RectVisible(DC, R) then
|
|
Renderer.FillRect(DC, R, LookAndFeel.CaptionSeparatorColor);
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeelPainter.LookAndFeel: TdxPSReportGroupWebLookAndFeel;
|
|
begin
|
|
Result := inherited LookAndFeel as TdxPSReportGroupWebLookAndFeel;
|
|
end;
|
|
|
|
{ TdxPSReportGroupWebLookAndFeel }
|
|
|
|
constructor TdxPSReportGroupWebLookAndFeel.Create(AReportCells: TdxReportCells);
|
|
begin
|
|
inherited Create(AReportCells);
|
|
BorderColor := clDefault;
|
|
BorderThickness := 1;
|
|
CaptionColor := clDefault;
|
|
CaptionSeparatorColor := clDefault;
|
|
CaptionSeparatorThickness := 0;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeel.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxPSReportGroupWebLookAndFeel then
|
|
with TdxPSReportGroupWebLookAndFeel(Source) do
|
|
begin
|
|
Self.BorderColor := BorderColor;
|
|
Self.BorderThickness := BorderThickness;
|
|
Self.CaptionColor := CaptionColor;
|
|
Self.CaptionSeparatorColor := CaptionSeparatorColor;
|
|
Self.CaptionSeparatorThickness := CaptionSeparatorThickness;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
class function TdxPSReportGroupWebLookAndFeel.BorderClass: TdxPSCellBorderClass;
|
|
begin
|
|
Result := TdxPSCellUltraFlatBorder;
|
|
end;
|
|
|
|
class function TdxPSReportGroupWebLookAndFeel.Name: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxReportGroupWebLookAndFeel);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeel.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
|
|
begin
|
|
inherited;
|
|
CaptionSeparatorThickness := MulDiv(CaptionSeparatorThickness, APixelsNumerator, APixelsDenominator);
|
|
end;
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeel.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited ReadData(AReader);
|
|
BorderColor := AReader.ReadInteger;
|
|
BorderThickness := AReader.ReadInteger;
|
|
CaptionColor := AReader.ReadInteger;
|
|
CaptionSeparatorColor := AReader.ReadInteger;
|
|
CaptionSeparatorThickness := AReader.ReadInteger;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeel.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited WriteData(AWriter);
|
|
AWriter.WriteInteger(BorderColor);
|
|
AWriter.WriteInteger(BorderThickness);
|
|
AWriter.WriteInteger(CaptionColor);
|
|
AWriter.WriteInteger(CaptionSeparatorColor);
|
|
AWriter.WriteInteger(CaptionSeparatorThickness);
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetBorderEdgeThickness(AGroup: TdxReportGroup;
|
|
ASide: TdxCellSide): Integer;
|
|
begin
|
|
if ASide = csTop then
|
|
Result := inherited GetBorderEdgeThickness(AGroup, ASide)
|
|
else
|
|
Result := BorderThickness;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetBorderThickness: Integer;
|
|
begin
|
|
Result := FBorderThickness;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeel.SetBorderThickness(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
FBorderThickness := Value;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetCaptionAreaHeight: Integer;
|
|
begin
|
|
Result := inherited GetCaptionAreaHeight + CaptionSeparatorThickness;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetCaptionBounds(AGroup: TdxReportGroup): TRect;
|
|
begin
|
|
if AGroup.ShowCaption then
|
|
begin
|
|
Result := AGroup.BoundsRect;
|
|
OffsetRect(Result, -Result.Left, -Result.Top);
|
|
InflateRect(Result, -BorderThickness * Renderer.LineThickness, -BorderThickness * Renderer.LineThickness);
|
|
Result.Bottom := Result.Top + CaptionHeight;
|
|
end
|
|
else
|
|
Result := NullRect;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetCaptionLeftRestSpaceBounds(AGroup: TdxReportGroup): TRect;
|
|
begin
|
|
Result := NullRect;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetCaptionRightRestSpaceBounds(AGroup: TdxReportGroup): TRect;
|
|
begin
|
|
Result := NullRect;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetCaptionSeparatorBounds(AGroup: TdxReportGroup): TRect;
|
|
begin
|
|
Result := GetCaptionBounds(AGroup);
|
|
if AGroup.ShowCaption then
|
|
begin
|
|
Result.Top := Result.Bottom;
|
|
Result.Bottom := Result.Top + CaptionSeparatorThickness;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetCaptionTextBounds(AGroup: TdxReportGroup): TRect;
|
|
begin
|
|
Result := GetCaptionBounds(AGroup);
|
|
end;
|
|
|
|
class function TdxPSReportGroupWebLookAndFeel.GetPainterClass: TdxPSReportGroupLookAndFeelPainterClass;
|
|
begin
|
|
Result := TdxPSReportGroupWebLookAndFeelPainter;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetBorderColor: TColor;
|
|
begin
|
|
Result := FBorderColor;
|
|
if Result = clDefault then Result := ReportCells.GroupBorderColor;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetCaptionColor: TColor;
|
|
begin
|
|
Result := FCaptionColor;
|
|
if Result = clDefault then Result := ReportCells.GroupCaptionColor;
|
|
end;
|
|
|
|
function TdxPSReportGroupWebLookAndFeel.GetCaptionSeparatorColor: TColor;
|
|
begin
|
|
Result := FCaptionSeparatorColor;
|
|
if Result = clDefault then Result := ReportCells.GroupCaptionSeparatorColor;
|
|
end;
|
|
|
|
procedure TdxPSReportGroupWebLookAndFeel.SetCaptionSeparatorThickness(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
FCaptionSeparatorThickness := Value;
|
|
end;
|
|
|
|
{ TdxReportGroup }
|
|
|
|
constructor TdxReportGroup.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create(AParent);
|
|
CaptionAlignment := taLeft;
|
|
ClipChildren := True;
|
|
ShowCaption := True;
|
|
end;
|
|
|
|
procedure TdxReportGroup.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxReportGroup then
|
|
begin
|
|
inherited;
|
|
with TdxReportGroup(Source) do
|
|
begin
|
|
Self.CaptionText := CaptionText;
|
|
Self.LookAndFeel := LookAndFeel;
|
|
end;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxReportGroup.DrawBorders(DC: HDC);
|
|
begin
|
|
if LookAndFeel <> nil then
|
|
LookAndFeel.Paint(DC, Self)
|
|
else
|
|
inherited DrawBorders(DC);
|
|
end;
|
|
|
|
procedure TdxReportGroup.CalculateCaptionTextWidth(DC: HDC);
|
|
var
|
|
F: TFont;
|
|
begin
|
|
FCaptionTextWidth := 0;
|
|
if CaptionText <> '' then
|
|
begin
|
|
if LookAndFeel <> nil then
|
|
F := LookAndFeel.CaptionFont
|
|
else
|
|
F := Font;
|
|
|
|
FCaptionTextWidth := Renderer.CalcTextWidth(DC, CaptionText, F);
|
|
if FCaptionTextWidth > 0 then
|
|
Inc(FCaptionTextWidth, 2 + 2);
|
|
end;
|
|
end;
|
|
|
|
function TdxReportGroup.GetBorderOuterBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := inherited GetBorderOuterBounds(DC);
|
|
if ShowCaption and (LookAndFeel <> nil) then
|
|
Inc(Result.Top, LookAndFeel.CaptionHeight div 2);
|
|
end;
|
|
|
|
procedure TdxReportGroup.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
|
|
begin
|
|
inherited;
|
|
FCaptionTextWidth := MulDiv(FCaptionTextWidth, APixelsNumerator, APixelsDenominator);
|
|
end;
|
|
|
|
procedure TdxReportGroup.InternalDrawBorders(DC: HDC);
|
|
begin
|
|
inherited DrawBorders(DC);
|
|
end;
|
|
|
|
function TdxReportGroup.GetBorderClass: TdxPSCellBorderClass;
|
|
begin
|
|
if UseOwnBorderClass or (LookAndFeel = nil) then
|
|
Result := inherited GetBorderClass
|
|
else
|
|
Result := LookAndFeel.BorderClass;
|
|
end;
|
|
|
|
function TdxReportGroup.GetBorderEdgeSalient(ASide: TdxCellSide; ASalient: TdxPSCellBorderSalientType): Integer;
|
|
begin
|
|
if LookAndFeel <> nil then
|
|
if ASalient = bstOuter then
|
|
Result := 0
|
|
else
|
|
Result := GetBorderEdgeThickness(ASide)
|
|
else
|
|
Result := inherited GetBorderEdgeSalient(ASide, ASalient);
|
|
end;
|
|
|
|
function TdxReportGroup.GetBorderEdgeThickness(ASide: TdxCellSide): Integer;
|
|
begin
|
|
if LookAndFeel <> nil then
|
|
Result := LookAndFeel.GetBorderEdgeThickness(Self, ASide)
|
|
else
|
|
Result := inherited GetBorderEdgeThickness(ASide);
|
|
end;
|
|
|
|
function TdxReportGroup.InternalGetBorderEdgeThickness(ASide: TdxCellSide): Integer;
|
|
begin
|
|
Result := inherited GetBorderEdgeThickness(ASide);
|
|
end;
|
|
|
|
function TdxReportGroup.IsBordersDrawn: Boolean;
|
|
begin
|
|
Result := inherited IsBordersDrawn or (CaptionText <> '');
|
|
end;
|
|
|
|
procedure TdxReportGroup.ReadData(AReader: TdxPSDataReader);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
inherited ReadData(AReader);
|
|
CaptionText := AReader.ReadString;
|
|
FCaptionTextWidth := AReader.ReadInteger;
|
|
|
|
Index := AReader.ReadInteger;
|
|
if Index <> -1 then
|
|
LookAndFeel := ReportCells.LookAndFeels[Index];
|
|
end;
|
|
|
|
procedure TdxReportGroup.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited WriteData(AWriter);
|
|
AWriter.WriteString(CaptionText);
|
|
AWriter.WriteInteger(CaptionTextWidth);
|
|
AWriter.WriteInteger(LookAndFeelIndex);
|
|
end;
|
|
|
|
function TdxReportGroup.GetCaptionAlignment: TdxTextAlignX;
|
|
begin
|
|
Result := TdxTextAlignX((Format and dxPSGlbl.dxFormatTextAlignXMask) shr dxPSGlbl.dxFormatTextAlignXOffset);
|
|
end;
|
|
|
|
function TdxReportGroup.GetCaptionTextWidth: Integer;
|
|
begin
|
|
Result := FCaptionTextWidth;
|
|
end;
|
|
|
|
function TdxReportGroup.GetCaptionTransparent: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatGroupCaptionTransparent);
|
|
end;
|
|
|
|
function TdxReportGroup.GetLookAndFeel: TdxPSReportGroupLookAndFeel;
|
|
begin
|
|
Result := FLookAndFeel;
|
|
if Result = nil then
|
|
if Parent is TdxReportGroup then
|
|
Result := TdxReportGroup(Parent).LookAndFeel
|
|
else
|
|
Result := ReportCells.LookAndFeel;
|
|
end;
|
|
|
|
function TdxReportGroup.GetLookAndFeelIndex: Integer;
|
|
begin
|
|
if FLookAndFeel <> nil then
|
|
Result := ReportCells.IndexOfReportGroupLookAndFeel(LookAndFeel)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
function TdxReportGroup.GetShowCaption: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatGroupShowCaption);
|
|
end;
|
|
|
|
function TdxReportGroup.GetUseOwnBorderClass: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatOwnBorderClass);
|
|
end;
|
|
|
|
procedure TdxReportGroup.SetCaptionAlignment(Value: TdxTextAlignX);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatTextAlignXMask or (Byte(Value) shl dxPSGlbl.dxFormatTextAlignXOffset);
|
|
end;
|
|
|
|
procedure TdxReportGroup.SetCaptionTransparent(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatGroupCaptionTransparent, Value);
|
|
end;
|
|
|
|
procedure TdxReportGroup.SetLookAndFeel(Value: TdxPSReportGroupLookAndFeel);
|
|
begin
|
|
FLookAndFeel := Value;
|
|
end;
|
|
|
|
procedure TdxReportGroup.SetShowCaption(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatGroupShowCaption, Value);
|
|
end;
|
|
|
|
procedure TdxReportGroup.SetUseOwnBorderClass(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatOwnBorderClass, Value);
|
|
end;
|
|
|
|
{ TdxReportCells }
|
|
|
|
constructor TdxReportCells.Create(AReportLink: TBasedxReportLink);
|
|
begin
|
|
inherited Create;
|
|
FReportLink := AReportLink;
|
|
|
|
BorderColor := dxDefaultGridLineColor;
|
|
BorderWidth := 1;
|
|
ExpandButtonBorderColor := dxDefaultExpandButtonBorderColor;
|
|
GroupBorderColor := dxDefaultGroupBorderColor;
|
|
GroupCaptionColor := dxDefaultGroupCaptionColor;
|
|
GroupCaptionSeparatorColor := dxDefaultGroupCaptionSeparatorColor;
|
|
GroupColor := dxDefaultGroupColor;
|
|
ShadowColor := dxDefaultShadowColor;
|
|
ShadowDepth := dxDefaultShadowDepth;
|
|
TreeLineColor := dxDefaultTreeLineColor;
|
|
TreeLineStyle := tlsDot;
|
|
|
|
FLookAndFeels := TList.Create;
|
|
FLookAndFeel := CreateGroupLookAndFeel(dxDefaultReportGroupLookAndFeel);
|
|
CreateGroupLookAndFeel(TdxPSReportGroupNullLookAndFeel);
|
|
|
|
FImageLists := TList.Create;
|
|
|
|
FCells := TdxReportCell.Create(nil);
|
|
FCells.FReportCells := Self;
|
|
FCells.Color := dxDefaultContentColor;
|
|
end;
|
|
|
|
destructor TdxReportCells.Destroy;
|
|
begin
|
|
FreeAndNil(FCells);
|
|
FreeAndNilReportGroupLookAndFeels;
|
|
FreeAndNil(FFooterCells);
|
|
FreeAndNil(FHeaderCells);
|
|
FreeAndNilOverlays;
|
|
FreeAndNilImageLists;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxReportCells.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxReportCells then
|
|
with TdxReportCells(Source) do
|
|
begin
|
|
Self.BorderColor := BorderColor;
|
|
Self.BorderWidth := BorderWidth;
|
|
Self.ExpandButtonBorderColor := ExpandButtonBorderColor;
|
|
Self.GroupBorderColor := GroupBorderColor;
|
|
Self.GroupCaptionColor := GroupCaptionColor;
|
|
Self.GroupCaptionSeparatorColor := GroupCaptionSeparatorColor;
|
|
Self.GroupColor := GroupColor;
|
|
Self.ShadowColor := ShadowColor;
|
|
Self.ShadowDepth := ShadowDepth;
|
|
Self.TreeLineColor := TreeLineColor;
|
|
Self.TreeLineStyle := TreeLineStyle;
|
|
|
|
Self.Cells.Assign(Cells);
|
|
if AreHeaderCellsAllocated then Self.HeaderCells.Assign(HeaderCells);
|
|
if AreFooterCellsAllocated then Self.FooterCells.Assign(FooterCells);
|
|
if HasOverlays then Self.AssignOverlays(TdxReportCells(Source));
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxReportCells.ClearItems;
|
|
begin
|
|
FCells.ClearCells;
|
|
FCells.ClearDataItems;
|
|
end;
|
|
|
|
procedure TdxReportCells.ClearLookAndFeels;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to LookAndFeelCount - 1 do
|
|
LookAndFeels[I].Free;
|
|
FLookAndFeels.Clear;
|
|
end;
|
|
|
|
function TdxReportCells.CreateGroupLookAndFeel(AClass: TdxPSReportGroupLookAndFeelClass;
|
|
ACheckExisting: Boolean = True): TdxPSReportGroupLookAndFeel;
|
|
begin
|
|
if ACheckExisting then
|
|
Result := FindGroupLookAndFeelByClass(AClass)
|
|
else
|
|
Result := nil;
|
|
|
|
if Result = nil then
|
|
begin
|
|
Result := AClass.Create(Self);
|
|
FLookAndFeels.Add(Result);
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCells.FindGroupLookAndFeelByClass(AClass: TdxPSReportGroupLookAndFeelClass): TdxPSReportGroupLookAndFeel;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to LookAndFeelCount - 1 do
|
|
begin
|
|
Result := LookAndFeels[I];
|
|
if Result.ClassType = AClass then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxReportCells.FindGroupLookAndFeelByData(AData: Pointer): TdxPSReportGroupLookAndFeel;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to LookAndFeelCount - 1 do
|
|
begin
|
|
Result := LookAndFeels[I];
|
|
if Result.Data = AData then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxReportCells.IndexOfReportGroupLookAndFeel(ALookAndFeel: TdxPSReportGroupLookAndFeel): Integer;
|
|
begin
|
|
Result := FLookAndFeels.IndexOf(ALookAndFeel);
|
|
end;
|
|
|
|
procedure TdxReportCells.DoProgress(const APercentDone: Double);
|
|
begin
|
|
if ReportLink <> nil then ReportLink.DoProgress(APercentDone);
|
|
end;
|
|
|
|
function TdxReportCells.AddOverlay: TdxReportCell;
|
|
begin
|
|
Result := TdxReportCell.Create(nil);
|
|
Result.FReportCells := Self;
|
|
if FOverlays = nil then FOverlays := TList.Create;
|
|
FOverlays.Add(Result);
|
|
end;
|
|
|
|
procedure TdxReportCells.AppendOverlays(Source: TdxReportCells;
|
|
AnOffsetX: Integer = 0; AnOffsetY: Integer = 0);
|
|
|
|
procedure OffsetOverlayCells(AnOverlay: TdxReportCell; AnOffsetX, AnOffsetY: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (AnOffsetX <> 0) or (AnOffsetY <> 0) then
|
|
for I := 0 to AnOverlay.CellCount - 1 do
|
|
with AnOverlay.Cells[I] do
|
|
begin
|
|
Left := Left + AnOffsetX;
|
|
Top := Top + AnOffsetY;
|
|
end;
|
|
end;
|
|
|
|
procedure OffsetOverlayDataItems(AnOverlay: TdxReportCell; AnOffsetX, AnOffsetY: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (AnOffsetX <> 0) or (AnOffsetY <> 0) then
|
|
for I := 0 to AnOverlay.DataItemCount - 1 do
|
|
with AnOverlay.DataItems[I] do
|
|
begin
|
|
Left := Left + AnOffsetX;
|
|
Top := Top + AnOffsetY;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
Overlay: TdxReportCell;
|
|
begin
|
|
for I := 0 to Source.OverlayCount - 1 do
|
|
begin
|
|
Overlay := AddOverlay;
|
|
Overlay.Assign(Source.Overlays[I]);
|
|
OffsetOverlayCells(Overlay, AnOffsetX, AnOffsetY);
|
|
OffsetOverlayDataItems(Overlay, AnOffsetX, AnOffsetY);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.AssignOverlays(Source: TdxReportCells;
|
|
AnOffsetX: Integer = 0; AnOffsetY: Integer = 0);
|
|
begin
|
|
ClearOverlays;
|
|
AppendOverlays(Source, AnOffsetX, AnOffsetY);
|
|
end;
|
|
|
|
procedure TdxReportCells.ClearOverlays;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to OverlayCount - 1 do
|
|
Overlays[I].Free;
|
|
if FOverlays <> nil then
|
|
FOverlays.Clear;
|
|
end;
|
|
|
|
procedure TdxReportCells.DeleteOverlay(AnOverlay: TdxReportCell);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Index := IndexOfOverlay(AnOverlay);
|
|
if Index <> -1 then
|
|
begin
|
|
Overlays[Index].Free;
|
|
if OverlayCount = 0 then FreeAndNil(FOverlays);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.FreeAndNilOverlays;
|
|
begin
|
|
ClearOverlays;
|
|
FreeAndNil(FOverlays);
|
|
end;
|
|
|
|
function TdxReportCells.HasOverlays: Boolean;
|
|
begin
|
|
Result := FOverlays <> nil;
|
|
end;
|
|
|
|
function TdxReportCells.IndexOfOverlay(AnOverlay: TdxReportCell): Integer;
|
|
begin
|
|
if HasOverlays then
|
|
Result := FOverlays.IndexOf(AnOverlay)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
function TdxReportCells.GetFontByIndex(AnIndex: Integer): TFont;
|
|
begin
|
|
Result := ReportLink.FontPool[AnIndex];
|
|
end;
|
|
|
|
function TdxReportCells.GetIndexByFont(AFont: TFont): Integer;
|
|
begin
|
|
Result := ReportLink.FontPool.Add(AFont);
|
|
end;
|
|
|
|
procedure TdxReportCells.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
BeforeReadData(AReader);
|
|
try
|
|
ClearItems;
|
|
try
|
|
ReadLookAndFeels(AReader);
|
|
ReadCells(AReader);
|
|
ReadFooterCells(AReader);
|
|
ReadHeaderCells(AReader);
|
|
ReadOverlayCells(AReader);
|
|
ReadProperties(AReader);
|
|
except
|
|
ClearItems;
|
|
raise;
|
|
end;
|
|
finally
|
|
AfterReadData(AReader);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
BeforeWriteData(AWriter);
|
|
try
|
|
WriteLookAndFeels(AWriter);
|
|
WriteCells(AWriter);
|
|
WriteFooterCells(AWriter);
|
|
WriteHeaderCells(AWriter);
|
|
WriteOverlayCells(AWriter);
|
|
WriteProperties(AWriter);
|
|
finally
|
|
AfterWriteData(AWriter);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.AfterReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportCells.AfterWriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
ClearImageLists;
|
|
end;
|
|
|
|
procedure TdxReportCells.BeforeReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
ClearImageLists;
|
|
OwnImageLists := True;
|
|
ReadImageLists(AReader);
|
|
end;
|
|
|
|
procedure TdxReportCells.BeforeWriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
ClearImageLists;
|
|
OwnImageLists := False;
|
|
GetImageLists;
|
|
WriteImageLists(AWriter);
|
|
end;
|
|
|
|
procedure TdxReportCells.ReadCells(AReader: TdxPSDataReader);
|
|
begin
|
|
Cells.ReadData(AReader);
|
|
end;
|
|
|
|
procedure TdxReportCells.ReadFooterCells(AReader: TdxPSDataReader);
|
|
begin
|
|
if AReader.ReadBoolean then FooterCells.ReadData(AReader);
|
|
end;
|
|
|
|
procedure TdxReportCells.ReadHeaderCells(AReader: TdxPSDataReader);
|
|
begin
|
|
if AReader.ReadBoolean then HeaderCells.ReadData(AReader);
|
|
end;
|
|
|
|
procedure TdxReportCells.ReadImageLists(AReader: TdxPSDataReader);
|
|
var
|
|
ImageList: TImageList;
|
|
begin
|
|
AReader.ReadListBegin;
|
|
try
|
|
while not AReader.EndOfList do
|
|
begin
|
|
ImageList := TImageList.Create(nil);
|
|
AReader.ReadImageList(ImageList);
|
|
FImageLists.Add(Imagelist);
|
|
end;
|
|
finally
|
|
AReader.ReadListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.ReadLookAndFeels(AReader: TdxPSDataReader);
|
|
var
|
|
LookAndFeelClass: TdxPSReportGroupLookAndFeelClass;
|
|
Index: Integer;
|
|
begin
|
|
ClearLookAndFeels;
|
|
|
|
AReader.ReadListBegin;
|
|
try
|
|
while not AReader.EndOfList do
|
|
begin
|
|
LookAndFeelClass := AReader.ReadLookAndFeelClass;
|
|
CreateGroupLookAndFeel(LookAndFeelClass, False).ReadData(AReader);
|
|
end;
|
|
finally
|
|
AReader.ReadListEnd;
|
|
end;
|
|
Index := AReader.ReadInteger;
|
|
if Index <> -1 then
|
|
LookAndFeel := LookAndFeels[Index]
|
|
else
|
|
LookAndFeel := nil;
|
|
|
|
{if LookAndFeelCount = 0 then
|
|
begin
|
|
FLookAndFeel := CreateGroupLookAndFeel(dxDefaultReportGroupLookAndFeel);
|
|
CreateGroupLookAndFeel(TdxPSReportGroupNullLookAndFeel);
|
|
end
|
|
else
|
|
FLookAndFeel := LookAndFeels[0];}
|
|
end;
|
|
|
|
procedure TdxReportCells.ReadOverlayCells(AReader: TdxPSDataReader);
|
|
begin
|
|
ClearOverlays;
|
|
AReader.ReadListBegin;
|
|
try
|
|
while not AReader.EndOfList do
|
|
AddOverlay.ReadData(AReader);
|
|
finally
|
|
AReader.ReadListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.ReadProperties(AReader: TdxPSDataReader);
|
|
begin
|
|
with AReader do
|
|
begin
|
|
BorderColor := ReadInteger;
|
|
BorderWidth := ReadInteger;
|
|
ExpandButtonBorderColor := ReadInteger;
|
|
GroupBorderColor := ReadInteger;
|
|
GroupCaptionColor := ReadInteger;
|
|
GroupCaptionSeparatorColor := ReadInteger;
|
|
GroupColor := ReadInteger;
|
|
ShadowColor := ReadInteger;
|
|
ShadowDepth := ReadInteger;
|
|
TreeLineColor := ReadInteger;
|
|
TreeLineStyle := TdxPSTreeLineStyle(ReadInteger);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.WriteCells(AWriter: TdxPSDataWriter);
|
|
begin
|
|
Cells.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TdxReportCells.WriteFooterCells(AWriter: TdxPSDataWriter);
|
|
begin
|
|
AWriter.WriteBoolean(AreFooterCellsAllocated);
|
|
if AreFooterCellsAllocated then FooterCells.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TdxReportCells.WriteHeaderCells(AWriter: TdxPSDataWriter);
|
|
begin
|
|
AWriter.WriteBoolean(AreHeaderCellsAllocated);
|
|
if AreHeaderCellsAllocated then HeaderCells.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TdxReportCells.WriteImageLists(AWriter: TdxPSDataWriter);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AWriter.WriteListBegin;
|
|
try
|
|
for I := 0 to FImageLists.Count - 1 do
|
|
AWriter.WriteImageList(TCustomImageList(FImageLists[I]));
|
|
finally
|
|
AWriter.WriteListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.WriteLookAndFeels(AWriter: TdxPSDataWriter);
|
|
var
|
|
I: Integer;
|
|
LookAndFeel: TdxPSReportGroupLookAndFeel;
|
|
begin
|
|
AWriter.WriteListBegin;
|
|
try
|
|
for I := 0 to LookAndFeelCount - 1 do
|
|
begin
|
|
LookAndFeel := LookAndFeels[I];
|
|
AWriter.WriteClassName(LookAndFeel);
|
|
LookAndFeel.WriteData(AWriter);
|
|
end;
|
|
finally
|
|
AWriter.WriteListEnd;
|
|
end;
|
|
|
|
AWriter.WriteInteger(IndexOfReportGroupLookAndFeel(Self.LookAndFeel));
|
|
end;
|
|
|
|
procedure TdxReportCells.WriteOverlayCells(AWriter: TdxPSDataWriter);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AWriter.WriteListBegin;
|
|
try
|
|
for I := 0 to OverlayCount - 1 do
|
|
Overlays[I].WriteData(AWriter);
|
|
finally
|
|
AWriter.WriteListEnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCells.WriteProperties(AWriter: TdxPSDataWriter);
|
|
begin
|
|
with AWriter do
|
|
begin
|
|
WriteInteger(BorderColor);
|
|
WriteInteger(BorderWidth);
|
|
WriteInteger(ExpandButtonBorderColor);
|
|
WriteInteger(GroupBorderColor);
|
|
WriteInteger(GroupCaptionColor);
|
|
WriteInteger(GroupCaptionSeparatorColor);
|
|
WriteInteger(GroupColor);
|
|
WriteInteger(ShadowColor);
|
|
WriteInteger(ShadowDepth);
|
|
WriteInteger(TreeLineColor);
|
|
WriteInteger(Integer(TreeLineStyle));
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCells.CalculateOverlaysHeight: Integer;
|
|
var
|
|
I, V: Integer;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to OverlayCount - 1 do
|
|
begin
|
|
V := Overlays[I].GetAbsoluteRect.Bottom;
|
|
if Result < V then Result := V;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCells.CalculateOverlaysWidth: Integer;
|
|
var
|
|
I, V: Integer;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to OverlayCount - 1 do
|
|
begin
|
|
V := Overlays[I].GetAbsoluteRect.Right;
|
|
if Result < V then Result := V;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCells.CalculateTotalHeight: Integer;
|
|
var
|
|
V: Integer;
|
|
begin
|
|
Result := Cells.Height;
|
|
V := CalculateOverlaysHeight;
|
|
if Result < V then Result := V;
|
|
end;
|
|
|
|
function TdxReportCells.CalculateTotalWidth: Integer;
|
|
var
|
|
V: Integer;
|
|
begin
|
|
Result := Cells.Width;
|
|
V := CalculateOverlaysWidth;
|
|
if Result < V then Result := V;
|
|
end;
|
|
|
|
procedure TdxReportCells.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Cells.ConvertCoords(APixelsNumerator, APixelsDenominator);
|
|
ShadowDepth := MulDiv(ShadowDepth, APixelsNumerator, APixelsDenominator);
|
|
|
|
for I := 0 to LookAndFeelCount - 1 do
|
|
LookAndFeels[I].ConvertCoords(APixelsNumerator, APixelsDenominator);
|
|
|
|
if AreFooterCellsAllocated then
|
|
FFooterCells.ConvertCoords(APixelsNumerator, APixelsDenominator);
|
|
if AreHeaderCellsAllocated then
|
|
HeaderCells.ConvertCoords(APixelsNumerator, APixelsDenominator);
|
|
|
|
if HasOverlays then
|
|
for I := 0 to OverlayCount - 1 do
|
|
Overlays[I].ConvertCoords(APixelsNumerator, APixelsDenominator);
|
|
end;
|
|
|
|
function TdxReportCells.GetCellTopLevelParent(AnItem: TdxReportItem): TdxReportCell;
|
|
|
|
function IsParentInTopLevels(AnItem: TdxReportItem): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := (AnItem = Cells) or
|
|
(AreHeaderCellsAllocated and (AnItem = HeaderCells)) or
|
|
(AreFooterCellsAllocated and (AnItem = FooterCells));
|
|
|
|
if not Result then
|
|
for I := 0 to OverlayCount - 1 do
|
|
begin
|
|
Result := AnItem = Overlays[I];
|
|
if Result then Exit;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Result := AnItem.Parent;
|
|
if Result <> nil then
|
|
while (Result.Parent <> nil) and not IsParentInTopLevels(Result.Parent) do
|
|
Result := Result.Parent;
|
|
end;
|
|
procedure TdxReportCells.FreeAndNilReportGroupLookAndFeels;
|
|
begin
|
|
ClearLookAndFeels;
|
|
FreeAndNil(FLookAndFeels);
|
|
end;
|
|
|
|
procedure TdxReportCells.PrepareReportGroupsLookAndFeels(DC: HDC);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to LookAndFeelCount - 1 do
|
|
LookAndFeels[I].Prepare(DC);
|
|
end;
|
|
|
|
procedure TdxReportCells.AddImageList(AnImageList: TCustomImageList);
|
|
begin
|
|
if (AnImageList <> nil) and (FImageLists.IndexOf(AnImageList) = -1) then
|
|
FImageLists.Add(AnImageList);
|
|
end;
|
|
|
|
procedure TdxReportCells.ClearImageLists;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if OwnImageLists then
|
|
for I := 0 to ImageListCount - 1 do
|
|
ImageLists[I].Free;
|
|
FImageLists.Clear;
|
|
end;
|
|
|
|
procedure TdxReportCells.FreeAndNilImageLists;
|
|
begin
|
|
ClearImageLists;
|
|
FreeAndNil(FImageLists);
|
|
end;
|
|
|
|
procedure TdxReportCells.GetImageLists;
|
|
begin
|
|
ReportLink.GetImageLists(AddImageList);
|
|
end;
|
|
|
|
function TdxReportCells.IndexOfImageList(AnImageList: TCustomImageList): Integer;
|
|
begin
|
|
Result := FImageLists.IndexOf(AnImageList);
|
|
end;
|
|
|
|
function TdxReportCells.GetAreFooterCellsAllocated: Boolean;
|
|
begin
|
|
Result := FFooterCells <> nil;
|
|
end;
|
|
|
|
function TdxReportCells.GetAreHeaderCellsAllocated: Boolean;
|
|
begin
|
|
Result := FHeaderCells <> nil;
|
|
end;
|
|
|
|
function TdxReportCells.GetBoundsRect: TRect;
|
|
begin
|
|
Result := Cells.BoundsRect;
|
|
end;
|
|
|
|
function TdxReportCells.GetCount: Integer;
|
|
begin
|
|
Result := Cells.CellCount;
|
|
end;
|
|
|
|
function TdxReportCells.GetFooterCells: TdxReportCell;
|
|
begin
|
|
if not AreFooterCellsAllocated then CreateFooterCells;
|
|
Result := FFooterCells;
|
|
end;
|
|
|
|
function TdxReportCells.GetHeaderCells: TdxReportCell;
|
|
begin
|
|
if not AreHeaderCellsAllocated then CreateHeaderCells;
|
|
Result := FHeaderCells;
|
|
end;
|
|
|
|
function TdxReportCells.GetImageList(Index: Integer): TCustomImageList;
|
|
begin
|
|
if Index = -1 then
|
|
Result := nil
|
|
else
|
|
Result := TCustomImageList(FImageLists[Index]);
|
|
end;
|
|
|
|
function TdxReportCells.GetImageListCount: Integer;
|
|
begin
|
|
if FImageLists <> nil then
|
|
Result := FImageLists.Count
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportCells.GetLookAndFeel(Index: Integer): TdxPSReportGroupLookAndFeel;
|
|
begin
|
|
Result := TdxPSReportGroupLookAndFeel(FLookAndFeels[Index]);
|
|
end;
|
|
|
|
function TdxReportCells.GetLookAndFeelCount: Integer;
|
|
begin
|
|
Result := FLookAndFeels.Count;
|
|
end;
|
|
|
|
function TdxReportCells.GetOverlay(Index: Integer): TdxReportCell;
|
|
begin
|
|
if HasOverlays then
|
|
Result := TdxReportCell(FOverlays[Index])
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxReportCells.GetOverlayCount: Integer;
|
|
begin
|
|
if HasOverlays then
|
|
Result := FOverlays.Count
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportCells.GetRenderer: TdxPSReportRenderer;
|
|
begin
|
|
Result := ReportLink.Renderer;
|
|
end;
|
|
|
|
procedure TdxReportCells.SetBorderColor(Value: TColor);
|
|
begin
|
|
if Value = clDefault then
|
|
FBorderColor := dxDefaultGridLineColor
|
|
else
|
|
FBorderColor := ColorToRGB(Value);
|
|
end;
|
|
|
|
procedure TdxReportCells.SetShadowColor(Value: TColor);
|
|
begin
|
|
if Value = clDefault then
|
|
FShadowColor := dxDefaultShadowColor
|
|
else
|
|
FShadowColor := ColorToRGB(Value);
|
|
end;
|
|
|
|
procedure TdxReportCells.SetShadowDepth(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
FShadowDepth := Value;
|
|
end;
|
|
|
|
procedure TdxReportCells.SetTreeLineColor(Value: TColor);
|
|
begin
|
|
if Value = clDefault then
|
|
FTreeLineColor := dxDefaultTreeLineColor
|
|
else
|
|
FTreeLineColor := ColorToRGB(Value);
|
|
end;
|
|
|
|
procedure TdxReportCells.CreateFooterCells;
|
|
begin
|
|
FFooterCells := TdxReportCell.Create(nil);
|
|
FFooterCells.FReportCells := Self;
|
|
FFooterCells.Color := dxDefaultFixedColor;
|
|
end;
|
|
|
|
procedure TdxReportCells.CreateHeaderCells;
|
|
begin
|
|
FHeaderCells := TdxReportCell.Create(nil);
|
|
FHeaderCells.FReportCells := Self;
|
|
FHeaderCells.Color := dxDefaultFixedColor;
|
|
end;
|
|
|
|
function TdxReportCells.GetFont: TFont;
|
|
begin
|
|
Result := Cells.Font;
|
|
end;
|
|
|
|
function TdxReportCells.GetFooterBoundsRect: TRect;
|
|
begin
|
|
if AreFooterCellsAllocated then
|
|
Result := FFooterCells.BoundsRect
|
|
else
|
|
Result := NullRect;
|
|
end;
|
|
|
|
function TdxReportCells.GetHeaderBoundsRect: TRect;
|
|
begin
|
|
if AreHeaderCellsAllocated then
|
|
Result := FHeaderCells.BoundsRect
|
|
else
|
|
Result := NullRect;
|
|
end;
|
|
|
|
function TdxReportCells.GetFooterCellCount: Integer;
|
|
begin
|
|
if AreFooterCellsAllocated then
|
|
Result := FFooterCells.CellCount
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportCells.GetHeaderCellCount: Integer;
|
|
begin
|
|
if AreHeaderCellsAllocated then
|
|
Result := FHeaderCells.CellCount
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
{ TAbstractdxReportCellData }
|
|
|
|
constructor TAbstractdxReportCellData.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create(AParent);
|
|
BreakByChars := dxDefaultBreakByChars; // True
|
|
EndEllipsis := dxDefaultEndEllipsis; // False
|
|
HidePrefix := dxDefaultHidePrefix; // False
|
|
Multiline := dxDefaultMultiline; // False
|
|
PreventLeftTextExceed := dxDefaultPreventLeftTextExceed; // True
|
|
PreventTopTextExceed := dxDefaultPreventTopTextExceed; // True
|
|
SortOrder := dxDefaultSortOrder; // csoNone
|
|
TextAlignX := dxDefaultTextAlignX; // taLeft
|
|
TextAlignY := dxDefaultTextAlignY; // taCenterY
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.DrawContent(DC: HDC; AStage: TdxPSRenderStages);
|
|
begin
|
|
if IsBackgroundBitmapDrawn then
|
|
DrawBackgroundBitmap(DC)
|
|
else
|
|
if IsBackgroundDrawn then
|
|
DrawBackground(DC);
|
|
|
|
if IsBordersDrawn then DrawBorders(DC);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetCustomDrawID: Integer;
|
|
begin
|
|
Result := Data;
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.MeasureContentHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := Height;
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.MeasureContentWidth(DC: HDC): Integer;
|
|
begin
|
|
Result := Width;
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.CustomDraw(DC: HDC): Boolean;
|
|
begin
|
|
Result := IsCustomDrawn and Renderer.CustomDrawReportItem(Self);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetAbsoluteEffectiveBounds(DC: HDC; AStage: TdxPSRenderStages): TRect;
|
|
begin
|
|
Result := GetEffectiveBounds(DC, AStage);
|
|
if Parent <> nil then
|
|
with Parent.AbsoluteOrigin do
|
|
OffsetRect(Result, X, Y);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetDefaultDTFormat: DWORD;
|
|
begin
|
|
Result := DXTO_AUTOINDENTS or DXTO_EXPANDTABS or DXTO_PATTERNEDTEXT or DXTO_CHARBREAK or DXTO_EDITCONTROL;
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetEffectiveBounds(DC: HDC; AStage: TdxPSRenderStages): TRect;
|
|
begin
|
|
Result := GetOuterBounds(DC);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetDTFormat: DWORD;
|
|
const
|
|
dxEndEllipsis: array[Boolean] of UINT = (0, DXTO_END_ELLIPSIS);
|
|
dxHidePrefix: array[Boolean] of UINT = (0, DXTO_HIDEPREFIX);
|
|
dxPreventLeftExceed: array[Boolean] of UINT = (0, DXTO_PREVENT_LEFT_EXCEED);
|
|
dxPreventTopExceed: array[Boolean] of UINT = (0, DXTO_PREVENT_TOP_EXCEED);
|
|
dxWordBreak: array[Boolean] of UINT = (DXTO_SINGLELINE, DXTO_WORDBREAK);
|
|
begin
|
|
Result := DefaultDTFormat or
|
|
dxMakeFormat(TextAlignX, TextAlignY) or
|
|
dxEndEllipsis[EndEllipsis] or
|
|
dxHidePrefix[HidePrefix] or
|
|
dxPreventLeftExceed[PreventLeftTextExceed] or
|
|
dxPreventTopExceed[PreventTopTextExceed] or
|
|
dxWordBreak[Multiline];
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.IsCustomDrawn: Boolean;
|
|
begin
|
|
with GetReportCells do
|
|
Result := (ReportLink <> nil) and ReportLink.PossibleCustomDraw(Self);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.IsDrawingNeeded(DC: HDC; AStage: TdxPSRenderStages;
|
|
const ARect: TRect): Boolean;
|
|
begin
|
|
Result := Visible and RectVisible(DC, GetEffectiveBounds(DC, AStage)) and IsDrawn(DC, AStage, ARect);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.IsDrawn(DC: HDC; AStage: TdxPSRenderStages;
|
|
const ARect: TRect): Boolean;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
Result := IntersectRect(R, GetAbsoluteEffectiveBounds(DC, AStage), ARect);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetSortOrder: TdxCellSortOrder;
|
|
begin
|
|
Result := TdxCellSortOrder((Format and dxPSGlbl.dxFormatSortOrderMask) shr dxPSGlbl.dxFormatSortOrderOffset);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetBreakByChars: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatBreakByChars);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetEndEllipsis: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatEndEllipsis);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetHidePrefix: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatHidePrefix);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetMultiline: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatMultiline);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetPreventLeftTextExceed: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatPreventLeftTextExceed);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetPreventTopTextExceed: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatPreventTopTextExceed);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetTextAlignX: TdxTextAlignX;
|
|
begin
|
|
Result := TdxTextAlignX((Format and dxPSGlbl.dxFormatTextAlignXMask) shr dxPSGlbl.dxFormatTextAlignXOffset);
|
|
end;
|
|
|
|
function TAbstractdxReportCellData.GetTextAlignY: TdxTextAlignY;
|
|
begin
|
|
Result := TdxTextAlignY((Format and dxPSGlbl.dxFormatTextAlignYMask) shr dxPSGlbl.dxFormatTextAlignYOffset);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetBreakByChars(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatBreakByChars, Value);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetEndEllipsis(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatEndEllipsis, Value);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetHidePrefix(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatHidePrefix, Value);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetMultiline(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatMultiline, Value);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetPreventLeftTextExceed(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatPreventLeftTextExceed, Value);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetPreventTopTextExceed(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatPreventTopTextExceed, Value);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetSortOrder(Value: TdxCellSortOrder);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatSortOrderMask or (Byte(Value) shl dxPSGlbl.dxFormatSortOrderOffset);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetTextAlignX(Value: TdxTextAlignX);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatTextAlignXMask or (Byte(Value) shl dxPSGlbl.dxFormatTextAlignXOffset);
|
|
end;
|
|
|
|
procedure TAbstractdxReportCellData.SetTextAlignY(Value: TdxTextAlignY);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatTextAlignYMask or (Byte(Value) shl dxPSGlbl.dxFormatTextAlignYOffset);
|
|
end;
|
|
|
|
{ TdxReportCellText }
|
|
|
|
procedure TdxReportCellText.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TdxReportCellText then
|
|
begin
|
|
SetText(TdxReportCellText(Source).GetText);
|
|
Indent := TdxReportCellText(Source).Indent;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCellText.DrawContent(DC: HDC; AStage: TdxPSRenderStages);
|
|
begin
|
|
|
|
if IsBackgroundBitmapDrawn then
|
|
DrawBackgroundBitmap(DC)
|
|
else
|
|
if IsBackgroundDrawn then
|
|
DrawBackground(DC);
|
|
|
|
if IsTextDrawn then DrawText(DC);
|
|
if IsSortMarkDrawn then DrawSortMark(DC);
|
|
if IsBordersDrawn then DrawBorders(DC);
|
|
end;
|
|
|
|
procedure TdxReportCellText.DrawSortMark(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := GetSortMarkBounds(DC);
|
|
if not IsRectEmpty(R) then
|
|
Renderer.DrawSortMark(DC, R, SortOrder, EdgeMode = cemPattern);
|
|
end;
|
|
|
|
procedure TdxReportCellText.DrawText(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
F: TFont;
|
|
S: string;
|
|
|
|
ASaveFont: HFONT;
|
|
ALimit: Integer;
|
|
ATextParams: TdxTextParams;
|
|
AFont: TFont;
|
|
|
|
function ExceedBounds: Boolean;
|
|
var
|
|
TextBounds: TRect;
|
|
begin
|
|
TextBounds := R;
|
|
SelectObject(DC, F.Handle);
|
|
Windows.DrawText(DC, PChar(S), -1, TextBounds, DT_CALCRECT);
|
|
Result := (R.Right - R.Left) < (TextBounds.Right - TextBounds.Left);
|
|
end;
|
|
|
|
begin
|
|
R := GetTextBounds(DC);
|
|
if not IsRectEmpty(R) then
|
|
begin
|
|
S := GetText;
|
|
AFont := GetFont;
|
|
ASaveFont := GetCurrentObject(DC, OBJ_FONT);
|
|
if Multiline or not AdjustFont then
|
|
Renderer.DrawTextEx(DC, R, 0, Indent, 0, S, AFont, DTFormat)
|
|
else
|
|
begin
|
|
SelectObject(DC, AFont.Handle);
|
|
ATextParams := dxCalcTextParams(DC, DTFormat);
|
|
if ATextParams.PatternedText then
|
|
Renderer.DrawTextEx(DC, R, 0, Indent, 0, S, AFont, DTFormat)
|
|
else
|
|
begin
|
|
F := TFont.Create;
|
|
try
|
|
F.Assign(AFont);
|
|
ALimit := MulDiv(F.Size, 2, 3);
|
|
while ExceedBounds and (F.Size > ALimit) do
|
|
F.Size := F.Size - 1;
|
|
SetTextColor(DC, ColorToRgb(AFont.Color));
|
|
Windows.DrawText(DC, PChar(S), -1, R, 0);
|
|
finally
|
|
F.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
SelectObject(DC, ASaveFont);
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCellText.CalculateLineCount(DC: HDC): Integer;
|
|
begin
|
|
Result := Renderer.CalcTextLineCount(DC, Text, Font, Width - Indent);
|
|
end;
|
|
|
|
function TdxReportCellText.MeasureContentHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := Renderer.CalcTextHeight(DC, Text, Multiline, Font, Width - Indent);
|
|
if (SortOrder <> csoNone) and (Result < dxSortMarkRgnSize) then
|
|
Result := dxSortMarkRgnSize;
|
|
end;
|
|
|
|
function TdxReportCellText.MeasureContentWidth(DC: HDC): Integer;
|
|
begin
|
|
if Multiline then
|
|
Result := inherited MeasureContentWidth(DC)
|
|
else
|
|
Result := Renderer.CalcTextWidth(DC, Text, Font);
|
|
if SortOrder <> csoNone then
|
|
Inc(Result, dxSortMarkRgnSize);
|
|
end;
|
|
|
|
function TdxReportCellText.MeasureFontHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := Renderer.CalcTextPatternHeight(DC, Font);
|
|
if (SortOrder <> csoNone) and (Result < dxSortMarkRgnSize) then
|
|
Result := dxSortMarkRgnSize;
|
|
if Result <> 0 then
|
|
Inc(Result, MeasureBordersHeight(DC));
|
|
end;
|
|
|
|
function TdxReportCellText.GetSortMarkBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := GetInnerBounds(DC);
|
|
Result.Left := Result.Right - MulDiv(dxSortMarkRgnSize, PixelsNumerator, PixelsDenominator);
|
|
end;
|
|
|
|
function TdxReportCellText.GetTextBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := GetInnerBounds(DC);
|
|
if IsSortMarkDrawn then
|
|
Result.Right := GetSortMarkBounds(DC).Left;
|
|
end;
|
|
|
|
function TdxReportCellText.IsSortMarkDrawn: Boolean;
|
|
begin
|
|
Result := SortOrder <> csoNone;
|
|
end;
|
|
|
|
function TdxReportCellText.IsTextDrawn: Boolean;
|
|
begin
|
|
Result := GetText <> '';
|
|
end;
|
|
|
|
procedure TdxReportCellText.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited ReadData(AReader);
|
|
FIndent := AReader.ReadInteger;
|
|
Text := AReader.ReadString;
|
|
end;
|
|
|
|
procedure TdxReportCellText.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited WriteData(AWriter);
|
|
AWriter.WriteInteger(Integer(FIndent));
|
|
AWriter.WriteString(Text)
|
|
end;
|
|
|
|
function TdxReportCellText.GetAdjustFont: Boolean;
|
|
begin
|
|
Result := FIndent and dxFormatTextAdjustFont <> 0;
|
|
end;
|
|
|
|
function TdxReportCellText.GetIndent: Integer;
|
|
begin
|
|
Result := FIndent and not dxFormatTextAdjustFont;
|
|
end;
|
|
|
|
procedure TdxReportCellText.SetAdjustFont(Value: Boolean);
|
|
begin
|
|
Integer(FIndent) := Integer(FIndent) and not dxFormatTextAdjustFont;
|
|
if Value then
|
|
Integer(FIndent) := Integer(FIndent) or dxFormatTextAdjustFont;
|
|
end;
|
|
|
|
procedure TdxReportCellText.SetIndent(Value: Integer);
|
|
begin
|
|
FIndent := (FIndent and dxFormatTextAdjustFont) or
|
|
(Cardinal(Value) and not dxFormatTextAdjustFont);
|
|
end;
|
|
|
|
{ TdxReportCellString }
|
|
|
|
function TdxReportCellString.GetText: string;
|
|
begin
|
|
Result := FText;
|
|
end;
|
|
|
|
procedure TdxReportCellString.SetText(const Value: string);
|
|
begin
|
|
FText := Value;
|
|
end;
|
|
|
|
{ TdxReportCellImageContainer }
|
|
|
|
constructor TdxReportCellImageContainer.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create(AParent);
|
|
ImageTransparent := True;
|
|
end;
|
|
|
|
procedure TdxReportCellImageContainer.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TdxReportCellImageContainer then
|
|
ImageTransparent := TdxReportCellImageContainer(Source).ImageTransparent;
|
|
end;
|
|
|
|
procedure TdxReportCellImageContainer.DrawContent(DC: HDC; AStage: TdxPSRenderStages);
|
|
begin
|
|
if IsBackgroundBitmapDrawn then DrawBackgroundBitmap(DC);
|
|
if IsTextBackgroundDrawn then DrawTextBackground(DC);
|
|
if IsTextDrawn then DrawText(DC);
|
|
if IsImageBackgroundDrawn then DrawImageBackground(DC);
|
|
if IsImageDrawn then DrawImage(DC);
|
|
if IsSortMarkDrawn then DrawSortMark(DC);
|
|
if IsBordersDrawn then DrawBorders(DC);
|
|
end;
|
|
|
|
procedure TdxReportCellImageContainer.DrawImage(DC: HDC);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportCellImageContainer.DrawImageBackground(DC: HDC);
|
|
begin
|
|
DrawBackgroundRect(DC, GetImageAreaBounds(DC));
|
|
end;
|
|
|
|
procedure TdxReportCellImageContainer.DrawTextBackground(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := GetTextBounds(DC);
|
|
if IsSortMarkDrawn then
|
|
R.Right := GetSortMarkBounds(DC).Right;
|
|
DrawBackgroundRect(DC, R);
|
|
end;
|
|
|
|
function TdxReportCellImageContainer.GetImageAreaBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := GetInnerBounds(DC);
|
|
if IsSortMarkDrawn then
|
|
Result.Right := GetSortMarkBounds(DC).Left;
|
|
end;
|
|
|
|
function TdxReportCellImageContainer.GetImageBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
procedure TdxReportCellImageContainer.GetImageSizes(var AImageWidth, AImageHeight: Integer);
|
|
begin
|
|
AImageWidth := 0;
|
|
AImageHeight := 0;
|
|
end;
|
|
|
|
function TdxReportCellImageContainer.HasImage: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TdxReportCellImageContainer.IsImageBackgroundDrawn: Boolean;
|
|
begin
|
|
Result := inherited IsBackgroundDrawn and not IsImageDrawn and not IsBackgroundBitmapDrawn;
|
|
end;
|
|
|
|
function TdxReportCellImageContainer.IsImageDrawn: Boolean;
|
|
begin
|
|
Result := HasImage;
|
|
end;
|
|
|
|
function TdxReportCellImageContainer.IsTextBackgroundDrawn: Boolean;
|
|
begin
|
|
Result := not Transparent and not IsBackgroundBitmapDrawn;
|
|
end;
|
|
|
|
function TdxReportCellImageContainer.GetImageTransparent: Boolean;
|
|
begin
|
|
Result := (Format and dxPSGlbl.dxFormatImageTransparent) = dxPSGlbl.dxFormatImageTransparent;
|
|
end;
|
|
|
|
procedure TdxReportCellImageContainer.SetImageTransparent(Value: Boolean);
|
|
const
|
|
dxImageTransparent: array[Boolean] of DWORD = (0, dxPSGlbl.dxFormatImageTransparent);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatImageTransparent or dxImageTransparent[Value];
|
|
end;
|
|
|
|
{ TdxReportCellCheck }
|
|
|
|
constructor TdxCustomReportCellCheck.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create(AParent);
|
|
Checked := False;
|
|
//BorderColor := clWindowText;
|
|
ButtonEdgeStyle := cbesUltraFlat;
|
|
CheckPos := dxDefaultCheckPos;
|
|
Enabled := True;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.DrawCheck(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := GetCheckBounds(DC);
|
|
if RectVisible(DC, R) then
|
|
Renderer.DrawCheckBox(DC, R, Checked, Enabled, IsRadio, ButtonEdgeStyle, BorderColor);
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.DrawImage(DC: HDC);
|
|
begin
|
|
DrawCheck(DC);
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.MeasureContentHeight(DC: HDC): Integer;
|
|
var
|
|
TextHeight: Integer;
|
|
begin
|
|
Result := 1 + CheckHeight + 1;
|
|
TextHeight := inherited MeasureContentHeight(DC);
|
|
if Result < TextHeight then Result := TextHeight;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.MeasureContentWidth(DC: HDC): Integer;
|
|
begin
|
|
Result := 1 + CheckWidth + 1;
|
|
if CheckPos <> ccpCenter then
|
|
Inc(Result, inherited MeasureContentWidth(DC));
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetCheckBounds(DC: HDC): TRect;
|
|
var
|
|
W, H: Integer;
|
|
begin
|
|
Result := GetImageAreaBounds(DC);
|
|
if not IsRectEmpty(Result) then
|
|
begin
|
|
GetImageSizes(W, H);
|
|
with Result do
|
|
begin
|
|
Inc(Left, (Right - Left - W) div 2);
|
|
Inc(Top, (Bottom - Top - H) div 2);
|
|
Right := Left + W;
|
|
Bottom := Top + H;
|
|
end;
|
|
FixupRect(DC, Result);
|
|
end;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetImageAreaBounds(DC: HDC): TRect;
|
|
var
|
|
W, H: Integer;
|
|
begin
|
|
GetImageSizes(W, H);
|
|
if (W <> 0) and (H <> 0) then
|
|
begin
|
|
Result := inherited GetImageAreaBounds(DC);
|
|
with Result do
|
|
case CheckPos of
|
|
ccpLeft:
|
|
Right := Left + W + 2 * Renderer.UnitsPerPixel;
|
|
ccpRight:
|
|
Left := Right - (W + 2 * Renderer.UnitsPerPixel);
|
|
end;
|
|
end
|
|
else
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetImageBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := GetCheckBounds(DC);
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.GetImageSizes(var AImageWidth, AImageHeight: Integer);
|
|
begin
|
|
AImageWidth := MulDiv(dxPSGlbl.CheckWidth, PixelsNumerator, PixelsDenominator);
|
|
AImageHeight := MulDiv(dxPSGlbl.CheckHeight, PixelsNumerator, PixelsDenominator);
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetTextBounds(DC: HDC): TRect;
|
|
begin
|
|
if CheckPos <> ccpCenter then
|
|
begin
|
|
Result := inherited GetTextBounds(DC);
|
|
case CheckPos of
|
|
ccpLeft:
|
|
Result.Left := GetImageAreaBounds(DC).Right;
|
|
ccpRight:
|
|
Result.Right := GetImageAreaBounds(DC).Left;
|
|
end;
|
|
end
|
|
else
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.HasImage: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.IsImageBackgroundDrawn: Boolean;
|
|
begin
|
|
Result := not Transparent and not IsBackgroundBitmapDrawn;
|
|
end;
|
|
|
|
class function TdxCustomReportCellCheck.IsRadio: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.SetChecked(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatCheckChecked, Value);
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetState: TCheckBoxState;
|
|
begin
|
|
if Enabled then
|
|
if Checked then
|
|
Result := cbChecked
|
|
else
|
|
Result := cbUnchecked
|
|
else
|
|
Result := cbGrayed;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetBoldBorder: Boolean;
|
|
begin
|
|
Result := ButtonEdgeStyle = cbesBoldFlat;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetButtonEdgeStyle: TdxCheckButtonEdgeStyle;
|
|
begin
|
|
Result := TdxCheckButtonEdgeStyle((Format and dxPSGlbl.dxFormatCheckButtonEdgeStyleMask) shr dxPSGlbl.dxFormatCheckButtonEdgeStyleOffset);
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetChecked: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatCheckChecked);
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetCheckPos: TdxCellCheckPos;
|
|
begin
|
|
Result := TdxCellCheckPos((Format and dxPSGlbl.dxFormatCheckPosMask) shr dxPSGlbl.dxFormatCheckPosOffset);
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetEnabled: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatCheckEnabled);
|
|
end;
|
|
|
|
function TdxCustomReportCellCheck.GetFlatBorder: Boolean;
|
|
begin
|
|
Result := ButtonEdgeStyle = cbesUltraFlat;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.SetBoldBorder(Value: Boolean);
|
|
begin
|
|
if Value then
|
|
ButtonEdgeStyle := cbesBoldFlat;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.SetButtonEdgeStyle(Value: TdxCheckButtonEdgeStyle);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatCheckButtonEdgeStyleMask or (Byte(Value) shl dxPSGlbl.dxFormatCheckButtonEdgeStyleOffset);
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.SetCheckPos(Value: TdxCellCheckPos);
|
|
begin
|
|
if Value = ccpCenter then
|
|
SetText('');
|
|
Format := Format and not dxPSGlbl.dxFormatCheckPosMask or (Byte(Value) shl dxPSGlbl.dxFormatCheckPosOffset);
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.SetEnabled(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatCheckEnabled, Value);
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheck.SetFlatBorder(Value: Boolean);
|
|
begin
|
|
if Value then
|
|
ButtonEdgeStyle := cbesUltraFlat
|
|
else
|
|
ButtonEdgeStyle := cbes3D;
|
|
end;
|
|
|
|
{ TdxCustomReportCellRadio }
|
|
|
|
class function TdxCustomReportCellRadio.IsRadio: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{ TdxCustomReportCellCheckImage }
|
|
|
|
constructor TdxCustomReportCellCheckImage.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited;
|
|
GlyphCount := 1;
|
|
end;
|
|
|
|
destructor TdxCustomReportCellCheckImage.Destroy;
|
|
begin
|
|
ReleaseGlyph;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxCustomReportCellCheckImage then
|
|
with TdxCustomReportCellCheckImage(Source) do
|
|
begin
|
|
Self.GlyphCount := GlyphCount;
|
|
if HasGlyph then
|
|
Self.SetGlyph(Glyph)
|
|
else
|
|
Self.ReleaseGlyph;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.DrawCheck(DC: HDC);
|
|
begin
|
|
if HasGlyph and not Glyph.Empty and (GlyphCount <> 0) then
|
|
DrawCheckGlyph(DC)
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.DrawCheckGlyph(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if HasGlyph and (GlyphCount <> 0) then
|
|
begin
|
|
R := GlyphPartialBounds;
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
//R := Rect(0, 0, Glyph.Height, Glyph.Height); {3.1}
|
|
with Renderer.FCheckBitmap do
|
|
begin
|
|
Height := R.Bottom - R.Top;
|
|
Width := R.Right - R.Left;
|
|
Canvas.Brush.Color := clWhite;
|
|
Canvas.FillRect(R);
|
|
Canvas.CopyRect(R, Glyph.Canvas, GlyphPartialBounds);
|
|
end;
|
|
Renderer.DrawGraphicEx(DC, GetCheckBounds(DC), GetImageAreaBounds(DC), nil, 0,
|
|
Renderer.FCheckBitmap, True, True, Color, ContentBkColor, ContentPattern, cibAlways);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.GetImageSizes(var AImageWidth, AImageHeight: Integer);
|
|
begin
|
|
if HasGlyph and not Glyph.Empty and (GlyphCount <> 0) then
|
|
begin
|
|
AImageWidth := MulDiv(Glyph.Width div GlyphCount, PixelsNumerator, PixelsDenominator);
|
|
AImageHeight := MulDiv(Glyph.Height, PixelsNumerator, PixelsDenominator);
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheckImage.GetGlyph: TBitmap;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheckImage.GetGlyphCount: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TdxCustomReportCellCheckImage.GetGlyphIndex: Integer;
|
|
//cbUnchecked, cbChecked, cbGrayed
|
|
const
|
|
GlyphIndexes: array[TCheckBoxState] of Integer = (0, 1, 2);
|
|
begin
|
|
Result := GlyphIndexes[State];
|
|
if (State = cbGrayed) and (GlyphCount < 3) then
|
|
Result := 0;
|
|
if Result > GlyphCount - 1 then
|
|
Result := GlyphCount - 1;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.SetGlyph(Value: TBitmap);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.SetGlyphCount(Value: Integer);
|
|
begin
|
|
end;
|
|
|
|
function TdxCustomReportCellCheckImage.HasGlyph: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.ReleaseGlyph;
|
|
begin
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited;
|
|
if AReader.ReadBoolean then AReader.ReadImage(Glyph);
|
|
end;
|
|
|
|
procedure TdxCustomReportCellCheckImage.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited;
|
|
AWriter.WriteBoolean(HasGlyph);
|
|
if HasGlyph then AWriter.WriteImage(Glyph);
|
|
end;
|
|
|
|
function TdxCustomReportCellCheckImage.GetGlyphPartialBounds: TRect;
|
|
begin
|
|
if HasGlyph and (GlyphCount <> 0) then
|
|
if GlyphCount = 1 then
|
|
Result := MakeBounds(0, 0, Glyph.Width, Glyph.Height)
|
|
else
|
|
Result := MakeBounds((Glyph.Width div GlyphCount) * GlyphIndex, 0, Glyph.Height, Glyph.Height)
|
|
else
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
{ TdxReportCellCheckImage }
|
|
|
|
function TdxReportCellCheckImage.GetGlyph: TBitmap;
|
|
begin
|
|
if FGlyph = nil then
|
|
FGlyph := TBitmap.Create;
|
|
Result := FGlyph;
|
|
end;
|
|
|
|
function TdxReportCellCheckImage.GetGlyphCount: Integer;
|
|
begin
|
|
Result := (Format and dxPSGlbl.dxFormatCheckGlyphCountMask) shr dxPSGlbl.dxFormatCheckGlyphCountOffset;
|
|
end;
|
|
|
|
procedure TdxReportCellCheckImage.SetGlyph(Value: TBitmap);
|
|
begin
|
|
if Value = nil then
|
|
ReleaseGlyph
|
|
else
|
|
Glyph.Assign(Value);
|
|
end;
|
|
|
|
procedure TdxReportCellCheckImage.SetGlyphCount(Value: Integer);
|
|
begin
|
|
// if Value < 1 then {3.1}
|
|
// Value := 1;
|
|
if Value < 0 then Value := 0;
|
|
if Value > MaxGlyphCount then
|
|
Value := MaxGlyphCount;
|
|
|
|
Format := Format and not dxPSGlbl.dxFormatCheckGlyphCountMask or (DWORD(Value) shl dxPSGlbl.dxFormatCheckGlyphCountOffset);
|
|
end;
|
|
|
|
function TdxReportCellCheckImage.HasGlyph: Boolean;
|
|
begin
|
|
Result := FGlyph <> nil;
|
|
end;
|
|
|
|
procedure TdxReportCellCheckImage.ReleaseGlyph;
|
|
begin
|
|
FreeAndNil(FGlyph);
|
|
end;
|
|
|
|
{ TdxCustomReportButtonGroup }
|
|
|
|
constructor TdxCustomReportButtonGroup.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create(AParent);
|
|
FColumnCount := 1;
|
|
FInterColumnsMinSpace := dxRadioGroupInterColumnsMinSpace;
|
|
FInterRowsMinSpace := dxRadioGroupInterRowsMinSpace;
|
|
FIndents := MakeRect(dxRadioGroupBoundsIndent, dxRadioGroupBoundsIndent, dxRadioGroupBoundsIndent, dxRadioGroupBoundsIndent);
|
|
ShowCaption := False;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxCustomReportButtonGroup then
|
|
with TdxCustomReportButtonGroup(Source) do
|
|
begin
|
|
Self.ColumnCount := ColumnCount;
|
|
Self.InterColumnsMinSpace := InterColumnsMinSpace;
|
|
Self.InterRowsMinSpace := InterRowsMinSpace;
|
|
Self.Indents := Indents;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.AdjustContent(DC: HDC);
|
|
type
|
|
TViewInfo = record
|
|
ColumnWidth: Integer;
|
|
ItemsArea: TRect;
|
|
RowHeight: Integer;
|
|
end;
|
|
|
|
var
|
|
ViewInfo: TViewInfo;
|
|
|
|
procedure CalcItemSizes;
|
|
var
|
|
I, Value: Integer;
|
|
begin
|
|
FItemSize.cX := 0;
|
|
for I := 0 to ItemCount - 1 do
|
|
begin
|
|
Value := Items[I].MeasureContentWidth(DC);
|
|
if FItemSize.cX < Value then FItemSize.cX := Value;
|
|
end;
|
|
// todo: 4 - difference between PS and cxRadioGroup AB9777
|
|
FItemSize.cY := Items[0].MeasureContentHeight(DC) - 4;
|
|
end;
|
|
|
|
procedure CalcViewInfo;
|
|
begin
|
|
FillChar(ViewInfo, SizeOf(TViewInfo), 0);
|
|
with ViewInfo do
|
|
begin
|
|
ItemsArea := BoundsRect;
|
|
OffsetRect(ItemsArea, -ItemsArea.Left, -ItemsArea.Top);
|
|
if ShowCaption then
|
|
ItemsArea := GetInnerBoundsRelativeTo(DC, ItemsArea);
|
|
|
|
Inc(ItemsArea.Left, Indents.Left);
|
|
if ShowCaption then
|
|
Dec(ItemsArea.Top, Indents.Top)
|
|
else
|
|
Inc(ItemsArea.Top, Indents.Top);
|
|
Dec(ItemsArea.Right, Indents.Right);
|
|
Dec(ItemsArea.Bottom, Indents.Bottom);
|
|
|
|
if not IsRectEmpty(ItemsArea) then
|
|
begin
|
|
ColumnWidth := (ItemsArea.Right - ItemsArea.Left) div ColumnCount;
|
|
if ColumnWidth < ItemSize.cX + InterColumnsMinSpace then
|
|
ColumnWidth := ItemSize.cX + InterColumnsMinSpace;
|
|
|
|
RowHeight := (ItemsArea.Bottom - ItemsArea.Top) div RowCount;
|
|
if RowHeight < ItemSize.cY then
|
|
RowHeight := ItemSize.cY;
|
|
{ if (RowCount > 1) and (RowHeight < ItemSize.cY + (1 * RowCount) + InterRowsMinSpace) then
|
|
RowHeight := ItemSize.cY - (1 * RowCount) + InterRowsMinSpace;}
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function GetColumnRect(AnIndex: Integer): TRect;
|
|
begin
|
|
with ViewInfo do
|
|
begin
|
|
Result := ItemsArea;
|
|
Result.Right := Result.Left + ColumnWidth;
|
|
OffsetRect(Result, AnIndex * ColumnWidth, 0);
|
|
end;
|
|
end;
|
|
|
|
function GetRowRect(AnIndex: Integer): TRect;
|
|
begin
|
|
with ViewInfo do
|
|
begin
|
|
Result := ItemsArea;
|
|
Result.Bottom := Result.Top + RowHeight;
|
|
OffsetRect(Result, 0, AnIndex * RowHeight);
|
|
end;
|
|
end;
|
|
|
|
function GetItemBounds(AnIndex: Integer): TRect;
|
|
var
|
|
Delta: Integer;
|
|
begin
|
|
with GetColumnRect(ItemColumns[AnIndex]) do
|
|
begin
|
|
Result.Left := Left;
|
|
Result.Right := Right;
|
|
end;
|
|
with GetRowRect(ItemRows[AnIndex]) do
|
|
begin
|
|
Result.Top := Top;
|
|
Result.Bottom := Bottom;
|
|
end;
|
|
|
|
Delta := (Result.Bottom - Result.Top - ItemSize.cY) div 2;
|
|
InflateRect(Result, 0, -Delta);
|
|
end;
|
|
|
|
procedure CheckItemVisibility(AnItem: TdxReportVisualItem);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
AnItem.Visible := IntersectRect(R, AnItem.BoundsRect, ViewInfo.ItemsArea);
|
|
end;
|
|
|
|
var
|
|
I, J, Index: Integer;
|
|
Item: TdxCustomReportCellCheck;
|
|
begin
|
|
if ItemCount <> 0 then
|
|
begin
|
|
CalcItemSizes;
|
|
CalcViewInfo;
|
|
if not IsRectEmpty(ViewInfo.ItemsArea) then
|
|
for I := 0 to ColumnCount - 1 do
|
|
for J := 0 to RowCount - 1 do
|
|
begin
|
|
Index := I * RowCount + J;
|
|
if Index > ItemCount - 1 then Break;
|
|
|
|
Item := Items[Index];
|
|
Item.BoundsRect := GetItemBounds(Index);
|
|
CheckItemVisibility(Item);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.MeasureContentHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := RowCount * (ItemSize.cY + InterRowsMinSpace) - InterRowsMinSpace;
|
|
Inc(Result, Indents.Top + Indents.Bottom);
|
|
if RowCount <> 0 then
|
|
Inc(Result, 2 * dxPSTextOut.dxTextSpace);
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.MeasureContentWidth(DC: HDC): Integer;
|
|
begin
|
|
Result := ColumnCount * (ItemSize.cX + InterColumnsMinSpace) - InterColumnsMinSpace;
|
|
Inc(Result, Indents.Left + Indents.Right);
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.Add(const AText: string = ''): TdxCustomReportCellCheck;
|
|
begin
|
|
Result := GetItemClass.Create(Self);
|
|
Result.Text := AText;
|
|
Result.BoundsRect := MakeRect(0, 0, -1, 0);
|
|
InitializeItem(Result);
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.Clear;
|
|
begin
|
|
ClearDataItems;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.Delete(Index: Integer);
|
|
begin
|
|
DeleteDataItem(Index);
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.FindItem(const ACaption: string): Integer;
|
|
begin
|
|
for Result := 0 to ItemCount - 1 do
|
|
if Items[Result].Text = ACaption then Exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
inherited;
|
|
R := Indents;
|
|
with R do
|
|
begin
|
|
Left := MulDiv(Left, APixelsNumerator, APixelsDenominator);
|
|
Right := MulDiv(Right, APixelsNumerator, APixelsDenominator);
|
|
Top := MulDiv(Top, APixelsNumerator, APixelsDenominator);
|
|
Bottom := MulDiv(Bottom, APixelsNumerator, APixelsDenominator);
|
|
end;
|
|
Indents := R;
|
|
|
|
InterColumnsMinSpace := MulDiv(InterColumnsMinSpace, APixelsNumerator, APixelsDenominator);
|
|
InterRowsMinSpace := MulDiv(InterRowsMinSpace, APixelsNumerator, APixelsDenominator);
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.SetFontIndex(Value: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
inherited;
|
|
for I := 0 to ItemCount - 1 do
|
|
Items[I].FontIndex := Value;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.ReadDataItems(AReader: TdxPSDataReader);
|
|
begin
|
|
FLocked := True;
|
|
try
|
|
inherited;
|
|
finally
|
|
FLocked := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited ReadData(AReader);
|
|
ColumnCount := AReader.ReadInteger;
|
|
InterColumnsMinSpace := AReader.ReadInteger;
|
|
InterRowsMinSpace := AReader.ReadInteger;
|
|
Indents := AReader.ReadRect;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited WriteData(AWriter);
|
|
AWriter.WriteInteger(ColumnCount);
|
|
AWriter.WriteInteger(InterColumnsMinSpace);
|
|
AWriter.WriteInteger(InterRowsMinSpace);
|
|
AWriter.WriteRect(Indents);
|
|
end;
|
|
|
|
class function TdxCustomReportButtonGroup.GetItemClass: TdxCustomReportCellCheckClass;
|
|
begin
|
|
Result := TdxCustomReportCellCheck;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.InitializeItem(AnItem: TdxCustomReportCellCheck);
|
|
begin
|
|
AnItem.ButtonEdgeStyle := ButtonEdgeStyle;
|
|
AnItem.CellSides := [];
|
|
AnItem.CheckPos := CheckPos;
|
|
AnItem.Color := Color;
|
|
AnItem.FontIndex := FontIndex;
|
|
AnItem.TextAlignY := taCenterY;
|
|
AnItem.Transparent := True;
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.GetButtonEdgeStyle: TdxCheckButtonEdgeStyle;
|
|
begin
|
|
Result := TdxCheckButtonEdgeStyle((Format and dxPSGlbl.dxFormatCheckButtonEdgeStyleMask) shr dxPSGlbl.dxFormatCheckButtonEdgeStyleOffset);
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.GetCheckPos: TdxCellCheckPos;
|
|
begin
|
|
Result := TdxCellCheckPos((Format and dxPSGlbl.dxFormatCheckPosMask) shr dxPSGlbl.dxFormatCheckPosOffset);
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.GetItem(Index: Integer): TdxCustomReportCellCheck;
|
|
begin
|
|
Result := DataItems[Index] as TdxCustomReportCellCheck;
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.GetItemColumn(Index: Integer): Integer;
|
|
begin
|
|
Result := Index div RowCount;
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.GetItemCount: Integer;
|
|
begin
|
|
Result := DataItemCount;
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.GetItemRow(Index: Integer): Integer;
|
|
begin
|
|
Result := Index mod RowCount;
|
|
end;
|
|
|
|
function TdxCustomReportButtonGroup.GetRowCount: Integer;
|
|
begin
|
|
Result := ItemCount div ColumnCount;
|
|
if (ItemCount <> 0) and (ItemCount mod ColumnCount <> 0) then
|
|
Inc(Result);
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.SetButtonEdgeStyle(Value: TdxCheckButtonEdgeStyle);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatCheckButtonEdgeStyleMask or (Byte(Value) shl dxPSGlbl.dxFormatCheckButtonEdgeStyleOffset);
|
|
|
|
for I := 0 to ItemCount - 1 do
|
|
Items[I].ButtonEdgeStyle := Value;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.SetCheckPos(Value: TdxCellCheckPos);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatCheckPosMask or (Byte(Value) shl dxPSGlbl.dxFormatCheckPosOffset);
|
|
|
|
if Value = ccpCenter then
|
|
for I := 0 to ItemCount - 1 do
|
|
Items[I].Text := ''
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.SetColumnCount(Value: Integer);
|
|
begin
|
|
if Value < 1 then Value := 1;
|
|
FColumnCount := Value;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.SetInterColumnsMinSpace(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
FInterColumnsMinSpace := Value;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.SetInterRowsMinSpace(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
FInterRowsMinSpace := Value;
|
|
end;
|
|
|
|
procedure TdxCustomReportButtonGroup.SetIndents(Value: TRect);
|
|
begin
|
|
with Value do
|
|
begin
|
|
if Left < 0 then Left := 0;
|
|
if Top < 0 then Top := 0;
|
|
if Right < 0 then Right := 0;
|
|
if Bottom < 0 then Bottom := 0;
|
|
end;
|
|
FIndents := Value;
|
|
end;
|
|
|
|
{ TdxReportCellRadioGroupButton }
|
|
|
|
type
|
|
TdxReportCellRadioGroupButton = class(TdxCustomReportCellRadio)
|
|
private
|
|
function GetParent: TdxReportRadioGroup;
|
|
protected
|
|
procedure SetChecked(Value: Boolean); override;
|
|
public
|
|
property Checked write SetChecked;
|
|
property Enabled;
|
|
property Parent: TdxReportRadioGroup read GetParent;
|
|
end;
|
|
|
|
// for backward compatibility with saved reports
|
|
TdxReportCellGroupButton = class(TdxReportCellRadioGroupButton);
|
|
|
|
function TdxReportCellRadioGroupButton.GetParent: TdxReportRadioGroup;
|
|
begin
|
|
Result := inherited Parent as TdxReportRadioGroup;
|
|
end;
|
|
|
|
procedure TdxReportCellRadioGroupButton.SetChecked(Value: Boolean);
|
|
begin
|
|
inherited SetChecked(Value);
|
|
if Value then
|
|
Parent.ItemIndex := Index
|
|
else
|
|
Parent.ItemIndex := -1;
|
|
end;
|
|
|
|
{ TdxReportRadioGroup }
|
|
|
|
function TdxReportRadioGroup.Add(const AText: string = ''): TdxCustomReportCellRadio;
|
|
begin
|
|
Result := inherited Add(AText) as TdxCustomReportCellRadio;
|
|
end;
|
|
|
|
class function TdxReportRadioGroup.GetItemClass: TdxCustomReportCellCheckClass;
|
|
begin
|
|
Result := TdxReportCellRadioGroupButton;
|
|
end;
|
|
|
|
function TdxReportRadioGroup.GetItem(Index: Integer): TdxCustomReportCellRadio;
|
|
begin
|
|
Result := inherited Items[Index] as TdxCustomReportCellRadio;
|
|
end;
|
|
|
|
function TdxReportRadioGroup.GetItemIndex: Integer;
|
|
begin
|
|
for Result := 0 to ItemCount - 1 do
|
|
if Items[Result].Checked then Exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure TdxReportRadioGroup.SetItemIndex(Value: Integer);
|
|
var
|
|
AnItemIndex: Integer;
|
|
begin
|
|
if Locked then Exit;
|
|
|
|
if Value < -1 then
|
|
Value := -1;
|
|
if Value > ItemCount - 1 then
|
|
Value := ItemCount - 1;
|
|
|
|
AnItemIndex := ItemIndex;
|
|
if AnItemIndex <> Value then
|
|
begin
|
|
Locked := True;
|
|
try
|
|
if AnItemIndex <> -1 then
|
|
Items[AnItemIndex].Checked := False;
|
|
if Value <> -1 then
|
|
Items[Value].Checked := True;
|
|
finally
|
|
Locked := False;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TdxReportCellCheckGroupButton }
|
|
|
|
type
|
|
TdxReportCellCheckGroupButton = class(TdxCustomReportCellCheckImage)
|
|
private
|
|
function GetParent: TdxReportCheckGroup;
|
|
protected
|
|
function GetGlyph: TBitmap; override;
|
|
function GetGlyphCount: Integer; override;
|
|
function HasGlyph: Boolean; override;
|
|
public
|
|
property Parent: TdxReportCheckGroup read GetParent;
|
|
end;
|
|
|
|
{ TdxReportCellCheckGroupButton }
|
|
|
|
function TdxReportCellCheckGroupButton.GetGlyph: TBitmap;
|
|
begin
|
|
if Parent <> nil then
|
|
Result := Parent.Glyph
|
|
else
|
|
Result := inherited GetGlyph;
|
|
end;
|
|
|
|
function TdxReportCellCheckGroupButton.GetGlyphCount: Integer;
|
|
begin
|
|
if Parent <> nil then
|
|
Result := Parent.GlyphCount
|
|
else
|
|
Result := inherited GetGlyphCount;
|
|
end;
|
|
|
|
function TdxReportCellCheckGroupButton.HasGlyph: Boolean;
|
|
begin
|
|
Result := (Parent <> nil) and Parent.HasGlyph;
|
|
end;
|
|
|
|
function TdxReportCellCheckGroupButton.GetParent: TdxReportCheckGroup;
|
|
begin
|
|
Result := inherited Parent as TdxReportCheckGroup;
|
|
end;
|
|
|
|
{ TdxReportCheckGroup }
|
|
|
|
constructor TdxReportCheckGroup.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited;
|
|
GlyphCount := 1;
|
|
end;
|
|
|
|
destructor TdxReportCheckGroup.Destroy;
|
|
begin
|
|
ReleaseGlyph;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxReportCheckGroup then
|
|
with TdxReportCheckGroup(Source) do
|
|
begin
|
|
if HasGlyph then
|
|
Self.Glyph := Glyph
|
|
else
|
|
Self.ReleaseGlyph;
|
|
Self.GlyphCount := GlyphCount;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCheckGroup.Add(const AText: string = ''): TdxCustomReportCellCheckImage;
|
|
begin
|
|
Result := inherited Add(AText) as TdxCustomReportCellCheckImage;
|
|
end;
|
|
|
|
function TdxReportCheckGroup.HasGlyph: Boolean;
|
|
begin
|
|
Result := FGlyph <> nil;//) and not FGlyph.Empty;
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.ReleaseGlyph;
|
|
begin
|
|
FreeAndNil(FGlyph);
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited;
|
|
GlyphCount := AReader.ReadInteger;
|
|
if AReader.ReadBoolean then AReader.ReadImage(Glyph);
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited;
|
|
AWriter.WriteInteger(GlyphCount);
|
|
AWriter.WriteBoolean(HasGlyph);
|
|
if HasGlyph then AWriter.WriteImage(Glyph);
|
|
end;
|
|
|
|
class function TdxReportCheckGroup.GetItemClass: TdxCustomReportCellCheckClass;
|
|
begin
|
|
Result := TdxReportCellCheckGroupButton;
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.InitializeItem(AnItem: TdxCustomReportCellCheck);
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
function TdxReportCheckGroup.GetGlyph: TBitmap;
|
|
begin
|
|
if FGlyph = nil then
|
|
FGlyph := TBitmap.Create;
|
|
Result := FGlyph;
|
|
end;
|
|
|
|
function TdxReportCheckGroup.GetItem(Index: Integer): TdxCustomReportCellCheckImage;
|
|
begin
|
|
Result := inherited Items[Index] as TdxCustomReportCellCheckImage;
|
|
end;
|
|
|
|
function TdxReportCheckGroup.GetItemChecked(Index: Integer): Boolean;
|
|
begin
|
|
Result := Items[Index].Checked;
|
|
end;
|
|
|
|
function TdxReportCheckGroup.GetItemEnabled(Index: Integer): Boolean;
|
|
begin
|
|
Result := Items[Index].Enabled;
|
|
end;
|
|
|
|
function TdxReportCheckGroup.GetItemState(Index: Integer): TCheckBoxState;
|
|
begin
|
|
Result := Items[Index].State;
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.SetGlyph(Value: TBitmap);
|
|
begin
|
|
Glyph.Assign(Value);
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.SetGlyphCount(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0; {3.1 1 -> 0}
|
|
if Value > MaxGlyphCount then Value := MaxGlyphCount;
|
|
FGlyphCount := Value;
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.SetItemChecked(Index: Integer; Value: Boolean);
|
|
begin
|
|
Items[Index].Checked := Value;
|
|
end;
|
|
|
|
procedure TdxReportCheckGroup.SetItemEnabled(Index: Integer; Value: Boolean);
|
|
begin
|
|
Items[Index].Enabled := Value;
|
|
end;
|
|
|
|
{ TCustomdxReportCellImageContainer }
|
|
|
|
constructor TCustomdxReportCellImageContainer.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create(AParent);
|
|
ImageIndex := -1;
|
|
ImageTransparent := True;
|
|
end;
|
|
|
|
destructor TCustomdxReportCellImageContainer.Destroy;
|
|
begin
|
|
FreeAndNil(FImage);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TCustomdxReportCellImageContainer.Assign(Source: TPersistent);
|
|
begin
|
|
inherited;
|
|
if Source is TCustomdxReportCellImageContainer then
|
|
with TCustomdxReportCellImageContainer(Source) do
|
|
begin
|
|
Self.SetImage(FImage);
|
|
Self.ImageTransparent := ImageTransparent;
|
|
Self.ImageIndex := ImageIndex;
|
|
Self.ImageList := ImageList;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxReportCellImageContainer.CreateImage(AGraphicClass: TGraphicClass): TGraphic;
|
|
begin
|
|
if (FImage = nil) or (FImage.ClassType <> AGraphicClass) then
|
|
begin
|
|
FreeAndNil(FImage);
|
|
FImage := dxPSUtl.CreateGraphic(AGraphicClass);
|
|
end;
|
|
Result := FImage;
|
|
end;
|
|
|
|
procedure TCustomdxReportCellImageContainer.DrawImage(DC: HDC);
|
|
begin
|
|
Renderer.DrawGraphicEx(DC, GetImageBounds(DC), GetImageAreaBounds(DC), ImageList,
|
|
ImageIndex, FImage, ImageTransparent, IsBackgroundBitmapDrawn or Transparent,
|
|
Color, ContentBkColor, ContentPattern, ActualImageBuffering);
|
|
end;
|
|
|
|
function TCustomdxReportCellImageContainer.GetActualImageBuffering: TdxCellImageActualBuffering;
|
|
begin
|
|
Result := ImageBuffering;
|
|
if Result = cibDefault then
|
|
if (ReportCells <> nil) and (ReportCells.ReportLink <> nil) then
|
|
if ReportCells.ReportLink.AlwaysBufferedGraphics then
|
|
Result := cibAlways
|
|
else
|
|
Result := cibNone
|
|
else
|
|
Result := cibAlways;
|
|
end;
|
|
|
|
function TCustomdxReportCellImageContainer.GetImageBuffering: TdxCellImageBuffering;
|
|
begin
|
|
Result := cibDefault;
|
|
end;
|
|
|
|
procedure TCustomdxReportCellImageContainer.GetImageSizes(var AImageWidth, AImageHeight: Integer);
|
|
begin
|
|
if ImageList <> nil then
|
|
begin
|
|
AImageWidth := MulDiv(ImageList.Width, PixelsNumerator, PixelsDenominator);
|
|
AImageHeight := MulDiv(ImageList.Height, PixelsNumerator, PixelsDenominator);
|
|
end
|
|
else
|
|
if FImage <> nil then
|
|
begin
|
|
AImageWidth := MulDiv(Image.Width, PixelsNumerator, PixelsDenominator);
|
|
AImageHeight := MulDiv(Image.Height, PixelsNumerator, PixelsDenominator);
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
function TCustomdxReportCellImageContainer.HasImage: Boolean;
|
|
begin
|
|
Result := ((FImage <> nil) and not Image.Empty) or
|
|
((ImageList <> nil) and (ImageIndex > -1) and (ImageIndex < ImageList.Count));
|
|
end;
|
|
|
|
procedure TCustomdxReportCellImageContainer.SetImageBuffering(Value: TdxCellImageBuffering);
|
|
begin
|
|
end;
|
|
|
|
function TCustomdxReportCellImageContainer.GetImageListIndex: Integer;
|
|
begin
|
|
Result := ReportCells.IndexOfImageList(ImageList);
|
|
end;
|
|
|
|
procedure TCustomdxReportCellImageContainer.ReadData(AReader: TdxPSDataReader);
|
|
var
|
|
SourceType, BytesToSkip: Integer;
|
|
GraphicClass: TGraphicClass;
|
|
begin
|
|
inherited ReadData(AReader);
|
|
|
|
if AReader.ReadBoolean then // HasImage
|
|
begin
|
|
SourceType := AReader.ReadInteger;
|
|
case SourceType of
|
|
imstImageList:
|
|
begin
|
|
ImageList := ReportCells.ImageLists[AReader.ReadInteger];
|
|
ImageIndex := AReader.ReadInteger;
|
|
end;
|
|
|
|
{imstShellLargeImageList:
|
|
begin
|
|
ImageList := dxPSUtl.ShellLargeImages;
|
|
ImageIndex := AReader.ReadInteger;
|
|
end;
|
|
|
|
imstShellSmallImageList:
|
|
begin
|
|
ImageList := dxPSUtl.ShellSmallImages;
|
|
ImageIndex := AReader.ReadInteger;
|
|
end;}
|
|
imstShellLargeImageList,
|
|
imstShellSmallImageList,
|
|
imstImage:
|
|
begin
|
|
GraphicClass := AReader.ReadGraphicClass;
|
|
if GraphicClass = nil then
|
|
begin
|
|
Image := nil;
|
|
BytesToSkip := {$IFDEF DELPHI6} AReader.ReadInt64 {$ELSE} AReader.ReadInteger {$ENDIF};
|
|
AReader.SkipBytes(BytesToSkip);
|
|
end
|
|
else
|
|
AReader.ReadImage(CreateImage(GraphicClass));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxReportCellImageContainer.WriteData(AWriter: TdxPSDataWriter);
|
|
|
|
function RetrieveSourceType: Integer;
|
|
begin
|
|
if ImageList <> nil then
|
|
if (ImageList = dxPSUtl.ShellLargeImages) or
|
|
(ImageList.HandleAllocated and (ImageList.Handle = dxPSUtl.ShellLargeImages.Handle)) then
|
|
Result := imstShellLargeImageList
|
|
else
|
|
if (ImageList = dxPSUtl.ShellSmallImages) or
|
|
(ImageList.HandleAllocated and (ImageList.Handle = dxPSUtl.ShellSmallImages.Handle)) then
|
|
Result := imstShellSmallImageList
|
|
else
|
|
Result := imstImageList
|
|
else
|
|
Result := imstImage;
|
|
end;
|
|
|
|
function RetrieveImage(ASourceType: Integer; AnImageIndex: Integer): TGraphic;
|
|
begin
|
|
case ASourceType of
|
|
imstShellLargeImageList:
|
|
begin
|
|
Result := TBitmap.Create;
|
|
dxPSUtl.ShellLargeImages.GetBitmap(AnImageIndex, TBitmap(Result));
|
|
end;
|
|
|
|
imstShellSmallImageList:
|
|
begin
|
|
Result := TBitmap.Create;
|
|
dxPSUtl.ShellSmallImages.GetBitmap(AnImageIndex, TBitmap(Result));
|
|
end;
|
|
else
|
|
Result := Self.Image;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
SourceType: Integer;
|
|
Buffer: TGraphic;
|
|
begin
|
|
inherited WriteData(AWriter);
|
|
|
|
AWriter.WriteBoolean(HasImage);
|
|
if HasImage then
|
|
begin
|
|
SourceType := RetrieveSourceType;
|
|
AWriter.WriteInteger(SourceType);
|
|
case SourceType of
|
|
imstImageList:
|
|
begin
|
|
AWriter.WriteInteger(GetImageListIndex);
|
|
AWriter.WriteInteger(ImageIndex);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
Buffer := RetrieveImage(SourceType, ImageIndex);
|
|
try
|
|
AWriter.WriteString(Buffer.ClassName);
|
|
AWriter.WriteImage(Buffer);
|
|
finally
|
|
if Buffer <> Self.Image then Buffer.Free;
|
|
end;
|
|
end;
|
|
{ imstShellLargeImageList,
|
|
imstShellSmallImageList:
|
|
AWriter.WriteInteger(ImageIndex);
|
|
imstImage:
|
|
begin
|
|
AWriter.WriteString(Image.ClassName);
|
|
AWriter.WriteImage(Image);
|
|
end;}
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxReportCellImageContainer.SetImage(Value: TGraphic);
|
|
begin
|
|
if Value <> nil then
|
|
begin
|
|
CreateImage(TGraphicClass(Value.ClassType));
|
|
Image.Assign(Value);
|
|
|
|
if Width = 0 then Width := Image.Width;
|
|
if Height = 0 then Height := Image.Height;
|
|
end
|
|
else
|
|
FreeAndNil(FImage);
|
|
end;
|
|
|
|
{ TdxReportCellImage }
|
|
|
|
constructor TdxReportCellImage.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create(AParent);
|
|
ImageLayout := ilImageCenterLeft;
|
|
IsTextDrawnForCenteredImage := False;
|
|
IsTextShiftedForHorizontallyCenteredImage := True;
|
|
MakeSpaceForEmptyImage := True;
|
|
end;
|
|
|
|
procedure TdxReportCellImage.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TdxReportCellImage then
|
|
begin
|
|
ImageLayout := TdxReportCellImage(Source).ImageLayout;
|
|
MakeSpaceForEmptyImage := TdxReportCellImage(Source).MakeSpaceForEmptyImage;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCellImage.MeasureContentHeight(DC: HDC): Integer;
|
|
var
|
|
TextHeight: Integer;
|
|
begin
|
|
if ImageList <> nil then
|
|
Result := ImageList.Height
|
|
else
|
|
if FImage <> nil then
|
|
Result := Image.Height
|
|
else
|
|
Result := 0;
|
|
|
|
if Result <> 0 then Inc(Result, 2);
|
|
|
|
if ImageLayout in [ilImageTopLeft, ilImageCenterLeft, ilImageBottomLeft, ilImageTopRight, ilImageCenterRight, ilImageBottomRight] then
|
|
begin
|
|
TextHeight := inherited MeasureContentHeight(DC);
|
|
if Result < TextHeight then Result := TextHeight;
|
|
end
|
|
else
|
|
if ImageLayout in [ilImageTopCenter, ilImageBottomCenter] then
|
|
if not IsTextShiftedForHorizontallyCenteredImage then
|
|
begin
|
|
TextHeight := inherited MeasureContentHeight(DC);
|
|
if TextHeight > Result then Result := TextHeight;
|
|
end
|
|
else
|
|
Inc(Result, inherited MeasureContentHeight(DC))
|
|
else
|
|
if IsTextDrawnForCenteredImage then
|
|
begin
|
|
TextHeight := inherited MeasureContentHeight(DC);
|
|
if TextHeight > Result then Result := TextHeight;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCellImage.MeasureContentWidth(DC: HDC): Integer;
|
|
var
|
|
TextWidth: Integer;
|
|
begin
|
|
if ImageList <> nil then
|
|
Result := ImageList.Width
|
|
else
|
|
if FImage <> nil then
|
|
Result := Image.Width
|
|
else
|
|
Result := 0;
|
|
|
|
if Result <> 0 then Inc(Result, 2);
|
|
|
|
if ImageLayout in [ilImageTopLeft, ilImageCenterLeft, ilImageBottomLeft, ilImageTopRight, ilImageCenterRight, ilImageBottomRight] then
|
|
Inc(Result, inherited MeasureContentHeight(DC))
|
|
else
|
|
if (ImageLayout in [ilImageTopCenter, ilImageBottomCenter]) or ((ImageLayout = ilImageCenterCenter) and IsTextDrawnForCenteredImage) then
|
|
begin
|
|
TextWidth := inherited MeasureContentWidth(DC);
|
|
if Result < TextWidth then Result := TextWidth;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCellImage.GetHalfContentWidth(DC: HDC): Integer;
|
|
var
|
|
W, H: Integer;
|
|
begin
|
|
GetImageSizes(W, H);
|
|
if IsTextDrawnForCenteredImage and not IsTextShiftedForHorizontallyCenteredImage and
|
|
(ImageLayout in [ilImageTopCenter, ilImageCenterCenter, ilImageBottomCenter]) then
|
|
Result := (Renderer.CalcTextWidth(DC, Text, Font) + W) div 2 + Renderer.LineThickness
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportCellImage.GetImageAreaBounds(DC: HDC): TRect;
|
|
var
|
|
W, H: Integer;
|
|
R: TRect;
|
|
begin
|
|
GetImageSizes(W, H);
|
|
if (W <> 0) and (H <> 0) then
|
|
begin
|
|
Result := inherited GetImageAreaBounds(DC);
|
|
with Result do
|
|
begin
|
|
case ImageLayout of
|
|
ilImageTopLeft:
|
|
Right := Left + W + 2 * Renderer.UnitsPerPixel;
|
|
ilImageTopCenter:
|
|
begin
|
|
if not IsTextShiftedForHorizontallyCenteredImage then
|
|
begin
|
|
Inc(Left, (Right - Left - W) div 2 + Renderer.UnitsPerPixel);
|
|
Right := Left + W + Renderer.UnitsPerPixel;
|
|
end;
|
|
Bottom := Top + H + 2 * Renderer.UnitsPerPixel;
|
|
end;
|
|
ilImageTopRight:
|
|
Left := Right - W - 2 * Renderer.UnitsPerPixel;
|
|
ilImageCenterLeft:
|
|
Right := Left + W + 2 * Renderer.UnitsPerPixel;
|
|
ilImageCenterCenter:
|
|
if not IsTextShiftedForHorizontallyCenteredImage then
|
|
begin
|
|
Inc(Left, (Right - Left - W) div 2 + Renderer.UnitsPerPixel);
|
|
Right := Left + W + Renderer.UnitsPerPixel;
|
|
Inc(Top, (Bottom - Top - H) div 2 + Renderer.UnitsPerPixel);
|
|
Bottom := Top + H + Renderer.UnitsPerPixel;
|
|
end;
|
|
ilImageCenterRight:
|
|
Left := Right - W - 2 * Renderer.UnitsPerPixel;
|
|
ilImageBottomLeft:
|
|
Right := Left + W + 2 * Renderer.UnitsPerPixel;
|
|
ilImageBottomCenter:
|
|
begin
|
|
if not IsTextShiftedForHorizontallyCenteredImage then
|
|
begin
|
|
Inc(Left, (Right - Left - W) div 2 + Renderer.UnitsPerPixel);
|
|
Right := Left + W + Renderer.UnitsPerPixel;
|
|
end;
|
|
Top := Bottom - H - 2 * Renderer.UnitsPerPixel;
|
|
end;
|
|
ilImageBottomRight:
|
|
Left := Right - W - 2 * Renderer.UnitsPerPixel;
|
|
end;
|
|
R := GetInnerBounds(DC);
|
|
OffsetRect(Result, -GetHalfContentWidth(DC), 0);
|
|
if Left < R.Left then Left := R.Left;
|
|
if Top < R.Top then Top := R.Top;
|
|
if Right > R.Right then Right := R.Right;
|
|
if Bottom > R.Bottom then Bottom := R.Bottom;
|
|
end;
|
|
end
|
|
else
|
|
Result := NullRect;
|
|
end;
|
|
|
|
function TdxReportCellImage.GetImageBounds(DC: HDC): TRect;
|
|
var
|
|
W, H: Integer;
|
|
begin
|
|
Result := GetImageAreaBounds(DC);
|
|
if not IsRectEmpty(Result) then
|
|
begin
|
|
GetImageSizes(W, H);
|
|
with Result do
|
|
begin
|
|
case ImageLayout of
|
|
ilImageTopLeft,
|
|
ilImageTopCenter,
|
|
ilImageTopRight:
|
|
Inc(Top, LineThickness);
|
|
|
|
ilImageCenterLeft,
|
|
ilImageCenterCenter,
|
|
ilImageCenterRight:
|
|
Inc(Top, (Bottom - Top - H) div 2);
|
|
|
|
ilImageBottomLeft,
|
|
ilImageBottomCenter,
|
|
ilImageBottomRight:
|
|
Top := Bottom - H - LineThickness;
|
|
end;
|
|
Inc(Left, (Right - Left - W) div 2);
|
|
Right := Left + W;
|
|
Bottom := Top + H;
|
|
// CorrectBounds(Result, DC);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCellImage.GetTextBounds(DC: HDC): TRect;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
Result := inherited GetTextBounds(DC);
|
|
if IsImageDrawn or MakeSpaceForEmptyImage then
|
|
begin
|
|
if not ((ImageLayout in [ilImageTopCenter, ilImageCenterCenter, ilImageBottomCenter]) and
|
|
not IsTextShiftedForHorizontallyCenteredImage) then
|
|
begin
|
|
R := GetImageBounds(DC);
|
|
if not IsRectEmpty(R) then
|
|
with Result do
|
|
case ImageLayout of
|
|
ilImageTopLeft, ilImageCenterLeft, ilImageBottomLeft:
|
|
Left := R.Right;
|
|
ilImageTopRight, ilImageCenterRight, ilImageBottomRight:
|
|
Right := R.Left;
|
|
ilImageTopCenter:
|
|
if IsTextShiftedForHorizontallyCenteredImage then
|
|
Top := R.Bottom;
|
|
ilImageCenterCenter:
|
|
if not IsTextDrawn then //TODO: TdxReportCellImage.GetTextBounds(
|
|
Result := NullRect;
|
|
ilImageBottomCenter:
|
|
if IsTextShiftedForHorizontallyCenteredImage then
|
|
Bottom := R.Top;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCellImage.IsImageBackgroundDrawn: Boolean;
|
|
begin
|
|
Result := inherited IsImageBackgroundDrawn and MakeSpaceForEmptyImage and
|
|
not ((ImageLayout in [ilImageTopCenter, ilImageCenterCenter, ilImageBottomCenter]) and
|
|
not IsTextShiftedForHorizontallyCenteredImage);
|
|
end;
|
|
|
|
function TdxReportCellImage.IsTextDrawn: Boolean;
|
|
begin
|
|
Result := inherited IsTextDrawn and ((ImageLayout <> ilImageCenterCenter) or IsTextDrawnForCenteredImage);
|
|
end;
|
|
|
|
function TdxReportCellImage.IsTextBackgroundDrawn: Boolean;
|
|
begin
|
|
Result := inherited IsTextBackgroundDrawn and
|
|
(not (ImageLayout in [ilImageTopCenter, ilImageCenterCenter, ilImageBottomCenter]) or
|
|
IsTextDrawnForCenteredImage or not HasImage);
|
|
end;
|
|
|
|
function TdxReportCellImage.GetImageLayout: TdxImageLayout;
|
|
begin
|
|
Result := TdxImageLayout((Format and dxPSGlbl.dxFormatImageLayoutMask) shr dxPSGlbl.dxFormatImageLayoutOffset);
|
|
end;
|
|
|
|
function TdxReportCellImage.GetIsTextDrawnForCenteredImage: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatIsTextDrawnForCenteredImage);
|
|
end;
|
|
|
|
function TdxReportCellImage.GetIsTextShiftedForHorizontallyCenteredImage: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatIsTextShiftedForHorizontallyCenteredImage);
|
|
end;
|
|
|
|
function TdxReportCellImage.GetMakeSpaceForEmptyImage: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatMakeSpaceForEmptyImage);
|
|
end;
|
|
|
|
procedure TdxReportCellImage.SetImageLayout(Value: TdxImageLayout);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatImageLayoutMask or (Byte(Value) shl dxPSGlbl.dxFormatImageLayoutOffset);
|
|
end;
|
|
|
|
procedure TdxReportCellImage.SetIsTextDrawnForCenteredImage(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatIsTextDrawnForCenteredImage, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellImage.SetIsTextShiftedForHorizontallyCenteredImage(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatIsTextShiftedForHorizontallyCenteredImage, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellImage.SetMakeSpaceForEmptyImage(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatMakeSpaceForEmptyImage, Value);
|
|
end;
|
|
|
|
{ TdxReportCellGraphic }
|
|
|
|
constructor TdxReportCellGraphic.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited;
|
|
ImageBuffering := cibAlways;
|
|
end;
|
|
|
|
{procedure TdxReportCellGraphic.Assign(Source: TPersistent);
|
|
begin
|
|
inherited;
|
|
if Source is TdxReportCellGraphic then
|
|
DrawMode := TdxReportCellGraphic(Source).DrawMode;
|
|
end;}
|
|
|
|
function TdxReportCellGraphic.MeasureFontHeight(DC: HDC): Integer;
|
|
begin
|
|
Result := Renderer.CalcTextPatternHeight(DC, Renderer.RenderInfo.BaseContentFont);
|
|
end;
|
|
|
|
function TdxReportCellGraphic.MeasureContentHeight(DC: HDC): Integer;
|
|
begin
|
|
if ImageList <> nil then
|
|
Result := ImageList.Height
|
|
else
|
|
if FImage <> nil then
|
|
begin
|
|
Result := Image.Height;
|
|
if Stretch and (Result > 0) and (Image.Width > 0) then
|
|
Result := Round(Result * Width / Image.Width);
|
|
end
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportCellGraphic.MeasureContentWidth(DC: HDC): Integer;
|
|
begin
|
|
if ImageList <> nil then
|
|
Result := ImageList.Width
|
|
else
|
|
if FImage <> nil then
|
|
Result := Image.Width
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxReportCellGraphic.GetImageBounds(DC: HDC): TRect;
|
|
var
|
|
W, H, cW, cH: Integer;
|
|
R: TRect;
|
|
begin
|
|
GetImageSizes(W, H);
|
|
if (W <> 0) and (H <> 0) then
|
|
begin
|
|
R := GetImageAreaBounds(DC);
|
|
with Result do
|
|
begin
|
|
case DrawMode of
|
|
gdmNone:
|
|
begin
|
|
Result.TopLeft := R.TopLeft;
|
|
Right := Left + W;
|
|
Bottom := Top + H;
|
|
end;
|
|
gdmCenter:
|
|
begin
|
|
Left := R.Left + (R.Right - R.Left - W) div 2;
|
|
Top := R.Top + (R.Bottom - R.Top - H) div 2;
|
|
Right := Left + W;
|
|
Bottom := Top + H;
|
|
end;
|
|
gdmStretch:
|
|
Result := R;
|
|
gdmStretchProportional,
|
|
gdmCenterAndStretchProportional:
|
|
begin
|
|
TopLeft := R.TopLeft;
|
|
cW := R.Right - R.Left;
|
|
cH := R.Bottom - R.Top;
|
|
if W / H > cW / cH then
|
|
begin
|
|
Right := Left + cW;
|
|
Bottom := Top + MulDiv(cW, H, W);
|
|
end
|
|
else
|
|
begin
|
|
Bottom := Top + cH;
|
|
Right := Left + MulDiv(cH, W, H);
|
|
end;
|
|
end;
|
|
end;
|
|
if DrawMode = gdmCenterAndStretchProportional then
|
|
begin
|
|
W := Right - Left;
|
|
H := Bottom - Top;
|
|
Left := R.Left + (R.Right - R.Left - W) div 2;
|
|
Top := R.Top + (R.Bottom - R.Top - H) div 2;
|
|
Right := Left + W;
|
|
Bottom := Top + H;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
function TdxReportCellGraphic.GetImageBuffering: TdxCellImageBuffering;
|
|
begin
|
|
Result := TdxCellImageBuffering((Format and dxPSGlbl.dxFormatGraphicBufferingMask) shr dxPSGlbl.dxFormatGraphicBufferingOffset);
|
|
end;
|
|
|
|
function TdxReportCellGraphic.GetTextBounds(DC: HDC): TRect;
|
|
begin
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
procedure TdxReportCellGraphic.SetImageBuffering(Value: TdxCellImageBuffering);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatGraphicBufferingMask or (Byte(Value) shl dxPSGlbl.dxFormatGraphicBufferingOffset);
|
|
end;
|
|
|
|
function TdxReportCellGraphic.GetCenter: Boolean;
|
|
begin
|
|
Result := DrawMode = gdmCenter;
|
|
end;
|
|
|
|
function TdxReportCellGraphic.GetDrawMode: TdxGraphicDrawMode;
|
|
begin
|
|
Result := TdxGraphicDrawMode((Format and dxPSGlbl.dxFormatGraphicDrawModeMask) shr dxPSGlbl.dxFormatGraphicDrawModeOffset);
|
|
end;
|
|
|
|
function TdxReportCellGraphic.GetStretch: Boolean;
|
|
begin
|
|
Result := (DrawMode = gdmStretchProportional) or (DrawMode = gdmCenterAndStretchProportional);
|
|
end;
|
|
|
|
procedure TdxReportCellGraphic.SetCenter(Value: Boolean);
|
|
begin
|
|
if Value then
|
|
if Stretch then
|
|
DrawMode := gdmCenterAndStretchProportional
|
|
else
|
|
DrawMode := gdmCenter;
|
|
end;
|
|
|
|
procedure TdxReportCellGraphic.SetDrawMode(Value: TdxGraphicDrawMode);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatGraphicDrawModeMask or (Byte(Value) shl dxPSGlbl.dxFormatGraphicDrawModeOffset);
|
|
end;
|
|
|
|
procedure TdxReportCellGraphic.SetStretch(Value: Boolean);
|
|
begin
|
|
if Value then
|
|
if Center then
|
|
DrawMode := gdmCenterAndStretchProportional
|
|
else
|
|
DrawMode := gdmStretchProportional;
|
|
end;
|
|
|
|
{ TdxReportCellExpandButton }
|
|
|
|
constructor TdxReportCellExpandButton.Create(AParent: TdxReportCell);
|
|
begin
|
|
inherited Create(AParent);
|
|
ButtonAlignHorz := bahCenter;
|
|
ButtonAlignVert := bavCenter;
|
|
ButtonBorder3D := False;
|
|
ButtonBorder3DSoft := False;
|
|
ButtonBorderShadow := False;
|
|
ButtonExpanded := False;
|
|
ButtonInteriorColor := clNone;
|
|
ButtonSize := dxDefaultCrossSignCrossSize; // 9
|
|
ButtonTransparent := True;
|
|
KeepOddSize := True;
|
|
ShowButton := False;
|
|
ShowButtonBorder := True;
|
|
TreeLineMode := tlmNone;
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TdxReportCellExpandButton then
|
|
begin
|
|
ButtonBorder3D := TdxReportCellExpandButton(Source).ButtonBorder3D;
|
|
ButtonBorder3DSoft := TdxReportCellExpandButton(Source).ButtonBorder3DSoft;
|
|
ButtonBorderShadow := TdxReportCellExpandButton(Source).ButtonBorderShadow;
|
|
ButtonExpanded := TdxReportCellExpandButton(Source).ButtonExpanded;
|
|
ButtonInteriorColor := TdxReportCellExpandButton(Source).ButtonInteriorColor;
|
|
ButtonSize := TdxReportCellExpandButton(Source).ButtonSize;
|
|
ButtonTransparent := TdxReportCellExpandButton(Source).ButtonTransparent;
|
|
KeepOddSize := TdxReportCellExpandButton(Source).KeepOddSize;
|
|
ShowButton := TdxReportCellExpandButton(Source).ShowButton;
|
|
ShowButtonBorder := TdxReportCellExpandButton(Source).ShowButtonBorder;
|
|
TreeLineMode := TdxReportCellExpandButton(Source).TreeLineMode;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.DrawContent(DC: HDC; AStage: TdxPSRenderStages);
|
|
begin
|
|
if IsBackgroundBitmapDrawn then
|
|
DrawBackgroundBitmap(DC)
|
|
else
|
|
if IsBackgroundDrawn then
|
|
DrawBackground(DC);
|
|
if ShowButton then DrawExpandButton(DC);
|
|
if AreTreeLinesDrawn then DrawTreeLines(DC);
|
|
if IsBordersDrawn then DrawBorders(DC);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.DrawExpandButton(DC: HDC);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := GetButtonBounds(DC);
|
|
if RectVisible(DC, R) then
|
|
Renderer.DrawExpandButton(DC, R, ButtonExpanded, ShowButtonBorder,
|
|
ButtonBorder3D, ButtonBorder3DSoft, ButtonBorderShadow, not ButtonTransparent,
|
|
ReportCells.ExpandButtonBorderColor, ButtonInteriorColor);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.DrawTreeLines(DC: HDC);
|
|
type
|
|
TdxTreeLinesDrawInfo = record
|
|
TopRect: TRect;
|
|
RightRect: TRect;
|
|
BottomRect: TRect;
|
|
end;
|
|
|
|
function GetTreeLineParts: TdxPSTreeLineParts;
|
|
const
|
|
Parts: array[TdxPSTreeLineMode] of TdxPSTreeLineParts =
|
|
([], [tlpTop, tlpBottom], [tlpTop, tlpRight, tlpBottom],
|
|
[tlpBottom, tlpRight], [tlpTop, tlpRight]);
|
|
begin
|
|
Result := Parts[TreeLineMode];
|
|
end;
|
|
|
|
procedure DrawTreeLine(const R: TRect; APattern: TdxPSFillPatternClass);
|
|
var
|
|
BkColor: TColor;
|
|
begin
|
|
if RectVisible(DC, R) then
|
|
begin
|
|
if Transparent then
|
|
BkColor := clWindow
|
|
else
|
|
BkColor := Color;
|
|
Renderer.FillRectEx(DC, R, ReportCells.TreeLineColor, BkColor, APattern);
|
|
end;
|
|
end;
|
|
|
|
procedure CalculateDrawInfo(const AButtonRect: TRect; var ADrawInfo: TdxTreeLinesDrawInfo);
|
|
begin
|
|
with ADrawInfo do
|
|
begin
|
|
TopRect := BoundsRect;
|
|
with TopRect do
|
|
begin
|
|
Inc(Left, (Right - Left) div 2 - Renderer.LineThickness div 2);
|
|
Right := Left + Renderer.UnitsPerPixel;
|
|
Dec(Bottom, (Bottom - Top) div 2);
|
|
end;
|
|
if csTop in CellSides then
|
|
Dec(TopRect.Top, Renderer.LineThickness);
|
|
|
|
RightRect := BoundsRect;
|
|
with RightRect do
|
|
begin
|
|
Inc(Left, (Right - Left) div 2);
|
|
Inc(Top, (Bottom - Top) div 2 - Renderer.LineThickness div 2);
|
|
Bottom := Top + Renderer.UnitsPerPixel;
|
|
end;
|
|
if csRight in CellSides then
|
|
Dec(RightRect.Right, Renderer.LineThickness);
|
|
|
|
BottomRect := BoundsRect;
|
|
with BottomRect do
|
|
begin
|
|
Inc(Left, (Right - Left) div 2 - Renderer.LineThickness div 2);
|
|
Right := Left + Renderer.UnitsPerPixel;
|
|
Inc(Top, (Bottom - Top) div 2);
|
|
end;
|
|
if csBottom in CellSides then
|
|
Dec(BottomRect.Bottom, Renderer.LineThickness);
|
|
|
|
if not IsRectEmpty(AButtonRect) then
|
|
begin
|
|
TopRect.Bottom := AButtonRect.Top - Renderer.LineThickness;
|
|
RightRect.Left := AButtonRect.Right + Renderer.LineThickness;
|
|
BottomRect.Top := AButtonRect.Bottom + Renderer.LineThickness;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
const
|
|
Patterns: array[TdxPSTreeLineStyle] of TdxPSFillPatternClass = (TdxPSSolidFillPattern, TdxPSGray50FillPattern);
|
|
var
|
|
Parts: TdxPSTreeLineParts;
|
|
Pattern: TdxPSFillPatternClass;
|
|
DrawInfo: TdxTreeLinesDrawInfo;
|
|
begin
|
|
Parts := GetTreeLineParts;
|
|
Pattern := Patterns[ReportCells.TreeLineStyle];
|
|
|
|
CalculateDrawInfo(GetButtonBounds(DC), DrawInfo);
|
|
with DrawInfo do
|
|
begin
|
|
if tlpTop in Parts then DrawTreeLine(TopRect, Pattern);
|
|
if tlpBottom in Parts then DrawTreeLine(BottomRect, Pattern);
|
|
if tlpRight in Parts then DrawTreeLine(RightRect, Pattern);
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonBounds(DC: HDC): TRect;
|
|
begin
|
|
if ShowButton then
|
|
begin
|
|
Result := CalculateButtonBounds;
|
|
FixupRect(DC, Result);
|
|
end
|
|
else
|
|
Result := dxPSGlbl.NullRect;
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.ConvertCoords(APixelsNumerator, APixelsDenominator: Integer);
|
|
begin
|
|
inherited;
|
|
ButtonSize := MulDiv(ButtonSize, APixelsNumerator, APixelsDenominator);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.AreTreeLinesDrawn: Boolean;
|
|
begin
|
|
Result := TreeLineMode <> tlmNone;
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.CalculateButtonBounds: TRect;
|
|
var
|
|
ButtonSize: Integer;
|
|
begin
|
|
Result := BoundsRect;
|
|
with Result do
|
|
begin
|
|
ButtonSize := ActualButtonSize;
|
|
case ButtonAlignHorz of
|
|
bahLeft:
|
|
begin
|
|
Inc(Left, ButtonIndents.Left);
|
|
Right := Left + ButtonSize;
|
|
end;
|
|
bahCenter:
|
|
begin
|
|
Inc(Left, (Right - Left - ButtonSize) div 2);
|
|
Right := Left + ButtonSize;
|
|
end;
|
|
bahRight:
|
|
begin
|
|
Dec(Right, ButtonIndents.Right);
|
|
Left := Right - ButtonSize;
|
|
end;
|
|
end;
|
|
|
|
case ButtonAlignVert of
|
|
bavTop:
|
|
begin
|
|
Inc(Top, ButtonIndents.Top);
|
|
Bottom := Top + ButtonSize;
|
|
end;
|
|
bavCenter:
|
|
begin
|
|
Inc(Top, (Bottom - Top - ButtonSize) div 2);
|
|
Bottom := Top + ButtonSize;
|
|
end;
|
|
bavBottom:
|
|
begin
|
|
Dec(Bottom, ButtonIndents.Bottom);
|
|
Top := Bottom - ButtonSize;
|
|
end;
|
|
end;
|
|
|
|
if Right < Left then Right := Left;
|
|
if Bottom < Top then Bottom := Top;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonAlignHorz: TdxReportCellExpandButtonAlignHorz;
|
|
begin
|
|
Result := bahCenter;
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonAlignVert: TdxReportCellExpandButtonAlignVert;
|
|
begin
|
|
Result := bavCenter;
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonIndents: TRect;
|
|
begin
|
|
if Renderer <> nil then
|
|
Result := MakeRect(LineThickness, LineThickness, LineThickness, LineThickness)
|
|
else
|
|
Result := NullRect;
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetButtonAlignHorz(Value: TdxReportCellExpandButtonAlignHorz);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetButtonAlignVert(Value: TdxReportCellExpandButtonAlignVert);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited ReadData(AReader);
|
|
ButtonInteriorColor := AReader.ReadInteger;
|
|
ButtonSize := AReader.ReadInteger;
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited WriteData(AWriter);
|
|
AWriter.WriteInteger(ButtonInteriorColor);
|
|
AWriter.WriteInteger(ButtonSize);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetActualButtonSize: Integer;
|
|
var
|
|
LineThickness: Integer;
|
|
begin
|
|
Result := ButtonSize;
|
|
|
|
LineThickness := Renderer.LineThickness;
|
|
if (Result mod LineThickness) > (LineThickness div 2) then
|
|
Inc(Result, LineThickness - (Result mod LineThickness))
|
|
else
|
|
Dec(Result, Result mod LineThickness);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonBorder3D: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExpandButtonBorder3D);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonBorder3DSoft: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExpandButtonBorder3DSoft);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonBorderShadow: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExpandButtonBorderShadow);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonExpanded: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExpandButtonExpanded);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetButtonTransparent: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExpandButtonTransparent);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetShowButtonBorder: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExpandButtonShowBorder);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetKeepOddSize: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExpandButtonKeepOddSize);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetShowButton: Boolean;
|
|
begin
|
|
Result := GetFormatBit(dxPSGlbl.dxFormatExpandButtonVisible);
|
|
end;
|
|
|
|
function TdxReportCellExpandButton.GetTreeLineMode: TdxPSTreeLineMode;
|
|
begin
|
|
Result := TdxPSTreeLineMode((Format and dxPSGlbl.dxFormatTreeLineModeMask) shr dxPSGlbl.dxFormatTreeLineModeOffset);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetButtonBorder3D(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExpandButtonBorder3D, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetButtonBorder3DSoft(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExpandButtonBorder3DSoft, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetButtonBorderShadow(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExpandButtonBorderShadow, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetButtonExpanded(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExpandButtonExpanded, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetButtonTransparent(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExpandButtonTransparent, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetKeepOddSize(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExpandButtonKeepOddSize, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetShowButton(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExpandButtonVisible, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetShowButtonBorder(Value: Boolean);
|
|
begin
|
|
SetFormatBit(dxPSGlbl.dxFormatExpandButtonShowBorder, Value);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButton.SetTreeLineMode(Value: TdxPSTreeLineMode);
|
|
begin
|
|
Format := Format and not dxPSGlbl.dxFormatTreeLineModeMask or (Byte(Value) shl dxPSGlbl.dxFormatTreeLineModeOffset);
|
|
end;
|
|
|
|
{ TdxReportCellExpandButtonEx }
|
|
|
|
function TdxReportCellExpandButtonEx.GetButtonAlignHorz: TdxReportCellExpandButtonAlignHorz;
|
|
begin
|
|
Result := TdxReportCellExpandButtonAlignHorz((FormatEx and dxPSGlbl.dxFormatExButtonAlignHorzMask) shr dxPSGlbl.dxFormatExButtonAlignHorzOffset);
|
|
end;
|
|
|
|
function TdxReportCellExpandButtonEx.GetButtonAlignVert: TdxReportCellExpandButtonAlignVert;
|
|
begin
|
|
Result := TdxReportCellExpandButtonAlignVert((FormatEx and dxPSGlbl.dxFormatExButtonAlignVertMask) shr dxPSGlbl.dxFormatExButtonAlignVertOffset);
|
|
end;
|
|
|
|
function TdxReportCellExpandButtonEx.GetButtonIndents: TRect;
|
|
begin
|
|
Result := inherited GetButtonIndents;
|
|
if Renderer <> nil then
|
|
with Result do
|
|
begin
|
|
Inc(Top, 5 * LineThickness);
|
|
Inc(Bottom, 5 * LineThickness);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButtonEx.SetButtonAlignHorz(Value: TdxReportCellExpandButtonAlignHorz);
|
|
begin
|
|
FormatEx := FormatEx and not dxPSGlbl.dxFormatExButtonAlignHorzMask or (Byte(Value) shl dxPSGlbl.dxFormatExButtonAlignHorzOffset);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButtonEx.SetButtonAlignVert(Value: TdxReportCellExpandButtonAlignVert);
|
|
begin
|
|
FormatEx := FormatEx and not dxPSGlbl.dxFormatExButtonAlignVertMask or (Byte(Value) shl dxPSGlbl.dxFormatExButtonAlignVertOffset);
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButtonEx.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
inherited;
|
|
FormatEx := AReader.ReadInteger;
|
|
end;
|
|
|
|
procedure TdxReportCellExpandButtonEx.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
inherited;
|
|
AWriter.WriteInteger(FormatEx);
|
|
end;
|
|
|
|
{ TdxPSExplorerChangeNotifier }
|
|
|
|
constructor TdxPSExplorerChangeNotifier.Create(AnExplorer: TCustomdxPSExplorer);
|
|
begin
|
|
inherited Create;
|
|
Explorer := AnExplorer;
|
|
end;
|
|
|
|
destructor TdxPSExplorerChangeNotifier.Destroy;
|
|
begin
|
|
Explorer := nil;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifier.SetExplorer(Value: TCustomdxPSExplorer);
|
|
begin
|
|
if FExplorer <> Value then
|
|
begin
|
|
if FExplorer <> nil then
|
|
FExplorer.UnregisterNotifier(Self);
|
|
if Value <> nil then
|
|
Value.RegisterNotifier(Self);
|
|
end;
|
|
end;
|
|
|
|
{ TdxPSExplorerChangeNotifierAdapter }
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.ExplorerRefresh(AStage: TdxPSExplorerRefreshStage);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.FolderPopulated(AFolder: TdxPSExplorerFolder);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.ItemAdded(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.ItemDataLoaded(AnItem: TdxPSExplorerItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.ItemDataUnloaded(AnItem: TdxPSExplorerItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.ItemDeleted(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.ItemParentChanged(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.ItemPropertiesChanged(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxPSExplorerChangeNotifierAdapter.ItemRenamed(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
end;
|
|
|
|
{ TdxPSExplorerTreeChangeNotifier }
|
|
|
|
constructor TdxPSExplorerTreeChangeNotifier.Create(ATreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
ARegister: Boolean = True);
|
|
begin
|
|
Assert(ATreeContainer <> nil);
|
|
FTreeContainer := ATreeContainer;
|
|
inherited Create(TreeContainer.Explorer);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.ExplorerRefresh(AStage: TdxPSExplorerRefreshStage);
|
|
begin
|
|
case AStage of
|
|
ersBefore:
|
|
begin
|
|
TreeContainer.EndEdit(True);
|
|
TreeContainer.BeginUpdate;
|
|
TreeContainer.SaveState;
|
|
end;
|
|
ersAfter:
|
|
begin
|
|
if Explorer <> nil then Explorer.BuildTree(TreeContainer);
|
|
TreeContainer.RestoreState;
|
|
TreeContainer.RefreshSorting(nil);
|
|
TreeContainer.EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.FolderPopulated(AFolder: TdxPSExplorerFolder);
|
|
begin
|
|
if Explorer <> nil then Explorer.PopulateTreeFolder(TreeContainer, AFolder);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.ItemAdded(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
with TreeContainer do
|
|
begin
|
|
AddItem(CreationParent, AnItem);
|
|
SelectedItem := AnItem;
|
|
if Control.Focused then BeginEdit(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.ItemDataLoaded(AnItem: TdxPSExplorerItem);
|
|
begin
|
|
TreeContainer.MakeItemVisible(AnItem);
|
|
TreeContainer.InvalidateItem(AnItem);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.ItemDataUnloaded(AnItem: TdxPSExplorerItem);
|
|
begin
|
|
TreeContainer.InvalidateItem(AnItem);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.ItemDeleted(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
TreeContainer.DeleteItem(AnItem);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.ItemParentChanged(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
TreeContainer.MoveItem(AnItem);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.ItemPropertiesChanged(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
if TreeContainer.SelectedItem = AnItem then
|
|
TreeContainer.SelectedItemText := AnItem.DisplayName;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeChangeNotifier.ItemRenamed(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
TreeContainer.RenameItem(AnItem);
|
|
end;
|
|
|
|
{ TCustomdxPSExplorerTreeContainer }
|
|
|
|
constructor TCustomdxPSExplorerTreeContainer.Create(AnExplorer: TCustomdxPSExplorer;
|
|
AHost: IdxPSExplorerTreeContainerHost);
|
|
begin
|
|
Assert(AnExplorer <> nil);
|
|
Assert(AHost <> nil);
|
|
|
|
inherited Create;
|
|
FExplorer := AnExplorer;
|
|
FHost := AHost;
|
|
|
|
CreateTreeContainer;
|
|
FChangeNotifier := TdxPSExplorerTreeChangeNotifier.Create(Self, True);
|
|
end;
|
|
|
|
destructor TCustomdxPSExplorerTreeContainer.Destroy;
|
|
begin
|
|
FreeAndNil(FControl);
|
|
FreeAndNil(FChangeNotifier);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerTreeContainer.ControlClass: TWinControlClass;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
class procedure TCustomdxPSExplorerTreeContainer.Register;
|
|
begin
|
|
dxPSExplorerTreeContainerFactory.Register(Self);
|
|
end;
|
|
|
|
class procedure TCustomdxPSExplorerTreeContainer.Unregister;
|
|
begin
|
|
dxPSExplorerTreeContainerFactory.Unregister(Self);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.BeginUpdate;
|
|
begin
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.EndUpdate;
|
|
begin
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanCreateFolder: Boolean;
|
|
begin
|
|
Result := Explorer.CanCreateFolder and not IsEditing and IsFolderSelected;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanCreateItem: Boolean;
|
|
begin
|
|
Result := Explorer.CanCreateItem and not IsEditing;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanDeleteSelection: Boolean;
|
|
begin
|
|
Result := not IsEditing and Explorer.CanDelete(SelectedItem);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanLoadSelectedItemData: Boolean;
|
|
begin
|
|
Result := (Control <> nil) and Control.Focused and not IsEditing and
|
|
IsItemSelected and TdxPSExplorerItem(SelectedItem).CanLoadData;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanRefresh: Boolean;
|
|
begin
|
|
Result := not IsEditing;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanRenameSelectedItem: Boolean;
|
|
begin
|
|
Result := not IsEditing and Explorer.CanRename(SelectedItem);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanShowPropertySheetsForSelectedItem: Boolean;
|
|
begin
|
|
Result := not IsEditing and (SelectedItem <> nil) and SelectedItem.HasPropertySheets;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanUnloadItemData: Boolean;
|
|
begin
|
|
Result := not IsEditing and (Host.ReportLink <> nil) and
|
|
Host.ReportLink.CanUnloadData and (Explorer.LoadedItem <> nil);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CreateItem: TdxPSExplorerItem;
|
|
begin
|
|
if CanCreateItem then
|
|
Result := Explorer.CreateNewItem(CreationParent, Host.ReportLink)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.DeleteSelection(AShowMessage: Boolean = True);
|
|
begin
|
|
if CanDeleteSelection and (not AShowMessage or dxPSUtl.MessageQuestion(SelectedItem.DeleteMessageText)) then
|
|
SelectedItem.Delete;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.IsSelectedItemCurrentlyLoaded: Boolean;
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
begin
|
|
Item := SelectedItem;
|
|
Result := (Item is TdxPSExplorerItem) and TdxPSExplorerItem(Item).IsCurrentlyLoaded;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.LoadSelectedItemData;
|
|
begin
|
|
if CanLoadSelectedItemData then
|
|
Explorer.LoadItemData(TdxPSExplorerItem(SelectedItem), Host.ReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.RenameSelectedItem;
|
|
begin
|
|
if CanRenameSelectedItem then BeginEdit(True);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.ShowSelectedItemPropertySheets: Boolean;
|
|
begin
|
|
Result := CanShowPropertySheetsForSelectedItem and TdxPSExplorerItem(SelectedItem).ShowPropertySheets;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.UnloadItemData;
|
|
begin
|
|
if CanUnloadItemData then
|
|
Explorer.UnloadItemData(Explorer.LoadedItem);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeContainer.CanFocus: Boolean;
|
|
begin
|
|
Result := (Control <> nil) and Control.CanFocus;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.SetFocus;
|
|
begin
|
|
if (Control <> nil) and Control.CanFocus and not IsRectEmpty(Control.ClientRect) then
|
|
Control.SetFocus;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.RefreshSorting(ANode: TObject);
|
|
begin
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.RefreshSorting(AFolder: TdxPSExplorerFolder);
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.DeleteItem(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
EndEdit(False);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.InvalidateItem(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.RestoreState;
|
|
begin
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.SaveState;
|
|
begin
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.CreateTreeContainer;
|
|
begin
|
|
if FControl = nil then
|
|
begin
|
|
FControl := ControlClass.Create(nil);
|
|
FControl.Parent := Host.TreeContainerParent;
|
|
InitializeTreeContainer;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.InitializeTreeContainer;
|
|
begin
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.ProcessKeyDown(var Key: Word; Shift: TShiftState);
|
|
var
|
|
PopupMenu: TPopupMenu;
|
|
MenuItem: TMenuItem;
|
|
begin
|
|
PopupMenu := dxPSUtl.Control_GetPopupMenu(Control);
|
|
if PopupMenu <> nil then
|
|
begin
|
|
MenuItem := PopupMenu.FindItem(Key, fkShortCut);
|
|
if (MenuItem <> nil) and MenuItem.Enabled and MenuItem.Visible then
|
|
begin
|
|
MenuItem.Click;
|
|
Key := 0;
|
|
Exit;
|
|
end
|
|
end;
|
|
|
|
if not IsEditing then
|
|
case Key of
|
|
VK_F2:
|
|
if Shift = [] then BeginEdit(True);
|
|
VK_F5:
|
|
if Shift = [] then Explorer.Refresh;
|
|
VK_DELETE:
|
|
if Shift = [] then DeleteSelection(True);
|
|
VK_ESCAPE:
|
|
Host.UpdateState;
|
|
VK_RETURN:
|
|
if ssCtrl in Shift then LoadSelectedItemData;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeContainer.ProcessKeyPress(var Key: Char);
|
|
begin
|
|
if IsEditing and not Explorer.AcceptItemNameChar(SelectedItem, Key) then
|
|
Key := #0;
|
|
end;
|
|
|
|
{ TdxPSExplorerTreeBuilder }
|
|
|
|
class procedure TdxPSExplorerTreeBuilder.Register;
|
|
begin
|
|
dxPSExplorerTreeBuilderFactory.Register(Self);
|
|
end;
|
|
|
|
class procedure TdxPSExplorerTreeBuilder.Unregister;
|
|
begin
|
|
dxPSExplorerTreeBuilderFactory.Unregister(Self);
|
|
end;
|
|
|
|
class procedure TdxPSExplorerTreeBuilder.BuildTree(AnExplorer: TCustomdxPSExplorer;
|
|
ATreeContainer: TCustomdxPSExplorerTreeContainer);
|
|
begin
|
|
with ATreeContainer do
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
Clear;
|
|
CreateFolderNode(ATreeContainer, nil, AnExplorer.Root);
|
|
ExpandItem(AnExplorer.Root);
|
|
SelectedItem := AnExplorer.Root;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class procedure TdxPSExplorerTreeBuilder.CreateFolderNode(ATreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
AParent, AFolder: TdxPSExplorerFolder);
|
|
begin
|
|
CreateItemNode(ATreeContainer, AParent, AFolder);
|
|
PopulateTreeFolder(ATreeContainer, AFolder);
|
|
end;
|
|
|
|
class procedure TdxPSExplorerTreeBuilder.CreateItemNode(ATreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
AParent: TdxPSExplorerFolder; AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
ATreeContainer.AddItem(AParent, AnItem);
|
|
end;
|
|
|
|
class procedure TdxPSExplorerTreeBuilder.PopulateTreeFolder(ATreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
AFolder: TdxPSExplorerFolder);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with ATreeContainer do
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
for I := 0 to AFolder.FolderCount - 1 do
|
|
CreateFolderNode(ATreeContainer, AFolder, AFolder.Folders[I]);
|
|
for I := 0 to AFolder.ItemCount - 1 do
|
|
CreateItemNode(ATreeContainer, AFolder, AFolder.Items[I]);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
//RefreshSorting(AFolder); {3.1}
|
|
end;
|
|
end;
|
|
|
|
{ TdxPSExplorerItemPropertySheets }
|
|
|
|
constructor TCustomdxPSExplorerItemPropertySheets.CreateEx(AnExplorerItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
Create(nil);
|
|
FExplorerItem := AnExplorerItem;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerItemPropertySheets.Execute(AnExplorerItem: TCustomdxPSExplorerItem): Boolean;
|
|
begin
|
|
with FormClass.CreateEx(AnExplorerItem) do
|
|
try
|
|
Initialize;
|
|
try
|
|
Result := ShowModal = mrOK;
|
|
finally
|
|
Done;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItemPropertySheets.ExplorerItem: TCustomdxPSExplorerItem;
|
|
begin
|
|
Result := FExplorerItem;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItemPropertySheets.Done;
|
|
begin
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItemPropertySheets.Initialize;
|
|
begin
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerItemPropertySheets.FormClass: TCustomdxPSExplorerItemPropertySheetsClass;
|
|
begin
|
|
Result := TCustomdxPSExplorerItemPropertySheetsClass(Self);
|
|
end;
|
|
|
|
{ TCustomdxPSExplorerItemComparator }
|
|
|
|
class function TCustomdxPSExplorerItemComparator.CompareItems(
|
|
AnItem1, AnItem2: Pointer): Integer;
|
|
begin
|
|
Result := TCustomdxPSExplorerItem(AnItem1).CompareTo(TCustomdxPSExplorerItem(AnItem2));
|
|
end;
|
|
|
|
{ TCustomdxPSExplorerItemHelper }
|
|
|
|
class function TCustomdxPSExplorerItemHelper.GetHasChildren(AFolder: TdxPSExplorerFolder): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerItemHelper.GetImageIndex(AnItem: TCustomdxPSExplorerItem): Integer;
|
|
begin
|
|
Result := AnItem.GetImageIndex;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerItemHelper.GetSelectedIndex(AnItem: TCustomdxPSExplorerItem): Integer;
|
|
begin
|
|
Result := AnItem.GetSelectedIndex;
|
|
end;
|
|
|
|
class procedure TCustomdxPSExplorerItemHelper.SetHasChildren(AFolder: TdxPSExplorerFolder; Value: Boolean);
|
|
begin
|
|
end;
|
|
|
|
{ TCustomdxPSExplorerItem }
|
|
|
|
constructor TCustomdxPSExplorerItem.Create(AnExplorer: TCustomdxPSExplorer;
|
|
AParent: TdxPSExplorerFolder);
|
|
begin
|
|
inherited Create;
|
|
Assert(AnExplorer <> nil);
|
|
FExplorer := AnExplorer;
|
|
Parent := AParent;
|
|
FName := GetNewName(nil);
|
|
FWindowHandle := dxPSUtl.dxAllocatehWnd(WndProc);
|
|
end;
|
|
|
|
destructor TCustomdxPSExplorerItem.Destroy;
|
|
begin
|
|
dxPSUtl.dxDeallocatehWnd(FWindowHandle);
|
|
if Parent <> nil then Parent.Remove(Self);
|
|
inherited;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.Explorer: TCustomdxPSExplorer;
|
|
begin
|
|
Result := FExplorer;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.CanAccept(AnItem: TCustomdxPSExplorerItem): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.CanDelete: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.CanMove: Boolean;
|
|
begin
|
|
Result := (Explorer = nil) or Explorer.CanMove(Self);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.CanMoveTo(AParent: TCustomdxPSExplorerItem): Boolean;
|
|
begin
|
|
Result := ((Explorer = nil) or Explorer.CanMoveTo(Self, AParent)) and
|
|
(AParent <> nil) and AParent.CanAccept(Self);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.CanRename: Boolean;
|
|
begin
|
|
Result := (Explorer = nil) or Explorer.CanRename(Self);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.CanRenameTo(const AName: string): Boolean;
|
|
begin
|
|
Result := (Explorer = nil) or Explorer.CanRenameTo(Self, AName);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItem.Delete;
|
|
begin
|
|
if CanDelete and (Explorer <> nil) then
|
|
Explorer.Delete(Self);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.GetUniqueID(out AnUniqueID: TBytes): Integer;
|
|
begin
|
|
SetLength(AnUniqueID, 0);
|
|
Result := 0;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.HasAsParent(AnItem: TCustomdxPSExplorerItem): Boolean;
|
|
var
|
|
ItemParent: TCustomdxPSExplorerItem;
|
|
begin
|
|
Result := not ((AnItem = nil) or (Parent = Self));
|
|
if Result then
|
|
begin
|
|
ItemParent := Parent;
|
|
while (ItemParent <> nil) and (ItemParent <> AnItem) do
|
|
ItemParent := ItemParent.Parent;
|
|
Result := ItemParent <> nil;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.IsNameChanged(const ANewName: string): Boolean;
|
|
begin
|
|
Result := not dxSameStr(ANewName, Name);
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerItem.HasPropertySheets: Boolean;
|
|
begin
|
|
Result := PropertySheetsClass <> nil;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerItem.PropertySheetsClass: TCustomdxPSExplorerItemPropertySheetsClass;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.ShowPropertySheets: Boolean;
|
|
begin
|
|
Result := HasPropertySheets and PropertySheetsClass.Execute(Self);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.CannotRenameMessageText(const AOldName, ANewName: string): string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.DeleteMessageText: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.OverwriteMessageText(Dest: TCustomdxPSExplorerItem): string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.GetDisplayName: string;
|
|
begin
|
|
Result := Name;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.CompareTo(AnItem: TCustomdxPSExplorerItem): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.DoDelete: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.DoMove(AParent: TdxPSExplorerFolder): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.DoRename(var ANewName: string): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.GetImageIndex: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.GetInfoTip: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.GetNewName(AReportLink: TBasedxReportLink): string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.GetSelectedIndex: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItem.InternalDelete;
|
|
begin
|
|
if IsWindow(FWindowHandle) then
|
|
PostMessage(FWindowHandle, CM_FREEEXPLORERITEM, 0, 0);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItem.InternalMove(AParent: TdxPSExplorerFolder);
|
|
begin
|
|
if Parent <> nil then Parent.Remove(Self);
|
|
if AParent <> nil then AParent.Add(Self);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItem.InternalRename(const AName: string);
|
|
begin
|
|
FName := AName;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItem.SetName(const Value: string);
|
|
begin
|
|
if (FName <> Value) and CanRenameTo(Value) then
|
|
Explorer.RenameTo(Self, Value);
|
|
end;
|
|
|
|
function GetItemStateInfoSize: Integer;
|
|
begin
|
|
Result := SizeOf(TCustomdxPSExplorerItemStateInfo);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerItem.GetItemStateInfo: TCustomdxPSExplorerItemStateInfo;
|
|
var
|
|
Bytes: TBytes;
|
|
begin
|
|
FillChar(Result, GetItemStateInfoSize, 0);
|
|
Result.Count := 0;
|
|
Result.UniqueIDSize := GetUniqueID(Bytes);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItem.WriteState(AStream: TStream);
|
|
var
|
|
ItemInfo: TCustomdxPSExplorerItemStateInfo;
|
|
Bytes: TBytes;
|
|
begin
|
|
ItemInfo := GetItemStateInfo;
|
|
AStream.WriteBuffer(ItemInfo, GetItemStateInfoSize);
|
|
if ItemInfo.UniqueIDSize <> 0 then
|
|
begin
|
|
GetUniqueID(Bytes);
|
|
AStream.WriteBuffer(Pointer(Bytes)^, ItemInfo.UniqueIDSize);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItem.WndProc(var Message: TMessage);
|
|
begin
|
|
with Message do
|
|
if Msg = CM_FREEEXPLORERITEM then
|
|
Free
|
|
else
|
|
Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerItem.SetParent(Value: TdxPSExplorerFolder);
|
|
begin
|
|
if (FParent <> Value) and CanMoveTo(Value) then
|
|
Explorer.MoveTo(Self, Value);
|
|
end;
|
|
|
|
{ TdxPSExplorerFolderHelper }
|
|
|
|
class function TdxPSExplorerFolderHelper.GetHasChildren(AFolder: TdxPSExplorerFolder): Boolean;
|
|
begin
|
|
Result := AFolder.HasChildren;
|
|
end;
|
|
|
|
class procedure TdxPSExplorerFolderHelper.SetHasChildren(AFolder: TdxPSExplorerFolder;
|
|
Value: Boolean);
|
|
begin
|
|
AFolder.HasChildren := Value;
|
|
end;
|
|
|
|
{ TdxPSExplorerFolder }
|
|
|
|
constructor TdxPSExplorerFolder.Create(AnExplorer: TCustomdxPSExplorer;
|
|
AParent: TdxPSExplorerFolder);
|
|
begin
|
|
inherited Create(AnExplorer, AParent);
|
|
FFolders := TList.Create;
|
|
FItems := TList.Create;
|
|
end;
|
|
|
|
destructor TdxPSExplorerFolder.Destroy;
|
|
begin
|
|
FreeAndNilFolders;
|
|
FreeAndNilItems;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.CanAccept(AnItem: TCustomdxPSExplorerItem): Boolean;
|
|
begin
|
|
Result := (AnItem <> Self) and (AnItem.Parent <> Self) and not HasAsParent(AnItem);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.CanRenameTo(const AName: string): Boolean;
|
|
begin
|
|
Result := inherited CanRenameTo(AName) and ((Parent = nil) or (Parent.FolderByName(AName) = nil));
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.CreateFolder: TdxPSExplorerFolder;
|
|
begin
|
|
Result := Explorer.CreateNewFolder(Self);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.CreateItem(AReportLink: TBasedxReportLink): TdxPSExplorerItem;
|
|
begin
|
|
Result := Explorer.CreateNewItem(Self, AReportLink);
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.Populate;
|
|
begin
|
|
Explorer.PopulateFolder(Self);
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.Delete;
|
|
begin
|
|
if CanDelete then
|
|
begin
|
|
DeleteFolders;
|
|
DeleteItems;
|
|
end;
|
|
inherited Delete;
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.DeleteFolders;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := FolderCount - 1 downto 0 do
|
|
Folders[I].Delete;
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.DeleteItems;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := ItemCount - 1 downto 0 do
|
|
Items[I].Delete;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.HasFolders: Boolean;
|
|
begin
|
|
Result := FolderCount <> 0;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.HasItems: Boolean;
|
|
begin
|
|
Result := ItemCount <> 0;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.HasLoadedItem: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Explorer.LoadedItem <> nil then
|
|
begin
|
|
Result := True;
|
|
for I := 0 to ItemCount - 1 do
|
|
if Items[I] = Explorer.LoadedItem then Exit;
|
|
for I := 0 to FolderCount - 1 do
|
|
if Folders[I].HasLoadedItem then Exit;
|
|
Result := False;
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.FolderByName(const AName: string): TdxPSExplorerFolder;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Populate;
|
|
for I := 0 to FolderCount - 1 do
|
|
begin
|
|
Result := Folders[I];
|
|
if Result.Name = AName then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.ItemByName(const AName: string): TdxPSExplorerItem;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to ItemCount - 1 do
|
|
begin
|
|
Result := Items[I];
|
|
if Result.Name = AName then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.CannotRenameMessageText(const AOldName, ANewName: string): string;
|
|
begin
|
|
Result := Format(cxGetResourceString(@sdxCannotRenameFolderText), [AOldName, ANewName]);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.DeleteMessageText: string;
|
|
begin
|
|
if HasFolders or HasItems then
|
|
Result := Format(cxGetResourceString(@sdxDeleteNonEmptyFolderMessageText), [DisplayName])
|
|
else
|
|
Result := Format(cxGetResourceString(@sdxDeleteFolderMessageText), [DisplayName]);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.OverwriteMessageText(Dest: TCustomdxPSExplorerItem): string;
|
|
begin
|
|
Result := Format(cxGetResourceString(@sdxOverwriteFolderMessageText), [Dest.DisplayName, DisplayName]);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.CompareTo(AnItem: TCustomdxPSExplorerItem): Integer;
|
|
begin
|
|
if AnItem is TdxPSExplorerFolder then
|
|
Result := CompareText(DisplayName, AnItem.DisplayName)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetItemStateInfo: TCustomdxPSExplorerItemStateInfo;
|
|
begin
|
|
Result := inherited GetItemStateInfo;
|
|
Result.Count := FolderCount + ItemCount;
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.WriteState(AStream: TStream);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
inherited;
|
|
for I := 0 to FolderCount - 1 do
|
|
Folders[I].WriteState(AStream);
|
|
for I := 0 to ItemCount - 1 do
|
|
Items[I].WriteState(AStream);
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.LoadData;
|
|
begin
|
|
Explorer.LoadData(Self);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetImageIndex: Integer;
|
|
begin
|
|
Result := iiExplorerFolderCollapsed;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetNewName(AReportLink: TBasedxReportLink): string;
|
|
var
|
|
Index: Integer;
|
|
Template: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxNewExplorerFolderItem);
|
|
if (Parent <> nil) and (Parent.FolderByName(Result) <> nil) then
|
|
begin
|
|
Index := 1;
|
|
Template := Result;
|
|
repeat
|
|
Inc(Index);
|
|
Result := Template + ' (' + IntToStr(Index) + ')';
|
|
until Parent.FolderByName(Result) = nil;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetSelectedIndex: Integer;
|
|
begin
|
|
Result := iiExplorerFolderExpanded;
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.Add(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
GetItemList(AnItem).Add(AnItem);
|
|
AnItem.FParent := Self;
|
|
HasChildren := True;
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.Remove(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
AnItem.FParent := nil;
|
|
GetItemList(AnItem).Remove(AnItem);
|
|
if FolderCount + ItemCount = 0 then
|
|
HasChildren := False;
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.FreeAndNilFolders;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := FolderCount - 1 downto 0 do
|
|
Folders[I].Free;
|
|
FreeAndNil(FFolders);
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.FreeAndNilItems;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := ItemCount - 1 downto 0 do
|
|
Items[I].Free;
|
|
FreeAndNil(FItems);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetFolder(Index: Integer): TdxPSExplorerFolder;
|
|
begin
|
|
Result := TdxPSExplorerFolder(FFolders[Index]);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetFolderCount: Integer;
|
|
begin
|
|
if FFolders <> nil then
|
|
Result := FFolders.Count
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetHasChildren: Boolean;
|
|
begin
|
|
Result := FHasChildren or (FolderCount + ItemCount <> 0);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetIsRoot: Boolean;
|
|
begin
|
|
Result := Self = Explorer.Root;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetItem(Index: Integer): TdxPSExplorerItem;
|
|
begin
|
|
Result := TdxPSExplorerItem(FItems[Index]);
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetItemCount: Integer;
|
|
begin
|
|
if FItems <> nil then
|
|
Result := FItems.Count
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetItemList(AnItem: TCustomdxPSExplorerItem): TList;
|
|
begin
|
|
Result := GetItemList(TCustomdxPSExplorerItemClass(AnItem.ClassType));
|
|
end;
|
|
|
|
function TdxPSExplorerFolder.GetItemList(AnItemClass: TCustomdxPSExplorerItemClass): TList;
|
|
begin
|
|
if AnItemClass.InheritsFrom(TdxPSExplorerItem) then
|
|
Result := FItems
|
|
else
|
|
if AnItemClass.InheritsFrom(TdxPSExplorerFolder) then
|
|
Result := FFolders
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxPSExplorerFolder.SetHasChildren(Value: Boolean);
|
|
begin
|
|
FHasChildren := Value or (FolderCount + ItemCount <> 0);
|
|
end;
|
|
|
|
{ TdxPSExplorerItem }
|
|
|
|
constructor TdxPSExplorerItem.Create(AnExplorer: TCustomdxPSExplorer; AParent: TdxPSExplorerFolder);
|
|
begin
|
|
inherited;
|
|
FReportDocument := TdxPSReportDocument.Create(nil);
|
|
FReportDocument.OnChanged := DocumentChanged;
|
|
end;
|
|
|
|
destructor TdxPSExplorerItem.Destroy;
|
|
begin
|
|
FreeAndNil(FReportDocument);
|
|
inherited;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.CanLoadData: Boolean;
|
|
begin
|
|
Result := not HasInvalidData and not IsCurrentlyLoaded;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.CanRenameTo(const AName: string): Boolean;
|
|
begin
|
|
Result := inherited CanRenameTo(AName) and ((Parent = nil) or (Parent.ItemByName(AName) = nil));
|
|
end;
|
|
|
|
function TdxPSExplorerItem.CannotRenameMessageText(const AOldName, ANewName: string): string;
|
|
begin
|
|
Result := Format(cxGetResourceString(@sdxCannotRenameItemText), [AOldName, ANewName]);
|
|
end;
|
|
|
|
function TdxPSExplorerItem.DataLoadErrorText: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxDataLoadErrorText);
|
|
end;
|
|
|
|
function TdxPSExplorerItem.DeleteMessageText: string;
|
|
begin
|
|
Result := Format(cxGetResourceString(@sdxDeleteItemMessageText), [DisplayName]);
|
|
end;
|
|
|
|
function TdxPSExplorerItem.OverwriteMessageText(Dest: TCustomdxPSExplorerItem): string;
|
|
begin
|
|
Result := Format(cxGetResourceString(@sdxOverwriteItemMessageText), [Dest.DisplayName, DisplayName]);
|
|
end;
|
|
|
|
function TdxPSExplorerItem.CreateDataStream(AMode: TdxPSStreamMode): TStream;
|
|
begin
|
|
Result := Explorer.CreateItemDataStream(Self, AMode);
|
|
end;
|
|
|
|
procedure TdxPSExplorerItem.RetrieveReportData(AReportLink: TBasedxReportLink);
|
|
var
|
|
Stream: TStream;
|
|
begin
|
|
if AReportLink <> nil then
|
|
begin
|
|
Stream := CreateDataStream(smWrite);
|
|
if Stream <> nil then
|
|
try
|
|
AReportLink.SaveDataToStream(Stream);
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.IsLoading: Boolean;
|
|
begin
|
|
Result := (Explorer <> nil) and Explorer.IsLoading;
|
|
end;
|
|
|
|
procedure TdxPSExplorerItem.Load(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if Explorer <> nil then
|
|
Explorer.LoadItemData(Self, AReportLink);
|
|
end;
|
|
|
|
procedure TdxPSExplorerItem.Unload;
|
|
begin
|
|
Explorer.UnloadItemData(Self);
|
|
end;
|
|
|
|
class function TdxPSExplorerItem.PropertySheetsClass: TCustomdxPSExplorerItemPropertySheetsClass;
|
|
begin
|
|
Result := TdxfmPSReportProperties;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.CompareTo(AnItem: TCustomdxPSExplorerItem): Integer;
|
|
begin
|
|
if AnItem is TdxPSExplorerItem then
|
|
Result := CompareText(DisplayName, AnItem.DisplayName)
|
|
else
|
|
Result := 1;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.DoDelete: Boolean;
|
|
begin
|
|
if IsCurrentlyLoaded then Unload;
|
|
Result := inherited DoDelete;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.GetFormCaption: string;
|
|
begin
|
|
Result := Name;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.GetImageIndex: Integer;
|
|
begin
|
|
if HasInvalidData then
|
|
Result := iiExplorerItemHasInvalidData
|
|
else
|
|
Result := iiExplorerItem;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.GetInfoTip: string;
|
|
begin
|
|
Result := ReportDocument.InfoTip;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.GetNewName(AReportLink: TBasedxReportLink): string;
|
|
var
|
|
Index: Integer;
|
|
Template: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxNewReport);
|
|
if AReportLink <> nil then
|
|
Result := AReportLink.GetNewReportStorageName;
|
|
if (Parent <> nil) and (Parent.ItemByName(Result) <> nil) then
|
|
begin
|
|
Index := 1;
|
|
Template := Result;
|
|
repeat
|
|
Inc(Index);
|
|
Result := Template + ' (' + IntToStr(Index) + ')';
|
|
until Parent.ItemByName(Result) = nil;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.GetSelectedIndex: Integer;
|
|
begin
|
|
if HasInvalidData then
|
|
Result := iiExplorerItemHasInvalidData
|
|
else
|
|
Result := iiExplorerItem;
|
|
end;
|
|
|
|
procedure TdxPSExplorerItem.InternalDelete;
|
|
begin
|
|
SaveDocument;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSExplorerItem.DocumentChanged(Sender: TObject);
|
|
begin
|
|
if not IsLoading then
|
|
begin
|
|
Name := ReportDocument.Caption;
|
|
Explorer.NotifyItemPropertiesChanged(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerItem.SaveDocument;
|
|
var
|
|
Stream: TStream;
|
|
OffsetTable: TdxPSDataStorageOffsetTable;
|
|
P: Integer;
|
|
Writer: TdxPSDataWriter;
|
|
begin
|
|
Stream := CreateDataStream(smWrite);
|
|
if Stream <> nil then
|
|
try
|
|
OffsetTable := TBasedxReportLink.ExtractOffsetTable(Stream, True);
|
|
try
|
|
P := Stream.Position;
|
|
try
|
|
Stream.Position := OffsetTable.Document;
|
|
Writer := TBasedxReportLink.CreateDataWriter(Stream);
|
|
try
|
|
ReportDocument.WriteData(Writer);
|
|
finally
|
|
Writer.Free;
|
|
end;
|
|
finally
|
|
Stream.Position := P;
|
|
end;
|
|
finally
|
|
OffsetTable.Free;
|
|
end;
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerItem.SetReportData(AReportLink: TBasedxReportLink);
|
|
var
|
|
Stream: TStream;
|
|
begin
|
|
if AReportLink <> nil then
|
|
begin
|
|
Stream := CreateDataStream(smRead);
|
|
if Stream <> nil then
|
|
try
|
|
try
|
|
AReportLink.LoadDataFromStream(Stream);
|
|
except
|
|
AReportLink.FinalizeDataStream;
|
|
HasInvalidData := True;
|
|
raise;
|
|
end;
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSExplorerItem.GetIsCurrentlyLoaded: Boolean;
|
|
begin
|
|
Result := Explorer.LoadedItem = Self;
|
|
end;
|
|
|
|
procedure TdxPSExplorerItem.SetHasInvalidData(Value: Boolean);
|
|
begin
|
|
if FHasInvalidData <> Value then
|
|
begin
|
|
FHasInvalidData := Value;
|
|
end;
|
|
end;
|
|
|
|
{ TCustomdxPSExplorerContextCommand }
|
|
|
|
constructor TCustomdxPSExplorerContextCommand.Create(AnExplorer: TCustomdxPSExplorer);
|
|
begin
|
|
inherited Create;
|
|
FBitmap := TBitmap.Create;
|
|
FExplorer := AnExplorer;
|
|
end;
|
|
|
|
destructor TCustomdxPSExplorerContextCommand.Destroy;
|
|
begin
|
|
FBitmap.Free;
|
|
inherited;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerContextCommand.Enabled: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerContextCommand.Execute;
|
|
begin
|
|
end;
|
|
|
|
function TCustomdxPSExplorerContextCommand.Explorer: TCustomdxPSExplorer;
|
|
begin
|
|
Result := FExplorer;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerContextCommand.SetBitmap(Value: TBitmap);
|
|
begin
|
|
Bitmap.Assign(Value);
|
|
end;
|
|
|
|
{ TdxPSExplorerContextCommandSeparator }
|
|
|
|
constructor TdxPSExplorerContextCommandSeparator.Create(AnExplorer: TCustomdxPSExplorer);
|
|
begin
|
|
inherited;
|
|
Caption := dxPSGlbl.cMenuSeparator;
|
|
end;
|
|
|
|
function TdxPSExplorerContextCommandSeparator.Enabled: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
{ TdxPSExplorerRefreshContextCommand }
|
|
|
|
constructor TdxPSExplorerRefreshContextCommand.Create(AnExplorer: TCustomdxPSExplorer);
|
|
begin
|
|
inherited;
|
|
Caption := cxGetResourceString(@sdxMenuExplorerRefresh);
|
|
Hint := cxGetResourceString(@sdxHintExplorerRefresh);
|
|
ShortCut := Menus.TextToShortCut('F5');
|
|
Bitmap_LoadFromResourceName(Bitmap, IDB_DXPSREFRESH);
|
|
Bitmap.Transparent := True;
|
|
end;
|
|
|
|
procedure TdxPSExplorerRefreshContextCommand.Execute;
|
|
begin
|
|
Explorer.Refresh;
|
|
end;
|
|
|
|
{ TCustomdxPSExplorer }
|
|
|
|
constructor TCustomdxPSExplorer.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
FNotifiers := TList.Create;
|
|
FCommands := TList.Create;
|
|
end;
|
|
|
|
destructor TCustomdxPSExplorer.Destroy;
|
|
begin
|
|
FreeAndNilCommands;
|
|
ReleaseAndNilNotifiers;
|
|
FreeAndNil(FRoot);
|
|
inherited;
|
|
end;
|
|
|
|
|
|
function TCustomdxPSExplorer.LoadedItem: TdxPSExplorerItem;
|
|
begin
|
|
Result := FLoadedItem;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CanCreateFolder: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CanCreateItem: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CreateNewFolder(AParent: TdxPSExplorerFolder): TdxPSExplorerFolder;
|
|
begin
|
|
Include(FState, esFolderCreating);
|
|
try
|
|
Result := GetFolderClass.Create(Self, AParent);
|
|
//DoCreateNewFolder(Result);
|
|
NotifyItemAdded(Result);
|
|
finally
|
|
Exclude(FState, esFolderCreating);
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CreateNewItem(AParent: TdxPSExplorerFolder;
|
|
AReportLink: TBasedxReportLink): TdxPSExplorerItem;
|
|
begin
|
|
Include(FState, esItemCreating);
|
|
try
|
|
Result := GetItemClass.Create(Self, AParent);
|
|
Result.FName := Result.GetNewName(AReportLink);
|
|
AReportLink.ReportDocument.RetrievePreview;
|
|
with Result.ReportDocument do
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
Assign(AReportLink.ReportDocument);
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
end;
|
|
|
|
//DoCreateNewItem(Result);
|
|
NotifyItemAdded(Result);
|
|
finally
|
|
Exclude(FState, esItemCreating);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.BuildTree(ATreeContainer: TCustomdxPSExplorerTreeContainer);
|
|
begin
|
|
dxPSExplorerTreeBuilderFactory_ActiveBuilderClass.BuildTree(Self, ATreeContainer);
|
|
//dxPSExplorerTreeBuilderFactory.ActiveBuilderClass.BuildTree(Self, ATreeContainer);
|
|
if LoadedItem <> nil then
|
|
ATreeContainer.MakeItemVisible(LoadedItem);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CreateTree(const AHost: IdxPSExplorerTreeContainerHost): TCustomdxPSExplorerTreeContainer;
|
|
begin
|
|
Result := dxPSExplorerTreeContainerFactory.ActiveTreeContainerClass.Create(Self, AHost);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.FindCustomItemByUniqueID(const AnUniqueID: TBytes): TCustomdxPSExplorerItem;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.LoadItemData(AnItem: TdxPSExplorerItem;
|
|
AReportLink: TBasedxReportLink);
|
|
begin
|
|
if LoadedItem <> nil then
|
|
NotifyItemDataUnloaded(LoadedItem);
|
|
|
|
try
|
|
AnItem.SetReportData(AReportLink);
|
|
FLoadedItem := AnItem;
|
|
NotifyItemDataLoaded(AnItem);
|
|
except
|
|
FLoadedItem := nil;
|
|
DoItemDataLoadError(AnItem);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.UnloadItemData(AnItem: TdxPSExplorerItem);
|
|
begin
|
|
FLoadedItem := nil;
|
|
NotifyItemDataUnloaded(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.Refresh;
|
|
begin
|
|
BeforeRefresh;
|
|
try
|
|
DoRefresh;
|
|
finally
|
|
AfterRefresh;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.RegisterNotifier(ANotifier: TdxPSExplorerChangeNotifier);
|
|
begin
|
|
if IndexOfNotifier(ANotifier) = -1 then
|
|
begin
|
|
FNotifiers.Add(ANotifier);
|
|
ANotifier.FExplorer := Self;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.UnregisterNotifier(ANotifier: TdxPSExplorerChangeNotifier);
|
|
begin
|
|
FNotifiers.Remove(ANotifier);
|
|
ANotifier.FExplorer := nil;
|
|
end;
|
|
|
|
{$IFNDEF DELPHI6}
|
|
|
|
{ IUnknown }
|
|
|
|
function TCustomdxPSExplorer.QueryInterface(const IID: TGUID; out Obj): HRESULT;
|
|
begin
|
|
if GetInterface(IID, Obj) then
|
|
Result := S_OK
|
|
else
|
|
Result := E_NOINTERFACE;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer._Addref: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer._Release: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
{ IdxPSExplorerContextCommands }
|
|
|
|
procedure TCustomdxPSExplorer.BuildCommandSet(ABuilder: IdxPSExplorerContextCommandBuilder);
|
|
begin
|
|
Assert(ABuilder <> nil);
|
|
ABuilder.AddExplorerContextCommand(AddCommandSeparator);
|
|
ABuilder.AddExplorerContextCommand(AddCommand(TdxPSExplorerRefreshContextCommand));
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.FinalizeCommand(ACommand: TCustomdxPSExplorerContextCommand);
|
|
begin
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.InitializeCommand(ACommand: TCustomdxPSExplorerContextCommand);
|
|
begin
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.AddCommand(ACommandClass: TCustomdxPSExplorerContextCommandClass): TCustomdxPSExplorerContextCommand;
|
|
begin
|
|
Result := FindCommand(ACommandClass);
|
|
if Result = nil then
|
|
Result := CreateCommand(ACommandClass);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.AddCommandSeparator: TdxPSExplorerContextCommandSeparator;
|
|
begin
|
|
Result := AddCommand(TdxPSExplorerContextCommandSeparator) as TdxPSExplorerContextCommandSeparator;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.ClearCommands;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to CommandCount - 1 do
|
|
Commands[I].Free;
|
|
FCommands.Clear;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CreateCommand(ACommandClass: TCustomdxPSExplorerContextCommandClass): TCustomdxPSExplorerContextCommand;
|
|
begin
|
|
Result := ACommandClass.Create(Self);
|
|
FCommands.Add(Result);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CreateCommandSeparator: TdxPSExplorerContextCommandSeparator;
|
|
begin
|
|
Result := TdxPSExplorerContextCommandSeparator.Create(Self);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.FindCommand(ACommandClass: TCustomdxPSExplorerContextCommandClass): TCustomdxPSExplorerContextCommand;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to CommandCount - 1 do
|
|
begin
|
|
Result := Commands[I];
|
|
if Result.ClassType = ACommandClass then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.FreeAndNilCommands;
|
|
begin
|
|
ClearCommands;
|
|
FreeAndNil(FCommands);
|
|
end;
|
|
|
|
class function TCustomdxPSExplorer.AcceptItemNameChar(AnItem: TCustomdxPSExplorerItem;
|
|
Ch: Char): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorer.GetFolderClass: TdxPSExplorerFolderClass;
|
|
begin
|
|
Result := TdxPSExplorerFolder;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorer.GetItemClass: TdxPSExplorerItemClass;
|
|
begin
|
|
Result := TdxPSExplorerItem;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorer.GetRootFolderClass: TdxPSExplorerFolderClass;
|
|
begin
|
|
Result := TdxPSExplorerFolder;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.GetRootDisplayName: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxExplorerRootFolderCaption);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.LoadData(AFolder: TdxPSExplorerFolder);
|
|
begin
|
|
BeginLoading;
|
|
try
|
|
LockNotifications;
|
|
try
|
|
dxPSStartWait;
|
|
try
|
|
DoLoadData(AFolder);
|
|
finally
|
|
dxPSStopWait;
|
|
end;
|
|
finally
|
|
UnlockNotifications
|
|
end;
|
|
finally
|
|
EndLoading;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CanDelete(AnItem: TCustomdxPSExplorerItem): Boolean;
|
|
begin
|
|
Result := (AnItem <> nil) and (AnItem <> Root);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CanMove(AnItem: TCustomdxPSExplorerItem): Boolean;
|
|
begin
|
|
Result := (AnItem <> nil) and (AnItem <> Root) and (AnItem <> LoadedItem);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CanMoveTo(AnItem: TCustomdxPSExplorerItem;
|
|
AParent: TCustomdxPSExplorerItem): Boolean;
|
|
begin
|
|
Result := CanMove(AnItem);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CanRename(AnItem: TCustomdxPSExplorerItem): Boolean;
|
|
begin
|
|
Result := (AnItem <> nil) and (AnItem <> Root) and (AnItem <> LoadedItem);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.CanRenameTo(AnItem: TCustomdxPSExplorerItem;
|
|
const AName: string): Boolean;
|
|
begin
|
|
Result := CanRename(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.Delete(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
if not (esLoading in State) then
|
|
if AnItem.DoDelete then
|
|
begin
|
|
NotifyItemDeleted(AnItem);
|
|
AnItem.InternalDelete;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.MoveTo(AnItem: TCustomdxPSExplorerItem;
|
|
AParent: TdxPSExplorerFolder);
|
|
begin
|
|
if AnItem.DoMove(AParent) then
|
|
begin
|
|
AnItem.InternalMove(AParent);
|
|
NotifyItemParentChanged(AnItem);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.PopulateFolder(AFolder: TdxPSExplorerFolder);
|
|
begin
|
|
if AFolder.HasChildren and (AFolder.FolderCount + AFolder.ItemCount = 0) then
|
|
begin
|
|
LoadData(AFolder);
|
|
NotifyFolderPopulated(AFolder);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.RenameTo(AnItem: TCustomdxPSExplorerItem; AName: string);
|
|
begin
|
|
if AnItem.DoRename(AName) then
|
|
begin
|
|
AnItem.InternalRename(AName);
|
|
NotifyItemRenamed(AnItem);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.AfterRefresh;
|
|
begin
|
|
Dec(FRefreshCounter);
|
|
if FRefreshCounter = 0 then
|
|
begin
|
|
UnlockNotifications;
|
|
LoadState;
|
|
NotifyRefresh(ersAfter);
|
|
Exclude(FState, esRefreshing);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.BeforeRefresh;
|
|
begin
|
|
if FRefreshCounter = 0 then
|
|
begin
|
|
Include(FState, esRefreshing);
|
|
SaveState;
|
|
NotifyRefresh(ersBefore);
|
|
LockNotifications;
|
|
end;
|
|
Inc(FRefreshCounter);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.DoRefresh;
|
|
begin
|
|
if LoadedItem <> nil then LoadedItem.Unload;
|
|
FreeAndNil(FRoot);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.RootNeeded;
|
|
begin
|
|
Root;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.DoItemDataLoadError(AnItem: TdxPSExplorerItem);
|
|
var
|
|
S: string;
|
|
ShowError: Boolean;
|
|
begin
|
|
S := AnItem.DataLoadErrorText;
|
|
ShowError := True;
|
|
if Assigned(FOnItemDataLoadError) then
|
|
FOnItemDataLoadError(Self, AnItem, ShowError, S);
|
|
if ShowError then
|
|
MessageError(S);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.InternalSetLoadedItem(Value: TdxPSExplorerItem);
|
|
begin
|
|
if Value <> nil then //?
|
|
FLoadedItem := Value;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.PopulateTreeFolder(ATreeContainer: TCustomdxPSExplorerTreeContainer;
|
|
AFolder: TdxPSExplorerFolder);
|
|
begin
|
|
dxPSExplorerTreeBuilderFactory_ActiveBuilderClass.PopulateTreeFolder(ATreeContainer, AFolder);
|
|
//dxPSExplorerTreeBuilderFactory.ActiveBuilderClass.PopulateTreeFolder(ATreeContainer, AFolder);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.LoadState;
|
|
|
|
function ReadItem: TCustomdxPSExplorerItem;
|
|
var
|
|
ItemInfo: TCustomdxPSExplorerItemStateInfo;
|
|
Bytes: TBytes;
|
|
I: Integer;
|
|
begin
|
|
FStateStream.ReadBuffer(ItemInfo, GetItemStateInfoSize);
|
|
if ItemInfo.UniqueIDSize <> 0 then
|
|
begin
|
|
SetLength(Bytes, ItemInfo.UniqueIDSize);
|
|
FStateStream.ReadBuffer(Pointer(Bytes)^, ItemInfo.UniqueIDSize);
|
|
Result := FindCustomItemByUniqueID(Bytes);
|
|
end
|
|
else
|
|
Result := nil;
|
|
for I := 0 to ItemInfo.Count - 1 do
|
|
ReadItem;
|
|
end;
|
|
|
|
procedure ReadLoadedItem;
|
|
var
|
|
Buffer: Integer;
|
|
begin
|
|
FStateStream.ReadBuffer(Buffer , SizeOf(Buffer));
|
|
if Buffer <> 0 then
|
|
InternalSetLoadedItem(TdxPSExplorerItem(ReadItem));
|
|
end;
|
|
|
|
begin
|
|
if FStateStream <> nil then
|
|
try
|
|
FStateStream.Position := 0;
|
|
ReadItem;
|
|
ReadLoadedItem;
|
|
finally
|
|
FreeAndNil(FStateStream);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.SaveState;
|
|
|
|
procedure WriteLoadedItem;
|
|
var
|
|
Flag: Integer;
|
|
begin
|
|
Flag := Ord(LoadedItem <> nil);
|
|
FStateStream.WriteBuffer(Flag, SizeOf(Flag));
|
|
if LoadedItem <> nil then
|
|
LoadedItem.WriteState(FStateStream);
|
|
end;
|
|
|
|
begin
|
|
if FRoot <> nil then
|
|
begin
|
|
FStateStream := TMemoryStream.Create;
|
|
try
|
|
Root.WriteState(FStateStream);
|
|
WriteLoadedItem;
|
|
except
|
|
FreeAndNil(FStateStream);
|
|
raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyFolderPopulated(AFolder: TdxPSExplorerFolder);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].FolderPopulated(AFolder);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyItemAdded(AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].ItemAdded(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyItemDataLoaded(AnItem: TdxPSExplorerItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].ItemDataLoaded(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyItemDataUnloaded(AnItem: TdxPSExplorerItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].ItemDataUnloaded(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyItemDeleted(AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].ItemDeleted(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyItemParentChanged(AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].ItemParentChanged(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyItemPropertiesChanged(AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].ItemPropertiesChanged(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyItemRenamed(AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].ItemRenamed(AnItem);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.NotifyRefresh(AStage: TdxPSExplorerRefreshStage);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not AreNotificationsLocked then
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].ExplorerRefresh(AStage);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.AreNotificationsLocked: Boolean;
|
|
begin
|
|
Result := FLockCounter <> 0;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.IndexOfNotifier(ANotifier: TdxPSExplorerChangeNotifier): Integer;
|
|
begin
|
|
Result := FNotifiers.IndexOf(ANotifier);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.LockNotifications;
|
|
begin
|
|
Inc(FLockCounter);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.ReleaseAndNilNotifiers;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to NotifierCount - 1 do
|
|
Notifiers[I].Explorer := nil;
|
|
FreeAndNil(FNotifiers);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.UnlockNotifications;
|
|
begin
|
|
Dec(FLockCounter);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.BeginLoading;
|
|
begin
|
|
if FLoadingCounter = 0 then Include(FState, esLoading);
|
|
Inc(FLoadingCounter);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.EndLoading;
|
|
begin
|
|
Dec(FLoadingCounter);
|
|
if FLoadingCounter = 0 then Exclude(FState, esLoading);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.IsLoading: Boolean;
|
|
begin
|
|
Result := FLoadingCounter <> 0;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.GetCommand(Index: Integer): TCustomdxPSExplorerContextCommand;
|
|
begin
|
|
Result := TCustomdxPSExplorerContextCommand(FCommands[Index]);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.GetCommandCount: Integer;
|
|
begin
|
|
Result := FCommands.Count;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.GetFilterLink: string;
|
|
begin
|
|
if FilterLinkClass <> nil then
|
|
Result := FilterLinkClass.ClassName
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.GetNotifier(Index: Integer): TdxPSExplorerChangeNotifier;
|
|
begin
|
|
Result := TdxPSExplorerChangeNotifier(FNotifiers[Index]);
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.GetNotifierCount: Integer;
|
|
begin
|
|
Result := FNotifiers.Count;
|
|
end;
|
|
|
|
function TCustomdxPSExplorer.GetRoot: TdxPSExplorerFolder;
|
|
begin
|
|
if FRoot = nil then
|
|
begin
|
|
BeginLoading;
|
|
try
|
|
LockNotifications;
|
|
try
|
|
FRoot := GetRootFolderClass.Create(Self, nil);
|
|
FRoot.FName := GetRootDisplayName;
|
|
LoadData(FRoot);
|
|
finally
|
|
UnlockNotifications;
|
|
end;
|
|
finally
|
|
EndLoading;
|
|
end;
|
|
end;
|
|
Result := FRoot;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorer.SetFilterLink(const Value: string);
|
|
var
|
|
ComponentClass: TComponentClass;
|
|
begin
|
|
if Value <> '' then
|
|
begin
|
|
ComponentClass := TComponentClass(GetClass(Value));
|
|
if dxPSIsSupportedCompClass(ComponentClass) then
|
|
FilterLinkClass := ComponentClass;
|
|
end
|
|
else
|
|
FilterLinkClass := nil;
|
|
end;
|
|
|
|
{ TdxReportTitle }
|
|
|
|
constructor TdxReportTitle.Create(AReportLink: TBasedxReportLink);
|
|
begin
|
|
inherited Create;
|
|
FReportLink := AReportLink;
|
|
FFont := TFont.Create;
|
|
DoRestoreDefaults;
|
|
FFont.OnChange := FontChanged;
|
|
end;
|
|
|
|
destructor TdxReportTitle.Destroy;
|
|
begin
|
|
FreeAndNil(FDefaultFont);
|
|
FreeAndNil(FFont);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxReportTitle.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxReportTitle then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
with TdxReportTitle(Source) do
|
|
begin
|
|
Self.AdjustOnReportScale := AdjustOnReportScale;
|
|
Self.Color := Color;
|
|
Self.Font := Font;
|
|
Self.Mode := Mode;
|
|
Self.Text := Text;
|
|
Self.TextAlignX := TextAlignX;
|
|
Self.TextAlignY := TextAlignY;
|
|
Self.Transparent := Transparent;
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxReportTitle.BeginUpdate;
|
|
begin
|
|
Inc(FUpdateCount);
|
|
end;
|
|
|
|
procedure TdxReportTitle.CancelUpdate;
|
|
begin
|
|
if FUpdateCount <> 0 then Dec(FUpdateCount);
|
|
end;
|
|
|
|
procedure TdxReportTitle.EndUpdate;
|
|
begin
|
|
if FUpdateCount <> 0 then
|
|
begin
|
|
Dec(FUpdateCount);
|
|
if FUpdateCount = 0 then CalculateRenderInfos;
|
|
end;
|
|
end;
|
|
|
|
function TdxReportTitle.DefaultFont: TFont;
|
|
begin
|
|
if FDefaultFont = nil then
|
|
begin
|
|
FDefaultFont := TFont.Create;
|
|
InitializeDefaultFont(FDefaultFont);
|
|
end;
|
|
Result := FDefaultFont;
|
|
end;
|
|
|
|
procedure TdxReportTitle.RestoreDefaults;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
DoRestoreDefaults;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportTitle.DoRestoreDefaults;
|
|
begin
|
|
FAdjustOnReportScale := False;
|
|
FColor := clWhite;
|
|
FLockCalcViewInfos := True;
|
|
try
|
|
Font := DefaultFont;
|
|
finally
|
|
FLockCalcViewInfos := False;
|
|
end;
|
|
FMode := tmOnEveryTopPage;
|
|
FTextAlignX := taCenterX;
|
|
FTextAlignY := taCenterY;
|
|
FTransparent := True;
|
|
end;
|
|
|
|
procedure TdxReportTitle.InitializeDefaultFont(AFont: TFont);
|
|
begin
|
|
AFont.Color := dxPSDefaultReportTitleFontColor;
|
|
AFont.Name := dxPSDefaultReportTitleFontName;
|
|
AFont.Size := dxPSDefaultReportTitleFontSize;
|
|
AFont.Style := dxPSDefaultReportTitleFontStyle;
|
|
end;
|
|
|
|
procedure TdxReportTitle.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
with AReader do
|
|
begin
|
|
AdjustOnReportScale := ReadBoolean;
|
|
Color := ReadInteger;
|
|
ReadFont(Font);
|
|
Mode := TdxReportTitleMode(ReadInteger);
|
|
Text := ReadString;
|
|
TextAlignX := TdxTextAlignX(ReadInteger);
|
|
TextAlignY := TdxTextAlignY(ReadInteger);
|
|
Transparent := ReadBoolean;
|
|
end;
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportTitle.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
with AWriter do
|
|
begin
|
|
WriteBoolean(AdjustOnReportScale);
|
|
WriteInteger(Color);
|
|
WriteFont(Font);
|
|
WriteInteger(Integer(Mode));
|
|
WriteString(Text);
|
|
WriteInteger(Integer(TextAlignX));
|
|
WriteInteger(Integer(TextAlignY));
|
|
WriteBoolean(Transparent);
|
|
end;
|
|
end;
|
|
|
|
function TdxReportTitle.IsFontStored: Boolean;
|
|
begin
|
|
Result := not dxPSUtl.dxAreFontsEqual(Font, DefaultFont);
|
|
end;
|
|
|
|
procedure TdxReportTitle.SetAdjustOnReportScale(Value: Boolean);
|
|
begin
|
|
if FAdjustOnReportScale <> Value then
|
|
begin
|
|
FAdjustOnReportScale := Value;
|
|
CalculateRenderInfos;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportTitle.SetColor(Value: TColor);
|
|
begin
|
|
FColor := Value;
|
|
end;
|
|
|
|
procedure TdxReportTitle.SetFont(Value: TFont);
|
|
begin
|
|
Font.Assign(Value);
|
|
end;
|
|
|
|
procedure TdxReportTitle.SetMode(Value: TdxReportTitleMode);
|
|
begin
|
|
if FMode <> Value then
|
|
begin
|
|
FMode := Value;
|
|
CalculateRenderInfos;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportTitle.SetText(const Value: string);
|
|
begin
|
|
if FText <> Value then
|
|
begin
|
|
FText := Value;
|
|
CalculateRenderInfos;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxReportTitle.SetTextAlignX(Value: TdxTextAlignX);
|
|
begin
|
|
if Value in [taLeft, taCenterX, taRight] then // backward compatibility
|
|
FTextAlignX := Value;
|
|
end;
|
|
|
|
procedure TdxReportTitle.SetTextAlignY(Value: TdxTextAlignY);
|
|
begin
|
|
if Value in [taTop, taCenterY, taBottom] then // backward compatibility
|
|
FTextAlignY := Value;
|
|
end;
|
|
|
|
procedure TdxReportTitle.SetTransparent(Value: Boolean);
|
|
begin
|
|
FTransparent := Value;
|
|
end;
|
|
|
|
procedure TdxReportTitle.CalculateRenderInfos;
|
|
begin
|
|
if (FUpdateCount = 0) and (ReportLink <> nil) then //and (FReportLink.CurrentComposition = nil) then
|
|
ReportLink.CalculateRenderInfos;
|
|
end;
|
|
|
|
procedure TdxReportTitle.FontChanged(Sender: TObject);
|
|
begin
|
|
if not LockCalcViewInfos then CalculateRenderInfos;
|
|
end;
|
|
|
|
{ TdxReportLinkPrinterPage }
|
|
|
|
type
|
|
TdxReportLinkPrinterPage = class(TdxPrinterPage)
|
|
private
|
|
FReportLink: TBasedxReportLink;
|
|
protected
|
|
function GetOwner: TPersistent; override;
|
|
function GetSupportsScaling: Boolean; override;
|
|
procedure PageParamsChanged(AUpdateCodes: TdxPrinterPageUpdateCodes); override;
|
|
public
|
|
property ReportLink: TBasedxReportLink read FReportLink;
|
|
end;
|
|
|
|
|
|
function TdxReportLinkPrinterPage.GetOwner: TPersistent;
|
|
begin
|
|
Result := ReportLink;
|
|
end;
|
|
|
|
function TdxReportLinkPrinterPage.GetSupportsScaling: Boolean;
|
|
begin
|
|
Result := ReportLink.SupportsScaling;
|
|
end;
|
|
|
|
procedure TdxReportLinkPrinterPage.PageParamsChanged(AUpdateCodes: TdxPrinterPageUpdateCodes);
|
|
begin
|
|
inherited;
|
|
if UpdateCount = 0 then
|
|
ReportLink.PageParamsChanged(Self, nil, AUpdateCodes);
|
|
end;
|
|
|
|
{ TdxPSReportDocument }
|
|
|
|
constructor TdxPSReportDocument.Create(AReportLink: TBasedxReportLink);
|
|
begin
|
|
inherited Create;
|
|
FReportLink := AReportLink;
|
|
FPreview := TMetafile.Create;
|
|
end;
|
|
|
|
destructor TdxPSReportDocument.Destroy;
|
|
begin
|
|
FreeAndNil(FPreview);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxPSReportDocument then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
DoAssign(TdxPSReportDocument(Source));
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.BeginUpdate;
|
|
begin
|
|
Inc(FUpdateCount);
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.CancelUpdate;
|
|
begin
|
|
if FUpdateCount <> 0 then Dec(FUpdateCount);
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.EndUpdate;
|
|
begin
|
|
if FUpdateCount <> 0 then
|
|
begin
|
|
Dec(FUpdateCount);
|
|
if UpdateCount = 0 then Changed;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportDocument.IsUpdateLocked: Boolean;
|
|
begin
|
|
Result := UpdateCount <> 0;
|
|
end;
|
|
|
|
function TdxPSReportDocument.DefaultCaption: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxNewReport);
|
|
end;
|
|
|
|
function TdxPSReportDocument.DefaultCreator: string;
|
|
begin
|
|
Result := dxPSUtl.GetUserName;
|
|
end;
|
|
|
|
function TdxPSReportDocument.DefaultDescription: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.RestoreDefaults;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
DoRestoreDefaults;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.RetrievePreview;
|
|
begin
|
|
Preview.Clear;
|
|
if ReportLink <> nil then
|
|
ReportLink.RetrievePageAsImage(0, TMetafile, Preview);
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited;
|
|
Filer.DefineProperty('IsCaptionAssigned', ReadIsCaptionAssigned, WriteIsCaptionAssigned,
|
|
FIsCaptionAssigned and (Caption = ''));
|
|
Filer.DefineProperty('IsCreatorAssigned', ReadIsCreatorAssigned, WriteIsCreatorAssigned,
|
|
FIsCreatorAssigned and (Creator = ''));
|
|
Filer.DefineProperty('IsDescriptionAssigned', ReadIsDescriptionAssigned, WriteIsDescriptionAssigned,
|
|
FIsDescriptionAssigned and (Description = ''));
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.Changed;
|
|
begin
|
|
if not IsUpdateLocked then
|
|
if Assigned(FOnChanged) then FOnChanged(Self);
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.DoAssign(Source: TdxPSReportDocument);
|
|
begin
|
|
Caption := Source.Caption;
|
|
CreationDate := Source.CreationDate;
|
|
Creator := Source.Creator;
|
|
Description := Source.Description;
|
|
Preview.Assign(Source.Preview);
|
|
FIsCaptionAssigned := Source.FIsCaptionAssigned;
|
|
FIsCreatorAssigned := Source.FIsCreatorAssigned;
|
|
FIsDescriptionAssigned := Source.FIsDescriptionAssigned;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.DoRestoreDefaults;
|
|
begin
|
|
FIsCaptionAssigned := False;
|
|
FisCreatorAssigned := False;
|
|
FIsDescriptionAssigned := False;
|
|
end;
|
|
|
|
function TdxPSReportDocument.GetInfoTip: string;
|
|
const
|
|
CRLF = #13#10;
|
|
begin
|
|
Result := '';
|
|
|
|
if Caption <> '' then
|
|
begin
|
|
if Result <> '' then Result := Result + CRLF;
|
|
Result := Result + DropAmpersand(cxGetResourceString(@sdxCaption)) + ' ' + Caption;
|
|
end;
|
|
|
|
if Creator <> '' then
|
|
begin
|
|
if Result <> '' then Result := Result + CRLF;
|
|
Result := Result + DropAmpersand(cxGetResourceString(@sdxCreator)) + ' ' + Creator;
|
|
end;
|
|
|
|
if Result <> '' then Result := Result + CRLF;
|
|
Result := Result + DropAmpersand(cxGetResourceString(@sdxCreationDate)) + ' ' + DateToStr(CreationDate);
|
|
|
|
if Description <> '' then
|
|
begin
|
|
if Result <> '' then Result := Result + CRLF;
|
|
Result := Result + DropAmpersand(cxGetResourceString(@sdxDescription)) + ' ' + Description;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
with AReader do
|
|
begin
|
|
Caption := ReadString;
|
|
CreationDate := ReadDate;
|
|
Creator := ReadString;
|
|
Description := ReadString;
|
|
ReadImage(Preview);
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
RetrievePreview;
|
|
with AWriter do
|
|
begin
|
|
WriteString(Caption);
|
|
WriteDate(CreationDate);
|
|
WriteString(Creator);
|
|
WriteString(Description);
|
|
WriteImage(Preview);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSReportDocument.GetCaption: string;
|
|
begin
|
|
if FIsCaptionAssigned then
|
|
Result := FCaption
|
|
else
|
|
Result := DefaultCaption;
|
|
end;
|
|
|
|
function TdxPSReportDocument.GetCreator: string;
|
|
begin
|
|
if FIsCreatorAssigned then
|
|
Result := FCreator
|
|
else
|
|
Result := DefaultCreator;
|
|
end;
|
|
|
|
function TdxPSReportDocument.GetDescription: string;
|
|
begin
|
|
if FIsDescriptionAssigned then
|
|
Result := FDescription
|
|
else
|
|
Result := DefaultDescription;
|
|
end;
|
|
|
|
function TdxPSReportDocument.IsCaptionStored: Boolean;
|
|
begin
|
|
Result := FIsCaptionAssigned and (FCaption <> DefaultCaption);
|
|
end;
|
|
|
|
function TdxPSReportDocument.IsCreatorStored: Boolean;
|
|
begin
|
|
Result := FIsCreatorAssigned and (FCreator <> DefaultCreator);
|
|
end;
|
|
|
|
function TdxPSReportDocument.IsDesciptionStored: Boolean;
|
|
begin
|
|
Result := FIsDescriptionAssigned and (FDescription <> DefaultDescription);
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.SetCaption(const Value: string);
|
|
begin
|
|
if Caption <> Value then
|
|
begin
|
|
FCaption := Value;
|
|
FIsCaptionAssigned := True;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.SetCreationDate(const Value: TDateTime);
|
|
begin
|
|
if FCreationDate <> Value then
|
|
begin
|
|
FCreationDate := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.SetCreator(const Value: string);
|
|
begin
|
|
if FCreator <> Value then
|
|
begin
|
|
FIsCreatorAssigned := True;
|
|
FCreator := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.SetDescription(const Value: string);
|
|
begin
|
|
if FDescription <> Value then
|
|
begin
|
|
FIsDescriptionAssigned := True;
|
|
FDescription := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.ReadIsCaptionAssigned(Reader: TReader);
|
|
begin
|
|
FIsCaptionAssigned := Reader.ReadBoolean;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.ReadIsCreatorAssigned(Reader: TReader);
|
|
begin
|
|
FIsCreatorAssigned := Reader.ReadBoolean;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.ReadIsDescriptionAssigned(Reader: TReader);
|
|
begin
|
|
FIsDescriptionAssigned := Reader.ReadBoolean;
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.WriteIsCaptionAssigned(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(FIsCaptionAssigned);
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.WriteIsCreatorAssigned(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(FIsCreatorAssigned);
|
|
end;
|
|
|
|
procedure TdxPSReportDocument.WriteIsDescriptionAssigned(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(FIsDescriptionAssigned);
|
|
end;
|
|
|
|
{ TdxPSDataStorageOffsetTable }
|
|
|
|
constructor TdxPSDataStorageOffsetTable.Create(ATemplate: TdxPSDataStorageOffsetTable = nil);
|
|
begin
|
|
inherited Create;
|
|
Assign(ATemplate);
|
|
end;
|
|
|
|
procedure TdxPSDataStorageOffsetTable.Assign(Source: TdxPSDataStorageOffsetTable);
|
|
begin
|
|
Clear;
|
|
if Source <> nil then DoAssign(Source);
|
|
end;
|
|
|
|
procedure TdxPSDataStorageOffsetTable.Clear;
|
|
begin
|
|
Information := 0;
|
|
Document := 0;
|
|
Title := 0;
|
|
Data := 0;
|
|
Reserved1 := 0;
|
|
Reserved2 := 0;
|
|
Reserved3 := 0;
|
|
Reserved4 := 0;
|
|
end;
|
|
|
|
type
|
|
TdxPSDataStorageOffsetTableInfo = record
|
|
Information: Longint;
|
|
Document: Longint;
|
|
Title: Longint;
|
|
Data: Longint;
|
|
Reserved1: Longint;
|
|
Reserved2: Longint;
|
|
Reserved3: Longint;
|
|
Reserved4: Longint;
|
|
end;
|
|
|
|
procedure TdxPSDataStorageOffsetTable.ReadData(AReader: TdxPSDataReader);
|
|
var
|
|
MemSize: Integer;
|
|
Info: TdxPSDataStorageOffsetTableInfo;
|
|
begin
|
|
AReader.Read(MemSize, SizeOf(MemSize));
|
|
AReader.Read(Info, MemSize);
|
|
|
|
Information := Info.Information;
|
|
Document := Info.Document;
|
|
Title := Info.Title;
|
|
Data := Info.Data;
|
|
Reserved1 := Info.Reserved1;
|
|
Reserved2 := Info.Reserved2;
|
|
Reserved3 := Info.Reserved3;
|
|
Reserved4 := Info.Reserved4;
|
|
end;
|
|
|
|
procedure TdxPSDataStorageOffsetTable.WriteData(AWriter: TdxPSDataWriter);
|
|
var
|
|
MemSize: Integer;
|
|
Info: TdxPSDataStorageOffsetTableInfo;
|
|
begin
|
|
MemSize := SizeOf(Info);
|
|
Info.Information := Information;
|
|
Info.Document := Document;
|
|
Info.Title := Title;
|
|
Info.Data := Data;
|
|
Info.Reserved1 := Reserved1;
|
|
Info.Reserved2 := Reserved2;
|
|
Info.Reserved3 := Reserved3;
|
|
Info.Reserved4 := Reserved4;
|
|
|
|
AWriter.Write(MemSize, SizeOf(MemSize));
|
|
AWriter.Write(Info, MemSize);
|
|
end;
|
|
|
|
procedure TdxPSDataStorageOffsetTable.DoAssign(Source: TdxPSDataStorageOffsetTable);
|
|
begin
|
|
Information := Source.Information;
|
|
Document := Source.Document;
|
|
Title := Source.Title;
|
|
Data := Source.Data;
|
|
Reserved1 := Source.Reserved1;
|
|
Reserved2 := Source.Reserved2;
|
|
Reserved3 := Source.Reserved3;
|
|
Reserved4 := Source.Reserved4;
|
|
end;
|
|
|
|
{ TdxPSDataStorageInfo }
|
|
|
|
constructor TdxPSDataStorageInfo.Create(AReportLink: TBasedxReportLink);
|
|
begin
|
|
inherited Create;
|
|
StorageVersion := dxPSGlbl.dxPSStorageVersion;
|
|
PrintingSystemVersion := dxPSGlbl.dxPSVersion;
|
|
if AReportLink <> nil then
|
|
begin
|
|
LinkClassName := AReportLink.ClassName;
|
|
LinkClass := TdxReportLinkClass(Classes.GetClass(LinkClassName));
|
|
if AReportLink.Component <> nil then
|
|
begin
|
|
ComponentClassName := AReportLink.Component.ClassName;
|
|
ComponentClass := TComponentClass(Classes.GetClass(ComponentClassName));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSDataStorageInfo.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
with AReader do
|
|
begin
|
|
StorageVersion := ReadInteger;
|
|
PrintingSystemVersion := ReadPSVersion;
|
|
LinkClassName := ReadString;
|
|
ComponentClassName := ReadString;
|
|
LinkClass := TdxReportLinkClass(Classes.GetClass(LinkClassName));
|
|
ComponentClass := TComponentClass(Classes.GetClass(ComponentClassName));
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSDataStorageInfo.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
with AWriter do
|
|
begin
|
|
WriteInteger(StorageVersion);
|
|
WritePSVersion(PrintingSystemVersion);
|
|
WriteClassName(LinkClass);
|
|
WriteClassName(ComponentClass);
|
|
end;
|
|
end;
|
|
|
|
{ TBasedxReportLink }
|
|
|
|
constructor TBasedxReportLink.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
FBackgroundBitmapPool := TdxPSBackgroundBitmapPool.Create;
|
|
FBuiltIn := IsDesigning;
|
|
FColor := dxDefaultContentColor; {clWhite}
|
|
FCurrentPage := 1;
|
|
FFont := TFont.Create;
|
|
FFont.Assign(DefaultFont);
|
|
FFont.OnChange := FontChanged;
|
|
FDataSource := rldsComponent;
|
|
FPageNumberFormat := pnfNumeral;
|
|
FPrinterPage := TdxReportLinkPrinterPage.Create;
|
|
TdxReportLinkPrinterPage(FPrinterPage).FReportLink := Self;
|
|
FReportDocument := CreateReportDocument;
|
|
FReportDocument.OnChanged := DocumentChanged;
|
|
FReportTitle := TdxReportTitle.Create(Self);
|
|
FSavedReportTitle := TdxReportTitle.Create(nil);
|
|
FSavedReportDocument := CreateReportDocument;
|
|
FScaleFonts := True;
|
|
FShowPageFooter := True;
|
|
FShowPageHeader := True;
|
|
FSubscriber := TdxPageParamsChangedSubscriber.Create([TdxSMPageParamsChangedEvent]);
|
|
TdxPageParamsChangedSubscriber(FSubscriber).OnPageParamsChanged := PageParamsChanged;
|
|
FStartPageIndex := 1;
|
|
FTransparent := True;
|
|
FUseHorzDelimiters := True;
|
|
FUseVertDelimiters := True;
|
|
end;
|
|
|
|
destructor TBasedxReportLink.Destroy;
|
|
begin
|
|
{$IFNDEF DELPHI5}
|
|
Destroying;
|
|
{$ENDIF}
|
|
ComponentPrinter := nil;
|
|
Component := nil;
|
|
DoDestroyReport; {v2.0}
|
|
FreeAndNil(FRenderer);
|
|
FreeAndNil(FRenderInfo);
|
|
FreeAndNil(FSubscriber);
|
|
FreeAndNil(FSavedReportDocument);
|
|
FreeAndNil(FSavedReportTitle);
|
|
FreeAndNil(FReportTitle);
|
|
FreeAndNil(FReportDocument);
|
|
FreeAndNil(FPrinterPage);
|
|
FreeAndNil(FFontPool);
|
|
FreeAndNil(FFont);
|
|
FreeAndNil(FDefaultFont);
|
|
FinalizeDataStream;
|
|
FreeAndNil(FBackgroundBitmapPool);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.BeforeDestruction;
|
|
begin
|
|
inherited;
|
|
DoDestroy;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TBasedxReportLink then
|
|
with TBasedxReportLink(Source) do
|
|
begin
|
|
Self.Color := Color;
|
|
Self.DesignerCaption := DesignerCaption;
|
|
Self.Font := Font;
|
|
Self.FootersOnEveryPage := FootersOnEveryPage;
|
|
Self.HeadersOnEveryPage := HeadersOnEveryPage;
|
|
Self.PageNumberFormat := PageNumberFormat;
|
|
Self.RealPrinterPage.BeginUpdate;
|
|
try
|
|
Self.RealPrinterPage := RealPrinterPage;
|
|
finally
|
|
Self.RealPrinterPage.CancelUpdate;
|
|
end;
|
|
Self.ReportDocument := ReportDocument;
|
|
Self.ReportTitle := ReportTitle;
|
|
Self.ScaleFonts := ScaleFonts;
|
|
Self.ShowEmptyPages := ShowEmptyPages;
|
|
Self.ShowPageFooter := ShowPageFooter;
|
|
Self.ShowPageHeader := ShowPageHeader;
|
|
Self.ShrinkToPageWidth := ShrinkToPageWidth;
|
|
Self.TimeFormat := TimeFormat;
|
|
Self.Transparent := Transparent;
|
|
|
|
Self.FIsDesignerCaptionAssigned := FIsDesignerCaptionAssigned;
|
|
end
|
|
else
|
|
if Source is TBasedxPrintStyle then
|
|
PrinterPage := TBasedxPrintStyle(Source).PrinterPage
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetParentComponent: TComponent;
|
|
begin
|
|
Result := ComponentPrinter;
|
|
end;
|
|
|
|
function TBasedxReportLink.HasParent: Boolean;
|
|
begin
|
|
Result := ComponentPrinter <> nil;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.LoadFromRegistry(const APath: string);
|
|
var
|
|
AssignedFormat: Boolean;
|
|
Registry: TRegistry;
|
|
begin
|
|
if APath = '' then Exit;
|
|
Registry := TRegistry.Create;
|
|
with Registry do
|
|
try
|
|
if OpenKey(APath, False) then
|
|
try
|
|
AssignedFormat := ValueExists(sdxAssignedDateFormat) and ReadBool(sdxAssignedDateFormat);
|
|
if AssignedFormat and ValueExists(sdxDateFormat) then
|
|
DateFormat := ReadInteger(sdxDateFormat);
|
|
|
|
AssignedFormat := ValueExists(sdxAssignedTimeFormat) and ReadBool(sdxAssignedTimeFormat);
|
|
if AssignedFormat and ValueExists(sdxTimeFormat) then
|
|
TimeFormat := ReadInteger(sdxTimeFormat);
|
|
|
|
AssignedFormat := ValueExists(sdxAssignedPageNumberFormat) and ReadBool(sdxAssignedPageNumberFormat);
|
|
if AssignedFormat and ValueExists(sdxPageNumberFormat) then
|
|
PageNumberFormat := TdxPageNumberFormat(ReadInteger(sdxPageNumberFormat));
|
|
|
|
if ValueExists(sdxStartPageIndex) then
|
|
StartPageIndex := ReadInteger(sdxStartPageIndex);
|
|
except
|
|
on ERegistryException do
|
|
else
|
|
raise;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SaveToRegistry(const APath: string);
|
|
var
|
|
Registry: TRegistry;
|
|
begin
|
|
if APath = '' then Exit;
|
|
Registry := TRegistry.Create;
|
|
with Registry do
|
|
try
|
|
if OpenKey(APath, True) then
|
|
try
|
|
WriteBool(sdxAssignedDateFormat, fvDate in AssignedFormatValues);
|
|
if fvDate in AssignedFormatValues then
|
|
WriteInteger(sdxDateFormat, DateFormat);
|
|
|
|
WriteBool(sdxAssignedTimeFormat, fvTime in AssignedFormatValues);
|
|
if fvTime in AssignedFormatValues then
|
|
WriteInteger(sdxTimeFormat, TimeFormat);
|
|
|
|
WriteBool(sdxAssignedPageNumberFormat, fvPageNumber in AssignedFormatValues);
|
|
if fvPageNumber in AssignedFormatValues then
|
|
WriteInteger(sdxPageNumberFormat, Integer(PageNumberFormat));
|
|
|
|
WriteInteger(sdxStartPageIndex, StartPageIndex);
|
|
except
|
|
on ERegistryException do
|
|
else
|
|
raise;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
class function TBasedxReportLink.Aggregable: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
class function TBasedxReportLink.CanBeUsedAsStub: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
class function TBasedxReportLink.Serializable: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TBasedxReportLink.DefaultDateFormat: Integer;
|
|
begin
|
|
if not (fvDate in AssignedFormatValues) and (ComponentPrinter <> nil) then
|
|
Result := ComponentPrinter.DateFormat
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TBasedxReportLink.DefaultDesignerCaption: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxReportDesignerCaption);
|
|
end;
|
|
|
|
function TBasedxReportLink.DefaultFont: TFont;
|
|
begin
|
|
if FDefaultFont = nil then
|
|
begin
|
|
FDefaultFont := TFont.Create;
|
|
InitializeDefaultFont(FDefaultFont);
|
|
end;
|
|
Result := FDefaultFont;
|
|
end;
|
|
|
|
function TBasedxReportLink.DefaultPageNumberFormat: TdxPageNumberFormat;
|
|
begin
|
|
if not (fvPageNumber in AssignedFormatValues) and (ComponentPrinter <> nil) then
|
|
Result := ComponentPrinter.PageNumberFormat
|
|
else
|
|
Result := pnfNumeral;
|
|
end;
|
|
|
|
function TBasedxReportLink.DefaultTimeFormat: Integer;
|
|
begin
|
|
if not (fvTime in AssignedFormatValues) and (ComponentPrinter <> nil) then
|
|
Result := ComponentPrinter.TimeFormat
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.RestoreDefaults;
|
|
begin
|
|
InternalRestoreDefaults;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.RestoreFromOriginal;
|
|
begin
|
|
if Component <> nil then InternalRestoreFromOriginal;
|
|
end;
|
|
|
|
function TBasedxReportLink.CheckToDesign: Boolean;
|
|
begin
|
|
Result := (DataSource = rldsComponent) and (GetDesignerClass <> nil);
|
|
end;
|
|
|
|
function TBasedxReportLink.DataProviderPresent: Boolean;
|
|
begin
|
|
if DataSource = rldsComponent then
|
|
Result := Component <> nil
|
|
else
|
|
Result := PossibleDataStorage(DataStream, False);
|
|
end;
|
|
|
|
function TBasedxReportLink.DesignerExists(AComponentClass: TComponentClass): Boolean;
|
|
begin
|
|
Result := GetDesignerClass <> nil;
|
|
end;
|
|
|
|
function TBasedxReportLink.DesignReport: Boolean;
|
|
var
|
|
DesignWindowClass: TdxReportLinkDesignWindowClass;
|
|
SaveLink: TBasedxReportLink;
|
|
begin
|
|
Result := False;
|
|
DesignWindowClass := GetDesignerClass;
|
|
if DesignWindowClass <> nil then
|
|
begin
|
|
FDesignWindow := DesignWindowClass.Create(nil);
|
|
try
|
|
DesignWindow.ReportLink := Self;
|
|
SaveLink := LinkClass.Create(nil);
|
|
try
|
|
SaveLink.Assign(Self);
|
|
BeforeDesignReport;
|
|
try
|
|
Result := DesignWindow.Execute;
|
|
finally
|
|
AfterDesignReport(Result);
|
|
end;
|
|
if not Result and not DesignWindow.Applyed then
|
|
Assign(SaveLink);
|
|
finally
|
|
SaveLink.Free;
|
|
end;
|
|
finally
|
|
FreeAndNil(FDesignWindow);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DestroyReport;
|
|
begin
|
|
Active := False;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.GetPageColRowCount(out APageColCount, APageRowCount: Integer);
|
|
begin
|
|
APageColCount := RenderInfo.PageColCount;
|
|
APageRowCount := RenderInfo.PageRowCount;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.Initialize;
|
|
begin
|
|
end;
|
|
|
|
function TBasedxReportLink.IsEmptyPage(AVirtualPageIndex: Integer): Boolean;
|
|
begin
|
|
if (AVirtualPageIndex > -1) and (AVirtualPageIndex < RenderInfo.VirtualPageCount) then
|
|
Result := RenderInfo.PageRenderInfos[AVirtualPageIndex].IsEmptyPage
|
|
else
|
|
Result := True;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsEmptyReport: Boolean;
|
|
begin
|
|
Result := (FRenderInfo = nil) or (RenderInfo.NonEmptyPageCount = 0);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.RebuildReport;
|
|
begin
|
|
if HasDesignWindow then DesignWindow.BeforeRebuildReport;
|
|
try
|
|
Active := False;
|
|
Active := True;
|
|
finally
|
|
if HasDesignWindow then DesignWindow.AfterRebuildReport;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetComponentUnconditionally(Value: TComponent);
|
|
begin
|
|
FComponent := Value;
|
|
if Active or FStreamedActive then
|
|
try
|
|
if FStreamedActive then FStreamedActive := False;
|
|
RebuildReport;
|
|
if not IsLoading and (ComponentPrinter <> nil) and not ComponentPrinter.AutoUpdateDateTime then
|
|
begin
|
|
DateTime := Now;
|
|
DesignerModified;
|
|
end;
|
|
LinkModified(False);
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
FComponent := nil;
|
|
if IsDesigning then
|
|
ShowException(E, ExceptAddr)
|
|
else
|
|
raise;
|
|
end;
|
|
end;
|
|
if Value <> nil then
|
|
Value.FreeNotification(Self);
|
|
end;
|
|
|
|
class procedure TBasedxReportLink.GetSupportedComponentList(AList: TdxClassList);
|
|
begin
|
|
dxPSGetLinkSupportedComponentsList(AList, LinkClass);
|
|
end;
|
|
|
|
class function TBasedxReportLink.IsSupportedCompClass(AComponentClass: TClass): Boolean;
|
|
begin
|
|
Result := dxPSIsSupportedCompClass(AComponentClass) and (dxPSLinkClassByCompClass(AComponentClass) = LinkClass);
|
|
end;
|
|
|
|
class function TBasedxReportLink.LinkClass: TdxReportLinkClass;
|
|
begin
|
|
Result := TdxReportLinkClass(GetTypeData(ClassInfo)^.ClassType);
|
|
end;
|
|
|
|
class function TBasedxReportLink.Supports(AnObject: TObject): Boolean;
|
|
begin
|
|
Result := (AnObject <> nil) and Supports(AnObject.ClassType);
|
|
end;
|
|
|
|
class function TBasedxReportLink.Supports(AClass: TClass): Boolean;
|
|
begin
|
|
Result := (AClass <> nil) and AClass.InheritsFrom(TComponent) and IsSupportedCompClass(AClass);
|
|
end;
|
|
|
|
function TBasedxReportLink.Print(AShowDialog: Boolean;
|
|
APPrintDlgData: PdxPrintDlgData): Boolean;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
ComponentPrinter.CurrentLink := Self;
|
|
Result := ComponentPrinter.Print(AShowDialog, APPrintDlgData, Self);
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.PrintEx(APageNums: TdxPageNumbers;
|
|
ACopies: Integer; ACollate: Boolean);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
ComponentPrinter.CurrentLink := Self;
|
|
ComponentPrinter.PrintEx(APageNums, ACopies, ACollate, Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.PrintPages(const APageIndexes: array of Integer);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
ComponentPrinter.CurrentLink := Self;
|
|
ComponentPrinter.PrintPages(APageIndexes, Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.PrintPagesEx(const APageIndexes: array of Integer;
|
|
APageNums: TdxPageNumbers; ACopyCount: Integer; ACollate: Boolean);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
ComponentPrinter.CurrentLink := Self;
|
|
ComponentPrinter.PrintPagesEx(APageIndexes, APageNums, ACopyCount, ACollate, Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.BuildPageSetupMenu(ARootItem: TComponent;
|
|
AData: Pointer; AIncludeDefineItem: Boolean = True);
|
|
var
|
|
MenuBuilder: TAbstractdxPSPageSetupMenuBuilder;
|
|
Styles: TStringList;
|
|
begin
|
|
if StyleManager = nil then Exit;
|
|
MenuBuilder := dxPSPageSetupMenuBuilderFactory.ActiveBuilder.Create;
|
|
try
|
|
try
|
|
Styles := TStringList.Create;
|
|
try
|
|
GetFilteredStyles(Styles);
|
|
MenuBuilder.BuildPageSetupMenu(ARootItem, AData, AIncludeDefineItem,
|
|
Styles, CurrentPrintStyle, StyleClick, DefineStylesClick);
|
|
finally
|
|
Styles.Free;
|
|
end;
|
|
except
|
|
Application.HandleException(Self);
|
|
end;
|
|
finally
|
|
MenuBuilder.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DefinePrintStylesDlg;
|
|
var
|
|
PreviewBtnClicked, PrintBtnClicked: Boolean;
|
|
begin
|
|
if StyleManager <> nil then
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
Include(ComponentPrinter.FState, cpsDefineStylesDialog);
|
|
|
|
try
|
|
StyleManager.DefinePrintStylesDlg(PreviewBtnClicked, PrintBtnClicked);
|
|
finally
|
|
if ComponentPrinter <> nil then
|
|
Exclude(ComponentPrinter.FState, cpsDefineStylesDialog);
|
|
end;
|
|
|
|
if PrintBtnClicked then
|
|
Print(True, nil)
|
|
else
|
|
if PreviewBtnClicked then Preview(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.GetFilteredStyles(AStrings: TStrings);
|
|
var
|
|
I: Integer;
|
|
Style: TBasedxPrintStyle;
|
|
begin
|
|
if StyleManager <> nil then
|
|
for I := 0 to StyleManager.Count - 1 do
|
|
begin
|
|
Style := StyleManager.Styles[I];
|
|
if IsSupportedStyle(Style) then
|
|
AStrings.AddObject(Style.StyleCaption, Style);
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.PageSetup: Boolean;
|
|
var
|
|
PreviewBtnClicked, PrintBtnClicked: Boolean;
|
|
begin
|
|
Result := PageSetupEx(0, True, True, PreviewBtnClicked, PrintBtnClicked);
|
|
if PreviewBtnClicked then
|
|
Preview(True)
|
|
else
|
|
if PrintBtnClicked then
|
|
Result := Print(True, nil);
|
|
end;
|
|
|
|
function TBasedxReportLink.PageSetupEx(AActivePageIndex: Integer;
|
|
AShowPreviewBtn, AShowPrintBtn: Boolean;
|
|
out APreviewBtnClicked, APrintBtnClicked: Boolean): Boolean;
|
|
var
|
|
PrintStyle: TBasedxPrintStyle;
|
|
PrintStyleExists: Boolean;
|
|
begin
|
|
PrintStyle := CurrentPrintStyle;
|
|
PrintStyleExists := PrintStyle <> nil;
|
|
if not PrintStyleExists then
|
|
PrintStyle := TdxPSPrintStyle.Create(nil);
|
|
try
|
|
if (dxPrintDevice <> nil) and (dxPrintDevice.DeviceMode <> nil) then
|
|
begin
|
|
PrinterPage.Orientation := TdxPrinterOrientation(dxPrintDevice.DeviceMode^.dmOrientation - 1);
|
|
PrinterPage.GrayShading := not Boolean(dxPrintDevice.DeviceMode^.dmColor - 1);
|
|
end;
|
|
if not PrintStyleExists then PrintStyle.Assign(Self);
|
|
if ComponentPrinter <> nil then ComponentPrinter.PreparePageSetup;
|
|
try
|
|
if not DataProviderPresent then
|
|
begin
|
|
AShowPreviewBtn := False;
|
|
AShowPrintBtn := False;
|
|
end;
|
|
Result := PrintStyle.PageSetup(AActivePageIndex, AShowPreviewBtn, AShowPrintBtn,
|
|
APreviewBtnClicked, APrintBtnClicked);
|
|
finally
|
|
if ComponentPrinter <> nil then ComponentPrinter.UnpreparePageSetup;
|
|
end;
|
|
if Result and not PrintStyleExists then
|
|
begin
|
|
Self.Assign(PrintStyle);
|
|
if ComponentPrinter <> nil then
|
|
ComponentPrinter.InitDevModeFromPrinterPageSettings(PrinterPage);
|
|
end;
|
|
if ComponentPrinter <> nil then ComponentPrinter.DoPageSetup(Self, Result);
|
|
finally
|
|
if not PrintStyleExists then PrintStyle.Free;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.PageSetupEx(AActivePageIndex: Integer;
|
|
APreviewBtnClicked, APrintBtnClicked: PBoolean): Boolean;
|
|
var
|
|
ShowPreviewBtn, ShowPrintBtn, PreviewBtnClicked, PrintBtnClicked: Boolean;
|
|
begin
|
|
ShowPreviewBtn := APreviewBtnClicked <> nil;
|
|
ShowPrintBtn := APrintBtnClicked <> nil;
|
|
Result := PageSetupEx(AActivePageIndex, ShowPreviewBtn, ShowPrintBtn, PreviewBtnClicked, PrintBtnClicked);
|
|
|
|
if ShowPreviewBtn then
|
|
APreviewBtnClicked^ := PreviewBtnClicked;
|
|
|
|
if ShowPrintBtn then
|
|
APrintBtnClicked^ := PrintBtnClicked;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.Preview(Modal: Boolean = True);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
ComponentPrinter.CurrentLink := Self;
|
|
ComponentPrinter.Preview(Modal, Self);
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.PreviewExists: Boolean;
|
|
begin
|
|
Result := IsCurrentLink and ComponentPrinter.PreviewExists;
|
|
end;
|
|
|
|
function TBasedxReportLink.ShowDateTimeFormatsDlg: Boolean;
|
|
var
|
|
Data: TdxDateTimeFormatDlgData;
|
|
begin
|
|
FillChar(Data, SizeOf(TdxDateTimeFormatDlgData), 0);
|
|
with Data do
|
|
begin
|
|
DateFormats := dxPgsDlg.DateFormats;
|
|
TimeFormats := dxPgsDlg.TimeFormats;
|
|
DateFormatIndex := DateFormat;
|
|
TimeFormatIndex := TimeFormat;
|
|
if ComponentPrinter <> nil then
|
|
AutoUpdateDateTime := ComponentPrinter.AutoUpdateDateTime;
|
|
ShowAsDefaultButton := True;
|
|
end;
|
|
Result := dxShowDateTimeFormatDlg(Data);
|
|
if Result then
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
ComponentPrinter.AutoUpdateDateTime := Data.AutoUpdateDateTime;
|
|
if Data.SetDateTimeFormatAsDefault then
|
|
begin
|
|
ComponentPrinter.DateFormat := Data.DateFormatIndex;
|
|
ComponentPrinter.TimeFormat := Data.TimeFormatIndex;
|
|
end;
|
|
end;
|
|
DateFormat := Data.DateFormatIndex;
|
|
TimeFormat := Data.TimeFormatIndex;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.ShowPageNumberFormatsDlg: Boolean;
|
|
var
|
|
Data: TdxPageNumberFormatDlgData;
|
|
begin
|
|
FillChar(Data, SizeOf(TdxPageNumberFormatDlgData), 0);
|
|
with Data do
|
|
begin
|
|
PageNumberFormats := dxPgsDlg.PageNumberFormats;
|
|
PageNumberFormat := Self.PageNumberFormat;
|
|
AllowContinueFromPrevSection := AllowContinuousPageIndexes;
|
|
if AllowContinueFromPrevSection then
|
|
ContinueFromPrevSection := ContinuousPageIndexes;
|
|
StartPageIndex := Self.StartPageIndex;
|
|
ShowAsDefaultButton := True;
|
|
end;
|
|
Result := dxShowPageNumberFormatDlg(Data);
|
|
if Result then
|
|
begin
|
|
if (ComponentPrinter <> nil) and Data.SetPageNumberFormatAsDefault then
|
|
ComponentPrinter.PageNumberFormat := Data.PageNumberFormat;
|
|
PageNumberFormat := Data.PageNumberFormat;
|
|
StartPageIndex := Data.StartPageIndex;
|
|
if AllowContinuousPageIndexes then
|
|
ContinuousPageIndexes := Data.ContinueFromPrevSection;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.ShowTitlePropertiesDlg: Boolean;
|
|
begin
|
|
Result := False;
|
|
if CanChangeTitle then
|
|
begin
|
|
Result := dxShowReportTitlePropertiesDlg(ReportTitle);
|
|
if Result and PreviewExists and DataProviderPresent then
|
|
RebuildReport;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.SupportsScaling: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TBasedxReportLink.CanChangeTitle: Boolean;
|
|
begin
|
|
Result := SupportsTitle and not IsAggregated and (DataSource = rldsComponent) and
|
|
((ComponentPrinter = nil) or not ComponentPrinter.IsExplorerMode);
|
|
end;
|
|
|
|
function TBasedxReportLink.SupportsTitle: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TBasedxReportLink.CanLoadData: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TBasedxReportLink.CanSaveData: Boolean;
|
|
begin
|
|
Result := Serializable and not IsEmptyReport and (DataSource = rldsComponent);
|
|
end;
|
|
|
|
function TBasedxReportLink.CanUnloadData: Boolean;
|
|
begin
|
|
Result := DataSource = rldsExternalStorage;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetNewReportStorageName: string;
|
|
const
|
|
CRLF = #13#10;
|
|
var
|
|
P, I: Integer;
|
|
begin
|
|
Result := ReportTitle.Text;
|
|
if Result = '' then
|
|
Result := ReportDocument.Caption;
|
|
if Result <> '' then
|
|
begin
|
|
P := Pos(CRLF, Result);
|
|
if P <> 0 then
|
|
Result := Copy(Result, 1, P - 1);
|
|
end;
|
|
if Result = '' then
|
|
Result := cxGetResourceString(@sdxNewReport);
|
|
|
|
for I := 1 to Length(dxPSUtl.InvalidFileNameChars) do
|
|
Result := StringReplace(Result, dxPSUtl.InvalidFileNameChars[I], '_', [rfReplaceAll, rfIgnoreCase]);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.LoadDataFromFile(const AName: string);
|
|
var
|
|
Stream: TStream;
|
|
begin
|
|
Stream := TFileStream.Create(AName, fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
FStorageName := AName;
|
|
LoadDataFromStream(Stream);
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.LoadDataFromStream(AStream: TStream);
|
|
begin
|
|
if PossibleDataStorage(AStream, True) then
|
|
begin
|
|
CopyDataStreamFrom(AStream);
|
|
if DataSource <> rldsExternalStorage then
|
|
DataSource := rldsExternalStorage
|
|
else
|
|
if IsRebuildNeededAndAllowed(True) then
|
|
RebuildReport;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SaveDataToFile(const AName: string);
|
|
var
|
|
Stream: TStream;
|
|
begin
|
|
try
|
|
Stream := TFileStream.Create(AName, fmCreate);// or fmOpenWrite);
|
|
try
|
|
SaveDataToStream(Stream);
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
except
|
|
// TODO: File is locked
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SaveDataToStream(AStream: TStream);
|
|
var
|
|
Writer: TdxPSDataWriter;
|
|
begin
|
|
if DataProviderPresent and (FReportCells = nil) then RebuildReport;
|
|
|
|
if ReportCells <> nil then //HasData
|
|
begin
|
|
PrepareLongOperation;
|
|
try
|
|
Include(FState, rlsDataSaving);
|
|
try
|
|
Writer := CreateDataWriter(AStream);
|
|
try
|
|
InternalWriteData(Writer);
|
|
finally
|
|
Writer.Free;
|
|
end;
|
|
finally
|
|
Exclude(FState, rlsDataSaving);
|
|
end;
|
|
finally
|
|
UnprepareLongOperation;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class function TBasedxReportLink.ExtractComponentClass(AStream: TStream;
|
|
ARaiseException: Boolean = False): TComponentClass;
|
|
var
|
|
StorageInfo: TdxPSDataStorageInfo;
|
|
begin
|
|
try
|
|
StorageInfo := ExtractStorageInfo(AStream, ARaiseException);
|
|
try
|
|
Result := StorageInfo.ComponentClass;
|
|
finally
|
|
FinalizeStorageInfo(StorageInfo);
|
|
end;
|
|
except
|
|
Result := nil;
|
|
if ARaiseException then raise;
|
|
end;
|
|
end;
|
|
|
|
class function TBasedxReportLink.ExtractLinkClass(AStream: TStream;
|
|
ARaiseException: Boolean = False): TdxReportLinkClass;
|
|
var
|
|
StorageInfo: TdxPSDataStorageInfo;
|
|
begin
|
|
try
|
|
StorageInfo := ExtractStorageInfo(AStream, ARaiseException);
|
|
try
|
|
Result := StorageInfo.LinkClass;
|
|
finally
|
|
FinalizeStorageInfo(StorageInfo);
|
|
end;
|
|
except
|
|
Result := nil;
|
|
if ARaiseException then raise;
|
|
end;
|
|
end;
|
|
|
|
class function TBasedxReportLink.ExtractOffsetTable(AStream: TStream;
|
|
ARaiseException: Boolean = False): TdxPSDataStorageOffsetTable;
|
|
var
|
|
P: {$IFDEF DELPHI6} Int64 {$ELSE} Integer {$ENDIF};
|
|
Reader: TdxPSDataReader;
|
|
begin
|
|
Result := nil;
|
|
try
|
|
P := AStream.Position;
|
|
try
|
|
AStream.Position := 0;
|
|
Reader := CreateDataReader(AStream);
|
|
try
|
|
Result := ReadOffsetTable(Reader);
|
|
finally
|
|
Reader.Free;
|
|
end;
|
|
finally
|
|
AStream.Position := P;
|
|
end;
|
|
except
|
|
FreeAndNil(Result);
|
|
if ARaiseException then raise;
|
|
end;
|
|
end;
|
|
|
|
class function TBasedxReportLink.ExtractReportDocument(AStream: TStream;
|
|
ARaiseException: Boolean = False): TdxPSReportDocument;
|
|
var
|
|
OffsetTable: TdxPSDataStorageOffsetTable;
|
|
P: {$IFDEF DELPHI6} Int64 {$ELSE} Integer {$ENDIF};
|
|
Reader: TdxPSDataReader;
|
|
begin
|
|
Result := nil;
|
|
try
|
|
OffsetTable := ExtractOffsetTable(AStream, ARaiseException);
|
|
if OffsetTable <> nil then
|
|
try
|
|
P := AStream.Position;
|
|
AStream.Position := OffsetTable.Document;
|
|
try
|
|
Reader := CreateDataReader(AStream);
|
|
try
|
|
Result := GetReportDocumentClass.Create(nil);
|
|
ReadReportDocument(Reader, Result);
|
|
finally
|
|
Reader.Free;
|
|
end;
|
|
finally
|
|
AStream.Position := P;
|
|
end;
|
|
finally
|
|
OffsetTable.Free;
|
|
end;
|
|
except
|
|
FreeAndNil(Result);
|
|
if ARaiseException then raise;
|
|
end;
|
|
end;
|
|
|
|
class function TBasedxReportLink.ExtractStorageInfo(AStream: TStream;
|
|
ARaiseException: Boolean = False): TdxPSDataStorageInfo;
|
|
var
|
|
OffsetTable: TdxPSDataStorageOffsetTable;
|
|
P: {$IFDEF DELPHI6} Int64 {$ELSE} Integer {$ENDIF};
|
|
Reader: TdxPSDataReader;
|
|
begin
|
|
try
|
|
OffsetTable := ExtractOffsetTable(AStream, ARaiseException);
|
|
if OffsetTable <> nil then
|
|
try
|
|
P := AStream.Position;
|
|
AStream.Position := OffsetTable.Information;
|
|
try
|
|
Reader := CreateDataReader(AStream);
|
|
try
|
|
Result := ReadStorageInfo(Reader);
|
|
finally
|
|
Reader.Free;
|
|
end;
|
|
finally
|
|
AStream.Position := P;
|
|
end;
|
|
finally
|
|
OffsetTable.Free;
|
|
end;
|
|
except
|
|
FreeAndNil(Result);
|
|
if ARaiseException then raise;
|
|
end;
|
|
end;
|
|
|
|
class function TBasedxReportLink.ExtractStorageVersion(AStream: TStream;
|
|
ARaiseException: Boolean = False): Integer;
|
|
var
|
|
StorageInfo: TdxPSDataStorageInfo;
|
|
begin
|
|
try
|
|
StorageInfo := ExtractStorageInfo(AStream, ARaiseException);
|
|
try
|
|
Result := StorageInfo.StorageVersion;
|
|
finally
|
|
FinalizeStorageInfo(StorageInfo);
|
|
end;
|
|
except
|
|
Result := dxPSGlbl.dxPSInvalidStorageVersion;
|
|
if ARaiseException then raise;
|
|
end;
|
|
end;
|
|
|
|
class procedure TBasedxReportLink.FinalizeStorageInfo(var AStorageInfo: TdxPSDataStorageInfo);
|
|
begin
|
|
FreeAndNil(AStorageInfo);
|
|
end;
|
|
|
|
class function TBasedxReportLink.PossibleDataStorage(AStream: TStream;
|
|
ARaiseException: Boolean = False): Boolean;
|
|
begin
|
|
Result := AStream <> nil;
|
|
if Result then
|
|
try
|
|
Result := ExtractStorageVersion(AStream, ARaiseException) = dxPSGlbl.dxPSStorageVersion;
|
|
except
|
|
Result := False;
|
|
if ARaiseException then raise;
|
|
end;
|
|
end;
|
|
|
|
class function TBasedxReportLink.PossibleDataStorage(const AFileName: string;
|
|
ARaiseException: Boolean = False): Boolean;
|
|
var
|
|
Stream: TFileStream;
|
|
begin
|
|
Result := FileExists(AFileName);
|
|
if Result then
|
|
try
|
|
Stream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
Result := PossibleDataStorage(Stream, ARaiseException);
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
except
|
|
Result := False;
|
|
if ARaiseException then raise;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.AddBackgroundBitmapToPool(ABitmap: TBitmap): Integer;
|
|
begin
|
|
Result := BackgroundBitmapPool.Add(ABitmap);
|
|
end;
|
|
|
|
function TBasedxReportLink.AddFontToPool(AFont: TFont): Integer;
|
|
begin
|
|
Result := FontPool.Add(AFont);
|
|
end;
|
|
|
|
function TBasedxReportLink.CreateGroupLookAndFeel(AClass: TdxPSReportGroupLookAndFeelClass;
|
|
ACheckExisting: Boolean = True): TdxPSReportGroupLookAndFeel;
|
|
begin
|
|
if ReportCells <> nil then
|
|
Result := ReportCells.CreateGroupLookAndFeel(AClass, ACheckExisting)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TBasedxReportLink.FindGroupLookAndFeelByClass(AClass: TdxPSReportGroupLookAndFeelClass): TdxPSReportGroupLookAndFeel;
|
|
begin
|
|
if ReportCells <> nil then
|
|
Result := ReportCells.FindGroupLookAndFeelByClass(AClass)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TBasedxReportLink.IndexOfReportGroupLookAndFeel(ALookAndFeel: TdxPSReportGroupLookAndFeel): Integer;
|
|
begin
|
|
if ReportCells <> nil then
|
|
Result := ReportCells.IndexOfReportGroupLookAndFeel(ALookAndFeel)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawPageHeader(APageIndex: Integer; ARect: TRect;
|
|
ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
begin
|
|
if FPainting then
|
|
Renderer.RenderPageHeaderOrFooterContent(RealPrinterPage.PageHeader,
|
|
APageIndex, ARect, ATitleParts, ADrawBackground);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawPageFooter(APageIndex: Integer; ARect: TRect;
|
|
ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
begin
|
|
if FPainting then
|
|
Renderer.RenderPageHeaderOrFooterContent(RealPrinterPage.PageFooter,
|
|
APageIndex, ARect, ATitleParts, ADrawBackground);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawCheckBox(Canvas: TCanvas; var R: TRect;
|
|
Checked, Enabled, FlatBorder: Boolean; BoldBorder: Boolean = False);
|
|
var
|
|
EdgeStyle: TdxCheckButtonEdgeStyle;
|
|
begin
|
|
if FPainting then
|
|
begin
|
|
EdgeStyle := cbes3D;
|
|
if FlatBorder then
|
|
EdgeStyle := cbesUltraFlat
|
|
else
|
|
if BoldBorder then
|
|
EdgeStyle := cbesBoldFlat;
|
|
Renderer.DrawCheckBox(Canvas.Handle, R, Checked, Enabled, False, EdgeStyle);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawCheckBox(Canvas: TCanvas; var R: TRect;
|
|
Checked, Enabled, IsRadio: Boolean; EdgeStyle: TdxCheckButtonEdgeStyle;
|
|
BorderColor: TColor = clWindowText);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawCheckBox(Canvas.Handle, R, Checked, Enabled, IsRadio, EdgeStyle, BorderColor);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawEdge(Canvas: TCanvas; var R: TRect;
|
|
EdgeMode: TdxCellEdgeMode; InnerEdge, OuterEdge: TdxCellEdgeStyle;
|
|
Sides: TdxCellSides = [csLeft..csBottom]; Soft: Boolean = True);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawEdge(Canvas.Handle, R, EdgeMode, {InnerEdge, } OuterEdge, Sides, Soft, -1);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawEllipse(Canvas: TCanvas; R: TRect; ForeColor, BkColor: TColor;
|
|
Pattern: TdxPSFillPatternClass; BorderColor: TColor; BorderThickness: Integer = 1);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawEllipse(Canvas.Handle, R, ForeColor, BkColor, Pattern, BorderColor, BorderThickness);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawExpandButton(Canvas: TCanvas; var R: TRect;
|
|
Expanded, DrawBorder, Edge3D, Edge3DSoft, Shadow, FillInterior: Boolean;
|
|
BorderColor, InteriorColor: TColor);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawExpandButton(Canvas.Handle, R, Expanded, DrawBorder, Edge3D,
|
|
Edge3DSoft, Shadow, FillInterior, BorderColor, InteriorColor);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawGlyph(DC: HDC; const R: TRect; AGlyph: Byte);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawGlyph(DC, R, AGlyph);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawGraphic(Canvas: TCanvas; var R: TRect;
|
|
const ClipRect: TRect; ImageList: TCustomImageList; ImageIndex: Integer;
|
|
Graphic: TGraphic; GraphicTransparent, Transparent: Boolean; BkColor: TColor);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawGraphic(Canvas.Handle, R, ClipRect, ImageList, ImageIndex,
|
|
Graphic, GraphicTransparent, Transparent, BkColor);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawGraphicEx(Canvas: TCanvas; var R: TRect;
|
|
const ClipRect: TRect; ImageList: TCustomImageList; ImageIndex: Integer;
|
|
Graphic: TGraphic; GraphicTransparent, Transparent: Boolean;
|
|
BkColor, ForeColor: TColor; Pattern: TdxPSFillPatternClass;
|
|
AnActualImageBuffering: TdxCellImageActualBuffering = cibAlways);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawGraphicEx(Canvas.Handle, R, ClipRect, ImageList, ImageIndex,
|
|
Graphic, GraphicTransparent, Transparent, BkColor, ForeColor, Pattern,
|
|
AnActualImageBuffering);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawRectangle(Canvas: TCanvas; R: TRect;
|
|
ForeColor, BkColor: TColor; ContentPattern: TdxPSFillPatternClass; BorderColor: TColor;
|
|
BorderThickness: Integer = 1);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawRectangle(Canvas.Handle, R, ForeColor, BkColor, ContentPattern,
|
|
BorderColor, BorderThickness);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawRoundRect(Canvas: TCanvas; R: TRect;
|
|
CornerWidth, CornerHeight: Integer; ForeColor, BkColor: TColor;
|
|
ContentPattern: TdxPSFillPatternClass; BorderColor: TColor;
|
|
BorderThickness: Integer = 1);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawRoundRect(Canvas.Handle, R, CornerWidth, CornerHeight,
|
|
ForeColor, BkColor, ContentPattern, BorderColor, BorderThickness);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawSortMark(Canvas: TCanvas; var R: TRect;
|
|
SortOrder: TdxCellSortOrder; Mono: Boolean);
|
|
begin
|
|
if FPainting and (SortOrder <> csoNone) then
|
|
Renderer.DrawSortMark(Canvas.Handle, R, SortOrder, Mono);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawText(Canvas: TCanvas; var R: TRect; AIndent: Integer;
|
|
const Text: string; Font: TFont; BkColor: TColor; TextAlignX: TdxTextAlignX;
|
|
TextAlignY: TdxTextAlignY; FillBackground, Multiline, EndEllipsis: Boolean);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawText(Canvas.Handle, R, 0, AIndent, 0, Text, Font, BkColor,
|
|
TextAlignX, TextAlignY, FillBackground, Multiline, EndEllipsis, True, True);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DrawTextEx(Canvas: TCanvas; var R: TRect;
|
|
MaxLineCount: Integer; LeftIndent, RightIndent: Integer; const Text: string;
|
|
Font: TFont; BkColor: TColor; TextAlignX: TdxTextAlignX; TextAlignY: TdxTextAlignY;
|
|
FillBackground, Multiline, EndEllipsis, PreventLeftTextExceed,
|
|
PreventTopTextExceed: Boolean);
|
|
begin
|
|
if FPainting then
|
|
Renderer.DrawText(Canvas.Handle, R, MaxLineCount, LeftIndent, RightIndent,
|
|
Text, Font, BkColor, TextAlignX, TextAlignY, FillBackground, Multiline,
|
|
EndEllipsis, PreventLeftTextExceed, PreventTopTextExceed);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FillEllipse(Canvas: TCanvas; const R: TRect; Color: TColor);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FillEllipse(Canvas.Handle, R, Color);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FillEllipseEx(Canvas: TCanvas; const R: TRect;
|
|
ForeColor, BkColor: TColor; Pattern: TdxPSFillPatternClass);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FillEllipseEx(Canvas.Handle, R, ForeColor, BkColor, Pattern);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FillRectEx(Canvas: TCanvas; const R: TRect;
|
|
ForeColor, BkColor: TColor; Pattern: TdxPSFillPatternClass);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FillRectEx(Canvas.Handle, R, ForeColor, BkColor, Pattern);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FillRoundRect(Canvas: TCanvas; const R: TRect;
|
|
CornerWidth, CornerHeight: Integer; Color: TColor);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FillRoundRect(Canvas.Handle, R, CornerWidth, CornerHeight, Color);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FillRoundRectEx(Canvas: TCanvas; const R: TRect;
|
|
CornerWidth, CornerHeight: Integer; ForeColor, BkColor: TColor;
|
|
Pattern: TdxPSFillPatternClass);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FillRoundRectEx(Canvas.Handle, R, CornerWidth, CornerHeight,
|
|
ForeColor, BkColor, Pattern);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FillRgnEx(Canvas: TCanvas; Rgn: HRGN;
|
|
ForeColor, BkColor: TColor; Pattern: TdxPSFillPatternClass);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FillRgnEx(Canvas.Handle, Rgn, ForeColor, BkColor, Pattern);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FrameEllipse(Canvas: TCanvas; R: TRect; Color: TColor;
|
|
Thickness: Integer = 1);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FrameEllipse(Canvas.Handle, R, Color, Thickness);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FrameRect(Canvas: TCanvas; R: TRect; Color: TColor;
|
|
Sides: TdxCellSides = [csLeft..csBottom]; Thickness: Integer = 1);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FrameRect(Canvas.Handle, R, Color, Sides, Thickness);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FrameRoundRect(Canvas: TCanvas; R: TRect;
|
|
CornerWidth, CornerHeight: Integer; Color: TColor; Thickness: Integer = 1);
|
|
begin
|
|
if FPainting then
|
|
Renderer.FrameRoundRect(Canvas.Handle, R, CornerWidth, CornerHeight, Color, Thickness);
|
|
end;
|
|
|
|
function TBasedxReportLink.RealPageIndexToVirtualPageIndex(APageIndex: Integer;
|
|
ATakeIntoAccountEmptyPages: Boolean): Integer;
|
|
begin
|
|
Result := RenderInfo.RealPageIndexToVirtualPageIndex(APageIndex, ATakeIntoAccountEmptyPages);
|
|
end;
|
|
|
|
function TBasedxReportLink.VirtualPageIndexToRealPageIndex(APageIndex: Integer): Integer;
|
|
begin
|
|
Result := RenderInfo.VirtualPageIndexToRealPageIndex(APageIndex);
|
|
end;
|
|
|
|
{$IFNDEF DELPHI6}
|
|
|
|
{ IUnknown }
|
|
|
|
function TBasedxReportLink.QueryInterface(const IID: TGUID; out Obj): HRESULT;
|
|
begin
|
|
if GetInterface(IID, Obj) then
|
|
Result := S_OK
|
|
else
|
|
Result := E_NOINTERFACE;
|
|
end;
|
|
|
|
function TBasedxReportLink._Addref: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TBasedxReportLink._Release: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
procedure TBasedxReportLink.AssignTo(Dest: TPersistent);
|
|
begin
|
|
if Dest is TBasedxPrintStyle then
|
|
TBasedxPrintStyle(Dest).PrinterPage := PrinterPage
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited DefineProperties(Filer);
|
|
Filer.DefineProperty('BuiltInReportLink', ReadBuiltIn, WriteBuiltIn, True);
|
|
Filer.DefineProperty('IsDesignerCaptionAssigned', ReadIsDesignerCaptionAssigned, WriteIsDesignerCaptionAssigned,
|
|
FIsDesignerCaptionAssigned and (DesignerCaption = ''));
|
|
Filer.DefineProperty('LinkedComponentName',
|
|
ReadComponentName, WriteComponentName, InternalStreaming and (Component <> nil));
|
|
Filer.DefineProperty('StyleManagerName',
|
|
ReadStyleManagerName, WriteStyleManagerName, InternalStreaming and (StyleManager <> nil));
|
|
end;
|
|
|
|
procedure TBasedxReportLink.Notification(AComponent: TComponent; Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if Operation = opRemove then
|
|
begin
|
|
if AComponent = Component then Component := nil;
|
|
if AComponent = StyleManager then StyleManager := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadState(Reader: TReader);
|
|
begin
|
|
inherited ReadState(Reader);
|
|
if Reader.Parent is TCustomdxComponentPrinter then
|
|
ComponentPrinter := Reader.Parent as TCustomdxComponentPrinter;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetName(const NewName: TComponentName);
|
|
begin
|
|
inherited SetName(NewName);
|
|
if Caption = '' then Caption := NewName;
|
|
DesignerUpdate(False);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetParentComponent(AParent: TComponent);
|
|
begin
|
|
inherited;
|
|
if not IsLoading then
|
|
ComponentPrinter := AParent as TCustomdxComponentPrinter;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FontChanged(Sender: TObject);
|
|
begin
|
|
LinkModified(True);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.LinkModified(Value: Boolean);
|
|
var
|
|
Compositions: TList;
|
|
I: Integer;
|
|
begin
|
|
FRebuildNeeded := Value;
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
Compositions := TList.Create;
|
|
try
|
|
ComponentPrinter.GetCompositionsByLink(Self, Compositions);
|
|
for I := 0 to Compositions.Count - 1 do
|
|
TdxCompositionReportLink(Compositions[I]).LinkModified(Value);
|
|
finally
|
|
Compositions.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsFontStored: Boolean;
|
|
begin
|
|
Result := not dxPSUtl.dxAreFontsEqual(Font, DefaultFont);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetColor(Value: TColor);
|
|
begin
|
|
if FColor <> Value then
|
|
begin
|
|
FColor := Value;
|
|
LinkModified(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetContinuousPageIndexes(Value: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetFont(Value: TFont);
|
|
begin
|
|
Font.Assign(Value);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetTransparent(Value: Boolean);
|
|
begin
|
|
if FTransparent <> Value then
|
|
begin
|
|
FTransparent := Value;
|
|
LinkModified(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.AfterDesignReport(ADone: Boolean);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
ComponentPrinter.DoDesignReport(Self, ADone);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.BeforeDesignReport;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
ComponentPrinter.DoBeforeDesignReport(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.AfterPrinting;
|
|
begin
|
|
if CurrentPrintStyle <> nil then CurrentPrintStyle.AfterPrinting;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.BeforePrinting;
|
|
begin
|
|
if CurrentPrintStyle <> nil then CurrentPrintStyle.BeforePrinting;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetBreakPagesByHardDelimiters: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TBasedxReportLink.CalculateActualScaleFactor: Integer;
|
|
begin
|
|
with RealPrinterPage do
|
|
begin
|
|
// Get Result in internal units -> convert from LoMetric to Inches and then from Inches to internal units (units used inside PS)
|
|
Result := MulDiv(PaintRectLoMetric.Right - PaintRectLoMetric.Left, FUnitsPerInch, 254);
|
|
// Take into account ScaleFactor
|
|
Result := MulDiv(Result, 100, ReportWidth) - 1;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.CannotActivateReportErrorString: string;
|
|
begin
|
|
if DataSource = rldsComponent then
|
|
Result := cxGetResourceString(@sdxMissingComponent)
|
|
else
|
|
Result := cxGetResourceString(@sdxInvalidExternalStorage);
|
|
end;
|
|
|
|
function TBasedxReportLink.CurrentComposition: TdxCompositionReportLink;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
Result := ComponentPrinter.CurrentCompositionByLink(Self)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetRealPrinterPage(Value: TdxPrinterPage);
|
|
begin
|
|
RealPrinterPage.Assign(Value);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetAllowContinuousPageIndexes: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetAlwaysBufferedGraphics: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetContinuousPageIndexes: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetEmptyPagesCanExist: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetFootersOnEveryPage(Value: Boolean);
|
|
begin
|
|
if not IsAggregated then FFootersOnEveryPage := Value
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetHeadersOnEveryPage(Value: Boolean);
|
|
begin
|
|
if not IsAggregated then FHeadersOnEveryPage := Value
|
|
end;
|
|
|
|
function TBasedxReportLink.GetRealScaleFactor: Integer;
|
|
begin
|
|
with RealPrinterPage do
|
|
if ScaleMode = smAdjust then
|
|
Result := ScaleFactor
|
|
else
|
|
Result := CalculateActualScaleFactor;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetReportHeight: Integer;
|
|
begin
|
|
if ReportCells <> nil then
|
|
Result := ReportCells.CalculateTotalHeight
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetReportWidth: Integer;
|
|
begin
|
|
if ReportCells <> nil then
|
|
Result := ReportCells.CalculateTotalWidth
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DefineStylesClick(Sender: TObject);
|
|
begin
|
|
DefinePrintStylesDlg;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.StyleClick(Sender: TObject);
|
|
var
|
|
PreviewBtnClicked, PrintBtnClicked: Boolean;
|
|
PrevCurrentStyle, Style: TBasedxPrintStyle;
|
|
begin
|
|
if StyleManager = nil then Exit;
|
|
|
|
try
|
|
Style := dxPSPageSetupMenuBuilderFactory.ActiveBuilder.ExtractPrintStyleFromObj(Sender);
|
|
except
|
|
Style := nil;
|
|
Application.HandleException(Self);
|
|
end;
|
|
if Style = nil then Exit;
|
|
|
|
PrevCurrentStyle := StyleManager.CurrentStyle;
|
|
StyleManager.CurrentStyle := Style;
|
|
|
|
if (ComponentPrinter <> nil) and not ComponentPrinter.IsForegroundPreviewWindow then
|
|
begin
|
|
if not PageSetupEx(0, True, True, PreviewBtnClicked, PrintBtnClicked) then
|
|
StyleManager.CurrentStyle := PrevCurrentStyle;
|
|
|
|
if PrintBtnClicked then
|
|
Print(True, nil)
|
|
else
|
|
if PreviewBtnClicked then Preview(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetCurrentPage(Value: Integer);
|
|
begin
|
|
if Value < 1 then
|
|
Value := 1;
|
|
if Value > PageCount then
|
|
Value := PageCount;
|
|
FCurrentPage := Value;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoCustomDrawEntirePage(ACanvas: TCanvas; R: TRect;
|
|
ARealPageIndex: Integer);
|
|
var
|
|
Nom: Integer;
|
|
begin
|
|
with ComponentPrinter do
|
|
begin
|
|
Nom := 100;
|
|
if PreviewExists then
|
|
Nom := PreviewWindow.ZoomFactor;
|
|
DoCustomDrawEntirePage(Self, ACanvas, ARealPageIndex, R, Nom, 100);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoCustomDrawPageHeaderOrFooter(AHFObject: TCustomdxPageObject;
|
|
ACanvas: TCanvas; APageIndex: Integer; R: TRect;
|
|
var ADefaultDrawText, ADefaultDrawBackground: Boolean);
|
|
begin
|
|
DoParentCustomDrawPageHeaderOrFooter(AHFObject, ACanvas, APageIndex, R,
|
|
ADefaultDrawText, ADefaultDrawBackground, PixelsNumerator);
|
|
if ADefaultDrawText or ADefaultDrawBackground then
|
|
if AHFObject is TdxPageHeader then
|
|
begin
|
|
if Assigned(FOnCustomDrawPageHeader) then
|
|
FOnCustomDrawPageHeader(Self, ACanvas, APageIndex, R,
|
|
PixelsNumerator, PixelsDenominator, ADefaultDrawText, ADefaultDrawBackground)
|
|
end
|
|
else
|
|
if Assigned(FOnCustomDrawPageFooter) then
|
|
FOnCustomDrawPageFooter(Self, ACanvas, APageIndex, R,
|
|
PixelsNumerator, PixelsDenominator, ADefaultDrawText, ADefaultDrawBackground);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoCustomDrawPageTitle(ACanvas: TCanvas; R: TRect;
|
|
var ATextAlignX: TdxTextAlignX; var ATextAlignY: TdxTextAlignY;
|
|
var AColor: TColor; AFont: TFont; var ADone: Boolean);
|
|
begin
|
|
DoParentCustomDrawReportTitle(ACanvas, R, ATextAlignX, ATextAlignY,
|
|
AColor, AFont, ADone, PixelsNumerator);
|
|
if not ADone and Assigned(FOnCustomDrawReportLinkTitle) then
|
|
FOnCustomDrawReportLinkTitle(Self, ACanvas, R, PixelsNumerator,
|
|
PixelsDenominator, ATextAlignX, ATextAlignY, AColor, AFont, ADone);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoParentCustomDrawPageHeaderOrFooter(
|
|
AHFObject: TCustomdxPageObject; ACanvas: TCanvas; APageIndex: Integer;
|
|
R: TRect; var ADefaultDrawText, ADefaultDrawBackground: Boolean;
|
|
APixelsNumerator: Integer);
|
|
begin
|
|
ComponentPrinter.DoCustomDrawPageHeaderOrFooter(Self, AHFObject, ACanvas,
|
|
APageIndex, R, ADefaultDrawText, ADefaultDrawBackground, APixelsNumerator);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoParentCustomDrawReportTitle(ACanvas: TCanvas; R: TRect;
|
|
var ATextAlignX: TdxTextAlignX; var ATextAlignY: TdxTextAlignY;
|
|
var AColor: TColor; AFont: TFont; var ADone: Boolean; APixelsNumerator: Integer);
|
|
begin
|
|
ComponentPrinter.DoCustomDrawReportTitle(Self, ACanvas, R, ATextAlignX, ATextAlignY,
|
|
AColor, AFont, ADone, APixelsNumerator);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.PaintPage(ACanvas: TCanvas; const APageBounds: TRect;
|
|
APageIndex, AContinuousPageIndex, AZoomFactor: Integer); //; ARenderer: TdxPSReportRenderer);
|
|
begin
|
|
FPainting := True;
|
|
try
|
|
Renderer.RenderPage(ACanvas, APageBounds, APageIndex, AContinuousPageIndex, AZoomFactor);
|
|
finally
|
|
FPainting := False;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsEntirePageCustomDrawn: Boolean;
|
|
begin
|
|
Result := Assigned(ComponentPrinter.FOnCustomDrawPage);
|
|
end;
|
|
|
|
function TBasedxReportLink.IsHeaderOrFooterCustomDrawn(AHFObject: TCustomdxPageObject): Boolean;
|
|
begin
|
|
if AHFObject is TdxPageHeader then
|
|
Result := Assigned(ComponentPrinter.FOnCustomDrawPageHeader) or Assigned(FOnCustomDrawPageHeader)
|
|
else
|
|
Result := Assigned(ComponentPrinter.FOnCustomDrawPageFooter) or Assigned(FOnCustomDrawPageFooter);
|
|
end;
|
|
|
|
function TBasedxReportLink.IsTitleCustomDrawn: Boolean;
|
|
begin
|
|
Result :=
|
|
Assigned(ComponentPrinter.FOnCustomDrawReportTitle) or
|
|
Assigned(FOnCustomDrawReportLinkTitle);
|
|
end;
|
|
|
|
function TBasedxReportLink.IsComposable(AComposition: TdxCompositionReportLink): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsSupportedStyle(APrintStyle: TBasedxPrintStyle): Boolean;
|
|
begin
|
|
Result := True;
|
|
if Assigned(FOnFilterStyle) then
|
|
begin
|
|
FOnFilterStyle(Self, APrintStyle, Result);
|
|
if not Result and (APrintStyle = CurrentPrintStyle) then
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.NeedTwoPassRendering: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DesignerModified;
|
|
begin
|
|
if ComponentPrinter <> nil then ComponentPrinter.DesignerModified;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DesignerUpdate(TheAll: Boolean);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
if TheAll then
|
|
ComponentPrinter.DesignerUpdate(nil)
|
|
else
|
|
ComponentPrinter.DesignerUpdate(Self);
|
|
end;
|
|
|
|
function TBasedxReportLink.IsDesigning: Boolean;
|
|
begin
|
|
Result := csDesigning in ComponentState;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsDestroying: Boolean;
|
|
begin
|
|
Result := csDestroying in ComponentState;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsLoading: Boolean;
|
|
begin
|
|
Result := csLoading in ComponentState;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoMeasureReportLinkTitle(var AHeight: Integer);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
ComponentPrinter.DoMeasureReportTitle(Self, AHeight);
|
|
if Assigned(FOnMeasureReportLinkTitle) then
|
|
FOnMeasureReportLinkTitle(Self, AHeight);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetCriticalSize(AReportCells: TdxReportCells): Integer;
|
|
begin
|
|
with AReportCells.BoundsRect do
|
|
Result := Right - Left;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.GetImageLists(AProc: TdxPSGetImageListProc);
|
|
begin
|
|
end;
|
|
|
|
function TBasedxReportLink.NeedCalcEmptyPages: Boolean;
|
|
begin
|
|
Result := EmptyPagesCanExist and not ShrinkToPageWidth;
|
|
end;
|
|
|
|
function TBasedxReportLink.PageReady(APageIndex: Integer): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.PrepareFonts(UPI: Integer);
|
|
begin
|
|
if FFontPool <> nil then FontPool.PrepareFonts(UPI);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.PrepareLongOperation;
|
|
begin
|
|
if ComponentPrinter <> nil then ComponentPrinter.PrepareLongOperation;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.UnprepareLongOperation;
|
|
begin
|
|
if ComponentPrinter <> nil then ComponentPrinter.UnprepareLongOperation;
|
|
end;
|
|
|
|
function TBasedxReportLink.CreateReportDocument: TdxPSReportDocument;
|
|
begin
|
|
Result := GetReportDocumentClass.Create(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DocumentChanged(Sender: TObject);
|
|
begin
|
|
if IsCurrentLink then
|
|
dxHFFormatObject.DateTime := DateTime;
|
|
end;
|
|
|
|
class function TBasedxReportLink.GetReportDocumentClass: TdxPSReportDocumentClass;
|
|
begin
|
|
Result := TdxPSReportDocument;
|
|
end;
|
|
|
|
function TBasedxReportLink.CreateReportCells: TdxReportCells;
|
|
begin
|
|
Result := GetReportCellsClass.Create(Self);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetReportCellsClass: TdxReportCellsClass;
|
|
begin
|
|
Result := TdxReportCells;
|
|
end;
|
|
|
|
class function TBasedxReportLink.CreateDataReader(AStream: TStream): TdxPSDataReader;
|
|
begin
|
|
Result := TdxPSDataReader.Create(AStream, 4096);
|
|
end;
|
|
|
|
class function TBasedxReportLink.CreateDataWriter(AStream: TStream): TdxPSDataWriter;
|
|
begin
|
|
Result := TdxPSDataWriter.Create(AStream, 4096);
|
|
end;
|
|
|
|
class function TBasedxReportLink.GetDataReaderClass: TdxPSDataReaderClass;
|
|
begin
|
|
Result := dxPSReaderFactory.ActualReaderClass;
|
|
end;
|
|
|
|
class function TBasedxReportLink.GetDataWriterClass: TdxPSDataWriterClass;
|
|
begin
|
|
Result := dxPSWriterFactory.ActualWriterClass;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.InternalLoadDataFromStream(AStream: TStream);
|
|
var
|
|
Reader: TdxPSDataReader;
|
|
begin
|
|
Include(FState, rlsDataLoading);
|
|
try
|
|
Reader := CreateDataReader(AStream);
|
|
try
|
|
try
|
|
InternalReadData(Reader);
|
|
except
|
|
ClearGDIPools;
|
|
AddFontToPool(Font);
|
|
ReportTitle.Assign(FSavedReportTitle);
|
|
ReportDocument.Assign(FSavedReportDocument);
|
|
raise;
|
|
end;
|
|
finally
|
|
Reader.Free;
|
|
end;
|
|
finally
|
|
Exclude(FState, rlsDataLoading);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.InternalReadData(AReader: TdxPSDataReader);
|
|
var
|
|
OffsetTable: TdxPSDataStorageOffsetTable;
|
|
begin
|
|
OffsetTable := ReadOffsetTable(AReader);
|
|
try
|
|
AReader.Position := OffsetTable.Information;
|
|
SkipStorageInfo(AReader);
|
|
|
|
AReader.Position := OffsetTable.Document;
|
|
ReadReportDocument(AReader, ReportDocument);
|
|
|
|
AReader.Position := OffsetTable.Title;
|
|
ReadTitle(AReader);
|
|
|
|
AReader.Position := OffsetTable.Data;
|
|
ReadData(AReader);
|
|
finally
|
|
OffsetTable.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.InternalWriteData(AWriter: TdxPSDataWriter);
|
|
var
|
|
OffsetTable: TdxPSDataStorageOffsetTable;
|
|
P: Longint;
|
|
begin
|
|
WriteOffsetTable(AWriter, nil);
|
|
|
|
OffsetTable := TdxPSDataStorageOffsetTable.Create(nil);
|
|
try
|
|
OffsetTable.Information := AWriter.Position;
|
|
WriteStorageInfo(AWriter, RetrieveStorageInfo);
|
|
|
|
OffsetTable.Document := AWriter.Position;
|
|
WriteReportDocument(AWriter, ReportDocument);
|
|
|
|
OffsetTable.Title := AWriter.Position;
|
|
WriteTitle(AWriter);
|
|
|
|
OffsetTable.Data := AWriter.Position;
|
|
WriteData(AWriter);
|
|
|
|
P := AWriter.Position;
|
|
AWriter.Position := 0;
|
|
|
|
WriteOffsetTable(AWriter, OffsetTable);
|
|
finally
|
|
OffsetTable.Free;
|
|
end;
|
|
AWriter.Position := P;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsRebuildNeededAndAllowed(ACheckPreviewMode: Boolean): Boolean;
|
|
begin
|
|
Result := IsCurrentLink and DataProviderPresent and not IsAggregated and
|
|
(not ACheckPreviewMode or PreviewExists);
|
|
end;
|
|
|
|
function TBasedxReportLink.RetrieveStorageInfo: TdxPSDataStorageInfo;
|
|
begin
|
|
Result := TdxPSDataStorageInfo.Create(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadData(AReader: TdxPSDataReader);
|
|
begin
|
|
ReadReportData(AReader);
|
|
ReadRenderInfo(AReader);
|
|
ReadBackgroundBitmapPool(AReader);
|
|
ReadFontPool(AReader);
|
|
end;
|
|
|
|
class function TBasedxReportLink.ReadOffsetTable(AReader: TdxPSDataReader): TdxPSDataStorageOffsetTable;
|
|
begin
|
|
Result := TdxPSDataStorageOffsetTable.Create(nil);
|
|
Result.ReadData(AReader);
|
|
end;
|
|
|
|
class procedure TBasedxReportLink.ReadReportDocument(AReader: TdxPSDataReader;
|
|
AReportDocument: TdxPSReportDocument);
|
|
begin
|
|
AReportDocument.ReadData(AReader);
|
|
end;
|
|
|
|
class function TBasedxReportLink.ReadStorageInfo(AReader: TdxPSDataReader): TdxPSDataStorageInfo;
|
|
begin
|
|
Result := TdxPSDataStorageInfo.Create(nil);
|
|
Result.ReadData(AReader);
|
|
end;
|
|
|
|
class procedure TBasedxReportLink.SkipStorageInfo(AReader: TdxPSDataReader);
|
|
var
|
|
StorageInfo: TdxPSDataStorageInfo;
|
|
begin
|
|
StorageInfo := nil;
|
|
try
|
|
StorageInfo := ReadStorageInfo(AReader);
|
|
except
|
|
FreeAndNil(StorageInfo);
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadTitle(AReader: TdxPSDataReader);
|
|
begin
|
|
ReportTitle.ReadData(AReader);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
WriteReportData(AWriter);
|
|
WriteRenderInfo(AWriter);
|
|
WriteBackgroundBitmapPool(AWriter);
|
|
WriteFontPool(AWriter);
|
|
end;
|
|
|
|
class procedure TBasedxReportLink.WriteOffsetTable(AWriter: TdxPSDataWriter;
|
|
AnOffsetTable: TdxPSDataStorageOffsetTable);
|
|
var
|
|
OffsetTable: TdxPSDataStorageOffsetTable;
|
|
begin
|
|
OffsetTable := TdxPSDataStorageOffsetTable.Create(AnOffsetTable);
|
|
try
|
|
OffsetTable.WriteData(AWriter);
|
|
finally
|
|
OffsetTable.Free;
|
|
end;
|
|
end;
|
|
|
|
class procedure TBasedxReportLink.WriteStorageInfo(AWriter: TdxPSDataWriter;
|
|
AStorageInfo: TdxPSDataStorageInfo);
|
|
begin
|
|
AStorageInfo.WriteData(AWriter);
|
|
end;
|
|
|
|
class procedure TBasedxReportLink.WriteReportDocument(AWriter: TdxPSDataWriter;
|
|
AReportDocument: TdxPSReportDocument);
|
|
begin
|
|
AReportDocument.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteTitle(AWriter: TdxPSDataWriter);
|
|
begin
|
|
ReportTitle.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadBackgroundBitmapPool(AReader: TdxPSDataReader);
|
|
begin
|
|
BackgroundBitmapPool.ReadData(AReader);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadReportData(AReader: TdxPSDataReader);
|
|
begin
|
|
if FReportCells = nil then FReportCells := TdxReportCells.Create(Self);
|
|
ReportCells.ReadData(AReader);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadFontPool(AReader: TdxPSDataReader);
|
|
begin
|
|
FontPool.ReadData(AReader);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadRenderInfo(AReader: TdxPSDataReader);
|
|
begin
|
|
RenderInfo.ReadData(AReader);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteBackgroundBitmapPool(AWriter: TdxPSDataWriter);
|
|
begin
|
|
BackgroundBitmapPool.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteFontPool(AWriter: TdxPSDataWriter);
|
|
begin
|
|
FontPool.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteReportData(AWriter: TdxPSDataWriter);
|
|
begin
|
|
ReportCells.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteRenderInfo(AWriter: TdxPSDataWriter);
|
|
begin
|
|
RenderInfo.WriteData(AWriter);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetActive(Value: Boolean);
|
|
begin
|
|
if (csReading in ComponentState) and Value then
|
|
FStreamedActive := Value
|
|
else
|
|
if (FActive <> Value) and (ComponentPrinter <> nil) then
|
|
if Value then
|
|
ComponentPrinter.ActivateLink(Self)
|
|
else
|
|
ComponentPrinter.DeactivateLink(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetComponent(Value: TComponent);
|
|
begin
|
|
if not (csReading in ComponentState) then
|
|
begin
|
|
if FComponent <> Value then
|
|
begin
|
|
if PreviewExists then
|
|
ComponentPrinter.DestroyPreviewWindow;
|
|
|
|
if Value = nil then
|
|
begin
|
|
Active := False;
|
|
FComponent := nil;
|
|
end
|
|
else
|
|
if IsSupportedCompClass(TComponentClass(Value.ClassType)) then
|
|
SetComponentUnconditionally(Value)
|
|
else
|
|
ComponentUnsupportedError(Value);
|
|
|
|
if not IsDestroying and not IsLoading then
|
|
begin
|
|
DoChangeComponent;
|
|
if ComponentPrinter <> nil then ComponentPrinter.DoChangeComponent(Self);
|
|
DesignerUpdate(False);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
FComponent := Value;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetShowPageFooter(Value: Boolean);
|
|
begin
|
|
if FShowPageFooter <> Value then
|
|
begin
|
|
FShowPageFooter := Value;
|
|
ShowPageFooterChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetShowPageHeader(Value: Boolean);
|
|
begin
|
|
if FShowPageHeader <> Value then
|
|
begin
|
|
FShowPageHeader := Value;
|
|
ShowPageHeaderChanged;
|
|
end;
|
|
end;
|
|
|
|
{procedure TBasedxReportLink.SetShrinkToPageHeight(Value: Boolean);
|
|
begin
|
|
|
|
end;}
|
|
|
|
procedure TBasedxReportLink.SetShrinkToPageWidth(Value: Boolean);
|
|
const
|
|
ScaleModeMap: array[Boolean] of TdxScaleMode = (smAdjust, smFit);
|
|
begin
|
|
if ShrinkToPageWidth <> Value then
|
|
begin
|
|
PrepareLongOperation;
|
|
try
|
|
with RealPrinterPage do
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
if Value then
|
|
begin
|
|
FitToPagesByTall := 1;
|
|
FitToPagesByWide := 1;
|
|
end;
|
|
ScaleMode := ScaleModeMap[Value];
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
finally
|
|
UnprepareLongOperation;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetShowEmptyPages(Value: Boolean);
|
|
begin
|
|
if FShowEmptyPages <> Value then
|
|
begin
|
|
FShowEmptyPages := Value;
|
|
ShowEmptyPagesChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetDateTime(const Value: TDateTime);
|
|
begin
|
|
ReportDocument.CreationDate := Value;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetDesignerCaption(const Value: string);
|
|
begin
|
|
if DesignerCaption <> Value then
|
|
begin
|
|
FDesignerCaption := Value;
|
|
FIsDesignerCaptionAssigned := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetDescription(const Value: string);
|
|
begin
|
|
ReportDocument.Description := Value;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetDateFormat: Integer;
|
|
begin
|
|
if not (fvDate in AssignedFormatValues) and (ComponentPrinter <> nil) then
|
|
Result := ComponentPrinter.DateFormat
|
|
else
|
|
Result := FDateFormat;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetDateTime: TDateTime;
|
|
begin
|
|
Result := ReportDocument.CreationDate;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetDescription: string;
|
|
begin
|
|
Result := ReportDocument.Description;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetDesignerCaption: string;
|
|
begin
|
|
if FIsDesignerCaptionAssigned then
|
|
Result := FDesignerCaption
|
|
else
|
|
Result := DefaultDesignerCaption;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetIndex: Integer;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
Result := ComponentPrinter.IndexOfLink(Self)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetIsAggregated: Boolean;
|
|
begin
|
|
Result := Controller <> nil;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetIsBuilding: Boolean;
|
|
begin
|
|
Result := (ComponentPrinter <> nil) and (cpsBuilding in ComponentPrinter.State);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetIsCurrentLink: Boolean;
|
|
begin
|
|
Result := (ComponentPrinter <> nil) and (ComponentPrinter.CurrentLink = Self);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetPageHeight: Integer;
|
|
begin
|
|
with RealPrinterPage.PaintRectPixels do
|
|
Result := Bottom - Top - 1;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetPageNumberFormat: TdxPageNumberFormat;
|
|
begin
|
|
if not (fvPageNumber in AssignedFormatValues) and (ComponentPrinter <> nil) then
|
|
Result := ComponentPrinter.PageNumberFormat
|
|
else
|
|
Result := FPageNumberFormat;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetPageWidth: Integer;
|
|
begin
|
|
with RealPrinterPage.PaintRectPixels do
|
|
Result := Right - Left - 1;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetPreviewWindow: TBasedxPreviewWindow;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
Result := ComponentPrinter.PreviewWindow
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetRealPrinterPage: TdxPrinterPage;
|
|
var
|
|
Style: TBasedxPrintStyle;
|
|
Composition: TdxCompositionReportLink;
|
|
begin
|
|
Result := nil;
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
Composition := ComponentPrinter.CurrentCompositionByLink(Self);
|
|
if Composition <> nil then Result := Composition.RealPrinterPage;
|
|
end;
|
|
if Result = nil then
|
|
begin
|
|
Style := CurrentPrintStyle;
|
|
if Style <> nil then
|
|
Result := Style.PrinterPage
|
|
else
|
|
Result := FPrinterPage;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetReportTitleMode: TdxReportTitleMode;
|
|
begin
|
|
Result := ReportTitle.Mode;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetReportTitleText: string;
|
|
begin
|
|
Result := ReportTitle.Text;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetRenderer: TdxPSReportRenderer;
|
|
begin
|
|
if FRenderer = nil then FRenderer := CreateRenderer;
|
|
Result := FRenderer;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetRenderInfo: TdxPSReportRenderInfo;
|
|
begin
|
|
if FRenderInfo = nil then FRenderInfo := CreateRenderInfo;
|
|
Result := FRenderInfo;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetRenderStage: TdxPSRenderStages;
|
|
begin
|
|
if FPainting and (FRenderer <> nil) then
|
|
Result := Renderer.RenderStage
|
|
else
|
|
Result := [];
|
|
end;
|
|
|
|
function TBasedxReportLink.GetShowEmptyPages: Boolean;
|
|
var
|
|
Composition: TdxCompositionReportLink;
|
|
begin
|
|
Result := FShowEmptyPages;
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
Composition := ComponentPrinter.CurrentCompositionByLink(Self);
|
|
if Composition <> nil then Result := Composition.ShowEmptyPages;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetShowPageFooter: Boolean;
|
|
var
|
|
Composition: TdxCompositionReportLink;
|
|
begin
|
|
Result := FShowPageFooter;
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
Composition := ComponentPrinter.CurrentCompositionByLink(Self);
|
|
if Composition <> nil then Result := Composition.ShowPageFooter;
|
|
end;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetShowPageHeader: Boolean;
|
|
var
|
|
Composition: TdxCompositionReportLink;
|
|
begin
|
|
Result := FShowPageHeader;
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
Composition := ComponentPrinter.CurrentCompositionByLink(Self);
|
|
if Composition <> nil then Result := Composition.ShowPageHeader;
|
|
end;
|
|
end;
|
|
|
|
{function TBasedxReportLink.GetShrinkToPageHeight: Boolean;
|
|
begin
|
|
with RealPrinterPage do
|
|
Result := (ScaleMode = smFit) and (FitToPagesByTall = 1);
|
|
end;}
|
|
|
|
function TBasedxReportLink.GetShrinkToPageWidth: Boolean;
|
|
begin
|
|
with RealPrinterPage do
|
|
Result := (ScaleMode = smFit);// and (FitToPagesByWide = 1);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetStartPageIndex: Integer;
|
|
begin
|
|
Result := FStartPageIndex;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetTimeFormat: Integer;
|
|
begin
|
|
if not (fvTime in AssignedFormatValues) and (ComponentPrinter <> nil) then
|
|
Result := ComponentPrinter.TimeFormat
|
|
else
|
|
Result := FTimeFormat;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetVirtualPageCount: Integer;
|
|
begin
|
|
Result := RenderInfo.VirtualPageCount;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsDateFormatStored: Boolean;
|
|
begin
|
|
Result := fvDate in AssignedFormatValues;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsDesignerCaptionStored: Boolean;
|
|
begin
|
|
Result := FIsDesignerCaptionAssigned and (DesignerCaption <> DefaultDesignerCaption);
|
|
end;
|
|
|
|
function TBasedxReportLink.IsTimeFormatStored: Boolean;
|
|
begin
|
|
Result := fvTime in AssignedFormatValues;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsPageNumberFormatStored: Boolean;
|
|
begin
|
|
Result := fvPageNumber in AssignedFormatValues;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetDateFormat(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if Value > dxPgsDlg.DateFormats.Count - 1 then
|
|
Value := dxPgsDlg.DateFormats.Count - 1;
|
|
//if FDateFormat <> Value then
|
|
begin
|
|
FDateFormat := Value;
|
|
AssignFormats(fvDate, FDateFormat <> DefaultDateFormat);
|
|
if IsCurrentLink then
|
|
dxHFFormatObject.DateFormat := dxPgsDlg.DateFormats[FDateFormat];
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetTimeFormat(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if Value > dxPgsDlg.TimeFormats.Count - 1 then
|
|
Value := dxPgsDlg.TimeFormats.Count - 1;
|
|
//if FTimeFormat <> Value then
|
|
begin
|
|
FTimeFormat := Value;
|
|
AssignFormats(fvTime, FTimeFormat <> DefaultTimeFormat);
|
|
if IsCurrentLink then
|
|
dxHFFormatObject.TimeFormat := dxPgsDlg.TimeFormats[FTimeFormat];
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetPageNumberFormat(Value: TdxPageNumberFormat);
|
|
begin
|
|
//if FPageNumberFormat <> Value then
|
|
begin
|
|
FPageNumberFormat := Value;
|
|
AssignFormats(fvPageNumber, FPageNumberFormat <> DefaultPageNumberFormat);
|
|
if IsCurrentLink then
|
|
dxHFFormatObject.PageNumberFormat := FPageNumberFormat;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetAbortBuilding(Value: Boolean);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
ComponentPrinter.AbortBuilding := Value;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetAssignedFormatValues(Value: TdxAssignedFormatValues);
|
|
begin
|
|
if DateFormat = DefaultDateFormat then
|
|
Exclude(Value, fvDate);
|
|
if TimeFormat = DefaultTimeFormat then
|
|
Exclude(Value, fvTime);
|
|
if PageNumberFormat = DefaultPageNumberFormat then
|
|
Exclude(Value, fvPageNumber);
|
|
if FAssignedFormatValues <> Value then
|
|
begin
|
|
FAssignedFormatValues := Value;
|
|
DesignerModified;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetCaption(const Value: string);
|
|
begin
|
|
ReportDocument.Caption := Value;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetAbortBuilding: Boolean;
|
|
begin
|
|
Result := (ComponentPrinter <> nil) and ComponentPrinter.AbortBuilding;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetCaption: string;
|
|
begin
|
|
Result := ReportDocument.Caption;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetCurrentPrintStyle: TBasedxPrintStyle;
|
|
begin
|
|
if StyleManager <> nil then
|
|
Result := StyleManager.CurrentStyle
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetFontPool: TdxPSReportFontPool;
|
|
begin
|
|
if not IsAggregated then
|
|
begin
|
|
if FFontPool = nil then FFontPool := TdxPSReportFontPool.Create;
|
|
Result := FFontPool;
|
|
end
|
|
else
|
|
Result := Controller.FontPool;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetHasDesignWindow: Boolean;
|
|
begin
|
|
Result := DesignWindow <> nil;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetHasPreviewWindow: Boolean;
|
|
begin
|
|
Result := (ComponentPrinter <> nil) and (ComponentPrinter.PreviewWindow <> nil);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.RetrievePageAsImage(APageIndex: Integer; AGraphicClass: TGraphicClass;
|
|
AGraphic: TGraphic);
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
TdxComponentPrinter(ComponentPrinter).EnumPagesAsImages([APageIndex],
|
|
AGraphicClass, False, RetrievePageAsImageCallBack, AGraphic, nil, nil, Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.RetrievePageAsImageCallBack(AComponentPrinter: TCustomdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; AIndex, APageIndex: Integer; const AGraphic: TGraphic;
|
|
AData: Pointer; var AContinue: Boolean);
|
|
begin
|
|
TGraphic(AData).Assign(AGraphic);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ShowEmptyPagesChanged;
|
|
begin
|
|
if EmptyPagesCanExist and (CurrentComposition = nil) then
|
|
CalculateRenderInfos;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ShowPageFooterChanged;
|
|
begin
|
|
if CurrentComposition = nil then CalculateRenderInfos;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ShowPageHeaderChanged;
|
|
begin
|
|
if CurrentComposition = nil then CalculateRenderInfos;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.StdProcessDataSourceDontPresent;
|
|
begin
|
|
raise EdxReportLink.Create(CannotActivateReportErrorString);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.TunePixelsNumerator(AReportCells: TdxReportCells);
|
|
const
|
|
MaxReportWidth = $7FFF;
|
|
MinFactor = 2;
|
|
var
|
|
Wo, W: Integer;
|
|
begin
|
|
Wo := GetCriticalSize(AReportCells);
|
|
W := MulDiv(Wo, RenderInfo.UnitsPerInch, PixelsDenominator);
|
|
if W > MaxReportWidth then
|
|
with RenderInfo do
|
|
begin
|
|
UnitsPerInch := MulDiv(PixelsDenominator, MaxReportWidth, Wo);
|
|
UnitsPerInch := UnitsPerInch - UnitsPerInch mod Screen.PixelsPerInch;
|
|
if UnitsPerInch < MinFactor * Screen.PixelsPerInch then
|
|
UnitsPerInch := MinFactor * Screen.PixelsPerInch;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.CalculateRenderInfos;
|
|
begin
|
|
if DataProviderPresent then
|
|
begin
|
|
PrepareLongOperation;
|
|
try
|
|
RenderInfo.Calculate;
|
|
finally
|
|
UnprepareLongOperation;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ClearGDIPools;
|
|
begin
|
|
BackgroundBitmapPool.Clear;
|
|
Renderer.BrushPool.Clear;
|
|
if (FFontPool <> nil) and not IsAggregated then
|
|
FontPool.Clear;
|
|
end;
|
|
|
|
function TBasedxReportLink.CreateRenderInfo: TdxPSReportRenderInfo;
|
|
begin
|
|
Result := GetRenderInfoClass.Create(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FreeRenderInfos;
|
|
begin
|
|
FreeAndNil(FRenderInfo);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetRenderInfoClass: TdxPSReportRenderInfoClass;
|
|
begin
|
|
Result := TdxPSReportRenderInfo;
|
|
end;
|
|
|
|
function TBasedxReportLink.CreateRenderer: TdxPSReportRenderer;
|
|
begin
|
|
Result := GetRendererClass.Create(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FreeRenderer;
|
|
begin
|
|
FreeAndNil(FRenderer);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetRendererClass: TdxPSReportRendererClass;
|
|
begin
|
|
Result := TdxPSReportRenderer;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.InitializeDefaultFont(AFont: TFont);
|
|
begin
|
|
AFont.CharSet := dxPSDefaultFontCharSet;
|
|
AFont.Color := dxPSDefaultFontColor;
|
|
AFont.Name := dxPSDefaultFontName;
|
|
AFont.Size := dxPSDefaultFontSize;
|
|
AFont.Style := dxPSDefaultFontStyle;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.InternalGetDelimiters(ADelimitersHorz, ADelimitersVert: TList);
|
|
begin
|
|
dxPSUtl.dxAppendList(RenderInfo.DelimiterXList, ADelimitersHorz);
|
|
dxPSUtl.dxAppendList(RenderInfo.DelimiterYList, ADelimitersVert);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetPageCount: Integer;
|
|
begin
|
|
Result := RenderInfo.NonEmptyPageCount;
|
|
if IsCurrentLink then
|
|
dxHFFormatObject.TotalPages := Result;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetUseHardVertDelimiters: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetVisiblePageCount: Integer;
|
|
begin
|
|
if ShowEmptyPages then
|
|
Result := VirtualPageCount
|
|
else
|
|
Result := PageCount;
|
|
end;
|
|
|
|
function TBasedxReportLink.GetRebuildOnPageParamsChange(AUpdateCodes: TdxPrinterPageUpdateCodes): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetStorageName(const Value: string);
|
|
begin
|
|
if FStorageName <> Value then
|
|
begin
|
|
FStorageName := Value;
|
|
if FileExists(FStorageName) and (DataSource = rldsExternalStorage) then
|
|
LoadDataFromFile(FStorageName);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetStyleManager(Value: TdxPrintStyleManager);
|
|
begin
|
|
if FStyleManager <> Value then
|
|
begin
|
|
FStyleManager := Value;
|
|
if Value <> nil then
|
|
Value.FreeNotification(Self);
|
|
if not IsDestroying then
|
|
PageParamsChanged(RealPrinterPage, CurrentPrintStyle, ucAll);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetPrinterPage(Value: TdxPrinterPage);
|
|
begin
|
|
PrinterPage.Assign(Value);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetReportDocument(Value: TdxPSReportDocument);
|
|
begin
|
|
ReportDocument.Assign(Value);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetReportTitleMode(Value: TdxReportTitleMode);
|
|
begin
|
|
ReportTitle.Mode := Value;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetReportTitleText(const Value: string);
|
|
begin
|
|
ReportTitle.Text := Value;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetReportTitle(Value: TdxReportTitle);
|
|
begin
|
|
ReportTitle.Assign(Value);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetComponentPrinter(Value: TCustomdxComponentPrinter);
|
|
begin
|
|
if FComponentPrinter <> Value then
|
|
begin
|
|
if FComponentPrinter <> nil then FComponentPrinter.RemoveLink(Self);
|
|
if Value <> nil then Value.InsertLink(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetIsCurrentLink(Value: Boolean);
|
|
begin
|
|
if Value then
|
|
if not (csReading in ComponentState) and (ComponentPrinter <> nil) then
|
|
ComponentPrinter.CurrentLink := Self;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetDataSource(Value: TdxReportLinkDataSource);
|
|
begin
|
|
if FDataSource <> Value then
|
|
begin
|
|
FDataSource := Value;
|
|
DoDataSourceChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetIndex(Value: Integer);
|
|
var
|
|
CurIndex: Integer;
|
|
begin
|
|
if ComponentPrinter = nil then Exit;
|
|
if Value < 0 then Value := 0;
|
|
if Value > ComponentPrinter.LinkCount - 1 then
|
|
Value := ComponentPrinter.LinkCount - 1;
|
|
CurIndex := GetIndex;
|
|
if CurIndex <> Value then
|
|
ComponentPrinter.MoveLink(CurIndex, Value);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadBuiltIn(Reader: TReader);
|
|
begin
|
|
FBuiltIn := Reader.ReadBoolean;
|
|
end;
|
|
|
|
function GetFullName(AComponent: TComponent): string;
|
|
begin
|
|
if AComponent = nil then
|
|
Result := ''
|
|
else
|
|
begin
|
|
Result := AComponent.Name;
|
|
while (AComponent.Name <> '') and (AComponent.Owner <> nil) do
|
|
begin
|
|
AComponent := AComponent.Owner;
|
|
if AComponent.Name <> '' then
|
|
Result := AComponent.Name + '.' + Result;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function GetComponentByName(const AName: string): TComponent;
|
|
|
|
procedure CheckOwner(AOwner: TComponent);
|
|
var
|
|
I: Integer;
|
|
AComponent: TComponent;
|
|
begin
|
|
if Result <> nil then Exit;
|
|
for I := 0 to AOwner.ComponentCount - 1 do
|
|
begin
|
|
AComponent := AOwner.Components[I];
|
|
if SameText(GetFullName(AComponent), AName) then
|
|
begin
|
|
Result := AComponent;
|
|
break;
|
|
end
|
|
else
|
|
CheckOwner(AComponent);
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AOwner: TComponent;
|
|
begin
|
|
Result := nil;
|
|
AOwner := Application;
|
|
while AOwner.Owner <> nil do
|
|
AOwner := AOwner.Owner;
|
|
CheckOwner(AOwner);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadComponentName(AReader: TReader);
|
|
begin
|
|
Component := GetComponentByName(AReader.ReadString);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadIsDesignerCaptionAssigned(Reader: TReader);
|
|
begin
|
|
FIsDesignerCaptionAssigned := Reader.ReadBoolean;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ReadStyleManagerName(AReader: TReader);
|
|
begin
|
|
StyleManager := GetComponentByName(AReader.ReadString) as TdxPrintStyleManager;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteBuiltIn(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(FBuiltIn);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteComponentName(AWriter: TWriter);
|
|
begin
|
|
AWriter.WriteString(GetFullName(Component));
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteIsDesignerCaptionAssigned(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(FIsDesignerCaptionAssigned);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.WriteStyleManagerName(AWriter: TWriter);
|
|
begin
|
|
AWriter.WriteString(GetFullName(StyleManager));
|
|
end;
|
|
|
|
procedure TBasedxReportLink.InternalActivate;
|
|
begin
|
|
if DataProviderPresent then
|
|
try
|
|
AbortBuilding := False;
|
|
try
|
|
DoCreateReport;
|
|
finally
|
|
FRebuildNeeded := False;
|
|
FActive := True;
|
|
if AbortBuilding then
|
|
begin
|
|
FRebuildNeeded := True;
|
|
DoDestroyReport;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
DoDestroyReport;
|
|
if IsDesigning then
|
|
ShowException(E, ExceptAddr)
|
|
else
|
|
raise;
|
|
end;
|
|
end
|
|
else
|
|
DoDataProviderDontPresent;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.InternalRestoreDefaults;
|
|
begin
|
|
Transparent := True;
|
|
Color := dxDefaultContentColor; {clWhite}
|
|
Font := DefaultFont;
|
|
FootersOnEveryPage := False;
|
|
HeadersOnEveryPage := False;
|
|
|
|
PageNumberFormat := DefaultPageNumberFormat;
|
|
DateFormat := DefaultDateFormat;
|
|
TimeFormat := DefaultTimeFormat;
|
|
|
|
FIsDesignerCaptionAssigned := False;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.InternalRestoreFromOriginal;
|
|
begin
|
|
if Component is TControl then
|
|
begin
|
|
Color := dxPSUtl.Control_GetColor(TControl(Component));
|
|
Font := dxPSUtl.Control_GetFont(TControl(Component));
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetUseHorzDelimiters(Value: Boolean);
|
|
begin
|
|
if FUseHorzDelimiters <> Value then
|
|
begin
|
|
FUseHorzDelimiters := Value;
|
|
LinkModified(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetUseVertDelimiters(Value: Boolean);
|
|
begin
|
|
if FUseVertDelimiters <> Value then
|
|
begin
|
|
FUseVertDelimiters := Value;
|
|
LinkModified(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.AssignFormats(AnItem: TdxAssignedFormatValue; AValue: Boolean);
|
|
begin
|
|
if AValue then
|
|
Include(FAssignedFormatValues, AnItem)
|
|
else
|
|
Exclude(FAssignedFormatValues, AnItem);
|
|
end;
|
|
|
|
function TBasedxReportLink.ValidateMargins: Boolean;
|
|
begin
|
|
Result := RealPrinterPage.ValidateMargins;
|
|
if not Result then
|
|
begin
|
|
Result := MessageQuestion(cxGetResourceString(@sdxOutsideMarginsMessage));
|
|
if Result then
|
|
RealPrinterPage.FixMarginsOutSide;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.SetStartPageIndex(Value: Integer);
|
|
begin
|
|
if Value < 1 then Value := 1;
|
|
if FStartPageIndex <> Value then
|
|
begin
|
|
FStartPageIndex := Value;
|
|
dxHFFormatObject.StartPageIndex := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoDestroy;
|
|
begin
|
|
if Assigned(FOnDestroy) then FOnDestroy(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ComponentUnsupportedError(AComponent: TComponent);
|
|
begin
|
|
if not IsDesigning then
|
|
raise EdxReportLink.CreateFmt(cxGetResourceString(@sdxComponentNotSupportedByLink), [AComponent.ClassName]);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoChangeComponent;
|
|
begin
|
|
if Assigned(FOnChangeComponent) then FOnChangeComponent(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoProgress(const APercentDone: Double);
|
|
begin
|
|
if (ComponentPrinter <> nil) and not IsAggregated then
|
|
ComponentPrinter.DoProgress(Self, APercentDone);
|
|
end;
|
|
|
|
function TBasedxReportLink.GetDesignerClass: TdxReportLinkDesignWindowClass;
|
|
begin
|
|
if Component <> nil then
|
|
Result := dxPSDesignerClassByCompClass(TComponentClass(Component.ClassType))
|
|
else
|
|
Result := dxPSDesignerClassByLinkClass(LinkClass);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoApplyInDesigner;
|
|
begin
|
|
RebuildReport;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoCreateReport;
|
|
begin
|
|
if FReportCells = nil then
|
|
FReportCells := CreateReportCells;
|
|
DoCreateReportData;
|
|
|
|
if not AbortBuilding and not IsInvalidReport then
|
|
if not IsAggregated then
|
|
begin
|
|
if IsWin95Or98 then
|
|
TunePixelsNumerator(FReportCells);
|
|
FPixelsNumerator := RenderInfo.UnitsPerInch;
|
|
if DataSource = rldsComponent then
|
|
begin
|
|
PrepareReportGroupsLookAndFeels;
|
|
ConvertCoords;
|
|
RenderInfo.GetDelimiters;
|
|
end;
|
|
CalculateRenderInfos;
|
|
end
|
|
else
|
|
if DataSource = rldsComponent then RenderInfo.GetDelimiters;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoCreateReportData;
|
|
var
|
|
ReraiseException: Boolean;
|
|
begin
|
|
case DataSource of
|
|
rldsComponent:
|
|
ConstructReport(FReportCells);
|
|
|
|
rldsExternalStorage:
|
|
try
|
|
InternalLoadDataFromStream(DataStream);
|
|
DataStream.Position := 0;
|
|
except
|
|
ReraiseException := (ComponentPrinter <> nil) and (ComponentPrinter.Explorer <> nil);
|
|
if not ReraiseException then
|
|
MessageError(Format(cxGetResourceString(@sdxReportFileLoadError), [StorageName]));
|
|
|
|
FIsInvalidReport := True;
|
|
try
|
|
DataSource := rldsComponent;
|
|
finally
|
|
FIsInvalidReport := False;
|
|
end;
|
|
if ReraiseException then raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoDataProviderDontPresent;
|
|
begin
|
|
if (ComponentPrinter = nil) or (ComponentPrinter.CurrentCompositionByLink(Self) = nil) then
|
|
StdProcessDataSourceDontPresent;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoDestroyReport;
|
|
begin
|
|
FActive := False;
|
|
|
|
PrepareLongOperation;
|
|
try
|
|
FreeAndNil(FReportCells);
|
|
if FRenderInfo <> nil then RenderInfo.Refresh;
|
|
if ComponentPrinter <> nil then ComponentPrinter.DoBeforeDestroyReport(Self);
|
|
finally
|
|
UnprepareLongOperation;
|
|
end;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoPageParamsChanged;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
ComponentPrinter.DoPageParamsChanged(Self);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.CopyDataStreamFrom(AStream: TStream);
|
|
begin
|
|
AStream.Position := 0;
|
|
FinalizeDataStream;
|
|
FDataStream := TMemoryStream.Create;
|
|
FDataStream.CopyFrom(AStream, AStream.Size);
|
|
FDataStream.Position := 0;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.FinalizeDataStream;
|
|
begin
|
|
FreeAndNil(FDataStream);
|
|
end;
|
|
|
|
function TBasedxReportLink.IsDrawFootersOnEveryPage: Boolean;
|
|
begin
|
|
Result := FootersOnEveryPage;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsDrawHeadersOnEveryPage: Boolean;
|
|
begin
|
|
Result := HeadersOnEveryPage;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ConstructReport(AReportCells: TdxReportCells);
|
|
begin
|
|
ClearGDIPools;
|
|
AddFontToPool(Font);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.ConvertCoords;
|
|
begin
|
|
FReportCells.ConvertCoords(PixelsNumerator, PixelsDenominator);
|
|
end;
|
|
|
|
procedure TBasedxReportLink.MakeDelimiters(AReportCells: TdxReportCells;
|
|
AHorzDelimiters, AVertDelimiters: TList);
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxReportLink.MakeHardDelimiters(AReportCells: TdxReportCells;
|
|
AVertDelimiters: TList);
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxReportLink.DoDataSourceChanged;
|
|
begin
|
|
if Assigned(FOnDataSourceChanged) then FOnDataSourceChanged(Self);
|
|
if IsRebuildNeededAndAllowed(True) then
|
|
begin
|
|
if DataSource = rldsComponent then
|
|
begin
|
|
ReportDocument.Assign(FSavedReportDocument);
|
|
ReportTitle.BeginUpdate;
|
|
try
|
|
ReportTitle.Assign(FSavedReportTitle);
|
|
finally
|
|
ReportTitle.CancelUpdate;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
FSavedReportDocument.Assign(ReportDocument);
|
|
FSavedReportTitle.Assign(ReportTitle);
|
|
end;
|
|
RebuildReport;
|
|
end
|
|
else
|
|
if DataSource = rldsComponent then
|
|
DestroyReport;
|
|
end;
|
|
|
|
procedure TBasedxReportLink.CustomDraw(AnItem: TAbstractdxReportCellData; ACanvas: TCanvas;
|
|
ABoundsRect, AClientRect: TRect; var ADone: Boolean);
|
|
begin
|
|
end;
|
|
|
|
function TBasedxReportLink.IsScaleGridLines: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TBasedxReportLink.IsSupportedCustomDraw(Item: TAbstractdxReportCellData): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
{ TdxCompositionLinkItem }
|
|
|
|
constructor TdxCompositionLinkItem.Create(Collection: TCollection);
|
|
begin
|
|
inherited Create(Collection);
|
|
FBuiltIn := (Composition <> nil) and Composition.IsDesigning;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItem.Assign(Source: TPersistent);
|
|
|
|
function IsInheritedForm: Boolean;
|
|
begin
|
|
with Composition do
|
|
Result := (csUpdating in ComponentState) or (csUpdating in ComponentPrinter.ComponentState) or
|
|
((ComponentPrinter.Owner <> nil) and (csUpdating in ComponentPrinter.Owner.ComponentState));
|
|
end;
|
|
|
|
begin
|
|
if Source is TdxCompositionLinkItem then
|
|
with TdxCompositionLinkItem(Source) do
|
|
if (ReportLink <> nil) and (Self.Composition <> nil) and (Self.Composition.ComponentPrinter <> nil) and IsInheritedForm then
|
|
Self.ReportLink := Self.Composition.ComponentPrinter.LinkByName(ReportLink.Name)
|
|
else
|
|
Self.ReportLink := ReportLink
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItem.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited;
|
|
Filer.DefineProperty('BuiltInCompositionItem', ReadData, WriteData, True);
|
|
Filer.DefineProperty('LinkName', ReadLinkName, WriteLinkName,
|
|
Composition.InternalStreaming and (ReportLink <> nil));
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItem.SetIndex(Value: Integer);
|
|
begin
|
|
if Collection <> nil then
|
|
TdxCompositionLinkItems(Collection).FDontNeedRebuild := True;
|
|
inherited;
|
|
end;
|
|
|
|
function TdxCompositionLinkItem.Composition: TdxCompositionReportLink;
|
|
begin
|
|
if Collection <> nil then
|
|
Result := TdxCompositionLinkItems(Collection).Composition
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItem.SetReportLink(Value: TBasedxReportLink);
|
|
begin
|
|
if (FReportLink <> Value) and (Collection <> nil) and
|
|
((Value = nil) or TdxCompositionLinkItems(Collection).IsLinkComposable(Value)) then
|
|
begin
|
|
if (FReportLink <> nil) and (Composition <> nil) and Composition.IsCurrentLink and
|
|
Composition.PreviewExists and not TdxCompositionLinkItems(Collection).LinkExists(Value) then
|
|
Composition.ComponentPrinter.DestroyPreviewWindow;
|
|
FReportLink := Value;
|
|
if Collection <> nil then
|
|
TdxCompositionLinkItems(Collection).FDontNeedRebuild := False;
|
|
Changed(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItem.ReadData(Reader: TReader);
|
|
begin
|
|
FBuiltIn := Reader.ReadBoolean;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItem.ReadLinkName(Reader: TReader);
|
|
begin
|
|
FLoadingReportLinkName := Reader.ReadString;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItem.WriteData(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(FBuiltIn);
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItem.WriteLinkName(Writer: TWriter);
|
|
begin
|
|
Writer.WriteString(GetFullName(ReportLink));
|
|
end;
|
|
|
|
{ TdxCompositionLinkItems }
|
|
|
|
constructor TdxCompositionLinkItems.Create(AComposition: TdxCompositionReportLink);
|
|
begin
|
|
inherited Create(TdxCompositionLinkItem);
|
|
FComposition := AComposition;
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.Add: TdxCompositionLinkItem;
|
|
begin
|
|
Result := TdxCompositionLinkItem(inherited Add);
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.AddLink(AReportLink: TBasedxReportLink): TdxCompositionLinkItem;
|
|
begin
|
|
if IsLinkComposable(AReportLink) then
|
|
begin
|
|
Result := Add;
|
|
Result.ReportLink := AReportLink;
|
|
end
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItems.DeleteItemsByLink(AReportLink: TBasedxReportLink);
|
|
var
|
|
List: TList;
|
|
I: Integer;
|
|
begin
|
|
List := TList.Create;
|
|
try
|
|
GetLinkEntries(AReportLink, List);
|
|
if List.Count <> 0 then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
for I := 0 to List.Count - 1 do
|
|
TObject(List[I]).Free;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItems.DeleteNonBuiltIns;
|
|
var
|
|
I: Integer;
|
|
Item: TdxCompositionLinkItem;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
for I := Count - 1 downto 0 do
|
|
begin
|
|
Item := Items[I];
|
|
if not Item.BuiltIn then Item.Free;
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItems.GetLinkEntries(AReportLink: TBasedxReportLink; AList: TList);
|
|
var
|
|
I: Integer;
|
|
Item: TdxCompositionLinkItem;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Item := Items[I];
|
|
if Item.ReportLink = AReportLink then AList.Add(Item);
|
|
end;
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.IndexOfLink(AReportLink: TBasedxReportLink): Integer;
|
|
begin
|
|
for Result := 0 to Count - 1 do
|
|
if AReportLink = Items[Result].ReportLink then
|
|
Exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.IsLinkComposable(AReportLink: TBasedxReportLink): Boolean;
|
|
begin
|
|
Result := (AReportLink <> nil) and (Composition <> nil) and AReportLink.IsComposable(Composition) and
|
|
(AReportLink.ComponentPrinter = Composition.ComponentPrinter) and
|
|
not (AReportLink is TdxCompositionReportLink);
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.LinkExists(AReportLink: TBasedxReportLink): Boolean;
|
|
var
|
|
List: TList;
|
|
begin
|
|
List := TList.Create;
|
|
try
|
|
GetLinkEntries(AReportLink, List);
|
|
Result := List.Count <> 0;
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.NextAssignedItem(AnItem: TdxCompositionLinkItem): TdxCompositionLinkItem;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
if AnItem <> nil then
|
|
Index := AnItem.Index + 1
|
|
else
|
|
Index := Count;
|
|
while (Index < Count) and (Items[Index].ReportLink = nil) do
|
|
Inc(Index);
|
|
if Index < Count then
|
|
Result := Items[Index]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.NonBuiltInsExists: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := True;
|
|
for I := 0 to Count - 1 do
|
|
if not Items[I].BuiltIn then Exit;
|
|
Result := False;
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.PrevAssignedItem(AnItem: TdxCompositionLinkItem): TdxCompositionLinkItem;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
if AnItem <> nil then
|
|
Index := AnItem.Index - 1
|
|
else
|
|
Index := -1;
|
|
while (Index > -1) and (Items[Index].ReportLink = nil) do
|
|
Dec(Index);
|
|
if Index > -1 then
|
|
Result := Items[Index]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItems.CorrectLinksAfterLoadings;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
Items[I].FReportLink := GetComponentByName(Items[I].FLoadingReportLinkName) as TBasedxReportLink;
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.GetOwner: TPersistent;
|
|
begin
|
|
Result := Composition;
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItems.Update(Item: TCollectionItem);
|
|
begin
|
|
if (Composition <> nil) and not Composition.IsDestroying and not Composition.IsLoading then
|
|
if FDontNeedRebuild or not Composition.DataProviderPresent then
|
|
begin
|
|
Composition.UpdateComposition(ucAll);
|
|
FDontNeedRebuild := False;
|
|
end
|
|
else
|
|
if Composition.DataProviderPresent then // TODO: Check non PreviewState
|
|
Composition.RebuildReport;
|
|
end;
|
|
|
|
function TdxCompositionLinkItems.GetItem(Index: Integer): TdxCompositionLinkItem;
|
|
begin
|
|
Result := TdxCompositionLinkItem(inherited Items[Index]);
|
|
end;
|
|
|
|
procedure TdxCompositionLinkItems.SetItem(Index: Integer; Value: TdxCompositionLinkItem);
|
|
begin
|
|
inherited SetItem(Index, Value);
|
|
end;
|
|
|
|
{ TdxPSCompositionReportRenderInfo }
|
|
|
|
constructor TdxPSCompositionReportRenderInfo.Create(AReportLink: TBasedxReportLink);
|
|
begin
|
|
inherited;
|
|
FStartIndexes := TList.Create;
|
|
end;
|
|
|
|
destructor TdxPSCompositionReportRenderInfo.Destroy;
|
|
begin
|
|
FreeAndNil(FStartIndexes);
|
|
inherited;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.CalculateNonEmptyPageCount: Integer;
|
|
var
|
|
Items: TStrings;
|
|
I: Integer;
|
|
RenderInfo: TdxPSReportRenderInfo;
|
|
begin
|
|
Result := 0;
|
|
Items := TStringList.Create;
|
|
try
|
|
ReportLink.GetItems(Items, True);
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
RenderInfo := TdxCompositionLinkItem(Items.Objects[I]).ReportLink.RenderInfo;
|
|
Inc(Result, RenderInfo.NonEmptyPageCount);
|
|
end;
|
|
finally
|
|
Items.Free;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.CalculatePageColCount: Integer;
|
|
var
|
|
Items: TStrings;
|
|
I: Integer;
|
|
RenderInfo: TdxPSReportRenderInfo;
|
|
begin
|
|
Result := 0;
|
|
Items := TStringList.Create;
|
|
try
|
|
ReportLink.GetItems(Items, True);
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
RenderInfo := TdxCompositionLinkItem(Items.Objects[I]).ReportLink.RenderInfo;
|
|
if Result < RenderInfo.PageColCount then
|
|
Result := RenderInfo.PageColCount;
|
|
end;
|
|
finally
|
|
Items.Free;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.CalculatePageRowCount: Integer;
|
|
var
|
|
Items: TStrings;
|
|
I: Integer;
|
|
RenderInfo: TdxPSReportRenderInfo;
|
|
begin
|
|
Result := 0;
|
|
Items := TStringList.Create;
|
|
try
|
|
ReportLink.GetItems(Items, True);
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
RenderInfo := TdxCompositionLinkItem(Items.Objects[I]).ReportLink.RenderInfo;
|
|
if Result < RenderInfo.PageRowCount then
|
|
Result := RenderInfo.PageRowCount;
|
|
end;
|
|
finally
|
|
Items.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSCompositionReportRenderInfo.DoCalculate;
|
|
var
|
|
Items: TStrings;
|
|
PrevPageCount, I: Integer;
|
|
Link: TBasedxReportLink;
|
|
begin
|
|
Items := TStringList.Create;
|
|
try
|
|
ReportLink.GetItems(Items, True);
|
|
FStartIndexes.Count := Items.Count;
|
|
|
|
PrevPageCount := 0;
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
Link := TdxCompositionLinkItem(Items.Objects[I]).ReportLink;
|
|
Link.CalculateRenderInfos;
|
|
if I = 0 then
|
|
StartIndexes[I] := 0
|
|
else
|
|
StartIndexes[I] := StartIndexes[I - 1] + PrevPageCount;
|
|
|
|
if ReportLink.ShowEmptyPages then
|
|
PrevPageCount := Link.RenderInfo.VirtualPageCount
|
|
else
|
|
PrevPageCount := Link.RenderInfo.NonEmptyPageCount;
|
|
|
|
Inc(VirtualPageCount, Link.VirtualPageCount);
|
|
end;
|
|
finally
|
|
Items.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSCompositionReportRenderInfo.Refresh;
|
|
begin
|
|
FNonEmptyPageCount := -1;
|
|
FPageColCount := -1;
|
|
FPageRowCount := -1;
|
|
FStartIndexes.Clear;
|
|
inherited;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.GetNonEmptyPageCount: Integer;
|
|
begin
|
|
if FNonEmptyPageCount = -1 then
|
|
FNonEmptyPageCount := CalculateNonEmptyPageCount;
|
|
Result := FNonEmptyPageCount;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.GetPageColCount: Integer;
|
|
begin
|
|
if FPageColCount = -1 then
|
|
FPageColCount := CalculatePageColCount;
|
|
Result := FPageColCount;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.GetPageRowCount: Integer;
|
|
begin
|
|
if FPageRowCount = -1 then
|
|
FPageRowCount := CalculatePageRowCount;
|
|
Result := FPageColCount;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.RealPageIndexToVirtualPageIndex(APageIndex: Integer;
|
|
ATakeIntoAccountEmptyPages: Boolean): Integer;
|
|
var
|
|
Item: TdxCompositionLinkItem;
|
|
begin
|
|
GetCompositionLinkItemByPageIndexAndFixIndex(APageIndex, APageIndex, Item);
|
|
if Item <> nil then
|
|
Result := Item.ReportLink.RealPageIndexToVirtualPageIndex(APageIndex, ATakeIntoAccountEmptyPages)
|
|
else
|
|
Result := APageIndex;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.VirtualPageIndexToRealPageIndex(APageIndex: Integer): Integer;
|
|
var
|
|
Item: TdxCompositionLinkItem;
|
|
begin
|
|
GetCompositionLinkItemByPageIndexAndFixIndex(APageIndex, APageIndex, Item);
|
|
if Item <> nil then
|
|
Result := Item.ReportLink.VirtualPageIndexToRealPageIndex(APageIndex)
|
|
else
|
|
Result := APageIndex;
|
|
end;
|
|
|
|
procedure TdxPSCompositionReportRenderInfo.GetCompositionLinkItemByPageIndexAndFixIndex(
|
|
APageIndex: Integer; var APageIndexRelativeToLink: Integer; var AnItem: TdxCompositionLinkItem);
|
|
|
|
function GetPageCount(ARenderInfo: TdxPSReportRenderInfo): Integer;
|
|
begin
|
|
if ReportLink.ShowEmptyPages then
|
|
Result := ARenderInfo.VirtualPageCount
|
|
else
|
|
Result := ARenderInfo.NonEmptyPageCount;
|
|
end;
|
|
|
|
var
|
|
Items: TStrings;
|
|
I: Integer;
|
|
begin
|
|
APageIndexRelativeToLink := APageIndex;
|
|
if (APageIndex = -1) or (FStartIndexes = nil) then
|
|
begin
|
|
AnItem := nil;
|
|
Exit;
|
|
end;
|
|
|
|
Items := TStringList.Create;
|
|
try
|
|
ReportLink.GetItems(Items, True);
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
AnItem := TdxCompositionLinkItem(Items.Objects[I]);
|
|
if (StartIndexes[I] <= APageIndex) and (APageIndex < StartIndexes[I] + GetPageCount(AnItem.ReportLink.RenderInfo)) then
|
|
begin
|
|
Dec(APageIndexRelativeToLink, StartIndexes[I]);
|
|
Exit;
|
|
end;
|
|
end;
|
|
AnItem := nil;
|
|
finally
|
|
Items.Free;
|
|
end;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.GetReportLink: TdxCompositionReportLink;
|
|
begin
|
|
Result := inherited ReportLink as TdxCompositionReportLink;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.GetStartIndex(Index: Integer): Integer;
|
|
begin
|
|
Result := Integer(FStartIndexes[Index]);
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderInfo.GetStartIndexCount: Integer;
|
|
begin
|
|
Result := FStartIndexes.Count;
|
|
end;
|
|
|
|
procedure TdxPSCompositionReportRenderInfo.SetStartIndex(Index: Integer; Value: Integer);
|
|
begin
|
|
FStartIndexes[Index] := TObject(Value);
|
|
end;
|
|
|
|
{ TdxPSCompositionReportRenderer }
|
|
|
|
procedure TdxPSCompositionReportRenderer.RenderPage(ACanvas: TCanvas;
|
|
const APageBounds: TRect; APageIndex, AContinuousPageIndex, AZoomFactor: Integer);
|
|
var
|
|
LinkPageIndex: Integer;
|
|
Item: TdxCompositionLinkItem;
|
|
begin
|
|
RenderInfo.GetCompositionLinkItemByPageIndexAndFixIndex(APageIndex, LinkPageIndex, Item);
|
|
if (Item <> nil) and (Item.ReportLink <> nil) then
|
|
begin
|
|
if not ReportLink.ContinuousPageIndexes then
|
|
dxHFFormatObject.TotalPages := Item.ReportLink.PageCount;
|
|
Item.ReportLink.PaintPage(ACanvas, APageBounds, LinkPageIndex, AContinuousPageIndex, AZoomFactor);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderer.GetRenderInfo: TdxPSCompositionReportRenderInfo;
|
|
begin
|
|
Result := inherited RenderInfo as TdxPSCompositionReportRenderInfo;
|
|
end;
|
|
|
|
function TdxPSCompositionReportRenderer.GetReportLink: TdxCompositionReportLink;
|
|
begin
|
|
Result := inherited ReportLink as TdxCompositionReportLink;
|
|
end;
|
|
|
|
{ TdxPSReportCompositionDocument }
|
|
|
|
function TdxPSReportCompositionDocument.DefaultDescription: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxComposition);
|
|
end;
|
|
|
|
function TdxPSReportCompositionDocument.GetReportLink: TdxCompositionReportLink;
|
|
begin
|
|
Result := inherited ReportLink as TdxCompositionReportLink;
|
|
end;
|
|
|
|
{ TdxCompositionReportLink }
|
|
|
|
constructor TdxCompositionReportLink.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
FContinuousPageIndexes := True;
|
|
ReportDocument.Description := cxGetResourceString(@sdxComposition);
|
|
FDesignerOptions := [coCanEdit, coShowDescription];
|
|
FItems := TdxCompositionLinkItems.Create(Self);
|
|
end;
|
|
|
|
destructor TdxCompositionReportLink.Destroy;
|
|
begin
|
|
FreeAndNil(FItems);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxCompositionReportLink then
|
|
with TdxCompositionReportLink(Source) do
|
|
begin
|
|
Self.ContinuousPageIndexes := ContinuousPageIndexes;
|
|
Self.DesignerOptions := DesignerOptions;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.DefaultDesignerCaption: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxCompositionDesignerCaption);
|
|
end;
|
|
|
|
function TdxCompositionReportLink.RealPageIndexToVirtualPageIndex(APageIndex: Integer;
|
|
ATakeIntoAccountEmptyPages: Boolean): Integer;
|
|
var
|
|
PageIndexRelativeToLink: Integer;
|
|
CurrentItem, Item: TdxCompositionLinkItem;
|
|
begin
|
|
Result := 0;
|
|
RenderInfo.GetCompositionLinkItemByPageIndexAndFixIndex(APageIndex, PageIndexRelativeToLink, CurrentItem);
|
|
Item := Items.PrevAssignedItem(CurrentItem);
|
|
while Item <> nil do
|
|
begin
|
|
Inc(Result, Item.ReportLink.VirtualPageCount);
|
|
Item := Items.PrevAssignedItem(Item);
|
|
end;
|
|
if CurrentItem <> nil then
|
|
Inc(Result, CurrentItem.ReportLink.RealPageIndexToVirtualPageIndex(PageIndexRelativeToLink, ATakeIntoAccountEmptyPages));
|
|
end;
|
|
|
|
function TdxCompositionReportLink.VirtualPageIndexToRealPageIndex(APageIndex: Integer): Integer;
|
|
var
|
|
PageIndexRelativeToLink: Integer;
|
|
CurrentItem, Item: TdxCompositionLinkItem;
|
|
begin
|
|
Result := 0;
|
|
RenderInfo.GetCompositionLinkItemByPageIndexAndFixIndex(APageIndex, PageIndexRelativeToLink, CurrentItem);
|
|
Item := Items.PrevAssignedItem(CurrentItem);
|
|
while Item <> nil do
|
|
begin
|
|
Inc(Result, 1 + Item.ReportLink.VirtualPageIndexToRealPageIndex(Item.ReportLink.VirtualPageCount - 1));
|
|
Item := Items.PrevAssignedItem(Item);
|
|
end;
|
|
if CurrentItem <> nil then
|
|
Inc(Result, CurrentItem.ReportLink.VirtualPageIndexToRealPageIndex(PageIndexRelativeToLink));
|
|
end;
|
|
|
|
class function TdxCompositionReportLink.CanBeUsedAsStub: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.DataProviderPresent: Boolean;
|
|
var
|
|
I: Integer;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
Result := True;
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
ReportLink := Items[I].ReportLink;
|
|
if (ReportLink <> nil) and ReportLink.DataProviderPresent then
|
|
Exit;
|
|
end;
|
|
Result := False;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.IsEmptyPage(AVirtualPageIndex: Integer): Boolean;
|
|
var
|
|
PageIndexRelativeToLink: Integer;
|
|
CurrentItem: TdxCompositionLinkItem;
|
|
begin
|
|
RenderInfo.GetCompositionLinkItemByPageIndexAndFixIndex(AVirtualPageIndex, PageIndexRelativeToLink, CurrentItem);
|
|
Result := (CurrentItem <> nil) and
|
|
CurrentItem.ReportLink.IsEmptyPage(PageIndexRelativeToLink);
|
|
end;
|
|
|
|
function TdxCompositionReportLink.SupportsTitle: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.GetItems(AStrings: TStrings; AExcludeUnassigned: Boolean);
|
|
var
|
|
I: Integer;
|
|
Item: TdxCompositionLinkItem;
|
|
S: string;
|
|
begin
|
|
AStrings.BeginUpdate;
|
|
try
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
Item := Items[I];
|
|
if (Item.ReportLink = nil) and AExcludeUnassigned then
|
|
Continue;
|
|
if Item.ReportLink = nil then
|
|
S := ''
|
|
else
|
|
S := Item.ReportLink.Caption;
|
|
AStrings.AddObject(S, Item);
|
|
end;
|
|
finally
|
|
AStrings.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.Notification(AComponent: TComponent; AOperation: TOperation);
|
|
var
|
|
List: TList;
|
|
I: Integer;
|
|
begin
|
|
inherited;
|
|
if (AOperation = opRemove) and (AComponent is TBasedxReportLink) and (AComponent <> Self) then
|
|
begin
|
|
List := TList.Create;
|
|
try
|
|
Items.GetLinkEntries(TBasedxReportLink(AComponent), List);
|
|
for I := 0 to List.Count - 1 do
|
|
TdxCompositionLinkItem(List[I]).ReportLink := nil;
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetContinuousPageIndexes: Boolean;
|
|
begin
|
|
Result := FContinuousPageIndexes;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.SetContinuousPageIndexes(Value: Boolean);
|
|
begin
|
|
if ContinuousPageIndexes <> Value then
|
|
begin
|
|
FContinuousPageIndexes := Value;
|
|
// TODO: Refresh preview
|
|
//if PreviewExists then PreviewWindow.InvalidateAllPages;
|
|
end;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetAllowContinuousPageIndexes: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetEmptyPagesCanExist: Boolean;
|
|
var
|
|
I: Integer;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
Result := True;
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
ReportLink := Items[I].ReportLink;
|
|
if (ReportLink <> nil) and ReportLink.GetEmptyPagesCanExist then
|
|
Exit;
|
|
end;
|
|
Result := False;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetRebuildOnPageParamsChange(AUpdateCodes: TdxPrinterPageUpdateCodes): Boolean;
|
|
var
|
|
I: Integer;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
Result := True;
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
ReportLink := Items[I].ReportLink;
|
|
if (ReportLink <> nil) and ReportLink.GetRebuildOnPageParamsChange(AUpdateCodes) then
|
|
Exit;
|
|
end;
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.ConstructReport(AReportCells: TdxReportCells);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.DoCreateReport;
|
|
var
|
|
I: Integer;
|
|
Item: TdxCompositionLinkItem;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
Include(FCompositionState, csRebuildReportLink);
|
|
try
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
Item := Items[I];
|
|
ReportLink := Item.ReportLink;
|
|
if (ReportLink <> nil) and ReportLink.DataProviderPresent and
|
|
((FInvalidatedLinks = nil) or (FInvalidatedLinks.IndexOf(ReportLink) <> -1)) then
|
|
begin
|
|
DoBeforeBuildReport(Item);
|
|
try
|
|
ReportLink.RebuildReport;
|
|
finally
|
|
DoAfterBuildReport(Item);
|
|
end;
|
|
end;
|
|
DoProgress(100 * (I + 1) / Items.Count);
|
|
if AbortBuilding then Break;
|
|
end;
|
|
finally
|
|
Exclude(FCompositionState, csRebuildReportLink);
|
|
end;
|
|
|
|
if not AbortBuilding then CalculateRenderInfos;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetRendererClass: TdxPSReportRendererClass;
|
|
begin
|
|
Result := TdxPSCompositionReportRenderer;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetRenderInfoClass: TdxPSReportRenderInfoClass;
|
|
begin
|
|
Result := TdxPSCompositionReportRenderInfo;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetReportHeight: Integer;
|
|
var
|
|
I: Integer;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
ReportLink := Items[I].ReportLink;
|
|
if ReportLink <> nil then
|
|
Inc(Result, ReportLink.ReportHeight);
|
|
end;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetReportWidth: Integer;
|
|
var
|
|
I, V: Integer;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
ReportLink := Items[I].ReportLink;
|
|
if ReportLink <> nil then
|
|
begin
|
|
V := ReportLink.ReportWidth;
|
|
if Result < V then Result := V;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.InternalRestoreDefaults;
|
|
var
|
|
I: Integer;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
FContinuousPageIndexes := True;
|
|
ReportDocument.Description := cxGetResourceString(@sdxComposition);
|
|
FDesignerCaption := cxGetResourceString(@sdxCompositionDesignerCaption);
|
|
FDesignerOptions := [coCanEdit, coShowDescription];
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
ReportLink := Items[I].ReportLink;
|
|
if ReportLink <> nil then
|
|
ReportLink.RestoreDefaults;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.InternalRestoreFromOriginal;
|
|
var
|
|
I: Integer;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
ReportLink := Items[I].ReportLink;
|
|
if ReportLink <> nil then
|
|
ReportLink.RestoreFromOriginal;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.ShowEmptyPagesChanged;
|
|
begin
|
|
if EmptyPagesCanExist then CalculateRenderInfos;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.ShowPageFooterChanged;
|
|
begin
|
|
CalculateRenderInfos;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.ShowPageHeaderChanged;
|
|
begin
|
|
CalculateRenderInfos;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.StdProcessDataSourceDontPresent;
|
|
begin
|
|
// raise EdxReportLink.Create(cxGetResourceString({$IFNDEF CLR}@{$ENDIF}sdxDataSourceDontPresent));
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.DoAfterBuildReport(AItem: TdxCompositionLinkItem);
|
|
begin
|
|
if Assigned(FOnAfterBuildReport) then FOnAfterBuildReport(Self, AItem);
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.DoBeforeBuildReport(AItem: TdxCompositionLinkItem);
|
|
begin
|
|
if Assigned(FOnBeforeBuildReport) then FOnBeforeBuildReport(Self, AItem);
|
|
end;
|
|
|
|
class function TdxCompositionReportLink.GetReportDocumentClass: TdxPSReportDocumentClass;
|
|
begin
|
|
Result := TdxPSReportCompositionDocument;
|
|
end;
|
|
|
|
class function TdxCompositionReportLink.Serializable: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetRenderer: TdxPSCompositionReportRenderer;
|
|
begin
|
|
Result := inherited Renderer as TdxPSCompositionReportRenderer;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetRenderInfo: TdxPSCompositionReportRenderInfo;
|
|
begin
|
|
Result := inherited RenderInfo as TdxPSCompositionReportRenderInfo;
|
|
end;
|
|
|
|
function TdxCompositionReportLink.GetReportDocument: TdxPSReportCompositionDocument;
|
|
begin
|
|
Result := inherited ReportDocument as TdxPSReportCompositionDocument;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.SetItems(Value: TdxCompositionLinkItems);
|
|
begin
|
|
FItems.Assign(Value);
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.SetReportDocument(Value: TdxPSReportCompositionDocument);
|
|
begin
|
|
inherited ReportDocument := Value;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.ActivateLink(AReportLink: TBasedxReportLink);
|
|
begin
|
|
Include(FCompositionState, csRebuildReportLink);
|
|
try
|
|
FInvalidatedLinks := TList.Create;
|
|
try
|
|
FInvalidatedLinks.Add(AReportLink);
|
|
RebuildReport;
|
|
finally
|
|
FreeAndNil(FInvalidatedLinks);
|
|
end;
|
|
finally
|
|
Exclude(FCompositionState, csRebuildReportLink);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCompositionReportLink.UpdateComposition(AUpdateCodes: TdxPrinterPageUpdateCodes);
|
|
begin
|
|
PageParamsChanged(RealPrinterPage, CurrentPrintStyle, AUpdateCodes);
|
|
end;
|
|
|
|
{ TAbstractdxReportLinkDesignWindow }
|
|
|
|
constructor TAbstractdxReportLinkDesignWindow.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Caption := cxGetResourceString(@sdxReportDesignerCaption);
|
|
end;
|
|
|
|
function TAbstractdxReportLinkDesignWindow.Execute: Boolean;
|
|
begin
|
|
Include(FState, dwsInitialize);
|
|
try
|
|
Initialize;
|
|
finally
|
|
Exclude(FState, dwsInitialize);
|
|
end;
|
|
Result := (ReportLink <> nil) and (ShowModal = mrOK);// and Modified and not Applyed;
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.CreateWnd;
|
|
begin
|
|
inherited;
|
|
if Icon.Handle = 0 then
|
|
Icon_LoadFromResourceName(Icon, IDB_DXPSREPORTDESIGNER);
|
|
SendMessage(Handle, WM_SETICON, 1, Icon.Handle);
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.KeyDown(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if (ReportLink <> nil) and ReportLink.PreviewExists and ReportLink.IsBuilding and (Key = VK_ESCAPE) then
|
|
ReportLink.AbortBuilding := True
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.AfterRebuildReport;
|
|
begin
|
|
KeyPreview := FPrevKeyPreview;
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.BeforeRebuildReport;
|
|
begin
|
|
FPrevKeyPreview := KeyPreview;
|
|
KeyPreview := True;
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.Initialize;
|
|
begin
|
|
LoadStrings;
|
|
Caption := ReportLink.DesignerCaption;
|
|
if ReportLink.IsDesigning and (Component <> nil) then
|
|
Caption := Caption + ' : ' + Component.Name;
|
|
if ReportLink.DesignerHelpContext <> 0 then
|
|
HelpContext := ReportLink.DesignerHelpContext;
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.LoadStrings;
|
|
begin
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.UpdateControlsState;
|
|
begin
|
|
end;
|
|
|
|
function TAbstractdxReportLinkDesignWindow.GetComponent: TComponent;
|
|
begin
|
|
if ReportLink <> nil then
|
|
Result := ReportLink.Component
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TAbstractdxReportLinkDesignWindow.GetIsDesigning: Boolean;
|
|
begin
|
|
Result := (ReportLink <> nil) and Reportlink.IsDesigning;
|
|
end;
|
|
|
|
function TAbstractdxReportLinkDesignWindow.IsCaptionStored: Boolean;
|
|
begin //TODO: TAbstractdxReportLinkDesignWindow.IsCaptionStored
|
|
Result := Caption <> cxGetResourceString(@sdxReportDesignerCaption);
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.SetModified(Value: Boolean);
|
|
begin
|
|
FModified := Value;
|
|
if Modified and Applyed then Applyed := False;
|
|
UpdateControlsState;
|
|
end;
|
|
|
|
procedure TAbstractdxReportLinkDesignWindow.WMHelp(var Message: TWMHelp);
|
|
var
|
|
Control: TWinControl;
|
|
ContextID: Integer;
|
|
begin
|
|
if csDesigning in ComponentState then
|
|
inherited
|
|
else
|
|
begin
|
|
ContextID := 0;
|
|
with Message.HelpInfo^ do
|
|
if iContextType = HELPINFO_WINDOW then
|
|
begin
|
|
Control := FindControl(hItemHandle);
|
|
if Control = nil then Exit;
|
|
Control := GetParentForm(Control);
|
|
if Control = nil then Exit;
|
|
ContextID := Control.HelpContext;
|
|
end;
|
|
if ContextID <> 0 then Application.HelpContext(ContextID);
|
|
end;
|
|
end;
|
|
|
|
{ TStandarddxReportLinkDesignWindow }
|
|
|
|
constructor TStandarddxReportLinkDesignWindow.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
CreateStdButtons;
|
|
{$IFDEF DELPHI7}
|
|
if PreviewHost <> nil then
|
|
begin
|
|
if ThemeServices.ThemesEnabled then
|
|
begin
|
|
TCustomPanelAccess(PreviewHost).BevelInner := bvNone;
|
|
TCustomPanelAccess(PreviewHost).BevelOuter := bvNone;
|
|
end;
|
|
FPrevPreviewHostWindowProc := PreviewHost.WindowProc;
|
|
PreviewHost.WindowProc := PreviewHostWindowProc;
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{$IFDEF DELPHI7}
|
|
destructor TStandarddxReportLinkDesignWindow.Destroy;
|
|
begin
|
|
if PreviewHost <> nil then
|
|
PreviewHost.WindowProc := FPrevPreviewHostWindowProc;
|
|
inherited;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.PlaceStdButtons;
|
|
const
|
|
btnWidth = 75;
|
|
btnLargeWidth = 115;
|
|
btnHeight = 23;
|
|
btnFirstOffsetX: array[Boolean] of Integer = (4, 10);
|
|
btnOffsetX = 4;
|
|
btnOffsetY = 6;
|
|
var
|
|
AWidth, ALargeWidth, AHeight, AOffsetX, AFirstOffsetX, AOffsetY: Integer;
|
|
begin
|
|
AWidth := MulDiv(btnWidth, Screen.PixelsPerInch, 96);
|
|
ALargeWidth := MulDiv(btnLargeWidth, Screen.PixelsPerInch, 96);
|
|
AHeight := MulDiv(btnHeight, Screen.PixelsPerInch, 96);
|
|
AFirstOffsetX := MulDiv(btnFirstOffsetX[foSizeableDialog in Options], Screen.PixelsPerInch, 96);
|
|
AOffsetX := MulDiv(btnOffsetX, Screen.PixelsPerInch, 96);
|
|
AOffsetY := MulDiv(btnOffsetY, Screen.PixelsPerInch, 96);
|
|
|
|
if btnHelp.Visible then
|
|
begin
|
|
btnHelp.BoundsRect :=
|
|
MakeBounds(ClientWidth - AFirstOffsetX - AWidth, ClientHeight - AOffsetY - AHeight, AWidth, AHeight);
|
|
btnApply.BoundsRect :=
|
|
MakeBounds(btnHelp.Left - AOffsetX - AWidth, ClientHeight - AOffsetY - AHeight, AWidth, AHeight);
|
|
end
|
|
else
|
|
btnApply.BoundsRect :=
|
|
MakeBounds(ClientWidth - AFirstOffsetX - AWidth, ClientHeight - AOffsetY - AHeight, AWidth, AHeight);
|
|
|
|
btnCancel.BoundsRect :=
|
|
MakeBounds(btnApply.Left - AOffsetX - AWidth, ClientHeight - AOffsetY - AHeight, AWidth, AHeight);
|
|
btnOK.BoundsRect :=
|
|
MakeBounds(btnCancel.Left - AOffsetX - AWidth, ClientHeight - AOffsetY - AHeight, AWidth, AHeight);
|
|
btnRestoreOriginal.BoundsRect :=
|
|
MakeBounds(AOffsetX, ClientHeight - AOffsetY - AHeight, ALargeWidth, AHeight);
|
|
btnRestoreDefaults.BoundsRect :=
|
|
MakeBounds(btnRestoreOriginal.BoundsRect.Right + AOffsetX, ClientHeight - AOffsetY - AHeight, ALargeWidth, AHeight);
|
|
btnTitleProperties.BoundsRect :=
|
|
MakeBounds(AOffsetX, ClientHeight - AOffsetY - AHeight, ALargeWidth, AHeight);
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.CreateStdButtons;
|
|
begin
|
|
btnHelp := TButton.Create(Self);
|
|
try
|
|
btnHelp.Name := sdxHelpButtonName;
|
|
except
|
|
end;
|
|
btnHelp.Parent := Self;
|
|
|
|
btnApply := TButton.Create(Self);
|
|
btnApply.Parent := Self;
|
|
btnApply.TabOrder := btnHelp.TabOrder - 1;
|
|
btnApply.OnClick := ApplyClick;
|
|
|
|
btnCancel := TButton.Create(Self);
|
|
btnCancel.Parent := Self;
|
|
btnCancel.Cancel := True;
|
|
btnCancel.ModalResult := mrCancel;
|
|
btnCancel.TabOrder := btnApply.TabOrder - 1;
|
|
|
|
btnOK := TButton.Create(Self);
|
|
btnOK.Parent := Self;
|
|
btnOK.Default := True;
|
|
btnOK.ModalResult := mrOK;
|
|
btnOK.TabOrder := btnCancel.TabOrder - 1;
|
|
|
|
btnRestoreOriginal := TButton.Create(Self);
|
|
btnRestoreOriginal.Parent := Self;
|
|
btnRestoreOriginal.TabOrder := btnOK.TabOrder - 1;
|
|
btnRestoreOriginal.OnClick := RestoreOriginalClick;
|
|
|
|
btnRestoreDefaults := TButton.Create(Self);
|
|
btnRestoreDefaults.Parent := Self;
|
|
btnRestoreDefaults.TabOrder := btnRestoreOriginal.TabOrder - 1;
|
|
btnRestoreDefaults.OnClick := RestoreDefaultsClick;
|
|
|
|
btnTitleProperties := TButton.Create(Self);
|
|
btnTitleProperties.Parent := Self;
|
|
btnTitleProperties.OnClick := TitlePropertiesClick;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.RestoreOriginalClick(Sender: TObject);
|
|
begin
|
|
BeginUpdateControls;
|
|
try
|
|
if ReportLink <> nil then ReportLink.RestoreFromOriginal;
|
|
DoInitialize;
|
|
finally
|
|
EndUpdateControls;
|
|
end;
|
|
Modified := True;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.RestoreDefaultsClick(Sender: TObject);
|
|
begin
|
|
BeginUpdateControls;
|
|
try
|
|
if ReportLink <> nil then ReportLink.RestoreDefaults;
|
|
DoInitialize;
|
|
finally
|
|
EndUpdateControls;
|
|
end;
|
|
Modified := True;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.TitlePropertiesClick(Sender: TObject);
|
|
begin
|
|
if (ReportLink <> nil) and ReportLink.ShowTitlePropertiesDlg then
|
|
begin
|
|
if not ReportLink.AbortBuilding then
|
|
begin
|
|
AtLeastOneTimeApplied := True;
|
|
Applyed := True;
|
|
end;
|
|
UpdateControlsState;
|
|
end;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.ApplyClick(Sender: TObject);
|
|
begin
|
|
DoApply;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.RegroupStdButtons;
|
|
var
|
|
StartTabOrder: Integer;
|
|
begin
|
|
Resize;
|
|
if HelpContext = 0 then
|
|
begin
|
|
btnOK.BoundsRect := btnCancel.BoundsRect;
|
|
btnCancel.BoundsRect := btnApply.BoundsRect;
|
|
btnApply.BoundsRect := btnHelp.BoundsRect;
|
|
btnHelp.Visible := False;
|
|
end
|
|
else
|
|
BorderIcons := BorderIcons + [biHelp];
|
|
|
|
btnRestoreOriginal.Visible := ReportLink.IsDesigning;
|
|
btnRestoreDefaults.Visible := ReportLink.IsDesigning;
|
|
if btnTitleProperties.Visible then
|
|
btnTitleProperties.Visible := ReportLink.CanChangeTitle and not ReportLink.IsDesigning;
|
|
if ReportLink.IsDesigning then
|
|
begin
|
|
btnRestoreOriginal.TabOrder := 0;
|
|
btnRestoreDefaults.TabOrder := 1;
|
|
end
|
|
else
|
|
if ReportLink.CanChangeTitle then
|
|
btnTitleProperties.TabOrder := 0;
|
|
|
|
StartTabOrder := 1 + Byte(ReportLink.IsDesigning);
|
|
btnOk.TabOrder := StartTabOrder;
|
|
btnCancel.TabOrder := StartTabOrder + 1;
|
|
btnApply.TabOrder := StartTabOrder + 2;
|
|
btnHelp.TabOrder := StartTabOrder + 3;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.Resize;
|
|
begin
|
|
PlaceStdButtons;
|
|
inherited;
|
|
end;
|
|
|
|
function TStandarddxReportLinkDesignWindow.CanApply: Boolean;
|
|
begin
|
|
Result := (ReportLink <> nil) and ReportLink.DataProviderPresent and
|
|
ReportLink.PreviewExists and Modified and not Applyed and not ReportLink.IsAggregated;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.DoApply;
|
|
begin
|
|
try
|
|
ReportLink.DoApplyInDesigner;
|
|
except
|
|
Application.HandleException(Self);
|
|
ModalResult := mrCancel;
|
|
raise;
|
|
end;
|
|
if not ReportLink.AbortBuilding then
|
|
begin
|
|
AtLeastOneTimeApplied := True;
|
|
Applyed := True;
|
|
end;
|
|
UpdateControlsState;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.Initialize;
|
|
begin
|
|
BeginUpdateControls;
|
|
try
|
|
inherited;
|
|
RegroupStdButtons;
|
|
DoInitialize;
|
|
finally
|
|
UpdateControlsState;
|
|
EndUpdateControls;
|
|
end;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.LoadStrings;
|
|
begin
|
|
inherited;
|
|
btnOK.Caption := cxGetResourceString(@sdxBtnOK);
|
|
btnCancel.Caption := cxGetResourceString(@sdxBtnCancel);
|
|
btnApply.Caption := cxGetResourceString(@sdxBtnApply);
|
|
btnHelp.Caption := cxGetResourceString(@sdxBtnHelp);
|
|
btnRestoreDefaults.Caption := cxGetResourceString(@sdxBtnRestoreDefaults);
|
|
btnRestoreOriginal.Caption := cxGetResourceString(@sdxBtnRestoreOriginal);
|
|
btnTitleProperties.Caption := cxGetResourceString(@sdxBtnTitleProperties);
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.UpdateControlsState;
|
|
begin
|
|
if btnTitleProperties <> nil then
|
|
btnTitleProperties.Enabled := not ReportLink.IsAggregated;
|
|
if btnApply <> nil then
|
|
btnApply.Enabled := CanApply;
|
|
if btnRestoreOriginal <> nil then
|
|
btnRestoreOriginal.Enabled := (ReportLink <> nil) and ReportLink.DataProviderPresent;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.DoInitialize;
|
|
begin
|
|
end;
|
|
|
|
{$IFDEF DELPHI7}
|
|
|
|
function TStandarddxReportLinkDesignWindow.GetPreviewHost: TCustomPanel;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.PreviewHostWindowProc(var Message: TMessage);
|
|
var
|
|
Control: TWinControl;
|
|
R: TRect;
|
|
Details: TThemedElementDetails;
|
|
DC: HDC;
|
|
PS: TPaintStruct;
|
|
begin
|
|
if ThemeServices.ThemesEnabled and (Message.Msg = WM_PAINT) then
|
|
begin
|
|
Control := PreviewHost;
|
|
DC := BeginPaint(Control.Handle, PS);
|
|
try
|
|
R := Control.ClientRect;
|
|
Details := ThemeServices.GetElementDetails(ttBody);
|
|
ThemeServices.DrawElement(DC, Details, Control.Parent.ClientRect);
|
|
|
|
Details := ThemeServices.GetElementDetails(teEditTextNormal);
|
|
ThemeServices.DrawEdge(DC, Details, R, BDR_SUNKENOUTER, BF_RECT or BF_FLAT);
|
|
InflateRect(R, -1, -1);
|
|
ThemeServices.DrawEdge(DC, Details, R, BDR_RAISEDINNER, BF_RECT or BF_FLAT);
|
|
finally
|
|
EndPaint(Control.Handle, PS);
|
|
end;
|
|
end
|
|
else
|
|
FPrevPreviewHostWindowProc(Message);
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.PaintPreview(ACanvas: TCanvas; R: TRect);
|
|
{$IFDEF DELPHI7}
|
|
var
|
|
Details: TThemedElementDetails;
|
|
{$ENDIF}
|
|
begin
|
|
{$IFDEF DELPHI7}
|
|
if (PreviewHost <> nil) and ThemeServices.ThemesEnabled then
|
|
begin
|
|
Details := ThemeServices.GetElementDetails(ttBody);
|
|
ThemeServices.DrawElement(ACanvas.Handle, Details, PreviewHost.Parent.ClientRect);
|
|
Exit;
|
|
end;
|
|
{$ENDIF}
|
|
ACanvas.Brush.Color := clWindow;
|
|
ACanvas.FillRect(R);
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.UpdatePreview;
|
|
begin
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.BeginUpdateControls;
|
|
begin
|
|
Inc(FUpdateControlsCount);
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.EndUpdateControls;
|
|
begin
|
|
if FUpdateControlsCount > 0 then
|
|
begin
|
|
Dec(FUpdateControlsCount);
|
|
if FUpdateControlsCount = 0 then UpdatePreview;
|
|
end;
|
|
end;
|
|
|
|
function TStandarddxReportLinkDesignWindow.LockControlsUpdate: Boolean;
|
|
begin
|
|
Result := FUpdateControlsCount <> 0;
|
|
end;
|
|
|
|
procedure TStandarddxReportLinkDesignWindow.SetAtLeastOneTimeApplied(Value: Boolean);
|
|
begin
|
|
if FAtLeastOneTimeApplied <> Value then
|
|
begin
|
|
FAtLeastOneTimeApplied := Value;
|
|
if FAtLeastOneTimeApplied then
|
|
btnCancel.Caption := cxGetResourceString(@sdxBtnClose)
|
|
else
|
|
btnCancel.Caption := cxGetResourceString(@sdxBtnCancel);
|
|
end;
|
|
end;
|
|
|
|
{ TdxPSPrintStyle }
|
|
|
|
constructor TdxPSPrintStyle.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
AddStdHFFunctions;
|
|
end;
|
|
|
|
function TdxPSPrintStyle.DefaultPageFooterText(APart: TdxPageTitlePart): string;
|
|
const
|
|
CRLF = #13#10;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Index := -1;
|
|
if dxHFFunctionLibrary <> nil then
|
|
case APart of
|
|
tpCenter:
|
|
Index := dxHFFunctionLibrary.IndexOfByClass(TdxHFPageNumberFunction);
|
|
tpRight:
|
|
Index := dxHFFunctionLibrary.IndexOfByClass(TdxHFDateFunction);
|
|
end;
|
|
|
|
if Index <> -1 then
|
|
Result := dxHFFunctionLibrary[Index].TemplateString + CRLF
|
|
else
|
|
Result := inherited DefaultPageFooterText(APart);
|
|
end;
|
|
|
|
function TdxPSPrintStyle.DefaultStyleCaption: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxStandardStyle);
|
|
end;
|
|
|
|
procedure TdxPSPrintStyle.AddStdHFFunctions;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
if dxHFFunctionLibrary = nil then Exit;
|
|
with PrinterPage.PageFooter do
|
|
begin
|
|
Index := dxHFFunctionLibrary.IndexOfByClass(TdxHFPageNumberFunction);
|
|
if Index <> -1 then
|
|
CenterTitle.Text := dxHFFunctionLibrary[Index].TemplateString;
|
|
Index := dxHFFunctionLibrary.IndexOfByClass(TdxHFDateFunction);
|
|
if Index <> -1 then
|
|
RightTitle.Text := dxHFFunctionLibrary[Index].TemplateString;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSPrintStyle.AfterGenerating;
|
|
begin
|
|
DoAfterGenerating;
|
|
end;
|
|
|
|
procedure TdxPSPrintStyle.BeforeGenerating;
|
|
begin
|
|
DoBeforeGenerating;
|
|
end;
|
|
|
|
procedure TdxPSPrintStyle.DoAfterGenerating;
|
|
begin
|
|
if Assigned(FOnAfterGenerating) then FOnAfterGenerating(Self);
|
|
end;
|
|
|
|
procedure TdxPSPrintStyle.DoAfterPrinting;
|
|
begin
|
|
if Assigned(FOnAfterPrinting) then FOnAfterPrinting(Self);
|
|
end;
|
|
|
|
procedure TdxPSPrintStyle.DoBeforeGenerating;
|
|
begin
|
|
if Assigned(FOnBeforeGenerating) then FOnBeforeGenerating(Self);
|
|
end;
|
|
|
|
procedure TdxPSPrintStyle.DoBeforePrinting;
|
|
begin
|
|
if Assigned(FOnBeforePrinting) then FOnBeforePrinting(Self);
|
|
end;
|
|
|
|
procedure TdxPSPrintStyle.InitializeDefaultStyleGlyph(ABitmap: TBitmap);
|
|
begin
|
|
inherited;
|
|
Bitmap_LoadFromResourceName(ABitmap, IDB_DXPSPRINTSTYLE_STANDARD);
|
|
end;
|
|
|
|
{ TBasedxPreviewWindow }
|
|
|
|
destructor TBasedxPreviewWindow.Destroy;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
begin
|
|
Exclude(ComponentPrinter.FState, cpsPreviewing);
|
|
if not ComponentPrinter.FModalPreview then
|
|
ComponentPrinter.DoAfterPreview(ReportLink);
|
|
ComponentPrinter.FPreviewWindow := nil;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.InitContent;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.InvalidateContent;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.InvalidatePage(APageIndex: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.InvalidateAllPages;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.InvalidatePagesContent;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.InvalidatePagesHeaderContent;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.InvalidatePagesFooterContent;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.CreationComplete;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.RebuildReport;
|
|
begin
|
|
if ReportLink <> nil then ReportLink.RebuildReport;
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.UpdateCaption;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
Caption := ComponentPrinter.PreviewCaption;
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.UpdateControls;
|
|
begin
|
|
UpdateCaption;
|
|
UpdateExplorerContextCommands;
|
|
if (ComponentPrinter <> nil) and (ComponentPrinter.PreviewWindowDesigner <> nil) then
|
|
ComponentPrinter.PreviewWindowDesigner.Modified;
|
|
end;
|
|
|
|
{$IFNDEF DELPHI6}
|
|
|
|
{ IUnknown }
|
|
|
|
function TBasedxPreviewWindow.QueryInterface(const IID: TGUID; out Obj): HRESULT;
|
|
begin
|
|
if GetInterface(IID, Obj) then
|
|
Result := S_OK
|
|
else
|
|
Result := E_NOINTERFACE;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow._Addref: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow._Release: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
{$IFDEF OLEDRAGANDDROP}
|
|
|
|
const
|
|
DropEffects: array[Boolean] of Longint = (DROPEFFECT_NONE, DROPEFFECT_COPY);
|
|
|
|
function TBasedxPreviewWindow.IDropTarget_DragEnter(const DataObj: IDataObject;
|
|
grfKeyState: Longint; Pt: TPoint; var dwEffect: Longint): HRESULT;
|
|
var
|
|
Format: TFormatETC;
|
|
Medium: TSTGMedium;
|
|
BufferSize: DWORD;
|
|
Buffer: PChar ;
|
|
begin
|
|
FillChar(Format, SizeOf(Format), 0);
|
|
with Format do
|
|
begin
|
|
cfFormat := CF_HDROP;
|
|
dwAspect := DVASPECT_CONTENT;
|
|
lindex := -1;
|
|
tymed := TYMED_HGLOBAL;
|
|
end;
|
|
DataObj._AddRef;
|
|
try
|
|
FDraggedFileName := '';
|
|
if (DataObj.GetData(Format, Medium) = S_OK) and (DragQueryFile(Medium.hGlobal, $FFFFFFFF, nil, 0) <> 0) then
|
|
try
|
|
BufferSize := DragQueryFile(Medium.hGlobal, 0, nil, 0);
|
|
Buffer := StrAlloc(BufferSize + 1);
|
|
try
|
|
if BufferSize = DragQueryFile(Medium.hGlobal, 0, Buffer, BufferSize) then
|
|
FDraggedFileName := StrPas(Buffer);
|
|
finally
|
|
StrDispose(Buffer);
|
|
end;
|
|
finally
|
|
if Medium.unkForRelease = nil then ReleaseSTGMedium(Medium);
|
|
end;
|
|
finally
|
|
DataObj._Release;
|
|
end;
|
|
|
|
dwEffect := DropEffects[CanDrop and DoCanAccept];
|
|
if dwEffect = DROPEFFECT_NONE then FDraggedFileName := '';
|
|
|
|
Result := S_OK;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.IDropTarget_DragOver(grfKeyState: Longint; Pt: TPoint;
|
|
var dwEffect: Longint): HRESULT;
|
|
begin
|
|
dwEffect := DropEffects[CanDrop];
|
|
Result := S_OK;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.IDropTarget_DragLeave: HRESULT;
|
|
begin
|
|
Result := S_OK;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.IDropTarget_Drop(const DataObj: IDataObject;
|
|
grfKeyState: Longint; Pt: TPoint; var dwEffect: Longint): HRESULT;
|
|
begin
|
|
dwEffect := DropEffects[CanDrop];
|
|
if dwEffect = DROPEFFECT_COPY then DoDrop;
|
|
Result := S_OK;
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
procedure TBasedxPreviewWindow.AddExplorerContextCommand(ACommand: TCustomdxPSExplorerContextCommand);
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.UpdateExplorerContextCommands;
|
|
begin
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.GetExplorerTree: TCustomdxPSExplorerTreeContainer;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.GetHFEditPart: TdxPageTitlePart;
|
|
begin
|
|
Result := tpLeft;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.GetShowExplorer: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.GetShowThumbnails: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.GetState: TdxPSPreviewState;
|
|
begin
|
|
Result := prsNone;
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.SetShowExplorer(Value: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.SetShowThumbnails(Value: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.BeginUpdate;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.CancelUpdate;
|
|
begin
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.EndUpdate;
|
|
begin
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.Locked: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.PaintPage(Sender: TObject; ACanvas: TCanvas;
|
|
ARect: TRect; APageIndex: Integer);
|
|
begin
|
|
ComponentPrinter.PaintPage(ACanvas, APageIndex, ARect, ARect, nil);
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.PaintThumbnailPage(Sender: TObject; ACanvas: TCanvas;
|
|
ARect: TRect; APageIndex: Integer);
|
|
begin
|
|
ComponentPrinter.PaintThumbnailPage(ACanvas, APageIndex, ARect, ARect, nil);
|
|
end;
|
|
|
|
{$IFDEF OLEDRAGANDDROP}
|
|
|
|
function TBasedxPreviewWindow.CanDrop: Boolean;
|
|
begin
|
|
Result := DraggedFileName <> '';
|
|
end;
|
|
|
|
function TBasedxPreviewWindow.DoCanAccept: Boolean;
|
|
begin
|
|
Result := (ReportLink <> nil) and ReportLink.CanLoadData and
|
|
ReportLink.PossibleDataStorage(DraggedFileName, False);
|
|
end;
|
|
|
|
procedure TBasedxPreviewWindow.DoDrop;
|
|
begin
|
|
if ReportLink <> nil then
|
|
begin
|
|
ReportLink.DataSource := rldsExternalStorage;
|
|
ReportLink.StorageName := DraggedFileName;
|
|
RebuildReport;
|
|
UpdateControls;
|
|
Application.BringToFront;
|
|
end;
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
function TBasedxPreviewWindow.GetReportLink: TBasedxReportLink;
|
|
begin
|
|
if ComponentPrinter <> nil then
|
|
Result := ComponentPrinter.CurrentLink
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
{ TdxComponentPrinterThumbnailsOptions }
|
|
|
|
constructor TdxComponentPrinterThumbnailsOptions.Create(APreviewOptions: TdxPreviewOptions);
|
|
begin
|
|
inherited Create;
|
|
FPreviewOptions := APreviewOptions;
|
|
FFont := TFont.Create;
|
|
RestoreDefaults;
|
|
end;
|
|
|
|
destructor TdxComponentPrinterThumbnailsOptions.Destroy;
|
|
begin
|
|
FreeAndNil(FDefaultFont);
|
|
FreeAndNil(FFont);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxComponentPrinterThumbnailsOptions.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TdxComponentPrinterThumbnailsOptions then
|
|
with TdxComponentPrinterThumbnailsOptions(Source) do
|
|
begin
|
|
Self.Font := Font;
|
|
Self.ShowPageNumbers := ShowPageNumbers;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
function TdxComponentPrinterThumbnailsOptions.DefaultFont: TFont;
|
|
begin
|
|
if FDefaultFont = nil then
|
|
begin
|
|
FDefaultFont := TFont.Create;
|
|
InitializeDefaultFont(FDefaultFont);
|
|
end;
|
|
Result := FDefaultFont;
|
|
end;
|
|
|
|
procedure TdxComponentPrinterThumbnailsOptions.RestoreDefaults;
|
|
begin
|
|
inherited;
|
|
Font := DefaultFont;
|
|
ShowPageNumbers := True;
|
|
end;
|
|
|
|
procedure TdxComponentPrinterThumbnailsOptions.InitializeDefaultFont(AFont: TFont);
|
|
begin
|
|
AFont.Color := dxPSDefaultPreviewThumbnailsFontColor;
|
|
AFont.Name := dxPSDefaultPreviewThumbnailsFontName;
|
|
AFont.Size := dxPSDefaultPreviewThumbnailsFontSize;
|
|
AFont.Style := dxPSDefaultPreviewThumbnailsFontStyle
|
|
end;
|
|
|
|
function TdxComponentPrinterThumbnailsOptions.IsFontStored: Boolean;
|
|
begin
|
|
Result := not dxPSUtl.dxAreFontsEqual(Font, DefaultFont);
|
|
end;
|
|
|
|
procedure TdxComponentPrinterThumbnailsOptions.SetFont(Value: TFont);
|
|
begin
|
|
Font.Assign(Value);
|
|
end;
|
|
|
|
procedure TdxComponentPrinterThumbnailsOptions.SetShowPageNumbers(Value: Boolean);
|
|
begin
|
|
if FShowPageNumbers <> Value then
|
|
begin
|
|
FShowPageNumbers := Value;
|
|
//TODO: TdxComponentPrinterThumbnailsOptions.SetShowPageNumbers
|
|
// if HasPreviewThumbnails then invalidate Preview.Thumbnails
|
|
end;
|
|
end;
|
|
|
|
{ TdxPreviewOptions }
|
|
|
|
constructor TdxPreviewOptions.Create;
|
|
begin
|
|
inherited;
|
|
FEnableOptions := dxDefaultPreviewEnableOptions;
|
|
FIcon := TIcon.Create;
|
|
FIcon.OnChange := IconChanged;
|
|
FSavePosition := True;
|
|
FSaveZoomPosition := True;
|
|
FThumbnailsOptions := TdxComponentPrinterThumbnailsOptions.Create(Self);
|
|
FWindowState := wsNormal;
|
|
FVisibleOptions := dxDefaultPreviewVisibleOptions;
|
|
end;
|
|
|
|
destructor TdxPreviewOptions.Destroy;
|
|
begin
|
|
FreeAndNil(FDefaultIcon);
|
|
FreeAndNil(FThumbnailsOptions);
|
|
FreeAndNil(FIcon);
|
|
inherited;
|
|
end;
|
|
|
|
function TdxPreviewOptions.DefaultCaption: string;
|
|
begin
|
|
Result := cxGetResourceString(@sdxPrintPreview);
|
|
end;
|
|
|
|
function TdxPreviewOptions.DefaultIcon: TIcon;
|
|
begin
|
|
if FDefaultIcon = nil then
|
|
begin
|
|
FDefaultIcon := TIcon.Create;
|
|
InitializeDefaultIcon(FDefaultIcon);
|
|
end;
|
|
Result := FDefaultIcon;
|
|
end;
|
|
|
|
function TdxPreviewOptions.DefaultRect: TRect;
|
|
begin
|
|
Result := dxPSUtl.GetDesktopWorkArea;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.RestoreOriginalIcon;
|
|
begin
|
|
//FIcon.Handle := 0;
|
|
FIsIconAssigned := False;
|
|
if ComponentPrinter <> nil then ComponentPrinter.DesignerModified;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
begin
|
|
Rect := MakeBounds(ALeft, ATop, AWidth, AHeight);
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited;
|
|
Filer.DefineBinaryProperty('PreviewBoundsRect', ReadBoundsRect, WriteBoundsRect,
|
|
IsBoundsStored);
|
|
Filer.DefineProperty('IsCaptionAssigned', ReadIsCaptionAssigned, WriteIsCaptionAssigned,
|
|
FIsCaptionAssigned and (Caption = ''));
|
|
Filer.DefineProperty('IsIconAssigned', ReadIsIconAssigned, WriteIsIconAssigned,
|
|
FIsIconAssigned and Icon.Empty);
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.DoAssign(Source: TdxBaseObject);
|
|
begin
|
|
inherited;
|
|
with TdxPreviewOptions(Source) do
|
|
begin
|
|
Self.Caption := Caption;
|
|
Self.EnableOptions := EnableOptions;
|
|
Self.HelpContext := HelpContext;
|
|
Self.HelpFile := HelpFile;
|
|
Self.Icon := Icon;
|
|
Self.Rect := Rect;
|
|
Self.SavePosition := SavePosition;
|
|
Self.SaveZoomPosition := SaveZoomPosition;
|
|
Self.ThumbnailsOptions := ThumbnailsOptions;
|
|
Self.WindowState := WindowState;
|
|
Self.VisibleOptions := VisibleOptions;
|
|
|
|
Self.FIsBoundsAssigned := FIsBoundsAssigned;
|
|
Self.FIsCaptionAssigned := FIsCaptionAssigned;
|
|
Self.FIsIconAssigned := FIsIconAssigned;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.DoRestoreDefaults;
|
|
begin
|
|
inherited;
|
|
FEnableOptions := dxDefaultPreviewEnableOptions;
|
|
|
|
FSavePosition := True;
|
|
FSaveZoomPosition := True;
|
|
ThumbnailsOptions.RestoreDefaults;
|
|
FWindowState := wsNormal;
|
|
FVisibleOptions := dxDefaultPreviewVisibleOptions;
|
|
|
|
FIsBoundsAssigned := False;
|
|
FIsCaptionAssigned := False;
|
|
FIsIconAssigned := False;
|
|
end;
|
|
|
|
function TdxPreviewOptions.GetIsIconAssigned: Boolean;
|
|
begin
|
|
Result := not dxPSUtl.dxAreGraphicsEqual(FIcon, DefaultIcon);
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.IconChanged(Sender: TObject);
|
|
begin
|
|
FIsIconAssigned := True;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.InitializeDefaultIcon(AnIcon: TIcon);
|
|
begin
|
|
Icon_LoadFromResourcename(AnIcon, IDB_DXPSPREVIEW);
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.RefreshIsIconAssigned;
|
|
begin
|
|
// FIsIconAssigned := dxPSUtl.dxAreGraphicsEqual(FIcon, DefaultIcon);
|
|
end;
|
|
|
|
function TdxPreviewOptions.GetCaption: string;
|
|
begin
|
|
if FIsCaptionAssigned then
|
|
Result := FCaption
|
|
else
|
|
Result := DefaultCaption;
|
|
end;
|
|
|
|
function TdxPreviewOptions.GetHelpFile: string;
|
|
begin
|
|
Result := dxPSEngine.HelpFile;
|
|
end;
|
|
|
|
function TdxPreviewOptions.GetIcon: TIcon;
|
|
begin
|
|
if FIsIconAssigned or ((ComponentPrinter <> nil) and (csLoading in ComponentPrinter.ComponentState)) then
|
|
Result := FIcon
|
|
else
|
|
Result := DefaultIcon;
|
|
end;
|
|
|
|
function TdxPreviewOptions.GetPosition(Index: Integer): Integer;
|
|
begin
|
|
with Rect do
|
|
case Index of
|
|
0: Result := Bottom - Top;
|
|
1: Result := Left;
|
|
2: Result := Top;
|
|
else
|
|
Result := Right - Left;
|
|
end;
|
|
end;
|
|
|
|
function TdxPreviewOptions.GetRect: TRect;
|
|
begin
|
|
if FIsBoundsAssigned then
|
|
Result := FRect
|
|
else
|
|
Result := DefaultRect;
|
|
end;
|
|
|
|
function TdxPreviewOptions.GetRegistryPath: string;
|
|
begin
|
|
Result := dxPSEngine.RealRegistryPath;
|
|
end;
|
|
|
|
function TdxPreviewOptions.IsBoundsStored: Boolean;
|
|
begin
|
|
Result := FIsBoundsAssigned and not EqualRect(FRect, DefaultRect);
|
|
end;
|
|
|
|
function TdxPreviewOptions.IsCaptionStored: Boolean;
|
|
begin
|
|
Result := FIsCaptionAssigned and (FCaption <> DefaultCaption);
|
|
end;
|
|
|
|
function TdxPreviewOptions.IsIconStored: Boolean;
|
|
begin
|
|
Result := FIsIconAssigned and not dxPSUtl.dxAreGraphicsEqual(FIcon, DefaultIcon);
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetEnableOptions(Value: TdxPreviewEnableOptions);
|
|
begin
|
|
if FEnableOptions <> Value then
|
|
begin
|
|
FEnableOptions := Value;
|
|
if HasPreviewWindow then
|
|
PreviewWindow.SetPreviewEnableOptions(FEnableOptions);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetCaption(const Value: string);
|
|
begin
|
|
if Caption <> Value then
|
|
begin
|
|
FCaption := Value;
|
|
FIsCaptionAssigned := True;
|
|
if HasPreviewWindow then PreviewWindow.Caption := Caption;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetHelpContext(Value: THelpContext);
|
|
begin
|
|
FHelpContext := Value;
|
|
if HasPreviewWindow then PreviewWindow.HelpContext := FHelpContext;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetHelpFile(const Value: string);
|
|
begin
|
|
dxPSEngine.HelpFile := Value;
|
|
if HasPreviewWindow then PreviewWindow.HelpFile := Value;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetIcon(Value: TIcon);
|
|
begin
|
|
FIcon.Assign(Value);
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetPosition(Index: Integer; Value: Integer);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := Self.Rect;
|
|
case Index of
|
|
0: R.Bottom := R.Top + Value;
|
|
1: R.Left := Value;
|
|
2: R.Top := Value;
|
|
3: R.Right := R.Left + Value;
|
|
end;
|
|
Self.Rect := R;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetRect(Value: TRect);
|
|
begin
|
|
with Value do
|
|
begin
|
|
if Right < Left then Right := Left;
|
|
if Bottom < Top then Bottom := Top;
|
|
end;
|
|
|
|
if not EqualRect(FRect, Value) then
|
|
begin
|
|
FRect := Value;
|
|
FIsBoundsAssigned := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetRegistryPath(const Value: string);
|
|
begin
|
|
dxPSEngine.RegistryPath := Value;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetShowExplorer(Value: Boolean);
|
|
begin
|
|
if FShowExplorer <> Value then
|
|
begin
|
|
FShowExplorer := Value;
|
|
if HasPreviewWindow then PreviewWindow.ShowExplorer := ShowExplorer;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetThumbnailsOptions(Value: TdxComponentPrinterThumbnailsOptions);
|
|
begin
|
|
ThumbnailsOptions.Assign(Value);
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetWindowState(Value: TWindowState);
|
|
begin
|
|
FWindowState := Value;
|
|
if HasPreviewWindow then PreviewWindow.WindowState := FWindowState;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.SetVisibleOptions(Value: TdxPreviewVisibleOptions);
|
|
begin
|
|
if FVisibleOptions <> Value then
|
|
begin
|
|
FVisibleOptions := Value;
|
|
if HasPreviewWindow then
|
|
PreviewWindow.SetPreviewVisibleOptions(FVisibleOptions);
|
|
end;
|
|
end;
|
|
|
|
function TdxPreviewOptions.HasPreviewWindow: Boolean;
|
|
begin
|
|
Result := (ComponentPrinter <> nil) and not ComponentPrinter.IsDesigning and
|
|
ComponentPrinter.PreviewExists;
|
|
end;
|
|
|
|
function TdxPreviewOptions.PreviewWindow: TBasedxPreviewWindow;
|
|
begin
|
|
Result := ComponentPrinter.PreviewWindow;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.ReadBoundsRect(Stream: TStream);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
Stream.ReadBuffer(R, SizeOf(R));
|
|
Rect := R;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.ReadIsCaptionAssigned(Reader: TReader);
|
|
begin
|
|
FIsCaptionAssigned := Reader.ReadBoolean;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.ReadIsIconAssigned(Reader: TReader);
|
|
begin
|
|
FIsIconAssigned := Reader.ReadBoolean;
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.WriteBoundsRect(Stream: TStream);
|
|
begin
|
|
Stream.WriteBuffer(FRect, SizeOf(TRect));
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.WriteIsCaptionAssigned(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(FIsCaptionAssigned);
|
|
end;
|
|
|
|
procedure TdxPreviewOptions.WriteIsIconAssigned(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(FIsIconAssigned);
|
|
end;
|
|
|
|
{ TdxPSComponentPrinterExplorerChangeNotifier }
|
|
|
|
constructor TdxPSComponentPrinterExplorerChangeNotifier.Create(AComponentPrinter: TCustomdxComponentPrinter);
|
|
begin
|
|
Assert(AComponentPrinter <> nil);
|
|
FComponentPrinter := AComponentPrinter;
|
|
inherited Create(nil);
|
|
end;
|
|
|
|
procedure TdxPSComponentPrinterExplorerChangeNotifier.ItemDataUnloaded(AnItem: TdxPSExplorerItem);
|
|
begin
|
|
if (AnItem.Explorer = Explorer) and (ComponentPrinter.CurrentLink <> nil) and not ComponentPrinter.IsDestroying then
|
|
begin
|
|
ComponentPrinter.CurrentLink.DataSource := rldsComponent;
|
|
ComponentPrinter.CurrentLink.FinalizeDataStream;
|
|
end;
|
|
end;
|
|
|
|
{ TCustomdxComponentPrinter }
|
|
|
|
constructor TCustomdxComponentPrinter.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
if AOwner <> nil then AOwner.FreeNotification(Self);
|
|
FAutoUpdateDateTime := True;
|
|
FBeepAfterLongOperations := True;
|
|
FCurrentLink := nil;
|
|
FDateFormat := 0;
|
|
FExplorerChangeNotifier := TdxPSComponentPrinterExplorerChangeNotifier.Create(Self);
|
|
FInternalStreaming := False;
|
|
FLongOperationTime := 5000;
|
|
FPageNumberFormat := pnfNumeral;
|
|
FReportLinkDesigner := nil;
|
|
FPreviewWindowDesigner := nil;
|
|
FPrintTitle := '';
|
|
FState := [];
|
|
FPreviewOptions := TdxPreviewOptions.Create;
|
|
FPreviewOptions.FComponentPrinter := Self;
|
|
FPrintFileList := TStringList.Create;
|
|
FOptions := dxDefaultCPOptions;
|
|
FReportLinks := TList.Create;
|
|
FSaveCopies := 1;
|
|
FSaveCollate := False;
|
|
FTimeFormat := 0;
|
|
FHFTextEntryChooseSubscriber := TdxHFTextEntryChooseSubscriber.Create([TdxHFTextEntryChooseEvent]);
|
|
TdxHFTextEntryChooseSubscriber(FHFTextEntryChooseSubscriber).OnHFTextEntryChoose := OnHFTextEntryChosen;
|
|
FWindowHandle := dxPSUtl.dxAllocatehWnd(WndProc);
|
|
FVersion := 0;
|
|
end;
|
|
|
|
destructor TCustomdxComponentPrinter.Destroy;
|
|
begin
|
|
{$IFNDEF DELPHI5}
|
|
Destroying;
|
|
{$ENDIF}
|
|
dxPSUtl.dxDeallocatehWnd(FWindowHandle);
|
|
FreeAndNil(FHFTextEntryChooseSubscriber);
|
|
FreeAndNil(FPrintFileList);
|
|
FreeAndNil(FPreviewWindowDesigner);
|
|
FreeAndNil(FReportLinkDesigner);
|
|
if not IsDesigning then DestroyPreviewWindow;
|
|
FreeAndNil(FPreviewOptions);
|
|
FreeAndNil(FExplorerChangeNotifier);
|
|
DeleteAllLinks;
|
|
FreeAndNil(FReportLinks);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.GetChildren(Proc: TGetChildProc; Root: TComponent);
|
|
var
|
|
I: Integer;
|
|
ReportLink: TBasedxReportLink;
|
|
begin
|
|
if not FInternalStreaming then
|
|
for I := 0 to LinkCount - 1 do
|
|
begin
|
|
ReportLink := Self.ReportLink[I];
|
|
if Root = ReportLink.Owner then Proc(ReportLink);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.Loaded;
|
|
begin
|
|
inherited;
|
|
PreviewOptions.RefreshIsIconAssigned;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.Notification(AComponent: TComponent; Operation: TOperation);
|
|
begin
|
|
inherited;
|
|
if Operation = opRemove then
|
|
begin
|
|
if AComponent = Explorer then Explorer := nil;
|
|
if AComponent = ExplorerStubLink then ExplorerStubLink := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetChildOrder(Child: TComponent; Order: Integer);
|
|
begin
|
|
inherited;
|
|
if FReportLinks.IndexOf(Child) > -1 then
|
|
(Child as TBasedxReportLink).Index := Order;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetName(const NewName: TComponentName);
|
|
var
|
|
AName: string;
|
|
OldName: string;
|
|
P, I: Integer;
|
|
Link: TBasedxReportLink;
|
|
begin
|
|
OldName := Name;
|
|
inherited SetName(NewName);
|
|
if IsDesigning and (LinkCount > 0) then
|
|
try
|
|
if ReportLinkDesigner <> nil then
|
|
ReportLinkDesigner.BeginUpdate;
|
|
try
|
|
for I := 0 to LinkCount - 1 do
|
|
begin
|
|
Link := ReportLink[I];
|
|
P := Pos(OldName, Link.Name);
|
|
if P = 0 then
|
|
AName := Name + Link.Name
|
|
else
|
|
AName := Copy(Link.Name, 1, P - 1) + Name +
|
|
Copy(Link.Name, P + Length(OldName), Length(Link.Name) - P - Length(OldName) + 1);
|
|
Link.Name := AName;
|
|
end;
|
|
finally
|
|
if ReportLinkDesigner <> nil then
|
|
ReportLinkDesigner.EndUpdate;
|
|
end;
|
|
except
|
|
on EComponentError do ; {Ignore rename errors }
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetExplorer(Value: TCustomdxPSExplorer);
|
|
begin
|
|
if FExplorer <> Value then
|
|
begin
|
|
FExplorer := Value;
|
|
if Explorer <> nil then
|
|
Explorer.FreeNotification(Self);
|
|
ExplorerChangeNotifier.Explorer := Explorer;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetExplorerStubLink(Value: TBasedxReportLink);
|
|
begin
|
|
if FExplorerStubLink <> Value then
|
|
if (Value = nil) or Value.CanBeUsedAsStub then
|
|
begin
|
|
FExplorerStubLink := Value;
|
|
if Value <> nil then
|
|
Value.FreeNotification(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetLongOperationTime(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if FLongOperationTime <> Value then
|
|
FLongOperationTime := Value;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetPreviewOptions(Value: TdxPreviewOptions);
|
|
begin
|
|
PreviewOptions.Assign(Value);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsCustomPrintDlgData: Boolean;
|
|
begin
|
|
Result := Assigned(FOnInitializePrintDlgData);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsForegroundPreviewWindow: Boolean;
|
|
begin
|
|
Result := (cpsPreviewing in State) and (PreviewWindow <> nil) and
|
|
(GetForegroundWindow = PreviewWindow.Handle);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsGenerateReportProgressEvent: Boolean;
|
|
begin
|
|
Result := not IsDesigning and not IsLoading and (cpoGenerateReportProgressEvent in Options);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsRebuildBeforeOutput(AForceRebuild: Boolean): Boolean;
|
|
begin
|
|
Result := AForceRebuild or IsDesigning;
|
|
if CurrentLink <> nil then
|
|
Result := Result or CurrentLink.RebuildNeeded or (CurrentLink.DataSource = rldsExternalStorage);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsRebuildBeforePreview: Boolean;
|
|
begin
|
|
Result := IsRebuildBeforeOutput(cpoAutoRebuildBeforePreview in Options);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsRebuildBeforePrint: Boolean;
|
|
begin
|
|
Result := IsRebuildBeforeOutput(cpoAutoRebuildBeforePrint in Options);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsShowHourGlass: Boolean;
|
|
begin
|
|
Result := cpoShowHourGlass in Options;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PaintThumbnailPage(ACanvas: TCanvas;
|
|
APageIndex: Integer; const APageBounds, AContentBounds: TRect;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink = nil then Exit;
|
|
|
|
AReportLink.PaintPage(ACanvas, APageBounds, APageIndex, APageIndex,
|
|
dxThumbnailsZoomFactors[PreviewWindow.ThumbnailsSize]);
|
|
|
|
if PreviewOptions.ThumbnailsOptions.ShowPageNumbers then
|
|
PaintThumbnailPageIndex(ACanvas, APageBounds, AReportLink.Renderer.PreparedPageIndex(APageIndex));
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PaintThumbnailPageIndex(ACanvas: TCanvas;
|
|
const R: TRect; APageIndex: Integer);
|
|
var
|
|
FontSize: Integer;
|
|
begin
|
|
with PreviewOptions.ThumbnailsOptions do
|
|
begin
|
|
FontSize := Font.Size;
|
|
if PreviewWindow.ThumbnailsSize = tsSmall then
|
|
Font.Size := Font.Size div 2;
|
|
dxPSUtl.DrawBlendedText(ACanvas, R, IntToStr(APageIndex + 1), Font);
|
|
Font.Size := FontSize;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.GetCurrentLinkIndex: Integer;
|
|
begin
|
|
if CurrentLink <> nil then
|
|
Result := CurrentLink.Index
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.GetExplorerRealStubLink: TBasedxReportLink;
|
|
begin
|
|
Result := FExplorerStubLink;
|
|
if Result = nil then
|
|
Result := AddEmptyLink(TBasedxReportLink);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.GetIsExplorerMode: Boolean;
|
|
begin
|
|
Result := cpsExplore in State;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.GetLinkCount: Integer;
|
|
begin
|
|
Result := FReportLinks.Count;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.GetPreviewCaption: string;
|
|
begin
|
|
if cpsExplore in State then
|
|
Result := cxGetResourceString(@sdxReportExplorer)
|
|
else
|
|
Result := PreviewOptions.Caption;
|
|
|
|
if (Explorer <> nil) and (Explorer.LoadedItem <> nil) then
|
|
Result := Result + ' ' + sdxDocumentCaptionSeparator + ' ' + Explorer.LoadedItem.FormCaption
|
|
else
|
|
if (CurrentLink <> nil) and (CurrentLink.DataSource = rldsExternalStorage) and (CurrentLink.StorageName <> '') then
|
|
Result := Result + ' ' + sdxDocumentCaptionSeparator + ' ' + CurrentLink.StorageName;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.GetReportLink(Index: Integer): TBasedxReportLink;
|
|
begin
|
|
Result := TBasedxReportLink(FReportLinks[Index]);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetAbortBuilding(Value: Boolean);
|
|
begin
|
|
FAbortBuilding := Value;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetAbortPrinting(Value: Boolean);
|
|
begin
|
|
FAbortPrinting := Value;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetAutoUpdateDateTime(Value: Boolean);
|
|
begin
|
|
if FAutoUpdateDateTime <> Value then
|
|
FAutoUpdateDateTime := Value;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetDateFormat(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if Value > dxPgsDlg.DateFormats.Count - 1 then
|
|
Value := dxPgsDlg.DateFormats.Count - 1;
|
|
if FDateFormat <> Value then
|
|
FDateFormat := Value;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetCurrentLink(Value: TBasedxReportLink);
|
|
begin
|
|
if (CurrentLink <> Value) and (IndexOfLink(Value) > -1) then
|
|
begin
|
|
if PreviewExists then DestroyPreviewWindow;
|
|
FCurrentLink := Value;
|
|
DoChangeCurrentLink;
|
|
FormatChanged(FCurrentLink);
|
|
DesignerUpdate(Value);//nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetCurrentLinkIndex(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if Value > LinkCount - 1 then
|
|
Value := LinkCount - 1;
|
|
if Value > -1 then
|
|
CurrentLink := ReportLink[Value];
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetPageNumberFormat(Value: TdxPageNumberFormat);
|
|
begin
|
|
if FPageNumberFormat <> Value then
|
|
FPageNumberFormat := Value;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetPrintFileList(Value: TStrings);
|
|
begin
|
|
FPrintFileList.Assign(Value);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetReportLink(Index: Integer; Value: TBasedxReportLink);
|
|
begin
|
|
ReportLink[Index].Assign(Value);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetTimeFormat(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if Value > dxPgsDlg.TimeFormats.Count - 1 then
|
|
Value := dxPgsDlg.TimeFormats.Count - 1;
|
|
if FTimeFormat <> Value then
|
|
FTimeFormat := Value;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.BeginPrintPages(const Source: string;
|
|
out APageIndexes: TIntegers): Boolean;
|
|
begin
|
|
Result := MakePageIndexes(Source, APageIndexes);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.EndPrintPages(var APageIndexes: TIntegers);
|
|
begin
|
|
SetLength(APageIndexes, 0);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.CreatePreviewWindow(AReportLink: TBasedxReportLink): TBasedxPreviewWindow;
|
|
var
|
|
PreviewClass: TdxPreviewWindowClass;
|
|
begin
|
|
Result := nil;
|
|
PreviewClass := GetPreviewClass;
|
|
if PreviewClass <> nil then
|
|
try
|
|
Result := PreviewClass.Create(nil);
|
|
Result.BeginUpdate;
|
|
try
|
|
Result.SetComponentPrinter(Self);
|
|
SetupPreviewProperties(Result);
|
|
Result.CreationComplete;
|
|
finally
|
|
Result.EndUpdate;
|
|
end;
|
|
except
|
|
FreeAndNil(Result);
|
|
raise;
|
|
end
|
|
else
|
|
raise EdxComponentPrinter.Create(cxGetResourceString(@sdxPreviewNotRegistered));
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DestroyPreviewWindow;
|
|
begin
|
|
if cpsPrinting in State then
|
|
AbortPrinting := True;
|
|
FreeAndNil(FPreviewWindow);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.FinalizeDefaultPrintDlgData(AReportLink: TBasedxReportLink;
|
|
var APrintDlgData: TdxPrintDlgData);
|
|
begin
|
|
FreeAndNil(APrintDlgData.DialogData.FileList);
|
|
DoFinalizePrintDlgData(AReportLink, APrintDlgData);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.InitializeDefaultPrintDlgData(AReportLink: TBasedxReportLink;
|
|
out APrintDlgData: TdxPrintDlgData);
|
|
const
|
|
BtnEnabledOn: TdxPrintDlgButtons = [pdbPreview, pdbPageSetup, pdbHelp];
|
|
BtnVisibleOn: TdxPrintDlgButtons = [pdbPreview, pdbPageSetup, pdbHelp];
|
|
OptEnabledOn: TdxPrintDlgOptions = [pdoCurrentPage];
|
|
OptVisibleOn: TdxPrintDlgOptions = [pdoCurrentPage];
|
|
begin
|
|
FillChar(APrintDlgData, SizeOf(TdxPrintDlgData), 0);
|
|
with APrintDlgData do
|
|
begin
|
|
DialogData.Collate := False;
|
|
DialogData.Copies := 1;
|
|
DialogData.FileList := TStringList.Create;
|
|
DialogData.FileList.Assign(PrintFileList);
|
|
DialogData.MaxRange := CurrentLink.PageCount; // (v2.2)
|
|
if DialogData.MaxRange = 0 then DialogData.MaxRange := -1;
|
|
DialogData.MinRange := 1;
|
|
if CurrentLink.PageCount = 0 then DialogData.MinRange := 0;
|
|
DialogData.PageCount := CurrentLink.PageCount;
|
|
DialogData.PageNums := pnAll;
|
|
DialogData.PageRanges := prAll;
|
|
if DialogData.PageCount > 0 then {v3.2}
|
|
DialogData.Pages := '1-' + IntToStr(DialogData.PageCount);
|
|
DialogData.PrintToFile := FSavePrintToFile;
|
|
if not IsDesigning and (not (cpsPreviewing in State) or (pvoPrintStyles in PreviewOptions.VisibleOptions)) then
|
|
DialogData.StyleManager := CurrentLink.StyleManager;
|
|
DialogData.PageCount := CurrentLink.PageCount;
|
|
|
|
Title := cxGetResourceString(@sdxPrintDialogCaption);
|
|
|
|
OptionsEnabled := pdoDefaultOptionsEnabled + OptEnabledOn;
|
|
OptionsVisible := pdoDefaultOptionsVisible + OptVisibleOn;
|
|
ButtonsEnabled := pdbDefault + BtnEnabledOn;
|
|
ButtonsVisible := pdbDefault + BtnVisibleOn;
|
|
if cpsPreviewing in State then
|
|
ButtonsVisible := ButtonsVisible - [pdbPreview];
|
|
|
|
Events.OnPageSetup := PrnDlgPageSetup;
|
|
IsCheckUserInput := True;
|
|
end;
|
|
DoInitializePrintDlgData(AReportLink, APrintDlgData);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.InitDevModeFromPrinterPageSettings(
|
|
APrinterPage: TdxPrinterPage);
|
|
begin
|
|
if (dxPrintDevice = nil) or (dxPrintDevice.DeviceMode = nil) then Exit;
|
|
dxPrintDevice.DeviceMode^.dmOrientation := Byte(APrinterPage.Orientation) + 1;
|
|
dxPrintDevice.DeviceMode^.dmColor := Byte(not APrinterPage.GrayShading) + 1;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.PrintDialog(AReportLink: TBasedxReportLink;
|
|
var APrintDlgData: TdxPrintDlgData): Boolean;
|
|
var
|
|
PreviewBtnClicked: Boolean;
|
|
begin
|
|
Include(FState, cpsPrintDialog);
|
|
try
|
|
Result := dxPrnDlg.dxPrintDialog(APrintDlgData);
|
|
PreviewBtnClicked := APrintDlgData.PreviewBtnClicked;
|
|
if Result then
|
|
begin
|
|
FSavePrintToFile := APrintDlgData.DialogData.PrintToFile;
|
|
PrintFileList := APrintDlgData.DialogData.FileList;
|
|
if AReportLink <> nil then
|
|
begin
|
|
AReportLink.PrinterPage.Orientation :=
|
|
TdxPrinterOrientation(dxPrintDevice.DeviceMode^.dmOrientation - 1);
|
|
AReportLink.PrinterPage.GrayShading :=
|
|
not Boolean(dxPrintDevice.DeviceMode^.dmColor - 1);
|
|
end;
|
|
if not PreviewBtnClicked then
|
|
with APrintDlgData.DialogData do
|
|
begin
|
|
if PrintToFile then
|
|
dxPrintDevice.FileName := FileName
|
|
else
|
|
dxPrintDevice.FileName := '';
|
|
FPrintAll := PageRanges = prAll;
|
|
if PageRanges in [prCurrent, prRange] then
|
|
begin
|
|
if PageRanges = prCurrent then
|
|
Pages := IntToStr(AReportLink.CurrentPage);
|
|
Result := PrintPagesAsStringEx(Pages, PageNums, Copies, Collate, AReportLink);
|
|
end
|
|
else // prAll
|
|
PrintEx(PageNums, Copies, Collate, AReportLink);
|
|
end;
|
|
end;
|
|
finally
|
|
FPrintAll := False;
|
|
Exclude(FState, cpsPrintDialog);
|
|
end;
|
|
|
|
if PreviewBtnClicked then Preview(True, AReportLink);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.PrintPagesAsStringEx(const APages: string;
|
|
APageNums: TdxPageNumbers; ACopyCount: Integer; ACollate: Boolean;
|
|
AReportLink: TBasedxReportLink = nil): Boolean;
|
|
var
|
|
PageIndexes: TIntegers;
|
|
begin
|
|
if BeginPrintPages(APages, PageIndexes) then
|
|
try
|
|
PrintPagesEx(PageIndexes, APageNums, ACopyCount, ACollate, AReportLink);
|
|
Result := True;
|
|
finally
|
|
EndPrintPages(PageIndexes);
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrnDlgPageSetup(Sender: TObject;
|
|
var ADone: Boolean; APreviewBtnClicked, APrintBtnClicked: PBoolean);
|
|
var
|
|
ShowPreviewBtn, ShowPrintBtn, PreviewBtnClicked, PrintBtnClicked: Boolean;
|
|
begin
|
|
ShowPreviewBtn := APreviewBtnClicked <> nil;
|
|
ShowPrintBtn := APrintBtnClicked <> nil;
|
|
ADone := (CurrentLink <> nil) and
|
|
PageSetupEx(0, ShowPreviewBtn, ShowPrintBtn, PreviewBtnClicked, PrintBtnClicked, CurrentLink);
|
|
if (ADone or PreviewBtnClicked) and PreviewExists then
|
|
begin
|
|
CurrentLink.CalculateRenderInfos;
|
|
with PreviewWindow do
|
|
begin
|
|
InitContent;
|
|
InvalidateContent;
|
|
UpdateControls;
|
|
end;
|
|
end;
|
|
|
|
if ShowPreviewBtn then
|
|
APreviewBtnClicked^ := PreviewBtnClicked;
|
|
|
|
if ShowPrintBtn then
|
|
APrintBtnClicked^ := PrintBtnClicked;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.RaiseBuildingEvent(AReportLink: TBasedxReportLink;
|
|
const APercentCompleted: Double; AStage: TdxPSBuildStage);
|
|
var
|
|
Event: TdxEvent;
|
|
begin
|
|
if CurrentCompositionByLink(AReportLink) <> nil then Exit;
|
|
Event := TdxPSBuildEvent.Create(Self, AReportLink, APercentCompleted, AStage);
|
|
dxPSProcessEvent(Event)
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.RaisePrintingEvent(AReportLink: TBasedxReportLink;
|
|
APageIndex, APageCount: Integer; AStage: TdxPSPrintStage);
|
|
var
|
|
Event: TdxEvent;
|
|
begin
|
|
Event := TdxPSPrintEvent.Create(Self, AReportLink, APageIndex, APageCount, AStage);
|
|
dxPSProcessEvent(Event);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.ActivateLink(AReportLink: TBasedxReportLink);
|
|
|
|
function IsCompositionActivatation(AComposition: TdxCompositionReportLink): Boolean;
|
|
begin
|
|
Result := (AComposition <> nil) and not (csRebuildReportLink in AComposition.CompositionState);
|
|
end;
|
|
|
|
var
|
|
Composition: TdxCompositionReportLink;
|
|
begin
|
|
Composition := CurrentCompositionByLink(AReportLink);
|
|
if (AReportLink is TdxCompositionReportLink) or (Composition = nil) or IsCompositionActivatation(Composition) then
|
|
begin
|
|
PrepareBuildReport(AReportLink);
|
|
PrepareLongOperation;
|
|
if AReportLink.CurrentPrintStyle is TdxPSPrintStyle then
|
|
TdxPSPrintStyle(AReportLink.CurrentPrintStyle).BeforeGenerating;
|
|
end;
|
|
try
|
|
if IsCompositionActivatation(Composition) then
|
|
Composition.ActivateLink(AReportLink)
|
|
else
|
|
AReportLink.InternalActivate;
|
|
|
|
if AutoUpdateDateTime then
|
|
if IsCompositionActivatation(Composition) and (Composition.DataSource = rldsComponent) then
|
|
Composition.DateTime := Now
|
|
else
|
|
if AReportLink.DataSource = rldsComponent then
|
|
AReportLink.DateTime := Now;
|
|
finally
|
|
if (AReportLink is TdxCompositionReportLink) or (Composition = nil) or IsCompositionActivatation(Composition) then
|
|
begin
|
|
if AReportLink.CurrentPrintStyle is TdxPSPrintStyle then
|
|
TdxPSPrintStyle(AReportLink.CurrentPrintStyle).AfterGenerating;
|
|
UnprepareLongOperation;
|
|
UnprepareBuildReport(AReportLink);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.CheckLink(Value: TBasedxReportLink): TBasedxReportLink;
|
|
begin
|
|
if Value <> nil then CurrentLink := Value;
|
|
Result := CurrentLink;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.CreateLink(ALinkClass: TdxReportLinkClass;
|
|
AComponent: TComponent; AOwner: TComponent): TBasedxReportLink;
|
|
var
|
|
LinkClass: TdxReportLinkClass;
|
|
begin
|
|
Result := nil;
|
|
LinkClass := ALinkClass;
|
|
if AComponent <> nil then
|
|
if IsSupportedCompClass(AComponent) then
|
|
LinkClass := dxPSLinkClassByCompClass(TComponentClass(AComponent.ClassType))
|
|
else
|
|
if IsDesigning then
|
|
raise EdxComponentPrinter.Create(cxGetResourceString(@sdxComponentNotSupported));
|
|
|
|
if LinkClass = nil then Exit;
|
|
|
|
Result := LinkClass.Create(AOwner);
|
|
if AComponent <> nil then
|
|
Result.Component := AComponent;
|
|
Result.SetComponentPrinter(Self);
|
|
DoAddReportLink(Result);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DeactivateLink(AReportLink: TBasedxReportLink);
|
|
begin
|
|
AReportLink.DoDestroyReport;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.InsertLink(Value: TBasedxReportLink);
|
|
begin
|
|
FReportLinks.Add(Value);
|
|
Value.FComponentPrinter := Self;
|
|
if LinkCount = 1 then Value.IsCurrentLink := True;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.MoveLink(ACurIndex, ANewIndex: Integer);
|
|
begin
|
|
FReportLinks.Move(ACurIndex, ANewIndex);
|
|
DesignerUpdate(nil);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.RemoveLink(Value: TBasedxReportLink);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
if not IsDestroying and (FCurrentLink = Value) then
|
|
begin
|
|
if PreviewExists then DestroyPreviewWindow;
|
|
Index := Value.Index;
|
|
end
|
|
else
|
|
Index := -1;
|
|
FReportLinks.Remove(Value);
|
|
Value.FComponentPrinter := nil;
|
|
if Index <> -1 then
|
|
ResyncCurrentLink(Index);
|
|
DoDeleteReportLink(Value);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.ResyncCurrentLink(AIndex: Integer);
|
|
begin
|
|
if AIndex > LinkCount - 1 then
|
|
AIndex := LinkCount - 1;
|
|
if AIndex < 0 then
|
|
begin
|
|
FCurrentLink := nil;
|
|
DoChangeCurrentLink;
|
|
end
|
|
else
|
|
CurrentLink := ReportLink[AIndex];
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.OnHFTextEntryChosen(Sender: TObject; const AEntry: string);
|
|
var
|
|
PagePart: TCustomdxPageObject;
|
|
Part1, Part2, Part3: string;
|
|
begin
|
|
if (CurrentLink <> nil) and (TdxPrintStyleManager(Sender) = CurrentLink.StyleManager) then
|
|
begin
|
|
if PreviewExists then
|
|
case PreviewWindow.State of
|
|
prsEditHeaders:
|
|
PagePart := CurrentLink.RealPrinterPage.PageHeader;
|
|
prsEditFooters:
|
|
PagePart := CurrentLink.RealPrinterPage.PageFooter;
|
|
else //prsNone
|
|
Exit;
|
|
end
|
|
else
|
|
PagePart := CurrentLink.RealPrinterPage.PageHeader;
|
|
|
|
if PagePart <> nil then
|
|
begin
|
|
dxPSSplitAutoHFTextEntry(AEntry, Part1, Part2, Part3);
|
|
if (Part2 = '') and (Part3 = '') then
|
|
PagePart.Titles[PreviewWindow.HFEditPart].Add(Part1)
|
|
else
|
|
with PagePart do
|
|
begin
|
|
if Part1 <> '' then LeftTitle.Add(Part1);
|
|
if Part2 <> '' then CenterTitle.Add(Part2);
|
|
if Part3 <> '' then RightTitle.Add(Part3);
|
|
end;
|
|
|
|
if PreviewExists then
|
|
case PreviewWindow.State of
|
|
prsEditHeaders:
|
|
PreviewWindow.InvalidatePagesHeaderContent;
|
|
prsEditFooters:
|
|
PreviewWindow.InvalidatePagesFooterContent;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DesignerModified;
|
|
begin
|
|
if ReportLinkDesigner <> nil then ReportLinkDesigner.Modified;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DesignerUpdate(AnItem: TBasedxReportLink);
|
|
begin
|
|
if ReportLinkDesigner <> nil then ReportLinkDesigner.Update(AnItem);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsDesigning: Boolean;
|
|
begin
|
|
Result := csDesigning in ComponentState;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsDestroying: Boolean;
|
|
begin
|
|
Result := csDestroying in ComponentState;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsLoading: Boolean;
|
|
begin
|
|
Result := csLoading in ComponentState;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.ShowExistingPreviewWindow;
|
|
const
|
|
Flags: array[Boolean] of UINT = (SW_SHOW, SW_RESTORE or SW_SHOWNORMAL);
|
|
var
|
|
WindowPlacement: TWindowPlacement;
|
|
Wnd: THandle;
|
|
begin
|
|
WindowPlacement.Length := SizeOf(WindowPlacement);
|
|
Wnd := PreviewWindow.Handle;
|
|
GetWindowPlacement(Wnd, @WindowPlacement);
|
|
ShowWindow(Wnd, Flags[WindowPlacement.ShowCmd = SW_SHOWMINIMIZED]);
|
|
SetForegroundWindow(Wnd);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.WndProc(var Message: TMessage);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with Message do
|
|
begin
|
|
case Msg of
|
|
WM_SETTINGCHANGE:
|
|
// if (PChar(message.lParam) = 'devices') then
|
|
begin
|
|
RereadDefaultPrinterPage;
|
|
for I := 0 to LinkCount - 1 do
|
|
TdxReportLinkPrinterPage(ReportLink[I].PrinterPage).SynchronizeMeasurementUnits;
|
|
DesignerModified;
|
|
end;
|
|
end;
|
|
Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.FormatChanged(AReportLink: TBasedxReportLink);
|
|
begin
|
|
dxHFFormatObject.DateFormat := dxPgsDlg.DateFormats[AReportLink.DateFormat];
|
|
dxHFFormatObject.DateTime := AReportLink.DateTime;
|
|
dxHFFormatObject.PageNumberFormat := AReportLink.PageNumberFormat;
|
|
dxHFFormatObject.StartPageIndex := AReportLink.StartPageIndex;
|
|
dxHFFormatObject.TimeFormat := dxPgsDlg.TimeFormats[AReportLink.TimeFormat];
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.AssignReportLinks(Source: TCustomdxComponentPrinter);
|
|
var
|
|
SaveOwner: TComponent;
|
|
I: Integer;
|
|
Link: TBasedxReportLink;
|
|
begin
|
|
if LinkCount > 0 then
|
|
SaveOwner := ReportLink[0].Owner
|
|
else
|
|
SaveOwner := Owner;
|
|
DeleteAllLinks;
|
|
if Source <> nil then
|
|
for I := 0 to Source.LinkCount - 1 do
|
|
begin
|
|
Link := Source.ReportLink[I];
|
|
with AddEmptyLinkEx(Link.LinkClass, SaveOwner) do
|
|
begin
|
|
Component := Link.Component;
|
|
Assign(Link);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.CreateLinkFromFile(const AFileName: string): TBasedxReportLink;
|
|
var
|
|
Stream: TFileStream;
|
|
begin
|
|
try
|
|
Stream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
Result := CreateLinkFromStream(Stream);
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
except
|
|
FreeAndNil(Result);
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.CreateLinkFromStream(AStream: TStream): TBasedxReportLink;
|
|
var
|
|
StorageInfo: TdxPSDataStorageInfo;
|
|
begin
|
|
try
|
|
StorageInfo := TBasedxReportLink.ExtractStorageInfo(AStream, False);
|
|
if StorageInfo.StorageVersion = dxPSStorageVersion then
|
|
if StorageInfo.LinkClass <> nil then
|
|
begin
|
|
Result := StorageInfo.LinkClass.Create(Self.Owner);
|
|
Result.InternalLoadDataFromStream(AStream);
|
|
end
|
|
else
|
|
raise EdxReportLink.CreateFmt(cxGetResourceString(@sdxLinkIsNotIncludedInUsesClause), [StorageInfo.LinkClassName])
|
|
else
|
|
raise EdxInvalidStorageVersion.Create(StorageInfo.StorageVersion);
|
|
except
|
|
FreeAndNil(Result);
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.AddComposition: TdxCompositionReportLink;
|
|
begin
|
|
Result := AddEmptyLinkEx(TdxCompositionReportLink, Self.Owner) as TdxCompositionReportLink;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.AddEmptyLink(ALinkClass: TdxReportLinkClass): TBasedxReportLink;
|
|
begin
|
|
Result := AddEmptyLinkEx(ALinkClass, Self.Owner);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.AddEmptyLinkEx(ALinkClass: TdxReportLinkClass;
|
|
AOwner: TComponent): TBasedxReportLink;
|
|
begin
|
|
Result := CreateLink(ALinkClass, nil, AOwner);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.AddLink(AComponent: TComponent): TBasedxReportLink;
|
|
begin
|
|
Result := AddLinkEx(AComponent, Self.Owner);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.AddLinkEx(AComponent: TComponent;
|
|
AOwner: TComponent): TBasedxReportLink;
|
|
begin
|
|
Result := CreateLink(nil, AComponent, AOwner);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DeleteAllLinks;
|
|
begin
|
|
while LinkCount > 0 do DeleteLink(LinkCount - 1);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DeleteLink(AIndex: Integer);
|
|
var
|
|
Link: TBasedxReportLink;
|
|
begin
|
|
if (AIndex > -1) and (AIndex < LinkCount) then
|
|
begin
|
|
Link := ReportLink[AIndex];
|
|
Link.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DestroyReport(AReportLink: TBasedxReportLink = nil);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then AReportLink.DestroyReport;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.FindLinkByComponent(Value: TComponent;
|
|
ACanCreate: Boolean = False): TBasedxReportLink;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Value <> nil then
|
|
for I := 0 to LinkCount - 1 do
|
|
begin
|
|
Result := ReportLink[I];
|
|
if Result.Component = Value then Exit;
|
|
end;
|
|
|
|
if ACanCreate then
|
|
Result := AddLink(Value)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.GetLinks(AList: TList);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to LinkCount - 1 do
|
|
AList.Add(ReportLink[I]);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IndexOfLink(AReportLink: TBasedxReportLink): Integer;
|
|
begin
|
|
Result := FReportLinks.IndexOf(AReportLink);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IndexOfLink(const AName: string): Integer;
|
|
begin
|
|
Result := IndexOfLinkByName(AName);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IndexOfLinkByName(const AName: string): Integer;
|
|
begin
|
|
Result := IndexOfLink(LinkByName(AName));
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.LinkByName(const AName: string): TBasedxReportLink;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to LinkCount - 1 do
|
|
begin
|
|
Result := ReportLink[I];
|
|
if Result.Name = AName then Exit;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.RebuildReport(AReportLink: TBasedxReportLink = nil);
|
|
begin
|
|
if AReportLink = nil then AReportLink := CurrentLink;
|
|
if AReportLink <> nil then AReportLink.RebuildReport;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.CurrentCompositionByLink(AReportLink: TBasedxReportLink): TdxCompositionReportLink;
|
|
var
|
|
I: Integer;
|
|
Link: TBasedxReportLink;
|
|
begin
|
|
for I := 0 to LinkCount - 1 do
|
|
begin
|
|
Link := ReportLink[I];
|
|
if (Link is TdxCompositionReportLink) and
|
|
TdxCompositionReportLink(Link).IsCurrentLink and
|
|
TdxCompositionReportLink(Link).Items.LinkExists(AReportLink) then
|
|
begin
|
|
Result := TdxCompositionReportLink(Link);
|
|
Exit;
|
|
end;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.GetCompositionsByLink(AReportLink: TBasedxReportLink;
|
|
ACompositions: TList);
|
|
var
|
|
I: Integer;
|
|
Link: TBasedxReportLink;
|
|
begin
|
|
for I := 0 to LinkCount - 1 do
|
|
begin
|
|
Link := ReportLink[I];
|
|
if (Link is TdxCompositionReportLink) and
|
|
TdxCompositionReportLink(Link).Items.LinkExists(AReportLink) then
|
|
ACompositions.Add(Link);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.GetItems(AComposition: TdxCompositionReportLink;
|
|
AStrings: TStrings; AExcludeAssigned: Boolean);
|
|
var
|
|
I: Integer;
|
|
Item: TBasedxReportLink;
|
|
begin
|
|
if AComposition.ComponentPrinter = Self then
|
|
begin
|
|
AStrings.BeginUpdate;
|
|
try
|
|
for I := 0 to LinkCount - 1 do
|
|
begin
|
|
Item := ReportLink[I];
|
|
if not (Item is TdxCompositionReportLink) and
|
|
(not AExcludeAssigned or not IsLinkInComposition(Item, AComposition)) then
|
|
AStrings.AddObject(Item.Caption, Item);
|
|
end;
|
|
finally
|
|
AStrings.EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsLinkInComposition(AReportLink: TBasedxReportLink;
|
|
AComposition: TdxCompositionReportLink): Boolean;
|
|
var
|
|
List: TList;
|
|
begin
|
|
List := TList.Create;
|
|
try
|
|
GetCompositionsByLink(AReportLink, List);
|
|
Result := List.IndexOf(AComposition) <> -1;
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.IsLinkInCurrentComposition(AReportLink: TBasedxReportLink): Boolean;
|
|
begin
|
|
Result := (CurrentLink is TdxCompositionReportLink) and
|
|
IsLinkInComposition(AReportLink, TdxCompositionReportLink(CurrentLink));
|
|
end;
|
|
|
|
class function TCustomdxComponentPrinter.GetNewLinkName(AReportLink: TBasedxReportLink): string;
|
|
begin
|
|
Result := sdxNewLinkNameTemplate;
|
|
end;
|
|
|
|
class function TCustomdxComponentPrinter.IsSupportedCompClass(AComponentClass: TClass): Boolean;
|
|
begin
|
|
Result := dxPSIsSupportedCompClass(AComponentClass);
|
|
end;
|
|
|
|
class function TCustomdxComponentPrinter.IsSupportedCompClass(AComponent: TObject{TComponent}): Boolean;
|
|
begin
|
|
Result := dxPSIsSupportedCompClass(AComponent);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PreparePageSetup;
|
|
begin
|
|
Include(FState, cpsPageSetupDialog);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.UnpreparePageSetup;
|
|
begin
|
|
Exclude(FState, cpsPageSetupDialog);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrepareBuildReport(AReportLink: TBasedxReportLink);
|
|
begin
|
|
Include(FState, cpsBuilding);
|
|
DoStartUpdateReport(AReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.UnprepareBuildReport(AReportLink: TBasedxReportLink);
|
|
begin
|
|
Exclude(FState, cpsBuilding);
|
|
DoEndUpdateReport(AReportLink);
|
|
if PreviewExists then
|
|
with PreviewWindow do
|
|
if PageCount <> AReportLink.PageCount then
|
|
begin
|
|
PageCount := AReportLink.PageCount;
|
|
ActivePageIndex := FSavePageIndex;
|
|
if (PageCount <> 0) and (ActivePageIndex = -1) then
|
|
ActivePageIndex := 0;
|
|
end
|
|
else
|
|
InvalidateContent;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrepareLongOperation;
|
|
begin
|
|
if IsDestroying then Exit;
|
|
if FLongOperationCounter = 0 then
|
|
begin
|
|
FStartTime := GetTickCount;
|
|
if IsShowHourGlass then dxPSStartWait;
|
|
end;
|
|
Inc(FLongOperationCounter);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.UnprepareLongOperation;
|
|
begin
|
|
if IsDestroying then Exit;
|
|
if FLongOperationCounter <> 0 then
|
|
begin
|
|
Dec(FLongOperationCounter);
|
|
if FLongOperationCounter = 0 then
|
|
begin
|
|
if IsShowHourGlass then
|
|
dxPSStopWait;
|
|
if BeepAfterLongOperations then
|
|
begin
|
|
FEndTime := GetTickCount;
|
|
if FEndTime - FStartTime > DWORD(LongOperationTime) then Beep;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.LoadFromFile(const AName: string);
|
|
var
|
|
Stream: TFileStream;
|
|
begin
|
|
if (AName <> '') and FileExists(AName) then
|
|
begin
|
|
Stream := TFileStream.Create(AName, fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
LoadFromStream(Stream);
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.LoadFromStream(AStream: TStream);
|
|
var
|
|
Version: Integer;
|
|
begin
|
|
LoadVersionFromStream(AStream, Version);
|
|
if Version <> Self.Version then Exit;
|
|
|
|
PrepareLoadFromStream(AStream);
|
|
try
|
|
BeforeLoadFromStream(AStream);
|
|
try
|
|
try
|
|
LoadLinksFromStream(AStream);
|
|
LoadItselfFromStream(AStream);
|
|
except
|
|
ErrorLoadFromStream(AStream);
|
|
end;
|
|
finally
|
|
AfterLoadFromStream(AStream);
|
|
end;
|
|
finally
|
|
UnprepareLoadFromStream(AStream);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.AfterLoadFromStream(AStream: TStream);
|
|
begin
|
|
FMemoryStream.Free;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SaveToFile(const AName: string);
|
|
var
|
|
Stream: TFileStream;
|
|
begin
|
|
if ValidateFileName(AName) then
|
|
begin
|
|
Stream := TFileStream.Create(AName, fmCreate);
|
|
try
|
|
SaveToStream(Stream);
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SaveToStream(AStream: TStream);
|
|
begin
|
|
PrepareSaveToStream(AStream);
|
|
try
|
|
SaveVersionToStream(AStream);
|
|
SaveLinksToStream(AStream);
|
|
SaveItselfToStream(AStream);
|
|
finally
|
|
UnprepareSaveToStream(AStream);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoCustomDrawEntirePage(AReportLink: TBasedxReportLink;
|
|
ACanvas: TCanvas; APageIndex: Integer; ARect: TRect; ANom, ADenom: Integer);
|
|
begin
|
|
if Assigned(FOnCustomDrawPage) then
|
|
FOnCustomDrawPage(Self, AReportLink, ACanvas, APageIndex, ARect, ANom, ADenom);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoNewPage(AReportLink: TBasedxReportLink;
|
|
APageIndex: Integer);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then
|
|
begin
|
|
if Assigned(FOnNewPage) then FOnNewPage(Self, AReportLink, APageIndex);
|
|
RaisePrintingEvent(AReportLink, APageIndex, 0, psProgress);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoEndPrint(AReportLink: TBasedxReportLink);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then
|
|
begin
|
|
if Assigned(FOnEndPrint) then FOnEndPrint(Self, AReportLink);
|
|
RaisePrintingEvent(AReportLink, 0, 0, psEnd);
|
|
end;
|
|
AbortPrinting := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoStartPrint(AReportLink: TBasedxReportLink;
|
|
FullPageCount: Integer);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then
|
|
begin
|
|
if Assigned(FOnStartPrint) then FOnStartPrint(Self, AReportLink, FullPageCount);
|
|
RaisePrintingEvent(AReportLink, 0, FullPageCount, psStart);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoAddReportLink(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if not IsLoading and not FInternalStreaming then
|
|
if Assigned(FOnAddReportLink) then FOnAddReportLink(Self, AReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoAfterPreview(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if cpoDropStorageModeAfterPreview in Options then
|
|
AReportLink.DataSource := rldsComponent;
|
|
if Assigned(FOnAfterPreview) then FOnAfterPreview(Self, AReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoBeforeDesignReport(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if Assigned(FOnBeforeDesignReport) then
|
|
FOnBeforeDesignReport(Self, AReportLink, AReportLink.DesignWindow);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoBeforeDestroyReport(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if PreviewExists then
|
|
begin
|
|
FSavePageIndex := PreviewWindow.ActivePageIndex;
|
|
PreviewWindow.PageCount := 0;
|
|
end
|
|
else
|
|
FSavePageIndex := -1;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoBeforePreview(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if (PreviewWindow <> nil) and Assigned(FOnBeforePreview) then
|
|
FOnBeforePreview(Self, AReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoChangeComponent(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if not IsLoading and Assigned(FOnChangeComponent) then
|
|
FOnChangeComponent(Self, AReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoChangeCurrentLink;
|
|
begin
|
|
if not IsLoading and not IsDestroying and Assigned(FOnChangeCurrentLink) then
|
|
FOnChangeCurrentLink(Self);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoDeleteReportLink(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if not IsLoading then
|
|
if Assigned(FOnDeleteReportLink) then FOnDeleteReportLink(Self, AReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoFinalizePrintDlgData(AReportLink: TBasedxReportLink;
|
|
var APrintDlgData: TdxPrintDlgData);
|
|
begin
|
|
if Assigned(FOnFinalizePrintDlgData) then
|
|
FOnFinalizePrintDlgData(Self, AReportLink, APrintDlgData);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoInitializePrintDlgData(AReportLink: TBasedxReportLink;
|
|
var APrintDlgData: TdxPrintDlgData);
|
|
begin
|
|
if Assigned(FOnInitializePrintDlgData) then
|
|
FOnInitializePrintDlgData(Self, AReportLink, APrintDlgData);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoMeasureReportTitle(AReportLink: TBasedxReportLink;
|
|
var AHeight: Integer);
|
|
begin
|
|
if Assigned(FOnMeasureReportTitle) then
|
|
FOnMeasureReportTitle(Self, AReportLink, AHeight);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoDesignReport(AReportLink: TBasedxReportLink;
|
|
ADone: Boolean);
|
|
begin
|
|
if Assigned(FOnDesignReport) then
|
|
FOnDesignReport(Self, AReportLink, ADone);
|
|
|
|
if ADone then
|
|
with AReportLink do
|
|
if DesignWindow.Modified and not DesignWindow.Applyed and IsRebuildNeededAndAllowed(False) then
|
|
RebuildReport;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoPrintDeviceBusy;
|
|
var
|
|
Done: Boolean;
|
|
begin
|
|
Done := False;
|
|
if Assigned(FOnPrintDeviceBusy) then FOnPrintDeviceBusy(Self, Done);
|
|
if not Done then StdProcessPrintDeviceBusy;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.StdProcessPrintDeviceBusy;
|
|
begin
|
|
MessageError(cxGetResourceString(@sdxPrintDeviceIsBusy));
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoPrintDeviceError;
|
|
var
|
|
Done: Boolean;
|
|
begin
|
|
Done := False;
|
|
if Assigned(FOnPrintDeviceError) then FOnPrintDeviceError(Self, Done);
|
|
if not Done then StdProcessPrintDeviceError;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.StdProcessPrintDeviceError;
|
|
begin
|
|
MessageError(cxGetResourceString(@sdxPrintDeviceError));
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoPageParamsChanged(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if cpsPreviewing in State then
|
|
begin
|
|
PreviewWindow.InitContent;
|
|
PreviewWindow.UpdateControls;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoPageSetup(AReportLink: TBasedxReportLink;
|
|
ADone: Boolean);
|
|
begin
|
|
if Assigned(FOnPageSetup) then FOnPageSetup(Self, AReportLink, ADone);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoProgress(AReportLink: TBasedxReportLink;
|
|
const PercentDone: Double);
|
|
|
|
procedure ProcessKeyboardMessages;
|
|
var
|
|
Msg: TMsg;
|
|
begin
|
|
while PeekMessage(Msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE) do
|
|
begin
|
|
case Integer(GetMessage(Msg, 0, WM_KEYFIRST, WM_KEYLAST)) of
|
|
-1: Break;
|
|
0: begin
|
|
PostQuitMessage(Msg.wParam);
|
|
Break;
|
|
end;
|
|
end;
|
|
DispatchMessage(Msg);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if IsGenerateReportProgressEvent then
|
|
if Assigned(FOnGenerateReportProgress) then FOnGenerateReportProgress(Self, AReportLink, PercentDone);
|
|
ProcessKeyboardMessages;
|
|
//Delay(20);
|
|
RaiseBuildingEvent(AReportLink, PercentDone, bsProgress);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoStartUpdateReport(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if IsGenerateReportProgressEvent then
|
|
if Assigned(FOnStartGenerateReport) then FOnStartGenerateReport(Self, AReportLink);
|
|
RaiseBuildingEvent(AReportLink, 0, bsStart);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoEndUpdateReport(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if IsGenerateReportProgressEvent then
|
|
if Assigned(FOnEndGenerateReport) then FOnEndGenerateReport(Self, AReportLink);
|
|
RaiseBuildingEvent(AReportLink, 0, bsEnd);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.GetPrintTitle(AReportLink: TBasedxReportLink): string;
|
|
begin
|
|
Result := FPrintTitle;
|
|
if Assigned(FOnGetPrintTitle) then
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then FOnGetPrintTitle(Self, AReportLink, Result);
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.PreviewExists: Boolean;
|
|
begin
|
|
Result := (PreviewWindow <> nil) and (cpsPreviewing in State);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SetupPreviewProperties(APreviewWindow: TBasedxPreviewWindow);
|
|
|
|
function GetCaption: string;
|
|
begin
|
|
if IsExplorerMode then
|
|
Result := cxGetResourceString(@sdxReportExplorer)
|
|
else
|
|
Result := PreviewOptions.Caption;
|
|
end;
|
|
|
|
begin
|
|
if not IsDesigning then
|
|
begin
|
|
{$IFDEF DELPHI9}
|
|
APreviewWindow.PopupMode := pmAuto;
|
|
{$ENDIF}
|
|
if not APreviewWindow.AreBoundsAssigned then
|
|
APreviewWindow.BoundsRect := PreviewOptions.Rect;
|
|
APreviewWindow.EnableOptions := PreviewOptions.EnableOptions;
|
|
APreviewWindow.HelpContext := PreviewOptions.HelpContext;
|
|
APreviewWindow.HelpFile := PreviewOptions.HelpFile;
|
|
APreviewWindow.VisibleOptions := PreviewOptions.VisibleOptions;
|
|
if not APreviewWindow.AreBoundsAssigned then
|
|
APreviewWindow.WindowState := PreviewOptions.WindowState;
|
|
end;
|
|
APreviewWindow.Caption := GetCaption;
|
|
APreviewWindow.Icon := PreviewOptions.Icon;
|
|
APreviewWindow.SaveZoomPosition := PreviewOptions.SaveZoomPosition;
|
|
APreviewWindow.ShowExplorer := PreviewOptions.ShowExplorer;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.Preview(AModal: Boolean = True;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink = nil then Exit;
|
|
|
|
if not PreviewExists then
|
|
begin
|
|
if AReportLink.DataProviderPresent and (IsDesigning or IsRebuildBeforePreview) then
|
|
begin
|
|
try
|
|
RebuildReport(AReportLink);
|
|
if AbortBuilding then Exit;
|
|
except
|
|
if Explorer <> nil then
|
|
begin
|
|
with Explorer do
|
|
begin
|
|
if LoadedItem <> nil then
|
|
DoItemDataLoadError(LoadedItem);
|
|
FLoadedItem := nil; //!!!
|
|
end;
|
|
if not (cpsExplore in State) then Exit;
|
|
end;
|
|
end;
|
|
DesignerModified;
|
|
end
|
|
else
|
|
if AutoUpdateDateTime then AReportLink.DateTime := Now;
|
|
|
|
if Explorer <> nil then Explorer.Refresh;
|
|
InitDevModeFromPrinterPageSettings(AReportLink.PrinterPage);
|
|
FPreviewWindow := CreatePreviewWindow(AReportLink);
|
|
if IsExplorerMode and (PreviewWindow <> nil) then
|
|
PreviewWindow.ExplorerTree.MakeItemVisible(Explorer.LoadedItem);
|
|
Include(FState, cpsPreviewing);
|
|
DoBeforePreview(AReportLink);
|
|
FModalPreview := AModal;
|
|
if AModal then
|
|
try
|
|
FPreviewWindow.ShowModal;
|
|
finally
|
|
DoAfterPreview(AReportLink);
|
|
FreeAndNil(FPreviewWindow);
|
|
end
|
|
else
|
|
FPreviewWindow.Show;
|
|
end
|
|
else
|
|
ShowExistingPreviewWindow;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PaintPage(ACanvas: TCanvas;
|
|
APageIndex: Integer; const APageBounds, AContentBounds: TRect;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
var
|
|
ZoomFactor: Integer;
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink = nil then Exit;
|
|
|
|
ZoomFactor := 100;
|
|
if (PreviewWindow <> nil) and IsDisplayDC(ACanvas.Handle) then
|
|
ZoomFactor := PreviewWindow.ZoomFactor;
|
|
|
|
AReportLink.PaintPage(ACanvas, APageBounds, APageIndex, APageIndex, ZoomFactor);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoCustomDrawReportTitle(AReportLink: TBasedxReportLink;
|
|
ACanvas: TCanvas; ARect: TRect; var ATextAlignX: TdxTextAlignX;
|
|
var ATextAlignY: TdxTextAlignY; var AColor: TColor; AFont: TFont;
|
|
var ADone: Boolean; APixelsNumerator: Integer = 0);
|
|
begin
|
|
if Assigned(FOnCustomDrawReportTitle) then
|
|
begin
|
|
if APixelsNumerator = 0 then
|
|
APixelsNumerator := PixelsNumerator;
|
|
FOnCustomDrawReportTitle(Self, AReportLink, ACanvas, ARect, APixelsNumerator,
|
|
PixelsDenominator, ATextAlignX, ATextAlignY, AColor, AFont, ADone);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DoCustomDrawPageHeaderOrFooter(
|
|
AReportLink: TBasedxReportLink; AHFObject: TCustomdxPageObject;
|
|
ACanvas: TCanvas; APageIndex: Integer; R: TRect;
|
|
var ADefaultDrawText, ADefaultDrawBackground: Boolean;
|
|
APixelsNumerator: Integer = 0);
|
|
begin
|
|
if APixelsNumerator = 0 then
|
|
APixelsNumerator := PixelsNumerator;
|
|
if AHFObject is TdxPageHeader then
|
|
begin
|
|
if Assigned(FOnCustomDrawPageHeader) then
|
|
FOnCustomDrawPageHeader(Self, AReportLink, ACanvas, APageIndex, R,
|
|
APixelsNumerator, PixelsDenominator, ADefaultDrawText, ADefaultDrawBackground)
|
|
end
|
|
else
|
|
if Assigned(FOnCustomDrawPageFooter) then
|
|
FOnCustomDrawPageFooter(Self, AReportLink, ACanvas, APageIndex, R,
|
|
APixelsNumerator, PixelsDenominator, ADefaultDrawText, ADefaultDrawBackground);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrintPage(AReportLink: TBasedxReportLink;
|
|
APageIndex: Integer);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if AbortPrinting then Exit;
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink = nil then Exit;
|
|
|
|
with dxPrintDevice do
|
|
begin
|
|
R := MakeBounds(0, 0, PageWidth, PageHeight);
|
|
InflateRect(R, PhysOffsetX, PhysOffsetY);
|
|
end;
|
|
PaintPage(dxPrintDevice.Canvas, APageIndex, R, R, AReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrintPages(const APageIndexes: array of Integer;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
begin
|
|
PrintPagesEx(APageIndexes, pnAll, 1, False, AReportLink);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrintPagesEx(const APageIndexes: array of Integer;
|
|
APageNums: TdxPageNumbers; ACopyCount: Integer; ACollate: Boolean;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
|
|
function GetTotalPageCount: Integer;
|
|
begin
|
|
Result := ACopyCount * Length(APageIndexes);
|
|
if APageNums <> pnAll then
|
|
begin
|
|
if (APageNums = pnOdd) and Odd(Result) then
|
|
Inc(Result);
|
|
Result := Result div 2;
|
|
end;
|
|
end;
|
|
|
|
procedure GetActualPageIndexes(out AnActualPageIndexes: TIntegers);
|
|
|
|
function AreAllPagesInRange: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if FPrintAll then
|
|
Result := True
|
|
else
|
|
begin
|
|
Result := Length(APageIndexes) = AReportLink.PageCount;
|
|
if Result then
|
|
for I := 1 to AReportLink.PageCount do
|
|
begin
|
|
Result := APageIndexes[I - 1] = I;
|
|
if not Result then Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
IsRecombineNeeded: Boolean;
|
|
ColCount, RowCount, I, J, K: Integer;
|
|
begin
|
|
SetLength(AnActualPageIndexes, Length(APageIndexes));
|
|
IsRecombineNeeded := AReportLink.RealPrinterPage.PageOrder = poDownThenOver;
|
|
if IsRecombineNeeded then
|
|
begin
|
|
AReportLink.GetPageColRowCount(ColCount, RowCount);
|
|
IsRecombineNeeded := (ColCount <> 1) and (RowCount <> 1) and AreAllPagesInRange;
|
|
end;
|
|
|
|
if IsRecombineNeeded then
|
|
begin
|
|
K := 0;
|
|
for I := 0 to ColCount - 1 do
|
|
for J := 0 to RowCount - 1 do
|
|
begin
|
|
AnActualPageIndexes[K] := APageIndexes[I + J * ColCount];
|
|
Inc(K);
|
|
end;
|
|
end
|
|
else
|
|
for I := 0 to Length(APageIndexes) - 1 do
|
|
AnActualPageIndexes[I] := APageIndexes[I];
|
|
end;
|
|
|
|
function CanPrintPage(AIndex, APageIndex: Integer): Boolean;
|
|
begin
|
|
Result := not ((APageIndex < 0) or
|
|
(APageIndex > AReportLink.PageCount - 1) or
|
|
((APageNums = pnEven) and not Odd(AIndex)) or
|
|
((APageNums = pnOdd) and Odd(AIndex)));
|
|
end;
|
|
|
|
procedure DoPrintPage(var ACurrentPage: Integer; APageIndex: Integer);
|
|
begin
|
|
if ACurrentPage > 0 then
|
|
begin
|
|
DoNewPage(AReportLink, ACurrentPage);
|
|
dxPrintDevice.NewPage;
|
|
end;
|
|
if Application.Terminated then AbortPrinting := True;
|
|
if not AbortPrinting then PrintPage(AReportLink, APageIndex);
|
|
Inc(ACurrentPage);
|
|
end;
|
|
|
|
var
|
|
CurrentPage, Index, PageIndex, CopyIndex: Integer;
|
|
ActualPageIndexes: TIntegers;
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
|
|
if (AReportLink = nil) or not AReportLink.DataProviderPresent then Exit;
|
|
|
|
PrepareReport(AReportLink);
|
|
try
|
|
if AbortBuilding or (AReportLink.PageCount = 0) then Exit;
|
|
|
|
dxInitPrintDevice(True);
|
|
if dxPrintDevice.Printing then
|
|
begin
|
|
DoPrintDeviceBusy;
|
|
Exit;
|
|
end;
|
|
|
|
if not AReportLink.ValidateMargins then Exit;
|
|
|
|
if ACopyCount < 1 then ACopyCount := 1;
|
|
GetActualPageIndexes(ActualPageIndexes);
|
|
|
|
AReportLink.BeforePrinting;
|
|
try
|
|
try
|
|
Include(FState, cpsPrinting);
|
|
try
|
|
PreparePrintDevice;
|
|
try
|
|
dxPrintDevice.Title := GetPrintTitle(AReportLink);
|
|
if dxPrintDevice.BeginDoc > 0 then
|
|
try
|
|
DoStartPrint(AReportLink, GetTotalPageCount);
|
|
|
|
CurrentPage := 0;
|
|
if not ACollate and (ACopyCount > 1) then
|
|
for Index := 0 to Length(ActualPageIndexes) - 1 do
|
|
begin
|
|
PageIndex := ActualPageIndexes[Index] - 1;
|
|
if not CanPrintPage(Index, PageIndex) then Continue;
|
|
for CopyIndex := 1 to ACopyCount do
|
|
begin
|
|
DoPrintPage(CurrentPage, PageIndex);
|
|
if AbortPrinting then Break;
|
|
end;
|
|
if AbortPrinting then Break;
|
|
end
|
|
else
|
|
for CopyIndex := 1 to ACopyCount do
|
|
begin
|
|
for Index := 0 to Length(ActualPageIndexes) - 1 do
|
|
begin
|
|
PageIndex := ActualPageIndexes[Index] - 1;
|
|
if not CanPrintPage(Index, PageIndex) then Continue;
|
|
DoPrintPage(CurrentPage, PageIndex);
|
|
if AbortPrinting then Break;
|
|
end;
|
|
if AbortPrinting then Break;
|
|
end;
|
|
finally
|
|
if dxPrintDevice.Printing then
|
|
if AbortPrinting then
|
|
dxPrintDevice.Abort
|
|
else
|
|
dxPrintDevice.EndDoc;
|
|
DoEndPrint(AReportLink);
|
|
end
|
|
else
|
|
if (dxPrintDevice.CurrentPort = nil) or
|
|
(StrIComp(dxPrintDevice.CurrentPort, sdxFilePort) <> 0) then
|
|
DoPrintDeviceError;
|
|
finally
|
|
UnpreparePrintDevice;
|
|
end;
|
|
finally
|
|
Exclude(FState, cpsPrinting);
|
|
end;
|
|
except
|
|
if dxPrintDevice.Printing then
|
|
try
|
|
dxPrintDevice.Abort;
|
|
except
|
|
Application.HandleException(Self);
|
|
end;
|
|
DoPrintDeviceError;
|
|
end;
|
|
finally
|
|
AReportLink.AfterPrinting;
|
|
end;
|
|
finally
|
|
UnprepareReport(AReportLink);
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.Print(AShowDialog: Boolean;
|
|
APPrintDlgData: PdxPrintDlgData;
|
|
AReportLink: TBasedxReportLink = nil): Boolean;
|
|
|
|
function GetPrintDlgData(AReportLink: TBasedxReportLink): TdxPrintDlgData;
|
|
begin
|
|
if APPrintDlgData <> nil then
|
|
Result := APPrintDlgData^
|
|
else
|
|
InitializeDefaultPrintDlgData(AReportLink, Result);
|
|
end;
|
|
|
|
procedure DonePrintDlgData(AReportLink: TBasedxReportLink; var APrintDlgData: TdxPrintDlgData);
|
|
begin
|
|
if APPrintDlgData = nil then
|
|
FinalizeDefaultPrintDlgData(AReportLink, APrintDlgData);
|
|
end;
|
|
|
|
var
|
|
PrintDlgData: TdxPrintDlgData;
|
|
begin
|
|
Result := False;
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink = nil then Exit;
|
|
InitDevModeFromPrinterPageSettings(AReportLink.PrinterPage);
|
|
try
|
|
if not AShowDialog then
|
|
begin
|
|
PrepareReport(AReportLink);
|
|
PrintDlgData := GetPrintDlgData(AReportLink);
|
|
try
|
|
if not AbortBuilding and (AReportLink.PageCount > 0) then
|
|
with PrintDlgData.DialogData do
|
|
Result := PrintPagesAsStringEx(Pages, PageNums, Copies, Collate, AReportLink)
|
|
else
|
|
Result := False;
|
|
finally
|
|
UnprepareReport(AReportLink);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
PrintDlgData := GetPrintDlgData(AReportLink);
|
|
Result := PrintDialog(AReportLink, PrintDlgData);
|
|
end;
|
|
finally
|
|
DonePrintDlgData(AReportLink, PrintDlgData);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrepareReport(AReportLink: TBasedxReportLink);
|
|
begin
|
|
if not AReportLink.FPrepared then
|
|
if AReportLink.DataProviderPresent then
|
|
begin
|
|
if not PreviewExists and (IsDesigning or IsRebuildBeforePrint) then
|
|
begin
|
|
RebuildReport(AReportLink);
|
|
DesignerModified;
|
|
end
|
|
else
|
|
if AutoUpdateDateTime then AReportLink.DateTime := Now;
|
|
|
|
AReportLink.FPrepared := True;
|
|
end
|
|
else
|
|
AReportLink.FPrepared := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.UnprepareReport(AReportLink: TBasedxReportLink);
|
|
begin
|
|
AReportLink.FPrepared := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.BeforeLoadFromStream(AStream: TStream);
|
|
begin
|
|
FMemoryStream := TMemoryStream.Create;
|
|
SaveToStream(FMemoryStream);
|
|
DeleteAllLinks;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.ErrorLoadFromStream(AStream: TStream);
|
|
begin
|
|
DeleteAllLinks;
|
|
FMemoryStream.Position := 0;
|
|
LoadFromStream(FMemoryStream);
|
|
Application.HandleException(Self);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrepareLoadFromStream(AStream: TStream);
|
|
begin
|
|
FInternalStreaming := True;
|
|
Include(FState, cpsLoading);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.UnprepareLoadFromStream(AStream: TStream);
|
|
begin
|
|
Exclude(FState, cpsLoading);
|
|
FInternalStreaming := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.LoadItselfFromStream(AStream: TStream);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AStream.ReadComponent(Self);
|
|
Loaded;
|
|
for I := 0 to LinkCount - 1 do
|
|
ReportLink[I].Loaded;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.LoadLinksFromStream(AStream: TStream);
|
|
var
|
|
Count, I: Integer;
|
|
Links: TList;
|
|
begin
|
|
AStream.ReadBuffer(Count, SizeOf(Count));
|
|
|
|
Links := TList.Create;
|
|
try
|
|
Links.Count := Count;
|
|
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Links[I] := AStream.ReadComponent(nil);
|
|
Owner.InsertComponent(TComponent(Links[I]));
|
|
end;
|
|
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
TBasedxReportLink(Links[I]).ComponentPrinter := Self;
|
|
if TObject(Links[I]) is TdxCompositionReportLink then
|
|
TdxCompositionReportLink(Links[I]).Items.CorrectLinksAfterLoadings;
|
|
end;
|
|
finally
|
|
Links.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.LoadVersionFromStream(AStream: TStream; var AVersion: Integer);
|
|
begin
|
|
AStream.ReadBuffer(AVersion , SizeOf(AVersion));
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrepareSaveToStream(AStream: TStream);
|
|
begin
|
|
FInternalStreaming := True;
|
|
Include(FState, cpsSaving);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.UnprepareSaveToStream(AStream: TStream);
|
|
begin
|
|
Exclude(FState, cpsSaving);
|
|
FInternalStreaming := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SaveItselfToStream(AStream: TStream);
|
|
begin
|
|
AStream.WriteComponent(Self);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SaveLinksToStream(AStream: TStream);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
I := LinkCount;
|
|
AStream.WriteBuffer(I , SizeOf(I));
|
|
for I := 0 to LinkCount - 1 do
|
|
begin
|
|
ReportLink[I].InternalStreaming := True;
|
|
AStream.WriteComponent(ReportLink[I]);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.SaveVersionToStream(AStream: TStream);
|
|
begin
|
|
AStream.WriteBuffer(Version , SizeOf(Version));
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PrintEx(APageNums: TdxPageNumbers;
|
|
ACopies: Integer; ACollate: Boolean; AReportLink: TBasedxReportLink = nil);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then
|
|
begin
|
|
PrepareReport(AReportLink);
|
|
try
|
|
if not AbortBuilding and (AReportLink.PageCount > 0) then
|
|
begin
|
|
FPrintAll := True;
|
|
try
|
|
PrintPagesAsStringEx('1-' + Trim(IntToStr(AReportLink.PageCount)), APageNums, ACopies, ACollate, AReportLink);
|
|
finally
|
|
FPrintAll := False;
|
|
end;
|
|
end;
|
|
finally
|
|
UnprepareReport(AReportLink);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.PreparePrintDevice;
|
|
begin
|
|
if dxPrintDevice.Copies > 1 then
|
|
begin
|
|
FSaveCopies := dxPrintDevice.Copies;
|
|
dxPrintDevice.Copies := 1;
|
|
end;
|
|
if dxPrintDevice.Collate then
|
|
begin
|
|
FSaveCollate := dxPrintDevice.Collate;
|
|
dxPrintDevice.Collate := False;
|
|
end;
|
|
CurrentLink.RealPrinterPage.ApplyToPrintDevice;
|
|
|
|
dxPSEdgePatternFactory.ResetPrintItems;
|
|
dxPSFillPatternFactory.ResetPrintItems;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.UnpreparePrintDevice;
|
|
begin
|
|
if FSaveCopies > 1 then
|
|
dxPrintDevice.Copies := FSaveCopies;
|
|
FSaveCopies := 1;
|
|
if FSaveCollate then
|
|
dxPrintDevice.Collate := FSaveCollate;
|
|
FSaveCollate := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.GetPageColRowCount(out ACol, ARow: Integer;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink = nil then
|
|
begin
|
|
ACol := 0;
|
|
ARow := 0;
|
|
end
|
|
else
|
|
AReportLink.GetPageColRowCount(ACol, ARow);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.GetPageCount(AReportLink: TBasedxReportLink = nil): Integer;
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then
|
|
Result := AReportLink.PageCount
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.PageSetup(AReportLink: TBasedxReportLink): Boolean;
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
Result := (AReportLink <> nil) and AReportLink.PageSetup;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.PageSetupEx(AActivePageIndex: Integer;
|
|
AShowPreviewBtn, AShowPrintBtn: Boolean; out APreviewBtnClicked, APrintBtnClicked: Boolean;
|
|
AReportLink: TBasedxReportLink = nil): Boolean;
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
Result := (AReportLink <> nil) and
|
|
AReportLink.PageSetupEx(AActivePageIndex, AShowPreviewBtn, AShowPrintBtn, APreviewBtnClicked, APrintBtnClicked);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.PageSetupEx(AActivePageIndex: Integer;
|
|
APreviewBtnClicked, APrintBtnClicked: PBoolean;
|
|
AReportLink: TBasedxReportLink = nil): Boolean;
|
|
var
|
|
ShowPreviewBtn, ShowPrintBtn, PreviewBtnClicked, PrintBtnClicked: Boolean;
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then
|
|
begin
|
|
ShowPreviewBtn := APreviewBtnClicked <> nil;
|
|
ShowPrintBtn := APrintBtnClicked <> nil;
|
|
Result := AReportLink.PageSetupEx(AActivePageIndex, ShowPreviewBtn, ShowPrintBtn, PreviewBtnClicked, PrintBtnClicked);
|
|
|
|
if ShowPreviewBtn then
|
|
APreviewBtnClicked^ := PreviewBtnClicked;
|
|
|
|
if ShowPrintBtn then
|
|
APrintBtnClicked^ := PrintBtnClicked;
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.Explore;
|
|
var
|
|
PrevCurrentLink: TBasedxReportLink;
|
|
begin
|
|
if Explorer <> nil then
|
|
begin
|
|
Include(FState, cpsExplore);
|
|
try
|
|
PrevCurrentLink := CurrentLink;
|
|
CurrentLink := ExplorerRealStubLink;
|
|
try
|
|
CurrentLink.DataSource := rldsExternalStorage;
|
|
Preview(True);
|
|
finally
|
|
if ExplorerStubLink = nil then { Link had been created manually before }
|
|
CurrentLink.Free;
|
|
CurrentLink := PrevCurrentLink;
|
|
end;
|
|
finally
|
|
Exclude(FState, cpsExplore);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.DesignerExists(AReportLink: TBasedxReportLink = nil): Boolean;
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
Result := (AReportLink <> nil) and (AReportLink.GetDesignerClass <> nil);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.DesignerExistsByComponent(AComponent: TComponent): Boolean;
|
|
begin
|
|
Result := (AComponent <> nil) and (dxPSDesignerClassByCompClass(TComponentClass(AComponent.ClassType)) <> nil);
|
|
end;
|
|
|
|
function TCustomdxComponentPrinter.DesignReport(AReportLink: TBasedxReportLink): Boolean;
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink <> nil then
|
|
begin
|
|
Include(FState, cpsDesigning);
|
|
try
|
|
Result := AReportLink.DesignReport;
|
|
finally
|
|
Exclude(FState, cpsDesigning);
|
|
end;
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DrawPageHeader(AReportLink: TBasedxReportLink;
|
|
APageIndex: Integer; ARect: TRect;
|
|
ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
begin
|
|
AReportLink.DrawPageHeader(APageIndex, ARect, ATitleParts, ADrawBackground);
|
|
end;
|
|
|
|
procedure TCustomdxComponentPrinter.DrawPageFooter(AReportLink: TBasedxReportLink;
|
|
APageIndex: Integer; ARect: TRect;
|
|
ATitleParts: TdxPageTitleParts; ADrawBackground: Boolean);
|
|
begin
|
|
AReportLink.DrawPageFooter(APageIndex, ARect, ATitleParts, ADrawBackground);
|
|
end;
|
|
|
|
{ TdxComponentPrinter }
|
|
|
|
constructor TdxComponentPrinter.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FCustomizeDlgOptions := [cdoShowDescription];
|
|
FOverWriteExistingFiles := False;
|
|
end;
|
|
|
|
destructor TdxComponentPrinter.Destroy;
|
|
begin
|
|
if not IsDesigning and (dxPSEngine.RealRegistryPath <> '') then
|
|
SaveToRegistry(dxPSEngine.RealRegistryPath);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.ShowCustomizeDlg;
|
|
{$IFNDEF CBUILDER6}
|
|
var
|
|
Data: TdxCPDesignerDlgData;
|
|
{$ENDIF}
|
|
begin
|
|
{$IFNDEF CBUILDER6}
|
|
FillChar(Data, SizeOf(TdxCPDesignerDlgData), 0);
|
|
Data.ComponentPrinter := Self;
|
|
if cdoShowDescription in CustomizeDlgOptions then
|
|
Include(Data.Options, doShowDescription);
|
|
Include(FState, cpsCustomizing);
|
|
try
|
|
dxShowCPDesignerDlg(Data);
|
|
finally
|
|
Exclude(FState, cpsCustomizing);
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
if (LinkCount > 0) and (CurrentLink = nil) then
|
|
CurrentLink := ReportLink[0];
|
|
if not IsDesigning then
|
|
LoadFromRegistry(dxPSEngine.RealRegistryPath);
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.SaveToRegistry(const APath: string);
|
|
|
|
procedure SaveFormats(const APath: string);
|
|
begin
|
|
with TRegistry.Create do
|
|
try
|
|
if OpenKey(APath, True) then
|
|
try
|
|
try
|
|
WriteBool(sdxAutoUpdateDateTime, AutoUpdateDateTime);
|
|
WriteInteger(sdxDateFormat, DateFormat);
|
|
WriteInteger(sdxTimeFormat, TimeFormat);
|
|
WriteInteger(sdxPageNumberFormat, Integer(PageNumberFormat));
|
|
except
|
|
on ERegistryException do
|
|
{ ignore }
|
|
else
|
|
raise;
|
|
end;
|
|
finally
|
|
CloseKey;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if APath = '' then Exit;
|
|
SaveFormats(APath);
|
|
dxSaveStringsToRegistry(APath + sdxPrintDlgFilesRegistryPath + '\' + Name, FPrintFileList);
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.LoadFromRegistry(const APath: string);
|
|
|
|
procedure LoadFormats(const APath: string);
|
|
begin
|
|
with TRegistry.Create do
|
|
try
|
|
if OpenKey(APath, False) then
|
|
try
|
|
try
|
|
if ValueExists(sdxAutoUpdateDateTime) then
|
|
AutoUpdateDateTime := ReadBool(sdxAutoUpdateDateTime);
|
|
if ValueExists(sdxDateFormat) then
|
|
DateFormat := ReadInteger(sdxDateFormat);
|
|
if ValueExists(sdxTimeFormat) then
|
|
TimeFormat := ReadInteger(sdxTimeFormat);
|
|
if ValueExists(sdxPageNumberFormat) then
|
|
PageNumberFormat := TdxPageNumberFormat(ReadInteger(sdxPageNumberFormat));
|
|
except
|
|
on ERegistryException do
|
|
{ ignore }
|
|
else
|
|
raise;
|
|
end;
|
|
finally
|
|
CloseKey;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if APath = '' then Exit;
|
|
LoadFormats(APath);
|
|
dxLoadStringsFromRegistry(APath + sdxPrintDlgFilesRegistryPath + '\' + Name, FPrintFileList);
|
|
end;
|
|
|
|
function TdxComponentPrinter.DoFilterComponent(AComponent: TComponent;
|
|
var ACaption, ADescription: string): Boolean;
|
|
begin
|
|
Result := True;
|
|
if Assigned(FOnFilterComponent) then
|
|
FOnFilterComponent(Self, AComponent, ACaption, ADescription, Result);
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.GetDefaultExportPageFileName(AIndex,
|
|
APageIndex: Integer; var AFileName: string);
|
|
begin
|
|
AFileName := Format(AFileName, [APageIndex]);
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.GetExportPageFileName(AIndex, APageIndex: Integer;
|
|
var AFileName: string);
|
|
begin
|
|
if Assigned(FOnExportGetPageFileName) then
|
|
FOnExportGetPageFileName(Self, AIndex, APageIndex, AFileName)
|
|
else
|
|
GetDefaultExportPageFileName(AIndex, APageIndex, AFileName);
|
|
end;
|
|
|
|
function TdxComponentPrinter.GetSupportedComponents(AComponents: TStrings): Boolean;
|
|
begin
|
|
Result := Assigned(FOnGetSupportedComponents);
|
|
if Result then
|
|
FOnGetSupportedComponents(Self, AComponents);
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.EnumPagesAsImages(const APageIndexes: array of Integer;
|
|
AGraphicClass: TGraphicClass; ADrawBackground: Boolean; ACallBackProc: TdxEnumPagesAsImagesProc;
|
|
ACallBackData, AProgressData, APrepareData: Pointer;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
begin
|
|
AReportLink := CheckLink(AReportLink);
|
|
if AReportLink = nil then Exit;
|
|
dxPSEnumReportPages(Self, AReportLink, APageIndexes, AGraphicClass, ADrawBackground,
|
|
ACallBackProc, ACallBackData, OnExportProgress, AProgressData,
|
|
OnExportPrepareGraphic, APrepareData);
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.WritePageAsImageToDisk(AComponentPrinter: TCustomdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; AIndex, APageIndex: Integer; const AGraphic: TGraphic;
|
|
AData: Pointer; var AContinue: Boolean);
|
|
const
|
|
Buttons: TMsgDlgButtons = [mbYes, mbYesToAll, mbNo, mbCancel {, mbHelp}];
|
|
var
|
|
FileName: string;
|
|
MessageResult: Word;
|
|
MessageText: string;
|
|
begin
|
|
if AData = nil then Exit;
|
|
FileName := string(AData);
|
|
GetExportPageFileName(AIndex, APageIndex, FileName);
|
|
if not ValidateFileName(FileName) then Exit;
|
|
|
|
FOverWriteFile := True;
|
|
if FileExists(FileName) and not OverWriteExistingFiles and not FOverWriteAll then
|
|
begin
|
|
FOverWriteFile := False;
|
|
Beep;
|
|
MessageText := Format(cxGetResourceString(@sdxConfirmOverWrite), [FileName]);
|
|
MessageResult := MessageDlg(MessageText, mtWarning, Buttons, 0);
|
|
case MessageResult of
|
|
mrYes:
|
|
FOverWriteFile := True;
|
|
mrYesToAll:
|
|
begin
|
|
FOverWriteFile := True;
|
|
FOverWriteAll := True;
|
|
end;
|
|
mrNo:
|
|
begin
|
|
AContinue := dxShowChooseFileNameDlg(FileName);
|
|
if AContinue then FOverWriteFile := True;
|
|
end;
|
|
mrCancel:
|
|
AContinue := False;
|
|
end;
|
|
end;
|
|
if FOverWriteFile then
|
|
begin
|
|
if AGraphic is TBitmap then
|
|
TBitmap(AGraphic).HandleType := bmDIB;
|
|
AGraphic.SaveToFile(FileName);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxComponentPrinter.SavePagesAsImagesToDisk(const APageIndexes: array of Integer;
|
|
AGraphicClass: TGraphicClass; ADrawBackground: Boolean; const AFileMask: string;
|
|
AProgressData, APrepareData: Pointer;
|
|
AReportLink: TBasedxReportLink = nil);
|
|
var
|
|
PFileMask: PChar;
|
|
begin
|
|
FOverWriteAll := False;
|
|
PrepareLongOperation;
|
|
try
|
|
PFileMask := PChar(AFileMask);
|
|
EnumPagesAsImages(APageIndexes, AGraphicClass, ADrawBackground,
|
|
WritePageAsImageToDisk, PFileMask, AProgressData, APrepareData,
|
|
AReportLink);
|
|
finally
|
|
FOverWriteAll := False;
|
|
UnprepareLongOperation;
|
|
end;
|
|
end;
|
|
|
|
{ TAbstractdxPreviewWindowDesigner }
|
|
|
|
constructor TAbstractdxPreviewWindowDesigner.Create(AComponentPrinter: TCustomdxComponentPrinter);
|
|
begin
|
|
inherited Create;
|
|
FComponentPrinter := AComponentPrinter;
|
|
if FComponentPrinter <> nil then
|
|
FComponentPrinter.FPreviewWindowDesigner := Self;
|
|
end;
|
|
|
|
destructor TAbstractdxPreviewWindowDesigner.Destroy;
|
|
begin
|
|
if FComponentPrinter <> nil then
|
|
FComponentPrinter.FPreviewWindowDesigner := nil;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TAbstractdxReportLinkDesigner }
|
|
|
|
constructor TAbstractdxReportLinkDesigner.Create(AComponentPrinter: TCustomdxComponentPrinter);
|
|
begin
|
|
inherited Create;
|
|
FComponentPrinter := AComponentPrinter;
|
|
if FComponentPrinter <> nil then
|
|
FComponentPrinter.FReportLinkDesigner := Self;
|
|
end;
|
|
|
|
destructor TAbstractdxReportLinkDesigner.Destroy;
|
|
begin
|
|
if FComponentPrinter <> nil then
|
|
FComponentPrinter.FReportLinkDesigner := nil;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ export }
|
|
|
|
procedure dxPSEnumReportPages(AComponentPrinter: TdxComponentPrinter;
|
|
AReportLink: TBasedxReportLink; const APageIndexes: array of Integer;
|
|
AGraphicClass: TGraphicClass; AnExportBackground: Boolean;
|
|
ACallBackProc: TdxEnumPagesAsImagesProc;
|
|
ACallBackData: Pointer;
|
|
AProgressProc: TdxExportProgressEvent;
|
|
AProgressData: Pointer;
|
|
APrepareGraphicProc: TdxExportPrepareGraphicEvent;
|
|
APrepareData: Pointer);
|
|
|
|
procedure GetPPI(out APPI: TPoint);
|
|
var
|
|
DC: HDC;
|
|
begin
|
|
DC := GetDC(0);
|
|
try
|
|
APPI.X := GetDeviceCaps(DC, LOGPIXELSX);
|
|
APPI.Y := GetDeviceCaps(DC, LOGPIXELSY);
|
|
finally
|
|
ReleaseDC(0, DC);
|
|
end;
|
|
end;
|
|
|
|
function AreAllPagesEnumerated: Boolean;
|
|
begin
|
|
Result := (Low(APageIndexes) = High(APageIndexes)) and (APageIndexes[0] = -1);
|
|
end;
|
|
|
|
procedure GetPageBounds(out R: TRect);
|
|
begin
|
|
with AReportLink.RealPrinterPage.PageSizePixels do
|
|
R := MakeRect(0, 0, X, Y);
|
|
end;
|
|
|
|
procedure PreparePageIndexes(out AnActualPageIndexes: TIntegers);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if AreAllPagesEnumerated then
|
|
begin
|
|
SetLength(AnActualPageIndexes, AReportLink.PageCount);
|
|
for I := 0 to AReportLink.PageCount - 1 do
|
|
AnActualPageIndexes[I] := I;
|
|
end
|
|
else
|
|
begin
|
|
SetLength(AnActualPageIndexes, Length(APageIndexes));
|
|
for I := 0 to Length(APageIndexes) - 1 do
|
|
AnActualPageIndexes[I] := APageIndexes[I];
|
|
end;
|
|
end;
|
|
|
|
function CreatePageAsMetafile(const ABounds: TRect; const APPI: TPoint; APageIndex: Integer): TMetafile;
|
|
{ const
|
|
HundredsMMInInch = 2540;}
|
|
var
|
|
MetaCanvas: TCanvas;
|
|
begin
|
|
Result := TMetafile.Create;
|
|
try
|
|
with ABounds do
|
|
begin
|
|
Result.Width := Right - Left;
|
|
Result.Height := Bottom - Top;
|
|
{ Result.MMHeight := MulDiv(Bottom - Top, HundredsMMInInch, APPI.X);
|
|
Result.MMWidth := MulDiv(Right - Left, HundredsMMInInch, APPI.Y);}
|
|
end;
|
|
|
|
MetaCanvas := TMetafileCanvas.Create(Result, 0);
|
|
try
|
|
if AGraphicClass.InheritsFrom(TMetafile) and Assigned(APrepareGraphicProc) then
|
|
APrepareGraphicProc(AComponentPrinter, AReportLink, Result, APrepareData);
|
|
|
|
if not AnExportBackground or AReportLink.RealPrinterPage.Background.IsEmpty then
|
|
begin
|
|
MetaCanvas.Brush.Color := clWhite;
|
|
MetaCanvas.FillRect(ABounds);
|
|
end
|
|
else
|
|
AReportLink.RealPrinterPage.Background.Paint(MetaCanvas, ABounds);
|
|
|
|
if (-1 < APageIndex) and (APageIndex < AReportLink.PageCount) then
|
|
AComponentPrinter.PaintPage(MetaCanvas, APageIndex, ABounds, ABounds, AReportLink);
|
|
finally
|
|
MetaCanvas.Free;
|
|
end;
|
|
except
|
|
Result.Free;
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
function CreatePageAsGraphic(const ABounds: TRect; const APPI: TPoint; APageIndex: Integer): TGraphic;
|
|
var
|
|
Metafile: TMetafile;
|
|
Bitmap: TBitmap;
|
|
begin
|
|
Metafile := CreatePageAsMetafile(ABounds, APPI, APageIndex);
|
|
try
|
|
if not AGraphicClass.InheritsFrom(TMetafile) then
|
|
begin
|
|
Bitmap := TBitmap.Create;
|
|
try
|
|
Bitmap.Height := Metafile.Height;
|
|
Bitmap.Width := Metafile.Width;
|
|
if AGraphicClass.InheritsFrom(TBitmap) and Assigned(APrepareGraphicProc) then
|
|
APrepareGraphicProc(AComponentPrinter, AReportLink, Bitmap, APrepareData);
|
|
Bitmap.Canvas.Draw(0, 0, Metafile);
|
|
|
|
if not AGraphicClass.InheritsFrom(TBitmap) then
|
|
begin
|
|
Result := dxPSUtl.CreateGraphic(AGraphicClass);
|
|
try
|
|
if Assigned(APrepareGraphicProc) then
|
|
APrepareGraphicProc(AComponentPrinter, AReportLink, Result, APrepareData);
|
|
Result.Assign(Bitmap);
|
|
except
|
|
Result.Free;
|
|
raise;
|
|
end;
|
|
end
|
|
else
|
|
Result := Bitmap;
|
|
finally
|
|
if not AGraphicClass.InheritsFrom(TBitmap) then Bitmap.Free;
|
|
end;
|
|
end
|
|
else
|
|
Result := Metafile;
|
|
finally
|
|
if not AGraphicClass.InheritsFrom(TMetafile) then Metafile.Free;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
PPI: TPoint;
|
|
PageCount, I, PageIndex: Integer;
|
|
ActualPageIndexes: TIntegers;
|
|
ContinueExport: Boolean;
|
|
R: TRect;
|
|
Graphic: TGraphic;
|
|
begin
|
|
if (AComponentPrinter = nil) or (AReportLink = nil) or not Assigned(ACallBackProc) then
|
|
Exit;
|
|
|
|
if AGraphicClass = nil then AGraphicClass := TMetafile;
|
|
|
|
GetPPI(PPI);
|
|
PreparePageIndexes(ActualPageIndexes);
|
|
try
|
|
GetPageBounds(R);
|
|
ContinueExport := True;
|
|
PageCount := Length(ActualPageIndexes);
|
|
for I := 0 to PageCount - 1 do
|
|
begin
|
|
PageIndex := ActualPageIndexes[I];
|
|
Graphic := CreatePageAsGraphic(R, PPI, PageIndex);
|
|
try
|
|
ACallBackProc(AComponentPrinter, AReportLink, I, PageIndex, Graphic, ACallBackData, ContinueExport);
|
|
finally
|
|
Graphic.Free;
|
|
end;
|
|
if not ContinueExport then Break;
|
|
if Assigned(AProgressProc) then
|
|
AProgressProc(AComponentPrinter, AReportLink, PageCount, I, PageIndex, AProgressData);
|
|
end;
|
|
finally
|
|
SetLength(ActualPageIndexes, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure InitializeUnits;
|
|
begin
|
|
if IsWin95Or98 then FUnitsPerInch := 960;
|
|
FPixelsNumerator := FUnitsPerInch;
|
|
FPixelsDenominator := Screen.PixelsPerInch;
|
|
end;
|
|
|
|
procedure RegisterAssistants;
|
|
begin
|
|
TdxPSExplorerTreeBuilder.Register;
|
|
TdxPSRunTimeComponentsProvider.Register;
|
|
|
|
TdxPSDataReader.Register;
|
|
TdxPSDataWriter.Register;
|
|
|
|
TdxPSCustomCellBorder.Register;
|
|
TdxPSCellNullBorder.Register;
|
|
TdxPSCellFlatBorder.Register;
|
|
TdxPSCellBoldFlatBorder.Register;
|
|
TdxPSCellUltraFlatBorder.Register;
|
|
TdxPSCustomCell3DBorder.Register;
|
|
TdxPSCellRaisedBorder.Register;
|
|
TdxPSCellRaisedSoftBorder.Register;
|
|
TdxPSCellSunkenBorder.Register;
|
|
TdxPSCellSunkenSoftBorder.Register;
|
|
TdxPSCellTwistedBorder.Register;
|
|
TdxPSCellEtchedBorder.Register;
|
|
TdxPSCellBumpedBorder.Register;
|
|
TdxPSColorBorder.Register;
|
|
|
|
TdxPSReportGroupNullLookAndFeel.Register;
|
|
TdxPSReportGroupStandardLookAndFeel.Register;
|
|
TdxPSReportGroupOfficeLookAndFeel.Register;
|
|
TdxPSReportGroupWebLookAndFeel.Register;
|
|
end;
|
|
|
|
procedure RegisterGraphicClasses;
|
|
const
|
|
GraphicClassCount = 3 {$IFDEF USEJPEGIMAGE} + 1 {$ENDIF};
|
|
GraphicClasses: array[0..GraphicClassCount - 1] of TGraphicClass =
|
|
(TBitmap, TMetafile, TIcon{$IFDEF USEJPEGIMAGE}, TJPEGImage{$ENDIF});
|
|
var
|
|
I: Integer;
|
|
GraphicClass: TGraphicClass;
|
|
begin
|
|
for I := Low(GraphicClasses) to High(GraphicClasses) do
|
|
begin
|
|
GraphicClass := GraphicClasses[I];
|
|
if GetClass(GraphicClass.ClassName) = nil then
|
|
RegisterClass(GraphicClass);
|
|
end;
|
|
end;
|
|
|
|
procedure RegisterItems;
|
|
begin
|
|
TdxReportCell.Register;
|
|
TdxReportGroup.Register;
|
|
TdxReportRadioGroup.Register;
|
|
TdxReportCheckGroup.Register;
|
|
|
|
TdxReportCellBox.Register;
|
|
TdxReportCellString.Register;
|
|
TdxReportCellCheck.Register;
|
|
TdxReportCellRadio.Register;
|
|
TdxReportCellCheckImage.Register;
|
|
TdxReportCellRadioGroupButton.Register;
|
|
TdxReportCellGroupButton.Register;
|
|
TdxReportCellCheckGroupButton.Register;
|
|
TdxReportCellImage.Register;
|
|
TdxReportCellGraphic.Register;
|
|
TdxReportCellExpandButton.Register;
|
|
TdxReportCellExpandButtonEx.Register;
|
|
end;
|
|
|
|
procedure UnregisterAssistants;
|
|
begin
|
|
TdxPSDataWriter.Unregister;
|
|
TdxPSDataReader.Unregister;
|
|
|
|
TdxPSRunTimeComponentsProvider.Unregister;
|
|
TdxPSExplorerTreeBuilder.Unregister;
|
|
end;
|
|
|
|
procedure UnregisterItems;
|
|
begin
|
|
TdxReportCellExpandButtonEx.Unregister;
|
|
TdxReportCellExpandButton.Unregister;
|
|
TdxReportCellGraphic.Unregister;
|
|
TdxReportCellImage.Unregister;
|
|
TdxReportCellCheckGroupButton.Unregister;
|
|
TdxReportCellGroupButton.Unregister;
|
|
TdxReportCellRadioGroupButton.Unregister;
|
|
TdxReportCellCheckImage.Unregister;
|
|
TdxReportCellRadio.Unregister;
|
|
TdxReportCellCheck.Unregister;
|
|
TdxReportCellString.Unregister;
|
|
TdxReportCellBox.Unregister;
|
|
|
|
TdxReportCheckGroup.Unregister;
|
|
TdxReportRadioGroup.Unregister;
|
|
TdxReportGroup.Unregister;
|
|
TdxReportCell.Unregister;
|
|
end;
|
|
|
|
initialization
|
|
{$IFDEF OLEDRAGANDDROP}
|
|
OleInitialize(nil);
|
|
{$ENDIF}
|
|
|
|
dxPgsDlg.dxPSRegisterPrintStyle(TdxPSPrintStyle, True);
|
|
dxPSRegisterReportLink(TdxCompositionReportLink, nil, TdxfmCompositionDesignWindow);
|
|
|
|
InitializeUnits;
|
|
|
|
RegisterAssistants;
|
|
RegisterGraphicClasses;
|
|
RegisterItems;
|
|
|
|
finalization
|
|
UnregisterItems;
|
|
UnregisterAssistants;
|
|
|
|
dxPSUnregisterAllReportLinks;
|
|
dxPgsDlg.dxPSUnregisterPrintStyle(TdxPSPrintStyle);
|
|
dxPSUnregisterAllPreviewWindows;
|
|
|
|
FreeAndNil(FExplorerImages);
|
|
|
|
{$IFDEF OLEDRAGANDDROP}
|
|
OleUninitialize;
|
|
{$ENDIF}
|
|
|
|
end.
|
|
|
|
|