LazControls: Select the first matching node in TreeFilterEdit. Issue #24795.

git-svn-id: trunk@50545 -
This commit is contained in:
juha 2015-11-30 20:14:18 +00:00
parent 9d06b8c931
commit 7bc722522a

View File

@ -71,7 +71,8 @@ type
fBranches: TBranchList; // Items under these nodes can be sorted. fBranches: TBranchList; // Items under these nodes can be sorted.
fExpandAllInitially: Boolean; // Expand all levels when searched for the first time. fExpandAllInitially: Boolean; // Expand all levels when searched for the first time.
fIsFirstTime: Boolean; // Needed for fExpandAllInitially. fIsFirstTime: Boolean; // Needed for fExpandAllInitially.
fTempSelected: Boolean; // First node that matched the filter. Will be selected if old selection is hidden.
fFirstPassedNode: TTreeNode;
fOnGetImageIndex: TImageIndexEvent; fOnGetImageIndex: TImageIndexEvent;
procedure SetFilteredTreeview(const AValue: TCustomTreeview); procedure SetFilteredTreeview(const AValue: TCustomTreeview);
procedure SetShowDirHierarchy(const AValue: Boolean); procedure SetShowDirHierarchy(const AValue: Boolean);
@ -469,7 +470,7 @@ var
begin begin
Result:=False; Result:=False;
Done:=False; Done:=False;
FilterLC := UTF8LowerCase(Filter); FilterLC:=UTF8LowerCase(Filter);
while Node<>nil do while Node<>nil do
begin begin
// Call OnFilterItem handler. // Call OnFilterItem handler.
@ -480,6 +481,8 @@ begin
// Filter by item's title text if needed. // Filter by item's title text if needed.
if not (Pass or Done) then if not (Pass or Done) then
Pass:=(FilterLC='') or (Pos(FilterLC,UTF8LowerCase(Node.Text))>0); Pass:=(FilterLC='') or (Pos(FilterLC,UTF8LowerCase(Node.Text))>0);
if Pass and (fFirstPassedNode=Nil) then
fFirstPassedNode:=Node;
// Recursive call for child nodes. // Recursive call for child nodes.
Node.Visible:=FilterTree(Node.GetFirstChild) or Pass; Node.Visible:=FilterTree(Node.GetFirstChild) or Pass;
if Node.Visible then if Node.Visible then
@ -526,7 +529,8 @@ begin
fBranches[i].ApplyFilter; fBranches[i].ApplyFilter;
end end
else begin // Apply filter for the whole tree. else begin // Apply filter for the whole tree.
if fExpandAllInitially and fIsFirstTime then begin if fExpandAllInitially and fIsFirstTime then
begin
fFilteredTreeview.FullExpand; fFilteredTreeview.FullExpand;
fIsFirstTime := False; fIsFirstTime := False;
end; end;
@ -541,33 +545,42 @@ var
ANode: TTreeNode; ANode: TTreeNode;
begin begin
if fFilteredTreeview = nil then Exit; if fFilteredTreeview = nil then Exit;
fFirstPassedNode:=Nil;
ANode:=fFilteredTreeview.Selected; ANode:=fFilteredTreeview.Selected;
if (ANode=nil) then Exit; if (ANode=nil) then Exit;
if fTempSelected and (ANode=fFilteredTreeview.Items.GetFirstVisibleNode) then Exit; if ANode=fFilteredTreeview.Items.GetFirstVisibleNode then Exit;
fSelectionList.Clear; // Clear old selection only if there is new one. fSelectionList.Clear; // Clear old selection only if there is new one.
fSelectionList.Add(ANode.Text); fSelectionList.Add(ANode.Text);
end; end;
procedure TTreeFilterEdit.RestoreSelection; procedure TTreeFilterEdit.RestoreSelection;
var var
ANode: TTreeNode; ANode, SelectNode: TTreeNode;
CurText: string; CurText: string;
i: Integer;
begin begin
fTempSelected:=fSelectionList.Count>0; SelectNode:=Nil;
for i:=fSelectionList.Count-1 downto 0 do begin // ToDo: support more than one items or otherwise clean the code.
CurText:=fSelectionList[i]; Assert(fSelectionList.Count < 2,
'TTreeFilterEdit.RestoreSelection: fSelectionList has more than one items.');
if fSelectionList.Count > 0 then
begin
CurText:=fSelectionList[0];
ANode:=fFilteredTreeview.Items.GetFirstVisibleNode; ANode:=fFilteredTreeview.Items.GetFirstVisibleNode;
while (ANode<>nil) and (ANode.Text<>CurText) do while (ANode<>nil) and (ANode.Text<>CurText) do
ANode:=ANode.GetNextVisible; ANode:=ANode.GetNextVisible;
if ANode<>nil then begin // Selection found if Assigned(ANode) then // Selection found
fFilteredTreeview.Selected:=ANode; begin
fSelectionList.Delete(i); SelectNode:=ANode;
fTempSelected:=False; fSelectionList.Delete(0);
end; end;
end; end;
if fTempSelected then // Original selection will be restored later. if Assigned(SelectNode) then // Original selection will be restored later.
fFilteredTreeview.Selected:=fFilteredTreeview.Items.GetFirstVisibleNode; ANode:=SelectNode
else if Assigned(fFirstPassedNode) then
ANode:=fFirstPassedNode
else
ANode:=fFilteredTreeview.Items.GetFirstVisibleNode;
fFilteredTreeview.Selected:=ANode;
end; end;
function TTreeFilterEdit.GetExistingBranch(ARootNode: TTreeNode): TTreeFilterBranch; function TTreeFilterEdit.GetExistingBranch(ARootNode: TTreeNode): TTreeFilterBranch;
@ -578,7 +591,8 @@ begin
Result := Nil; Result := Nil;
if not Assigned(fBranches) then Exit; if not Assigned(fBranches) then Exit;
for i := 0 to fBranches.Count-1 do for i := 0 to fBranches.Count-1 do
if fBranches[i].fRootNode = ARootNode then begin if fBranches[i].fRootNode = ARootNode then
begin
Result := fBranches[i]; Result := fBranches[i];
Break; Break;
end; end;