Componentes.Terceros.DevExp.../official/x.44/ExpressQuantumTreeList 5/Sources/cxTL.pas

23286 lines
724 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressQuantumTreeList }
{ }
{ 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 EXPRESSQUANTUMTREELIST 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 cxTL;
{$I cxVer.inc}
interface
uses
Variants, Classes, SysUtils, Clipbrd, Windows, Messages, ExtCtrls, Controls, Forms, StdCtrls, Menus,
Graphics, ImgList, ComCtrls, Contnrs, Math, cxControls, cxContainer, cxCheckBox, cxCheckListBox,
cxGraphics, cxVariants, cxNavigator, cxStorage, cxClasses, cxEdit, cxListBox, cxInplaceContainer,
cxLookAndFeels, cxLookAndFeelPainters, cxData, cxDataUtils, cxCustomData, cxStyles, cxGeometry,
cxTLStrs, cxScrollBar, cxLibraryConsts, cxDataStorage, cxPC, dxCore, cxLookupEdit, dxUxTheme;
const
cxTLMajorVersion = '5';
// default size values for treelist items
cxTreeListDefWidth = 100;
cxTreeListDefMinWidth = 20;
// default values for treelist options view
cxTreeListHeaderMovingZoneSize = 20;
cxTreeListDefIndicatorWidth = 12;
cxTreeListDefSeparatorWidth = 2;
cxTreeListDefDropArrowColor = $00FF00;
CustomizationPopupColumnOffset = 10;
cxTreeListResizeInc = 50;
// treelist styles predefined indexes
tlcs_Header = ecs_EditContainerStylesMaxIndex + 1;
tlcs_Footer = ecs_EditContainerStylesMaxIndex + 2;
// for band styles
tlbs_Content = 0;
tlbs_Footer = 1;
tlbs_Header = 2;
tlbs_HeaderBackground = 3;
// for control styles
tlsv_Content = ecs_Content;
tlsv_BandBackground = ecs_EditingStylesMaxIndex + 1;
tlsv_BandContent = ecs_EditingStylesMaxIndex + 2;
tlsv_BandHeader = ecs_EditingStylesMaxIndex + 3;
tlsv_ColumnFooter = ecs_EditingStylesMaxIndex + 4;
tlsv_ColumnHeader = ecs_EditingStylesMaxIndex + 5;
tlsv_ContentEven = ecs_EditingStylesMaxIndex + 6;
tlsv_ContentOdd = ecs_EditingStylesMaxIndex + 7;
tlsv_Footer = ecs_EditingStylesMaxIndex + 8;
tlsv_HotTrack = ecs_EditingStylesMaxIndex + 12;
tlsv_IncSearch = ecs_EditingStylesMaxIndex + 9;
tlsv_Indicator = ecs_EditingStylesMaxIndex + 10;
tlsv_Preview = ecs_EditingStylesMaxIndex + 11;
// base constants for descendants
cxtlMaxControlStyleIndex = tlsv_Preview;
cxtlMaxColumnStyleIndex = tlcs_Footer;
cxtlMaxBandStyleIndex = tlbs_HeaderBackground;
// base index for hitcodes bits
tlhc_HitAtBackground = 4;
tlhc_HitAtBand = 5;
tlhc_HitAtBandContainer = 6;
tlhc_HitAtBandCustomizing = 7;
tlhc_HitAtBandHeader = 8;
tlhc_HitAtButton = 9;
tlhc_HitAtCheckButton = 10;
tlhc_HitAtColumn = 11;
tlhc_HitAtColumnCustomizing = 12;
tlhc_HitAtColumnHeader = 13;
tlhc_HitAtFooter = 14;
tlhc_HitAtFooterItem = 15;
tlhc_HitAtGroupFooter = 16;
tlhc_HitAtGroupFooterItem = 17;
tlhc_HitAtImage = 18;
tlhc_HitAtIndent = 19;
tlhc_HitAtIndicator = 20;
tlhc_HitAtNode = 21;
tlhc_HitAtNodePreview = 22;
tlhc_HitAtSeparator = 23;
tlhc_HitAtSizingHorz = 24;
tlhc_HitAtSizingVert = 25;
tlhc_HitAtStateImage = 26;
// events state
tlesNone = $0000;
tlesChanged = $0001;
tlesSelection = $0002;
// hit test and sizing constants
cxtlHitDelta = 3;
cxtlScrollDelta = 10;
cxtlSizingMarkWidth = 1;
//
cxtlEditCell = 1;
cxtlPreviewCell = 2;
cxtlBandPartCell = 3;
cxtlColumnHeaderCell = 4;
cxtlBandHeaderCell = 5;
cxtlIndentCell = 6;
cxtlIndicatorCell = 7;
cxtlBackgroundCell = 8;
cxtlFooterCell = 9;
// popup menu commands
// Summary commands
tlcmNone = 0;
tlcmSum = 1;
tlcmMin = 2;
tlcmMax = 3;
tlcmCount = 4;
tlcmAverage = 5;
tlcmAllNodes = 6;
// Column Header commands
tlcmSortAscending = 20;
tlcmSortDescending = 21;
tlcmClearSorting = 22;
tlcmFooter = 23;
tlcmGroupFootersInvisible = 24;
tlcmGroupFootersVisibleWhenExpanded = 25;
tlcmGroupFootersAlwaysVisible = 26;
tlcmRemoveThisColumn = 27;
tlcmFieldChooser = 28;
tlcmHorzAlignmentLeft = 29;
tlcmHorzAlignmentRight = 30;
tlcmHorzAlignmentCenter = 31;
tlcmVertAlignmentTop = 32;
tlcmVertAlignmentBottom = 33;
tlcmVertAlignmentCenter = 34;
tlcmBestFit = 35;
tlcmBestFitAllColumns = 36;
tlcmUser = tlcmBestFitAllColumns + 1000;
// overs
cvis_ViewInfoCalculate = 4;
//
cxColumnTextSeparator = #9;
cxLineSeparator = #13#10;
cxTreeListScrollWidthDragInterval = 50;
cxTreeListIndentOffsetSize = 6;
cxTreeListEditCellHeightOffset = 2;
cxTreeListDragDropTextAreaOffset: TPoint = (X: 20; Y:0);
{$UNDEF CXTEST}
type
EcxTreeList = class(Exception);
TcxCustomTreeListClass = class of TcxCustomTreeList;
TcxTreeListController = class;
TcxTreeListDataController = class;
TcxTreeListColumn = class;
TcxTreeListColumnSummary = class;
TcxTreeListPopupMenu = class;
TcxTreeListPopupMenus = class;
TcxTreeListSummary = class;
TcxTreeListSummaryItem = class;
TcxTreeListSummaryItems = class;
TcxTreeListBand = class;
TcxTreeListBands = class;
TcxTreeListBandRow = class;
TcxTreeListBandRows = class;
TcxTreeListOptionsBehavior = class;
TcxTreeListOptionsSelection = class;
TcxTreeListOptionsCustomizing = class;
TcxTreeListOptionsCustomizingClass = class of TcxTreeListOptionsCustomizing;
TcxTreeListHitTest = class;
TcxTreeListNodeViewData = class;
TcxTreeListLevelInfo = class;
TcxTreeListViewInfo = class;
TcxTreeListCustomCellViewInfo = class;
TcxTreeListCustomCellViewInfoClass = class of TcxTreeListCustomCellViewInfo;
TcxTreeListCustomHeaderCellViewInfo = class;
TcxTreeListHeaderCellViewInfo = class;
TcxTreeListColumnHeaderCellViewInfo = class;
TcxTreeListEditCellViewInfo = class;
TcxTreeListIndicatorCellViewInfo = class;
TcxTreeListCustomizationForm = class;
TcxTreeListOptionsView = class;
TcxTreeListPainter = class;
TcxTreeListNode = class;
TcxTreeListNodeClass = class of TcxTreeListNode;
TcxTreeListPreview = class;
TcxTreeListPreviewClass = class of TcxTreeListPreview;
TcxCustomTreeList = class;
TcxTreeListCustomizing = class;
TcxTreeListItemsCustomizeListBox = class;
TcxTreeListStyles = class;
// overriding types
PIntArray = ^TIntArray;
TIntArray = array[0..MaxInt div SizeOf(Integer) - 1] of Integer;
TcxTreeListBandFixedKind = (tlbfNone, tlbfLeft, tlbfRight);
TcxTreeListBandExpandable = (tlbeDefault, tlbeExpandable, tlbeNotExpandable);
TcxTreeListGridLines = (tlglNone, tlglHorz, tlglVert, tlglBoth);
TcxTreeListImageIndexType = (tlitImageIndex, tlitSelectedIndex, tlitStateIndex, tlitOverlayIndex, tlitOverlayStateIndex);
TcxTreeListImageIndexes = set of TcxTreeListImageIndexType;
TcxTreeListNodeAttachMode = (tlamAdd, tlamAddFirst, tlamAddChild, tlamAddChildFirst, tlamInsert);
TcxTreeListNodeAddMode = (tlnaAdd, tlnaAddFirst, tlnaInsert);
TcxTreeListNodeImageIndexes = array[TcxTreeListImageIndexType] of TImageIndex;
TcxTreeListCompareFunc = function(AItem1, AItem2: TcxTreeListNode): Integer;
TcxCachedContentParams = array[Boolean] of TcxViewParams;
TcxTreeListFindFunc = function(ANode: TcxTreeListNode; AData: Pointer): Boolean;
{ IcxTreeListListener }
IcxTreeListDesigner = interface
['{1F4D4387-57E1-4756-9093-1124077A0F54}']
procedure ComponentModified;
procedure ComponentRemoved(Sender: TObject);
end;
IcxTreeListDesignTimeOperations = interface
['{781A0614-EA26-4214-85D2-10C7DA2AF22B}']
function SupportBandColumnEditor: Boolean;
function SupportItemsEditor: Boolean;
function SupportCreateAllItems: Boolean;
procedure CreateAllItems;
end;
PcxTreeListNodeData = ^TcxTreeListNodeData;
TcxTreeListNodeData = record
Node: TcxTreeListNode;
NodeData: Pointer;
end;
TcxTreeListChange = (tcStructure, tcData, tcLayout, tcImages, tcColumns,
tcSortOrder, tcLoading, tcSelection, tcFocusedNode);
TcxTreeListChanges = set of TcxTreeListChange;
{ TcxTreeListSummaryInfo }
TcxTreeListSummaryInfo = record
Value: Variant;
TempValue: Variant;
Count: Integer;
end;
TcxTreeListSummaryInfos = array of TcxTreeListSummaryInfo;
{ TcxTreeListNode }
TcxTreeListNodeState = (nsDeleting, nsHasChildren, nsValuesAssigned, nsCollapsed, nsValidIndexes, nsInternalDelete,
nsHidden, nsHeightAssigned, nsInserting, nsEditing, nsCheck, nsDisabled, Reserved);
TcxTreeListNodeStates = set of TcxTreeListNodeState;
TcxTreeListNodeCheckInfo = (nciChecked, nciGrayed, nciAllowGrayed, nciCheckGroup,
nciRadioGroup, nciCheckValid, nciChangeCheck);
TcxTreeListNodeCheckInfos = set of TcxTreeListNodeCheckInfo;
TcxTreeListNodeCheckGroupType = (ncgNone, ncgCheckGroup, ncgRadioGroup);
TcxTreeListNode = class(TPersistent, IUnknown, IcxDragSizing)
private
FAbsoluteIndex: Integer;
FCount: Integer;
FData: Pointer;
FFirst: TcxTreeListNode;
FHandle: Pointer;
FHeight: Integer;
FIndex: Integer;
FLast: TcxTreeListNode;
FNext: TcxTreeListNode;
FOriginalIndex: Integer;
FTreeList: TcxCustomTreeList;
FParent: TcxTreeListNode;
FPrev: TcxTreeListNode;
FViewData: TcxTreeListNodeViewData;
function GetAbsoluteIndex: Integer;
function GetAllowGrayed: Boolean;
function GetChecked: Boolean;
function GetCheckedCount: Integer;
function GetChildVisibleCount: Integer;
function GetCheckGroupType: TcxTreeListNodeCheckGroupType;
function GetCheckState: TcxCheckBoxState;
function GetEnabled: Boolean;
function GetExpanded: Boolean;
function GetFocused: Boolean;
function GetGrayedCount: Integer;
function GetHasCheckbox: Boolean;
function GetHasChildren: Boolean;
function GetHasVisibleChildren: Boolean;
function GetHotTrack: Boolean;
function GetIndex: Integer;
function GetIsDeleting: Boolean;
function GetIsFirst: Boolean;
function GetIsGroupNode: Boolean;
function GetIsHidden: Boolean;
function GetIsLast: Boolean;
function GetIsPrinted: Boolean;
function GetIsRadioGroup: Boolean;
function GetIsVisible: Boolean;
function GetItem(AIndex: Integer): TcxTreeListNode;
function GetLevel: Integer;
function GetRoot: TcxTreeListNode;
function GetSelected: Boolean;
function GetSummary: TcxTreeListSummary;
function GetNodeImageIndex(AIndex: Integer): TImageIndex;
function GetText(AIndex: Integer): string;
function GetValue(AIndex: Integer): Variant;
function GetValueCount: Integer;
function GetVisible: Boolean;
function GetVisibleIndex: Integer;
procedure AdjustIndexes;
procedure InternalInsert(AValue: TcxTreeListNode);
procedure InternalRemove(AValue: TcxTreeListNode);
procedure SetAllowGrayed(AValue: Boolean);
procedure SetChecked(AValue: Boolean);
procedure SetCheckGroupType(AValue: TcxTreeListNodeCheckGroupType);
procedure SetCheckState(AValue: TcxCheckBoxState);
procedure SetEnabled(AValue: Boolean);
procedure SetExpanded(AValue: Boolean);
procedure SetFirst(AValue: TcxTreeListNode);
procedure SetFocused(AValue: Boolean);
procedure SetFooterSummaryValue(AIndex: Integer; AValue: Variant);
procedure SetHasChildren(AValue: Boolean);
procedure SetHeight(AValue: Integer);
procedure SetItem(AIndex: Integer; AValue: TcxTreeListNode);
procedure SetLast(AValue: TcxTreeListNode);
procedure SetNodeImageIndex(AIndex: Integer; AValue: TImageIndex);
procedure SetParentFor(AValue: TcxTreeListNode; AValidateIndexes: Boolean = True);
procedure SetText(AIndex: Integer; const AValue: string);
procedure SetSelected(AValue: Boolean);
procedure SetValue(AIndex: Integer; const AValue: Variant);
procedure SetVisible(AValue: Boolean);
protected
FImageIndexes: TcxTreeListNodeImageIndexes;
FSummaryInfo: TcxTreeListSummaryInfos;
FVisibleIndex: Integer;
CheckInfo: TcxTreeListNodeCheckInfos;
State: TcxTreeListNodeStates;
procedure AssignData(ASource: TcxTreeListNode); virtual;
function GetFooterSummaryCount: Integer; virtual;
function GetFooterSummaryText(AIndex: Integer): string; virtual;
function GetFooterSummaryValue(AIndex: Integer): Variant; virtual;
function GetInserting: Boolean; virtual;
function GetIsFirstVisible: Boolean; virtual;
function GetIsLastVisible: Boolean; virtual;
function GetNextVisibleEx(IsPrev: Boolean): TcxTreeListNode;
function GetNextSiblingEx(ANode: TcxTreeListNode; AForward: Boolean): TcxTreeListNode;
function GetOwner: TPersistent; override;
function GetRootParent: TcxTreeListNode;
procedure InternalFree;
procedure InitializeHandle; virtual;
procedure ReadData(AStream: TStream; AVersion: Integer); virtual;
procedure SetChildrenCheckState(AValue: TcxCheckBoxState; AExclude: TcxTreeListNode);
procedure WriteData(AStream: TStream); virtual;
// IcxDragSizing
function CanSizing(ADirection: TcxDragSizingDirection): Boolean;
function GetSizingBoundsRect(ADirection: TcxDragSizingDirection): TRect;
function GetSizingIncrement(ADirection: TcxDragSizingDirection): Integer;
function IsDynamicUpdate: Boolean;
procedure PopulateItems(AList: TList);
procedure SetSizeDelta(ADirection: TcxDragSizingDirection; ADelta: Integer);
procedure UpdateItems(AList: TList);
// IUnknown
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
property CheckedCount: Integer read GetCheckedCount;
property GrayedCount: Integer read GetGrayedCount;
property Handle: Pointer read FHandle write FHandle;
property OriginalIndex: Integer read FOriginalIndex;
property IsPrinted: Boolean read GetIsPrinted;
property IsRadioGroup: Boolean read GetIsRadioGroup;
property Summary: TcxTreeListSummary read GetSummary;
property ViewData: TcxTreeListNodeViewData read FViewData write FViewData;
public
constructor Create(AOwner: TcxCustomTreeList); virtual;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure AssignValues(const AValues: array of Variant);
function AddChild: TcxTreeListNode; virtual;
function AddChildFirst: TcxTreeListNode; virtual;
procedure AlphaSort(ARecurse: Boolean = False);
function CanCollapse: Boolean;
function CanExpand: Boolean;
function CanMove(ADest: TcxTreeListNode; AMode: TcxTreeListNodeAttachMode): Boolean;
procedure CheckClick;
procedure Collapse(Recurse: Boolean);
procedure CustomSort(ASortProc: TcxTreeListCompareFunc; ARecurse: Boolean = False);
procedure Delete;
procedure DeleteChildren;
function DisplayRect(AEntryOnly: Boolean): TRect;
procedure EndEdit(Cancel: Boolean);
procedure Expand(Recurse: Boolean);
function GetNext: TcxTreeListNode;
function GetNextChild(ANode: TcxTreeListNode): TcxTreeListNode;
function getNextSibling: TcxTreeListNode; {GetNextSibling conflicts with C++ macro}
function GetNextSiblingVisible: TcxTreeListNode;
function GetNextVisible: TcxTreeListNode;
function GetPrev: TcxTreeListNode;
function GetPrevChild(ANode: TcxTreeListNode): TcxTreeListNode;
function getPrevSibling: TcxTreeListNode; {GetPrevSibling conflicts with a C++ macro}
function GetPrevSiblingVisible: TcxTreeListNode;
function GetPrevVisible: TcxTreeListNode;
function getFirstChild: TcxTreeListNode; {GetFirstChild conflicts with C++ macro}
function GetFirstChildVisible: TcxTreeListNode;
function GetLastChild: TcxTreeListNode;
function GetLastChildVisible: TcxTreeListNode;
//
function HasAsParent(ANode: TcxTreeListNode): Boolean;
function IndexOf(ANode: TcxTreeListNode): Integer;
function InsertChild(ABeforeNode: TcxTreeListNode): TcxTreeListNode; virtual;
procedure Invalidate;
function IsSibling(ANode: TcxTreeListNode): Boolean;
procedure LoadChildren;
procedure MakeVisible;
procedure MoveTo(ADestNode: TcxTreeListNode; AMode: TcxTreeListNodeAttachMode); virtual;
procedure Repaint(ARecalculate: Boolean); virtual;
property AbsoluteIndex: Integer read GetAbsoluteIndex;
property AllowGrayed: Boolean read GetAllowGrayed write SetAllowGrayed;
property Checked: Boolean read GetChecked write SetChecked;
property CheckGroupType: TcxTreeListNodeCheckGroupType read GetCheckGroupType write SetCheckGroupType;
property CheckState: TcxCheckBoxState read GetCheckState write SetCheckState;
property ChildVisibleCount: Integer read GetChildVisibleCount;
property Count: Integer read FCount;
property Data: Pointer read FData write FData;
property Deleting: Boolean read GetIsDeleting;
property Enabled: Boolean read GetEnabled write SetEnabled;
property Expanded: Boolean read GetExpanded write SetExpanded;
property Focused: Boolean read GetFocused write SetFocused;
property FooterSummaryCount: Integer read GetFooterSummaryCount;
property FooterSummaryTexts[Index: Integer]: string read GetFooterSummaryText;
property FooterSummaryValues[Index: Integer]: Variant read GetFooterSummaryValue
write SetFooterSummaryValue;
property HasCheckbox: Boolean read GetHasCheckbox;
property HasChildren: Boolean read GetHasChildren write SetHasChildren;
property HasVisibleChildren: Boolean read GetHasVisibleChildren;
property Height: Integer read FHeight write SetHeight;
property HotTrack: Boolean read GetHotTrack;
property ImageIndex: TImageIndex index 0 read GetNodeImageIndex write SetNodeImageIndex;
property Index: Integer read GetIndex;
property Inserting: Boolean read GetInserting;
property IsFirst: Boolean read GetIsFirst;
property IsFirstVisible: Boolean read GetIsFirstVisible;
property IsGroupNode: Boolean read GetIsGroupNode;
property IsHidden: Boolean read GetIsHidden;
property IsLast: Boolean read GetIsLast;
property IsLastVisible: Boolean read GetIsLastVisible;
property IsVisible: Boolean read GetIsVisible;
property Items[Index: Integer]: TcxTreeListNode read GetItem write SetItem; default;
property Level: Integer read GetLevel;
property OverlayIndex: TImageIndex index 3 read GetNodeImageIndex write SetNodeImageIndex;
property OverlayStateIndex: TImageIndex index 4 read GetNodeImageIndex write SetNodeImageIndex;
property Parent: TcxTreeListNode read FParent;
property Root: TcxTreeListNode read GetRoot;
property Selected: Boolean read GetSelected write SetSelected;
property SelectedIndex: TImageIndex index 1 read GetNodeImageIndex write SetNodeImageIndex;
property StateIndex: TImageIndex index 2 read GetNodeImageIndex write SetNodeImageIndex;
property Texts[Index: Integer]: string read GetText write SetText;
property TreeList: TcxCustomTreeList read FTreeList;
property ValueCount: Integer read GetValueCount;
property Values[Index: Integer]: Variant read GetValue write SetValue;
property Visible: Boolean read GetVisible write SetVisible;
property VisibleIndex: Integer read GetVisibleIndex;
end;
{ TcxTreeListRootNode }
TcxTreeListRootNode = class(TcxTreeListNode)
protected
function GetFooterSummaryCount: Integer; override;
function GetFooterSummaryText(AIndex: Integer): string; override;
procedure InitializeHandle; override;
end;
{ TcxUnboundTreeListNode }
TcxUnboundTreeListNode = class(TcxTreeListNode)
protected
procedure ReadData(AStream: TStream; AVersion: Integer); override;
procedure WriteData(AStream: TStream); override;
public
constructor Create(AOwner: TcxCustomTreeList); override;
procedure Assign(Source: TPersistent); override;
end;
{ TcxTreeListColumnStyles }
TcxTreeListColumnStyles = class(TcxEditContainerStyles)
private
function GetBand: TcxTreeListBand;
function GetColumn: TcxTreeListColumn;
function GetTreeList: TcxCustomTreeList;
protected
procedure GetDefaultViewParams(Index: Integer; AData: TObject; out AParams: TcxViewParams); override;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
function GetContentParams(ANode: TcxTreeListNode): TcxViewParams;
property Band: TcxTreeListBand read GetBand;
property Column: TcxTreeListColumn read GetColumn;
property TreeList: TcxCustomTreeList read GetTreeList;
published
property Header: TcxStyle index tlcs_Header read GetValue write SetValue;
property Footer: TcxStyle index tlcs_Footer read GetValue write SetValue;
property Content;
end;
{ TcxTreeListColumnPosition }
TcxTreeListColumnPosition = class(TcxOwnedPersistent)
private
FBand: TcxTreeListBand;
FBandIndex: Integer;
FColIndex: Integer;
FLineCount: Integer;
FRow: TcxTreeListBandRow;
FRowIndex: Integer;
FVisibleColIndex: Integer;
function GetBandIndex: Integer;
function GetColIndex: Integer;
function GetColumn: TcxTreeListColumn;
function GetIsUpdating: Boolean;
function GetRowIndex: Integer;
function GetTreeList: TcxCustomTreeList;
function GetVisibleBandIndex: Integer;
function GetVisibleRowIndex: Integer;
procedure SetBandIndex(AValue: Integer);
procedure SetColIndex(AValue: Integer);
procedure SetLineCount(AValue: Integer);
procedure SetRow(AValue: TcxTreeListBandRow);
procedure SetRowIndex(AValue: Integer);
protected
procedure Changed; virtual;
function IsPositionChanged: Boolean; virtual;
procedure Restore; virtual;
procedure Store; virtual;
property IsUpdating: Boolean read GetIsUpdating;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
procedure SetPosition(AColIndex, ARowIndex: Integer; IsInsertRow: Boolean = False);
procedure SetPositionEx(ABandIndex, AColIndex, ARowIndex: Integer; IsInsertRow: Boolean = False);
property Band: TcxTreeListBand read FBand;
property Column: TcxTreeListColumn read GetColumn;
property Row: TcxTreeListBandRow read FRow write SetRow;
property TreeList: TcxCustomTreeList read GetTreeList;
property VisibleBandIndex: Integer read GetVisibleBandIndex;
property VisibleColIndex: Integer read FVisibleColIndex;
property VisibleRowIndex: Integer read GetVisibleRowIndex;
published
property ColIndex: Integer read GetColIndex write SetColIndex;
property LineCount: Integer read FLineCount write SetLineCount default 1;
property RowIndex: Integer read GetRowIndex write SetRowIndex;
property BandIndex: Integer read GetBandIndex write SetBandIndex;
end;
TcxTreeListColumnPositionClass = class of TcxTreeListColumnPosition;
{ TcxTreeListCaption }
TcxTreeListCaption = class(TcxOwnedPersistent)
private
FAlignHorz: TAlignment;
FAlignVert: TcxAlignmentVert;
FGlyph: TBitmap;
FGlyphAlignHorz: TAlignment;
FGlyphAlignVert: TcxAlignmentVert;
FMultiLine: Boolean;
FShowEndEllipsis: Boolean;
FText: string;
FOnChange: TNotifyEvent;
procedure SetAlignHorz(AValue: TAlignment);
procedure SetAlignVert(AValue: TcxAlignmentVert);
procedure SetGlyph(AValue: TBitmap);
procedure SetGlyphAlignHorz(AValue: TAlignment);
procedure SetGlyphAlignVert(AValue: TcxAlignmentVert);
procedure SetMultiLine(AValue: Boolean);
procedure SetShowEndEllipsis(AValue: Boolean);
procedure SetText(const AValue: string);
protected
procedure Changed; virtual;
function GetText: string; virtual;
function IsTextStored: Boolean; virtual;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
public
constructor Create(AOwner: TPersistent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
published
property AlignHorz: TAlignment read FAlignHorz write SetAlignHorz default taLeftJustify;
property AlignVert: TcxAlignmentVert read FAlignVert write SetAlignVert default vaTop;
property Glyph: TBitmap read FGlyph write SetGlyph;
property GlyphAlignHorz: TAlignment read FGlyphAlignHorz write SetGlyphAlignHorz default taLeftJustify;
property GlyphAlignVert: TcxAlignmentVert read FGlyphAlignVert write SetGlyphAlignVert default vaTop;
property MultiLine: Boolean read FMultiLine write SetMultiLine default False;
property ShowEndEllipsis: Boolean read FShowEndEllipsis write SetShowEndEllipsis default True;
property Text: string read GetText write SetText stored IsTextStored;
end;
{ TcxTreeListColumnOptions }
TcxTreeListColumnOptions = class(TcxCustomEditContainerItemOptions)
private
FCellEndEllipsis: Boolean;
FFooter: Boolean;
FGroupFooter: Boolean;
FHidden: Boolean;
FSizing: Boolean;
FVertSizing: Boolean;
function GetColumn: TcxTreeListColumn;
procedure SetCellEndEllipsis(AValue: Boolean);
procedure SetFooter(AValue: Boolean);
procedure SetGroupFooter(AValue: Boolean);
procedure SetSizing(AValue: Boolean);
procedure SetVertSizing(AValue: Boolean);
protected
procedure Changed; override;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
procedure RestoreDefaults; virtual;
property Column: TcxTreeListColumn read GetColumn;
published
property CellEndEllipsis: Boolean read FCellEndEllipsis write SetCellEndEllipsis default True;
property Footer: Boolean read FFooter write SetFooter default True;
property GroupFooter: Boolean read FGroupFooter write SetGroupFooter default True;
property Hidden: Boolean read FHidden write FHidden default False;
property Sizing: Boolean read FSizing write SetSizing default True;
property VertSizing: Boolean read FVertSizing write SetVertSizing default True;
property Customizing;
property Editing;
property Focusing;
property IncSearch;
property Moving;
property ShowEditButtons;
property Sorting;
property TabStop;
end;
{ TcxTreeListSummaryItem }
TcxTreeListSummaryItemGetTextEvent = procedure(Sender: TcxTreeListSummaryItem;
const AValue: Variant; var AText: string) of object;
TcxTreeListSummaryItem = class(TcxCustomDataSummaryItem)
private
FAbsoluteIndex: Integer;
FAlignHorz: TAlignment;
FAlignVert: TcxAlignmentVert;
FAllNodes: Boolean;
FCalculatedColumn: TcxTreeListColumn;
FMultiLine: Boolean;
FVisible: Boolean;
FVisibleIndexInColumn: Integer;
FOnGetText: TcxTreeListSummaryItemGetTextEvent;
function GetCalculatedColumn: TcxTreeListColumn;
function GetColumn: TcxTreeListColumn;
function IsCalculatedColumnStored: Boolean;
procedure SetAlignHorz(AValue: TAlignment);
procedure SetAlignVert(AValue: TcxAlignmentVert);
procedure SetAllNodes(AValue: Boolean);
procedure SetCalculatedColumn(AValue: TcxTreeListColumn);
procedure SetMultiLine(AValue: Boolean);
procedure SetVisible(AValue: Boolean);
protected
procedure AssignValues(Source: TcxCustomDataSummaryItem); override;
function GetDataController: TcxCustomDataController; override;
function GetValueFormat(AValueType: TcxSummaryValueType; const AValue: Variant;
AIsFooter: Boolean): string; override;
procedure Notification(AComponent: TComponent; Operation: TOperation);
public
constructor Create(Collection: TCollection); override;
function FormatValue(const AValue: Variant; AIsFooter: Boolean): string; override;
property AbsoluteIndex: Integer read FAbsoluteIndex write FAbsoluteIndex;
property Column: TcxTreeListColumn read GetColumn;
property VisibleIndexInColumn: Integer read FVisibleIndexInColumn;
published
property AlignHorz: TAlignment read FAlignHorz write SetAlignHorz default taLeftJustify;
property AlignVert: TcxAlignmentVert read FAlignVert write SetAlignVert default vaTop;
property AllNodes: Boolean read FAllNodes write SetAllNodes default True;
property CalculatedColumn: TcxTreeListColumn read GetCalculatedColumn write SetCalculatedColumn stored IsCalculatedColumnStored;
property MultiLine: Boolean read FMultiLine write SetMultiLine default False;
property Visible: Boolean read FVisible write SetVisible default True;
property Format;
property Kind;
property OnGetText: TcxTreeListSummaryItemGetTextEvent read FOnGetText write FOnGetText;
end;
TcxTreeListSummaryItemClass = class of TcxTreeListSummaryItem;
{ TcxTreeListColumnSummary }
TcxTreeListColumnSummary = class(TcxOwnedPersistent)
private
FFooterSummaryItems: TcxTreeListSummaryItems;
FGroupFooterSummaryItems: TcxTreeListSummaryItems;
function GetColumn: TcxTreeListColumn;
function GetFooterVisibleCount: Integer;
function GetGroupFooterVisibleCount: Integer;
procedure SetFooterSummaryItems(AValue: TcxTreeListSummaryItems);
procedure SetGroupFooterSummaryItems(AValue: TcxTreeListSummaryItems);
protected
procedure Changed(ARedrawOnly: Boolean);
public
constructor Create(AOwner: TPersistent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
property Column: TcxTreeListColumn read GetColumn;
property FooterVisibleCount: Integer read GetFooterVisibleCount;
property GroupFooterVisibleCount: Integer read GetGroupFooterVisibleCount;
published
property FooterSummaryItems: TcxTreeListSummaryItems read FFooterSummaryItems write SetFooterSummaryItems;
property GroupFooterSummaryItems: TcxTreeListSummaryItems read FGroupFooterSummaryItems write SetGroupFooterSummaryItems;
end;
{ TcxTreeListSummaryItems }
TcxTreeListSummaryItems = class(TcxCollection)
private
FSummary: TcxTreeListColumnSummary;
FVisibleCount: Integer;
function GetColumn: TcxTreeListColumn;
function GetItem(AIndex: Integer): TcxTreeListSummaryItem;
procedure SetItem(AIndex: Integer; AValue: TcxTreeListSummaryItem);
protected
function GetOwner: TPersistent; override;
procedure Update(Item: TCollectionItem); override;
public
constructor Create(ASummary: TcxTreeListColumnSummary; AItemClass: TcxTreeListSummaryItemClass); virtual;
function Add: TcxTreeListSummaryItem;
function GetItemByKind(AKind: TcxSummaryKind): TcxTreeListSummaryItem;
property Column: TcxTreeListColumn read GetColumn;
property Items[Index: Integer]: TcxTreeListSummaryItem read GetItem write SetItem; default;
property Summary: TcxTreeListColumnSummary read FSummary;
property VisibleCount: Integer read FVisibleCount;
end;
TcxTreeListColumnSummaryClass = class of TcxTreeListColumnSummary;
{ TcxTreeListColumn }
TcxTreeListOnGetDisplayTextEvent = procedure(Sender: TcxTreeListColumn;
ANode: TcxTreeListNode; var Value: string) of object;
TcxTreeListGetEditPropertiesEvent = procedure(Sender: TcxTreeListColumn;
ANode: TcxTreeListNode; var EditProperties: TcxCustomEditProperties) of object;
TcxTreeListColumn = class(TcxCustomInplaceEditContainer, IUnknown, IcxDragSizing, IcxStoredObject)
private
FCaption: TcxTreeListCaption;
FCalculatedWidth: Integer;
FData: Integer;
FHeaderCell: TcxTreeListColumnHeaderCellViewInfo;
FMinWidth: Integer;
FOnChangeName: TNotifyEvent;
FPosition: TcxTreeListColumnPosition;
FSortIndex: Integer;
FSortOrder: TcxDataSortOrder;
FSummary: TcxTreeListColumnSummary;
FSummaryFooter: TPersistent;
FVisible: Boolean;
FWidth: Integer;
FOnGetDisplayText: TcxTreeListOnGetDisplayTextEvent;
// IcxStoredObject events
FOnGetStoredProperties: TcxGetStoredPropertiesEvent;
FOnGetStoredPropertyValue: TcxGetStoredPropertyValueEvent;
FOnSetStoredPropertyValue: TcxSetStoredPropertyValueEvent;
function GetActuallyVisible: Boolean;
function GetDataController: TcxTreeListDataController;
function GetDataBinding: TcxItemDataBinding;
function GetDisplayText(ANode: TcxTreeListNode): string;
function GetDisplayWidth: Integer;
function GetEditingProperties: TcxTreeListGetEditPropertiesEvent;
function GetEditProperties: TcxTreeListGetEditPropertiesEvent;
function GetHasIndent: Boolean;
function GetID: Integer;
function GetIndentWidth: Integer;
function GetIsFixed: Boolean;
function GetIsHidden: Boolean;
function GetIsLeft: Boolean;
function GetIsPreview: Boolean;
function GetIsRight: Boolean;
function GetIsLoading: Boolean;
function GetIsReading: Boolean;
function GetIsUpdating: Boolean;
function GetIsWidthStored: Boolean;
function GetItemIndex: Integer;
function GetOptions: TcxTreeListColumnOptions;
function GetSortIndex: Integer;
function GetStyles: TcxTreeListColumnStyles;
function GetTreeList: TcxCustomTreeList;
function GetValueByNode(ANode: TcxTreeListNode): Variant;
function GetValueDef: TcxValueDef;
function GetVisibleIndex: Integer;
function GetWidth: Integer;
procedure SetCaption(AValue: TcxTreeListCaption);
procedure SetDataBinding(AValue: TcxItemDataBinding);
procedure SetDisplayWidth(AValue: Integer);
procedure SetEditingProperties(AValue: TcxTreeListGetEditPropertiesEvent);
procedure SetEditProperties(AValue: TcxTreeListGetEditPropertiesEvent);
procedure SetIsPreview(AValue: Boolean);
procedure SetItemIndex(AValue: Integer);
procedure SetMinWidth(AValue: Integer);
procedure SetOptions(AValue: TcxTreeListColumnOptions);
procedure SetPosition(AValue: TcxTreeListColumnPosition);
procedure SetSortIndex(AValue: Integer);
procedure SetSortOrder(AValue: TcxDataSortOrder);
procedure SetStyles(AValue: TcxTreeListColumnStyles);
procedure SetSummary(AValue: TcxTreeListColumnSummary);
procedure SetSummaryFooter(AValue: TPersistent);
procedure SetValueByNode(ANode: TcxTreeListNode; const AValue: Variant);
procedure SetVisible(AValue: Boolean);
procedure SetWidth(AValue: Integer);
protected
//editing
function CanEdit: Boolean; override;
function GetEditValue: Variant; override;
function CanInitEditing: Boolean; override;
procedure AssignWidth;
procedure CancelSorting;
function CanFocus: Boolean; override;
function CanMoving: Boolean; virtual;
function CanSort: Boolean; virtual;
procedure ChangeCaption(Sender: TObject); virtual;
procedure Changed; override;
procedure ForceWidth(AWidth: Integer);
function GetHeaderFooterBestfitSize: Integer; virtual;
function GetOptionsClass: TcxCustomEditContainerItemOptionsClass; override;
function GetRealSortOrder: TcxDataSortOrder; virtual;
function GetStylesClass: TcxEditContainerStylesClass; override;
function GetSummaryClass: TcxTreeListColumnSummaryClass; virtual;
procedure SetEditingControl(Value: TcxEditingControl); override;
procedure SetName(const Value: TComponentName); override;
procedure SetParentComponent(Value: TComponent); override;
// IcxTreeListDragSizing implementation
function CanSizing(ADirection: TcxDragSizingDirection): Boolean; virtual;
function GetAvailableMaxWidth: Integer; virtual;
function GetRealMinSize: Integer;
function GetSizingBoundsRect(ADirection: TcxDragSizingDirection): TRect; virtual;
function GetSizingIncrement(ADirection: TcxDragSizingDirection): Integer; virtual;
function IsDynamicUpdate: Boolean; virtual;
procedure SetSizeDelta(ADirection: TcxDragSizingDirection; ADelta: Integer); virtual;
// IcxStoredObject
function GetObjectName: string;
function GetProperties(AProperties: TStrings): Boolean; virtual;
function GetPropertyIndex(const AName: string): Integer;
procedure GetPropertyValue(const AName: string; var AValue: Variant); virtual;
procedure SetPropertyValue(const AName: string; const AValue: Variant); virtual;
// column metods
procedure ChangeSortOrder(ASortOrder: TcxDataSortOrder; AShift: TShiftState);
procedure ConvertOldFooterSummaries;
procedure DoGetDisplayText(ARecordIndex: Integer; var AText: string); override;
function DoGetNodeDisplayText(ANode: TcxTreeListNode; const AValue: Variant): Variant; virtual;
function DoOnGetDisplayText(ANode: TcxTreeListNode; AsText: Boolean = False;
AValueOnly: Boolean = False): Variant; virtual;
function GetCellHeight(ANode: TcxTreeListNode; AWidth, ALines: Integer;
AFont: TFont; const AValue: Variant): Integer;
function GetPositionClass: TcxTreeListColumnPositionClass; virtual;
function HasDataTextHandler: Boolean; override;
procedure InitAutoWidthItem(AItem: TcxAutoWidthItem); virtual;
procedure SetCurrentValue(const Value: Variant); override;
property Data: Integer read FData write FData;
property DataController: TcxTreeListDataController read GetDataController;
property HasIndent: Boolean read GetHasIndent;
property HeaderCell: TcxTreeListColumnHeaderCellViewInfo read FHeaderCell;
property ID: Integer read GetID;
property IsFixed: Boolean read GetIsFixed;
property IsLoading: Boolean read GetIsLoading;
property IsReading: Boolean read GetIsReading;
property IsUpdating: Boolean read GetIsUpdating;
property ValueDef: TcxValueDef read GetValueDef;
property Controller;
property EditingControl;
property EditViewData;
property OnChangeName: TNotifyEvent read FOnChangeName write FOnChangeName;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyBestFit;
function GetParentComponent: TComponent; override;
function HasParent: Boolean; override;
procedure MakeVisible;
procedure RestoreDefaults; virtual;
procedure RestoreWidths; virtual;
property ActuallyVisible: Boolean read GetActuallyVisible;
property DisplayTexts[ANode: TcxTreeListNode]: string read GetDisplayText;
property DisplayWidth: Integer read GetDisplayWidth write SetDisplayWidth;
property IndentWidth: Integer read GetIndentWidth;
property IsHidden: Boolean read GetIsHidden;
property IsLeft: Boolean read GetIsLeft;
property IsPreview: Boolean read GetIsPreview write SetIsPreview;
property IsRight: Boolean read GetIsRight;
property PropertiesValue;
property TreeList: TcxCustomTreeList read GetTreeList;
property VisibleIndex: Integer read GetVisibleIndex;
property Editing;
property EditValue;
property Focused;
property ItemIndex read GetItemIndex write SetItemIndex;
property Value;
property ValueCount;
property Values[ANode: TcxTreeListNode]: Variant read GetValueByNode write SetValueByNode;
published
property SummaryFooter: TPersistent read FSummaryFooter write SetSummaryFooter stored False;
property Visible: Boolean read FVisible write SetVisible default True;
property Caption: TcxTreeListCaption read FCaption write SetCaption;
property DataBinding: TcxItemDataBinding read GetDataBinding write SetDataBinding;
property MinWidth: Integer read FMinWidth write SetMinWidth default cxTreeListDefMinWidth;
property Options: TcxTreeListColumnOptions read GetOptions write SetOptions;
property Width: Integer read GetWidth write SetWidth stored GetIsWidthStored;
property Position: TcxTreeListColumnPosition read FPosition write SetPosition;
property SortOrder: TcxDataSortOrder read FSortOrder write SetSortOrder default soNone;
property SortIndex: Integer read GetSortIndex write SetSortIndex default -1;
property Styles: TcxTreeListColumnStyles read GetStyles write SetStyles;
property Summary: TcxTreeListColumnSummary read FSummary write SetSummary;
property OnGetDisplayText: TcxTreeListOnGetDisplayTextEvent read FOnGetDisplayText write FOnGetDisplayText;
property OnGetEditingProperties: TcxTreeListGetEditPropertiesEvent read GetEditingProperties write SetEditingProperties;
property OnGetEditProperties: TcxTreeListGetEditPropertiesEvent read GetEditProperties write SetEditProperties;
// IcxStoredObject events
property OnGetStoredProperties: TcxGetStoredPropertiesEvent read FOnGetStoredProperties write FOnGetStoredProperties;
property OnGetStoredPropertyValue: TcxGetStoredPropertyValueEvent read FOnGetStoredPropertyValue write FOnGetStoredPropertyValue;
property OnSetStoredPropertyValue: TcxSetStoredPropertyValueEvent read FOnSetStoredPropertyValue write FOnSetStoredPropertyValue;
property PropertiesClassName;
property Properties;
property PropertiesEvents;
property RepositoryItem;
end;
TcxTreeListColumnClass = class of TcxTreeListColumn;
{ TcxTreeListSizingDragAndDropObject }
TcxTreeListSizingDragAndDropObject = class(TcxSizingDragAndDropObject)
private
FOffset: TPoint;
FDragItem: TObject;
protected
procedure BeginDragAndDrop; override;
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override;
function GetSizingMarkBounds: TRect; override;
end;
{ TcxTreeListDragAndDropObject }
TcxTreeListDropInfo = class
public
Accepted: Boolean;
Band: TcxTreeListBand;
ColIndex: Integer;
Customizing: Boolean;
DropPos: TPoint;
Position: TcxPosition;
end;
TcxTreeListDragAndDropObject = class(TcxCustomControlDragAndDropObject)
private
FArrows: TcxPlaceArrows;
FDropInfo: TcxTreeListDropInfo;
function DrawArrowsNeeded: Boolean;
function GetBands: TcxTreeListBands;
function GetCustomizing: Boolean;
function GetDestBand: TcxTreeListBand;
function GetDragHeader: TcxTreeListHeaderCellViewInfo;
function GetDropPosition: TcxPosition;
function GetHitTest: TcxTreeListHitTest;
function GetOptionsCustomize: TcxTreeListOptionsCustomizing;
function GetPainter: TcxTreeListPainter;
function GetTreeList: TcxCustomTreeList;
function GetViewInfo: TcxTreeListViewInfo;
protected
FOrigin: TPoint;
procedure BeginDragAndDrop; override;
procedure ChangeArrowsPosition;
function CanCustomize: Boolean; virtual; abstract;
function CanDrop: Boolean; virtual; abstract;
function CanRemove: Boolean; virtual; abstract;
function CheckInCustomizing(const APoint: TPoint): Boolean;
procedure CheckDragPosition; virtual; abstract;
function CreateDropInfo: TcxTreeListDropInfo; virtual;
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override;
function Drop: Boolean; virtual; abstract;
procedure EndDragAndDrop(Accepted: Boolean); override;
function GetArrowAreaBounds: TRect; virtual;
function GetDisplayRect: TRect; override;
function GetDragAndDropCursor(Accepted: Boolean): TCursor; override;
procedure InitDropInfo(const P: TPoint); virtual;
procedure InitializeScrollArea(const Area: TRect); virtual;
procedure MakeCustomizingPageVisible; virtual; abstract;
procedure Paint; override;
public
constructor Create(AControl: TcxControl); override;
destructor Destroy; override;
property Arrows: TcxPlaceArrows read FArrows;
property Bands: TcxTreeListBands read GetBands;
property Customizing: Boolean read GetCustomizing;
property DestBand: TcxTreeListBand read GetDestBand;
property DragHeader: TcxTreeListHeaderCellViewInfo read GetDragHeader;
property DropInfo: TcxTreeListDropInfo read FDropInfo;
property DropPosition: TcxPosition read GetDropPosition;
property HitTest: TcxTreeListHitTest read GetHitTest;
property OptionsCustomizing: TcxTreeListOptionsCustomizing read GetOptionsCustomize;
property Painter: TcxTreeListPainter read GetPainter;
property TreeList: TcxCustomTreeList read GetTreeList;
property ViewInfo: TcxTreeListViewInfo read GetViewInfo;
end;
{ TcxTreeListDragAndDropBandObject }
TcxTreeListDragAndDropBandObject = class(TcxTreeListDragAndDropObject)
private
procedure AfterDropPositionChange;
procedure BeforeDropPositionChange;
function GetBand: TcxTreeListBand;
function GetDropColIndex: Integer;
function GetDropParentBandIndex: Integer;
protected
function CanCustomize: Boolean; override;
function CanDrop: Boolean; override;
function CanRemove: Boolean; override;
function CheckBandInsertAt(ABand: TcxTreeListBand): Boolean;
procedure CheckDragPosition; override;
function Drop: Boolean; override;
function GetBoundsForInsert(ABand: TcxTreeListBand): TRect;
procedure MakeCustomizingPageVisible; override;
public
property Band: TcxTreeListBand read GetBand;
end;
{ TcxTreeListDragAndDropColumnObject }
TcxTreeListColumnDropInfo = class(TcxTreeListDropInfo)
public
Area: TRect;
Column: TcxTreeListColumn;
RowIndex: Integer;
InsertRow: Boolean;
end;
TcxTreeListDragAndDropColumnObject = class(TcxTreeListDragAndDropObject)
private
function GetColumn: TcxTreeListColumn;
function GetDropInfo: TcxTreeListColumnDropInfo;
protected
function CanCustomize: Boolean; override;
function CanDrop: Boolean; override;
procedure CheckDropColumnIndex(ARow: TcxTreeListBandRow; var AColIndex: Integer);
function CanRemove: Boolean; override;
function ChangeColumnOnly: Boolean;
function CheckBandDropArea(ABand: TcxTreeListBand): Boolean;
procedure CheckDragPosition; override;
function CreateDropInfo: TcxTreeListDropInfo; override;
function Drop: Boolean; override;
function GetArrowAreaBounds: TRect; override;
procedure InitDropInfoFromColumn(AColumn: TcxTreeListColumn);
procedure MakeCustomizingPageVisible; override;
public
property Column: TcxTreeListColumn read GetColumn;
property DropInfo: TcxTreeListColumnDropInfo read GetDropInfo;
end;
{ TcxTreeListCellNavigator }
TcxTreeListCellNavigator = class(TcxCustomCellNavigator)
private
FColumnChanged: Boolean;
FCurrentNavigationColumn: TcxTreeListColumn;
function GetCellIndex(AColumn: TcxTreeListColumn; ARow: TcxTreeListBandRow): Integer;
function GetController: TcxTreeListController;
function GetFocusedNode: TcxTreeListNode;
function GetTreeList: TcxCustomTreeList;
function GoToNextCellInBand(AForward: Boolean; AColumn: TcxTreeListColumn; var ACellIndex: Integer): Boolean;
function GoToNextNodeCell(AForward: Boolean; ANode: TcxTreeListNode; AColumn: TcxTreeListColumn; var ACellIndex: Integer): Boolean;
protected
procedure AppendRecord(var ARowIndex, ACellIndex: Integer);
procedure CalcNextRow(AForward: Boolean; var ARowIndex, ACellIndex: Integer); override;
function GetCount(ARecordIndex: Integer): Integer; override;
function GetCellContainer(ARowIndex, ACellIndex: Integer): TcxCustomInplaceEditContainer; override;
function GetNode(ARowIndex: Integer): TcxTreeListNode;
procedure Init(var ARowIndex, ACellIndex, ARowCount: Integer); override;
function IsGroupRow(ARowIndex: Integer): Boolean;
procedure SaveCurrentNavigationColumn;
procedure SetFocusCell(ARowIndex, ACellIndex: Integer; AShift: TShiftState); override;
public
procedure FocusNextCell(AForward, ANextRow: Boolean; AShift: TShiftState = []); override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure Refresh; override;
property Controller: TcxTreeListController read GetController;
property TreeList: TcxCustomTreeList read GetTreeList;
property FocusedNode: TcxTreeListNode read GetFocusedNode;
end;
{ TcxTreeListPopup }
TcxTreeListPopup = class(TcxCustomPopupWindow)
private
FOwner: TcxTreeListIndicatorCellViewInfo;
function GetTreeList: TcxCustomTreeList;
procedure SetOwner(AValue: TcxTreeListIndicatorCellViewInfo);
protected
function CalculateOwnerBounds: TRect; virtual;
procedure CreateListBox; virtual; abstract;
function GetClientMinWidth: Integer; virtual;
procedure InitPopup; override;
function NeedIgnoreMouseMessageAfterCloseUp(AWnd: THandle; AMsg: Cardinal;
AShift: TShiftState; const APos: TPoint): Boolean; override;
procedure Paint; override;
procedure VisibleChanged; override;
public
constructor Create(AOwnerControl: TWinControl); override;
procedure Popup; reintroduce; virtual;
property BorderWidths;
property TreeList: TcxCustomTreeList read GetTreeList;
property ClientMinWidth: Integer read GetClientMinWidth;
property Owner: TcxTreeListIndicatorCellViewInfo read FOwner write SetOwner;
end;
{ TcxTreeListCustomizationPopup }
TcxTreeListCustomizationPopup = class(TcxTreeListPopup)
private
FCheckListBox: TcxCheckListBox;
procedure CheckListBoxClick(Sender: TObject);
procedure CheckListBoxCheckClick(Sender: TObject; AIndex: Integer;
APrevState, ANewState: TcxCheckBoxState);
procedure CheckListBoxKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure CheckListBoxMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
protected
procedure AddCheckListBoxItems; virtual; abstract;
procedure AdjustCheckListBoxSize(AFixedHeight: Boolean = False); virtual;
procedure CheckClicked(AIndex: Integer; AChecked: Boolean); virtual;
procedure CreateListBox; override;
function GetCheckListBoxColumnWidth: Integer; virtual;
procedure GetCheckListBoxSelectedItems(AItems: TList);
function GetDropDownCount: Integer; virtual; abstract;
procedure InitPopup; override;
procedure ItemClicked(AItem: TObject; AChecked: Boolean); virtual; abstract;
procedure RefreshCheckListBoxItems;
procedure SetCheckListBoxSelectedItems(AItems: TList);
property CheckListBoxColumnWidth: Integer read GetCheckListBoxColumnWidth;
public
procedure CloseUp; override;
procedure CorrectBoundsWithDesktopWorkArea(var APosition: TPoint); override;
property CheckListBox: TcxCheckListBox read FCheckListBox;
end;
{ TcxTreeListColumnsCustomizationPopup }
TcxTreeListColumnsCustomizationPopup = class(TcxTreeListCustomizationPopup)
protected
procedure AddCheckListBoxItems; override;
function GetDropDownCount: Integer; override;
procedure ItemClicked(AItem: TObject; AChecked: Boolean); override;
end;
{ TcxTreeListBandsCustomizationPopup }
TcxTreeListBandsCustomizationPopup = class(TcxTreeListCustomizationPopup)
protected
procedure AddCheckListBoxItems; override;
function GetDropDownCount: Integer; override;
procedure ItemClicked(AItem: TObject; AChecked: Boolean); override;
end;
TcxTreeListEditingController = class(TcxEditingController)
end;
{ TcxTreeListController }
TcxTreeListController = class(TcxCustomControlController)
private
FBandsCustomizationPopup: TcxTreeListBandsCustomizationPopup;
FClickedObject: TObject;
FColumnsCustomizationPopup: TcxTreeListColumnsCustomizationPopup;
FDragDropInProcess: Boolean;
FFocusedNode: TcxTreeListNode;
FFocusedNodeIndex: Integer;
FForcingWidthBand: TcxTreeListBand;
FForcingWidthColumn: TcxTreeListColumn;
FHotTrackColumn: TcxTreeListColumn;
FHotTrackNode: TcxTreeListNode;
FHotTrackShift: TShiftState;
FIncSearchNode: TcxTreeListNode;
FIncSearchText: string;
FPressedHeader: TcxTreeListCustomHeaderCellViewInfo;
FPrevFocusedNode: TcxTreeListNode;
FResizeDirection: TcxDragSizingDirection;
FSearchNotification: Boolean;
FSelectionAnchor: TcxTreeListNode;
function GetBandsCustomizationPopup: TcxTreeListBandsCustomizationPopup;
function GetColumnsCustomizationPopup: TcxTreeListColumnsCustomizationPopup;
function GetDataController: TcxTreeListDataController;
function GetEditingController: TcxTreeListEditingController;
function GetFocusedNodeIndex: Integer;
function GetHitTest: TcxTreeListHitTest;
function GetIsDragCopy: Boolean;
function GetOptionsBehavior: TcxTreeListOptionsBehavior;
function GetOptionsSelection: TcxTreeListOptionsSelection;
function GetSelection: TList;
function GetSelectionAnchor: TcxTreeListNode;
function GetTreeList: TcxCustomTreeList;
procedure SetForcingWidthColumn(AColumn: TcxTreeListColumn);
procedure SetIncSearchNode(ANode: TcxTreeListNode);
procedure SetPressedHeader(AHeader: TcxTreeListCustomHeaderCellViewInfo);
protected
DragNodesList: TList;
DragNode: TcxTreeListNode;
PrevCursor: TCursor;
// DragDrop fields
ExpandingNode: TcxTreeListNode;
ExpandTimer: TTimer;
ScrollControllers: array[TcxBorder] of TcxAutoScrollingObject;
procedure BeforeShowEdit; override;
procedure CheckEdit; override;
function CheckAutoScrolling(const APoint: TPoint): Boolean; virtual;
//
procedure CheckFocusedNodeItem;
procedure ChangeFocusedNode(ANode: TcxTreeListNode); virtual;
function GetFocusedRecordIndex: Integer; override;
procedure SetFocusedNode(ANode: TcxTreeListNode); virtual;
procedure SetFocusedNodeItem(ANode: TcxTreeListNode; AColumn: TcxTreeListColumn); virtual;
procedure SetFocusedRecordIndex(Value: Integer); override;
// Drag drop
procedure BeforeStartDrag; override;
function CreateAutoScrollObject(Kind: TScrollBarKind;
const ARect: TRect; ACode: TScrollCode): TcxAutoScrollingObject;
procedure CheckButtonTimer; virtual;
procedure DragDrop(Source: TObject; X, Y: Integer); override;
procedure DragEnter; virtual;
procedure DragLeave; virtual;
procedure DragMove(Source: TObject; const P: TPoint; var Accepted: Boolean); virtual;
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
var Accept: Boolean); override;
procedure DropTo(ANode: TcxTreeListNode; AsChildren: Boolean); virtual;
procedure EndDrag(Target: TObject; X, Y: Integer); override;
procedure OnExpandTimer(Sender: TObject); virtual;
procedure ResetButtonTimer;
//
procedure DoNextNode(AForward: Boolean);
procedure DoNextPage(AForward: Boolean; Shift: TShiftState); override;
procedure DoShowNextPageEx(AGoForward, ASetCursor: Boolean;
AShift: TShiftState); virtual;
procedure FocusedRecordChanged(APrevFocusedRecordIndex, AFocusedRecordIndex: Integer); override;
procedure FocusedItemChanged(APrevFocusedItem: TcxCustomInplaceEditContainer); override;
function IsKeyForController(AKey: Word; AShift: TShiftState): Boolean; override;
function IsNodeKeyHandle(ANode: TcxTreeListNode;
var AKey: Word; Shift: TShiftState): Boolean; virtual;
function GetFocusedCellViewInfo(AEditContainer: TcxCustomInplaceEditContainer): TcxEditCellViewInfo; override;
function GetNavigatorClass: TcxCustomCellNavigatorClass; override;
function GetNode(ARecordIndex: Integer): TcxTreeListNode;
function GetResizeDirection: TcxDragSizingDirection; override;
procedure MouseLeave; override;
procedure DoCancelMode; override;
// incremental search
procedure CancelIncSearching; override;
function DoSearch(AFromNode: TcxTreeListNode; AItemIndex: Integer;
const AText: string; AGoForward: Boolean): Boolean; virtual;
function GetIncSearchingItem: TcxCustomInplaceEditContainer; override;
function GetIncSearchingText: string; override;
function GetIsIncSearching: Boolean; override;
function GetNextNodeForIncSearch(ANode: TcxTreeListNode; AGoForward: Boolean): TcxTreeListNode;
procedure CheckLocate(AFound: Boolean);
procedure SearchLocate(AItem: TcxCustomInplaceEditContainer; const AValue: string); override;
procedure SearchLocateNext(AItem: TcxCustomInplaceEditContainer; AForward: Boolean); override;
// design selection
function CanCreateSelectionHelper: Boolean;
function IsObjectSelected(AObject: TPersistent): Boolean; virtual;
procedure SelectObject(AObject: TPersistent; AShift: TShiftState); virtual;
procedure UnselectObject(AObject: TPersistent); virtual;
// selection
procedure CancelSelection(KeepPrimary: Boolean = True);
procedure Select(ANode: TcxTreeListNode; AShift: TShiftState); virtual;
procedure SelectRange(const AStartNode, AFinishNode: TcxTreeListNode);
procedure ViewInfoChanged; override;
property DataController: TcxTreeListDataController read GetDataController;
property EditingController: TcxTreeListEditingController read GetEditingController;
property SearchNotification: Boolean read FSearchNotification write FSearchNotification;
public
procedure AfterPaint; override;
procedure BeginDragAndDrop; override;
function CanDrag(X, Y: Integer): Boolean; override;
function CanDeleteSelection: Boolean;
function CanInsertNode: Boolean;
function CanSelectNode(ANode: TcxTreeListNode): Boolean;
function CheckCustomizationPopup: Boolean;
procedure CheckDeletedNode(ANode: TcxTreeListNode);
procedure CheckFocusedNode;
procedure CheckHeaderClick(AShift: TShiftState);
procedure CheckNodeContentClick(Shift: TShiftState);
procedure DblClick; override;
function DeleteConfirmation: Boolean;
function DoHeaderMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean; virtual;
function DoNodeMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean; virtual;
procedure DoMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure DoMouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure DoMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure EndDragAndDrop(Accepted: Boolean); override;
function FindNearestFocusableNode(AVisibleIndex: Integer): TcxTreeListNode;
function FindNearestFocusableColumn(AVisibleIndex: Integer): TcxTreeListColumn;
function HitAtNodeContent: Boolean;
function GetCursor(X, Y: Integer): TCursor; override;
function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
procedure MakeFocusedItemVisible; override;
procedure MakeFocusedRecordVisible; override;
procedure Reset; virtual;
procedure Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode;
var AScrollPos: Integer); override;
procedure SetSelection(AList: TList);
procedure SetFocusedRecordItem(ARecordIndex: Integer; AItem: TcxCustomInplaceEditContainer); override;
procedure SetHotTrackCursor(ACursor: TCursor);
procedure SetHotTrackNode(ANode: TcxTreeListNode; AShift: TShiftState);
procedure ShowEdit(AShift: TShiftState; X, Y: Integer);
function StartDragAndDrop(const P: TPoint): Boolean; override;
procedure UpdateHotTrackNode(AShift: TShiftState); overload;
procedure UpdateHotTrackNode(X, Y: Integer; AShift: TShiftState); overload;
property BandsCustomizationPopup: TcxTreeListBandsCustomizationPopup read GetBandsCustomizationPopup;
property ClickedObject: TObject read FClickedObject write FClickedObject;
property ColumnsCustomizationPopup: TcxTreeListColumnsCustomizationPopup read GetColumnsCustomizationPopup;
property DragDropInProcess: Boolean read FDragDropInProcess write FDragDropInProcess;
property FocusedNode: TcxTreeListNode read FFocusedNode write SetFocusedNode;
property FocusedNodeIndex: Integer read GetFocusedNodeIndex write FFocusedNodeIndex;
property ForcingWidthBand: TcxTreeListBand read FForcingWidthBand write FForcingWidthBand;
property ForcingWidthColumn: TcxTreeListColumn read FForcingWidthColumn write SetForcingWidthColumn;
property HitTest: TcxTreeListHitTest read GetHitTest;
property HotTrackColumn: TcxTreeListColumn read FHotTrackColumn write FHotTrackColumn;
property HotTrackNode: TcxTreeListNode read FHotTrackNode write FHotTrackNode;
property HotTrackShift: TShiftState read FHotTrackShift write FHotTrackShift;
property IncSearchNode: TcxTreeListNode read FIncSearchNode write SetIncSearchNode;
property IncSearchText: string read FIncSearchText write FIncSearchText;
property IsDragCopy: Boolean read GetIsDragCopy;
property OptionsBehavior: TcxTreeListOptionsBehavior read GetOptionsBehavior;
property OptionsSelection: TcxTreeListOptionsSelection read GetOptionsSelection;
property PressedHeader: TcxTreeListCustomHeaderCellViewInfo read FPressedHeader write SetPressedHeader;
property PrevFocusedNode: TcxTreeListNode read FPrevFocusedNode;
property Selection: TList read GetSelection;
property SelectionAnchor: TcxTreeListNode read GetSelectionAnchor write FSelectionAnchor;
property TreeList: TcxCustomTreeList read GetTreeList;
end;
{ TcxTreeListHitTest }
TcxTreeListHitTest = class(TcxCustomHitTestController)
private
FDragItem: TObject;
FHitBand: TcxTreeListBand;
FHitColumn: TcxTreeListColumn;
FHitNode: TcxTreeListNode;
function GetHitAtImages: Boolean;
function GetHitAtFooterArea: Boolean;
function GetHitAtHeader: Boolean;
function GetHitCell: TcxCustomViewInfoItem;
function GetTreeList: TcxCustomTreeList;
function GetViewInfo: TcxTreeListViewInfo;
protected
function AllowDesignMouseEvents(X, Y: Integer; AShift: TShiftState): Boolean; override;
function CanShowHint(AItem: TObject): Boolean; override;
procedure CheckFooterColumn;
procedure CheckSelection(AShift: TShiftState); virtual;
procedure DoCalculate; override;
function GetCurrentCursor: TCursor; override;
function GetState(Index: Integer): Boolean;
procedure SetHitState(Index: Integer; Value: Boolean);
property DragItem: TObject read FDragItem write FDragItem;
property HitAtFooterArea: Boolean read GetHitAtFooterArea;
property HitAtHeader: Boolean read GetHitAtHeader;
property ViewInfo: TcxTreeListViewInfo read GetViewInfo;
public
function CanMoving: Boolean; virtual;
function CanSizing: Boolean; virtual;
property Cursor: TCursor read GetCurrentCursor;
property HitAtBackground: Boolean index tlhc_HitAtBackground read GetState;
property HitAtBand: Boolean index tlhc_HitAtBand read GetState;
property HitAtBandContainer: Boolean index tlhc_HitAtBandContainer read GetState;
property HitAtBandCustomizing: Boolean index tlhc_HitAtBandCustomizing read GetState;
property HitAtBandHeader: Boolean index tlhc_HitAtBandHeader read GetState;
property HitAtButton: Boolean index tlhc_HitAtButton read GetState;
property HitAtCheckButton: Boolean index tlhc_HitAtCheckButton read GetState;
property HitAtColumn: Boolean index tlhc_HitAtColumn read GetState;
property HitAtColumnCustomizing: Boolean index tlhc_HitAtColumnCustomizing read GetState;
property HitAtColumnHeader: Boolean index tlhc_HitAtColumnHeader read GetState;
property HitAtFooter: Boolean index tlhc_HitAtFooter read GetState;
property HitAtFooterItem: Boolean index tlhc_HitAtFooterItem read GetState;
property HitAtGroupFooter: Boolean index tlhc_HitAtGroupFooter read GetState;
property HitAtGroupFooterItem: Boolean index tlhc_HitAtGroupFooterItem read GetState;
property HitAtImage: Boolean index tlhc_HitAtImage read GetState;
property HitAtImages: Boolean read GetHitAtImages;
property HitAtIndent: Boolean index tlhc_HitAtIndent read GetState;
property HitAtIndicator: Boolean index tlhc_HitAtIndicator read GetState;
property HitAtNode: Boolean index tlhc_HitAtNode read GetState;
property HitAtNodePreview: Boolean index tlhc_HitAtNodePreview read GetState;
property HitAtSeparator: Boolean index tlhc_HitAtSeparator read GetState;
property HitAtSizingHorz: Boolean index tlhc_HitAtSizingHorz read GetState;
property HitAtSizingVert: Boolean index tlhc_HitAtSizingVert read GetState;
property HitAtStateImage: Boolean index tlhc_HitAtStateImage read GetState;
property HitBand: TcxTreeListBand read FHitBand;
property HitCell: TcxCustomViewInfoItem read GetHitCell;
property HitColumn: TcxTreeListColumn read FHitColumn;
property HitNode: TcxTreeListNode read FHitNode;
property TreeList: TcxCustomTreeList read GetTreeList;
end;
{ TcxTreeListHitTestArea }
TcxTreeListHitTestArea = class
private
FArea: TRect;
FLink: TcxTreeListCustomCellViewInfo;
protected
procedure Calculate; virtual; abstract;
function GetHitTest(AHitTest: TcxTreeListHitTest): Boolean; virtual;
procedure InitHitTest(AHitTest: TcxTreeListHitTest); virtual; abstract;
public
constructor Create(ALink: TcxTreeListCustomCellViewInfo); virtual;
property Area: TRect read FArea write FArea;
property Link: TcxTreeListCustomCellViewInfo read FLink;
end;
{ TcxTreeListHeaderSizingArea }
TcxTreeListHeaderSizingArea = class(TcxTreeListHitTestArea)
private
FDirection: TcxDragSizingDirection;
protected
procedure Calculate; override;
procedure InitHitTest(AHitTest: TcxTreeListHitTest); override;
public
constructor CreateEx(ALink: TcxTreeListCustomCellViewInfo; ADirection: TcxDragSizingDirection);
property Direction: TcxDragSizingDirection read FDirection;
end;
{ TcxTreeListNodeSizingArea }
TcxTreeListNodeSizingArea = class(TcxTreeListHitTestArea)
protected
procedure Calculate; override;
function GetHitTest(AHitTest: TcxTreeListHitTest): Boolean; override;
procedure InitHitTest(AHitTest: TcxTreeListHitTest); override;
public
constructor Create(ALink: TcxTreeListCustomCellViewInfo); override;
destructor Destroy; override;
end;
{ TcxTreeListCustomCellViewInfo }
TcxTreeListSeparators = array[0..1] of TRect;
TcxTreeListCustomCellViewInfo = class(TcxCustomViewInfoItem, IUnknown)
private
function GetExtPaintStyle: Boolean;
function GetHitTestController: TcxTreeListHitTest;
function GetOptionsView: TcxTreeListOptionsView;
function GetStyles: TcxTreeListStyles;
function GetTreeList: TcxCustomTreeList;
function GetVisibleRect: TRect;
protected
FAttachNode: TcxTreeListNode;
FBorderColor: TColor;
FBorders: TcxBorders;
FNode: TcxTreeListNode;
procedure DoCalculate; override;
procedure DoDraw(ACanvas: TcxCanvas); override;
function CellHasOrigin: Boolean; virtual;
function GetCellOrigin: TPoint; virtual;
function GetClipRect: TRect;
function GetControl: TcxEditingControl; override;
function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; override;
procedure SetBounds(const ABounds, AVisibleBounds: TRect);
procedure SetHitTestCodes(const ACodes: array of Integer);
function GetSelected: Boolean; virtual;
// IUnknown
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
property AttachNode: TcxTreeListNode read FAttachNode;
property HitTest: TcxTreeListHitTest read GetHitTestController;
property OptionsView: TcxTreeListOptionsView read GetOptionsView;
property Selected: Boolean read GetSelected;
property Styles: TcxTreeListStyles read GetStyles;
public
constructor CreateEx(ATreeList: TcxCustomTreeList;
const ABounds, AVisibleRect: TRect); virtual;
property BorderColor: TColor read FBorderColor write FBorderColor;
property Borders: TcxBorders read FBorders;
property ExtPaintStyle: Boolean read GetExtPaintStyle;
property Node: TcxTreeListNode read FNode;
property TreeList: TcxCustomTreeList read GetTreeList;
property VisibleRect: TRect read GetVisibleRect;
end;
{ TcxTreeListBackgroundCellViewInfo }
TcxTreeListBackgroundCellViewInfo = class(TcxTreeListCustomCellViewInfo)
protected
function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; override;
procedure Scroll(const DX, DY: Integer); override;
public
class function CustomDrawID: Integer; override;
end;
{ TcxTreeListFooterCellViewInfo }
TcxTreeListFooterCellViewInfo = class(TcxTreeListCustomCellViewInfo, IcxHotTrackElement)
private
FColumn: TcxTreeListColumn;
FHidden: Boolean;
FText: string;
function GetShowEndEllipsis: Boolean;
protected
procedure DoCalculate; override;
procedure DoDraw(ACanvas: TcxCanvas); override;
procedure DrawText(ACanvas: TcxCanvas); virtual;
function GetAlignHorz: TAlignment; virtual;
function GetAlignVert: TcxAlignmentVert; virtual;
function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; override;
function GetItem: TcxTreeListSummaryItem; virtual;
function GetMultiline: Boolean; virtual;
procedure Initialize(ANode, AttachNode: TcxTreeListNode; AColumn: TcxTreeListColumn); virtual;
procedure Scroll(const DX, DY: Integer); override;
// IcxHotTrackElement
function GetOrigin: TPoint; virtual;
function IsNeedHint(ACanvas: TcxCanvas; const P: TPoint; out AText: TCaption;
out AIsMultiLine: Boolean; out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean; virtual;
procedure UpdateHotTrackState(const APoint: TPoint);
public
constructor CreateEx(ATreeList: TcxCustomTreeList;
const ABounds, AVisibleRect: TRect); override;
class function CustomDrawID: Integer; override;
property AlignHorz: TAlignment read GetAlignHorz;
property AlignVert: TcxAlignmentVert read GetAlignVert;
property AttachNode;
property Column: TcxTreeListColumn read FColumn;
property Hidden: Boolean read FHidden;
property MultiLine: Boolean read GetMultiLine;
property ShowEndEllipsis: Boolean read GetShowEndEllipsis;
property Text: string read FText;
property TreeList;
end;
{ TcxTreeListFooterSingleCellViewInfo }
TcxTreeListFooterSingleCellViewInfo = class(TcxTreeListFooterCellViewInfo)
private
FSummaryItem: TcxTreeListSummaryItem;
protected
function GetItem: TcxTreeListSummaryItem; override;
function GetSelected: Boolean; override;
procedure Initialize(ANode, AttachNode: TcxTreeListNode; AColumn: TcxTreeListColumn;
ASummaryItem: TcxTreeListSummaryItem); reintroduce; overload;
public
property SummaryItem: TcxTreeListSummaryItem read FSummaryItem;
end;
{ TcxTreeListFooterMultiItemsCellViewInfo }
TcxTreeListFooterMultiItemsCellViewInfo = class(TcxTreeListFooterCellViewInfo)
private
FNeedShowHint: Boolean;
FSummaryItems: TcxTreeListSummaryItems;
FHintRect: TRect;
FVisibleCount: Integer;
function GetSeparator: string;
protected
function CanDifferentStyles: Boolean;
procedure DrawText(ACanvas: TcxCanvas); override;
function GetAlignHorz: TAlignment; override;
function GetAlignVert: TcxAlignmentVert; override;
function GetItem: TcxTreeListSummaryItem; override;
function GetSelected: Boolean; override;
procedure Initialize(ADataNode, AttachNode: TcxTreeListNode; AColumn: TcxTreeListColumn;
ASummaryItems: TcxTreeListSummaryItems); reintroduce; overload;
function IsNeedHint(ACanvas: TcxCanvas; const P: TPoint; out AText: TCaption;
out AIsMultiLine: Boolean; out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean; override;
public
property Separator: string read GetSeparator;
property SummaryItems: TcxTreeListSummaryItems read FSummaryItems;
property VisibleCount: Integer read FVisibleCount;
end;
{ TcxTreeListCustomHeaderCellViewInfo }
TcxTreeListCustomHeaderCellViewInfo = class(TcxTreeListCustomCellViewInfo, IcxHotTrackElement)
private
FIsLast: Boolean;
FNeighbors: TcxNeighbors;
FState: TcxButtonState;
FTextBounds: TRect;
function GetHotTrack: Boolean;
function GetPressed: Boolean;
procedure SetHotTrack(AValue: Boolean);
procedure SetPressed(AValue: Boolean);
procedure SetState(AValue: TcxButtonState);
protected
BordersMargins: TRect;
function CanNeighborFor(ACandidate: TcxTreeListHeaderCellViewInfo): Boolean; virtual;
procedure CheckClipping(const ADisplayRect, AAvailableRect: TRect); override;
function CheckNeighbors(ACandidate: TcxTreeListHeaderCellViewInfo; AShift: Integer): Boolean; virtual;
procedure Click; virtual;
procedure DoCalculate; override;
procedure DoDraw(ACanvas: TcxCanvas); override;
function GetAlignHorz: TAlignment; virtual;
function GetAlignVert: TcxAlignmentVert; virtual;
function GetIsVisible: Boolean; virtual;
function GetMultiline: Boolean; virtual;
function GetShowEndEllipsis: Boolean; virtual;
function GetText: string; virtual;
// IcxHotTrackElement
function GetOrigin: TPoint; virtual;
function IsNeedHint(ACanvas: TcxCanvas; const P: TPoint; out AText: TCaption;
out AIsMultiLine: Boolean; out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean; virtual;
procedure UpdateHotTrackState(const APoint: TPoint);
public
constructor CreateEx(ATreeList: TcxCustomTreeList;
const ABounds, AVisibleRect: TRect); override;
property HotTrack: Boolean read GetHotTrack write SetHotTrack;
property IsLast: Boolean read FIsLast;
property MultiLine: Boolean read GetMultiLine;
property Neighbors: TcxNeighbors read FNeighbors;
property Pressed: Boolean read GetPressed write SetPressed;
property State: TcxButtonState read FState write SetState;
property TextBounds: TRect read FTextBounds;
end;
{ TcxTreeListIndicatorCellViewInfo }
TcxTreeListIndicatorPosition = (tlipBands, tlipColumns, tlipContent, tlipFooter);
TcxTreeListIndicatorCellViewInfo = class(TcxTreeListCustomHeaderCellViewInfo)
private
FKind: TcxIndicatorKind;
FPosition: TcxTreeListIndicatorPosition;
FSizingArea: TcxTreeListNodeSizingArea;
procedure SetKind(AValue: TcxIndicatorKind);
protected
function ActualIndicatorKind: TcxIndicatorKind;
procedure DoCalculate; override;
procedure DoDraw(ACanvas: TcxCanvas); override;
function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; override;
function GetPopup: TcxTreeListCustomizationPopup;
procedure Initialize(ANode: TcxTreeListNode; APosition: TcxTreeListIndicatorPosition); virtual;
function IsQuickCustomizationEnabled: Boolean;
procedure Scroll(const DX, DY: Integer); override;
procedure ShowPopup;
function ClosePopupWhenNilOwner: Boolean;
function GetOwnerBounds: TRect;
procedure PopupClosed;
property SizingArea: TcxTreeListNodeSizingArea read FSizingArea write FSizingArea;
public
destructor Destroy; override;
class function CustomDrawID: Integer; override;
property Kind: TcxIndicatorKind read FKind write SetKind;
property Position: TcxTreeListIndicatorPosition read FPosition;
end;
{ TcxTreeListHeaderCellViewInfo }
TcxTreeListHeaderCellViewInfo = class(TcxTreeListCustomHeaderCellViewInfo, IcxDragSizing)
private
FCaption: TcxTreeListCaption;
FGlyphPosition: TPoint;
FItem: TPersistent;
FSortMarkBounds: TRect;
function GetDragSizing: IcxDragSizing;
function GetGlyph: TBitmap;
function GetGlyphAlignHorz: TAlignment;
function GetGlyphAlignVert: TcxAlignmentVert;
protected
FHintCalculated: Boolean;
GlyphClipping: Boolean;
procedure DoCalculate; override;
procedure DoCalculateGlyphPosition;
procedure DoDraw(ACanvas: TcxCanvas); override;
function GetAlignHorz: TAlignment; override;
function GetAlignVert: TcxAlignmentVert; override;
function GetFixed: Boolean; virtual;
function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; override;
function GetMultiline: Boolean; override;
function GetSelected: Boolean; override;
function GetShowEndEllipsis: Boolean; override;
function GetSortOrder: TcxDataSortOrder; virtual;
function GetText: string; override;
procedure Initialize(ACaption: TcxTreeListCaption);
procedure Scroll(const DX, DY: Integer); override;
procedure SetHitItem; virtual;
property DragSizing: IcxDragSizing read GetDragSizing implements IcxDragSizing;
property Item: TPersistent read FItem;
public
property AlignHorz: TAlignment read GetAlignHorz;
property AlignVert: TcxAlignmentVert read GetAlignVert;
property Fixed: Boolean read GetFixed;
property Glyph: TBitmap read GetGlyph;
property GlyphAlignHorz: TAlignment read GetGlyphAlignHorz;
property GlyphAlignVert: TcxAlignmentVert read GetGlyphAlignVert;
property GlyphPosition: TPoint read FGlyphPosition;
property ShowEndEllipsis: Boolean read GetShowEndEllipsis;
property SortMarkBounds: TRect read FSortMarkBounds;
property SortOrder: TcxDataSortOrder read GetSortOrder;
property Text: string read GetText;
property TextBounds;
property TreeList;
end;
{ TcxTreeListBandHeaderCellViewInfo }
TcxTreeListBandHeaderCellViewInfo = class(TcxTreeListHeaderCellViewInfo)
private
function GetBand: TcxTreeListBand;
protected
procedure Click; override;
procedure DoCalculate; override;
function GetFixed: Boolean; override;
function GetIsVisible: Boolean; override;
procedure SetHitItem; override;
public
class function CustomDrawID: Integer; override;
property Band: TcxTreeListBand read GetBand;
end;
{ TcxTreeListColumnHeaderCellViewInfo }
TcxTreeListColumnHeaderCellViewInfo = class(TcxTreeListHeaderCellViewInfo)
private
function GetBand: TcxTreeListBand;
function GetColumn: TcxTreeListColumn;
protected
procedure Click; override;
procedure DoCalculate; override;
function GetFixed: Boolean; override;
function GetIsVisible: Boolean; override;
function GetSortOrder: TcxDataSortOrder; override;
procedure SetHitItem; override;
public
class function CustomDrawID: Integer; override;
property Band: TcxTreeListBand read GetBand;
property Column: TcxTreeListColumn read GetColumn;
end;
{ TcxTreeListBandCellViewInfo }
TcxTreeListBandPart = (tlbpHeader, tlbpContent, tlbpGroupFooter, tlbpFooter, tlbpSeparator);
TcxTreeListBandCellViewInfo = class(TcxTreeListCustomCellViewInfo)
private
FBand: TcxTreeListBand;
FPart: TcxTreeListBandPart;
protected
procedure DoCalculate; override;
procedure DoDraw(ACanvas: TcxCanvas); override;
function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; override;
procedure Initialize(ABand: TcxTreeListBand; ANode, AAttachNode: TcxTreeListNode; APart: TcxTreeListBandPart);
procedure Scroll(const DX, DY: Integer); override;
public
class function CustomDrawID: Integer; override;
property Band: TcxTreeListBand read FBand;
property Part: TcxTreeListBandPart read FPart;
property AttachNode;
end;
{ TcxTreeListEditCellViewInfo }
TcxTreeListEditCellViewInfo = class(TcxEditCellViewInfo)
private
FBorderColor: TColor;
FNodeViewData: TcxTreeListNodeViewData;
function GetBand: TcxTreeListBand;
function GetEditing: Boolean;
function GetNode: TcxTreeListNode;
function GetOptionsView: TcxTreeListOptionsView;
function GetTreeList: TcxCustomTreeList;
protected
function ContentOffset: TRect; override;
procedure DoCalculate; override;
procedure DoDraw(ACanvas: TcxCanvas); override;
function GetButtonTransparency: TcxEditButtonTransparency; override;
function GetCellOrg: TPoint; override;
function GetColumn: TcxTreeListColumn; virtual;
function GetDisplayValue: Variant; override;
function GetEditRect: TRect; override;
function GetEditViewParams: TcxViewParams; override;
function GetFocused: Boolean; override;
function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; override;
function GetHotTrack: Boolean; virtual;
function GetIncSearchParams: TcxViewParams;
// IcxHotTrackElement
function GetOrigin: TPoint; override;
function IsNeedHint(ACanvas: TcxCanvas; const P: TPoint;
out AText: TCaption; out AIsMultiLine: Boolean; out ATextRect: TRect;
var IsNeedOffsetHint: Boolean): Boolean; override;
function GetRecordIndex: Integer; override;
function GetSelected: Boolean; virtual;
function GetSelectedTextColor: Integer; override;
function GetSelectedBKColor: Integer; override;
function GetViewInfoData: Pointer; override;
function IsAutoHeight: Boolean; override;
function IsEditHotTrack(const APoint: TPoint): Boolean; virtual;
function IsEndEllipsis: Boolean; override;
function IsFixed: Boolean; virtual;
function IsTransparent: Boolean; override;
procedure Scroll(const DX, DY: Integer); override;
public
class function CustomDrawID: Integer; override;
property Band: TcxTreeListBand read GetBand;
property BorderColor: TColor read FBorderColor write FBorderColor;
property Column: TcxTreeListColumn read GetColumn;
property Editing: Boolean read GetEditing;
property EditRect: TRect read GetEditRect;
property Focused: Boolean read GetFocused;
property HotTrack: Boolean read GetHotTrack;
property Node: TcxTreeListNode read GetNode;
property NodeViewData: TcxTreeListNodeViewData read FNodeViewData;
property OptionsView: TcxTreeListOptionsView read GetOptionsView;
property Selected: Boolean read GetSelected;
property TreeList: TcxCustomTreeList read GetTreeList;
end;
{ TcxTreeListGroupNodeEditViewInfo }
TcxTreeListGroupNodeEditViewInfo = class(TcxTreeListEditCellViewInfo)
protected
function GetColumn: TcxTreeListColumn; override;
function GetFocused: Boolean; override;
function IsFixed: Boolean; override;
procedure Scroll(const DX, DY: Integer); override;
end;
{ TcxTreeListPreviewCellViewInfo }
TcxTreeListPreviewCellViewInfo = class(TcxTreeListEditCellViewInfo)
private
FPreview: TcxTreeListPreview;
protected
function ContentOffset: TRect; override;
procedure DoCalculate; override;
function GetButtonTransparency: TcxEditButtonTransparency; override;
function GetColumn: TcxTreeListColumn; override;
function GetEditViewParams: TcxViewParams; override;
function GetHotTrack: Boolean; override;
function GetMaxLineCount: Integer; override;
function IsAutoHeight: Boolean; override;
function IsEditHotTrack(const APoint: TPoint): Boolean; override;
procedure Scroll(const DX, DY: Integer); override;
public
constructor Create(AOwner: TObject); override;
class function CustomDrawID: Integer; override;
property Preview: TcxTreeListPreview read FPreview;
end;
{ TcxTreeListIndentCellViewInfo }
TcxTreeListIndentLine = (ilVertUp, ilVertDown, ilHorz);
TcxTreeListIndentLines = set of TcxTreeListIndentLine;
TcxTreeListNodeIndentKind = (nikLevel, nikImage, nikState, nikCheck, nikFooter);
TcxTreeListIndentCellViewInfo = class(TcxTreeListCustomCellViewInfo, IcxHotTrackElement)
private
FButton: Boolean;
FGlyphRect: TRect;
FHorzTreeLine: TRect;
FHotTrack: Boolean;
FImageIndex: Integer;
FImages: TCustomImageList;
FIndex: Integer;
FKind: TcxTreeListNodeIndentKind;
FLevelNode: TcxTreeListNode;
FLines: TcxTreeListIndentLines;
FOverlayIndex: Integer;
FVertTreeLine: TRect;
function GetCheckState: TcxCheckBoxState;
function GetFixed: Boolean;
function GetHasImage: Boolean;
function GetIsExpanded: Boolean;
protected
procedure DoCalculate; override;
procedure DoDraw(ACanvas: TcxCanvas); override;
procedure DrawCheck(ACanvas: TcxCanvas); virtual;
procedure DrawImage(ACanvas: TcxCanvas); virtual;
procedure DrawLines(ACanvas: TcxCanvas); virtual;
procedure DrawTreeLine(ACanvas: TcxCanvas; const ARect: TRect);
function GetCheckBoxViewInfo(ACanvas: TcxCanvas): TcxCustomEditViewInfo;
function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; override;
procedure InitializeLevelIndent(ANode, AAttachNode: TcxTreeListNode; AIndex: Integer); overload;
procedure InitializeImageIndent(AImages: TCustomImageList); virtual;
procedure Scroll(const DX, DY: Integer); override;
procedure SetSize(ATop, AHeight: Integer);
// IcxHotTrackElement
function GetOrigin: TPoint; virtual;
function IsNeedHint(ACanvas: TcxCanvas; const P: TPoint; out AText: TCaption;
out AIsMultiLine: Boolean; out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean; virtual;
procedure UpdateHotTrackState(const APoint: TPoint);
public
class function CustomDrawID: Integer; override;
property Button: Boolean read FButton;
property CheckState: TcxCheckBoxState read GetCheckState;
property Fixed: Boolean read GetFixed;
property GlyphRect: TRect read FGlyphRect write FGlyphRect;
property HasImage: Boolean read GetHasImage;
property HorzTreeLine: TRect read FHorzTreeLine;
property HotTrack: Boolean read FHotTrack;
property ImageIndex: Integer read FImageIndex;
property Images: TCustomImageList read FImages;
property Index: Integer read FIndex;
property IsExpanded: Boolean read GetIsExpanded;
property Kind: TcxTreeListNodeIndentKind read FKind;
property LevelNode: TcxTreeListNode read FLevelNode;
property Lines: TcxTreeListIndentLines read FLines;
property OverlayIndex: Integer read FOverlayIndex;
property VertTreeLine: TRect read FVertTreeLine;
property ViewParams;
property TreeList;
end;
{ TcxTreeListNodeViewData }
TcxTreeListNodeViewData = class
public
Bounds: TRect;
Cells: TcxCustomControlCells;
CheckFooterRgn: Boolean;
ContentBounds: TRect;
DrawFocusRect: Boolean;
Focused: Boolean;
FocusRectBounds: TRect;
GroupFooterCount: Integer;
Height: Integer;
ImageIndent: TcxTreeListIndentCellViewInfo;
IndentWidth: Integer;
Node: TcxTreeListNode;
Origin: TPoint;
PreviewHeight: Integer;
RowsHeight: Integer;
RowsOffset: Integer;
Selected: Boolean;
StateImageIndent: TcxTreeListIndentCellViewInfo;
ViewInfo: TcxTreeListViewInfo;
constructor Create(AViewInfo: TcxTreeListViewInfo; ANode: TcxTreeListNode; ACapacity: Integer); virtual;
destructor Destroy; override;
function GetRealBounds: TRect;
function GetRealContentBounds: TRect;
procedure Paint(ACanvas: TcxCanvas; AHandler: TcxCustomDrawCellEvent);
procedure Scroll(DX, DY: Integer; ALeftFixed, ARightFixed: Boolean); virtual;
function Update(AForceUpdate: Boolean): Boolean;
end;
{ TcxTreeListViewInfo }
TcxTreeListViewInfo = class(TcxCustomControlViewInfo)
private
FBandHeaderLineHeight: Integer;
FBandLineHeight: Integer;
FBounds: TRect;
FCells: TcxCustomControlCells;
FContentParts: array[TcxTreeListBandFixedKind] of TRect;
FContentHeight: Integer;
FContentWidth: Integer;
FCheckBoxProperties: TcxCustomEditProperties;
FCheckBoxViewData: TcxCustomEditViewData;
FCheckBoxViewInfo: TcxCustomEditViewInfo;
FDefaultCellHeight: Integer;
FDragItem: TObject;
FFakeCell: TcxTreeListEditCellViewInfo;
FFooterLineHeight: Integer;
FGridLineColor: TColor;
FGridLines: TcxBorders;
FHeaderCells: TList;
FHeaderLineHeight: Integer;
FHitTestCells: TcxObjectList;
FHorzBackgroundCell: TcxTreeListBackgroundCellViewInfo;
FHScrollArea: TRect;
FHScrollInc: Integer;
FHScrollPage: Integer;
FHScrollPos: Integer;
FHScrollSize: Integer;
FMultiRows: Boolean;
FNodesHeight: Integer;
FNodesViewData: TcxObjectList;
FNodesVisibleCount: Integer;
FPrevFont: TFont;
FPrevFontHeight: Integer;
FPreviewLineHeight: Integer;
FRows: PIntegerArray;
FTreeLineColor: TColor;
function GetBands: TcxTreeListBands;
function GetBandsHeight: Integer;
function GetBorderSize: Integer;
function GetCalculateInProcess: Boolean;
function GetCheckBoxSize: TSize;
function GetColumn(AIndex: Integer): TcxTreeListColumn;
function GetColumnCount: Integer;
function GetColumnDefaultEditHeight(AColumn: TcxTreeListColumn): Integer;
function GetColumnsRowCount: Integer;
function GetContentPart(AKind: TcxTreeListBandFixedKind): TRect;
function GetCount: Integer;
function GetDefaultRowHeight: Integer;
function GetFixedSeparatorWidth: Integer;
function GetFooterHeight: Integer;
function GetFooterLineCount: Integer;
function GetGroupFooterHeight: Integer;
function GetGroupFooterLineCount: Integer;
function GetHeadersHeight: Integer;
function GetImages: TCustomImageList;
function GetIndentBand: TcxTreeListBand;
function GetIndentLeftMost: Boolean;
function GetIndicatorWidth: Integer;
function GetLastNode: TcxTreeListNode;
function GetLevelInfo(ALevel: Integer): TcxTreeListLevelInfo;
function GetNodeViewData(AIndex: Integer): TcxTreeListNodeViewData;
function GetOptionsView: TcxTreeListOptionsView;
function GetOriginalViewInfo: TcxTreeListViewInfo;
function GetPainter: TcxCustomLookAndFeelPainterClass;
function GetPreview: TcxTreeListPreview;
function GetRoot: TcxTreeListNode;
function GetRowOffset(AIndex: Integer): Integer;
function GetSummary: TcxTreeListSummary;
function GetStateImages: TCustomImageList;
function GetStyles: TcxTreeListStyles;
function GetTopNode: TcxTreeListNode;
function GetTreeList: TcxCustomTreeList;
function GetVScrollPage: Integer;
function GetVScrollPos: Integer;
function GetVScrollSize: Integer;
procedure SetCalculateInProcess(AValue: Boolean);
procedure SetHScrollPos(APosition: Integer);
procedure SetLastNode(ANode: TcxTreeListNode);
procedure SetRowOffset(AIndex: Integer; const AValue: Integer);
protected
function AddBackgroundPart(const ABounds: TRect): TcxTreeListBackgroundCellViewInfo;
function AddBandHeader(ABand: TcxTreeListBand; var ABounds: TRect;
const AClipRect: TRect): TcxTreeListBandHeaderCellViewInfo;
function AddBandPart(APart: TcxTreeListBandPart; ABand: TcxTreeListBand; ANode, AAttachNode: TcxTreeListNode;
ABounds, AClipRect: TRect): TcxTreeListBandCellViewInfo;
function AddBandSeparator(ANode: TcxTreeListNode;
var ABounds: TRect; const AClipBounds: TRect): TcxTreeListBandCellViewInfo;
procedure AddBandsHeaders(AKind: TcxTreeListBandFixedKind; const ABounds, AClipBounds: TRect);
procedure AddCell(ACellClass: TcxTreeListCustomCellViewInfoClass;
const ABounds, AVisibleRect: TRect; var AInstance);
function AddColumnHeader(AColumn: TcxTreeListColumn; var ABounds: TRect;
const AClipBounds: TRect): TcxTreeListColumnHeaderCellViewInfo;
function AddEditCell(AViewData: TcxTreeListNodeViewData; AColumn: TcxTreeListColumn;
ABounds, AClipRect: TRect; AClass: TcxEditCellViewInfoClass): TcxTreeListEditCellViewInfo;
procedure AddColumnFooterItems(ADataNode, AttachNode: TcxTreeListNode;
AColumn: TcxTreeListColumn; const ABounds, AClipRect: TRect);
procedure AddFixedSeparators(ABounds: TRect; AAttachNode: TcxTreeListNode);
procedure AddFooter(AAttachNode: TcxTreeListNode; AIndex, AIndent: Integer; const ABounds: TRect);
procedure AddHeaderHitTestAreas(ACell: TcxTreeListHeaderCellViewInfo; AHorz, AVert: Boolean);
function AddImageIndent(ANode: TcxTreeListNode; AImages: TCustomImageList;
var ABounds: TRect; const AClipRect: TRect): TcxTreeListIndentCellViewInfo;
function AddIndent(ANode, AAttachNode: TcxTreeListNode; ALevel: Integer; AKind: TcxTreeListNodeIndentKind;
var ABounds: TRect; const AClipRect: TRect): TcxTreeListIndentCellViewInfo;
function AddIndentCheck(ANode: TcxTreeListNode;
var ABounds: TRect; const AClipRect: TRect): TcxTreeListIndentCellViewInfo;
function AddIndicator(ANode: TcxTreeListNode; APosition: TcxTreeListIndicatorPosition;
var ABounds: TRect): TcxTreeListIndicatorCellViewInfo;
procedure AddNodeBands(AViewData: TcxTreeListNodeViewData);
procedure AddNodeCategorized(AViewData: TcxTreeListNodeViewData);
procedure AddNodeColumns(AViewData: TcxTreeListNodeViewData);
procedure AddNodeFooters(AViewData: TcxTreeListNodeViewData);
procedure AddNodeIndents(AViewData: TcxTreeListNodeViewData);
function AddNodePreview(AViewData: TcxTreeListNodeViewData): TcxTreeListEditCellViewInfo;
procedure AddNodeStandardContent(AViewData: TcxTreeListNodeViewData);
function AddNodeViewData(ANode: TcxTreeListNode; AInsert: Boolean): TcxTreeListNodeViewData;
procedure AdjustNodeIndents(AViewData: TcxTreeListNodeViewData);
procedure AfterCalculate; virtual;
procedure BeforeCalculate; virtual;
procedure CalculateBackgroundParts; virtual;
procedure CalculateBandsLayout; virtual;
procedure CalculateColumnsLayout; virtual;
function CalculateDefaultEditHeight: Integer; override;
procedure CalculateDefaultHeights; override;
procedure CalculateFooterLayout; virtual;
procedure CalculateHeadersNeighbors;
procedure CalculateHitTest(AHitTest: TcxTreeListHitTest); virtual;
procedure CalculateHorzScrollInfo(AAvailableWidth, AContentWidth: Integer); virtual;
function CalculateNodeAutoHeight(AViewData: TcxTreeListNodeViewData): Integer;
procedure CalculateNodesOrigin; virtual;
procedure CalculateNodesViewData; virtual;
procedure CalculateNodesViewDataBackward(ANode: TcxTreeListNode; ACheckHeight: Boolean; var AvailableHeight: Integer); virtual;
procedure CalculateNodesViewDataForward(ANode: TcxTreeListNode; var AvailableHeight: Integer); virtual;
procedure CellsChanged;
function CheckScrollPosition(AScrollCode: TScrollCode; APos, APage, AInc, AMax : Integer;
var AScrollPos: Integer): Boolean; virtual;
procedure CorrectBorders; virtual;
procedure Clear;
procedure DeleteNodeViewData(AIndex: Integer);
procedure DoCalculate; override;
function GetContentBounds: TRect; virtual;
function GetFontHeight(const AFont: TFont): Integer;
function GetIsIndicatorVisible: Boolean; virtual;
function GetIsPrinting: Boolean; virtual;
function GetLevelContentOffset(ALevel: Integer): Integer;
function GetNodeContentOffset(ANode: TcxTreeListNode): Integer;
function HasFooter(ANode: TcxTreeListNode): Boolean; virtual;
function HasStateIndent(ANode: TcxTreeListNode): Boolean;
procedure InflateBoundsForGridLines(var ABounds, AClipRect: TRect);
procedure InitializeRows(const ANewHeight: Integer; var AViewData: TcxTreeListNodeViewData);
procedure InitScrollBarsParameters; virtual;
procedure InvalidateRect(const ARect: TRect);
procedure MakeVisible(ANode: TcxTreeListNode);
procedure RecalculateHitTestCells;
procedure RecreateCheckBoxViewData;
procedure ScrollHorz(AScrollCode: TScrollCode; var AScrollPos: Integer);
procedure ScrollVert(AScrollCode: TScrollCode; var AScrollPos: Integer);
procedure SetDirty;
procedure UpdateScrollBars; virtual;
procedure UpdateSelection; override;
procedure ValidateScrollPos(var APosition: Integer; const APage, AMax: Integer);
property CalculateInProcess: Boolean read GetCalculateInProcess write SetCalculateInProcess;
property FakeCell: TcxTreeListEditCellViewInfo read FFakeCell;
property HitTestCells: TcxObjectList read FHitTestCells;
property IsPrinting: Boolean read GetIsPrinting;
property RowOffset[Index: Integer]: Integer read GetRowOffset write SetRowOffset;
public
constructor Create(AOwner: TcxEditingControl); override;
destructor Destroy; override;
function GetEditCell(ANode: TcxTreeListNode;
AColumn: TcxTreeListColumn): TcxTreeListEditCellViewInfo;
function Validate: Boolean;
property BandHeaderLineHeight: Integer read FBandHeaderLineHeight;
property BandLineHeight: Integer read FBandLineHeight;
property Bands: TcxTreeListBands read GetBands;
property BandsHeight: Integer read GetBandsHeight;
property BorderSize: Integer read GetBorderSize;
property Bounds: TRect read FBounds write FBounds;
property Cells: TcxCustomControlCells read FCells write FCells;
property CheckboxSize: TSize read GetCheckBoxSize;
property CheckBoxViewInfo: TcxCustomEditViewInfo read FCheckBoxViewInfo;
property CheckBoxViewData: TcxCustomEditViewData read FCheckBoxViewData;
property ColumnCount: Integer read GetColumnCount;
property Columns[Index: Integer]: TcxTreeListColumn read GetColumn;
property ColumnsRowCount: Integer read GetColumnsRowCount;
property ContentBounds: TRect read GetContentBounds;
property ContentHeight: Integer read FContentHeight write FContentHeight ;
property ContentParts[AKind: TcxTreeListBandFixedKind]: TRect read GetContentPart;
property ContentWidth: Integer read FContentWidth;
property Count: Integer read GetCount;
property DefaultCellHeight: Integer read FDefaultCellHeight;
property DefaultRowHeight: Integer read GetDefaultRowHeight;
property FixedSeparatorWidth: Integer read GetFixedSeparatorWidth;
property FooterHeight: Integer read GetFooterHeight;
property FooterLineCount: Integer read GetFooterLineCount;
property FooterLineHeight: Integer read FFooterLineHeight;
property GridLineColor: TColor read FGridLineColor;
property GridLines: TcxBorders read FGridLines write FGridLines;
property GroupFooterHeight: Integer read GetGroupFooterHeight;
property GroupFooterLineCount: Integer read GetGroupFooterLineCount;
property HeaderLineHeight: Integer read FHeaderLineHeight;
property HeadersHeight: Integer read GetHeadersHeight;
property HorzBackgroundCell: TcxTreeListBackgroundCellViewInfo read FHorzBackgroundCell;
property HScrollArea: TRect read FHScrollArea;
property HScrollInc: Integer read FHScrollInc;
property HScrollPage: Integer read FHScrollPage;
property HScrollPos: Integer read FHScrollPos write SetHScrollPos;
property HScrollSize: Integer read FHScrollSize;
property IndentBand: TcxTreeListBand read GetIndentBand;
property IndentLeftMost: Boolean read GetIndentLeftMost;
property IsIndicatorVisible: Boolean read GetIsIndicatorVisible;
property LevelInfo[ALevel: Integer]: TcxTreeListLevelInfo read GetLevelInfo;
property VScrollPage: Integer read GetVScrollPage;
property VScrollPos: Integer read GetVScrollPos;
property VScrollSize: Integer read GetVScrollSize;
property Images: TCustomImageList read GetImages;
property IndicatorWidth: Integer read GetIndicatorWidth;
property LastNode: TcxTreeListNode read GetLastNode write SetLastNode;
property MultiRows: Boolean read FMultiRows;
property NodesHeight: Integer read FNodesHeight;
property NodesViewData: TcxObjectList read FNodesViewData;
property NodesVisibleCount: Integer read FNodesVisibleCount;
property NodeViewData[Index: Integer]: TcxTreeListNodeViewData read GetNodeViewData;
property OptionsView: TcxTreeListOptionsView read GetOptionsView;
property OriginalViewInfo: TcxTreeListViewInfo read GetOriginalViewInfo;
property Painter: TcxCustomLookAndFeelPainterClass read GetPainter;
property Preview: TcxTreeListPreview read GetPreview;
property PreviewLineHeight: Integer read FPreviewLineHeight;
property Root: TcxTreeListNode read GetRoot;
property Summary: TcxTreeListSummary read GetSummary;
property StateImages: TCustomImageList read GetStateImages;
property Styles: TcxTreeListStyles read GetStyles;
property TopNode: TcxTreeListNode read GetTopNode;
property TreeList: TcxCustomTreeList read GetTreeList;
property TreeLineColor: TColor read FTreeLineColor;
end;
{ TcxTreeListPainter }
TcxTreeListPainter = class(TcxCustomControlPainter)
private
FChanged: Boolean;
FCustomDrawSupported: Boolean;
function GetCells: TcxCustomControlCells;
function GetTreeList: TcxCustomTreeList;
function GetViewInfo: TcxTreeListViewInfo;
protected
procedure DoPaint; override;
procedure CheckBuffer(AWidth, AHeight: Integer);
procedure CheckCustomDrawSupport; virtual;
procedure CheckDirty;
procedure CustomDrawCell(ACanvas: TcxCanvas;
ACell: TcxCustomViewInfoItem; var ADone: Boolean); virtual;
procedure SetBuffered(Value: Boolean); override;
public
constructor Create(AOwner: TcxEditingControl); override;
procedure Paint; override;
procedure CheckSize(const AWidth, AHeight: Integer);
property Cells: TcxCustomControlCells read GetCells;
property Changed: Boolean read FChanged write FChanged;
property CustomDrawSupported: Boolean read FCustomDrawSupported write FCustomDrawSupported;
property TreeList: TcxCustomTreeList read GetTreeList;
property ViewInfo: TcxTreeListViewInfo read GetViewInfo;
end;
{ TcxTreeListBandOptions }
TcxTreeListBandOptions = class(TcxOwnedPersistent)
private
FCustomizing: Boolean;
FHidden: Boolean;
FMoving: Boolean;
FOnlyOwnColumns: Boolean;
FSizing: Boolean;
FVertSizing: Boolean;
procedure SetSizing(AValue: Boolean);
procedure SetVertSizing(AValue: Boolean);
protected
procedure Changed; virtual;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
procedure RestoreDefaults; virtual;
published
property Customizing: Boolean read FCustomizing write FCustomizing default True;
property Hidden: Boolean read FHidden write FHidden default False;
property Moving: Boolean read FMoving write FMoving default True;
property OnlyOwnColumns: Boolean read FOnlyOwnColumns write FOnlyOwnColumns default False;
property Sizing: Boolean read FSizing write SetSizing default True;
property VertSizing: Boolean read FVertSizing write SetVertSizing default True;
end;
TcxTreeListBandOptionsClass = class of TcxTreeListBandOptions;
{ TcxTreeListBandStyles }
TcxTreeListBandStyles = class(TcxStyles)
private
function GetBand: TcxTreeListBand;
function GetTreeList: TcxCustomTreeList;
protected
procedure Changed(AIndex: Integer); override;
procedure DoGetContentParams(ANode: TcxTreeListNode; AColumn: TcxTreeListColumn; var AParams: TcxViewParams); virtual;
procedure GetDefaultViewParams(Index: Integer; AData: TObject; out AParams: TcxViewParams); override;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
function GetContentParams(ANode: TcxTreeListNode; AColumn: TcxTreeListColumn): TcxViewParams;
property Band: TcxTreeListBand read GetBand;
property TreeList: TcxCustomTreeList read GetTreeList;
published
property Content: TcxStyle index tlbs_Content read GetValue write SetValue;
property Footer: TcxStyle index tlbs_Footer read GetValue write SetValue;
property Header: TcxStyle index tlbs_Header read GetValue write SetValue;
property HeaderBackground: TcxStyle index tlbs_HeaderBackground read GetValue write SetValue;
end;
{ TcxTreeListBandPosition }
TcxTreeListBandPosition = class(TcxOwnedPersistent)
private
FBandIndex: Integer;
FColIndex: Integer;
FParentBand: TcxTreeListBand;
function GetBand: TcxTreeListBand;
function GetBandIndex: Integer;
function GetColIndex: Integer;
function GetTreeList: TcxCustomTreeList;
function GetVisibleColIndex: Integer;
procedure SetBandIndex(AValue: Integer);
procedure SetColIndex(AValue: Integer);
function IsColIndexStored: Boolean;
function IsLocked: Boolean;
protected
procedure Changed; virtual;
function CheckBandIndex(var AIndex: Integer): Boolean;
function IsPositionChanged: Boolean;
procedure Restore;
procedure Store;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
property Band: TcxTreeListBand read GetBand;
property ParentBand: TcxTreeListBand read FParentBand;
property TreeList: TcxCustomTreeList read GetTreeList;
property VisibleColIndex: Integer read GetVisibleColIndex;
published
property BandIndex: Integer read GetBandIndex write SetBandIndex default -1;
property ColIndex: Integer read GetColIndex write SetColIndex stored IsColIndexStored;
end;
{ TcxTreeListBand }
TcxTreeListBand = class(TcxInterfacedCollectionItem, IUnknown, IcxDragSizing, IcxStoredObject)
private
FBandRows: TcxTreeListBandRows;
FCalculatedWidth: Integer;
FCaption: TcxTreeListCaption;
FChildBands: TList;
FChildVisibleBands: TList;
FColumns: TList;
FExpandable: TcxTreeListBandExpandable;
FFixedKind: TcxTreeListBandFixedKind;
FHasEmptyArea: Boolean;
FHeaderCell: TcxTreeListBandHeaderCellViewInfo;
FLineCount: Integer;
FMinWidth: Integer;
FOptions: TcxTreeListBandOptions;
FPosition: TcxTreeListBandPosition;
FStyles: TcxTreeListBandStyles;
FVisible: Boolean;
FVisibleColumns: TList;
FWidth: Integer;
// IcxStoredObject events
FOnGetStoredProperties: TcxGetStoredPropertiesEvent;
FOnGetStoredPropertyValue: TcxGetStoredPropertyValueEvent;
FOnSetStoredPropertyValue: TcxSetStoredPropertyValueEvent;
function GetActuallyExpandable: Boolean;
function GetActuallyVisible: Boolean;
function GetBands: TcxTreeListBands;
function GetCalculatedWidth: Integer;
function GetColumn(AIndex: Integer): TcxTreeListColumn;
function GetColumnCount: Integer;
function GetChildBand(AIndex: Integer): TcxTreeListBand;
function GetChildBandCount: Integer;
function GetDisplayWidth: Integer;
function GetFirstChildBottomBand: TcxTreeListBand;
function GetHasEmptyArea: Boolean;
function GetIndentWidth: Integer;
function GetIsBottom: Boolean;
function GetIsFirstInGroup: Boolean;
function GetIsLastAsChild: Boolean;
function GetIsLastInGroup: Boolean;
function GetIsLeftMost: Boolean;
function GetIsLoading: Boolean;
function GetIsRightMost: Boolean;
function GetIsRoot: Boolean;
function GetIsWidthFixed: Boolean;
function GetLevel: Integer;
function GetParentBand: TcxTreeListBand;
function GetParentBandWidthAssigned: TcxTreeListBand;
function GetRootIndex: Integer;
function GetRootParentBand: TcxTreeListBand;
function GetTreeList: TcxCustomTreeList;
function GetVisibleIndex: Integer;
function GetVisibleColumn(AIndex: Integer): TcxTreeListColumn;
function GetVisibleColumnCount: Integer;
function GetVisibleRootIndex: Integer;
procedure SetCaption(AValue: TcxTreeListCaption);
procedure SetCalculatedWidth(AValue: Integer);
procedure SetColumn(AIndex: Integer; AValue: TcxTreeListColumn);
procedure SetDisplayWidth(AValue: Integer);
procedure SetExpandable(AValue: TcxTreeListBandExpandable);
procedure SetFixedKind(AValue: TcxTreeListBandFixedKind);
procedure SetMinWidth(AValue: Integer);
procedure SetOptions(AValue: TcxTreeListBandOptions);
procedure SetPosition(AValue: TcxTreeListBandPosition);
procedure SetRootIndex(AValue: Integer);
procedure SetStyles(AValue: TcxTreeListBandStyles);
procedure SetVisible(AValue: Boolean);
procedure SetVisibleColumn(AIndex: Integer; AValue: TcxTreeListColumn);
procedure SetWidth(AValue: Integer);
protected
function ActualMinWidth: Integer;
procedure AdjustSubItems;
procedure AssignChildBandWidths;
procedure AssignColumnsWidth;
procedure AssignWidth;
procedure InitAutoWidthItem(AItem: TcxAutoWidthItem);
function IsBandFixedDuringSizing: Boolean;
function IsOnlyOwnColumns: Boolean;
procedure CalculateLineCount(ACurrentLine: Integer);
function CanDropColumnAt(const APoint: TPoint; out ARowIndex, AColIndex: Integer): Boolean; virtual;
procedure CheckExpandable(var ABand: TcxTreeListBand);
procedure ForceWidth(AValue: Integer);
function GetMaxDeltaWidth: Integer;
function CanMoving: Boolean; virtual;
procedure ChangeCaption(Sender: TObject); virtual;
function GetOptionsClass: TcxTreeListBandOptionsClass; virtual;
procedure AddBand(ABand: TcxTreeListBand);
procedure AddColumn(AColumn: TcxTreeListColumn);
procedure ColumnSizeChanged(AColumn: TcxTreeListColumn);
procedure DeleteColumn(AColumn: TcxTreeListColumn);
procedure LayoutChanged;
procedure MoveBandsToRoot;
procedure MoveColumnsTo(ABand: TcxTreeListBand);
procedure Refresh;
procedure RemoveBand(ABand: TcxTreeListBand);
procedure RemoveChildBands;
procedure RemoveColumns;
procedure SetIndex(Value: Integer); override;
// IcxTreeListDragSizing implementation
function CanSizing(ADirection: TcxDragSizingDirection): Boolean;
function GetSizingBoundsRect(ADirection: TcxDragSizingDirection): TRect; virtual;
function GetSizingIncrement(ADirection: TcxDragSizingDirection): Integer; virtual;
function IsDynamicUpdate: Boolean; virtual;
procedure SetSizeDelta(ADirection: TcxDragSizingDirection; ADelta: Integer); virtual;
// IcxStoredObject
function GetObjectName: string;
function GetProperties(AProperties: TStrings): Boolean; virtual;
function GetPropertyIndex(const AName: string): Integer;
procedure GetPropertyValue(const AName: string; var AValue: Variant); virtual;
procedure SetPropertyValue(const AName: string; const AValue: Variant); virtual;
property CalculatedWidth: Integer read GetCalculatedWidth write SetCalculatedWidth;
property ChildVisibleBands: TList read FChildVisibleBands;
property FirstChildBottomBand: TcxTreeListBand read GetFirstChildBottomBand;
property HasEmptyArea: Boolean read GetHasEmptyArea write FHasEmptyArea;
property HeaderCell: TcxTreeListBandHeaderCellViewInfo read FHeaderCell write FHeaderCell;
property IsFirstInGroup: Boolean read GetIsFirstInGroup;
property IsLastInGroup: Boolean read GetIsLastInGroup;
property IsWidthFixed: Boolean read GetIsWidthFixed;
property ParentBandWidthAssigned: TcxTreeListBand read GetParentBandWidthAssigned;
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyBestFit;
function IndexOf(AChildBand: TcxTreeListBand): Integer;
function HasAsParent(ABand: TcxTreeListBand): Boolean;
procedure MoveBand(ABand: TcxTreeListBand; AColIndex: Integer);
procedure RestoreDefaults; virtual;
procedure RestoreWidths;
property ActuallyExpandable: Boolean read GetActuallyExpandable;
property ActuallyVisible: Boolean read GetActuallyVisible;
property BandRows: TcxTreeListBandRows read FBandRows;
property Bands: TcxTreeListBands read GetBands;
property ChildBandCount: Integer read GetChildBandCount;
property ChildBands[Index: Integer]: TcxTreeListBand read GetChildBand;
property ColumnCount: Integer read GetColumnCount;
property Columns[Index: Integer]: TcxTreeListColumn read GetColumn write SetColumn;
property DisplayWidth: Integer read GetDisplayWidth write SetDisplayWidth;
property IndentWidth: Integer read GetIndentWidth;
property IsBottom: Boolean read GetIsBottom;
property IsLastAsChild: Boolean read GetIsLastAsChild;
property IsLeftMost: Boolean read GetIsLeftMost;
property IsLoading: Boolean read GetIsLoading;
property IsRightMost: Boolean read GetIsRightMost;
property IsRoot: Boolean read GetIsRoot;
property Level: Integer read GetLevel;
property LineCount: Integer read FLineCount;
property ParentBand: TcxTreeListBand read GetParentBand;
property RootIndex: Integer read GetRootIndex write SetRootIndex;
property RootParentBand: TcxTreeListBand read GetRootParentBand;
property TreeList: TcxCustomTreeList read GetTreeList;
property VisibleColumnCount: Integer read GetVisibleColumnCount;
property VisibleColumns[Index: Integer]: TcxTreeListColumn read GetVisibleColumn write SetVisibleColumn;
property VisibleIndex: Integer read GetVisibleIndex;
property VisibleRootIndex: Integer read GetVisibleRootIndex;
property Index;
published
property Caption: TcxTreeListCaption read FCaption write SetCaption;
property Expandable: TcxTreeListBandExpandable read FExpandable write SetExpandable default tlbeDefault;
property FixedKind: TcxTreeListBandFixedKind read FFixedKind write SetFixedKind default tlbfNone;
property MinWidth: Integer read FMinWidth write SetMinWidth default cxTreeListDefMinWidth;
property Options: TcxTreeListBandOptions read FOptions write SetOptions;
property Position: TcxTreeListBandPosition read FPosition write SetPosition;
property Styles: TcxTreeListBandStyles read FStyles write SetStyles;
property Visible: Boolean read FVisible write SetVisible default True;
property Width: Integer read FWidth write SetWidth default 0;
// IcxStoredObject events
property OnGetStoredProperties: TcxGetStoredPropertiesEvent read FOnGetStoredProperties write FOnGetStoredProperties;
property OnGetStoredPropertyValue: TcxGetStoredPropertyValueEvent read FOnGetStoredPropertyValue write FOnGetStoredPropertyValue;
property OnSetStoredPropertyValue: TcxSetStoredPropertyValueEvent read FOnSetStoredPropertyValue write FOnSetStoredPropertyValue;
end;
TcxTreeListBandClass = class of TcxTreeListBand;
{ TcxTreeListBands }
TcxTreeListBands = class(TCollection, {$IFNDEF DELPHI6} IUnknown, {$ENDIF} IcxStoredObject, IcxStoredParent)
private
FBottomItems: TList;
FColumnsLineCount: Integer;
FExpandableBand: TcxTreeListBand;
FLineCount: Integer;
FRootItems: TList;
FTreeList: TcxCustomTreeList;
FVisibleItems: TList;
FVisibleLeftFixedCount: Integer;
FVisibleRightFixedCount: Integer;
FVisibleRootItems: TList;
FVisibleRootLeftFixedCount: Integer;
FVisibleRootRightFixedCount: Integer;
function GetBottomItem(AIndex: Integer): TcxTreeListBand;
function GetBottomItemCount: Integer;
function GetFirstVisibleBand: TcxTreeListBand;
function GetItem(AIndex: Integer): TcxTreeListBand;
function GetLastVisibleBand: TcxTreeListBand;
function GetRootItemCount: Integer;
function GetRootItem(AIndex: Integer): TcxTreeListBand;
function GetVisibleItem(AIndex: Integer): TcxTreeListBand;
function GetVisibleItemCount: Integer;
function GetVisibleRootItem(AIndex: Integer): TcxTreeListBand;
function GetVisibleRootItemCount: Integer;
procedure SetItem(AIndex: Integer; AValue: TcxTreeListBand);
protected
procedure Adjust(ABands: TList = nil; AWidth: Integer = 0); virtual;
procedure AssignColumnsWidth;
procedure AssignRootItemWidths;
function CanExpandableLeftMostOnly: Boolean; virtual;
procedure ClearCalculatedWidths;
function GetFirstVisibleIndex(AFixedKind: TcxTreeListBandFixedKind): Integer;
function GetFirstVisibleRootIndex(AFixedKind: TcxTreeListBandFixedKind): Integer;
function GetLastVisibleIndex(AFixedKind: TcxTreeListBandFixedKind): Integer;
function GetLastVisibleRootIndex(AFixedKind: TcxTreeListBandFixedKind): Integer;
function GetVisibleCountByKind(AFixedKind: TcxTreeListBandFixedKind): Integer;
function GetOwner: TPersistent; override;
procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); override;
function PopulateVisibleChildren(ABand: TcxTreeListBand): Integer;
procedure RefreshInformation;
procedure Update(Item: TCollectionItem); override;
// IInterface
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
// IcxStoredObject }
function GetObjectName: string;
function GetProperties(AProperties: TStrings): Boolean; virtual;
procedure GetPropertyValue(const AName: string; var AValue: Variant); virtual;
procedure SetPropertyValue(const AName: string; const AValue: Variant); virtual;
// IcxStoredParent
function CreateChild(const AObjectName, AClassName: string): TObject; virtual;
procedure DeleteChild(const AObjectName: string; AObject: TObject); virtual;
procedure GetChildren(AChildren: TStringList); virtual;
public
constructor Create(AOwner: TcxCustomTreeList); virtual;
destructor Destroy; override;
procedure Assign(ASource: TPersistent); override;
function Add: TcxTreeListBand;
procedure RestoreDefaults; virtual;
procedure RestoreWidths; virtual;
function VisibleIndexOf(ABand: TcxTreeListBand): Integer;
property BottomItemCount: Integer read GetBottomItemCount;
property BottomItems[Index: Integer]: TcxTreeListBand read GetBottomItem;
property ColumnsLineCount: Integer read FColumnsLineCount;
property ExpandableBand: TcxTreeListBand read FExpandableBand;
property FirstVisible: TcxTreeListBand read GetFirstVisibleBand;
property Items[AIndex: Integer]: TcxTreeListBand read GetItem write SetItem; default;
property LastVisible: TcxTreeListBand read GetLastVisibleBand;
property LineCount: Integer read FLineCount;
property RootItemCount: Integer read GetRootItemCount;
property RootItems[Index: Integer]: TcxTreeListBand read GetRootItem;
property TreeList: TcxCustomTreeList read FTreeList;
property VisibleItemCount: Integer read GetVisibleItemCount;
property VisibleItems[Index: Integer]: TcxTreeListBand read GetVisibleItem;
property VisibleLeftFixedCount: Integer read FVisibleLeftFixedCount;
property VisibleRightFixedCount: Integer read FVisibleRightFixedCount;
property VisibleRootItemCount: Integer read GetVisibleRootItemCount;
property VisibleRootItems[Index: Integer]: TcxTreeListBand read GetVisibleRootItem;
property VisibleRootLeftFixedCount: Integer read FVisibleRootLeftFixedCount;
property VisibleRootRightFixedCount: Integer read FVisibleRootRightFixedCount;
end;
{ TcxTreeListBandRow }
TcxTreeListBandRow = class
private
FBandRows: TcxTreeListBandRows;
FItems: TList;
FLineCount: Integer;
FLineOffset: Integer;
FMinWidth: Integer;
FVisibleItems: TList;
FWidth: Integer;
function GetBand: TcxTreeListBand;
function GetCount: Integer;
function GetFirst: TcxTreeListColumn;
function GetIndex: Integer;
function GetIsFirst: Boolean;
function GetIsLast: Boolean;
function GetItem(AIndex: Integer): TcxTreeListColumn;
function GetVisibleIndex: Integer;
function GetVisibleItem(AIndex: Integer): TcxTreeListColumn;
function GetVisibleItemCount: Integer;
function GetLast: TcxTreeListColumn;
function GetTreeList: TcxCustomTreeList;
protected
procedure AdjustColumns;
procedure AssignColumnsWidth;
procedure CheckEmpty;
procedure Refresh; virtual;
public
constructor Create(AOwner: TcxTreeListBandRows); virtual;
destructor Destroy; override;
function IndexOf(AColumn: TcxTreeListColumn): Integer;
property Band: TcxTreeListBand read GetBand;
property BandRows: TcxTreeListBandRows read FBandRows;
property Count: Integer read GetCount;
property First: TcxTreeListColumn read GetFirst;
property Index: Integer read GetIndex;
property IsFirst: Boolean read GetIsLast;
property IsLast: Boolean read GetIsFirst;
property Items[Index: Integer]: TcxTreeListColumn read GetItem; default;
property Last: TcxTreeListColumn read GetLast;
property LineCount: Integer read FLineCount;
property LineOffset: Integer read FLineOffset;
property MinWidth: Integer read FMinWidth;
property TreeList: TcxCustomTreeList read GetTreeList;
property VisibleIndex: Integer read GetVisibleIndex;
property VisibleItemCount: Integer read GetVisibleItemCount;
property VisibleItems[Index: Integer]: TcxTreeListColumn read GetVisibleItem;
property Width: Integer read FWidth;
end;
{ TcxTreeListBandRows }
TcxTreeListBandRows = class
private
FBand: TcxTreeListBand;
FItems: TcxObjectList;
FLineCount: Integer;
FRowMaxWidth: Integer;
FRowMinWidth: Integer;
FVisibleItems: TList;
function GetCount: Integer;
function GetFirst: TcxTreeListBandRow;
function GetItem(Index: Integer): TcxTreeListBandRow;
function GetItemEx(Index: Integer): TcxTreeListBandRow;
function GetLast: TcxTreeListBandRow;
function GetVisibleItemCount: Integer;
function GetVisibleItem(AIndex: Integer): TcxTreeListBandRow;
protected
function Add: TcxTreeListBandRow;
function CheckRowIndex(ARowIndex: Integer): TcxTreeListBandRow;
procedure CheckRowEmpty(ARowIndex: Integer);
function Insert(AIndex: Integer): TcxTreeListBandRow;
procedure Refresh; virtual;
public
constructor Create(AOwner: TcxTreeListBand); virtual;
destructor Destroy; override;
property Band: TcxTreeListBand read FBand;
property Count: Integer read GetCount;
property First: TcxTreeListBandRow read GetFirst;
property Items[Index: Integer]: TcxTreeListBandRow read GetItem; default;
property Last: TcxTreeListBandRow read GetLast;
property LineCount: Integer read FLineCount;
property RowMaxWidth: Integer read FRowMaxWidth;
property RowMinWidth: Integer read FRowMinWidth;
property VisibleItemCount: Integer read GetVisibleItemCount;
property VisibleItems[Index: Integer]: TcxTreeListBandRow read GetVisibleItem;
end;
{ TcxTreeListOptionsView }
TcxTreeListGroupFootersMode = (tlgfInvisible, tlgfVisibleWhenExpanded, tlgfAlwaysVisible);
TcxTreeListTreeLineStyle = (tllsNone, tllsDot, tllsSolid);
TcxTreeListPaintStyle = (tlpsStandard, tlpsCategorized);
TcxTreeListOptionsView = class(TcxControlOptionsView, IUnknown)
private
FBandLineHeight: Integer;
FBands: Boolean;
FButtons: Boolean;
FCategorizedColumn: TcxTreeListColumn;
FCheckGroups: Boolean;
FColumnAutoWidth: Boolean;
FDropArrowColor: TColor;
FDynamicIndent: Boolean;
FDynamicFocusedStateImages: Boolean;
FExtPaintStyle: Boolean;
FFixedSeparatorColor: TColor;
FFixedSeparatorWidth: Integer;
FFooter: Boolean;
FGridLineColor: TColor;
FGridLines: TcxTreeListGridLines;
FGroupFooters: TcxTreeListGroupFootersMode;
FHeaders: Boolean;
FIndicator: Boolean;
FIndicatorWidth: Integer;
FPaintStyle: TcxTreeListPaintStyle;
FShowRoot: Boolean;
FSimpleCustomizeBox: Boolean;
FTreeLineColor: TColor;
FTreeLineStyle: TcxTreeListTreeLineStyle;
FUseImageIndexForSelected: Boolean;
FUseNodeColorForIndent: Boolean;
function GetIsIndicatorVisible: Boolean;
function GetTreeList: TcxCustomTreeList;
procedure SetBandLineHeight(AValue: Integer);
procedure SetBands(AValue: Boolean);
procedure SetButtons(AValue: Boolean);
procedure SetCategorizedColumn(AValue: TcxTreeListColumn);
procedure SetCheckGroups(AValue: Boolean);
procedure SetColumnAutoWidth(AValue: Boolean);
procedure SetDynamicIndent(AValue: Boolean);
procedure SetDynamicFocusedStateImages(AValue: Boolean);
procedure SetExtPaintStyle(AValue: Boolean);
procedure SetFixedSeparatorColor(AValue: TColor);
procedure SetFixedSeparatorWidth(AValue: Integer);
procedure SetFooter(AValue: Boolean);
procedure SetGridLineColor(AValue: TColor);
procedure SetGridLines(AValue: TcxTreeListGridLines);
procedure SetGroupFooters(AValue: TcxTreeListGroupFootersMode);
procedure SetHeaders(AValue: Boolean);
procedure SetIndicator(AValue: Boolean);
procedure SetIndicatorWidth(AValue: Integer);
procedure SetPaintStyle(AValue: TcxTreeListPaintStyle);
procedure SetShowRoot(AValue: Boolean);
procedure SetSimpleCustomizeBox(AValue: Boolean);
procedure SetTreeLineColor(AValue: TColor);
procedure SetTreeLineStyle(AValue: TcxTreeListTreeLineStyle);
procedure SetUseImageIndexForSelected(AValue: Boolean);
procedure SetUseNodeColorForIndent(AValue: Boolean);
protected
procedure Changed; override;
function GetControl: TObject;
// helper functions
function HorzIncrement: Integer;
function IsCategorizedPaint: Boolean;
function IsExtPaintStyle: Boolean;
function VertIncrement: Integer;
// IUnknown
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
property TreeList: TcxCustomTreeList read GetTreeList;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
function GetCategorizedColumn: TcxTreeListColumn;
procedure RestoreDefaults; virtual;
property IsIndicatorVisible: Boolean read GetIsIndicatorVisible;
published
property BandLineHeight: Integer read FBandLineHeight write SetBandLineHeight default 0;
property Bands: Boolean read FBands write SetBands default False;
property Buttons: Boolean read FButtons write SetButtons default True;
property CategorizedColumn: TcxTreeListColumn read FCategorizedColumn write SetCategorizedColumn;
property ColumnAutoWidth: Boolean read FColumnAutoWidth write SetColumnAutoWidth default False;
property CheckGroups: Boolean read FCheckGroups write SetCheckGroups default False;
property DropArrowColor: TColor read FDropArrowColor write FDropArrowColor default cxTreeListDefDropArrowColor;
property DynamicIndent: Boolean read FDynamicIndent write SetDynamicIndent default False;
property DynamicFocusedStateImages: Boolean read FDynamicFocusedStateImages write SetDynamicFocusedStateImages default False;
property ExtPaintStyle: Boolean read FExtPaintStyle write SetExtPaintStyle default False;
property FixedSeparatorColor: TColor read FFixedSeparatorColor write SetFixedSeparatorColor default clDefault;
property FixedSeparatorWidth: Integer read FFixedSeparatorWidth write SetFixedSeparatorWidth default cxTreeListDefSeparatorWidth;
property Footer: Boolean read FFooter write SetFooter default False;
property GridLineColor: TColor read FGridLineColor write SetGridLineColor default clDefault;
property GridLines: TcxTreeListGridLines read FGridLines write SetGridLines default tlglNone;
property GroupFooters: TcxTreeListGroupFootersMode read FGroupFooters write SetGroupFooters default tlgfInvisible;
property Headers: Boolean read FHeaders write SetHeaders default True;
property Indicator: Boolean read FIndicator write SetIndicator default False;
property IndicatorWidth: Integer read FIndicatorWidth write SetIndicatorWidth default cxTreeListDefIndicatorWidth;
property PaintStyle: TcxTreeListPaintStyle read FPaintStyle write SetPaintStyle default tlpsStandard;
property ShowRoot: Boolean read FShowRoot write SetShowRoot default True;
property SimpleCustomizeBox: Boolean read FSimpleCustomizeBox write SetSimpleCustomizeBox default False;
property TreeLineColor: TColor read FTreeLineColor write SetTreeLineColor default clDefault;
property TreeLineStyle: TcxTreeListTreeLineStyle read FTreeLineStyle write SetTreeLineStyle default tllsDot;
property UseImageIndexForSelected: Boolean read FUseImageIndexForSelected write SetUseImageIndexForSelected default True;
property UseNodeColorForIndent: Boolean read FUseNodeColorForIndent write SetUseNodeColorForIndent default True;
property CellAutoHeight;
property CellEndEllipsis;
property CellTextMaxLineCount;
property ScrollBars;
property ShowEditButtons;
end;
{ TcxTreeListOptionsCustomizing }
TcxTreeListOptionsCustomizing = class(TcxOwnedPersistent)
private
FBandCustomizing: Boolean;
FBandHiding: Boolean;
FBandHorzSizing: Boolean;
FBandMoving: Boolean;
FBandsQuickCustomization: Boolean;
FBandsQuickCustomizationMaxDropDownCount: Integer;
FBandVertSizing: Boolean;
FColumnCustomizing: Boolean;
FColumnHiding: Boolean;
FColumnHorzSizing: Boolean;
FColumnMoving: Boolean;
FColumnsQuickCustomization: Boolean;
FColumnsQuickCustomizationMaxDropDownCount: Integer;
FColumnVertSizing: Boolean;
FDynamicSizing: Boolean;
FNestedBands: Boolean;
FNodeSizing: Boolean;
FRowSizing: Boolean;
function GetTreeList: TcxCustomTreeList;
procedure SetBandCustomizing(AValue: Boolean);
procedure SetBandHiding(AValue: Boolean);
procedure SetBandHorzSizing(AValue: Boolean);
procedure SetBandMoving(AValue: Boolean);
procedure SetBandsQuickCustomization(AValue: Boolean);
procedure SetBandVertSizing(AValue: Boolean);
procedure SetColumnCustomizing(AValue: Boolean);
procedure SetColumnHiding(AValue: Boolean);
procedure SetColumnHorzSizing(AValue: Boolean);
procedure SetColumnMoving(AValue: Boolean);
procedure SetColumnsQuickCustomization(AValue: Boolean);
procedure SetColumnVertSizing(AValue: Boolean);
procedure SetDynamicSizing(AValue: Boolean);
procedure SetNestedBands(AValue: Boolean);
procedure SetNodeSizing(AValue: Boolean);
procedure SetRowSizing(AValue: Boolean);
protected
procedure Changed; virtual;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
property TreeList: TcxCustomTreeList read GetTreeList;
published
property BandCustomizing: Boolean read FBandCustomizing write SetBandCustomizing default True;
property BandHorzSizing: Boolean read FBandHorzSizing write SetBandHorzSizing default True;
property BandHiding: Boolean read FBandHiding write SetBandHiding default False;
property BandMoving: Boolean read FBandMoving write SetBandMoving default True;
property BandsQuickCustomization: Boolean read FBandsQuickCustomization write SetBandsQuickCustomization default False;
property BandsQuickCustomizationMaxDropDownCount: Integer read FBandsQuickCustomizationMaxDropDownCount write FBandsQuickCustomizationMaxDropDownCount default 0;
property BandVertSizing: Boolean read FBandVertSizing write SetBandVertSizing default True;
property ColumnCustomizing: Boolean read FColumnCustomizing write SetColumnCustomizing default True;
property ColumnHiding: Boolean read FColumnHiding write SetColumnHiding default False;
property ColumnHorzSizing: Boolean read FColumnHorzSizing write SetColumnHorzSizing default True;
property ColumnMoving: Boolean read FColumnMoving write SetColumnMoving default True;
property ColumnsQuickCustomization: Boolean read FColumnsQuickCustomization write SetColumnsQuickCustomization default False;
property ColumnsQuickCustomizationMaxDropDownCount: Integer read FColumnsQuickCustomizationMaxDropDownCount write FColumnsQuickCustomizationMaxDropDownCount default 0;
property ColumnVertSizing: Boolean read FColumnVertSizing write SetColumnVertSizing default True;
property DynamicSizing: Boolean read FDynamicSizing write SetDynamicSizing default False;
property NestedBands: Boolean read FNestedBands write SetNestedBands default True;
property NodeSizing: Boolean read FNodeSizing write SetNodeSizing default False;
property RowSizing: Boolean read FRowSizing write SetRowSizing default False;
end;
{ TcxTreeListOptionsSelection }
TcxTreeListOptionsSelection = class(TcxOwnedPersistent)
private
FCellSelect: Boolean;
FHideFocusRect: Boolean;
FHideSelection: Boolean;
FInvertSelect: Boolean;
FMultiSelect: Boolean;
function GetTreeList: TcxCustomTreeList;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
property TreeList: TcxCustomTreeList read GetTreeList;
published
property CellSelect: Boolean read FCellSelect write FCellSelect default True;
property HideFocusRect: Boolean read FHideFocusRect write FHideFocusRect default True;
property HideSelection: Boolean read FHideSelection write FHideSelection default False;
property InvertSelect: Boolean read FInvertSelect write FInvertSelect default True;
property MultiSelect: Boolean read FMultiSelect write FMultiSelect default False;
end;
TcxTreeListOptionsSelectionClass = class of TcxTreeListOptionsSelection;
{ TcxTreeListOptionsBehavior }
TcxTreeListOptionsBehavior = class(TcxControlOptionsBehavior)
private
FAutoDragCopy: Boolean;
FConfirmDelete: Boolean;
FDragCollapse: Boolean;
FDragExpand: Boolean;
FDragFocusing: Boolean;
FExpandOnDblClick: Boolean;
FExpandOnIncSearch: Boolean;
FFooterHints: Boolean;
FHeaderHints: Boolean;
FHotTrack: Boolean;
FMultiSort: Boolean;
FShowHourGlass: Boolean;
FSorting: Boolean;
FWaitExpandingTime: Integer;
function GetChangeDelay: Integer;
function GetIncSearchItem: TcxTreeListColumn;
function GetTreeList: TcxCustomTreeList;
procedure ReadBoolean(AReader: TReader);
procedure SetChangeDelay(AValue: Integer);
procedure SetFooterHints(AValue: Boolean);
procedure SetHeaderHints(AValue: Boolean);
procedure SetIncSearchItem(AValue: TcxTreeListColumn);
protected
procedure DefineProperties(Filer: TFiler); override;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
property TreeList: TcxCustomTreeList read GetTreeList;
published
property AutoDragCopy: Boolean read FAutoDragCopy write FAutoDragCopy default False;
property ChangeDelay: Integer read GetChangeDelay write SetChangeDelay default 0;
property ConfirmDelete: Boolean read FConfirmDelete write FConfirmDelete default True;
property DragCollapse: Boolean read FDragCollapse write FDragCollapse default True;
property DragDropText;
property DragExpand: Boolean read FDragExpand write FDragExpand default True;
property DragFocusing: Boolean read FDragFocusing write FDragFocusing default False;
property ExpandOnDblClick: Boolean read FExpandOnDblClick write FExpandOnDblClick default True;
property ExpandOnIncSearch: Boolean read FExpandOnIncSearch write FExpandOnIncSearch default False;
property FocusCellOnCycle;
property FooterHints: Boolean read FFooterHints write SetFooterHints default False;
property HeaderHints: Boolean read FHeaderHints write SetHeaderHints default False;
property HotTrack: Boolean read FHotTrack write FHotTrack default False;
property IncSearch;
property IncSearchItem: TcxTreeListColumn read GetIncSearchItem write SetIncSearchItem default nil;
property MultiSort: Boolean read FMultiSort write FMultiSort default True;
property ShowHourGlass: Boolean read FShowHourGlass write FShowHourGlass default True;
property Sorting: Boolean read FSorting write FSorting default True;
property WaitForExpandNodeTime: Integer read FWaitExpandingTime write FWaitExpandingTime default 500;
end;
{ TcxTreeListOptionsData }
TcxTreeListOptionsData = class(TcxControlOptionsData)
private
FDeleting: Boolean;
FInserting: Boolean;
FSummaryNullIgnore: Boolean;
function GetAnsiSort: Boolean;
function GetCaseInsensitive: Boolean;
procedure SetAnsiSort(Value: Boolean);
procedure SetCaseInsensitive(Value: Boolean);
procedure SetSummaryNullIgnore(Value: Boolean);
protected
procedure Changed; override;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
published
property AnsiSort: Boolean read GetAnsiSort write SetAnsiSort default False;
property CaseInsensitive: Boolean read GetCaseInsensitive write SetCaseInsensitive default False;
property Deleting: Boolean read FDeleting write FDeleting default True;
property Inserting: Boolean read FInserting write FInserting default False;
property SummaryNullIgnore: Boolean read FSummaryNullIgnore write SetSummaryNullIgnore default False;
end;
{ TcxTreeListPreview }
TcxTreeListPreviewPlace = (tlppBottom, tlppTop);
TcxTreeListPreview = class(TcxOwnedInterfacedPersistent)
private
FAutoHeight: Boolean;
FColumn: TcxTreeListColumn;
FLeftIndent: Integer;
FMaxLineCount: Integer;
FPlace: TcxTreeListPreviewPlace;
FRightIndent: Integer;
FVisible: Boolean;
function GetActive: Boolean;
function GetTreeList: TcxCustomTreeList;
procedure SetAutoHeight(AValue: Boolean);
procedure SetColumn(AValue: TcxTreeListColumn);
procedure SetLeftIndent(AValue: Integer);
procedure SetMaxLineCount(AValue: Integer);
procedure SetPlace(AValue: TcxTreeListPreviewPlace);
procedure SetRightIndent(AValue: Integer);
procedure SetVisible(AValue: Boolean);
protected
procedure Changed; virtual;
function GetControl: TObject;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
property Active: Boolean read GetActive;
property TreeList: TcxCustomTreeList read GetTreeList;
published
property AutoHeight: Boolean read FAutoHeight write SetAutoHeight default True;
property Column: TcxTreeListColumn read FColumn write SetColumn;
property LeftIndent: Integer read FLeftIndent write SetLeftIndent default 5;
property MaxLineCount: Integer read FMaxLineCount write SetMaxLineCount default 3;
property Place: TcxTreeListPreviewPlace read FPlace write SetPlace default tlppBottom;
property RightIndent: Integer read FRightIndent write SetRightIndent default 5;
property Visible: Boolean read FVisible write SetVisible default False;
end;
{ TcxTreeListStyleSheet }
TcxTreeListStyleSheet = class(TcxCustomStyleSheet)
private
function GetStylesValue: TcxTreeListStyles;
procedure SetStylesValue(Value: TcxTreeListStyles);
public
class function GetStylesClass: TcxCustomStylesClass; override;
published
property Styles: TcxTreeListStyles read GetStylesValue write SetStylesValue;
end;
{ TcxTreeListStyles }
TcxTreeListGetBandContentStyleEvent = procedure(Sender: TcxCustomTreeList;
ABand: TcxTreeListBand; ANode: TcxTreeListNode; var AStyle: TcxStyle) of object;
TcxTreeListGetBandStyleEvent = procedure(Sender: TcxCustomTreeList;
ABand: TcxTreeListBand; var AStyle: TcxStyle) of object;
TcxTreeListGetColumnFooterStyleEvent = procedure(Sender: TcxCustomTreeList;
AColumn: TcxTreeListColumn; ANode: TcxTreeListNode; AFooterItem: TcxTreeListSummaryItem; var AStyle: TcxStyle) of object;
TcxTreeListGetColumnStyleEvent = procedure(Sender: TcxCustomTreeList;
AColumn: TcxTreeListColumn; var AStyle: TcxStyle) of object;
TcxTreeListGetContentStyleEvent = procedure(Sender: TcxCustomTreeList;
AColumn: TcxTreeListColumn; ANode: TcxTreeListNode; var AStyle: TcxStyle) of object;
TcxTreeListGetNodeIndentStyleEvent = procedure(Sender: TcxCustomTreeList;
ANode: TcxTreeListNode; ALevel: Integer; var AStyle: TcxStyle) of object;
TcxTreeListGetPreviewStyleEvent = procedure(Sender: TcxCustomTreeList;
ANode: TcxTreeListNode; var AStyle: TcxStyle) of object;
TcxTreeListStyles = class(TcxCustomControlStyles)
private
FOnGetBandBackgroundStyle: TcxTreeListGetBandStyleEvent;
FOnGetBandContentStyle: TcxTreeListGetBandContentStyleEvent;
FOnGetBandHeaderStyle: TcxTreeListGetBandStyleEvent;
FOnGetBandFooterStyle: TcxTreeListGetBandContentStyleEvent;
FOnGetColumnFooterStyle: TcxTreeListGetColumnFooterStyleEvent;
FOnGetColumnHeaderStyle: TcxTreeListGetColumnStyleEvent;
FOnGetContentStyle: TcxTreeListGetContentStyleEvent;
FOnGetHotTrackStyle: TcxTreeListGetContentStyleEvent;
FOnGetNodeIndentStyle: TcxTreeListGetNodeIndentStyleEvent;
FOnGetPreviewStyle: TcxTreeListGetPreviewStyleEvent;
function GetLoolAndFeel: TcxLookAndFeel;
function GetTreeList: TcxCustomTreeList;
protected
procedure DoGetBandBackgroundParams(ABand: TcxTreeListBand; var AParams: TcxViewParams); virtual;
procedure DoGetBandContentParams(ABand: TcxTreeListBand; ANode: TcxTreeListNode; var AParams: TcxViewParams); virtual;
procedure DoGetBandFooterParams(ABand: TcxTreeListBand; ANode: TcxTreeListNode; var AParams: TcxViewParams); virtual;
procedure DoGetBandHeaderParams(ABand: TcxTreeListBand; var AParams: TcxViewParams); virtual;
procedure DoGetColumnFooterParams(AColumn: TcxTreeListColumn; ANode: TcxTreeListNode;
ASummaryItem: TcxTreeListSummaryItem; var AParams: TcxViewParams); virtual;
procedure DoGetColumnHeaderParams(AColumn: TcxTreeListColumn; var AParams: TcxViewParams); virtual;
procedure DoGetContentParams(ANode: TcxTreeListNode; AColumn: TcxTreeListColumn; var AParams: TcxViewParams); virtual;
procedure DoGetNodeContentParams(ANode: TcxTreeListNode; AStyle: TcxStyle; var AParams: TcxViewParams); virtual;
procedure DoGetPreviewParams(ANode: TcxTreeListNode; var AParams: TcxViewParams); virtual;
procedure GetDefaultViewParams(Index: Integer; AData: TObject; out AParams: TcxViewParams); override;
function SelectionFontAssigned: Boolean;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
function GetBandBackgroundParams(ABand: TcxTreeListBand): TcxViewParams;
function GetBandContentParams(ABand: TcxTreeListBand; ANode: TcxTreeListNode): TcxViewParams;
function GetBandFooterParams(ABand: TcxTreeListBand; ANode: TcxTreeListNode): TcxViewParams;
function GetBandHeaderParams(ABand: TcxTreeListBand): TcxViewParams;
function GetColumnFooterParams(AColumn: TcxTreeListColumn;
ANode: TcxTreeListNode; ASummaryItem: TcxTreeListSummaryItem = nil): TcxViewParams;
function GetColumnHeaderParams(AColumn: TcxTreeListColumn): TcxViewParams;
function GetContentParams(ANode: TcxTreeListNode; AColumn: TcxTreeListColumn): TcxViewParams;
function GetFooterParams: TcxViewParams;
function GetIncSearchParams: TcxViewParams;
function GetIndentParams(ANode: TcxTreeListNode; AIndent: Integer): TcxViewParams;
function GetIndicatorParams: TcxViewParams;
function GetPreviewParams(ANode: TcxTreeListNode): TcxViewParams;
property LookAndFeel: TcxLookAndFeel read GetLoolAndFeel;
property TreeList: TcxCustomTreeList read GetTreeList;
published
property BandBackground: TcxStyle index tlsv_BandBackground read GetValue write SetValue;
property BandContent: TcxStyle index tlsv_BandContent read GetValue write SetValue;
property BandHeader: TcxStyle index tlsv_BandHeader read GetValue write SetValue;
property ColumnFooter: TcxStyle index tlsv_ColumnFooter read GetValue write SetValue;
property ColumnHeader: TcxStyle index tlsv_ColumnHeader read GetValue write SetValue;
property ContentEven: TcxStyle index tlsv_ContentEven read GetValue write SetValue;
property ContentOdd: TcxStyle index tlsv_ContentOdd read GetValue write SetValue;
property Footer: TcxStyle index tlsv_Footer read GetValue write SetValue;
property HotTrack: TcxStyle index tlsv_HotTrack read GetValue write SetValue;
property IncSearch: TcxStyle index tlsv_IncSearch read GetValue write SetValue;
property Indicator: TcxStyle index tlsv_Indicator read GetValue write SetValue;
property Preview: TcxStyle index tlsv_Preview read GetValue write SetValue;
property OnGetBandBackgroundStyle: TcxTreeListGetBandStyleEvent read FOnGetBandBackgroundStyle write FOnGetBandBackgroundStyle;
property OnGetBandContentStyle: TcxTreeListGetBandContentStyleEvent read FOnGetBandContentStyle write FOnGetBandContentStyle;
property OnGetBandFooterStyle: TcxTreeListGetBandContentStyleEvent read FOnGetBandFooterStyle write FOnGetBandFooterStyle;
property OnGetBandHeaderStyle: TcxTreeListGetBandStyleEvent read FOnGetBandHeaderStyle write FOnGetBandHeaderStyle;
property OnGetColumnFooterStyle: TcxTreeListGetColumnFooterStyleEvent read FOnGetColumnFooterStyle write FOnGetColumnFooterStyle;
property OnGetColumnHeaderStyle: TcxTreeListGetColumnStyleEvent read FOnGetColumnHeaderStyle write FOnGetColumnHeaderStyle;
property OnGetContentStyle: TcxTreeListGetContentStyleEvent read FOnGetContentStyle write FOnGetContentStyle;
property OnGetHotTrackStyle: TcxTreeListGetContentStyleEvent read FOnGetHotTrackStyle write FOnGetHotTrackStyle;
property OnGetNodeIndentStyle: TcxTreeListGetNodeIndentStyleEvent read FOnGetNodeIndentStyle write FOnGetNodeIndentStyle;
property OnGetPreviewStyle: TcxTreeListGetPreviewStyleEvent read FOnGetPreviewStyle write FOnGetPreviewStyle;
property Background;
property Content;
property Inactive;
property Selection;
property StyleSheet;
end;
{ TcxTreeListItemsCustomizeListBox }
TcxTreeListItemsCustomizeListBox = class(TcxListBox)
private
FHeaders: TcxObjectList;
FTreeList: TcxCustomTreeList;
function GetHeader(AIndex: Integer): TcxTreeListHeaderCellViewInfo;
function GetPainter: TcxCustomLookAndFeelPainterClass;
protected
procedure AddItem(ACaption: TcxTreeListCaption);
function CreateCell: TcxTreeListHeaderCellViewInfo; virtual; abstract;
procedure DblClick; override;
procedure DoDrawItem(AControl: TcxListBox; ACanvas: TcxCanvas;
AIndex: Integer; ARect: TRect; AState: TOwnerDrawState); virtual;
procedure DoDrawItemEx(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
function GetItemHeight(AItem: Integer): Integer; virtual;
function GetOrigin(AHeader: TcxTreeListHeaderCellViewInfo): TPoint;
procedure PopulateItems; virtual; abstract;
procedure MakeItemVisible(AHeader: TcxTreeListHeaderCellViewInfo); virtual; abstract;
procedure MeasureItem(AControl: TcxListBox; Index: Integer; var Height: Integer); virtual;
procedure Paint; override;
procedure RefreshList;
procedure Resize; override;
function StartDragAndDrop(const P: TPoint): Boolean; override;
property Headers[Index: Integer]: TcxTreeListHeaderCellViewInfo read GetHeader;
property Painter: TcxCustomLookAndFeelPainterClass read GetPainter;
public
constructor CreateEx(AOwner: TComponent; ATreeList: TcxCustomTreeList; AParent: TWinControl);
destructor Destroy; override;
property TreeList: TcxCustomTreeList read FTreeList;
end;
TcxTreeListColumnsCustomizeListBox = class(TcxTreeListItemsCustomizeListBox)
protected
function CreateCell: TcxTreeListHeaderCellViewInfo; override;
function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; override;
procedure MakeItemVisible(AHeader: TcxTreeListHeaderCellViewInfo); override;
procedure PopulateItems; override;
end;
TcxTreeListBandsCustomizeListBox = class(TcxTreeListItemsCustomizeListBox)
protected
function CreateCell: TcxTreeListHeaderCellViewInfo; override;
function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; override;
procedure MakeItemVisible(AHeader: TcxTreeListHeaderCellViewInfo); override;
procedure PopulateItems; override;
end;
{ TcxTreeListCustomizationForm }
TcxTreeListCustomizationForm = class(TForm)
private
FDragDropListBox: TcxTreeListItemsCustomizeListBox;
FHookTimer: TcxTimer;
FOwner: TcxTreeListCustomizing;
function GetTreeList: TcxCustomTreeList;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure FinishDragDrop(Sender: TcxTreeListItemsCustomizeListBox);
procedure StartDragDrop(Sender: TcxTreeListItemsCustomizeListBox);
procedure TimerHandler(Sender: TObject);
public
constructor CreateEx(AOwner: TcxTreeListCustomizing);
destructor Destroy; override;
property HookTimer: TcxTimer read FHookTimer;
property Customizing: TcxTreeListCustomizing read FOwner;
property DragDropListBox: TcxTreeListItemsCustomizeListBox read FDragDropListBox;
property TreeList: TcxCustomTreeList read GetTreeList;
end;
{ TcxTreeListCustomizing }
TcxTreeListCustomizing = class(TcxOwnedInterfacedPersistent, IcxTreeListDesigner)
private
FBandListBox: TcxTreeListItemsCustomizeListBox;
FBounds: TRect;
FForm: TcxTreeListCustomizationForm;
FHeaderListBox: TcxTreeListItemsCustomizeListBox;
FIsPositionAssigned: Boolean;
FPageControl: TcxPageControl;
FRowCount: Integer;
FTabSheetBands: TcxTabSheet;
FTabSheetHeaders: TcxTabSheet;
function GetForm: TForm;
function GetIsSimpleMode: Boolean;
function GetPosition: TPoint;
function GetTreeList: TcxCustomTreeList;
function GetVisible: Boolean;
procedure SetPosition(const AValue: TPoint);
procedure SetRowCount(AValue: Integer);
procedure SetVisible(AValue: Boolean);
protected
procedure CalculateSize(var AWidth, AHeight: Integer);
procedure Close(Sender: TObject; var Action: TCloseAction); virtual;
procedure CreateControls; virtual;
procedure CreateCustomizingForm; virtual;
procedure FinishCustomizing(const ABounds: TRect); virtual;
procedure HideCustomizingForm;
procedure SetControlParent(AControl, AParent: TWinControl);
procedure ShowCustomizingForm;
procedure Update; virtual;
// IcxTreeListDesigner
procedure ComponentModified; virtual;
procedure ComponentRemoved(Sender: TObject); virtual;
property BandListBox: TcxTreeListItemsCustomizeListBox read FBandListBox;
property HeaderListBox: TcxTreeListItemsCustomizeListBox read FHeaderListBox;
property SimpleMode: Boolean read GetIsSimpleMode;
public
constructor Create(AOwner: TPersistent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure MakeBandPageVisible;
procedure MakeColumnPageVisible;
function PtInCustomizingBox(const APoint: TPoint): Boolean;
property Form: TForm read GetForm;
property IsPositionAssigned: Boolean read FIsPositionAssigned write FIsPositionAssigned;
property Position: TPoint read GetPosition write SetPosition;
property RowCount: Integer read FRowCount write SetRowCount default 10;
property TreeList: TcxCustomTreeList read GetTreeList;
property Visible: Boolean read GetVisible write SetVisible;
end;
TcxTreeListCustomizingClass = class of TcxTreeListCustomizing;
{ TcxTreeListDataController }
TcxTreeListForEachNodeProc = procedure(ANode: TcxTreeListNode; Data: Pointer) of object;
TcxTreeListDataController = class(TcxControlDataController)
private
FAllocatedRecords: Integer;
FEditingNode: TcxTreeListNode;
FIsValueChanged: Boolean;
FNodesCount: Integer;
function GetHasEditData: Boolean;
function GetRoot: TcxTreeListNode;
function GetTreeList: TcxCustomTreeList;
function GetValueDef(AIndex: Integer): TcxValueDef;
procedure FreeRecordProc(ANode: TcxTreeListNode; AData: Pointer);
procedure InsertValueDef(AColumn: TcxTreeListColumn);
procedure InsertValueDefProc(ANode: TcxTreeListNode; AData: Pointer);
procedure SetEditingNode(AValue: TcxTreeListNode);
procedure SetIsValueChanged(AValue: Boolean);
procedure RemoveValueDef(AColumn: TcxTreeListColumn);
procedure RemoveValueDefProc(ANode: TcxTreeListNode; AData: Pointer);
protected
function Compare(AValueDef: TcxValueDef; AHandle1, AHandle2: Pointer): Integer;
function CopyData(ASource: TcxTreeListNode): Pointer;
procedure DestroyHandles;
procedure ForEachRecord(AProc: TcxTreeListForEachNodeProc; AData: Pointer);
function IsLoading: Boolean; override;
procedure PostRecord; virtual;
procedure PostValues; virtual;
procedure SetNodeData(ASource: Pointer; ADest: TcxTreeListNode);
function StringCompare(const V1, V2: Variant): Integer; virtual;
procedure SyncFocused(ANode: TcxTreeListNode); virtual;
property EditingNode: TcxTreeListNode read FEditingNode write SetEditingNode;
property IsValueChanged: Boolean read FIsValueChanged write SetIsValueChanged;
property TreeList: TcxCustomTreeList read GetTreeList;
property ValueDefs[AIndex: Integer]: TcxValueDef read GetValueDef;
public
constructor Create(AOwner: TComponent); override;
function AddItem(AItem: TObject): TcxCustomDataField; override;
function AllocateRecord: Pointer;
procedure ChangeValueTypeClass(AItemIndex: Integer; AValueTypeClass: TcxValueTypeClass); override;
function CompareNodesByColumns(ANode1, ANode2: TcxTreeListNode; AColumns: TList): Integer; virtual;
procedure FreeNodeRecord(ANode: TcxTreeListNode);
procedure FreeRecord(var ARecord: Pointer);
function GetDisplayText(ARecordIndex, AItemIndex: Integer): string; override;
function GetNodeDisplayText(ANode: TcxTreeListNode; AIndex: Integer): Variant; virtual;
function GetNodeValue(ANode: TcxTreeListNode; AIndex: Integer): Variant; virtual;
function GetValue(ARecordIndex, AItemIndex: Integer): Variant; override;
function GetValueForCompare(ANode: TcxTreeListNode; AField: TcxCustomDataField): Variant;
procedure InitializeNodeFromRecordIndex(ANode: TcxTreeListNode);
procedure InitializeRecordIndexFromNode(ANode: TcxTreeListNode);
procedure Cancel; override;
procedure Edit; override;
procedure Post(AForcePost: Boolean = False); override;
procedure PostEditingData; override;
procedure RemoveItem(AItem: TObject); override;
function SetEditValue(AItemIndex: Integer; const AValue: Variant;
AEditValueSource: TcxDataEditValueSource): Boolean; override;
procedure SetNodeValue(ANode: TcxTreeListNode; AIndex: Integer; const AValue: Variant); virtual;
procedure SetValue(ARecordIndex, AItemIndex: Integer; const Value: Variant); override;
procedure UpdateItemIndexes; override;
property AllocatedRecords: Integer read FAllocatedRecords;
property HasEditData: Boolean read GetHasEditData;
property NodesCount: Integer read FNodesCount;
property Root: TcxTreeListNode read GetRoot;
end;
{ TcxTreeListCustomPopupMenu }
TcxTreeListCustomPopupMenu = class(TcxOwnedPersistent)
private
FPopupMenu: TComponent;
protected
function GetRoot: TComponent; virtual; abstract;
function GetTreeList: TcxCustomTreeList; virtual; abstract;
function Popup(X, Y: Integer): Boolean; virtual;
procedure SetPopupMenu(AValue: TComponent); virtual;
property PopupMenu: TComponent read FPopupMenu write SetPopupMenu;
public
property Root: TComponent read GetRoot;
property TreeList: TcxCustomTreeList read GetTreeList;
end;
{ TcxTreeListCustomBuiltInMenu }
TcxTreeListBuiltInMenuItemType = (tlmitDefault, tlmitChecked, tlmitSubItem);
TcxTreeListCustomBuiltInMenu = class(TcxTreeListCustomPopupMenu)
protected
function CreateMenuItem(AOwner: TComponent; const ACaption: string; ACommand: Integer;
AEnabled: Boolean = True; AItemType: TcxTreeListBuiltInMenuItemType = tlmitDefault;
AChecked: Boolean = False; AImageIndex: Integer = -1; AWithSeparator: Boolean = False;
AInternal: Boolean = True): TComponent; virtual; abstract;
procedure CreatePopupMenu; virtual;
procedure DestroyPopupMenu; virtual;
procedure GetBitmapFromImageList(AImages: TCustomImageList;
AImageIndex: Integer; ABitmap: TBitmap);
function GetImages(AInternal: Boolean): TCustomImageList;
function GetPopupClass: TComponentClass; virtual; abstract;
function GetRoot: TComponent; override;
function GetTreeList: TcxCustomTreeList; override;
procedure Initialize;
procedure MenuItemClickHandler(Sender: TObject); virtual;
public
destructor Destroy; override;
end;
TcxTreeListCustomBuiltInMenuClass = class of TcxTreeListCustomBuiltInMenu;
{ TcxTreeListBuiltInMenu }
TcxTreeListBuiltInMenu = class(TcxTreeListCustomBuiltInMenu)
private
function GetPopupMenu: TPopupMenu;
protected
function CreateMenuItem(AOwner: TComponent; const ACaption: string; ACommand: Integer;
AEnabled: Boolean = True; AItemType: TcxTreeListBuiltInMenuItemType = tlmitDefault;
AChecked: Boolean = False; AImageIndex: Integer = -1; AWithSeparator: Boolean = False;
AInternal: Boolean = True): TComponent; override;
function GetPopupClass: TComponentClass; override;
function GetRoot: TComponent; override;
procedure CreatePopupMenu; override;
public
property PopupMenu: TPopupMenu read GetPopupMenu;
end;
{ TcxTreeListPopupMenu }
TcxTreeListPopupMenuClickEvent = procedure(Sender: TcxCustomTreeList;
AItem: TObject; var AHandled: Boolean) of object;
TcxTreeListPopupMenuPopupEvent = procedure(Sender: TcxCustomTreeList;
AContextMenu: TcxTreeListPopupMenu; var AHandled: Boolean) of object;
TcxTreeListPopupMenu = class(TcxTreeListCustomPopupMenu)
private
FBuiltInMenu: TcxTreeListCustomBuiltInMenu;
FImages: TCustomImageList;
FUseBuiltInMenu: Boolean;
FUserImages: TCustomImageList;
FOnClick: TcxTreeListPopupMenuClickEvent;
FOnPopup: TcxTreeListPopupMenuPopupEvent;
function GetBuiltInMenu: TcxTreeListCustomBuiltInMenu;
function GetImages: TCustomImageList;
procedure SetUseBuiltInMenu(AValue: Boolean);
procedure SetUserImages(AValue: TCustomImageList);
protected
function CreateInternalMenuItem(AOwner: TComponent; const ACaption: string; ACommand: Integer;
AEnabled: Boolean = True; AItemType: TcxTreeListBuiltInMenuItemType = tlmitDefault;
AChecked: Boolean = False; AImageIndex: Integer = -1; AWithSeparator: Boolean = False): TComponent;
procedure CreateItems; virtual;
procedure DoExecute(ACommand: Integer); virtual;
procedure DoMenuItemClick(Sender: TObject);
procedure DoClick(AItem: TObject; var AHandled: Boolean); virtual;
function DoPopup: Boolean; virtual;
function DoShowPopupMenu(const P: TPoint): Boolean; virtual;
function GetResourceImagesCount: Integer; virtual;
function GetResourceImagesNamePrefix: string; virtual;
function GetRoot: TComponent; override;
function GetTreeList: TcxCustomTreeList; override;
procedure InitializeInternalMenu;
function IsPopupSuitable(AHitTest: TcxTreeListHitTest): Boolean; virtual;
procedure LoadResourceImages; virtual;
procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;
function Popup(X, Y: Integer): Boolean; override;
procedure SetPopupMenu(AValue: TComponent); override;
property Images: TCustomImageList read GetImages;
public
constructor Create(AOwner: TPersistent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
function CreateMenuItem(AOwner: TComponent; const ACaption: string; ACommand: Integer;
AEnabled: Boolean = True; AItemType: TcxTreeListBuiltInMenuItemType = tlmitDefault;
AChecked: Boolean = False; AImageIndex: Integer = -1; AWithSeparator: Boolean = False): TComponent;
property BuiltInMenu: TcxTreeListCustomBuiltInMenu read GetBuiltInMenu;
property UserImages: TCustomImageList read FUserImages write SetUserImages;
published
property PopupMenu;
property UseBuiltInMenu: Boolean read FUseBuiltInMenu write SetUseBuiltInMenu default False;
property OnClick: TcxTreeListPopupMenuClickEvent read FOnClick write FOnClick;
property OnPopup: TcxTreeListPopupMenuPopupEvent read FOnPopup write FOnPopup;
end;
TcxTreeListPopupMenuClass = class of TcxTreeListPopupMenu;
{ TcxTreeListFooterPopupMenu }
TcxTreeListFooterPopupMenuItem = (tlfmiSum, tlfmiMin, tlfmiMax, tlfmiAverage,
tlfmiCount, tlfmiNone, tlfmiAllNodes);
TcxTreeListFooterPopupMenuItems = set of TcxTreeListFooterPopupMenuItem;
TcxTreeListFooterPopupMenu = class(TcxTreeListPopupMenu)
private
FItems: TcxTreeListFooterPopupMenuItems;
FSummaryItems: TcxTreeListSummaryItems;
function GetVisibleItemKinds: TcxSummaryKinds;
function IsAllNodes: Boolean;
function IsItemEnabled(AKind: TcxSummaryKind): Boolean;
function IsItemsStored: Boolean;
protected
procedure CreateItems; override;
procedure DoExecute(ACommand: Integer); override;
function GetResourceImagesCount: Integer; override;
function GetResourceImagesNamePrefix: string; override;
function IsPopupSuitable(AHitTest: TcxTreeListHitTest): Boolean; override;
property SummaryItems: TcxTreeListSummaryItems read FSummaryItems;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
published
property Items: TcxTreeListFooterPopupMenuItems read FItems write FItems stored IsItemsStored;
end;
{ TcxTreeListGroupFooterPopupMenu }
TcxTreeListGroupFooterPopupMenu = class(TcxTreeListFooterPopupMenu)
protected
function IsPopupSuitable(AHitTest: TcxTreeListHitTest): Boolean; override;
end;
{ TcxTreeListColumnHeaderPopupMenu }
TcxTreeListColumnHeaderPopupMenuItem = (tlchmiSortAscending, tlchmiSortDescending,
tlchmiClearSorting, tlchmiFooter, tlchmiGroupFooters, tlchmiRemoveThisColumn,
tlchmiFieldChooser, tlchmiHorzAlignment, tlchmiVertAlignment, tlchmiBestFit,
tlchmiBestFitAllColumns);
TcxTreeListColumnHeaderPopupMenuItems = set of TcxTreeListColumnHeaderPopupMenuItem;
TcxTreeListColumnHeaderPopupMenu = class(TcxTreeListPopupMenu)
private
FColumn: TcxTreeListColumn;
FItems: TcxTreeListColumnHeaderPopupMenuItems;
FSeparatorNeeded: Boolean;
procedure CreateAlignmentSubMenus;
function IsItemsStored: Boolean;
function IsSeparatorNeeded: Boolean;
protected
procedure CreateItems; override;
procedure DoExecute(ACommand: Integer); override;
function GetResourceImagesCount: Integer; override;
function GetResourceImagesNamePrefix: string; override;
function IsPopupSuitable(AHitTest: TcxTreeListHitTest): Boolean; override;
property Column: TcxTreeListColumn read FColumn write FColumn;
public
constructor Create(AOwner: TPersistent); override;
procedure Assign(Source: TPersistent); override;
published
property Items: TcxTreeListColumnHeaderPopupMenuItems read FItems write FItems stored IsItemsStored;
end;
{ TcxTreeListPopupMenus }
TcxTreeListPopupMenus = class(TcxOwnedPersistent)
private
FMenus: TObjectList;
FColumnHeaderMenu: TcxTreeListColumnHeaderPopupMenu;
FFooterMenu: TcxTreeListFooterPopupMenu;
FGroupFooterMenu: TcxTreeListGroupFooterPopupMenu;
function GetHitTest: TcxTreeListHitTest;
function GetTreeList: TcxCustomTreeList;
procedure SetColumnHeaderMenu(AValue: TcxTreeListColumnHeaderPopupMenu);
procedure SetFooterMenu(AValue: TcxTreeListFooterPopupMenu);
procedure SetGroupFooterMenu(AValue: TcxTreeListGroupFooterPopupMenu);
protected
procedure CreateMenus;
function DoShowPopupMenu(const P: TPoint): Boolean;
procedure Notification(AComponent: TComponent; Operation: TOperation);
property HitTest: TcxTreeListHitTest read GetHitTest;
public
constructor Create(AOwner: TPersistent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
property TreeList: TcxCustomTreeList read GetTreeList;
published
property ColumnHeaderMenu: TcxTreeListColumnHeaderPopupMenu read FColumnHeaderMenu write SetColumnHeaderMenu;
property FooterMenu: TcxTreeListFooterPopupMenu read FFooterMenu write SetFooterMenu;
property GroupFooterMenu: TcxTreeListGroupFooterPopupMenu read FGroupFooterMenu write SetGroupFooterMenu;
end;
{ TcxTreeListSummary }
TcxTreeListSummary = class
private
FAbsoluteFooterSummaryItems: TList;
FAbsoluteGroupFooterSummaryItems: TList;
FFooterSummaryRowCount: Integer;
FFooterSummaryVisibleCount: Integer;
FGroupFooterSummaryRowCount: Integer;
FGroupFooterSummaryVisibleCount: Integer;
FIsDirty: Boolean;
FTreeList: TcxCustomTreeList;
function GetFooterSummaryCount: Integer;
function GetFooterSummaryItem(AIndex: Integer): TcxTreeListSummaryItem;
function GetFooterSummaryText(ASummaryItem: TcxTreeListSummaryItem): string;
function GetFooterSummaryValue(ASummaryItem: TcxTreeListSummaryItem): Variant;
function GetGroupFooterSummaryCount: Integer;
function GetGroupFooterSummaryItem(AIndex: Integer): TcxTreeListSummaryItem;
function GetGroupFooterSummaryText(ASummaryItem: TcxTreeListSummaryItem; ANode: TcxTreeListNode): string;
function GetGroupFooterSummaryValue(ASummaryItem: TcxTreeListSummaryItem; ANode: TcxTreeListNode): Variant;
function GetRoot: TcxTreeListNode;
procedure SetFooterSummaryValue(ASummaryItem: TcxTreeListSummaryItem; const Value: Variant);
procedure SetGroupFooterSummaryValue(ASummaryItem: TcxTreeListSummaryItem;
ANode: TcxTreeListNode; const Value: Variant);
protected
procedure AddSummaryItems(AAbsoluteSummaryItems: TList; ASummaryItems: TcxTreeListSummaryItems;
AIsVisible: Boolean; var AVisibleCount, AVisibleRowCount: Integer);
procedure Calculate;
procedure CalculateNode(ADestNode, AValueNode: TcxTreeListNode; AItems: TList);
procedure CheckChanges; virtual;
function DoProcessSummaryValue(ANode: TcxTreeListNode; ASummaryItem: TcxTreeListSummaryItem;
var ASummaryValue: Variant; var ASummaryCount: Integer; var AValue: Variant; var ACount: Integer): Boolean;
procedure FinalizeValues(ANode: TcxTreeListNode; AItems: TList);
procedure InitializeValues(ANode: TcxTreeListNode; AItems: TList);
procedure Notification(AComponent: TComponent; Operation: TOperation);
procedure ProcessNode(AParent: TcxTreeListNode);
procedure ProcessSummaryValue(ANode: TcxTreeListNode; ASummaryItem: TcxTreeListSummaryItem;
var ASummaryValue: Variant; var ASummaryCount: Integer);
procedure ProcessSummaryValues(ADestNode, AValueNode: TcxTreeListNode; AItems: TList);
property IsDirty: Boolean read FIsDirty write FIsDirty;
property Root: TcxTreeListNode read GetRoot;
public
constructor Create(ATreeList: TcxCustomTreeList); virtual;
destructor Destroy; override;
procedure Recalculate;
property FooterSummaryCount: Integer read GetFooterSummaryCount;
property FooterSummaryRowCount: Integer read FFooterSummaryRowCount;
property FooterSummaryVisibleCount: Integer read FFooterSummaryVisibleCount;
property FooterSummaryItems[Index: Integer]: TcxTreeListSummaryItem read GetFooterSummaryItem;
property FooterSummaryTexts[ASummaryItem: TcxTreeListSummaryItem]: string read GetFooterSummaryText;
property FooterSummaryValues[ASummaryItem: TcxTreeListSummaryItem]: Variant
read GetFooterSummaryValue write SetFooterSummaryValue;
property GroupFooterSummaryCount: Integer read GetGroupFooterSummaryCount;
property GroupFooterSummaryRowCount: Integer read FGroupFooterSummaryRowCount;
property GroupFooterSummaryVisibleCount: Integer read FGroupFooterSummaryVisibleCount;
property GroupFooterSummaryItems[Index: Integer]: TcxTreeListSummaryItem read GetGroupFooterSummaryItem;
property GroupFooterSummaryTexts[ASummaryItem: TcxTreeListSummaryItem; ANode: TcxTreeListNode]: string read GetGroupFooterSummaryText;
property GroupFooterSummaryValues[ASummaryItem: TcxTreeListSummaryItem; ANode: TcxTreeListNode]: Variant
read GetGroupFooterSummaryValue write SetGroupFooterSummaryValue;
property TreeList: TcxCustomTreeList read FTreeList;
end;
TcxTreeListSummaryClass = class of TcxTreeListSummary;
{ TcxTreeListLevelInfo }
TcxTreeListLevelInfo = class
private
FImages: TCustomImageList;
FImagesChangeLink: TChangeLink;
FOffset: Integer;
FSize: TSize;
FStateImages: TCustomImageList;
FStateImagesChangeLink: TChangeLink;
FTreeList: TcxCustomTreeList;
FWidth: Integer;
function GetTotalWidth: Integer;
function GetDynamicIndent: Boolean;
procedure SetImages(AValue: TCustomImageList);
procedure SetStateImages(AValue: TCustomImageList);
protected
procedure Changed(Sender: TObject);
procedure Notification(AComponent: TComponent; Operation: TOperation);
function Update(const AOffset: Integer): Integer;
public
constructor Create(ATreeList: TcxCustomTreeList);
destructor Destroy; override;
property DynamicIndent: Boolean read GetDynamicIndent;
property Images: TCustomImageList read FImages write SetImages;
property Offset: Integer read FOffset write FOffset;
property Size: TSize read FSize;
property StateImages: TCustomImageList read FStateImages write SetStateImages;
property TotalWidth: Integer read GetTotalWidth;
property TreeList: TcxCustomTreeList read FTreeList;
property Width: Integer read FWidth;
end;
{ TcxTreeListLikeParams }
TcxTreeListLikeParams = class
private
FPercent: Char;
FUnderline: Char;
public
constructor Create(APercent: Char = '%'; AUnderline: Char = '_');
property Percent: Char read FPercent write FPercent;
property UnderLine: Char read FUnderline write FUnderline;
end;
{ TcxCustomTreeList }
TcxTreeListNodeChangedEvent = procedure(
Sender: TcxCustomTreeList; ANode: TcxTreeListNode) of object;
TcxTreeListNodeCheckChangedEvent = procedure(
Sender: TcxCustomTreeList; ANode: TcxTreeListNode; AState: TcxCheckBoxState) of object;
TcxTreeListNodeChangingEvent = procedure(
Sender: TcxCustomTreeList; ANode: TcxTreeListNode; var Allow: Boolean) of object;
TcxTreeListColumnChangedEvent = procedure(
Sender: TcxCustomTreeList; AColumn: TcxTreeListColumn) of object;
TcxTreeListBandChangedEvent = procedure(
Sender: TcxCustomTreeList; ABand: TcxTreeListBand) of object;
TcxTreeListMoveToEvent = procedure(Sender: TcxCustomTreeList; AttachNode: TcxTreeListNode;
AttachMode: TcxTreeListNodeAttachMode; Nodes: TList; var IsCopy, Done: Boolean) of object;
TcxTreeListNodeCompareEvent = procedure(Sender: TcxCustomTreeList;
ANode1, ANode2: TcxTreeListNode; var ACompare: Integer) of object;
TcxTreeListFocusedNodeChangedEvent = procedure(Sender: TcxCustomTreeList;
APrevFocusedNode, AFocusedNode: TcxTreeListNode) of object;
TcxTreeListGetCellHintEvent = procedure(Sender: TcxCustomTreeList; ACell: TObject;
var AText: string; var ANeedShow: Boolean) of object;
TcxTreeListGetLevelImagesEvent = procedure(Sender: TcxCustomTreeList; ALevel: Integer;
var AImages, AStateImages: TCustomImageList) of object;
TcxTreeListGetNodeImageIndexEvent = procedure(Sender: TcxCustomTreeList;
ANode: TcxTreeListNode; AIndexType: TcxTreeListImageIndexType; var AIndex: TImageIndex) of object;
TcxTreeListGetNodeHeightEvent = procedure(Sender: TcxCustomTreeList;
ANode: TcxTreeListNode; var AHeight: Integer) of object;
TcxTreeListGetPreviewTextEvent = procedure(Sender: TcxCustomTreeList;
ANode: TcxTreeListNode; var AText: string) of object;
TcxTreeListGetNodePreviewHeightEvent = procedure(Sender: TcxCustomTreeList;
ANode: TcxTreeListNode; const ADisplayValue: Variant; var AHeight: Integer) of object;
TcxTreeListIsGroupNodeEvent = procedure(Sender: TcxCustomTreeList;
ANode: TcxTreeListNode; var IsGroup: Boolean) of object;
TcxTreeListEditingEvent = procedure(Sender: TcxCustomTreeList;
AColumn: TcxTreeListColumn; var Allow: Boolean) of object;
TcxTreeListFocusedColumnChanged = procedure(Sender: TcxCustomTreeList;
APrevFocusedColumn, AFocusedColumn: TcxTreeListColumn) of object;
TcxTreeListHotTrackNodeEvent = procedure(Sender: TcxCustomTreeList; ANode: TcxTreeListNode;
AShift: TShiftState; var ACursor: TCursor) of object;
TcxTreeListNodeDataChangedEvent = procedure(Sender: TcxCustomTreeList;
ANode: TcxTreeListNode; AColumn: TcxTreeListColumn) of object;
TcxTreeListCustomDrawBandCellEvent = procedure(Sender: TcxCustomTreeList;
ACanvas: TcxCanvas; AViewInfo: TcxTreeListBandCellViewInfo; var ADone: Boolean) of object;
TcxTreeListCustomDrawBackgroundCellEvent = procedure(Sender: TcxCustomTreeList;
ACanvas: TcxCanvas; AViewInfo: TcxTreeListCustomCellViewInfo; var ADone: Boolean) of object;
TcxTreeListCustomDrawHeaderCellEvent = procedure(Sender: TcxCustomTreeList;
ACanvas: TcxCanvas; AViewInfo: TcxTreeListHeaderCellViewInfo; var ADone: Boolean) of object;
TcxTreeListCustomDrawEditCellEvent = procedure(Sender: TcxCustomTreeList;
ACanvas: TcxCanvas; AViewInfo: TcxTreeListEditCellViewInfo; var ADone: Boolean) of object;
TcxTreeListCustomDrawIndentCellEvent = procedure(Sender: TcxCustomTreeList;
ACanvas: TcxCanvas; AViewInfo: TcxTreeListIndentCellViewInfo; var ADone: Boolean) of object;
TcxTreeListCustomDrawIndicatorCellEvent = procedure(Sender: TcxCustomTreeList;
ACanvas: TcxCanvas; AViewInfo: TcxTreeListIndicatorCellViewInfo; var ADone: Boolean) of object;
TcxTreeListCustomDrawFooterCellEvent = procedure(Sender: TcxCustomTreeList;
ACanvas: TcxCanvas; AViewInfo: TcxTreeListFooterCellViewInfo; var ADone: Boolean) of object;
TcxTreeListFindMode = (tlfmNormal, tlfmLike, tlfmExact);
//// V5
TcxTreeListSummaryEventArguments = record
Node: TcxTreeListNode;
SummaryItem: TcxTreeListSummaryItem;
end;
TcxTreeListSummaryEventOutArguments = record
Value: Variant;
SummaryValue: Variant;
CountValue: Integer;
Done: Boolean;
end;
TcxTreeListSummaryEvent = procedure(ASender: TcxCustomTreeList;
const Arguments: TcxTreeListSummaryEventArguments;
var OutArguments: TcxTreeListSummaryEventOutArguments) of object;
TcxCustomTreeList = class(TcxExtEditingControl, IcxNavigator, IcxStoredParent,
IcxStoredObject, IcxTreeListDesignTimeOperations, IdxSkinSupport)
private
FAbsoluteItems: TList;
FAbsoluteVisibleItems: TList;
FBands: TcxTreeListBands;
FDefaultLevelInfo: TcxTreeListLevelInfo;
FChanges: TcxTreeListChanges;
FChangesLocked: Boolean;
FCustomizing: TcxTreeListCustomizing;
FDefaultIndentSize: TSize;
FDefaultLayout: Boolean;
FDefaultRowHeight: Integer;
FDelayTimer: TTimer;
FDesigners: TList;
FDragNode: TcxTreeListNode;
FExpansionLevel: Integer;
FIgnoreLoadingStatus: Boolean;
FIsCancelOperation: Boolean;
FIsRestoring: Boolean;
FLevelsInfo: TcxObjectList;
FLockChanges: Boolean;
FNavigatorNotifier: TcxNavigatorControlNotifier;
FNeedSort: Boolean;
FOptionsCustomizing: TcxTreeListOptionsCustomizing;
FOptionsSelection: TcxTreeListOptionsSelection;
FPopupMenus: TcxTreeListPopupMenus;
FPopupMenusEvents: TNotifyEvent;
FPostChanged: Boolean;
FPreview: TcxTreeListPreview;
FRoot: TcxTreeListNode;
FSortedColumns: TList;
FSelectionList: TList;
FStoredCursor: TCursor;
FStylesEvents: TNotifyEvent;
FSummary: TcxTreeListSummary;
FTopVisibleNode: TcxTreeListNode;
FVisibleColumns: TList;
FOnBandHeaderClick: TcxTreeListBandChangedEvent;
FOnBandSizeChanged: TcxTreeListBandChangedEvent;
FOnCanFocusNode: TcxTreeListNodeChangingEvent;
FOnCanSelectNode: TcxTreeListNodeChangingEvent;
FOnChange: TNotifyEvent;
FOnColumnHeaderClick: TcxTreeListColumnChangedEvent;
FOnColumnSizeChanged: TcxTreeListColumnChangedEvent;
FOnCompare: TcxTreeListNodeCompareEvent;
//
FGlassCursorRefCount: Integer;
FOnBeginDragNode: TcxTreeListNodeChangingEvent;
FOnCollapsed: TcxTreeListNodeChangedEvent;
FOnCollapsing: TcxTreeListNodeChangingEvent;
FOnCustomDrawBackgroundCell: TcxTreeListCustomDrawBackgroundCellEvent;
FOnCustomDrawBandCell: TcxTreeListCustomDrawBandCellEvent;
FOnCustomDrawBandHeaderCell: TcxTreeListCustomDrawHeaderCellEvent;
FOnCustomDrawDataCell: TcxTreeListCustomDrawEditCellEvent;
FOnCustomDrawFooterCell: TcxTreeListCustomDrawFooterCellEvent;
FOnCustomDrawHeaderCell: TcxTreeListCustomDrawHeaderCellEvent;
FOnCustomDrawIndentCell: TcxTreeListCustomDrawIndentCellEvent;
FOnCustomDrawIndicatorCell: TcxTreeListCustomDrawIndicatorCellEvent;
FOnCustomDrawPreviewCell: TcxTreeListCustomDrawEditCellEvent;
FOnCustomizationVisibleChanged: TNotifyEvent;
FOnDeletion: TcxTreeListNodeChangedEvent;
FOnExpanded: TcxTreeListNodeChangedEvent;
FOnExpanding: TcxTreeListNodeChangingEvent;
FOnGetLevelImages: TcxTreeListGetLevelImagesEvent;
FOnGetNodeHeight: TcxTreeListGetNodeHeightEvent;
FOnGetNodeImageIndex: TcxTreeListGetNodeImageIndexEvent;
FOnGetNodePreviewHeight: TcxTreeListGetNodePreviewHeightEvent;
// TL5
FOnAfterSummary: TNotifyEvent;
FOnDataChanged: TNotifyEvent;
FOnFocusedColumnChanged: TcxTreeListFocusedColumnChanged;
FOnFocusedNodeChanged: TcxTreeListFocusedNodeChangedEvent;
FOnGetCellHint: TcxTreeListGetCellHintEvent;
// IcxStoredObject events
FOnGetStoredProperties: TcxGetStoredPropertiesEvent;
FOnGetStoredPropertyValue: TcxGetStoredPropertyValueEvent;
FOnInitStoredObject: TcxInitStoredObjectEvent;
FOnSetStoredPropertyValue: TcxSetStoredPropertyValueEvent;
FOnHotTrackNode: TcxTreeListHotTrackNodeEvent;
FOnIsGroupNode: TcxTreeListIsGroupNodeEvent;
FOnLayoutChanged: TNotifyEvent;
FOnMoveTo: TcxTreeListMoveToEvent;
FOnNodeChanged: TcxTreeListNodeDataChangedEvent;
FOnNodeCheckChanged: TcxTreeListNodeCheckChangedEvent;
FOnSelectionChanged: TNotifyEvent;
FOnSorted: TNotifyEvent;
FOnSorting: TNotifyEvent;
FOnSummary: TcxTreeListSummaryEvent;
FOnTopRecordIndexChanged: TNotifyEvent;
function GetAvailableContentWidth: Integer;
function GetAbsoluteCount: Integer;
function GetAbsoluteItem(AIndex: Integer): TcxTreeListNode;
function GetAbsoluteItemsList: TList;
function GetAbsoluteVisibleCount: Integer;
function GetAbsoluteVisibleItem(AIndex: Integer): TcxTreeListNode;
function GetAbsoluteVisibleItemsList: TList;
function GetBands: TcxTreeListBands;
function GetColumn(AIndex: Integer): TcxTreeListColumn;
function GetColumnCount: Integer;
function GetColumnsList: TList;
function GetController: TcxTreeListController;
function GetCount: Integer;
function GetDataController: TcxTreeListDataController;
function GetDefaultRowHeight: Integer;
function GetFocusedColumn: TcxTreeListColumn;
function GetFocusedNode: TcxTreeListNode;
function GetHitTest: TcxTreeListHitTest;
function GetImages: TCustomImageList;
function GetIndentWidth: Integer;
function GetInplaceEditor: TcxCustomEdit;
function GetIsCancelOperation: Boolean;
function GetIsEditing: Boolean;
function GetIsInserting: Boolean;
function GetItem(Index: Integer): TcxTreeListNode;
function GetLastNode: TcxTreeListNode;
function GetLastVisibleNode: TcxTreeListNode;
function GetLevelInfo(ALevel: Integer): TcxTreeListLevelInfo;
function GetNavigatorIsActive: Boolean;
function GetOnEdited: TcxTreeListColumnChangedEvent;
function GetOnEditing: TcxTreeListEditingEvent;
function GetOnEditValueChanged: TcxTreeListColumnChangedEvent;
function GetOptionsBehavior: TcxTreeListOptionsBehavior;
function GetOptionsData: TcxTreeListOptionsData;
function GetOptionsView: TcxTreeListOptionsView;
function GetSearching: Boolean;
function GetSearchingText: string;
function GetSelection(AIndex: Integer): TcxtreeListNode;
function GetSelectionCount: Integer;
function GetSorted: Boolean;
function GetSortedColumnCount: Integer;
function GetSortedColumn(Index: Integer): TcxTreeListColumn;
function GetStateImages: TCustomImageList;
function GetStyles: TcxTreeListStyles;
function GetTopNode: TcxTreeListNode;
function GetTopVisibleNode: TcxTreeListNode;
function GetVisibleCount: Integer;
function GetViewInfo: TcxTreeListViewInfo;
function GetVisibleColumn(AIndex: Integer): TcxTreeListColumn;
function GetVisibleColumnCount: Integer;
procedure SetAbsoluteItem(AIndex: Integer; AValue: TcxTreeListNode);
procedure SetAbsoluteVisibleItem(AIndex: Integer; AValue: TcxTreeListNode);
procedure SetBands(Value: TcxTreeListBands);
procedure SetColumn(AIndex: Integer; Value: TcxTreeListColumn);
procedure SetDefaultRowHeight(AValue: Integer);
procedure SetDefaultLayout(AValue: Boolean);
procedure SetFocusedColumn(AValue: TcxTreeListColumn);
procedure SetFocusedNodeProp(Value: TcxTreeListNode);
procedure SetImages(AValue: TCustomImageList);
procedure SetIsRestoring(AValue: Boolean);
procedure SetLastVisibleNode(AValue: TcxTreeListNode);
procedure SetOnEdited(Value: TcxTreeListColumnChangedEvent);
procedure SetOnEditing(Value: TcxTreeListEditingEvent);
procedure SetOnEditValueChanged(Value: TcxTreeListColumnChangedEvent);
procedure SetOptionsBehavior(Value: TcxTreeListOptionsBehavior);
procedure SetOptionsCustomizing(Value: TcxTreeListOptionsCustomizing);
procedure SetOptionsData(Value: TcxTreeListOptionsData);
procedure SetOptionsSelection(Value: TcxTreeListOptionsSelection);
procedure SetOptionsView(Value: TcxTreeListOptionsView);
procedure SetPopupMenus(Value: TcxTreeListPopupMenus);
procedure SetPreview(Value: TcxTreeListPreview);
procedure SetSearchingText(const Value: string);
procedure SetSorted(Value: Boolean);
procedure SetStateImages(AValue: TCustomImageList);
procedure SetStyles(Value: TcxTreeListStyles);
procedure SetTopVisibleNode(ANode: TcxTreeListNode);
procedure SetVisibleColumn(Index: Integer; AValue: TcxTreeListColumn);
procedure DoChangedTimer(Sender: TObject);
procedure UpdateDesignerForms;
// IcxStoredObject
function GetObjectName: string;
function GetProperties(AProperties: TStrings): Boolean;
procedure GetPropertyValue(const AName: string; var AValue: Variant);
procedure SetPropertyValue(const AName: string; const AValue: Variant);
// IcxStoredParent
function IcxStoredParent.CreateChild = StoredCreateChild;
procedure IcxStoredParent.DeleteChild = StoredDeleteChild;
procedure IcxStoredParent.GetChildren = GetStoredChildren;
// messages
procedure CMDrag(var Message: TCMDrag); message CM_DRAG;
protected
// V5
procedure AddChanges(AChanges: TcxTreeListChanges);
function AddNode(ANode, ARelative: TcxTreeListNode; AData: Pointer;
AttachMode: TcxTreeListNodeAttachMode): TcxTreeListNode; virtual;
function AddNodeInternal(ANode, ARelative: TcxTreeListNode;
AddMethod: TcxTreeListNodeAttachMode): TcxTreeListNode; virtual;
procedure AfterMouseDown(AButton: TMouseButton; X, Y: Integer); override;
procedure AssignData(ASource: TcxCustomTreeList); virtual;
procedure AssignOptions(ASource: TcxCustomTreeList); virtual;
procedure BeforeUpdate; override;
procedure BoundsChanged; override;
procedure CalculateForceIndentWidth;
function CanCompare: Boolean; virtual;
procedure CheckChanges; virtual;
procedure CheckEvents;
procedure CheckLevelsInfo; virtual;
procedure CheckSelectionAndFocused;
procedure CheckSortOrderList;
procedure CheckStructure; virtual;
procedure ClearCalculatedWidths;
procedure ColumnSortOrderChanged(AColumn: TcxTreeListColumn; AShift: TShiftState);
function CreateNode: TcxTreeListNode; virtual;
procedure CreateSubClasses; override;
procedure DestroySubClasses; override;
procedure DoAfterSummary; virtual;
procedure DoBandHeaderClick(ABand: TcxTreeListBand); virtual;
function DoBeginDragNode(ANode: TcxTreeListNode): Boolean;
function DoCanFocusNode(ANode: TcxTreeListNode): Boolean; virtual;
function DoCanNodeCollapse(ANode: TcxTreeListNode): Boolean; virtual;
function DoCanNodeExpand(ANode: TcxTreeListNode): Boolean; virtual;
function DoCanSelectNode(ANode: TcxTreeListNode): Boolean; virtual;
procedure DoChanged(BlockChangedEvent: Boolean = True); virtual;
procedure DoColumnHeaderClick(AColumn: TcxTreeListColumn); virtual;
procedure DoCompare(ANode1, ANode2: TcxTreeListNode; var ACompare: Integer); virtual;
procedure DoCustomizationVisibleChanged; virtual;
procedure DoDataChangedEvent(Sender: TObject); virtual;
procedure DoDeletion(ANode: TcxTreeListNode); virtual;
procedure DoEditValueChanged(AItem: TcxCustomInplaceEditContainer); override;
procedure DoExpand(ANode: TcxTreeListNode); virtual;
procedure DoFocusedItemChanged(APrevFocusedItem, AFocusedItem: TcxCustomInplaceEditContainer); virtual;
procedure DoFocusedNodeChanged(APrevNode, AFocusedNode: TcxTreeListNode); virtual;
procedure DoGetCellHint(ACell: TObject; var AText: string; var ANeedShow: Boolean); override;
procedure DoGetLevelImages(AInfo: TcxTreeListLevelInfo; ALevel: Integer); virtual;
procedure DoGetNodeHeight(ANode: TcxTreeListNode; var AHeight: Integer); virtual;
function DoGetNodeImageIndex(ANode: TcxTreeListNode; AIndex: TcxTreeListImageIndexType): TImageIndex; virtual;
procedure DoGetPreviewHeight(ANode: TcxTreeListNode; var AHeight: Integer); virtual;
procedure DoHotTrackNode(ANode: TcxTreeListNode; AShift: TShiftState; var ACursor: TCursor); virtual;
function DoIsGroupNode(ANode: TcxTreeListNode): Boolean; virtual;
procedure DoLayoutChangedEvent; virtual;
function DoMoveToEvent(AttachNode: TcxTreeListNode;
AttachMode: TcxTreeListNodeAttachMode; Nodes: TList; var IsCopy: Boolean): Boolean; virtual;
procedure DoNodeChanged(ANode: TcxTreeListNode; AColumn: TcxTreeListColumn); virtual;
procedure DoNodeCheckChanged(ANode: TcxTreeListNode; AState: TcxCheckBoxState); virtual;
procedure DoNodeCollapsed(ANode: TcxTreeListNode); virtual;
procedure DoNodeExpanded(ANode: TcxTreeListNode); virtual;
procedure DoSelectAll; virtual;
procedure DoSelectionChanged; virtual;
procedure DoSetNodeFocused(ANode: TcxTreeListNode; AValue: Boolean; Shift: TShiftState = []); virtual;
procedure DoSorted; virtual;
procedure DoSorting; virtual;
procedure DoSortNodes; virtual;
procedure DoStartDrag(var DragObject: TDragObject); override;
procedure DoTopRecordIndexChanged; virtual;
procedure ForceLayoutChanged; virtual;
// used classes
function GetBandItemClass: TcxTreeListBandClass; virtual;
function GetControllerClass: TcxCustomControlControllerClass; override;
function GetControlStylesClass: TcxCustomControlStylesClass; override;
function GetDataControllerClass: TcxCustomDataControllerClass; override;
function GetEditingControllerClass: TcxEditingControllerClass; override;
function GetHitTestControllerClass: TcxHitTestControllerClass; override;
function GetOptionsBehaviorClass: TcxControlOptionsBehaviorClass; override;
function GetOptionsCustomizingClass: TcxTreeListOptionsCustomizingClass; virtual;
function GetOptionsDataClass: TcxControlOptionsDataClass; override;
function GetOptionsSelectionClass: TcxTreeListOptionsSelectionClass; virtual;
function GetOptionsViewClass: TcxControlOptionsViewClass; override;
function GetPainterClass: TcxCustomControlPainterClass; override;
function GetPreviewClass: TcxTreeListPreviewClass; virtual;
function GetRootClass: TcxTreeListNodeClass; virtual;
function GetSummaryClass: TcxTreeListSummaryClass; virtual;
function GetTreeListColumnClass: TcxTreeListColumnClass; virtual;
function GetTreeListCustomizingClass: TcxTreeListCustomizingClass; virtual;
function GetViewInfoClass: TcxCustomControlViewInfoClass; override;
//
function GetCountNodeForBestFit: Integer; virtual;
function GetDefaultColumnContainer: TcxTreeListBand;
function GetSameColumn(AColumn: TcxTreeListColumn): TcxTreeListColumn;
function GetStartNodeForBestFit: TcxTreeListNode; virtual;
function IsLocked: Boolean; override;
function IsTreeListLocked: Boolean; virtual;
procedure ImageChanged;
procedure ImagesChanged(Sender: TObject); virtual;
procedure InternalClearAll;
procedure InternalCopy(ANode, ADestNode: TcxTreeListNode); virtual;
procedure InternalDelete(ANodes: TList);
procedure InternalMove(ANode, ADestNode: TcxTreeListNode; AMode: TcxTreeListNodeAttachMode); virtual;
procedure InvalidateRectEx(const R: TRect; EraseBackground: Boolean); override;
function IsNodeEdited(ANode: TcxTreeListNode): Boolean;
function IsNodeInserting(ANode: TcxTreeListNode): Boolean; virtual;
procedure LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues); override;
procedure RefreshFields; virtual;
procedure SetNodeParent(ANewNode, ANewParent: TcxTreeListNode; AMode: TcxTreeListNodeAddMode);
procedure StructureChanged; virtual;
procedure UpdateFocusedNode(AColumn: TcxTreeListColumn); virtual;
procedure ValidateStates;
procedure BeforeShowingEdit;
function CanMultiSelect: Boolean; virtual;
procedure DoBandSizeChanged(ABand: TcxTreeListBand); virtual;
procedure DoClear; virtual;
procedure DoColumnSizeChanged(AColumn: TcxTreeListColumn); virtual;
function DoCreateColumn: TcxTreeListColumn;
procedure DoDeleteSelection; virtual;
procedure DoDeleteNode(ANode: TcxTreeListNode); virtual;
procedure DoInternalMoveTo(AttachNode: TcxTreeListNode;
AttachMode: TcxTreeListNodeAttachMode; ANodes: TList; IsCopy: Boolean);
procedure DoMoveTo(AttachNode: TcxTreeListNode;
AttachMode: TcxTreeListNodeAttachMode; ANodes: TList; IsCopy: Boolean); virtual;
// doXXXX metods fire OnXXXX events
procedure DoOnBandSizeChanged(ABand: TcxTreeListBand); virtual;
procedure DoOnColumnSizeChanged(AColumn: TcxTreeListColumn); virtual;
//
function DoWriteHeaderToText: string; virtual;
function DoWriteNodeToText(ANode: TcxTreeListNode): string; virtual;
procedure DoWriteToClipboard(AOnlySelected: Boolean); virtual;
function DoWriteToText(AOnlySelected: Boolean; out AText: string): Boolean;
procedure DeleteNodes(AList: TList); virtual;
function GetIsActive: Boolean; virtual;
function GetFixedContentSize: Integer; virtual;
function GetMaxBandWidth(ABand: TcxTreeListBand): Integer;
function GetMouseWheelScrollingKind: TcxMouseWheelScrollingKind; override;
procedure InitInsertingNode(ANode: TcxTreeListNode); virtual;
function InsertNode(ARelative: TcxTreeListNode; IsAppend: Boolean): Boolean; virtual;
procedure MakeNodeVisible(ANode: TcxTreeListNode); virtual;
procedure RestoreCursor;
procedure SetGlassCursor;
procedure SortingStateChanged(AColumn: TcxTreeListColumn; AShift: TShiftState);
// IcxTreeListDesignTimeOperations implementation
function SupportBandColumnEditor: Boolean; virtual;
function SupportItemsEditor: Boolean; virtual;
function SupportCreateAllItems: Boolean; virtual;
procedure CreateAllItems; virtual;
// IcxNavigator
function IcxNavigator.IsActive = GetNavigatorIsActive;
function IcxNavigator.IsEditing = GetIsEditing;
function IcxNavigator.IsBof = IsBof;
function IcxNavigator.IsEof = IsEof;
procedure RefreshNavigatorButtons;
procedure DoAction(AButtonIndex: Integer);
function GetNotifier: TcxNavigatorControlNotifier;
function IsActionSupported(AButtonIndex: Integer): Boolean;
function CanAppend: Boolean;
function CanEdit: Boolean;
function CanDelete: Boolean;
function CanInsert: Boolean;
procedure ClearBookmark;
procedure GotoBookmark;
function HasData: Boolean;
function IsBookmarkAvailable: Boolean;
procedure SaveBookmark;
// updates
// nodes
// procedure DoSetNodeSelected(ANode: TcxTreeListNode; Value: Boolean; Shift: TShiftState = []); virtual;
function GetSelectionsEx: TList;
// sorting
// overrided methods
procedure CheckCreateDesignSelectionHelper; override;
procedure ControlUpdateData(AInfo: TcxUpdateControlInfo); override;
procedure DataChanged; override;
procedure DataLayoutChanged; override;
procedure DoLayoutChanged; override;
function DoShowPopupMenu(AMenu: TComponent; X, Y: Integer): Boolean; override;
function DragDropImageDisplayRect: TRect; override;
procedure DrawDragDropImage(ADragBitmap: TBitmap; ACanvas: TcxCanvas); override;
function GetDragDropText: string; virtual;
function GetDragDropViewParams: TcxViewParams; virtual;
function GetDragObjectClass: TDragControlObjectClass; override;
procedure InitScrollBarsParameters; override;
// inherits for loading bug fixing
procedure AssignItemsPosition;
procedure ReadState(Reader: TReader); override;
procedure SaveItemsPosition;
procedure Updated; override;
procedure Updating; override;
// cxStorage implementation
procedure GetStoredChildren(AChildren: TStringList); virtual;
function GetStoredObjectName: string; virtual;
function GetStoredObjectProperties(AProperties: TStrings): Boolean; virtual;
procedure GetStoredPropertyValue(const AName: string; var AValue: Variant); virtual;
procedure SetStoredPropertyValue(const AName: string; const AValue: Variant); virtual;
function StoredCreateChild(const AObjectName, AClassName: string): TObject; virtual;
procedure StoredDeleteChild(const AObjectName: string; AObject: TObject); virtual;
// standart control metods
{$IFNDEF DELPHI12}
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
{$ENDIF}
function IsUpdating: Boolean;
procedure Loaded; override;
procedure Modified; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure SetName(const NewName: TComponentName); override;
property AbsoluteItemsList: TList read GetAbsoluteItemsList;
property AbsoluteVisibleItemsList: TList read GetAbsoluteVisibleItemsList;
property AvailableContentWidth: Integer read GetAvailableContentWidth;
property ChangeDelayTimer: TTimer read FDelayTimer;
property Changes: TcxTreeListChanges read FChanges write FChanges;
property ChangesLocked: Boolean read FChangesLocked write FChangesLocked;
property ColumnsList: TList read GetColumnsList;
property Controller: TcxTreeListController read GetController;
property DataController: TcxTreeListDataController read GetDataController;
property IgnoreLoadingStatus: Boolean read FIgnoreLoadingStatus write FIgnoreLoadingStatus;
property IsCancelOperation: Boolean read GetIsCancelOperation write FIsCancelOperation;
property IndentWidth: Integer read GetIndentWidth;
property IsRestoring: Boolean read FIsRestoring write SetIsRestoring;
property LockChanges: Boolean read FLockChanges write FLockChanges;
property LevelsInfo[ALevel: Integer]: TcxTreeListLevelInfo read GetLevelInfo;
property StoredCursor: TCursor read FStoredCursor;
property ViewInfo: TcxTreeListViewInfo read GetViewInfo;
property OnAfterSummary: TNotifyEvent read FOnAfterSummary write FOnAfterSummary;
property OnBandHeaderClick: TcxTreeListBandChangedEvent read FOnBandHeaderClick write FOnBandHeaderClick;
property OnBandSizeChanged: TcxTreeListBandChangedEvent read FOnBandSizeChanged write FOnBandSizeChanged;
property OnBeginDragNode: TcxTreeListNodeChangingEvent read FOnBeginDragNode write FOnBeginDragNode;
property OnCanFocusNode: TcxTreeListNodeChangingEvent read FOnCanFocusNode write FOnCanFocusNode;
property OnCanSelectNode: TcxTreeListNodeChangingEvent read FOnCanSelectNode write FOnCanSelectNode;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnCollapsed: TcxTreeListNodeChangedEvent read FOnCollapsed write FOnCollapsed;
property OnCollapsing: TcxTreeListNodeChangingEvent read FOnCollapsing write FOnCollapsing;
property OnColumnHeaderClick: TcxTreeListColumnChangedEvent read FOnColumnHeaderClick write FOnColumnHeaderClick;
property OnColumnSizeChanged: TcxTreeListColumnChangedEvent read FOnColumnSizeChanged write FOnColumnSizeChanged;
property OnCompare: TcxTreeListNodeCompareEvent read FOnCompare write FOnCompare;
property OnCustomDrawBackgroundCell: TcxTreeListCustomDrawBackgroundCellEvent read FOnCustomDrawBackgroundCell write FOnCustomDrawBackgroundCell;
property OnCustomDrawBandCell: TcxTreeListCustomDrawBandCellEvent read FOnCustomDrawBandCell write FOnCustomDrawBandCell;
property OnCustomDrawBandHeaderCell: TcxTreeListCustomDrawHeaderCellEvent read FOnCustomDrawBandHeaderCell write FOnCustomDrawBandHeaderCell;
property OnCustomDrawDataCell: TcxTreeListCustomDrawEditCellEvent read FOnCustomDrawDataCell write FOnCustomDrawDataCell;
property OnCustomDrawFooterCell: TcxTreeListCustomDrawFooterCellEvent read FOnCustomDrawFooterCell write FOnCustomDrawFooterCell;
property OnCustomDrawHeaderCell: TcxTreeListCustomDrawHeaderCellEvent read FOnCustomDrawHeaderCell write FOnCustomDrawHeaderCell;
property OnCustomDrawIndentCell: TcxTreeListCustomDrawIndentCellEvent read FOnCustomDrawIndentCell write FOnCustomDrawIndentCell;
property OnCustomDrawIndicatorCell: TcxTreeListCustomDrawIndicatorCellEvent read FOnCustomDrawIndicatorCell write FOnCustomDrawIndicatorCell;
property OnCustomDrawPreviewCell: TcxTreeListCustomDrawEditCellEvent read FOnCustomDrawPreviewCell write FOnCustomDrawPreviewCell;
property OnCustomizationFormVisibleChanged: TNotifyEvent read FOnCustomizationVisibleChanged write FOnCustomizationVisibleChanged;
property OnDeletion: TcxTreeListNodeChangedEvent read FOnDeletion write FOnDeletion;
property OnExpanded: TcxTreeListNodeChangedEvent read FOnExpanded write FOnExpanded;
property OnExpanding: TcxTreeListNodeChangingEvent read FOnExpanding write FOnExpanding;
property OnGetCellHint: TcxTreeListGetCellHintEvent read FOnGetCellHint write FOnGetCellHint;
property OnGetLevelImages: TcxTreeListGetLevelImagesEvent read FOnGetLevelImages write FOnGetLevelImages;
property OnGetNodeHeight: TcxTreeListGetNodeHeightEvent read FOnGetNodeHeight write FOnGetNodeHeight;
property OnGetNodeImageIndex: TcxTreeListGetNodeImageIndexEvent read FOnGetNodeImageIndex write FOnGetNodeImageIndex;
property OnGetNodePreviewHeight: TcxTreeListGetNodePreviewHeightEvent read FOnGetNodePreviewHeight write FOnGetNodePreviewHeight;
property OnHotTrackNode: TcxTreeListHotTrackNodeEvent read FOnHotTrackNode write FOnHotTrackNode;
property OnIsGroupNode: TcxTreeListIsGroupNodeEvent read FOnIsGroupNode write FOnIsGroupNode;
property OnMoveTo: TcxTreeListMoveToEvent read FOnMoveTo write FOnMoveTo;
property OnNodeChanged: TcxTreeListNodeDataChangedEvent read FOnNodeChanged write FOnNodeChanged;
property OnNodeCheckChanged: TcxTreeListNodeCheckChangedEvent read FOnNodeCheckChanged write FOnNodeCheckChanged;
property OnSelectionChanged: TNotifyEvent read FOnSelectionChanged write FOnSelectionChanged;
property OnSorted: TNotifyEvent read FOnSorted write FOnSorted;
property OnSorting: TNotifyEvent read FOnSorting write FOnSorting;
property OnSummary: TcxTreeListSummaryEvent read FOnSummary write FOnSummary;
property OnTopRecordIndexChanged: TNotifyEvent read FOnTopRecordIndexChanged write FOnTopRecordIndexChanged;
property PopupMenusEvents: TNotifyEvent read FPopupMenusEvents write FPopupMenusEvents;
property StylesEvents: TNotifyEvent read FStylesEvents write FStylesEvents;
//
property OnDataChanged: TNotifyEvent read FOnDataChanged write FOnDataChanged;
property OnEdited: TcxTreeListColumnChangedEvent read GetOnEdited write SetOnEdited;
property OnEditing: TcxTreeListEditingEvent read GetOnEditing write SetOnEditing;
property OnEditValueChanged: TcxTreeListColumnChangedEvent read GetOnEditValueChanged write SetOnEditValueChanged;
property OnFocusedColumnChanged: TcxTreeListFocusedColumnChanged read FOnFocusedColumnChanged write FOnFocusedColumnChanged;
property OnFocusedNodeChanged: TcxTreeListFocusedNodeChangedEvent read FOnFocusedNodeChanged write FOnFocusedNodeChanged;
property OnLayoutChanged: TNotifyEvent read FOnLayoutChanged write FOnLayoutChanged;
// IcxStoredObject events
property OnGetStoredProperties: TcxGetStoredPropertiesEvent read FOnGetStoredProperties write FOnGetStoredProperties;
property OnGetStoredPropertyValue: TcxGetStoredPropertyValueEvent read FOnGetStoredPropertyValue write FOnGetStoredPropertyValue;
property OnInitStoredObject: TcxInitStoredObjectEvent read FOnInitStoredObject write FOnInitStoredObject;
property OnSetStoredPropertyValue: TcxSetStoredPropertyValueEvent read FOnSetStoredPropertyValue write FOnSetStoredPropertyValue;
//
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure AdjustColumnsWidth;
procedure ApplyBestFit;
procedure Cancel;
procedure Clear;
function CreateColumn(ABand: TcxTreeListBand = nil): TcxTreeListColumn; virtual;
procedure DeleteAllColumns; virtual;
procedure DeleteSelection;
procedure DragDrop(Source: TObject; X, Y: Integer); override;
procedure Edit;
{$IFDEF DELPHI12}
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
{$ENDIF}
procedure MakeDefaultLayout; virtual;
procedure Post;
procedure FullCollapse;
procedure FullExpand;
procedure FullRefresh; virtual;
function Find(AData: Pointer; AStart: TcxTreeListNode; AExpandedOnly, AForward: Boolean;
AFilter: TcxTreeListFindFunc; AIgnoreStartNode: Boolean = False): TcxTreeListNode; virtual;
function FindNodeByText(const AText: string; AColumn: TcxTreeListColumn; AStartNode: TcxTreeListNode = nil;
AExpandedOnly: Boolean = False; AForward: Boolean = True; ACaseSensitive: Boolean = True; AMode: TcxTreeListFindMode = tlfmNormal;
ALikeParams: TcxTreeListLikeParams = nil; AIgnoreStartNode: Boolean = False): TcxTreeListNode;
procedure SelectAll;
procedure Select(Node: TcxTreeListNode; ShiftState: TShiftState = []); overload; virtual;
procedure Select(const ANodes: array of TcxTreeListNode); overload; virtual;
procedure Select(ANodesList: TList); overload; virtual;
procedure SetFocusedNode(ANode: TcxTreeListNode; AShift: TShiftState);
function StartDrag(DragObject: TDragObject): Boolean; override;
procedure Subselect(Node: TcxTreeListNode); virtual;
procedure Deselect(Node: TcxTreeListNode); virtual;
procedure ClearSelection(KeepPrimary: Boolean = False); virtual;
procedure ClearSorting;
function ColumnByName(const AName: string): TcxTreeListColumn;
function GetSelections(AList: TList): TcxTreeListNode;
// navigation
procedure GotoBOF;
procedure GotoEOF;
procedure GotoNext;
procedure GotoNextPage;
procedure GotoPrev;
procedure GotoPrevPage;
function IsBOF: Boolean;
function IsEOF: Boolean;
// edit control
procedure CancelEdit;
procedure HideEdit;
procedure ShowEdit;
procedure ShowEditByKey(AKey: Char);
procedure ShowEditByMouse(X, Y: Integer; AShift: TShiftState);
// storing layout
procedure RestoreFromIniFile(const AStorageName: string; AChildrenCreating: Boolean = False;
AChildrenDeleting: Boolean = False);
procedure RestoreFromRegistry(const AStorageName: string; AChildrenCreating: Boolean = False;
AChildrenDeleting: Boolean = False);
procedure RestoreFromStream(AStream: TStream; AChildrenCreating: Boolean = False;
AChildrenDeleting: Boolean = False);
procedure StoreToIniFile(AStorageName: string; AReCreate: Boolean = True);
procedure StoreToRegistry(AStorageName: string; AReCreate: Boolean = True);
procedure StoreToStream(AStream: TStream);
// searching
function FindNext(AForward: Boolean): Boolean;
procedure CancelSearching;
// positions
function CellRect(ANode: TcxTreeListNode; AColumn: TcxTreeListColumn): TRect;
function GetEditRect(ANode: TcxTreeListNode; AColumn: TcxTreeListColumn): TRect;
function GetNodeAt(X, Y: Integer): TcxTreeListNode;
// misc
procedure CopyAllToClipboard;
procedure CopySelectedToClipboard;
procedure RestoreColumnsDefaults;
procedure RestoreColumnsWidths;
property AbsoluteCount: Integer read GetAbsoluteCount;
property AbsoluteItems[Index: Integer]: TcxTreeListNode read GetAbsoluteItem write SetAbsoluteItem;
property AbsoluteVisibleCount: Integer read GetAbsoluteVisibleCount;
property AbsoluteVisibleItems[Index: Integer]: TcxTreeListNode read GetAbsoluteVisibleItem write SetAbsoluteVisibleItem;
property Bands: TcxTreeListBands read GetBands write SetBands;
property ColumnCount: Integer read GetColumnCount;
property Columns[Index: Integer]: TcxTreeListColumn read GetColumn write SetColumn;
property Count: Integer read GetCount;
property Customizing: TcxTreeListCustomizing read FCustomizing write FCustomizing;
property DefaultIndentSize: TSize read FDefaultIndentSize;
property DefaultLayout: Boolean read FDefaultLayout write SetDefaultLayout default False;
property DefaultRowHeight: Integer read GetDefaultRowHeight write SetDefaultRowHeight default 0;
property Designers: TList read FDesigners; // for internal use !
property DragNode: TcxTreeListNode read FDragNode;
property ExpansionLevel: Integer read FExpansionLevel;
property FocusedColumn: TcxTreeListColumn read GetFocusedColumn write SetFocusedColumn;
property FocusedNode: TcxTreeListNode read GetFocusedNode write SetFocusedNodeProp;
property HitTest: TcxTreeListHitTest read GetHitTest;
property Images: TCustomImageList read GetImages write SetImages;
property InplaceEditor: TcxCustomEdit read GetInplaceEditor;
property IsActive: Boolean read GetIsActive;
property IsEditing: Boolean read GetIsEditing;
property IsInserting: Boolean read GetIsInserting;
property Items[Index: Integer]: TcxTreeListNode read GetItem;
property LastNode: TcxTreeListNode read GetLastNode;
property LastVisibleNode: TcxTreeListNode read GetLastVisibleNode write SetLastVisibleNode;
property OptionsBehavior: TcxTreeListOptionsBehavior read GetOptionsBehavior write SetOptionsBehavior;
property OptionsCustomizing: TcxTreeListOptionsCustomizing read FOptionsCustomizing write SetOptionsCustomizing;
property OptionsData: TcxTreeListOptionsData read GetOptionsData write SetOptionsData;
property OptionsSelection: TcxTreeListOptionsSelection read FOptionsSelection write SetOptionsSelection;
property OptionsView: TcxTreeListOptionsView read GetOptionsView write SetOptionsView;
property PopupMenus: TcxTreeListPopupMenus read FPopupMenus write SetPopupMenus;
property Preview: TcxTreeListPreview read FPreview write SetPreview;
property Root: TcxTreeListNode read FRoot;
property Searching: Boolean read GetSearching;
property SearchingText: string read GetSearchingText write SetSearchingText;
property SelectionCount: Integer read GetSelectionCount;
property SelectionList: TList read FSelectionList;
property Selections[Index: Integer]: TcxTreeListNode read GetSelection;
property Sorted: Boolean read GetSorted write SetSorted;
property SortedColumnCount: Integer read GetSortedColumnCount;
property SortedColumns[Index: Integer]: TcxTreeListColumn read GetSortedColumn;
property StateImages: TCustomImageList read GetStateImages write SetStateImages;
property Styles: TcxTreeListStyles read GetStyles write SetStyles;
property Summary: TcxTreeListSummary read FSummary;
property TopNode: TcxTreeListNode read GetTopNode;
property TopVisibleNode: TcxTreeListNode read GetTopVisibleNode write SetTopVisibleNode;
property VisibleColumnCount: Integer read GetVisibleColumnCount;
property VisibleColumns[Index: Integer]: TcxTreeListColumn read GetVisibleColumn write SetVisibleColumn;
property VisibleCount: Integer read GetVisibleCount;
property BorderSize;
property LookAndFeel;
property Color;
published
{ V5 deprecated properties }
property BufferedPaint stored False;
end;
{ TcxTreeList }
TcxTreeList = class(TcxCustomTreeList)
private
FDataStream: TMemoryStream;
function InternalCreateNode(AParent, APrev: TcxTreeListNode;
var AIndex: Integer): TcxTreeListNode;
protected
procedure AssignData(ASource: TcxCustomTreeList); override;
procedure CorrectHandles;
procedure DefineProperties(Filer: TFiler); override;
procedure Loaded; override;
function SupportItemsEditor: Boolean; override;
procedure ReadData(AStream: TStream); virtual;
procedure ReadStructure(AStream: TStream; AVersion: Integer);
procedure WriteData(AStream: TStream); virtual;
procedure WriteStructure(AStream: TStream);
public
function Add: TcxTreeListNode; overload;
function Add(ASibling: TcxTreeListNode; AData: Pointer = nil): TcxTreeListNode; overload;
function AddChild(AParent: TcxTreeListNode; AData: Pointer = nil): TcxTreeListNode;
function AddChildFirst(AParent: TcxTreeListNode; AData: Pointer = nil): TcxTreeListNode;
function AddFirst: TcxTreeListNode; overload;
function AddFirst(ASibling: TcxTreeListNode; AData: Pointer = nil): TcxTreeListNode; overload;
function AddNode(ANode, ARelative: TcxTreeListNode;
AData: Pointer; AttachMode: TcxTreeListNodeAttachMode): TcxTreeListNode; override;
function Insert(ASibling: TcxTreeListNode; AData: Pointer = nil): TcxTreeListNode;
function InsertEx(ANode, ASibling: TcxTreeListNode; AData: Pointer = nil): TcxTreeListNode;
procedure LoadFromFile(const AFileName: string);
procedure LoadFromStream(AStream: TStream);
procedure SaveToFile(const AFileName: string);
procedure SaveToStream(AStream: TStream);
property ColumnCount;
property Columns;
property Customizing;
property FocusedColumn;
property FocusedNode;
property HitTest;
property IsEditing;
property Root;
property SelectionCount;
property Selections;
property Sorted;
property SortedColumnCount;
property SortedColumns;
property TopVisibleNode;
property VisibleColumnCount;
property VisibleColumns;
property VisibleCount;
published
property Align;
property Anchors;
property Bands;
property BorderStyle;
property Constraints;
property Cursor;
property DefaultLayout;
property DefaultRowHeight;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property HelpContext;
property HelpKeyword;
property HelpType;
property Hint;
property Images;
property LookAndFeel;
property OptionsBehavior;
property OptionsCustomizing;
property OptionsData;
property OptionsSelection;
property OptionsView;
property ParentColor;
property ParentFont;
property PopupMenu;
property PopupMenus;
property Preview;
property StateImages;
property Styles;
property TabOrder;
property TabStop;
property Visible;
property OnAfterSummary;
property OnBandHeaderClick;
property OnBandSizeChanged;
property OnBeginDragNode;
property OnCanFocusNode;
property OnCanResize;
property OnCanSelectNode;
property OnChange;
property OnClick;
property OnCollapsed;
property OnCollapsing;
property OnColumnHeaderClick;
property OnColumnSizeChanged;
property OnCompare;
property OnConstrainedResize;
property OnContextPopup;
property OnCustomDrawBackgroundCell;
property OnCustomDrawBandCell;
property OnCustomDrawBandHeaderCell;
property OnCustomDrawDataCell;
property OnCustomDrawFooterCell;
property OnCustomDrawHeaderCell;
property OnCustomDrawIndentCell;
property OnCustomDrawIndicatorCell;
property OnCustomDrawPreviewCell;
property OnCustomizationFormVisibleChanged;
property OnDataChanged;
property OnDblClick;
property OnDeletion;
property OnDockDrop;
property OnDockOver;
property OnDragDrop;
property OnDragOver;
property OnEdited;
property OnEditing;
property OnEditValueChanged;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnExpanded;
property OnExpanding;
property OnFocusedColumnChanged;
property OnFocusedNodeChanged;
property OnGetCellHint;
property OnGetLevelImages;
property OnGetNodeHeight;
property OnGetNodeImageIndex;
property OnGetNodePreviewHeight;
property OnGetSiteInfo;
property OnGetStoredProperties;
property OnGetStoredPropertyValue;
property OnHotTrackNode;
property OnInitEdit;
property OnInitStoredObject;
property OnIsGroupNode;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnLayoutChanged;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnMoveTo;
property OnNodeChanged;
property OnNodeCheckChanged;
property OnResize;
property OnSelectionChanged;
property OnSetStoredPropertyValue;
property OnSorted;
property OnSorting;
property OnStartDock;
property OnStartDrag;
property OnSummary;
property OnTopRecordIndexChanged;
property OnUnDock;
property PopupMenusEvents;
property StylesEvents;
end;
procedure cxTreeListError(const Description: string);
function cxCompareNodesByLevel(ANode1, ANode2: TcxTreeListNode): Integer;
var
cxTreeListBuiltInMenuClass: TcxTreeListCustomBuiltInMenuClass = TcxTreeListBuiltInMenu;
DesignerNavigatorProc: procedure(AListener: TObject; AddListener: Boolean) of object;
implementation
uses Types, RTLConsts, cxLike;
{$R cxTL.res}
const
CRLF = #13#10;
Weights: array[TcxTreeListBandFixedKind] of Integer = (0, -1, 1);
cxTreeListVersion = $00050000;
cxInvalidIndex = -1;
cxMinCapacityInc = 32;
cxMaxCapacityInc = 32768;
cxDefaultImageIndexes: TcxTreeListNodeImageIndexes = (0, 0, -1, -1, -1);
// internal column state
tlcsVisible = $08;
// internal band state
tlbsVisible = $00;
tlbsFixedLeft = $02;
tlbsFixedRight = $04;
tlbsAllFixed = tlbsFixedRight or tlbsFixedLeft;
ColumnPropertiesName: array[0..10] of string =
('Visible', 'Index', 'LineCount', 'ColIndex', 'RowIndex',
'BandIndex', 'Caption', 'SortOrder', 'SortIndex', 'RealMinWidth', 'RealWidth');
BandPropertiesName: array[0..6] of string =
('Caption', 'RealMinWidth', 'RealWidth', 'Visible', 'Index', 'BandIndex', 'ColIndex');
GridLineBorders: array[TcxTreeListGridLines] of TcxBorders =
([], [bTop, bBottom], [bLeft, bRight], cxBordersAll);
OddEvenStyleIndexes: array[Boolean] of Integer =(tlsv_ContentEven, tlsv_ContentOdd);
type
TAllowExpandChangingFunc = function: Boolean of object;
TcxDefColorFunc = function: TColor of object;
TcxTreeListStreamHeader = packed record
Minor, Major: Word;
Size: Integer;
end;
PcxTreeListValueDefData = ^TcxTreeListValueDefData;
TcxTreeListValueDefData = packed record
Index: Integer;
ValueDef: TcxValueDef;
end;
{ TcxFakeCellViewInfo }
TcxFakeCellViewInfo = class(TcxTreeListEditCellViewInfo)
private
function GetTreeListViewInfo: TcxTreeListViewInfo;
protected
FCalcHeight: Boolean;
FColumn: TcxTreeListColumn;
function GetButtonTransparency: TcxEditButtonTransparency; override;
function GetControl: TcxEditingControl; override;
function GetEditContainer: TcxCustomInplaceEditContainer; override;
function GetFocused: Boolean; override;
function GetSelected: Boolean; override;
procedure Initialize(ANode: TcxTreeListNode; AHeight, AWidth: Integer; ACalcHeight: Boolean);
function IsAutoHeight: Boolean; override;
function IsEndEllipsis: Boolean; override;
public
constructor Create(AOwner: TObject); override;
destructor Destroy; override;
function MeasureHeight(AColumn: TcxTreeListColumn;
ANode: TcxTreeListNode; AIsCategory: Boolean): Integer;
function MeasureWidth(AColumn: TcxTreeListColumn; ANode: TcxTreeListNode): Integer;
property TreeListViewInfo: TcxTreeListViewInfo read GetTreeListViewInfo;
end;
{ TcxTreeListCellPos }
TcxTreeListCellPos = class
public
Item: TObject;
Node: TcxTreeListNode;
constructor Create(ANode: TcxTreeListNode; AItem: TObject);
end;
function cxFind(ATreeList: TcxCustomTreeList; AData: Pointer;
AStart: TcxTreeListNode; AExpandedOnly, AForward: Boolean;
AFilter: TcxTreeListFindFunc; AIgnoreStartNode: Boolean): TcxTreeListNode;
function LoadChildren(ANode: TcxTreeListNode): Boolean;
begin
with ANode do
begin
if (FCount = 0) and HasChildren and not Expanded and not AExpandedOnly then
ANode.LoadChildren;
Result := (FCount <> 0) and (Expanded or not AExpandedOnly);
end;
end;
function GetNext(ANode: TcxTreeListNode): TcxTreeListNode;
begin
Result := ANode;
if not LoadChildren(Result) then
while Result <> nil do
begin
if Result.FNext <> nil then
begin
Result := Result.FNext;
Break;
end;
while (Result <> nil) and (Result.FNext = nil) do
Result := Result.Parent;
end
else
Result := Result.FFirst;
end;
function GetPrev(ANode: TcxTreeListNode): TcxTreeListNode;
begin
Result := ANode;
if Result.FPrev <> nil then
begin
Result := Result.FPrev;
while LoadChildren(Result) do Result := Result.FLast;
end
else
begin
Result := Result.Parent;
if Result = ATreeList.Root then
Result := nil;
end;
end;
function GetAnother(ANode: TcxTreeListNode): TcxTreeListNode;
begin
if AForward then
Result := GetNext(ANode)
else
Result := GetPrev(ANode);
end;
var
ACurrent: TcxTreeListNode;
begin
Result := nil;
ACurrent := AStart;
if ACurrent = nil then
ACurrent := ATreeList.Root.FFirst;
ATreeList.BeginUpdate;
try
while (ACurrent <> nil) and (Result = nil) do
begin
if AFilter(ACurrent, AData) then
begin
Result := ACurrent;
if AIgnoreStartNode and (Result = AStart) then
begin
Result := nil;
ACurrent := GetAnother(ACurrent);
end;
end
else
ACurrent := GetAnother(ACurrent);
end;
finally
ATreeList.EndUpdate;
end;
end;
function cxGetLatest(ANode: TcxTreeListNode;
ACheckExpanded: Boolean = True): TcxTreeListNode;
begin
Result := ANode;
if Result <> nil then
begin
if ACheckExpanded then
while (Result.Count > 0) and not (nsCollapsed in Result.State) do
Result := Result.FLast
else
while Result.HasChildren do
begin
Result.LoadChildren;
if Result.Count > 0 then
Result := Result.FLast
else
Break;
end;
end;
end;
function cxExcludeBorders(const ARect: TRect; ABorders: TcxBorders): TRect;
begin
Result := ARect;
with Result do
begin
Inc(Left, Byte(bLeft in ABorders));
Inc(Top, Byte(bTop in ABorders));
Dec(Right, Byte(bRight in ABorders));
Dec(Bottom, Byte(bBottom in ABorders));
end;
end;
function cxGetNativeColor(AColor: TColor; ADefColorFunc: TcxDefColorFunc): TColor;
begin
if AColor = clDefault then
Result := ADefColorFunc
else
Result := AColor;
end;
function cxCompareBandsByPosition(
ABand1, ABand2: TcxTreeListBand): Integer;
begin
Result := ABand1.Position.FBandIndex - ABand2.Position.FBandIndex;
if Result = 0 then
Result := ABand1.Position.FColIndex - ABand2.Position.FColIndex;
if Result = 0 then
Result := ABand1.Index - ABand2.Index;
end;
function cxCompareColumnsByPosition(
AColumn1, AColumn2: TcxTreeListColumn): Integer;
begin
Result := AColumn1.Position.FBandIndex - AColumn2.Position.FBandIndex;
if Result = 0 then
Result := AColumn1.Position.FRowIndex - AColumn2.Position.FRowIndex;
if Result = 0 then
Result := AColumn1.Position.FColIndex - AColumn2.Position.FColIndex;
if Result = 0 then
Result := AColumn1.ItemIndex - AColumn2.ItemIndex;
end;
function cxCompareColumnsBySortIndex(
AColumn1, AColumn2: TcxTreeListColumn): Integer;
begin
if (AColumn2.SortIndex < 0) and (AColumn1.SortIndex >= 0) then
Result := -1
else
Result := AColumn1.SortIndex - AColumn2.SortIndex;
if Result = 0 then
Result := Byte(AColumn1.ActuallyVisible) - Byte(AColumn2.ActuallyVisible);
if Result = 0 then
Result := cxCompareColumnsByPosition(AColumn1, AColumn2);
end;
function cxCompareVisibleBands(AItem1, AItem2: Pointer): Integer;
begin
with TcxTreeListBand(AItem1) do
begin
Result := Weights[FixedKind] - Weights[TcxTreeListBand(AItem2).FixedKind];
if Result = 0 then
Result := Index - TcxTreeListBand(AItem2).Index;
end;
end;
function cxCompareBands(ABand1, ABand2: TcxTreeListBand): Integer;
const
Weight: array[TcxTreeListBandFixedKind] of Integer = (0, -1, 1);
begin
Result := Weight[ABand1.FixedKind] - Weight[ABand2.FixedKind];
if Result = 0 then
Result := ABand1.Index - ABand2.Index;
end;
function cxCompareNodes(ANode1, ANode2: TcxTreeListNode): Integer;
begin
ANode1.TreeList.DoCompare(ANode1, ANode2, Result);
end;
function cxCompareNodesByAbsoluteIndex(
ANode1, ANode2: TcxTreeListNode): Integer;
begin
Result := ANode1.AbsoluteIndex - ANode2.AbsoluteIndex;
end;
function cxCompareNodesByRecordIndex(
ANode1, ANode2: TcxTreeListNode): Integer;
begin
Result := Integer(ANode2.Handle) - Integer(ANode1.Handle);
end;
function cxCompareNodesByLevel(
ANode1, ANode2: TcxTreeListNode): Integer;
begin
Result := ANode2.Level - ANode1.Level;
end;
function cxCompareCells(ACell1, ACell2: TcxCustomViewInfoItem): Integer;
begin
Result := ACell1.CustomDrawID - ACell2.CustomDrawID;
if Result = 0 then
begin
Result := ACell1.BoundsRect.Top - ACell2.BoundsRect.Top;
if Result = 0 then
Result := ACell1.BoundsRect.Left - ACell2.BoundsRect.Left;
end;
end;
function cxCompareHitTestCells(ACell1, ACell2: TcxTreeListHitTestArea): Integer;
begin
if ACell1.Link = ACell2.Link then
Result := ACell1.Area.Top - ACell2.Area.Top
else
Result := cxCompareCells(ACell1.Link, ACell2.Link);
end;
procedure cxValidateSingleLine(APos: TcxTreeListColumnPosition);
begin
APos.FRowIndex := 0;
APos.FLineCount := 1;
end;
procedure cxTreeListError(const Description: string);
begin
raise EcxTreeList.Create(Description);
end;
procedure cxTLUnused;
begin
cxTreeListError('V5 unused');
end;
procedure cxError(Condition: Boolean;
const Description: string; Args: array of const); overload;
begin
if Condition then
raise Exception.CreateFmt(Description, Args);
end;
{ TcxTreeListHitTest }
function TcxTreeListHitTest.CanMoving: Boolean;
begin
Result := not CanSizing and ((HitAtBandHeader and HitBand.CanMoving) or
(HitAtColumnHeader and HitColumn.CanMoving));
end;
function TcxTreeListHitTest.CanSizing: Boolean;
begin
Result := HitAtSizingHorz or HitAtSizingVert;
end;
function TcxTreeListHitTest.AllowDesignMouseEvents(
X, Y: Integer; AShift: TShiftState): Boolean;
begin
Result := not TreeList.IsLocked and (inherited AllowDesignMouseEvents(X, Y, AShift) or
(TreeList.DragAndDropState <> ddsNone) or
HitAtBandHeader or HitAtColumnHeader or HitAtBandCustomizing or
HitAtColumnCustomizing or CanSizing or HitAtButton or
(HitCell is TcxTreeListFooterCellViewInfo) and not TcxTreeListFooterCellViewInfo(HitCell).Hidden);
end;
function TcxTreeListHitTest.CanShowHint(AItem: TObject): Boolean;
begin
if AItem is TcxTreeListHeaderCellViewInfo then
Result := TreeList.OptionsBehavior.HeaderHints
else
if AItem is TcxTreeListFooterCellViewInfo then
Result := TreeList.OptionsBehavior.FooterHints
else
Result := inherited CanShowHint(AItem);
end;
procedure TcxTreeListHitTest.CheckFooterColumn;
var
AColumnRect, R: TRect;
ARow: TcxTreeListBandRow;
AColumn: TcxTreeListColumn;
AColIndex, ARowIndex, AVisibleRowCount: Integer;
begin
if (HitBand = nil) or not (HitTestItem is TcxTreeListBandCellViewInfo) then Exit;
with TcxTreeListBandCellViewInfo(HitTestItem) do
R := cxRectOffset(DisplayRect, GetCellOrigin);
AVisibleRowCount := HitBand.BandRows.VisibleItemCount;
for ARowIndex := AVisibleRowCount - 1 downto 0 do
begin
ARow := HitBand.BandRows.VisibleItems[ARowIndex];
for AColIndex := 0 to ARow.VisibleItemCount - 1 do
begin
AColumn := ARow.VisibleItems[AColIndex];
AColumnRect := AColumn.HeaderCell.DisplayRect;
if cxInRange(HitX, AColumnRect.Left, AColumnRect.Right) and cxInRange(HitY,
R.Top + MulDiv(cxRectHeight(R), ARow.LineOffset, AVisibleRowCount), R.Bottom) then
begin
FHitColumn := AColumn;
SetHitState(tlhc_HitAtColumn, True);
end;
end;
end;
end;
procedure TcxTreeListHitTest.CheckSelection(AShift: TShiftState);
var
AController: TcxTreeListController;
I: Integer;
begin
if not TreeList.IsDesigning then Exit;
AController := TcxTreeListController(Controller);
if HitAtBandHeader then
AController.SelectObject(HitBand, AShift)
else
if HitAtColumnHeader then
AController.SelectObject(HitColumn, AShift)
else
if HitCell is TcxTreeListFooterSingleCellViewInfo then
AController.SelectObject(TcxTreeListFooterSingleCellViewInfo(HitCell).SummaryItem, AShift)
else
if HitCell is TcxTreeListFooterMultiItemsCellViewInfo then
for I := 0 to TcxTreeListFooterMultiItemsCellViewInfo(HitCell).SummaryItems.Count - 1 do
if TcxTreeListFooterMultiItemsCellViewInfo(HitCell).SummaryItems[I].Visible then
begin
AController.SelectObject(TcxTreeListFooterMultiItemsCellViewInfo(HitCell).SummaryItems[I], AShift);
AShift := [ssShift];
end;
end;
procedure TcxTreeListHitTest.DoCalculate;
begin
ClearState;
FHitBand := nil;
FHitColumn := nil;
FHitNode := nil;
if not IsMouseEvent then
HitTestItem := nil;
FDragItem := nil;
if not TreeList.IsLocked then
ViewInfo.CalculateHitTest(Self);
if HitAtFooter or HitAtGroupFooter then
CheckFooterColumn;
end;
function TcxTreeListHitTest.GetCurrentCursor: TCursor;
const
ACursors: array[Boolean, Boolean] of TCursor =
((crcxHorzSize, crcxVertSize), (crHSplit, crVSplit));
begin
Result := inherited GetCurrentCursor;
if (TreeList.DragAndDropState = ddsInProcess) and
not (TreeList.DragAndDropObject is TcxSizingDragAndDropObject) then Exit;
if (Result = crDefault) and CanSizing then
Result := ACursors[TreeList.DragAndDropState <> ddsNone, HitAtSizingVert];
end;
function TcxTreeListHitTest.GetState(Index: Integer): Boolean;
begin
Result := (HitState and (1 shl Index)) <> 0;
end;
procedure TcxTreeListHitTest.SetHitState(Index: Integer; Value: Boolean);
begin
if Value then
FHitState := FHitState or (1 shl Index)
else
FHitState := FHitState and not (1 shl Index);
end;
function TcxTreeListHitTest.GetHitAtImages: Boolean;
begin
Result := HitAtImage or HitAtStateImage;
end;
function TcxTreeListHitTest.GetHitAtFooterArea: Boolean;
begin
Result := HitAtFooter or HitAtFooterItem or
HitAtGroupFooter or HitAtGroupFooterItem;
end;
function TcxTreeListHitTest.GetHitAtHeader: Boolean;
begin
Result := (HitAtBandHeader or HitAtColumnHeader or HitAtBandCustomizing or
HitAtColumnCustomizing) and (HitTestItem is TcxTreeListCustomHeaderCellViewInfo);
end;
function TcxTreeListHitTest.GetHitCell: TcxCustomViewInfoItem;
begin
Result := HitTestItem as TcxCustomViewInfoItem;
end;
function TcxTreeListHitTest.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(Control);
end;
function TcxTreeListHitTest.GetViewInfo: TcxTreeListViewInfo;
begin
Result := TcxTreeListViewInfo(inherited ViewInfo);
end;
{ TcxTreeListHitTestArea }
constructor TcxTreeListHitTestArea.Create(
ALink: TcxTreeListCustomCellViewInfo);
begin
FLink := ALink;
end;
function TcxTreeListHitTestArea.GetHitTest(
AHitTest: TcxTreeListHitTest): Boolean;
begin
Result := PtInRect(Area, AHitTest.HitPoint);
if Result then
InitHitTest(AHitTest);
end;
{ TcxTreeListHeaderSizingArea }
constructor TcxTreeListHeaderSizingArea.CreateEx(
ALink: TcxTreeListCustomCellViewInfo; ADirection: TcxDragSizingDirection);
begin
inherited Create(ALink);
FDirection := ADirection;
Calculate;
end;
procedure TcxTreeListHeaderSizingArea.Calculate;
begin
FArea := cxRectInflate(FLink.DisplayRect, cxtlHitDelta, cxtlHitDelta);
if Direction = dsdHorz then
begin
if FLink.DisplayRect.Right > FLink.VisibleRect.Right then
FArea := cxNullRect
else
FArea.Left := FArea.Right - cxtlHitDelta * 2
end
else
FArea.Top := FArea.Bottom - cxtlHitDelta * 2;
if FLink.HasClipping then
IntersectRect(FArea, FArea, cxRectInflate(FLink.VisibleRect, 0, cxtlHitDelta));
end;
procedure TcxTreeListHeaderSizingArea.InitHitTest(AHitTest: TcxTreeListHitTest);
const
AStates: array[TcxDragSizingDirection] of Integer =
(tlhc_HitAtSizingHorz, tlhc_HitAtSizingVert);
begin
AHitTest.SetHitState(AStates[Direction], True);
TcxTreeListHeaderCellViewInfo(Link).SetHitItem;
AHitTest.DragItem := TcxTreeListHeaderCellViewInfo(Link).Item;
if AHitTest.IsItemEditCell then
AHitTest.HitTestItem := nil;
end;
{ TcxTreeListNodeSizingArea }
constructor TcxTreeListNodeSizingArea.Create(ALink: TcxTreeListCustomCellViewInfo);
begin
inherited Create(ALink);
Calculate;
end;
destructor TcxTreeListNodeSizingArea.Destroy;
begin
if FLink <> nil then
TcxTreeListIndicatorCellViewInfo(FLink).SizingArea := nil;
inherited Destroy;
end;
procedure TcxTreeListNodeSizingArea.Calculate;
begin
FArea := cxRectOffset(FLink.DisplayRect, FLink.GetCellOrigin);
FArea.Top := FArea.Bottom - cxtlHitDelta;
FArea.Bottom := FArea.Bottom + cxtlHitDelta;
end;
function TcxTreeListNodeSizingArea.GetHitTest(
AHitTest: TcxTreeListHitTest): Boolean;
begin
Result := PtInRect(Area, AHitTest.HitPoint);
if Result and Link.TreeList.OptionsCustomizing.RowSizing then
Result := Link.TreeList.TopVisibleNode = Link.Node;
if Result then
InitHitTest(AHitTest);
end;
procedure TcxTreeListNodeSizingArea.InitHitTest(AHitTest: TcxTreeListHitTest);
begin
AHitTest.SetHitState(tlhc_HitAtSizingVert, True);
AHitTest.SetHitState(tlhc_HitAtNode, True);
AHitTest.FHitNode := TcxTreeListIndentCellViewInfo(FLink).AttachNode;
AHitTest.FDragItem := AHitTest.FHitNode;
end;
{ TcxCustomTreeList }
constructor TcxCustomTreeList.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAbsoluteItems := TList.Create;
FAbsoluteVisibleItems := TList.Create;
ControlStyle := ControlStyle + [csDisplayDragImage];
Width := 250;
Height := 150;
FRoot := GetRootClass.Create(Self);
if Assigned(DesignerNavigatorProc) then
DesignerNavigatorProc(Self, True);
FChanges := [tcStructure];
end;
destructor TcxCustomTreeList.Destroy;
begin
DataController.Cancel;
BeginUpdate;
DoClear;
ViewInfo.Clear;
Customizing.Visible := False;
FAbsoluteItems.Free;
FAbsoluteVisibleItems.Free;
if Assigned(DesignerNavigatorProc) then
DesignerNavigatorProc(Self, False);
FreeAndNil(FRoot);
inherited Destroy;
end;
procedure TcxCustomTreeList.Assign(Source: TPersistent);
begin
if Source is TcxCustomTreeList then
begin
BeginUpdate;
try
DefaultRowHeight := TcxCustomTreeList(Source).DefaultRowHeight;
AssignData(Source as TcxCustomTreeList);
AssignOptions(Source as TcxCustomTreeList);
DataController.Assign(TcxCustomTreeList(Source).DataController);
Styles.Assign(TcxCustomTreeList(Source).DataController);
AddChanges([tcStructure..tcSelection]);
finally
EndUpdate;
end;
end
else
inherited Assign(Source);
end;
procedure TcxCustomTreeList.AdjustColumnsWidth;
var
I: Integer;
APrevValue: Boolean;
begin
APrevValue := OptionsView.ColumnAutoWidth;
OptionsView.ColumnAutoWidth := True;
BeginUpdate;
try
for I := 0 to VisibleColumnCount - 1 do
VisibleColumns[I].Width := VisibleColumns[I].DisplayWidth;
for I := 0 to Bands.VisibleItemCount - 1 do
Bands.VisibleItems[I].Width := Bands.VisibleItems[I].DisplayWidth;
finally
EndUpdate;
end;
OptionsView.ColumnAutoWidth := APrevValue;
end;
procedure TcxCustomTreeList.ApplyBestFit;
var
I: Integer;
begin
BeginUpdate;
try
for I := 0 to Bands.VisibleItemCount - 1 do
Bands.VisibleItems[I].ApplyBestFit;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.Cancel;
begin
DataController.Cancel;
end;
procedure TcxCustomTreeList.Clear;
begin
BeginUpdate;
try
DoClear;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.DoBandSizeChanged(ABand: TcxTreeListBand);
begin
Modified;
LayoutChanged;
DoOnBandSizeChanged(ABand);
end;
procedure TcxCustomTreeList.DoColumnSizeChanged(AColumn: TcxTreeListColumn);
begin
Modified;
DoOnColumnSizeChanged(AColumn);
end;
function TcxCustomTreeList.DoCreateColumn: TcxTreeListColumn;
function GetItemName: string;
var
I: Integer;
begin
Result := GetTreeListColumnClass.ClassName;
for I := Length(Result) downto 1 do
if dxCharInSet(Result[I], ['A'..'Z']) then
begin
Delete(Result, 1, I - 1);
Break;
end;
end;
begin
Result := GetTreeListColumnClass.Create(Owner);
Result.EditingControl := Self;
Result.Name := CreateUniqueName(Owner, Self, Result, scxTLPrefixName, '');
Modified;
UpdateDesignerForms;
end;
function TcxCustomTreeList.CreateColumn(
ABand: TcxTreeListBand = nil): TcxTreeListColumn;
begin
BeginUpdate;
try
Result := DoCreateColumn;
ClearCalculatedWidths;
if ABand = nil then
ABand := GetDefaultColumnContainer;
Result.Position.BandIndex := ABand.Index;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.DeleteAllColumns;
begin
BeginUpdate;
try
ViewInfo.SetDirty;
DataController.DestroyHandles;
while ColumnCount > 0 do
Columns[0].Free;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.DeleteSelection;
begin
DoDeleteSelection;
end;
procedure TcxCustomTreeList.DragDrop(Source: TObject; X, Y: Integer);
begin
if Source <> Self then
begin
if Assigned(OnDragDrop) then
OnDragDrop(Self, Source, X, Y);
Controller.DragDrop(Source, X, Y);
Exit;
end;
HitTest.HitPoint := Point(X, Y);
try
if Assigned(OnDragDrop) then
OnDragDrop(Self, Source, X, Y);
Controller.DragDrop(Source, X, Y);
FocusedNode := DragNode;
finally
FDragNode := nil;
if FocusedNode <> nil then
FocusedNode.MakeVisible;
end;
end;
procedure TcxCustomTreeList.Edit;
begin
if OptionsData.Editing then
DataController.Edit;
end;
procedure TcxCustomTreeList.MakeDefaultLayout;
var
I: Integer;
begin
BeginUpdate;
try
OptionsView.Bands := False;
while Bands.Count > 1 do
Bands[Bands.Count - 1].Free;
if Bands.Count = 0 then Bands.Add;
Bands[0].RestoreDefaults;
Bands[0].Visible := True;
for I := 0 to ColumnCount - 1 do
with Columns[I] do
begin
RestoreDefaults;
Position.BandIndex := 0;
end;
finally
EndUpdate;
Modified;
FDefaultLayout := True;
end;
end;
procedure TcxCustomTreeList.Post;
begin
DataController.Post;
end;
procedure TcxCustomTreeList.FullCollapse;
begin
SetGlassCursor;
try
Root.Collapse(True);
finally
RestoreCursor;
end;
end;
procedure TcxCustomTreeList.FullExpand;
begin
SetGlassCursor;
try
Root.Expand(True);
finally
RestoreCursor;
end;
end;
procedure TcxCustomTreeList.FullRefresh;
begin
AddChanges([tcStructure..tcFocusedNode]);
LayoutChanged;
end;
function TcxCustomTreeList.Find(AData: Pointer;
AStart: TcxTreeListNode; AExpandedOnly, AForward: Boolean;
AFilter: TcxTreeListFindFunc; AIgnoreStartNode: Boolean = False): TcxTreeListNode;
begin
Result := cxFind(Self, AData, AStart, AExpandedOnly, AForward, AFilter, AIgnoreStartNode);
end;
type
PFindTextInfo = ^TFindTextInfo;
TFindTextInfo = record
Text: string;
Column: TcxTreeListColumn;
CaseSensitive: Boolean;
Mode: TcxTreeListFindMode;
LikeParams: TcxTreeListLikeParams;
IgnoreStartNode: Boolean;
end;
function FindTextFilter(ANode: TcxTreeListNode; AData: Pointer): Boolean;
var
ANodeText: string;
APercent, AUnderline: Char;
begin
with PFindTextInfo(AData)^ do
begin
ANodeText := ANode.Texts[Column.ItemIndex];
if not CaseSensitive then
begin
ANodeText := AnsiUpperCase(ANodeText);
Text := AnsiUpperCase(Text);
end;
case Mode of
tlfmLike:
begin
if LikeParams = nil then
begin
APercent := '%';
AUnderline := '_';
end
else
begin
APercent := LikeParams.Percent;
AUnderline := LikeParams.UnderLine;
end;
Result := LikeStr(ANodeText, Text,
APercent, AUnderLine);
end;
tlfmExact:
begin
Result := ANodeText = Text;
end;
else
Result := AnsiStrPos(PChar(ANodeText), PChar(Text)) <> nil;
end;
end;
end;
function TcxCustomTreeList.FindNodeByText(const AText: string;
AColumn: TcxTreeListColumn; AStartNode: TcxTreeListNode = nil;
AExpandedOnly: Boolean = False; AForward: Boolean = True;
ACaseSensitive: Boolean = True; AMode: TcxTreeListFindMode = tlfmNormal;
ALikeParams: TcxTreeListLikeParams = nil; AIgnoreStartNode: Boolean = False): TcxTreeListNode;
var
AFindInfo: TFindTextInfo;
begin
AFindInfo.Text := AText;
AFindInfo.Column := AColumn;
AFindInfo.CaseSensitive := ACaseSensitive;
AFindInfo.Mode := AMode;
AFindInfo.LikeParams := ALikeParams;
AFindInfo.IgnoreStartNode := AIgnoreStartNode;
Result := Find(@AFindInfo, AStartNode, AExpandedOnly, AForward, FindTextFilter,
AIgnoreStartNode);
end;
procedure TcxCustomTreeList.SetFocusedNode(
ANode: TcxTreeListNode; AShift: TShiftState);
begin
if (ANode = nil) or not ANode.IsVisible then
Exit;
if OptionsBehavior.AlwaysShowEditor then
Controller.SetFocusedRecordItem(Integer(ANode), FocusedColumn)
else
Controller.FocusedNode := ANode;
end;
procedure TcxCustomTreeList.SelectAll;
begin
if not OptionsSelection.MultiSelect or (AbsoluteVisibleCount = 0) then Exit;
BeginUpdate;
try
DoSelectAll;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.CancelEdit;
begin
Controller.EditingController.HideEdit(False);
end;
procedure TcxCustomTreeList.HideEdit;
begin
Controller.EditingController.HideEdit(True);
end;
procedure TcxCustomTreeList.Select(Node: TcxTreeListNode;
ShiftState: TShiftState = []);
begin
Controller.Select(Node, ShiftState);
end;
procedure TcxCustomTreeList.Select(const ANodes: array of TcxTreeListNode);
var
I: Integer;
begin
BeginUpdate;
try
ClearSelection;
for I := Low(ANodes) to High(ANodes) do
ANodes[I].Selected := True;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.Select(ANodesList: TList);
begin
if (ANodesList <> nil) and (ANodesList.Count > 0) then Exit;
BeginUpdate;
try
ClearSelection;
SelectionList.Assign(ANodesList);
DoSelectionChanged;
finally
EndUpdate;
end
end;
procedure TcxCustomTreeList.Deselect(Node: TcxTreeListNode);
begin
Node.Selected := False;
end;
procedure TcxCustomTreeList.ShowEdit;
begin
if not OptionsData.Editing then Exit;
DataController.Edit;
Controller.EditingController.ShowEdit();
end;
procedure TcxCustomTreeList.ShowEditByKey(AKey: Char);
begin
BeforeShowingEdit;
with Controller do
EditingController.ShowEdit(FocusedItem, AKey);
end;
procedure TcxCustomTreeList.ShowEditByMouse(X, Y: Integer; AShift: TShiftState);
begin
BeforeShowingEdit;
with Controller do
EditingController.ShowEdit(FocusedItem, AShift, X, Y);
end;
procedure TcxCustomTreeList.RestoreFromIniFile(const AStorageName: string;
AChildrenCreating: Boolean = False; AChildrenDeleting: Boolean = False);
var
AStorage: TcxStorage;
begin
AStorage := TcxStorage.Create(AStorageName);
try
AStorage.NamePrefix := Name;
if AChildrenCreating then
AStorage.Modes := [smChildrenCreating];
if AChildrenDeleting then
AStorage.Modes := AStorage.Modes + [smChildrenDeleting];
BeginUpdate;
try
IsRestoring := True;
try
AStorage.UseInterfaceOnly := True;
AStorage.RestoreFromIni(Self);
finally
IsRestoring := False;
end;
finally
EndUpdate;
end;
finally
AStorage.Free;
end;
end;
procedure TcxCustomTreeList.RestoreFromRegistry(const AStorageName: string;
AChildrenCreating: Boolean = False; AChildrenDeleting: Boolean = False);
var
AStorage: TcxStorage;
begin
AStorage := TcxStorage.Create(AStorageName);
try
AStorage.UseInterfaceOnly := True;
AStorage.NamePrefix := Name;
if AChildrenCreating then
AStorage.Modes := [smChildrenCreating];
if AChildrenDeleting then
AStorage.Modes := AStorage.Modes + [smChildrenDeleting];
BeginUpdate;
try
IsRestoring := True;
try
AStorage.RestoreFromRegistry(Self);
finally
IsRestoring := False;
end;
finally
EndUpdate;
end;
finally
AStorage.Free;
end;
end;
procedure TcxCustomTreeList.RestoreFromStream(AStream: TStream;
AChildrenCreating: Boolean = False; AChildrenDeleting: Boolean = False);
var
AStorage: TcxStorage;
begin
AStorage := TcxStorage.Create(AStream);
try
AStorage.UseInterfaceOnly := True;
AStorage.NamePrefix := Name;
if AChildrenCreating then
AStorage.Modes := [smChildrenCreating];
if AChildrenDeleting then
AStorage.Modes := AStorage.Modes + [smChildrenDeleting];
BeginUpdate;
try
IsRestoring := True;
try
AStorage.RestoreFromStream(Self);
finally
IsRestoring := False;
end;
finally
EndUpdate;
end;
finally
AStorage.Free;
end;
end;
procedure TcxCustomTreeList.StoreToIniFile(AStorageName: string;
AReCreate: Boolean = True);
var
AStorage: TcxStorage;
begin
AStorage := TcxStorage.Create(AStorageName);
try
AStorage.UseInterfaceOnly := True;
AStorage.NamePrefix := Name;
AStorage.ReCreate := AReCreate;
AStorage.StoreToIni(Self);
finally
AStorage.Free;
end;
end;
procedure TcxCustomTreeList.StoreToRegistry(AStorageName: string;
AReCreate: Boolean = True);
var
AStorage: TcxStorage;
begin
AStorage := TcxStorage.Create(AStorageName);
try
AStorage.UseInterfaceOnly := True;
AStorage.NamePrefix := Name;
AStorage.ReCreate := AReCreate;
AStorage.StoreToRegistry(Self);
finally
AStorage.Free;
end;
end;
procedure TcxCustomTreeList.StoreToStream(AStream: TStream);
var
AStorage: TcxStorage;
begin
AStorage := TcxStorage.Create(AStream);
try
AStorage.UseInterfaceOnly := True;
AStorage.NamePrefix := Name;
AStorage.StoreToStream(Self);
finally
AStorage.Free;
end;
end;
function TcxCustomTreeList.CellRect(
ANode: TcxTreeListNode; AColumn: TcxTreeListColumn): TRect;
var
AViewInfo: TcxTreeListEditCellViewInfo;
begin
AViewInfo := ViewInfo.GetEditCell(ANode, AColumn);
if AViewInfo <> nil then
Result := AViewInfo.ClipRect
else
Result := cxInvalidRect;
end;
// searching
function TcxCustomTreeList.FindNext(AForward: Boolean): Boolean;
var
ANode: TcxTreeListNode;
const
ALocateKeys: array[Boolean] of Word = (VK_UP, VK_DOWN);
begin
if Searching then
begin
ANode := FocusedNode;
Controller.IncSearchKeyDown(ALocateKeys[AForward], [ssCtrl]);
end
else
ANode := nil;
Result := ANode <> FocusedNode;
end;
procedure TcxCustomTreeList.CancelSearching;
begin
Controller.CancelIncSearching;
end;
function TcxCustomTreeList.GetEditRect(
ANode: TcxTreeListNode; AColumn: TcxTreeListColumn): TRect;
var
AViewInfo: TcxTreeListEditCellViewInfo;
begin
AViewInfo := ViewInfo.GetEditCell(ANode, AColumn);
if AViewInfo <> nil then
Result := AViewInfo.EditRect
else
Result := cxInvalidRect;
end;
function TcxCustomTreeList.GetNodeAt(
X, Y: Integer): TcxTreeListNode;
begin
HitTest.ReCalculate(cxPoint(X, Y));
if HitTest.HitAtNode then
Result := HitTest.HitNode
else
Result := nil;
end;
procedure TcxCustomTreeList.CopyAllToClipboard;
begin
DoWriteToClipboard(False);
end;
procedure TcxCustomTreeList.CopySelectedToClipboard;
begin
DoWriteToClipboard(True);
end;
procedure TcxCustomTreeList.RestoreColumnsDefaults;
var
I: Integer;
begin
BeginUpdate;
try
for I := 0 to ColumnCount - 1 do
Columns[I].RestoreDefaults;
RestoreColumnsWidths;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.RestoreColumnsWidths;
var
I: Integer;
begin
BeginUpdate;
try
for I := 0 to ColumnCount - 1 do
Columns[I].RestoreDefaults;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.Subselect(Node: TcxTreeListNode);
begin
if not CanMultiSelect then
cxTreeListError(cxGetResourceString(@scxMultiSelectRequired))
else
Node.Selected := True;
end;
procedure TcxCustomTreeList.ClearSelection(KeepPrimary: Boolean = False);
begin
Controller.CancelSelection(KeepPrimary)
end;
procedure TcxCustomTreeList.ClearSorting;
begin
Sorted := False;
end;
function TcxCustomTreeList.ColumnByName(
const AName: string): TcxTreeListColumn;
var
I: Integer;
begin
Result := nil;
for I := 0 to ColumnCount - 1 do
if CompareText(Columns[I].Name, AName) = 0 then
begin
Result := Columns[I];
Break;
end;
end;
function TcxCustomTreeList.GetSelections(AList: TList): TcxTreeListNode;
begin
AList.Clear;
if OptionsSelection.MultiSelect then
AList.Assign(SelectionList)
else
if FocusedNode <> nil then
AList.Add(FocusedNode);
Result := FocusedNode;
end;
procedure TcxCustomTreeList.GotoBOF;
begin
FocusedNode := Root.GetFirstChild;
end;
procedure TcxCustomTreeList.GotoEOF;
begin
FocusedNode := cxGetLatest(Root.GetLastChild);
end;
procedure TcxCustomTreeList.GotoNext;
begin
if not IsEOF and (FocusedNode <> nil) then
FocusedNode := FocusedNode.GetNextVisible;
end;
procedure TcxCustomTreeList.GotoNextPage;
begin
Controller.DoNextPage(True, []);
end;
procedure TcxCustomTreeList.GotoPrev;
begin
if not IsBOF and (FocusedNode <> nil) then
FocusedNode := FocusedNode.GetPrevVisible;
end;
procedure TcxCustomTreeList.GotoPrevPage;
begin
Controller.DoNextPage(False, []);
end;
function TcxCustomTreeList.IsBOF: Boolean;
begin
Result := (FocusedNode <> nil) and (FocusedNode.GetPrevVisible = nil);
end;
function TcxCustomTreeList.IsEOF: Boolean;
begin
Result := (FocusedNode <> nil) and (FocusedNode.GetNextVisible = nil);
end;
procedure TcxCustomTreeList.CheckCreateDesignSelectionHelper;
begin
end;
procedure TcxCustomTreeList.ControlUpdateData(
AInfo: TcxUpdateControlInfo);
begin
inherited ControlUpdateData(AInfo);
ViewInfo.Invalidate(True);
RefreshNavigatorButtons;
end;
procedure TcxCustomTreeList.DataChanged;
begin
ViewInfo.SetDirty;
inherited DataChanged;
Include(FChanges, tcData);
LayoutChanged;
end;
procedure TcxCustomTreeList.DataLayoutChanged;
begin
inherited DataLayoutChanged;
Include(FChanges, tcData);
LayoutChanged;
end;
function cxCompareColumnsVisibleOrder(AColumn1, AColumn2: TcxTreeListColumn): Integer;
begin
Result := Weights[AColumn1.Position.Band.FixedKind] - Weights[AColumn2.Position.Band.FixedKind];
if Result <> 0 then Exit;
Result := AColumn1.Position.Band.VisibleIndex - AColumn2.Position.Band.VisibleIndex;
if Result = 0 then
begin
Result := AColumn1.Position.VisibleRowIndex - AColumn2.Position.VisibleRowIndex;
if Result = 0 then
begin
Result := AColumn1.Position.VisibleColIndex - AColumn2.Position.VisibleColIndex;
if Result = 0 then
Result := AColumn1.VisibleIndex - AColumn2.VisibleIndex;
end;
end;
end;
procedure TcxCustomTreeList.DoLayoutChanged;
begin
IsCancelOperation := False;
CheckChanges;
ImageChanged;
Bands.RefreshInformation;
ViewInfo.State[cvis_StyleInvalid] := True;
Bands.Adjust;
FVisibleColumns.Sort(@cxCompareColumnsVisibleOrder);
CalculateForceIndentWidth;
inherited DoLayoutChanged;
UpdateDesignerForms;
DoLayoutChangedEvent;
end;
function TcxCustomTreeList.DoShowPopupMenu(AMenu: TComponent; X, Y: Integer): Boolean;
begin
Result := PopupMenus.DoShowPopupMenu(Point(X, Y));
if not Result then
Result := inherited DoShowPopupMenu(AMenu, X, Y);
end;
procedure TcxCustomTreeList.InitScrollBarsParameters;
begin
if ([csLoading, csDestroying, csUpdating, csReading] * ComponentState <> [])
or DataController.IsLoading or (Root = nil) then Exit;
ViewInfo.InitScrollBarsParameters;
end;
procedure TcxCustomTreeList.AssignItemsPosition;
var
I: Integer;
AList: TList;
begin
IgnoreLoadingStatus := not IsLoading;
AList := TList.Create;
try
// align bands
for I := 0 to Bands.Count - 1 do
AList.Add(Bands[I]);
AList.Sort(@cxCompareBandsByPosition);
for I := 0 to AList.Count - 1 do
TcxTreeListBand(AList[I]).Position.Restore;
// align columns
AList.Assign(ColumnsList);
AList.Sort(@cxCompareColumnsByPosition);
for I := 0 to ColumnCount - 1 do
TcxTreeListColumn(AList[I]).Position.Restore;
finally
AList.Free;
end;
end;
procedure TcxCustomTreeList.ReadState(Reader: TReader);
begin
SaveItemsPosition;
inherited ReadState(Reader);
AssignItemsPosition;
end;
procedure TcxCustomTreeList.SaveItemsPosition;
var
I: Integer;
begin
for I := 0 to ColumnCount - 1 do
Columns[I].Position.Store;
for I := 0 to Bands.Count - 1 do
Bands[I].Position.Store;
end;
procedure TcxCustomTreeList.Updated;
begin
inherited Updated;
AssignItemsPosition;
end;
procedure TcxCustomTreeList.Updating;
begin
SaveItemsPosition;
inherited Updating;
end;
function TcxCustomTreeList.DragDropImageDisplayRect: TRect;
begin
with GetDragDropViewParams do
begin
Result := inherited DragDropImageDisplayRect;
Result.Bottom := cxTextHeight(Font);
Result.Right := VisibleColumns[0].DisplayWidth;
Result := cxRectOffset(Result, [ScreenToClient(GetMouseCursorPos),
cxTreeListDragDropTextAreaOffset]);
Result := cxRectInflate(Result, cxTextOffset, cxTextOffset);
end;
end;
procedure TcxCustomTreeList.DrawDragDropImage(
ADragBitmap: TBitmap; ACanvas: TcxCanvas);
var
R: TRect;
begin
cxApplyViewParams(ACanvas, GetDragDropViewParams);
R := Rect(0, 0, ADragBitmap.Width, ADragBitmap.Height);
ACanvas.FillRect(R);
ACanvas.FrameRect(R, clBlack, 1, cxBordersAll);
ACanvas.Brush.Style := bsClear;
ACanvas.DrawTexT(GetDragDropText, cxTextRect(R),
cxAlignLeft or cxAlignVCenter or cxSingleLine);
end;
function TcxCustomTreeList.GetDragDropText: string;
begin
Result := FDragNode.Texts[VisibleColumns[0].ItemIndex];
end;
function TcxCustomTreeList.GetDragDropViewParams: TcxViewParams;
begin
Result := Styles.GetContentParams(FDragNode, VisibleColumns[0]);
with Styles.GetSelectionParams do
begin
Result.Color := Color;
if Styles.SelectionFontAssigned then
Result.Font := Font;
Result.TextColor := TextColor;
end;
end;
function TcxCustomTreeList.GetDragObjectClass: TDragControlObjectClass;
begin
Result := nil;
end;
function TcxCustomTreeList.StartDrag(DragObject: TDragObject): Boolean;
begin
Result := DragNode <> nil;
end;
procedure TcxCustomTreeList.GetStoredChildren(AChildren: TStringList);
var
I: Integer;
begin
AChildren.AddObject('', Bands);
for I := 0 to ColumnCount - 1 do
AChildren.AddObject('', Columns[I]);
end;
function TcxCustomTreeList.GetStoredObjectName: string;
begin
Result := Name;
end;
function TcxCustomTreeList.GetStoredObjectProperties(
AProperties: TStrings): Boolean;
begin
if Assigned(OnGetStoredProperties) then
OnGetStoredProperties(Self, AProperties);
Result := True;
end;
procedure TcxCustomTreeList.GetStoredPropertyValue(
const AName: string; var AValue: Variant);
begin
if Assigned(OnGetStoredPropertyValue) then
OnGetStoredPropertyValue(Self, AName, AValue);
end;
procedure TcxCustomTreeList.SetStoredPropertyValue(
const AName: string; const AValue: Variant);
begin
if Assigned(OnSetStoredPropertyValue) then
OnSetStoredPropertyValue(Self, AName, AValue);
end;
function TcxCustomTreeList.StoredCreateChild(
const AObjectName, AClassName: string): TObject;
begin
if AClassName = GetTreeListColumnClass.ClassName then
begin
Result := CreateColumn;
TcxTreeListColumn(Result).Name := AObjectName;
if Assigned(OnInitStoredObject) then
FOnInitStoredObject(Self, Result);
end
else
Result := nil;
end;
procedure TcxCustomTreeList.StoredDeleteChild(
const AObjectName: string; AObject: TObject);
begin
end;
procedure TcxCustomTreeList.GetChildren(
Proc: TGetChildProc; Root: TComponent);
procedure DoStore(AColumn: TcxTreeListColumn);
begin
if AColumn.Owner = Root then
Proc(AColumn);
end;
var
I: Integer;
begin
inherited GetChildren(Proc, Root);
for I := 0 to ColumnCount - 1 do DoStore(Columns[I]);
end;
function TcxCustomTreeList.IsUpdating: Boolean;
begin
Result := csUpdating in ComponentState;
end;
procedure TcxCustomTreeList.Loaded;
procedure ConvertOldFooterSummaries;
var
I: Integer;
begin
for I := 0 to ColumnCount - 1 do
Columns[I].ConvertOldFooterSummaries;
end;
begin
inherited Loaded;
FSortedColumns.Sort(@cxCompareColumnsBySortIndex);
if FocusedNode <> nil then
FocusedNode.MakeVisible;
AssignItemsPosition;
ConvertOldFooterSummaries;
DataChanged;
StructureChanged;
ForceLayoutChanged;
end;
procedure TcxCustomTreeList.Modified;
begin
if HandleAllocated then
inherited Modified;
FDefaultLayout := False;
end;
procedure TcxCustomTreeList.Notification(
AComponent: TComponent; Operation: TOperation);
var
I: Integer;
begin
inherited Notification(AComponent, Operation);
if PopupMenus <> nil then
PopupMenus.Notification(AComponent, Operation);
if not IsDestroying then
begin
if (Summary <> nil) and (Operation = opRemove) and (AComponent is TcxTreeListColumn) then
Summary.Notification(AComponent, Operation);
if Operation = opRemove then
FDefaultLevelInfo.Notification(AComponent, Operation);
if FLevelsInfo <> nil then
for I := 0 to FLevelsInfo.Count - 1 do
LevelsInfo[I].Notification(AComponent, Operation);
end;
end;
procedure TcxCustomTreeList.SetName(const NewName: TComponentName);
begin
inherited SetName(NewName);
UpdateDesignerForms;
end;
procedure TcxCustomTreeList.AddChanges(AChanges: TcxTreeListChanges);
begin
FChanges := FChanges + AChanges;
end;
function TcxCustomTreeList.AddNode(ANode, ARelative: TcxTreeListNode;
AData: Pointer; AttachMode: TcxTreeListNodeAttachMode): TcxTreeListNode;
begin
Result := AddNodeInternal(ANode, ARelative, AttachMode);
Result.FData := AData;
end;
function TcxCustomTreeList.AddNodeInternal(ANode, ARelative: TcxTreeListNode;
AddMethod: TcxTreeListNodeAttachMode): TcxTreeListNode;
const
IsAddChild: array[TcxTreeListNodeAttachMode] of Boolean =
(False, False, True, True, False);
AddMode: array[TcxTreeListNodeAttachMode] of TcxTreeListNodeAddMode =
(tlnaAdd, tlnaAddFirst, tlnaAdd, tlnaAddFirst, tlnaInsert);
begin
if ANode = nil then
Result := CreateNode
else
Result := ANode;
if (ARelative = nil) and (AddMethod = tlamInsert) then
AddMethod := tlamAdd;
if ARelative <> nil then
SetNodeParent(Result, ARelative, AddMode[AddMethod])
else
SetNodeParent(Result, FRoot, AddMode[AddMethod]);
if AddMode[AddMethod] = tlnaInsert then
Result.FOriginalIndex := Result.Index
else
Result.FOriginalIndex := Result.Parent.Count;
LayoutChanged;
end;
procedure TcxCustomTreeList.AfterMouseDown(AButton: TMouseButton; X, Y: Integer);
begin
if (DragMode = dmAutomatic) and (AButton = mbLeft) and
(not IsDesigning or AllowAutoDragAndDropAtDesignTime(X, Y, [])) and
CanDrag(X, Y) and (DragDetect(Handle) = ddDrag) then
BeginDrag(True);
if AButton = mbMiddle then DoScrolling;
end;
procedure TcxCustomTreeList.AssignOptions(ASource: TcxCustomTreeList);
begin
Font := ASource.Font;
Styles := ASource.Styles;
Images := ASource.Images;
StateImages := ASource.StateImages;
OptionsCustomizing := ASource.OptionsCustomizing;
OptionsView := ASource.OptionsView;
OptionsBehavior := ASource.OptionsBehavior;
OptionsSelection := ASource.OptionsSelection;
end;
procedure TcxCustomTreeList.AssignData(ASource: TcxCustomTreeList);
var
I: Integer;
AName: string;
AColumn: TcxTreeListColumn;
begin
Bands := ASource.Bands;
SaveItemsPosition;
while ContainerList.Count > ASource.ContainerList.Count do
TComponent(ContainerList.Last).Free;
while ContainerList.Count < ASource.ContainerList.Count do
begin
AName := TComponent(ASource.ContainerList[ContainerList.Count]).Name;
AColumn := DoCreateColumn;
if (Owner = nil) or (Owner.FindComponent(AName) = nil) then
AColumn.Name := AName;
end;
for I := 0 to Min(ContainerList.Count, ASource.ContainerList.Count) - 1 do
TcxTreeListColumn(ContainerList[I]).Assign(TPersistent(ASource.ContainerList[I]));
AssignItemsPosition;
Preview := ASource.Preview;
end;
procedure TcxCustomTreeList.BeforeUpdate;
begin
inherited BeforeUpdate;
CheckChanges;
end;
procedure TcxCustomTreeList.BoundsChanged;
begin
AddChanges([tcLayout]);
inherited BoundsChanged;
end;
procedure TcxCustomTreeList.CalculateForceIndentWidth;
var
ABand: TcxTreeListBand;
AColumn: TcxTreeListColumn;
I, AForceDelta: Integer;
begin
ABand := Bands.ExpandableBand;
if (ABand = nil) or IsLoading then Exit;
AForceDelta := ABand.BandRows.RowMinWidth + IndentWidth - ABand.DisplayWidth;
if AForceDelta > 0 then
Bands.ExpandableBand.ForceWidth(Bands.ExpandableBand.DisplayWidth + AForceDelta);
for I := 0 to ABand.BandRows.VisibleItemCount - 1 do
begin
AColumn := ABand.BandRows.VisibleItems[I].VisibleItems[0];
AForceDelta := AColumn.MinWidth + IndentWidth - AColumn.DisplayWidth;
if AForceDelta > 0 then
AColumn.ForceWidth(AColumn.DisplayWidth + AForceDelta);
end;
end;
function TcxCustomTreeList.CanCompare: Boolean;
begin
Result := (SortedColumnCount > 0) or Assigned(FOnCompare);
end;
procedure TcxCustomTreeList.CheckChanges;
begin
if (Changes = []) or ChangesLocked or IsLoading then Exit;
BeginUpdate;
try
ChangesLocked := True;
try
TcxTreeListPainter(Painter).CheckSize(Width, Height);
if tcSortOrder in Changes then
Include(FChanges, tcData);
if tcData in Changes then
DoSortNodes;
if (tcStructure in Changes) or (DataController.NodesCount <> FAbsoluteItems.Count) then
CheckStructure;
if [tcSelection, tcFocusedNode] * Changes <> [] then
CheckSelectionAndFocused;
if [tcData, tcStructure] * Changes <> [] then
Summary.Calculate;
if tcImages in Changes then
CheckLevelsInfo;
CheckEvents;
Changes := [];
ChangesLocked := False;
except
FChanges := [];
BeginUpdate;
raise;
end;
finally
CancelUpdate;
end;
end;
procedure TcxCustomTreeList.CheckEvents;
begin
if not IsDestroying then
begin
if tcFocusedNode in Changes then
begin
if Controller.FocusedNode = nil then
Controller.CheckFocusedNode;
if Controller.PrevFocusedNode <> FocusedNode then
DoFocusedNodeChanged(Controller.PrevFocusedNode, FocusedNode);
end;
if tcSelection in Changes then
DoSelectionChanged;
end;
Exclude(FChanges, tcFocusedNode);
Exclude(FChanges, tcSelection);
end;
procedure TcxCustomTreeList.CheckLevelsInfo;
var
AOffset, I: Integer;
begin
FDefaultIndentSize.cy := Max(ViewInfo.DefaultRowHeight,
LookAndFeelPainter.ExpandButtonSize + cxTreeListIndentOffsetSize);
FDefaultIndentSize.cx := LookAndFeelPainter.ExpandButtonSize + cxTreeListIndentOffsetSize;
BeginUpdate;
try
for I := 0 to FExpansionLevel do
begin
if I = FLevelsInfo.Count then
FLevelsInfo.Add(TcxTreeListLevelInfo.Create(Self));
DoGetLevelImages(LevelsInfo[I], I);
if not OptionsView.DynamicIndent then
FDefaultIndentSize.cx := Max(FDefaultIndentSize.cx, LevelsInfo[I].Size.cx);
if not OptionsView.CellAutoHeight then
FDefaultIndentSize.cy := Max(FDefaultIndentSize.cy, LevelsInfo[I].Size.cy);
end;
for I := FExpansionLevel + 1 to FLevelsInfo.Count - 1 do
FLevelsInfo[I].Free;
FLevelsInfo.Count := FExpansionLevel + 1;
AOffset := 0;
for I := 0 to FExpansionLevel do
begin
AOffset := LevelsInfo[I].Update(AOffset);
if (I = 0) and not OptionsView.ShowRoot then
begin
Dec(LevelsInfo[I].FWidth, DefaultIndentSize.cx);
Dec(AOffset, DefaultIndentSize.cx);
end;
end;
finally
FChanges := FChanges - [tcImages];
CancelUpdate;
end;
end;
procedure TcxCustomTreeList.CheckSelectionAndFocused;
begin
if (Controller.FocusedNode = nil) and cxInRange(
Controller.FocusedNodeIndex, 0, FAbsoluteVisibleItems.Count - 1) then
Controller.FFocusedNode := FAbsoluteVisibleItems[Controller.FocusedNodeIndex];
end;
procedure TcxCustomTreeList.CheckSortOrderList;
var
I: Integer;
begin
for I := 0 to ColumnCount - 1 do
Columns[I].FSortIndex := FSortedColumns.IndexOf(Columns[I])
end;
procedure TcxCustomTreeList.CheckStructure;
var
ANode: TcxTreeListNode;
ALevel, AHiddenLevel: Integer;
begin
ANode := Root.FFirst;
ALevel := 0;
AHiddenLevel := 0;
FExpansionLevel := -1;
FAbsoluteItems.Count := 0;
FAbsoluteItems.Capacity := DataController.NodesCount;
FAbsoluteVisibleItems.Count := 0;
FAbsoluteVisibleItems.Capacity := DataController.NodesCount;
Include(FChanges, tcImages);
while ANode <> nil do
begin
ANode.FAbsoluteIndex := FAbsoluteItems.Count;
FAbsoluteItems.Add(ANode);
ANode.FVisibleIndex := -1;
if (AHiddenLevel = 0) and not (nsHidden in ANode.State) then
begin
ANode.FVisibleIndex := Integer(FAbsoluteVisibleItems.Add(ANode));
FExpansionLevel := Max(FExpansionLevel, ALevel);
end;
if ANode.FFirst <> nil then
begin
Inc(ALevel);
if (AHiddenLevel > 0) or (nsCollapsed in ANode.State) or (nsHidden in ANode.State) then
Inc(AHiddenLevel);
ANode := ANode.FFirst;
end
else
if ANode.FNext <> nil then
ANode := ANode.FNext
else
begin
while (ANode <> Root) and (ANode.FNext = nil) do
begin
if AHiddenLevel > 0 then
Dec(AHiddenLevel);
Dec(ALevel);
ANode := ANode.Parent;
end;
if ANode <> Root then
ANode := ANode.FNext
else
ANode := nil;
end;
end;
end;
procedure TcxCustomTreeList.ClearCalculatedWidths;
var
I: Integer;
begin
for I := 0 to ColumnCount - 1 do
Columns[I].FCalculatedWidth := 0;
for I := 0 to Bands.Count - 1 do
Bands[I].FCalculatedWidth := 0;
end;
procedure TcxCustomTreeList.ColumnSortOrderChanged(
AColumn: TcxTreeListColumn; AShift: TShiftState);
var
AIndex: Integer;
begin
BeginUpdate;
try
if ssCtrl in AShift then
AColumn.CancelSorting
else
begin
if not IsLoading and (not OptionsBehavior.MultiSort or not (ssShift in AShift)) then
begin
for AIndex := 0 to ColumnCount - 1 do
if Columns[AIndex] <> AColumn then
Columns[AIndex].CancelSorting;
end;
if FSortedColumns.IndexOf(AColumn) < 0 then
begin
AIndex := FSortedColumns.Add(AColumn);
if not IsLoading then
AColumn.FSortIndex := AIndex;
end;
end;
FChanges := FChanges + [tcData, tcSortOrder];
finally
EndUpdate;
end;
end;
function TcxCustomTreeList.CreateNode: TcxTreeListNode;
begin
Result := TcxUnboundTreeListNode.Create(Self);
Include(FChanges, tcStructure);
end;
procedure TcxCustomTreeList.CreateSubClasses;
begin
inherited CreateSubClasses;
FDefaultLevelInfo := TcxTreeListLevelInfo.Create(Self);
FLevelsInfo := TcxObjectList.Create();
FNavigatorNotifier := TcxNavigatorControlNotifier.Create;
FSortedColumns := TList.Create;
FDesigners := TList.Create;
FSelectionList := TList.Create;
FOptionsCustomizing := GetOptionsCustomizingClass.Create(Self);
FOptionsSelection := GetOptionsSelectionClass.Create(Self);
FPopupMenus := TcxTreeListPopupMenus.Create(Self);
FPreview := GetPreviewClass.Create(Self);
FBands := TcxTreeListBands.Create(Self);
FVisibleColumns := TList.Create;
FCustomizing := GetTreeListCustomizingClass.Create(Self);
FSummary := GetSummaryClass.Create(Self);
FDelayTimer := TTimer.Create(Self);
FDelayTimer.Enabled := False;
FDelayTimer.Interval := 0;
FDelayTimer.OnTimer := DoChangedTimer;
end;
procedure TcxCustomTreeList.DestroySubClasses;
begin
UpdateDesignerForms;
BeginUpdate;
try
FreeAndNil(FNavigatorNotifier);
FreeAndNil(FVisibleColumns);
FreeAndNil(FPreview);
DeleteAllColumns;
FreeAndNil(FBands);
FreeAndNil(FPopupMenus);
FreeAndNil(FOptionsCustomizing);
FreeAndNil(FOptionsSelection);
FreeAndNil(FCustomizing);
FreeAndNil(FSortedColumns);
FreeAndNil(FSummary);
FreeAndNil(FDefaultLevelInfo);
FreeAndNil(FLevelsInfo);
FreeAndNil(FDelayTimer);
FreeAndNil(FSelectionList);
FreeAndNil(FDesigners);
FreeAndNil(FOptionsCustomizing);
finally
inherited DestroySubClasses;
end;
end;
procedure TcxCustomTreeList.DoAfterSummary;
begin
if Assigned(FOnAfterSummary) then
FOnAfterSummary(Self);
end;
procedure TcxCustomTreeList.DoBandHeaderClick(ABand: TcxTreeListBand);
begin
if Assigned(FOnBandHeaderClick) then
FOnBandHeaderClick(Self, ABand);
end;
function TcxCustomTreeList.DoBeginDragNode(
ANode: TcxTreeListNode): Boolean;
begin
Result := True;
if Assigned(FOnBeginDragNode) then
FOnBeginDragNode(Self, ANode, Result);
end;
function TcxCustomTreeList.DoCanFocusNode(
ANode: TcxTreeListNode): Boolean;
begin
Result := True;
if Assigned(FOnCanFocusNode) then
FOnCanFocusNode(Self, ANode, Result);
end;
function TcxCustomTreeList.DoCanNodeCollapse(
ANode: TcxTreeListNode): Boolean;
begin
Result := ANode.HasChildren;
if Result and Assigned(FOnCollapsing) then
FOnCollapsing(Self, ANode, Result);
end;
function TcxCustomTreeList.DoCanNodeExpand(
ANode: TcxTreeListNode): Boolean;
begin
Result := ANode.HasChildren;
if Result and Assigned(FOnExpanding) then
FOnExpanding(Self, ANode, Result);
end;
function TcxCustomTreeList.DoCanSelectNode(
ANode: TcxTreeListNode): Boolean;
begin
Result := True;
if (ANode <> nil) and Assigned(FOnCanSelectNode) then
FOnCanSelectNode(Self, ANode, Result);
end;
procedure TcxCustomTreeList.DoChanged(BlockChangedEvent: Boolean = True);
begin
if BlockChangedEvent and (OptionsBehavior.ChangeDelay > 0) then Exit;
try
if FPostChanged and Assigned(FOnChange) then
FOnChange(Self);
finally
FPostChanged := False;
end;
end;
procedure TcxCustomTreeList.DoColumnHeaderClick(AColumn: TcxTreeListColumn);
begin
if Assigned(FOnColumnHeaderClick) then
FOnColumnHeaderClick(Self, AColumn);
end;
procedure TcxCustomTreeList.DoCompare(
ANode1, ANode2: TcxTreeListNode; var ACompare: Integer);
const
AEquals: array[Boolean] of Integer = (1, 0);
begin
ACompare := AEquals[ANode1 = ANode2];
if not Assigned(FOnCompare) then
begin
if ACompare <> 0 then
ACompare := DataController.CompareNodesByColumns(ANode1, ANode2, FSortedColumns)
end
else
FOnCompare(Self, ANode1, ANode2, ACompare);
end;
procedure TcxCustomTreeList.DoCustomizationVisibleChanged;
begin
if Assigned(FOnCustomizationVisibleChanged) then
FOnCustomizationVisibleChanged(Self);
end;
procedure TcxCustomTreeList.DoDataChangedEvent(Sender: TObject);
begin
if Assigned(FOnDataChanged) then
FOnDataChanged(Self);
end;
procedure TcxCustomTreeList.DoDeletion(ANode: TcxTreeListNode);
begin
if Assigned(FOnDeletion) then
FOnDeletion(Self, ANode);
end;
procedure TcxCustomTreeList.DoEditValueChanged(
AItem: TcxCustomInplaceEditContainer);
begin
inherited DoEditValueChanged(AItem);
DoChanged();
end;
procedure TcxCustomTreeList.DoExpand(ANode: TcxTreeListNode);
begin
end;
procedure TcxCustomTreeList.DoFocusedItemChanged(
APrevFocusedItem, AFocusedItem: TcxCustomInplaceEditContainer);
begin
if Assigned(FOnFocusedColumnChanged) then
FOnFocusedColumnChanged(Self, TcxTreeListColumn(APrevFocusedItem), TcxTreeListColumn(AFocusedItem));
end;
procedure TcxCustomTreeList.DoFocusedNodeChanged(
APrevNode, AFocusedNode: TcxTreeListNode);
begin
if Assigned(FOnFocusedNodeChanged) then
FOnFocusedNodeChanged(Self, APrevNode, AFocusedNode);
if not OptionsSelection.MultiSelect then DoSelectionChanged;
end;
procedure TcxCustomTreeList.DoGetCellHint(ACell: TObject; var AText: string;
var ANeedShow: Boolean);
begin
if Assigned(FOnGetCellHint) then
FOnGetCellHint(Self, ACell, AText, ANeedShow);
end;
procedure TcxCustomTreeList.DoGetLevelImages(
AInfo: TcxTreeListLevelInfo; ALevel: Integer);
var
AImages, AStateImages: TCustomImageList;
begin
AImages := Images;
AStateImages := StateImages;
if Assigned(FOnGetLevelImages) then
FOnGetLevelImages(Self, ALevel, AImages, AStateImages);
AInfo.Images := AImages;
AInfo.StateImages := AStateImages;
AInfo.Update(0);
end;
procedure TcxCustomTreeList.DoGetNodeHeight(
ANode: TcxTreeListNode; var AHeight: Integer);
begin
if Assigned(FOnGetNodeHeight) then
FOnGetNodeHeight(Self, ANode, AHeight)
end;
function TcxCustomTreeList.DoGetNodeImageIndex(
ANode: TcxTreeListNode; AIndex: TcxTreeListImageIndexType): TImageIndex;
begin
LockChanges := True;
try
if ANode = nil then
Result := -1
else
begin
Result := ANode.FImageIndexes[AIndex];
if (AIndex = tlitSelectedIndex) and (Result = -1) and OptionsView.UseImageIndexForSelected then
Result := ANode.FImageIndexes[tlitImageIndex];
if Assigned(OnGetNodeImageIndex) then
OnGetNodeImageIndex(Self, ANode, AIndex, Result);
end;
finally
LockChanges := False;
end;
end;
procedure TcxCustomTreeList.DoGetPreviewHeight(
ANode: TcxTreeListNode; var AHeight: Integer);
begin
if Assigned(FOnGetNodePreviewHeight) then
FOnGetNodePreviewHeight(Self, ANode, ANode.Values[Preview.Column.ItemIndex], AHeight);
end;
procedure TcxCustomTreeList.DoHotTrackNode(
ANode: TcxTreeListNode; AShift: TShiftState; var ACursor: TCursor);
begin
ACursor := Cursor;
if Assigned(FOnHotTrackNode) then
FOnHotTrackNode(Self, ANode, AShift, ACursor);
end;
function TcxCustomTreeList.DoIsGroupNode(
ANode: TcxTreeListNode): Boolean;
begin
Result := (ANode <> nil) and
(OptionsView.PaintStyle = tlpsCategorized) and ANode.HasChildren;
if Assigned(FOnIsGroupNode) then
FOnIsGroupNode(Self, ANode, Result);
end;
procedure TcxCustomTreeList.DoLayoutChangedEvent;
begin
if Assigned(FOnLayoutChanged) then
FOnLayoutChanged(Self);
end;
function TcxCustomTreeList.DoMoveToEvent(AttachNode: TcxTreeListNode;
AttachMode: TcxTreeListNodeAttachMode; Nodes: TList; var IsCopy: Boolean): Boolean;
begin
Result := False;
if Assigned(FOnMoveTo) then
FOnMoveTo(Self, AttachNode, AttachMode, Nodes, IsCopy, Result);
end;
procedure TcxCustomTreeList.DoNodeChanged(
ANode: TcxTreeListNode; AColumn: TcxTreeListColumn);
begin
if DataController.IsLoading or IsLocked then
begin
Include(FChanges, tcData);
Exit;
end;
if DataController.EditingNode <> ANode then
begin
if AColumn <> nil then
Include(FChanges, tcData)
else
Include(FChanges, tcStructure);
end;
LayoutChanged;
if Assigned(FOnNodeChanged) then
FOnNodeChanged(Self, ANode, AColumn);
end;
procedure TcxCustomTreeList.DoNodeCheckChanged(
ANode: TcxTreeListNode; AState: TcxCheckBoxState);
begin
if Assigned(FOnNodeCheckChanged) then
FOnNodeCheckChanged(Self, ANode, AState);
end;
procedure TcxCustomTreeList.DoNodeCollapsed(ANode: TcxTreeListNode);
begin
if Assigned(FOnCollapsed) then
FOnCollapsed(Self, ANode);
end;
procedure TcxCustomTreeList.DoNodeExpanded(ANode: TcxTreeListNode);
begin
if Assigned(FOnExpanded) then
FOnExpanded(Self, ANode);
end;
procedure TcxCustomTreeList.DoSetNodeFocused(
ANode: TcxTreeListNode; AValue: Boolean; Shift: TShiftState = []);
begin
if AValue then
FocusedNode := ANode
else
if ANode.Focused then FocusedNode := nil;
end;
procedure TcxCustomTreeList.RefreshFields;
var
I: Integer;
begin
ViewInfo.SetDirty;
for I := 0 to ContainerList.Count - 1 do
TcxTreeListColumn(ContainerList[I]).DataChanged;
end;
procedure TcxCustomTreeList.SetNodeParent(ANewNode, ANewParent: TcxTreeListNode;
AMode: TcxTreeListNodeAddMode);
begin
case AMode of
tlnaAdd:
ANewParent.SetLast(ANewNode);
tlnaAddFirst:
ANewParent.SetFirst(ANewNode);
tlnaInsert:
ANewNode.InternalInsert(ANewParent);
end;
AddChanges([tcStructure]);
end;
procedure TcxCustomTreeList.StructureChanged;
begin
Include(FChanges, tcStructure);
LayoutChanged;
end;
procedure TcxCustomTreeList.UpdateFocusedNode(AColumn: TcxTreeListColumn);
begin
ViewInfo.UpdateSelection;
end;
procedure TcxCustomTreeList.ValidateStates;
begin
if FChanges <> [] then
ForceLayoutChanged;
// HandleNeeded;
end;
procedure TcxCustomTreeList.DoSelectionChanged;
begin
if Assigned(FOnSelectionChanged) then
FOnSelectionChanged(Self);
end;
procedure TcxCustomTreeList.DoSelectAll;
var
I: Integer;
begin
SelectionList.Clear;
SelectionList.Capacity := AbsoluteVisibleCount;
for I := 0 to AbsoluteVisibleCount - 1 do
begin
if not DoCanSelectNode(AbsoluteVisibleItems[I]) then Continue;
SelectionList.Add(AbsoluteVisibleItems[I]);
end;
end;
procedure TcxCustomTreeList.DoSorted;
begin
if Assigned(FOnSorted) then
FOnSorted(Self);
end;
procedure TcxCustomTreeList.DoSorting;
begin
if Assigned(FOnSorting) then
FOnSorting(Self);
end;
procedure TcxCustomTreeList.DoSortNodes;
begin
if (not (tcSortOrder in Changes) and not Sorted) or IsLoading or IsDestroying or
IsUpdating or (tcLoading in Changes) then Exit;
DoSorting;
try
Root.AlphaSort(True);
FNeedSort := False;
finally
DoSorted;
end;
end;
procedure TcxCustomTreeList.DoStartDrag(var DragObject: TDragObject);
begin
DragPos := ScreenToClient(GetMouseCursorPos);
if HitTest.HitNode = nil then
HitTest.FHitNode := FDragNode;
inherited DoStartDrag(DragObject);
end;
procedure TcxCustomTreeList.DoTopRecordIndexChanged;
begin
if Assigned(FOnTopRecordIndexChanged) then
FOnTopRecordIndexChanged(Self);
end;
procedure TcxCustomTreeList.ForceLayoutChanged;
begin
BeforeUpdate;
DoLayoutChanged;
end;
function TcxCustomTreeList.GetBandItemClass: TcxTreeListBandClass;
begin
Result := TcxTreeListBand;
end;
function TcxCustomTreeList.GetControllerClass: TcxCustomControlControllerClass;
begin
Result := TcxTreeListController;
end;
function TcxCustomTreeList.GetControlStylesClass: TcxCustomControlStylesClass;
begin
Result := TcxTreeListStyles;
end;
function TcxCustomTreeList.GetHitTestControllerClass: TcxHitTestControllerClass;
begin
Result := TcxTreeListHitTest;
end;
function TcxCustomTreeList.GetOptionsBehaviorClass: TcxControlOptionsBehaviorClass;
begin
Result := TcxTreeListOptionsBehavior;
end;
function TcxCustomTreeList.GetOptionsCustomizingClass:
TcxTreeListOptionsCustomizingClass;
begin
Result := TcxTreeListOptionsCustomizing;
end;
function TcxCustomTreeList.GetOptionsDataClass: TcxControlOptionsDataClass;
begin
Result := TcxTreeListOptionsData;
end;
function TcxCustomTreeList.GetOptionsSelectionClass: TcxTreeListOptionsSelectionClass;
begin
Result := TcxTreeListOptionsSelection;
end;
function TcxCustomTreeList.GetOptionsViewClass: TcxControlOptionsViewClass;
begin
Result := TcxTreeListOptionsView;
end;
function TcxCustomTreeList.GetPainterClass: TcxCustomControlPainterClass;
begin
Result := TcxTreeListPainter;
end;
function TcxCustomTreeList.GetPreviewClass: TcxTreeListPreviewClass;
begin
Result := TcxTreeListPreview;
end;
function TcxCustomTreeList.GetRootClass: TcxTreeListNodeClass;
begin
Result := TcxTreeListRootNode;
end;
function TcxCustomTreeList.GetSummaryClass: TcxTreeListSummaryClass;
begin
Result := TcxTreeListSummary;
end;
function TcxCustomTreeList.GetTreeListColumnClass: TcxTreeListColumnClass;
begin
Result := TcxTreeListColumn;
end;
function TcxCustomTreeList.GetTreeListCustomizingClass: TcxTreeListCustomizingClass;
begin
Result := TcxTreeListCustomizing;
end;
function TcxCustomTreeList.GetViewInfoClass: TcxCustomControlViewInfoClass;
begin
Result := TcxTreeListViewInfo;
end;
function TcxCustomTreeList.GetDataControllerClass: TcxCustomDataControllerClass;
begin
Result := TcxTreeListDataController;
end;
function TcxCustomTreeList.GetEditingControllerClass: TcxEditingControllerClass;
begin
Result := TcxTreeListEditingController;
end;
function TcxCustomTreeList.GetDefaultColumnContainer: TcxTreeListBand;
begin
if Bands.Count = 0 then
Result := Bands.Add
else
if Bands.BottomItemCount > 0 then
Result := Bands.BottomItems[0]
else
Result := Bands[0];
end;
function TcxCustomTreeList.GetSameColumn(AColumn: TcxTreeListColumn): TcxTreeListColumn;
begin
Result := nil;
if (AColumn <> nil) and cxInRange(AColumn.ID, 0, ContainerList.Count - 1) then
Result := ContainerList[AColumn.ID];
end;
function TcxCustomTreeList.GetStartNodeForBestFit: TcxTreeListNode;
begin
Result := nil;
if AbsoluteVisibleCount > 0 then
begin
if GetCountNodeForBestFit < 0 then
Result := AbsoluteVisibleItems[0]
else
Result := ViewInfo.TopNode
end;
end;
function TcxCustomTreeList.IsLocked: Boolean;
begin
Result := inherited IsLocked or IsTreeListLocked;
end;
function TcxCustomTreeList.IsTreeListLocked: Boolean;
begin
Result := (LockUpdate > 0) or ([csLoading, csDestroying, csUpdating, csReading] * ComponentState <> []);
end;
procedure TcxCustomTreeList.ImageChanged;
begin
if Painter is TcxTreeListPainter then
TcxTreeListPainter(Painter).Changed := True;
end;
procedure TcxCustomTreeList.ImagesChanged(Sender: TObject);
begin
Include(FChanges, tcImages);
LayoutChanged;
end;
procedure TcxCustomTreeList.InternalClearAll;
begin
InternalDelete(FAbsoluteItems);
end;
procedure TcxCustomTreeList.InternalCopy(
ANode, ADestNode: TcxTreeListNode);
var
ANewNode: TcxTreeListNode;
begin
ANewNode := AddNode(nil, ADestNode, nil, tlamAddChild);
ANewNode.AssignData(ANode);
ANode := ANode.GetFirstChild;
while ANode <> nil do
begin
InternalCopy(ANode, ANewNode);
ANode := ANode.FNext;
end;
end;
procedure TcxCustomTreeList.InternalDelete(ANodes: TList);
var
I: Integer;
begin
if ANodes.Count = 0 then Exit;
BeginUpdate;
try
ANodes.Sort(@cxCompareNodesByLevel);
for I := 0 to ANodes.Count - 1 do
TcxTreeListNode(ANodes[I]).InternalFree;
ANodes.Clear;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.InternalMove(
ANode, ADestNode: TcxTreeListNode; AMode: TcxTreeListNodeAttachMode);
begin
if (ANode = nil) or (ADestNode = nil) or ADestNode.HasAsParent(ANode) or
((ADestNode = ANode.Parent) and (AMode = tlamAddChild)) or (ANode = ADestNode) then Exit;
AddNodeInternal(ANode, ADestNode, AMode);
end;
procedure TcxCustomTreeList.InvalidateRectEx(
const R: TRect; EraseBackground: Boolean);
begin
ImageChanged;
inherited InvalidateRectEx(R, EraseBackground);
end;
function TcxCustomTreeList.IsNodeEdited(ANode: TcxTreeListNode): Boolean;
begin
Result := (DataController.EditingNode = ANode) and
(nsEditing in ANode.State);
end;
function TcxCustomTreeList.IsNodeInserting(ANode: TcxTreeListNode): Boolean;
begin
Result := (ANode <> nil) and (nsInserting in ANode.State);
end;
procedure TcxCustomTreeList.LookAndFeelChanged(
Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues);
begin
HideEdit;
ViewInfo.SetDirty;
inherited LookAndFeelChanged(Sender, AChangedValues);
end;
function TcxCustomTreeList.CanMultiSelect: Boolean;
begin
Result := OptionsSelection.MultiSelect;
end;
procedure TcxCustomTreeList.BeforeShowingEdit;
begin
with Controller do
SetFocusedRecordItem(FocusedRecordIndex, FocusedItem);
end;
procedure TcxCustomTreeList.DoClear;
begin
InternalClearAll;
end;
procedure TcxCustomTreeList.DoDeleteSelection;
var
AList: TList;
begin
if FocusedNode = nil then
Exit;
if FocusedNode.Inserting then
begin
DataController.Cancel;
Exit;
end;
BeginUpdate;
try
AList := GetSelectionsEx;
try
if AList.Count > 0 then
begin
AList.Sort(@cxCompareNodesByLevel);
DeleteNodes(AList);
end;
finally
FreeAndNil(AList);
end;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.DoDeleteNode(ANode: TcxTreeListNode);
begin
Controller.CheckDeletedNode(ANode);
if FTopVisibleNode = ANode then
begin
FTopVisibleNode := ANode.GetNextSiblingVisible;
if FTopVisibleNode = nil then
FTopVisibleNode := ANode.GetPrev;
DoTopRecordIndexChanged;
end;
DataController.FreeNodeRecord(ANode);
if HitTest.FHitNode = ANode then
HitTest.FHitNode := nil;
SelectionList.Remove(ANode);
if ANode = FDragNode then
FDragNode := nil;
end;
procedure TcxCustomTreeList.DoInternalMoveTo(AttachNode: TcxTreeListNode;
AttachMode: TcxTreeListNodeAttachMode; ANodes: TList; IsCopy: Boolean);
function CheckNodesList: Boolean;
var
I: Integer;
begin
I := 0;
while I < ANodes.Count do
begin
if TcxTreeListNode(ANodes[I]).CanMove(AttachNode, AttachMode) then
Inc(I)
else
ANodes.Delete(I);
end;
Result := ANodes.Count > 0;
end;
begin
if IsCopy and (AttachMode = tlamInsert) then
AttachNode := AttachNode.Parent;
if not CheckNodesList or DoMoveToEvent(AttachNode, AttachMode, ANodes, IsCopy) then Exit;
DoMoveTo(AttachNode, AttachMode, ANodes, IsCopy);
end;
procedure TcxCustomTreeList.DoMoveTo(AttachNode: TcxTreeListNode;
AttachMode: TcxTreeListNodeAttachMode; ANodes: TList; IsCopy: Boolean);
var
I: Integer;
begin
with ANodes do
begin
for I := Count - 1 downto 0 do
begin
if IsCopy then
InternalCopy(TcxTreeListNode(List^[I]), AttachNode)
else
InternalMove(TcxTreeListNode(List^[I]), AttachNode, AttachMode);
end;
end;
end;
procedure TcxCustomTreeList.DoOnBandSizeChanged(ABand: TcxTreeListBand);
begin
if Assigned(FOnBandSizeChanged) then
FOnBandSizeChanged(Self, ABand);
end;
procedure TcxCustomTreeList.DoOnColumnSizeChanged(
AColumn: TcxTreeListColumn);
begin
if Assigned(FOnColumnSizeChanged) then
FOnColumnSizeChanged(Self, AColumn);
end;
function TcxCustomTreeList.DoWriteHeaderToText: string;
var
I: Integer;
begin
Result := '';
for I := 0 to VisibleColumnCount - 1 do
begin
if I > 0 then
Result := Result + cxColumnTextSeparator;
Result := Result + VisibleColumns[I].Caption.Text;
end;
end;
function TcxCustomTreeList.DoWriteNodeToText(ANode: TcxTreeListNode): string;
var
I: Integer;
begin
Result := '';
for I := 0 to VisibleColumnCount - 1 do
begin
if Result <> '' then
Result := Result + cxColumnTextSeparator;
Result := Result + ANode.Texts[I];
end;
end;
procedure TcxCustomTreeList.DoWriteToClipboard(AOnlySelected: Boolean);
var
AText: string;
begin
if DoWriteToText(AOnlySelected, AText) then
ClipBoard.AsText := AText
end;
function TcxCustomTreeList.DoWriteToText(AOnlySelected: Boolean; out AText: string): Boolean;
var
ANode: TcxTreeListNode;
begin
ANode := Root.GetFirstChild;
if OptionsView.Headers then
AText := DoWriteHeaderToText
else
AText := '';
while ANode <> nil do
begin
if not AOnlySelected or ANode.Selected then
AText := AText + cxLineSeparator + DoWriteNodeToText(ANode);
ANode := ANode.GetNext;
end;
Result := AText <> '';
end;
procedure TcxCustomTreeList.DeleteNodes(AList: TList);
var
I: Integer;
begin
BeginUpdate;
try
for I := 0 to AList.Count - 1 do
TcxTreeListNode(AList[I]).Delete;
finally
EndUpdate;
end;
end;
function TcxCustomTreeList.GetCountNodeForBestFit: Integer;
begin
Result := -1;
end;
function TcxCustomTreeList.GetIsActive: Boolean;
begin
Result := Controller.Focused;
end;
function TcxCustomTreeList.GetFixedContentSize: Integer;
begin
Result := 0;
if (Bands.FirstVisible <> nil) and (Bands.FirstVisible.FixedKind = tlbfLeft) then
Inc(Result, Bands.FirstVisible.DisplayWidth);
if (Bands.LastVisible <> nil) and (Bands.LastVisible.FixedKind = tlbfRight) then
Inc(Result, Bands.LastVisible.DisplayWidth);
end;
function TcxCustomTreeList.GetMaxBandWidth(ABand: TcxTreeListBand): Integer;
begin
Result := MaxInt;
end;
function TcxCustomTreeList.GetMouseWheelScrollingKind: TcxMouseWheelScrollingKind;
begin
Result := mwskVertical;
end;
procedure TcxCustomTreeList.InitInsertingNode(ANode: TcxTreeListNode);
begin
ANode.MakeVisible;
ANode.Focused := True;
DataController.EditingNode := ANode;
end;
function TcxCustomTreeList.InsertNode(
ARelative: TcxTreeListNode; IsAppend: Boolean): Boolean;
var
ANode: TcxTreeListNode;
const
AMode: array[Boolean] of TcxTreeListNodeAttachMode = (tlamInsert, tlamAddChild);
begin
BeginUpdate;
try
ANode := ARelative;
if (ANode <> nil) and ANode.Inserting then
ANode := ANode.Parent;
IsAppend := IsAppend or (ANode = nil);
if (ARelative <> nil) and IsAppend then
ANode.LoadChildren;
if ANode = nil then
ANode := Root;
ANode := AddNode(nil, ANode, nil, AMode[IsAppend]);
Result := ANode <> nil;
if Result then
begin
if Result then
begin
InitInsertingNode(ANode);
Include(ANode.State, nsInserting);
end;
end;
DataController.IsValueChanged := False;
finally
EndUpdate;
end;
end;
procedure TcxCustomTreeList.MakeNodeVisible(ANode: TcxTreeListNode);
begin
if (ANode = nil) or not ANode.IsVisible then Exit;
if FTopVisibleNode = nil then
begin
FTopVisibleNode := ANode;
DoTopRecordIndexChanged;
ViewInfo.SetDirty;
end;
CheckChanges;
if ANode = TopVisibleNode then
ANode.Repaint(True)
else
begin
ViewInfo.Validate;
if not ANode.IsPrinted then
TopVisibleNode := ANode
else
ViewInfo.MakeVisible(ANode);
ImageChanged;
end;
end;
procedure TcxCustomTreeList.RestoreCursor;
begin
if not OptionsBehavior.ShowHourGlass then Exit;
Dec(FGlassCursorRefCount);
if FGlassCursorRefCount = 0 then
Screen.Cursor := FStoredCursor;
end;
procedure TcxCustomTreeList.SetGlassCursor;
begin
if not OptionsBehavior.ShowHourGlass then Exit;
if FGlassCursorRefCount = 0 then
begin
if OptionsBehavior.HotTrack and (Controller.HotTrackNode <> nil) then
FStoredCursor := Controller.PrevCursor
else
FStoredCursor := Screen.Cursor;
end;
if HandleAllocated and Visible then
Screen.Cursor := crHourGlass;
Inc(FGlassCursorRefCount);
end;
procedure TcxCustomTreeList.SortingStateChanged(
AColumn: TcxTreeListColumn; AShift: TShiftState);
begin
end;
function TcxCustomTreeList.SupportBandColumnEditor: Boolean;
begin
Result := True;
end;
function TcxCustomTreeList.SupportItemsEditor: Boolean;
begin
Result := False
end;
function TcxCustomTreeList.SupportCreateAllItems: Boolean;
begin
Result := False;
end;
procedure TcxCustomTreeList.CreateAllItems;
begin
end;
// IcxNavigator
procedure TcxCustomTreeList.RefreshNavigatorButtons;
begin
if not (IsLoading or IsDestroying) and (FNavigatorNotifier <> nil) then
FNavigatorNotifier.RefreshNavigatorButtons;
end;
procedure TcxCustomTreeList.DoAction(AButtonIndex: Integer);
begin
case AButtonIndex of
NBDI_FIRST:
GotoBOF;
NBDI_PRIORPAGE:
GotoPrevPage;
NBDI_PRIOR:
GotoPrev;
NBDI_NEXT:
GotoNext;
NBDI_NEXTPAGE:
GotoNextPage;
NBDI_LAST:
GotoEOF;
NBDI_INSERT:
if FocusedNode <> nil then
AddNode(nil, FocusedNode, nil, tlamInsert).Focused := True
else
AddNode(nil, Root, nil, tlamAdd).Focused := True;
NBDI_APPEND:
if FocusedNode <> nil then
AddNode(nil, FocusedNode.Parent, nil, tlamAdd).Focused := True
else
AddNode(nil, Root, nil, tlamAdd).Focused := True;
NBDI_DELETE:
Self.DeleteSelection;
NBDI_EDIT:
ShowEdit;
NBDI_POST:
DataController.Post;
NBDI_CANCEL:
begin
DataController.Cancel;
Controller.EditingController.UpdateEditValue;
end;
NBDI_REFRESH:
DataController.Refresh;
NBDI_SAVEBOOKMARK:
SaveBookmark;
NBDI_GOTOBOOKMARK:
GotoBookmark;
end;
end;
function TcxCustomTreeList.GetNotifier: TcxNavigatorControlNotifier;
begin
Result := FNavigatorNotifier;
end;
function TcxCustomTreeList.IsActionSupported(AButtonIndex: Integer): Boolean;
begin
Result := AButtonIndex in [NBDI_FIRST..NBDI_GOTOBOOKMARK];
end;
function TcxCustomTreeList.CanAppend: Boolean;
begin
Result := CanInsert;
end;
function TcxCustomTreeList.CanEdit: Boolean;
begin
Result := OptionsData.Editing and (HasData or CanInsert) and not IsEditing;
end;
function TcxCustomTreeList.CanDelete: Boolean;
begin
Result := OptionsData.Deleting and HasData;
end;
function TcxCustomTreeList.CanInsert: Boolean;
begin
Result := OptionsData.Inserting and ((FocusedNode <> nil) or not HasData);
end;
procedure TcxCustomTreeList.ClearBookmark;
begin
DataController.ClearBookmark;
end;
procedure TcxCustomTreeList.GotoBookmark;
begin
DataController.GotoBookmark;
end;
function TcxCustomTreeList.HasData: Boolean;
begin
Result := (VisibleColumnCount > 0) and (AbsoluteVisibleCount > 0);
end;
function TcxCustomTreeList.IsBookmarkAvailable: Boolean;
begin
Result := DataController.IsBookmarkAvailable and HasData;
end;
procedure TcxCustomTreeList.SaveBookmark;
begin
DataController.SaveBookmark;
end;
function TcxCustomTreeList.GetSelectionsEx: TList;
begin
Result := TList.Create;
GetSelections(Result);
if (FocusedNode <> nil) and not FocusedNode.Selected then
Result.Add(FocusedNode);
end;
function TcxCustomTreeList.GetOnEditing: TcxTreeListEditingEvent;
begin
Result := TcxTreeListEditingEvent(inherited OnEditing);
end;
function TcxCustomTreeList.GetOnEdited: TcxTreeListColumnChangedEvent;
begin
Result := TcxTreeListColumnChangedEvent(inherited OnEdited);
end;
function TcxCustomTreeList.GetOnEditValueChanged: TcxTreeListColumnChangedEvent;
begin
Result := TcxTreeListColumnChangedEvent(inherited OnEditValueChanged);
end;
function TcxCustomTreeList.GetSearching: Boolean;
begin
Result := Controller.IsIncSearching;
end;
function TcxCustomTreeList.GetSearchingText: string;
begin
Result := Controller.IncSearchText
end;
function TcxCustomTreeList.GetAvailableContentWidth: Integer;
begin
Result := ClientBounds.Right - ClientBounds.Left;
if Bands.VisibleLeftFixedCount > 0 then
Dec(Result, OptionsView.FixedSeparatorWidth);
if Bands.VisibleRightFixedCount > 0 then
Dec(Result, OptionsView.FixedSeparatorWidth);
if OptionsView.IsIndicatorVisible then
Dec(Result, OptionsView.IndicatorWidth);
if Result < 0 then
Result := 0;
end;
function TcxCustomTreeList.GetAbsoluteCount: Integer;
begin
CheckChanges;
Result := FAbsoluteItems.Count;
end;
function TcxCustomTreeList.GetAbsoluteItem(
AIndex: Integer): TcxTreeListNode;
begin
CheckChanges;
Result := TcxTreeListNode(FAbsoluteItems[AIndex]);
end;
function TcxCustomTreeList.GetAbsoluteItemsList: TList;
begin
CheckChanges;
Result := FAbsoluteItems;
end;
function TcxCustomTreeList.GetAbsoluteVisibleCount: Integer;
begin
CheckChanges;
Result := FAbsoluteVisibleItems.Count;
end;
function TcxCustomTreeList.GetAbsoluteVisibleItem(
AIndex: Integer): TcxTreeListNode;
begin
CheckChanges;
Result := TcxTreeListNode(FAbsoluteVisibleItems[AIndex]);
end;
function TcxCustomTreeList.GetAbsoluteVisibleItemsList: TList;
begin
CheckChanges;
Result := FAbsoluteVisibleItems;
end;
procedure TcxCustomTreeList.SetAbsoluteItem(
AIndex: Integer; AValue: TcxTreeListNode);
begin
AbsoluteItems[AIndex].Assign(AValue);
end;
procedure TcxCustomTreeList.SetAbsoluteVisibleItem(
AIndex: Integer; AValue: TcxTreeListNode);
begin
AbsoluteVisibleItems[AIndex].Assign(AValue);
end;
function TcxCustomTreeList.GetBands: TcxTreeListBands;
begin
Result := FBands;
end;
function TcxCustomTreeList.GetColumn(
AIndex: Integer): TcxTreeListColumn;
begin
Result := TcxTreeListColumn(ColumnsList[AIndex]);
end;
function TcxCustomTreeList.GetColumnCount: Integer;
begin
Result := ColumnsList.Count;
end;
function TcxCustomTreeList.GetColumnsList: TList;
begin
Result := ContainerList;
end;
function TcxCustomTreeList.GetController: TcxTreeListController;
begin
Result := TcxTreeListController(inherited Controller);
end;
function TcxCustomTreeList.GetCount: Integer;
begin
Result := Root.Count;
end;
function TcxCustomTreeList.GetDataController: TcxTreeListDataController;
begin
Result := TcxTreeListDataController(inherited DataController);
end;
function TcxCustomTreeList.GetDefaultRowHeight: Integer;
begin
Result := FDefaultRowHeight;
end;
function TcxCustomTreeList.GetFocusedColumn: TcxTreeListColumn;
begin
Result := TcxTreeListColumn(Controller.FocusedItem);
end;
function TcxCustomTreeList.GetFocusedNode: TcxTreeListNode;
begin
Result := Controller.FocusedNode;
end;
function TcxCustomTreeList.GetHitTest: TcxTreeListHitTest;
begin
Result := TcxTreeListHitTest(Controller.HitTestController);
end;
function TcxCustomTreeList.GetImages: TCustomImageList;
begin
Result := FDefaultLevelInfo.Images;
end;
function TcxCustomTreeList.GetLastNode: TcxTreeListNode;
begin
if AbsoluteVisibleCount > 0 then
Result := AbsoluteVisibleItems[AbsoluteVisibleCount - 1]
else
Result := nil;
end;
function TcxCustomTreeList.GetLastVisibleNode: TcxTreeListNode;
begin
ViewInfo.Validate;
Result := ViewInfo.LastNode;
end;
function TcxCustomTreeList.GetLevelInfo(
ALevel: Integer): TcxTreeListLevelInfo;
begin
Result := TcxTreeListLevelInfo(FLevelsInfo[ALevel]);
end;
function TcxCustomTreeList.GetNavigatorIsActive: Boolean;
begin
Result := DataController.Active;
end;
function TcxCustomTreeList.GetIndentWidth: Integer;
begin
CheckChanges;
if (ExpansionLevel < 0) or (Bands.ExpandableBand = nil) then
Result := 0
else
Result := LevelsInfo[ExpansionLevel].TotalWidth;
if OptionsView.CheckGroups then
Inc(Result, ViewInfo.CheckboxSize.cx)
end;
function TcxCustomTreeList.GetInplaceEditor: TcxCustomEdit;
begin
if IsEditing then
Result := Controller.EditingController.Edit
else
Result := nil;
end;
function TcxCustomTreeList.GetIsCancelOperation: Boolean;
begin
Result := FIsCancelOperation or (GetAsyncKeyState(VK_ESCAPE) < 0);
FIsCancelOperation := Result;
end;
function TcxCustomTreeList.GetIsEditing: Boolean;
begin
Result := Controller.IsEditing;
end;
function TcxCustomTreeList.GetIsInserting: Boolean;
begin
Result := IsNodeInserting(FocusedNode);
end;
function TcxCustomTreeList.GetItem(Index: Integer): TcxTreeListNode;
begin
Result := Root.Items[Index];
end;
function TcxCustomTreeList.GetOptionsBehavior: TcxTreeListOptionsBehavior;
begin
Result := TcxTreeListOptionsBehavior(inherited OptionsBehavior);
end;
function TcxCustomTreeList.GetOptionsData: TcxTreeListOptionsData;
begin
Result := TcxTreeListOptionsData(inherited OptionsData);
end;
function TcxCustomTreeList.GetOptionsView: TcxTreeListOptionsView;
begin
Result := TcxTreeListOptionsView(inherited OptionsView);
end;
function TcxCustomTreeList.GetSelection(AIndex: Integer): TcxTreeListNode;
begin
if (AIndex = 0) and not OptionsSelection.MultiSelect and (FocusedNode <> nil) then
Result := FocusedNode
else
Result := TcxTreeListNode(SelectionList[AIndex]);
end;
function TcxCustomTreeList.GetSelectionCount: Integer;
begin
Result := SelectionList.Count;
if not OptionsSelection.MultiSelect and (FocusedNode <> nil) then
Result := 1;
end;
function TcxCustomTreeList.GetSortedColumnCount: Integer;
begin
Result := FSortedColumns.Count;
end;
function TcxCustomTreeList.GetSortedColumn(
Index: Integer): TcxTreeListColumn;
begin
Result := TcxTreeListColumn(FSortedColumns[Index]);
end;
function TcxCustomTreeList.GetStateImages: TCustomImageList;
begin
Result := FDefaultLevelInfo.StateImages;
end;
function TcxCustomTreeList.GetStyles: TcxTreeListStyles;
begin
Result := TcxTreeListStyles(inherited Styles);
end;
function TcxCustomTreeList.GetSorted: Boolean;
begin
Result := FSortedColumns.Count > 0;
end;
function TcxCustomTreeList.GetTopNode: TcxTreeListNode;
begin
if AbsoluteVisibleCount > 0 then
Result := AbsoluteVisibleItems[0]
else
Result := nil;
end;
function TcxCustomTreeList.GetTopVisibleNode: TcxTreeListNode;
begin
Result := FTopVisibleNode;
if Result = nil then
Result := Root.getFirstChild;
if (Result <> nil) and (Result.IsHidden or not Result.IsVisible) then
begin
if Result.GetNextVisible <> nil then
Result := Result.GetNextVisible
else
if Result.GetPrevVisible <> nil then
Result := Result.GetPrevVisible;
end;
end;
function TcxCustomTreeList.GetVisibleCount: Integer;
begin
Result := ViewInfo.NodesVisibleCount;
end;
function TcxCustomTreeList.GetViewInfo: TcxTreeListViewInfo;
begin
Result := TcxTreeListViewInfo(inherited ViewInfo);
end;
function TcxCustomTreeList.GetVisibleColumn(
AIndex: Integer): TcxTreeListColumn;
begin
Result := TcxTreeListColumn(FVisibleColumns[AIndex]);
end;
function TcxCustomTreeList.GetVisibleColumnCount: Integer;
begin
Result := FVisibleColumns.Count;
end;
procedure TcxCustomTreeList.SetBands(Value: TcxTreeListBands);
begin
FBands.Assign(Value);
end;
procedure TcxCustomTreeList.SetColumn(
AIndex: Integer; Value: TcxTreeListColumn);
begin
TcxTreeListColumn(ColumnsList[AIndex]).Assign(Value);
end;
procedure TcxCustomTreeList.SetDefaultRowHeight(AValue: Integer);
begin
if AValue < 0 then
AValue := 0;
if AValue = DefaultRowHeight then Exit;
FDefaultRowHeight := AValue;
LayoutChanged;
end;
procedure TcxCustomTreeList.SetDefaultLayout(AValue: Boolean);
begin
if AValue <> FDefaultLayout then
begin
FDefaultLayout := AValue;
if AValue then
MakeDefaultLayout;
end;
end;
procedure TcxCustomTreeList.SetFocusedColumn(AValue: TcxTreeListColumn);
begin
if (AValue <> nil) and AValue.ActuallyVisible then
Controller.FocusedItem := AValue
else
if AValue = nil then
Controller.FocusedItem := AValue;
end;
procedure TcxCustomTreeList.SetFocusedNodeProp(Value: TcxTreeListNode);
begin
SetFocusedNode(Value, []);
end;
procedure TcxCustomTreeList.SetImages(AValue: TCustomImageList);
begin
FDefaultLevelInfo.Images := AValue;
end;
procedure TcxCustomTreeList.SetIsRestoring(AValue: Boolean);
begin
if FIsRestoring <> AValue then
begin
FIsRestoring := AValue;
if not FIsRestoring then
AssignItemsPosition;
end;
end;
procedure TcxCustomTreeList.SetLastVisibleNode(AValue: TcxTreeListNode);
begin
ViewInfo.LastNode := AValue;
LayoutChanged;
end;
procedure TcxCustomTreeList.SetOnEdited(Value: TcxTreeListColumnChangedEvent);
begin
inherited OnEdited := TcxecItemEvent(Value);
end;
procedure TcxCustomTreeList.SetOnEditing(Value: TcxTreeListEditingEvent);
begin
inherited OnEditing := TcxecEditingEvent(Value);
end;
procedure TcxCustomTreeList.SetOnEditValueChanged(
Value: TcxTreeListColumnChangedEvent);
begin
inherited OnEditValueChanged := TcxecItemEvent(Value);
end;
procedure TcxCustomTreeList.SetOptionsBehavior(
Value: TcxTreeListOptionsBehavior);
begin
OptionsBehavior.Assign(Value);
end;
procedure TcxCustomTreeList.SetOptionsCustomizing(
Value: TcxTreeListOptionsCustomizing);
begin
FOptionsCustomizing.Assign(Value);
end;
procedure TcxCustomTreeList.SetOptionsData(Value: TcxTreeListOptionsData);
begin
inherited OptionsData := Value;
end;
procedure TcxCustomTreeList.SetOptionsView(Value: TcxTreeListOptionsView);
begin
inherited OptionsView := Value;
end;
procedure TcxCustomTreeList.SetPopupMenus(Value: TcxTreeListPopupMenus);
begin
FPopupMenus.Assign(Value);
end;
procedure TcxCustomTreeList.SetOptionsSelection(
Value: TcxTreeListOptionsSelection);
begin
FOptionsSelection.Assign(Value);
end;
procedure TcxCustomTreeList.SetPreview(Value: TcxTreeListPreview);
begin
FPreview.Assign(Value);
end;
procedure TcxCustomTreeList.SetSearchingText(const Value: string);
begin
if Value = '' then
CancelSearching
else
Controller.IncSearchingText := Value
end;
procedure TcxCustomTreeList.SetSorted(Value: Boolean);
var
I: Integer;
begin
if not Value then
begin
for I := 0 to ColumnCount - 1 do
Columns[I].SortOrder := soNone;
end;
Root.AlphaSort(True);
end;
procedure TcxCustomTreeList.SetStateImages(AValue: TCustomImageList);
begin
FDefaultLevelInfo.StateImages := AValue;
end;
procedure TcxCustomTreeList.SetStyles(Value: TcxTreeListStyles);
begin
Styles.Assign(Value);
end;
procedure TcxCustomTreeList.SetTopVisibleNode(ANode: TcxTreeListNode);
begin
if (ANode <> TopVisibleNode) and (ANode <> nil) and ANode.IsVisible then
begin
FTopVisibleNode := ANode;
DoTopRecordIndexChanged;
LayoutChanged;
end;
end;
procedure TcxCustomTreeList.SetVisibleColumn(
Index: Integer; AValue: TcxTreeListColumn);
begin
VisibleColumns[Index].Assign(AValue);
end;
procedure TcxCustomTreeList.DoChangedTimer(Sender: TObject);
begin
if not IsDestroying and not IsLoading then
DoChanged(False);
end;
procedure TcxCustomTreeList.UpdateDesignerForms;
var
I: Integer;
AIntf: IcxTreeListDesigner;
begin
for I := 0 to Designers.Count - 1 do
if Supports(TObject(Designers[I]), IcxTreeListDesigner, AIntf) then
begin
if IsDestroying then
AIntf.ComponentRemoved(Self)
else
AIntf.ComponentModified;
end;
end;
function TcxCustomTreeList.GetObjectName: string;
begin
Result := GetStoredObjectName;
end;
function TcxCustomTreeList.GetProperties(AProperties: TStrings): Boolean;
begin
Result := GetStoredObjectProperties(AProperties);
end;
procedure TcxCustomTreeList.GetPropertyValue(
const AName: string; var AValue: Variant);
begin
GetStoredPropertyValue(AName, AValue);
end;
procedure TcxCustomTreeList.SetPropertyValue(
const AName: string; const AValue: Variant);
begin
SetStoredPropertyValue(AName, AValue);
end;
procedure TcxCustomTreeList.CMDrag(var Message: TCMDrag);
var
C: Integer;
const
AcceptedCursors: array[Boolean, Boolean] of TCursor =
((crDrag, crDragCopy), (crcxDragMulti, crcxMultiDragCopy));
begin
C := 0;
if Assigned(Controller.DragNodesList) then
C := Controller.DragNodesList.Count;
DragCursor := AcceptedCursors[C > 1,
Controller.IsDragCopy];
inherited;
end;
{ TcxTreeListController }
function TcxTreeListController.CheckAutoScrolling(
const APoint: TPoint): Boolean;
var
ASide: TcxBorder;
begin
Result := False;
for ASide := bLeft to bBottom do
Result := Result or ScrollControllers[ASide].Check(APoint);
end;
procedure TcxTreeListController.BeforeShowEdit;
begin
if not EditingController.IsEditing then
MakeFocusedItemVisible;
end;
procedure TcxTreeListController.CheckEdit;
begin
inherited CheckEdit;
TreeList.RefreshNavigatorButtons;
end;
procedure TcxTreeListController.CheckFocusedNodeItem;
begin
if FocusedNode = nil then
FocusedNode := FindNearestFocusableNode(0);
if FocusedItem = nil then
FocusedItem := FindNearestFocusableColumn(0);
end;
procedure TcxTreeListController.ChangeFocusedNode(ANode: TcxTreeListNode);
begin
if (ANode <> nil) and ANode.IsHidden or not TreeList.DoCanFocusNode(ANode) then Exit;
if ANode <> FFocusedNode then
begin
if (FFocusedNode <> nil) and FFocusedNode.Inserting and (TreeList.DataController.EditingNode = nil) then
DataController.Cancel
else
DataController.Post(True);
end;
TreeList.AddChanges([tcFocusedNode]);
if not OptionsSelection.MultiSelect then
TreeList.AddChanges([tcSelection]);
FPrevFocusedNode := FFocusedNode;
FFocusedNode := ANode;
TreeList.DataController.SyncFocused(FFocusedNode);
CancelIncSearching;
end;
function TcxTreeListController.GetFocusedRecordIndex: Integer;
begin
Result := Integer(FocusedNode);
end;
procedure TcxTreeListController.SetFocusedNode(ANode: TcxTreeListNode);
begin
if not TreeList.DoCanSelectNode(ANode) then Exit;
try
ChangeFocusedNode(ANode);
finally
if ANode <> nil then
ANode.MakeVisible;
TreeList.ViewInfo.UpdateSelection;
end;
end;
procedure TcxTreeListController.SetFocusedNodeItem(
ANode: TcxTreeListNode; AColumn: TcxTreeListColumn);
begin
SetFocusedRecordItem(Integer(ANode), AColumn);
end;
procedure TcxTreeListController.SetFocusedRecordIndex(Value: Integer);
begin
if TcxTreeListNode(Value) = FocusedNode then Exit;
if Value = 0 then
FocusedNode := nil
else
FocusedNode := TcxTreeListNode(Value);
end;
procedure TcxTreeListController.BeforeStartDrag;
begin
inherited BeforeStartDrag;
DragNodesList := TreeList.GetSelectionsEx;
if HitTest.HitAtNode and (HitTest.HitAtColumn or HitTest.HitAtIndicator or HitTest.HitAtImages) then
begin
DragNode := HitTest.HitNode;
if not TreeList.DoBeginDragNode(DragNode) then
DragNode := nil;
end
else
DragNode := nil;
end;
function TcxTreeListController.CreateAutoScrollObject(Kind: TScrollBarKind;
const ARect: TRect; ACode: TScrollCode): TcxAutoScrollingObject;
begin
Result := TcxControllerAutoScrollingObject.Create(Self);
Result.SetParams(ARect, Kind, ACode, 1);
end;
procedure TcxTreeListController.CheckButtonTimer;
var
NeedTimer: Boolean;
begin
if (ExpandingNode <> HitTest.HitNode) or not HitTest.HitAtButton then
ResetButtonTimer;
if ExpandingNode = nil then
begin
NeedTimer := HitTest.HitAtButton and
(OptionsBehavior.DragExpand and not HitTest.HitNode.Expanded) or
(OptionsBehavior.DragCollapse and HitTest.HitNode.Expanded);
if NeedTimer then
begin
ExpandTimer.Interval := OptionsBehavior.WaitForExpandNodeTime;
ExpandTimer.Enabled := True;
ExpandTimer.OnTimer := OnExpandTimer;
ExpandingNode := HitTest.HitNode;
end;
end;
end;
procedure TcxTreeListController.DragDrop(Source: TObject; X, Y: Integer);
begin
with TreeList, HitTest do
begin
BeginUpdate;
try
if Source is TBaseDragControlObject then
Source := TBaseDragControlObject(Source).Control;
if (Source = TreeList) and HitAtNode then
DropTo(HitNode, HitAtNodePreview or HitAtColumn);
if FocusedNode <> nil then
FocusedNode.MakeVisible;
finally
EndUpdate;
end;
end;
end;
procedure TcxTreeListController.DragEnter;
var
R: TRect;
begin
if DragDropInProcess then Exit;
if TreeList.FDragNode = nil then
TreeList.FDragNode := TreeList.FocusedNode;
R := TreeList.ViewInfo.ContentBounds;
ScrollControllers[bTop] := CreateAutoScrollObject(sbVertical,
cxRectSetHeight(R, cxtlScrollDelta * 2), scLineUp);
ScrollControllers[bBottom] := CreateAutoScrollObject(sbVertical,
cxRectSetTop(R, R.Bottom - cxtlScrollDelta * 2), scLineDown);
if (TreeList.Bands.ExpandableBand <> nil) and (TreeList.Bands.ExpandableBand.FixedKind = tlbfNone) then
begin
R.Left := TreeList.ViewInfo.ContentParts[tlbfNone].Left;
R.Bottom := TreeList.ViewInfo.ContentParts[tlbfNone].Bottom
end;
ScrollControllers[bLeft] := CreateAutoScrollObject(sbHorizontal,
cxRectSetWidth(R, cxtlScrollDelta * 2), scLineUp);
ScrollControllers[bRight] := CreateAutoScrollObject(sbHorizontal,
cxRectSetWidth(R, R.Right - cxtlScrollDelta * 2, cxtlScrollDelta * 2), scLineDown);
ExpandTimer := TTimer.Create(TreeList);
end;
procedure TcxTreeListController.DragLeave;
var
ASide: TcxBorder;
begin
for ASide := bLeft to bBottom do
FreeAndNil(ScrollControllers[ASide]);
FreeAndNil(ExpandTimer);
DragDropInProcess := False;
end;
procedure TcxTreeListController.DragMove(
Source: TObject; const P: TPoint; var Accepted: Boolean);
procedure ProcessDragMove;
begin
HitTest.Recalculate(P);
if HitTest.HitAtButton then
CheckButtonTimer
else
ExpandingNode := nil;
CheckAutoScrolling(P);
end;
begin
ProcessDragMove;
HitTest.ReCalculate(P);
with TreeList.OptionsBehavior do
begin
if HitTest.HitAtNode and DragFocusing and not HitTest.HitNode.Focused then
HitTest.HitNode.Focused := True;
end;
end;
procedure TcxTreeListController.DragOver(
Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
case State of
dsDragEnter:
DragEnter;
dsDragLeave:
DragLeave;
dsDragMove:
DragMove(Source, Point(X, Y), Accept);
end;
inherited DragOver(Source, X, Y, State, Accept);
end;
procedure TcxTreeListController.DropTo(
ANode: TcxTreeListNode; AsChildren: Boolean);
const
AModes: array[Boolean] of TcxTreeListNodeAttachMode = (tlamInsert, tlamAddChild);
begin
if ANode <> nil then
begin
if TreeList.OptionsBehavior.DragFocusing and
(DragNodesList.IndexOf(TreeList.DragNode) = cxInvalidIndex) then
DragNodesList.Add(TreeList.DragNode);
try
TreeList.DoInternalMoveTo(ANode,
AModes[AsChildren], DragNodesList, TreeList.Controller.IsDragCopy);
finally
FreeAndNil(DragNodesList);
TreeList.Controller.CancelSelection;
end;
end;
end;
procedure TcxTreeListController.EndDrag(Target: TObject; X, Y: Integer);
begin
HitTestController.ReCalculate(Point(X, Y));
if (GetAsyncKeyState(VK_SHIFT) >= 0) and not IsCtrlPressed then
CancelSelection;
if TreeList.OptionsBehavior.AlwaysShowEditor or TreeList.OptionsBehavior.ImmediateEditor and
((FocusedItem <> nil) and (FocusedNode <> nil)) then EditingController.ShowEdit();
FreeAndNil(DragNodesList);
end;
procedure TcxTreeListController.OnExpandTimer(Sender: TObject);
begin
ResetButtonTimer;
if HitTest.HitAtButton and (HitTest.HitNode = ExpandingNode) then
ExpandingNode.Expanded := not ExpandingNode.Expanded
else
ExpandingNode := nil;
end;
procedure TcxTreeListController.ResetButtonTimer;
begin
if ExpandTimer <> nil then
ExpandTimer.Enabled := False;
end;
procedure TcxTreeListController.DoNextNode(AForward: Boolean);
begin
if (FocusedNode <> nil) and (FocusedNode.GetNextVisibleEx(AForward) <> nil) then
FocusedNode := FocusedNode.GetNextVisibleEx(AForward);
end;
procedure TcxTreeListController.DoNextPage(AForward: Boolean; Shift: TShiftState);
begin
DoShowNextPageEx(AForward, True, Shift);
TreeList.Controller.CheckEdit;
TreeList.Update;
end;
procedure TcxTreeListController.DoShowNextPageEx(
AGoForward, ASetCursor: Boolean; AShift: TShiftState);
function GetNext(ANode: TcxTreeListNode; IsNext: Boolean): TcxTreeListNode;
begin
Result := ANode;
if (ANode <> nil) and (TreeList.VisibleCount = 1) then
Result := ANode.GetNextVisibleEx(not IsNext);
end;
begin
if AGoForward then
begin
if (TreeList.LastVisibleNode <> nil) and TreeList.LastVisibleNode.IsLastVisible and
TreeList.LastVisibleNode.Focused and ASetCursor then Exit;
if ASetCursor then
begin
TreeList.TopVisibleNode := GetNext(FocusedNode, True);
TreeList.SetFocusedNode(TreeList.LastVisibleNode, AShift)
end
else
TreeList.TopVisibleNode := GetNext(TreeList.LastVisibleNode, True);
end
else
begin
if (TreeList.TopVisibleNode <> nil) and TreeList.TopVisibleNode.IsFirstVisible and
TreeList.TopVisibleNode.Focused and ASetCursor then Exit;
if ASetCursor then
begin
TreeList.LastVisibleNode := GetNext(FocusedNode, False);
TreeList.SetFocusedNode(TreeList.TopVisibleNode, AShift)
end
else
TreeList.LastVisibleNode := GetNext(TreeList.TopVisibleNode, False);
end;
TreeList.LayoutChanged;
end;
procedure TcxTreeListController.FocusedRecordChanged(
APrevFocusedRecordIndex, AFocusedRecordIndex: Integer);
begin
if AFocusedRecordIndex <> FocusedRecordIndex then
CancelSelection(True);
end;
procedure TcxTreeListController.FocusedItemChanged(
APrevFocusedItem: TcxCustomInplaceEditContainer);
begin
inherited FocusedItemChanged(APrevFocusedItem);
TreeList.ViewInfo.UpdateSelection;
TreeList.DoFocusedItemChanged(APrevFocusedItem, FocusedItem);
end;
function TcxTreeListController.IsKeyForController(
AKey: Word; AShift: TShiftState): Boolean;
begin
Result := (AKey = VK_ADD) or (AKey = VK_SUBTRACT) or (AKey = VK_MULTIPLY) or
(AKey = VK_HOME) or (AKey = VK_END);
Result := inherited IsKeyForController(AKey, AShift) or
((IsEditing and (ssCtrl in AShift) and Result) or (not IsEditing and Result));
end;
function TcxTreeListController.IsNodeKeyHandle(ANode: TcxTreeListNode;
var AKey: Word; Shift: TShiftState): Boolean;
begin
Result := True;
case AKey of
VK_SUBTRACT, VK_ADD:
if (IncSearchText = '') and (ANode <> nil) and ANode.HasChildren then
ANode.Expanded := AKey = VK_ADD
else
Result := False;
VK_MULTIPLY:
if (ANode <> nil) and ANode.HasChildren then
ANode.Expand(AKey = VK_MULTIPLY);
VK_HOME:
begin
if ssCtrl in Shift then
TreeList.Select(TreeList.TopNode, Shift)
else
if TreeList.VisibleColumnCount > 0 then
TreeList.VisibleColumns[0].Focused := True
else
Result := False;
end;
VK_SPACE:
if ANode.HasCheckbox and ANode.Enabled then
ANode.CheckClick
else
Result := False;
VK_END:
begin
if ssCtrl in Shift then
TreeList.Select(TreeList.LastNode, Shift)
else
if TreeList.VisibleColumnCount > 0 then
TreeList.VisibleColumns[TreeList.VisibleColumnCount - 1].Focused := True
else
Result := False;
end;
VK_DELETE:
begin
Result := (ssCtrl in Shift) and
CanDeleteSelection and DeleteConfirmation;
if Result then
TreeList.DeleteSelection;
end;
VK_INSERT:
begin
if (FocusedNode = nil) or (not CanInsertNode) then
Result := False
else
TreeList.InsertNode(FocusedNode, ssCtrl in Shift);
end;
else
Result := False
end;
end;
function TcxTreeListController.CanDrag(X, Y: Integer): Boolean;
begin
HitTest.HitPoint := Point(X, Y);
Result := not HitTest.CanSizing and not TreeList.IsDesigning and not IsEditing and
(HitTest.HitAtNode and HitTest.HitNode.Selected and not HitTest.HitAtIndent and
not HitTest.HitAtFooterArea);
if Result then
TreeList.FDragNode := HitTest.HitNode;
end;
procedure TcxTreeListController.AfterPaint;
begin
inherited AfterPaint;
if (TreeList.DragAndDropState = ddsInProcess) and
(TreeList.DragAndDropObject is TcxTreeListSizingDragAndDropObject) then
TcxTreeListSizingDragAndDropObject(TreeList.DragAndDropObject).DirtyChanged;
end;
procedure TcxTreeListController.BeginDragAndDrop;
begin
inherited BeginDragAndDrop;
TreeList.Update;
end;
function TcxTreeListController.DoHeaderMouseDown(
Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean;
begin
Result := False;
if CheckCustomizationPopup then
HitTest.RecalculateOnMouseEvent(X, Y, Shift)
else
begin
if HitTest.HitAtHeader and not HitTest.CanSizing and
not (ssDouble in Shift) and (Button = mbLeft) then
FClickedObject := TcxTreeListHeaderCellViewInfo(HitTest.HitTestItem).Item;
if HitTest.HitAtHeader and not HitTest.CanSizing and
(ClickedObject = TcxTreeListHeaderCellViewInfo(HitTest.HitTestItem).Item) then
begin
TcxTreeListCustomHeaderCellViewInfo(HitTest.HitTestItem).Pressed := True;
Result := True;
end;
end;
end;
function TcxTreeListController.DoNodeMouseDown(
Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean;
begin
Result := False;
if CanDrag(X, Y) and HitTest.HitAtNode and IsEditing then
TreeList.DragAndDropState := ddsNone;
if not (ssDouble in Shift) then
CheckNodeContentClick(Shift);
if HitTest.HitAtCheckButton and (Button = mbLeft) then
HitTest.HitNode.CheckClick
else
if HitTest.HitAtButton and (Button = mbLeft) then
begin
HitTest.HitNode.Expanded := not HitTest.HitNode.Expanded;
Result := True;
end;
end;
procedure TcxTreeListController.DoMouseDown(
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
AIsHotTrack: Boolean;
begin
inherited MouseDown(Button, Shift, X, Y);
EditingController.StopEditShowingTimer;
EditingController.HideEdit(True);
HitTest.RecalculateOnMouseEvent(X, Y, Shift);
HitTest.CheckSelection(Shift);
AIsHotTrack := HitTest.HitAtColumn and not HitTest.HitAtNodePreview and
HitTest.IsItemEditCell and TcxTreeListEditCellViewInfo(HitTest.HitTestItem).IsEditHotTrack(Point(X, Y));
if not DoHeaderMouseDown(Button, Shift, X, Y) and not HitTest.CanSizing then
DoNodeMouseDown(Button, Shift, X, Y);
WasFocusedBeforeClick := HitTest.HitAtColumn and not HitTest.HitAtNodePreview and
HitTest.HitAtNode and HitTest.HitNode.Focused and HitTest.HitColumn.Focused;
if AIsHotTrack then
ShowEdit(Shift, X, Y);
end;
procedure TcxTreeListController.DoMouseMove(
Shift: TShiftState; X, Y: Integer);
begin
inherited DoMouseMove(Shift, X, Y);
UpdateHotTrackNode(X, Y, Shift);
end;
procedure TcxTreeListController.DoMouseUp(
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if PressedHeader <> nil then
PressedHeader.Pressed := False;
HitTest.RecalculateOnMouseEvent(X, Y, Shift);
DragItem := nil;
HotTrackController.SetHotElement(nil, cxNullPoint);
UpdateHotTrackNode(X, Y, Shift);
if Button = mbLeft then
CheckHeaderClick(Shift);
ClickedObject := nil;
(Navigator as TcxTreeListCellNavigator).SaveCurrentNavigationColumn;
HitTest.RecalculateOnMouseEvent(X, Y, Shift);
if not IsEditing and WasFocusedBeforeClick and (HitTest.HitNode = TreeList.FocusedNode) then
begin
if GetImmediateEditor then
ShowEdit(Shift, X, Y)
else
EditingController.StartEditShowingTimer(HitTest.HitColumn);
end;
inherited MouseUp(Button, Shift, X, Y);
end;
procedure TcxTreeListController.CheckDeletedNode(ANode: TcxTreeListNode);
begin
if ANode = HotTrackNode then
SetHotTrackNode(nil, []);
if DragNodesList <> nil then
DragNodesList.Remove(ANode);
if ANode = FPrevFocusedNode then
FPrevFocusedNode := nil;
if ANode = IncSearchNode then
IncSearchNode := nil;
if ANode = FSelectionAnchor then
FSelectionAnchor := nil;
if (ANode = FFocusedNode) and (FFocusedNode <> nil) then
begin
FocusedNodeIndex := FFocusedNode.VisibleIndex;
FFocusedNode := nil;
TreeList.AddChanges([tcSelection, tcFocusedNode]);
end;
end;
procedure TcxTreeListController.CheckFocusedNode;
begin
if FocusedNode = nil then
ChangeFocusedNode(FindNearestFocusableNode(FocusedNodeIndex));
end;
procedure TcxTreeListController.CheckHeaderClick(AShift: TShiftState);
const
ASortOrder: array[Boolean, TcxDataSortOrder] of TcxDataSortOrder =
((soAscending, soDescending, soAscending), (soNone, soNone, soNone));
begin
if not HitTest.HitAtColumnHeader or HitTest.CanSizing or
TreeList.IsDesigning or (ClickedObject <> HitTest.HitColumn) then Exit;
TreeList.SetGlassCursor;
try
HitTest.HitColumn.ChangeSortOrder(ASortOrder[ssCtrl in AShift,
HitTest.HitColumn.SortOrder], AShift);
finally
TreeList.RestoreCursor;
end;
end;
procedure TcxTreeListController.CheckNodeContentClick(Shift: TShiftState);
begin
if HitAtNodeContent then
begin
TreeList.BeginUpdate;
try
if HitTest.HitAtColumn then
FocusedItem := FindNearestFocusableColumn(HitTest.HitColumn.VisibleIndex);
if FocusedItem = nil then
FocusedItem := FindNearestFocusableColumn(0);
Select(HitTest.HitNode, Shift)
finally
TreeList.CancelUpdate;
end;
end
else
if HitTest.HitAtBackground then
CancelSelection;
end;
function TcxTreeListController.CanDeleteSelection: Boolean;
begin
Result := TreeList.OptionsData.Deleting and not TreeList.IsEditing;
end;
function TcxTreeListController.CanInsertNode: Boolean;
begin
Result := TreeList.OptionsData.Inserting;
if not Result then Exit;
Result := (DataController.EditingNode = nil) or
(DataController.EditingNode.Inserting and DataController.IsValueChanged);
if Result then
DataController.Post;
end;
function TcxTreeListController.CanSelectNode(
ANode: TcxTreeListNode): Boolean;
begin
Result := TreeList.DoCanFocusNode(ANode) and TreeList.DoCanSelectNode(ANode);
end;
function TcxTreeListController.CheckCustomizationPopup: Boolean;
begin
Result := (HitTest.HitAtBandCustomizing or HitTest.HitAtColumnCustomizing) and
TcxTreeListIndicatorCellViewInfo(HitTest.HitTestItem).IsQuickCustomizationEnabled and
not (ColumnsCustomizationPopup.JustClosed or BandsCustomizationPopup.JustClosed);
if Result then
TcxTreeListIndicatorCellViewInfo(HitTest.HitTestItem).ShowPopup;
end;
procedure TcxTreeListController.DblClick;
begin
if IsEditing and (FocusedNode <> nil) and FocusedNode.HasChildren then
EditingController.HideEdit(True);
EditingController.StopEditShowingTimer;
inherited DblClick;
HitTest.Recalculate;
if HitTest.HitAtNode and not (HitTest.HitAtButton or HitTest.HitAtFooterArea or
HitTest.HitAtCheckButton or IsEditing) and OptionsBehavior.ExpandOnDblClick then
HitTest.HitNode.Expanded := not HitTest.HitNode.Expanded;
if HitTest.HitAtSizingHorz then
begin
if HitTest.HitAtBandHeader then
HitTest.HitBand.ApplyBestFit
else
HitTest.HitColumn.ApplyBestFit;
end;
ClickedObject := nil;
end;
function TcxTreeListController.FindNearestFocusableNode(
AVisibleIndex: Integer): TcxTreeListNode;
begin
Result := nil;
if TreeList.AbsoluteVisibleCount <= 0 then Exit;
AVisibleIndex := Max(0, Min(TreeList.AbsoluteVisibleCount - 1, AVisibleIndex));
Result := TreeList.AbsoluteVisibleItems[AVisibleIndex];
while (Result <> nil) and not TreeList.DoCanFocusNode(Result) do
Result := Result.GetNextVisible;
if Result <> nil then Exit;
Result := TreeList.AbsoluteVisibleItems[AVisibleIndex];
while (Result <> nil) and not TreeList.DoCanFocusNode(Result) do
Result := Result.GetPrevVisible;
end;
function TcxTreeListController.FindNearestFocusableColumn(
AVisibleIndex: Integer): TcxTreeListColumn;
var
I: Integer;
begin
Result := nil;
AVisibleIndex := Max(0, Min(AVisibleIndex, TreeList.VisibleColumnCount - 1));
if AVisibleIndex < TreeList.VisibleColumnCount then
begin
for I := AVisibleIndex to TreeList.VisibleColumnCount - 1 do
if TreeList.VisibleColumns[I].Options.Focusing then
begin
Result := TreeList.VisibleColumns[I];
Exit;
end;
for I := AVisibleIndex downto 0 do
if TreeList.VisibleColumns[I].Options.Focusing then
begin
Result := TreeList.VisibleColumns[I];
Break;
end;
end;
end;
procedure TcxTreeListController.EndDragAndDrop(Accepted: Boolean);
begin
inherited EndDragAndDrop(Accepted);
end;
function TcxTreeListController.DeleteConfirmation: Boolean;
begin
if TreeList.OptionsBehavior.ConfirmDelete then
Result := cxConfirmMessageBox(
cxGetResourceString(@scxTreeListDeletingFocusedConfirmationText),
cxGetResourceString(@scxTreeListDeletingConfirmationCaption))
else
Result := True;
end;
function TcxTreeListController.GetCursor(X, Y: Integer): TCursor;
begin
Result := crDefault;
if not TreeList.IsDesigning and not (TreeList.FGlassCursorRefCount > 0) then
begin
HitTest.HitPoint := Point(X, Y);
Result := HitTest.Cursor;
end;
end;
function TcxTreeListController.GetDragAndDropObjectClass: TcxDragAndDropObjectClass;
const
HeaderDragObject: array[Boolean] of TcxDragAndDropObjectClass =
(TcxTreeListDragAndDropBandObject, TcxTreeListDragAndDropColumnObject);
begin
DragItem := HitTest.DragItem;
if HitTest.CanSizing then
begin
FResizeDirection := TcxDragSizingDirection(HitTest.HitAtSizingVert);
Result := TcxTreeListSizingDragAndDropObject;
end
else
if HitTest.CanMoving then
Result := HeaderDragObject[HitTest.HitAtColumnHeader]
else
if HitTest.HitAtNode then
Result := nil
else
Result := inherited GetDragAndDropObjectClass;
end;
function TcxTreeListController.HitAtNodeContent: Boolean;
begin
Result := HitTest.HitAtNode and (HitTest.HitAtIndicator or HitTest.HitAtImages or
HitTest.HitAtColumn or HitTest.HitAtBand or HitTest.HitAtNodePreview) and
not HitTest.HitAtFooterArea;
end;
procedure TcxTreeListController.KeyDown(var Key: Word;
Shift: TShiftState);
var
AKey: Word;
APrevNode: TcxTreeListNode;
begin
AKey := Key;
EatKeyPress := IsNodeKeyHandle(FocusedNode, Key, Shift);
CheckFocusedNodeItem;
if (AKey = VK_SPACE) and (FocusedNode <> nil) and
OptionsSelection.MultiSelect and ([ssCtrl, ssShift] * Shift <> []) then
begin
if (ssCtrl in Shift) then
begin
FocusedNode.Selected := not FocusedNode.Selected;
if FocusedNode.Selected then
FSelectionAnchor := FocusedNode;
end
else
Select(FocusedNode, Shift);
Key := 0;
end;
if (TreeList.VisibleColumnCount = 1) and (FocusedNode <> nil) and (FocusedNode.HasChildren) and
(((Key = VK_LEFT) and FocusedNode.Expanded) or ((Key = VK_RIGHT) and not FocusedNode.Expanded)) then
begin
FocusedNode.Expanded := not FocusedNode.Expanded;
Key := 0;
end;
inherited KeyDown(Key, Shift);
case AKey of
VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_NEXT, VK_PRIOR, VK_HOME, VK_END:
begin
if Key in [VK_NEXT, VK_PRIOR, VK_HOME, VK_END] then
begin
APrevNode := SelectionAnchor;
Selection.Clear;
if (SelectionAnchor <> nil) then
Selection.Add(SelectionAnchor);
Select(FocusedNode, Shift);
SelectionAnchor := APrevNode;
end
else
Select(FocusedNode, Shift);
end;
VK_MENU, VK_SHIFT, VK_CONTROL:
begin
if SelectionAnchor = nil then
SelectionAnchor := FocusedNode;
SetHotTrackNode(HotTrackNode, Shift);
end;
end;
end;
procedure TcxTreeListController.KeyUp(var Key: Word; Shift: TShiftState);
begin
inherited KeyUp(Key, Shift);
case Key of
VK_MENU, VK_SHIFT, VK_CONTROL:
SetHotTrackNode(HotTrackNode, Shift);
end;
end;
procedure TcxTreeListController.MakeFocusedItemVisible;
var
AColumn: TcxTreeListColumn;
begin
AColumn := TcxTreeListColumn(FocusedItem);
if AColumn <> nil then
begin
AColumn.MakeVisible;
if not TreeList.IsLocked then
MakeFocusedRecordVisible;
end;
end;
procedure TcxTreeListController.MakeFocusedRecordVisible;
begin
if FocusedNode <> nil then
FocusedNode.MakeVisible;
end;
procedure TcxTreeListController.Reset;
begin
FPressedHeader := nil;
ClickedObject := nil;
end;
procedure TcxTreeListController.Scroll(AScrollBarKind: TScrollBarKind;
AScrollCode: TScrollCode; var AScrollPos: Integer);
begin
if TreeList.IsLocked or (AScrollCode = scEndScroll) then Exit;
EditingController.StopEditShowingTimer;
if AScrollBarKind = sbHorizontal then
TreeList.ViewInfo.ScrollHorz(AScrollCode, AScrollPos)
else
TreeList.ViewInfo.ScrollVert(AScrollCode, AScrollPos);
UpdateHotTrackNode([]);
TreeList.ViewInfo.IsDirty := False;
TreeList.UpdateScrollBars;
end;
procedure TcxTreeListController.SetSelection(AList: TList);
var
AHelper: TcxCustomDesignSelectionHelper;
begin
if not CanCreateSelectionHelper then Exit;
AHelper := cxDesignSelectionHelperClass.Create(TreeList);
try
AHelper.SetSelection(AList);
finally
AHelper.Free;
end;
end;
procedure TcxTreeListController.SetFocusedRecordItem(ARecordIndex: Integer;
AItem: TcxCustomInplaceEditContainer);
begin
if AItem = TreeList.Preview.Column then
AItem := FocusedItem;
if not TreeList.Dragging then
inherited SetFocusedRecordItem(ARecordIndex, AItem);
end;
procedure TcxTreeListController.SetHotTrackCursor(ACursor: TCursor);
begin
TreeList.Cursor := ACursor;
end;
procedure TcxTreeListController.SetHotTrackNode(
ANode: TcxTreeListNode; AShift: TShiftState);
var
ACursor: TCursor;
APrevNode: TcxTreeListNode;
begin
if not TreeList.Focused or TreeList.HitTest.CanSizing then
ANode := nil;
if (TreeList.IsDestroying or not TreeList.OptionsBehavior.HotTrack) or
((ANode = HotTrackNode) and (HotTrackColumn = HitTest.HitColumn)) then Exit;
APrevNode := HotTrackNode;
HotTrackNode := ANode;
HotTrackColumn := HitTest.HitColumn;
HotTrackShift := AShift;
if APrevNode <> nil then
APrevNode.Repaint(True)
else
begin
if TreeList.FGlassCursorRefCount > 0 then
PrevCursor := TreeList.FStoredCursor
else
PrevCursor := TreeList.Cursor;
end;
if ANode <> nil then
begin
ANode.Repaint(True);
TreeList.DoHotTrackNode(ANode, AShift, ACursor);
SetHotTrackCursor(ACursor);
end
else
SetHotTrackCursor(PrevCursor);
end;
procedure TcxTreeListController.ShowEdit(AShift: TShiftState; X, Y: Integer);
begin
if FocusedItem = nil then Exit;
WasFocusedBeforeClick := False;
EditingController.ShowEdit(FocusedItem, [ssLeft] * AShift, X, Y);
end;
function TcxTreeListController.StartDragAndDrop(const P: TPoint): Boolean;
begin
HitTest.HitPoint := P;
Result := HitTest.CanSizing or HitTest.CanMoving;
//and not (HitTest.HitAtNode and HitTest.HitNode.Selected and not HitTest.HitAtIndent);
end;
procedure TcxTreeListController.UpdateHotTrackNode(AShift: TShiftState);
begin
with HitTest.HitPoint do
UpdateHotTrackNode(X, Y, AShift);
end;
procedure TcxTreeListController.UpdateHotTrackNode(X, Y: Integer; AShift: TShiftState);
begin
HitTest.RecalculateOnMouseEvent(X, Y, AShift);
if HitTest.HitAtNode and not HitTest.HitAtFooterArea then
SetHottrackNode(HitTest.HitNode, AShift)
else
SetHottrackNode(nil, AShift);
end;
function TcxTreeListController.GetFocusedCellViewInfo(
AEditContainer: TcxCustomInplaceEditContainer): TcxEditCellViewInfo;
begin
Result := nil;
if (AEditContainer = nil) or TreeList.ViewInfo.IsDirty then Exit;
Result := TreeList.ViewInfo.GetEditCell(FocusedNode, TcxTreeListColumn(AEditContainer));
end;
function TcxTreeListController.GetNavigatorClass: TcxCustomCellNavigatorClass;
begin
Result := TcxTreeListCellNavigator;
end;
function TcxTreeListController.GetNode(ARecordIndex: Integer): TcxTreeListNode;
begin
if ARecordIndex >= 0 then
Result := TcxTreeListNode(ARecordIndex)
else
Result := nil;
end;
procedure TcxTreeListController.CancelIncSearching;
begin
if TreeList.IsDestroying or TreeList.IsLoading or
(IncSearchNode = nil) or SearchNotification then Exit;
IncSearchText := '';
IncSearchNode := nil;
inherited CancelIncSearching;
end;
function TcxTreeListController.DoSearch(AFromNode: TcxTreeListNode;
AItemIndex: Integer; const AText: string; AGoForward: Boolean): Boolean;
function DoSearchNode(AForward: Boolean; var ANode: TcxTreeListNode): Boolean;
begin
Result := False;
ANode := AFromNode;
while not Result and (ANode <> nil) do
begin
Result := ANode.Visible and
DataCompareText(ANode.Texts[AItemIndex], AText, True);
if not Result then
ANode := GetNextNodeForIncSearch(ANode, AForward);
end;
end;
var
ANode: TcxTreeListNode;
begin
EditingController.StopEditShowingTimer;
Result := DoSearchNode(AGoForward, ANode);
if not Result then
Result := DoSearchNode(not AGoForward, ANode);
if Result then
IncSearchNode := ANode;
end;
function TcxTreeListController.GetIncSearchingItem: TcxCustomInplaceEditContainer;
begin
Result := TreeList.OptionsBehavior.IncSearchItem;
if Result = nil then
Result := TreeList.FocusedColumn;
end;
function TcxTreeListController.GetIncSearchingText: string;
begin
Result := IncSearchText;
end;
function TcxTreeListController.GetIsIncSearching: Boolean;
begin
Result := IncSearchText <> '';
end;
function TcxTreeListController.GetNextNodeForIncSearch(
ANode: TcxTreeListNode; AGoForward: Boolean): TcxTreeListNode;
begin
Result := nil;
if TreeList.OptionsBehavior.ExpandOnIncSearch then
begin
if AGoForward then
begin
ANode.LoadChildren;
Result := ANode.GetNext
end
else
Result := ANode.GetPrev
end
else
if cxInRange(ANode.VisibleIndex + cxIntOffs[AGoForward], 0, TreeList.AbsoluteVisibleCount - 1) then
Result := TreeList.AbsoluteVisibleItems[ANode.VisibleIndex + cxIntOffs[AGoForward]];
end;
procedure TcxTreeListController.CheckLocate(AFound: Boolean);
begin
if AFound then Exit;
if IncSearchNode = nil then
IncSearchText := ''
else
IncSearchText := Copy(IncSearchingText, 1, Length(IncSearchingText) - 1)
end;
procedure TcxTreeListController.SearchLocate(
AItem: TcxCustomInplaceEditContainer; const AValue: string);
var
ANode: TcxTreeListNode;
begin
ANode := TreeList.FocusedNode;
if ANode = nil then
ANode := TreeList.Root.FFirst;
if (AItem = nil) or (ANode = nil) then Exit;
IncSearchText := AValue;
CheckLocate(DoSearch(ANode, TcxTreeListColumn(AItem).ItemIndex, IncSearchText, True));
end;
procedure TcxTreeListController.SearchLocateNext(
AItem: TcxCustomInplaceEditContainer; AForward: Boolean);
var
ANode: TcxTreeListNode;
begin
if (AItem = nil) or (TreeList.FocusedNode = nil) then Exit;
ANode := GetNextNodeForIncSearch(TreeList.FocusedNode, AForward);
if ANode = nil then
ANode := TreeList.FocusedNode;
CheckLocate(DoSearch(ANode, TcxTreeListColumn(AItem).ItemIndex, IncSearchText, AForward));
end;
function TcxTreeListController.CanCreateSelectionHelper: Boolean;
begin
Result := TreeList.IsDesigning and not TreeList.IsDestroying and not TreeList.IsLoading and
(cxDesignSelectionHelperClass <> nil) and TreeList.HandleAllocated;
end;
function TcxTreeListController.IsObjectSelected(AObject: TPersistent): Boolean;
var
AHelper: TcxCustomDesignSelectionHelper;
begin
Result := False;
if not CanCreateSelectionHelper then Exit;
AHelper := cxDesignSelectionHelperClass.Create(TreeList);
try
Result := AHelper.IsObjectSelected(AObject);
finally
AHelper.Free;
end;
end;
procedure TcxTreeListController.SelectObject(
AObject: TPersistent; AShift: TShiftState);
var
AHelper: TcxCustomDesignSelectionHelper;
begin
if not CanCreateSelectionHelper then Exit;
AHelper := cxDesignSelectionHelperClass.Create(TreeList);
try
AHelper.Select(AObject, AShift);
finally
AHelper.Free;
end;
end;
procedure TcxTreeListController.UnselectObject(AObject: TPersistent);
var
AHelper: TcxCustomDesignSelectionHelper;
begin
if not CanCreateSelectionHelper then Exit;
AHelper := cxDesignSelectionHelperClass.Create(TreeList);
try
AHelper.UnselectObject(AObject);
finally
AHelper.Free;
end;
end;
procedure TcxTreeListController.CancelSelection(KeepPrimary: Boolean = True);
begin
if OptionsSelection.MultiSelect then
begin
TreeList.BeginUpdate;
try
SelectionAnchor := nil;
Selection.Clear;
if (FocusedNode <> nil) and KeepPrimary then
FocusedNode.Selected := True
finally
TreeList.EndUpdate;
end;
end;
end;
procedure TcxTreeListController.Select(
ANode: TcxTreeListNode; AShift: TShiftState);
begin
if not CanSelectNode(ANode) then Exit;
TreeList.BeginUpdate;
try
if ANode = nil then
begin
TreeList.FocusedNode := nil;
Exit;
end;
ANode.Focused := True;
if not (ssShift in AShift) and ((ssCtrl in AShift) or not ANode.Selected) then
SelectionAnchor := ANode;
if not ANode.Selected and (not OptionsSelection.MultiSelect or ([ssShift, ssCtrl] * AShift = [])) then
begin
Selection.Clear;
Selection.Add(ANode);
end
else
if [ssCtrl, ssLeft] * AShift = [ssCtrl, ssLeft] then
begin
if ANode.Selected then
Selection.Remove(ANode)
else
Selection.Add(ANode);
end
else
if (ssLeft in AShift) and ANode.Selected then
Exit
else
if ssShift in AShift then
begin
if SelectionAnchor = nil then
FSelectionAnchor := FocusedNode;
SelectRange(SelectionAnchor, ANode);
end;
TreeList.AddChanges([tcSelection]);
finally
TreeList.CancelUpdate;
TreeList.ViewInfo.UpdateSelection;
end;
end;
procedure TcxTreeListController.SelectRange(
const AStartNode, AFinishNode: TcxTreeListNode);
var
I: Integer;
begin
if AStartNode.VisibleIndex > AFinishNode.VisibleIndex then
begin
SelectRange(AFinishNode, AStartNode);
Exit;
end;
Selection.Clear;
Selection.Capacity := AFinishNode.VisibleIndex - AStartNode.VisibleIndex + 1;
for I := AStartNode.VisibleIndex to AFinishNode.VisibleIndex do
Selection.Add(TreeList.AbsoluteVisibleItems[I]);
end;
procedure TcxTreeListController.ViewInfoChanged;
begin
Reset;
TreeList.ViewInfo.IsDirty := True;
inherited ViewInfoChanged;
end;
function TcxTreeListController.GetResizeDirection: TcxDragSizingDirection;
begin
Result := FResizeDirection;
end;
procedure TcxTreeListController.MouseLeave;
begin
inherited MouseLeave;
if PressedHeader <> nil then
PressedHeader.Pressed := False;
with TreeList.ScreenToClient(GetMouseCursorPos) do
UpdateHotTrackNode(X, Y, []);
end;
procedure TcxTreeListController.DoCancelMode;
begin
inherited DoCancelMode;
MouseLeave;
end;
function TcxTreeListController.GetBandsCustomizationPopup: TcxTreeListBandsCustomizationPopup;
begin
if FBandsCustomizationPopup = nil then
FBandsCustomizationPopup := TcxTreeListBandsCustomizationPopup.Create(TreeList);
Result := FBandsCustomizationPopup;
end;
function TcxTreeListController.GetColumnsCustomizationPopup: TcxTreeListColumnsCustomizationPopup;
begin
if FColumnsCustomizationPopup = nil then
FColumnsCustomizationPopup := TcxTreeListColumnsCustomizationPopup.Create(TreeList);
Result := FColumnsCustomizationPopup;
end;
function TcxTreeListController.GetDataController: TcxTreeListDataController;
begin
Result := TreeList.DataController;
end;
function TcxTreeListController.GetEditingController: TcxTreeListEditingController;
begin
Result := TcxTreeListEditingController(inherited EditingController);
end;
function TcxTreeListController.GetFocusedNodeIndex: Integer;
begin
Result := FFocusedNodeIndex;
if FFocusedNode <> nil then
Result := FFocusedNode.VisibleIndex;
end;
function TcxTreeListController.GetHitTest: TcxTreeListHitTest;
begin
Result := TreeList.HitTest;
end;
function TcxTreeListController.GetOptionsBehavior: TcxTreeListOptionsBehavior;
begin
Result := TreeList.OptionsBehavior;
end;
function TcxTreeListController.GetOptionsSelection: TcxTreeListOptionsSelection;
begin
Result := TreeList.OptionsSelection;
end;
function TcxTreeListController.GetIsDragCopy: Boolean;
begin
Result := IsCtrlPressed and TreeList.OptionsBehavior.AutoDragCopy;
end;
function TcxTreeListController.GetSelection: TList;
begin
Result := TreeList.SelectionList;
end;
function TcxTreeListController.GetSelectionAnchor: TcxTreeListNode;
begin
Result := FSelectionAnchor;
if Result = nil then
Result := FocusedNode;
while (Result <> nil) and not Result.IsVisible do
Result := Result.Parent;
end;
function TcxTreeListController.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(EditingControl);
end;
procedure TcxTreeListController.SetForcingWidthColumn(
AColumn: TcxTreeListColumn);
begin
FForcingWidthColumn := AColumn;
end;
procedure TcxTreeListController.SetIncSearchNode(ANode: TcxTreeListNode);
var
APrevNode: TcxTreeListNode;
begin
if ANode = IncSearchNode then
begin
if (ANode <> nil) then
ANode.Repaint(True);
Exit;
end;
FSearchNotification := True;
try
APrevNode := IncSearchNode;
FIncSearchNode := ANode;
if (APrevNode <> nil) and not APrevNode.Deleting then
APrevNode.Repaint(True);
if IncSearchNode <> nil then
begin
TreeList.FocusedNode := IncSearchNode;
IncSearchNode.Repaint(True);
end;
finally
FSearchNotification := False;
end;
end;
procedure TcxTreeListController.SetPressedHeader(
AHeader: TcxTreeListCustomHeaderCellViewInfo);
begin
if (FPressedHeader <> AHeader) and (FPressedHeader <> nil) then
FPressedHeader.State := cxbsNormal;
FPressedHeader := AHeader;
if FPressedHeader <> nil then
begin
FPressedHeader.State := cxbsPressed;
FPressedHeader.Click;
end;
end;
{ TcxTreeListSummary }
constructor TcxTreeListSummary.Create(ATreeList: TcxCustomTreeList);
begin
inherited Create;
FTreeList := ATreeList;
FAbsoluteFooterSummaryItems := TList.Create;
FAbsoluteGroupFooterSummaryItems := TList.Create;
end;
destructor TcxTreeListSummary.Destroy;
begin
FreeAndNil(FAbsoluteGroupFooterSummaryItems);
FreeAndNil(FAbsoluteFooterSummaryItems);
inherited Destroy;
end;
procedure TcxTreeListSummary.Recalculate;
begin
TreeList.StructureChanged;
end;
procedure TcxTreeListSummary.AddSummaryItems(AAbsoluteSummaryItems: TList;
ASummaryItems: TcxTreeListSummaryItems; AIsVisible: Boolean;
var AVisibleCount, AVisibleRowCount: Integer);
var
I: Integer;
begin
for I := 0 to ASummaryItems.Count - 1 do
ASummaryItems[I].AbsoluteIndex := AAbsoluteSummaryItems.Add(ASummaryItems[I]);
if AIsVisible then
begin
Inc(AVisibleCount, ASummaryItems.VisibleCount);
AVisibleRowCount := Max(AVisibleRowCount, ASummaryItems.VisibleCount *
ASummaryItems.Column.Position.LineCount);
end;
end;
procedure TcxTreeListSummary.Calculate;
var
I: Integer;
begin
FAbsoluteFooterSummaryItems.Clear;
FAbsoluteGroupFooterSummaryItems.Clear;
FFooterSummaryRowCount := 0;
FFooterSummaryVisibleCount := 0;
FGroupFooterSummaryRowCount := 0;
FGroupFooterSummaryVisibleCount := 0;
for I := 0 to FTreeList.ColumnCount - 1 do
begin
AddSummaryItems(FAbsoluteFooterSummaryItems, FTreeList.Columns[I].Summary.FooterSummaryItems,
FTreeList.Columns[I].ActuallyVisible and FTreeList.Columns[I].Options.Footer,
FFooterSummaryVisibleCount, FFooterSummaryRowCount);
AddSummaryItems(FAbsoluteGroupFooterSummaryItems, FTreeList.Columns[I].Summary.GroupFooterSummaryItems,
FTreeList.Columns[I].ActuallyVisible and FTreeList.Columns[I].Options.GroupFooter,
FGroupFooterSummaryVisibleCount, FGroupFooterSummaryRowCount);
end;
IsDirty := True;
end;
procedure TcxTreeListSummary.CalculateNode(ADestNode, AValueNode: TcxTreeListNode; AItems: TList);
begin
ProcessSummaryValues(ADestNode, AValueNode, AItems);
while ADestNode <> Root do
begin
ADestNode := ADestNode.Parent;
if ADestNode <> Root then
ProcessSummaryValues(ADestNode, AValueNode, AItems);
end;
end;
procedure TcxTreeListSummary.CheckChanges;
begin
if IsDirty then
begin
IsDirty := False;
ProcessNode(Root);
TreeList.DoAfterSummary;
end;
end;
function TcxTreeListSummary.DoProcessSummaryValue(ANode: TcxTreeListNode; ASummaryItem: TcxTreeListSummaryItem;
var ASummaryValue: Variant; var ASummaryCount: Integer; var AValue: Variant; var ACount: Integer): Boolean;
var
AArguments: TcxTreeListSummaryEventArguments;
AOutArguments: TcxTreeListSummaryEventOutArguments;
begin
Result := Assigned(TreeList.OnSummary);
if Result then
begin
AArguments.Node := ANode;
AArguments.SummaryItem := ASummaryItem;
AOutArguments.Value := AValue;
AOutArguments.SummaryValue := ASummaryValue;
AOutArguments.CountValue := ACount;
AOutArguments.Done := False;
TreeList.OnSummary(TreeList, AArguments, AOutArguments);
ASummaryValue := AOutArguments.SummaryValue;
ACount := AOutArguments.CountValue;
AValue := AOutArguments.Value;
Result := AOutArguments.Done;
end;
end;
procedure TcxTreeListSummary.FinalizeValues(ANode: TcxTreeListNode; AItems: TList);
var
ASummaryItem: TcxTreeListSummaryItem;
I: Integer;
AVarIsDate: Boolean;
ASummaryInfos: TcxTreeListSummaryInfos;
begin
ASummaryInfos := ANode.FSummaryInfo;
for I := 0 to AItems.Count - 1 do
begin
ASummaryItem := AItems[I];
if VarIsEmpty(ASummaryInfos[I].TempValue) then
ASummaryInfos[I].Value := Null;
case ASummaryItem.Kind of
skMin, skMax, skSum:
ASummaryInfos[I].Value := ASummaryInfos[I].TempValue;
skCount:
ASummaryInfos[I].Value := ASummaryInfos[I].Count;
skAverage:
if (ASummaryInfos[I].Count > 0) and not VarIsEmpty(ASummaryInfos[I].TempValue) then
begin
AVarIsDate := VarIsDate(ASummaryInfos[I].TempValue);
ASummaryInfos[I].Value := ASummaryInfos[I].TempValue / ASummaryInfos[I].Count;
if AVarIsDate then
VarCast(ASummaryInfos[I].Value, ASummaryInfos[I].TempValue, varDate);
end;
end;
end;
end;
procedure TcxTreeListSummary.InitializeValues(ANode: TcxTreeListNode; AItems: TList);
var
I: Integer;
ASummaryItem: TcxTreeListSummaryItem;
begin
SetLength(ANode.FSummaryInfo, 0);
SetLength(ANode.FSummaryInfo, AItems.Count);
for I := 0 to AItems.Count - 1 do
begin
ASummaryItem := TcxTreeListSummaryItem(AItems[I]);
ANode.FSummaryInfo[I].Count := 0;
if ASummaryItem.Kind in [skSum, skAverage] then
ANode.FSummaryInfo[I].TempValue := 0
else
ANode.FSummaryInfo[I].TempValue := Null;
ANode.FSummaryInfo[I].Value := Null;
end;
end;
procedure TcxTreeListSummary.Notification(AComponent: TComponent; Operation: TOperation);
var
I: Integer;
begin
Calculate;
for I := 0 to FAbsoluteFooterSummaryItems.Count - 1 do
TcxTreeListSummaryItem(FAbsoluteFooterSummaryItems[I]).Notification(AComponent, Operation);
for I := 0 to FAbsoluteGroupFooterSummaryItems.Count - 1 do
TcxTreeListSummaryItem(FAbsoluteGroupFooterSummaryItems[I]).Notification(AComponent, Operation);
end;
procedure TcxTreeListSummary.ProcessNode(AParent: TcxTreeListNode);
var
AList: TList;
ANode: TcxTreeListNode;
begin
AList := FAbsoluteGroupFooterSummaryItems;
if AParent = Root then
AList := FAbsoluteFooterSummaryItems;
InitializeValues(AParent, AList);
ANode := AParent.GetFirstChildVisible;
while ANode <> nil do
begin
CalculateNode(Root, ANode, FAbsoluteFooterSummaryItems);
if AParent <> Root then
CalculateNode(AParent, ANode, FAbsoluteGroupFooterSummaryItems);
if ANode.HasChildren then
ProcessNode(ANode)
else
SetLength(ANode.FSummaryInfo, 0);
ANode := ANode.GetNextSiblingVisible;
end;
FinalizeValues(AParent, AList);
end;
procedure TcxTreeListSummary.ProcessSummaryValue(ANode: TcxTreeListNode; ASummaryItem: TcxTreeListSummaryItem;
var ASummaryValue: Variant; var ASummaryCount: Integer);
var
AValue: Variant;
ACount: Integer;
begin
ACount := 1;
AValue := ANode.Values[ASummaryItem.CalculatedColumn.ItemIndex];
if not DoProcessSummaryValue(ANode, ASummaryItem, ASummaryValue, ASummaryCount, AValue, ACount) and
not (TreeList.OptionsData.SummaryNullIgnore and VarIsNull(AValue)) then
begin
if VarIsNull(ASummaryValue) then
ASummaryValue := AValue
else
if not VarIsNull(AValue) then
case ASummaryItem.Kind of
skSum, skAverage:
ASummaryValue := ASummaryValue + AValue;
skMin:
if AValue < ASummaryValue then
ASummaryValue := AValue;
skMax:
if AValue > ASummaryValue then
ASummaryValue := AValue;
end;
Inc(ASummaryCount, ACount);
end;
end;
procedure TcxTreeListSummary.ProcessSummaryValues(ADestNode, AValueNode: TcxTreeListNode; AItems: TList);
var
I: Integer;
ASummaryItem: TcxTreeListSummaryItem;
AAbsoluteItemIndex: Integer;
begin
for I := 0 to AItems.Count - 1 do
begin
ASummaryItem := AItems[I];
if(ASummaryItem.AllNodes or (AValueNode.Parent = ADestNode)) and
(ASummaryItem.Kind <> skNone) then
begin
AAbsoluteItemIndex := ASummaryItem.AbsoluteIndex;
ProcessSummaryValue(AValueNode, ASummaryItem, ADestNode.FSummaryInfo[AAbsoluteItemIndex].TempValue,
ADestNode.FSummaryInfo[AAbsoluteItemIndex].Count);
end;
end;
end;
function TcxTreeListSummary.GetFooterSummaryCount: Integer;
begin
Result := FAbsoluteFooterSummaryItems.Count;
end;
function TcxTreeListSummary.GetFooterSummaryItem(
AIndex: Integer): TcxTreeListSummaryItem;
begin
Result := TcxTreeListSummaryItem(FAbsoluteFooterSummaryItems[AIndex]);
end;
function TcxTreeListSummary.GetFooterSummaryText(
ASummaryItem: TcxTreeListSummaryItem): string;
begin
Result := GetGroupFooterSummaryText(ASummaryItem, Root);
end;
function TcxTreeListSummary.GetFooterSummaryValue(
ASummaryItem: TcxTreeListSummaryItem): Variant;
begin
Result := GetGroupFooterSummaryValue(ASummaryItem, Root);
end;
function TcxTreeListSummary.GetGroupFooterSummaryCount: Integer;
begin
Result := FAbsoluteGroupFooterSummaryItems.Count;
end;
function TcxTreeListSummary.GetGroupFooterSummaryItem(
AIndex: Integer): TcxTreeListSummaryItem;
begin
Result := TcxTreeListSummaryItem(FAbsoluteGroupFooterSummaryItems[AIndex]);
end;
function TcxTreeListSummary.GetGroupFooterSummaryText(
ASummaryItem: TcxTreeListSummaryItem; ANode: TcxTreeListNode): string;
begin
Result := ASummaryItem.FormatValue(
GetGroupFooterSummaryValue(ASummaryItem, ANode), True);
end;
function TcxTreeListSummary.GetGroupFooterSummaryValue(
ASummaryItem: TcxTreeListSummaryItem; ANode: TcxTreeListNode): Variant;
begin
Result := ANode.FooterSummaryValues[ASummaryItem.AbsoluteIndex];
end;
function TcxTreeListSummary.GetRoot: TcxTreeListNode;
begin
Result := TreeList.Root;
end;
procedure TcxTreeListSummary.SetFooterSummaryValue(
ASummaryItem: TcxTreeListSummaryItem; const Value: Variant);
begin
GroupFooterSummaryValues[ASummaryItem, Root] := Value;
end;
procedure TcxTreeListSummary.SetGroupFooterSummaryValue(
ASummaryItem: TcxTreeListSummaryItem; ANode: TcxTreeListNode;
const Value: Variant);
begin
ANode.FooterSummaryValues[ASummaryItem.AbsoluteIndex] := Value;
end;
{ TcxTreeListSizingDragAndDropObject }
procedure TcxTreeListSizingDragAndDropObject.BeginDragAndDrop;
begin
FOffset := cxNullPoint;
FDragItem := TcxTreeListController(Controller).DragItem;
with TcxTreeListController(Controller) do
begin
if DragItem is TcxTreeListCustomCellViewInfo then
begin
if GetResizeDirection = dsdHorz then
FOffset.X := TcxTreeListCustomCellViewInfo(DragItem).DisplayRect.Right - CurMousePos.X
else
FOffset.Y := TcxTreeListCustomCellViewInfo(DragItem).DisplayRect.Bottom - CurMousePos.Y
end
else
if DragItem is TcxTreeListNode then
with TcxTreeListNode(DragItem).FViewData do
FOffset.Y := Origin.Y + Height - CurMousePos.Y;
end;
inherited BeginDragAndDrop;
end;
procedure TcxTreeListSizingDragAndDropObject.DragAndDrop(
const P: TPoint; var Accepted: Boolean);
begin
TcxTreeListController(Controller).ClickedObject := nil;
TcxTreeListController(Controller).DragItem := FDragItem;
inherited;
end;
function TcxTreeListSizingDragAndDropObject.GetSizingMarkBounds: TRect;
begin
Result := inherited GetSizingMarkBounds;
OffsetRect(Result, FOffset.X, FOffset.Y);
end;
{ TcxTreeListDragAndDropBandObject }
function TcxTreeListDragAndDropBandObject.CanCustomize: Boolean;
begin
Result := Band.Options.Customizing and OptionsCustomizing.BandCustomizing;
end;
function TcxTreeListDragAndDropBandObject.CanDrop: Boolean;
function GetNearestColIndex(AForward: Boolean): Integer;
begin
Result := Band.Position.VisibleColIndex;
if AForward then
Inc(Result)
else
Dec(Result);
end;
begin
Result := TreeList.Bands.VisibleItemCount = 0;
if Result or (DestBand = nil) or (DestBand = Band) then Exit;
Result := DestBand.FixedKind = Band.FixedKind;
if not Result and not Band.Visible and
(Bands.GetVisibleCountByKind(Band.FixedKind) = 0) and DestBand.IsRoot then
begin
case Band.FixedKind of
tlbfLeft:
Result := (DropPosition = posLeft) and
(DestBand.VisibleRootIndex = Bands.GetFirstVisibleRootIndex(tlbfNone));
tlbfNone:
Result := (DropPosition = posRight) and
(DestBand.VisibleRootIndex = Bands.GetLastVisibleRootIndex(tlbfLeft)) or
(DropPosition = posLeft) and
(DestBand.VisibleRootIndex = Bands.GetFirstVisibleRootIndex(tlbfRight));
tlbfRight:
Result := (DropPosition = posRight) and
(DestBand.VisibleRootIndex = Bands.GetLastVisibleRootIndex(tlbfNone));
end;
end;
if not Result or not Band.Visible then Exit;
case DropInfo.Position of
posLeft, posRight:
Result := (DestBand.ParentBand <> Band.ParentBand) or
(DestBand.Position.VisibleColIndex <> GetNearestColIndex(DropPosition = posLeft));
posTop:
Result := (DestBand.ParentBand <> Band) or (Band.FChildVisibleBands.Count > 1);
posBottom:
Result := (Band.ParentBand <> DestBand) or (DestBand.FChildVisibleBands.Count > 1);
end;
end;
function TcxTreeListDragAndDropBandObject.CanRemove: Boolean;
begin
Result := CanCustomize and (Customizing or TreeList.OptionsCustomizing.BandHiding) and
not Band.Options.Hidden and (not Band.IsRoot or (Bands.VisibleItemCount > 1));
end;
function TcxTreeListDragAndDropBandObject.CheckBandInsertAt(
ABand: TcxTreeListBand): Boolean;
var
I: Integer;
begin
Result := PtInRect(GetBoundsForInsert(ABand), DropInfo.DropPos);
if Result then
begin
DropInfo.Band := ABand;
DropInfo.Position := GetPointPosition(ABand.HeaderCell.GetClipRect, DropInfo.DropPos,
True, TreeList.OptionsCustomizing.NestedBands);
end
else
if TreeList.OptionsCustomizing.NestedBands and not ABand.IsBottom then
begin
for I := 0 to ABand.ChildVisibleBands.Count - 1 do
begin
Result := CheckBandInsertAt(TcxTreeListBand(ABand.ChildVisibleBands[I]));
if Result then Break;
end;
end;
end;
procedure TcxTreeListDragAndDropBandObject.CheckDragPosition;
var
I: Integer;
begin
DropInfo.Band := nil;
DropInfo.Position := posLeft;
for I := 0 to TreeList.Bands.VisibleRootItemCount - 1 do
if CheckBandInsertAt(TreeList.Bands.VisibleRootItems[I]) then Break;
end;
function TcxTreeListDragAndDropBandObject.Drop: Boolean;
begin
Result := True;
if CanDrop then
begin
BeforeDropPositionChange;
Band.Position.BandIndex := GetDropParentBandIndex;
Band.Position.ColIndex := GetDropColIndex;
AfterDropPositionChange;
Band.Visible := True;
end
else
if (DestBand = nil) and CanRemove then
Band.Visible := False
else
if Bands.VisibleItemCount = 0 then
begin
Band.Position.BandIndex := -1;
Band.Visible := True;
end
else
Result := False;
end;
function TcxTreeListDragAndDropBandObject.GetBoundsForInsert(
ABand: TcxTreeListBand): TRect;
begin
Result := ABand.HeaderCell.GetClipRect;
if ABand.IsRoot then
Dec(Result.Top, cxTreeListHeaderMovingZoneSize);
if ABand.IsBottom then
Inc(Result.Bottom, cxTreeListHeaderMovingZoneSize);
end;
procedure TcxTreeListDragAndDropBandObject.MakeCustomizingPageVisible;
begin
if Band.ActuallyVisible then
TreeList.Customizing.FHeaderListBox.ItemIndex := -1;
TreeList.Customizing.MakeBandPageVisible;
end;
procedure TcxTreeListDragAndDropBandObject.AfterDropPositionChange;
var
I: Integer;
begin
case DropPosition of
posTop:
begin
DestBand.Position.BandIndex := Band.Index;
DestBand.Position.ColIndex := 0;
end;
posBottom:
begin
I := 0;
while I < DestBand.ChildVisibleBands.Count do
if DestBand.ChildVisibleBands[I] <> Band then
tcxTreeListBand(DestBand.ChildVisibleBands[I]).Position.BandIndex := Band.Index
else
Inc(I);
end;
end;
end;
procedure TcxTreeListDragAndDropBandObject.BeforeDropPositionChange;
var
AColIndex, I: Integer;
begin
if (DropPosition <> posBottom) and (GetDropParentBandIndex = Band.Index) then
begin
AColIndex := Band.Position.ColIndex;
for I := Band.ChildBandCount - 1 downto 0 do
with Band.ChildBands[I].Position do
begin
BandIndex := Band.Position.BandIndex;
ColIndex := AColIndex;
end;
end;
end;
function TcxTreeListDragAndDropBandObject.GetBand: TcxTreeListBand;
begin
Result := TcxTreeListBandHeaderCellViewInfo(DragHeader).Band;
end;
function TcxTreeListDragAndDropBandObject.GetDropParentBandIndex: Integer;
begin
if DropPosition = posBottom then
Result := DestBand.Index
else
begin
if DestBand = nil then
Result := -1
else
Result := DestBand.Position.BandIndex;
end;
end;
function TcxTreeListDragAndDropBandObject.GetDropColIndex: Integer;
begin
if DropPosition = posBottom then
Result := 0
else
begin
if DestBand = nil then
Result := 0
else
Result := DestBand.Position.ColIndex;
if DropPosition = posRight then Inc(Result);
if Band.Position.ColIndex < Result then Dec(Result);
end;
end;
{ TcxTreeListDragAndDropColumnObject }
function TcxTreeListDragAndDropColumnObject.CanCustomize: Boolean;
begin
Result := Column.Options.Customizing and
OptionsCustomizing.ColumnCustomizing;
end;
function TcxTreeListDragAndDropColumnObject.CanDrop: Boolean;
var
AIndex: Integer;
begin
Result := DropInfo.Accepted and (DropPosition <> posNone);
if not Result or not ChangeColumnOnly then Exit;
AIndex := DropInfo.ColIndex - Column.Position.VisibleColIndex;
Result := (AIndex < 0) or (AIndex > 1) or not Column.Visible;
end;
function TcxTreeListDragAndDropColumnObject.CanRemove: Boolean;
begin
Result := CanCustomize and (Customizing or OptionsCustomizing.ColumnHiding) and
not Column.Options.Hidden and (TreeList.VisibleColumnCount > 1);
end;
procedure TcxTreeListDragAndDropColumnObject.CheckDropColumnIndex(
ARow: TcxTreeListBandRow; var AColIndex: Integer);
begin
if AColIndex < ARow.VisibleItemCount then
AColIndex := ARow.VisibleItems[AColIndex].Position.ColIndex
else
AColIndex := ARow.Count + 1;
end;
function TcxTreeListDragAndDropColumnObject.ChangeColumnOnly: Boolean;
begin
Result := not DropInfo.InsertRow and (DestBand = Column.Position.Band) and
(DropInfo.RowIndex = Column.Position.RowIndex);
end;
function TcxTreeListDragAndDropColumnObject.CheckBandDropArea(
ABand: TcxTreeListBand): Boolean;
var
I: Integer;
begin
DropInfo.Area := cxRectSetTop(ABand.HeaderCell.GetClipRect,
ABand.HeaderCell.DisplayRect.Bottom,
ViewInfo.HeadersHeight + cxTreeListHeaderMovingZoneSize);
Result := PtInRect(DropInfo.Area, DropInfo.DropPos) and
((ABand <> Column.Position.Band) or (ABand.VisibleColumnCount > 1));
if not Result then Exit;
DropInfo.Band := ABand;
Dec(DropInfo.Area.Bottom, cxTreeListHeaderMovingZoneSize);
DropInfo.ColIndex := 0;
DropInfo.Position := posBottom;
DropInfo.InsertRow := True;
DropInfo.RowIndex := ABand.BandRows.Count;
if ABand.BandRows.VisibleItemCount = 0 then
DropInfo.Position := posTop
else
if DropInfo.Area.Bottom > DropInfo.DropPos.Y then
begin
DropInfo.Area.Bottom := DropInfo.Area.Top;
for I := 0 to ABand.BandRows.VisibleItemCount - 1 do
begin
Inc(DropInfo.Area.Bottom,
ABand.BandRows.VisibleItems[I].LineCount * ViewInfo.HeaderLineHeight);
DropInfo.RowIndex := ABand.BandRows.VisibleItems[I].Index + 1;
if DropInfo.Area.Bottom > DropInfo.DropPos.Y then Break;
end;
end;
end;
procedure TcxTreeListDragAndDropColumnObject.CheckDragPosition;
var
I: Integer;
const
HorzPos: array[Boolean] of TcxPosition = (posRight, posLeft);
begin
DropInfo.InsertRow := False;
if HitTest.HitAtBandContainer or HitTest.HitAtBandHeader then
DropInfo.Band := HitTest.HitBand
else
DropInfo.Band := nil;
DropInfo.Position := posNone;
DropInfo.Accepted := HitTest.HitAtColumnHeader;
if DropInfo.Accepted then
InitDropInfoFromColumn(HitTest.HitColumn)
else
for I := 0 to Bands.BottomItemCount - 1 do
begin
DropInfo.Accepted := CheckBandDropArea(Bands.BottomItems[I]);
if DropInfo.Accepted then Break;
end;
if DropInfo.Accepted and (DropInfo.Position = posNone) then
begin
DropInfo.Position := HorzPos[DropInfo.DropPos.X <= cxRectCenter(DropInfo.Area).X];
if (DropInfo.Position = posRight) then
Inc(DropInfo.ColIndex);
end;
DropInfo.Accepted := DropInfo.Position <> posNone;
end;
function TcxTreeListDragAndDropColumnObject.CreateDropInfo: TcxTreeListDropInfo;
begin
Result := TcxTreeListColumnDropInfo.Create;
end;
function TcxTreeListDragAndDropColumnObject.Drop: Boolean;
begin
Result := True;
if ((DestBand = nil) or DropInfo.Customizing) and CanRemove then
Column.Visible := False
else
if DestBand <> nil then
begin
Column.Position.BandIndex := DestBand.Index;
if DropInfo.InsertRow then
Column.Position.Row := DestBand.BandRows.Insert(DropInfo.RowIndex)
else
Column.Position.RowIndex := DropInfo.RowIndex;
CheckDropColumnIndex(Column.Position.Row, DropInfo.ColIndex);
Column.Position.ColIndex := DropInfo.ColIndex;
Column.Visible := True;
DestBand.AdjustSubItems;
end
else
Result := False;
end;
function TcxTreeListDragAndDropColumnObject.GetArrowAreaBounds: TRect;
begin
Result := DropInfo.Area;
end;
procedure TcxTreeListDragAndDropColumnObject.InitDropInfoFromColumn(
AColumn: TcxTreeListColumn);
begin
DropInfo.Band := AColumn.Position.Band;
DropInfo.ColIndex := AColumn.Position.VisibleColIndex;
DropInfo.RowIndex := AColumn.Position.RowIndex;
DropInfo.Area := AColumn.HeaderCell.GetClipRect;
end;
procedure TcxTreeListDragAndDropColumnObject.MakeCustomizingPageVisible;
begin
if Column.ActuallyVisible then
TreeList.Customizing.FHeaderListBox.ItemIndex := -1;
TreeList.Customizing.MakeColumnPageVisible;
end;
function TcxTreeListDragAndDropColumnObject.GetColumn: TcxTreeListColumn;
begin
Result := TcxTreeListColumnHeaderCellViewInfo(DragHeader).Column;
end;
function TcxTreeListDragAndDropColumnObject.GetDropInfo: TcxTreeListColumnDropInfo;
begin
Result := TcxTreeListColumnDropInfo(inherited DropInfo);
end;
{ TcxTreeListDragAndDropObject }
constructor TcxTreeListDragAndDropObject.Create(AControl: TcxControl);
begin
if AControl is TcxTreeListItemsCustomizeListBox then
begin
inherited Create(TcxTreeListItemsCustomizeListBox(AControl).TreeList)
end
else
inherited Create(AControl);
MapWindowPoint(AControl.Handle, TreeList.Handle, FOrigin);
OrgOffset := FOrigin;
FArrows := TcxPlaceArrows.CreateArrows(TreeList.OptionsView.DropArrowColor, clBtnText);
FDropInfo := CreateDropInfo;
DragHeader.Pressed := True;
end;
destructor TcxTreeListDragAndDropObject.Destroy;
begin
FArrows.Free;
FDropInfo.Free;
inherited Destroy;
end;
procedure TcxTreeListDragAndDropObject.BeginDragAndDrop;
begin
inherited BeginDragAndDrop;
InitializeScrollArea(ViewInfo.HScrollArea);
if Customizing then
MakeCustomizingPageVisible;
end;
procedure TcxTreeListDragAndDropObject.ChangeArrowsPosition;
const
Position2Border: array[TcxPosition] of TcxBorder =
(bLeft, bLeft, bRight, bTop, bBottom);
begin
if DrawArrowsNeeded then
begin
Arrows.MoveTo(cxRectOffset(GetArrowAreaBounds,
TreeList.ClientToScreen(Point(0, 0))), Position2Border[DropPosition]);
Arrows.Visible := True;
end
else
Arrows.Visible := False;
end;
function TcxTreeListDragAndDropObject.CheckInCustomizing(
const APoint: TPoint): Boolean;
begin
Result := TreeList.Customizing.PtInCustomizingBox(
TreeList.ClientToScreen(APoint));
end;
function TcxTreeListDragAndDropObject.CreateDropInfo: TcxTreeListDropInfo;
begin
Result := TcxTreeListDropInfo.Create;
end;
procedure TcxTreeListDragAndDropObject.DragAndDrop(
const P: TPoint; var Accepted: Boolean);
var
APos: TPoint;
begin
APos := cxPointOffset(P, FOrigin);
TreeList.Controller.ClickedObject := nil;
InitDropInfo(APos);
ChangeArrowsPosition;
Accepted := DropInfo.Customizing or (DropInfo.Band <> nil) or (Bands.VisibleItemCount = 0);
inherited DragAndDrop(APos, Accepted);
end;
procedure TcxTreeListDragAndDropObject.EndDragAndDrop(Accepted: Boolean);
begin
DragHeader.Pressed := False;
try
DropInfo.Accepted := Accepted and (DropInfo.Accepted or DropInfo.Customizing or
CanRemove) and not TreeList.Controller.DragCancel;
inherited EndDragAndDrop(DropInfo.Accepted);
if DropInfo.Accepted then
begin
TreeList.BeginUpdate;
if not Drop then
TreeList.CancelUpdate
else
begin
TreeList.EndUpdate;
TreeList.Modified;
end;
end;
finally
Dirty := False;
TreeList.Controller.DragItem := nil;
end;
end;
function TcxTreeListDragAndDropObject.GetArrowAreaBounds: TRect;
begin
Result := cxNullRect;
if not CanDrop then Exit;
if Bands.VisibleItemCount = 0 then
Result := cxRectSetHeight(ViewInfo.Bounds, ViewInfo.FBandHeaderLineHeight)
else
begin
Result := DestBand.HeaderCell.GetClipRect;
case DropPosition of
posRight:
Result.Left := Result.Right;
posBottom:
Result.Top := Result.Bottom;
end;
end;
end;
function TcxTreeListDragAndDropObject.GetDisplayRect: TRect;
begin
Result := cxRectOffset(DragHeader.BoundsRect, FOrigin);
end;
function TcxTreeListDragAndDropObject.GetDragAndDropCursor(
Accepted: Boolean): TCursor;
begin
if Accepted then
Result := crArrow
else
if CanRemove then
Result := crcxRemove
else
Result := crcxNoDrop;
end;
procedure TcxTreeListDragAndDropObject.InitDropInfo(const P: TPoint);
begin
HitTest.HitPoint := P;
DropInfo.DropPos := P;
DropInfo.Customizing := CanCustomize and CheckInCustomizing(P);
CheckDragPosition;
DropInfo.Accepted := CanDrop;
end;
procedure TcxTreeListDragAndDropObject.InitializeScrollArea(const Area: TRect);
begin
if cxRectIsNull(Area) then Exit;
AddAutoScrollingObject(cxRectSetLeft(Area,
Area.Left, cxtlScrollDelta), sbHorizontal, scLineUp);
AddAutoScrollingObject(cxRectSetRight(Area,
Area.Right, cxtlScrollDelta), sbHorizontal, scLineDown);
end;
procedure TcxTreeListDragAndDropObject.Paint;
var
ADone: Boolean;
APrevState: TcxButtonState;
ABorders: TcxBorders;
ANeighbors: TcxNeighbors;
AMargins: TRect;
begin
APrevState := DragHeader.State;
ABorders := DragHeader.Borders;
try
DragHeader.FState := cxbsDefault;
DragHeader.FBorders := cxBordersAll;
AMargins := DragHeader.BordersMargins;
DragHeader.BordersMargins := cxNullRect;
ANeighbors := DragHeader.FNeighbors;
DragHeader.FNeighbors := [];
Canvas.WindowOrg := DragHeader.DisplayRect.TopLeft;
Painter.CustomDrawCell(Canvas, DragHeader, ADone);
if not ADone then
DragHeader.Draw(Canvas);
finally
DragHeader.BordersMargins := AMargins;
DragHeader.FNeighbors := ANeighbors;
DragHeader.FBorders := ABorders;
DragHeader.FState := APrevState;
end;
end;
function TcxTreeListDragAndDropObject.DrawArrowsNeeded: Boolean;
begin
Result := CanDrop and not DropInfo.Customizing;
end;
function TcxTreeListDragAndDropObject.GetBands: TcxTreeListBands;
begin
Result := TreeList.Bands;
end;
function TcxTreeListDragAndDropObject.GetCustomizing: Boolean;
begin
Result := TreeList.Customizing.Visible;
end;
function TcxTreeListDragAndDropObject.GetDestBand: TcxTreeListBand;
begin
Result := DropInfo.Band;
end;
function TcxTreeListDragAndDropObject.GetDragHeader: TcxTreeListHeaderCellViewInfo;
begin
Result := TreeList.Controller.DragItem as TcxTreeListHeaderCellViewInfo;
end;
function TcxTreeListDragAndDropObject.GetDropPosition: TcxPosition;
begin
Result := DropInfo.Position;
end;
function TcxTreeListDragAndDropObject.GetHitTest: TcxTreeListHitTest;
begin
Result := TreeList.HitTest;
end;
function TcxTreeListDragAndDropObject.GetOptionsCustomize: TcxTreeListOptionsCustomizing;
begin
Result := TreeList.OptionsCustomizing;
end;
function TcxTreeListDragAndDropObject.GetPainter: TcxTreeListPainter;
begin
Result := TcxTreeListPainter(TreeList.Painter);
end;
function TcxTreeListDragAndDropObject.GetTreeList: TcxCustomTreeList;
begin
Result := Control as TcxCustomTreeList;
end;
function TcxTreeListDragAndDropObject.GetViewInfo: TcxTreeListViewInfo;
begin
Result := TreeList.ViewInfo;
end;
{ TcxTreeListPopup }
constructor TcxTreeListPopup.Create(AOwnerControl: TWinControl);
begin
inherited Create(AOwnerControl);
Color := clWindow;
IsTopMost := True;
OwnerParent := TreeList;
CreateListBox;
end;
function TcxTreeListPopup.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(OwnerControl);
end;
procedure TcxTreeListPopup.SetOwner(AValue: TcxTreeListIndicatorCellViewInfo);
begin
if FOwner <> AValue then
begin
if (AValue = nil) and Visible and FOwner.ClosePopupWhenNilOwner then
CloseUp;
FOwner := AValue;
end;
end;
function TcxTreeListPopup.CalculateOwnerBounds: TRect;
begin
Result := FOwner.GetOwnerBounds;
end;
function TcxTreeListPopup.GetClientMinWidth: Integer;
begin
with Owner.GetOwnerBounds do
Result := Right - Left - NCWidth;
end;
procedure TcxTreeListPopup.InitPopup;
begin
inherited InitPopup;
BorderStyle := TreeList.LookAndFeelPainter.PopupBorderStyle;
Font := TreeList.Font;
OwnerBounds := CalculateOwnerBounds;
end;
function TcxTreeListPopup.NeedIgnoreMouseMessageAfterCloseUp(AWnd: THandle;
AMsg: Cardinal; AShift: TShiftState; const APos: TPoint): Boolean;
begin
Result := cxRectPtIn(OwnerBounds, TreeList.ScreenToClient(APos));
end;
procedure TcxTreeListPopup.Paint;
begin
DrawFrame;
Canvas.Brush.Color := Color;
Canvas.FillRect(ClientBounds);
end;
procedure TcxTreeListPopup.VisibleChanged;
begin
inherited;
if not Visible and (FOwner <> nil) then
FOwner.PopupClosed;
end;
procedure TcxTreeListPopup.Popup;
begin
SetCaptureControl(nil);
inherited Popup(FindNextControl(nil, True, True, False));
end;
{ TcxTreeListCustomizationPopup }
procedure TcxTreeListCustomizationPopup.CloseUp;
begin
inherited CloseUp;
FCheckListBox.Clear;
FCheckListBox.Columns := 0;
end;
procedure TcxTreeListCustomizationPopup.CorrectBoundsWithDesktopWorkArea(
var APosition: TPoint);
var
ADesktopWorkArea: TRect;
ADesktopSpace, AColumnCount: Integer;
begin
ADesktopWorkArea := GetDesktopWorkArea(OwnerScreenBounds.TopLeft);
if APosition.Y < ADesktopWorkArea.Top then
ADesktopSpace := APosition.Y + Height - ADesktopWorkArea.Top
else
if APosition.Y + Height > ADesktopWorkArea.Bottom then
ADesktopSpace := ADesktopWorkArea.Bottom - APosition.Y
else
ADesktopSpace := 0;
if ADesktopSpace <> 0 then
begin
AColumnCount := RoundDiv(CheckListBox.Height, ADesktopSpace - NCHeight);
repeat
RestoreControlsBounds;
CheckListBox.Columns := AColumnCount;
AdjustCheckListBoxSize;
CalculateSize;
APosition := CalculatePosition;
Inc(AColumnCount);
until (ADesktopWorkArea.Top <= APosition.Y - GetScrollBarSize.cy) and
(APosition.Y + Height + GetScrollBarSize.cy <= ADesktopWorkArea.Bottom);
if APosition.X + Width > ADesktopWorkArea.Right then
begin
RestoreControlsBounds;
CheckListBox.Columns :=
(ADesktopWorkArea.Right - APosition.X - NCWidth) div CheckListBoxColumnWidth;
AdjustCheckListBoxSize(True);
CalculateSize;
APosition := CalculatePosition;
end;
end;
end;
procedure TcxTreeListCustomizationPopup.AdjustCheckListBoxSize(
AFixedHeight: Boolean = False);
var
ADropDownCount: Integer;
function CalculateClientWidth: Integer;
begin
if FCheckListBox.Columns > 1 then
Result := CheckListBoxColumnWidth * FCheckListBox.Columns
else
begin
Result := FCheckListBox.GetBestFitWidth;
if (ADropDownCount <> -1) and (FCheckListBox.Items.Count > ADropDownCount) then
Inc(Result, GetScrollBarSize.cx);
Inc(Result, cxTextOffset);
end;
end;
function CalculateClientHeight: Integer;
begin
if ADropDownCount = -1 then
Result := FCheckListBox.ClientHeight + GetScrollBarSize.cy
else
Result := FCheckListBox.GetHeight(ADropDownCount);
end;
begin
if AFixedHeight then
ADropDownCount := -1
else
if FCheckListBox.Columns > 1 then
ADropDownCount := RoundDiv(FCheckListBox.Items.Count, FCheckListBox.Columns)
else
begin
ADropDownCount := GetDropDownCount;
if (ADropDownCount = 0) or (FCheckListBox.Items.Count < ADropDownCount) then
ADropDownCount := FCheckListBox.Items.Count;
end;
FCheckListBox.ClientWidth := CalculateClientWidth;
FCheckListBox.ClientHeight := CalculateClientHeight;
end;
procedure TcxTreeListCustomizationPopup.CheckClicked(AIndex: Integer; AChecked: Boolean);
begin
ItemClicked(CheckListBox.Items[AIndex].ItemObject, AChecked);
end;
procedure TcxTreeListCustomizationPopup.CreateListBox;
begin
FCheckListBox := TcxCheckListBox.Create(Self);
with FCheckListBox do
begin
EditValueFormat := cvfIndices;
with Style do
begin
LookAndFeel.MasterLookAndFeel := TreeList.LookAndFeel;
BorderStyle := cbsNone;
HotTrack := False;
TransparentBorder := False;
end;
StyleFocused.BorderStyle := cbsNone;
StyleHot.BorderStyle := cbsNone;
ParentFont := True;
Parent := Self;
OnClick := CheckListBoxClick;
OnClickCheck := CheckListBoxCheckClick;
OnKeyDown := CheckListBoxKeyDown;
OnMouseDown := CheckListBoxMouseDown;
end;
end;
function TcxTreeListCustomizationPopup.GetCheckListBoxColumnWidth: Integer;
begin
Result := CheckListBox.GetBestFitWidth + CustomizationPopupColumnOffset;
end;
procedure TcxTreeListCustomizationPopup.GetCheckListBoxSelectedItems(AItems: TList);
var
I: Integer;
begin
for I := 0 to CheckListBox.Count - 1 do
if CheckListBox.Selected[I] then
AItems.Add(CheckListBox.Items[I].ItemObject);
end;
procedure TcxTreeListCustomizationPopup.InitPopup;
begin
inherited InitPopup;
with FCheckListBox do
begin
Canvas.Font := Font;
DragMode := dmManual;
InnerCheckListBox.MultiSelect := DragMode = dmAutomatic;
end;
AddCheckListBoxItems;
AdjustCheckListBoxSize;
end;
procedure TcxTreeListCustomizationPopup.RefreshCheckListBoxItems;
begin
CheckListBox.Items.BeginUpdate;
try
CheckListBox.Clear;
AddCheckListBoxItems;
finally
CheckListBox.Items.EndUpdate;
end;
end;
procedure TcxTreeListCustomizationPopup.SetCheckListBoxSelectedItems(AItems: TList);
var
I, AIndex: Integer;
begin
for I := 0 to AItems.Count - 1 do
begin
AIndex := CheckListBox.Items.IndexOfObject(AItems[I]);
if AIndex <> -1 then
CheckListBox.Selected[AIndex] := True;
end;
end;
procedure TcxTreeListCustomizationPopup.CheckListBoxClick(Sender: TObject);
var
AItems: TList;
begin
if not TreeList.IsDesigning then Exit;
AItems := TList.Create;
try
GetCheckListBoxSelectedItems(AItems);
TreeList.Controller.SetSelection(AItems);
finally
AItems.Free;
end;
end;
procedure TcxTreeListCustomizationPopup.CheckListBoxCheckClick(Sender: TObject;
AIndex: Integer; APrevState, ANewState: TcxCheckBoxState);
begin
CheckClicked(AIndex, ANewState = cbsChecked);
end;
procedure TcxTreeListCustomizationPopup.CheckListBoxKeyDown(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
if Key = VK_ESCAPE then
CloseUp;
end;
procedure TcxTreeListCustomizationPopup.CheckListBoxMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
CheckListBoxClick(Sender);
end;
{ TcxTreeListColumnsCustomizationPopup }
procedure TcxTreeListColumnsCustomizationPopup.AddCheckListBoxItems;
var
I: Integer;
AColumn: TcxTreeListColumn;
AItem: TcxCheckListBoxItem;
begin
CheckListBox.Items.BeginUpdate;
try
for I := 0 to TreeList.ColumnCount - 1 do
begin
AColumn := TreeList.Columns[I];
if not AColumn.Options.Customizing or
AColumn.Options.Hidden then
Continue;
AItem := CheckListBox.Items.Add;
AItem.Checked := AColumn.Visible;
AItem.ItemObject := AColumn;
AItem.Text := AColumn.Caption.Text;
end;
finally
CheckListBox.Items.EndUpdate;
end;
end;
function TcxTreeListColumnsCustomizationPopup.GetDropDownCount: Integer;
begin
Result := TreeList.OptionsCustomizing.ColumnsQuickCustomizationMaxDropDownCount;
end;
procedure TcxTreeListColumnsCustomizationPopup.ItemClicked(
AItem: TObject; AChecked: Boolean);
begin
TcxTreeListColumn(AItem).Visible := AChecked;
TreeList.Modified;
end;
{ TcxTreeListBandsCustomizationPopup }
procedure TcxTreeListBandsCustomizationPopup.AddCheckListBoxItems;
var
I: Integer;
ABand: TcxTreeListBand;
AItem: TcxCheckListBoxItem;
begin
CheckListBox.Items.BeginUpdate;
try
CheckListBox.Items.Clear;
for I := 0 to TreeList.Bands.Count - 1 do
begin
ABand := TreeList.Bands[I];
if not ABand.Options.Customizing or
ABand.Options.Hidden then
Continue;
AItem := CheckListBox.Items.Add;
AItem.Checked := ABand.Visible;
AItem.ItemObject := ABand;
AItem.Text := ABand.Caption.Text;
end;
finally
CheckListBox.Items.EndUpdate;
end;
end;
function TcxTreeListBandsCustomizationPopup.GetDropDownCount: Integer;
begin
Result := TreeList.OptionsCustomizing.BandsQuickCustomizationMaxDropDownCount;
end;
procedure TcxTreeListBandsCustomizationPopup.ItemClicked(AItem: TObject; AChecked: Boolean);
var
AItems: TList;
begin
TcxTreeListBand(AItem).Visible := AChecked;
AItems := TList.Create;
try
GetCheckListBoxSelectedItems(AItems);
RefreshCheckListBoxItems;
SetCheckListBoxSelectedItems(AItems);
finally
AItems.Free;
end;
AdjustCheckListBoxSize;
RestoreControlsBounds;
CalculateSize;
TreeList.Modified;
end;
{ TcxTreeListColumnStyles }
constructor TcxTreeListColumnStyles.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
BitmapInViewParams := True;
end;
procedure TcxTreeListColumnStyles.Assign(Source: TPersistent);
begin
if Source is TcxTreeListColumnStyles then
begin
Header := TcxTreeListColumnStyles(Source).Header;
Footer := TcxTreeListColumnStyles(Source).Footer;
end;
inherited Assign(Source);
end;
function TcxTreeListColumnStyles.GetContentParams(
ANode: TcxTreeListNode): TcxViewParams;
begin
GetViewParams(ecs_Content, ANode, nil, Result);
end;
procedure TcxTreeListColumnStyles.GetDefaultViewParams(
Index: Integer; AData: TObject; out AParams: TcxViewParams);
var
ACellPos: TcxTreeListCellPos;
begin
inherited GetDefaultViewParams(Index, AData, AParams);
case Index of
ecs_Content:
begin
if Column.IsPreview then
TreeList.Styles.DoGetPreviewParams(TcxTreeListNode(AData), AParams)
else
if Band <> nil then
Band.Styles.DoGetContentParams(TcxTreeListNode(AData), Column, AParams)
else
TreeList.Styles.DoGetContentParams(TcxTreeListNode(AData), Column, AParams);
end;
tlcs_Footer:
if Band <> nil then
begin
ACellPos := TcxTreeListCellPos.Create(TcxTreeListNode(AData), Column);
try
Band.Styles.GetViewParams(tlbs_Footer, ACellPos, nil, AParams);
finally
ACellPos.Free;
end;
end;
tlcs_Header:
TreeList.Styles.DoGetColumnHeaderParams(Column, AParams);
end;
end;
function TcxTreeListColumnStyles.GetBand: TcxTreeListBand;
begin
Result := Column.Position.Band;
end;
function TcxTreeListColumnStyles.GetColumn: TcxTreeListColumn;
begin
Result := TcxTreeListColumn(GetOwner);
end;
function TcxTreeListColumnStyles.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(Control);
end;
{ TcxTreeListColumnPosition }
constructor TcxTreeListColumnPosition.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FBandIndex := -1;
FColIndex := -1;
FLineCount := 1;
FRowIndex := -1;
FVisibleColIndex := -1;
end;
procedure TcxTreeListColumnPosition.Assign(Source: TPersistent);
begin
if Source is TcxTreeListColumnPosition then
begin
Self.FBandIndex := TcxTreeListColumnPosition(Source).BandIndex;
Self.FRowIndex := TcxTreeListColumnPosition(Source).RowIndex;
Self.FColIndex := TcxTreeListColumnPosition(Source).ColIndex;
Self.FLineCount := TcxTreeListColumnPosition(Source).LineCount;
end
else
inherited Assign(Source);
end;
procedure TcxTreeListColumnPosition.SetPosition(
AColIndex, ARowIndex: Integer; IsInsertRow: Boolean = False);
begin
SetPositionEx(BandIndex, AColIndex, ARowIndex, IsInsertRow);
end;
procedure TcxTreeListColumnPosition.SetPositionEx(
ABandIndex, AColIndex, ARowIndex: Integer; IsInsertRow: Boolean = False);
begin
TreeList.BeginUpdate;
try
BandIndex := ABandIndex;
ColIndex := AColIndex;
if Band <> nil then
begin
if not IsInsertRow or not cxInRange(ARowIndex, 0, Band.BandRows.Count) then
RowIndex := ARowIndex
else
Row := Band.BandRows.Insert(ARowIndex);
end;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListColumnPosition.Changed;
begin
TreeList.StructureChanged;
end;
function TcxTreeListColumnPosition.IsPositionChanged: Boolean;
begin
Result := (BandIndex <> FBandIndex) or (ColIndex <> FColIndex) or
(RowIndex <> FRowIndex);
end;
procedure TcxTreeListColumnPosition.Restore;
begin
BandIndex := FBandIndex;
RowIndex := FRowIndex;
ColIndex := FColIndex;
end;
procedure TcxTreeListColumnPosition.Store;
begin
FBandIndex := BandIndex;
FColIndex := ColIndex;
FRowIndex := RowIndex;
end;
function TcxTreeListColumnPosition.GetColumn: TcxTreeListColumn;
begin
Result := TcxTreeListColumn(GetOwner);
end;
function TcxTreeListColumnPosition.GetIsUpdating: Boolean;
begin
Result := Column.IsLoading or Column.IsUpdating or
TreeList.IsRestoring or TreeList.IsLoading or TreeList.IsUpdating;
end;
function TcxTreeListColumnPosition.GetTreeList: TcxCustomTreeList;
begin
Result := Column.TreeList;
end;
function TcxTreeListColumnPosition.GetBandIndex: Integer;
begin
if FBand = nil then
Result := -1
else
Result := FBand.Index;
end;
function TcxTreeListColumnPosition.GetColIndex: Integer;
begin
if Row = nil then
Result := -1
else
Result := Row.IndexOf(Column);
end;
function TcxTreeListColumnPosition.GetRowIndex: Integer;
begin
if Row = nil then
Result := -1
else
Result := Row.Index;
end;
function TcxTreeListColumnPosition.GetVisibleBandIndex: Integer;
begin
if FBand = nil then
Result := -1
else
Result := FBand.VisibleIndex;
end;
function TcxTreeListColumnPosition.GetVisibleRowIndex: Integer;
begin
if Row = nil then
Result := -1
else
Result := Row.VisibleIndex;
end;
procedure TcxTreeListColumnPosition.SetBandIndex(AValue: Integer);
var
ANewBand: TcxTreeListBand;
begin
if BandIndex = AValue then Exit;
if Column.IsReading or Column.IsUpdating then
begin
FBandIndex := AValue;
Exit;
end;
if (0 <= AValue) and (AValue < TreeList.Bands.Count) then
ANewBand := TreeList.Bands[AValue]
else
ANewBand := nil;
if (ANewBand <> nil) and not ANewBand.IsBottom then
ANewBand.MoveBandsToRoot;
TreeList.BeginUpdate;
try
if FBand <> nil then
FBand.DeleteColumn(Column);
FBand := nil;
if ANewBand <> nil then
ANewBand.AddColumn(Column);
Changed;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListColumnPosition.SetColIndex(AValue: Integer);
begin
if IsUpdating then
FColIndex := AValue
else
if (FBand <> nil) and (ColIndex >= 0) and (AValue >= 0) then
begin
if AValue > ColIndex then
Dec(AValue);
AValue := Min(Row.Count - 1, AValue);
Row.FItems.Move(ColIndex, AValue);
Changed;
end;
end;
procedure TcxTreeListColumnPosition.SetLineCount(AValue: Integer);
begin
if AValue < 1 then
AValue := 1;
if FLineCount <> AValue then
begin
FLineCount := AValue;
Changed;
end;
end;
procedure TcxTreeListColumnPosition.SetRow(AValue: TcxTreeListBandRow);
begin
if AValue.Band <> Band then
BandIndex := AValue.Band.Index;
if FRow = AValue then Exit;
if FRow <> nil then
begin
FRow.FItems.Remove(Column);
FRow.CheckEmpty;
end;
if AValue <> nil then
AValue.FItems.Add(Column);
FRow := AValue;
Changed;
end;
procedure TcxTreeListColumnPosition.SetRowIndex(AValue: Integer);
begin
if IsUpdating then
FRowIndex := AValue
else
begin
if (FBand = nil) or (RowIndex = AValue) then Exit;
if AValue >= 0 then
Row := Band.BandRows.CheckRowIndex(AValue);
end;
end;
{ TcxTreeListCaption }
constructor TcxTreeListCaption.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FGlyph := TBitmap.Create;
FShowEndEllipsis := True;
end;
destructor TcxTreeListCaption.Destroy;
begin
FreeAndNil(FGlyph);
inherited Destroy;
end;
procedure TcxTreeListCaption.Assign(Source: TPersistent);
begin
if Source is TcxTreeListCaption then
begin
FAlignHorz := TcxTreeListCaption(Source).FAlignHorz;
FAlignVert := TcxTreeListCaption(Source).FAlignVert;
FText := TcxTreeListCaption(Source).Text;
FGlyphAlignHorz := TcxTreeListCaption(Source).FGlyphAlignHorz;
FGlyphAlignVert := TcxTreeListCaption(Source).FGlyphAlignVert;
FMultiLine := TcxTreeListCaption(Source).FMultiLine;
FShowEndEllipsis := TcxTreeListCaption(Source).FShowEndEllipsis;
Glyph := TcxTreeListCaption(Source).Glyph;
end
else
inherited Assign(Source);
end;
procedure TcxTreeListCaption.Changed;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
function TcxTreeListCaption.GetText: string;
begin
Result := FText;
if (Result = '') and (GetOwner is TcxTreeListColumn) then
Result := TcxTreeListColumn(GetOwner).GetDefaultCaption;
end;
function TcxTreeListCaption.IsTextStored: Boolean;
begin
Result := FText <> '';
if Result and (GetOwner is TcxTreeListColumn) then
Result := FText <> TcxTreeListColumn(GetOwner).GetDefaultCaption;
end;
procedure TcxTreeListCaption.SetAlignHorz(AValue: TAlignment);
begin
if AValue <> FAlignHorz then
begin
FAlignHorz := AValue;
Changed;
end;
end;
procedure TcxTreeListCaption.SetAlignVert(AValue: TcxAlignmentVert);
begin
if AValue <> FAlignVert then
begin
FAlignVert := AValue;
Changed;
end;
end;
procedure TcxTreeListCaption.SetGlyph(AValue: TBitmap);
begin
if AValue = nil then
FGlyph.FreeImage
else
FGlyph.Assign(AValue);
Changed;
end;
procedure TcxTreeListCaption.SetGlyphAlignHorz(AValue: TAlignment);
begin
if AValue <> FGlyphAlignHorz then
begin
FGlyphAlignHorz := AValue;
if not FGlyph.Empty then
Changed;
end;
end;
procedure TcxTreeListCaption.SetGlyphAlignVert(AValue: TcxAlignmentVert);
begin
if AValue <> FGlyphAlignVert then
begin
FGlyphAlignVert := AValue;
if not FGlyph.Empty then
Changed;
end;
end;
procedure TcxTreeListCaption.SetMultiLine(AValue: Boolean);
begin
if AValue <> FMultiLine then
begin
FMultiLine := AValue;
Changed;
end;
end;
procedure TcxTreeListCaption.SetShowEndEllipsis(AValue: Boolean);
begin
if AValue <> FShowEndEllipsis then
begin
FShowEndEllipsis := AValue;
Changed;
end;
end;
procedure TcxTreeListCaption.SetText(const AValue: string);
begin
if AValue <> FText then
begin
FText := AValue;
Changed;
end;
end;
{ TcxTreeListColumnOptions }
constructor TcxTreeListColumnOptions.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
RestoreDefaults;
end;
procedure TcxTreeListColumnOptions.Assign(Source: TPersistent);
begin
if Source is TcxTreeListColumnOptions then
begin
FCellEndEllipsis := TcxTreeListColumnOptions(Source).CellEndEllipsis;
FSizing := TcxTreeListColumnOptions(Source).Sizing;
FFooter := TcxTreeListColumnOptions(Source).Footer;
FHidden := TcxTreeListColumnOptions(Source).Hidden;
FGroupFooter := TcxTreeListColumnOptions(Source).FGroupFooter;
FVertSizing := TcxTreeListColumnOptions(Source).VertSizing;
end;
inherited Assign(Source);
end;
procedure TcxTreeListColumnOptions.RestoreDefaults;
begin
FCellEndEllipsis := True;
FSizing := True;
FFooter := True;
FHidden := False;
FGroupFooter := True;
Sorting := True;
Customizing := True;
Editing := True;
TabStop := True;
Focusing := True;
Moving := True;
VertSizing := True;
Changed;
end;
procedure TcxTreeListColumnOptions.Changed;
begin
Column.Changed;
end;
function TcxTreeListColumnOptions.GetColumn: TcxTreeListColumn;
begin
Result := TcxTreeListColumn(EditContainer);
end;
procedure TcxTreeListColumnOptions.SetCellEndEllipsis(AValue: Boolean);
begin
if AValue <> FFooter then
begin
FCellEndEllipsis := AValue;
Changed;
end;
end;
procedure TcxTreeListColumnOptions.SetFooter(AValue: Boolean);
begin
if AValue <> FFooter then
begin
FFooter := AValue;
Changed;
end;
end;
procedure TcxTreeListColumnOptions.SetGroupFooter(AValue: Boolean);
begin
if AValue <> FGroupFooter then
begin
FGroupFooter := AValue;
Changed;
end;
end;
procedure TcxTreeListColumnOptions.SetSizing(AValue: Boolean);
begin
if AValue <> FSizing then
begin
FSizing := AValue;
Changed;
end;
end;
procedure TcxTreeListColumnOptions.SetVertSizing(AValue: Boolean);
begin
if AValue <> FVertSizing then
begin
FVertSizing := AValue;
Changed;
end;
end;
{ TcxTreeListSummaryItem }
constructor TcxTreeListSummaryItem.Create(Collection: TCollection);
begin
inherited Create(Collection);
FAbsoluteIndex := -1;
FAllNodes := True;
FVisible := True;
end;
function TcxTreeListSummaryItem.FormatValue(const AValue: Variant; AIsFooter: Boolean): string;
begin
Result := inherited FormatValue(AValue, AIsFooter);
if Assigned(FOnGetText) then
FOnGetText(Self, AValue, Result);
end;
procedure TcxTreeListSummaryItem.AssignValues(Source: TcxCustomDataSummaryItem);
begin
inherited AssignValues(Source);
if Source is TcxTreeListSummaryItem then
begin
FCalculatedColumn := Column.TreeList.GetSameColumn(
TcxTreeListSummaryItem(Source).CalculatedColumn);
AllNodes := TcxTreeListSummaryItem(Source).AllNodes;
Visible := TcxTreeListSummaryItem(Source).Visible;
OnGetText := TcxTreeListSummaryItem(Source).OnGetText;
end;
end;
function TcxTreeListSummaryItem.GetDataController: TcxCustomDataController;
begin
Result := nil;
end;
function TcxTreeListSummaryItem.GetValueFormat(AValueType: TcxSummaryValueType; const AValue: Variant;
AIsFooter: Boolean): string;
begin
Result := inherited GetValueFormat(AValueType, AValue, AIsFooter);
if Result = '' then
Result := cxDataGetDataSummaryValueDefaultFormat(AValueType, AValue, AIsFooter);
end;
procedure TcxTreeListSummaryItem.Notification(AComponent: TComponent; Operation: TOperation);
begin
if (Operation = opRemove) and (AComponent = FCalculatedColumn) then
CalculatedColumn := nil;
end;
function TcxTreeListSummaryItem.GetCalculatedColumn: TcxTreeListColumn;
begin
if FCalculatedColumn <> nil then
Result := FCalculatedColumn
else
Result := Column;
end;
function TcxTreeListSummaryItem.GetColumn: TcxTreeListColumn;
begin
Result := TcxTreeListSummaryItems(Collection).Column;
end;
function TcxTreeListSummaryItem.IsCalculatedColumnStored: Boolean;
begin
Result := FCalculatedColumn <> nil;
end;
procedure TcxTreeListSummaryItem.SetAlignHorz(AValue: TAlignment);
begin
if AValue <> FAlignHorz then
begin
FAlignHorz := AValue;
Changed(True);
end;
end;
procedure TcxTreeListSummaryItem.SetAlignVert(AValue: TcxAlignmentVert);
begin
if AValue <> FAlignVert then
begin
FAlignVert := AValue;
Changed(True);
end;
end;
procedure TcxTreeListSummaryItem.SetAllNodes(AValue: Boolean);
begin
if AValue <> FAllNodes then
begin
FAllNodes := AValue;
Changed(True);
end;
end;
procedure TcxTreeListSummaryItem.SetCalculatedColumn(AValue: TcxTreeListColumn);
begin
if AValue <> FCalculatedColumn then
begin
FCalculatedColumn := AValue;
Changed(True);
end;
end;
procedure TcxTreeListSummaryItem.SetMultiLine(AValue: Boolean);
begin
if AValue <> FMultiLine then
begin
FMultiLine := AValue;
Changed(True);
end;
end;
procedure TcxTreeListSummaryItem.SetVisible(AValue: Boolean);
begin
if AValue <> FVisible then
begin
FVisible := AValue;
Changed(True);
end;
end;
{ TcxTreeListColumnSummary }
procedure TcxTreeListColumnSummary.Assign(Source: TPersistent);
begin
if Source is TcxTreeListColumnSummary then
begin
GroupFooterSummaryItems := TcxTreeListColumnSummary(Source).GroupFooterSummaryItems;
FooterSummaryItems := TcxTreeListColumnSummary(Source).FooterSummaryItems;
end
else
inherited Assign(Source);
end;
procedure TcxTreeListColumnSummary.Changed(ARedrawOnly: Boolean);
begin
Column.TreeList.StructureChanged;
end;
constructor TcxTreeListColumnSummary.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FFooterSummaryItems := TcxTreelistSummaryItems.Create(Self, TcxTreeListSummaryItem);
FGroupFooterSummaryItems := TcxTreelistSummaryItems.Create(Self, TcxTreeListSummaryItem);
end;
destructor TcxTreeListColumnSummary.Destroy;
begin
FreeAndNil(FGroupFooterSummaryItems);
FreeAndNil(FFooterSummaryItems);
inherited Destroy;
end;
function TcxTreeListColumnSummary.GetColumn: TcxTreeListColumn;
begin
Result := TcxTreeListColumn(GetOwner);
end;
function TcxTreeListColumnSummary.GetFooterVisibleCount: Integer;
begin
Result := FooterSummaryItems.Count;
end;
function TcxTreeListColumnSummary.GetGroupFooterVisibleCount: Integer;
begin
Result := GroupFooterSummaryItems.Count;
end;
procedure TcxTreeListColumnSummary.SetFooterSummaryItems(
AValue: TcxTreeListSummaryItems);
begin
FFooterSummaryItems.Assign(AValue);
end;
procedure TcxTreeListColumnSummary.SetGroupFooterSummaryItems(
AValue: TcxTreeListSummaryItems);
begin
FGroupFooterSummaryItems.Assign(AValue);
end;
{ TcxTreeListSummaryItems }
constructor TcxTreeListSummaryItems.Create(ASummary: TcxTreeListColumnSummary; AItemClass: TcxTreeListSummaryItemClass);
begin
inherited Create(AItemClass);
FSummary := ASummary;
end;
function TcxTreeListSummaryItems.Add: TcxTreeListSummaryItem;
begin
BeginUpdate;
try
Result := TcxTreeListSummaryItem(inherited Add);
finally
EndUpdate
end;
end;
function TcxTreeListSummaryItems.GetItemByKind(AKind: TcxSummaryKind): TcxTreeListSummaryItem;
var
I: Integer;
begin
Result := nil;
for I := 0 to Count - 1 do
if Items[I].Kind = AKind then
begin
Result := Items[I];
Break;
end;
end;
function TcxTreeListSummaryItems.GetOwner: TPersistent;
begin
Result := FSummary;
end;
procedure TcxTreeListSummaryItems.Update(Item: TCollectionItem);
var
I: Integer;
AItem: TcxTreeListSummaryItem;
begin
FVisibleCount := 0;
for I := 0 to Count - 1 do
begin
AItem := Items[I];
if AItem.Visible then
begin
AItem.FVisibleIndexInColumn := FVisibleCount;
Inc(FVisibleCount);
end
else
AItem.FVisibleIndexInColumn := -1;
end;
FSummary.Changed(Item <> nil);
end;
function TcxTreeListSummaryItems.GetItem(
AIndex: Integer): TcxTreeListSummaryItem;
begin
Result := TcxTreeListSummaryItem(inherited GetItem(AIndex));
end;
procedure TcxTreeListSummaryItems.SetItem(AIndex: Integer;
AValue: TcxTreeListSummaryItem);
begin
inherited SetItem(AIndex, AValue);
end;
function TcxTreeListSummaryItems.GetColumn: TcxTreeListColumn;
begin
Result := Summary.Column;
end;
type
TcxTreeListDeprecatedColumnSummaryFooter = class(TcxOwnedPersistent)
private
FAlignHorz: TAlignment;
FAlignVert: TcxAlignmentVert;
FFormat: string;
FKind: TcxSummaryKind;
FMultiLine: Boolean;
public
procedure Assign(Source: TPersistent); override;
published
property AlignHorz: TAlignment read FAlignHorz write FAlignHorz;
property AlignVert: TcxAlignmentVert read FAlignVert write FAlignVert;
property Format: string read FFormat write FFormat;
property Kind: TcxSummaryKind read FKind write FKind;
property MultiLine: Boolean read FMultiLine write FMultiLine;
end;
{ TcxTreeListDeprecatedColumnSummaryFooter }
procedure TcxTreeListDeprecatedColumnSummaryFooter.Assign(
Source: TPersistent);
var
ASourceSummaryFooter: TcxTreeListDeprecatedColumnSummaryFooter;
begin
if Source is TcxTreeListDeprecatedColumnSummaryFooter then
begin
ASourceSummaryFooter := TcxTreeListDeprecatedColumnSummaryFooter(Source);
AlignHorz := ASourceSummaryFooter.AlignHorz;
AlignVert := ASourceSummaryFooter.AlignVert;
Format := ASourceSummaryFooter.Format;
Kind := ASourceSummaryFooter.Kind;
MultiLine := ASourceSummaryFooter.MultiLine;
end
else
inherited Assign(Source);
end;
{ TcxTreeListColumn }
constructor TcxTreeListColumn.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FSortIndex := -1;
FSummaryFooter := TcxTreeListDeprecatedColumnSummaryFooter.Create(Self);
FSummary := GetSummaryClass.Create(Self);
FCaption := TcxTreeListCaption.Create(Self);
FCaption.OnChange := ChangeCaption;
FPosition := GetPositionClass.Create(Self);
FMinWidth := cxTreeListDefMinWidth;
FVisible := True;
end;
destructor TcxTreeListColumn.Destroy;
begin
SortOrder := soNone;
Position.BandIndex := -1;
if TreeList <> nil then
TreeList.HideEdit;
if (TreeList <> nil) and not TreeList.IsDestroying then
begin
TreeList.AddChanges([tcColumns]);
TreeList.UpdateDesignerForms;
TreeList.ViewInfo.SetDirty;
if TreeList <> nil then
TreeList.ColumnsList.Remove(Self);
if Controller.FocusedItem = Self then
Controller.FocusedItem := nil;
if TreeList.Preview.Column = Self then
TreeList.Preview.Column := nil;
if TreeList.OptionsView.CategorizedColumn = Self then
TreeList.OptionsView.CategorizedColumn := nil;
end;
FreeAndNil(FCaption);
FreeAndNil(FPosition);
FreeAndNil(FSummary);
FreeAndNil(FSummaryFooter);
inherited Destroy;
end;
procedure TcxTreeListColumn.Assign(Source: TPersistent);
var
AColumn: TcxTreeListColumn;
begin
TreeList.BeginUpdate;
try
inherited Assign(Source);
if Source is TcxTreeListColumn then
begin
AColumn := TcxTreeListColumn(Source);
FCalculatedWidth := AColumn.FCalculatedWidth;
FMinWidth := AColumn.FMinWidth;
FWidth := AColumn.FWidth;
Position := TcxTreeListColumn(Source).Position;
Caption := AColumn.Caption;
SortOrder := AColumn.FSortOrder;
Summary := AColumn.Summary;
Visible := AColumn.Visible;
end;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListColumn.ApplyBestFit;
var
ANode: TcxTreeListNode;
AWidth, ACount: Integer;
begin
if (TreeList = nil) or TreeList.IsLoading or TreeList.IsDestroying then Exit;
TreeList.ValidateStates;
ANode := TreeList.GetStartNodeForBestFit;
if ANode = nil then Exit;
AWidth := MinWidth + IndentWidth;
ACount := TreeList.GetCountNodeForBestFit;
try
TreeList.HideEdit;
while (ACount <> 0) and (ANode <> nil) do
begin
AWidth := Max(AWidth, TcxFakeCellViewInfo(
TreeList.ViewInfo.FakeCell).MeasureWidth(Self, ANode));
ANode := ANode.GetNextVisible;
Dec(ACount);
end;
SetSizeDelta(dsdHorz, Max(AWidth, GetHeaderFooterBestfitSize) - DisplayWidth);
finally
TreeList.Controller.CheckEdit;
end;
end;
function TcxTreeListColumn.GetDisplayText(ANode: TcxTreeListNode): string;
begin
Result := VarToStr(DoOnGetDisplayText(ANode, True));
end;
function TcxTreeListColumn.GetParentComponent: TComponent;
begin
Result := EditingControl;
end;
function TcxTreeListColumn.HasParent: Boolean;
begin
Result := True;
end;
procedure TcxTreeListColumn.MakeVisible;
var
CellR, R: TRect;
begin
if not ActuallyVisible or (Position.Band.FixedKind <> tlbfNone) or
(HeaderCell = nil) or not HeaderCell.HasClipping then Exit;
R := TreeList.ViewInfo.HScrollArea;
CellR := HeaderCell.DisplayRect;
if FocusedCellViewInfo <> nil then
begin
if (cxRectWidth(FocusedCellViewInfo.VisibleRect) < MinWidth) then
CellR := FocusedCellViewInfo.BoundsRect
else
if (CellR.Left <= R.Left) and (CellR.Right >= R.Right) and
(FocusedCellViewInfo.BoundsRect.Left > R.Left) then Exit;
end;
if (CellR.Right > R.Right) and (CellR.Left > R.Left) then
TreeList.ViewInfo.HScrollPos := TreeList.ViewInfo.HScrollPos + (CellR.Right - R.Right)
else
if CellR.Left < R.Left then
TreeList.ViewInfo.HScrollPos := TreeList.ViewInfo.HScrollPos - (R.Left - CellR.Left);
TreeList.UpdateScrollBars;
end;
procedure TcxTreeListColumn.RestoreDefaults;
begin
TreeList.BeginUpdate;
try
Options.RestoreDefaults;
SortOrder := soNone;
Caption.FAlignVert := vaTop;
Caption.FAlignHorz := taLeftJustify;
RestoreWidths;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListColumn.RestoreWidths;
begin
TreeList.BeginUpdate;
try
FMinWidth := cxTreeListDefMinWidth;
SetWidth(cxTreeListDefWidth);
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListColumn.AssignWidth;
begin
if FWidth = 0 then
FWidth := DisplayWidth;
end;
function TcxTreeListColumn.CanMoving: Boolean;
begin
Result := TreeList.OptionsCustomizing.ColumnMoving and Options.Moving;
end;
function TcxTreeListColumn.CanSort: Boolean;
begin
Result := not Assigned(OnGetEditProperties) and
(esoSorting in PropertiesValue.GetSupportedOperations);
if not Result then
Result := Assigned(TreeList.FOnCompare);
end;
procedure TcxTreeListColumn.ChangeCaption(Sender: TObject);
begin
Changed;
end;
procedure TcxTreeListColumn.Changed;
begin
inherited Changed;
if TreeList <> nil then
TreeList.Summary.Recalculate;
end;
procedure TcxTreeListColumn.ForceWidth(AWidth: Integer);
begin
TreeList.ValidateStates;
AWidth := Max(AWidth, MinWidth);
if Width = AWidth then Exit;
TreeList.Controller.ForcingWidthColumn := Self;
TreeList.Bands.AssignColumnsWidth;
Width := AWidth;
TreeList.Bands.Adjust();
TreeList.Bands.AssignColumnsWidth;
TreeList.Controller.ForcingWidthColumn := nil;
end;
function TcxTreeListColumn.CanEdit: Boolean;
begin
Result := Assigned(ValueDef) and CanFocus and Options.Editing and
TreeList.Options.OptionsData.Editing and (TreeList.FocusedNode <> nil) and
not TreeList.FocusedNode.IsHidden;
end;
function TcxTreeListColumn.GetEditValue: Variant;
begin
if Editing then
begin
if TreeList.FocusedNode = nil then
Result := Null
else
Result := DataController.GetNodeValue(TreeList.FocusedNode, ItemIndex);
end
else
Result := Unassigned;
end;
function TcxTreeListColumn.CanInitEditing: Boolean;
begin
Result := CanEdit;
if Result then
begin
if TreeList.DataController.EditingNode <> TreeList.FocusedNode then
TreeList.Post;
TreeList.DataController.Edit;
end;
end;
procedure TcxTreeListColumn.CancelSorting;
begin
FSortOrder := soNone;
FSortIndex := -1;
TreeList.FSortedColumns.Remove(Self);
TreeList.AddChanges([tcSortOrder]);
end;
function TcxTreeListColumn.CanFocus: Boolean;
begin
Result := inherited CanFocus and TreeList.OptionsSelection.CellSelect and
(Self <> TreeList.Preview.Column);
end;
function TcxTreeListColumn.GetRealSortOrder: TcxDataSortOrder;
begin
Result := soNone;
if CanSort then
Result := FSortOrder;
end;
function TcxTreeListColumn.GetHeaderFooterBestfitSize: Integer;
begin
Result := 0;
if TreeList.OptionsView.Headers then
begin
Result := cxTextWidth(TreeList.Styles.GetColumnHeaderParams(
Self).Font, Caption.Text) + cxTextOffset * 3;
if not Caption.Glyph.Empty and (Byte(Caption.GlyphAlignHorz) < 2) then
Inc(Result, Caption.Glyph.Width + cxTextOffset);
if SortOrder <> soNone then
Inc(Result, TreeList.LookAndFeelPainter.SortingMarkAreaSize.X);
end;
if Options.Footer and TreeList.OptionsView.Footer
and (Summary.FooterVisibleCount > 0) then
begin
//todo: v5
end;
end;
function TcxTreeListColumn.GetOptionsClass: TcxCustomEditContainerItemOptionsClass;
begin
Result := TcxTreeListColumnOptions;
end;
function TcxTreeListColumn.GetStylesClass: TcxEditContainerStylesClass;
begin
Result := TcxTreeListColumnStyles;
end;
function TcxTreeListColumn.GetSummaryClass: TcxTreeListColumnSummaryClass;
begin
Result := TcxTreeListColumnSummary;
end;
procedure TcxTreeListColumn.SetEditingControl(Value: TcxEditingControl);
begin
if TreeList <> nil then
begin
TreeList.ContainerList.Remove(Self);
TreeList.AddChanges([tcColumns]);
end;
inherited SetEditingControl(Value);
if TreeList <> nil then
begin
TreeList.AddChanges([tcColumns]);
TreeList.UpdateDesignerForms;
end;
end;
procedure TcxTreeListColumn.SetName(const Value: TComponentName);
begin
inherited SetName(Value);
if Assigned(FOnChangeName) then
FOnChangeName(Self);
end;
procedure TcxTreeListColumn.SetParentComponent(Value: TComponent);
begin
if Value is TcxEditingControl then
EditingControl := Value as TcxEditingControl
else
EditingControl := nil;
end;
function TcxTreeListColumn.CanSizing(ADirection: TcxDragSizingDirection): Boolean;
begin
if ADirection = dsdVert then
Result := Options.VertSizing and TreeList.OptionsCustomizing.ColumnVertSizing
else
Result := Options.Sizing and TreeList.OptionsCustomizing.ColumnHorzSizing;
end;
function TcxTreeListColumn.GetAvailableMaxWidth: Integer;
var
I: Integer;
begin
if Position.Band.Width = 0 then
Result := High(SmallInt)
else
begin
if Position.Band.Width = 0 then
Result := Position.Band.Width - Position.Row.MinWidth
else
begin
Result := Position.Band.CalculatedWidth;
for I := 0 to Position.Row.VisibleItemCount - 1 do
begin
if I = Position.VisibleColIndex then Continue;
if (I < Position.VisibleColIndex) and
(Position.VisibleColIndex <> Position.Row.VisibleItemCount - 1) then
Dec(Result, Position.Row.VisibleItems[I].DisplayWidth)
else
Dec(Result, Position.Row.VisibleItems[I].MinWidth);
end;
end;
end;
end;
function TcxTreeListColumn.GetRealMinSize: Integer;
begin
if Options.Sizing then
Result := FMinWidth + IndentWidth
else
Result := FWidth;
end;
function TcxTreeListColumn.GetSizingBoundsRect(
ADirection: TcxDragSizingDirection): TRect;
begin
if ADirection = dsdVert then
Result := cxRectSetTop(TreeList.ClientRect,
HeaderCell.DisplayRect.Top + TreeList.ViewInfo.HeaderLineHeight)
else
begin
Result := cxRectSetLeft(TreeList.ClientRect,
HeaderCell.DisplayRect.Left + GetRealMinSize, GetAvailableMaxWidth - GetRealMinSize);
end;
end;
function TcxTreeListColumn.GetSizingIncrement(
ADirection: TcxDragSizingDirection): Integer;
begin
if ADirection = dsdHorz then
Result := 1
else
Result := TreeList.ViewInfo.HeaderLineHeight;
end;
function TcxTreeListColumn.IsDynamicUpdate: Boolean;
begin
Result := TreeList.OptionsCustomizing.DynamicSizing and
TreeList.HitTest.HitAtSizingHorz;
end;
procedure TcxTreeListColumn.SetSizeDelta(
ADirection: TcxDragSizingDirection; ADelta: Integer);
begin
if ADelta = 0 then Exit;
TreeList.BeginUpdate;
try
if ADirection = dsdVert then
Position.LineCount := Position.LineCount + ADelta
else
ForceWidth(DisplayWidth + ADelta);
finally
TreeList.EndUpdate;
end;
TreeList.LayoutChanged;
TreeList.Modified;
end;
function TcxTreeListColumn.GetObjectName: string;
begin
Result := Name;
if Result = '' then
Result := ClassName + IntToStr(ItemIndex);
end;
function TcxTreeListColumn.GetProperties(AProperties: TStrings): Boolean;
var
I: Integer;
begin
for I := Low(ColumnPropertiesName) to High(ColumnPropertiesName) do
AProperties.Add(ColumnPropertiesName[I]);
if Assigned(OnGetStoredProperties) then
OnGetStoredProperties(Self, AProperties);
Result := True;
end;
function TcxTreeListColumn.GetPropertyIndex(const AName: string): Integer;
var
I: Integer;
begin
Result := -1;
for I := Low(ColumnPropertiesName) to High(ColumnPropertiesName) do
begin
if AnsiCompareText(ColumnPropertiesName[I], AName) = 0 then
begin
Result := I;
Break;
end;
end;
end;
procedure TcxTreeListColumn.GetPropertyValue(
const AName: string; var AValue: Variant);
begin
case GetPropertyIndex(AName) of
0:
AValue := Visible;
1:
AValue := ItemIndex;
2:
AValue := Position.LineCount;
3:
AValue := Position.ColIndex;
4:
AValue := Position.RowIndex;
5:
AValue := Position.BandIndex;
6:
AValue := Caption.Text;
7:
AValue := SortOrder;
9:
AValue := FMinWidth;
10:
AValue := FWidth;
else
if Assigned(OnGetStoredPropertyValue) then
OnGetStoredPropertyValue(Self, AName, AValue);
end;
end;
procedure TcxTreeListColumn.SetPropertyValue(
const AName: string; const AValue: Variant);
begin
case GetPropertyIndex(AName) of
0:
Visible := AValue;
1:
ItemIndex := AValue;
2:
Position.LineCount := AValue;
3:
Position.ColIndex := AValue;
4:
Position.RowIndex := AValue;
5:
Position.BandIndex := AValue;
6:
if Caption.Text = '' then
Caption.Text := AValue;
7:
FSortOrder := AValue;
9:
FMinWidth := AValue;
10:
FWidth := AValue;
else
if Assigned(OnSetStoredPropertyValue) then
OnSetStoredPropertyValue(Self, AName, AValue);
end;
end;
procedure TcxTreeListColumn.ChangeSortOrder(
ASortOrder: TcxDataSortOrder; AShift: TShiftState);
begin
if not Options.Sorting or not CanSort then
ASortOrder := FSortOrder;
if ASortOrder <> FSortOrder then
begin
FSortOrder := ASortOrder;
TreeList.ColumnSortOrderChanged(Self, AShift);
TreeList.Modified;
end;
end;
procedure TcxTreeListColumn.ConvertOldFooterSummaries;
var
ASummaryFooter: TcxTreeListDeprecatedColumnSummaryFooter;
begin
ASummaryFooter := TcxTreeListDeprecatedColumnSummaryFooter(SummaryFooter);
if ASummaryFooter.Kind <> skNone then
with FSummary.FooterSummaryItems.Add do
begin
AlignHorz := ASummaryFooter.AlignHorz;
AlignVert := ASummaryFooter.AlignVert;
MultiLine := ASummaryFooter.MultiLine;
Format := ASummaryFooter.Format;
Kind := ASummaryFooter.Kind;
end;
end;
procedure TcxTreeListColumn.DoGetDisplayText(
ARecordIndex: Integer; var AText: string);
begin
if ARecordIndex <> 0 then
AText := DoGetNodeDisplayText(TcxTreeListNode(ARecordIndex), AText);
end;
function TcxTreeListColumn.DoGetNodeDisplayText(
ANode: TcxTreeListNode; const AValue: Variant): Variant;
var
AText: string;
begin
Result := AValue;
if Assigned(OnGetDisplayText) then
begin
AText := VarToStr(Result);
OnGetDisplayText(Self, ANode, AText);
Result := AText;
end;
end;
function TcxTreeListColumn.DoOnGetDisplayText(
ANode: TcxTreeListNode; AsText: Boolean = False; AValueOnly: Boolean = False): Variant;
var
AProperties: TcxCustomEditProperties;
AText: string;
begin
AProperties := DoGetEditProperties(ANode);
if AProperties.GetEditValueSource(False) = evsValue then
Result := DataController.GetNodeValue(ANode, ItemIndex)
else
Result := DataController.GetNodeDisplayText(ANode, ItemIndex);
if AValueOnly then Exit;
if Assigned(OnGetDisplayText) or AsText then
begin
if AProperties.GetEditValueSource(False) = evsValue then
begin
if AsText then
AText := AProperties.GetDisplayText(ANode.Values[ItemIndex], True)
else
AText := '';
AText := DoGetNodeDisplayText(ANode, AText);
if (AText = '') and not AsText then
Result := ANode.Values[ItemIndex]
else
Result := AText;
end
else
Result := DoGetNodeDisplayText(ANode, Result);
end;
end;
function TcxTreeListColumn.GetCellHeight(ANode: TcxTreeListNode;
AWidth, ALines: Integer; AFont: TFont; const AValue: Variant): Integer;
var
ASizeProp: TcxEditSizeProperties;
AEditProp: TcxCustomEditProperties;
AViewData: TcxCustomEditViewData;
begin
ASizeProp := cxDefaultEditSizeProp;
AEditProp := DoGetEditProperties(ANode);
AViewData := nil;
try
if AEditProp = PropertiesValue then
AViewData := EditViewData
else
AViewData := AEditProp.CreateViewData(TreeList.EditStyle, True);
AViewData.Style.Font := AFont;
ASizeProp.Width := AWidth;
ASizeProp.MaxLineCount := ALines;
Result := AViewData.GetEditSize(GetControlCanvas, AValue, ASizeProp).cy;
finally
if AViewData <> EditViewData then FreeAndNil(AViewData);
end;
end;
function TcxTreeListColumn.GetPositionClass: TcxTreeListColumnPositionClass;
begin
Result := TcxTreeListColumnPosition;
end;
function TcxTreeListColumn.HasDataTextHandler: Boolean;
begin
Result := Assigned(FOnGetDisplayText);
end;
procedure TcxTreeListColumn.InitAutoWidthItem(AItem: TcxAutoWidthItem);
begin
AItem.Width := Width;
AItem.Fixed := IsFixed;
AItem.MinWidth := FMinWidth + IndentWidth;
if AItem.Fixed then
begin
AItem.Width := Max(AItem.Width, AItem.MinWidth);
AItem.MinWidth := AItem.Width
end;
AItem.AutoWidth := -1;
end;
procedure TcxTreeListColumn.SetCurrentValue(const Value: Variant);
begin
if TreeList.FocusedNode <> nil then
TreeList.FocusedNode.Values[ItemIndex] := Value;
end;
function TcxTreeListColumn.GetEditingProperties: TcxTreeListGetEditPropertiesEvent;
begin
Result := TcxTreeListGetEditPropertiesEvent(inherited OnGetEditingProperties);
end;
function TcxTreeListColumn.GetEditProperties: TcxTreeListGetEditPropertiesEvent;
begin
Result := TcxTreeListGetEditPropertiesEvent(inherited OnGetEditProperties);
end;
function TcxTreeListColumn.GetHasIndent: Boolean;
begin
Result := (Position.Band <> nil) and (Position.VisibleColIndex = 0) and
Position.Band.ActuallyExpandable;
end;
function TcxTreeListColumn.GetID: Integer;
begin
Result := -1;
if TreeList <> nil then
Result := TreeList.ContainerList.IndexOf(Self);
end;
function TcxTreeListColumn.GetIndentWidth: Integer;
begin
Result := 0;
if HasIndent then
Result := Position.Band.IndentWidth;
end;
function TcxTreeListColumn.GetActuallyVisible: Boolean;
begin
Result := Visible and (Position.Band <> nil) and Position.Band.ActuallyVisible;
end;
function TcxTreeListColumn.GetDataController: TcxTreeListDataController;
begin
Result := TcxTreeListDataController(inherited DataController);
end;
function TcxTreeListColumn.GetDataBinding: TcxItemDataBinding;
begin
Result := TcxItemDataBinding(inherited DataBinding);
end;
function TcxTreeListColumn.GetDisplayWidth: Integer;
begin
TreeList.ValidateStates;
if not ActuallyVisible then
Result := 0
else
begin
Result := FCalculatedWidth;
if Result = 0 then
Result := Width;
end;
end;
function TcxTreeListColumn.GetIsFixed: Boolean;
var
AForcingColumn: TcxTreeListColumn;
APos: TcxTreeListColumnPosition;
begin
AForcingColumn := TreeList.Controller.ForcingWidthColumn;
Result := (TreeList.Controller.ForcingWidthColumn = Self) or not Options.Sizing;
if not Result and (AForcingColumn <> nil) then
begin
APos := AForcingColumn.Position;
Result := (APos = Position) or not AForcingColumn.IsRight and
(Position.Row = APos.Row) and (Position.VisibleColIndex < APos.VisibleColIndex);
end;
end;
function TcxTreeListColumn.GetIsHidden: Boolean;
begin
Result := not ActuallyVisible or IsPreview;
end;
function TcxTreeListColumn.GetIsLeft: Boolean;
begin
Result := ActuallyVisible and (Position.VisibleColIndex = 0);
end;
function TcxTreeListColumn.GetIsPreview: Boolean;
begin
Result := (TreeList <> nil) and (TreeList.Preview.Column = Self);
end;
function TcxTreeListColumn.GetIsRight: Boolean;
begin
with Position do
Result := ActuallyVisible and (VisibleColIndex = Row.VisibleItemCount - 1);
end;
function TcxTreeListColumn.GetIsLoading: Boolean;
begin
Result := (csLoading in ComponentState) and
((TreeList = nil) or not TreeList.IgnoreLoadingStatus);
end;
function TcxTreeListColumn.GetIsReading: Boolean;
begin
Result := csReading in ComponentState;
end;
function TcxTreeListColumn.GetIsUpdating: Boolean;
begin
Result := csUpdating in ComponentState;
end;
function TcxTreeListColumn.GetIsWidthStored: Boolean;
begin
Result := FWidth <> 0;
end;
function TcxTreeListColumn.GetSortIndex: Integer;
begin
Result := FSortIndex;
if SortOrder = soNone then
Result := -1;
end;
function TcxTreeListColumn.GetStyles: TcxTreeListColumnStyles;
begin
Result := TcxTreeListColumnStyles(inherited Styles);
end;
function TcxTreeListColumn.GetItemIndex: Integer;
begin
Result := TreeList.ColumnsList.IndexOf(Self);
end;
function TcxTreeListColumn.GetOptions: TcxTreeListColumnOptions;
begin
Result := TcxTreeListColumnOptions(inherited Options);
end;
function TcxTreeListColumn.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(EditingControl);
end;
function TcxTreeListColumn.GetValueByNode(ANode: TcxTreeListNode): Variant;
begin
Result := ANode.Values[ItemIndex];
end;
function TcxTreeListColumn.GetValueDef: TcxValueDef;
begin
Result := TcxCustomDataHelper.GetValueDef(
DataController.Fields[inherited ItemIndex]);
end;
function TcxTreeListColumn.GetVisibleIndex: Integer;
begin
Result := TreeList.FVisibleColumns.IndexOf(Self)
end;
function TcxTreeListColumn.GetWidth: Integer;
begin
Result := FWidth;
if Result = 0 then
Result := cxTreeListDefWidth;
Result := Max(MinWidth, Result);
end;
procedure TcxTreeListColumn.SetCaption(AValue: TcxTreeListCaption);
begin
FCaption.Assign(AValue);
end;
procedure TcxTreeListColumn.SetDataBinding(AValue: TcxItemDataBinding);
begin
DataBinding.Assign(AValue);
end;
procedure TcxTreeListColumn.SetDisplayWidth(AValue: Integer);
begin
ForceWidth(AValue);
end;
procedure TcxTreeListColumn.SetEditingProperties(
AValue: TcxTreeListGetEditPropertiesEvent);
begin
inherited OnGetEditingProperties := TcxGetEditPropertiesEvent(AValue);
end;
procedure TcxTreeListColumn.SetEditProperties(
AValue: TcxTreeListGetEditPropertiesEvent);
begin
inherited OnGetEditProperties := TcxGetEditPropertiesEvent(AValue);
end;
procedure TcxTreeListColumn.SetIsPreview(AValue: Boolean);
begin
if Value <> IsPreview then
begin
if Value then
TreeList.Preview.Column := Self
else
TreeList.Preview.Column := nil;
end;
end;
procedure TcxTreeListColumn.SetItemIndex(AValue: Integer);
function IsIndexValid(AIndex: Integer): Boolean;
begin
Result := (AIndex >= 0) and (AIndex < TreeList.ContainerList.Count)
end;
begin
TreeList.BeginUpdate;
try
Inc(AValue, TreeList.ContainerList.Count - TreeList.ColumnsList.Count);
if IsIndexValid(ItemIndex) and IsIndexValid(AValue) then
TreeList.ContainerList.Exchange(ItemIndex, AValue);
TreeList.DataController.UpdateItemIndexes;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListColumn.SetMinWidth(AValue: Integer);
begin
if AValue < 0 then
AValue := 0;
if AValue <> FMinWidth then
begin
FMinWidth := AValue;
SetWidth(FMinWidth);
end;
end;
procedure TcxTreeListColumn.SetOptions(AValue: TcxTreeListColumnOptions);
begin
Options.Assign(AValue);
end;
procedure TcxTreeListColumn.SetPosition(AValue: TcxTreeListColumnPosition);
begin
FPosition.Assign(AValue);
end;
procedure TcxTreeListColumn.SetSortIndex(AValue: Integer);
var
I: Integer;
begin
if SortOrder = soNone then
AValue := -1;
if AValue <> FSortIndex then
begin
FSortIndex := AValue;
if IsLoading then Exit;
if AValue >= 0 then
begin
for I := AValue to TreeList.SortedColumnCount - 1 do
if TreeList.SortedColumns[I].FSortIndex > 0 then
Inc(TreeList.SortedColumns[I].FSortIndex);
end;
TreeList.DataLayoutChanged;
end;
end;
procedure TcxTreeListColumn.SetSortOrder(AValue: TcxDataSortOrder);
begin
ChangeSortOrder(AValue, []);
end;
procedure TcxTreeListColumn.SetStyles(AValue: TcxTreeListColumnStyles);
begin
Styles.Assign(AValue);
end;
procedure TcxTreeListColumn.SetSummary(AValue: TcxTreeListColumnSummary);
begin
FSummary.Assign(AValue);
end;
procedure TcxTreeListColumn.SetSummaryFooter(AValue: TPersistent);
begin
FSummaryFooter.Assign(AValue);
end;
procedure TcxTreeListColumn.SetValueByNode(
ANode: TcxTreeListNode; const AValue: Variant);
begin
ANode.Values[ItemIndex] := AValue;
end;
procedure TcxTreeListColumn.SetVisible(AValue: Boolean);
begin
if AValue <> FVisible then
begin
FVisible := AValue;
TreeList.ClearCalculatedWidths;
Changed;
end;
end;
procedure TcxTreeListColumn.SetWidth(AValue: Integer);
begin
AValue := Max(MinWidth + IndentWidth, AValue);
if AValue < 0 then Exit;
if AValue <> FWidth then
begin
FWidth := AValue;
FCalculatedWidth := AValue;
if (Position.Band <> nil) and not IsLoading and not IsUpdating then
Position.Band.ColumnSizeChanged(Self);
Changed;
end;
end;
{ TcxFakeCellViewInfo }
constructor TcxFakeCellViewInfo.Create(AOwner: TObject);
begin
inherited Create(AOwner);
FNodeViewData := TcxTreeListNodeViewData.Create(AOwner as TcxTreeListViewInfo, nil, 0);
end;
destructor TcxFakeCellViewInfo.Destroy;
begin
FNodeViewData.Node := nil;
FNodeViewData.Free;
FColumn := nil;
inherited Destroy;
end;
function TcxFakeCellViewInfo.MeasureHeight(AColumn: TcxTreeListColumn;
ANode: TcxTreeListNode; AIsCategory: Boolean): Integer;
var
W: Integer;
begin
FColumn := AColumn;
W := Column.DisplayWidth - OptionsView.VertIncrement;
if AIsCategory then
W := TreeListViewInfo.ContentWidth;
if AColumn.IndentWidth > 0 then
W := W - TreeListViewInfo.GetNodeContentOffset(ANode);
Initialize(ANode, W, TreeListViewInfo.DefaultEditHeight, True);
Result := Max(TreeListViewInfo.DefaultEditHeight,
Column.GetEditHeight(Self) + OptionsView.HorzIncrement * 2);
end;
function TcxFakeCellViewInfo.MeasureWidth(
AColumn: TcxTreeListColumn; ANode: TcxTreeListNode): Integer;
var
AIndent: Integer;
begin
FColumn := AColumn;
Initialize(ANode, 0, TreeListViewInfo.DefaultEditHeight, False);
AIndent := 0;
if Column.IndentWidth > 0 then
AIndent := TreeListViewInfo.GetNodeContentOffset(ANode);
Result := Max(Column.MinWidth + Column.IndentWidth,
AIndent + Column.GetEditWidth(Self) + OptionsView.HorzIncrement * 2);
end;
function TcxFakeCellViewInfo.GetButtonTransparency: TcxEditButtonTransparency;
begin
Result := ebtNone;
end;
function TcxFakeCellViewInfo.GetControl: TcxEditingControl;
begin
Result := TreeListViewInfo.TreeList;
end;
function TcxFakeCellViewInfo.GetEditContainer: TcxCustomInplaceEditContainer;
begin
Result := FColumn;
end;
function TcxFakeCellViewInfo.GetFocused: Boolean;
begin
Result := False;
end;
function TcxFakeCellViewInfo.GetSelected: Boolean;
begin
Result := False;
end;
procedure TcxFakeCellViewInfo.Initialize(ANode: TcxTreeListNode;
AHeight, AWidth: Integer; ACalcHeight: Boolean);
begin
FCalcHeight := ACalcHeight;
FNodeViewData.Node := ANode;
CellContentRect := cxRect(0, 0, AHeight, AWidth);
Column.InitEditViewInfo(Self);
end;
function TcxFakeCellViewInfo.IsAutoHeight: Boolean;
begin
Result := FCalcHeight;
end;
function TcxFakeCellViewInfo.IsEndEllipsis: Boolean;
begin
Result := False;
end;
function TcxFakeCellViewInfo.GetTreeListViewInfo: TcxTreeListViewInfo;
begin
Result := FNodeViewData.ViewInfo;
end;
{ TcxTreeListCellPos }
constructor TcxTreeListCellPos.Create(
ANode: TcxTreeListNode; AItem: TObject);
begin
Item := AItem;
Node := ANode;
end;
{ TcxTreeListPainter }
constructor TcxTreeListPainter.Create(
AOwner: TcxEditingControl);
begin
inherited Create(AOwner);
Buffered := True;
end;
procedure TcxTreeListPainter.Paint;
var
ACanvas: TcxCanvas;
begin
if Buffered then
begin
if Changed then
begin
ACanvas := FCanvas;
try
BitmapCanvas.SetClipRegion(FCanvas.GetClipRegion, roSet);
FCanvas := BitmapCanvas;
DoPaint;
finally
FCanvas := ACanvas;
end;
end;
Canvas.Draw(0, 0, Bitmap);
end
else
DoPaint;
CheckDirty;
end;
procedure TcxTreeListPainter.CheckSize(const AWidth, AHeight: Integer);
begin
CheckBuffer((AWidth div cxTreeListResizeInc + 1) * cxTreeListResizeInc,
(AHeight div cxTreeListResizeInc + 1) * cxTreeListResizeInc);
end;
procedure TcxTreeListPainter.DoPaint;
var
I: Integer;
AClipRgn: TcxRegion;
begin
if TreeList.IsLocked then
inherited DoPaint
else
begin
CheckCustomDrawSupport;
Cells.Paint(Canvas, CustomDrawCell);
AClipRgn := Canvas.GetClipRegion();
try
Canvas.IntersectClipRect(ViewInfo.ContentBounds);
for I := 0 to ViewInfo.Count - 1 do
ViewInfo.NodeViewData[I].Paint(Canvas, CustomDrawCell);
finally
Canvas.SetClipRegion(AClipRgn, roSet);
end;
end
end;
procedure TcxTreeListPainter.CheckBuffer(AWidth, AHeight: Integer);
begin
if not Buffered or ((Bitmap.Width >= AWidth) and (Bitmap.Height >= AHeight)) then Exit;
Bitmap.FreeImage;
Bitmap.Height := AHeight;
Bitmap.Width := AWidth;
Changed := True;
end;
procedure TcxTreeListPainter.CheckCustomDrawSupport;
begin
with TreeList do
begin
FCustomDrawSupported := Assigned(OnCustomDrawBackgroundCell) or
((OptionsView.Headers or OptionsView.Bands) and Assigned(OnCustomDrawHeaderCell)) or
(OptionsView.Footer and Assigned(OnCustomDrawFooterCell)) or
(OptionsView.Indicator and Assigned(OnCustomDrawIndicatorCell)) or
Assigned(OnCustomDrawBandCell) or Assigned(OnCustomDrawIndentCell) or
Assigned(OnCustomDrawDataCell) or Assigned(OnCustomDrawPreviewCell);
end;
end;
procedure TcxTreeListPainter.CheckDirty;
begin
{ if TreeList.DragAndDropObject <> nil then
TcxTreeListSizingDragAndDropObject(TreeList.DragAndDropObject).Dirty := False;}
end;
procedure TcxTreeListPainter.CustomDrawCell(
ACanvas: TcxCanvas; ACell: TcxCustomViewInfoItem; var ADone: Boolean);
begin
ADone := False;
if not CustomDrawSupported then Exit;
with TreeList do
begin
case ACell.CustomDrawID of
cxtlBackgroundCell:
if Assigned(OnCustomDrawBackgroundCell) then
OnCustomDrawBackgroundCell(TreeList, ACanvas, TcxTreeListCustomCellViewInfo(ACell), ADone);
cxtlColumnHeaderCell:
if Assigned(OnCustomDrawHeaderCell) then
OnCustomDrawHeaderCell(TreeList, ACanvas, TcxTreeListHeaderCellViewInfo(ACell), ADone);
cxtlBandHeaderCell:
if Assigned(OnCustomDrawBandHeaderCell) then
OnCustomDrawBandHeaderCell(TreeList, ACanvas, TcxTreeListHeaderCellViewInfo(ACell), ADone);
cxtlBandPartCell:
if Assigned(OnCustomDrawBandCell) then
OnCustomDrawBandCell(TreeList, ACanvas, TcxTreeListBandCellViewInfo(ACell), ADone);
cxtlEditCell:
if Assigned(OnCustomDrawDataCell) then
OnCustomDrawDataCell(TreeList, ACanvas, TcxTreeListEditCellViewInfo(ACell), ADone);
cxtlFooterCell:
if Assigned(OnCustomDrawFooterCell) then
OnCustomDrawFooterCell(TreeList, ACanvas, TcxTreeListFooterCellViewInfo(ACell), ADone);
cxtlIndentCell:
if Assigned(OnCustomDrawIndentCell) then
OnCustomDrawIndentCell(TreeList, ACanvas, TcxTreeListIndentCellViewInfo(ACell), ADone);
cxtlIndicatorCell:
if Assigned(OnCustomDrawIndicatorCell) then
OnCustomDrawIndicatorCell(TreeList, ACanvas, TcxTreeListIndicatorCellViewInfo(ACell), ADone);
cxtlPreviewCell:
if Assigned(OnCustomDrawPreviewCell) then
OnCustomDrawPreviewCell(TreeList, ACanvas, TcxTreeListEditCellViewInfo(ACell), ADone);
end;
end;
end;
procedure TcxTreeListPainter.SetBuffered(Value: Boolean);
begin
inherited SetBuffered(True);
end;
function TcxTreeListPainter.GetCells: TcxCustomControlCells;
begin
Result := ViewInfo.Cells;
end;
function TcxTreeListPainter.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(Control);
end;
function TcxTreeListPainter.GetViewInfo: TcxTreeListViewInfo;
begin
Result := TcxTreeListViewInfo(inherited ViewInfo);
end;
{ TcxTreeListPreview }
constructor TcxTreeListPreview.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FAutoHeight := True;
FLeftIndent := 5;
FMaxLineCount := 3;
FRightIndent := 5;
end;
procedure TcxTreeListPreview.Assign(Source: TPersistent);
var
APreview: TcxTreeListPreview;
begin
if Source is TcxTreeListPreview then
begin
APreview := TcxTreeListPreview(Source);
AutoHeight := APreview.AutoHeight;
if APreview.Column <> nil then
Column := TreeList.Columns[APreview.Column.ItemIndex];
LeftIndent := APreview.LeftIndent;
MaxLineCount := APreview.MaxLineCount;
Place := APreview.Place;
RightIndent := APreview.RightIndent;
Visible := APreview.Visible;
end
else
inherited Assign(Source);
end;
procedure TcxTreeListPreview.Changed;
begin
TreeList.LayoutChanged;
end;
function TcxTreeListPreview.GetControl: TObject;
begin
Result := TreeList;
end;
function TcxTreeListPreview.GetActive: Boolean;
begin
Result := Visible and (FColumn <> nil) and (TreeList.VisibleColumnCount > 0) and
((MaxLineCount <> 0) or AutoHeight)
end;
function TcxTreeListPreview.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(GetOwner);
end;
procedure TcxTreeListPreview.SetAutoHeight(AValue: Boolean);
begin
if AValue <> FAutoHeight then
begin
FAutoHeight := AValue;
Changed;
end;
end;
procedure TcxTreeListPreview.SetColumn(AValue: TcxTreeListColumn);
begin
if AValue <> FColumn then
begin
FColumn := AValue;
Changed;
end;
end;
procedure TcxTreeListPreview.SetLeftIndent(AValue: Integer);
begin
AValue := Max(0, AValue);
if AValue <> FLeftIndent then
begin
FLeftIndent := AValue;
Changed;
end;
end;
procedure TcxTreeListPreview.SetMaxLineCount(AValue: Integer);
begin
AValue := Max(AValue, 0);
if AValue <> FMaxLineCount then
begin
FMaxLineCount := AValue;
Changed;
end;
end;
procedure TcxTreeListPreview.SetPlace(AValue: TcxTreeListPreviewPlace);
begin
if AValue <> FPlace then
begin
FPlace := AValue;
Changed;
end;
end;
procedure TcxTreeListPreview.SetRightIndent(AValue: Integer);
begin
AValue := Max(AValue, 0);
if AValue <> FRightIndent then
begin
FRightIndent := AValue;
Changed;
end;
end;
procedure TcxTreeListPreview.SetVisible(AValue: Boolean);
begin
if AValue <> FVisible then
begin
FVisible := AValue;
Changed;
end;
end;
{ TcxTreeListCellNavigator }
function TcxTreeListCellNavigator.GetCount(ARecordIndex: Integer): Integer;
begin
if IsGroupRow(ARecordIndex) then
Result := 1
else
Result := TreeList.VisibleColumnCount;
end;
procedure TcxTreeListCellNavigator.CalcNextRow(AForward: Boolean;
var ARowIndex, ACellIndex: Integer);
var
AColumn: TcxTreeListColumn;
ANewRow: Integer;
ACellFound: Boolean;
begin
ACellFound := False;
//Check Row index
ACellIndex := Min(TreeList.VisibleColumnCount - 1, Max(ACellIndex, 0));
if not IsGroupRow(ARowIndex) and (ACellIndex >= 0) then
begin
AColumn := TreeList.VisibleColumns[ACellIndex];
ACellFound := GoToNextCellInBand(AForward, AColumn, ACellIndex);
end
else
AColumn := nil;
if not ACellFound then
begin
ANewRow := ARowIndex + cxIntOffs[AForward];
if cxInRange(ANewRow, 0, TreeList.AbsoluteVisibleCount - 1) then
begin
ARowIndex := ANewRow;
GoToNextNodeCell(AForward, TreeList.AbsoluteVisibleItems[ARowIndex], AColumn, ACellIndex);
end
else
if AForward then AppendRecord(ARowIndex, ACellIndex);
end
end;
procedure TcxTreeListCellNavigator.AppendRecord(
var ARowIndex, ACellIndex: Integer);
begin
if TreeList.IsEditing then
DataController.Post;
if TreeList.IsInserting then
begin
TreeList.DataController.PostRecord;
if [dceChanging, dceModified] * DataController.EditState <> [] then
TreeList.Post
else
Exit;
end;
if TcxTreeListController(Controller).CanInsertNode and TreeList.InsertNode(nil, True) then
ARowIndex := TreeList.AbsoluteVisibleCount - 1;
end;
function TcxTreeListCellNavigator.GetCellContainer(
ARowIndex, ACellIndex: Integer): TcxCustomInplaceEditContainer;
begin
if not cxInRange(ACellIndex, 0, GetCount(ARowIndex) - 1) then
Result := nil
else
Result := TreeList.VisibleColumns[ACellIndex];
end;
function TcxTreeListCellNavigator.GetNode(
ARowIndex: Integer): TcxTreeListNode;
begin
Result := nil;
if (ARowIndex < 0) or (ARowIndex >= TreeList.AbsoluteVisibleCount) then Exit;
Result := TreeList.AbsoluteVisibleItems[ARowIndex];
end;
procedure TcxTreeListCellNavigator.Init(
var ARowIndex, ACellIndex, ARowCount: Integer);
var
ANode: TcxTreeListNode;
begin
ARowCount := TreeList.AbsoluteVisibleCount;
ANode := TcxTreeListController(Controller).FocusedNode;
if ANode <> nil then
ARowIndex := ANode.VisibleIndex
else
ARowIndex := 0;
if TreeList.FocusedColumn <> nil then
ACellIndex := TreeList.FocusedColumn.VisibleIndex
else
ACellIndex := 0;
end;
function TcxTreeListCellNavigator.IsGroupRow(ARowIndex: Integer): Boolean;
begin
Result := (GetNode(ARowIndex) <> nil) and GetNode(ARowIndex).IsGroupNode;
end;
procedure TcxTreeListCellNavigator.SaveCurrentNavigationColumn;
begin
FCurrentNavigationColumn := TcxTreeListColumn(Controller.FocusedItem);
end;
procedure TcxTreeListCellNavigator.SetFocusCell(
ARowIndex, ACellIndex: Integer; AShift: TShiftState);
var
ANode: TcxTreeListNode;
begin
if ARowIndex < 0 then Exit;
ANode := GetNode(ARowIndex);
if ANode.IsGroupNode then
Controller.SetFocusedNodeItem(ANode, TreeList.OptionsView.GetCategorizedColumn)
else
Controller.SetFocusedNodeItem(ANode, TreeList.VisibleColumns[ACellIndex]);
if FColumnChanged then
SaveCurrentNavigationColumn;
end;
procedure TcxTreeListCellNavigator.FocusNextCell(AForward, ANextRow: Boolean;
AShift: TShiftState = []);
begin
FColumnChanged := not ANextRow;
inherited FocusNextCell(AForward, ANextRow, AShift);
end;
procedure TcxTreeListCellNavigator.KeyDown(var Key: Word; Shift: TShiftState);
var
ANode: TcxTreeListNode;
begin
if TreeList.OptionsSelection.CellSelect and
([ssShift, ssCtrl] * Shift = []) and (TreeList.VisibleColumnCount > 0) then
inherited KeyDown(Key, Shift)
else
case Key of
VK_LEFT, VK_RIGHT:
begin
if TreeList.ViewInfo.HScrollSize <> 0 then
TreeList.ScrollContent(TcxDirection(Byte(Key = VK_RIGHT) + 1));
Key := 0;
end;
VK_UP, VK_DOWN:
begin
if TreeList.FocusedNode <> nil then
begin
ANode := TreeList.FocusedNode.GetNextVisibleEx(Key = VK_UP);
if ANode <> nil then
TreeList.SetFocusedNode(ANode, Shift);
end;
Key := 0;
end;
end;
end;
procedure TcxTreeListCellNavigator.Refresh;
begin
inherited Refresh;
end;
function TcxTreeListCellNavigator.GetCellIndex(
AColumn: TcxTreeListColumn; ARow: TcxTreeListBandRow): Integer;
var
AColumnIndex: Integer;
begin
AColumnIndex := AColumn.Position.VisibleColIndex;
if FCurrentNavigationColumn <> nil then
AColumnIndex := FCurrentNavigationColumn.Position.VisibleColIndex;
Result := ARow.VisibleItems[Min(AColumnIndex, ARow.VisibleItemCount - 1)].VisibleIndex;
end;
function TcxTreeListCellNavigator.GetController: TcxTreeListController;
begin
Result := TcxTreeListController(inherited Controller);
end;
function TcxTreeListCellNavigator.GetFocusedNode: TcxTreeListNode;
begin
Result := TreeList.FocusedNode;
end;
function TcxTreeListCellNavigator.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(TcxTreeListController(Controller).EditingControl);
end;
function TcxTreeListCellNavigator.GoToNextCellInBand(AForward: Boolean;
AColumn: TcxTreeListColumn; var ACellIndex: Integer): Boolean;
var
ARow: Integer;
ARows: TcxTreeListBandRows;
begin
Result := False;
ARows := AColumn.Position.Band.BandRows;
ARow := AColumn.Position.VisibleRowIndex + cxIntOffs[AForward];
if ARows.VisibleItemCount <= 1 then Exit;
while not Result and cxInRange(ARow, 0, ARows.VisibleItemCount - 1) do
begin
if ARows.VisibleItems[ARow].VisibleItemCount > 0 then
begin
ACellIndex := GetCellIndex(AColumn, ARows.VisibleItems[ARow]);
Result := True;
end
else
Inc(ARow, cxIntOffs[AForward]);
end;
end;
function TcxTreeListCellNavigator.GoToNextNodeCell(AForward: Boolean;
ANode: TcxTreeListNode; AColumn: TcxTreeListColumn; var ACellIndex: Integer): Boolean;
var
ARow: Integer;
ARows: TcxTreeListBandRows;
begin
if AColumn = nil then
AColumn := FCurrentNavigationColumn;
Result := (ANode <> nil) and (AColumn <> nil);
if Result then
begin
if ANode.IsGroupNode then
ACellIndex := 0
else
begin
ARows := AColumn.Position.Band.BandRows;
ARow := cxSetValue(AForward, 0, ARows.VisibleItemCount - 1);
ACellIndex := GetCellIndex(AColumn, ARows.VisibleItems[ARow]);
end;
end;
end;
{ TcxTreeListStyleSheet }
function TcxTreeListStyleSheet.GetStylesValue: TcxTreeListStyles;
begin
Result := TcxTreeListStyles(GetStyles)
end;
procedure TcxTreeListStyleSheet.SetStylesValue(Value: TcxTreeListStyles);
begin
SetStyles(Value);
end;
class function TcxTreeListStyleSheet.GetStylesClass: TcxCustomStylesClass;
begin
Result := TcxTreeListStyles;
end;
{ TcxTreeListStyles }
constructor TcxTreeListStyles.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
BitmapInViewParams := True;
end;
procedure TcxTreeListStyles.Assign(Source: TPersistent);
var
I: Integer;
begin
if Source is TcxTreeListStyles then
begin
for I := tlsv_BandBackground to tlsv_Preview do
SetValue(I, TcxTreeListStyles(Source).GetValue(I));
end;
inherited Assign(Source);
end;
function TcxTreeListStyles.GetBandBackgroundParams(
ABand: TcxTreeListBand): TcxViewParams;
begin
ABand.Styles.GetViewParams(tlbs_HeaderBackground, ABand, nil, Result);
end;
function TcxTreeListStyles.GetBandContentParams(ABand: TcxTreeListBand;
ANode: TcxTreeListNode): TcxViewParams;
begin
Result := ABand.Styles.GetContentParams(ANode, nil);
end;
function TcxTreeListStyles.GetBandFooterParams(
ABand: TcxTreeListBand; ANode: TcxTreeListNode): TcxViewParams;
begin
ABand.Styles.GetViewParams(tlbs_Footer, ANode, nil, Result);
end;
function TcxTreeListStyles.GetBandHeaderParams(
ABand: TcxTreeListBand): TcxViewParams;
begin
if ABand = nil then
DoGetBandHeaderParams(nil, Result)
else
ABand.Styles.GetViewParams(tlbs_Header, nil, nil, Result);
end;
function TcxTreeListStyles.GetColumnFooterParams(AColumn: TcxTreeListColumn;
ANode: TcxTreeListNode; ASummaryItem: TcxTreeListSummaryItem = nil): TcxViewParams;
begin
DoGetColumnFooterParams(AColumn, ANode, ASummaryItem, Result);
end;
function TcxTreeListStyles.GetColumnHeaderParams(
AColumn: TcxTreeListColumn): TcxViewParams;
begin
if AColumn = nil then
DoGetColumnHeaderParams(nil, Result)
else
AColumn.Styles.GetViewParams(tlcs_Header, AColumn, nil, Result);
end;
function TcxTreeListStyles.GetContentParams(ANode: TcxTreeListNode;
AColumn: TcxTreeListColumn): TcxViewParams;
var
AStyle: TcxStyle;
ACellPos: TcxTreeListCellPos;
begin
AStyle := nil;
if (ANode <> nil) and ANode.HotTrack and not TreeList.IsEditing and ((AColumn = nil) or not AColumn.IsPreview) then
begin
if Assigned(FOnGetHotTrackStyle) then
FOnGetHotTrackStyle(TreeList, AColumn, ANode, AStyle);
FillChar(Result, SizeOf(Result), 0);
ACellPos := TcxTreeListCellPos.Create(ANode, AColumn);
try
GetViewParams(tlsv_HotTrack, ACellPos, AStyle, Result);
finally
ACellPos.Free;
end;
end
else
Result := AColumn.Styles.GetContentParams(ANode);
end;
function TcxTreeListStyles.GetFooterParams: TcxViewParams;
begin
GetViewParams(tlsv_Footer, nil, nil, Result);
end;
function TcxTreeListStyles.GetIncSearchParams: TcxViewParams;
begin
GetViewParams(tlsv_IncSearch, nil, nil, Result);
end;
function TcxTreeListStyles.GetIndentParams(
ANode: TcxTreeListNode; AIndent: Integer): TcxViewParams;
var
AStyle: TcxStyle;
begin
AStyle := nil;
if Assigned(FOnGetNodeIndentStyle) then
FOnGetNodeIndentStyle(TreeList, ANode, AIndent, AStyle);
if not TreeList.OptionsView.UseNodeColorForIndent and (ANode <> nil) then
begin
AIndent := ANode.Level - AIndent + Byte(TreeList.OptionsView.ShowRoot);
while AIndent > 0 do
begin
ANode := ANode.Parent;
Dec(AIndent);
end;
end;
DoGetNodeContentParams(ANode, AStyle, Result);
end;
function TcxTreeListStyles.GetIndicatorParams: TcxViewParams;
begin
GetViewParams(tlsv_Indicator, nil, nil, Result);
end;
function TcxTreeListStyles.GetPreviewParams(ANode: TcxTreeListNode): TcxViewParams;
begin
Result := GetContentParams(ANode, TreeList.Preview.Column);
end;
procedure TcxTreeListStyles.DoGetBandBackgroundParams(
ABand: TcxTreeListBand; var AParams: TcxViewParams);
var
AStyle: TcxStyle;
begin
AStyle := nil;
if Assigned(FOnGetBandBackgroundStyle) then
FOnGetBandBackgroundStyle(TreeList, ABand, AStyle);
GetViewParams(tlsv_BandBackground, ABand, AStyle, AParams);
end;
procedure TcxTreeListStyles.DoGetBandContentParams(ABand: TcxTreeListBand;
ANode: TcxTreeListNode; var AParams: TcxViewParams);
var
AStyle: TcxStyle;
ACellPos: TcxTreeListCellPos;
begin
AStyle := nil;
if Assigned(FOnGetBandContentStyle) then
FOnGetBandContentStyle(TreeList, ABand, ANode, AStyle);
if GetValue(tlsv_BandContent) <> nil then
begin
ACellPos := TcxTreeListCellPos.Create(ANode, ABand);
try
GetViewParams(tlsv_BandContent, ACellPos, AStyle, AParams)
finally
ACellPos.Free;
end;
end
else
DoGetNodeContentParams(ANode, AStyle, AParams);
end;
procedure TcxTreeListStyles.DoGetBandFooterParams(ABand: TcxTreeListBand;
ANode: TcxTreeListNode; var AParams: TcxViewParams);
var
AStyle: TcxStyle;
begin
AStyle := nil;
if Assigned(FOnGetBandFooterStyle) then
FOnGetBandFooterStyle(TreeList, ABand, ANode, AStyle);
GetViewParams(tlsv_Footer, ABand, AStyle, AParams);
end;
procedure TcxTreeListStyles.DoGetBandHeaderParams(
ABand: TcxTreeListBand; var AParams: TcxViewParams);
var
AStyle: TcxStyle;
begin
AStyle := nil;
if Assigned(FOnGetBandHeaderStyle) then
FOnGetBandHeaderStyle(TreeList, ABand, AStyle);
GetViewParams(tlsv_BandHeader, ABand, AStyle, AParams);
end;
procedure TcxTreeListStyles.DoGetColumnFooterParams(AColumn: TcxTreeListColumn;
ANode: TcxTreeListNode; ASummaryItem: TcxTreeListSummaryItem; var AParams: TcxViewParams);
var
AStyle: TcxStyle;
begin
AStyle := nil;
if Assigned(FOnGetColumnFooterStyle) then
FOnGetColumnFooterStyle(TreeList, AColumn, ANode, ASummaryItem, AStyle);
if AColumn <> nil then
AColumn.Styles.GetViewParams(tlcs_Footer, ANode, AStyle, AParams)
else
GetViewParams(tlsv_ColumnFooter, AColumn, AStyle, AParams);
end;
procedure TcxTreeListStyles.DoGetColumnHeaderParams(
AColumn: TcxTreeListColumn; var AParams: TcxViewParams);
var
AStyle: TcxStyle;
begin
AStyle := nil;
if Assigned(FOnGetColumnHeaderStyle) then
FOnGetColumnHeaderStyle(TreeList, AColumn, AStyle);
GetViewParams(tlsv_ColumnHeader, AColumn, AStyle, AParams);
end;
procedure TcxTreeListStyles.DoGetContentParams(ANode: TcxTreeListNode;
AColumn: TcxTreeListColumn; var AParams: TcxViewParams);
var
AStyle: TcxStyle;
begin
AStyle := nil;
if AColumn.IsPreview then
begin
DoGetPreviewParams(ANode, AParams);
Exit;
end
else
begin
if Assigned(FOnGetContentStyle) and (ANode <> nil) then
FOnGetContentStyle(TreeList, AColumn, ANode, AStyle);
DoGetNodeContentParams(ANode, AStyle, AParams);
end;
end;
procedure TcxTreeListStyles.DoGetNodeContentParams(
ANode: TcxTreeListNode; AStyle: TcxStyle; var AParams: TcxViewParams);
begin
if (ANode <> nil) and (GetValue(OddEvenStyleIndexes[Odd(ANode.VisibleIndex)]) <> nil) then
GetViewParams(OddEvenStyleIndexes[Odd(ANode.VisibleIndex)], ANode, AStyle, AParams)
else
GetViewParams(ecs_Content, ANode, AStyle, AParams);
end;
procedure TcxTreeListStyles.DoGetPreviewParams(
ANode: TcxTreeListNode; var AParams: TcxViewParams);
var
AStyle: TcxStyle;
begin
AStyle := nil;
if Assigned(FOnGetPreviewStyle) then
FOnGetPreviewStyle(TreeList, ANode, AStyle);
GetViewParams(tlsv_Preview, ANode, AStyle, AParams);
end;
procedure TcxTreeListStyles.GetDefaultViewParams(
Index: Integer; AData: TObject; out AParams: TcxViewParams);
begin
inherited GetDefaultViewParams(Index, AData, AParams);
if (Index = tlsv_Content) and (AData is TcxTreeListCellPos) and
(TcxTreeListCellPos(AData).Node <> nil) then
Index := OddEvenStyleIndexes[Odd(TcxTreeListCellPos(AData).Node.VisibleIndex)];
with LookAndFeelPainter, AParams do
begin
Font := TcxCustomTreeList(Control).Font;
case Index of
tlsv_Preview:
begin
Color := DefaultContentColor;
TextColor := DefaultPreviewTextColor;
end;
tlsv_HotTrack:
begin
with TcxTreeListCellPos(AData) do
AParams := TcxTreeListColumn(Item).Styles.GetContentParams(Node);
TextColor := clHighlightText;
end;
tlsv_Content, tlsv_BandContent:
begin
Color := DefaultContentColor;
TextColor := DefaultContentTextColor;
end;
tlsv_ContentOdd:
begin
Color := DefaultContentOddColor;
TextColor := DefaultContentTextColor;
end;
tlsv_ContentEven:
begin
Color := DefaultContentEvenColor;
TextColor := DefaultContentTextColor;
end;
tlsv_BandHeader, tlsv_Indicator, tlsv_ColumnHeader:
begin
Color := DefaultHeaderColor;
TextColor := DefaultHeaderTextColor;
end;
tlsv_Footer, tlsv_ColumnFooter:
begin
Color := DefaultFooterColor;
TextColor := DefaultFooterTextColor;
end;
tlsv_BandBackground:
begin
Color := DefaultHeaderBackgroundColor;
TextColor := DefaultHeaderBackgroundTextColor;
end;
tlsv_IncSearch:
begin
Color := DefaultSelectionColor;
TextColor := DefaultSelectionTextColor;
end;
end;
end;
end;
function TcxTreeListStyles.SelectionFontAssigned: Boolean;
begin
if TreeList.Controller.Focused or Control.Focused then
Result := (Selection <> nil) and (cxStyles.svFont in Selection.AssignedValues)
else
Result := (Inactive <> nil) and (cxStyles.svFont in Inactive.AssignedValues);
end;
function TcxTreeListStyles.GetLoolAndFeel: TcxLookAndFeel;
begin
Result := TreeList.LookAndFeel;
end;
function TcxTreeListStyles.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(GetOwner);
end;
{ TcxTreeListOptionsCustomizing }
constructor TcxTreeListOptionsCustomizing.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FBandCustomizing := True;
FBandHorzSizing := True;
FBandMoving := True;
FBandVertSizing := True;
FColumnCustomizing := True;
FColumnHorzSizing := True;
FColumnMoving := True;
FColumnVertSizing := True;
FNestedBands := True;
end;
procedure TcxTreeListOptionsCustomizing.Assign(Source: TPersistent);
begin
if Source is TcxTreeListOptionsCustomizing then
with TcxTreeListOptionsCustomizing(Source) do
begin
Self.BandCustomizing := BandCustomizing;
Self.BandHiding := BandHiding;
Self.BandHorzSizing := BandHorzSizing;
Self.BandMoving := BandMoving;
Self.BandsQuickCustomization := BandsQuickCustomization;
Self.BandsQuickCustomizationMaxDropDownCount := BandsQuickCustomizationMaxDropDownCount;
Self.BandVertSizing := BandVertSizing;
Self.ColumnCustomizing := ColumnCustomizing;
Self.ColumnHiding := Self.ColumnHiding;
Self.ColumnHorzSizing := ColumnHorzSizing;
Self.ColumnMoving := ColumnMoving;
Self.ColumnsQuickCustomization := ColumnsQuickCustomization;
Self.ColumnsQuickCustomizationMaxDropDownCount := ColumnsQuickCustomizationMaxDropDownCount;
Self.ColumnVertSizing := ColumnVertSizing;
Self.DynamicSizing := DynamicSizing;
Self.NestedBands := NestedBands;
Self.NodeSizing := NodeSizing;
Self.RowSizing := RowSizing;
end
else
inherited Assign(Source);
end;
procedure TcxTreeListOptionsCustomizing.Changed;
begin
TreeList.LayoutChanged;
end;
function TcxTreeListOptionsCustomizing.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(GetOwner);
end;
procedure TcxTreeListOptionsCustomizing.SetBandCustomizing(AValue: Boolean);
begin
if AValue <> FBandCustomizing then
begin
FBandCustomizing := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetBandHiding(AValue: Boolean);
begin
if AValue <> FBandHiding then
begin
FBandHiding := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetBandHorzSizing(AValue: Boolean);
begin
if AValue <> FBandHorzSizing then
begin
FBandHorzSizing := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetBandMoving(AValue: Boolean);
begin
if AValue <> FBandMoving then
begin
FBandMoving := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetBandsQuickCustomization(
AValue: Boolean);
begin
if AValue <> FBandsQuickCustomization then
begin
FBandsQuickCustomization := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetBandVertSizing(AValue: Boolean);
begin
if AValue <> FBandVertSizing then
begin
FBandVertSizing := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetColumnCustomizing(AValue: Boolean);
begin
if AValue <> FColumnCustomizing then
begin
FColumnCustomizing := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetColumnHiding(AValue: Boolean);
begin
if AValue <> FColumnHiding then
begin
FColumnHiding := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetColumnHorzSizing(AValue: Boolean);
begin
if AValue <> FColumnHorzSizing then
begin
FColumnHorzSizing := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetColumnMoving(AValue: Boolean);
begin
if AValue <> FColumnMoving then
begin
FColumnMoving := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetColumnsQuickCustomization(
AValue: Boolean);
begin
if AValue <> FColumnsQuickCustomization then
begin
FColumnsQuickCustomization := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetColumnVertSizing(AValue: Boolean);
begin
if AValue <> FColumnVertSizing then
begin
FColumnVertSizing := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetDynamicSizing(AValue: Boolean);
begin
if AValue <> FDynamicSizing then
begin
FDynamicSizing := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetNestedBands(AValue: Boolean);
begin
if AValue <> FNestedBands then
begin
FNestedBands := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetNodeSizing(AValue: Boolean);
begin
if AValue <> FNodeSizing then
begin
FNodeSizing := AValue;
if AValue then
FRowSizing := False;
Changed;
end;
end;
procedure TcxTreeListOptionsCustomizing.SetRowSizing(AValue: Boolean);
begin
if AValue <> FRowSizing then
begin
FRowSizing := AValue;
if AValue then
FNodeSizing := False;
Changed;
end;
end;
{ TcxTreeListOptionsSelection }
constructor TcxTreeListOptionsSelection.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FCellSelect := True;
FHideFocusRect := True;
FInvertSelect := True;
end;
procedure TcxTreeListOptionsSelection.Assign(Source: TPersistent);
begin
if Source is TcxTreeListOptionsSelection then
with TcxTreeListOptionsSelection(Source) do
begin
Self.CellSelect := CellSelect;
Self.HideFocusRect := HideFocusRect;
Self.HideSelection := HideSelection;
Self.InvertSelect := InvertSelect;
Self.MultiSelect := MultiSelect;
end
else
inherited Assign(Source);
end;
function TcxTreeListOptionsSelection.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(GetOwner);
end;
{ TcxTreeListOptionsBehavior }
constructor TcxTreeListOptionsBehavior.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
ConfirmDelete := True;
DragCollapse := True;
DragExpand := True;
ShowHourGlass := True;
Sorting := True;
MultiSort := True;
WaitForExpandNodeTime := 500;
ExpandOnDblClick := True;
end;
procedure TcxTreeListOptionsBehavior.Assign(Source: TPersistent);
var
ASource: TcxTreeListOptionsBehavior;
begin
if Source is TcxTreeListOptionsBehavior then
begin
ASource := TcxTreeListOptionsBehavior(Source);
FAutoDragCopy := ASource.AutoDragCopy;
FConfirmDelete := ASource.ConfirmDelete;
FDragCollapse := ASource.DragCollapse;
FDragExpand := ASource.DragExpand;
FDragFocusing := ASource.DragFocusing;
FExpandOnDblClick := ASource.ExpandOnDblClick;
FExpandOnIncSearch := ASource.ExpandOnIncSearch;
FFooterHints := ASource.FooterHints;
FHeaderHints := ASource.HeaderHints;
FHotTrack := ASource.HotTrack;
FMultiSort := ASource.MultiSort;
FShowHourGlass := ASource.ShowHourGlass;
FSorting := ASource.Sorting;
ChangeDelay := ASource.ChangeDelay;
WaitForExpandNodeTime := ASource.WaitForExpandNodeTime;
IncSearchItem := TreeList.GetSameColumn(ASource.IncSearchItem);
end;
inherited Assign(Source);
end;
procedure TcxTreeListOptionsBehavior.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('AutomateLeftMostIndent', ReadBoolean, nil, True);
end;
function TcxTreeListOptionsBehavior.GetChangeDelay: Integer;
begin
Result := TreeList.FDelayTimer.Interval;
end;
function TcxTreeListOptionsBehavior.GetIncSearchItem: TcxTreeListColumn;
begin
Result := TcxTreeListColumn(inherited IncSearchItem);
end;
function TcxTreeListOptionsBehavior.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(GetOwner);
end;
procedure TcxTreeListOptionsBehavior.ReadBoolean(AReader: TReader);
begin
AReader.ReadBoolean;
end;
procedure TcxTreeListOptionsBehavior.SetChangeDelay(AValue: Integer);
begin
AValue := Max(0, AValue);
TreeList.ChangeDelayTimer.Enabled := AValue > 0;
TreeList.ChangeDelayTimer.Interval := AValue;
end;
procedure TcxTreeListOptionsBehavior.SetFooterHints(
AValue: Boolean);
begin
if FFooterHints <> AValue then
begin
FFooterHints := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsBehavior.SetHeaderHints(
AValue: Boolean);
begin
if FHeaderHints <> AValue then
begin
FHeaderHints := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsBehavior.SetIncSearchItem(AValue: TcxTreeListColumn);
begin
inherited IncSearchItem := AValue;
end;
{ TcxTreeListOptionsData }
constructor TcxTreeListOptionsData.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
Deleting := True;
end;
procedure TcxTreeListOptionsData.Assign(Source: TPersistent);
begin
if Source is TcxTreeListOptionsData then
begin
FDeleting := TcxTreeListOptionsData(Source).FDeleting;
FInserting := TcxTreeListOptionsData(Source).FInserting;
SummaryNullIgnore := TcxTreeListOptionsData(Source).SummaryNullIgnore;
end;
inherited Assign(Source);
end;
procedure TcxTreeListOptionsData.Changed;
begin
inherited Changed;
TcxCustomTreeList(GetOwner).RefreshNavigatorButtons;
end;
function TcxTreeListOptionsData.GetAnsiSort: Boolean;
begin
Result := dcoAnsiSort in
TcxCustomTreeList(GetOwner).DataController.Options;
end;
function TcxTreeListOptionsData.GetCaseInsensitive: Boolean;
begin
Result := dcoCaseInsensitive in
TcxCustomTreeList(GetOwner).DataController.Options;
end;
procedure TcxTreeListOptionsData.SetAnsiSort(Value: Boolean);
begin
with TcxCustomTreeList(GetOwner).DataController do
begin
if Value then
Options := Options + [dcoAnsiSort]
else
Options := Options - [dcoAnsiSort]
end;
end;
procedure TcxTreeListOptionsData.SetCaseInsensitive(Value: Boolean);
begin
with TcxCustomTreeList(GetOwner).DataController do
begin
if Value then
Options := Options + [dcoCaseInsensitive]
else
Options := Options - [dcoCaseInsensitive]
end;
end;
procedure TcxTreeListOptionsData.SetSummaryNullIgnore(Value: Boolean);
begin
if FSummaryNullIgnore <> Value then
begin
FSummaryNullIgnore := Value;
TcxCustomTreeList(GetOwner).Summary.Recalculate;
end;
end;
{ TcxTreeList }
function TcxTreeList.Add: TcxTreeListNode;
begin
Result := Add(nil);
end;
function TcxTreeList.Add(ASibling: TcxTreeListNode;
AData: Pointer = nil): TcxTreeListNode;
begin
if ASibling <> nil then
ASibling := ASibling.Parent;
Result := AddNode(nil, ASibling, AData, tlamAdd);
end;
function TcxTreeList.AddChild(AParent: TcxTreeListNode;
AData: Pointer = nil): TcxTreeListNode;
begin
Result := AddNode(nil, AParent, AData, tlamAddChild);
end;
function TcxTreeList.AddChildFirst(AParent: TcxTreeListNode;
AData: Pointer = nil): TcxTreeListNode;
begin
Result := AddNode(nil, AParent, AData, tlamAddChildFirst);
end;
function TcxTreeList.AddFirst: TcxTreeListNode;
begin
Result := AddFirst(nil);
end;
function TcxTreeList.AddFirst(ASibling: TcxTreeListNode; // need test???
AData: Pointer = nil): TcxTreeListNode;
begin
if ASibling <> nil then
ASibling := ASibling.Parent;
Result := AddNode(nil, ASibling, AData, tlamAddFirst);
end;
function TcxTreeList.AddNode(ANode, ARelative: TcxTreeListNode;
AData: Pointer; AttachMode: TcxTreeListNodeAttachMode): TcxTreeListNode;
begin
Result := inherited AddNode(ANode, ARelative, AData, AttachMode);
end;
function TcxTreeList.Insert(ASibling: TcxTreeListNode;
AData: Pointer = nil): TcxTreeListNode;
begin
Result := AddNode(nil, ASibling, AData, tlamInsert);
end;
function TcxTreeList.InsertEx(ANode, ASibling: TcxTreeListNode;
AData: Pointer = nil): TcxTreeListNode;
begin
Result := AddNode(ANode, ASibling, AData, tlamInsert);
end;
procedure TcxTreeList.LoadFromFile(const AFileName: string);
var
AFileStream: TFileStream;
begin
AFileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
try
LoadFromStream(AFileStream);
finally
FreeAndNil(AFileStream);
end;
end;
procedure TcxTreeList.LoadFromStream(AStream: TStream);
begin
SetGlassCursor;
try
ReadData(AStream);
finally
RestoreCursor;
end;
end;
procedure TcxTreeList.SaveToFile(const AFileName: string);
var
AFileStream: TFileStream;
begin
AFileStream := TFileStream.Create(AFileName, fmCreate);
try
SaveToStream(AFileStream);
finally
FreeAndNil(AFileStream);
end;
end;
procedure TcxTreeList.SaveToStream(AStream: TStream);
begin
SetGlassCursor;
try
WriteData(AStream);
finally
RestoreCursor;
end;
end;
procedure TcxTreeList.AssignData(ASource: TcxCustomTreeList);
var
AStream: TMemoryStream;
begin
inherited AssignData(ASource);
if ASource is TcxTreeList then
begin
AStream := TMemoryStream.Create;
try
TcxTreeList(ASource).SaveToStream(AStream);
AStream.Position := 0;
LoadFromStream(AStream);
finally
AStream.Free;
end;
end;
end;
procedure TcxTreeList.CorrectHandles;
var
I: Integer;
begin
if AbsoluteCount = 0 then Exit;
FAbsoluteItems.Sort(@cxCompareNodesByRecordIndex);
DataController.FAllocatedRecords := 0;
for I := 0 to FAbsoluteItems.Count - 1 do
DataController.InitializeNodeFromRecordIndex(TcxTreeListNode(FAbsoluteItems.List^[I]));
FAbsoluteItems.Sort(@cxCompareNodesByAbsoluteIndex);
end;
procedure TcxTreeList.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineBinaryProperty('Data', ReadData, WriteData, AbsoluteCount > 0);
end;
procedure TcxTreeList.Loaded;
begin
BeginUpdate;
try
inherited Loaded;
Include(FChanges, tcLoading);
try
if FDataStream <> nil then
try
ReadData(FDataStream);
finally
FDataStream.Free;
end;
Exclude(FChanges, tcLoading);
finally
FChanges := [tcStructure..tcSortOrder];
end;
finally
EndUpdate;
end;
end;
function TcxTreeList.SupportItemsEditor: Boolean;
begin
Result := True;
end;
procedure TcxTreeList.ReadData(AStream: TStream);
var
AHeader: TcxTreeListStreamHeader;
begin
if IsLoading then
begin
FDataStream := TMemoryStream.Create;
FDataStream.CopyFrom(AStream, AStream.Size - AStream.Position);
FDataStream.Position := 0;
Exit;
end;
AStream.ReadBuffer(AHeader, SizeOf(TcxTreeListStreamHeader));
if (AHeader.Size <> AStream.Size) then
cxTreeListError(cxGetResourceString(@scxInvalidStreamFormat));
BeginUpdate;
try
DoClear;
try
DataController.LoadFromStream(AStream);
ReadStructure(AStream, AHeader.Major);
except
DoClear;
raise;
end;
finally
EndUpdate;
end;
end;
procedure TcxTreeList.ReadStructure(AStream: TStream; AVersion: Integer);
var
AIndex: Integer;
ANewNode, ANode: TcxTreeListNode;
begin
ANode := Root;
AStream.ReadBuffer(Root.FCount, SizeOf(Integer));
if Root.FCount = 0 then Exit;
AIndex := 0;
repeat
ANewNode := InternalCreateNode(ANode, ANode.FLast, AIndex);
ANewNode.ReadData(AStream, AVersion);
if ANewNode.FCount > 0 then
begin
ANode := ANewNode;
AIndex := 0;
Continue;
end
else
while ANewNode.FParent <> nil do
begin
ANode := ANewNode.FParent;
AIndex := ANode.FLast.FIndex + 1;
if AIndex < ANode.Count then
Break
else
ANewNode := ANode;
end;
until (ANode = Root) and (AIndex = ANode.Count);
if AStream.Position < AStream.Size then
Root.ReadData(AStream, AVersion);
CorrectHandles;
end;
procedure TcxTreeList.WriteData(AStream: TStream);
var
I: Integer;
AHeader: TcxTreeListStreamHeader;
begin
AStream.Position := 0;
PInteger(@AHeader)^ := cxTreeListVersion;
AHeader.Size := AStream.Size;
AStream.WriteBuffer(AHeader, SizeOf(AHeader));
TcxDataStorageHelper.SetRecordsCapacity(DataController.DataStorage, AbsoluteCount);
for I := 0 to AbsoluteCount - 1 do
DataController.InitializeRecordIndexFromNode(TcxTreeListNode(FAbsoluteItems[I]));
try
DataController.SaveToStream(AStream);
WriteStructure(AStream);
AHeader.Size := AStream.Size;
AStream.Position := Integer(@AHeader.Size) - Integer(@AHeader);
AStream.Write(AHeader.Size, SizeOf(AHeader.Size));
AStream.Position := AHeader.Size;
finally
CorrectHandles;
end;
end;
procedure TcxTreeList.WriteStructure(AStream: TStream);
var
ANode: TcxTreeListNode;
begin
ANode := Root.GetFirstChild;
AStream.WriteBuffer(Root.FCount, SizeOf(Integer));
while ANode <> nil do
begin
ANode.WriteData(AStream);
if ANode.FCount > 0 then
ANode := ANode.GetFirstChild
else
begin
while (ANode <> nil) and (ANode.FNext = nil) do
ANode := ANode.FParent;
if ANode <> nil then
ANode := ANode.FNext;
end;
end;
Root.WriteData(AStream);
end;
function TcxTreeList.InternalCreateNode(AParent, APrev: TcxTreeListNode;
var AIndex: Integer): TcxTreeListNode;
begin
Result := CreateNode;
Result.FParent := AParent;
if APrev <> nil then
APrev.FNext := Result
else
AParent.FFirst := Result;
Result.FIndex := AIndex;
Result.FPrev := APrev;
AParent.FLast := Result;
Inc(AIndex);
end;
{ TcxTreeListBandOptions }
constructor TcxTreeListBandOptions.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
RestoreDefaults;
end;
procedure TcxTreeListBandOptions.Assign(Source: TPersistent);
begin
if Source is TcxTreeListBandOptions then
begin
FCustomizing := TcxTreeListBandOptions(Source).FCustomizing;
FHidden := TcxTreeListBandOptions(Source).FHidden;
FMoving := TcxTreeListBandOptions(Source).FMoving;
FOnlyOwnColumns := TcxTreeListBandOptions(Source).FOnlyOwnColumns;
FSizing := TcxTreeListBandOptions(Source).FSizing;
FVertSizing := TcxTreeListBandOptions(Source).VertSizing;
end
else
inherited Assign(Source);
end;
procedure TcxTreeListBandOptions.RestoreDefaults;
begin
FCustomizing := True;
FHidden := False;
FMoving := True;
FOnlyOwnColumns := False;
FSizing := True;
FVertSizing := True;
Changed;
end;
procedure TcxTreeListBandOptions.Changed;
begin
TcxTreeListBand(GetOwner).LayoutChanged;
end;
procedure TcxTreeListBandOptions.SetSizing(AValue: Boolean);
begin
if AValue <> FSizing then
begin
FSizing := AValue;
Changed;
end;
end;
procedure TcxTreeListBandOptions.SetVertSizing(AValue: Boolean);
begin
if AValue <> FVertSizing then
begin
FVertSizing := AValue;
Changed;
end;
end;
{ TcxTreeListBandStyles }
constructor TcxTreeListBandStyles.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
BitmapInViewParams := True;
end;
procedure TcxTreeListBandStyles.Assign(Source: TPersistent);
begin
if Source is TcxTreeListBandStyles then
begin
Content := TcxTreeListBandStyles(Source).Content;
Footer := TcxTreeListBandStyles(Source).Footer;
Header := TcxTreeListBandStyles(Source).Header;
HeaderBackground := TcxTreeListBandStyles(Source).HeaderBackground;
end;
inherited Assign(Source);
end;
function TcxTreeListBandStyles.GetContentParams(
ANode: TcxTreeListNode; AColumn: TcxTreeListColumn): TcxViewParams;
begin
if AColumn <> nil then
Result := AColumn.Styles.GetContentParams(ANode)
else
DoGetContentParams(ANode, AColumn, Result);
end;
function TcxTreeListBandStyles.GetBand: TcxTreeListBand;
begin
Result := TcxTreeListBand(GetOwner);
end;
function TcxTreeListBandStyles.GetTreeList: TcxCustomTreeList;
begin
Result := Band.TreeList;
end;
procedure TcxTreeListBandStyles.Changed(AIndex: Integer);
begin
inherited Changed(AIndex);
TreeList.UpdateViewStyles;
end;
procedure TcxTreeListBandStyles.DoGetContentParams(
ANode: TcxTreeListNode; AColumn: TcxTreeListColumn; var AParams: TcxViewParams);
var
ACellPos: TcxTreeListCellPos;
begin
ACellPos := TcxTreeListCellPos.Create(ANode, AColumn);
try
GetViewParams(tlbs_Content, ACellPos, nil, AParams);
finally
ACellPos.Free;
end;
end;
procedure TcxTreeListBandStyles.GetDefaultViewParams(Index: Integer; AData: TObject;
out AParams: TcxViewParams);
begin
inherited GetDefaultViewParams(Index, AData, AParams);
case Index of
tlbs_Content:
if AData is TcxTreeListCellPos then
begin
with TcxTreeListCellPos(AData) do
begin
if Item <> nil then
TreeList.Styles.DoGetContentParams(Node, TcxTreeListColumn(Item), AParams)
else
TreeList.Styles.DoGetBandContentParams(Band, Node, AParams);
end;
end
else
TreeList.Styles.DoGetBandContentParams(Band, nil, AParams);
tlbs_Footer:
if AData is TcxTreeListCellPos then
TreeList.Styles.GetViewParams(tlsv_ColumnFooter, TcxTreeListCellPos(AData).Item, nil, AParams)
else
TreeList.Styles.DoGetBandFooterParams(Band, TcxTreeListNode(AData), AParams);
tlbs_Header:
TreeList.Styles.DoGetBandHeaderParams(Band, AParams);
tlbs_HeaderBackground:
TreeList.Styles.DoGetBandBackgroundParams(Band, AParams);
end;
end;
{ TcxTreeListBandPosition }
constructor TcxTreeListBandPosition.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FBandIndex := -1;
FColIndex := -1;
end;
procedure TcxTreeListBandPosition.Assign(Source: TPersistent);
begin
if Source is TcxTreeListBandPosition then
begin
FBandIndex := TcxTreeListBandPosition(Source).BandIndex;
FColIndex := TcxTreeListBandPosition(Source).ColIndex
end
else
inherited Assign(Source);
end;
procedure TcxTreeListBandPosition.Changed;
begin
Band.LayoutChanged;
end;
function TcxTreeListBandPosition.CheckBandIndex(var AIndex: Integer): Boolean;
var
AColIndex, I: Integer;
ABand: TcxTreeListBand;
begin
Result := Band.Index <> AIndex;
if TreeList.IsDestroying or not Result then Exit;
Result := (AIndex = -1) or ((AIndex >= 0) and (AIndex < TreeList.Bands.Count));
if not Result or (AIndex = - 1) then Exit;
ABand := TreeList.Bands[AIndex];
if not ABand.HasAsParent(Band) then Exit;
AColIndex := ColIndex;
TreeList.BeginUpdate;
try
for I := Band.ChildBandCount - 1 downto 0 do
with Band.ChildBands[I].Position do
begin
BandIndex := Self.BandIndex;
ColIndex := AColIndex;
end;
AIndex := ABand.Index;
finally
TreeList.EndUpdate;
end;
end;
function TcxTreeListBandPosition.IsPositionChanged: Boolean;
begin
Result := (BandIndex <> FBandIndex) or (ColIndex <> FColIndex);
end;
procedure TcxTreeListBandPosition.Restore;
begin
BandIndex := FBandIndex;
if not Band.IsRoot then
ColIndex := FColIndex;
end;
procedure TcxTreeListBandPosition.Store;
begin
FBandIndex := BandIndex;
FColIndex := ColIndex;
end;
function TcxTreeListBandPosition.GetBandIndex: Integer;
begin
if ParentBand = nil then
Result := -1
else
Result := ParentBand.Index;
end;
function TcxTreeListBandPosition.GetColIndex: Integer;
begin
if ParentBand = nil then
Result := Band.RootIndex
else
Result := ParentBand.IndexOf(Band);
end;
function TcxTreeListBandPosition.GetBand: TcxTreeListBand;
begin
Result := TcxTreeListBand(GetOwner);
end;
function TcxTreeListBandPosition.GetTreeList: TcxCustomTreeList;
begin
Result := Band.TreeList;
end;
function TcxTreeListBandPosition.GetVisibleColIndex: Integer;
begin
if ParentBand = nil then
Result := Band.Bands.FVisibleRootItems.IndexOf(Self)
else
Result := ParentBand.FChildVisibleBands.IndexOf(Band);
end;
procedure TcxTreeListBandPosition.SetBandIndex(AValue: Integer);
begin
if IsLocked then
begin
FBandIndex := AValue;
Exit;
end;
if not CheckBandIndex(AValue) or (BandIndex = AValue) then Exit;
TreeList.BeginUpdate;
try
if ParentBand <> nil then
ParentBand.RemoveBand(Band);
if AValue >= 0 then
begin
FParentBand := TreeList.Bands[AValue];
FParentBand.AddBand(Band);
end
else
FParentBand := nil;
Band.LayoutChanged;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListBandPosition.SetColIndex(AValue: Integer);
begin
if IsLocked then
FColIndex := AValue
else
if ColIndex <> AValue then
begin
if ParentBand = nil then
Band.RootIndex := AValue
else
ParentBand.MoveBand(Band, AValue);
end;
end;
function TcxTreeListBandPosition.IsColIndexStored: Boolean;
begin
Result := not Band.IsRoot;
end;
function TcxTreeListBandPosition.IsLocked: Boolean;
begin
Result := TreeList.IsDestroying or Band.IsLoading or TreeList.IsUpdating;
end;
{ TcxTreeListBand }
constructor TcxTreeListBand.Create(Collection: TCollection);
begin
TcxTreeListBands(Collection).TreeList.BeginUpdate;
inherited Create(Collection);
FChildBands := TList.Create;
FChildVisibleBands := TList.Create;
FVisibleColumns := TList.Create;
FBandRows := TcxTreeListBandRows.Create(Self);
FColumns := TList.Create;
FPosition := TcxTreeListBandPosition.Create(Self);
FCaption := TcxTreeListCaption.Create(Self);
FCaption.OnChange := ChangeCaption;
FStyles := TcxTreeListBandStyles.Create(Self);
FOptions := GetOptionsClass.Create(Self);
Visible := True;
RestoreWidths;
TcxTreeListBands(Collection).TreeList.EndUpdate;
end;
destructor TcxTreeListBand.Destroy;
var
ATreeList: TcxCustomTreeList;
begin
ATreeList := TreeList;
ATreeList.BeginUpdate;
TreeList.Controller.UnselectObject(Self);
Position.BandIndex := -1;
RemoveChildBands;
RemoveColumns;
FreeAndNil(FChildVisibleBands);
FreeAndNil(FCaption);
FreeAndNil(FColumns);
FreeAndNil(FOptions);
FreeAndNil(FPosition);
FreeAndNil(FStyles);
FreeAndNil(FBandRows);
FreeAndNil(FVisibleColumns);
FreeAndNil(FChildBands);
inherited Destroy;
ATreeList.EndUpdate;
end;
procedure TcxTreeListBand.Assign(Source: TPersistent);
var
ABand: TcxTreeListBand;
begin
if Source is TcxTreeListBand then
begin
ABand := TcxTreeListBand(Source);
FCalculatedWidth := ABand.FCalculatedWidth;
FMinWidth := ABand.MinWidth;
FWidth := ABand.FWidth;
Position := ABand.Position;
Options := ABand.Options;
Styles := ABand.Styles;
Caption := ABand.Caption;
FixedKind := ABand.FixedKind;
Visible := ABand.Visible;
end
else
inherited Assign(Source);
end;
procedure TcxTreeListBand.ApplyBestFit;
var
AColIndex: Integer;
begin
TreeList.ValidateStates;
TreeList.BeginUpdate;
try
TreeList.HideEdit;
FWidth := 0;
if VisibleColumnCount > 0 then
begin
for AColIndex := 0 to VisibleColumnCount - 1 do
VisibleColumns[AColIndex].ApplyBestFit;
BandRows.Refresh;
FCalculatedWidth := BandRows.RowMaxWidth;
end
else
FCalculatedWidth := FMinWidth;
finally
TreeList.EndUpdate;
end;
end;
function TcxTreeListBand.IndexOf(AChildBand: TcxTreeListBand): Integer;
begin
Result := FChildBands.IndexOf(AChildBand);
end;
function TcxTreeListBand.HasAsParent(ABand: TcxTreeListBand): Boolean;
var
AParent: TcxTreeListBand;
begin
Result := False;
AParent := Self;
while not Result and (AParent <> nil) do
begin
AParent := AParent.ParentBand;
Result := AParent = ABand;
end;
end;
procedure TcxTreeListBand.MoveBand(ABand: TcxTreeListBand; AColIndex: Integer);
begin
ABand.Position.BandIndex := Index;
AColIndex := Min(Max(0, AColIndex), ChildBandCount - 1);
FChildBands.Move(ABand.Position.ColIndex, AColIndex);
LayoutChanged;
end;
procedure TcxTreeListBand.RestoreDefaults;
begin
TreeList.BeginUpdate;
try
Options.RestoreDefaults;
RestoreWidths;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListBand.RestoreWidths;
begin
FMinWidth := cxTreeListDefMinWidth;
SetWidth(0);
end;
function TcxTreeListBand.ActualMinWidth: Integer;
var
I, ASum: Integer;
begin
Result := Max(MinWidth, BandRows.RowMinWidth);
ASum := 0;
for I := 0 to ChildVisibleBands.Count - 1 do
Inc(ASum, TcxTreeListBand(ChildVisibleBands[I]).ActualMinWidth);
Result := Max(Result, ASum);
end;
procedure TcxTreeListBand.AdjustSubItems;
var
I: Integer;
begin
BandRows.Refresh;
if VisibleColumnCount > 0 then
begin
for I := 0 to BandRows.VisibleItemCount - 1 do
BandRows.VisibleItems[I].AdjustColumns;
end
else
Bands.Adjust(FChildVisibleBands, CalculatedWidth);
end;
procedure TcxTreeListBand.AssignChildBandWidths;
var
I: Integer;
begin
for I := 0 to ChildVisibleBands.Count - 1 do
TcxTreeListBand(ChildVisibleBands[I]).AssignWidth;
end;
procedure TcxTreeListBand.AssignColumnsWidth;
var
I: Integer;
begin
for I := 0 to BandRows.Count - 1 do
BandRows[I].AssignColumnsWidth;
end;
procedure TcxTreeListBand.AssignWidth;
begin
if ActuallyVisible then
FWidth := FCalculatedWidth;
end;
procedure TcxTreeListBand.InitAutoWidthItem(AItem: TcxAutoWidthItem);
begin
AItem.Width := Width;
if AItem.Width = 0 then
AItem.Width := CalculatedWidth;
AItem.Fixed := IsWidthFixed;
AItem.MinWidth := Max(FMinWidth, BandRows.RowMinWidth);
AItem.Width := Max(AItem.Width, AItem.MinWidth + IndentWidth);
if AItem.Fixed then
AItem.MinWidth := Max(AItem.MinWidth, AItem.Width);
AItem.AutoWidth := -1;
end;
function TcxTreeListBand.IsBandFixedDuringSizing: Boolean;
var
AForcingBand: TcxTreeListBand;
begin
AForcingBand := TreeList.Controller.ForcingWidthBand;
Result := (AForcingBand <> nil) and ((Self = AForcingBand) or
not AForcingBand.IsLastAsChild and (ParentBand = AForcingBand.ParentBand) and
(Position.VisibleColIndex < AForcingBand.Position.VisibleColIndex));
end;
function TcxTreeListBand.IsOnlyOwnColumns: Boolean;
begin
Result := Options.OnlyOwnColumns;
end;
procedure TcxTreeListBand.CalculateLineCount(ACurrentLine: Integer);
begin
FLineCount := ACurrentLine - Level;
if ParentBand <> nil then
ParentBand.CalculateLineCount(Level);
Refresh;
end;
function TcxTreeListBand.CanDropColumnAt(
const APoint: TPoint; out ARowIndex, AColIndex: Integer): Boolean;
begin
Result := True;
ARowIndex := 0;
AColIndex := 0;
end;
procedure TcxTreeListBand.CheckExpandable(var ABand: TcxTreeListBand);
begin
if Expandable = tlbeNotExpandable then Exit;
if (ABand = nil) or not (ABand.Expandable = tlbeExpandable) and (Expandable <> tlbeDefault) then
ABand := Self;
end;
procedure TcxTreeListBand.ForceWidth(AValue: Integer);
procedure AssignBandWidths;
var
ABand: TcxTreeListBand;
begin
if ParentBandWidthAssigned <> nil then
ParentBand.AssignChildBandWidths;
if not TreeList.OptionsView.ColumnAutoWidth then Exit;
ABand := ParentBand;
while ABand <> nil do
begin
ABand.AssignChildBandWidths;
ABand := ABand.ParentBand;
end;
Bands.AssignRootItemWidths;
end;
begin
TreeList.BeginUpdate;
try
AssignBandWidths;
TreeList.Controller.ForcingWidthBand := Self;
try
Width := AValue;
Bands.Adjust();
AssignBandWidths;
finally
TreeList.Controller.ForcingWidthBand := nil;
end;
finally
TreeList.EndUpdate;
end;
end;
function TcxTreeListBand.GetMaxDeltaWidth: Integer;
begin
Result := TreeList.GetMaxBandWidth(Self) - DisplayWidth;
end;
function TcxTreeListBand.CanMoving: Boolean;
begin
Result := Options.Moving and TreeList.OptionsCustomizing.BandMoving;
end;
procedure TcxTreeListBand.ChangeCaption(Sender: TObject);
begin
TreeList.LayoutChanged;
end;
function TcxTreeListBand.GetOptionsClass: TcxTreeListBandOptionsClass;
begin
Result := TcxTreeListBandOptions;
end;
procedure TcxTreeListBand.MoveColumnsTo(ABand: TcxTreeListBand);
var
I, J: Integer;
AColumn: TcxTreeListColumn;
begin
if ABand = Self then Exit;
for I := 0 to BandRows.Count - 1 do
for J := 0 to BandRows[0].Count - 1 do
begin
AColumn := BandRows[0][0];
ABand.AddColumn(AColumn);
AColumn.Position.RowIndex := I;
AColumn.Position.ColIndex := J;
end;
FColumns.Clear;
BandRows.FItems.Clear;
Refresh;
ABand.Refresh;
end;
procedure TcxTreeListBand.LayoutChanged;
begin
if Bands = nil then Exit;
if TreeList.IsLocked then
Bands.RefreshInformation
else
Bands.Update(nil);
end;
procedure TcxTreeListBand.MoveBandsToRoot;
var
AColIndex, I: Integer;
begin
if RootParentBand = nil then
AColIndex := FPosition.ColIndex + 1
else
AColIndex := RootParentBand.Position.ColIndex + 1;
TreeList.BeginUpdate;
try
for I := ChildBandCount - 1 downto 0 do
with ChildBands[I].Position do
begin
BandIndex := -1;
ColIndex := AColIndex;
end;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListBand.AddBand(ABand: TcxTreeListBand);
begin
FChildBands.Add(ABand);
ABand.FixedKind := FixedKind;
MoveColumnsTo(FirstChildBottomBand);
Refresh;
end;
procedure TcxTreeListBand.AddColumn(AColumn: TcxTreeListColumn);
begin
FColumns.Add(AColumn);
with AColumn.Position do
begin
FBand := Self;
Row := BandRows.CheckRowIndex(0)
end;
end;
procedure TcxTreeListBand.ColumnSizeChanged(AColumn: TcxTreeListColumn);
begin
FCalculatedWidth := 0;
AdjustSubItems;
TreeList.DoColumnSizeChanged(AColumn);
end;
procedure TcxTreeListBand.DeleteColumn(AColumn: TcxTreeListColumn);
var
AIndex: Integer;
begin
FColumns.Remove(AColumn);
with AColumn.Position do
begin
AIndex := RowIndex;
Row.FItems.Remove(AColumn);
FRow := nil;
end;
BandRows.CheckRowEmpty(AIndex);
end;
procedure TcxTreeListBand.Refresh;
var
I: Integer;
begin
FVisibleColumns.Clear;
FChildVisibleBands.Clear;
BandRows.Refresh;
if VisibleColumnCount > 0 then
TreeList.FVisibleColumns.Assign(FVisibleColumns, laOr);
for I := 0 to ChildBandCount - 1 do
if ChildBands[I].Visible then
FChildVisibleBands.Add(ChildBands[I]);
end;
procedure TcxTreeListBand.RemoveBand(ABand: TcxTreeListBand);
begin
FChildBands.Remove(ABand);
Refresh;
end;
procedure TcxTreeListBand.RemoveChildBands;
begin
if (Bands = nil) or TreeList.IsUpdating or TreeList.IsDestroying then Exit;
while ChildBandCount > 0 do
begin
ChildBands[0].Visible := False;
ChildBands[0].Position.BandIndex := -1;
end;
end;
procedure TcxTreeListBand.RemoveColumns;
var
I: Integer;
begin
if TreeList.IsDestroying or (FColumns = nil) then Exit;
TreeList.BeginUpdate;
try
for I := ColumnCount - 1 downto 0 do
Columns[I].Position.BandIndex := -1;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListBand.SetIndex(Value: Integer);
var
APrevIndex: Integer;
begin
APrevIndex := Index;
inherited SetIndex(Value);
if Index <> APrevIndex then
LayoutChanged;
end;
function TcxTreeListBand.CanSizing(ADirection: TcxDragSizingDirection): Boolean;
begin
if ADirection = dsdVert then
Result := Options.VertSizing and TreeList.OptionsCustomizing.BandVertSizing and IsBottom
else
Result := TreeList.OptionsCustomizing.BandHorzSizing and Options.Sizing;
end;
function TcxTreeListBand.GetSizingBoundsRect(
ADirection: TcxDragSizingDirection): TRect;
begin
if ADirection = dsdVert then
Result := cxRectSetTop(TreeList.ClientRect,
HeaderCell.DisplayRect.Top + TreeList.ViewInfo.BandHeaderLineHeight)
else
Result := cxRectSetLeft(TreeList.ClientRect, Max(HeaderCell.DisplayRect.Left +
ActualMinWidth + IndentWidth, HeaderCell.VisibleRect.Left));
end;
function TcxTreeListBand.GetSizingIncrement(
ADirection: TcxDragSizingDirection): Integer;
begin
Result := 1;
end;
function TcxTreeListBand.IsDynamicUpdate: Boolean;
begin
Result := TreeList.OptionsCustomizing.DynamicSizing and TreeList.HitTest.HitAtSizingHorz;
end;
procedure TcxTreeListBand.SetSizeDelta(
ADirection: TcxDragSizingDirection; ADelta: Integer);
begin
if ADelta = 0 then Exit;
if ADirection <> dsdHorz then
TreeList.OptionsView.BandLineHeight :=
(TreeList.ViewInfo.BandsHeight + ADelta) div Bands.LineCount
else
ForceWidth(DisplayWidth + ADelta);
TreeList.DoBandSizeChanged(Self);
end;
function TcxTreeListBand.GetObjectName: string;
begin
Result := 'Band' + IntToStr(Index);
end;
function TcxTreeListBand.GetProperties(
AProperties: TStrings): Boolean;
var
I: Integer;
begin
for I := Low(BandPropertiesName) to High(BandPropertiesName) do
AProperties.Add(BandPropertiesName[I]);
if Assigned(OnGetStoredProperties) then
OnGetStoredProperties(Self, AProperties);
Result := True;
end;
function TcxTreeListBand.GetPropertyIndex(const AName: string): Integer;
var
I: Integer;
begin
Result := -1;
for I := Low(BandPropertiesName) to High(BandPropertiesName) do
if BandPropertiesName[I] = AName then
begin
Result := I;
Break;
end;
end;
procedure TcxTreeListBand.GetPropertyValue(
const AName: string; var AValue: Variant);
begin
case GetPropertyIndex(AName) of
0:
AValue := Caption.Text;
1:
AValue := FMinWidth;
2:
AValue := FWidth;
3:
AValue := Visible;
4:
AValue := Index;
5:
AValue := Position.BandIndex;
6:
AValue := Position.ColIndex;
else
if Assigned(OnGetStoredPropertyValue) then
OnGetStoredPropertyValue(Self, AName, AValue);
end;
end;
procedure TcxTreeListBand.SetPropertyValue(
const AName: string; const AValue: Variant);
begin
case GetPropertyIndex(AName) of
0:
if Caption.Text = '' then
Caption.Text := AValue;
1:
FMinWidth := AValue;
2:
FWidth := AValue;
3:
Visible := AValue;
4:
Index := AValue;
5:
Position.BandIndex := AValue;
6:
Position.ColIndex := AValue;
else
if Assigned(OnSetStoredPropertyValue) then
OnSetStoredPropertyValue(Self, AName, AValue);
end;
end;
function TcxTreeListBand.GetParentBand: TcxTreeListBand;
begin
Result := FPosition.ParentBand;
end;
function TcxTreeListBand.GetParentBandWidthAssigned: TcxTreeListBand;
begin
Result := ParentBand;
while Result <> nil do
begin
if Result.Width <> 0 then Break;
Result := Result.ParentBand;
end;
end;
function TcxTreeListBand.GetRootIndex: Integer;
begin
if Bands = nil then
Result := -1
else
Result := Bands.FRootItems.IndexOf(Self);
end;
function TcxTreeListBand.GetRootParentBand: TcxTreeListBand;
begin
Result := ParentBand;
if Result = nil then Exit;
while Result.ParentBand <> nil do
Result := ParentBand.ParentBand;
end;
function TcxTreeListBand.GetTreeList: TcxCustomTreeList;
begin
Result := Bands.TreeList;
end;
function TcxTreeListBand.GetActuallyExpandable: Boolean;
begin
Result := FirstChildBottomBand = Bands.ExpandableBand;
end;
function TcxTreeListBand.GetActuallyVisible: Boolean;
begin
Result := FVisible and ((ParentBand = nil) or ParentBand.ActuallyVisible);
end;
function TcxTreeListBand.GetBands: TcxTreeListBands;
begin
Result := TcxTreeListBands(Collection);
end;
function TcxTreeListBand.GetCalculatedWidth: Integer;
var
AWidth, I: Integer;
begin
Refresh;
if FCalculatedWidth = 0 then
begin
FCalculatedWidth := FWidth;
if FCalculatedWidth = 0 then
begin
FCalculatedWidth := FWidth;
if FCalculatedWidth = 0 then
FCalculatedWidth := BandRows.RowMaxWidth;
if (ChildBandCount > 0) then
begin
AWidth := 0;
for I := 0 to ChildBandCount - 1 do
if ChildBands[I].Visible then
Inc(AWidth, ChildBands[I].CalculatedWidth);
FCalculatedWidth := Max(FCalculatedWidth, AWidth);
end;
if FCalculatedWidth = 0 then
FCalculatedWidth := Max(cxTreeListDefWidth, MinWidth);
end;
end;
Result := Max(FCalculatedWidth, BandRows.RowMinWidth);
end;
function TcxTreeListBand.GetColumn(AIndex: Integer): TcxTreeListColumn;
begin
Result := TcxTreeListColumn(FColumns[AIndex]);
end;
function TcxTreeListBand.GetColumnCount: Integer;
begin
Result := FColumns.Count;
end;
function TcxTreeListBand.GetChildBand(AIndex: Integer): TcxTreeListBand;
begin
Result := TcxTreeListBand(FChildBands[AIndex]);
end;
function TcxTreeListBand.GetChildBandCount: Integer;
begin
Result := FChildBands.Count;
end;
function TcxTreeListBand.GetDisplayWidth: Integer;
begin
Result := CalculatedWidth;
end;
function TcxTreeListBand.GetFirstChildBottomBand: TcxTreeListBand;
begin
Result := Self;
while Result.ChildBandCount > 0 do
Result := Result.ChildBands[0];
end;
function TcxTreeListBand.GetHasEmptyArea: Boolean;
begin
Result := FHasEmptyArea or
(BandRows.LineCount <> Bands.ColumnsLineCount);
end;
function TcxTreeListBand.GetIndentWidth: Integer;
begin
Result := 0;
if ActuallyExpandable then
Result := TreeList.IndentWidth;
end;
function TcxTreeListBand.GetIsBottom: Boolean;
begin
Result := ChildBandCount = 0;
end;
function TcxTreeListBand.GetIsFirstInGroup: Boolean;
var
ABand: TcxTreeListBand;
begin
Result := False;
ABand := Bands.VisibleItems[Bands.GetFirstVisibleIndex(FixedKind)];
while not Result and (ABand <> nil) do
begin
Result := ABand = Self;
if ABand.ChildVisibleBands.Count > 0 then
ABand := TcxTreeListBand(ABand.ChildVisibleBands[0])
else
ABand := nil;
end;
end;
function TcxTreeListBand.GetIsLastAsChild: Boolean;
function GetVisibleBandCount: Integer;
begin
if ParentBand = nil then
Result := Bands.RootItemCount
else
Result := ParentBand.FChildVisibleBands.Count;
end;
begin
Result := FPosition.VisibleColIndex = GetVisibleBandCount - 1;
end;
function TcxTreeListBand.GetIsLastInGroup: Boolean;
var
ABand: TcxTreeListBand;
begin
Result := False;
ABand := Bands.VisibleItems[Bands.GetLastVisibleIndex(FixedKind)];
while not Result and (ABand <> nil) do
begin
Result := ABand = Self;
if ABand.ChildVisibleBands.Count > 0 then
ABand := TcxTreeListBand(ABand.ChildVisibleBands[ABand.ChildVisibleBands.Count - 1])
else
ABand := nil;
end;
end;
function TcxTreeListBand.GetIsLeftMost: Boolean;
begin
Result := IsFirstInGroup and
(Bands.GetFirstVisibleIndex(FixedKind) = 0);
end;
function TcxTreeListBand.GetIsLoading: Boolean;
begin
Result := TreeList.IsLoading and not TreeList.IgnoreLoadingStatus;
end;
function TcxTreeListBand.GetIsRightMost: Boolean;
begin
Result := IsLastInGroup and
(Bands.GetLastVisibleIndex(FixedKind) = Bands.VisibleItemCount - 1);
end;
function TcxTreeListBand.GetIsRoot: Boolean;
begin
Result := Position.ParentBand = nil;
end;
function TcxTreeListBand.GetIsWidthFixed: Boolean;
var
AForcingColumn: TcxTreeListColumn;
begin
AForcingColumn := TreeList.Controller.ForcingWidthColumn;
Result := not Options.Sizing or IsBandFixedDuringSizing or
((AForcingColumn <> nil) and (AForcingColumn.Position.Band.ParentBandWidthAssigned = Self));
end;
function TcxTreeListBand.GetLevel: Integer;
var
AParent: TcxTreeListBand;
begin
Result := 0;
AParent := ParentBand;
while AParent <> nil do
begin
Inc(Result);
AParent := AParent.ParentBand;
end;
end;
function TcxTreeListBand.GetVisibleColumn(AIndex: Integer): TcxTreeListColumn;
begin
Result := TcxTreeListColumn(FVisibleColumns[AIndex]);
end;
function TcxTreeListBand.GetVisibleColumnCount: Integer;
begin
Result := FVisibleColumns.Count;
end;
function TcxTreeListBand.GetVisibleRootIndex: Integer;
begin
Result := Bands.FVisibleRootItems.IndexOf(Self);
end;
function TcxTreeListBand.GetVisibleIndex: Integer;
begin
Result := Bands.VisibleIndexOf(Self);
end;
procedure TcxTreeListBand.SetCalculatedWidth(AValue: Integer);
begin
FCalculatedWidth := AValue;
AdjustSubItems;
end;
procedure TcxTreeListBand.SetCaption(AValue: TcxTreeListCaption);
begin
FCaption.Assign(AValue);
end;
procedure TcxTreeListBand.SetColumn(AIndex: Integer; AValue: TcxTreeListColumn);
begin
Columns[AIndex].Assign(AValue);
end;
procedure TcxTreeListBand.SetDisplayWidth(AValue: Integer);
begin
ForceWidth(AValue);
end;
procedure TcxTreeListBand.SetExpandable(AValue: TcxTreeListBandExpandable);
begin
if AValue <> FExpandable then
begin
FExpandable := AValue;
LayoutChanged;
end;
end;
procedure TcxTreeListBand.SetFixedKind(AValue: TcxTreeListBandFixedKind);
var
I: Integer;
begin
if AValue <> FixedKind then
begin
FFixedKind := AValue;
TreeList.BeginUpdate;
try
for I := 0 to ChildBandCount - 1 do
ChildBands[I].FixedKind := AValue;
if not IsRoot and (FFixedKind <> ParentBand.FixedKind) then
Position.BandIndex := -1;
finally
TreeList.EndUpdate;
end;
end;
end;
procedure TcxTreeListBand.SetMinWidth(AValue: Integer);
begin
if AValue <> FMinWidth then
begin
FMinWidth := AValue;
LayoutChanged;
end;
end;
procedure TcxTreeListBand.SetOptions(AValue: TcxTreeListBandOptions);
begin
FOptions.Assign(AValue);
end;
procedure TcxTreeListBand.SetPosition(AValue: TcxTreeListBandPosition);
begin
FPosition.Assign(AValue);
end;
procedure TcxTreeListBand.SetRootIndex(AValue: Integer);
begin
if not IsRoot or TreeList.IsDestroying then Exit;
AValue := Max(0, Min(AValue, Bands.RootItemCount - 1));
if RootIndex <> AValue then
Index := Bands.RootItems[AValue].Index;
end;
procedure TcxTreeListBand.SetStyles(AValue: TcxTreeListBandStyles);
begin
FStyles.Assign(AValue);
end;
procedure TcxTreeListBand.SetVisibleColumn(
AIndex: Integer; AValue: TcxTreeListColumn);
begin
VisibleColumns[AIndex].Assign(AValue);
end;
procedure TcxTreeListBand.SetVisible(AValue: Boolean);
begin
if AValue <> FVisible then
begin
FVisible := AValue;
TreeList.ClearCalculatedWidths;
LayoutChanged;
end;
end;
procedure TcxTreeListBand.SetWidth(AValue: Integer);
begin
if AValue < 0 then Exit;
if AValue > 0 then
AValue := Max(AValue, ActualMinWidth);
if AValue <> FWidth then
begin
FWidth := AValue;
FCalculatedWidth := AValue;
AdjustSubItems;
if ActuallyVisible then
TreeList.LayoutChanged;
end;
end;
{ TcxTreeListBands }
constructor TcxTreeListBands.Create(AOwner: TcxCustomTreeList);
begin
inherited Create(AOwner.GetBandItemClass);
FTreeList := AOwner;
FRootItems := TList.Create;
FVisibleItems := TList.Create;
FVisibleRootItems := TList.Create;
FBottomItems := TList.Create;
end;
destructor TcxTreeListBands.Destroy;
begin
FBottomItems.Free;
FVisibleRootItems.Free;
FVisibleItems.Free;
FRootItems.Free;
inherited Destroy;
end;
procedure TcxTreeListBands.Assign(ASource: TPersistent);
var
I: Integer;
begin
if ASource is TcxTreeListBand then
begin
TreeList.BeginUpdate;
try
TreeList.SaveItemsPosition;
for I := 0 to TcxTreeListBands(ASource).Count - 1 do
Add.Assign(TcxTreeListBands(ASource)[I]);
TreeList.AssignItemsPosition;
finally
TreeList.EndUpdate;
end;
end
else
inherited Assign(ASource);
end;
function TcxTreeListBands.Add: TcxTreeListBand;
begin
BeginUpdate;
try
Result := TcxTreeListBand(inherited Add);
finally
EndUpdate;
end;
end;
procedure TcxTreeListBands.RestoreDefaults;
var
I: Integer;
begin
TreeList.BeginUpdate;
try
for I := 0 to Count - 1 do
Items[I].RestoreDefaults;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListBands.RestoreWidths;
var
I: Integer;
begin
TreeList.BeginUpdate;
try
for I := 0 to Count - 1 do
Items[I].RestoreWidths;
finally
TreeList.EndUpdate;
end;
end;
function TcxTreeListBands.VisibleIndexOf(ABand: TcxTreeListBand): Integer;
begin
Result := FVisibleItems.IndexOf(ABand);
end;
function TcxTreeListBands.PopulateVisibleChildren(
ABand: TcxTreeListBand): Integer;
var
I: Integer;
begin
Result := 0;
if not ABand.Visible then Exit;
Inc(Result);
FVisibleItems.Add(ABand);
if ABand.FixedKind = tlbfLeft then
Inc(FVisibleLeftFixedCount)
else
if ABand.FixedKind = tlbfRight then
Inc(FVisibleRightFixedCount);
for I := 0 to ABand.ChildBandCount - 1 do
Inc(Result, PopulateVisibleChildren(ABand.ChildBands[I]));
if Result = 1 then
begin
FBottomItems.Add(ABand);
FLineCount := Max(FLineCount, ABand.Level + 1);
end;
end;
procedure TcxTreeListBands.RefreshInformation;
var
I: Integer;
ABand: TcxTreeListBand;
begin
FRootItems.Clear;
FBottomItems.Clear;
FVisibleItems.Clear;
FVisibleRootItems.Clear;
TreeList.FVisibleColumns.Clear;
FLineCount := 0;
FColumnsLineCount := 0;
FVisibleLeftFixedCount := 0;
FVisibleRightFixedCount := 0;
FVisibleRootLeftFixedCount := 0;
FVisibleRootRightFixedCount := 0;
FExpandableBand := nil;
if Count = 0 then Exit;
for I := 0 to Count - 1 do
begin
ABand := Items[I];
ABand.FLineCount := 0;
if ABand.IsRoot then
begin
FRootItems.Add(ABand);
if ABand.ActuallyVisible then
begin
if ABand.FixedKind = tlbfLeft then
Inc(FVisibleRootLeftFixedCount)
else
if ABand.FixedKind = tlbfRight then
Inc(FVisibleRootRightFixedCount);
FVisibleRootItems.Add(ABand);
end;
end;
end;
FVisibleRootItems.Sort(@cxCompareBands);
for I := 0 to VisibleRootItemCount - 1 do
PopulateVisibleChildren(VisibleRootItems[I]);
FVisibleItems.Sort(@cxCompareBands);
FColumnsLineCount := Byte(BottomItemCount > 0);
for I := 0 to BottomItemCount - 1 do
with BottomItems[I] do
begin
CalculateLineCount(Self.FLineCount);
CheckExpandable(FExpandableBand);
FColumnsLineCount := Max(FColumnsLineCount, BandRows.LineCount);
end;
if CanExpandableLeftMostOnly and (FExpandableBand <> nil) then
FExpandableBand := BottomItems[0];
end;
procedure TcxTreeListBands.Adjust(
ABands: TList = nil; AWidth: Integer = 0);
var
I: Integer;
AAutoWidth: TcxAutoWidthObject;
begin
if ABands = nil then
begin
ABands := FVisibleRootItems;
AWidth := TreeList.AvailableContentWidth;
ClearCalculatedWidths;
RefreshInformation;
end;
if ABands.Count = 0 then Exit;
for I := 0 to ABands.Count - 1 do
TcxTreeListBand(ABands[I]).AdjustSubItems;
if (ABands <> FVisibleRootItems) or TreeList.OptionsView.ColumnAutoWidth then
begin
AAutoWidth := TcxAutoWidthObject.Create(ABands.Count);
try
AAutoWidth.AvailableWidth := AWidth;
for I := 0 to ABands.Count - 1 do
TcxTreeListBand(ABands[I]).InitAutoWidthItem(AAutoWidth.AddItem);
AAutoWidth.Calculate;
for I := 0 to ABands.Count - 1 do
TcxTreeListBand(ABands[I]).CalculatedWidth := AAutoWidth.Items[I].AutoWidth;
finally
AAutoWidth.Free;
end;
end;
end;
procedure TcxTreeListBands.AssignColumnsWidth;
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].AssignColumnsWidth;
TreeList.ClearCalculatedWidths;
end;
procedure TcxTreeListBands.AssignRootItemWidths;
var
I: Integer;
begin
for I := 0 to RootItemCount - 1 do
RootItems[I].AssignWidth;
end;
function TcxTreeListBands.CanExpandableLeftMostOnly: Boolean;
begin
Result := TreeList.OptionsView.IsCategorizedPaint or
TreeList.Preview.Active;
end;
procedure TcxTreeListBands.ClearCalculatedWidths;
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].FCalculatedWidth := 0;
end;
function TcxTreeListBands.GetFirstVisibleIndex(
AFixedKind: TcxTreeListBandFixedKind): Integer;
begin
case AFixedKind of
tlbfNone:
Result := VisibleLeftFixedCount;
tlbfRight:
Result := VisibleItemCount - VisibleRightFixedCount;
else
Result := 0;
end
end;
function TcxTreeListBands.GetFirstVisibleRootIndex(
AFixedKind: TcxTreeListBandFixedKind): Integer;
begin
case AFixedKind of
tlbfNone:
Result := VisibleRootLeftFixedCount;
tlbfRight:
Result := VisibleRootItemCount - VisibleRootRightFixedCount;
else
Result := 0;
end;
end;
function TcxTreeListBands.GetLastVisibleIndex(
AFixedKind: TcxTreeListBandFixedKind): Integer;
begin
case AFixedKind of
tlbfLeft:
Result := GetFirstVisibleIndex(tlbfNone) - 1;
tlbfNone:
Result := GetFirstVisibleIndex(tlbfRight) - 1;
else
Result := VisibleItemCount - 1;
end;
end;
function TcxTreeListBands.GetLastVisibleRootIndex(
AFixedKind: TcxTreeListBandFixedKind): Integer;
begin
case AFixedKind of
tlbfLeft:
Result := GetFirstVisibleRootIndex(tlbfNone) - 1;
tlbfNone:
Result := GetFirstVisibleRootIndex(tlbfRight) - 1;
else
Result := VisibleRootItemCount - 1;
end;
end;
function TcxTreeListBands.GetVisibleCountByKind(
AFixedKind: TcxTreeListBandFixedKind): Integer;
begin
Result := FVisibleLeftFixedCount;
case AFixedKind of
tlbfNone:
Result := VisibleItemCount - FVisibleRightFixedCount - Result;
tlbfRight:
Result := FVisibleRightFixedCount;
end;
end;
function TcxTreeListBands.GetOwner: TPersistent;
begin
Result := FTreeList;
end;
procedure TcxTreeListBands.Update(Item: TCollectionItem);
begin
inherited Update(Item);
if not TreeList.IsLocked then
TreeList.LayoutChanged;
end;
procedure TcxTreeListBands.Notify(
Item: TCollectionItem; Action: TCollectionNotification);
begin
if (Action = cnExtracting) and (TreeList <> nil) then
TcxTreeListBand(Item).RemoveColumns;
inherited Notify(Item, Action);
end;
// IInterface
function TcxTreeListBands.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := cxE_NOINTERFACE;
end;
function TcxTreeListBands._AddRef: Integer;
begin
Result := -1;
end;
function TcxTreeListBands._Release: Integer;
begin
Result := -1;
end;
// IcxStoredObject }
function TcxTreeListBands.GetObjectName: string;
begin
Result := 'Bands';
end;
function TcxTreeListBands.GetProperties(AProperties: TStrings): Boolean;
begin
Result := True;
end;
procedure TcxTreeListBands.GetPropertyValue(
const AName: string; var AValue: Variant);
begin
end;
procedure TcxTreeListBands.SetPropertyValue(
const AName: string; const AValue: Variant);
begin
end;
// IcxStoredParent
function TcxTreeListBands.CreateChild(
const AObjectName, AClassName: string): TObject;
begin
if AClassName = 'TcxTreeListBand' then
Result := Add
else
Result := nil;
end;
procedure TcxTreeListBands.DeleteChild(const AObjectName: string; AObject: TObject);
begin
AObject.Free;
end;
procedure TcxTreeListBands.GetChildren(AChildren: TStringList);
var
I: Integer;
begin
for I := 0 to Count - 1 do
AChildren.AddObject('', Items[I]);
end;
function TcxTreeListBands.GetBottomItem(AIndex: Integer): TcxTreeListBand;
begin
Result := TcxTreeListBand(FBottomItems[AIndex]);
end;
function TcxTreeListBands.GetBottomItemCount: Integer;
begin
Result := FBottomItems.Count;
end;
function TcxTreeListBands.GetFirstVisibleBand: TcxTreeListBand;
begin
if VisibleItemCount > 0 then
Result := VisibleItems[0]
else
Result := nil;
end;
function TcxTreeListBands.GetItem(AIndex: Integer): TcxTreeListBand;
begin
Result := TcxTreeListBand(inherited GetItem(AIndex));
end;
function TcxTreeListBands.GetLastVisibleBand: TcxTreeListBand;
begin
if VisibleItemCount > 0 then
Result := VisibleItems[VisibleItemCount - 1]
else
Result := nil;
end;
function TcxTreeListBands.GetRootItemCount: Integer;
begin
Result := FRootItems.Count;
end;
function TcxTreeListBands.GetRootItem(AIndex: Integer): TcxTreeListBand;
begin
Result := TcxTreeListBand(FRootItems[AIndex]);
end;
function TcxTreeListBands.GetVisibleItem(AIndex: Integer): TcxTreeListBand;
begin
Result := TcxTreeListBand(FVisibleItems[AIndex]);
end;
function TcxTreeListBands.GetVisibleItemCount: Integer;
begin
Result := FVisibleItems.Count;
end;
function TcxTreeListBands.GetVisibleRootItem(AIndex: Integer): TcxTreeListBand;
begin
Result := TcxTreeListBand(FVisibleRootItems[AIndex])
end;
function TcxTreeListBands.GetVisibleRootItemCount: Integer;
begin
Result := FVisibleRootItems.Count;
end;
procedure TcxTreeListBands.SetItem(AIndex: Integer; AValue: TcxTreeListBand);
begin
Items[AIndex].Assign(AValue);
end;
{ TcxTreeListBandRow }
constructor TcxTreeListBandRow.Create(AOwner: TcxTreeListBandRows);
begin
FBandRows := AOwner;
FItems := TList.Create;
FVisibleItems := TList.Create;
end;
destructor TcxTreeListBandRow.Destroy;
begin
FreeAndNil(FVisibleItems);
FreeAndNil(FItems);
inherited Destroy;
end;
function TcxTreeListBandRow.IndexOf(AColumn: TcxTreeListColumn): Integer;
begin
Result := FItems.IndexOf(AColumn);
end;
procedure TcxTreeListBandRow.AdjustColumns;
var
I: Integer;
AAutoWidth: TcxAutoWidthObject;
begin
if Count = 0 then Exit;
AAutoWidth := TcxAutoWidthObject.Create(VisibleItemCount);
try
AAutoWidth.AvailableWidth := Band.CalculatedWidth;
for I := 0 to VisibleItemCount - 1 do
VisibleItems[I].InitAutoWidthItem(AAutoWidth.AddItem);
AAutoWidth.Calculate;
for I := 0 to VisibleItemCount - 1 do
VisibleItems[I].FCalculatedWidth := AAutoWidth.Items[I].AutoWidth;
finally
AAutoWidth.Free;
end;
end;
procedure TcxTreeListBandRow.AssignColumnsWidth;
var
I: Integer;
begin
for I := 0 to Count - 1 do
if Items[I].DisplayWidth <> 0 then
Items[I].FWidth := Items[I].DisplayWidth;
end;
procedure TcxTreeListBandRow.CheckEmpty;
begin
BandRows.CheckRowEmpty(Index);
end;
procedure TcxTreeListBandRow.Refresh;
var
I: Integer;
AColumn: TcxTreeListColumn;
begin
FVisibleItems.Clear;
FLineOffset := 0;
FLineCount := 0;
FMinWidth := 0;
FWidth := 0;
for I := 0 to Count - 1 do
begin
AColumn := Items[I];
if AColumn.Visible and not AColumn.IsPreview then
begin
AColumn.Position.FVisibleColIndex := FVisibleItems.Add(AColumn);
FLineCount := Max(FLineCount, AColumn.Position.LineCount);
Band.FHasEmptyArea := Band.FHasEmptyArea or
((FLineCount <> 0) and (FLineCount <> AColumn.Position.LineCount));
Inc(FWidth, AColumn.Width);
Inc(FMinWidth, AColumn.MinWidth);
end
else
AColumn.Position.FVisibleColIndex := -1;
end;
end;
function TcxTreeListBandRow.GetBand: TcxTreeListBand;
begin
Result := FBandRows.FBand;
end;
function TcxTreeListBandRow.GetCount: Integer;
begin
Result := FItems.Count
end;
function TcxTreeListBandRow.GetIsFirst: Boolean;
begin
Result := BandRows.First = Self;
end;
function TcxTreeListBandRow.GetFirst: TcxTreeListColumn;
begin
if VisibleItemCount > 0 then
Result := VisibleItems[0]
else
Result := nil;
end;
function TcxTreeListBandRow.GetIndex: Integer;
begin
Result := BandRows.FItems.IndexOf(Self);
end;
function TcxTreeListBandRow.GetIsLast: Boolean;
begin
Result := BandRows.Last = Self;
end;
function TcxTreeListBandRow.GetItem(AIndex: Integer): TcxTreeListColumn;
begin
Result := TcxTreeListColumn(FItems[AIndex])
end;
function TcxTreeListBandRow.GetVisibleIndex: Integer;
begin
Result := BandRows.FVisibleItems.IndexOf(Self);
end;
function TcxTreeListBandRow.GetVisibleItem(AIndex: Integer): TcxTreeListColumn;
begin
Result := TcxTreeListColumn(FVisibleItems[AIndex]);
end;
function TcxTreeListBandRow.GetVisibleItemCount: Integer;
begin
Result := FVisibleItems.Count;
end;
function TcxTreeListBandRow.GetLast: TcxTreeListColumn;
begin
if VisibleItemCount > 0 then
Result := VisibleItems[VisibleItemCount - 1]
else
Result := nil;
end;
function TcxTreeListBandRow.GetTreeList: TcxCustomTreeList;
begin
Result := FBandRows.FBand.GetTreeList;
end;
{ TcxTreeListBandRows }
constructor TcxTreeListBandRows.Create(AOwner: TcxTreeListBand);
begin
FBand := AOwner;
FItems := TcxObjectList.Create;
FVisibleItems := TList.Create;
end;
destructor TcxTreeListBandRows.Destroy;
begin
FVisibleItems.Free;
FreeAndNil(FItems);
inherited Destroy;
end;
function TcxTreeListBandRows.Add: TcxTreeListBandRow;
begin
Result := TcxTreeListBandRow.Create(Self);
FItems.Add(Result);
end;
function TcxTreeListBandRows.CheckRowIndex(
ARowIndex: Integer): TcxTreeListBandRow;
begin
ARowIndex := Max(0, ARowIndex);
if ARowIndex < Count then
Result := Items[ARowIndex]
else
Result := Add;
end;
procedure TcxTreeListBandRows.CheckRowEmpty(ARowIndex: Integer);
begin
if (ARowIndex >= 0) and (ARowIndex < Count) and (Items[ARowIndex].Count = 0) then
begin
Items[ARowIndex].Free;
FItems.Delete(ARowIndex);
end;
end;
function TcxTreeListBandRows.Insert(AIndex: Integer): TcxTreeListBandRow;
begin
Result := TcxTreeListBandRow.Create(Self);
FItems.Insert(AIndex, Result);
end;
procedure TcxTreeListBandRows.Refresh;
var
I: Integer;
AItem: TcxTreeListBandRow;
begin
FRowMinWidth := 0;
FRowMaxWidth := 0;
FLineCount := 0;
FVisibleItems.Clear;
Band.HasEmptyArea := False;
for I := 0 to Count - 1 do
begin
AItem := Items[I];
AItem.Refresh;
if AItem.VisibleItemCount > 0 then
begin
FVisibleItems.Add(AItem);
FRowMinWidth := Max(FRowMinWidth, AItem.MinWidth);
FRowMaxWidth := Max(FRowMaxWidth, AItem.Width);
AItem.FLineOffset := FLineCount;
Inc(FLineCount, AItem.LineCount);
Band.FVisibleColumns.Assign(AItem.FVisibleItems, laOr);
end;
end;
end;
function TcxTreeListBandRows.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TcxTreeListBandRows.GetFirst: TcxTreeListBandRow;
begin
Result := GetItemEx(0);
end;
function TcxTreeListBandRows.GetItem(Index: Integer): TcxTreeListBandRow;
begin
Result := TcxTreeListBandRow(FItems[Index]);
end;
function TcxTreeListBandRows.GetItemEx(Index: Integer): TcxTreeListBandRow;
begin
if (Index < 0) or (Index >= Count) then
Result := nil
else
Result := Items[Index];
end;
function TcxTreeListBandRows.GetLast: TcxTreeListBandRow;
begin
Result := GetItemEx(FItems.Count - 1);
end;
function TcxTreeListBandRows.GetVisibleItemCount: Integer;
begin
Result := FVisibleItems.Count;
end;
function TcxTreeListBandRows.GetVisibleItem(AIndex: Integer): TcxTreeListBandRow;
begin
Result := TcxTreeListBandRow(FVisibleItems[AIndex]);
end;
{ TcxTreeListNode }
constructor TcxTreeListNode.Create(AOwner: TcxCustomTreeList);
begin
FTreeList := AOwner;
FOriginalIndex := -1;
FillChar(FImageIndexes, SizeOf(FImageIndexes), -1);
Inc(TreeList.DataController.FNodesCount);
State := [nsCollapsed];
end;
destructor TcxTreeListNode.Destroy;
begin
TreeList.BeginUpdate;
try
if FViewData <> nil then
FViewData.Node := nil;
Dec(TreeList.DataController.FNodesCount);
Include(State, nsDeleting);
TreeList.AddChanges([tcStructure, tcData]);
TreeList.DoDeletion(Self);
if HasChildren and (Count > 0) then
DeleteChildren;
TreeList.DoDeleteNode(Self);
TreeList.AddChanges([tcStructure]);
InternalRemove(Self);
finally
TreeList.EndUpdate;
inherited Destroy;
end;
end;
procedure TcxTreeListNode.Assign(Source: TPersistent);
var
ANode: TcxTreeListNode;
begin
if Source is TcxTreeListNode then
begin
ANode := TcxTreeListNode(Source);
Focused := ANode.Focused;
HasChildren := ANode.HasChildren;
AssignData(ANode);
end
else
inherited Assign(Source);
end;
procedure TcxTreeListNode.AssignValues(
const AValues: array of Variant);
var
I, K: Integer;
begin
K := 0;
for I := Low(AValues) to High(AValues) do
begin
if K >= ValueCount then Break;
Values[I] := AValues[I];
Inc(K);
end;
end;
function TcxTreeListNode.AddChild: TcxTreeListNode;
begin
Result := TreeList.AddNode(nil, Self, nil, tlamAddChild);
end;
function TcxTreeListNode.AddChildFirst: TcxTreeListNode;
begin
Result := TreeList.AddNode(nil, Self, nil, tlamAddChildFirst);
end;
procedure TcxTreeListNode.AlphaSort(ARecurse: Boolean = False);
begin
CustomSort(nil, ARecurse);
end;
function TcxTreeListNode.CanCollapse: Boolean;
begin
Result := TreeList.DoCanNodeCollapse(Self);
end;
function TcxTreeListNode.CanExpand: Boolean;
begin
Result := TreeList.DoCanNodeExpand(Self);
end;
function TcxTreeListNode.CanMove(
ADest: TcxTreeListNode; AMode: TcxTreeListNodeAttachMode): Boolean;
begin
if (ADest = nil) or ((ADest = Self) and (AMode in [tlamAddChild, tlamAddChildFirst, tlamInsert])) or
ADest.HasAsParent(Self) then
Result := False
else
Result := True;
end;
procedure TcxTreeListNode.CheckClick;
const
ANewState: array[Boolean, TcxCheckBoxState] of TcxCheckBoxState =
((cbsChecked, cbsUnchecked, cbsChecked), (cbsChecked, cbsGrayed, cbsUnchecked));
begin
if not Enabled or not HasCheckbox or
((Parent.CheckGroupType = ncgRadioGroup) and Checked) then Exit;
CheckState := ANewState[AllowGrayed, CheckState];
end;
procedure TcxTreeListNode.Collapse(Recurse: Boolean);
var
ANode: TcxTreeListNode;
begin
if not HasChildren then Exit;
TreeList.BeginUpdate;
try
Expanded := False;
if Recurse then
begin
ANode := FFirst;
while ANode <> nil do
begin
ANode.Collapse(True);
ANode := ANode.FNext;
end;
end;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListNode.CustomSort(
ASortProc: TcxTreeListCompareFunc; ARecurse: Boolean = False);
var
I: Integer;
AList: TList;
begin
if not Assigned(ASortProc) and not TreeList.CanCompare and (Count > 1) then Exit;
TreeList.BeginUpdate;
try
AList := TList.Create;
try
PopulateItems(AList);
if not Assigned(ASortProc) then
ASortProc := @cxCompareNodes;
AList.Sort(@ASortProc);
UpdateItems(AList);
if ARecurse and (Count > 0) then
begin
for I := 0 to AList.Count - 1 do
TcxTreeListNode(AList.List^[I]).CustomSort(ASortProc, ARecurse);
end;
finally
AList.Free;
end;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListNode.Delete;
begin
if not Deleting then Free;
end;
procedure TcxTreeListNode.DeleteChildren;
var
ANode: TcxTreeListNode;
begin
TreeList.BeginUpdate;
try
while FFirst <> nil do
begin
if nsInternalDelete in State then
Include(FFirst.State, nsInternalDelete);
Include(FFirst.State, nsDeleting);
ANode := FFirst;
FFirst := FFirst.FNext;
FreeAndNil(ANode);
end;
finally
FCount := 0;
HasChildren := False;
FFirst := nil;
FLast := nil;
TreeList.EndUpdate;
end;
end;
function TcxTreeListNode.DisplayRect(AEntryOnly: Boolean): TRect;
begin
Result := cxNullRect;
if ViewData = nil then Exit;
if AEntryOnly then
Result := ViewData.GetRealBounds
else
Result := ViewData.GetRealContentBounds;
Result := cxRectOffset(Result, ViewData.Origin);
end;
procedure TcxTreeListNode.EndEdit(Cancel: Boolean);
begin
TreeList.Controller.EditingController.HideEdit(not Cancel);
end;
procedure TcxTreeListNode.Expand(Recurse: Boolean);
var
ANode: TcxTreeListNode;
begin
if not HasChildren or TreeList.IsCancelOperation then Exit;
TreeList.BeginUpdate;
try
Expanded := True;
if Recurse then
begin
ANode := FFirst;
while ANode <> nil do
begin
ANode.Expand(True);
ANode := ANode.FNext;
end;
end;
finally
TreeList.EndUpdate;
end;
end;
function TcxTreeListNode.GetNextChild(ANode: TcxTreeListNode): TcxTreeListNode;
begin
if ANode <> nil then
Result := TcxTreeListNode(ANode.FNext)
else
Result := nil;
end;
function TcxTreeListNode.GetFirstChild: TcxTreeListNode;
begin
Result := FFirst
end;
function TcxTreeListNode.GetFirstChildVisible: TcxTreeListNode;
begin
Result := FFirst;
while (Result <> nil) and not Result.Visible do
Result := Result.FNext;
end;
function TcxTreeListNode.GetLastChild: TcxTreeListNode;
begin
Result := FLast
end;
function TcxTreeListNode.GetLastChildVisible: TcxTreeListNode;
begin
Result := FLast;
while (Result <> nil) and not Result.Visible do
Result := Result.FPrev;
end;
function TcxTreeListNode.GetNext: TcxTreeListNode;
var
ANode: TcxTreeListNode;
begin
if not (nsInternalDelete in State) then
LoadChildren;
Result := FFirst;
if FCount = 0 then
begin
ANode := Self;
while ANode <> nil do
begin
if ANode.FNext <> nil then
begin
Result := ANode.FNext;
Break;
end;
while (ANode <> nil) and (ANode.FNext = nil) do ANode := ANode.Parent;
end;
end;
end;
function TcxTreeListNode.GetNextSibling: TcxTreeListNode;
begin
Result := FNext;
end;
function TcxTreeListNode.GetNextSiblingVisible: TcxTreeListNode;
begin
Result := FNext;
while (Result <> nil) and not Result.Visible do
Result := Result.FNext;
end;
function TcxTreeListNode.GetPrev: TcxTreeListNode;
begin
Result := FPrev;
if Result <> nil then
Result := cxGetLatest(Result, False)
else
Result := Parent;
if Result = TreeList.Root then
Result := nil;
end;
function TcxTreeListNode.GetPrevSibling: TcxTreeListNode;
begin
Result := FPrev;
end;
function TcxTreeListNode.GetPrevSiblingVisible: TcxTreeListNode;
begin
Result := FPrev;
while (Result <> nil) and not Result.Visible do
Result := Result.FPrev;
end;
function TcxTreeListNode.GetPrevChild(ANode: TcxTreeListNode): TcxTreeListNode;
begin
if ANode <> nil then
Result := TcxTreeListNode(ANode.FPrev)
else
Result := nil;
end;
function TcxTreeListNode.HasAsParent(ANode: TcxTreeListNode): Boolean;
var
AItem: TcxTreeListNode;
begin
Result := False;
AItem := Parent;
while (AItem <> nil) and not Result do
begin
Result := AItem = ANode;
AItem := AItem.FParent;
end;
end;
function TcxTreeListNode.IndexOf(ANode: TcxTreeListNode): Integer;
begin
if ANode.Parent = Self then
Result := ANode.FIndex
else
Result := -1;
end;
function TcxTreeListNode.InsertChild(
ABeforeNode: TcxTreeListNode): TcxTreeListNode;
begin
Result := TreeList.AddNode(nil, ABeforeNode, nil, tlamInsert);
end;
procedure TcxTreeListNode.Invalidate;
begin
if ViewData <> nil then
TreeList.InvalidateRectEx(DisplayRect(false), False);
end;
function TcxTreeListNode.IsSibling(ANode: TcxTreeListNode): Boolean;
begin
Result := (ANode <> nil) and (ANode.FParent = FParent);
end;
procedure TcxTreeListNode.LoadChildren;
begin
if (Count <> 0) or not HasChildren or Expanded or TreeList.IsDestroying then Exit;
TreeList.BeginUpdate;
try
TreeList.DoExpand(Self);
finally
if Count > 0 then
TreeList.EndUpdate
else
TreeList.CancelUpdate;
end;
end;
procedure TcxTreeListNode.MakeVisible;
var
ANode: TcxTreeListNode;
begin
if not IsVisible then
begin
TreeList.BeginUpdate;
try
ANode := FParent;
while ANode <> nil do
begin
ANode.Expanded := True;
if not ANode.Expanded then Break;
ANode := ANode.FParent;
end;
finally
TreeList.EndUpdate;
end;
end;
if IsVisible then
TreeList.MakeNodeVisible(Self);
end;
procedure TcxTreeListNode.MoveTo(
ADestNode: TcxTreeListNode; AMode: TcxTreeListNodeAttachMode);
begin
if (ADestNode = nil) or (ADestNode = Self) then Exit;
if AMode in [tlamAdd, tlamAddFirst] then
ADestNode := ADestNode.Parent;
if not ADestNode.HasAsParent(Self) then
TreeList.InternalMove(Self, ADestNode, AMode);
end;
procedure TcxTreeListNode.Repaint(ARecalculate: Boolean);
begin
if FViewData = nil then Exit;
ViewData.Update(True);
end;
function TcxTreeListNode.GetNextSiblingEx(
ANode: TcxTreeListNode; AForward: Boolean): TcxTreeListNode;
begin
if AForward then
Result := ANode.FNext
else
Result := ANode.FPrev;
end;
procedure TcxTreeListNode.AssignData(ASource: TcxTreeListNode);
var
I: Integer;
begin
State := ASource.State;
CheckInfo := ASource.CheckInfo;
if (ASource.Parent <> nil) and (Parent <> nil) then
Parent.CheckInfo := Parent.CheckInfo + ASource.Parent.CheckInfo * [nciCheckGroup, nciRadioGroup];
for I := 0 to ASource.ValueCount - 1 do
Values[I] := ASource.Values[I];
end;
function TcxTreeListNode.GetFooterSummaryCount: Integer;
begin
if HasChildren then
Result := Summary.GroupFooterSummaryCount
else
Result := 0;
end;
function TcxTreeListNode.GetFooterSummaryText(AIndex: Integer): string;
begin
Result := Summary.GroupFooterSummaryTexts[
Summary.GroupFooterSummaryItems[AIndex], Self];
end;
function TcxTreeListNode.GetFooterSummaryValue(AIndex: Integer): Variant;
begin
cxError(not cxInRange(AIndex, 0, FooterSummaryCount - 1), SListIndexError, [AIndex]);
Summary.CheckChanges;
Result := FSummaryInfo[AIndex].Value;
end;
function TcxTreeListNode.GetInserting: Boolean;
begin
Result := TreeList.IsNodeInserting(Self);
end;
function TcxTreeListNode.GetIsFirstVisible: Boolean;
begin
Result := FVisibleIndex = 0;
end;
function TcxTreeListNode.GetIsLastVisible: Boolean;
begin
Result := (FVisibleIndex >= 0) and (FVisibleIndex = TreeList.AbsoluteVisibleCount - 1);
end;
function TcxTreeListNode.GetNextVisibleEx(IsPrev: Boolean): TcxTreeListNode;
begin
if IsPrev then
Result := GetPrevVisible
else
Result := GetNextVisible;
end;
function TcxTreeListNode.GetOwner: TPersistent;
begin
Result := TreeList;
end;
procedure TcxTreeListNode.InternalFree;
begin
Include(State, nsInternalDelete);
Free;
end;
procedure TcxTreeListNode.InitializeHandle;
begin
if FHandle = nil then
FHandle := TreeList.DataController.AllocateRecord;
end;
function OldState2State(AState: Integer): TcxTreeListNodeStates;
const
tlnsHasChildren = $0004;
tlnsCollapsed = $0010;
begin
Result := [];
if AState and tlnsHasChildren = tlnsHasChildren then
Include(Result, nsHasChildren);
if AState and tlnsCollapsed = tlnsCollapsed then
Include(Result, nsCollapsed);
end;
procedure TcxTreeListNode.ReadData(AStream: TStream; AVersion: Integer);
var
AOldState: Integer;
begin
if AVersion = 4 then
begin
AStream.ReadBuffer(AOldState, SizeOf(Integer));
State := OldState2State(AOldState);
end
else
AStream.ReadBuffer(State, SizeOf(State));
if nsCheck in State then
AStream.ReadBuffer(CheckInfo, SizeOf(CheckInfo));
if nsHeightAssigned in State then
AStream.ReadBuffer(FHeight, SizeOf(Integer));
FCount := 0;
if nsHasChildren in State then
AStream.ReadBuffer(FCount, SizeOf(Integer));
end;
procedure TcxTreeListNode.SetChildrenCheckState(
AValue: TcxCheckBoxState; AExclude: TcxTreeListNode);
var
ANode: TcxTreeListNode;
begin
ANode := FLast;
while ANode <> nil do
begin
if ANode <> AExclude then
ANode.CheckState := AValue;
ANode := ANode.FPrev;
end;
end;
procedure TcxTreeListNode.WriteData(AStream: TStream);
begin
if FCount > 0 then
Include(State, nsHasChildren);
if CheckInfo <> [] then
Include(State, nsCheck);
AStream.WriteBuffer(State, SizeOf(State));
if nsCheck in State then
AStream.WriteBuffer(CheckInfo, SizeOf(CheckInfo));
if nsHeightAssigned in State then
AStream.WriteBuffer(FHeight, SizeOf(Integer));
if (FCount > 0) or (nsHasChildren in State) then
AStream.WriteBuffer(FCount, SizeOf(Integer));
end;
function TcxTreeListNode.CanSizing(
ADirection: TcxDragSizingDirection): Boolean;
begin
with TreeList do
begin
Result := OptionsCustomizing.RowSizing and (ADirection = dsdVert);
Result := Result and not OptionsView.CellAutoHeight
end;
end;
function TcxTreeListNode.GetSizingBoundsRect(
ADirection: TcxDragSizingDirection): TRect;
begin
if ViewData = nil then
Result := cxEmptyRect
else
begin
Result := cxRectSetTop(TreeList.ClientBounds, FViewData.Origin.Y +
TreeList.ViewInfo.ColumnsRowCount * (TreeList.ViewInfo.DefaultCellHeight + cxTextOffset * 2) +
TreeList.ViewInfo.GroupFooterHeight * ViewData.GroupFooterCount, TreeList.ClientHeight);
end;
end;
function TcxTreeListNode.GetSizingIncrement(
ADirection: TcxDragSizingDirection): Integer;
begin
Result := 1;
end;
function TcxTreeListNode.IsDynamicUpdate: Boolean;
begin
Result := TreeList.OptionsCustomizing.DynamicSizing;
end;
procedure TcxTreeListNode.PopulateItems(AList: TList);
var
I: Integer;
ANode: TcxTreeListNode;
begin
I := 0;
AList.Count := Count;
ANode := FFirst;
while ANode <> nil do
begin
AList.List^[I] := ANode;
ANode := ANode.FNext;
Inc(I);
end;
end;
procedure TcxTreeListNode.SetSizeDelta(
ADirection: TcxDragSizingDirection; ADelta: Integer);
begin
if ADelta = 0 then Exit;
if TreeList.OptionsCustomizing.RowSizing then
TreeList.DefaultRowHeight := Max(TreeList.ViewInfo.DefaultCellHeight,
Max(TreeList.ViewInfo.DefaultCellHeight, TreeList.DefaultRowHeight) + ADelta)
else
begin
if Height = 0 then
Height := TreeList.ViewInfo.DefaultRowHeight * TreeList.ViewInfo.ColumnsRowCount;
Height := Max(TreeList.ViewInfo.DefaultCellHeight * TreeList.ViewInfo.ColumnsRowCount,
Height + ADelta);
end;
TreeList.Modified;
end;
procedure TcxTreeListNode.UpdateItems(AList: TList);
var
I, L: Integer;
AItems: PPointerList;
ANode: TcxTreeListNode;
AChanged: Boolean;
begin
if Count = 0 then Exit;
L := Count - 1;
AItems := AList.List;
AChanged := False;
for I := 0 to L do
begin
ANode := TcxTreeListNode(AItems^[I]);
AChanged := AChanged or (ANode.FIndex <> I);
ANode.FIndex := I;
if I > 0 then
ANode.FPrev := AItems^[I - 1]
else
ANode.FPrev := nil;
if I < L then
ANode.FNext := AItems^[I + 1]
else
ANode.FNext := nil;
end;
FFirst := TcxTreeListNode(AItems^[0]);
FLast := TcxTreeListNode(AItems^[L]);
if AChanged then
TreeList.StructureChanged;
end;
function TcxTreeListNode.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := cxE_NOINTERFACE;
end;
function TcxTreeListNode._AddRef: Integer;
begin
Result := -1;
end;
function TcxTreeListNode._Release: Integer;
begin
Result := -1;
end;
function TcxTreeListNode.GetRootParent: TcxTreeListNode;
begin
Result := Self;
while (Result.FParent <> nil) and (Result.FParent <> TreeList.Root) do
Result := Result.FParent;
end;
function TcxTreeListNode.GetAbsoluteIndex: Integer;
begin
Result := FAbsoluteIndex;
end;
function TcxTreeListNode.GetAllowGrayed: Boolean;
begin
Result := (nciAllowGrayed in CheckInfo) and
((Parent = nil) or (Parent.CheckGroupType <> ncgRadioGroup));
end;
function TcxTreeListNode.GetChecked: Boolean;
begin
Result := (nciChecked in CheckInfo) or
((nciGrayed in CheckInfo) and (Parent <> nil) and Parent.IsRadioGroup);
end;
function TcxTreeListNode.GetCheckedCount: Integer;
var
ANode: TcxTreeListNode;
begin
Result := 0;
ANode := FFirst;
while ANode <> nil do
begin
if ANode.CheckState = cbsChecked then
Inc(Result);
ANode := ANode.FNext;
end;
end;
function TcxTreeListNode.GetChildVisibleCount: Integer;
var
ANode: TcxTreeListNode;
begin
Result := 0;
ANode := FFirst;
while ANode <> nil do
begin
if not (nsHidden in ANode.State) then
Inc(Result);
ANode := ANode.FNext;
end;
end;
function TcxTreeListNode.GetCheckGroupType: TcxTreeListNodeCheckGroupType;
begin
if nciCheckGroup in CheckInfo then
Result := ncgCheckGroup
else
if nciRadioGroup in CheckInfo then
Result := ncgRadioGroup
else
Result := ncgNone;
end;
function TcxTreeListNode.GetCheckState: TcxCheckBoxState;
begin
Result := cbsUnchecked;
if nciGrayed in CheckInfo then
Result := cbsGrayed
else
if nciChecked in CheckInfo then
Result := cbsChecked;
end;
function TcxTreeListNode.GetEnabled: Boolean;
begin
Result := not (nsDisabled in State);
end;
function TcxTreeListNode.GetExpanded: Boolean;
begin
Result := (Count > 0) and (not (nsCollapsed in State) or (FParent = nil));
end;
function TcxTreeListNode.GetFocused: Boolean;
begin
Result := TreeList.Controller.FocusedNode = Self;
end;
function TcxTreeListNode.GetGrayedCount: Integer;
var
ANode: TcxTreeListNode;
begin
Result := 0;
ANode := FFirst;
while ANode <> nil do
begin
if ANode.CheckState = cbsGrayed then
Inc(Result);
ANode := ANode.FNext;
end;
end;
function TcxTreeListNode.GetHasCheckbox: Boolean;
begin
Result := TreeList.OptionsView.CheckGroups and
(Parent <> nil) and (Parent.CheckGroupType <> ncgNone)
end;
function TcxTreeListNode.GetHasChildren: Boolean;
begin
Result := (nsHasChildren in State) or (ChildVisibleCount > 0);
end;
function TcxTreeListNode.GetHasVisibleChildren: Boolean;
var
ANode: TcxTreeListNode;
begin
Result := HasChildren and (Count = 0);
if not HasChildren or (Count = 0) then Exit;
ANode := FFirst;
while not Result and (ANode <> nil) do
begin
Result := not (nsHidden in ANode.State);
ANode := ANode.FNext;
end;
end;
function TcxTreeListNode.GetIndex: Integer;
begin
if Parent <> nil then
Parent.AdjustIndexes;
Result := FIndex;
end;
function TcxTreeListNode.GetIsDeleting: Boolean;
var
ANode: TcxTreeListNode;
begin
Result := False;
ANode := Self;
while not Result and (ANode <> nil) do
begin
Result := nsDeleting in ANode.State;
ANode := ANode.Parent;
end;
end;
function TcxTreeListNode.GetHotTrack: Boolean;
begin
Result := TreeList.Controller.HotTrackNode = Self;
end;
function TcxTreeListNode.GetIsFirst: Boolean;
begin
Result := (FParent = nil) or (FParent.FFirst = Self);
end;
function TcxTreeListNode.GetIsGroupNode: Boolean;
begin
Result := TreeList.DoIsGroupNode(Self);
end;
function TcxTreeListNode.GetIsHidden: Boolean;
var
ANode: TcxTreeListNode;
begin
ANode := Parent;
Result := not Visible;
while not Result and (ANode <> TreeList.Root) do
begin
Result := not ANode.Visible;
ANode := ANode.Parent;
end;
end;
function TcxTreeListNode.GetIsLast: Boolean;
begin
Result := (FParent = nil) or (FParent.FLast = Self);
end;
function TcxTreeListNode.GetIsPrinted: Boolean;
begin
Result := ViewData <> nil;
end;
function TcxTreeListNode.GetIsRadioGroup: Boolean;
begin
Result := CheckGroupType = ncgRadioGroup;
end;
function TcxTreeListNode.GetIsVisible: Boolean;
var
ANode: TcxTreeListNode;
begin
Result := FParent <> nil;
ANode := Self;
while Result and (ANode.FParent <> nil) and (ANode.FParent <> TreeList.Root) do
begin
Result := not (nsCollapsed in ANode.FParent.State);
ANode := ANode.FParent;
end;
end;
function TcxTreeListNode.GetItem(AIndex: Integer): TcxTreeListNode;
begin
cxError((AIndex < 0) or (AIndex >= FCount),
cxGetResourceString(@scxIndexOutOfBounds), [AIndex]);
if Parent <> nil then
Parent.AdjustIndexes;
if (FLast.Index shr 1) <= AIndex then
begin
Result := FLast;
while Result.FIndex <> AIndex do
Result := Result.FPrev;
end
else
begin
Result := FFirst;
while Result.FIndex <> AIndex do
Result := Result.FNext;
end;
end;
function TcxTreeListNode.GetLevel: Integer;
var
ANode: TcxTreeListNode;
begin
ANode := FParent;
Result := -1;
while ANode <> nil do
begin
Inc(Result);
ANode := ANode.FParent;
end;
end;
function TcxTreeListNode.GetRoot: TcxTreeListNode;
begin
Result := Self;
while Result.Parent <> nil do
Result := Result.Parent;
end;
function TcxTreeListNode.GetSelected: Boolean;
begin
if TreeList.OptionsSelection.MultiSelect then
Result := TreeList.SelectionList.IndexOf(Self) <> cxInvalidIndex
else
Result := Focused;
end;
function TcxTreeListNode.GetSummary: TcxTreeListSummary;
begin
Result := TreeList.Summary;
end;
function TcxTreeListNode.GetNextVisible: TcxTreeListNode;
var
I: Integer;
begin
Result := nil;
for I := FAbsoluteIndex + 1 to TreeList.AbsoluteCount - 1 do
if TcxTreeListNode(TreeList.FAbsoluteItems.List^[I]).VisibleIndex >= 0 then
begin
Result := TcxTreeListNode(TreeList.FAbsoluteItems.List^[I]);
Break;
end;
end;
function TcxTreeListNode.GetNodeImageIndex(AIndex: Integer): TImageIndex;
begin
Result := TreeList.DoGetNodeImageIndex(Self, TcxTreeListImageIndexType(AIndex));
end;
function TcxTreeListNode.GetPrevVisible: TcxTreeListNode;
var
I: Integer;
begin
Result := nil;
for I := FAbsoluteIndex - 1 downto 0 do
if TcxTreeListNode(TreeList.FAbsoluteItems.List^[I]).VisibleIndex >= 0 then
begin
Result := TcxTreeListNode(TreeList.FAbsoluteItems.List^[I]);
Break;
end;
end;
function TcxTreeListNode.GetText(AIndex: Integer): string;
begin
Result := TreeList.Columns[AIndex].DisplayTexts[Self];
end;
function TcxTreeListNode.GetValue(AIndex: Integer): Variant;
begin
Result := TreeList.DataController.GetNodeValue(Self, AIndex);
end;
function TcxTreeListNode.GetValueCount: Integer;
begin
Result := TreeList.ColumnCount;
end;
function TcxTreeListNode.GetVisible: Boolean;
begin
Result := not (nsHidden in State);
end;
function TcxTreeListNode.GetVisibleIndex: Integer;
begin
if IsVisible then
Result := FVisibleIndex
else
Result := -1;
end;
procedure TcxTreeListNode.AdjustIndexes;
var
AIndex: Integer;
ANode: TcxTreeListNode;
begin
if nsValidIndexes in State then Exit;
AIndex := 0;
ANode := FFirst;
while ANode <> nil do
begin
ANode.FIndex := AIndex;
ANode := ANode.FNext;
Inc(AIndex);
end;
Include(State, nsValidIndexes);
end;
procedure TcxTreeListNode.InternalInsert(AValue: TcxTreeListNode);
begin
if FParent <> nil then
InternalRemove(Self);
FPrev := AValue.FPrev;
if FPrev <> nil then
FPrev.FNext := Self
else
AValue.FParent.FFirst := Self;
FNext := AValue;
if FNext <> nil then
FNext.FPrev := Self
else
AValue.FParent.FLast := Self;
AValue.FParent.SetParentFor(Self);
end;
procedure TcxTreeListNode.InternalRemove(AValue: TcxTreeListNode);
begin
if AValue.FParent <> nil then
begin
Exclude(AValue.FParent.State, nsValidIndexes);
Dec(AValue.FParent.FCount);
if AValue.FParent.FFirst = AValue then
AValue.FParent.FFirst := AValue.FNext;
if AValue.FParent.FLast = AValue then
AValue.FParent.FLast := AValue.FPrev;
if AValue.FParent.FCount = 0 then
AValue.FParent.State := AValue.FParent.State - [nsHasChildren] + [nsCollapsed];
end;
if AValue.FNext <> nil then
AValue.FNext.FPrev := AValue.FPrev;
if AValue.FPrev <> nil then
AValue.FPrev.FNext := AValue.FNext;
AValue.FPrev := nil;
AValue.FNext := nil;
AValue.FParent := nil;
end;
procedure TcxTreeListNode.SetAllowGrayed(AValue: Boolean);
begin
if AValue then
Include(CheckInfo, nciAllowGrayed)
else
Exclude(CheckInfo, nciAllowGrayed);
end;
procedure TcxTreeListNode.SetChecked(AValue: Boolean);
begin
if AValue then
CheckState := cbsChecked
else
CheckState := cbsUnchecked;
end;
procedure TcxTreeListNode.SetCheckGroupType(
AValue: TcxTreeListNodeCheckGroupType);
const
AState: array[TcxTreeListNodeCheckGroupType] of TcxTreeListNodeCheckInfos =
([], [nciCheckGroup], [nciRadioGroup]);
begin
if AValue <> CheckGroupType then
begin
CheckInfo := CheckInfo - [nciCheckGroup, nciRadioGroup] + AState[AValue];
TreeList.LayoutChanged;
end;
end;
procedure TcxTreeListNode.SetCheckState(AValue: TcxCheckBoxState);
var
ACheckedCount: Integer;
const
AState: array[TcxCheckBoxState] of TcxTreeListNodeCheckInfos =
([], [nciChecked], [nciGrayed]);
AParentCheckState: array[Boolean] of TcxCheckBoxState = (cbsGrayed, cbsChecked);
begin
if AValue = CheckState then Exit;
CheckInfo := CheckInfo - [nciChecked, nciGrayed] + AState[AValue] + [nciChangeCheck];
try
if (CheckState in [cbsChecked, cbsUnchecked]) and HasChildren then
begin
LoadChildren;
if not IsRadioGroup or (CheckState = cbsUnchecked) or (CheckedCount = 0) then
SetChildrenCheckState(CheckState, nil);
end;
if Parent <> nil then
begin
if Parent.IsRadioGroup and Checked then
Parent.SetChildrenCheckState(cbsUnchecked, Self);
if not (nciChangeCheck in Parent.CheckInfo) then
begin
ACheckedCount := Parent.CheckedCount;
if (ACheckedCount = 0) and (Parent.GrayedCount = 0) then
Parent.CheckState := cbsUnchecked
else
Parent.CheckState := AParentCheckState[(ACheckedCount = Parent.Count) or
((ACheckedCount > 0) and Parent.IsRadioGroup)];
end;
end;
finally
CheckInfo := CheckInfo - [nciChangeCheck];
if (Parent <> nil) and (Parent.CheckGroupType <> ncgNone) then
Repaint(True);
TreeList.DoNodeCheckChanged(Self, CheckState);
end;
end;
procedure TcxTreeListNode.SetEnabled(AValue: Boolean);
begin
if AValue then
Exclude(State, nsDisabled)
else
Include(State, nsDisabled);
TreeList.LayoutChanged;
end;
procedure TcxTreeListNode.SetExpanded(AValue: Boolean);
var
AExpanded: Boolean;
begin
if AValue <> Expanded then
begin
AExpanded := Expanded;
if Parent = nil then Exit;
TreeList.BeginUpdate;
try
TreeList.AddChanges([tcStructure]);
if AValue then
begin
if not TreeList.DoCanNodeExpand(Self) then Exit;
TreeList.DoExpand(Self);
Exclude(State, nsCollapsed);
TreeList.DoNodeExpanded(Self);
end
else
begin
if not TreeList.DoCanNodeCollapse(Self) then Exit;
Include(State, nsCollapsed);
TreeList.DoNodeCollapsed(Self);
end;
if AExpanded <> Expanded then
TreeList.StructureChanged;
finally
TreeList.EndUpdate;
end
end;
end;
procedure TcxTreeListNode.SetFirst(AValue: TcxTreeListNode);
begin
InternalRemove(AValue);
if FFirst <> nil then
begin
AValue.FNext := FFirst;
FFirst.FPrev := AValue;
end
else
FLast := AValue;
FFirst := AValue;
SetParentFor(AValue, False);
end;
procedure TcxTreeListNode.SetFocused(AValue: Boolean);
begin
if AValue <> Focused then
begin
TreeList.Controller.FocusedNode := Self;
TreeList.ViewInfo.UpdateSelection;
end;
end;
procedure TcxTreeListNode.SetFooterSummaryValue(AIndex: Integer; AValue: Variant);
begin
cxError(not cxInRange(AIndex, 0, FooterSummaryCount - 1), SListIndexError, [AIndex]);
FSummaryInfo[AIndex].Value := AValue;
end;
procedure TcxTreeListNode.SetHasChildren(AValue: Boolean);
begin
if HasChildren <> AValue then
begin
if AValue then
Include(State, nsHasChildren)
else
if FCount = 0 then
Exclude(State, nsHasChildren);
TreeList.DoNodeChanged(Self, nil);
end;
end;
procedure TcxTreeListNode.SetHeight(AValue: Integer);
begin
AValue := Max(0, AValue);
if AValue <> FHeight then
begin
FHeight := AValue;
if FHeight = 0 then
Exclude(State, nsHeightAssigned)
else
Include(State, nsHeightAssigned);
TreeList.LayoutChanged;
end;
end;
procedure TcxTreeListNode.SetItem(AIndex: Integer; AValue: TcxTreeListNode);
begin
GetItem(AIndex).Assign(AValue);
end;
procedure TcxTreeListNode.SetLast(AValue: TcxTreeListNode);
begin
InternalRemove(AValue);
if FLast <> nil then
begin
AValue.FPrev := FLast;
FLast.FNext := AValue;
end
else
FFirst := AValue;
FLast := AValue;
SetParentFor(AValue, False);
end;
procedure TcxTreeListNode.SetNodeImageIndex(
AIndex: Integer; AValue: TImageIndex);
begin
if FImageIndexes[TcxTreeListImageIndexType(AIndex)] <> AValue then
begin
FImageIndexes[TcxTreeListImageIndexType(AIndex)] := AValue;
TreeList.DoNodeChanged(Self, nil);
end;
end;
procedure TcxTreeListNode.SetParentFor(
AValue: TcxTreeListNode; AValidateIndexes: Boolean = True);
begin
AValue.FParent := Self;
Inc(FCount);
if AValidateIndexes then
Exclude(State, nsValidIndexes);
TreeList.DoNodeChanged(AValue, nil);
end;
procedure TcxTreeListNode.SetText(AIndex: Integer; const AValue: string);
begin
SetValue(AIndex, AValue);
end;
procedure TcxTreeListNode.SetSelected(AValue: Boolean);
begin
if Selected <> AValue then
try
if not AValue then
begin
TreeList.SelectionList.Remove(Self);
TreeList.DoSelectionChanged;
end
else
TreeList.Select(Self);
finally
TreeList.ViewInfo.UpdateSelection;
end;
end;
procedure TcxTreeListNode.SetValue(AIndex: Integer; const AValue: Variant);
begin
if Focused and (TreeList.DataController.EditingNode <> nil) then
TreeList.DataController.SetEditValue(AIndex, AValue, evsValue)
else
TreeList.DataController.SetNodeValue(Self, AIndex, AValue);
end;
procedure TcxTreeListNode.SetVisible(AValue: Boolean);
begin
if AValue <> Visible then
begin
if not AValue then
Include(State, nsHidden)
else
Exclude(State, nsHidden);
TreeList.DoNodeChanged(Self, nil);
end;
end;
{ TcxTreeListRootNode }
function TcxTreeListRootNode.GetFooterSummaryCount: Integer;
begin
Result := Summary.FooterSummaryCount;
end;
function TcxTreeListRootNode.GetFooterSummaryText(
AIndex: Integer): string;
begin
Result := Summary.FooterSummaryTexts[
Summary.FooterSummaryItems[AIndex]];
end;
procedure TcxTreeListRootNode.InitializeHandle;
begin
FHandle := nil;
end;
{ TcxUnboundTreeListNode }
constructor TcxUnboundTreeListNode.Create(AOwner: TcxCustomTreeList);
begin
inherited Create(AOwner);
FImageIndexes := cxDefaultImageIndexes;
end;
procedure TcxUnboundTreeListNode.Assign(Source: TPersistent);
begin
if Source is TcxUnboundTreeListNode then
FImageIndexes := TcxUnboundTreeListNode(Source).FImageIndexes;
inherited Assign(Source);
end;
procedure TcxUnboundTreeListNode.ReadData(AStream: TStream; AVersion: Integer);
begin
AStream.ReadBuffer(FHandle, SizeOf(Integer));
inherited ReadData(AStream, AVersion);
if AVersion = 4 then
AStream.ReadBuffer(FImageIndexes, SizeOf(Integer) * 3)
else
AStream.ReadBuffer(FImageIndexes, SizeOf(FImageIndexes));
end;
procedure TcxUnboundTreeListNode.WriteData(AStream: TStream);
begin
AStream.WriteBuffer(FHandle, SizeOf(Integer));
inherited WriteData(AStream);
AStream.WriteBuffer(FImageIndexes, SizeOf(FImageIndexes))
end;
{ TcxTreeListItemsCustomizeListBox }
constructor TcxTreeListItemsCustomizeListBox.CreateEx(AOwner: TComponent;
ATreeList: TcxCustomTreeList; AParent: TWinControl);
begin
inherited Create(AOwner);
FTreeList := ATreeList;
Align := alClient;
Parent := AParent;
Color := clBtnFace;
Style.HotTrack := False;
Style.LookAndFeel.MasterLookAndFeel := TreeList.LookAndFeel;
Style.TransparentBorder := False;
ParentFont := True;
OnMeasureItem := MeasureItem;
InnerListBox.OnDrawItem := DoDrawItemEx;
OnDrawItem := DoDrawItem;
ListStyle := lbOwnerDrawVariable;
ItemHeight := GetItemHeight(0);
FHeaders := TcxObjectList.Create;
RefreshList;
end;
destructor TcxTreeListItemsCustomizeListBox.Destroy;
begin
FreeAndNil(FHeaders);
inherited Destroy;
end;
procedure TcxTreeListItemsCustomizeListBox.AddItem(
ACaption: TcxTreeListCaption);
var
ACell: TcxTreeListHeaderCellViewInfo;
begin
ACell := CreateCell;
ACell.Initialize(ACaption);
Items.AddObject(ACaption.Text, ACell);
FHeaders.Add(ACell);
end;
procedure TcxTreeListItemsCustomizeListBox.DblClick;
var
AIndex: Integer;
begin
AIndex := ItemAtPos(ScreenToClient(GetMouseCursorPos), True);
if AIndex >= 0 then
begin
FinishDragAndDrop(False);
MakeItemVisible(Headers[AIndex]);
end;
end;
procedure TcxTreeListItemsCustomizeListBox.DoDrawItem(AControl: TcxListBox;
ACanvas: TcxCanvas; AIndex: Integer; ARect: TRect; AState: TOwnerDrawState);
var
ASaveState: TcxButtonState;
begin
ASaveState := Headers[AIndex].State;
try
if [odFocused, odSelected] * AState <> [] then
Headers[AIndex].FState := cxbsPressed;
Headers[AIndex].Draw(ACanvas);
SelectClipRgn(ACanvas.Handle, 0);
finally
Headers[AIndex].FState := ASaveState;
end;
end;
procedure TcxTreeListItemsCustomizeListBox.DoDrawItemEx(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
end;
function TcxTreeListItemsCustomizeListBox.GetItemHeight(AItem: Integer): Integer;
begin
Result := Painter.HeaderHeight(cxTextHeight(Font));
end;
function TcxTreeListItemsCustomizeListBox.GetOrigin(AHeader: TcxTreeListHeaderCellViewInfo): TPoint;
begin
Result := ClientToScreen(AHeader.BoundsRect.TopLeft);
end;
procedure TcxTreeListItemsCustomizeListBox.MeasureItem(AControl: TcxListBox;
Index: Integer; var Height: Integer);
begin
Height := GetItemHeight(Index);
end;
procedure TcxTreeListItemsCustomizeListBox.Paint;
begin
with Painter do
begin
DrawBorder(Canvas, ClientRect);
IntersectClipRect(Handle, BorderSize, BorderSize,
ClientWidth - BorderSize, ClientHeight - BorderSize);
inherited Paint;
end;
end;
procedure TcxTreeListItemsCustomizeListBox.RefreshList;
begin
if csDestroying in ComponentState then Exit;
Items.BeginUpdate;
try
Clear;
FHeaders.Clear;
PopulateItems;
Resize;
finally
Items.EndUpdate;
end;
end;
procedure TcxTreeListItemsCustomizeListBox.Resize;
var
I: Integer;
begin
inherited Resize;
for I := 0 to Count - 1 do
Headers[I].SetBounds(Rect(0, I * ItemHeight, ClientWidth -
Painter.BorderSize * 2, (I + 1) * ItemHeight), ClientRect);
Invalidate;
end;
function TcxTreeListItemsCustomizeListBox.StartDragAndDrop(
const P: TPoint): Boolean;
var
AIndex: Integer;
begin
AIndex := ItemAtPos(P, True);
Result := AIndex >= 0;
if Result then
TreeList.Controller.DragItem := Headers[AIndex];
end;
function TcxTreeListItemsCustomizeListBox.GetHeader(
AIndex: Integer): TcxTreeListHeaderCellViewInfo;
begin
Result := FHeaders[AIndex] as TcxTreeListHeaderCellViewInfo;
end;
function TcxTreeListItemsCustomizeListBox.GetPainter: TcxCustomLookAndFeelPainterClass;
begin
Result := TreeList.LookAndFeel.Painter;
end;
{ TcxTreeListColumnsCustomizeListBox }
function TcxTreeListColumnsCustomizeListBox.CreateCell: TcxTreeListHeaderCellViewInfo;
begin
Result := TcxTreeListColumnHeaderCellViewInfo.CreateEx(TreeList, ClientRect, ClientRect);
end;
function TcxTreeListColumnsCustomizeListBox.GetDragAndDropObjectClass: TcxDragAndDropObjectClass;
begin
Result := TcxTreeListDragAndDropColumnObject;
end;
procedure TcxTreeListColumnsCustomizeListBox.MakeItemVisible(
AHeader: TcxTreeListHeaderCellViewInfo);
var
ABand: TcxTreeListBand;
begin
ABand := TcxTreeListColumnHeaderCellViewInfo(AHeader).Band;
if (ABand <> nil) and ABand.ActuallyVisible then
TcxTreeListColumnHeaderCellViewInfo(AHeader).Column.Visible := True;
end;
procedure TcxTreeListColumnsCustomizeListBox.PopulateItems;
var
I: Integer;
begin
for I := 0 to TreeList.ColumnCount - 1 do
if not TreeList.Columns[I].ActuallyVisible then
AddItem(TreeList.Columns[I].Caption);
end;
{ TcxTreeListBandsCustomizeListBox }
function TcxTreeListBandsCustomizeListBox.CreateCell: TcxTreeListHeaderCellViewInfo;
begin
Result := TcxTreeListBandHeaderCellViewInfo.CreateEx(
TreeList, ClientRect, ClientRect);
end;
function TcxTreeListBandsCustomizeListBox.GetDragAndDropObjectClass: TcxDragAndDropObjectClass;
begin
Result := TcxTreeListDragAndDropBandObject;
end;
procedure TcxTreeListBandsCustomizeListBox.MakeItemVisible(
AHeader: TcxTreeListHeaderCellViewInfo);
begin
with TcxTreeListBandHeaderCellViewInfo(AHeader).Band do
begin
if (ParentBand = nil) or ParentBand.ActuallyVisible then
Visible := True;
end;
end;
procedure TcxTreeListBandsCustomizeListBox.PopulateItems;
var
I: Integer;
begin
for I := 0 to TreeList.Bands.Count - 1 do
if not TreeList.Bands[I].ActuallyVisible then
AddItem(TreeList.Bands[I].Caption);
end;
{ TcxTreeListCustomizationForm }
constructor TcxTreeListCustomizationForm.CreateEx(AOwner: TcxTreeListCustomizing);
begin
CreateNew(nil);
FOwner := AOwner;
FHookTimer := TcxTimer.Create(Self);
FHookTimer.Enabled := False;
FHookTimer.Interval := 10;
FHookTimer.OnTimer := TimerHandler;
Visible := False;
end;
destructor TcxTreeListCustomizationForm.Destroy;
begin
Customizing.FinishCustomizing(BoundsRect);
FreeAndNil(FHookTimer);
inherited Destroy;
end;
function TcxTreeListCustomizationForm.GetTreeList: TcxCustomTreeList;
begin
Result := Customizing.TreeList;
end;
procedure TcxTreeListCustomizationForm.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or WS_POPUP;
if not TreeList.IsDestroying then
WndParent := TreeList.Handle;
end;
end;
procedure TcxTreeListCustomizationForm.FinishDragDrop(
Sender: TcxTreeListItemsCustomizeListBox);
begin
FDragDropListBox := nil
end;
procedure TcxTreeListCustomizationForm.StartDragDrop(
Sender: TcxTreeListItemsCustomizeListBox);
begin
FDragDropListBox := Sender;
end;
procedure TcxTreeListCustomizationForm.TimerHandler(Sender: TObject);
begin
if IsIconic(Application.Handle) then
Visible := False
else
if not TreeList.Visible or not IsWindowVisible(TreeList.Handle) then
Customizing.Visible := False
else
if not Visible then
begin
ShowWindow(Handle, SW_SHOWNOACTIVATE);
Visible := True;
end;
if not Active and (DragDropListBox <> nil) then
DragDropListBox.FinishDragAndDrop(False);
end;
{ TcxTreeListCustomizing }
constructor TcxTreeListCustomizing.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FRowCount := 10;
FBounds := cxRect(-2000, -2000, -2000, -2000);
TreeList.Designers.Add(Self);
end;
destructor TcxTreeListCustomizing.Destroy;
begin
TreeList.Designers.Remove(Self);
Visible := False;
inherited Destroy;
end;
procedure TcxTreeListCustomizing.Assign(Source: TPersistent);
begin
if Source is TcxTreeListCustomizing then
begin
RowCount := TcxTreeListCustomizing(Source).RowCount;
Visible := TcxTreeListCustomizing(Visible).Visible;
end;
end;
procedure TcxTreeListCustomizing.MakeBandPageVisible;
begin
Visible := True;
if (FBandListBox <> nil) and (FBandListBox.Parent = FTabSheetBands) then
FPageControl.ActivePage := FTabSheetBands;
end;
procedure TcxTreeListCustomizing.MakeColumnPageVisible;
begin
Visible := True;
if FHeaderListBox.Parent = FTabSheetHeaders then
FPageControl.ActivePage := FTabSheetHeaders;
end;
function TcxTreeListCustomizing.PtInCustomizingBox(const APoint: TPoint): Boolean;
begin
Result := Visible and (FForm <> nil) and PtInRect(FForm.BoundsRect, APoint);
end;
procedure TcxTreeListCustomizing.CalculateSize(var AWidth, AHeight: Integer);
begin
AWidth := 200;
AHeight := 300;
end;
procedure TcxTreeListCustomizing.Close(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
procedure TcxTreeListCustomizing.CreateControls;
begin
if not SimpleMode then
begin
FPageControl := TcxPageControl.Create(FForm);
FPageControl.HotTrack := True;
FPageControl.Focusable := False;
FPageControl.LookAndFeel.MasterLookAndFeel := TreeList.LookAndFeel;
FPageControl.Parent := FForm;
FPageControl.BoundsRect := cxTextRect(FForm.ClientRect);
FPageControl.Anchors := [akTop, akLeft, akRight, akBottom];
// bands
FTabSheetBands := TcxTabSheet.Create(FForm);
FTabSheetBands.Caption := cxGetResourceString(@scxBandsCaption);
FTabSheetBands.PageControl := FPageControl;
FTabSheetBands.TabVisible := True;
FBandListBox := TcxTreeListBandsCustomizeListBox.CreateEx(
FForm, TreeList, FTabSheetBands);
// columns
FTabSheetHeaders := TcxTabSheet.Create(FForm);
FTabSheetHeaders.Caption := cxGetResourceString(@scxColumnsCaption);
FTabSheetHeaders.PageControl := FPageControl;
FTabSheetHeaders.Parent := FPageControl;
FHeaderListBox := TcxTreeListColumnsCustomizeListBox.CreateEx(
FForm, TreeList, FTabSheetHeaders);
end
else
FHeaderListBox := TcxTreeListColumnsCustomizeListBox.CreateEx(FForm, TreeList, FForm);
end;
procedure TcxTreeListCustomizing.CreateCustomizingForm;
var
I: Integer;
const
UnusedItems: array[0..4, 0..1] of Integer =
((7, MF_BYPOSITION), (5, MF_BYPOSITION), (SC_MAXIMIZE, MF_BYCOMMAND),
(SC_MINIMIZE, MF_BYCOMMAND), (SC_RESTORE, MF_BYCOMMAND));
begin
FForm := TcxTreeListCustomizationForm.CreateEx(Self);
with FForm do
begin
Caption := cxGetResourceString(@scxCustomizeCaption);
BorderStyle := bsSizeToolWin;
BorderIcons := [biSystemMenu];
Font.Assign(TreeList.Font);
{ ClientWidth := SizeDelta.cx * cxTextWidth(Font, '0');
ClientHeight := (RowCount + 1) * FLineHeight;
FLineHeight := cxTextHeight(Font) + SizeDelta.cy;}
Color := clBtnFace;
OnClose := Self.Close;
for I := 0 to High(UnusedItems) do
DeleteMenu(GetSystemMenu(Handle, False), UnusedItems[I, 0], UnusedItems[I, 1]);
end;
CreateControls;
end;
procedure TcxTreeListCustomizing.FinishCustomizing(const ABounds: TRect);
begin
FBounds := ABounds;
FIsPositionAssigned := True;
FBandListBox := nil;
FHeaderListBox := nil;
FPageControl := nil;
FTabSheetBands := nil;
FTabSheetHeaders := nil;
FForm := nil;
TreeList.DoCustomizationVisibleChanged;
end;
procedure TcxTreeListCustomizing.HideCustomizingForm;
begin
if Visible then
begin
FForm.HookTimer.Enabled := False;
FreeAndNil(FForm);
end;
end;
procedure TcxTreeListCustomizing.SetControlParent(
AControl, AParent: TWinControl);
begin
AControl.Parent := AParent;
if AParent <> nil then
begin
AControl.BoundsRect := AParent.ClientRect;
Visible := True;
end;
end;
procedure TcxTreeListCustomizing.ShowCustomizingForm;
var
W, H: Integer;
begin
if Visible then Exit;
if FForm = nil then
CreateCustomizingForm;
if not IsPositionAssigned then
begin
if GetParentForm(TreeList) = nil then
FBounds := TreeList.BoundsRect
else
FBounds := GetParentForm(TreeList).BoundsRect;
CalculateSize(W, H);
FBounds := cxRectSetRight(FBounds, FBounds.Right, W);
FBounds := cxRectSetBottom(FBounds, FBounds.Bottom, H);
end;
FForm.BoundsRect := FBounds;
FForm.Show;
FForm.HookTimer.Enabled := True;
TreeList.DoCustomizationVisibleChanged;
end;
procedure TcxTreeListCustomizing.ComponentModified;
begin
if Visible then
begin
if FHeaderListBox <> nil then
FHeaderListBox.RefreshList;
if FBandListBox <> nil then
FBandListBox.RefreshList;
end
end;
procedure TcxTreeListCustomizing.ComponentRemoved(Sender: TObject);
begin
end;
procedure TcxTreeListCustomizing.Update;
begin
if FBandListBox <> nil then
FBandListBox.Invalidate;
if FHeaderListBox <> nil then
FHeaderListBox.Invalidate;
end;
function TcxTreeListCustomizing.GetForm: TForm;
begin
Result := FForm;
end;
function TcxTreeListCustomizing.GetPosition: TPoint;
begin
if Visible then
Result := Point(Form.Top, Form.Left)
else
Result := FBounds.TopLeft;
end;
function TcxTreeListCustomizing.GetTreeList: TcxCustomTreeList;
begin
Result := GetOwner as TcxCustomTreeList;
end;
function TcxTreeListCustomizing.GetIsSimpleMode: Boolean;
begin
Result := TreeList.OptionsView.SimpleCustomizeBox or
not TreeList.OptionsView.Bands;
end;
function TcxTreeListCustomizing.GetVisible: Boolean;
begin
Result := (FForm <> nil) and FForm.Visible;
end;
procedure TcxTreeListCustomizing.SetPosition(const AValue: TPoint);
begin
FBounds.TopLeft := AValue;
if Visible then
begin
Form.Left := AValue.X;
Form.Top := AValue.Y;
end;
FIsPositionAssigned := True;
end;
procedure TcxTreeListCustomizing.SetRowCount(AValue: Integer);
begin
AValue := Max(AValue, 2);
if AValue <> FRowCount then
FRowCount := AValue;
end;
procedure TcxTreeListCustomizing.SetVisible(AValue: Boolean);
begin
if AValue then
ShowCustomizingForm
else
HideCustomizingForm;
end;
{ TcxTreeListCustomCellViewInfo }
constructor TcxTreeListCustomCellViewInfo.CreateEx(
ATreeList: TcxCustomTreeList; const ABounds, AVisibleRect: TRect);
begin
inherited Create(ATreeList);
DisplayRect := ABounds;
VisibleBounds := AVisibleRect;
CheckClipping(DisplayRect, VisibleBounds);
end;
{procedure TcxTreeListCustomCellViewInfo.CheckClipping(
const ADisplayRect, AAvailableRect: TRect);
var
R: TRect;
begin
if AAvailableRect.Right > ADisplayRect.Right then
begin
R := AAvailableRect;
R.Right := ADisplayRect.Right;
inherited CheckClipping(ADisplayRect, R);
end
else
inherited CheckClipping(ADisplayRect, AAvailableRect);
end;}
procedure TcxTreeListCustomCellViewInfo.DoCalculate;
begin
CheckClipping(DisplayRect, VisibleBounds);
end;
procedure TcxTreeListCustomCellViewInfo.DoDraw(ACanvas: TcxCanvas);
var
P: TPoint;
begin
if not Visible then Exit;
if not CellHasOrigin then
ACanvas.FillRect(BoundsRect, ViewParams, Borders, BorderColor)
else
begin
SetWindowOrgEx(ACanvas.Handle, 0, 0, @P);
ACanvas.FillRect(cxRectOffset(BoundsRect, GetCellOrigin),
ViewParams, Borders, BorderColor);
SetWindowOrgEx(ACanvas.Handle, P.X, P.Y, nil);
end;
end;
function TcxTreeListCustomCellViewInfo.CellHasOrigin: Boolean;
begin
Result := (FAttachNode <> nil) and (FAttachNode.FViewData <> nil);
end;
function TcxTreeListCustomCellViewInfo.GetClipRect: TRect;
begin
Result := ClipRect;
if cxRectIsEmpty(DisplayRect) then
begin
Result := VisibleRect;
if Result.Left < DisplayRect.Left then
Result.Left := DisplayRect.Left;
if Result.Right > DisplayRect.Right then
Result.Right := DisplayRect.Right;
end
end;
function TcxTreeListCustomCellViewInfo.GetCellOrigin: TPoint;
begin
if CellHasOrigin then
Result := FAttachNode.ViewData.Origin
else
Result := cxNullPoint;
end;
function TcxTreeListCustomCellViewInfo.GetControl: TcxEditingControl;
begin
Result := TcxCustomTreeList(Owner);
end;
function TcxTreeListCustomCellViewInfo.GetHitTest(
AHitTest: TcxCustomHitTestController): Boolean;
begin
if CellHasOrigin then
Result := Visible and PtInRect(cxRectOffset(ClipRect, GetCellOrigin), AHitTest.HitPoint)
else
Result := Visible and PtInRect(ClipRect, AHitTest.HitPoint);
if not Result then Exit;
if not VisibleInfoCalculated then
DoCalculate;
if AttachNode <> nil then
begin
HitTest.FHitNode := AttachNode;
if Node <> nil then
SetHitTestCodes([tlhc_HitAtNode]);
end;
TcxTreeListHitTest(AHitTest).HitTestItem := Self;
end;
procedure TcxTreeListCustomCellViewInfo.SetBounds(
const ABounds, AVisibleBounds: TRect);
begin
CheckClipping(ABounds, AVisibleBounds);
VisibleInfoCalculated := False;
end;
procedure TcxTreeListCustomCellViewInfo.SetHitTestCodes(
const ACodes: array of Integer);
var
I: Integer;
begin
for I := Low(ACodes) to High(ACodes) do
TreeList.HitTest.SetHitState(ACodes[I], True);
end;
function TcxTreeListCustomCellViewInfo.GetSelected: Boolean;
begin
Result := False;
end;
function TcxTreeListCustomCellViewInfo.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := cxE_NOINTERFACE;
end;
function TcxTreeListCustomCellViewInfo._AddRef: Integer;
begin
Result := -1;
end;
function TcxTreeListCustomCellViewInfo._Release: Integer;
begin
Result := -1;
end;
function TcxTreeListCustomCellViewInfo.GetExtPaintStyle: Boolean;
begin
Result := OptionsView.ExtPaintStyle;
end;
function TcxTreeListCustomCellViewInfo.GetHitTestController: TcxTreeListHitTest;
begin
Result := TreeList.HitTest;
end;
function TcxTreeListCustomCellViewInfo.GetOptionsView: TcxTreeListOptionsView;
begin
Result := TreeList.OptionsView;
end;
function TcxTreeListCustomCellViewInfo.GetStyles: TcxTreeListStyles;
begin
Result := TreeList.Styles;
end;
function TcxTreeListCustomCellViewInfo.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(Owner);
end;
function TcxTreeListCustomCellViewInfo.GetVisibleRect: TRect;
begin
Result := VisibleBounds;
end;
{ TcxTreeListBackgroundCellViewInfo }
class function TcxTreeListBackgroundCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlBackgroundCell;
end;
function TcxTreeListBackgroundCellViewInfo.GetHitTest(
AHitTest: TcxCustomHitTestController): Boolean;
begin
Result := inherited GetHitTest(AHitTest);
if Result then
SetHitTestCodes([tlhc_HitAtBackground]);
end;
procedure TcxTreeListBackgroundCellViewInfo.Scroll(const DX, DY: Integer);
begin
end;
{ TcxTreeListFooterCellViewInfo }
constructor TcxTreeListFooterCellViewInfo.CreateEx(ATreeList: TcxCustomTreeList;
const ABounds, AVisibleRect: TRect);
begin
inherited CreateEx(ATreeList, ABounds, AVisibleRect);
FBorders := cxBordersAll;
end;
class function TcxTreeListFooterCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlFooterCell;
end;
procedure TcxTreeListFooterCellViewInfo.DoCalculate;
begin
inherited DoCalculate;
ItemViewParams := Styles.GetColumnFooterParams(Column, Node, GetItem);
FHidden := FHidden or ((GetItem = nil) or not GetItem.Visible);
end;
procedure TcxTreeListFooterCellViewInfo.DoDraw(ACanvas: TcxCanvas);
begin
if Hidden then Exit;
if not Transparent then
Painter.DrawFooterCellContent(ACanvas, BoundsRect, AlignHorz, AlignVert, MultiLine,
'', ViewParams.Font, ViewParams.TextColor, ViewParams.Color, DrawBackgroundHandler);
DrawText(ACanvas);
Painter.DrawFooterCellBorder(ACanvas, BoundsRect);
if Selected then
begin
ACanvas.DrawFocusRect(cxRectInflate(DisplayRect, -1, -1));
ACanvas.DrawFocusRect(cxRectInflate(DisplayRect, -2, -2));
end;
end;
procedure TcxTreeListFooterCellViewInfo.DrawText(ACanvas: TcxCanvas);
begin
ACanvas.Brush.Style := bsClear;
ACanvas.DrawTexT(FText, cxTextRect(BoundsRect), AlignHorz, AlignVert, MultiLine, ShowEndEllipsis);
ACanvas.Brush.Style := bsSolid;
end;
function TcxTreeListFooterCellViewInfo.GetAlignHorz: TAlignment;
begin
Result := GetItem.FAlignHorz;
end;
function TcxTreeListFooterCellViewInfo.GetAlignVert: TcxAlignmentVert;
begin
Result := GetItem.FAlignVert;
end;
function TcxTreeListFooterCellViewInfo.GetItem: TcxTreeListSummaryItem;
begin
Result := nil;
end;
function TcxTreeListFooterCellViewInfo.GetHitTest(
AHitTest: TcxCustomHitTestController): Boolean;
var
R: TRect;
begin
Result := False;
if not Visible then Exit;
R := ClipRect;
if AttachNode <> nil then
R := cxRectOffset(R, AttachNode.ViewData.Origin);
Result := PtInRect(cxRectInflate(R, cxTextOffset, cxTextOffset), AHitTest.HitPoint);
if not Result then Exit;
if not VisibleInfoCalculated then
DoCalculate;
HitTest.FHitNode := AttachNode;
if AttachNode <> nil then
SetHitTestCodes([tlhc_HitAtNode]);
TcxTreeListHitTest(AHitTest).HitTestItem := Self;
HitTest.FHitColumn := Column;
SetHitTestCodes([tlhc_HitAtColumn]);
if (Node = nil) or (Node.Parent = nil) then
SetHitTestCodes([tlhc_HitAtFooterItem])
else
SetHitTestCodes([tlhc_HitAtGroupFooterItem]);
end;
function TcxTreeListFooterCellViewInfo.GetMultiline: Boolean;
begin
Result := (Column.Position.LineCount > 1) and (GetItem <> nil) and GetItem.MultiLine;
end;
procedure TcxTreeListFooterCellViewInfo.Initialize(
ANode, AttachNode: TcxTreeListNode; AColumn: TcxTreeListColumn);
begin
FAttachNode := AttachNode;
FNode := ANode;
FColumn := AColumn;
FText := '';
end;
procedure TcxTreeListFooterCellViewInfo.Scroll(const DX, DY: Integer);
begin
if Column.Position.Band.FixedKind <> tlbfNone then Exit;
inherited Scroll(DX, 0);
end;
function TcxTreeListFooterCellViewInfo.GetOrigin: TPoint;
begin
Result := cxPointOffset(DisplayRect.TopLeft, GetCellOrigin);
end;
function TcxTreeListFooterCellViewInfo.IsNeedHint(ACanvas: TcxCanvas;
const P: TPoint; out AText: TCaption; out AIsMultiLine: Boolean;
out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean;
var
AFlags: Integer;
AAccessibleTextBounds, ANeededTextBounds: TRect;
begin
AFlags := cxAlignTop or cxAlignLeft or cxDontPrint;
if AIsMultiLine then
AFlags := AFlags or cxWordBreak;
ACanvas.Font := ViewParams.Font;
AIsMultiLine := MultiLine;
AAccessibleTextBounds := cxRectOffset(cxTextRect(BoundsRect), GetCellOrigin);
ANeededTextBounds := AAccessibleTextBounds;
AText := FText;
ACanvas.TextExtent(AText, ANeededTextBounds, AFlags);
Result := PtInRect(AAccessibleTextBounds, P) and
not cxRectContain(AAccessibleTextBounds, ANeededTextBounds);
ATextRect := ANeededTextBounds;
IsNeedOffsetHint := False;
end;
procedure TcxTreeListFooterCellViewInfo.UpdateHotTrackState(
const APoint: TPoint);
begin
end;
function TcxTreeListFooterCellViewInfo.GetShowEndEllipsis: Boolean;
begin
Result := Column.Options.CellEndEllipsis;
end;
{ TcxTreeListFooterSingleCellViewInfo }
function TcxTreeListFooterSingleCellViewInfo.GetItem: TcxTreeListSummaryItem;
begin
Result := SummaryItem;
end;
function TcxTreeListFooterSingleCellViewInfo.GetSelected: Boolean;
begin
Result := TreeList.Controller.IsObjectSelected(GetItem);
end;
procedure TcxTreeListFooterSingleCellViewInfo.Initialize(
ANode, AttachNode: TcxTreeListNode;
AColumn: TcxTreeListColumn; ASummaryItem: TcxTreeListSummaryItem);
begin
inherited Initialize(ANode, AttachNode, AColumn);
FSummaryItem := ASummaryItem;
FText := Node.FooterSummaryTexts[GetItem.AbsoluteIndex];
end;
{ TcxTreeListFooterMultiItemsCellViewInfo }
function TcxTreeListFooterMultiItemsCellViewInfo.CanDifferentStyles: Boolean;
begin
Result := True {Assigned(Styles.FOnGetColumnFooterStyle)} and (VisibleCount > 1);
end;
procedure TcxTreeListFooterMultiItemsCellViewInfo.DrawText(ACanvas: TcxCanvas);
var
R, R1: TRect;
AText: string;
AWidth, ACountInLine, I, J: Integer;
begin
if not CanDifferentStyles then
inherited DrawText(ACanvas)
else
begin
R := cxTextRect(DisplayRect);
J := 0;
FNeedShowHint := False;
ACanvas.SaveClipRegion;
try
ACanvas.IntersectClipRect(R);
FHintRect := R;
R := cxRectSetHeight(R, cxTextHeight(ViewParams.Font) + cxTextOffset * 2);
ACanvas.Font := ViewParams.Font;
ACanvas.Brush.Style := bsClear;
AWidth := 0;
ACountInLine := 0;
for I := 0 to SummaryItems.Count - 1 do
begin
if not SummaryItems[I].Visible then Continue;
Inc(J);
Inc(R.Left, AWidth);
AText := Node.FooterSummaryTexts[SummaryItems[I].AbsoluteIndex];
if J < VisibleCount then
AText := AText + ListSeparator;
AWidth := cxTextWidth(ViewParams.Font, AText);
if (ACountInLine = 0) or (cxRectWidth(R) >= AWidth) or not MultiLine then
Inc(ACountInLine)
else
if (cxRectWidth(R) < AWidth) then
begin
R1 := cxRectSetTop(cxTextRect(DisplayRect), R.Bottom, cxRectHeight(R));
ACountInLine := 1;
FNeedShowHint := FNeedShowHint or (R1.Bottom > cxTextRect(DisplayRect).Bottom);
if FNeedShowHint then
Inc(ACountInLine)
else
R := R1;
end;
FNeedShowHint := FNeedShowHint or ((R.Left + AWidth) > cxTextRect(DisplayRect).Right);
ACanvas.Font.Color := Styles.GetColumnFooterParams(Column, Node, SummaryItems[I]).TextColor;
ACanvas.Brush.Style := bsClear;
ACanvas.DrawTexT(AText, R, AlignHorz, AlignVert, False, ShowEndEllipsis);
ACanvas.Brush.Style := bsSolid;
end;
FHintRect.Bottom := R.Bottom;
FHintRect.Right := R.Right;
finally
ACanvas.RestoreClipRegion;
end;
end;
end;
function TcxTreeListFooterMultiItemsCellViewInfo.GetAlignHorz: TAlignment;
begin
Result := inherited GetAlignHorz;
if CanDifferentStyles and not Multiline then
Result := taLeftJustify;
end;
function TcxTreeListFooterMultiItemsCellViewInfo.GetAlignVert: TcxAlignmentVert;
begin
Result := inherited GetAlignVert;
if CanDifferentStyles then
Result := vaTop;
end;
function TcxTreeListFooterMultiItemsCellViewInfo.GetItem: TcxTreeListSummaryItem;
var
I: Integer;
begin
Result := nil;
for I := 0 to SummaryItems.Count - 1 do
begin
Result := SummaryItems[I];
if Result.Visible then Break;
end;
end;
function TcxTreeListFooterMultiItemsCellViewInfo.GetSelected: Boolean;
var
I: Integer;
begin
Result := False;
for I := 0 to SummaryItems.Count - 1 do
if SummaryItems[I].Visible and
TreeList.Controller.IsObjectSelected(SummaryItems[I]) then
begin
Result := True;
Break;
end;
end;
procedure TcxTreeListFooterMultiItemsCellViewInfo.Initialize(
ADataNode, AttachNode: TcxTreeListNode; AColumn: TcxTreeListColumn;
ASummaryItems: TcxTreeListSummaryItems);
var
I: Integer;
begin
inherited Initialize(ADataNode, AttachNode, AColumn);
FSummaryItems := ASummaryItems;
FVisibleCount := 0;
for I := 0 to SummaryItems.Count - 1 do
if SummaryItems[I].Visible then
begin
Inc(FVisibleCount);
if FText <> '' then
FText := FText + Separator;
FText := FText + Node.FooterSummaryTexts[SummaryItems[I].AbsoluteIndex];
end;
end;
function TcxTreeListFooterMultiItemsCellViewInfo.IsNeedHint(ACanvas: TcxCanvas;
const P: TPoint; out AText: TCaption; out AIsMultiLine: Boolean;
out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean;
begin
if not CanDifferentStyles then
Result := inherited IsNeedHint(ACanvas, P, AText, AIsMultiLine, ATextRect,
IsNeedOffsetHint)
else
begin
ACanvas.Font := ViewParams.Font;
AIsMultiLine := MultiLine;
Result := FNeedShowHint and PtInRect(cxRectOffset(FHintRect, GetCellOrigin), P);
AText := FText;
ATextRect := FHintRect;
IsNeedOffsetHint := False;
end;
end;
function TcxTreeListFooterMultiItemsCellViewInfo.GetSeparator: string;
begin
Result := ListSeparator;
if Multiline then
Result := CRLF;
end;
{ TcxTreeListCustomHeaderCellViewInfo }
constructor TcxTreeListCustomHeaderCellViewInfo.CreateEx(
ATreeList: TcxCustomTreeList; const ABounds, AVisibleRect: TRect);
begin
inherited CreateEx(ATreeList, ABounds, AVisibleRect);
FBorders := cxBordersAll;
end;
function TcxTreeListCustomHeaderCellViewInfo.CanNeighborFor(
ACandidate: TcxTreeListHeaderCellViewInfo): Boolean;
begin
Result := not cxRectIsEmpty(ACandidate.DisplayRect) and
not cxRectIsEmpty(DisplayRect);
end;
procedure TcxTreeListCustomHeaderCellViewInfo.CheckClipping(
const ADisplayRect, AAvailableRect: TRect);
begin
inherited CheckClipping(ADisplayRect, AAvailableRect);
ClipRect := cxRectInflate(ClipRect, BordersMargins);
end;
function TcxTreeListCustomHeaderCellViewInfo.CheckNeighbors(
ACandidate: TcxTreeListHeaderCellViewInfo; AShift: Integer): Boolean;
begin
Result := False;
if AShift = 0 then Exit;
if BoundsRect.Right = ACandidate.BoundsRect.Left then
begin
Include(FNeighbors, nRight);
Include(ACandidate.FNeighbors, nLeft);
ACandidate.BordersMargins.Left := AShift;
Result := True;
end;
if CanNeighborFor(ACandidate) and (BoundsRect.Bottom = ACandidate.BoundsRect.Top) then
begin
Include(FNeighbors, nBottom);
Include(ACandidate.FNeighbors, nTop);
ACandidate.BordersMargins.Top := AShift;
Result := True;
end;
end;
procedure TcxTreeListCustomHeaderCellViewInfo.Click;
begin
end;
procedure TcxTreeListCustomHeaderCellViewInfo.DoCalculate;
begin
FTextBounds := cxTextRect(cxExcludeBorders(BoundsRect, Borders));
inherited DoCalculate;
end;
procedure TcxTreeListCustomHeaderCellViewInfo.DoDraw(ACanvas: TcxCanvas);
var
R: TRect;
begin
R := cxRectInflate(BoundsRect, BordersMargins);
if ExtPaintStyle then
Painter.DrawHeaderEx(ACanvas, R, TextBounds, Neighbors, Borders,
State, GetAlignHorz, GetAlignVert, GetMultiline, GetShowEndEllipsis, GetText, ViewParams.Font,
ViewParams.TextColor, ViewParams.Color, DrawBackgroundHandler)
else
Painter.DrawHeader(ACanvas, R, TextBounds, Neighbors, Borders,
State, GetAlignHorz, GetAlignVert, GetMultiline, GetShowEndEllipsis, GetText, ViewParams.Font,
ViewParams.TextColor, ViewParams.Color, DrawBackgroundHandler, IsLast)
end;
function TcxTreeListCustomHeaderCellViewInfo.GetAlignHorz: TAlignment;
begin
Result := taLeftJustify;
end;
function TcxTreeListCustomHeaderCellViewInfo.GetAlignVert: TcxAlignmentVert;
begin
Result := vaTop;
end;
function TcxTreeListCustomHeaderCellViewInfo.GetIsVisible: Boolean;
begin
Result := True;
end;
function TcxTreeListCustomHeaderCellViewInfo.GetMultiline: Boolean;
begin
Result := False;
end;
function TcxTreeListCustomHeaderCellViewInfo.GetShowEndEllipsis: Boolean;
begin
Result := False;
end;
function TcxTreeListCustomHeaderCellViewInfo.GetText: string;
begin
Result := '';
end;
function TcxTreeListCustomHeaderCellViewInfo.GetOrigin: TPoint;
begin
Result := DisplayRect.TopLeft;
end;
function TcxTreeListCustomHeaderCellViewInfo.IsNeedHint(ACanvas: TcxCanvas;
const P: TPoint; out AText: TCaption; out AIsMultiLine: Boolean;
out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean;
var
R: TRect;
AFlags: Integer;
begin
AText := GetText;
try
AFlags := cxAlignTop or cxAlignLeft or cxDontPrint;
if AIsMultiLine then
AFlags := AFlags or cxWordBreak;
ACanvas.Font := ViewParams.Font;
R := TextBounds;
ACanvas.TextExtent(GetText, R, AFlags);
AIsMultiLine := MultiLine;
Result := PtInRect(TextBounds, P) and
((cxRectWidth(R) > cxRectWidth(TextBounds)) or (cxRectHeight(R) > cxRectHeight(TextBounds)));
finally
AText := GetText;
ATextRect := R;
IsNeedOffsetHint := False;
end;
end;
procedure TcxTreeListCustomHeaderCellViewInfo.UpdateHotTrackState(
const APoint: TPoint);
begin
if Pressed then Exit;
if (TreeList.Controller.DragItem = nil) and PtInRect(GetClipRect, APoint) then
State := cxbsHot
else
State := cxbsNormal;
end;
function TcxTreeListCustomHeaderCellViewInfo.GetHotTrack: Boolean;
begin
Result := State = cxbsHot;
end;
function TcxTreeListCustomHeaderCellViewInfo.GetPressed: Boolean;
begin
Result := State = cxbsPressed;
end;
procedure TcxTreeListCustomHeaderCellViewInfo.SetHotTrack(AValue: Boolean);
begin
if Pressed or not GetIsVisible then Exit;
if AValue then
State := cxbsHot
else
State := cxbsNormal;
end;
procedure TcxTreeListCustomHeaderCellViewInfo.SetPressed(AValue: Boolean);
begin
if (AValue = Pressed) or not GetIsVisible then Exit;
if AValue then
TreeList.Controller.PressedHeader := Self
else
TreeList.Controller.PressedHeader := nil;
end;
procedure TcxTreeListCustomHeaderCellViewInfo.SetState(AValue: TcxButtonState);
begin
if (State <> AValue) and GetIsVisible then
begin
FState := AValue;
Invalidate;
end;
end;
{ TcxTreeListIndicatorCellViewInfo }
destructor TcxTreeListIndicatorCellViewInfo.Destroy;
begin
if FSizingArea <> nil then
begin
TreeList.ViewInfo.HitTestCells.Remove(FSizingArea);
FSizingArea.Free;
end;
inherited Destroy;
end;
class function TcxTreeListIndicatorCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlIndicatorCell;
end;
function TcxTreeListIndicatorCellViewInfo.ActualIndicatorKind: TcxIndicatorKind;
begin
Result := ikNone;
if Node = nil then Exit;
if Node.Focused then
begin
if Node.Selected and (TreeList.SelectionCount > 1) then
Result := ikMultiArrow
else
Result := ikArrow;
if TreeList.IsNodeEdited(Node) then
Result := ikEdit
else
if TreeList.IsNodeInserting(Node) then
Result := ikInsert
end
else
if Node.Selected then Result := ikMultiDot;
end;
procedure TcxTreeListIndicatorCellViewInfo.DoCalculate;
begin
inherited DoCalculate;
FKind := ActualIndicatorKind;
case Position of
tlipBands:
ItemViewParams := TreeList.Styles.GetBandHeaderParams(nil);
tlipColumns:
ItemViewParams := TreeList.Styles.GetColumnHeaderParams(nil);
tlipContent, tlipFooter:
ItemViewParams := TreeList.Styles.GetIndicatorParams;
end;
end;
procedure TcxTreeListIndicatorCellViewInfo.DoDraw(ACanvas: TcxCanvas);
begin
if Position = tlipContent then
begin
if ExtPaintStyle then
Painter.DrawIndicatorItemEx(ACanvas, DisplayRect,
Kind, ViewParams.Color, DrawBackgroundHandler)
else
Painter.DrawIndicatorItem(ACanvas, DisplayRect, Kind,
ViewParams.Color, DrawBackgroundHandler);
ACanvas.ExcludeClipRect(ClipRect);
end
else
if Position = tlipFooter then
Painter.DrawFooterPanel(ACanvas, DisplayRect, ViewParams, Borders)
else
begin
inherited DoDraw(ACanvas);
if (Position in [tlipBands, tlipColumns]) and IsQuickCustomizationEnabled then
Painter.DrawIndicatorCustomizationMark(ACanvas, DisplayRect, ViewParams.TextColor);
end;
end;
function TcxTreeListIndicatorCellViewInfo.GetHitTest(
AHitTest: TcxCustomHitTestController): Boolean;
begin
Result := inherited GetHitTest(AHitTest);
if not Result then Exit;
SetHitTestCodes([tlhc_HitAtIndicator]);
case Position of
tlipBands:
if IsQuickCustomizationEnabled then
SetHitTestCodes([tlhc_HitAtBandCustomizing]);
tlipColumns:
if IsQuickCustomizationEnabled then
SetHitTestCodes([tlhc_HitAtColumnCustomizing]);
tlipFooter:
SetHitTestCodes([tlhc_HitAtFooter]);
end;
end;
function TcxTreeListIndicatorCellViewInfo.GetPopup: TcxTreeListCustomizationPopup;
begin
if Position = tlipBands then
Result := TreeList.Controller.BandsCustomizationPopup
else
Result := TreeList.Controller.ColumnsCustomizationPopup;
end;
procedure TcxTreeListIndicatorCellViewInfo.Initialize(ANode: TcxTreeListNode;
APosition: TcxTreeListIndicatorPosition);
begin
FNode := ANode;
FAttachNode := ANode;
FPosition := APosition;
FState := cxbsNormal;
FPosition := APosition;
end;
function TcxTreeListIndicatorCellViewInfo.IsQuickCustomizationEnabled: Boolean;
begin
with TreeList.OptionsCustomizing do
begin
if Position = tlipBands then
Result := BandsQuickCustomization and BandCustomizing
else
Result := ColumnsQuickCustomization and ColumnCustomizing;
end;
end;
procedure TcxTreeListIndicatorCellViewInfo.Scroll(const DX, DY: Integer);
begin
inherited Scroll(0, DY);
end;
procedure TcxTreeListIndicatorCellViewInfo.ShowPopup;
var
APopup: TcxTreeListCustomizationPopup;
begin
APopup := GetPopup;
Pressed := True;
APopup.Owner := Self;
APopup.Popup;
end;
// IcxTreeListPopupOwner
function TcxTreeListIndicatorCellViewInfo.ClosePopupWhenNilOwner: Boolean;
begin
Result := False;
end;
function TcxTreeListIndicatorCellViewInfo.GetOwnerBounds: TRect;
begin
Result := DisplayRect;
end;
procedure TcxTreeListIndicatorCellViewInfo.PopupClosed;
begin
Pressed := False;
end;
procedure TcxTreeListIndicatorCellViewInfo.SetKind(AValue: TcxIndicatorKind);
begin
if AValue <> FKind then
begin
FKind := AValue;
Invalidate;
end;
end;
{ TcxTreeListHeaderCellViewInfo }
procedure TcxTreeListHeaderCellViewInfo.DoCalculate;
begin
inherited DoCalculate;
FTextBounds := cxRectInflate(cxExcludeBorders(DisplayRect, Borders),
-cxHeaderTextOffset, -cxHeaderTextOffset);
if SortOrder <> soNone then
begin
FSortMarkBounds := FTextBounds;
FSortMarkBounds.Left := FSortMarkBounds.Right - Painter.SortingMarkAreaSize.X;
FTextBounds.Right := FSortMarkBounds.Left;
end;
DoCalculateGlyphPosition;
end;
procedure TcxTreeListHeaderCellViewInfo.DoCalculateGlyphPosition;
var
AWidth, AHeight: Integer;
begin
if Glyph.Empty then Exit;
AWidth := Glyph.Width;
AHeight := Glyph.Height;
case GlyphAlignHorz of
taLeftJustify:
begin
FGlyphPosition.X := FTextBounds.Left;
Inc(FTextBounds.Left, AWidth + cxHeaderTextOffset);
end;
taRightJustify:
begin
Dec(FTextBounds.Right, AWidth);
FGlyphPosition.X := FTextBounds.Right;
Dec(FTextBounds.Right, cxHeaderTextOffset);
end;
taCenter:
FGlyphPosition.X := (FTextBounds.Left + FTextBounds.Right - AWidth) div 2;
end;
case GlyphAlignVert of
vaTop:
FGlyphPosition.Y := FTextBounds.Top;
vaBottom:
FGlyphPosition.Y := FTextBounds.Bottom - AHeight;
vaCenter:
FGlyphPosition.Y := (FTextBounds.Bottom + FTextBounds.Top - AHeight) div 2;
end;
GlyphClipping := not cxInRange(FGlyphPosition.X, ClipRect.Left, ClipRect.Right - AWidth) or
not cxInRange(FGlyphPosition.Y, ClipRect.Top, ClipRect.Bottom - AHeight);
end;
procedure TcxTreeListHeaderCellViewInfo.DoDraw(ACanvas: TcxCanvas);
var
AClipRgn: TcxRegion;
begin
inherited DoDraw(ACanvas);
if not Glyph.Empty then
begin
AClipRgn := ACanvas.GetClipRegion;
if GlyphClipping then
ACanvas.IntersectClipRect(ClipRect);
ACanvas.DrawGlyph(FGlyphPosition.X, FGlyphPosition.Y, Glyph);
ACanvas.SetClipRegion(AClipRgn, roSet);
end;
if SortOrder <> soNone then
Painter.DrawSortingMark(ACanvas, FSortMarkBounds, SortOrder = soAscending);
if State = cxbsPressed then
Painter.DrawHeaderPressed(ACanvas, DisplayRect);
if Selected then
begin
ACanvas.DrawFocusRect(cxRectInflate(
cxRectInflate(DisplayRect, BordersMargins), -1, -1));
ACanvas.DrawFocusRect(cxRectInflate(
cxRectInflate(DisplayRect, BordersMargins), -2, -2));
end;
end;
function TcxTreeListHeaderCellViewInfo.GetDragSizing: IcxDragSizing;
begin
Supports(Item, IcxDragSizing, Result);
end;
function TcxTreeListHeaderCellViewInfo.GetFixed: Boolean;
begin
Result := False;
end;
function TcxTreeListHeaderCellViewInfo.GetHitTest(
AHitTest: TcxCustomHitTestController): Boolean;
begin
Result := inherited GetHitTest(AHitTest);
if Result then
SetHitItem;
end;
function TcxTreeListHeaderCellViewInfo.GetMultiline: Boolean;
begin
Result := FCaption.MultiLine;
end;
function TcxTreeListHeaderCellViewInfo.GetSelected: Boolean;
begin
Result := TreeList.Controller.IsObjectSelected(Item);
end;
function TcxTreeListHeaderCellViewInfo.GetShowEndEllipsis: Boolean;
begin
Result := FCaption.ShowEndEllipsis;
end;
function TcxTreeListHeaderCellViewInfo.GetSortOrder: TcxDataSortOrder;
begin
Result := soNone;
end;
procedure TcxTreeListHeaderCellViewInfo.Initialize(ACaption: TcxTreeListCaption);
begin
FCaption := ACaption;
FItem := ACaption.Owner;
end;
procedure TcxTreeListHeaderCellViewInfo.Scroll(const DX, DY: Integer);
begin
if Fixed then Exit;
OffsetRect(FSortMarkBounds, DX, 0);
OffsetRect(FTextBounds, DX, 0);
FGlyphPosition := cxPointOffset(FGlyphPosition, DX, 0);
inherited Scroll(DX, 0);
end;
procedure TcxTreeListHeaderCellViewInfo.SetHitItem;
begin
HitTest.FDragItem := Self;
end;
function TcxTreeListHeaderCellViewInfo.GetAlignHorz: TAlignment;
begin
Result := FCaption.FAlignHorz;
end;
function TcxTreeListHeaderCellViewInfo.GetAlignVert: TcxAlignmentVert;
begin
Result := FCaption.FAlignVert;
end;
function TcxTreeListHeaderCellViewInfo.GetGlyph: TBitmap;
begin
Result := FCaption.Glyph;
end;
function TcxTreeListHeaderCellViewInfo.GetGlyphAlignHorz: TAlignment;
begin
Result := FCaption.GlyphAlignHorz;
end;
function TcxTreeListHeaderCellViewInfo.GetGlyphAlignVert: TcxAlignmentVert;
begin
Result := FCaption.GlyphAlignVert;
end;
function TcxTreeListHeaderCellViewInfo.GetText: string;
begin
Result := FCaption.Text;
end;
{ TcxTreeListBandHeaderCellViewInfo }
class function TcxTreeListBandHeaderCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlBandHeaderCell;
end;
procedure TcxTreeListBandHeaderCellViewInfo.Click;
begin
TreeList.DoBandHeaderClick(Band);
end;
procedure TcxTreeListBandHeaderCellViewInfo.DoCalculate;
begin
inherited DoCalculate;
ItemViewParams := TreeList.Styles.GetBandHeaderParams(Band);
end;
function TcxTreeListBandHeaderCellViewInfo.GetFixed: Boolean;
begin
Result := Band.FixedKind <> tlbfNone;
end;
function TcxTreeListBandHeaderCellViewInfo.GetIsVisible: Boolean;
begin
Result := Band.ActuallyVisible;
end;
procedure TcxTreeListBandHeaderCellViewInfo.SetHitItem;
begin
inherited SetHitItem;
HitTest.FHitBand := Band;
SetHitTestCodes([tlhc_HitAtBandHeader]);
end;
function TcxTreeListBandHeaderCellViewInfo.GetBand: TcxTreeListBand;
begin
Result := Item as TcxTreeListBand;
end;
{ TcxTreeListColumnHeaderCellViewInfo }
class function TcxTreeListColumnHeaderCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlColumnHeaderCell;
end;
procedure TcxTreeListColumnHeaderCellViewInfo.Click;
begin
TreeList.DoColumnHeaderClick(Column);
end;
procedure TcxTreeListColumnHeaderCellViewInfo.DoCalculate;
begin
inherited DoCalculate;
ItemViewParams := TreeList.Styles.GetColumnHeaderParams(Column);
end;
function TcxTreeListColumnHeaderCellViewInfo.GetFixed: Boolean;
begin
Result := Band.FixedKind <> tlbfNone;
end;
function TcxTreeListColumnHeaderCellViewInfo.GetIsVisible: Boolean;
begin
Result := Column.ActuallyVisible;
end;
function TcxTreeListColumnHeaderCellViewInfo.GetSortOrder: TcxDataSortOrder;
begin
Result := Column.GetRealSortOrder;
end;
procedure TcxTreeListColumnHeaderCellViewInfo.SetHitItem;
begin
inherited SetHitItem;
HitTest.FHitColumn := Column;
SetHitTestCodes([tlhc_HitAtColumnHeader]);
end;
function TcxTreeListColumnHeaderCellViewInfo.GetBand: TcxTreeListBand;
begin
Result := Column.Position.Band;
end;
function TcxTreeListColumnHeaderCellViewInfo.GetColumn: TcxTreeListColumn;
begin
Result := Item as TcxTreeListColumn;
end;
{ TcxTreeListBandCellViewInfo }
class function TcxTreeListBandCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlBandPartCell;
end;
procedure TcxTreeListBandCellViewInfo.DoCalculate;
var
ACanSelect: Boolean;
begin
inherited DoCalculate;
case Part of
tlbpHeader:
ItemViewParams := Styles.GetBandBackgroundParams(Band);
tlbpContent:
begin
ACanSelect := TreeList.OptionsSelection.CellSelect and TreeList.OptionsSelection.InvertSelect;
if (Node <> nil) and Node.Selected and (not Node.Focused or ACanSelect) then
ItemViewParams := Styles.GetSelectionParams
else
ItemViewParams := Styles.GetBandContentParams(Band, Node);
end;
tlbpFooter, tlbpGroupFooter:
ItemViewParams := Styles.GetBandFooterParams(Band, Node);
tlbpSeparator:
begin
ItemViewParams := Styles.GetBackgroundParams;
ItemViewParams.Color := ColorToRgb(cxGetNativeColor(OptionsView.FFixedSeparatorColor,
Painter.DefaultFixedSeparatorColor));
end;
end;
end;
procedure TcxTreeListBandCellViewInfo.DoDraw(ACanvas: TcxCanvas);
begin
if Part in [tlbpFooter, tlbpGroupFooter] then
Painter.DrawFooterPanel(ACanvas, DisplayRect, ViewParams, Borders)
else
inherited DoDraw(ACanvas);
if Part = tlbpSeparator then
ACanvas.ExcludeClipRect(ClipRect);
end;
function TcxTreeListBandCellViewInfo.GetHitTest(
AHitTest: TcxCustomHitTestController): Boolean;
begin
Result := inherited GetHitTest(AHitTest);
if not Result then Exit;
HitTest.FHitBand := Band;
HitTest.FHitNode := Node;
case Part of
tlbpHeader:
SetHitTestCodes([tlhc_HitAtBandContainer]);
tlbpContent:
SetHitTestCodes([tlhc_HitAtBand]);
tlbpFooter:
SetHitTestCodes([tlhc_HitAtFooter, tlhc_HitAtBand]);
tlbpGroupFooter:
SetHitTestCodes([tlhc_HitAtGroupFooter, tlhc_HitAtBand]);
tlbpSeparator:
SetHitTestCodes([tlhc_HitAtSeparator]);
end;
end;
procedure TcxTreeListBandCellViewInfo.Initialize(ABand: TcxTreeListBand;
ANode, AAttachNode: TcxTreeListNode; APart: TcxTreeListBandPart);
begin
FBand := ABand;
FAttachNode := AAttachNode;
FNode := ANode;
FPart := APart;
end;
procedure TcxTreeListBandCellViewInfo.Scroll(const DX, DY: Integer);
begin
if (Band = nil) or (Band.FixedKind <> tlbfNone) then Exit;
if Part <> tlbpContent then
inherited Scroll(DX, 0)
else
inherited Scroll(DX, DY);
end;
{ TcxTreeListEditCellViewInfo }
class function TcxTreeListEditCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlEditCell;
end;
function TcxTreeListEditCellViewInfo.ContentOffset: TRect;
begin
Result := cxSimpleRect;
end;
function TcxTreeListEditCellViewInfo.GetColumn: TcxTreeListColumn;
begin
Result := TcxTreeListColumn(EditContainer);
end;
procedure TcxTreeListEditCellViewInfo.DoCalculate;
begin
ItemViewParams := GetEditViewParams;
inherited DoCalculate;
end;
procedure TcxTreeListEditCellViewInfo.DoDraw(ACanvas: TcxCanvas);
var
P: TPoint;
begin
if CellTransparent then
ACanvas.FrameRect(DisplayRect, BorderColor, 1, Borders)
else
begin
SetWindowOrgEx(ACanvas.Handle, 0, 0, @P);
ACanvas.FillRect(cxRectOffset(DisplayRect, NodeViewData.Origin),
ViewParams, Borders, BorderColor);
SetWindowOrgEx(ACanvas.Handle, P.X, P.Y, nil);
end;
EditViewInfo.PaintEx(ACanvas);
if Focused and (Node.ViewData <> nil) and not Node.ViewData.DrawFocusRect then
ACanvas.DrawFocusRect(cxExcludeBorders(DisplayRect, Borders));
end;
function TcxTreeListEditCellViewInfo.GetButtonTransparency: TcxEditButtonTransparency;
var
B1: TcxEditingControlEditShowButtons;
B2: TcxEditItemShowEditButtons;
AFocused: Boolean;
begin
AFocused := Node = TreeList.FocusedNode;
B1 := TreeList.OptionsView.ShowEditButtons;
B2 := Column.Options.ShowEditButtons;
if (B2 = eisbAlways) or (B2 = eisbDefault) and
((B1 = ecsbAlways) or (B1 = ecsbFocused) and AFocused) then
Result := ebtNone
else
Result := ebtHideInactive;
end;
function TcxTreeListEditCellViewInfo.GetCellOrg: TPoint;
begin
Result := NodeViewData.Origin
end;
function TcxTreeListEditCellViewInfo.GetDisplayValue: Variant;
begin
Result := Column.DoOnGetDisplayText(Node, False, True);
end;
function TcxTreeListEditCellViewInfo.GetEditRect: TRect;
begin
Result := CellEditRect;
if (Node <> nil) and (Node.ViewData <> nil) then
Result := cxRectOffset(Result, Node.ViewData.Origin);
end;
function TcxTreeListEditCellViewInfo.GetEditViewParams: TcxViewParams;
var
AParams: TcxViewParams;
begin
Result := TreeList.Styles.GetContentParams(Node, Column);
if Selected then
begin
AParams := TreeList.Styles.GetSelectionParams;
Result.Color := AParams.Color;
Result.TextColor := AParams.TextColor;
end;
end;
function TcxTreeListEditCellViewInfo.GetFocused: Boolean;
begin
Result := Node.Focused and Column.Focused;
end;
function TcxTreeListEditCellViewInfo.GetHitTest(
AHitTest: TcxCustomHitTestController): Boolean;
begin
Result := PtInRect(cxRectOffset(ClipRect, NodeViewData.Origin), AHitTest.HitPoint);
if not Result then Exit;
TcxTreeListHitTest(AHitTest).FHitNode := Node;
TcxTreeListHitTest(AHitTest).FHitColumn := Column;
TcxTreeListHitTest(AHitTest).SetHitState(tlhc_HitAtNode, True);
case CustomDrawID of
cxtlPreviewCell:
TcxTreeListHitTest(AHitTest).SetHitState(tlhc_HitAtNodePreview, True);
else
TcxTreeListHitTest(AHitTest).SetHitState(tlhc_HitAtColumn, True);
end;
TcxTreeListHitTest(AHitTest).HitTestItem := Self;
end;
function TcxTreeListEditCellViewInfo.GetHotTrack: Boolean;
begin
Result := Node.HotTrack;
end;
function TcxTreeListEditCellViewInfo.GetIncSearchParams: TcxViewParams;
begin
Result := TreeList.Styles.GetIncSearchParams;
if Result.Color = clDefault then
Result.Color := inherited GetSelectedBKColor;
if Result.TextColor = clDefault then
Result.TextColor := inherited GetSelectedTextColor;
end;
function TcxTreeListEditCellViewInfo.GetOrigin: TPoint;
begin
Result := cxPointOffset(inherited GetOrigin, Node.ViewData.Origin);
end;
function TcxTreeListEditCellViewInfo.IsNeedHint(ACanvas: TcxCanvas;
const P: TPoint; out AText: TCaption; out AIsMultiLine: Boolean;
out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean;
begin
Result := inherited IsNeedHint(ACanvas, cxPointOffset(P, cxPointInvert(Node.ViewData.Origin)),
AText, AIsMultiLine, ATextRect, IsNeedOffsetHint);
end;
function TcxTreeListEditCellViewInfo.GetRecordIndex: Integer;
begin
Result := Integer(Node);
end;
function TcxTreeListEditCellViewInfo.GetSelected: Boolean;
begin
Result := Node.Selected and not (Node.Focused and Column.Editing);
if not Node.Focused or not Result then Exit;
if TreeList.OptionsSelection.CellSelect then
begin
if TreeList.OptionsSelection.InvertSelect then
Result := not Focused;
end
end;
function TcxTreeListEditCellViewInfo.GetSelectedTextColor: Integer;
begin
Result := GetIncSearchParams.TextColor;
end;
function TcxTreeListEditCellViewInfo.GetSelectedBKColor: Integer;
begin
Result := GetIncSearchParams.Color
end;
function TcxTreeListEditCellViewInfo.GetViewInfoData: Pointer;
begin
Result := Node;
end;
function TcxTreeListEditCellViewInfo.IsAutoHeight: Boolean;
begin
Result := TreeList.OptionsView.CellAutoHeight;
end;
function TcxTreeListEditCellViewInfo.IsEditHotTrack(
const APoint: TPoint): Boolean;
begin
Result := ViewInfo.IsHotTrack(cxPointOffset(APoint,
cxPointInvert(GetCellOrg)));
end;
function TcxTreeListEditCellViewInfo.IsEndEllipsis: Boolean;
begin
Result := inherited IsEndEllipsis and Column.Options.CellEndEllipsis;
end;
function TcxTreeListEditCellViewInfo.IsFixed: Boolean;
begin
Result := (Band <> nil) and (Band.FixedKind <> tlbfNone);
end;
function TcxTreeListEditCellViewInfo.IsTransparent: Boolean;
begin
Result := True;
end;
procedure TcxTreeListEditCellViewInfo.Scroll(const DX, DY: Integer);
var
AVisible: Boolean;
begin
if IsFixed or (DX = 0) then Exit;
AVisible := Visible;
CheckClipping(cxRectOffset(DisplayRect, DX, 0), VisibleBounds);
ViewInfo.Left := ViewInfo.Left + DX;
if AVisible <> Visible then
VisibleInfoCalculated := False;
end;
function TcxTreeListEditCellViewInfo.GetBand: TcxTreeListBand;
begin
Result := Column.Position.Band;
end;
function TcxTreeListEditCellViewInfo.GetEditing: Boolean;
begin
Result := Column.Editing;
end;
function TcxTreeListEditCellViewInfo.GetNode: TcxTreeListNode;
begin
if NodeViewData = nil then
Result := nil
else
Result := NodeViewData.Node;
end;
function TcxTreeListEditCellViewInfo.GetOptionsView: TcxTreeListOptionsView;
begin
Result := TreeList.OptionsView;
end;
function TcxTreeListEditCellViewInfo.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(Control);
end;
{ TcxTreeListIndentCellViewInfo }
class function TcxTreeListIndentCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlIndentCell;
end;
procedure TcxTreeListIndentCellViewInfo.DoCalculate;
var
DY: Integer;
C: TPoint;
begin
inherited DoCalculate;
InitializeImageIndent(Images);
ItemViewParams := Styles.GetIndentParams(Node, Index);
FButton := TreeList.OptionsView.Buttons and (Images = nil) and (Kind = nikLevel) and
(Index = Node.Level) and Node.HasVisibleChildren;
if (Images = nil) and (OptionsView.TreeLineStyle <> tllsNone) then
begin
C := cxRectCenter(DisplayRect);
DY := 0;
if (Node.ViewData.PreviewHeight > 0) and (TreeList.Preview.Place = tlppTop) then
DY := 1;
if ilHorz in Lines then
FHorzTreeLine := cxRect(C.X, C.Y - 1 + DY, DisplayRect.Right, C.Y + DY);
if [ilVertUp, ilVertDown] * Lines <> [] then
begin
FVertTreeLine := cxRect(C.X, DisplayRect.Top, C.X + 1, DisplayRect.Bottom);
if not (ilVertUp in Lines) then
FVertTreeLine.Top := C.Y - 1;
if not (ilVertDown in Lines) then
FVertTreeLine.Bottom := C.Y - 1;
end;
end;
FGlyphRect := cxInvalidRect;
if Button then
begin
FGlyphRect := cxRectCenter(DisplayRect,
Painter.SmallExpandButtonSize, Painter.SmallExpandButtonSize);
end
else
if Images <> nil then
FGlyphRect := cxRectCenter(DisplayRect, Images.Width, Images.Height)
else
if Kind = nikCheck then
begin
if Node.Parent.CheckGroupType = ncgRadioGroup then
FGlyphRect := cxRectCenter(DisplayRect, Painter.RadioButtonSize)
else
FGlyphRect := DisplayRect;
end;
end;
procedure TcxTreeListIndentCellViewInfo.DoDraw(ACanvas: TcxCanvas);
begin
inherited DoDraw(ACanvas);
if Kind = nikCheck then
DrawCheck(ACanvas)
else
if Images <> nil then
DrawImage(ACanvas)
else
DrawLines(ACanvas);
end;
procedure TcxTreeListIndentCellViewInfo.DrawCheck(ACanvas: TcxCanvas);
const
AState: array[Boolean, Boolean] of TcxButtonState =
((cxbsDisabled, cxbsDisabled), (cxbsNormal, cxbsHot));
begin
if Node.Parent.CheckGroupType = ncgRadioGroup then
Painter.DrawRadioButton(ACanvas, GlyphRect.Left, GlyphRect.Top,
AState[Node.Enabled, HotTrack], CheckState = cbsChecked, False, clDefault)
else
GetCheckBoxViewInfo(ACanvas).Paint(ACanvas)
end;
procedure TcxTreeListIndentCellViewInfo.DrawImage(ACanvas: TcxCanvas);
begin
Images.Draw(ACanvas.Canvas, GlyphRect.Left, GlyphRect.Top, ImageIndex,
dsTransparent, Images.ImageType, True);
Images.Draw(ACanvas.Canvas, GlyphRect.Left, GlyphRect.Top, OverlayIndex,
dsTransparent, Images.ImageType, True);
end;
procedure TcxTreeListIndentCellViewInfo.DrawLines(ACanvas: TcxCanvas);
begin
if [ilVertUp, ilVertDown] * Lines <> [] then
DrawTreeLine(ACanvas, VertTreeLine);
if ilHorz in Lines then
DrawTreeLine(ACanvas, HorzTreeLine);
if Button then
Painter.DrawSmallExpandButton(ACanvas, GlyphRect, IsExpanded,
TreeList.ViewInfo.TreeLineColor, ViewParams.Color);
end;
procedure TcxTreeListIndentCellViewInfo.DrawTreeLine(
ACanvas: TcxCanvas; const ARect: TRect);
begin
if OptionsView.TreeLineStyle = tllsDot then
cxFillHalfToneRect(ACanvas.Canvas, ARect, ViewParams.Color, TreeList.ViewInfo.TreeLineColor)
else
ACanvas.FillRect(ARect, TreeList.ViewInfo.TreeLineColor);
end;
function TcxTreeListIndentCellViewInfo.GetCheckBoxViewInfo(
ACanvas: TcxCanvas): TcxCustomEditViewInfo;
var
P: TPoint;
AViewData: TcxCustomEditViewData;
begin
Result := TreeList.ViewInfo.CheckBoxViewInfo;
AViewData := TreeList.ViewInfo.CheckBoxViewData;
AViewData.EditValueToDrawValue(ACanvas, Integer(Node.CheckState), Result);
P := cxInvalidPoint;
AViewData.Enabled := Node.Enabled;
if HotTrack then
P := cxRectCenter(DisplayRect);
AViewData.Calculate(ACanvas, DisplayRect, P, cxmbNone, [], Result, False);
Result.Transparent := True;
end;
function TcxTreeListIndentCellViewInfo.GetHitTest(
AHitTest: TcxCustomHitTestController): Boolean;
var
R: TRect;
const
AImages: array[Boolean] of Integer =
(tlhc_HitAtImage, tlhc_HitAtStateImage);
begin
Result := inherited GetHitTest(AHitTest);
if not Result then Exit;
HitTest.FHitNode := Node;
SetHitTestCodes([tlhc_HitAtIndent]);
if Images <> nil then
SetHitTestCodes([AImages[Kind = nikState]])
else
begin
R := cxRectOffset(GlyphRect, GetCellOrigin);
InflateRect(R, cxTextOffset, cxTextOffset);
if Kind = nikCheck then
SetHitTestCodes([tlhc_HitAtCheckButton])
else
if Button and PtInRect(R, AHitTest.HitPoint) then
SetHitTestCodes([tlhc_HitAtButton])
end;
end;
procedure TcxTreeListIndentCellViewInfo.InitializeLevelIndent(
ANode, AAttachNode: TcxTreeListNode; AIndex: Integer);
begin
FIndex := AIndex;
FNode := ANode;
FAttachNode := AAttachNode;
FLines := [];
FLevelNode := ANode;
while FLevelNode.Level <> AIndex do
FLevelNode := FLevelNode.Parent;
if OptionsView.TreeLineStyle <> tllsNone then
begin
if Kind = nikFooter then
begin
if LevelNode.GetNextSiblingVisible <> nil then
FLines := [ilVertUp, ilVertDown]
end
else
begin
if (LevelNode <> Node) or (Node.VisibleIndex <> 0) then
Include(FLines, ilVertUp);
if LevelNode.GetNextSiblingVisible <> nil then
Include(FLines, ilVertDown)
else
if LevelNode <> Node then
Exclude(FLines, ilVertUp);
if (LevelNode = Node) then
Include(FLines, ilHorz);
end;
end;
end;
procedure TcxTreeListIndentCellViewInfo.InitializeImageIndent(
AImages: TCustomImageList);
begin
FImages := AImages;
FImageIndex := -1;
FOverlayIndex := -1;
if (Images = nil) or not (Kind in [nikImage, nikState]) then Exit;
if Kind = nikImage then
begin
FImageIndex := TreeList.DoGetNodeImageIndex(Node, TcxTreeListImageIndexType(Node.Selected));
if FImageIndex <> - 1 then
FOverlayIndex := TreeList.DoGetNodeImageIndex(Node, tlitOverlayIndex);
end
else
begin
FImageIndex := TreeList.DoGetNodeImageIndex(Node, tlitStateIndex);
if FImageIndex <> - 1 then
FOverlayIndex := TreeList.DoGetNodeImageIndex(Node, tlitOverlayStateIndex);
end;
end;
procedure TcxTreeListIndentCellViewInfo.Scroll(const DX, DY: Integer);
begin
if Fixed then Exit;
inherited Scroll(DX, 0);
end;
procedure TcxTreeListIndentCellViewInfo.SetSize(ATop, AHeight: Integer);
begin
CheckClipping(cxRectSetTop(BoundsRect, ATop, AHeight),
cxRectSetTop(VisibleBounds, ATop, AHeight));
end;
// IcxHotTrackElement
function TcxTreeListIndentCellViewInfo.GetOrigin: TPoint;
begin
Result := cxPointOffset(DisplayRect.TopLeft, GetCellOrigin);
end;
function TcxTreeListIndentCellViewInfo.IsNeedHint(
ACanvas: TcxCanvas; const P: TPoint; out AText: TCaption;
out AIsMultiLine: Boolean; out ATextRect: TRect;
var IsNeedOffsetHint: Boolean): Boolean;
begin
Result := False;
end;
procedure TcxTreeListIndentCellViewInfo.UpdateHotTrackState(const APoint: TPoint);
begin
FHotTrack := PtInRect(cxRectOffset(DisplayRect, GetCellOrigin), APoint);
TreeList.InvalidateRectEx(cxRectOffset(DisplayRect, GetCellOrigin), False);
end;
function TcxTreeListIndentCellViewInfo.GetCheckState: TcxCheckBoxState;
begin
Result := Node.CheckState;
end;
function TcxTreeListIndentCellViewInfo.GetFixed: Boolean;
begin
Result := (TreeList.Bands.ExpandableBand = nil) or
(TreeList.Bands.ExpandableBand.FixedKind <> tlbfNone);
end;
function TcxTreeListIndentCellViewInfo.GetHasImage: Boolean;
begin
Result := (Images <> nil) and ((ImageIndex >= 0) or (OverlayIndex >= 0));
end;
function TcxTreeListIndentCellViewInfo.GetIsExpanded: Boolean;
begin
Result := Button and Node.Expanded;
end;
{ TcxTreeListGroupNodeEditViewInfo }
function TcxTreeListGroupNodeEditViewInfo.GetColumn: TcxTreeListColumn;
begin
Result := TreeList.OptionsView.GetCategorizedColumn;
end;
function TcxTreeListGroupNodeEditViewInfo.GetFocused: Boolean;
begin
Result := Node.Focused;
end;
function TcxTreeListGroupNodeEditViewInfo.IsFixed: Boolean;
begin
Result := TreeList.Bands.VisibleLeftFixedCount > 0;
end;
procedure TcxTreeListGroupNodeEditViewInfo.Scroll(const DX, DY: Integer);
var
R: TRect;
begin
if IsFixed or (DX = 0) then Exit;
R := DisplayRect;
Inc(R.Left, DX);
CheckClipping(R, VisibleBounds);
ViewInfo.Left := ViewInfo.Left + DX;
VisibleInfoCalculated := False;
end;
{ TcxTreeListPreviewCellViewInfo }
constructor TcxTreeListPreviewCellViewInfo.Create(AOwner: TObject);
begin
inherited Create(AOwner);
FPreview := TreeList.Preview;
end;
class function TcxTreeListPreviewCellViewInfo.CustomDrawID: Integer;
begin
Result := cxtlPreviewCell;
end;
function TcxTreeListPreviewCellViewInfo.ContentOffset: TRect;
begin
Result := inherited ContentOffset;
Result.Left := Preview.LeftIndent;
Result.Right := Preview.RightIndent;
end;
procedure TcxTreeListPreviewCellViewInfo.DoCalculate;
begin
Include(ViewData.PaintOptions, epoAllowZeroHeight);
inherited DoCalculate;
end;
function TcxTreeListPreviewCellViewInfo.GetColumn: TcxTreeListColumn;
begin
Result := Preview.Column;
end;
function TcxTreeListPreviewCellViewInfo.GetButtonTransparency: TcxEditButtonTransparency;
begin
Result := ebtHideInactive;
end;
function TcxTreeListPreviewCellViewInfo.GetEditViewParams: TcxViewParams;
begin
Result := TreeList.Styles.GetPreviewParams(Node);
end;
function TcxTreeListPreviewCellViewInfo.GetHotTrack: Boolean;
begin
Result := False;
end;
function TcxTreeListPreviewCellViewInfo.GetMaxLineCount: Integer;
begin
Result := Preview.MaxLineCount;
end;
function TcxTreeListPreviewCellViewInfo.IsAutoHeight: Boolean;
begin
Result := True;
end;
function TcxTreeListPreviewCellViewInfo.IsEditHotTrack(
const APoint: TPoint): Boolean;
begin
Result := False;
end;
procedure TcxTreeListPreviewCellViewInfo.Scroll(const DX, DY: Integer);
begin
if TreeList.Bands.VisibleLeftFixedCount = 0 then
inherited Scroll(DX, 0);
end;
{ TcxTreeListLevelInfo }
constructor TcxTreeListLevelInfo.Create(ATreeList: TcxCustomTreeList);
begin
FTreeList := ATreeList;
FImagesChangeLink := TChangeLink.Create;
FImagesChangeLink.OnChange := Changed;
FStateImagesChangeLink := TChangeLink.Create;
FStateImagesChangeLink.OnChange := Changed;
end;
destructor TcxTreeListLevelInfo.Destroy;
begin
Images := nil;
StateImages := nil;
FImagesChangeLink.Free;
FStateImagesChangeLink.Free;
inherited Destroy;
end;
procedure TcxTreeListLevelInfo.Changed(Sender: TObject);
begin
Update(0);
TreeList.ImagesChanged(Sender);
end;
procedure TcxTreeListLevelInfo.Notification(
AComponent: TComponent; Operation: TOperation);
begin
if Operation <> opRemove then Exit;
if AComponent = Images then
Images := nil;
if AComponent = StateImages then
StateImages := nil;
end;
function TcxTreeListLevelInfo.Update(const AOffset: Integer): Integer;
begin
FOffset := AOffset;
FSize := TreeList.DefaultIndentSize;
FWidth := FSize.cx;
if Images <> nil then
begin
FSize.cy := Max(FSize.cy, Images.Height + cxTreeListIndentOffsetSize div 2);
Inc(FWidth, Images.Width + cxTreeListIndentOffsetSize div 2);
if not DynamicIndent then
FSize.cx := Max(Images.Width + cxTreeListIndentOffsetSize div 2, FSize.cx);
end;
if StateImages <> nil then
begin
FSize.cy := Max(FSize.cy, StateImages.Height + cxTreeListIndentOffsetSize div 2);
Inc(FWidth, StateImages.Width + cxTreeListIndentOffsetSize div 2);
end;
Result := FOffset + FSize.cx;
end;
function TcxTreeListLevelInfo.GetTotalWidth: Integer;
begin
Result := FOffset + Width;
end;
function TcxTreeListLevelInfo.GetDynamicIndent: Boolean;
begin
Result := TreeList.OptionsView.DynamicIndent;
end;
procedure TcxTreeListLevelInfo.SetImages(AValue: TCustomImageList);
begin
if AValue <> FImages then
cxSetImageList(AValue, FImages, FImagesChangeLink, TreeList);
end;
procedure TcxTreeListLevelInfo.SetStateImages(AValue: TCustomImageList);
begin
if AValue <> StateImages then
cxSetImageList(AValue, FStateImages, FStateImagesChangeLink, TreeList);
end;
{ TcxTreeListLikeParams }
constructor TcxTreeListLikeParams.Create(APercent: Char = '%';
AUnderline: Char = '_');
begin
FPercent := APercent;
FUnderline := AUnderline;
end;
{ TcxTreeListNodeViewData }
constructor TcxTreeListNodeViewData.Create(
AViewInfo: TcxTreeListViewInfo; ANode: TcxTreeListNode; ACapacity: Integer);
begin
ViewInfo := AViewInfo;
Node := ANode;
Focused := (ANode <> nil) and ANode.Focused;
Selected := (ANode <> nil) and ANode.Selected;
if ANode <> nil then
Node.FViewData := Self;
Cells := TcxCustomControlCells.Create;
Cells.Capacity := ACapacity;
end;
destructor TcxTreeListNodeViewData.Destroy;
begin
if not ViewInfo.TreeList.IsDestroying then
ViewInfo.CellsChanged;
FreeAndNil(Cells);
if Node <> nil then
Node.FViewData := nil;
inherited Destroy;
end;
function TcxTreeListNodeViewData.GetRealBounds: TRect;
begin
Result := cxRectOffset(Bounds, Origin);
end;
function TcxTreeListNodeViewData.GetRealContentBounds: TRect;
begin
Result := cxRectOffset(ContentBounds, Origin)
end;
procedure TcxTreeListNodeViewData.Paint(
ACanvas: TcxCanvas; AHandler: TcxCustomDrawCellEvent);
var
I: Integer;
AWindowOrg: TPoint;
AClipRgn, AFooterRgn: TcxRegion;
begin
if not ACanvas.RectVisible(cxRectInflate(GetRealBounds, 1, 1)) then Exit;
AClipRgn := ACanvas.GetClipRegion();
try
AWindowOrg := ACanvas.WindowOrg;
ACanvas.WindowOrg := cxPointInvert(Origin);
Cells.Paint(ACanvas, AHandler);
if DrawFocusRect and Node.Focused then
begin
for I := 0 to Cells.Count - 1 do
if Cells[I].Visible and (Cells[I].CustomDrawID = cxtlIndentCell) then
ACanvas.ExcludeClipRect(Cells[I].VisibleRect);
ACanvas.DrawFocusRect(FocusRectBounds);
end;
if CheckFooterRgn then
begin
for I := 0 to Cells.Count - 1 do
if Cells[I].Visible and (Cells[I].CustomDrawID = cxtlBandPartCell) and
(TcxTreeListBandCellViewInfo(Cells[I]).Part in [tlbpGroupFooter, tlbpFooter]) then
begin
AFooterRgn := TcxRegion.Create(cxRectOffset(TcxTreeListBandCellViewInfo(Cells[I]).ClipRect, Origin));
AClipRgn.Combine(AFooterRgn, roSubtract);
end;
end;
ACanvas.WindowOrg := AWindowOrg;
finally
ACanvas.SetClipRegion(AClipRgn, roSet);
end;
end;
procedure TcxTreeListNodeViewData.Scroll(DX, DY: Integer;
ALeftFixed, ARightFixed: Boolean);
var
I: Integer;
begin
for I := 0 to Cells.Count - 1 do
TcxTreeListCustomCellViewInfo(Cells[I]).Scroll(DX, 0);
Origin := cxPointOffset(Origin, 0, DY);
if not ARightFixed then
begin
Inc(ContentBounds.Right, DX);
Inc(FocusRectBounds.Right, DX);
end;
if not ALeftFixed then
begin
Inc(ContentBounds.Left, DX);
Inc(FocusRectBounds.Left, DX);
end;
end;
function TcxTreeListNodeViewData.Update(AForceUpdate: Boolean): Boolean;
var
I: Integer;
R: TRect;
begin
Result := (Selected <> Node.Selected) or Focused or Node.Focused or AForceUpdate;
Selected := Node.Selected;
Focused := Node.Focused;
if not Result then Exit;
for I := 0 to Cells.Count - 1 do
Cells[I].VisibleInfoCalculated := False;
R := GetRealBounds;
R.Left := 0;
Node.TreeList.InvalidateRectEx(cxRectInflate(R, 1, 1), False);
end;
{ TcxTreeListCustomPopupMenu }
function TcxTreeListCustomPopupMenu.Popup(X, Y: Integer): Boolean;
begin
Result := ShowPopupMenu(TreeList, FPopupMenu, X, Y);
end;
procedure TcxTreeListCustomPopupMenu.SetPopupMenu(AValue: TComponent);
begin
FPopupMenu := AValue;
end;
{ TcxTreeListCustomBuiltInMenu }
destructor TcxTreeListCustomBuiltInMenu.Destroy;
begin
DestroyPopupMenu;
inherited Destroy;
end;
procedure TcxTreeListCustomBuiltInMenu.CreatePopupMenu;
begin
FPopupMenu := GetPopupClass.Create(TreeList);
end;
procedure TcxTreeListCustomBuiltInMenu.DestroyPopupMenu;
begin
FreeAndNil(FPopupMenu);
end;
procedure TcxTreeListCustomBuiltInMenu.GetBitmapFromImageList(AImages: TCustomImageList; AImageIndex: Integer; ABitmap: TBitmap);
begin
if (AImages <> nil) and cxInRange(AImageIndex, 0, AImages.Count - 1) then
begin
ABitmap.PixelFormat := pf32bit;
TcxImageList.GetImageInfo(AImages.Handle, AImageIndex, ABitmap, nil);
end;
end;
function TcxTreeListCustomBuiltInMenu.GetImages(AInternal: Boolean): TCustomImageList;
begin
if AInternal then
Result := TcxTreeListPopupMenu(Owner).Images
else
Result := TcxTreeListPopupMenu(Owner).UserImages;
end;
function TcxTreeListCustomBuiltInMenu.GetRoot: TComponent;
begin
Result := FPopupMenu;
end;
function TcxTreeListCustomBuiltInMenu.GetTreeList: TcxCustomTreeList;
begin
Result := TcxTreeListPopupMenu(Owner).TreeList;
end;
procedure TcxTreeListCustomBuiltInMenu.Initialize;
begin
DestroyPopupMenu;
CreatePopupMenu;
end;
procedure TcxTreeListCustomBuiltInMenu.MenuItemClickHandler(Sender: TObject);
begin
TcxTreeListPopupMenu(Owner).DoMenuItemClick(Sender);
end;
{ TcxTreeListBuiltInMenuItem }
type
TcxTreeListBuiltInMenuItem = class(TMenuItem)
private
FInternal: Boolean;
FBuiltInMenu: TcxTreeListBuiltInMenu;
procedure CalculateRects(ACanvas: TCanvas; const ARect: TRect;
AState: TOwnerDrawState; out AImageAreaRect, ATextRect: TRect);
procedure DrawCheck(ACanvas: TCanvas; const AImageAreaRect: TRect);
procedure DoDrawImage(ACanvas: TCanvas; const AImageAreaRect: TRect;
ABitmap: TBitmap; AImages: TCustomImageList; AImageIndex: Integer;
ADrawMode: TcxImageDrawMode);
procedure DrawBackground(ACanvas: TCanvas; const ARect: TRect;
AState: TOwnerDrawState);
procedure DrawImage(ACanvas: TCanvas; const ARect: TRect;
AState: TOwnerDrawState; const AImageAreaRect: TRect);
procedure DrawImageCheckedBackground(ACanvas: TCanvas; const AImageAreaRect: TRect);
procedure DrawText(ACanvas: TCanvas; const ARect: TRect;
AState: TOwnerDrawState; ATextRect: TRect);
protected
procedure AdvancedDrawItem(ACanvas: TCanvas; ARect: TRect;
State: TOwnerDrawState; TopLevel: Boolean); override;
public
constructor Create(ABuiltInMenu: TcxTreeListBuiltInMenu; AInternal: Boolean); reintroduce; virtual;
end;
constructor TcxTreeListBuiltInMenuItem.Create(ABuiltInMenu: TcxTreeListBuiltInMenu; AInternal: Boolean);
begin
inherited Create(nil);
FInternal := AInternal;
FBuiltInMenu := ABuiltInMenu;
end;
procedure TcxTreeListBuiltInMenuItem.AdvancedDrawItem(ACanvas: TCanvas; ARect: TRect;
State: TOwnerDrawState; TopLevel: Boolean);
var
AImageAreaRect: TRect;
ATextRect: TRect;
begin
if not IsWinXPOrLater or FBuiltInMenu.PopupMenu.IsRightToLeft then
inherited AdvancedDrawItem(ACanvas, ARect, State, TopLevel)
else
begin
CalculateRects(ACanvas, ARect, State, AImageAreaRect, ATextRect);
DrawBackground(ACanvas, ARect, State);
DrawImage(ACanvas, ARect, State, AImageAreaRect);
DrawText(ACanvas, ARect, State, ATextRect);
end;
end;
procedure TcxTreeListBuiltInMenuItem.CalculateRects(ACanvas: TCanvas; const ARect: TRect;
AState: TOwnerDrawState; out AImageAreaRect, ATextRect: TRect);
begin
AImageAreaRect := ARect;
AImageAreaRect.Right := AImageAreaRect.Left + cxRectHeight(AImageAreaRect);
ATextRect := ARect;
ATextRect.Left := AImageAreaRect.Right + 3;
Dec(ATextRect.Right);
end;
procedure TcxTreeListBuiltInMenuItem.DrawCheck(ACanvas: TCanvas; const AImageAreaRect: TRect);
var
ACheckRect: TRect;
AcxCanvas: TcxCanvas;
begin
ACheckRect := cxRectCenter(AImageAreaRect, TcxCustomLookAndFeelPainter.CheckButtonSize);
InflateRect(ACheckRect, -TcxCustomLookAndFeelPainter.CheckBorderSize,
-TcxCustomLookAndFeelPainter.CheckBorderSize);
AcxCanvas := TcxCanvas.Create(ACanvas);
try
AcxCanvas.Brush.Style := bsClear;
TcxCustomLookAndFeelPainter.DrawCheck(AcxCanvas, ACheckRect, cxbsNormal,
True, clBtnText);
AcxCanvas.Brush.Style := bsSolid;
finally
AcxCanvas.Free;
end;
end;
procedure TcxTreeListBuiltInMenuItem.DoDrawImage(ACanvas: TCanvas;
const AImageAreaRect: TRect; ABitmap: TBitmap; AImages: TCustomImageList;
AImageIndex: Integer; ADrawMode: TcxImageDrawMode);
var
AImageRect: TRect;
begin
AImageRect := Bounds(AImageAreaRect.Left + 1, AImageAreaRect.Top + 1,
FBuiltInMenu.GetImages(True).Width, FBuiltInMenu.GetImages(True).Height);
cxDrawImage(ACanvas.Handle, AImageRect, AImageRect, ABitmap, AImages,
AImageIndex, ADrawMode);
end;
procedure TcxTreeListBuiltInMenuItem.DrawBackground(ACanvas: TCanvas; const ARect: TRect;
AState: TOwnerDrawState);
const
ABrushColor: array [Boolean] of TColor = (clHighlight, clMenuHighlight);
begin
if odSelected in AState then
begin
ACanvas.Brush.Color := ABrushColor[IsThemeActive];
ACanvas.Font.Color := clHighlightText;
end;
ACanvas.FillRect(ARect);
end;
procedure TcxTreeListBuiltInMenuItem.DrawImage(ACanvas: TCanvas; const ARect: TRect;
AState: TOwnerDrawState; const AImageAreaRect: TRect);
const
ADrawMode: array [Boolean] of TcxImageDrawMode = (idmDisabled, idmNormal);
var
AImages: TCustomImageList;
begin
AImages := FBuiltInMenu.GetImages(FInternal);
if Checked then
DrawImageCheckedBackground(ACanvas, AImageAreaRect);
if (AImages <> nil) and cxInRange(ImageIndex, 0, AImages.Count - 1) then
DoDrawImage(ACanvas, AImageAreaRect, Bitmap, AImages, ImageIndex, ADrawMode[Enabled])
else
if Checked then
DrawCheck(ACanvas, AImageAreaRect);
end;
procedure TcxTreeListBuiltInMenuItem.DrawImageCheckedBackground(ACanvas: TCanvas;
const AImageAreaRect: TRect);
begin
ACanvas.Brush.Color := clBtnShadow;
ACanvas.FrameRect(AImageAreaRect);
ACanvas.Brush.Color := clBtnFace;
ACanvas.FillRect(cxRectInflate(AImageAreaRect, -1, -1));
end;
procedure TcxTreeListBuiltInMenuItem.DrawText(ACanvas: TCanvas; const ARect: TRect;
AState: TOwnerDrawState; ATextRect: TRect);
begin
DoDrawText(ACanvas, Caption, ATextRect, odSelected in AState,
DT_SINGLELINE or DT_EXPANDTABS or DT_LEFT or DT_VCENTER);
if ShortCut <> 0 then
begin
Dec(ATextRect.Right, 10);
DoDrawText(ACanvas, ShortCutToText(ShortCut), ATextRect,
odSelected in AState, DT_SINGLELINE or DT_RIGHT or DT_VCENTER);
end;
end;
{ TcxTreeListBuiltInMenu }
function TcxTreeListBuiltInMenu.CreateMenuItem(AOwner: TComponent; const ACaption: string;
ACommand: Integer; AEnabled: Boolean; AItemType: TcxTreeListBuiltInMenuItemType;
AChecked: Boolean; AImageIndex: Integer; AWithSeparator: Boolean; AInternal: Boolean): TComponent;
var
ASeparator: TMenuItem;
begin
Result := TcxTreeListBuiltInMenuItem.Create(Self, AInternal);
if AWithSeparator then
begin
ASeparator := TMenuItem.Create(nil);
ASeparator.Caption := '-';
TMenuItem(AOwner).Add(ASeparator);
end;
with TcxTreeListBuiltInMenuItem(Result) do
begin
Caption := ACaption;
Checked := AChecked;
Enabled := AEnabled;
ImageIndex := AImageIndex;
Tag := ACommand;
if AInternal then
GetBitmapFromImageList(GetImages(AInternal), AImageIndex, Bitmap);
OnClick := MenuItemClickHandler;
end;
TMenuItem(AOwner).Add(TMenuItem(Result));
end;
function TcxTreeListBuiltInMenu.GetPopupClass: TComponentClass;
begin
Result := TPopupMenu;
end;
function TcxTreeListBuiltInMenu.GetRoot: TComponent;
begin
Result := PopupMenu.Items;
end;
procedure TcxTreeListBuiltInMenu.CreatePopupMenu;
begin
inherited CreatePopupMenu;
if GetImages(False) <> nil then
PopupMenu.Images := GetImages(False)
else
PopupMenu.Images := GetImages(True);
end;
function TcxTreeListBuiltInMenu.GetPopupMenu: TPopupMenu;
begin
Result := TPopupMenu(FPopupMenu);
end;
{ TcxTreeListPopupMenu }
constructor TcxTreeListPopupMenu.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
LoadResourceImages;
end;
destructor TcxTreeListPopupMenu.Destroy;
begin
PopupMenu := nil;
FreeAndNil(FBuiltInMenu);
FreeAndNil(FImages);
inherited Destroy;
end;
procedure TcxTreeListPopupMenu.Assign(Source: TPersistent);
begin
if Source is TcxTreeListPopupMenu then
begin
UseBuiltInMenu := TcxTreeListPopupMenu(Source).UseBuiltInMenu;
PopupMenu := TcxTreeListPopupMenu(Source).PopupMenu;
OnClick := TcxTreeListPopupMenu(Source).OnClick;
OnPopup := TcxTreeListPopupMenu(Source).OnPopup;
end
else
inherited Assign(Source);
end;
function TcxTreeListPopupMenu.CreateMenuItem(AOwner: TComponent; const ACaption: string;
ACommand: Integer; AEnabled: Boolean; AItemType: TcxTreeListBuiltInMenuItemType;
AChecked: Boolean; AImageIndex: Integer; AWithSeparator: Boolean): TComponent;
begin
Result := BuiltInMenu.CreateMenuItem(AOwner, ACaption, ACommand, AEnabled,
AItemType, AChecked, AImageIndex, AWithSeparator, False);
end;
function TcxTreeListPopupMenu.CreateInternalMenuItem(AOwner: TComponent; const ACaption: string;
ACommand: Integer; AEnabled: Boolean = True; AItemType: TcxTreeListBuiltInMenuItemType = tlmitDefault;
AChecked: Boolean = False; AImageIndex: Integer = -1; AWithSeparator: Boolean = False): TComponent;
begin
Result := BuiltInMenu.CreateMenuItem(AOwner, ACaption, ACommand, AEnabled,
AItemType, AChecked, AImageIndex, AWithSeparator);
end;
procedure TcxTreeListPopupMenu.CreateItems;
begin
end;
procedure TcxTreeListPopupMenu.DoExecute(ACommand: Integer);
begin
end;
procedure TcxTreeListPopupMenu.DoMenuItemClick(Sender: TObject);
var
AHandled: Boolean;
begin
DoClick(Sender, AHandled);
if not AHandled then
DoExecute(TComponent(Sender).Tag);
end;
procedure TcxTreeListPopupMenu.DoClick(AItem: TObject;
var AHandled: Boolean);
begin
AHandled := False;
if Assigned(FOnClick) then
FOnClick(TreeList, AItem, AHandled);
end;
function TcxTreeListPopupMenu.DoPopup: Boolean;
begin
Result := False;
if Assigned(FOnPopup) then
FOnPopup(TreeList, Self, Result);
end;
function TcxTreeListPopupMenu.DoShowPopupMenu(const P: TPoint): Boolean;
begin
Result := IsPopupSuitable(TcxTreeListPopupMenus(Owner).HitTest) and Popup(P.X, P.Y);
end;
function TcxTreeListPopupMenu.GetResourceImagesCount: Integer;
begin
Result := 0;
end;
function TcxTreeListPopupMenu.GetResourceImagesNamePrefix: string;
begin
Result := '';
end;
function TcxTreeListPopupMenu.GetRoot: TComponent;
begin
Result := BuiltInMenu.Root;
end;
function TcxTreeListPopupMenu.GetTreeList: TcxCustomTreeList;
begin
Result := TcxTreeListPopupMenus(Owner).TreeList;
end;
procedure TcxTreeListPopupMenu.InitializeInternalMenu;
begin
BuiltInMenu.Initialize;
CreateItems;
end;
function TcxTreeListPopupMenu.IsPopupSuitable(AHitTest: TcxTreeListHitTest): Boolean;
begin
Result := False;
end;
procedure TcxTreeListPopupMenu.LoadResourceImages;
var
B: TBitmap;
I: Integer;
begin
FImages := TcxImageList.CreateSize(16, 16);
for I := 1 to GetResourceImagesCount do
begin
B := TBitmap.Create;
try
B.LoadFromResourceName(HInstance, GetResourceImagesNamePrefix + IntToStr(I));
TcxImageList(Images).AddMasked(B, clNone);
finally
B.Free;
end;
end;
end;
procedure TcxTreeListPopupMenu.Notification(AComponent: TComponent;
Operation: TOperation);
begin
if (Operation = opRemove) then
if (AComponent = PopupMenu) then
PopupMenu := nil
else
if (AComponent = UserImages) then
UserImages := nil;
end;
function TcxTreeListPopupMenu.Popup(X, Y: Integer): Boolean;
begin
if UseBuiltInMenu then
InitializeInternalMenu;
Result := DoPopup;
if not Result then
if UseBuiltInMenu then
Result := BuiltInMenu.Popup(X, Y)
else
Result := inherited Popup(X, Y);
end;
procedure TcxTreeListPopupMenu.SetPopupMenu(AValue: TComponent);
begin
if PopupMenu <> AValue then
begin
if PopupMenu <> nil then
PopupMenu.RemoveFreeNotification(TreeList);
inherited;
if PopupMenu <> nil then
PopupMenu.FreeNotification(TreeList);
end;
end;
function TcxTreeListPopupMenu.GetBuiltInMenu: TcxTreeListCustomBuiltInMenu;
begin
if FBuiltInMenu = nil then
FBuiltInMenu := cxTreeListBuiltInMenuClass.Create(Self);
Result := FBuiltInMenu;
end;
function TcxTreeListPopupMenu.GetImages: TCustomImageList;
begin
Result := FImages;
end;
procedure TcxTreeListPopupMenu.SetUseBuiltInMenu(AValue: Boolean);
begin
if FUseBuiltInMenu <> AValue then
begin
FUseBuiltInMenu := AValue;
if not FUseBuiltInMenu then
FreeAndNil(FBuiltInMenu);
end;
end;
procedure TcxTreeListPopupMenu.SetUserImages(AValue: TCustomImageList);
begin
if FUserImages <> AValue then
begin
if FUserImages <> nil then
FUserImages.RemoveFreeNotification(TreeList);
FUserImages := AValue;
if FUserImages <> nil then
FUserImages.FreeNotification(TreeList);
end;
end;
{ TcxTreeListFooterPopupMenu }
constructor TcxTreeListFooterPopupMenu.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FItems := [tlfmiSum, tlfmiMin, tlfmiMax, tlfmiAverage, tlfmiCount,
tlfmiNone, tlfmiAllNodes];
end;
procedure TcxTreeListFooterPopupMenu.Assign(Source: TPersistent);
begin
inherited Assign(Source);
if Source is TcxTreeListFooterPopupMenu then
FItems := TcxTreeListFooterPopupMenu(Source).Items;
end;
procedure TcxTreeListFooterPopupMenu.CreateItems;
var
ASummaryKinds: TcxSummaryKinds;
ADoesVisibleItemExist: Boolean;
begin
inherited;
ASummaryKinds := GetVisibleItemKinds;
ADoesVisibleItemExist := ASummaryKinds * [skSum..skAverage] <> [];
if tlfmiSum in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListSumMenuItem),
tlcmSum, IsItemEnabled(skSum), tlmitChecked, skSum in ASummaryKinds, tlcmSum - 1);
if tlfmiMin in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListMinMenuItem),
tlcmMin, IsItemEnabled(skMin), tlmitChecked, skMin in ASummaryKinds, tlcmMin - 1);
if tlfmiMax in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListMaxMenuItem),
tlcmMax, IsItemEnabled(skMax), tlmitChecked, skMax in ASummaryKinds, tlcmMax - 1);
if tlfmiCount in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListCountMenuItem),
tlcmCount, IsItemEnabled(skCount), tlmitChecked, skCount in ASummaryKinds, tlcmCount - 1);
if tlfmiAverage in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListAvgMenuItem),
tlcmAverage, IsItemEnabled(skAverage), tlmitChecked, skAverage in ASummaryKinds, tlcmAverage - 1);
if tlfmiNone in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListNoneMenuItem),
tlcmNone, IsItemEnabled(skNone), tlmitChecked, not ADoesVisibleItemExist, - 1, True);
if tlfmiAllNodes in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListAllNodesMenuItem),
tlcmAllNodes, ADoesVisibleItemExist, tlmitChecked, ADoesVisibleItemExist and IsAllNodes, - 1, True);
end;
procedure TcxTreeListFooterPopupMenu.DoExecute(ACommand: Integer);
procedure SetItemsVisibility(AKind: TcxSummaryKind);
var
I: Integer;
AValue: Boolean;
begin
AValue := (AKind <> skNone) and not (AKind in GetVisibleItemKinds);
if not AValue or (SummaryItems.GetItemByKind(AKind) <> nil) then
begin
for I := 0 to SummaryItems.Count - 1 do
if ((SummaryItems[I].Kind = AKind) or (AKind = skNone)) then
SummaryItems[I].Visible := AValue;
end
else
with SummaryItems.Add do
begin
Kind := AKind;
AllNodes := IsAllNodes;
end;
end;
procedure SetAllNodes(AValue: Boolean);
var
I: Integer;
begin
SummaryItems.BeginUpdate;
try
for I := 0 to SummaryItems.Count - 1 do
SummaryItems[I].AllNodes := AValue;
finally
SummaryItems.EndUpdate;
end;
end;
begin
inherited;
case ACommand of
tlcmNone..tlcmAverage: SetItemsVisibility(TcxSummaryKind(ACommand));
tlcmAllNodes: SetAllNodes(not IsAllNodes);
end;
end;
function TcxTreeListFooterPopupMenu.GetResourceImagesCount: Integer;
begin
Result := 5;
end;
function TcxTreeListFooterPopupMenu.GetResourceImagesNamePrefix: string;
begin
Result := 'TLFTRIMG';
end;
function TcxTreeListFooterPopupMenu.IsPopupSuitable(AHitTest: TcxTreeListHitTest): Boolean;
begin
Result := (AHitTest.HitAtFooterItem or AHitTest.HitAtFooter) and
(AHitTest.FHitColumn <> nil);
if Result then
FSummaryItems := AHitTest.FHitColumn.Summary.FooterSummaryItems;
end;
function TcxTreeListFooterPopupMenu.GetVisibleItemKinds: TcxSummaryKinds;
var
I: Integer;
begin
Result := [];
for I := 0 to SummaryItems.Count - 1 do
if SummaryItems[I].Visible then
Include(Result, SummaryItems[I].Kind);
end;
function TcxTreeListFooterPopupMenu.IsAllNodes: Boolean;
var
I: Integer;
begin
Result := False;
for I := 0 to SummaryItems.Count - 1 do
if SummaryItems[I].AllNodes then
begin
Result := True;
Break;
end;
end;
function TcxTreeListFooterPopupMenu.IsItemEnabled(AKind: TcxSummaryKind): Boolean;
function IsSummaryKindAllowedForValueType(AValueTypeClass: TcxValueTypeClass): Boolean;
const
ANumberVarTypes = [varSmallint, varInteger, varSmallint, varSingle, varByte,
varDouble, varCurrency, varDate, varLongWord, varWord, varInt64, varShortInt];
ATimeVarTypes = [varDate];
var
AVarType: Integer;
begin
Result := False;
if AValueTypeClass <> nil then
begin
AVarType := AValueTypeClass.GetVarType;
Result := ((AVarType in ANumberVarTypes) or (AVarType = TcxFMTBcdValueType.GetVarType)) and
not((AVarType in ATimeVarTypes) and (AKind in [skSum, skAverage]));
end;
end;
var
AColumn: TcxTreeListColumn;
begin
AColumn := SummaryItems.Column;
Result := (AKind in [skCount, skNone]) or not(AColumn.Properties is TcxCustomLookupEditProperties) and
IsSummaryKindAllowedForValueType(AColumn.ValueDef.ValueTypeClass);
end;
function TcxTreeListFooterPopupMenu.IsItemsStored: Boolean;
begin
Result := FItems <> [tlfmiSum, tlfmiMin, tlfmiMax, tlfmiAverage, tlfmiCount,
tlfmiNone, tlfmiAllNodes];
end;
{ TcxTreeListGroupFooterPopupMenu }
function TcxTreeListGroupFooterPopupMenu.IsPopupSuitable(AHitTest: TcxTreeListHitTest): Boolean;
begin
Result := (AHitTest.HitAtGroupFooterItem or AHitTest.HitAtGroupFooter) and
(AHitTest.FHitColumn <> nil);
if Result then
FSummaryItems := AHitTest.FHitColumn.Summary.GroupFooterSummaryItems;
end;
{ TcxTreeListColumnHeaderPopupMenu }
constructor TcxTreeListColumnHeaderPopupMenu.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FItems := [tlchmiSortAscending, tlchmiSortDescending, tlchmiClearSorting, tlchmiFooter,
tlchmiGroupFooters, tlchmiRemoveThisColumn, tlchmiFieldChooser, tlchmiHorzAlignment,
tlchmiVertAlignment, tlchmiBestFit, tlchmiBestFitAllColumns];
end;
procedure TcxTreeListColumnHeaderPopupMenu.Assign(Source: TPersistent);
begin
inherited Assign(Source);
if Source is TcxTreeListColumnHeaderPopupMenu then
FItems := TcxTreeListColumnHeaderPopupMenu(Source).Items;
end;
procedure TcxTreeListColumnHeaderPopupMenu.CreateItems;
var
ASubMenu: TComponent;
AAlignmentMenuItemsNeeded: Boolean;
begin
inherited CreateItems;
if tlchmiSortAscending in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListSortAscendingMenuItem),
tlcmSortAscending, True, tlmitChecked, Column.SortOrder = soAscending, 0);
if tlchmiSortDescending in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListSortDescendingMenuItem),
tlcmSortDescending, True, tlmitChecked, Column.SortOrder = soDescending, 1);
if tlchmiClearSorting in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListClearSortingMenuItem),
tlcmClearSorting, Column.SortOrder <> soNone, tlmitDefault, False, - 1);
FSeparatorNeeded := True;
if tlchmiFooter in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListFooterMenuItem),
tlcmFooter, True, tlmitChecked, TreeList.OptionsView.Footer, 4, IsSeparatorNeeded);
if tlchmiGroupFooters in Items then
begin
ASubMenu := CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListGroupFootersMenuItem),
-1, True, tlmitSubItem, False, 5, IsSeparatorNeeded);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListGroupFootersInvisibleMenuItem),
tlcmGroupFootersInvisible, True, tlmitChecked, TreeList.OptionsView.GroupFooters = tlgfInvisible);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListGroupFootersVisibleWhenExpandedMenuItem),
tlcmGroupFootersVisibleWhenExpanded, True, tlmitChecked, TreeList.OptionsView.GroupFooters = tlgfVisibleWhenExpanded);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListGroupFootersAlwaysVisibleMenuItem),
tlcmGroupFootersAlwaysVisible, True, tlmitChecked, TreeList.OptionsView.GroupFooters = tlgfAlwaysVisible);
end;
FSeparatorNeeded := True;
if (tlchmiRemoveThisColumn in Items) and not Column.Options.Hidden and
Column.CanMoving and (TreeList.VisibleColumnCount > 1) then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListRemoveThisColumnMenuItem),
tlcmRemoveThisColumn, True, tlmitDefault, False, - 1, IsSeparatorNeeded);
if tlchmiFieldChooser in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListFieldChooserMenuItem),
tlcmFieldChooser, True, tlmitDefault, False, 2, IsSeparatorNeeded);
FSeparatorNeeded := True;
AAlignmentMenuItemsNeeded := Column.Properties <> nil;
if AAlignmentMenuItemsNeeded then
CreateAlignmentSubMenus;
if tlchmiBestFit in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListBestFitMenuItem),
tlcmBestFit, True, tlmitDefault, False, 3, IsSeparatorNeeded);
if tlchmiBestFitAllColumns in Items then
CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListBestFitAllColumnsMenuItem),
tlcmBestFitAllColumns, True, tlmitDefault, False, - 1, True);
end;
procedure TcxTreeListColumnHeaderPopupMenu.DoExecute(ACommand: Integer);
begin
inherited;
case ACommand of
tlcmSortAscending:
Column.SortOrder := soAscending;
tlcmSortDescending:
Column.SortOrder := soDescending;
tlcmClearSorting:
Column.SortOrder := soNone;
tlcmFooter:
TreeList.OptionsView.Footer := not TreeList.OptionsView.Footer;
tlcmGroupFootersInvisible..tlcmGroupFootersAlwaysVisible:
TreeList.OptionsView.GroupFooters := TcxTreeListGroupFootersMode(ACommand - tlcmGroupFootersInvisible);
tlcmRemoveThisColumn:
Column.Visible := False;
tlcmFieldChooser:
TreeList.Customizing.Visible := True;
tlcmHorzAlignmentLeft..tlcmHorzAlignmentCenter:
Column.Properties.Alignment.Horz := TcxEditHorzAlignment(ACommand - tlcmHorzAlignmentLeft);
tlcmVertAlignmentTop..tlcmVertAlignmentCenter:
Column.Properties.Alignment.Vert := TcxEditVertAlignment(ACommand - tlcmVertAlignmentTop);
tlcmBestFit:
Column.ApplyBestFit;
tlcmBestFitAllColumns:
TreeList.ApplyBestFit;
end;
end;
function TcxTreeListColumnHeaderPopupMenu.GetResourceImagesCount: Integer;
begin
Result := 6;
end;
function TcxTreeListColumnHeaderPopupMenu.GetResourceImagesNamePrefix: string;
begin
Result := 'TLHDRIMG';
end;
function TcxTreeListColumnHeaderPopupMenu.IsPopupSuitable(AHitTest: TcxTreeListHitTest): Boolean;
begin
Result := AHitTest.HitAtColumnHeader;
if Result then
Column := AHitTest.HitColumn;
end;
procedure TcxTreeListColumnHeaderPopupMenu.CreateAlignmentSubMenus;
var
ASubMenu: TComponent;
begin
if tlchmiHorzAlignment in Items then
begin
ASubMenu := CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListHorizontalAlignmentMenuItem),
-1, True, tlmitSubItem, False, -1, IsSeparatorNeeded);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListHorizontalAlignmentLeftMenuItem),
tlcmHorzAlignmentLeft, True, tlmitChecked, Column.Properties.Alignment.Horz = taLeftJustify);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListHorizontalAlignmentCenterMenuItem),
tlcmHorzAlignmentCenter, True, tlmitChecked, Column.Properties.Alignment.Horz = taCenter);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListHorizontalAlignmentRightMenuItem),
tlcmHorzAlignmentRight, True, tlmitChecked, Column.Properties.Alignment.Horz = taRightJustify);
end;
if tlchmiVertAlignment in Items then
begin
ASubMenu := CreateInternalMenuItem(Root, cxGetResourceString(@scxTreeListVerticalAlignmentMenuItem),
-1, True, tlmitSubItem, False, -1, IsSeparatorNeeded);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListVerticalAlignmentTopMenuItem),
tlcmVertAlignmentTop, True, tlmitChecked, Column.Properties.Alignment.Vert = taTopJustify);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListVerticalAlignmentCenterMenuItem),
tlcmVertAlignmentCenter, True, tlmitChecked, Column.Properties.Alignment.Vert = taVCenter);
CreateInternalMenuItem(ASubMenu, cxGetResourceString(@scxTreeListVerticalAlignmentBottomMenuItem),
tlcmVertAlignmentBottom, True, tlmitChecked, Column.Properties.Alignment.Vert = taBottomJustify);
end;
end;
function TcxTreeListColumnHeaderPopupMenu.IsItemsStored: Boolean;
begin
Result := FItems <> [tlchmiSortAscending, tlchmiSortDescending, tlchmiClearSorting,
tlchmiFooter, tlchmiGroupFooters, tlchmiRemoveThisColumn, tlchmiFieldChooser,
tlchmiHorzAlignment, tlchmiVertAlignment, tlchmiBestFit, tlchmiBestFitAllColumns];
end;
function TcxTreeListColumnHeaderPopupMenu.IsSeparatorNeeded: Boolean;
begin
Result := FSeparatorNeeded;
FSeparatorNeeded := False;
end;
{ TcxTreeListPopupMenus }
constructor TcxTreeListPopupMenus.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FMenus := TObjectList.Create;
CreateMenus;
end;
destructor TcxTreeListPopupMenus.Destroy;
begin
FreeAndNil(FMenus);
inherited Destroy;
end;
procedure TcxTreeListPopupMenus.Assign(Source: TPersistent);
begin
if Source is TcxTreeListPopupMenus then
begin
ColumnHeaderMenu := TcxTreeListPopupMenus(Source).ColumnHeaderMenu;
GroupFooterMenu := TcxTreeListPopupMenus(Source).GroupFooterMenu;
FooterMenu := TcxTreeListPopupMenus(Source).FooterMenu;
end
else
inherited Assign(Source);
end;
procedure TcxTreeListPopupMenus.CreateMenus;
begin
FFooterMenu := TcxTreeListFooterPopupMenu.Create(Self);
FMenus.Add(FFooterMenu);
FGroupFooterMenu := TcxTreeListGroupFooterPopupMenu.Create(Self);
FMenus.Add(FGroupFooterMenu);
FColumnHeaderMenu := TcxTreeListColumnHeaderPopupMenu.Create(Self);
FMenus.Add(FColumnHeaderMenu);
end;
function TcxTreeListPopupMenus.DoShowPopupMenu(const P: TPoint): Boolean;
var
I: Integer;
begin
Result := False;
for I := 0 to FMenus.Count - 1 do
if TcxTreeListPopupMenu(FMenus[I]).DoShowPopupMenu(P) then
begin
Result := True;
Break;
end;
end;
procedure TcxTreeListPopupMenus.Notification(AComponent: TComponent;
Operation: TOperation);
var
I: Integer;
begin
for I := 0 to FMenus.Count - 1 do
TcxTreeListPopupMenu(FMenus[I]).Notification(AComponent, Operation);
end;
function TcxTreeListPopupMenus.GetHitTest: TcxTreeListHitTest;
begin
Result := TreeList.HitTest;
end;
function TcxTreeListPopupMenus.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(Owner);
end;
procedure TcxTreeListPopupMenus.SetColumnHeaderMenu(AValue: TcxTreeListColumnHeaderPopupMenu);
begin
FColumnHeaderMenu.Assign(AValue);
end;
procedure TcxTreeListPopupMenus.SetFooterMenu(
AValue: TcxTreeListFooterPopupMenu);
begin
FFooterMenu.Assign(AValue);
end;
procedure TcxTreeListPopupMenus.SetGroupFooterMenu(
AValue: TcxTreeListGroupFooterPopupMenu);
begin
FGroupFooterMenu.Assign(AValue);
end;
{ TcxTreeListOptionsView }
constructor TcxTreeListOptionsView.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FIndicatorWidth := cxTreeListDefIndicatorWidth;
FFixedSeparatorWidth := cxTreeListDefSeparatorWidth;
FDropArrowColor := cxTreeListDefDropArrowColor;
FButtons := True;
FHeaders := True;
FFixedSeparatorColor := clDefault;
FGridLineColor := clDefault;
FTreeLineColor := clDefault;
FTreeLineStyle := tllsDot;
FUseNodeColorForIndent := True;
FUseImageIndexForSelected := True;
FShowRoot := True;
end;
procedure TcxTreeListOptionsView.Assign(Source: TPersistent);
var
ASource: TcxTreeListOptionsView;
begin
if Source is TcxTreeListOptionsView then
begin
ASource := TcxTreeListOptionsView(Source);
FCategorizedColumn := TreeList.GetSameColumn(ASource.FCategorizedColumn);
FBandLineHeight := ASource.FBandLineHeight;
FBands := ASource.FBands;
FButtons := ASource.FButtons;
FColumnAutoWidth := ASource.ColumnAutoWidth;
FCheckGroups := ASource.CheckGroups;
FDropArrowColor := ASource.FDropArrowColor;
FDropArrowColor := ASource.FDropArrowColor;
FDynamicIndent := ASource.FDynamicIndent;
FDynamicFocusedStateImages := ASource.FDynamicFocusedStateImages;
FExtPaintStyle := ASource.FExtPaintStyle;
FFixedSeparatorColor := ASource.FFixedSeparatorColor;
FFixedSeparatorWidth := ASource.FixedSeparatorWidth;
FGridLineColor := ASource.GridLineColor;
FGridLines := ASource.FGridLines;
FGroupFooters := ASource.GroupFooters;
FHeaders := ASource.FHeaders;
FIndicator := ASource.FIndicator;
FIndicatorWidth := ASource.FIndicatorWidth;
FPaintStyle := ASource.FPaintStyle;
FShowRoot := ASource.FShowRoot;
FSimpleCustomizeBox := ASource.FSimpleCustomizeBox;
FTreeLineColor := ASource.FTreeLineColor;
FTreeLineStyle := ASource.FTreeLineStyle;
FUseImageIndexForSelected := ASource.FUseImageIndexForSelected;
FUseNodeColorForIndent := ASource.FUseNodeColorForIndent;
end;
inherited Assign(Source);
end;
function TcxTreeListOptionsView.GetCategorizedColumn: TcxTreeListColumn;
begin
if FCategorizedColumn <> nil then
Result := FCategorizedColumn
else
if TreeList.VisibleColumnCount > 0 then
Result := TreeList.VisibleColumns[0]
else
Result := nil;
end;
procedure TcxTreeListOptionsView.RestoreDefaults;
begin
FBandLineHeight := 0;
FBands := False;
FButtons := True;
FColumnAutoWidth := False;
FCheckGroups := False;
FDropArrowColor := cxTreeListDefDropArrowColor;
FDynamicIndent := False;
FDynamicFocusedStateImages := False;
FExtPaintStyle := False;
FFixedSeparatorColor := clDefault;
FFixedSeparatorWidth := cxTreeListDefSeparatorWidth;
FFooter := False;
FGridLineColor := clDefault;
FGridLines := tlglNone;
FGroupFooters := tlgfInvisible;
FHeaders := True;
FIndicator := False;
FIndicatorWidth := cxTreeListDefIndicatorWidth;
FPaintStyle := tlpsStandard;
FShowRoot := True;
FSimpleCustomizeBox := False;
FTreeLineColor := clDefault;
FTreeLineStyle := tllsDot;
FUseImageIndexForSelected := True;
FUseNodeColorForIndent := True;
Changed;
end;
procedure TcxTreeListOptionsView.Changed;
begin
TreeList.LayoutChanged;
end;
function TcxTreeListOptionsView.GetControl: TObject;
begin
Result := TreeList;
end;
function TcxTreeListOptionsView.HorzIncrement: Integer;
begin
Result := Byte(GridLines in [tlglVert, tlglBoth])
end;
function TcxTreeListOptionsView.IsCategorizedPaint: Boolean;
begin
Result := PaintStyle = tlpsCategorized;
end;
function TcxTreeListOptionsView.IsExtPaintStyle: Boolean;
begin
Result := ExtPaintStyle and (GetTreeList.LookAndFeel.SkinPainter = nil);
end;
function TcxTreeListOptionsView.VertIncrement: Integer;
begin
Result := Byte(GridLines in [tlglHorz, tlglBoth])
end;
function TcxTreeListOptionsView._AddRef: Integer;
begin
Result := -1;
end;
function TcxTreeListOptionsView._Release: Integer;
begin
Result := -1;
end;
function TcxTreeListOptionsView.QueryInterface(
const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := cxE_NOINTERFACE;
end;
function TcxTreeListOptionsView.GetIsIndicatorVisible: Boolean;
begin
with TreeList.OptionsCustomizing do
begin
Result := Indicator or (BandsQuickCustomization and BandCustomizing) or
(ColumnsQuickCustomization and ColumnCustomizing);
end;
end;
function TcxTreeListOptionsView.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(EditingControl);
end;
procedure TcxTreeListOptionsView.SetCategorizedColumn(AValue: TcxTreeListColumn);
begin
if AValue <> FCategorizedColumn then
begin
FCategorizedColumn := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetCheckGroups(AValue: Boolean);
begin
if AValue <> FCheckGroups then
begin
FCheckGroups := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetColumnAutoWidth(AValue: Boolean);
begin
if AValue <> FColumnAutoWidth then
begin
FColumnAutoWidth := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetDynamicIndent(AValue: Boolean);
begin
if AValue <> FDynamicIndent then
begin
FDynamicIndent := AValue;
TreeList.ImagesChanged(nil);
end;
end;
procedure TcxTreeListOptionsView.SetBandLineHeight(AValue: Integer);
begin
if AValue < 0 then Exit;
if AValue <> FBandLineHeight then
begin
FBandLineHeight := AValue;
if Bands then
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetBands(AValue: Boolean);
begin
if AValue <> Bands then
begin
FBands := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetButtons(AValue: Boolean);
begin
if AValue <> FButtons then
begin
FButtons := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetIndicator(AValue: Boolean);
begin
if AValue <> FIndicator then
begin
FIndicator := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetIndicatorWidth(AValue: Integer);
begin
if AValue < 0 then Exit;
if AValue <> FIndicatorWidth then
begin
FIndicatorWidth := AValue;
if Indicator then
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetDynamicFocusedStateImages(AValue: Boolean);
begin
if AValue <> FDynamicFocusedStateImages then
begin
FDynamicFocusedStateImages := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetExtPaintStyle(AValue: Boolean);
begin
if AValue <> FExtPaintStyle then
begin
FExtPaintStyle := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetFixedSeparatorColor(AValue: TColor);
begin
if AValue <> FFixedSeparatorColor then
begin
FFixedSeparatorColor := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetFixedSeparatorWidth(AValue: Integer);
begin
if AValue < 0 then Exit;
if AValue <> FFixedSeparatorWidth then
begin
FFixedSeparatorWidth := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetFooter(AValue: Boolean);
begin
if AValue <> FFooter then
begin
FFooter := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetGridLineColor(AValue: TColor);
begin
if AValue <> FGridLineColor then
begin
FGridLineColor := AValue;
if GridLines <> tlglNone then
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetGridLines(AValue: TcxTreeListGridLines);
begin
if AValue <> FGridLines then
begin
FGridLines := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetGroupFooters(
AValue: TcxTreeListGroupFootersMode);
begin
if AValue <> FGroupFooters then
begin
FGroupFooters := AValue;
TreeList.StructureChanged;
end;
end;
procedure TcxTreeListOptionsView.SetHeaders(AValue: Boolean);
begin
if AValue <> FHeaders then
begin
FHeaders := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetPaintStyle(AValue: TcxTreeListPaintStyle);
begin
if AValue <> FPaintStyle then
begin
FPaintStyle := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetShowRoot(AValue: Boolean);
begin
if AValue <> FShowRoot then
begin
FShowRoot := AValue;
TreeList.ImagesChanged(nil);
end;
end;
procedure TcxTreeListOptionsView.SetSimpleCustomizeBox(AValue: Boolean);
begin
if AValue <> FSimpleCustomizeBox then
begin
FSimpleCustomizeBox := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetTreeLineColor(AValue: TColor);
begin
if AValue <> FTreeLineColor then
begin
FTreeLineColor := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetTreeLineStyle(
AValue: TcxTreeListTreeLineStyle);
begin
if AValue <> FTreeLineStyle then
begin
FTreeLineStyle := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetUseImageIndexForSelected(AValue: Boolean);
begin
if AValue <> FUseImageIndexForSelected then
begin
FUseImageIndexForSelected := AValue;
Changed;
end;
end;
procedure TcxTreeListOptionsView.SetUseNodeColorForIndent(AValue: Boolean);
begin
if AValue <> FUseNodeColorForIndent then
begin
FUseNodeColorForIndent := AValue;
Changed;
end;
end;
{ TcxTreeListViewInfo }
constructor TcxTreeListViewInfo.Create(AOwner: TcxEditingControl);
begin
inherited Create(AOwner);
FHitTestCells := TcxObjectList.Create;
FHeaderCells := TList.Create;
FFakeCell := TcxFakeCellViewInfo.Create(Self);
FCells := TcxCustomControlCells.Create;
FNodesViewData := TcxObjectList.Create;
FCheckBoxProperties := TcxCheckBoxProperties.Create(nil);
TcxCheckBoxProperties(FCheckBoxProperties).AllowGrayed := True;
TcxCheckBoxProperties(FCheckBoxProperties).ValueChecked := Integer(cbsChecked);
TcxCheckBoxProperties(FCheckBoxProperties).ValueUnchecked := Integer(cbsUnchecked);
TcxCheckBoxProperties(FCheckBoxProperties).ValueGrayed := Integer(cbsGrayed);
FCheckBoxViewInfo := TcxCustomEditViewInfo(FCheckBoxProperties.GetViewInfoClass.Create);
RecreateCheckBoxViewData;
end;
destructor TcxTreeListViewInfo.Destroy;
begin
Clear;
FreeAndNil(FCheckBoxViewData);
FreeAndNil(FCheckBoxViewInfo);
FreeAndNil(FCheckBoxProperties);
FreeAndNil(FHeaderCells);
FreeAndNil(FNodesViewData);
FreeAndNil(FFakeCell);
FreeAndNil(FCells);
FreeAndNil(FHitTestCells);
inherited Destroy;
end;
function TcxTreeListViewInfo.GetEditCell(ANode: TcxTreeListNode;
AColumn: TcxTreeListColumn): TcxTreeListEditCellViewInfo;
var
I: Integer;
begin
Result := nil;
if (ANode = nil) or (ANode.ViewData = nil) then Exit;
for I := 0 to ANode.ViewData.Cells.Count - 1 do
if (TObject(ANode.ViewData.Cells[I]) is TcxTreeListEditCellViewInfo) and
(TcxTreeListEditCellViewInfo(ANode.ViewData.Cells[I]).Column = AColumn) then
begin
Result := TcxTreeListEditCellViewInfo(ANode.ViewData.Cells[I]);
Break;
end;
end;
function TcxTreeListViewInfo.Validate: Boolean;
begin
Result := (IsDirty or (TreeList.Changes -
[tcSelection, tcFocusedNode] <> [])) and not CalculateInProcess;
if Result then
TreeList.ForceLayoutChanged;
end;
function TcxTreeListViewInfo.AddBackgroundPart(
const ABounds: TRect): TcxTreeListBackgroundCellViewInfo;
begin
AddCell(TcxTreeListBackgroundCellViewInfo, ABounds, ABounds, Result);
Result.ItemViewParams := Styles.GetBackgroundParams;
end;
function TcxTreeListViewInfo.AddBandHeader(ABand: TcxTreeListBand;
var ABounds: TRect; const AClipRect: TRect): TcxTreeListBandHeaderCellViewInfo;
var
R: TRect;
begin
R := ABounds;
R.Right := ABounds.Left + ABand.DisplayWidth;
R.Bottom := R.Top + ABand.LineCount * BandLineHeight;
AddCell(TcxTreeListBandHeaderCellViewInfo, R, AClipRect, Result);
Result.Initialize(ABand.Caption);
ABounds.Left := R.Right;
ABand.FHeaderCell := Result;
if ABand.IsFirstInGroup and not ABand.IsLeftMost then
Exclude(Result.FBorders, bLeft);
if cxRectHeight(ABounds) > 0 then
AddHeaderHitTestAreas(Result, ABand.CanSizing(dsdHorz), ABand.CanSizing(dsdVert));
FHeaderCells.Add(Result);
end;
function TcxTreeListViewInfo.AddBandPart(APart: TcxTreeListBandPart;
ABand: TcxTreeListBand; ANode, AAttachNode: TcxTreeListNode;
ABounds, AClipRect: TRect): TcxTreeListBandCellViewInfo;
begin
if APart in [tlbpContent, tlbpSeparator] then
InflateBoundsForGridLines(ABounds, AClipRect);
AddCell(TcxTreeListBandCellViewInfo, ABounds, AClipRect, Result);
if APart = tlbpContent then
Result.FBorders := GridLines;
if (APart = tlbpHeader) and (bRight in GridLines) and ABand.IsRightMost and (Count > 0) then
Include(Result.FBorders, bRight);
Result.Initialize(ABand, ANode, AAttachNode, APart);
end;
function TcxTreeListViewInfo.AddBandSeparator(ANode: TcxTreeListNode;
var ABounds: TRect; const AClipBounds: TRect): TcxTreeListBandCellViewInfo;
begin
Result := AddBandPart(tlbpSeparator, nil, ANode, ANode,
cxRectSetWidth(ABounds, FixedSeparatorWidth), AClipBounds);
Result.FBorders := [];
Inc(ABounds.Left, FixedSeparatorWidth);
end;
procedure TcxTreeListViewInfo.AddBandsHeaders(
AKind: TcxTreeListBandFixedKind; const ABounds, AClipBounds: TRect);
procedure AddSubItems(AParent: TcxTreeListBand; var R: TRect);
var
I: Integer;
ASubBounds: TRect;
begin
if not AParent.Visible then Exit;
ASubBounds := R;
R.Bottom := R.Top + AParent.LineCount * BandLineHeight;
AddBandHeader(AParent, R, AClipBounds);
ASubBounds.Top := R.Bottom;
for I := 0 to AParent.ChildBandCount - 1 do
AddSubItems(AParent.ChildBands[I], ASubBounds);
end;
var
I: Integer;
R: TRect;
ABand: TcxTreeListBand;
begin
R := ABounds;
for I := 0 to Bands.VisibleRootItemCount - 1 do
begin
ABand := Bands.VisibleRootItems[I];
if ABand.FixedKind = AKind then
AddSubItems(ABand, R);
end;
end;
procedure TcxTreeListViewInfo.AddCell(
ACellClass: TcxTreeListCustomCellViewInfoClass;
const ABounds, AVisibleRect: TRect; var AInstance);
begin
Pointer(AInstance) := ACellClass.CreateEx(TreeList, ABounds, AVisibleRect);
TcxTreeListCustomCellViewInfo(AInstance).FBorderColor := GridLineColor;
Cells.Add(Pointer(AInstance));
end;
function TcxTreeListViewInfo.AddColumnHeader(AColumn: TcxTreeListColumn;
var ABounds: TRect; const AClipBounds: TRect): TcxTreeListColumnHeaderCellViewInfo;
var
R: TRect;
ABand: TcxTreeListBand;
begin
R := ABounds;
R.Right := R.Left + AColumn.DisplayWidth;
AddCell(TcxTreeListColumnHeaderCellViewInfo, R, AClipBounds, Result);
Result.Initialize(AColumn.Caption);
ABand := AColumn.Position.Band;
if (AColumn.Position.VisibleColIndex = 0) and ABand.IsFirstInGroup and
not ABand.IsLeftMost and (bRight in GridLines) then
Exclude(Result.FBorders, bLeft);
AColumn.FHeaderCell := Result;
ABounds.Left := R.Right;
FHeaderCells.Add(Result);
if cxRectHeight(ABounds) > 0 then
AddHeaderHitTestAreas(Result, AColumn.CanSizing(dsdHorz), AColumn.CanSizing(dsdVert));
end;
function TcxTreeListViewInfo.AddEditCell(AViewData: TcxTreeListNodeViewData;
AColumn: TcxTreeListColumn; ABounds, AClipRect: TRect;
AClass: TcxEditCellViewInfoClass): TcxTreeListEditCellViewInfo;
begin
InflateBoundsForGridLines(ABounds, AClipRect);
Result := TcxTreeListEditCellViewInfo(AClass.Create(AColumn));
Result.FNodeViewData := AViewData;
Result.CellBorders := GridLines;
Result.BorderColor := GridLineColor;
Result.CheckClipping(ABounds, AClipRect);
AColumn.InitEditViewInfo(Result);
Result.CheckVisibleInfo;
Cells.Add(Result);
end;
procedure TcxTreeListViewInfo.AddColumnFooterItems(
ADataNode, AttachNode: TcxTreeListNode;
AColumn: TcxTreeListColumn; const ABounds, AClipRect: TRect);
var
I: Integer;
R: TRect;
AMultiLine: Boolean;
AItems: TcxTreeListSummaryItems;
ACell: TcxTreeListFooterCellViewInfo;
AOffset: Integer;
begin
R := cxRectSetTop(ABounds, AClipRect.Top +
AColumn.Position.Row.LineOffset * FooterLineHeight,
AColumn.Position.LineCount * FooterLineHeight);
AOffset := 0;
if not IsPrinting then
begin
InflateRect(R, -Painter.FooterCellOffset, 0);
Dec(R.Bottom);
AOffset := Painter.FooterCellOffset;
end;
if ADataNode = Root then
begin
AItems := AColumn.Summary.FooterSummaryItems;
AMultiLine := not MultiRows and (Summary.FooterSummaryRowCount > 1);
end
else
begin
AItems := AColumn.Summary.GroupFooterSummaryItems;
AMultiLine := not MultiRows and (Summary.GroupFooterSummaryRowCount > 1);
end;
if not AMultiLine or (AItems.Count = 0) then
begin
AddCell(TcxTreeListFooterMultiItemsCellViewInfo,
cxRectSetHeight(R, cxRectHeight(R) - AOffset) , AClipRect, ACell);
TcxTreeListFooterMultiItemsCellViewInfo(ACell).Initialize(ADataNode, AttachNode, AColumn, AItems);
end
else
for I := 0 to AItems.Count - 1 do
if AItems[I].Visible then
begin
AddCell(TcxTreeListFooterSingleCellViewInfo, cxRectSetHeight(R, cxRectHeight(R) - AOffset), AClipRect, ACell);
TcxTreeListFooterSingleCellViewInfo(ACell).Initialize(ADataNode, AttachNode, AColumn, AItems[I]);
OffsetRect(R, 0, FooterLineHeight * AColumn.Position.LineCount);
end;
end;
procedure TcxTreeListViewInfo.AddFixedSeparators(ABounds: TRect;
AAttachNode: TcxTreeListNode);
var
R: TRect;
begin
if FixedSeparatorWidth = 0 then Exit;
R := cxRectSetWidth(ABounds, FixedSeparatorWidth);
if Bands.VisibleLeftFixedCount > 0 then
begin
R := cxRectSetLeft(R, ContentParts[tlbfLeft].Right);
AddBandPart(tlbpSeparator, nil, AAttachNode, AAttachNode, R, R);
end;
if (Bands.VisibleRootRightFixedCount > 0) and ((R.Right <= ContentParts[tlbfRight].Left) or
(Bands.VisibleRootLeftFixedCount = 0)) then
begin
R := cxRectSetRight(R, ContentParts[tlbfRight].Left);
if R.Left < IndicatorWidth then
R.Left := IndicatorWidth;
if R.Left >= R.Right then Exit;
AddBandPart(tlbpSeparator, nil, AAttachNode, AAttachNode, R, R);
end;
end;
procedure TcxTreeListViewInfo.AddFooter(AAttachNode: TcxTreeListNode;
AIndex, AIndent: Integer; const ABounds: TRect);
var
I, J: Integer;
ABand: TcxTreeListBand;
AClipRect, ACellsClipRect, R: TRect;
AColumn: TcxTreeListColumn;
ADataNode: TcxTreeListNode;
APart: TcxTreeListBandCellViewInfo;
const
BandPart: array[Boolean] of tcxTreeListBandPart = (tlbpGroupFooter, tlbpFooter);
begin
ADataNode := AAttachNode;
if AAttachNode = Root then
AAttachNode := nil;
for I := 0 to AIndex - 1 do
ADataNode := ADataNode.Parent;
for I := 0 to Bands.BottomItemCount - 1 do
begin
ABand := Bands.BottomItems[I];
R := cxRectSetYPos(ABand.HeaderCell.DisplayRect,
ABounds.Top, ABounds.Bottom);
AClipRect := cxRectSetYPos(ABand.HeaderCell.VisibleRect,
ABounds.Top, ABounds.Bottom);
if (ADataNode <> Root) and (ABand = Bands.ExpandableBand) then
begin
Inc(R.Left, AIndent);
if I = 0 then
AClipRect.Left := Min(AClipRect.Left, R.Left);
end;
ACellsClipRect := R;
if (I = 0) and not IsPrinting then
Inc(ACellsClipRect.Left);
if I = Bands.BottomItemCount - 1 then
Dec(ACellsClipRect.Right);
APart := AddBandPart(BandPart[ADataNode = Root], ABand, ADataNode, AAttachNode, R, AClipRect);
APart.FBorders := [bTop, bBottom];
APart.BorderColor := Painter.FooterSeparatorColor;
if (Bands.ExpandableBand = ABand) and (APart.Part = tlbpGroupFooter) then
Include(APart.FBorders, bLeft);
if (I = (Bands.BottomItemCount - 1)) or (APart.Part = tlbpGroupFooter) and
(Bands.BottomItems[I + 1] = Bands.ExpandableBand) then
Include(APart.FBorders, bRight);
if not IsPrinting then
begin
Inc(AClipRect.Top, Painter.FooterSeparatorSize +
Painter.FooterSeparatorSize + Painter.FooterCellOffset);
Dec(AClipRect.Bottom, Painter.FooterBorderSize);
end;
for J := 0 to ABand.VisibleColumnCount - 1 do
begin
AColumn := ABand.VisibleColumns[J];
if ((ADataNode = Root) and not AColumn.Options.Footer) or
((ADataNode <> Root) and not AColumn.Options.GroupFooter) then Continue;
if cxRectIntersect(R, ACellsClipRect, cxRectSetYPos(AColumn.HeaderCell.DisplayRect,
AClipRect.Top, AClipRect.Bottom)) then
begin
if (ABand = Bands.ExpandableBand) and (I <> 0) and not IsPrinting then
Inc(R.Left);
AddColumnFooterItems(ADataNode, AAttachNode, ABand.VisibleColumns[J], R, AClipRect);
end;
end;
AddFixedSeparators(cxRectInflate(ABounds, 0, -Painter.FooterBorderSize), AAttachNode);
end;
end;
procedure TcxTreeListViewInfo.AddHeaderHitTestAreas(
ACell: TcxTreeListHeaderCellViewInfo; AHorz, AVert: Boolean);
begin
if AHorz then
FHitTestCells.Add(TcxTreeListHeaderSizingArea.CreateEx(ACell, dsdHorz));
if AVert then
FHitTestCells.Add(TcxTreeListHeaderSizingArea.CreateEx(ACell, dsdVert));
end;
function TcxTreeListViewInfo.AddImageIndent(ANode: TcxTreeListNode;
AImages: TCustomImageList; var ABounds: TRect; const AClipRect: TRect): TcxTreeListIndentCellViewInfo;
begin
ABounds.Right := ABounds.Left + AImages.Width + cxTreeListIndentOffsetSize div 2;
Result := AddIndent(ANode, ANode, -1, nikImage, ABounds, AClipRect);
Result.InitializeImageIndent(AImages);
end;
function TcxTreeListViewInfo.AddIndent(ANode, AAttachNode: TcxTreeListNode;
ALevel: Integer; AKind: TcxTreeListNodeIndentKind;
var ABounds: TRect; const AClipRect: TRect): TcxTreeListIndentCellViewInfo;
begin
if ALevel <> -1 then
ABounds.Right := ABounds.Left + LevelInfo[ALevel].Size.cx
else
ALevel := ANode.Level;
AddCell(TcxTreeListIndentCellViewInfo, ABounds, AClipRect, Result);
Result.FKind := AKind;
Result.InitializeLevelIndent(ANode, AAttachNode, ALevel);
ABounds.Left := ABounds.Right;
if (bBottom in GridLines) and ANode.IsLastVisible and ((AKind = nikFooter) or not HasFooter(ANode)) then
Include(Result.FBorders, bBottom);
end;
function TcxTreeListViewInfo.AddIndentCheck(ANode: TcxTreeListNode;
var ABounds: TRect; const AClipRect: TRect): TcxTreeListIndentCellViewInfo;
begin
ABounds.Right := ABounds.Left + CheckboxSize.cx;
Result := AddIndent(ANode, ANode, -1, nikCheck, ABounds, AClipRect);
end;
function TcxTreeListViewInfo.AddIndicator(ANode: TcxTreeListNode;
APosition: TcxTreeListIndicatorPosition; var ABounds: TRect): TcxTreeListIndicatorCellViewInfo;
var
R: TRect;
begin
R := ABounds;
R.Right := R.Left + OptionsView.IndicatorWidth;
AddCell(TcxTreeListIndicatorCellViewInfo, R, ABounds, Result);
Result.Initialize(ANode, APosition);
if APosition in [tlipBands, tlipColumns] then
FHeaderCells.Add(Result);
ABounds.Left := R.Right;
if (ANode <> nil) and (TreeList.OptionsCustomizing.NodeSizing or
TreeList.OptionsCustomizing.RowSizing) then
begin
Result.SizingArea := TcxTreeListNodeSizingArea.Create(Result);
FHitTestCells.Add(Result.SizingArea);
end;
end;
procedure TcxTreeListViewInfo.AddNodeBands(AViewData: TcxTreeListNodeViewData);
var
I: Integer;
ABand: TcxTreeListBand;
AClipRect, R: TRect;
begin
AClipRect := cxRectSetTop(cxNullRect, RowOffset[0], AViewData.RowsHeight);
for I := 0 to Bands.BottomItemCount - 1 do
begin
ABand := Bands.BottomItems[I];
R := cxRectSetTop(ABand.HeaderCell.DisplayRect, RowOffset[0], AViewData.RowsHeight);
AClipRect := cxRectSetTop(ABand.HeaderCell.VisibleRect, RowOffset[0], AViewData.RowsHeight);
if I = 0 then
AViewData.Bounds.TopLeft := R.TopLeft;
if ABand.ActuallyExpandable then
Inc(R.Left, AViewData.IndentWidth + Byte(bLeft in GridLines));
if I = 0 then
AViewData.ContentBounds.TopLeft := R.TopLeft;
AViewData.ContentBounds.BottomRight := R.BottomRight;
AViewData.Bounds.BottomRight := R.BottomRight;
AddBandPart(tlbpContent, ABand, AViewData.Node, AViewData.Node, R, AClipRect);
end;
AddFixedSeparators(AClipRect, AViewData.Node);
end;
procedure TcxTreeListViewInfo.AddNodeCategorized(
AViewData: TcxTreeListNodeViewData);
var
AHeight: Integer;
begin
AHeight := AViewData.Node.Height;
if AHeight = 0 then
AHeight := DefaultRowHeight;
if OptionsView.CellAutoHeight then
begin
AHeight := Max(AHeight, LevelInfo[AViewData.Node.Level].Size.cy);
AHeight := TcxFakeCellViewInfo(FakeCell).MeasureHeight(
OptionsView.GetCategorizedColumn, AViewData.Node, True);
end;
TreeList.DoGetNodeHeight(AViewData.Node, AHeight);
AViewData.Bounds := cxRectSetTop(ContentBounds, AViewData.Height, AHeight);
if Bands.VisibleLeftFixedCount = 0 then
OffsetRect(AViewData.Bounds, -HScrollPos, 0);
AViewData.ContentBounds := AViewData.Bounds;
Inc(AViewData.ContentBounds.Left, AViewData.IndentWidth + IndicatorWidth + Byte(bLeft in GridLines));
if (Bands.VisibleRightFixedCount > 0) and (AViewData.ContentBounds.Left > ContentParts[tlbfRight].Left) then
begin
AViewData.ContentBounds.Left := ContentParts[tlbfRight].Left + AViewData.IndentWidth + Byte(bLeft in GridLines);
AViewData.Bounds.Left := ContentParts[tlbfRight].Left;
AddFixedSeparators(AViewData.Bounds, AViewData.Node);
Inc(AViewData.Bounds.Left, FixedSeparatorWidth);
end;
AViewData.Bounds.Right := Min(AViewData.Bounds.Right, Bounds.Right);
AViewData.ContentBounds.Right := AViewData.Bounds.Right;
AddEditCell(AViewData, OptionsView.GetCategorizedColumn, AViewData.ContentBounds,
AViewData.Bounds, TcxTreeListGroupNodeEditViewInfo);
AViewData.RowsHeight := AHeight;
Inc(AViewData.Height, AHeight);
end;
procedure TcxTreeListViewInfo.AddNodeColumns(AViewData: TcxTreeListNodeViewData);
var
I: Integer;
AClipRect, R: TRect;
ARow: TcxTreeListBandRow;
AColumn: TcxTreeListColumn;
begin
for I := ColumnCount - 1 downto 0 do
begin
AColumn := Columns[I];
ARow := AColumn.Position.Row;
R := cxRectSetYPos(AColumn.HeaderCell.DisplayRect, RowOffset[ARow.LineOffset],
RowOffset[ARow.LineOffset + AColumn.Position.LineCount]);
if AColumn.HasIndent then
Inc(R.Left, AViewData.IndentWidth + Byte(bLeft in GridLines));
AClipRect := cxRectSetYPos(AColumn.HeaderCell.VisibleRect, R.Top, R.Bottom);
AddEditCell(AViewData, AColumn, R, AClipRect, TcxTreeListEditCellViewInfo);
end;
end;
procedure TcxTreeListViewInfo.AddNodeFooters(AViewData: TcxTreeListNodeViewData);
var
R, ABounds: TRect;
ANode, AAttachLevelNode: TcxTreeListNode;
AIndex, ALevel, AOffset, AFooterLevel: Integer;
begin
AIndex := 1;
ANode := AViewData.Node;
AAttachLevelNode := ANode;
AViewData.CheckFooterRgn := [bTop, bBottom] * GridLines <> [];
AFooterLevel := ANode.Level;
if not ANode.HasChildren or ANode.Expanded or
(OptionsView.GroupFooters <> tlgfAlwaysVisible) and (ANode.Parent <> Root) then
ANode := ANode.Parent
else
AIndex := 0;
if (OptionsView.GroupFooters = tlgfAlwaysVisible) and
(ANode <> AViewData.Node) and not (ANode = Root) then
Dec(AFooterLevel);
repeat
ABounds := cxRectSetTop(AViewData.Bounds, AViewData.Height - 1 +
Byte(IsPrinting), GroupFooterHeight + 1 - Byte(IsPrinting));
AOffset := LevelInfo[AFooterLevel].Offset;
if OptionsView.ShowRoot or (AFooterLevel > 0) then
Inc(AOffset, TreeList.DefaultIndentSize.cx);
AddFooter(AViewData.Node, AIndex, AOffset, ABounds);
Inc(AViewData.GroupFooterCount);
if Bands.ExpandableBand <> nil then
begin
R := cxRectSetLeft(ABounds, Bands.ExpandableBand.HeaderCell.DisplayRect.Left);
ABounds := cxRectSetLeft(ABounds, Bands.ExpandableBand.HeaderCell.VisibleRect.Left);
for ALevel := Byte(not OptionsView.ShowRoot) to AFooterLevel do
AddIndent(AViewData.Node, AViewData.Node, ALevel, nikFooter, R, ABounds);
end;
Inc(AViewData.Height, GroupFooterHeight);
if ANode.GetNextSiblingVisible <> nil then Break;
ANode := ANode.Parent;
AAttachLevelNode := AAttachLevelNode.Parent;
Dec(AFooterLevel);
Inc(AIndex);
until (ANode = nil) or (ANode = Root) or (AAttachLevelNode.GetNextSiblingVisible <> nil);
end;
procedure TcxTreeListViewInfo.AddNodeIndents(AViewData: TcxTreeListNodeViewData);
var
I, ALevel: Integer;
ABounds, AClipRect: TRect;
AIndent: TcxTreeListIndentCellViewInfo;
begin
AIndent := nil;
ALevel := AViewData.Node.Level;
with Bands.ExpandableBand do
begin
ABounds := cxRectSetHeight(HeaderCell.DisplayRect, DefaultRowHeight);
AClipRect := cxRectSetHeight(HeaderCell.VisibleRect, DefaultRowHeight);
AViewData.IndentWidth := ABounds.Left;
end;
for I := Byte(not OptionsView.ShowRoot) to ALevel do
AIndent := AddIndent(AViewData.Node, AViewData.Node, I, nikLevel, ABounds, AClipRect);
if AViewData.Node.HasCheckbox then
AIndent := AddIndentCheck(AViewData.Node, ABounds, AClipRect);
if HasStateIndent(AViewData.Node) then
begin
AIndent := AddImageIndent(AViewData.Node, LevelInfo[ALevel].StateImages, ABounds, AClipRect);
AIndent.FKind := nikState;
AViewData.StateImageIndent := AIndent;
end;
if LevelInfo[ALevel].Images <> nil then
begin
AIndent := AddImageIndent(AViewData.Node, LevelInfo[ALevel].Images, ABounds, AClipRect);
AViewData.ImageIndent := AIndent;
end;
if AIndent <> nil then
AViewData.IndentWidth := AIndent.BoundsRect.Right - AViewData.IndentWidth
else
AViewData.IndentWidth := 0;
end;
function TcxTreeListViewInfo.AddNodePreview(
AViewData: TcxTreeListNodeViewData): TcxTreeListEditCellViewInfo;
var
AClipRect, ABounds: TRect;
APrevHeight, AHeight: Integer;
begin
if Preview.MaxLineCount > 0 then
AHeight := Preview.MaxLineCount * PreviewLineHeight +
cxTextOffset + OptionsView.VertIncrement
else
AHeight := ContentHeight;
AClipRect := cxRectSetTop(ContentBounds, AViewData.Height, AHeight);
if IsIndicatorVisible then
Inc(AClipRect.Left, OptionsView.IndicatorWidth);
ABounds := AClipRect;
if IndentLeftMost then
begin
Inc(ABounds.Left, AViewData.IndentWidth + Byte(bLeft in GridLines));
if Bands.VisibleLeftFixedCount = 0 then
OffsetRect(ABounds, -HScrollPos, 0);
end;
Result := AddEditCell(AViewData, Preview.Column, ABounds, AClipRect,
TcxTreeListPreviewCellViewInfo) as TcxTreeListPreviewCellViewInfo;
APrevHeight := AHeight;
if Preview.AutoHeight then
AHeight := Min(AHeight, Result.CalculateEditHeight - cxTextOffset - OptionsView.VertIncrement * 2);
TreeList.DoGetPreviewHeight(AViewData.Node, AHeight);
if AHeight < 0 then
AHeight := 0;
if AHeight <> APrevHeight then
begin
FCells.Delete(FCells.Count - 1);
FreeAndNil(Result);
if AHeight > 0 then
begin
if Preview.AutoHeight then
Inc(AHeight, OptionsView.VertIncrement * 2 + cxTextOffset);
ABounds := cxRectSetHeight(ABounds, AHeight);
Result := AddEditCell(AViewData, Preview.Column, ABounds,
cxRectSetHeight(AClipRect, AHeight), TcxTreeListPreviewCellViewInfo);
end;
end;
AViewData.PreviewHeight := AHeight;
Inc(AViewData.Height, AHeight);
end;
procedure TcxTreeListViewInfo.AddNodeStandardContent(
AViewData: TcxTreeListNodeViewData);
var
AHeight: Integer;
begin
AHeight := AViewData.Node.Height;
if AHeight = 0 then
AHeight := DefaultRowHeight * ColumnsRowCount;
if OptionsView.CellAutoHeight then
begin
AHeight := Max(AHeight, LevelInfo[AViewData.Node.Level].Size.cy);
InitializeRows(AHeight, AViewData);
Dec(AViewData.Height, AHeight);
AHeight := CalculateNodeAutoHeight(AViewData);
end;
TreeList.DoGetNodeHeight(AViewData.Node, AHeight);
InitializeRows(AHeight, AViewData);
AddNodeBands(AViewData);
AddNodeColumns(AViewData);
end;
function TcxTreeListViewInfo.AddNodeViewData(ANode: TcxTreeListNode;
AInsert: Boolean): TcxTreeListNodeViewData;
var
R: TRect;
begin
Result := TcxTreeListNodeViewData.Create(Self, ANode,
ColumnCount + Byte(Preview.Active) + ANode.Level + 5);
Result.DrawFocusRect := not TreeList.OptionsSelection.CellSelect or
TreeList.OptionsSelection.InvertSelect;
FCells := Result.Cells;
if AInsert then
NodesViewData.Insert(0, Result)
else
NodesViewData.Add(Result);
if (Bands.ExpandableBand <> nil) then
AddNodeIndents(Result);
if Preview.Active and (Preview.Place = tlppTop) then
AddNodePreview(Result);
if (ColumnCount > 0) and ANode.IsGroupNode then
begin
Result.DrawFocusRect := False;
AddNodeCategorized(Result)
end
else
AddNodeStandardContent(Result);
Result.FocusRectBounds := cxRectSetTop(Result.ContentBounds,
Result.PreviewHeight, Result.RowsHeight - OptionsView.VertIncrement);
if Preview.Active and (Preview.Place = tlppBottom) then
AddNodePreview(Result);
AdjustNodeIndents(Result);
Result.ContentBounds := cxRectSetTop(Result.ContentBounds,
0, Result.Height - Byte(bRight in GridLines));
if HasFooter(ANode) then
AddNodeFooters(Result);
if IsIndicatorVisible then
begin
if Bands.VisibleItemCount = 0 then
begin
Result.Height := DefaultRowHeight;
Result.Bounds.Right := IndicatorWidth
end;
R := cxRectSetTop(Bounds, 0, Result.Height);
AddIndicator(ANode, tlipContent, R);
end;
Result.Bounds := cxRectSetTop(Result.Bounds, 0, Result.Height);
Result.Bounds.Left := Bounds.Left;
end;
procedure TcxTreeListViewInfo.AdjustNodeIndents(
AViewData: TcxTreeListNodeViewData);
var
I, AHeight, ATop: Integer;
begin
ATop := 0;
AHeight := AViewData.Height;
if not IndentLeftMost then
begin
ATop := RowOffset[0];
AHeight := AViewData.RowsHeight;
end;
for I := 0 to Cells.Count - 1 do
if Cells[I] is TcxTreeListIndentCellViewInfo then
TcxTreeListIndentCellViewInfo(Cells[I]).SetSize(ATop, AHeight);
end;
function TcxTreeListViewInfo.CalculateDefaultEditHeight: Integer;
var
I: Integer;
begin
Result := TreeList.FDefaultRowHeight;
FDefaultCellHeight := 0;
if Result = 0 then
begin
for I := 0 to ColumnCount - 1 do
if not Columns[I].IsPreview then
begin
FDefaultCellHeight := Max(FDefaultCellHeight, GetColumnDefaultEditHeight(Columns[I]));
Result := Max(Result, FDefaultCellHeight);
end;
end;
if Preview.Active then
FPreviewLineHeight := GetColumnDefaultEditHeight(Preview.Column)
else
FPreviewLineHeight := 0;
if Result = 0 then
Result := GetFontHeight(TreeList.Font) + cxTextOffset;
Inc(Result, OptionsView.VertIncrement + cxTreeListEditCellHeightOffset);
FHScrollInc := cxTextWidth(TreeList.Font, 'W');
if FDefaultCellHeight = 0 then
FDefaultCellHeight := GetFontHeight(TreeList.Font) + cxTextOffset;
Result := Max(Result, TreeList.DefaultIndentSize.cy);
end;
procedure TcxTreeListViewInfo.CalculateDefaultHeights;
var
I: Integer;
begin
FFooterLineHeight := 0;
if not OptionsView.Bands then
FBandLineHeight := 0
else
begin
FBandHeaderLineHeight := 0;
for I := 0 to Bands.VisibleItemCount - 1 do
FBandHeaderLineHeight := Max(FBandHeaderLineHeight, Painter.HeaderHeight(
GetFontHeight(Styles.GetBandHeaderParams(Bands.VisibleItems[I]).Font)));
FBandLineHeight := OptionsView.BandLineHeight;
if FBandLineHeight = 0 then
FBandLineHeight := FBandHeaderLineHeight;
end;
for I := 0 to ColumnCount - 1 do
begin
if OptionsView.Headers then
FHeaderLineHeight := Max(FHeaderLineHeight, Painter.HeaderHeight(
GetFontHeight(Styles.GetColumnHeaderParams(Columns[I]).Font)));
if OptionsView.Footer and Columns[I].Options.Footer then
FFooterLineHeight := Max(FFooterLineHeight, Painter.HeaderHeight(
GetFontHeight(Styles.GetColumnFooterParams(Columns[I], Root).Font)));
end;
if OptionsView.Footer then
begin
if FFooterLineHeight = 0 then
FFooterLineHeight := Painter.HeaderHeight(GetFontHeight(TreeList.Font));
end;
if FHeaderLineHeight = 0 then
FHeaderLineHeight := Painter.HeaderHeight(GetFontHeight(TreeList.Font));
if FFooterLineHeight = 0 then
FFooterLineHeight := Painter.HeaderHeight(GetFontHeight(TreeList.Font));
Inc(FFooterLineHeight, Painter.FooterCellOffset);
inherited CalculateDefaultHeights;
end;
procedure TcxTreeListViewInfo.AfterCalculate;
var
I: Integer;
begin
CorrectBorders;
if FDragItem = nil then Exit;
TreeList.Controller.DragItem := nil;
for I := 0 to Cells.Count - 1 do
if (Cells[I] is TcxTreeListHeaderCellViewInfo) and
(TcxTreeListHeaderCellViewInfo(Cells[I]).Item = FDragItem) then
TreeList.Controller.DragItem := TcxTreeListHeaderCellViewInfo(Cells[I]);
end;
procedure TcxTreeListViewInfo.BeforeCalculate;
begin
RecreateCheckBoxViewData;
FBounds := TreeList.ClientBounds;
FRows := AllocMem((ColumnsRowCount + 1) * SizeOf(Integer));
FGridLineColor := OptionsView.GridLineColor;
if FGridLineColor = clDefault then
FGridLineColor := Painter.DefaultGridLineColor;
FGridLines := GridLineBorders[OptionsView.GridLines];
FTreeLineColor := ColorToRGB(cxGetNativeColor(
OptionsView.TreeLineColor, Painter.DefaultGridLineColor));
end;
procedure TcxTreeListViewInfo.CalculateBackgroundParts;
var
ABounds: TRect;
begin
ABounds := Bounds;
// right part
Inc(ABounds.Left, ContentWidth);
if ContentWidth = 0 then
Inc(ABounds.Left, IndicatorWidth);
if not cxRectIsEmpty(ABounds) then
AddBackgroundPart(ABounds);
Dec(ABounds.Left, ContentWidth);
//bottom part
ABounds := cxRectSetYPos(ContentBounds, ContentBounds.Bottom,
Bounds.Bottom - FooterHeight);
if FHorzBackgroundCell <> nil then
FHorzBackgroundCell.SetBounds(ABounds, ABounds)
else
if not cxRectIsEmpty(ABounds) then
FHorzBackgroundCell := AddBackgroundPart(ABounds);
end;
procedure TcxTreeListViewInfo.CalculateBandsLayout;
var
I: Integer;
AKind: TcxTreeListBandFixedKind;
ABounds, AClipBounds, R: TRect;
ALengths: array[TcxTreeListBandFixedKind] of Integer;
begin
FContentWidth := 0;
ABounds := cxRectSetHeight(Bounds, BandsHeight + HeadersHeight);
if IsIndicatorVisible then
begin
R := cxRectSetHeight(ABounds, BandsHeight);
AddIndicator(nil, tlipBands, R);
FContentWidth := OptionsView.IndicatorWidth;
Inc(ABounds.Left, OptionsView.IndicatorWidth);
end;
AClipBounds := ABounds;
FillChar(ALengths, SizeOf(ALengths), 0);
FillChar(FContentParts, SizeOf(FContentParts), 0);
for I := 0 to Bands.BottomItemCount - 1 do
with Bands.BottomItems[I] do
Inc(ALengths[FixedKind], DisplayWidth);
Inc(FContentWidth, ALengths[tlbfLeft] + ALengths[tlbfNone] + ALengths[tlbfRight]);
if Bands.VisibleLeftFixedCount > 0 then
begin
FContentParts[tlbfLeft] := cxRectSetWidth(ABounds, ALengths[tlbfLeft]);
AddBandsHeaders(tlbfLeft, FContentParts[tlbfLeft], AClipBounds);
Inc(ABounds.Left, ALengths[tlbfLeft]);
AddBandSeparator(nil, ABounds, ABounds);
AClipBounds.Left := ABounds.Left;
Inc(FContentWidth, FixedSeparatorWidth);
end;
FContentParts[tlbfNone] := cxRectSetLeft(ABounds, ABounds.Left, ALengths[tlbfNone]);
if Bands.VisibleRightFixedCount > 0 then
begin
FContentParts[tlbfRight] := cxRectSetLeft(ABounds, Min(FContentParts[tlbfNone].Right,
Bounds.Right - ALengths[tlbfRight] - FixedSeparatorWidth),
ALengths[tlbfRight] + FixedSeparatorWidth);
ABounds.Right := FContentParts[tlbfRight].Left;
AClipBounds.Left := Max(FContentParts[tlbfRight].Left, ABounds.Left);
AddBandSeparator(nil, FContentParts[tlbfRight], AClipBounds);
AddBandsHeaders(tlbfRight, FContentParts[tlbfRight], AClipBounds);
Inc(FContentWidth, FixedSeparatorWidth);
end;
for AKind := Low(TcxTreeListBandFixedKind) to High(TcxTreeListBandFixedKind) do
FContentParts[AKind].Bottom := Bounds.Bottom;
CalculateHorzScrollInfo(cxRectWidth(ABounds), ALengths[tlbfNone]);
OffsetRect(FContentParts[tlbfNone], -HScrollPos, 0);
AddBandsHeaders(tlbfNone, FContentParts[tlbfNone], ABounds);
end;
procedure TcxTreeListViewInfo.CalculateColumnsLayout;
var
I, ARowIndex, AColIndex: Integer;
ABand: TcxTreeListBand;
ARow: TcxTreeListBandRow;
AColumn: TcxTreeListColumn;
ABounds, AClipBounds, ARowBounds: TRect;
begin
FMultiRows := False;
if IsIndicatorVisible then
begin
ABounds := cxRectSetTop(Bounds, Bounds.Top + BandsHeight, HeadersHeight);
AddIndicator(nil, tlipColumns, ABounds);
end;
for I := 0 to Bands.BottomItemCount - 1 do
begin
ABand := Bands.BottomItems[I];
ABounds := cxRectSetTop(ABand.HeaderCell.BoundsRect,
Bounds.Top + BandsHeight, HeadersHeight);
AClipBounds := cxRectSetTop(ABand.HeaderCell.VisibleRect,
Bounds.Top + BandsHeight, HeadersHeight);
AddBandPart(tlbpHeader, ABand, nil, nil, ABounds, AClipBounds);
FMultiRows := FMultiRows or (ABand.BandRows.VisibleItemCount > 1);
for ARowIndex := 0 to ABand.BandRows.VisibleItemCount - 1 do
begin
ARow := ABand.BandRows.VisibleItems[ARowIndex];
ARowBounds := cxRectSetTop(ABounds,
ABounds.Top + ARow.LineOffset * HeaderLineHeight, ARow.LineCount * HeaderLineHeight);
for AColIndex := 0 to ARow.VisibleItemCount - 1 do
begin
AColumn := ARow.VisibleItems[AColIndex];
ARowBounds.Bottom := ARowBounds.Top + AColumn.Position.LineCount * HeaderLineHeight;
AddColumnHeader(AColumn, ARowBounds, AClipBounds);
end;
end;
end;
end;
procedure TcxTreeListViewInfo.CalculateHeadersNeighbors;
var
I, J, AShift: Integer;
ACell: TcxTreeListCustomHeaderCellViewInfo;
begin
AShift := Byte(Painter.HeaderBorders([nLeft..nBottom]) <> cxBordersAll);
for I := 0 to FHeaderCells.Count - 1 do
begin
ACell := TcxTreeListCustomHeaderCellViewInfo(FHeaderCells[I]);
ACell.FIsLast := (ACell.BoundsRect.Right = ContentBounds.Right);
for J := I + 1 to FHeaderCells.Count - 1 do
ACell.CheckNeighbors(TcxTreeListHeaderCellViewInfo(FHeaderCells[J]), AShift);
end;
end;
procedure TcxTreeListViewInfo.CalculateHitTest(
AHitTest: TcxTreeListHitTest);
var
I: Integer;
begin
Validate;
Cells.CalculateHitTest(AHitTest);
if PtInRect(ContentBounds, AHitTest.HitPoint) then
begin
for I := 0 to Count - 1 do
if NodeViewData[I].Cells.CalculateHitTest(AHitTest) then Break;
end;
for I := 0 to HitTestCells.Count - 1 do
if TcxTreeListHitTestArea(HitTestCells[I]).GetHitTest(AHitTest) then Break;
end;
procedure TcxTreeListViewInfo.CalculateHorzScrollInfo(
AAvailableWidth, AContentWidth: Integer);
var
APos: Integer;
begin
FHScrollPage := AAvailableWidth;
FHScrollSize := AContentWidth;
APos := FHScrollPos;
ValidateScrollPos(APos, FHScrollPage, FContentWidth);
if AContentWidth > AAvailableWidth then
begin
FHScrollArea := cxRectSetXPos(ContentParts[tlbfNone], Max(ContentParts[
tlbfNone].Left, Bounds.Left), Min(ContentParts[tlbfNone].Right, Bounds.Right));
if Bands.VisibleRightFixedCount > 0 then
FHScrollArea.Right := ContentParts[tlbfRight].Left - FixedSeparatorWidth;
if Bands.VisibleLeftFixedCount > 0 then
FHScrollArea.Left := ContentParts[tlbfLeft].Right + FixedSeparatorWidth;
end
else
FHScrollArea := cxNullRect;
HScrollPos := APos;
end;
procedure TcxTreeListViewInfo.CalculateFooterLayout;
var
ABounds: TRect;
begin
ABounds := Bounds;
ABounds.Top := ABounds.Bottom - FooterHeight;
ABounds.Right := ContentBounds.Right;
if IsIndicatorVisible then
AddIndicator(nil, tlipFooter, ABounds);
if (Bands.VisibleItemCount > 0) and (FooterHeight > 0) then
AddFooter(Root, 0, 0, ABounds);
end;
function TcxTreeListViewInfo.CalculateNodeAutoHeight(
AViewData: TcxTreeListNodeViewData): Integer;
var
ARow: TcxTreeListBandRow;
I, AFinishRow, AHeight: Integer;
begin
for I := 0 to ColumnCount - 1 do
begin
ARow := Columns[I].Position.Row;
AHeight := TcxFakeCellViewInfo(FakeCell).MeasureHeight(Columns[I], AViewData.Node, False);
AFinishRow := ARow.LineOffset + Columns[I].Position.LineCount;
RowOffset[AFinishRow] := Max(RowOffset[AFinishRow] -
RowOffset[ARow.LineOffset], RowOffset[ARow.LineOffset] + AHeight);
end;
Result := RowOffset[ColumnsRowCount] - RowOffset[0];
AViewData.RowsHeight := Result;
end;
procedure TcxTreeListViewInfo.CalculateNodesOrigin;
var
AOffset: TPoint;
I, ALastPos: Integer;
begin
I := 0;
FNodesVisibleCount := 0;
AOffset := Point(0, ContentBounds.Top);
ALastPos := Bounds.Bottom - FooterHeight;
FContentHeight := ALastPos;
while I < Count do
begin
NodeViewData[I].Origin := AOffset;
Inc(AOffset.Y, NodeViewData[I].Height);
Inc(I);
if (AOffset.Y <= ALastPos) or (FNodesVisibleCount = 0) then
Inc(FNodesVisibleCount)
else
while I < Count do
DeleteNodeViewData(I);
end;
if AOffset.Y < ALastPos then
begin
FContentHeight := AOffset.Y;
if FHorzBackgroundCell = nil then
FHorzBackgroundCell := AddBackgroundPart(cxRectSetYPos(ContentBounds, AOffset.Y, ALastPos))
else
FHorzBackgroundCell.SetBounds(cxRectSetYPos(ContentBounds, AOffset.Y, ALastPos), Bounds);
end
else
if FHorzBackgroundCell <> nil then
FHorzBackgroundCell.SetBounds(cxEmptyRect, cxEmptyRect);
FContentHeight := FContentHeight - ContentBounds.Top;
if (NodesVisibleCount > 0) and (TreeList.FTopVisibleNode <> NodeViewData[0].Node) then
begin
TreeList.FTopVisibleNode := NodeViewData[0].Node;
TreeList.DoTopRecordIndexChanged;
end;
RecalculateHitTestCells;
end;
procedure TcxTreeListViewInfo.CalculateNodesViewData;
var
AHeight: Integer;
ANode: TcxTreeListNode;
begin
ANode := TreeList.TopVisibleNode;
if (ANode = nil) or (TreeList.AbsoluteVisibleCount = 0) then
begin
FContentHeight := 0;
Exit;
end;
FContentHeight := cxRectHeight(Bounds) - HeadersHeight - BandsHeight - FooterHeight;
AHeight := FContentHeight;
CalculateNodesViewDataForward(ANode, AHeight);
CalculateNodesViewDataBackward(ANode.GetPrevVisible, True, AHeight);
CalculateNodesOrigin;
end;
procedure TcxTreeListViewInfo.CalculateNodesViewDataBackward(
ANode: TcxTreeListNode; ACheckHeight: Boolean; var AvailableHeight: Integer);
var
APrevHeight: Integer;
ACells: TcxCustomControlCells;
AViewData: TcxTreeListNodeViewData;
begin
ACells := FCells;
try
while (ANode <> nil) and (AvailableHeight > 0) do
begin
APrevHeight := AvailableHeight;
AViewData := AddNodeViewData(ANode, True);
Dec(AvailableHeight, AViewData.Height);
if ACheckHeight and (AvailableHeight < 0) and (Count > 1) then
begin
AvailableHeight := APrevHeight;
FNodesViewData.Delete(0);
AViewData.Free;
Break;
end;
ANode := ANode.GetPrevVisible;
end;
finally
FCells := ACells;
end;
end;
procedure TcxTreeListViewInfo.CalculateNodesViewDataForward(
ANode: TcxTreeListNode; var AvailableHeight: Integer);
var
ACells: TcxCustomControlCells;
begin
ACells := FCells;
try
while (ANode <> nil) and (AvailableHeight > 0) do
begin
Dec(AvailableHeight, AddNodeViewData(ANode, False).Height);
ANode := ANode.GetNextVisible;
end;
finally
FCells := ACells;
end;
end;
procedure TcxTreeListViewInfo.CellsChanged;
begin
TreeList.Controller.ViewInfoChanged;
end;
function TcxTreeListViewInfo.CheckScrollPosition(AScrollCode: TScrollCode;
APos, APage, AInc, AMax : Integer; var AScrollPos: Integer): Boolean;
begin
case AScrollCode of
scLineUp:
AScrollPos := APos - AInc;
scLineDown:
AScrollPos := APos + AInc;
scPageUp:
AScrollPos := APos - APage;
scPageDown:
AScrollPos := APos + APage;
scTop:
AScrollPos := 0;
scBottom:
AScrollPos := AMax;
scTrack:
AScrollCode := scPosition;
end;
if AScrollPos < 0 then
AScrollPos := 0
else
if AScrollPos + APage > AMax then AScrollPos := AMax - APage;
if AScrollCode = scPosition then cxRange(AScrollPos, 0, AMax);
Result := AScrollPos <> APos;
end;
procedure TcxTreeListViewInfo.CorrectBorders;
var
I, L, ARow: Integer;
ABand: TcxTreeListBand;
begin
if Painter.HeaderBorders([nLeft..nBottom]) = cxBordersAll then Exit;
for I := 0 to Bands.VisibleRootItemCount - 2 do
begin
ABand := Bands.VisibleRootItems[I];
if ABand.FixedKind <> Bands.VisibleRootItems[I + 1].FixedKind then
begin
repeat
Inc(ABand.HeaderCell.DisplayRect.Right, 1);
if ABand.ChildVisibleBands.Count > 0 then
ABand := TcxTreeListBand(ABand.ChildVisibleBands.Last);
until ABand.IsBottom;
for ARow := 0 to ABand.BandRows.VisibleItemCount - 1 do
begin
L := ABand.BandRows[ARow].VisibleItemCount - 1;
if L > 0 then
Inc(ABand.BandRows[ARow].VisibleItems[L].HeaderCell.DisplayRect.Right, 1);
end;
end;
end;
end;
procedure TcxTreeListViewInfo.Clear;
begin
FHitTestCells.Clear;
FDragItem := nil;
if TreeList.Controller.DragItem is TcxTreeListHeaderCellViewInfo then
FDragItem := TcxTreeListHeaderCellViewInfo(TreeList.Controller.DragItem).Item;
TreeList.Controller.DragItem := nil;
FreeMem(FRows);
FHorzBackgroundCell := nil;
FRows := nil;
FHeaderCells.Clear;
FPrevFont := nil;
FCells.Clear;
FNodesViewData.Clear;
end;
procedure TcxTreeListViewInfo.DeleteNodeViewData(AIndex: Integer);
begin
FNodesViewData[AIndex].Free;
FNodesViewData.Delete(AIndex);
end;
procedure TcxTreeListViewInfo.DoCalculate;
begin
inherited DoCalculate;
CalculateInProcess := True;
CellsChanged;
IsDirty := False;
Clear;
BeforeCalculate;
try
CalculateBandsLayout;
CalculateColumnsLayout;
CalculateNodesViewData;
CalculateFooterLayout;
CalculateBackgroundParts;
Cells.Sort(@cxCompareCells);
CalculateHeadersNeighbors;
HitTestCells.Sort(@cxCompareHitTestCells);
finally
AfterCalculate;
CalculateInProcess := False;
end;
end;
function TcxTreeListViewInfo.GetContentBounds: TRect;
begin
Result := Bounds;
Inc(Result.Top, HeadersHeight + BandsHeight);
Result.Bottom := Result.Top + FContentHeight;
Result.Right := Result.Left + FContentWidth;
end;
function TcxTreeListViewInfo.GetFontHeight(const AFont: TFont): Integer;
begin
if AFont <> FPrevFont then
begin
FPrevFont := AFont;
FPrevFontHeight := cxTextHeight(AFont);
end;
Result := FPrevFontHeight;
end;
function TcxTreeListViewInfo.GetIsIndicatorVisible: Boolean;
begin
Result := OptionsView.IsIndicatorVisible;
end;
function TcxTreeListViewInfo.GetIsPrinting: Boolean;
begin
Result := False;
end;
function TcxTreeListViewInfo.GetLevelContentOffset(ALevel: Integer): Integer;
begin
Result := LevelInfo[ALevel].Offset + LevelInfo[ALevel].Width;
end;
function TcxTreeListViewInfo.GetNodeContentOffset(ANode: TcxTreeListNode): Integer;
begin
Result := GetLevelContentOffset(ANode.Level);
if ANode.HasCheckbox then
Result := Result + Painter.CheckButtonSize.cx + Painter.CheckBorderSize;
end;
function TcxTreeListViewInfo.HasFooter(ANode: TcxTreeListNode): Boolean;
begin
Result := False;
if OptionsView.GroupFooters = tlgfAlwaysVisible then
Result := (ANode.HasChildren and not ANode.Expanded) or
(not ANode.HasChildren and (ANode.GetNextSiblingVisible = nil) and (ANode.Parent <> Root))
else
if OptionsView.GroupFooters = tlgfVisibleWhenExpanded then
Result := not ANode.Expanded and (ANode.GetNextSiblingVisible = nil) and (ANode.Level > 0);
end;
function TcxTreeListViewInfo.HasStateIndent(ANode: TcxTreeListNode): Boolean;
begin
if LevelInfo[ANode.Level].StateImages = nil then
Result := False
else
Result := (not OptionsView.DynamicFocusedStateImages or ANode.Focused) and
cxInRange(ANode.StateIndex, 0, LevelInfo[ANode.Level].StateImages.Count - 1);
end;
procedure TcxTreeListViewInfo.InflateBoundsForGridLines(
var ABounds, AClipRect: TRect);
begin
if bTop in GridLines then
begin
if ABounds.Top = AClipRect.Top then
Dec(AClipRect.Top);
Dec(ABounds.Top);
end;
if bLeft in GridLines then
begin
if ABounds.Left = AClipRect.Left then
Dec(AClipRect.Left);
Dec(ABounds.Left);
end;
end;
procedure TcxTreeListViewInfo.InitializeRows(
const ANewHeight: Integer; var AViewData: TcxTreeListNodeViewData);
var
I: Integer;
AScaleFactor: Double;
begin
if AViewData.RowsHeight = 0 then
begin
AViewData.RowsOffset := AViewData.Height;
FRows^[0] := AViewData.Height;
if ANewHeight = 0 then Exit;
for I := 1 to ColumnsRowCount do
FRows^[I] := MulDiv(ANewHeight, I, ColumnsRowCount) + AViewData.RowsOffset;
end
else
if AViewData.RowsHeight <> ANewHeight then
begin
AScaleFactor := ANewHeight / AViewData.RowsHeight;
for I := ColumnsRowCount downto 1 do
FRows^[I] := Round((FRows^[I] - FRows^[I - 1]) * AScaleFactor);
for I := 1 to ColumnsRowCount do
FRows^[I] := FRows^[I] + FRows^[I - 1];
FRows^[ColumnsRowCount] := ANewHeight;
end;
AViewData.RowsHeight := ANewHeight;
Inc(AViewData.Height, ANewHeight);
end;
procedure TcxTreeListViewInfo.InitScrollBarsParameters;
begin
Validate;
TreeList.SetScrollBarInfo(sbHorizontal, 0, HScrollSize - 1,
HScrollInc, HScrollPage, HScrollPos, True, True);
TreeList.SetScrollBarInfo(sbVertical, 0, VScrollSize - 1, 1,
VScrollPage, VScrollPos, True, True);
end;
procedure TcxTreeListViewInfo.InvalidateRect(const ARect: TRect);
begin
TreeList.InvalidateRectEx(ARect, False);
end;
procedure TcxTreeListViewInfo.MakeVisible(ANode: TcxTreeListNode);
var
APos: Integer;
begin
APos := VScrollPos + 1;
while ANode.ViewData.GetRealBounds.Bottom > ContentBounds.Bottom do
ScrollVert(scLineDown, APos);
TreeList.ViewInfo.IsDirty := False;
UpdateScrollBars;
end;
procedure TcxTreeListViewInfo.RecalculateHitTestCells;
var
I: Integer;
begin
for I := 0 to HitTestCells.Count - 1 do
TcxTreeListHitTestArea(HitTestCells[I]).Calculate;
end;
procedure TcxTreeListViewInfo.RecreateCheckBoxViewData;
begin
FreeAndNil(FCheckBoxViewData);
FCheckBoxViewData := FCheckBoxProperties.CreateViewData(TreeList.EditStyle, True);
end;
procedure TcxTreeListViewInfo.ScrollHorz(
AScrollCode: TScrollCode; var AScrollPos: Integer);
begin
CheckScrollPosition(AScrollCode, HScrollPos, HScrollPage, HScrollInc,
HScrollSize + HScrollInc, AScrollPos);
HScrollPos := AScrollPos;
end;
procedure TcxTreeListViewInfo.ScrollVert(
AScrollCode: TScrollCode; var AScrollPos: Integer);
var
ANode: TcxTreeListNode;
AHeight, APrevPos: Integer;
begin
if (TopNode = nil) or (Count = 0) then Exit;
APrevPos := VScrollPos;
AHeight := 1;
if (AScrollCode in [scLineUp, scPageUp]) and not TopNode.IsFirstVisible then
begin
if AScrollCode = scPageUp then
AHeight := Max(1, cxRectHeight(Bounds) - HeadersHeight - BandsHeight -
FooterHeight - NodeViewData[NodesVisibleCount - 1].Height);
CalculateNodesViewDataBackward(TopNode.GetPrevVisible, False, AHeight);
end
else
if AScrollCode = scLineDown then
begin
ANode := NodeViewData[Count - 1].Node;
if (ANode <> TopNode) and (not ANode.IsLastVisible or (Count > NodesVisibleCount)) then
begin
AHeight := NodeViewData[0].Height;
DeleteNodeViewData(0);
if (ANode.GetNextVisible = nil) and (ANode <> TopNode) then
TreeList.TopVisibleNode := TopNode.GetNextVisible
else
CalculateNodesViewDataForward(ANode.GetNextVisible, AHeight);
end
else
if (ANode = TopNode) and not ANode.IsLastVisible then
TreeList.TopVisibleNode := ANode.GetNextVisible;
end
else
if AScrollCode = scPageDown then
begin
if (LastNode = TopNode) and (LastNode.GetNextVisible <> nil) then
TreeList.TopVisibleNode := LastNode.GetNextVisible
else
TreeList.TopVisibleNode := LastNode;
end
else
if AScrollCode in [scTrack, scPosition] then
begin
TreeList.TopVisibleNode := TreeList.AbsoluteVisibleItems[Min(TreeList.AbsoluteVisibleCount - 1,
Max(0, AScrollPos))];
end;
CalculateNodesOrigin;
AScrollPos := VScrollPos;
if APrevPos <> VScrollPos then
InvalidateRect(ContentBounds);
if FHorzBackgroundCell <> nil then
FHorzBackgroundCell.Invalidate;
end;
procedure TcxTreeListViewInfo.SetDirty;
begin
IsDirty := True;
Clear;
end;
procedure TcxTreeListViewInfo.UpdateScrollBars;
begin
if TreeList.HandleAllocated then
TreeList.UpdateScrollBars;
end;
procedure TcxTreeListViewInfo.UpdateSelection;
var
I: Integer;
AFullUpdate: Boolean;
begin
inherited UpdateSelection;
if Validate then
begin
InvalidateRect(Bounds);
Exit;
end;
AFullUpdate := False;
for I := 0 to Count - 1 do
begin
if not NodeViewData[I].Update(False) then Continue;
AFullUpdate := AFullUpdate or ((NodeViewData[I].StateImageIndent <> nil)
<> HasStateIndent(NodeViewData[I].Node));
end;
if AFullUpdate then
begin
DoCalculate;
if OptionsView.CellAutoHeight then
InvalidateRect(cxRectSetYPos(Bounds,
BandsHeight + HeadersHeight, Bounds.Bottom - FooterHeight));
end;
end;
procedure TcxTreeListViewInfo.ValidateScrollPos(
var APosition: Integer; const APage, AMax: Integer);
begin
if APosition + APage > AMax then
APosition := Max(0, AMax - APage)
else
APosition := Max(APosition, 0);
end;
function TcxTreeListViewInfo.GetBands: TcxTreeListBands;
begin
Result := TreeList.Bands;
end;
function TcxTreeListViewInfo.GetBandsHeight: Integer;
begin
if OptionsView.Bands then
begin
Result := Bands.LineCount * BandLineHeight;
if IsIndicatorVisible and (Result = 0) then
Result := DefaultRowHeight;
end
else
Result := 0;
end;
function TcxTreeListViewInfo.GetBorderSize: Integer;
begin
Result := TreeList.BorderSize;
end;
function TcxTreeListViewInfo.GetCalculateInProcess: Boolean;
begin
Result := State[cvis_ViewInfoCalculate];
end;
function TcxTreeListViewInfo.GetCheckBoxSize: TSize;
begin
Result := Painter.CheckButtonSize;
Inc(Result.cx, cxTextOffset * 2);
Inc(Result.cy, cxTextOffset * 2);
end;
function TcxTreeListViewInfo.GetColumn(AIndex: Integer): TcxTreeListColumn;
begin
Result := TreeList.VisibleColumns[AIndex];
end;
function TcxTreeListViewInfo.GetColumnCount: Integer;
begin
Result := TreeList.VisibleColumnCount;
end;
function TcxTreeListViewInfo.GetColumnDefaultEditHeight(
AColumn: TcxTreeListColumn): Integer;
begin
Result := AColumn.GetEditDefaultHeight(
AColumn.Styles.GetContentParams(Root.FFirst).Font);
if Root.FFirst = nil then Exit;
Result := Max(Result, AColumn.GetEditDefaultHeight(
AColumn.Styles.GetContentParams(Root.FFirst.GetNextVisible).Font));
end;
function TcxTreeListViewInfo.GetColumnsRowCount: Integer;
begin
Result := Bands.ColumnsLineCount;
end;
function TcxTreeListViewInfo.GetContentPart(
AKind: TcxTreeListBandFixedKind): TRect;
begin
Result := FContentParts[AKind];
end;
function TcxTreeListViewInfo.GetCount: Integer;
begin
Result := FNodesViewData.Count;
end;
function TcxTreeListViewInfo.GetDefaultRowHeight: Integer;
begin
Result := DefaultEditHeight;
end;
function TcxTreeListViewInfo.GetFixedSeparatorWidth: Integer;
begin
Result := OptionsView.FixedSeparatorWidth;
end;
function TcxTreeListViewInfo.GetFooterHeight: Integer;
begin
Result := FooterLineCount * FooterLineHeight;
if (Result = 0) or IsPrinting then
Exit;
Result := Result + Painter.FooterSeparatorSize +
Painter.FooterCellOffset + Painter.FooterBorderSize;
end;
function TcxTreeListViewInfo.GetFooterLineCount: Integer;
begin
if not OptionsView.Footer then
Result := 0
else
if not MultiRows then
Result := Max(1, Summary.FooterSummaryRowCount)
else
Result := Max(1, ColumnsRowCount);
end;
function TcxTreeListViewInfo.GetGroupFooterHeight: Integer;
begin
Result := GroupFooterLineCount * FooterLineHeight;
if (Result = 0) or IsPrinting then Exit;
Result := Result + Painter.FooterSeparatorSize +
Painter.FooterCellOffset + Painter.FooterBorderSize;
end;
function TcxTreeListViewInfo.GetGroupFooterLineCount: Integer;
begin
if OptionsView.GroupFooters = tlgfInvisible then
Result := 0
else
if not MultiRows then
Result := Max(1, Summary.GroupFooterSummaryRowCount)
else
Result := Max(1, ColumnsRowCount);
end;
function TcxTreeListViewInfo.GetHeadersHeight: Integer;
begin
if OptionsView.Headers then
begin
Result := ColumnsRowCount * HeaderLineHeight;
if IsIndicatorVisible and (Result = 0) then
Result := DefaultRowHeight;
end
else
Result := 0;
end;
function TcxTreeListViewInfo.GetImages: TCustomImageList;
begin
Result := TreeList.Images;
end;
function TcxTreeListViewInfo.GetIndentBand: TcxTreeListBand;
begin
Result := Bands.ExpandableBand;
end;
function TcxTreeListViewInfo.GetIndentLeftMost: Boolean;
begin
Result := (IndentBand <> nil) and
(IndentBand = Bands.BottomItems[0]);
end;
function TcxTreeListViewInfo.GetIndicatorWidth: Integer;
begin
if IsIndicatorVisible then
Result := OptionsView.IndicatorWidth
else
Result := 0;
end;
function TcxTreeListViewInfo.GetLastNode: TcxTreeListNode;
begin
if FNodesVisibleCount > 0 then
Result := NodeViewData[FNodesVisibleCount - 1].Node
else
Result := nil;
end;
function TcxTreeListViewInfo.GetLevelInfo(
ALevel: Integer): TcxTreeListLevelInfo;
begin
Result := TreeList.LevelsInfo[ALevel];
end;
function TcxTreeListViewInfo.GetNodeViewData(
AIndex: Integer): TcxTreeListNodeViewData;
begin
Result := TcxTreeListNodeViewData(FNodesViewData[AIndex])
end;
function TcxTreeListViewInfo.GetOptionsView: TcxTreeListOptionsView;
begin
Result := TreeList.OptionsView;
end;
function TcxTreeListViewInfo.GetOriginalViewInfo: TcxTreeListViewInfo;
begin
Result := TreeList.ViewInfo;
end;
function TcxTreeListViewInfo.GetPainter: TcxCustomLookAndFeelPainterClass;
begin
Result := inherited LookAndFeelPainter;
end;
function TcxTreeListViewInfo.GetPreview: TcxTreeListPreview;
begin
Result := TreeList.Preview;
end;
function TcxTreeListViewInfo.GetRoot: TcxTreeListNode;
begin
Result := TreeList.Root;
end;
function TcxTreeListViewInfo.GetRowOffset(AIndex: Integer): Integer;
begin
Result := FRows^[AIndex];
end;
function TcxTreeListViewInfo.GetSummary: TcxTreeListSummary;
begin
Result := TreeList.Summary;
end;
function TcxTreeListViewInfo.GetStateImages: TCustomImageList;
begin
Result := TreeList.StateImages;
end;
function TcxTreeListViewInfo.GetStyles: TcxTreeListStyles;
begin
Result := TreeList.Styles;
end;
function TcxTreeListViewInfo.GetTopNode: TcxTreeListNode;
begin
Result := TreeList.TopVisibleNode;
if (Result <> nil) and not Result.Visible then
Result := Result.GetNextVisible;
if Result = nil then
begin
Result := TreeList.TopVisibleNode;
if Result <> nil then
Result := Result.GetPrevVisible;
end;
end;
function TcxTreeListViewInfo.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(Control)
end;
function TcxTreeListViewInfo.GetVScrollPage: Integer;
begin
Result := Max(1, FNodesVisibleCount);
end;
function TcxTreeListViewInfo.GetVScrollPos: Integer;
begin
Result := 0;
if TopNode <> nil then
Result := TopNode.VisibleIndex;
end;
function TcxTreeListViewInfo.GetVScrollSize: Integer;
begin
Result := TreeList.AbsoluteVisibleCount;
end;
procedure TcxTreeListViewInfo.SetCalculateInProcess(AValue: Boolean);
begin
State[cvis_ViewInfoCalculate] := AValue;
end;
procedure TcxTreeListViewInfo.SetHScrollPos(APosition: Integer);
var
I: Integer;
begin
ValidateScrollPos(APosition, FHScrollPage, FHScrollSize);
if APosition = FHScrollPos then Exit;
for I := 0 to Cells.Count - 1 do
TcxTreeListCustomCellViewInfo(Cells[I]).Scroll(FHScrollPos - APosition, 0);
for I := 0 to Count - 1 do
NodeViewData[I].Scroll(FHScrollPos - APosition, 0,
Bands.VisibleLeftFixedCount > 0, Bands.VisibleRightFixedCount > 0);
RecalculateHitTestCells;
FHScrollPos := APosition;
InvalidateRect(HScrollArea);
end;
procedure TcxTreeListViewInfo.SetLastNode(ANode: TcxTreeListNode);
var
AHeight: Integer;
begin
NodesViewData.Clear;
AHeight := Max(1, cxRectHeight(Bounds) - HeadersHeight - BandsHeight - FooterHeight);
CalculateNodesViewDataBackward(ANode, False, AHeight);
if (AHeight < 0) and (Count > 1) then
TreeList.TopVisibleNode := NodeViewData[1].Node
else
TreeList.TopVisibleNode := NodeViewData[0].Node;
end;
procedure TcxTreeListViewInfo.SetRowOffset(
AIndex: Integer; const AValue: Integer);
var
I, D: Integer;
begin
D := AValue - FRows^[AIndex];
FRows^[AIndex] := AValue;
if D > 0 then
begin
for I := AIndex + 1 to ColumnsRowCount do
Inc(FRows^[I], D);
end;
end;
{ TcxTreeListDataController }
constructor TcxTreeListDataController.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FNodesCount := -1;
end;
function TcxTreeListDataController.AddItem(AItem: TObject): TcxCustomDataField;
begin
Result := inherited AddItem(AItem);
InsertValueDef(TcxTreeListColumn(AItem));
TreeList.Controller.CancelIncSearching;
end;
function TcxTreeListDataController.AllocateRecord: Pointer;
begin
Result := TcxDataStorageHelper.AllocateRecord(DataStorage);
Inc(FAllocatedRecords);
end;
procedure TcxTreeListDataController.ChangeValueTypeClass(
AItemIndex: Integer; AValueTypeClass: TcxValueTypeClass);
begin
if GetItemValueTypeClass(AItemIndex) = AValueTypeClass then Exit;
RemoveValueDef(TcxTreeListColumn(TreeList.ContainerList[AItemIndex]));
inherited ChangeValueTypeClass(AItemIndex, AValueTypeClass);
InsertValueDef(TcxTreeListColumn(TreeList.ContainerList[AItemIndex]));
end;
function TcxTreeListDataController.CompareNodesByColumns(
ANode1, ANode2: TcxTreeListNode; AColumns: TList): Integer;
var
I: Integer;
V1, V2: Variant;
AField: TcxCustomDataField;
begin
Result := Byte(AColumns.Count > 0);
for I := 0 to AColumns.Count - 1 do
begin
AField := Fields[TcxTreeListColumn(AColumns[I]).ItemIndex];
if IsConversionNeededForCompare(AField) then
begin
V1 := GetValueForCompare(ANode1, AField);
V2 := GetValueForCompare(ANode2, AField);
if VarIsStr(V1) and VarIsStr(V2) then
Result := StringCompare(VarToStr(V1), VarToStr(V2))
else
Result := VarCompare(V1, V2);
end
else
Result := Compare(TcxTreeListColumn(AColumns[I]).ValueDef, ANode1.Handle, ANode2.Handle);
if TcxTreeListColumn(AColumns[I]).SortOrder = soDescending then
Result := -Result;
if Result <> 0 then Break;
end;
if Result = 0 then
begin
Result := ANode1.OriginalIndex - ANode2.OriginalIndex;
if Result = 0 then
Result := 1;
end;
end;
procedure TcxTreeListDataController.FreeNodeRecord(ANode: TcxTreeListNode);
begin
if ANode = EditingNode then
EditingNode := nil;
FreeRecord(ANode.FHandle);
end;
procedure TcxTreeListDataController.FreeRecord(var ARecord: Pointer);
begin
if ARecord = nil then Exit;
TcxDataStorageHelper.FreeRecord(DataStorage, ARecord);
Dec(FAllocatedRecords);
end;
function TcxTreeListDataController.GetDisplayText(
ARecordIndex, AItemIndex: Integer): string;
begin
cxTLUnused;
end;
function TcxTreeListDataController.GetNodeDisplayText(
ANode: TcxTreeListNode; AIndex: Integer): Variant;
begin
if ANode.Handle = nil then
Result := ''
else
Result := TcxDataStorageHelper.GetDisplayText(ValueDefs[AIndex], ANode.Handle);
end;
function TcxTreeListDataController.GetNodeValue(
ANode: TcxTreeListNode; AIndex: Integer): Variant;
begin
if ANode.Handle = nil then
Result := Null
else
Result := TcxDataStorageHelper.GetValue(ValueDefs[AIndex], ANode.Handle);
end;
function TcxTreeListDataController.GetValue(
ARecordIndex, AItemIndex: Integer): Variant;
begin
Result := GetNodeValue(TreeList.AbsoluteItems[ARecordIndex], AItemIndex);
end;
function TcxTreeListDataController.GetValueForCompare(
ANode: TcxTreeListNode; AField: TcxCustomDataField): Variant;
begin
if IsSortByDisplayTextNeeded(AField) then
Result := TcxDataStorageHelper.GetDisplayText(
TcxCustomDataHelper.GetValueDef(AField), ANode.Handle)
else
Result := TcxDataStorageHelper.GetValue(
TcxCustomDataHelper.GetValueDef(AField), ANode.Handle);
end;
procedure TcxTreeListDataController.InitializeNodeFromRecordIndex(
ANode: TcxTreeListNode);
begin
ANode.Handle := TcxDataStorageHelper.RemoveRecord(
DataStorage, Integer(ANode.Handle));
if ANode.Handle <> nil then
Inc(FAllocatedRecords);
end;
procedure TcxTreeListDataController.InitializeRecordIndexFromNode(
ANode: TcxTreeListNode);
begin
ANode.Handle := Pointer(TcxDataStorageHelper.AppendRecord(
DataStorage, ANode.Handle));
end;
procedure TcxTreeListDataController.Cancel;
begin
if EditingNode = nil then Exit;
try
if not EditingNode.Deleting and not EditingNode.Inserting then
SetNodeData(Root.FHandle, EditingNode);
finally
FreeNodeRecord(Root);
EditingNode := nil;
end;
end;
procedure TcxTreeListDataController.Edit;
begin
if not TreeList.OptionsData.Editing then Exit;
EditingNode := TreeList.FocusedNode;
FIsValueChanged := False;
end;
procedure TcxTreeListDataController.Post(AForcePost: Boolean = False);
begin
if EditingNode = nil then Exit;
TreeList.BeginUpdate;
try
PostEditingData;
if not FIsValueChanged then
Cancel
else
begin
FreeNodeRecord(Root);
TreeList.AddChanges([tcData]);
end;
EditingNode := nil;
PostRecord;
finally
TreeList.EndUpdate;
end;
end;
procedure TcxTreeListDataController.PostEditingData;
begin
if (EditingNode = nil) or (Root.Handle = nil) or (nsDeleting in EditingNode.State) then Exit;
TreeList.UpdateData;
if IsValueChanged then
Exclude(EditingNode.State, nsInserting);
PostValues;
end;
procedure TcxTreeListDataController.RemoveItem(AItem: TObject);
begin
RemoveValueDef(TcxTreeListColumn(AItem));
TreeList.Controller.CancelIncSearching;
inherited RemoveItem(AItem);
end;
function TcxTreeListDataController.SetEditValue(AItemIndex: Integer;
const AValue: Variant; AEditValueSource: TcxDataEditValueSource): Boolean;
var
V: Variant;
begin
if EditingNode = nil then
begin
Result := False;
Exit;
end;
AItemIndex := TcxTreeListColumn(TreeList.ContainerList[AItemIndex]).ItemIndex;
V := AValue;
if (AEditValueSource = evsText) and (VarToStr(AValue) = '') then
V := Null;
// if VarCompare(V, GetNodeValue(EditingNode, AItemIndex)) <> 0 then
SetNodeValue(EditingNode, AItemIndex, V);
Result := True;
end;
procedure TcxTreeListDataController.SetNodeValue(
ANode: TcxTreeListNode; AIndex: Integer; const AValue: Variant);
var
AColumn: TcxTreeListColumn;
begin
if ANode = nil then Exit;
if ANode.Handle = nil then
ANode.InitializeHandle;
if ANode.Handle = nil then Exit;
AColumn := TreeList.Columns[AIndex];
TcxDataStorageHelper.SetValue(ANode.Handle, AColumn.ValueDef, AValue);
FIsValueChanged := True;
if IsLoading then Exit;
TreeList.DoNodeChanged(ANode, AColumn);
end;
procedure TcxTreeListDataController.SetValue(
ARecordIndex, AItemIndex: Integer; const Value: Variant);
begin
cxTLUnused;
end;
procedure TcxTreeListDataController.UpdateItemIndexes;
begin
inherited UpdateItemIndexes;
TreeList.AddChanges([tcColumns]);
end;
function TcxTreeListDataController.Compare(
AValueDef: TcxValueDef; AHandle1, AHandle2: Pointer): Integer;
begin
if AHandle1 = nil then
begin
if AHandle2 = nil then
Result := 0
else
Result := -1;
end
else
if AHandle2 = nil then
Result := 1
else
Result := TcxDataStorageHelper.Compare(AValueDef, AHandle1, AHandle2);
end;
function TcxTreeListDataController.CopyData(ASource: TcxTreeListNode): Pointer;
var
I: Integer;
begin
Result := AllocateRecord;
for I := 0 to TreeList.ColumnCount - 1 do
begin
TcxDataStorageHelper(DataStorage).SetValue(Result,
ValueDefs[I], GetNodeValue(ASource, I));
end;
end;
procedure TcxTreeListDataController.DestroyHandles;
begin
ForEachRecord(FreeRecordProc, nil);
end;
procedure TcxTreeListDataController.ForEachRecord(
AProc: TcxTreeListForEachNodeProc; AData: Pointer);
var
ANode: TcxTreeListNode;
begin
if (Root = nil) or (AllocatedRecords = 0) then Exit;
ANode := Root;
while ANode <> nil do
begin
AProc(ANode, AData);
if ANode.FFirst <> nil then
ANode := ANode.FFirst
else
if ANode.FNext <> nil then
ANode := ANode.FNext
else
begin
while (ANode <> nil) and (ANode.FNext = nil) do
ANode := ANode.Parent;
if ANode <> nil then
ANode := ANode.FNext;
end;
end;
end;
function TcxTreeListDataController.IsLoading: Boolean;
begin
Result := inherited IsLoading;
end;
procedure TcxTreeListDataController.PostRecord;
begin
end;
procedure TcxTreeListDataController.PostValues;
begin
end;
procedure TcxTreeListDataController.SetNodeData(
ASource: Pointer; ADest: TcxTreeListNode);
var
I: Integer;
begin
for I := 0 to TreeList.ColumnCount - 1 do
SetNodeValue(ADest, I, TcxDataStorageHelper.GetValue(ValueDefs[I], ASource));
end;
function TcxTreeListDataController.StringCompare(const V1, V2: Variant): Integer;
begin
if dcoAnsiSort in Options then
begin
if dcoCaseInsensitive in Options then
Result := AnsiCompareText(V1, V2)
else
Result := AnsiCompareStr(V1, V2);
end
else
begin
if dcoCaseInsensitive in Options then
Result := CompareStr(AnsiUpperCase(V1), AnsiUpperCase(V2))
else
Result := VarCompare(V1, V2);
end;
end;
procedure TcxTreeListDataController.SyncFocused(ANode: TcxTreeListNode);
begin
end;
function TcxTreeListDataController.GetHasEditData: Boolean;
begin
Result := Root.Handle <> nil;
end;
function TcxTreeListDataController.GetRoot: TcxTreeListNode;
begin
Result := TreeList.Root;
end;
function TcxTreeListDataController.GetTreeList: TcxCustomTreeList;
begin
Result := TcxCustomTreeList(GetOwner);
end;
function TcxTreeListDataController.GetValueDef(AIndex: Integer): TcxValueDef;
begin
Result := TreeList.Columns[AIndex].ValueDef;
end;
procedure TcxTreeListDataController.FreeRecordProc(
ANode: TcxTreeListNode; AData: Pointer);
begin
FreeNodeRecord(ANode);
end;
procedure TcxTreeListDataController.InsertValueDef(AColumn: TcxTreeListColumn);
var
AData: TcxTreeListValueDefData;
begin
if AColumn.ValueDef = nil then Exit;
AData.Index := AColumn.ValueDef.ValueDefs.Count;
AData.ValueDef := AColumn.ValueDef;
ForEachRecord(InsertValueDefProc, @AData);
end;
procedure TcxTreeListDataController.InsertValueDefProc(
ANode: TcxTreeListNode; AData: Pointer);
var
PSource: PAnsiChar;
begin
if ANode.FHandle = nil then Exit;
ReallocMem(ANode.FHandle, PcxTreeListValueDefData(AData)^.ValueDef.ValueDefs.RecordSize);
PSource := PAnsiChar(ANode.FHandle) + PcxTreeListValueDefData(AData)^.ValueDef.Offset;
FillChar(PSource^, PcxTreeListValueDefData(AData)^.ValueDef.BufferSize, 0);
end;
procedure TcxTreeListDataController.SetEditingNode(AValue: TcxTreeListNode);
var
APrevNode: TcxTreeListNode;
begin
APrevNode := FEditingNode;
if (AValue <> FEditingNode) and (FEditingNode <> nil) then
begin
Exclude(EditingNode.State, nsEditing);
if not HasEditData and (nsInserting in EditingNode.State) then
begin
FEditingNode := nil;
APrevNode.Free;
end
else
if HasEditData then
begin
if EditingNode.Deleting then
Cancel
else
Post
end
else
TreeList.DoNodeChanged(EditingNode, nil);
end;
FEditingNode := AValue;
if (FEditingNode <> nil) and ((APrevNode <> AValue) or not HasEditData) then
begin
Root.Handle := CopyData(AValue);
Include(EditingNode.State, nsEditing);
TreeList.DoNodeChanged(EditingNode, nil);
end;
end;
procedure TcxTreeListDataController.SetIsValueChanged(AValue: Boolean);
begin
FIsValueChanged := AValue;
end;
procedure TcxTreeListDataController.RemoveValueDef(AColumn: TcxTreeListColumn);
var
AData: TcxTreeListValueDefData;
begin
AData.ValueDef := AColumn.ValueDef;
ForEachRecord(RemoveValueDefProc, @AData);
end;
procedure TcxTreeListDataController.RemoveValueDefProc(
ANode: TcxTreeListNode; AData: Pointer);
var
AFreeRecord: Boolean;
ARecordSize: Integer;
PDest, PSource: PAnsiChar;
begin
if (ANode.FHandle = nil) or (PcxTreeListValueDefData(AData)^.ValueDef = nil) then Exit;
AFreeRecord := TcxDataStorageHelper.GetStoredCount(DataStorage) <= 1;
ARecordSize := TcxDataStorageHelper.GetRecordSize(DataStorage);
if AFreeRecord then
FreeNodeRecord(ANode)
else
with PcxTreeListValueDefData(AData)^ do
begin
TcxDataStorageHelper.FreeBuffer(ValueDef, ANode.FHandle);
PDest := PAnsiChar(ANode.FHandle) + ValueDef.Offset;
PSource := PAnsiChar(PDest) + ValueDef.BufferSize;
System.Move(PSource^, PDest^, ARecordSize - (PSource - PAnsiChar(ANode.FHandle)));
ReallocMem(ANode.FHandle, ARecordSize - ValueDef.BufferSize);
end;
end;
initialization
Classes.RegisterClass(TcxTreeListStyleSheet);
finalization
Classes.UnRegisterClass(TcxTreeListStyleSheet);
end.