ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/branches/journaling/ibcontrols/IBTreeView.pas
(Generate patch)

Comparing:
ibx/trunk/ibcontrols/IBTreeView.pas (file contents), Revision 27 by tony, Tue Apr 14 13:10:23 2015 UTC vs.
ibx/branches/journaling/ibcontrols/IBTreeView.pas (file contents), Revision 362 by tony, Tue Dec 7 13:27:39 2021 UTC

# Line 31 | Line 31 | interface
31  
32   uses
33    Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ComCtrls,
34 <  DB, IBSQLParser, IBCustomDataSet;
34 >  DB, DBTreeView, IBSQLParser, IBCustomDataSet;
35  
36   type
37    {
# Line 41 | Line 41 | type
41      Node text can similarly be edited.
42    }
43  
44  TVariantArray = array of variant;
45
44    TIBTreeView = class;
45 <
48 <  { TIBTreeViewDatalink }
49 <
50 <  TIBTreeViewDatalink = class(TDataLink)
51 <  private
52 <    FOwner: TIBTreeView;
53 <  protected
54 <    procedure ActiveChanged; override;
55 <    procedure DataSetChanged; override;
56 <    procedure RecordChanged(Field: TField); override;
57 <    procedure UpdateData; override;
58 <  public
59 <    constructor Create(AOwner: TIBTreeView);
60 <  end;
45 >  TIBTreeNode = TDBTreeNode;
46  
47    { TIBTreeViewControlLink }
48  
# Line 71 | Line 56 | type
56      constructor Create(AOwner: TIBTreeView);
57    end;
58  
59 <  { TIBTreeNode }
75 <
76 <  TIBTreeNode = class(TTreeNode)
77 <  private
78 <    FKeyValue: variant;
79 <  public
80 <    procedure DeleteAll;
81 <    property KeyValue: variant read FKeyValue;
82 <  end;
83 <
84 <  TIBTreeView = class(TCustomTreeView)
59 >  TIBTreeView = class(TDBTreeView)
60    private
61      { Private declarations }
87    FDataLink: TIBTreeViewDatalink;
62      FIBTreeViewControlLink: TIBTreeViewControlLink;
89    FHasChildField: string;
90    FKeyField: string;
91    FTextField: string;
92    FParentField: string;
93    FExpandNode: TTreeNode;
94    FNoAddNodeToDataset: boolean;
95    FRelationName: string;
96    FUpdateNode: TIBTreeNode;
97    FModifiedNode: TIBTreeNode;
98    FUpdating: boolean;
99    FLocatingNode: boolean;
100    FLastSelected: TVariantArray;
101    procedure ActiveChanged(Sender: TObject);
102    procedure AddNodes;
103    procedure DataSetChanged(Sender: TObject);
104    function GetDataSet: TDataSet;
105    function GetDataSource: TDataSource;
106    function GetRelationNameQualifier: string;
107    function GetSelectedKeyValue: variant;
108    procedure IBControlLinkChanged;
109    procedure NodeMoved(Node: TTreeNode);
110    procedure NodeUpdated(Node: TTreeNode);
111    procedure RecordChanged(Sender: TObject; Field: TField);
112    procedure SetHasChildField(AValue: string);
113    procedure SetKeyField(AValue: string);
114    procedure SetTextField(AValue: string);
115    procedure SetDataSource(AValue: TDataSource);
116    procedure SetParentField(AValue: string);
117    function ScrollToNode(Node: TIBTreeNode): boolean;
118    procedure UpdateData(Sender: TObject);
63      procedure UpdateParams(Sender: TObject; Parser: TSelectSQLParser);
64      procedure UpdateSQL(Sender: TObject; Parser: TSelectSQLParser);
65     protected
66 <    { Protected declarations }
67 <     procedure Added(Node: TTreeNode); override;
124 <     procedure Delete(Node: TTreeNode); override;
125 <     procedure Change(Node: TTreeNode); override;
126 <     function CreateNode: TTreeNode; override;
127 <     function CanEdit(Node: TTreeNode): Boolean; override;
128 <     procedure Expand(Node: TTreeNode); override;
129 <     procedure Loaded; override;
130 <     procedure NodeChanged(Node: TTreeNode; ChangeEvent: TTreeNodeChangeReason); override;
131 <     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
132 <     procedure Reinitialise;
66 >     procedure DataSourceChanged; override;
67 >     procedure RefreshDataset; override;
68    public
69      { Public declarations }
70      constructor Create(TheComponent: TComponent); override;
71      destructor Destroy; override;
137    function FindNode(KeyValuePath: array of variant; SelectNode: boolean): TIBTreeNode; overload;
138    function FindNode(KeyValue: variant): TIBTreeNode; overload;
139    function GetNodePath(Node: TTreeNode): TVariantArray;
140    property DataSet: TDataSet read GetDataSet;
141    property SelectedKeyValue: variant read GetSelectedKeyValue;
142  published
143    { Published declarations }
144    property Align;
145    property Anchors;
146    property AutoExpand;
147    property BorderSpacing;
148    //property BiDiMode;
149    property BackgroundColor;
150    property BorderStyle;
151    property BorderWidth;
152    property Color;
153    property Constraints;
154    property TextField: string read FTextField write SetTextField;
155    property DataSource: TDataSource read GetDataSource write SetDataSource;
156    property DefaultItemHeight;
157    property DragKind;
158    property DragCursor;
159    property DragMode;
160    property Enabled;
161    property ExpandSignColor;
162    property ExpandSignType;
163    property Font;
164    property HideSelection;
165    property HotTrack;
166    property Images;
167    property Indent;
168    property HasChildField: string read FHasChildField write SetHasChildField;
169    property KeyField: string read FKeyField write SetKeyField;
170    property MultiSelect;
171    property MultiSelectStyle;
172    //property ParentBiDiMode;
173    property ParentColor default False;
174    property ParentField: string read FParentField write SetParentField;
175    property ParentFont;
176    property ParentShowHint;
177    property PopupMenu;
178    property ReadOnly;
179    property RelationName: string read FRelationName write FRelationName;
180    property RightClickSelect;
181    property RowSelect;
182    property ScrollBars;
183    property SelectionColor;
184    property ShowButtons;
185    property ShowHint;
186    property ShowLines;
187    property ShowRoot;
188    property StateImages;
189    property TabOrder;
190    property TabStop default True;
191    property Tag;
192    property ToolTips;
193    property Visible;
194    property OnAddition;
195    property OnAdvancedCustomDraw;
196    property OnAdvancedCustomDrawItem;
197    property OnChange;
198    property OnChanging;
199    property OnClick;
200    property OnCollapsed;
201    property OnCollapsing;
202    property OnCompare;
203    property OnContextPopup;
204    property OnCreateNodeClass;
205    property OnCustomCreateItem;
206    property OnCustomDraw;
207    property OnCustomDrawItem;
208    property OnDblClick;
209    property OnDeletion;
210    property OnDragDrop;
211    property OnDragOver;
212    property OnEdited;
213    property OnEditing;
214    property OnEditingEnd;
215    //property OnEndDock;
216    property OnEndDrag;
217    property OnEnter;
218    property OnExit;
219    property OnExpanded;
220    property OnExpanding;
221    property OnGetImageIndex;
222    property OnGetSelectedIndex;
223    property OnKeyDown;
224    property OnKeyPress;
225    property OnKeyUp;
226    property OnMouseDown;
227    property OnMouseEnter;
228    property OnMouseLeave;
229    property OnMouseMove;
230    property OnMouseUp;
231    property OnNodeChanged;
232    property OnSelectionChanged;
233    property OnShowHint;
234    //property OnStartDock;
235    property OnStartDrag;
236    property OnUTF8KeyPress;
237    property Options;
238    property Items;
239    property TreeLineColor;
240    property TreeLinePenStyle;
72    end;
73  
74 <  function StrIntListToVar(s: string): TVariantArray;
75 <  function VarToStrIntList(a: TVariantArray): string;
74 > function StrIntListToVar(s: string): TVariantArray;
75 > function VarToStrIntList(a: TVariantArray): string;
76  
77   implementation
78  
79 < uses IBQuery,Variants;
79 > uses IBQuery;
80  
81   function StrIntListToVar(s: string): TVariantArray;
251 var i, idx: integer;
252    List: TStringList;
82   begin
83 <  List := TStringList.Create;
255 <  try
256 <    idx := 1;
257 <    List.Clear;
258 <    while idx <= Length(s) do
259 <       List.Add(ExtractFieldName(s,idx));
260 <
261 <    Setlength(Result,List.Count);
262 <    for i := 0 to List.Count - 1 do
263 <        Result[i] := StrToInt(List[i])
264 <  finally
265 <    List.Free
266 <  end;
83 >  Result := DBTreeView.StrIntListToVar(s);
84   end;
85  
86   function VarToStrIntList(a: TVariantArray): string;
270 var i: integer;
87   begin
88 <  for i := 0 to Length(a) - 1 do
273 <      if VarIsOrdinal(a[i]) then
274 <      begin
275 <        if i = 0 then
276 <           Result := IntToStr(a[i])
277 <        else
278 <          Result := Result + ';' + IntToStr(a[i])
279 <      end
280 <      else
281 <        raise Exception.Create('Ordinal Type Expected when converting to integer string');
88 >  Result := DBTreeView.VarToStrIntList(a);
89   end;
90  
91 +
92   { TIBTreeViewControlLink }
93  
94   constructor TIBTreeViewControlLink.Create(AOwner: TIBTreeView);
# Line 299 | Line 107 | begin
107    FOwner.UpdateSQL(self,TIBParserDataSet(Sender).Parser)
108   end;
109  
302 { TIBTreeNode }
303
304 procedure TIBTreeNode.DeleteAll;
305 var Node, NextNode: TTreeNode;
306 begin
307    Expand(true);
308    Node := GetFirstChild;
309    while Node <> nil do
310    begin
311      NextNode := Node.GetNextSibling;
312      TIBTreeNode(Node).DeleteAll;
313      Node := NextNode;
314    end;
315    Delete
316 end;
317
318 { TIBTreeView }
319
320 procedure TIBTreeView.ActiveChanged(Sender: TObject);
321 var AtTopLevel: boolean;
322 begin
323  if (csDesigning in ComponentState) then Exit;
324  IBControlLinkChanged;
325  if assigned(DataSet) and not DataSet.Active then
326  begin
327    if not assigned(FExpandNode) and not assigned(FUpdateNode) then {must really be closing}
328      Reinitialise
329  end
330  else
331  begin
332    AtTopLevel := Items.TopLvlCount = 0;
333    AddNodes;
334    if not FLocatingNode and (Selected = nil) and (Items.TopLvlCount > 0) then
335    begin
336      if Length(FLastSelected) > 0 then
337         Selected := FindNode(FLastSelected,true)
338      else
339        Selected := Items.TopLvlItems[0];
340    end
341  end
342 end;
343
344 procedure TIBTreeView.AddNodes;
345 var Node: TTreeNode;
346    ChildCount: integer;
347 begin
348  if assigned(FExpandNode) or (Items.Count = 0) then
349  begin
350    ChildCount := 0;
351    FNoAddNodeToDataset := true;
352    try
353      DataSet.First;
354      while not DataSet.EOF do
355      begin
356        Node := Items.AddChild(FExpandNode,DataSet.FieldByName(TextField).AsString);
357        TIBTreeNode(Node).FKeyValue := DataSet.FieldByName(KeyField).AsVariant;
358        Node.HasChildren := (HasChildField = '') or (DataSet.FieldByName(HasChildField).AsInteger <> 0);
359        Inc(ChildCount);
360        DataSet.Next
361      end;
362    finally
363      FNoAddNodeToDataset := false
364    end;
365    if assigned(FExpandNode) then
366      FExpandNode.HasChildren := ChildCount > 0;
367    FExpandNode := nil
368  end
369 end;
370
371 procedure TIBTreeView.DataSetChanged(Sender: TObject);
372 begin
373 //  Reinitialise
374 end;
375
376 function TIBTreeView.GetDataSet: TDataSet;
377 begin
378  Result := FDataLink.DataSet
379 end;
380
381 function TIBTreeView.GetDataSource: TDataSource;
382 begin
383  Result := FDataLink.DataSource
384 end;
385
386 function TIBTreeView.GetRelationNameQualifier: string;
387 begin
388  if FRelationName <> '' then
389     Result := FRelationName + '.'
390  else
391    Result := ''
392 end;
393
394 function TIBTreeView.GetSelectedKeyValue: variant;
395 begin
396  Result := NULL;
397  if assigned(Selected) and (Selected is TIBTreeNode) then
398     Result := TIBTreeNode(Selected).KeyValue
399 end;
400
401 procedure TIBTreeView.NodeMoved(Node: TTreeNode);
402 begin
403  {Need to update Parent}
404  if ScrollToNode(TIBTreeNode(Node))  then
405  begin
406      FDataLink.Edit;
407      FModifiedNode := TIBTreeNode(Node)
408  end;
409 end;
410
411 procedure TIBTreeView.NodeUpdated(Node: TTreeNode);
412 begin
413  {Need to Update List Field}
414  if ScrollToNode(TIBTreeNode(Node)) then
415  begin
416    FDataLink.Edit;
417    FModifiedNode := TIBTreeNode(Node);
418    FDataLink.UpdateRecord
419  end;
420 end;
421
422 procedure TIBTreeView.RecordChanged(Sender: TObject; Field: TField);
423 var Node: TIBTreeNode;
424    Destination: TIBTreeNode;
425 begin
426  if DataSet.State = dsInsert then Exit;
427
428  if assigned(Field) and (Field.FieldName = TextField) then
429  begin
430    Node := FindNode(DataSet.FieldByName(KeyField).AsVariant);
431    if assigned(Node) then
432    begin
433      FUpdating := true;
434      try
435        Node.Text := Field.Text
436      finally
437        FUpdating := false
438      end;
439    end;
440  end
441  else
442  if assigned(Field) and (Field.FieldName = ParentField) then
443  begin
444    Node := FindNode(DataSet.FieldByName(KeyField).AsVariant);
445    if assigned(Node)  then
446    begin
447      if DataSet.FieldByName(ParentField).IsNull then
448         Destination := nil
449      else
450        Destination := FindNode(DataSet.FieldByName(ParentField).AsVariant);
451
452      if Destination = Node.Parent then Exit;
453
454      FUpdating := true;
455      try
456        Node.MoveTo(Destination,naAddChild);
457      finally
458        FUpdating := false
459      end;
460    end;
461  end
462 end;
463
464 procedure TIBTreeView.SetHasChildField(AValue: string);
465 begin
466  if FHasChildField = AValue then Exit;
467  FHasChildField := AValue;
468  Reinitialise
469 end;
470
471 procedure TIBTreeView.SetKeyField(AValue: string);
472 begin
473  if FKeyField = AValue then Exit;
474  FKeyField := AValue;
475  Reinitialise
476 end;
477
478 procedure TIBTreeView.SetTextField(AValue: string);
479 begin
480  if FTextField = AValue then Exit;
481  FTextField := AValue;
482  Reinitialise
483 end;
484
485 procedure TIBTreeView.SetDataSource(AValue: TDataSource);
486 begin
487  FDataLink.DataSource := AValue;
488  IBControlLinkChanged;
489 end;
490
491 procedure TIBTreeView.SetParentField(AValue: string);
492 begin
493  if FParentField = AValue then Exit;
494  FParentField := AValue;
495  Reinitialise
496 end;
497
498 function TIBTreeView.ScrollToNode(Node: TIBTreeNode): boolean;
499 begin
500  Result :=  assigned(DataSet) and DataSet.Active and assigned(Node) and not varIsNull(Node.KeyValue);
501  if Result then
502  begin
503    if DataSet.Active and (DataSet.RecordCount > 0)
504         and (Node.KeyValue = DataSet.FieldByName(KeyField).AsVariant) then Exit;
505
506    FUpdateNode := Node;
507    try
508      DataSet.Active := false;
509      DataSet.Active := true;
510    finally
511      FUpdateNode := nil
512    end;
513    Result := DataSet.FieldByName(KeyField).AsVariant = Node.KeyValue
514  end;
515 end;
516
517 procedure TIBTreeView.UpdateData(Sender: TObject);
518 begin
519  if assigned(FModifiedNode) then
520  begin
521    DataSet.FieldByName(TextField).AsString := FModifiedNode.Text;
522    if FModifiedNode.Parent = nil then
523      DataSet.FieldByName(ParentField).Clear
524    else
525      DataSet.FieldByName(ParentField).AsVariant := TIBTreeNode(FModifiedNode.Parent).KeyValue;
526    FModifiedNode := nil
527  end
528 end;
110  
111   procedure TIBTreeView.UpdateParams(Sender: TObject; Parser: TSelectSQLParser);
112   begin
# Line 544 | Line 125 | begin
125    begin
126      if DataSource.DataSet is TIBQuery then
127        TIBQuery(DataSource.DataSet).ParamByName('IBX_PARENT_VALUE').Value :=
128 <        TIBTreeNode(FExpandNode).KeyValue
128 >        TDBTreeNode(FExpandNode).KeyValue
129      else
130      if DataSource.DataSet is TIBDataSet then
131        TIBDataSet(DataSource.DataSet).ParamByName('IBX_PARENT_VALUE').Value :=
132 <        TIBTreeNode(FExpandNode).KeyValue
132 >        TDBTreeNode(FExpandNode).KeyValue
133    end;
134   end;
135  
136   procedure TIBTreeView.UpdateSQL(Sender: TObject; Parser: TSelectSQLParser);
137   begin
138      if not assigned(FExpandNode) and assigned(FUpdateNode)  then {Scrolling dataset}
139 <      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + FKeyField + '" = :IBX_KEY_VALUE')
139 >      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + KeyField + '" = :IBX_KEY_VALUE')
140      else
141      if (Items.Count = 0) then
142        {Need to Load Root Nodes}
143 <      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + FParentField + '" is null')
143 >      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + ParentField + '" is null')
144      else
145      if assigned(FExpandNode) then
146 <      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + FParentField + '" = :IBX_PARENT_VALUE');
147 < end;
148 <
149 < procedure TIBTreeView.Added(Node: TTreeNode);
569 < begin
570 <  if assigned(DataSet) and DataSet.Active and not FNoAddNodeToDataset then
571 <  begin
572 <    DataSet.Append;
573 <    TIBTreeNode(Node).FKeyValue := DataSet.FieldByName(KeyField).AsVariant;
574 <    if (Node.Text = '') and not DataSet.FieldByName(TextField).IsNull then
575 <       Node.Text := DataSet.FieldByName(TextField).AsString;
576 <    FModifiedNode := TIBTreeNode(Node);
577 <    FDataLink.UpdateRecord
578 <  end;
579 <  inherited Added(Node);
580 < end;
581 <
582 < procedure TIBTreeView.Delete(Node: TTreeNode);
583 < begin
584 <  if not (tvsUpdating in States) {TreeNodes being cleared}
585 <     and not (tvsManualNotify in States) {Tree Collapse with node delete}
586 <     and ScrollToNode(TIBTreeNode(Node)) then
587 <     DataSet.Delete;
588 <  inherited Delete(Node);
589 < end;
590 <
591 < procedure TIBTreeView.Change(Node: TTreeNode);
592 < begin
593 <  inherited Change(Node);
594 <  ScrollToNode(TIBTreeNode(Node));
595 < end;
596 <
597 < function TIBTreeView.CreateNode: TTreeNode;
598 < var
599 <  NewNodeClass: TTreeNodeClass;
600 < begin
601 <  Result := nil;
602 <  if Assigned(OnCustomCreateItem) then
603 <    OnCustomCreateItem(Self, Result);
604 <  if Result = nil then
605 <  begin
606 <    NewNodeClass:=TIBTreeNode;
607 <    if Assigned(OnCreateNodeClass) then
608 <      OnCreateNodeClass(Self,NewNodeClass);
609 <    Result := NewNodeClass.Create(Items);
610 <  end;
611 < end;
612 <
613 < function TIBTreeView.CanEdit(Node: TTreeNode): Boolean;
614 < begin
615 <  Result := inherited CanEdit(Node)
616 <              and assigned(DataSet) and not DataSet.FieldByName(TextField).ReadOnly
617 < end;
618 <
619 < procedure TIBTreeView.Expand(Node: TTreeNode);
620 < begin
621 <  inherited Expand(Node);
622 <  if Node.HasChildren and assigned(DataSet) and (Node.GetFirstChild = nil) then
623 <  begin
624 <    FExpandNode := Node;
625 <    DataSet.Active := false;
626 <    DataSet.Active := true;
627 <    if assigned(Selected) then
628 <      ScrollToNode(TIBTreeNode(Selected))
629 <  end;
630 < end;
631 <
632 < procedure TIBTreeView.IBControlLinkChanged;
633 < begin
634 <  if assigned(DataSource) and (DataSource.DataSet <> nil) and (DataSource.DataSet is TIBParserDataset) then
635 <    FIBTreeViewControllink.IBDataSet := TIBCustomDataSet(DataSource.DataSet)
636 <  else
637 <    FIBTreeViewControllink.IBDataSet := nil;
638 < end;
639 <
640 < procedure TIBTreeView.Loaded;
641 < begin
642 <  inherited Loaded;
643 <  Reinitialise
644 < end;
645 <
646 < procedure TIBTreeView.NodeChanged(Node: TTreeNode;
647 <  ChangeEvent: TTreeNodeChangeReason);
648 < begin
649 <  inherited NodeChanged(Node, ChangeEvent);
650 <  if not FNoAddNodeToDataset and not FUpdating then
651 <  case ChangeEvent of
652 <  ncTextChanged:
653 <    NodeUpdated(Node);
654 <  ncParentChanged:
655 <    NodeMoved(Node);
656 <  end;
146 >    begin
147 >      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + ParentField + '" = :IBX_PARENT_VALUE');
148 >      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + KeyField + '" = :IBX_PARENT_VALUE',true);
149 >    end;
150   end;
151  
152 < procedure TIBTreeView.Notification(AComponent: TComponent; Operation: TOperation
660 <  );
152 > procedure TIBTreeView.DataSourceChanged;
153   begin
154 <  inherited Notification(AComponent, Operation);
155 <  if (Operation = opRemove) and
156 <     (FDataLink <> nil) and (AComponent = DataSource) then
157 <     DataSource := nil;
154 >    if assigned(DataSource) and (DataSource.DataSet <> nil) and (DataSource.DataSet is TIBParserDataset) then
155 >      FIBTreeViewControllink.IBDataSet := TIBCustomDataSet(DataSource.DataSet)
156 >    else
157 >      FIBTreeViewControllink.IBDataSet := nil;
158   end;
159  
160 < procedure TIBTreeView.Reinitialise;
160 > procedure TIBTreeView.RefreshDataset;
161   begin
162 <  if [csDesigning,csLoading] * ComponentState <> [] then Exit;
163 <  FLastSelected := GetNodePath(Selected);
672 <  Items.Clear;
162 >  DataSet.Active := false;
163 >  DataSet.Active := true;
164   end;
165  
166   constructor TIBTreeView.Create(TheComponent: TComponent);
167   begin
168    inherited Create(TheComponent);
678  FDataLink := TIBTreeViewDatalink.Create(self);
169    FIBTreeViewControlLink := TIBTreeViewControlLink.Create(self);
170   end;
171  
172   destructor TIBTreeView.Destroy;
173   begin
684  if assigned(FDataLink) then FDataLink.Free;
174    if assigned(FIBTreeViewControlLink) then FIBTreeViewControlLink.Free;
175    inherited Destroy;
176   end;
177  
689 function TIBTreeView.FindNode(KeyValuePath: array of variant;
690  SelectNode: boolean): TIBTreeNode;
691 var Node: TTreeNode;
692    i,j: integer;
693 begin
694  Result := nil;
695  FLocatingNode := true;
696  try
697   for j := 0 to Items.TopLvlCount - 1 do
698   begin
699    Node := Items.TopLvlItems[j];
700    i := 0;
701    Node.Expand(false);
702    while assigned(Node)  do
703    begin
704      if TIBTreeNode(Node).KeyValue = KeyValuePath[i] then
705      begin
706        Inc(i);
707        if i = Length(KeyValuePath) then
708        begin
709          Result := TIBTreeNode(Node);
710          if SelectNode then
711             Selected := Node;
712          Exit
713        end
714        else
715        begin
716          Node.Expand(false);
717          Node := Node.GetFirstChild;
718        end
719      end
720      else
721        Node := Node.GetNextSibling
722    end
723   end
724  finally
725    FLocatingNode := false
726  end
727 end;
728
729 function TIBTreeView.FindNode(KeyValue: variant): TIBTreeNode;
730 var i: integer;
731 begin
732  Result := nil;
733  if (Selected <> nil) and (TIBTreeNode(Selected).KeyValue = KeyValue) then
734     Result := TIBTreeNode(Selected)
735  else
736  {Find it the hard way}
737  begin
738    FullExpand;
739    for i := 0 to Items.Count -1 do
740      if TIBTreeNode(Items[i]).KeyValue = KeyValue then
741      begin
742        Result := TIBTreeNode(Items[i])
743      end;
744  end;
745 end;
746
747 function TIBTreeView.GetNodePath(Node: TTreeNode): TVariantArray;
748 var aParent: TTreeNode;
749    i: integer;
750 begin
751  if not assigned(Node) or not (Node is TIBTreeNode) then
752     SetLength(Result,0)
753  else
754  begin
755    {Count length of Path}
756    i := 1;
757    aParent := Node.Parent;
758    while (aParent <> nil) do
759    begin
760        Inc(i);
761        aParent := aParent.Parent
762    end;
763
764    {Save Path}
765    Setlength(Result,i);
766    while i > 0 do
767    begin
768      Dec(i);
769      Result[i] := TIBTreeNode(Node).KeyValue;
770      Node := Node.Parent
771    end;
772  end;
773 end;
774
775 { TIBTreeViewDatalink }
776
777 procedure TIBTreeViewDatalink.ActiveChanged;
778 begin
779  FOwner.ActiveChanged(self)
780 end;
781
782 procedure TIBTreeViewDatalink.DataSetChanged;
783 begin
784  FOwner.DataSetChanged(self)
785 end;
786
787 procedure TIBTreeViewDatalink.RecordChanged(Field: TField);
788 begin
789  FOwner.RecordChanged(self,Field);
790 end;
791
792 procedure TIBTreeViewDatalink.UpdateData;
793 begin
794  FOwner.UpdateData(self)
795 end;
796
797 constructor TIBTreeViewDatalink.Create(AOwner: TIBTreeView);
798 begin
799  inherited Create;
800  FOwner := AOwner
801 end;
802
178   end.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines