View Issue Details

IDProjectCategoryView StatusLast Update
0003376JEDI VCL00 JVCL Componentspublic2006-01-24 02:12
Reporterivan_raAssigned ToAHUser 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.00 
Target VersionFixed in Version3.20 
Summary0003376: TJvDBTreeView AV after deleteng of node
Descriptionwhen you delete first topmost node TJvDBTreeView raises exception (AV).
This is code:

procedure TJvCustomDBTreeView.DeleteNode(Node: TTreeNode);
var
  NewSel: TTreeNode;
begin
  CheckDataSet;
  Inc(FUpdateLock);
  InDelete := True;
  try
    NewSel := FindNextNode(Selected);

    If (NewSel = nil) then
      NewSel := Items.GetFirstNode; // this is deleted node in this case
      ~~~~~~~~~~~~~~~~~~~~~~~~
    FDataLink.DataSet.Delete;
    Selected.Free;
    if (NewSel <> nil) then
    begin
      NewSel.Selected := True; // AV because its already disposed
      ~~~~~~~~~~~~~~~~~~~~~~
      Change2(NewSel);
    end;
  finally
    InDelete := False;
    Dec(FUpdateLock);
  end;
end;
Additional InformationI suggest to test NewSel:
...
    If (NewSel = nil) then
      NewSel := Items.GetFirstNode; // this is deleted node in this case
    If (NewSel = Selected) then // NEW
      NewSel := Selected.GetNextSibling; // CODE
...
TagsNo tags attached.

Activities

ivan_ra

2006-01-23 08:10

developer   ~0008424

Last edited: 2006-01-23 08:35

The cause of bug is in current code of FindNextNode.

function TJvCustomDBTreeView.FindNextNode(const Node: TTreeNode): TTreeNode;
begin
  if (Node <> nil) and (Node.Parent <> nil) then
    if Node.Parent.Count > 1 then
      if Node.Index = Node.Parent.Count - 1 then
        Result := Node.Parent[Node.Index - 1]
      else
        Result := Node.Parent[Node.Index + 1]
    else
      Result := Node.Parent
  else
   { if Items.Count > 1 then
      if Node.Index = Items.Count-1 then
        Result := Items[Node.Index-1] else
        Result := Items[Node.Index+1]
    else}
    Result := nil;
end;

When the node is topmost, function returns nil. In this case code of procedure DeleteNode finds First Node and and after all trys to select it. But when we delete First Node, we will get AV. So, we must check, is new selected node deleted or not:
    If (NewSel = Selected) then // NEW
      NewSel := Selected.GetNextSibling; // CODE

But more correct decision is to rewrite FindNextNode for case when Node.Parent=nil (uncomment last strings):

function TJvCustomDBTreeView.FindNextNode(const Node: TTreeNode): TTreeNode;
begin
  result := nil;
  if Node = nil then Exit;
  if Node.Parent <> nil then
    if Node.Parent.Count > 1 then
      if Node.Index = Node.Parent.Count - 1 then
        Result := Node.Parent[Node.Index - 1]
      else
        Result := Node.Parent[Node.Index + 1]
    else
      Result := Node.Parent
  else
    if Items.Count > 1 then
      if Node.Index = Items.Count-1 then
        Result := Items[Node.Index-1] else
        Result := Items[Node.Index+1];
end;

The problm will be solved wthout rewriting of DeleteNode code

AHUser

2006-01-24 02:12

developer   ~0008437

Fixed in CVS.

Issue History

Date Modified Username Field Change
2005-12-22 03:29 ivan_ra New Issue
2006-01-23 08:10 ivan_ra Note Added: 0008424
2006-01-23 08:35 ivan_ra Note Edited: 0008424
2006-01-24 02:12 AHUser Status new => resolved
2006-01-24 02:12 AHUser Resolution open => fixed
2006-01-24 02:12 AHUser Assigned To => AHUser
2006-01-24 02:12 AHUser Note Added: 0008437