Class TCustomDBTreeView (unit dbTree)

Inherits from

TCustomTreeViewEx

Constructors


constructor Create(AOwner: TComponent);

procedure TTreeViewLink.


Functions

procedure BuildTreeIfNeeded;


procedure Delete;

cancel of insert works like deleting it

destructor Destroy;


function FindTextID(const S: string; var ID: string; TVFindTextOptions: TTVFindTextOptions): Boolean;


function GetExpanded(Separator: Char): string;

With GetExpanded you can save all Items[].

function GetIDNode(const aID: string): TTreeNode;

To get the Node that has the ID:

function IDOfNode(Node: TTreeNode): string;

{ IsRootNode is true if the node has no parent: } function IsRootNode(Node: TTreeNode): Boolean; { IsSingleRootNode is true if the node is the only one without parent: } function IsSingleRootNode(Node: TTreeNode): Boolean; *) { To get the ID of a Node:

procedure Insert(AsChild: Boolean);

Check EVERY record for the highest ID-Value:

function MoveNode(Source, Destination: TTreeNode; Mode: TNodeAttachMode): Boolean;


procedure RebuildTree;

We just received the focus.

procedure SetExpanded(const List: string; Separator: Char);


procedure SynchronizeCurrentRecordToSelectedNode;

If not dtSynchronizeDataSet in Options, use this procedure to move the dataset to the selected node of the tree:

procedure SynchronizeSelectedNodeToCurrentRecord;

If not dtSynchronizeDataSet in Options, use this procedure to show the current record of the dataset in the tree:

DataSet.


function TextIDList(const S: string; TVFindTextOptions: TTVFindTextOptions): TStringList;


procedure ActiveChanged(Value: Boolean);


procedure BuildTree;


function CanDelete(Node: TTreeNode): Boolean;


function CanEdit(Node: TTreeNode): Boolean;


procedure Change(Node: TTreeNode);

proc AfterEdit was not called: user canceled editing

procedure ClosedLoop;


function CreateNode: TTreeNode;


procedure CreateWnd;


procedure DataChanged;


procedure DataSetAfterCancel;


procedure DataSetAfterDelete;

No reason to abort deletion or do it ous way:

procedure DataSetAfterPost;

insert-mode was not done by us.

procedure DataSetBeforeDelete;

sorry, but we have to do a complete rebuild:

procedure DataSetBeforePost;

If we get the focus later, please edit node:

function DataSetLocate(const ID: string): Boolean;


procedure DatasetRefreshed;

TCustomDBTreeView has changed Dataset, do nothing:

procedure DestroyWnd;


function DoDelete(Node: TTreeNode): Boolean;


function DragAllowed(Node: TTreeNode): Boolean;

Synchronize now

procedure Edit(const Item: TTVItem);

if we just lost focus, don't touch DataSet

procedure EditingChanged;

maybe structure of tree changed:

procedure Expand(Node: TTreeNode);


function GetDeleteQuestion(Node: TTreeNode): string;

EnableControls;

function GetNewID: string;

Called by procedure Insert, GetNewID has to calculate the ID of a new record.

procedure KeyDown(var Key: Word; Shift: TShiftState);


procedure KillAllTimer;


procedure Notification(AComponent: TComponent; Operation: TOperation);


procedure RecordChanged(Field: TField);


procedure RecordNumberChanged;


procedure RootNotFound;


function AddNewNodeFromDataset( Node: TTreeNode; AsChild: Boolean): TTreeNode;

if (csDesigning in ComponentState) then ShowMessage('No record with root-ID (' + FRootID + ') found.

procedure AfterEdit(Sender: TObject; Node: TTreeNode; var S: string);


procedure CNNotify(var Message: TWMNotify);


procedure CreateTree(ParentNode: TTreeNode; const AParent: string; TempRecordList: TTVRecordList);

Catch calls of GoToKey method

function CreateTVRecordList: TTVRecordList;


function GetDataSet: TDataSet;


function GetDataSetIDNode: TTreeNode;

found

function GetDataSource: TDataSource;


function GetID(AIndex: Integer): string;


function GetSelectedID: string;


procedure IndexChanged;


function NeedRebuild: Boolean;

make changes visible

procedure SelectID(const Value: string);


procedure SetDataSource(ADataSource: TDataSource);


procedure SetOptions(Value: TDBTreeOptions);


procedure SetRootID(ID: string);

if (not (dtvsBuilding in FState)) and (FDisableCount = 0) and (Selected <> nil) then Selected.

procedure SetTableIDField(const Value: string);

BuildTree will be done at ActiveChanged

procedure SetTableParentField(const Value: string);


procedure SetTableTextField(const Value: string);


procedure WMSetFocus(var Message: TMessage);

changes are not visible until EndUpdate

procedure WMTimer(var Msg: TWMTimer);


Properties

property DataSet : TDataSet

DataSource.

property DataSource : TDataSource

possible published:

property IDs : string

ID of Items[Index].

property Options : TDBTreeOptions


property RootID : string


property SelectedID : string

The ID of the current selected node, or set Selected with SelectedID := ID:

property TableIDField : string


property TableParentField : string


property TableTextField : string


property TreeViewLink : TTreeViewLink


Events

event OnClosedLoop : TNotifyEvent


event OnGetNextID : TDBTVGetNextIDEvent

Called by the procedure Insert, OnGetNextID has to calculate the ID of a new record.

event OnRootNotFound : TNotifyEvent


Variables

FDelRootID : string;


FIDOfDeleted : string;


FOnClosedLoop : TNotifyEvent;


FOnGetNextID : TDBTVGetNextIDEvent;


FOnRootNotFound : TNotifyEvent;


FOptions : TDBTreeOptions;


FPrevState : TDataSetState;


FReBuildTimer : Longint;


FRootID : string;


FSaveIDList : TStringList;


FState : TDBTreeViewStates;


FTableIDField : string;


FTableParentField : string;


FTableTextField : string;


FTreeViewLink : TTreeViewLink;


FTVRecordList : TTVRecordList;


FUserOnEdited : TTVEditedEvent;



Constructors


constructor Create(AOwner: TComponent);

procedure TTreeViewLink.DoBeforeCancel(DataSet: TDataSet); begin inherited; end; procedure TTreeViewLink.DoAfterEdit(DataSet: TDataSet); begin inherited; end; procedure TTreeViewLink.DoAfterInsert(DataSet: TDataSet); begin inherited; end; *) { TCustomDBTreeView ---------------------------------------------------------


Functions


procedure BuildTreeIfNeeded;


procedure Delete;

cancel of insert works like deleting it


destructor Destroy;


function FindTextID(const S: string; var ID: string; TVFindTextOptions: TTVFindTextOptions): Boolean;


function GetExpanded(Separator: Char): string;

With GetExpanded you can save all Items[].Expanded in a string (e.g. to save this in an INI-file) to restore all Items[].Expanded with SetExpanded:

EnableControls;


function GetIDNode(const aID: string): TTreeNode;

To get the Node that has the ID:


function IDOfNode(Node: TTreeNode): string;

{ IsRootNode is true if the node has no parent: } function IsRootNode(Node: TTreeNode): Boolean; { IsSingleRootNode is true if the node is the only one without parent: } function IsSingleRootNode(Node: TTreeNode): Boolean; *) { To get the ID of a Node:


procedure Insert(AsChild: Boolean);

Check EVERY record for the highest ID-Value:


function MoveNode(Source, Destination: TTreeNode; Mode: TNodeAttachMode): Boolean;


procedure RebuildTree;

We just received the focus. If the dateaset is in edit- or insert-mode and dtFocusOnEdit is in Options, we have to set the selected node into the edit-mode.


procedure SetExpanded(const List: string; Separator: Char);


procedure SynchronizeCurrentRecordToSelectedNode;

If not dtSynchronizeDataSet in Options, use this procedure to move the dataset to the selected node of the tree:


procedure SynchronizeSelectedNodeToCurrentRecord;

If not dtSynchronizeDataSet in Options, use this procedure to show the current record of the dataset in the tree:

DataSet.Locate does not work with empty value


function TextIDList(const S: string; TVFindTextOptions: TTVFindTextOptions): TStringList;


procedure ActiveChanged(Value: Boolean);


procedure BuildTree;


function CanDelete(Node: TTreeNode): Boolean;


function CanEdit(Node: TTreeNode): Boolean;


procedure Change(Node: TTreeNode);

proc AfterEdit was not called: user canceled editing


procedure ClosedLoop;


function CreateNode: TTreeNode;


procedure CreateWnd;


procedure DataChanged;


procedure DataSetAfterCancel;


procedure DataSetAfterDelete;

No reason to abort deletion or do it ous way:


procedure DataSetAfterPost;

insert-mode was not done by us. Structure of tree has changed:


procedure DataSetBeforeDelete;

sorry, but we have to do a complete rebuild:


procedure DataSetBeforePost;

If we get the focus later, please edit node:


function DataSetLocate(const ID: string): Boolean;


procedure DatasetRefreshed;

TCustomDBTreeView has changed Dataset, do nothing:


procedure DestroyWnd;


function DoDelete(Node: TTreeNode): Boolean;


function DragAllowed(Node: TTreeNode): Boolean;

Synchronize now


procedure Edit(const Item: TTVItem);

if we just lost focus, don't touch DataSet


procedure EditingChanged;

maybe structure of tree changed:


procedure Expand(Node: TTreeNode);


function GetDeleteQuestion(Node: TTreeNode): string;

EnableControls;


function GetNewID: string;

Called by procedure Insert, GetNewID has to calculate the ID of a new record. It calls OnGetNextID:

Synchronize now


procedure KeyDown(var Key: Word; Shift: TShiftState);


procedure KillAllTimer;


procedure Notification(AComponent: TComponent; Operation: TOperation);


procedure RecordChanged(Field: TField);


procedure RecordNumberChanged;


procedure RootNotFound;


function AddNewNodeFromDataset( Node: TTreeNode; AsChild: Boolean): TTreeNode;

if (csDesigning in ComponentState) then ShowMessage('No record with root-ID (' + FRootID + ') found.'); {


procedure AfterEdit(Sender: TObject; Node: TTreeNode; var S: string);


procedure CNNotify(var Message: TWMNotify);


procedure CreateTree(ParentNode: TTreeNode; const AParent: string; TempRecordList: TTVRecordList);

Catch calls of GoToKey method


function CreateTVRecordList: TTVRecordList;


function GetDataSet: TDataSet;


function GetDataSetIDNode: TTreeNode;

found


function GetDataSource: TDataSource;


function GetID(AIndex: Integer): string;


function GetSelectedID: string;


procedure IndexChanged;


function NeedRebuild: Boolean;

make changes visible


procedure SelectID(const Value: string);


procedure SetDataSource(ADataSource: TDataSource);


procedure SetOptions(Value: TDBTreeOptions);


procedure SetRootID(ID: string);

if (not (dtvsBuilding in FState)) and (FDisableCount = 0) and (Selected <> nil) then Selected.MakeVisible;


procedure SetTableIDField(const Value: string);

BuildTree will be done at ActiveChanged


procedure SetTableParentField(const Value: string);


procedure SetTableTextField(const Value: string);


procedure WMSetFocus(var Message: TMessage);

changes are not visible until EndUpdate


procedure WMTimer(var Msg: TWMTimer);


Properties


property DataSet : TDataSet

DataSource.DataSet:


property DataSource : TDataSource

possible published:


property IDs : string

ID of Items[Index]. Index is 0 to Items.Count -1:


property Options : TDBTreeOptions


property RootID : string


property SelectedID : string

The ID of the current selected node, or set Selected with SelectedID := ID:


property TableIDField : string


property TableParentField : string


property TableTextField : string


property TreeViewLink : TTreeViewLink


Events


event OnClosedLoop : TNotifyEvent


event OnGetNextID : TDBTVGetNextIDEvent

Called by the procedure Insert, OnGetNextID has to calculate the ID of a new record. This is not needed if the type of the ID-field is ftAutoInc. You have to override GetNewID if you hide the record with the highest ID and the type of the ID-field is not ftAutoInc: - DataSet is TQuery and TQuery.SQL uses 'WHERE ...' - DataSet.MasterSource is set. If you use a TQuery as Dataset, it is recommended to calculate the new ID yourself. If you set the new ID on Dataset.OnNewRecord, please use OnGetNextID or your own GetNewID because the ID is needed before the Dataset gets into insert-mode.


event OnRootNotFound : TNotifyEvent


Variables


FDelRootID : string;


FIDOfDeleted : string;


FOnClosedLoop : TNotifyEvent;


FOnGetNextID : TDBTVGetNextIDEvent;


FOnRootNotFound : TNotifyEvent;


FOptions : TDBTreeOptions;


FPrevState : TDataSetState;


FReBuildTimer : Longint;


FRootID : string;


FSaveIDList : TStringList;


FState : TDBTreeViewStates;


FTableIDField : string;


FTableParentField : string;


FTableTextField : string;


FTreeViewLink : TTreeViewLink;


FTVRecordList : TTVRecordList;


FUserOnEdited : TTVEditedEvent;