unit ULObjUsrTreeViewu;{v0.62}{TreeView for rendering ULObj}
{
  (C) 2000 - 2001 Jindrich Jindrich, Pavel Pisa, PiKRON Ltd.

  Originators of the CHROMuLAN project:

  Jindrich Jindrich - http://www.jindrich.com
                      http://orgchem.natur.cuni.cz/Chromulan/
                      software developer, project coordinator
  Pavel Pisa        - http://cmp.felk.cvut.cz/~pisa
                      embeded software developer
  PiKRON Ltd.       - http://www.pikron.com
                      project initiator, sponsor, instrument developer

  The CHROMuLAN project is distributed under the GNU General Public Licence.
  See file COPYING for details.

  Originators reserve the right to use and publish sources
  under different conditions too. If third party contributors
  do not accept this condition, they can delete this statement
  and only GNU license will apply.
}
interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls,
  ULObjUsru, ULObjEditPanelu, ComCtrls, ULStringGrid;

type

  TULObjUsrTreeView = class(TTreeView)
  private
    { Private declarations }
    FULObjUsr: TULObjUsr;
    FGrid: TULStringGrid;
    FPanel: TULObjEditPanel;
    FOwnsObjUsr: boolean;
    procedure SetULObjUsr(AULObjUsr: TULObjUsr);
    procedure AddChilds(ANode: TTreeNode{v0.62}{/v0.62 ; AULObjUsr: TULObjUsr});
    {v0.62}
    procedure RemoveChilds(ANode: TTreeNode);
    {/v0.62}
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); reintroduce;
    destructor Destroy; override;
    function NodeAdd(AOwnerNode: TTreeNode; AULObjUsr: TULObjUsr): TTreeNode;

    procedure TreeViewChange(Sender: TObject; Node: TTreeNode);
    procedure TreeViewExpanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    procedure TreeViewCollapsed(Sender: TObject; Node: TTreeNode);

    property ULObjUsr: TULObjUsr read FULObjUsr write SetULObjUsr;
    property OwnsObjUsr: boolean read FOwnsObjUsr write FOwnsObjUsr;
    property Grid: TULStringGrid read FGrid write FGrid;
    property Panel: TULObjEditPanel read FPanel write FPanel;
  end;

procedure TreeNodeUpdateChilds(ANode: TTreeNode);

implementation
uses
  ULObjUsrNodeu;

function TreeNodeHasChildData(ANode: TTreeNode; AData:pointer): boolean;
var
  i: integer;
begin
  Result := false;
  for i := 0 to ANode.Count - 1 do begin
    if ANode.Item[i].Data = AData then begin
      Result := true;
      exit;
    end;
  end;
end;

procedure TreeNodeUpdateChilds(ANode: TTreeNode);
var
  u, c: TULObjUsr;
  i: integer;
  n: TTreeNode;
begin
  u := TULObjUsr(ANode.Data);
  i := 0;
  while i < ANode.Count do begin
    c := TULObjUsr(ANode.Item[i].Data);
    if u.ChildList.IndexOf(c) < 0 then begin
      ANode.Item[i].Delete;
    end else begin
      inc(i);
    end;
  end;
  for i := 0 to u.ChildCount - 1 do begin
    c := u.Childs[i];
    if not TreeNodeHasChildData(ANode, c) then begin
      {
      TULObjUsrTreeView(ANode.TreeView).NodeAdd(ANode, c);}
      n := TTreeView(ANode.TreeView).Items.AddChildObject(ANode, c.Caption, c);
      if c is TULObjUsrNode then with c as TULObjUsrNode do begin
        TreeNodeRegister(n);
      end;
      n.HasChildren := true;
    end;
  end;
end;


{TULObjUsrTreeView.}
procedure TULObjUsrTreeView.SetULObjUsr(AULObjUsr: TULObjUsr);

{  i: integer;}
{v0.62}{/v0.62 n: TTreeNode;}

begin
  {ttreeview}
  if FULObjUsr = AULObjUsr then
    exit;
  if FULObjUsr <> nil then begin
    if FOwnsObjUsr then
      FULObjUsr.Free;
  end;
  FULObjUsr := AULObjUsr;
  Items.Clear;
  if FULObjUsr <> nil then begin
    NodeAdd(nil, AULObjUsr);
  end;
end;

procedure TULObjUsrTreeView.AddChilds(ANode: TTreeNode);
var
  AULObjUsr: TULObjUsr;
  i: integer;
begin
  AULObjUsr := TULObjUsr(ANode.Data);
  for i := 0 to AULObjUsr.ChildCount - 1 do begin
    if not TreeNodeHasChildData(ANode, AULObjUsr.Childs[i]) then
      NodeAdd(ANode, AULObjUsr.Childs[i]);
  end;
end;

function TULObjUsrTreeView.NodeAdd(AOwnerNode: TTreeNode; AULObjUsr: TULObjUsr): TTreeNode;
begin
  Result := Items.AddChildObject(AOwnerNode, AULObjUsr.Caption, AULObjUsr);
  if AULObjUsr is TULObjUsrNode then with AULObjUsr as TULObjUsrNode do begin
    TreeNodeRegister(Result);
  end;
  Result.HasChildren := true;
end;

procedure TULObjUsrTreeView.RemoveChilds(ANode: TTreeNode);
var
  n: TTreeNode;
  u: TULObjUsr;
begin
  while ANode.Count > 0 do begin
    n := ANode.Item[0];
    RemoveChilds(n);
    u := TULObjUsr(n.Data);
    if u is TULObjUsrNode then with u as TULObjUsrNode do begin
      TreeNodeUnregister(n);
    end;
    n.Delete;
  end;
end;

constructor TULObjUsrTreeView.Create(AOwner: TComponent);
begin
  { was in TreeForm:
  FGrid := TULStringGrid.Create(Self);
  FGrid.AutoSizeBrowseCols := true;
  FGrid.Align := alClient;
  FGrid.Left := 350;
  FGrid.Top := 5;
  FGrid.Width := 200;
  FGrid.Height := 400;
  FGrid.Parent := Self;
  }
  inherited Create(AOwner);
  OnChange := TreeViewChange;
  OnCollapsed := TreeViewCollapsed;
  OnExpanding := TreeViewExpanding;
end;

procedure TULObjUsrTreeView.TreeViewChange(Sender: TObject;
  Node: TTreeNode);
begin
  if FGrid <> nil then
    FGrid.Obj := TULObjUsr(Node.Data).Obj;
  if FPanel <> nil then
    FPanel.Obj := TULObjUsr(Node.Data).Obj;
end;

destructor TULObjUsrTreeView.Destroy;
begin
  ULObjUsr := nil;
  inherited;
end;

procedure TULObjUsrTreeView.TreeViewExpanding(Sender: TObject;
  Node: TTreeNode; var AllowExpansion: Boolean);
begin
  AddChilds(Node);
end;

procedure TULObjUsrTreeView.TreeViewCollapsed(Sender: TObject;
  Node: TTreeNode); {ttreeview}
begin
  RemoveChilds(Node);
  Node.HasChildren := true;
end;

end.
