IDE: find in files: accelerated showing results

git-svn-id: trunk@53531 -
This commit is contained in:
mattias 2016-12-02 21:48:31 +00:00
parent 16f22c6fc1
commit 757e1e9e4d

View File

@ -37,9 +37,10 @@ unit SearchResultView;
interface interface
uses uses
Classes, SysUtils, LCLProc, Forms, Controls, Graphics, ComCtrls, LCLType, LCLIntf, LazUTF8, Classes, SysUtils, LCLProc, Forms, Controls, Graphics, ComCtrls, LCLType,
Menus, strutils, IDEOptionDefs, LazarusIDEStrConsts, EnvironmentOpts, InputHistory, LCLIntf, LazUTF8, AvgLvlTree, LazFileUtils, Menus, strutils, IDEOptionDefs,
IDEProcs, Project, MainIntf, Clipbrd, ActnList, IDECommands, TreeFilterEdit; LazarusIDEStrConsts, EnvironmentOpts, InputHistory, IDEProcs, Project,
MainIntf, Clipbrd, ActnList, IDECommands, TreeFilterEdit;
type type
@ -99,6 +100,7 @@ type
fUpdateCount: integer; fUpdateCount: integer;
FSearchInListPhrases: string; FSearchInListPhrases: string;
fFiltered: Boolean; fFiltered: Boolean;
fFilenameToNode: TAvgLvlTree; // TTreeNode sorted for Text
procedure SetSkipped(const AValue: integer); procedure SetSkipped(const AValue: integer);
procedure AddNode(Line: string; MatchPos: TLazSearchMatchPos); procedure AddNode(Line: string; MatchPos: TLazSearchMatchPos);
public public
@ -223,6 +225,23 @@ implementation
const const
MaxTextLen = 80; MaxTextLen = 80;
function CompareTVNodeTextAsFilename(Node1, Node2: Pointer): integer;
var
TVNode1: TTreeNode absolute Node1;
TVNode2: TTreeNode absolute Node2;
begin
Result:=CompareFilenames(TVNode1.Text,TVNode2.Text);
end;
function CompareFilenameWithTVNode(Filename, Node: Pointer): integer;
var
aFilename: String;
TVNode: TTreeNode absolute Node;
begin
aFilename:=String(Filename);
Result:=CompareFilenames(aFilename,TVNode.Text);
end;
function CopySearchMatchPos(var Src, Dest: TLazSearchMatchPos): Boolean; function CopySearchMatchPos(var Src, Dest: TLazSearchMatchPos): Boolean;
begin begin
Result := False; Result := False;
@ -329,13 +348,13 @@ end;
procedure TSearchResultsView.mniCopyItemClick(Sender: TObject); procedure TSearchResultsView.mniCopyItemClick(Sender: TObject);
var var
tv: TCustomTreeView; tv: TCustomTreeView;
node: TTreeNode; Node: TTreeNode;
begin begin
tv := popList.PopupComponent as TCustomTreeView; tv := popList.PopupComponent as TCustomTreeView;
with tv.ScreenToClient(popList.PopupPoint) do with tv.ScreenToClient(popList.PopupPoint) do
node := tv.GetNodeAt(X, Y); Node := tv.GetNodeAt(X, Y);
if node <> nil then if Node <> nil then
Clipboard.AsText := node.Text; Clipboard.AsText := Node.Text;
end; end;
procedure TSearchResultsView.mniCopySelectedClick(Sender: TObject); procedure TSearchResultsView.mniCopySelectedClick(Sender: TObject);
@ -1032,13 +1051,21 @@ procedure TLazSearchResultTV.AddNode(Line: string; MatchPos: TLazSearchMatchPos)
var var
Node: TTreeNode; Node: TTreeNode;
ChildNode: TTreeNode; ChildNode: TTreeNode;
AVLNode: TAvgLvlTreeNode;
begin begin
if MatchPos=nil then exit; if MatchPos=nil then exit;
Node := Items.FindNodeWithText(MatchPos.FileName); AVLNode:=fFilenameToNode.FindKey(PChar(MatchPos.FileName),@CompareFilenameWithTVNode);
if AVLNode<>nil then
Node := TTreeNode(AVLNode.Data)
else
Node := nil;
//enter a new file entry //enter a new file entry
if not Assigned(Node) then if not Assigned(Node) then
begin
Node := Items.Add(Node, MatchPos.FileName); Node := Items.Add(Node, MatchPos.FileName);
fFilenameToNode.Add(Node);
end;
ChildNode := Items.AddChild(Node, Line); ChildNode := Items.AddChild(Node, Line);
Node.Expanded:=true; Node.Expanded:=true;
@ -1058,16 +1085,18 @@ begin
fUpdateStrings:= TStringList.Create; fUpdateStrings:= TStringList.Create;
FSearchInListPhrases := ''; FSearchInListPhrases := '';
fFiltered := False; fFiltered := False;
fFilenameToNode:=TAvgLvlTree.Create(@CompareTVNodeTextAsFilename);
end;//Create end;//Create
Destructor TLazSearchResultTV.Destroy; Destructor TLazSearchResultTV.Destroy;
begin begin
fFilenameToNode.Free;
if Assigned(fSearchObject) then if Assigned(fSearchObject) then
FreeAndNil(fSearchObject); FreeAndNil(fSearchObject);
//if UpdateStrings is empty, the objects are stored in Items due to filtering //if UpdateStrings is empty, the objects are stored in Items due to filtering
//filtering clears UpdateStrings //filtering clears UpdateStrings
if (fUpdateStrings.Count = 0) then if (fUpdateStrings.Count = 0) then
FreeObjectsTN(Items); FreeObjectsTN(Items);
if Assigned(fUpdateStrings) then if Assigned(fUpdateStrings) then
begin begin
FreeObjects(fUpdateStrings); FreeObjects(fUpdateStrings);
@ -1110,6 +1139,7 @@ begin
Items.BeginUpdate; Items.BeginUpdate;
Items.Clear; Items.Clear;
fFilenameToNode.Clear;
for i := 0 to fUpdateStrings.Count - 1 do for i := 0 to fUpdateStrings.Count - 1 do
AddNode(fUpdateStrings[i], TLazSearchMatchPos(fUpdateStrings.Objects[i])); AddNode(fUpdateStrings[i], TLazSearchMatchPos(fUpdateStrings.Objects[i]));
@ -1184,19 +1214,20 @@ end;
procedure TLazSearchResultTV.FreeObjectsTN(tnItems: TTreeNodes); procedure TLazSearchResultTV.FreeObjectsTN(tnItems: TTreeNodes);
var i: Integer; var i: Integer;
begin begin
for i:=0 to tnItems.Count-1 do fFilenameToNode.Clear;
if Assigned(tnItems[i].Data) then for i:=0 to tnItems.Count-1 do
TLazSearchMatchPos(tnItems[i].Data).Free; if Assigned(tnItems[i].Data) then
TLazSearchMatchPos(tnItems[i].Data).Free;
end; end;
procedure TLazSearchResultTV.FreeObjects(slItems: TStrings); procedure TLazSearchResultTV.FreeObjects(slItems: TStrings);
var i: Integer; var i: Integer;
begin begin
if (slItems.Count <= 0) then Exit; if (slItems.Count <= 0) then Exit;
for i:=0 to slItems.Count-1 do for i:=0 to slItems.Count-1 do
begin begin
if Assigned(slItems.Objects[i]) then if Assigned(slItems.Objects[i]) then
slItems.Objects[i].Free; slItems.Objects[i].Free;
end;//End for-loop end;//End for-loop
end; end;