Skip to content

Commit c08d66b

Browse files
Merge pull request #1275 from hermannoffen/refix-725@v7
Refix #725 @ V7_stable to fix the regression of #836
2 parents 49c9364 + e2d5373 commit c08d66b

File tree

1 file changed

+63
-15
lines changed

1 file changed

+63
-15
lines changed

Source/VirtualTrees.pas

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28067,25 +28067,73 @@ function TBaseVirtualTree.GetLastVisibleNoInit(Node: PVirtualNode = nil;
2806728067
ConsiderChildrenAbove: Boolean = True; IncludeFiltered: Boolean = False): PVirtualNode;
2806828068

2806928069
// Returns the very last visible node in the tree while optionally considering toChildrenAbove.
28070+
// Note that the visibility of all ancestor nodes of the resulting node must not be considered.
2807028071
// No initialization is performed.
28071-
var
28072-
Next: PVirtualNode;
2807328072

28074-
begin
28075-
Result := GetLastVisibleChildNoInit(Node, IncludeFiltered);
28076-
if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.PaintOptions) then
28077-
while Assigned(Result) and (vsExpanded in Result.States) do
28073+
//--------------- local functions -------------------------------------------
28074+
28075+
function GetNodeIsVisible(ChildNode: PVirtualNode): Boolean;
28076+
begin
28077+
Result := (vsVisible in ChildNode.States) and
28078+
(IncludeFiltered or not IsEffectivelyFiltered[ChildNode]);
28079+
end;
28080+
28081+
function GetNodeHasVisibleChildren(ChildNode: PVirtualNode): Boolean;
28082+
begin
28083+
Result := (vsHasChildren in ChildNode.States) and
28084+
(vsExpanded in ChildNode.States) and
28085+
not (vsAllChildrenHidden in ChildNode.States);
28086+
end;
28087+
28088+
function IterateChildren(ParentNode: PVirtualNode): PVirtualNode;
28089+
var
28090+
Run: PVirtualNode;
28091+
begin
28092+
Result := nil;
28093+
28094+
Run := GetLastChildNoInit(ParentNode); // Do not use 'GetLastVisibleChildNoInit' here (see above).
28095+
while Assigned(Run) do
2807828096
begin
28079-
// Test if there is a next last child. If not keep the node from the last run.
28080-
// Otherwise use the next last child.
28081-
Next := GetLastChildNoInit(Result);
28082-
if Assigned(Next) and (not (vsVisible in Next.States) or
28083-
(not IncludeFiltered and IsEffectivelyFiltered[Next])) then
28084-
Next := GetPreviousVisibleSiblingNoInit(Next, IncludeFiltered);
28085-
if Next = nil then
28086-
Break;
28087-
Result := Next;
28097+
if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then
28098+
begin
28099+
if GetNodeIsVisible(Run) then
28100+
Result := Run
28101+
else if GetNodeHasVisibleChildren(Run) then
28102+
Result := IterateChildren(Run);
28103+
end else
28104+
begin
28105+
if GetNodeHasVisibleChildren(Run) then
28106+
Result := IterateChildren(Run)
28107+
else if GetNodeIsVisible(Run) then
28108+
Result := Run;
28109+
end;
28110+
28111+
if Assigned(Result) then
28112+
break;
28113+
28114+
Run := GetPreviousSiblingNoInit(Run);
2808828115
end;
28116+
end;
28117+
28118+
//--------------- end local functions ---------------------------------------
28119+
28120+
var
28121+
Run: PVirtualNode;
28122+
28123+
begin
28124+
Result := nil;
28125+
28126+
// First, check wether the given node and all its parents are expanded.
28127+
// If not, there can not be any visible child node.
28128+
Run := Node;
28129+
while Assigned(Run) and (Run <> RootNode) do
28130+
begin
28131+
if not (vsExpanded in Run.States) then
28132+
exit;
28133+
Run := Run.Parent;
28134+
end;
28135+
28136+
Result := IterateChildren(Node);
2808928137
end;
2809028138

2809128139
//----------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)