home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d56 / RMCTL.ZIP / rmTreeNonView.pas < prev    next >
Pascal/Delphi Source File  |  2001-06-22  |  39KB  |  1,473 lines

  1. {================================================================================
  2. Copyright (C) 1997-2001 Mills Enterprise
  3.  
  4. Unit     : rmTreeNonView
  5. Purpose  : To have a non-visual tree component.
  6. Date     : 12-01-1999
  7. Author   : Ryan J. Mills
  8. Version  : 1.80
  9. Notes    : This unit was originally based upon the work of Patrick O'Keeffe.
  10.            It was at his request that I took the component over and rm'ified it.
  11. ================================================================================}
  12.  
  13. unit rmTreeNonView;
  14.  
  15. interface
  16.  
  17. {$I CompilerDefines.INC}
  18.  
  19. uses
  20.    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  21.    Contnrs;
  22.  
  23. type
  24.    TAddMode = (taAddFirst, taAdd, taInsert) ;
  25.    TNodeAttachMode = (naAdd, naAddFirst, naAddChild, naAddChildFirst, naInsert) ;
  26.  
  27.    PNodeInfo = ^TNodeInfo;
  28.    TNodeInfo = packed record
  29.       Count: Integer;
  30.       Text: string[255];
  31.    end;
  32.  
  33.    TrmCustomTreeNonView = class;
  34.    TrmTreeNonViewNodes = class;
  35.    TrmTreeNonViewNode = class;
  36.  
  37.    TrmHashData = class(TObject)
  38.       Hash: longint;
  39.       IDLength: Integer;
  40.       Node: TrmTreeNonViewNode;
  41.    end;
  42.  
  43. { TrmTreeNonViewNode }
  44.  
  45.    TrmTreeNonViewNode = class(TPersistent)
  46.    private
  47.       FOwner: TrmTreeNonViewNodes;
  48.       FText: string;
  49.       FData: Pointer;
  50.       FChildList: TList;
  51.       FDeleting: Boolean;
  52.       FParent: TrmTreeNonViewNode;
  53.       fExpanded: boolean;
  54.       function GetLevel: Integer;
  55.       function GetParent: TrmTreeNonViewNode;
  56.       procedure SetParent(Value: TrmTreeNonViewNode) ;
  57.       function GetChildren: Boolean;
  58.       function GetIndex: Integer;
  59.       function GetItem(Index: Integer) : TrmTreeNonViewNode;
  60.       function GetCount: Integer;
  61.       function GetrmTreeNonView: TrmCustomTreeNonView;
  62.       function IsEqual(Node: TrmTreeNonViewNode) : Boolean;
  63.       procedure ReadData(Stream: TStream; Info: PNodeInfo) ;
  64.       procedure SetData(Value: Pointer) ;
  65.       procedure SetItem(Index: Integer; Value: TrmTreeNonViewNode) ;
  66.       procedure SetText(const S: string) ;
  67.       procedure WriteData(Stream: TStream; Info: PNodeInfo) ;
  68.       function GetItemCount: Integer;
  69.       procedure RemoveHash;
  70.       procedure RenewHash;
  71.       function GetNodePath: string;
  72.    public
  73.       constructor Create(AOwner: TrmTreeNonViewNodes) ;
  74.       destructor Destroy; override;
  75.       procedure Assign(Source: TPersistent) ; override;
  76.       procedure Delete;
  77.       procedure DeleteChildren;
  78.       function GetFirstChild: TrmTreeNonViewNode;
  79.       function GetLastChild: TrmTreeNonViewNode;
  80.       function GetNext: TrmTreeNonViewNode;
  81.       function GetNextChild(Value: TrmTreeNonViewNode) : TrmTreeNonViewNode;
  82.       function GetNextSibling: TrmTreeNonViewNode;
  83.       function GetPrev: TrmTreeNonViewNode;
  84.       function GetPrevChild(Value: TrmTreeNonViewNode) : TrmTreeNonViewNode;
  85.       function getPrevSibling: TrmTreeNonViewNode;
  86.       function HasAsParent(Value: TrmTreeNonViewNode) : Boolean;
  87.       function IndexOf(Value: TrmTreeNonViewNode) : Integer;
  88.       function MoveTo(Destination: TrmTreeNonViewNode; Mode: TNodeAttachMode) : TrmTreeNonViewNode;
  89.  
  90.       property Count: Integer read GetCount;
  91.       property Data: Pointer read FData write SetData;
  92.       property Deleting: Boolean read FDeleting;
  93.       property HasChildren: Boolean read GetChildren;
  94.       property Expanded: boolean read fExpanded write fExpanded default false;
  95.       property Index: Integer read GetIndex;
  96.       property Item[Index: Integer]: TrmTreeNonViewNode read GetItem write SetItem; default;
  97.       property Level: Integer read GetLevel;
  98.       property Owner: TrmTreeNonViewNodes read FOwner;
  99.       property Parent: TrmTreeNonViewNode read GetParent write SetParent;
  100.       property TreeNonView: TrmCustomTreeNonView read GetrmTreeNonView;
  101.       property NodePath: string read GetNodePath;
  102.       property Text: string read FText write SetText;
  103.       property ItemCount: Integer read GetItemCount;
  104.    end;
  105.  
  106. { TrmTreeNonViewNodes }
  107.  
  108.    TrmTreeNonViewNodes = class(TPersistent)
  109.    private
  110.       FOwner: TrmCustomTreeNonView;
  111.       FRootNodeList: TList;
  112.       FHashList: TObjectList;
  113.       function GetNodeFromIndex(Index: Integer) : TrmTreeNonViewNode;
  114.       procedure ReadData(Stream: TStream) ;
  115.       procedure WriteData(Stream: TStream) ;
  116.       function HashValue(St: string) : LongInt;
  117.       function LocateHashIndex(Path: string) : integer;
  118.       procedure BinaryInsert(Path: string; Node: TrmTreeNonViewNode) ;
  119.       procedure RemoveHash(Node: TrmTreeNonViewNode) ;
  120.    protected
  121.       function InternalAddObject(Node: TrmTreeNonViewNode; const S: string;
  122.          Ptr: Pointer; AddMode: TAddMode) : TrmTreeNonViewNode;
  123.       procedure DefineProperties(Filer: TFiler) ; override;
  124.       function GetCount: Integer;
  125.       procedure SetItem(Index: Integer; Value: TrmTreeNonViewNode) ;
  126.    public
  127.       procedure dumphash;
  128.       constructor Create(AOwner: TrmCustomTreeNonView) ;
  129.       destructor Destroy; override;
  130.       function AddChildFirst(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  131.       function AddChild(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  132.       function AddChildObjectFirst(Node: TrmTreeNonViewNode; const S: string;
  133.          Ptr: Pointer) : TrmTreeNonViewNode;
  134.       function AddChildObject(Node: TrmTreeNonViewNode; const S: string;
  135.          Ptr: Pointer) : TrmTreeNonViewNode;
  136.       function AddFirst(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  137.       function Add(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  138.       function AddObjectFirst(Node: TrmTreeNonViewNode; const S: string;
  139.          Ptr: Pointer) : TrmTreeNonViewNode;
  140.       function AddObject(Node: TrmTreeNonViewNode; const S: string;
  141.          Ptr: Pointer) : TrmTreeNonViewNode;
  142.       procedure Assign(Source: TPersistent) ; override;
  143.       procedure Clear;
  144.       procedure Delete(Node: TrmTreeNonViewNode) ;
  145.       function GetFirstNode: TrmTreeNonViewNode;
  146.       function Insert(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  147.       function InsertObject(Node: TrmTreeNonViewNode; const S: string;
  148.          Ptr: Pointer) : TrmTreeNonViewNode;
  149.       function LocateNode(Path: string) : TrmTreeNonViewNode;
  150.       property Count: Integer read GetCount;
  151.       property Item[Index: Integer]: TrmTreeNonViewNode read GetNodeFromIndex; default;
  152.       property Owner: TrmCustomTreeNonView read FOwner;
  153.    end;
  154.  
  155. { TrmCustomTreeNonView }
  156.  
  157.    TrmTreeNonViewEvent = procedure(Sender: TObject; Node: TrmTreeNonViewNode) of object;
  158.    ErmTreeNonViewError = class(Exception) ;
  159.  
  160.    TrmCustomTreeNonView = class(TComponent)
  161.    private
  162.       FMemStream: TMemoryStream;
  163.       FTreeNodes: TrmTreeNonViewNodes;
  164.       FOnDeletion: TrmTreeNonViewEvent;
  165.       fOnNodeTextChanged: TrmTreeNonViewEvent;
  166.       FSepChar: Char;
  167.  
  168.       procedure SetrmTreeNonViewNodes(Value: TrmTreeNonViewNodes) ;
  169.       function ParentName(s: string) : string;
  170.       function ChildName(s: string) : string;
  171.    protected
  172.       function CreateNode: TrmTreeNonViewNode; virtual;
  173.       procedure Delete(Node: TrmTreeNonViewNode) ; dynamic;
  174.  
  175.       property SepChar: Char read FSepChar write FSepChar;
  176.       property Items: TrmTreeNonViewNodes read FTreeNodes write SetrmTreeNonViewNodes;
  177.       property OnDeletion: TrmTreeNonViewEvent read FOnDeletion write FOnDeletion;
  178.       property OnNodeTextChanged: TrmTreeNonViewEvent read fOnNodeTextChanged write fOnNodeTextChanged;
  179.    public
  180.       constructor Create(AOwner: TComponent) ; override;
  181.       destructor Destroy; override;
  182.       procedure LoadFromFile(const FileName: string) ;
  183.       procedure LoadFromStream(Stream: TStream) ;
  184.       procedure SaveToFile(const FileName: string) ;
  185.       procedure SaveToStream(Stream: TStream) ;
  186.       function AddPathNode(Node: TrmTreeNonViewNode; Path: string) : TrmTreeNonViewNode;
  187.       function FindPathNode(Path: string) : TrmTreeNonViewNode;
  188.       function NodePath(Node: TrmTreeNonViewNode) : string;
  189.       procedure TextSort(ParentNode: TrmTreeNonViewNode; Recursive: boolean) ; virtual;
  190.    end;
  191.  
  192.    TrmTreeNonView = class(TrmCustomTreeNonView)
  193.    private
  194.     { Private declarations }
  195.    protected
  196.     { Protected declarations }
  197.    public
  198.     { Public declarations }
  199.    published
  200.     { Published declarations }
  201.       property SepChar;
  202.       property Items;
  203.       property OnDeletion;
  204.       property OnNodeTextChanged;
  205.    end;
  206.  
  207. implementation
  208.  
  209. uses Consts, rmLibrary;
  210.  
  211. procedure rmTreeNonViewError(const Msg: string) ;
  212. begin
  213.    raise ErmTreeNonViewError.Create(Msg) ;
  214. end;
  215.  
  216. constructor TrmTreeNonViewNode.Create(AOwner: TrmTreeNonViewNodes) ;
  217. begin
  218.    inherited Create;
  219.    FOwner := AOwner;
  220.    FChildList := TList.Create;
  221.    fExpanded := false;
  222. end;
  223.  
  224. destructor TrmTreeNonViewNode.Destroy;
  225. begin
  226.    FDeleting := True;
  227.    Data := nil;
  228.    FChildList.Free;
  229.    inherited Destroy;
  230. end;
  231.  
  232. function TrmTreeNonViewNode.GeTrmTreeNonView: TrmCustomTreeNonView;
  233. begin
  234.    Result := Owner.Owner;
  235. end;
  236.  
  237. function TrmTreeNonViewNode.HasAsParent(Value: TrmTreeNonViewNode) : Boolean;
  238. begin
  239.    if Value <> nil then
  240.    begin
  241.       if Parent = nil then
  242.          Result := False
  243.       else if Parent = Value then
  244.          Result := True
  245.       else
  246.          Result := Parent.HasAsParent(Value) ;
  247.    end
  248.    else
  249.       Result := True;
  250. end;
  251.  
  252. procedure TrmTreeNonViewNode.SetText(const S: string) ;
  253. var
  254.    fRemoved: boolean;
  255. begin
  256.    fRemoved := false;
  257.  
  258.    if not (FText = '') and (FText <> S) then
  259.    begin
  260.       Self.RemoveHash;
  261.       fRemoved := true;
  262.    end;
  263.  
  264.    FText := S;
  265.  
  266.    if fRemoved and not (fText = '') then
  267.    begin
  268.       Self.RenewHash;
  269.    end;
  270.  
  271.    if assigned(TreeNonView.OnNodeTextChanged) then
  272.       TreeNonView.OnNodeTextChanged(TreeNonView, self) ;
  273. end;
  274.  
  275. procedure TrmTreeNonViewNode.SetData(Value: pointer) ;
  276. begin
  277.    FData := Value;
  278. end;
  279.  
  280. function TrmTreeNonViewNode.GetChildren: Boolean;
  281. begin
  282.    Result := FChildList.Count > 0;
  283. end;
  284.  
  285. function TrmTreeNonViewNode.GetParent: TrmTreeNonViewNode;
  286. begin
  287.    Result := FParent;
  288. end;
  289.  
  290. procedure TrmTreeNonViewNode.SetParent(Value: TrmTreeNonViewNode) ;
  291. begin
  292.    removeHash;
  293.  
  294.    if (fParent <> nil) then
  295.       fParent.FChildList.delete(fParent.FChildList.indexOf(self) ) ;
  296.  
  297.    if value <> nil then
  298.    begin
  299.       FParent := Value;
  300.       if fParent.FChildList.indexof(self) = -1 then
  301.          fParent.FChildList.Add(self) ;
  302.       RenewHash;
  303.    end;
  304. end;
  305.  
  306. function TrmTreeNonViewNode.GetNextSibling: TrmTreeNonViewNode;
  307. var
  308.    CurIdx: Integer;
  309.  
  310. begin
  311.    if Parent <> nil then
  312.    begin
  313.       CurIdx := Parent.FChildList.IndexOf(Self) ;
  314.       if (CurIdx + 1) < Parent.FChildList.Count then
  315.          Result := Parent.FChildList.Items[CurIdx + 1]
  316.       else
  317.          Result := nil;
  318.    end
  319.    else
  320.    begin
  321.       CurIdx := Owner.FRootNodeList.IndexOf(Self) ;
  322.       if (CurIdx + 1) < Owner.FRootNodeList.Count then
  323.          Result := Owner.FRootNodeList.Items[CurIdx + 1]
  324.       else
  325.          Result := nil;
  326.    end;
  327. end;
  328.  
  329. function TrmTreeNonViewNode.GetPrevSibling: TrmTreeNonViewNode;
  330. var
  331.    CurIdx: Integer;
  332. begin
  333.    if Parent <> nil then
  334.    begin
  335.       CurIdx := Parent.FChildList.IndexOf(Self) ;
  336.       if (CurIdx - 1) >= 0 then
  337.          Result := Parent.FChildList.Items[CurIdx - 1]
  338.       else
  339.          Result := nil;
  340.    end
  341.    else
  342.    begin
  343.       CurIdx := Owner.FRootNodeList.IndexOf(Self) ;
  344.       if (CurIdx - 1) >= Owner.FRootNodeList.Count then
  345.          Result := Owner.FRootNodeList.Items[CurIdx - 1]
  346.       else
  347.          Result := nil;
  348.    end;
  349. end;
  350.  
  351. function TrmTreeNonViewNode.GetNextChild(Value: TrmTreeNonViewNode) : TrmTreeNonViewNode;
  352. begin
  353.    if Value <> nil then
  354.       Result := Value.GetNextSibling
  355.    else
  356.       Result := nil;
  357. end;
  358.  
  359. function TrmTreeNonViewNode.GetPrevChild(Value: TrmTreeNonViewNode) : TrmTreeNonViewNode;
  360. begin
  361.    if Value <> nil then
  362.       Result := Value.GetPrevSibling
  363.    else
  364.       Result := nil;
  365. end;
  366.  
  367. function TrmTreeNonViewNode.GetFirstChild: TrmTreeNonViewNode;
  368. begin
  369.    if FChildList.Count > 0 then
  370.    begin
  371.       Result := FChildList.Items[0];
  372.    end
  373.    else
  374.       Result := nil;
  375. end;
  376.  
  377. function TrmTreeNonViewNode.GetLastChild: TrmTreeNonViewNode;
  378. begin
  379.    if FChildList.Count > 0 then
  380.    begin
  381.       Result := FChildList.Items[FChildList.Count - 1]
  382.    end
  383.    else
  384.       Result := nil;
  385. end;
  386.  
  387. function TrmTreeNonViewNode.GetNext: TrmTreeNonViewNode;
  388. var
  389.    N: TrmTreeNonViewNode;
  390.    P: TrmTreeNonViewNode;
  391.  
  392. begin
  393.    if HasChildren then
  394.       N := GetFirstChild
  395.    else
  396.    begin
  397.       N := GetNextSibling;
  398.       if N = nil then
  399.       begin
  400.          P := Parent;
  401.          while P <> nil do
  402.          begin
  403.             N := P.GetNextSibling;
  404.             if N <> nil then
  405.                Break;
  406.             P := P.Parent;
  407.          end;
  408.       end;
  409.    end;
  410.    Result := N;
  411. end;
  412.  
  413. function TrmTreeNonViewNode.GetPrev: TrmTreeNonViewNode;
  414. var
  415.    Node: TrmTreeNonViewNode;
  416.  
  417. begin
  418.    Result := GetPrevSibling;
  419.    if Result <> nil then
  420.    begin
  421.       Node := Result;
  422.       repeat
  423.          Result := Node;
  424.          Node := Result.GetLastChild;
  425.       until Node = nil;
  426.    end
  427.    else
  428.       Result := Parent;
  429. end;
  430.  
  431. function TrmTreeNonViewNode.GetIndex: Integer;
  432. var
  433.    Node: TrmTreeNonViewNode;
  434.  
  435. begin
  436.    Result := -1;
  437.    Node := parent;
  438.    if Node = nil then
  439.    begin
  440.       if fowner <> nil then
  441.          FOwner.FRootNodeList.indexof(self)
  442.    end
  443.    else
  444.       result := parent.FChildList.indexof(self) ;
  445.  
  446. {  Result := -1;
  447.   Node := Self;
  448.   while Node <> nil do
  449.   begin
  450.     Inc(Result);
  451.     Node := Node.GetPrevSibling;
  452.   end;}
  453. end;
  454.  
  455. function TrmTreeNonViewNode.GetItem(Index: Integer) : TrmTreeNonViewNode;
  456. begin
  457.    if (index >= 0) and (index < FChildList.count) then
  458.       Result := fchildlist[index]
  459.    else
  460.    begin
  461.       result := nil;
  462.       rmTreeNonViewError('List Index Out of Bounds') ;
  463.    end;
  464.  
  465. {  Result := GetFirstChild;
  466.   while (Result <> nil) and (Index > 0) do
  467.   begin
  468.     Result := GetNextChild(Result);
  469.     Dec(Index);
  470.   end;
  471.   if Result = nil then rmTreeNonViewError('List Index Out of Bounds');}
  472. end;
  473.  
  474. procedure TrmTreeNonViewNode.SetItem(Index: Integer; Value: TrmTreeNonViewNode) ;
  475. begin
  476.    item[Index].Assign(Value) ;
  477. end;
  478.  
  479. function TrmTreeNonViewNode.IndexOf(Value: TrmTreeNonViewNode) : Integer;
  480. {var
  481.   Node: TrmTreeNonViewNode;}
  482. begin
  483.    Result := fChildList.indexof(Value) ;
  484. {  Result := -1;
  485.   Node := GetFirstChild;
  486.   while (Node <> nil) do
  487.   begin
  488.     Inc(Result);
  489.     if Node = Value then Break;
  490.     Node := GetNextChild(Node);
  491.   end;
  492.   if Node = nil then
  493.     Result := -1;}
  494. end;
  495.  
  496. function TrmTreeNonViewNode.MoveTo(Destination: TrmTreeNonViewNode; Mode: TNodeAttachMode) : TrmTreeNonViewNode;
  497. var
  498.    AddMode: TAddMode;
  499.    node: TrmTreeNonViewNode;
  500.  
  501. begin
  502.    Result := nil;
  503.    if (Destination = nil) or not Destination.HasAsParent(Self) then
  504.    begin
  505.       AddMode := taAdd;
  506.       if (Destination <> nil) and not (Mode in [naAddChild, naAddChildFirst]) then
  507.          Node := Destination.Parent
  508.       else
  509.          Node := Destination;
  510.  
  511.       case Mode of
  512.          naAdd,
  513.             naAddChild: AddMode := taAdd;
  514.          naAddFirst,
  515.             naAddChildFirst: AddMode := taAddFirst;
  516.          naInsert:
  517.             begin
  518.                Node := Destination.GetPrevSibling;
  519.                if Node = nil then
  520.                   AddMode := taAddFirst
  521.                else
  522.                   AddMode := taInsert;
  523.             end;
  524.       end;
  525.       if node <> self then
  526.       begin
  527.          result := owner.InternalAddObject(node, Text, data, AddMode) ;
  528.          delete;
  529.       end;
  530.    end
  531.    else
  532.       result := self;
  533. end;
  534.  
  535. function TrmTreeNonViewNode.GetCount: Integer;
  536. {var
  537.   Node: TrmTreeNonViewNode;}
  538. begin
  539.    result := FChildList.Count;
  540. {  Result := 0;
  541.   Node := GetFirstChild;
  542.   while Node <> nil do
  543.   begin
  544.     Inc(Result);
  545.     Node := Node.GetNextChild(Node);
  546.   end;}
  547. end;
  548.  
  549. function TrmTreeNonViewNode.GetLevel: Integer;
  550. var
  551.    Node: TrmTreeNonViewNode;
  552.  
  553. begin
  554.    Result := 0;
  555.    Node := Parent;
  556.    while Node <> nil do
  557.    begin
  558.       Inc(Result) ;
  559.       Node := Node.Parent;
  560.    end;
  561. end;
  562.  
  563. procedure TrmTreeNonViewNode.Delete;
  564. begin
  565.    if HasChildren then
  566.       DeleteChildren;
  567.  
  568.    Owner.RemoveHash(self) ;
  569.    if Parent <> nil then
  570.    begin
  571.       Parent.FChildList.Delete(Parent.FChildList.IndexOf(Self) ) ;
  572.       Parent.FChildList.Pack;
  573.    end
  574.    else
  575.    begin
  576.       Owner.FRootNodeList.Delete(Owner.FRootNodeList.IndexOf(Self) ) ;
  577.       Owner.FRootNodeList.Pack;
  578.    end;
  579.    TrmCustomTreeNonView(Owner.Owner) .Delete(Self) ;
  580.    Free;
  581. end;
  582.  
  583. procedure TrmTreeNonViewNode.DeleteChildren;
  584. var
  585.    Node: TrmTreeNonViewNode;
  586.  
  587. begin
  588.    Node := GetFirstChild;
  589.    while Node <> nil do
  590.    begin
  591.       Node.Delete;
  592.       Node := GetFirstChild;
  593.    end;
  594. end;
  595.  
  596. procedure TrmTreeNonViewNode.Assign(Source: TPersistent) ;
  597. var
  598.    Node: TrmTreeNonViewNode;
  599.  
  600. begin
  601.    if Source is TrmTreeNonViewNode then
  602.    begin
  603.       Node := TrmTreeNonViewNode(Source) ;
  604.       Text := Node.Text;
  605.       Data := Node.Data;
  606.    end
  607.    else
  608.       inherited Assign(Source) ;
  609. end;
  610.  
  611. function TrmTreeNonViewNode.IsEqual(Node: TrmTreeNonViewNode) : Boolean;
  612. begin
  613.    Result := (Text = Node.Text) and (Data = Node.Data) ;
  614. end;
  615.  
  616. procedure TrmTreeNonViewNode.ReadData(Stream: TStream; Info: PNodeInfo) ;
  617. var
  618.    I, Size, ItemCount: Integer;
  619.    ObjType: Integer;
  620.  
  621. begin
  622.    Stream.ReadBuffer(Size, SizeOf(Size) ) ;
  623.    Stream.ReadBuffer(Info^, Size) ;
  624.    Text := Info^.Text;
  625.    ItemCount := Info^.Count;
  626.    Stream.ReadBuffer(ObjType, SizeOf(ObjType) ) ;
  627.    case ObjType of
  628.       0:
  629.          begin
  630.         //do nothing
  631.          end;
  632.  
  633.       1:
  634.          begin
  635.             Data := Stream.ReadComponent(nil) ;
  636.          end;
  637.    end;
  638.    for I := 0 to ItemCount - 1 do
  639.       Owner.AddChild(Self, '') .ReadData(Stream, Info) ;
  640. end;
  641.  
  642. procedure TrmTreeNonViewNode.WriteData(Stream: TStream; Info: PNodeInfo) ;
  643. var
  644.    I,
  645.       Size,
  646.       L,
  647.       ItemCount,
  648.       ObjType: Integer;
  649.  
  650. begin
  651.    L := Length(Text) ;
  652.    if L > 255 then
  653.       L := 255;
  654.    Size := SizeOf(TNodeInfo) + L - 255;
  655.    Info^.Text := Text;
  656.    ItemCount := Count;
  657.    Info^.Count := ItemCount;
  658.    Stream.WriteBuffer(Size, SizeOf(Size) ) ;
  659.    Stream.WriteBuffer(Info^, Size) ;
  660.    if Assigned(Self.Data) then
  661.    begin
  662.       try
  663.          TObject(self.data) .classtype;
  664.          if (TObject(Self.Data) is TComponent) then
  665.          begin
  666.             ObjType := 1;
  667.             Stream.WriteBuffer(ObjType, SizeOf(ObjType) ) ;
  668.             Stream.WriteComponent(TComponent(Data) ) ;
  669.          end
  670.          else
  671.          begin
  672.             ObjType := 0;
  673.             Stream.WriteBuffer(ObjType, SizeOf(ObjType) ) ;
  674.          end;
  675.       except
  676.          ObjType := 0;
  677.          Stream.WriteBuffer(ObjType, SizeOf(ObjType) ) ;
  678.       end;
  679.    end
  680.    else
  681.    begin
  682.       ObjType := 0;
  683.       Stream.WriteBuffer(ObjType, SizeOf(ObjType) ) ;
  684.    end;
  685.    for I := 0 to ItemCount - 1 do
  686.       Item[I].WriteData(Stream, Info) ;
  687. end;
  688.  
  689. { TrmTreeNonViewNodes }
  690.  
  691. constructor TrmTreeNonViewNodes.Create(AOwner: TrmCustomTreeNonView) ;
  692. begin
  693.    inherited Create;
  694.    FOwner := AOwner;
  695.    FRootNodeList := TList.Create;
  696.    FHashList := TObjectList.Create;
  697.    FHashList.OwnsObjects := true;
  698. end;
  699.  
  700. destructor TrmTreeNonViewNodes.Destroy;
  701. begin
  702.    Clear;
  703.    FRootNodeList.Free;
  704.    FHashList.Free;
  705.    inherited Destroy;
  706. end;
  707.  
  708. function TrmTreeNonViewNodes.GetCount: Integer;
  709. var
  710.    Idx: Integer;
  711.  
  712. begin
  713.    Result := FRootNodeList.Count;
  714.    for Idx := 0 to FRootNodeList.Count - 1 do
  715.    begin
  716.       Result := Result + TrmTreeNonViewNode(FRootNodeList[Idx]) .ItemCount;
  717.    end;
  718. end;
  719.  
  720. procedure TrmTreeNonViewNodes.Delete(Node: TrmTreeNonViewNode) ;
  721. var
  722.    wIndex: integer;
  723. begin
  724.    wIndex := LocateHashIndex(Owner.NodePath(Node) ) ;
  725.    if wIndex > -1 then
  726.       FHashList.delete(wIndex) ;
  727.    Node.Delete;
  728. end;
  729.  
  730. procedure TrmTreeNonViewNodes.Clear;
  731. var
  732.    N: TrmTreeNonViewNode;
  733.  
  734. begin
  735.    N := GetFirstNode;
  736.    while N <> nil do
  737.    begin
  738.       N.Delete;
  739.       N := GetFirstNode;
  740.    end;
  741.    FHashList.Clear;
  742. end;
  743.  
  744. function TrmTreeNonViewNodes.AddChildFirst(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  745. begin
  746.    Result := AddChildObjectFirst(Node, S, nil) ;
  747. end;
  748.  
  749. function TrmTreeNonViewNodes.AddChildObjectFirst(Node: TrmTreeNonViewNode; const S: string;
  750.    Ptr: Pointer) : TrmTreeNonViewNode;
  751. begin
  752.    Result := InternalAddObject(Node, S, Ptr, taAddFirst) ;
  753. end;
  754.  
  755. function TrmTreeNonViewNodes.AddChild(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  756. begin
  757.    Result := AddChildObject(Node, S, nil) ;
  758. end;
  759.  
  760. function TrmTreeNonViewNodes.AddChildObject(Node: TrmTreeNonViewNode; const S: string;
  761.    Ptr: Pointer) : TrmTreeNonViewNode;
  762. begin
  763.    Result := InternalAddObject(Node, S, Ptr, taAdd) ;
  764. end;
  765.  
  766. function TrmTreeNonViewNodes.AddFirst(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  767. begin
  768.    Result := AddObjectFirst(Node, S, nil) ;
  769. end;
  770.  
  771. function TrmTreeNonViewNodes.AddObjectFirst(Node: TrmTreeNonViewNode; const S: string;
  772.    Ptr: Pointer) : TrmTreeNonViewNode;
  773. begin
  774.    if Node <> nil then Node := Node.Parent;
  775.    Result := InternalAddObject(Node, S, Ptr, taAddFirst) ;
  776. end;
  777.  
  778. function TrmTreeNonViewNodes.Add(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  779. begin
  780.    Result := AddObject(Node, S, nil) ;
  781. end;
  782.  
  783. function TrmTreeNonViewNodes.AddObject(Node: TrmTreeNonViewNode; const S: string;
  784.    Ptr: Pointer) : TrmTreeNonViewNode;
  785. begin
  786.    if Node <> nil then Node := Node.Parent;
  787.    Result := InternalAddObject(Node, S, Ptr, taAdd) ;
  788. end;
  789.  
  790. function TrmTreeNonViewNodes.Insert(Node: TrmTreeNonViewNode; const S: string) : TrmTreeNonViewNode;
  791. begin
  792.    Result := InsertObject(Node, S, nil) ;
  793. end;
  794.  
  795. function TrmTreeNonViewNodes.InsertObject(Node: TrmTreeNonViewNode; const S: string; Ptr: Pointer) : TrmTreeNonViewNode;
  796. var
  797.    Parent: TrmTreeNonViewNode;
  798.    AddMode: TAddMode;
  799.    Target: TrmTreeNonViewNode;
  800. begin
  801.    AddMode := taInsert;
  802.    Target := node;
  803.    if Node <> nil then
  804.    begin
  805.       Parent := Node.Parent;
  806.       if Parent <> nil then
  807.          Node := Node.GetPrevSibling;
  808.       if Node = nil then
  809.       begin
  810.          AddMode := taAddFirst;
  811.          target := parent;
  812.       end;
  813.    end;
  814.    Result := InternalAddObject(Target, S, Ptr, AddMode) ;
  815. end;
  816.  
  817. function TrmTreeNonViewNodes.InternalAddObject(Node: TrmTreeNonViewNode; const S: string;
  818.    Ptr: Pointer; AddMode: TAddMode) : TrmTreeNonViewNode;
  819. var
  820.    nvnParent: TrmTreeNonViewNode;
  821.    nindex: integer;
  822. begin
  823.    Result := Owner.CreateNode;
  824.    try
  825.       case AddMode of
  826.          taAddFirst:
  827.             begin
  828.                if Node = nil then
  829.                begin
  830.                   FRootNodeList.Insert(0, Result) ;
  831.                   Result.Parent := nil;
  832.                end
  833.                else
  834.                begin
  835.                   Node.FChildList.Insert(0, Result) ;
  836.                   Result.Parent := Node;
  837.                end;
  838.                try
  839.                   Result.Data := Ptr;
  840.                   Result.Text := S;
  841.                   BinaryInsert(Owner.NodePath(Result) , Result) ;
  842.                except
  843.                   raise;
  844.                end;
  845.             end;
  846.  
  847.          taAdd:
  848.             begin
  849.                if Node = nil then
  850.                begin
  851.                   FRootNodeList.Add(Result) ;
  852.                   Result.Parent := nil;
  853.                end
  854.                else
  855.                begin
  856.                   Node.FChildList.Add(Result) ;
  857.                   Result.Parent := Node;
  858.                end;
  859.                try
  860.                   Result.Data := Ptr;
  861.                   Result.Text := S;
  862.                   BinaryInsert(Owner.NodePath(Result) , Result) ;
  863.                except
  864.                   raise;
  865.                end;
  866.             end;
  867.  
  868.          taInsert:
  869.             begin
  870.                nvnParent := Node.Parent;
  871.                if nvnParent = nil then
  872.                begin
  873.                   if Node = nil then
  874.                   begin
  875.                      FRootNodeList.Insert(0, Result) ;
  876.                      Result.Parent := nil;
  877.                   end
  878.                   else
  879.                   begin
  880.                      nIndex := fRootNodeList.IndexOf(Node) ;
  881.                      if nIndex <> -1 then
  882.                      begin
  883.                         fRootNodeList.Insert(nIndex, Result) ;
  884.                         result.parent := nil;
  885.                      end
  886.                      else
  887.                         rmTreeNonViewError('Unable to find Node reference') ;
  888.                   end;
  889.                end
  890.                else
  891.                begin
  892.                   nIndex := nvnParent.FChildList.IndexOf(node) ;
  893.                   if nIndex >= 0 then
  894.                   begin
  895.                      nvnParent.FChildList.Insert(nIndex, Result) ;
  896.                      result.parent := nvnParent;
  897.                   end
  898.                   else
  899.                      rmTreeNonViewError('Unable to find Node reference') ;
  900.                end;
  901.  
  902.                try
  903.                   Result.Data := Ptr;
  904.                   Result.Text := S;
  905.                   BinaryInsert(Owner.NodePath(Result) , Result) ;
  906.                except
  907.                   raise;
  908.                end;
  909.             end;
  910.       end;
  911.    except
  912.       raise;
  913.    end;
  914. end;
  915.  
  916. function TrmTreeNonViewNodes.GetFirstNode: TrmTreeNonViewNode;
  917. begin
  918.    if FRootNodeList.Count = 0 then
  919.       Result := nil
  920.    else
  921.       Result := FRootNodeList.Items[0];
  922. end;
  923.  
  924. function TrmTreeNonViewNodes.GetNodeFromIndex(Index: Integer) : TrmTreeNonViewNode;
  925. var
  926.    I: Integer;
  927. begin
  928.    Result := GetFirstNode;
  929.    I := Index;
  930.    while (I <> 0) and (Result <> nil) do
  931.    begin
  932.       Result := Result.GetNext;
  933.       Dec(I) ;
  934.    end;
  935.    if Result = nil then
  936.       rmTreeNonViewError('Index out of range') ;
  937. end;
  938.  
  939. procedure TrmTreeNonViewNodes.SetItem(Index: Integer; Value: TrmTreeNonViewNode) ;
  940. begin
  941.    GetNodeFromIndex(Index) .Assign(Value) ;
  942. end;
  943.  
  944. procedure TrmTreeNonViewNodes.Assign(Source: TPersistent) ;
  945. var
  946.    TreeNodes: TrmTreeNonViewNodes;
  947.    MemStream: TMemoryStream;
  948.    wNode: TrmTreeNonViewNode;
  949. begin
  950.    if Source is TrmTreeNonViewNodes then
  951.    begin
  952.       TreeNodes := TrmTreeNonViewNodes(Source) ;
  953.       Clear;
  954.       MemStream := TMemoryStream.Create;
  955.       try
  956.          TreeNodes.WriteData(MemStream) ;
  957.          MemStream.Position := 0;
  958.          ReadData(MemStream) ;
  959.       finally
  960.          MemStream.Free;
  961.       end;
  962.  
  963.       //Now that we've assigned all the nodes
  964.       //we need to redo that hashlist
  965.       wNode := Self.GetFirstNode;
  966.       while wNode <> nil do
  967.       begin
  968.          wNode.RenewHash;
  969.          wNode := wNode.GetNextSibling;
  970.       end;
  971.    end
  972.    else
  973.       inherited Assign(Source) ;
  974. end;
  975.  
  976. procedure TrmTreeNonViewNodes.DefineProperties(Filer: TFiler) ;
  977.  
  978.    function WriteNodes: Boolean;
  979.    var
  980.       I: Integer;
  981.       Nodes: TrmTreeNonViewNodes;
  982.    begin
  983.       Nodes := TrmTreeNonViewNodes(Filer.Ancestor) ;
  984.       if Nodes = nil then
  985.          Result := Count > 0
  986.       else if Nodes.Count <> Count then
  987.          Result := True
  988.       else
  989.       begin
  990.          Result := False;
  991.          for I := 0 to Count - 1 do
  992.          begin
  993.             Result := not Item[I].IsEqual(Nodes[I]) ;
  994.             if Result then Break;
  995.          end
  996.       end;
  997.    end;
  998.  
  999. begin
  1000.    inherited DefineProperties(Filer) ;
  1001.    Filer.DefineBinaryProperty('Data', ReadData, WriteData, WriteNodes) ;
  1002. end;
  1003.  
  1004. procedure TrmTreeNonViewNodes.ReadData(Stream: TStream) ;
  1005. var
  1006.    I, Count: Integer;
  1007.    Info: TNodeInfo;
  1008.  
  1009. begin
  1010.    Clear;
  1011.    Stream.ReadBuffer(Count, SizeOf(Count) ) ;
  1012.    for I := 0 to Count - 1 do
  1013.       Add(nil, '') .ReadData(Stream, @Info) ;
  1014. end;
  1015.  
  1016. procedure TrmTreeNonViewNodes.WriteData(Stream: TStream) ;
  1017. var
  1018.    I: Integer;
  1019.    Node: TrmTreeNonViewNode;
  1020.    Info: TNodeInfo;
  1021.  
  1022. begin
  1023.    I := 0;
  1024.    Node := GetFirstNode;
  1025.    while Node <> nil do
  1026.    begin
  1027.       Inc(I) ;
  1028.       Node := Node.GetNextSibling;
  1029.    end;
  1030.    Stream.WriteBuffer(I, SizeOf(I) ) ;
  1031.    Node := GetFirstNode;
  1032.    while Node <> nil do
  1033.    begin
  1034.       Node.WriteData(Stream, @Info) ;
  1035.       Node := Node.GetNextSibling;
  1036.    end;
  1037. end;
  1038.  
  1039. function TrmTreeNonViewNodes.HashValue(St: string) : Longint;
  1040. begin
  1041.    result := GetStrCRC32(St) ;
  1042. end;
  1043.  
  1044. function TrmTreeNonViewNodes.LocateHashIndex(Path: string) : integer;
  1045. var
  1046.    wHash: longint;
  1047.    wData: TrmHashData;
  1048.    First, Middle, Last, Temp: longint;
  1049.    wFound: boolean;
  1050. begin
  1051.    wHash := HashValue(Path) ;
  1052.  
  1053.    result := -1;
  1054.    First := 0;
  1055.    Last := FHashList.count - 1;
  1056.    wFound := false;
  1057.    middle := round((last + first) / 2) ;
  1058.  
  1059.    while (not wFound) and (first <= last) do
  1060.    begin
  1061.       middle := round((last + first) / 2) ;
  1062.       wData := TrmHashData(fHashlist[middle]) ;
  1063.  
  1064.       if wHash = wData.hash then
  1065.          wFound := true
  1066.       else
  1067.       begin
  1068.          if wHash < wData.hash then
  1069.             last := middle - 1
  1070.          else
  1071.             first := middle + 1;
  1072.       end;
  1073.    end;
  1074.  
  1075.    if wFound then
  1076.    begin
  1077.       Temp := middle;
  1078.  
  1079.       while (Middle > 0) and (Middle - 1 >= First) and (TrmHashData(FHashList[middle - 1]) .Hash = wHash) do
  1080.          dec(Middle) ;
  1081.  
  1082.       while (result = -1) and (Middle < FHashList.Count) and (Middle + 1 < Last) and (TrmHashData(FHashList[middle + 1]) .Hash = wHash) do
  1083.       begin
  1084.          wData := TrmHashData(FHashList[middle]) ;
  1085.          if (Owner.NodePath(wData.Node) = Path) then
  1086.             result := middle
  1087.          else
  1088.             inc(Middle) ;
  1089.       end;
  1090.  
  1091.       if result = -1 then
  1092.          result := temp;
  1093.    end;
  1094. end;
  1095.  
  1096. procedure TrmTreeNonViewNodes.BinaryInsert(Path: string; Node: TrmTreeNonViewNode) ;
  1097. var
  1098.    wHash: longint;
  1099.    wLen: integer;
  1100.    wData: TrmHashData;
  1101.    First, Middle, Last: longint;
  1102.    wFound: boolean;
  1103. begin
  1104.    wHash := HashValue(Path) ;
  1105.    wLen := Length(Path) ;
  1106.  
  1107.    First := 0;
  1108.    Last := FHashList.count - 1;
  1109.    wFound := false;
  1110.  
  1111.    while (not wFound) and (first <= last) do
  1112.    begin
  1113.       middle := round((last + first) / 2) ;
  1114.       wData := TrmHashData(fHashlist[middle]) ;
  1115.  
  1116.       if wHash = wData.hash then
  1117.          wFound := true
  1118.       else
  1119.       begin
  1120.          if wHash < wData.hash then
  1121.             last := middle - 1
  1122.          else
  1123.             first := middle + 1;
  1124.       end;
  1125.    end;
  1126.  
  1127.    if wFound then
  1128.    begin
  1129.       middle := round((last + first) / 2) ;
  1130.       wFound := false;
  1131.  
  1132.       while (Middle > 0) and (Middle - 1 >= First) and (TrmHashData(FHashList[middle - 1]) .Hash = wHash) do
  1133.          dec(Middle) ;
  1134.  
  1135.       while (not wfound) and (Middle < FHashList.Count) and (Middle + 1 < Last) and (TrmHashData(FHashList[middle + 1]) .Hash = wHash) do
  1136.       begin
  1137.          wData := TrmHashData(FHashList[middle]) ;
  1138.          if (Owner.NodePath(wData.Node) = Path) then
  1139.             wFound := true
  1140.          else
  1141.             inc(Middle) ;
  1142.       end;
  1143.       if not wFound then
  1144.          first := middle;
  1145.    end;
  1146.  
  1147.    if not wfound then
  1148.    begin
  1149.       wData := TrmHashData.create;
  1150.       wData.Hash := wHash;
  1151.       wData.IDLength := wLen;
  1152.       wData.Node := Node;
  1153.       fHashList.Insert(first, wData) ;
  1154.    end;
  1155. end;
  1156.  
  1157. function TrmTreeNonViewNodes.LocateNode(Path: string) : TrmTreeNonViewNode;
  1158. var
  1159.    wIndex: integer;
  1160. begin
  1161.    wIndex := LocateHashIndex(Path) ;
  1162.    if wIndex = -1 then
  1163.       result := nil
  1164.    else
  1165.       result := TrmHashData(FHashList[wIndex]) .Node;
  1166. end;
  1167.  
  1168. procedure TrmTreeNonViewNodes.RemoveHash(Node: TrmTreeNonViewNode) ;
  1169. var
  1170.    wIndex: integer;
  1171. begin
  1172.    wIndex := LocateHashIndex(Owner.NodePath(Node) ) ;
  1173.    if wIndex > -1 then
  1174.       FHashList.delete(wIndex) ;
  1175. end;
  1176.  
  1177. procedure TrmTreeNonViewNodes.dumphash;
  1178. var
  1179.    fstr: TextFile;
  1180.    loop: integer;
  1181.    wdata: trmhashdata;
  1182. begin
  1183.    AssignFile(fstr, 'c:\nvhash.txt') ;
  1184.    rewrite(fstr) ;
  1185.    for loop := 0 to fhashlist.count - 1 do
  1186.    begin
  1187.       wData := Trmhashdata(fhashlist[loop]) ;
  1188.       writeln(fstr, owner.nodepath(wdata.node) ) ;
  1189.    end;
  1190.    closefile(fstr) ;
  1191. end;
  1192.  
  1193. { TrmCustomTreeNonView }
  1194.  
  1195. constructor TrmCustomTreeNonView.Create(AOwner: TComponent) ;
  1196. begin
  1197.    inherited Create(AOwner) ;
  1198.    FSepChar := '/';
  1199.    FTreeNodes := TrmTreeNonViewNodes.Create(Self) ;
  1200. end;
  1201.  
  1202. destructor TrmCustomTreeNonView.Destroy;
  1203. begin
  1204.    Items.Free;
  1205.    FMemStream.Free;
  1206.    inherited Destroy;
  1207. end;
  1208.  
  1209. procedure TrmCustomTreeNonView.SetrmTreeNonViewNodes(Value: TrmTreeNonViewNodes) ;
  1210. begin
  1211.    Items.Assign(Value) ;
  1212. end;
  1213.  
  1214. procedure TrmCustomTreeNonView.Delete(Node: TrmTreeNonViewNode) ;
  1215. begin
  1216.    if Assigned(FOnDeletion) then
  1217.       FOnDeletion(Self, Node) ;
  1218. end;
  1219.  
  1220. function TrmCustomTreeNonView.CreateNode: TrmTreeNonViewNode;
  1221. begin
  1222.    Result := TrmTreeNonViewNode.Create(Items) ;
  1223. end;
  1224.  
  1225. procedure TrmCustomTreeNonView.LoadFromFile(const FileName: string) ;
  1226. var
  1227.    Stream: TStream;
  1228. begin
  1229.    Stream := TFileStream.Create(FileName, fmOpenRead) ;
  1230.    try
  1231.       LoadFromStream(Stream) ;
  1232.    finally
  1233.       Stream.Free;
  1234.    end;
  1235. end;
  1236.  
  1237. procedure TrmCustomTreeNonView.LoadFromStream(Stream: TStream) ;
  1238. begin
  1239.  
  1240. end;
  1241.  
  1242. procedure TrmCustomTreeNonView.SaveToFile(const FileName: string) ;
  1243. var
  1244.    Stream: TStream;
  1245. begin
  1246.    Stream := TFileStream.Create(FileName, fmCreate) ;
  1247.    try
  1248.       SaveToStream(Stream) ;
  1249.    finally
  1250.       Stream.Free;
  1251.    end;
  1252. end;
  1253.  
  1254. procedure TrmCustomTreeNonView.SaveToStream(Stream: TStream) ;
  1255. var
  1256.    N: TrmTreeNonViewNode;
  1257.    L: TStringList;
  1258.  
  1259. begin
  1260.    L := TStringList.Create;
  1261.    try
  1262.       N := Items.GetFirstNode;
  1263.       while N <> nil do
  1264.       begin
  1265.          L.Add(NodePath(N) ) ;
  1266.          N := N.GetNext;
  1267.       end;
  1268.       L.SaveToStream(Stream) ;
  1269.    finally
  1270.       L.Free;
  1271.    end;
  1272. end;
  1273.  
  1274. function TrmCustomTreeNonView.NodePath(Node: TrmTreeNonViewNode) : string;
  1275. var
  1276.    Temp: string;
  1277.  
  1278. begin
  1279.    Temp := '';
  1280.  
  1281.    while Node <> nil do
  1282.    begin
  1283.       Temp := FSepChar + Node.Text + Temp;
  1284.       Node := Node.Parent;
  1285.    end;
  1286.    Result := Temp;
  1287. end;
  1288.  
  1289. function TrmTreeNonViewNode.GetItemCount: Integer;
  1290. var
  1291.    Idx: Integer;
  1292.  
  1293. begin
  1294.    Result := FChildList.Count;
  1295.    for Idx := 0 to FChildList.Count - 1 do
  1296.    begin
  1297.       Result := Result + TrmTreeNonViewNode(FChildList[Idx]) .ItemCount;
  1298.    end;
  1299. end;
  1300.  
  1301. procedure TrmCustomTreeNonView.TextSort(ParentNode: TrmTreeNonViewNode;
  1302.    Recursive: boolean) ;
  1303. var
  1304.    Child: TrmTreeNonViewNode;
  1305.    WList, woList: TList;
  1306.    index: integer;
  1307.    found: boolean;
  1308.  
  1309. begin
  1310.    if ParentNode = nil then
  1311.       Child := FTreeNodes.GetFirstNode
  1312.    else
  1313.       Child := ParentNode.GetFirstChild;
  1314.  
  1315.    if assigned(child) then
  1316.    begin
  1317.       if child.parent = nil then
  1318.          woList := FTreeNodes.frootnodelist
  1319.       else
  1320.          woList := child.parent.FChildList;
  1321.  
  1322.       wList := TList.create;
  1323.       try
  1324.          while woList.count > 0 do
  1325.          begin
  1326.             wList.add(woList[0]) ;
  1327.             woList.delete(0) ;
  1328.          end;
  1329.  
  1330.          if Recursive then
  1331.             TextSort(TrmTreeNonViewNode(wList[0]) , recursive) ;
  1332.  
  1333.          woList.add(wList[0]) ;
  1334.          wList.delete(0) ;
  1335.          while wList.count > 0 do
  1336.          begin
  1337.             if Recursive then
  1338.                TextSort(TrmTreeNonViewNode(wList[0]) , recursive) ;
  1339.  
  1340.             index := 0;
  1341.             found := false;
  1342.             while index < woList.Count do
  1343.             begin
  1344.                if TrmTreeNonViewNode(wList[0]) .FText > TrmTreeNonViewNode(woList[index]) .fText then
  1345.                   inc(index)
  1346.                else
  1347.                begin
  1348.                   woList.Insert(index, wList[0]) ;
  1349.                   wList.delete(0) ;
  1350.                   found := true;
  1351.                   break;
  1352.                end;
  1353.             end;
  1354.             if not found then
  1355.             begin
  1356.                woList.add(wList[0]) ;
  1357.                wList.delete(0) ;
  1358.             end;
  1359.          end;
  1360.       finally
  1361.          wList.free;
  1362.       end;
  1363.    end;
  1364. end;
  1365.  
  1366. function TrmCustomTreeNonView.FindPathNode(Path: string) : TrmTreeNonViewNode;
  1367. begin
  1368.    result := Items.LocateNode(Path) ;
  1369. end;
  1370.  
  1371. function TrmCustomTreeNonView.AddPathNode(Node: TrmTreeNonViewNode; Path: string) : TrmTreeNonViewNode;
  1372. var
  1373.    wNode, wParent, wChild: TrmTreeNonViewNode;
  1374.    wPName, wCName: string;
  1375. begin
  1376.    result := nil;
  1377.    if path = '' then
  1378.       exit;
  1379.  
  1380.    if path[1] = sepchar then
  1381.       path := NodePath(Node) + path
  1382.    else
  1383.       path := nodepath(node) + sepchar + path;
  1384.  
  1385.    wNode := Items.LocateNode(Path) ;
  1386.    if wNode = nil then
  1387.    begin
  1388.       wPName := ParentName(Path) ;
  1389.       wCName := ChildName(Path) ;
  1390.  
  1391.       if (wPName = '') and (wCName = '') then
  1392.          exit;
  1393.  
  1394.       wParent := Items.LocateNode(wPName) ;
  1395.       if wParent = nil then
  1396.          wParent := AddPathNode(nil, wPname) ;
  1397.       wChild := Items.AddChild(wParent, wCName) ;
  1398.       result := wChild;
  1399.    end
  1400.    else
  1401.       result := wNode;
  1402. end;
  1403.  
  1404. function TrmCustomTreeNonView.ParentName(s: string) : string;
  1405. var
  1406.    wLen: integer;
  1407. begin
  1408.    wLen := length(s) ;
  1409.    if s[wLen] = SepChar then
  1410.    begin
  1411.       system.Delete(s, wLen, 1) ;
  1412.       dec(wLen) ;
  1413.    end;
  1414.    while (wlen > 0) and (s[wLen] <> sepchar) do
  1415.    begin
  1416.       system.Delete(s, wLen, 1) ;
  1417.       dec(wLen) ;
  1418.    end;
  1419.    if (wLen > 0) and (s[wLen] = SepChar) then
  1420.       system.Delete(s, wLen, 1) ;
  1421.    result := s;
  1422. end;
  1423.  
  1424. function TrmCustomTreeNonView.ChildName(s: string) : string;
  1425. var
  1426.    wLen: integer;
  1427. begin
  1428.    wLen := length(s) ;
  1429.    if s[wLen] = SepChar then
  1430.    begin
  1431.       system.Delete(s, wLen, 1) ;
  1432.       dec(wLen) ;
  1433.    end;
  1434.    while (wLen > 0) and (s[wLen] <> sepchar) do
  1435.       dec(wLen) ;
  1436.    system.delete(s, 1, wLen) ;
  1437.    result := s;
  1438. end;
  1439.  
  1440. procedure TrmTreeNonViewNode.RemoveHash;
  1441. var
  1442.    wNode: TrmTreeNonViewNode;
  1443. begin
  1444.    FOwner.RemoveHash(self) ;
  1445.    wNode := getFirstChild;
  1446.    while wNode <> nil do
  1447.    begin
  1448.       wNode.RemoveHash;
  1449.       wNode := wNode.getNextSibling;
  1450.    end;
  1451. end;
  1452.  
  1453. procedure TrmTreeNonViewNode.RenewHash;
  1454. var
  1455.    wNode: TrmTreeNonViewNode;
  1456. begin
  1457.    FOwner.BinaryInsert(FOwner.Owner.NodePath(self) , self) ;
  1458.    wNode := getFirstChild;
  1459.    while wNode <> nil do
  1460.    begin
  1461.       wNode.RenewHash;
  1462.       wNode := wNode.getNextSibling;
  1463.    end;
  1464. end;
  1465.  
  1466. function TrmTreeNonViewNode.GetNodePath: string;
  1467. begin
  1468.    Result := TreeNonView.NodePath(self) ;
  1469. end;
  1470.  
  1471. end.
  1472.  
  1473.