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 272 by tony, Mon Feb 4 13:34:37 2019 UTC vs.
Revision 315 by tony, Thu Feb 25 11:56:36 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 <    constructor Create(AnOwner: TTreeNodes); override;
81 <    procedure DeleteAll;
82 <    property KeyValue: variant read FKeyValue;
83 <  end;
84 <
85 <  TIBTreeView = class(TCustomTreeView)
59 >  TIBTreeView = class(TDBTreeView)
60    private
61      { Private declarations }
88    FDataLink: TIBTreeViewDatalink;
62      FIBTreeViewControlLink: TIBTreeViewControlLink;
90    FHasChildField: string;
91    FImageIndexField: string;
92    FKeyField: string;
93    FSelectedIndexField: string;
94    FTextField: string;
95    FParentField: string;
96    FExpandNode: TTreeNode;
97    FNoAddNodeToDataset: boolean;
98    FRelationName: string;
99    FUpdateNode: TIBTreeNode;
100    FModifiedNode: TIBTreeNode;
101    FUpdating: boolean;
102    FLocatingNode: boolean;
103    FLastSelected: TVariantArray;
104    procedure ActiveChanged(Sender: TObject);
105    procedure AddNodes;
106    procedure DataSetChanged(Sender: TObject);
107    function GetDataSet: TDataSet;
108    function GetDataSource: TDataSource;
109    function GetRelationNameQualifier: string;
110    function GetSelectedKeyValue: variant;
111    procedure IBControlLinkChanged;
112    procedure NodeMoved(Node: TTreeNode);
113    procedure NodeUpdated(Node: TTreeNode);
114    procedure RecordChanged(Sender: TObject; Field: TField);
115    procedure SetHasChildField(AValue: string);
116    procedure SetImageIndexField(AValue: string);
117    procedure SetKeyField(AValue: string);
118    procedure SetSelectedIndexField(AValue: string);
119    procedure SetTextField(AValue: string);
120    procedure SetDataSource(AValue: TDataSource);
121    procedure SetParentField(AValue: string);
122    function ScrollToNode(Node: TIBTreeNode): boolean;
123    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;
129 <     procedure Delete(Node: TTreeNode); override;
130 <     procedure Change(Node: TTreeNode); override;
131 <     function CreateNode: TTreeNode; override;
132 <     function CanEdit(Node: TTreeNode): Boolean; override;
133 <     procedure Expand(Node: TTreeNode); override;
134 <     procedure Loaded; override;
135 <     procedure NodeChanged(Node: TTreeNode; ChangeEvent: TTreeNodeChangeReason); override;
136 <     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
137 <     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;
142    function FindNode(KeyValuePath: TVariantArray; SelectNode: boolean): TIBTreeNode; overload;
143    function FindNode(KeyValue: variant): TIBTreeNode; overload;
144    function GetNodePath(Node: TTreeNode): TVariantArray;
145    property DataSet: TDataSet read GetDataSet;
146    property SelectedKeyValue: variant read GetSelectedKeyValue;
147  published
148    { Published declarations }
149    property Align;
150    property Anchors;
151    property AutoExpand;
152    property BorderSpacing;
153    //property BiDiMode;
154    property BackgroundColor;
155    property BorderStyle;
156    property BorderWidth;
157    property Color;
158    property Constraints;
159    property TextField: string read FTextField write SetTextField;
160    property DataSource: TDataSource read GetDataSource write SetDataSource;
161    property DefaultItemHeight;
162    property DragKind;
163    property DragCursor;
164    property DragMode;
165    property Enabled;
166    property ExpandSignColor;
167    property ExpandSignType;
168    property Font;
169    property HideSelection;
170    property HotTrack;
171    property Images;
172    property Indent;
173    property HasChildField: string read FHasChildField write SetHasChildField;
174    property ImageIndexField: string read FImageIndexField write SetImageIndexField;
175    property SelectedIndexField: string read FSelectedIndexField write SetSelectedIndexField;
176    property KeyField: string read FKeyField write SetKeyField;
177    property MultiSelect;
178    property MultiSelectStyle;
179    //property ParentBiDiMode;
180    property ParentColor default False;
181    property ParentField: string read FParentField write SetParentField;
182    property ParentFont;
183    property ParentShowHint;
184    property PopupMenu;
185    property ReadOnly;
186    property RelationName: string read FRelationName write FRelationName;
187    property RightClickSelect;
188    property RowSelect;
189    property ScrollBars;
190    property SelectionColor;
191    property ShowButtons;
192    property ShowHint;
193    property ShowLines;
194    property ShowRoot;
195    property StateImages;
196    property TabOrder;
197    property TabStop default True;
198    property Tag;
199    property ToolTips;
200    property Visible;
201    property OnAddition;
202    property OnAdvancedCustomDraw;
203    property OnAdvancedCustomDrawItem;
204    property OnChange;
205    property OnChanging;
206    property OnClick;
207    property OnCollapsed;
208    property OnCollapsing;
209    property OnCompare;
210    property OnContextPopup;
211    property OnCreateNodeClass;
212    property OnCustomCreateItem;
213    property OnCustomDraw;
214    property OnCustomDrawItem;
215    property OnDblClick;
216    property OnDeletion;
217    property OnDragDrop;
218    property OnDragOver;
219    property OnEdited;
220    property OnEditing;
221    property OnEditingEnd;
222    //property OnEndDock;
223    property OnEndDrag;
224    property OnEnter;
225    property OnExit;
226    property OnExpanded;
227    property OnExpanding;
228    property OnGetImageIndex;
229    property OnGetSelectedIndex;
230    property OnKeyDown;
231    property OnKeyPress;
232    property OnKeyUp;
233    property OnMouseDown;
234    property OnMouseEnter;
235    property OnMouseLeave;
236    property OnMouseMove;
237    property OnMouseUp;
238    property OnNodeChanged;
239    property OnSelectionChanged;
240    property OnShowHint;
241    //property OnStartDock;
242    property OnStartDrag;
243    property OnUTF8KeyPress;
244    property Options;
245    property Items;
246    property TreeLineColor;
247    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;
258 var i, idx: integer;
259    List: TStringList;
82   begin
83 <  List := TStringList.Create;
262 <  try
263 <    idx := 1;
264 <    List.Clear;
265 <    while idx <= Length(s) do
266 <       List.Add(ExtractFieldName(s,idx));
267 <
268 <    Setlength(Result,List.Count);
269 <    for i := 0 to List.Count - 1 do
270 <        Result[i] := StrToInt(List[i])
271 <  finally
272 <    List.Free
273 <  end;
83 >  Result := DBTreeView.StrIntListToVar(s);
84   end;
85  
86   function VarToStrIntList(a: TVariantArray): string;
277 var i: integer;
87   begin
88 <  for i := 0 to Length(a) - 1 do
280 <      if VarIsOrdinal(a[i]) then
281 <      begin
282 <        if i = 0 then
283 <           Result := IntToStr(a[i])
284 <        else
285 <          Result := Result + ';' + IntToStr(a[i])
286 <      end
287 <      else
288 <        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 306 | Line 107 | begin
107    FOwner.UpdateSQL(self,TIBParserDataSet(Sender).Parser)
108   end;
109  
309 { TIBTreeNode }
310
311 constructor TIBTreeNode.Create(AnOwner: TTreeNodes);
312 begin
313  inherited Create(AnOwner);
314  FKeyValue := NULL;
315 end;
316
317 procedure TIBTreeNode.DeleteAll;
318 var Node, NextNode: TTreeNode;
319 begin
320    Expand(true);
321    Node := GetFirstChild;
322    while Node <> nil do
323    begin
324      NextNode := Node.GetNextSibling;
325      TIBTreeNode(Node).DeleteAll;
326      Node := NextNode;
327    end;
328    Delete
329 end;
330
331 { TIBTreeView }
332
333 procedure TIBTreeView.ActiveChanged(Sender: TObject);
334 begin
335  if (csDesigning in ComponentState) then Exit;
336  IBControlLinkChanged;
337  if assigned(DataSet) and not DataSet.Active then
338  begin
339    if not assigned(FExpandNode) and not assigned(FUpdateNode) then {must really be closing}
340      Reinitialise
341  end
342  else
343  begin
344    AddNodes;
345    if not FLocatingNode and (Selected = nil) and (Items.TopLvlCount > 0) then
346    begin
347      if Length(FLastSelected) > 0 then
348         Selected := FindNode(FLastSelected,true)
349      else
350        Selected := Items.TopLvlItems[0];
351    end
352  end
353 end;
354
355 procedure TIBTreeView.AddNodes;
356 var Node: TTreeNode;
357    ChildCount: integer;
358 begin
359  if assigned(FExpandNode) or (Items.Count = 0) then
360  begin
361    ChildCount := 0;
362    FNoAddNodeToDataset := true;
363    try
364      DataSet.First;
365      while not DataSet.EOF do
366      begin
367        if (FExpandNode = nil) or (TIBTreeNode(FExpandNode).KeyValue <> DataSet.FieldByName(KeyField).AsVariant) then
368        begin
369          Node := Items.AddChild(FExpandNode,DataSet.FieldByName(TextField).AsString);
370          Node.HasChildren := (HasChildField = '') or (DataSet.FieldByName(HasChildField).AsInteger <> 0);
371          Inc(ChildCount);
372        end;
373        DataSet.Next
374      end;
375    finally
376      FNoAddNodeToDataset := false
377    end;
378    if assigned(FExpandNode) then
379      FExpandNode.HasChildren := ChildCount > 0;
380    FExpandNode := nil
381  end
382 end;
383
384 procedure TIBTreeView.DataSetChanged(Sender: TObject);
385 begin
386 //  Do nothing;
387 end;
388
389 function TIBTreeView.GetDataSet: TDataSet;
390 begin
391  Result := FDataLink.DataSet
392 end;
393
394 function TIBTreeView.GetDataSource: TDataSource;
395 begin
396  Result := FDataLink.DataSource
397 end;
398
399 function TIBTreeView.GetRelationNameQualifier: string;
400 begin
401  if FRelationName <> '' then
402     Result := FRelationName + '.'
403  else
404    Result := ''
405 end;
406
407 function TIBTreeView.GetSelectedKeyValue: variant;
408 begin
409  Result := NULL;
410  if assigned(Selected) and (Selected is TIBTreeNode) then
411     Result := TIBTreeNode(Selected).KeyValue
412 end;
413
414 procedure TIBTreeView.NodeMoved(Node: TTreeNode);
415 begin
416  {Need to update Parent}
417  if ScrollToNode(TIBTreeNode(Node))  then
418  begin
419      FDataLink.Edit;
420      FModifiedNode := TIBTreeNode(Node)
421  end;
422 end;
423
424 procedure TIBTreeView.NodeUpdated(Node: TTreeNode);
425 begin
426  {Need to Update List Field}
427  if ScrollToNode(TIBTreeNode(Node)) then
428  begin
429    FDataLink.Edit;
430    FModifiedNode := TIBTreeNode(Node);
431    FDataLink.UpdateRecord
432  end;
433 end;
434
435 procedure TIBTreeView.RecordChanged(Sender: TObject; Field: TField);
436 var Node: TIBTreeNode;
437    Destination: TIBTreeNode;
438 begin
439  if DataSet.State = dsInsert then Exit;
440
441  if assigned(Field) and (Field.FieldName = TextField) then
442  begin
443    Node := FindNode(DataSet.FieldByName(KeyField).AsVariant);
444    if assigned(Node) then
445    begin
446      FUpdating := true;
447      try
448        Node.Text := Field.Text
449      finally
450        FUpdating := false
451      end;
452    end;
453  end
454  else
455  if assigned(Field) and (Field.FieldName = ImageIndexField) then
456  begin
457    Node := FindNode(DataSet.FieldByName(KeyField).AsVariant);
458    if assigned(Node) then
459    begin
460      FUpdating := true;
461      try
462        Node.ImageIndex := Field.AsInteger
463      finally
464        FUpdating := false
465      end;
466    end;
467  end
468  else
469  if assigned(Field) and (Field.FieldName = ParentField) then
470  begin
471    Node := FindNode(DataSet.FieldByName(KeyField).AsVariant);
472    if assigned(Node)  then
473    begin
474      if DataSet.FieldByName(ParentField).IsNull then
475         Destination := nil
476      else
477        Destination := FindNode(DataSet.FieldByName(ParentField).AsVariant);
478
479      if (Destination = nil) or (Destination = Node.Parent) then Exit;
480
481      FUpdating := true;
482      try
483        Node.MoveTo(Destination,naAddChild);
484      finally
485        FUpdating := false
486      end;
487    end;
488  end
489 end;
490
491 procedure TIBTreeView.SetHasChildField(AValue: string);
492 begin
493  if FHasChildField = AValue then Exit;
494  FHasChildField := AValue;
495  Reinitialise
496 end;
497
498 procedure TIBTreeView.SetImageIndexField(AValue: string);
499 begin
500  if FImageIndexField = AValue then Exit;
501  FImageIndexField := AValue;
502  Reinitialise
503 end;
504
505 procedure TIBTreeView.SetKeyField(AValue: string);
506 begin
507  if FKeyField = AValue then Exit;
508  FKeyField := AValue;
509  Reinitialise
510 end;
511
512 procedure TIBTreeView.SetSelectedIndexField(AValue: string);
513 begin
514  if FSelectedIndexField = AValue then Exit;
515  FSelectedIndexField := AValue;
516  Reinitialise;
517 end;
518
519 procedure TIBTreeView.SetTextField(AValue: string);
520 begin
521  if FTextField = AValue then Exit;
522  FTextField := AValue;
523  Reinitialise
524 end;
525
526 procedure TIBTreeView.SetDataSource(AValue: TDataSource);
527 begin
528  FDataLink.DataSource := AValue;
529  IBControlLinkChanged;
530 end;
531
532 procedure TIBTreeView.SetParentField(AValue: string);
533 begin
534  if FParentField = AValue then Exit;
535  FParentField := AValue;
536  Reinitialise
537 end;
538
539 function TIBTreeView.ScrollToNode(Node: TIBTreeNode): boolean;
540 begin
541  Result :=  assigned(DataSet) and DataSet.Active and assigned(Node) and not varIsNull(Node.KeyValue);
542  if Result then
543  begin
544    if DataSet.Active and (DataSet.RecordCount > 0)
545         and DataSet.Locate(KeyField,Node.KeyValue,[]) then Exit;
546
547    FUpdateNode := Node;
548    try
549      DataSet.Active := false;
550      DataSet.Active := true;
551    finally
552      FUpdateNode := nil
553    end;
554    Result := DataSet.FieldByName(KeyField).AsVariant = Node.KeyValue
555  end;
556 end;
557
558 procedure TIBTreeView.UpdateData(Sender: TObject);
559 begin
560  if assigned(FModifiedNode) then
561  begin
562    DataSet.FieldByName(TextField).AsString := FModifiedNode.Text;
563    if FModifiedNode.Parent = nil then
564      DataSet.FieldByName(ParentField).Clear
565    else
566      DataSet.FieldByName(ParentField).AsVariant := TIBTreeNode(FModifiedNode.Parent).KeyValue;
567    FModifiedNode := nil
568  end
569 end;
110  
111   procedure TIBTreeView.UpdateParams(Sender: TObject; Parser: TSelectSQLParser);
112   begin
# Line 585 | 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      begin
147 <      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + FParentField + '" = :IBX_PARENT_VALUE');
148 <      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + FKeyField + '" = :IBX_PARENT_VALUE',true);
609 <    end;
610 < end;
611 <
612 < procedure TIBTreeView.Added(Node: TTreeNode);
613 < begin
614 <  if assigned(DataSet) and DataSet.Active then
615 <  begin
616 <    if not FNoAddNodeToDataset then
617 <    begin
618 <      DataSet.Append;
619 <      if (Node.Text = '') and not DataSet.FieldByName(TextField).IsNull then
620 <         Node.Text := DataSet.FieldByName(TextField).AsString;
621 <      FModifiedNode := TIBTreeNode(Node);
622 <      FDataLink.UpdateRecord;
147 >      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + ParentField + '" = :IBX_PARENT_VALUE');
148 >      Parser.Add2WhereClause(GetRelationNameQualifier + '"' + KeyField + '" = :IBX_PARENT_VALUE',true);
149      end;
624    TIBTreeNode(Node).FKeyValue := DataSet.FieldByName(KeyField).AsVariant;
625    if ImageIndexField <> '' then
626      Node.ImageIndex := DataSet.FieldByName(ImageIndexField).AsInteger;
627    if SelectedIndexField <> '' then
628      Node.SelectedIndex := DataSet.FieldByName(SelectedIndexField).AsInteger;
629  end;
630  inherited Added(Node);
631 end;
632
633 procedure TIBTreeView.Delete(Node: TTreeNode);
634 begin
635  if not (tvsUpdating in States) {TreeNodes being cleared}
636     and not (tvsManualNotify in States) {Tree Collapse with node delete}
637     and ScrollToNode(TIBTreeNode(Node)) then
638     DataSet.Delete;
639  inherited Delete(Node);
640 end;
641
642 procedure TIBTreeView.Change(Node: TTreeNode);
643 begin
644  inherited Change(Node);
645  ScrollToNode(TIBTreeNode(Node));
646 end;
647
648 function TIBTreeView.CreateNode: TTreeNode;
649 var
650  NewNodeClass: TTreeNodeClass;
651 begin
652  Result := nil;
653  if Assigned(OnCustomCreateItem) then
654    OnCustomCreateItem(Self, Result);
655  if Result = nil then
656  begin
657    NewNodeClass:=TIBTreeNode;
658    if Assigned(OnCreateNodeClass) then
659      OnCreateNodeClass(Self,NewNodeClass);
660    Result := NewNodeClass.Create(Items);
661  end;
662 end;
663
664 function TIBTreeView.CanEdit(Node: TTreeNode): Boolean;
665 begin
666  Result := inherited CanEdit(Node)
667              and assigned(DataSet) and not DataSet.FieldByName(TextField).ReadOnly
668 end;
669
670 procedure TIBTreeView.Expand(Node: TTreeNode);
671 begin
672  inherited Expand(Node);
673  if Node.HasChildren and assigned(DataSet) and (Node.GetFirstChild = nil) then
674  begin
675    FExpandNode := Node;
676    DataSet.Active := false;
677    DataSet.Active := true;
678    Selected := Node;
679  end;
680 end;
681
682 procedure TIBTreeView.IBControlLinkChanged;
683 begin
684  if assigned(DataSource) and (DataSource.DataSet <> nil) and (DataSource.DataSet is TIBParserDataset) then
685    FIBTreeViewControllink.IBDataSet := TIBCustomDataSet(DataSource.DataSet)
686  else
687    FIBTreeViewControllink.IBDataSet := nil;
150   end;
151  
152 < procedure TIBTreeView.Loaded;
152 > procedure TIBTreeView.DataSourceChanged;
153   begin
154 <  inherited Loaded;
155 <  IBControlLinkChanged;
156 <  Reinitialise
157 < end;
696 <
697 < procedure TIBTreeView.NodeChanged(Node: TTreeNode;
698 <  ChangeEvent: TTreeNodeChangeReason);
699 < begin
700 <  inherited NodeChanged(Node, ChangeEvent);
701 <  if not FNoAddNodeToDataset and not FUpdating then
702 <  case ChangeEvent of
703 <  ncTextChanged:
704 <    NodeUpdated(Node);
705 <  ncParentChanged:
706 <    NodeMoved(Node);
707 <  end;
708 < end;
709 <
710 < procedure TIBTreeView.Notification(AComponent: TComponent; Operation: TOperation
711 <  );
712 < begin
713 <  inherited Notification(AComponent, Operation);
714 <  if (Operation = opRemove) and
715 <     (FDataLink <> nil) and (AComponent = DataSource) then
716 <     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);
723 <  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);
729  FDataLink := TIBTreeViewDatalink.Create(self);
169    FIBTreeViewControlLink := TIBTreeViewControlLink.Create(self);
170   end;
171  
172   destructor TIBTreeView.Destroy;
173   begin
735  if assigned(FDataLink) then FDataLink.Free;
174    if assigned(FIBTreeViewControlLink) then FIBTreeViewControlLink.Free;
175    inherited Destroy;
176   end;
177  
740 function TIBTreeView.FindNode(KeyValuePath: TVariantArray; SelectNode: boolean
741  ): TIBTreeNode;
742 var Node: TTreeNode;
743    i,j: integer;
744 begin
745  Result := nil;
746  if Length(KeyValuePath) = 0 then Exit;
747
748  FLocatingNode := true;
749  try
750   for j := 0 to Items.TopLvlCount - 1 do
751   begin
752    Node := Items.TopLvlItems[j];
753    i := 0;
754    Node.Expand(false);
755    while assigned(Node)  do
756    begin
757      if not VarIsNull(TIBTreeNode(Node).KeyValue) and
758                        (TIBTreeNode(Node).KeyValue = KeyValuePath[i]) then
759      begin
760        Inc(i);
761        if i = Length(KeyValuePath) then
762        begin
763          Result := TIBTreeNode(Node);
764          if SelectNode then
765             Selected := Node;
766          Exit
767        end
768        else
769        begin
770          Node.Expand(false);
771          Node := Node.GetFirstChild;
772        end
773      end
774      else
775        Node := Node.GetNextSibling
776    end
777   end
778  finally
779    FLocatingNode := false
780  end
781 end;
782
783 function TIBTreeView.FindNode(KeyValue: variant): TIBTreeNode;
784 var i: integer;
785 begin
786  Result := nil;
787  if (Selected <> nil) and (TIBTreeNode(Selected).KeyValue = KeyValue) then
788     Result := TIBTreeNode(Selected)
789  else
790  {Find it the hard way}
791  begin
792    FullExpand;
793    for i := 0 to Items.Count -1 do
794      if TIBTreeNode(Items[i]).KeyValue = KeyValue then
795      begin
796        Result := TIBTreeNode(Items[i])
797      end;
798  end;
799 end;
800
801 function TIBTreeView.GetNodePath(Node: TTreeNode): TVariantArray;
802 var aParent: TTreeNode;
803    i: integer;
804 begin
805  if not assigned(Node) or not (Node is TIBTreeNode) then
806     SetLength(Result,0)
807  else
808  begin
809    {Count length of Path}
810    i := 1;
811    aParent := Node.Parent;
812    while (aParent <> nil) do
813    begin
814        Inc(i);
815        aParent := aParent.Parent
816    end;
817
818    {Save Path}
819    Setlength(Result,i);
820    while i > 0 do
821    begin
822      Dec(i);
823      Result[i] := TIBTreeNode(Node).KeyValue;
824      Node := Node.Parent
825    end;
826  end;
827 end;
828
829 { TIBTreeViewDatalink }
830
831 procedure TIBTreeViewDatalink.ActiveChanged;
832 begin
833  FOwner.ActiveChanged(self)
834 end;
835
836 procedure TIBTreeViewDatalink.DataSetChanged;
837 begin
838  FOwner.DataSetChanged(self)
839 end;
840
841 procedure TIBTreeViewDatalink.RecordChanged(Field: TField);
842 begin
843  FOwner.RecordChanged(self,Field);
844 end;
845
846 procedure TIBTreeViewDatalink.UpdateData;
847 begin
848  FOwner.UpdateData(self)
849 end;
850
851 constructor TIBTreeViewDatalink.Create(AOwner: TIBTreeView);
852 begin
853  inherited Create;
854  FOwner := AOwner
855 end;
856
178   end.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines