Componentes.Terceros.DevExp.../internal/x.46/2/ExpressQuantumGrid 6/Sources/cxGrid.pas

2460 lines
71 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressQuantumGrid }
{ }
{ Copyright (c) 1998-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSQUANTUMGRID 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 cxGrid;
{$I cxVer.inc}
interface
uses
{$IFDEF DELPHI6}
Types,
{$ENDIF}
Windows, Messages,
Classes, Controls, Graphics, ImgList, Forms, StdCtrls,
cxClasses, cxGraphics, cxLookAndFeels, cxLookAndFeelPainters, cxControls, cxPC,
cxNavigator, cxCustomData,
cxGridCommon, cxGridLevel, cxGridDetailsSite, cxGridCustomView;
const
(*
CM_DEFERUPDATES = WM_USER + 333;
*)
cxGridLevelTabsDefaultCaptionAlignment = taCenter;
cxGridLevelTabsDefaultImageBorder = 0;
cxGridRootLevelDefaultDetailFrameWidth = 0;
cxGridDefaultDragOpeningWaitTime = 800;//500;
type
TcxGridViewInfo = class;
TcxCustomGrid = class;
{ changes }
TcxGridLayoutChange = class(TcxCustomGridViewChange)
public
procedure Execute; override;
function IsCompatibleWith(AChange: TcxCustomGridChange): Boolean; override;
end;
TcxGridSizeChange = class(TcxCustomGridViewChange)
private
FKeepMaster: Boolean;
FUpdateGridViewOnly: Boolean;
public
constructor Create(AGridView: TcxCustomGridView;
AUpdateGridViewOnly: Boolean = False; AKeepMaster: Boolean = False); reintroduce; virtual;
procedure Execute; override;
function IsCompatibleWith(AChange: TcxCustomGridChange): Boolean; override;
function IsEqual(AChange: TcxCustomGridChange): Boolean; override;
property KeepMaster: Boolean read FKeepMaster;
property UpdateGridViewOnly: Boolean read FUpdateGridViewOnly
write FUpdateGridViewOnly;
end;
TcxGridViewChange = class(TcxCustomGridViewChange)
private
FUpdateBounds: TRect;
FUpdateRegion: TcxRegion;
public
constructor Create(AGridView: TcxCustomGridView;
const AUpdateBounds: TRect); reintroduce; overload; virtual;
constructor Create(AGridView: TcxCustomGridView;
const AUpdateRegion: TcxRegion); reintroduce; overload; virtual;
constructor Create(AGridView: TcxCustomGridView); reintroduce; overload;
destructor Destroy; override;
procedure Execute; override;
function IsCompatibleWith(AChange: TcxCustomGridChange): Boolean; override;
function IsEqual(AChange: TcxCustomGridChange): Boolean; override;
property UpdateBounds: TRect read FUpdateBounds;
property UpdateRegion: TcxRegion read FUpdateRegion;
end;
{ notification }
TcxGridNotificationKind = (gnkFocusedViewChanged, gnkFocusedRecordChanged,
gnkRecordCountChanged, gnkContextMenu, gnkCustomization, gnkKeyDown);
TcxGridNotificationKinds = set of TcxGridNotificationKind;
TcxCustomGridNotification = class
protected
function NotificationKinds: TcxGridNotificationKinds; virtual; abstract;
procedure Notify(AKind: TcxGridNotificationKind; AData: TObject;
var AHandled: Boolean); virtual; abstract;
end;
{ structure navigator }
TcxCustomGridStructureNavigatorClass = class of TcxCustomGridStructureNavigator;
TcxCustomGridStructureNavigator = class(TcxControl)
private
FGrid: TcxCustomGrid;
protected
procedure Changed; virtual;
procedure FontChanged; override;
function MayFocus: Boolean; override;
function CalculateBoundsRect: TRect; virtual; abstract;
public
constructor Create(AGrid: TcxCustomGrid); reintroduce; virtual;
procedure BeforeGridLoading; virtual;
function IsObjectSelected(AObject: TPersistent): Boolean; virtual; abstract;
procedure SelectionChanged(ASelection: TList); virtual; abstract;
procedure SelectObject(AObject: TPersistent; AClearSelection: Boolean); virtual; abstract;
procedure SelectObjects(AObjects: TList); virtual; abstract;
procedure UnselectObject(AObject: TPersistent); virtual; abstract;
property Grid: TcxCustomGrid read FGrid;
end;
{ handlers }
TcxCustomGridHandler = class
private
FControl: TcxCustomGrid;
function GetActiveController: TcxCustomGridController;
function GetActiveGridView: TcxCustomGridView;
function GetLookAndFeelPainter: TcxCustomLookAndFeelPainterClass;
function GetViewInfo: TcxGridViewInfo;
protected
property ActiveController: TcxCustomGridController read GetActiveController;
property ActiveGridView: TcxCustomGridView read GetActiveGridView;
property LookAndFeelPainter: TcxCustomLookAndFeelPainterClass read GetLookAndFeelPainter;
property ViewInfo: TcxGridViewInfo read GetViewInfo;
public
constructor Create(AControl: TcxCustomGrid); virtual;
property Control: TcxCustomGrid read FControl;
end;
TcxGridDesignControllerClass = class of TcxGridDesignController;
TcxGridDesignController = class(TcxCustomGridDesignController)
private
FControl: TcxCustomGrid;
protected
function GetControl: TcxControl; override;
public
constructor Create(AControl: TcxCustomGrid); virtual;
end;
TcxGridDragOpenInfoTab = class(TcxCustomGridDragOpenInfo)
public
Level: TcxGridLevel;
constructor Create(ALevel: TcxGridLevel); virtual;
function Equals(AInfo: TcxCustomGridDragOpenInfo): Boolean; override;
procedure Run; override;
end;
TcxGridControllerClass = class of TcxGridController;
TcxGridController = class(TcxCustomGridHandler)
private
FDesignController: TcxGridDesignController;
FDragOpenInfo: TcxCustomGridDragOpenInfo;
FDragOpenTimer: TcxTimer;
function GetDesignController: TcxGridDesignController;
procedure DragOpenTimerHandler(Sender: TObject);
protected
function GetDesignControllerClass: TcxGridDesignControllerClass; virtual;
public
destructor Destroy; override;
procedure DoCancelMode; virtual;
procedure FocusChanged; virtual;
function GetCursor(X, Y: Integer): TCursor; virtual;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
var Accept: Boolean); virtual;
procedure EndDrag(Target: TObject; X, Y: Integer); virtual;
procedure StartDrag(var DragObject: TDragObject); virtual;
function GetDragOpenInfo(AHitTest: TcxCustomGridHitTest): TcxCustomGridDragOpenInfo; virtual;
function IsDragOpenHitTest(AHitTest: TcxCustomGridHitTest;
out ADragOpenInfo: TcxCustomGridDragOpenInfo): Boolean;
procedure StartDragOpen(ADragOpenInfo: TcxCustomGridDragOpenInfo);
procedure StopDragOpen;
property DragOpenInfo: TcxCustomGridDragOpenInfo read FDragOpenInfo;
property DesignController: TcxGridDesignController read GetDesignController;
end;
TcxGridPainterClass = class of TcxGridPainter;
TcxGridPainter = class(TcxCustomGridHandler)
private
function GetCanvas: TcxCanvas;
protected
procedure DrawDetailsSite; virtual;
//procedure DrawEmptyArea; virtual;
public
procedure Invalidate(AInvalidateDetails: Boolean); overload; virtual;
procedure Invalidate(const R: TRect); overload; virtual;
procedure Paint; virtual;
property Canvas: TcxCanvas read GetCanvas;
end;
TcxGridTopDetailsSiteViewInfoClass = class of TcxGridTopDetailsSiteViewInfo;
TcxGridTopDetailsSiteViewInfo = class(TcxCustomGridDetailsSiteViewInfo)
private
function GetControl: TcxCustomGrid;
protected
function CalculateHeight: Integer; override;
function CalculateWidth: Integer; override;
function GetActiveGridView: TcxCustomGridView; override;
function GetActiveLevel: TcxGridLevel; override;
function GetCanvas: TcxCanvas; override;
function GetContainer: TcxControl; override;
function GetDesignController: TcxCustomGridDesignController; override;
function GetMasterRecord: TObject; override;
function GetMaxHeight: Integer; override;
function GetMaxWidth: Integer; override;
procedure InitTabHitTest(AHitTest: TcxGridDetailsSiteTabHitTest); override;
property Control: TcxCustomGrid read GetControl;
public
procedure ChangeActiveTab(ALevel: TcxGridLevel; AFocusView: Boolean = False); override;
function DetailHasData(ALevel: TcxGridLevel): Boolean; override;
function SupportsTabAccelerators: Boolean; override;
procedure VisibilityChanged(AVisible: Boolean); override;
end;
TcxGridViewInfoClass = class of TcxGridViewInfo;
TcxGridViewInfo = class(TcxCustomGridHandler)
private
FDetailsSiteViewInfo: TcxGridTopDetailsSiteViewInfo;
FDetailsSiteViewInfoCachedInfo: TcxCustomGridDetailsSiteViewInfoCachedInfo;
FIsCalculating: Boolean;
function GetBounds: TRect;
function GetClientBounds: TRect;
function GetEmptyAreaColor: TColor;
protected
procedure CreateViewInfos; virtual;
procedure DestroyViewInfos; virtual;
function GetDetailsSiteViewInfoClass: TcxGridTopDetailsSiteViewInfoClass; virtual;
procedure RecreateViewInfos;
procedure Calculate; virtual;
public
constructor Create(AControl: TcxCustomGrid); override;
destructor Destroy; override;
function GetHitTest(X, Y: Integer): TcxCustomGridHitTest; virtual;
procedure MainCalculate;
property Bounds: TRect read GetBounds;
property ClientBounds: TRect read GetClientBounds;
property DetailsSiteViewInfo: TcxGridTopDetailsSiteViewInfo read FDetailsSiteViewInfo;
property EmptyAreaColor: TColor read GetEmptyAreaColor;
property IsCalculating: Boolean read FIsCalculating;
end;
{ controls }
TcxGridLevelTabsClass = class of TcxGridLevelTabs;
TcxGridLevelTabs = class(TPersistent)
private
FCaptionAlignment: TAlignment;
FFreeNotificator: TcxFreeNotificator;
FImageBorder: Integer;
FImages: TCustomImageList;
FImagesChangeLink: TChangeLink;
FOwner: TcxCustomGrid;
FSlants: TcxTabSlants;
FStyle: TcxPCStyleID;
procedure SetCaptionAlignment(Value: TAlignment);
procedure SetImageBorder(Value: Integer);
procedure SetImages(Value: TCustomImageList);
procedure SetSlants(Value: TcxTabSlants);
procedure SetStyle(Value: TcxPCStyleID);
procedure FreeNotification(Sender: TComponent);
procedure ImagesChanged(Sender: TObject);
procedure SlantsChanged(Sender: TObject);
protected
procedure Changed;
public
constructor Create(AOwner: TcxCustomGrid); virtual;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
property Owner: TcxCustomGrid read FOwner;
published
property CaptionAlignment: TAlignment read FCaptionAlignment write SetCaptionAlignment default cxGridLevelTabsDefaultCaptionAlignment;
property ImageBorder: Integer read FImageBorder write SetImageBorder default cxGridLevelTabsDefaultImageBorder;
property Images: TCustomImageList read FImages write SetImages;
property Slants: TcxTabSlants read FSlants write SetSlants;
property Style: TcxPCStyleID read FStyle write SetStyle default cxPCDefaultStyle;
end;
TcxGridRootLevelOptions = class(TcxGridLevelOptions)
public
constructor Create(ALevel: TcxGridLevel); override;
published
property DetailFrameWidth default cxGridRootLevelDefaultDetailFrameWidth;
end;
TcxGridRootLevel = class(TcxGridLevel)
protected
function GetOptionsClass: TcxGridLevelOptionsClass; override;
end;
TcxGridActiveTabChangedEvent = procedure(Sender: TcxCustomGrid; ALevel: TcxGridLevel) of object;
TcxGridFocusedViewChangedEvent = procedure(Sender: TcxCustomGrid;
APrevFocusedView, AFocusedView: TcxCustomGridView) of object;
TcxGridLayoutChangedEvent = procedure(Sender: TcxCustomGrid; AGridView: TcxCustomGridView) of object;
TcxCustomGrid = class(TcxControl, IcxNavigator, IdxSkinSupport)
private
FActiveLevel: TcxGridLevel;
FChanges: TList;
FChangesStack: TList;
FController: TcxGridController;
FCreatingStructureNavigator: Boolean;
FDragOpening: Boolean;
FDragOpeningWaitTime: Integer;
FFocusedView: TcxCustomGridView;
FIsPopupControl: Boolean;
FLastFocused: Boolean;
FLevels: TcxGridLevel;
FLevelTabs: TcxGridLevelTabs;
FNavigatorNotifier: TcxNavigatorControlNotifier;
FNotifications: TList;
FPainter: TcxGridPainter;
FProcessingChangesStack: Boolean;
FStructureNavigator: TcxCustomGridStructureNavigator;
FTabStop: Boolean;
FTag: TObject;
FUpdateLockCount: Integer;
FViewInfo: TcxGridViewInfo;
FViews: TList;
FOnActiveTabChanged: TcxGridActiveTabChangedEvent;
FOnFocusedViewChanged: TcxGridFocusedViewChangedEvent;
FOnLayoutChanged: TcxGridLayoutChangedEvent;
FSubClassEvents: TNotifyEvent;
function GetActiveView: TcxCustomGridView;
function GetFocusedViewNavigator: IcxNavigator;
function GetView(Index: Integer): TcxCustomGridView;
function GetViewCount: Integer;
function GetRootLevelOptions: TcxGridLevelOptions;
function GetRootLevelStyles: TcxGridLevelStyles;
function GetStructureNavigator: TcxCustomGridStructureNavigator;
function GetUpdateLocked: Boolean;
procedure SetActiveLevel(Value: TcxGridLevel);
procedure SetDragOpeningWaitTime(Value: Integer);
procedure SetFocusedView(Value: TcxCustomGridView);
procedure SetLevels(Value: TcxGridLevel);
procedure SetLevelTabs(Value: TcxGridLevelTabs);
procedure SetRootLevelOptions(Value: TcxGridLevelOptions);
procedure SetRootLevelStyles(Value: TcxGridLevelStyles);
procedure SetTabStop(Value: Boolean);
procedure AddView(AView: TcxCustomGridView);
procedure RemoveView(AView: TcxCustomGridView);
procedure DestroyViews;
procedure DestroyChanges(AChanges: TList);
procedure DestroyViewChanges(AView: TcxCustomGridView);
procedure CreateStructureNavigator;
//procedure CMDeferUpdates(var Message: TMessage); message CM_DEFERUPDATES;
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
protected
// IcxNavigator
function IcxNavigator.IsActive = NavigatorIsActive;
function IcxNavigator.IsBof = NavigatorIsBof;
function IcxNavigator.IsEof = NavigatorIsEof;
function IcxNavigator.CanAppend = NavigatorCanAppend;
function IcxNavigator.CanEdit = NavigatorCanEdit;
function IcxNavigator.CanDelete = NavigatorCanDelete;
function IcxNavigator.CanInsert = NavigatorCanInsert;
procedure IcxNavigator.ClearBookmark = NavigatorClearBookmark;
function IcxNavigator.IsEditing = NavigatorIsEditing;
function IcxNavigator.IsBookmarkAvailable = NavigatorIsBookmarkAvailable;
procedure IcxNavigator.DoAction = NavigatorDoAction;
function IcxNavigator.GetNotifier = NavigatorGetNotifier;
function IcxNavigator.IsActionSupported = NavigatorIsActionSupported;
function NavigatorIsActive: Boolean;
function NavigatorIsBof: Boolean;
function NavigatorIsEof: Boolean;
function NavigatorCanAppend: Boolean;
function NavigatorCanEdit: Boolean;
function NavigatorCanDelete: Boolean;
function NavigatorCanInsert: Boolean;
function NavigatorIsEditing: Boolean;
procedure NavigatorClearBookmark;
function NavigatorIsBookmarkAvailable: Boolean;
procedure NavigatorDoAction(AButtonIndex: Integer);
function NavigatorGetNotifier: TcxNavigatorControlNotifier;
function NavigatorIsActionSupported(AButtonIndex: Integer): Boolean;
procedure AddChildComponent(AComponent: TcxControlChildComponent); override;
procedure RemoveChildComponent(AComponent: TcxControlChildComponent); override;
procedure BoundsChanged; override;
procedure DoCancelMode; override;
procedure DoContextPopup(MousePos: TPoint; var Handled: Boolean); override;
procedure FocusChanged; override;
{$IFNDEF DELPHI12}
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
{$ENDIF}
function GetCursor(X, Y: Integer): TCursor; override;
function GetDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean; override;
function GetIsFocused: Boolean; override;
procedure Loaded; override;
function MayFocus: Boolean; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues); override;
procedure Paint; override;
procedure ReadState(Reader: TReader); override;
procedure SetChildOrder(Child: TComponent; Order: Integer); override;
procedure SetName(const NewName: TComponentName); override;
procedure WndProc(var Message: TMessage); override;
procedure DoEndDrag(Target: TObject; X, Y: Integer); override;
procedure DoStartDrag(var DragObject: TDragObject); override;
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override;
procedure CreateHandlers; virtual;
procedure DestroyHandlers; virtual;
procedure DoActiveTabChanged(ALevel: TcxGridLevel); virtual;
procedure DoChange(AGridChange: TcxCustomGridChange);
procedure DoLayoutChanged(AGridView: TcxCustomGridView); virtual;
procedure DoProcessChangesStack;
procedure DoUpdate(AChanges: TList);
procedure FocusedViewChanged(APrevFocusedView, AFocusedView: TcxCustomGridView); virtual;
function GetControllerClass: TcxGridControllerClass; virtual;
function GetDefaultViewClass: TcxCustomGridViewClass; virtual;
function GetLevelsClass: TcxGridLevelClass; virtual;
function GetLevelTabsClass: TcxGridLevelTabsClass; virtual;
function GetPainterClass: TcxGridPainterClass; virtual;
function GetViewInfoClass: TcxGridViewInfoClass; virtual;
procedure LevelChanged(ALevel: TcxGridLevel; AChangeKind: TcxGridLevelChangeKind);
procedure RefreshNavigators;
procedure StructureNavigatorChanged;
function UpdateOnRootViewDataChange: Boolean; virtual;
procedure ViewChanged(AView: TcxCustomGridView; AChangeKind: TcxGridViewChangeNotificationKind);
procedure UpdateFocusing(AChildFocused: Boolean);
property LastFocused: Boolean read FLastFocused;
property FocusedViewNavigator: IcxNavigator read GetFocusedViewNavigator;
property IsPopupControl: Boolean read FIsPopupControl write FIsPopupControl;
property NavigatorNotifier: TcxNavigatorControlNotifier read FNavigatorNotifier;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{$IFDEF DELPHI12}
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
{$ENDIF}
procedure Invalidate(AHardUpdate: Boolean = False); reintroduce;
procedure RemoveFocus(AGoForward: Boolean);
procedure BeginUpdate;
procedure CancelUpdate;
procedure Changed(AGridChange: TcxCustomGridChange);
procedure CheckFocusedView;
procedure EndUpdate;
procedure LayoutChanged; virtual;
procedure SizeChanged; virtual;
property UpdateLocked: Boolean read GetUpdateLocked;
function CreateView(AViewClass: TcxCustomGridViewClass): TcxCustomGridView;
function ViewExists(AView: TcxCustomGridView): Boolean;
procedure RegisterNotification(ANotification: TcxCustomGridNotification);
procedure UnregisterNotification(ANotification: TcxCustomGridNotification);
function SendNotifications(AKind: TcxGridNotificationKind; AData: TObject = nil): Boolean;
procedure RootViewDataChanged(AView: TcxCustomGridView); virtual;
// IdxLocalizerListener
procedure TranslationChanged; override;
property ActiveView: TcxCustomGridView read GetActiveView;
property ActiveLevel: TcxGridLevel read FActiveLevel write SetActiveLevel;
property BorderStyle default cxcbsDefault;
property Color;
property Controller: TcxGridController read FController;
property DragOpening: Boolean read FDragOpening write FDragOpening default True;
property DragOpeningWaitTime: Integer read FDragOpeningWaitTime write SetDragOpeningWaitTime
default cxGridDefaultDragOpeningWaitTime;
property FocusedView: TcxCustomGridView read FFocusedView write SetFocusedView;
property Font;
property Levels: TcxGridLevel read FLevels write SetLevels;
property LevelTabs: TcxGridLevelTabs read FLevelTabs write SetLevelTabs;
property LookAndFeel;
property LookAndFeelPainter;
property Painter: TcxGridPainter read FPainter;
property RootLevelOptions: TcxGridLevelOptions read GetRootLevelOptions write SetRootLevelOptions;
property RootLevelStyles: TcxGridLevelStyles read GetRootLevelStyles write SetRootLevelStyles;
property StructureNavigator: TcxCustomGridStructureNavigator read GetStructureNavigator;
property TabStop: Boolean read FTabStop write SetTabStop default True;
property ViewCount: Integer read GetViewCount;
property ViewInfo: TcxGridViewInfo read FViewInfo;
property Views[Index: Integer]: TcxCustomGridView read GetView;
property OnActiveTabChanged: TcxGridActiveTabChangedEvent read FOnActiveTabChanged write FOnActiveTabChanged;
property OnFocusedViewChanged: TcxGridFocusedViewChangedEvent read FOnFocusedViewChanged write FOnFocusedViewChanged;
property OnLayoutChanged: TcxGridLayoutChangedEvent read FOnLayoutChanged write FOnLayoutChanged;
published
property RootLevelStylesEvents: TNotifyEvent read FSubClassEvents write FSubClassEvents;
end;
TcxGrid = class(TcxCustomGrid)
published
property Align;
property Anchors;
{$IFDEF DELPHI6}
property BevelEdges;
property BevelInner;
property BevelOuter;
property BevelKind;
property BevelWidth;
property BorderWidth;
{$ENDIF}
property BorderStyle;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
//property ParentColor;
property ParentFont;
property PopupMenu;
property TabOrder;
property TabStop;
property Visible;
//property OnClick;
{$IFDEF DELPHI5}
property OnContextPopup;
{$ENDIF}
//property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
{property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;}
property OnResize;
property OnStartDock;
property OnStartDrag;
property DragOpening;
property DragOpeningWaitTime;
property LevelTabs;
property LookAndFeel;
property RootLevelOptions;
property RootLevelStyles;
property OnActiveTabChanged;
property OnFocusedViewChanged;
property OnLayoutChanged;
property OnMouseEnter;
property OnMouseLeave;
end;
{ TcxGridViewRepository }
TcxGridViewRepository = class(TComponent) {5}
private
FItems: TList;
function GetCount: Integer;
function GetItem(Index: Integer): TcxCustomGridView;
procedure DestroyItems;
protected
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
procedure AddItem(AItem: TcxCustomGridView);
procedure RemoveItem(AItem: TcxCustomGridView);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function CreateItem(AItemClass: TcxCustomGridViewClass): TcxCustomGridView;
property Count: Integer read GetCount;
property Items[Index: Integer]: TcxCustomGridView read GetItem; default;
end;
var
cxGridStructureNavigatorClass: TcxCustomGridStructureNavigatorClass;
function GetParentGrid(AControl: TControl): TcxCustomGrid;
implementation
uses
SysUtils, Math, cxGridCustomTableView;
function GetLevel(ACaller: TComponent; Index: Integer): TComponent;
begin
Result := TComponent(TList(TcxCustomGrid(ACaller).FTag)[Index]);
end;
function GetView(ACaller: TComponent; Index: Integer): TComponent;
begin
Result := TcxCustomGrid(ACaller).Views[Index];
end;
{ TcxGridLayoutChange }
procedure TcxGridLayoutChange.Execute;
begin
if GridView <> nil then
with GridView do
if TcxCustomGridViewAccess.GetChangeable(GridView) and
not IsRectEmpty(Site.BoundsRect) then
begin
ViewInfo.MainCalculate(Site.BoundsRect);
Painter.Invalidate;
end
else
else
with TcxCustomGrid(Control) do
if ViewInfo <> nil then
begin
ViewInfo.MainCalculate;
Painter.Invalidate(True);
end;
if Control <> nil then {7}
TcxCustomGrid(Control).DoLayoutChanged(GridView);
end;
function TcxGridLayoutChange.IsCompatibleWith(AChange: TcxCustomGridChange): Boolean;
begin
Result := inherited IsCompatibleWith(AChange) or
(AChange is TcxGridLayoutChange) and
((TcxGridLayoutChange(AChange).GridView = nil) or
(GridView <> nil) and GridView.HasAsMaster(TcxGridLayoutChange(AChange).GridView)) or
(AChange is TcxGridSizeChange) and
((TcxGridSizeChange(AChange).GridView = nil) or
(GridView <> nil) and
((GridView = TcxGridSizeChange(AChange).GridView) or
GridView.HasAsMaster(TcxGridSizeChange(AChange).GridView)));
end;
{ TcxGridSizeChange }
constructor TcxGridSizeChange.Create(AGridView: TcxCustomGridView;
AUpdateGridViewOnly: Boolean = False; AKeepMaster: Boolean = False);
begin
inherited Create(AGridView);
FUpdateGridViewOnly := AUpdateGridViewOnly;
FKeepMaster := AKeepMaster;
end;
procedure TcxGridSizeChange.Execute;
begin
if GridView = nil then
with TcxCustomGrid(Control) do
if ActiveView <> nil then
ActiveView.SizeChanged(False, FKeepMaster)
else
LayoutChanged
else
with GridView do
if TcxCustomGridViewAccess.GetChangeable(GridView) then
begin
if ViewInfoCache <> nil then
ViewInfoCache.UnassignValues(FKeepMaster);
if FUpdateGridViewOnly and FKeepMaster then
LayoutChanged
else
if MasterGridView = nil then
if {(Control = nil) or }IsPattern then
{//}LayoutChanged
else
TcxCustomGrid(Control).LayoutChanged
else
if not IsPattern and not MasterGridView.SizeChanged(False, FKeepMaster) then
LayoutChanged;
end;
end;
function TcxGridSizeChange.IsCompatibleWith(AChange: TcxCustomGridChange): Boolean;
begin
Result := inherited IsCompatibleWith(AChange) or
(AChange is TcxGridSizeChange) and (TcxGridSizeChange(AChange).GridView = GridView) and
(TcxGridSizeChange(AChange).KeepMaster = FKeepMaster) and FUpdateGridViewOnly or
(AChange is TcxGridDataChange) and (TcxGridDataChange(AChange).GridView = GridView);
end;
function TcxGridSizeChange.IsEqual(AChange: TcxCustomGridChange): Boolean;
begin
Result := inherited IsEqual(AChange) and
(FKeepMaster = TcxGridSizeChange(AChange).KeepMaster) and
(FUpdateGridViewOnly = TcxGridSizeChange(AChange).UpdateGridViewOnly);
end;
{ TcxGridViewChange }
constructor TcxGridViewChange.Create(AGridView: TcxCustomGridView;
const AUpdateBounds: TRect);
begin
inherited Create(AGridView);
FUpdateBounds := AUpdateBounds;
end;
constructor TcxGridViewChange.Create(AGridView: TcxCustomGridView;
const AUpdateRegion: TcxRegion);
begin
inherited Create(AGridView);
FUpdateRegion := TcxRegion.Create;
FUpdateRegion.Combine(AUpdateRegion, roSet, False);
end;
constructor TcxGridViewChange.Create(AGridView: TcxCustomGridView);
begin
Create(AGridView, Rect(0, 0, 0, 0));
end;
destructor TcxGridViewChange.Destroy;
begin
FUpdateRegion.Free;
inherited;
end;
procedure TcxGridViewChange.Execute;
begin
if not IsRectEmpty(FUpdateBounds) then
GridView.Painter.Invalidate(FUpdateBounds)
else
if FUpdateRegion <> nil then
GridView.Painter.Invalidate(FUpdateRegion)
else
GridView.Painter.Invalidate;
end;
function TcxGridViewChange.IsCompatibleWith(AChange: TcxCustomGridChange): Boolean;
begin
Result := inherited IsCompatibleWith(AChange) or
(AChange is TcxGridLayoutChange) and (TcxGridLayoutChange(AChange).GridView = GridView) or
(AChange is TcxGridSizeChange) and (TcxGridSizeChange(AChange).GridView = GridView);
end;
function TcxGridViewChange.IsEqual(AChange: TcxCustomGridChange): Boolean;
begin
Result := inherited IsEqual(AChange) and
((FUpdateRegion = nil) and (TcxGridViewChange(AChange).UpdateRegion = nil) and
EqualRect(FUpdateBounds, TcxGridViewChange(AChange).UpdateBounds) or
(FUpdateRegion <> nil) and (TcxGridViewChange(AChange).UpdateRegion <> nil) and
FUpdateRegion.IsEqual(TcxGridViewChange(AChange).UpdateRegion));
end;
{ TcxCustomGridStructureNavigator }
constructor TcxCustomGridStructureNavigator.Create(AGrid: TcxCustomGrid);
begin
inherited Create(nil);
FGrid := AGrid;
Parent := FGrid;
end;
procedure TcxCustomGridStructureNavigator.Changed;
begin
BoundsRect := CalculateBoundsRect;
BringToFront;
Invalidate;
end;
procedure TcxCustomGridStructureNavigator.FontChanged;
begin
inherited;
Changed;
end;
function TcxCustomGridStructureNavigator.MayFocus: Boolean;
begin
Result := False;
end;
procedure TcxCustomGridStructureNavigator.BeforeGridLoading;
begin
end;
{ TcxCustomGridHandler }
constructor TcxCustomGridHandler.Create(AControl: TcxCustomGrid);
begin
inherited Create;
FControl := AControl;
end;
function TcxCustomGridHandler.GetActiveController: TcxCustomGridController;
begin
if ActiveGridView <> nil then
Result := ActiveGridView.Controller
else
Result := nil;
end;
function TcxCustomGridHandler.GetActiveGridView: TcxCustomGridView;
begin
Result := FControl.ActiveView;
end;
function TcxCustomGridHandler.GetLookAndFeelPainter: TcxCustomLookAndFeelPainterClass;
begin
Result := FControl.LookAndFeelPainter;
end;
function TcxCustomGridHandler.GetViewInfo: TcxGridViewInfo;
begin
Result := FControl.ViewInfo;
end;
{ TcxGridDesignController }
constructor TcxGridDesignController.Create(AControl: TcxCustomGrid);
begin
inherited Create;
FControl := AControl;
end;
function TcxGridDesignController.GetControl: TcxControl;
begin
Result := FControl;
end;
{ TcxGridDragOpenInfoTab }
constructor TcxGridDragOpenInfoTab.Create(ALevel: TcxGridLevel);
begin
inherited Create;
Level := ALevel;
end;
function TcxGridDragOpenInfoTab.Equals(AInfo: TcxCustomGridDragOpenInfo): Boolean;
begin
Result := inherited Equals(AInfo) and
(Level = TcxGridDragOpenInfoTab(AInfo).Level);
end;
procedure TcxGridDragOpenInfoTab.Run;
begin
Level.Active := True;
end;
{ TcxGridController }
destructor TcxGridController.Destroy;
begin
FreeAndNil(FDesignController);
inherited;
end;
function TcxGridController.GetDesignController: TcxGridDesignController;
begin
if (FDesignController = nil) and Control.IsDesigning then
FDesignController := GetDesignControllerClass.Create(Control);
Result := FDesignController;
end;
procedure TcxGridController.DragOpenTimerHandler(Sender: TObject);
begin
FDragOpenTimer.Enabled := False;
try
FDragOpenInfo.Run;
finally
StopDragOpen;
end;
end;
function TcxGridController.GetDesignControllerClass: TcxGridDesignControllerClass;
begin
Result := TcxGridDesignController;
end;
procedure TcxGridController.DoCancelMode;
begin
if ActiveController <> nil then
ActiveController.DoCancelMode;
end;
procedure TcxGridController.FocusChanged;
begin
if ActiveController <> nil then
ActiveController.DoControlFocusChanged;
end;
function TcxGridController.GetCursor(X, Y: Integer): TCursor;
begin
Result := crDefault;
end;
procedure TcxGridController.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
AHitTest: TcxCustomGridHitTest;
begin
AHitTest := ViewInfo.GetHitTest(X, Y);
if AHitTest.ViewInfo <> nil then
AHitTest.ViewInfo.MouseDown(AHitTest, Button, Shift);
end;
procedure TcxGridController.MouseMove(Shift: TShiftState; X, Y: Integer);
var
AHitTest: TcxCustomGridHitTest;
begin
AHitTest := ViewInfo.GetHitTest(X, Y);
if AHitTest.ViewInfo <> nil then
AHitTest.ViewInfo.MouseMove(AHitTest, Shift);
end;
procedure TcxGridController.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
end;
procedure TcxGridController.DragOver(Source: TObject; X, Y: Integer; State: TDragState;
var Accept: Boolean);
procedure ProcessOpening;
var
AHitTest: TcxCustomGridHitTest;
ADragOpenInfo: TcxCustomGridDragOpenInfo;
begin
AHitTest := ViewInfo.GetHitTest(X, Y);
if (State <> dsDragLeave) and IsDragOpenHitTest(AHitTest, ADragOpenInfo) then
StartDragOpen(ADragOpenInfo)
else
StopDragOpen;
end;
begin
if Control.DragOpening then
ProcessOpening;
end;
procedure TcxGridController.EndDrag(Target: TObject; X, Y: Integer);
begin
StopDragOpen;
end;
procedure TcxGridController.StartDrag(var DragObject: TDragObject);
begin
end;
function TcxGridController.GetDragOpenInfo(AHitTest: TcxCustomGridHitTest): TcxCustomGridDragOpenInfo;
begin
if AHitTest.HitTestCode = htTab then
with TcxGridDetailsSiteTabHitTest(AHitTest) do
Result := TcxGridDragOpenInfoTab.Create(Level)
else
Result := nil;
end;
function TcxGridController.IsDragOpenHitTest(AHitTest: TcxCustomGridHitTest;
out ADragOpenInfo: TcxCustomGridDragOpenInfo): Boolean;
begin
ADragOpenInfo := GetDragOpenInfo(AHitTest);
Result := ADragOpenInfo <> nil;
end;
procedure TcxGridController.StartDragOpen(ADragOpenInfo: TcxCustomGridDragOpenInfo);
begin
if (FDragOpenInfo <> nil) and FDragOpenInfo.Equals(ADragOpenInfo) then
begin
ADragOpenInfo.Free;
Exit;
end;
FDragOpenInfo.Free;
FDragOpenInfo := ADragOpenInfo;
if FDragOpenTimer = nil then
begin
FDragOpenTimer := TcxTimer.Create(nil);
with FDragOpenTimer do
begin
Interval := Control.DragOpeningWaitTime;
OnTimer := DragOpenTimerHandler;
end;
end
else
with FDragOpenTimer do
begin
Enabled := False;
Enabled := True;
end;
end;
procedure TcxGridController.StopDragOpen;
begin
FreeAndNil(FDragOpenTimer);
FreeAndNil(FDragOpenInfo);
end;
{ TcxGridPainter }
function TcxGridPainter.GetCanvas: TcxCanvas;
begin
Result := Control.ActiveCanvas;
end;
procedure TcxGridPainter.DrawDetailsSite;
begin
with TcxGridTopDetailsSiteViewInfo(ViewInfo.DetailsSiteViewInfo) do
if Visible then Paint(Self.Canvas);
end;
{procedure TcxGridPainter.DrawEmptyArea;
begin
Canvas.Brush.Color := ViewInfo.EmptyAreaColor;
Canvas.FillRect(ViewInfo.ClientBounds);
end;}
procedure TcxGridPainter.Invalidate(AInvalidateDetails: Boolean);
var
I: Integer;
AControl: TControl;
begin
Control.Invalidate;
if AInvalidateDetails then
for I := 0 to Control.ControlCount - 1 do
begin
AControl := Control.Controls[I];
if AControl is TcxGridSite then
AControl.Invalidate;
end;
end;
procedure TcxGridPainter.Invalidate(const R: TRect);
begin
Control.InvalidateRect(R, False);
end;
procedure TcxGridPainter.Paint;
begin
DrawDetailsSite;
//DrawEmptyArea;
end;
{ TcxGridTopDetailsSiteViewInfo }
function TcxGridTopDetailsSiteViewInfo.GetControl: TcxCustomGrid;
begin
Result := TcxCustomGrid(Level.Control);
end;
function TcxGridTopDetailsSiteViewInfo.CalculateHeight: Integer;
begin
Result := MaxHeight;
end;
function TcxGridTopDetailsSiteViewInfo.CalculateWidth: Integer;
begin
Result := MaxWidth;
end;
function TcxGridTopDetailsSiteViewInfo.GetActiveGridView: TcxCustomGridView;
begin
Result := Control.ActiveView;
end;
function TcxGridTopDetailsSiteViewInfo.GetActiveLevel: TcxGridLevel;
begin
Result := Control.ActiveLevel;
end;
function TcxGridTopDetailsSiteViewInfo.GetCanvas: TcxCanvas;
begin
Result := Control.Painter.Canvas;
end;
function TcxGridTopDetailsSiteViewInfo.GetContainer: TcxControl;
begin
Result := Control;
end;
function TcxGridTopDetailsSiteViewInfo.GetDesignController: TcxCustomGridDesignController;
begin
Result := Control.Controller.DesignController;
end;
function TcxGridTopDetailsSiteViewInfo.GetMasterRecord: TObject;
begin
Result := nil;
end;
function TcxGridTopDetailsSiteViewInfo.GetMaxHeight: Integer;
begin
with Control.ViewInfo.ClientBounds do
Result := Bottom - Top;
end;
function TcxGridTopDetailsSiteViewInfo.GetMaxWidth: Integer;
begin
with Control.ViewInfo.ClientBounds do
Result := Right - Left;
end;
procedure TcxGridTopDetailsSiteViewInfo.InitTabHitTest(AHitTest: TcxGridDetailsSiteTabHitTest);
begin
AHitTest.Owner := Control;
end;
procedure TcxGridTopDetailsSiteViewInfo.ChangeActiveTab(ALevel: TcxGridLevel;
AFocusView: Boolean = False);
begin
Control.ActiveLevel := ALevel;
end;
function TcxGridTopDetailsSiteViewInfo.DetailHasData(ALevel: TcxGridLevel): Boolean;
begin
Result := (ALevel.GridView <> nil) and not ALevel.GridView.ViewData.IsEmpty;
end;
function TcxGridTopDetailsSiteViewInfo.SupportsTabAccelerators: Boolean;
begin
Result := True;
end;
procedure TcxGridTopDetailsSiteViewInfo.VisibilityChanged(AVisible: Boolean);
begin
if not Control.IsDestroying then inherited;
end;
{ TcxGridViewInfo }
constructor TcxGridViewInfo.Create(AControl: TcxCustomGrid);
begin
inherited;
CreateViewInfos;
end;
destructor TcxGridViewInfo.Destroy;
begin
DestroyViewInfos;
FDetailsSiteViewInfoCachedInfo.Free;
inherited;
end;
function TcxGridViewInfo.GetBounds: TRect;
begin
Result := Control.Bounds;
end;
function TcxGridViewInfo.GetClientBounds: TRect;
begin
Result := Control.ClientBounds;
end;
function TcxGridViewInfo.GetEmptyAreaColor: TColor;
begin
Result := Control.Color;
end;
procedure TcxGridViewInfo.CreateViewInfos;
begin
FDetailsSiteViewInfo :=
TcxGridTopDetailsSiteViewInfoClass(GetDetailsSiteViewInfoClass).Create(Control.Levels);
if FDetailsSiteViewInfoCachedInfo <> nil then
FDetailsSiteViewInfo.SetCachedInfo(FDetailsSiteViewInfoCachedInfo);
end;
procedure TcxGridViewInfo.DestroyViewInfos;
begin
FDetailsSiteViewInfo.GetCachedInfo(FDetailsSiteViewInfoCachedInfo);
FDetailsSiteViewInfo.Free;
end;
function TcxGridViewInfo.GetDetailsSiteViewInfoClass: TcxGridTopDetailsSiteViewInfoClass;
begin
Result := TcxGridTopDetailsSiteViewInfo;
end;
procedure TcxGridViewInfo.RecreateViewInfos;
begin
DestroyViewInfos;
CreateViewInfos;
end;
procedure TcxGridViewInfo.Calculate;
begin
RecreateViewInfos;
with ClientBounds, TcxGridTopDetailsSiteViewInfo(FDetailsSiteViewInfo) do
if Visible then Calculate(Left, Top);
end;
function TcxGridViewInfo.GetHitTest(X, Y: Integer): TcxCustomGridHitTest;
begin
Result := TcxGridTopDetailsSiteViewInfo(FDetailsSiteViewInfo).GetHitTest(Point(X, Y));
if Result = nil then
Result := TcxGridNoneHitTest.Instance(Point(X, Y));
end;
procedure TcxGridViewInfo.MainCalculate;
var
APrevIsCalculating: Boolean;
begin
APrevIsCalculating := IsCalculating;
FIsCalculating := True;
try
Calculate;
finally
FIsCalculating := APrevIsCalculating;
end;
end;
{ TcxGridLevelTabs }
constructor TcxGridLevelTabs.Create(AOwner: TcxCustomGrid);
begin
inherited Create;
FOwner := AOwner;
FCaptionAlignment := cxGridLevelTabsDefaultCaptionAlignment;
FFreeNotificator := TcxFreeNotificator.Create(nil);
FFreeNotificator.OnFreeNotification := FreeNotification;
FImageBorder := cxGridLevelTabsDefaultImageBorder;
FImagesChangeLink := TChangeLink.Create;
FImagesChangeLink.OnChange := ImagesChanged;
FSlants := TcxTabSlants.Create(Self);
FSlants.OnChange := SlantsChanged;
FStyle := cxPCDefaultStyle;
end;
destructor TcxGridLevelTabs.Destroy;
begin
FSlants.Free;
FImagesChangeLink.Free;
FFreeNotificator.Free;
inherited;
end;
procedure TcxGridLevelTabs.SetCaptionAlignment(Value: TAlignment);
begin
if FCaptionAlignment <> Value then
begin
FCaptionAlignment := Value;
Changed;
end;
end;
procedure TcxGridLevelTabs.SetImageBorder(Value: Integer);
begin
if Value < 0 then Value := 0;
if FImageBorder <> Value then
begin
FImageBorder := Value;
Changed;
end;
end;
procedure TcxGridLevelTabs.SetImages(Value: TCustomImageList);
begin
cxSetImageList(Value, FImages, FImagesChangeLink, FFreeNotificator);
end;
procedure TcxGridLevelTabs.SetSlants(Value: TcxTabSlants);
begin
FSlants.Assign(Value);
end;
procedure TcxGridLevelTabs.SetStyle(Value: TcxPCStyleID);
begin
if FStyle <> Value then
begin
FStyle := Value;
Changed;
end;
end;
procedure TcxGridLevelTabs.FreeNotification(Sender: TComponent);
begin
if Sender = Images then Images := nil;
end;
procedure TcxGridLevelTabs.ImagesChanged(Sender: TObject);
begin
Changed;
end;
procedure TcxGridLevelTabs.SlantsChanged(Sender: TObject);
begin
Changed;
end;
procedure TcxGridLevelTabs.Changed;
begin
FOwner.SizeChanged;
end;
procedure TcxGridLevelTabs.Assign(Source: TPersistent);
begin
if Source is TcxGridLevelTabs then
with TcxGridLevelTabs(Source) do
begin
Self.CaptionAlignment := CaptionAlignment;
Self.ImageBorder := ImageBorder;
Self.Images := Images;
Self.Slants := Slants;
Self.Style := Style;
end
else
inherited;
end;
{ TcxGridRootLevelOptions }
constructor TcxGridRootLevelOptions.Create(ALevel: TcxGridLevel);
begin
inherited;
DetailFrameWidth := cxGridRootLevelDefaultDetailFrameWidth;
end;
{ TcxGridRootLevel }
function TcxGridRootLevel.GetOptionsClass: TcxGridLevelOptionsClass;
begin
Result := TcxGridRootLevelOptions;
end;
{ TcxCustomGrid }
constructor TcxCustomGrid.Create(AOwner: TComponent);
begin
inherited;
BorderStyle := cxcbsDefault;
ControlStyle := ControlStyle + [csDisplayDragImage];
FDragOpening := True;
FDragOpeningWaitTime := cxGridDefaultDragOpeningWaitTime;
FLevelTabs := GetLevelTabsClass.Create(Self);
FNotifications := TList.Create;
FViews := TList.Create;
FChanges := TList.Create;
FChangesStack := TList.Create;
FTabStop := True;
Levels := GetLevelsClass.Create(nil);
CreateHandlers;
Width := 250;
Height := 200;
end;
destructor TcxCustomGrid.Destroy;
procedure HideRootViews;
var
I: Integer;
begin
for I := 0 to Levels.VisibleCount - 1 do
with Levels.VisibleItems[I] do
if GridView <> nil then GridView.ViewInfo.DoVisibilityChanged(False);
end;
begin
HideRootViews;
//Levels := nil;
DestroyHandlers;
Levels := nil;
DestroyViews;
FViews.Free;
FreeAndNil(FNotifications);
FreeAndNil(FLevelTabs);
DestroyChanges(FChangesStack);
FreeAndNil(FChangesStack);
FreeAndNil(FChanges);
inherited;
end;
function TcxCustomGrid.GetActiveView: TcxCustomGridView;
begin
if FActiveLevel = nil then
Result := nil
else
Result := FActiveLevel.GridView;
end;
function TcxCustomGrid.GetFocusedViewNavigator: IcxNavigator;
begin
if (FocusedView = nil) or not Supports(FocusedView, IcxNavigator) then
Result := nil
else
Result := FocusedView as IcxNavigator;
end;
function TcxCustomGrid.GetView(Index: Integer): TcxCustomGridView;
begin
Result := TcxCustomGridView(FViews[Index]);
end;
function TcxCustomGrid.GetViewCount: Integer;
begin
Result := FViews.Count;
end;
function TcxCustomGrid.GetRootLevelOptions: TcxGridLevelOptions;
begin
Result := FLevels.Options;
end;
function TcxCustomGrid.GetRootLevelStyles: TcxGridLevelStyles;
begin
Result := FLevels.Styles;
end;
function TcxCustomGrid.GetStructureNavigator: TcxCustomGridStructureNavigator;
begin
CreateStructureNavigator;
Result := FStructureNavigator;
end;
function TcxCustomGrid.GetUpdateLocked: Boolean;
{
function DataControllerLocked: Boolean; //!!!!!!!!!!!!!!!!!!!!
var
I, J: Integer;
function CheckDataController(AView: TcxCustomGridView; out ALocked: Boolean): Boolean;
begin
ALocked := AView.DataController.LockCount <> 0;
Result := ALocked;
end;
begin
for I := 0 to ViewCount - 1 do
begin
if CheckDataController(Views[I], Result) then Exit;
for J := 0 to Views[I].CloneCount - 1 do
if CheckDataController(Views[I].Clones[J], Result) then Exit;
end;
Result := False;
end;
}
begin
Result := (FUpdateLockCount <> 0) {or DataControllerLocked};
end;
procedure TcxCustomGrid.SetActiveLevel(Value: TcxGridLevel);
begin
if FActiveLevel <> Value then
begin
if Value = nil then
Value := FLevels.GetAvailableItem
else
if not Value.Visible then
Exit;
FActiveLevel := Value;
SizeChanged;
if not IsLoading and (FActiveLevel <> nil) then
DoActiveTabChanged(FActiveLevel);
if FActiveLevel <> nil then
FocusedView := FActiveLevel.GridView
else
FocusedView := nil;
end;
end;
procedure TcxCustomGrid.SetDragOpeningWaitTime(Value: Integer);
begin
if Value < 0 then Value := 0;
FDragOpeningWaitTime := Value;
end;
procedure TcxCustomGrid.SetFocusedView(Value: TcxCustomGridView);
var
APrevFocusedView: TcxCustomGridView;
APrevFocused: Boolean;
function GetAvailableView: TcxCustomGridView;
var
I: Integer;
function CheckMasterView(AView: TcxCustomGridView): TcxCustomGridView;
begin
Result := AView;
repeat
Result := Result.MasterGridView;
until (Result = nil) or not Result.IsDestroying;
end;
begin
Result := CheckMasterView(FFocusedView);
if Result = nil then
begin
for I := 0 to Levels.Count - 1 do
begin
Result := Levels[I].GridView;
if (Result <> nil) and not Result.IsDestroying then Exit;
end;
Result := nil;
end;
end;
begin
if (Value <> nil) and not TcxCustomGridViewAccess.CanFocus(Value) then Exit;
if FFocusedView <> Value then
begin
APrevFocusedView := FFocusedView;
if not IsDestroying and not IsDesigning and
((Value = nil) and (ActiveLevel <> nil) and (ActiveLevel.GridView <> nil) or
(Value <> nil) and Value.IsDestroying) then
Value := GetAvailableView;
FFocusedView := Value;
if APrevFocusedView <> nil then
begin
APrevFocused := IsFocused;
try
TcxCustomGridViewAccess.FocusChanged(APrevFocusedView, False);
except
FocusedView := APrevFocusedView;
raise;
end;
if APrevFocused and not IsFocused then
SetFocus;
end;
if FFocusedView <> nil then
begin
TcxCustomGridViewAccess.FocusChanged(FFocusedView, True);
TcxGridLevel(FFocusedView.Level).Active := True;
end
else
if IsFocused and CanFocusEx then
SetFocus;
FocusedViewChanged(APrevFocusedView, FFocusedView);
end;
end;
procedure TcxCustomGrid.SetLevels(Value: TcxGridLevel);
begin
FLevels.Free;
FLevels := Value;
if FLevels <> nil then
FLevels.Control := Self;
end;
procedure TcxCustomGrid.SetLevelTabs(Value: TcxGridLevelTabs);
begin
FLevelTabs.Assign(Value);
end;
procedure TcxCustomGrid.SetRootLevelOptions(Value: TcxGridLevelOptions);
begin
end;
procedure TcxCustomGrid.SetRootLevelStyles(Value: TcxGridLevelStyles);
begin
end;
procedure TcxCustomGrid.SetTabStop(Value: Boolean);
begin
if FTabStop <> Value then
begin
FTabStop := Value;
if FocusedView <> nil then
FocusedView.TabStop := FTabStop;
end;
end;
procedure TcxCustomGrid.AddView(AView: TcxCustomGridView);
begin
FViews.Add(AView);
AView.DataController.SetMasterMode(nil, True);
end;
procedure TcxCustomGrid.RemoveView(AView: TcxCustomGridView);
begin
FViews.Remove(AView);
DestroyViewChanges(AView);
//ViewChanged(AView, vsRemoved);
end;
procedure TcxCustomGrid.DestroyViews;
var
I: Integer;
begin
for I := ViewCount - 1 downto 0 do
Views[I].Free;
end;
procedure TcxCustomGrid.DestroyChanges(AChanges: TList);
var
I: Integer;
begin
for I := 0 to AChanges.Count - 1 do
TObject(AChanges[I]).Free;
AChanges.Clear;
end;
procedure TcxCustomGrid.DestroyViewChanges(AView: TcxCustomGridView);
procedure ClearViewChanges(AChanges: TList);
var
I: Integer;
begin
for I := AChanges.Count - 1 downto 0 do
if (TcxCustomGridChange(AChanges[I]) is TcxCustomGridViewChange) and
(TcxCustomGridViewChange(AChanges[I]).GridView = AView) then
begin
TObject(AChanges[I]).Free;
AChanges.Delete(I);
end;
end;
begin
ClearViewChanges(FChanges);
ClearViewChanges(FChangesStack);
end;
procedure TcxCustomGrid.CreateStructureNavigator;
begin
if (FStructureNavigator = nil) and
IsDesigning and (cxGridStructureNavigatorClass <> nil) and
(FController <> nil) and not FCreatingStructureNavigator then
begin
FCreatingStructureNavigator := True;
try
FStructureNavigator := cxGridStructureNavigatorClass.Create(Self);
finally
FCreatingStructureNavigator := False;
end;
end;
end;
{procedure TcxCustomGrid.CMDeferUpdates(var Message: TMessage);
begin
DoProcessChangesStack;
end;}
procedure TcxCustomGrid.CMDialogChar(var Message: TCMDialogChar);
begin
if TcxGridTopDetailsSiteViewInfo(ViewInfo.DetailsSiteViewInfo).ProcessDialogChar(Message.CharCode) then
Message.Result := 1
else
inherited;
end;
function TcxCustomGrid.NavigatorIsActive: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.IsActive;
end;
function TcxCustomGrid.NavigatorIsBof: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.IsBof;
end;
function TcxCustomGrid.NavigatorIsEof: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.IsEof;
end;
function TcxCustomGrid.NavigatorCanAppend: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.CanAppend;
end;
function TcxCustomGrid.NavigatorCanEdit: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.CanEdit;
end;
function TcxCustomGrid.NavigatorCanDelete: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.CanDelete;
end;
function TcxCustomGrid.NavigatorCanInsert: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.CanInsert;
end;
function TcxCustomGrid.NavigatorIsEditing: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.IsEditing;
end;
procedure TcxCustomGrid.NavigatorClearBookmark;
begin
if FocusedViewNavigator <> nil then
FocusedViewNavigator.ClearBookmark;
end;
function TcxCustomGrid.NavigatorIsBookmarkAvailable: Boolean;
begin
if FocusedViewNavigator = nil then
Result := False
else
Result := FocusedViewNavigator.IsBookmarkAvailable;
end;
procedure TcxCustomGrid.NavigatorDoAction(AButtonIndex: Integer);
begin
if FocusedViewNavigator <> nil then
FocusedViewNavigator.DoAction(AButtonIndex);
end;
function TcxCustomGrid.NavigatorGetNotifier: TcxNavigatorControlNotifier;
begin
Result := FNavigatorNotifier;
end;
function TcxCustomGrid.NavigatorIsActionSupported(AButtonIndex: Integer): Boolean;
begin
Result := True;
end;
procedure TcxCustomGrid.AddChildComponent(AComponent: TcxControlChildComponent);
begin
inherited;
if AComponent is TcxCustomGridView then
AddView(TcxCustomGridView(AComponent));
end;
procedure TcxCustomGrid.RemoveChildComponent(AComponent: TcxControlChildComponent);
begin
inherited;
if AComponent is TcxCustomGridView then
RemoveView(TcxCustomGridView(AComponent));
end;
procedure TcxCustomGrid.BoundsChanged;
begin
if (ViewInfo = nil) or not ViewInfo.IsCalculating then
SizeChanged;
inherited;
StructureNavigatorChanged;
end;
procedure TcxCustomGrid.DoCancelMode;
begin
inherited;
FController.DoCancelMode;
end;
procedure TcxCustomGrid.DoContextPopup(MousePos: TPoint; var Handled: Boolean);
begin
inherited;
if not Handled then
Handled := SendNotifications(gnkContextMenu, TObject((MousePos.X = -1) and (MousePos.Y = -1)));
end;
procedure TcxCustomGrid.FocusChanged;
begin
inherited;
if not IsDestroying and Focused and (FocusedView <> nil) then
TcxCustomGridViewAccess.FocusChanged(FocusedView, True);
end;
procedure TcxCustomGrid.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
I: Integer;
begin
inherited;
for I := 0 to ViewCount - 1 do
if Views[I].Owner = Root then
Proc(Views[I]);
for I := 0 to FLevels.Count - 1 do
if FLevels[I].Owner = Root then
Proc(FLevels[I]);
end;
function TcxCustomGrid.GetCursor(X, Y: Integer): TCursor;
begin
Result := FController.GetCursor(X, Y);
if Result = crDefault then
Result := inherited GetCursor(X, Y);
end;
function TcxCustomGrid.GetDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean;
var
AHitTest: TcxCustomGridHitTest;
begin
Result := inherited GetDesignHitTest(X, Y, Shift);
if not Result and (ssLeft in Shift) then
begin
AHitTest := ViewInfo.GetHitTest(X, Y);
Result := AHitTest.HitTestCode = htTab;
end;
end;
function TcxCustomGrid.GetIsFocused: Boolean;
var
AForm: TCustomForm;
begin
Result := FIsPopupControl{8} or inherited GetIsFocused;
if not Result then
begin
AForm := GetParentForm(Self);
Result := (AForm <> nil) and (AForm.ActiveControl <> Self) and
ContainsControl(AForm.ActiveControl) and AForm.ActiveControl.Focused and
(not (AForm.ActiveControl is TcxControl) or TcxControl(AForm.ActiveControl).IsFocused);
end;
end;
procedure TcxCustomGrid.Loaded;
begin
inherited;
BeginUpdate;
try
LayoutChanged;
finally
EndUpdate;
end;
StructureNavigatorChanged;
end;
function TcxCustomGrid.MayFocus: Boolean;
begin
Result := False;
end;
procedure TcxCustomGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited;
FController.MouseDown(Button, Shift, X, Y);
end;
procedure TcxCustomGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
inherited;
FController.MouseMove(Shift, X, Y);
end;
procedure TcxCustomGrid.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited;
FController.MouseUp(Button, Shift, X, Y);
end;
procedure TcxCustomGrid.LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues);
var
I: Integer;
begin
inherited;
//SizeChanged;
for I := 0 to ViewCount - 1 do
TcxCustomGridViewAccess.LookAndFeelChanged(Views[I]);
SizeChanged;
end;
procedure TcxCustomGrid.Paint;
begin
inherited;
FPainter.Paint;
end;
procedure TcxCustomGrid.ReadState(Reader: TReader);
begin
if StructureNavigator <> nil then StructureNavigator.BeforeGridLoading;
inherited;
end;
procedure TcxCustomGrid.SetChildOrder(Child: TComponent; Order: Integer);
begin
inherited;
if Child is TcxGridLevel then
TcxGridLevel(Child).Index := Order - ViewCount;
end;
procedure TcxCustomGrid.SetName(const NewName: TComponentName);
var
AOldName: TComponentName;
ALevels: TList;
procedure RetriveLevels;
procedure AddLevel(ALevel: TcxGridLevel);
var
I: Integer;
begin
if ALevel.Name <> '' then ALevels.Add(ALevel);
for I := 0 to ALevel.Count - 1 do
AddLevel(ALevel[I]);
end;
begin
AddLevel(Levels);
end;
begin
AOldName := Name;
inherited;
if Name <> AOldName then
begin
RenameComponents(Self, Owner, Name, AOldName, ViewCount, @cxGrid.GetView);
ALevels := TList.Create;
try
RetriveLevels;
FTag := ALevels;
RenameComponents(Self, Owner, Name, AOldName, ALevels.Count, @cxGrid.GetLevel);
finally
ALevels.Free;
end;
StructureNavigatorChanged;
end;
end;
procedure TcxCustomGrid.WndProc(var Message: TMessage);
begin
{if (Message.Msg = WM_MOUSEACTIVATE) and IsDesigning then
Exit;}
inherited WndProc(Message);
end;
procedure TcxCustomGrid.DoEndDrag(Target: TObject; X, Y: Integer);
begin
FController.EndDrag(Target, X, Y);
inherited;
end;
procedure TcxCustomGrid.DoStartDrag(var DragObject: TDragObject);
begin
inherited;
FController.StartDrag(DragObject);
end;
procedure TcxCustomGrid.DragOver(Source: TObject; X, Y: Integer; State: TDragState;
var Accept: Boolean);
begin
inherited;
FController.DragOver(Source, X, Y, State, Accept);
end;
procedure TcxCustomGrid.CreateHandlers;
begin
FController := GetControllerClass.Create(Self);
FPainter := GetPainterClass.Create(Self);
FViewInfo := GetViewInfoClass.Create(Self);
FNavigatorNotifier := TcxNavigatorControlNotifier.Create;
CreateStructureNavigator;
end;
procedure TcxCustomGrid.DestroyHandlers;
begin
FreeAndNil(FStructureNavigator);
FreeAndNil(FNavigatorNotifier);
FreeAndNil(FViewInfo);
FreeAndNil(FPainter);
FreeAndNil(FController);
end;
procedure TcxCustomGrid.DoActiveTabChanged(ALevel: TcxGridLevel);
begin
if StructureNavigator <> nil then StructureNavigator.BringToFront;
if Assigned(FOnActiveTabChanged) then FOnActiveTabChanged(Self, ALevel);
end;
procedure TcxCustomGrid.DoChange(AGridChange: TcxCustomGridChange);
begin
try
if {IsLoading or - because of details} IsDestroying then Exit;
with AGridChange do
begin
Control := Self;
Execute;
end;
finally
AGridChange.Free;
end;
end;
procedure TcxCustomGrid.DoLayoutChanged(AGridView: TcxCustomGridView);
begin
if Assigned(FOnLayoutChanged) then FOnLayoutChanged(Self, AGridView);
end;
procedure TcxCustomGrid.DoProcessChangesStack;
begin
FProcessingChangesStack := True;
try
DoUpdate(FChangesStack);
finally
FProcessingChangesStack := False;
end;
end;
procedure TcxCustomGrid.DoUpdate(AChanges: TList);
var
AFinalChanges: TList;
procedure BuildFinalChangesList;
var
I, J: Integer;
AChange: TcxCustomGridChange;
function FinalChangesContainClass(AChange: TcxCustomGridChange): Boolean;
var
I: Integer;
begin
for I := 0 to AFinalChanges.Count - 1 do
begin
Result := TcxCustomGridChange(AFinalChanges[I]).IsEqual(AChange);
if Result then Exit;
end;
Result := False;
end;
begin
for I := 0 to AChanges.Count - 1 do
begin
AChange := TcxCustomGridChange(AChanges[I]);
if not AChange.IsCumulative or not FinalChangesContainClass(AChange) then
AFinalChanges.Add(AChange)
else
AChange.Free;
end;
AChanges.Clear;
I := 0;
while I < AFinalChanges.Count do
begin
AChange := TcxCustomGridChange(AFinalChanges[I]);
for J := I + 1 to AFinalChanges.Count - 1 do
if AChange.IsCompatibleWith(TcxCustomGridChange(AFinalChanges[J])) then
begin
AChange.Free;
AFinalChanges.Delete(I);
Dec(I);
Break;
end;
Inc(I);
end;
//!!!
for I := AFinalChanges.Count - 1 downto 0 do
begin
AChange := TcxCustomGridChange(AFinalChanges[I]);
for J := I - 1 downto 0 do
if AChange.IsCompatibleWith(TcxCustomGridChange(AFinalChanges[J])) then
begin
AChange.Free;
AFinalChanges.Delete(I);
Break;
end;
end;
end;
procedure DoFinalChanges;
var
ALockChanges: Boolean;
I: Integer;
AChange: TcxCustomGridChange;
// T: Integer;
begin
// T := GetTickCount;
if AFinalChanges.Count = 0 then Exit;
ALockChanges := AFinalChanges.Count > 1;
if ALockChanges then
BeginUpdate;
try
for I := 0 to AFinalChanges.Count - 1 do
begin
AChange := TcxCustomGridChange(AFinalChanges[I]);
if ALockChanges and not AChange.CanExecuteWhenLocked then
EndUpdate;
DoChange(AChange);
if ALockChanges and not UpdateLocked then
BeginUpdate;
end;
finally
if ALockChanges then
EndUpdate;
end;
// Application.MainForm.Caption := IntToStr(GetTickCount - T);
end;
begin
AFinalChanges := TList.Create;
try
BuildFinalChangesList;
DoFinalChanges;
finally
AFinalChanges.Free;
end;
end;
procedure TcxCustomGrid.FocusedViewChanged(APrevFocusedView, AFocusedView: TcxCustomGridView);
begin
if IsDestroying then Exit;
RefreshNavigators;
SendNotifications(gnkFocusedViewChanged);
if Assigned(FOnFocusedViewChanged) then
FOnFocusedViewChanged(Self, APrevFocusedView, AFocusedView);
end;
function TcxCustomGrid.GetControllerClass: TcxGridControllerClass;
begin
Result := TcxGridController;
end;
function TcxCustomGrid.GetDefaultViewClass: TcxCustomGridViewClass;
begin
Result := nil;
end;
function TcxCustomGrid.GetLevelsClass: TcxGridLevelClass;
begin
Result := TcxGridRootLevel;
end;
function TcxCustomGrid.GetLevelTabsClass: TcxGridLevelTabsClass;
begin
Result := TcxGridLevelTabs;
end;
function TcxCustomGrid.GetPainterClass: TcxGridPainterClass;
begin
Result := TcxGridPainter;
end;
function TcxCustomGrid.GetViewInfoClass: TcxGridViewInfoClass;
begin
Result := TcxGridViewInfo;
end;
procedure TcxCustomGrid.StructureNavigatorChanged;
begin
if StructureNavigator <> nil then StructureNavigator.Changed;
end;
function TcxCustomGrid.UpdateOnRootViewDataChange: Boolean;
begin
Result := (RootLevelOptions.DetailTabsPosition <> dtpNone) and
not RootLevelOptions.TabsForEmptyDetails;
end;
procedure TcxCustomGrid.Invalidate(AHardUpdate: Boolean = False);
procedure InvalidateView(AView: TcxCustomGridView);
var
I: Integer;
begin
if AView = nil then Exit;
AView.Invalidate(AHardUpdate);
for I := 0 to TcxGridLevel(AView.Level).VisibleCount - 1 do
InvalidateView(TcxGridLevel(AView.Level).VisibleItems[I].GridView);
end;
begin
if IsDestroying then Exit;
if AHardUpdate then
LayoutChanged
else
inherited Invalidate;
InvalidateView(ActiveView);
end;
procedure TcxCustomGrid.RemoveFocus(AGoForward: Boolean);
begin
if IsFocused then
PostMessage(GetParentForm(Self).Handle, WM_NEXTDLGCTL, WPARAM(not AGoForward), LPARAM(False));
end;
procedure TcxCustomGrid.BeginUpdate;
begin
Inc(FUpdateLockCount);
end;
procedure TcxCustomGrid.CancelUpdate;
begin
if FUpdateLockCount > 0 then
begin
Dec(FUpdateLockCount);
if FUpdateLockCount = 0 then
DestroyChanges(FChanges);
end;
end;
procedure TcxCustomGrid.Changed(AGridChange: TcxCustomGridChange);
begin
if AGridChange.IsLockable then
if UpdateLocked then
FChanges.Add(AGridChange)
else
(* if HandleAllocated and not FProcessingChangesStack then
begin
if FChangesStack.Count = 0 then
PostMessage(Handle, CM_DEFERUPDATES, 0, 0);
FChangesStack.Add(AGridChange);
end
else *)
DoChange(AGridChange)
else
DoChange(AGridChange);
end;
procedure TcxCustomGrid.CheckFocusedView;
begin
if (FFocusedView <> nil) and not TcxCustomGridViewAccess.CanFocus(FFocusedView) then
if (ActiveView <> nil) and TcxCustomGridViewAccess.CanFocus(ActiveView) then
ActiveView.Focused := True
else
FocusedView := nil;
end;
procedure TcxCustomGrid.EndUpdate;
begin
if FUpdateLockCount > 0 then
begin
Dec(FUpdateLockCount);
if FUpdateLockCount = 0 then DoUpdate(FChanges);
end;
end;
procedure TcxCustomGrid.LayoutChanged;
begin
if not IsLoading then
Changed(TcxGridLayoutChange.Create(nil));
end;
procedure TcxCustomGrid.LevelChanged(ALevel: TcxGridLevel; AChangeKind: TcxGridLevelChangeKind);
begin
StructureNavigatorChanged;
end;
procedure TcxCustomGrid.RefreshNavigators;
begin
if FNavigatorNotifier <> nil then
FNavigatorNotifier.RefreshNavigatorButtons;
end;
procedure TcxCustomGrid.SizeChanged;
begin
if not IsLoading then
Changed(TcxGridSizeChange.Create(nil));
end;
procedure TcxCustomGrid.UpdateFocusing(AChildFocused: Boolean);
function NeedFocusingUpdate: Boolean;
begin
Result :=
AChildFocused and not FLastFocused or
not AChildFocused and not IsFocused;
end;
begin
if IsDestroying then Exit;
if NeedFocusingUpdate then
begin
FLastFocused := AChildFocused;
FController.FocusChanged;
end;
end;
procedure TcxCustomGrid.ViewChanged(AView: TcxCustomGridView;
AChangeKind: TcxGridViewChangeNotificationKind);
begin
StructureNavigatorChanged;
end;
function TcxCustomGrid.CreateView(AViewClass: TcxCustomGridViewClass): TcxCustomGridView;
begin
Result := AViewClass.Create(Owner);
Result.Control := Self;
// Result := AViewClass.CreateEx(Self);
AddView(Result);
end;
function TcxCustomGrid.ViewExists(AView: TcxCustomGridView): Boolean;
var
I: Integer;
begin
for I := 0 to ViewCount - 1 do
begin
Result := (Views[I] = AView) or Views[I].HasAsClone(AView);
if Result then Exit;
end;
Result := False;
end;
procedure TcxCustomGrid.RegisterNotification(ANotification: TcxCustomGridNotification);
begin
if FNotifications.IndexOf(ANotification) = -1 then
FNotifications.Add(ANotification);
end;
procedure TcxCustomGrid.UnregisterNotification(ANotification: TcxCustomGridNotification);
begin
FNotifications.Remove(ANotification);
end;
function TcxCustomGrid.SendNotifications(AKind: TcxGridNotificationKind;
AData: TObject = nil): Boolean;
var
I: Integer;
ANotification: TcxCustomGridNotification;
begin
Result := False;
if (AKind = gnkContextMenu) and IsDesigning then Exit;
for I := 0 to FNotifications.Count - 1 do
begin
ANotification := TcxCustomGridNotification(FNotifications[I]);
if AKind in ANotification.NotificationKinds then
begin
ANotification.Notify(AKind, AData, Result);
if Result then Break;
end;
end;
end;
procedure TcxCustomGrid.RootViewDataChanged(AView: TcxCustomGridView);
begin
if UpdateOnRootViewDataChange then
LayoutChanged;
end;
procedure TcxCustomGrid.TranslationChanged;
begin
SizeChanged;
end;
{ TcxGridViewRepository }
constructor TcxGridViewRepository.Create(AOwner: TComponent);
begin
inherited;
FItems := TList.Create;
end;
destructor TcxGridViewRepository.Destroy;
begin
DestroyItems;
FItems.Free;
inherited;
end;
function TcxGridViewRepository.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TcxGridViewRepository.GetItem(Index: Integer): TcxCustomGridView;
begin
Result := TcxCustomGridView(FItems[Index]);
end;
procedure TcxGridViewRepository.DestroyItems;
var
I: Integer;
begin
for I := Count - 1 downto 0 do
Items[I].Free;
end;
procedure TcxGridViewRepository.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
I: Integer;
begin
inherited;
for I := 0 to Count - 1 do
if Items[I].Owner = Root then
Proc(Items[I]);
end;
procedure TcxGridViewRepository.AddItem(AItem: TcxCustomGridView);
begin
FItems.Add(AItem);
AItem.Repository := Self;
AItem.DataController.SetMasterMode(nil, True);
end;
function TcxGridViewRepository.CreateItem(AItemClass: TcxCustomGridViewClass): TcxCustomGridView;
begin
Result := AItemClass.Create(Owner);
AddItem(Result);
end;
procedure TcxGridViewRepository.RemoveItem(AItem: TcxCustomGridView);
begin
FItems.Remove(AItem);
AItem.Repository := nil;
if AItem.Control <> nil then
TcxCustomGrid(AItem.Control).DestroyViewChanges(AItem);
end;
{ functions }
function GetParentGrid(AControl: TControl): TcxCustomGrid;
var
AGridView: TcxCustomGridView;
begin
AGridView := GetParentGridView(AControl);
if AGridView = nil then
Result := nil
else
Result := TcxCustomGrid(AGridView.Control);
end;
initialization
RegisterClass(TcxGridLevel);
PageControlDependsControls.Add(Pointer(TcxCustomGrid));
finalization
PageControlDependsControls.Remove(Pointer(TcxCustomGrid));
end.