Forum > Packages and Libraries

VirtualTreeView , IterateSubtree and DeleteNode

(1/1)

Nimral:
Hi,

in the VTV Documentation, IterateSubtree section it says:


--- Quote ---Notes

An application should not modify the content of the tree (e.g. delete nodes) during the iteration, otherwise the

outcome is unpredictable and may result in an access violation.

--- End quote ---

Unfortunately, I want to do exactly that: iterate through a tree and delete all nodes which meet a certain criteria.

Any chance to do an "Iterate-friendly" DeleteNode?

Thnx, Armin.




GetMem:

--- Quote from: Nimral on August 02, 2021, 09:38:29 pm ---Hi,

in the VTV Documentation, IterateSubtree section it says:


--- Quote ---Notes

An application should not modify the content of the tree (e.g. delete nodes) during the iteration, otherwise the

outcome is unpredictable and may result in an access violation.

--- End quote ---

Unfortunately, I want to do exactly that: iterate through a tree and delete all nodes which meet a certain criteria.

Any chance to do an "Iterate-friendly" DeleteNode?

Thnx, Armin.

--- End quote ---

Add the nodes to an array first, like this:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  Node: PVirtualNode;  VirtualNodes: array of PVirtualNode;  Len, I: Integer;begin  VirtualNodes := nil;  Node := VST.GetFirst;  while Assigned(Node) do  begin    if (SomeCondition) then    begin      //add node to array      Len := Length(VirtualNodes);      SetLength(VirtualNodes, Len + 1);      VirtualNodes[Len] := Node;    end;    Node := VST.GetNext(Node);  end;   //delete the nodes  VST.BeginUpdate;  try    for I := Low(VirtualNodes) to High(VirtualNodes) do      VST.DeleteNode(VirtualNodes[I]);  finally    VST.EndUpdate;  end;end;  

Nimral:
Doing it by hand is certainly an option.

What I had in mind though ... I use  IterateSubtree much, but I guess I am out of luck with deletes, since IterateSubtree relies on the tree's GetNextChild and GetNextSibling functionality, which is broken as soon as I delete a node from inside the IterateSubtree callback. What I dream of (for code readibllity's sake ...) is beeing able to do something like


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---for n in VST.SelectedNodes do   VST.DeleteNode(n); ... or VST.IterateSubtree(VST.RootNode,@DeleteIfMatches,nil); 
where DeleteIfMatches checks the Node and does the delete if applicable.

Currently I am testing this:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function VTVIterateSubtree(Sender: TBaseVirtualTree; ParentNode: PVirtualNode; Callback: TVTGetNodeProc;  Data: Pointer): PVirtualNode; var  CurrentNode, NextNode: PVirtualNode;  abort: boolean; begin  Result := nil;  assert(assigned(ParentNode), 'VTVIterateSubtree: Node is undefined.');  if Assigned(ParentNode) then  begin    CurrentNode := Sender.GetFirstChild(ParentNode);    while assigned(CurrentNode) do    begin      NextNode := Sender.GetNextSibling(CurrentNode);      Abort := False;      if assigned(CallBack) then Callback(Sender, CurrentNode, Data, Abort);      if abort then exit(CurrentNode);      // traverse into subtrees      result := VTVIterateSubtree(Sender, CurrentNode, Callback, Data);      CurrentNode := NextNode;    end;  end;end;  

Nimral:
Getmem,

finally I dumped all iterators, and decided to go with the "conventional" approach, like you suggested :-)

Thanks!

Armin.

Navigation

[0] Message Index

Go to full version