Preventing Duplicates


A very common requirement for trees, is that all node names belonging to a parent have unique names. This is similar to the restriction on file names, all file names in a directory must be unique. However there is no built into restriction in TTreeViews, so this checking must be done manually.

Here is a function to check if an name is already in use



   function IsDuplicateName(  Node : TTreeNode;
                              sNewName : string;
                              bInclusive : boolean
                            ) : boolean;
   var
      TestNode : TTreeNode;
   begin
      if(  Node = nil  ) then
      begin
         Result := false;
         Exit;
      end;

         {Include this Node?}
      if(  bInclusive  ) then
         if(   CompareText(  Node.Text,  sNewName  ) = 0   ) then
         begin
            Result := true;
            Exit;
         end;

         {Test all previous siblings}
      TestNode := Node;
      repeat
            {Get next}
         TestNode := TestNode.GetPrevSibling;

         if(  TestNode <> nil  ) then
               {Is this a duplicate}
            if(   CompareText(  TestNode.Text,  sNewName  ) = 0   ) then
            begin
               Result := true;
               Exit;
            end;
      until (TestNode = nil);


         {Test all next siblings}
      TestNode := Node;
      repeat
            {Get next}
         TestNode := TestNode.GetNextSibling;

         if(  TestNode <> nil  ) then
               {Is this a duplicate}
            if(   CompareText(  TestNode.Text,  sNewName  ) = 0   ) then
            begin
               Result := true;
               Exit;
            end;
      until (TestNode = nil);

      Result := false;
   end;


This function checks for duplicate nodes using the following alorighm

  1. If this is an inclusive search
  2. Check all siblings prior to the node in param 1
  3. Check all siblings after the node in param 1

Here is the updated source for but_Add's onClick event



   procedure TForm1.but_AddClick(Sender: TObject);
   var
      sText : string;
   begin
         {If nothing is selected}
      if(  tv_eg1.Selected = nil  ) then
      begin
            {Does a root node already exist?}
         if(  tv_eg1.Items.Count = 0  ) then
         begin
               {Add the root node}
            with tv_eg1.Items.AddFirst(  nil,  'Root'  ) do
            begin
               Selected := true;

                  {Set the roots image index}
               ImageIndex := IMG_NODE_ROOT;
                  {Set the roots selected index. The same image is uses
                     as for the ImageIndex}
               SelectedIndex := IMG_NODE_ROOT;
            end;
         end
         else begin
               {There is a root, so user must first select a node}
            MessageBeep(  -1  );
            ShowMessage(  'Select a parent node'  );
            Exit;
         end;
      end
      else begin
            {Get a name for the new node}
         InputQuery(  'New Node',  'Caption ?',  sText  );

            {Check if this name is already in use}
         if(   IsDuplicateName(  tv_eg1.Selected.GetFirstChild,
                                 sText,
                                 true
                               )
            ) then
         begin
            MessageBeep(  -1  );
            ShowMessage(  'A node with this name already exists'  );
            Exit;
         end;


            {Add the node as a child of the selected node}
         with tv_eg1.Items.AddChildFirst(  tv_eg1.Selected,  sText  ) do
         begin
               {Set the image used when the node is not selected}
            ImageIndex := IMG_NODE_CLOSED;
               {Image used when the node is selected}
            SelectedIndex := IMG_NODE_OPEN;

            MakeVisible;
         end;
      end;
   end;






All information on these www pages is copyright (©) 1997 Andre .v.d. Merwe And may not be copied or mirrored without my permission.

es is copyright (©) 1997 Andre .v.d. Merwe And may not be copied or mirrored without my permission.