mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-04 13:18:19 +02:00
Improve TreeFilterEdit. Support many filtered branches and prepare for filtering the whole tree.
git-svn-id: trunk@34251 -
This commit is contained in:
parent
eb5c673298
commit
bb9e426743
@ -5,14 +5,45 @@ unit TreeFilterEdit;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Forms, LResources, LCLType, Graphics,
|
||||
Controls, ComCtrls, EditBtn, FileUtil, AvgLvlTree;
|
||||
Classes, SysUtils, Forms, LResources, Graphics,
|
||||
Controls, ComCtrls, EditBtn, FileUtil, AvgLvlTree, fgl;
|
||||
|
||||
type
|
||||
|
||||
TImageIndexEvent = function (Str: String; Data: TObject;
|
||||
var AIsEnabled: Boolean): Integer of object;
|
||||
|
||||
TTreeFilterEdit = class;
|
||||
TTreeNodeList = specialize TFPGList<TTreeNode>;
|
||||
|
||||
{ TBranch }
|
||||
|
||||
// A branch in the tree which can be sorted
|
||||
TBranch = class
|
||||
private
|
||||
fOwner: TTreeFilterEdit;
|
||||
fRootNode: TTreeNode;
|
||||
fOriginalData: TStringList; // Data supplied by caller.
|
||||
fSortedData: TStringList; // Data sorted for viewing.
|
||||
fImgIndex: Integer;
|
||||
// Full filename in node data is needed when showing the directory hierarchy.
|
||||
// It is stored automatically if AFullFilename is passed to contructor.
|
||||
fFilenameMap: TStringToStringTree;
|
||||
fTVNodeStack: TTreeNodeList;
|
||||
function CompareFNs(AFilename1,AFilename2: string): integer;
|
||||
procedure SortAndFilter;
|
||||
procedure ApplyFilter;
|
||||
procedure FreeTVNodeData(Node: TTreeNode);
|
||||
procedure TVDeleteUnneededNodes(p: integer);
|
||||
procedure TVClearUnneededAndCreateHierachy(Filename: string);
|
||||
public
|
||||
constructor Create(AOwner: TTreeFilterEdit; ARootNode: TTreeNode);
|
||||
destructor Destroy; override;
|
||||
procedure AddNodeData(ANodeText: string; AData: TObject; AFullFilename: string = '');
|
||||
end;
|
||||
|
||||
TBranchList = specialize TFPGObjectList<TBranch>;
|
||||
|
||||
{ TTreeFilterEdit }
|
||||
|
||||
TTreeFilterEdit = class(TCustomControlFilterEdit)
|
||||
@ -21,23 +52,10 @@ type
|
||||
fImageIndexDirectory: integer; // Needed if directory structure is shown.
|
||||
fSelectionList: TStringList; // Store/restore the old selections here.
|
||||
fShowDirHierarchy: Boolean; // Show direcories / files as a tree structure.
|
||||
// Full filename in node data is needed when showing the directory hierarchy.
|
||||
// It is stored automatically if the map is populated by MapShortToFullFilename.
|
||||
fFilenameMap: TStringToStringTree;
|
||||
// Data supplied by caller through Data property.
|
||||
fOriginalData: TStringList;
|
||||
// Data sorted for viewing.
|
||||
fSortedData: TStringList;
|
||||
fRootNode: TTreeNode; // The filtered items are under this node.
|
||||
fBranches: TBranchList; // Items are under these nodes can be sorted.
|
||||
fOnGetImageIndex: TImageIndexEvent;
|
||||
fImgIndex: Integer;
|
||||
fTVNodeStack: TFPList;
|
||||
function CompareFNs(AFilename1,AFilename2: string): integer;
|
||||
procedure SetFilteredTreeview(const AValue: TTreeview);
|
||||
procedure SetShowDirHierarchy(const AValue: Boolean);
|
||||
procedure FreeTVNodeData(Node: TTreeNode);
|
||||
procedure TVDeleteUnneededNodes(p: integer);
|
||||
procedure TVClearUnneededAndCreateHierachy(Filename: string);
|
||||
protected
|
||||
procedure MoveNext; override;
|
||||
procedure MovePrev; override;
|
||||
@ -49,16 +67,16 @@ type
|
||||
destructor Destroy; override;
|
||||
procedure StoreSelection; override;
|
||||
procedure RestoreSelection; override;
|
||||
procedure MapShortToFullFilename(ShortFilename, FullFilename: string);
|
||||
function GetBranch(ARootNode: TTreeNode): TBranch;
|
||||
public
|
||||
property ImageIndexDirectory: integer read fImageIndexDirectory write fImageIndexDirectory;
|
||||
property SelectionList: TStringList read fSelectionList;
|
||||
property ShowDirHierarchy: Boolean read fShowDirHierarchy write SetShowDirHierarchy;
|
||||
property Data: TStringList read fOriginalData;
|
||||
property RootNode: TTreeNode read fRootNode write fRootNode;
|
||||
property Branches: TBranchList read fBranches write fBranches;
|
||||
published
|
||||
property FilteredTreeview: TTreeview read fFilteredTreeview write SetFilteredTreeview;
|
||||
property OnGetImageIndex: TImageIndexEvent read fOnGetImageIndex write fOnGetImageIndex; deprecated 'use OnDrawItem handler in FilteredListbox';
|
||||
property OnGetImageIndex: TImageIndexEvent read fOnGetImageIndex write fOnGetImageIndex;
|
||||
// deprecated 'use OnGetImageIndex handler in FilteredTreeview';
|
||||
end;
|
||||
|
||||
{ TFileNameItem }
|
||||
@ -82,6 +100,199 @@ begin
|
||||
RegisterComponents('LazControls',[TTreeFilterEdit]);
|
||||
end;
|
||||
|
||||
{ TBranch }
|
||||
|
||||
constructor TBranch.Create(AOwner: TTreeFilterEdit; ARootNode: TTreeNode);
|
||||
begin
|
||||
inherited Create;
|
||||
fOwner:=AOwner;
|
||||
fRootNode:=ARootNode; // RootNode can also be Nil. Then all items are at top level.
|
||||
fOriginalData:=TStringList.Create;
|
||||
fSortedData:=TStringList.Create;
|
||||
fFilenameMap:=TStringToStringTree.Create(True);
|
||||
fImgIndex:=-1;
|
||||
end;
|
||||
|
||||
destructor TBranch.Destroy;
|
||||
begin
|
||||
fFilenameMap.Free;
|
||||
fSortedData.Free;
|
||||
fOriginalData.Free;
|
||||
FreeTVNodeData(fRootNode);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TBranch.AddNodeData(ANodeText: string; AData: TObject; AFullFilename: string);
|
||||
begin
|
||||
fOriginalData.AddObject(ANodeText, AData);
|
||||
if AFullFilename <> '' then
|
||||
fFilenameMap[ANodeText]:=AFullFilename;
|
||||
end;
|
||||
|
||||
function TBranch.CompareFNs(AFilename1,AFilename2: string): integer;
|
||||
begin
|
||||
if fOwner.SortData then
|
||||
Result:=CompareFilenames(AFilename1, AFilename2)
|
||||
else if fOwner.fShowDirHierarchy then
|
||||
Result:=CompareFilenames(ExtractFilePath(AFilename1), ExtractFilePath(AFilename2))
|
||||
else
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
procedure TBranch.SortAndFilter;
|
||||
// Copy data from fOriginalData to fSortedData in sorted order
|
||||
var
|
||||
Origi, i: Integer;
|
||||
FileN: string;
|
||||
begin
|
||||
fSortedData.Clear;
|
||||
for Origi:=0 to fOriginalData.Count-1 do begin
|
||||
FileN:=fOriginalData[Origi];
|
||||
if (fOwner.Filter='') or (Pos(fOwner.Filter,lowercase(FileN))>0) then begin
|
||||
i:=fSortedData.Count-1;
|
||||
while i>=0 do begin
|
||||
if CompareFNs(FileN,fSortedData[i])>=0 then break;
|
||||
dec(i);
|
||||
end;
|
||||
fSortedData.InsertObject(i+1,FileN, fOriginalData.Objects[Origi]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TBranch.ApplyFilter;
|
||||
var
|
||||
TVNode: TTreeNode;
|
||||
i: Integer;
|
||||
FileN, s: string;
|
||||
ena: Boolean;
|
||||
begin
|
||||
if fFilenameMap.Count > 0 then
|
||||
FreeTVNodeData(fRootNode); // Free node data now, it will be filled later.
|
||||
if Assigned(fRootNode) then
|
||||
fRootNode.DeleteChildren // Delete old tree nodes.
|
||||
else
|
||||
fOwner.FilteredTreeview.Items.Clear;
|
||||
if fOwner.ShowDirHierarchy then
|
||||
fTVNodeStack:=TTreeNodeList.Create;
|
||||
for i:=0 to fSortedData.Count-1 do begin
|
||||
FileN:=fSortedData[i];
|
||||
if fOwner.ShowDirHierarchy then begin
|
||||
TVClearUnneededAndCreateHierachy(FileN);
|
||||
TVNode:=fTVNodeStack[fTVNodeStack.Count-1];
|
||||
end
|
||||
else
|
||||
TVNode:=fOwner.FilteredTreeview.Items.AddChild(fRootNode,FileN);
|
||||
// else TVNode:=fFilteredTreeview.Items.Add(Nil,FileN);
|
||||
if fFilenameMap.Count > 0 then begin
|
||||
s:=FileN;
|
||||
if fFilenameMap.Contains(FileN) then
|
||||
s:=fFilenameMap[FileN]; // Full file name.
|
||||
TVNode.Data:=TFileNameItem.Create(s);
|
||||
end;
|
||||
ena := True;
|
||||
if Assigned(fOwner.OnGetImageIndex) then
|
||||
fImgIndex:=fOwner.OnGetImageIndex(FileN, fSortedData.Objects[i], ena);
|
||||
TVNode.ImageIndex:=fImgIndex;
|
||||
TVNode.SelectedIndex:=fImgIndex;
|
||||
// if Assigned(fSelectedPart) then
|
||||
// TVNode.Selected:=fSelectedPart=fSortedData.Objects[i];
|
||||
end;
|
||||
if fOwner.ShowDirHierarchy then // TVDeleteUnneededNodes(0); ?
|
||||
fTVNodeStack.Free;
|
||||
if Assigned(fRootNode) then
|
||||
fRootNode.Expanded:=True;
|
||||
end;
|
||||
|
||||
procedure TBranch.FreeTVNodeData(Node: TTreeNode);
|
||||
var
|
||||
Child: TTreeNode;
|
||||
begin
|
||||
if Node=nil then exit;
|
||||
if (Node.Data<>nil) then begin
|
||||
TObject(Node.Data).Free;
|
||||
Node.Data:=nil;
|
||||
end;
|
||||
Child:=Node.GetFirstChild;
|
||||
while Child<>nil do
|
||||
begin
|
||||
FreeTVNodeData(Child); // Recursive call.
|
||||
Child:=Child.GetNextSibling;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TBranch.TVDeleteUnneededNodes(p: integer);
|
||||
// delete all nodes behind the nodes in the stack, and depth>=p
|
||||
var
|
||||
i: Integer;
|
||||
Node: TTreeNode;
|
||||
begin
|
||||
for i:=fTVNodeStack.Count-1 downto p do begin
|
||||
Node:=fTVNodeStack[i];
|
||||
while Node.GetNextSibling<>nil do
|
||||
Node.GetNextSibling.Free;
|
||||
end;
|
||||
fTVNodeStack.Count:=p;
|
||||
end;
|
||||
|
||||
procedure TBranch.TVClearUnneededAndCreateHierachy(Filename: string);
|
||||
// TVNodeStack contains a path of TTreeNode for the last filename
|
||||
var
|
||||
DelimPos: Integer;
|
||||
FilePart: String;
|
||||
Node: TTreeNode;
|
||||
p: Integer;
|
||||
begin
|
||||
p:=0;
|
||||
while Filename<>'' do begin
|
||||
// get the next file name part
|
||||
DelimPos:=System.Pos(PathDelim,Filename);
|
||||
if DelimPos>0 then begin
|
||||
FilePart:=copy(Filename,1,DelimPos-1);
|
||||
Filename:=copy(Filename,DelimPos+1,length(Filename));
|
||||
end else begin
|
||||
FilePart:=Filename;
|
||||
Filename:='';
|
||||
end;
|
||||
//debugln(['ClearUnneededAndCreateHierachy FilePart=',FilePart,' Filename=',Filename,' p=',p]);
|
||||
if p < fTVNodeStack.Count then begin
|
||||
Node:=fTVNodeStack[p];
|
||||
if (FilePart=Node.Text) and (Node.Data=nil) then begin
|
||||
// same sub directory
|
||||
end
|
||||
else begin
|
||||
// change directory => last directory is complete
|
||||
// => delete unneeded nodes after last path
|
||||
TVDeleteUnneededNodes(p+1);
|
||||
if Node.GetNextSibling<>nil then begin
|
||||
Node:=Node.GetNextSibling;
|
||||
Node.Text:=FilePart;
|
||||
end
|
||||
else
|
||||
Node:=fOwner.FilteredTreeview.Items.Add(Node,FilePart);
|
||||
fTVNodeStack[p]:=Node;
|
||||
end;
|
||||
end else begin
|
||||
// new sub node
|
||||
if p>0 then
|
||||
Node:=fTVNodeStack[p-1]
|
||||
else
|
||||
Node:=fRootNode;
|
||||
if Node.GetFirstChild<>nil then begin
|
||||
Node:=Node.GetFirstChild;
|
||||
Node.Text:=FilePart;
|
||||
end
|
||||
else
|
||||
Node:=fOwner.FilteredTreeview.Items.AddChild(Node,FilePart);
|
||||
fTVNodeStack.Add(Node);
|
||||
end;
|
||||
if (Filename<>'') then begin
|
||||
Node.ImageIndex:=fOwner.ImageIndexDirectory;
|
||||
Node.SelectedIndex:=Node.ImageIndex;
|
||||
end;
|
||||
inc(p);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TFileNameItem }
|
||||
|
||||
constructor TFileNameItem.Create(AFilename: string);
|
||||
@ -94,21 +305,14 @@ end;
|
||||
constructor TTreeFilterEdit.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
fOriginalData:=TStringList.Create;
|
||||
fSelectionList:=TStringList.Create;
|
||||
fFilenameMap:=TStringToStringTree.Create(True);
|
||||
fSortedData:=TStringList.Create;
|
||||
fImageIndexDirectory := -1;
|
||||
fImgIndex:=-1;
|
||||
end;
|
||||
|
||||
destructor TTreeFilterEdit.Destroy;
|
||||
begin
|
||||
fSortedData.Free;
|
||||
fFilenameMap.Free;
|
||||
fBranches.Free;
|
||||
fSelectionList.Free;
|
||||
fOriginalData.Free;
|
||||
FreeTVNodeData(fRootNode);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -132,11 +336,6 @@ begin
|
||||
fShowDirHierarchy:=AValue;
|
||||
end;
|
||||
|
||||
procedure TTreeFilterEdit.MapShortToFullFilename(ShortFilename, FullFilename: string);
|
||||
begin
|
||||
fFilenameMap[ShortFilename]:=FullFilename;
|
||||
end;
|
||||
|
||||
procedure TTreeFilterEdit.ApplyFilterCore;
|
||||
var
|
||||
TVNode: TTreeNode;
|
||||
@ -144,73 +343,30 @@ var
|
||||
FileN, s: string;
|
||||
ena: Boolean;
|
||||
begin
|
||||
if fFilenameMap.Count > 0 then
|
||||
FreeTVNodeData(fRootNode); // Free node data now, it will be filled later.
|
||||
if Assigned(fRootNode) then // Delete old tree nodes.
|
||||
fRootNode.DeleteChildren
|
||||
else
|
||||
fFilteredTreeview.Items.Clear;
|
||||
if fShowDirHierarchy then
|
||||
fTVNodeStack:=TFPList.Create;
|
||||
fFilteredTreeview.BeginUpdate;
|
||||
for i:=0 to fSortedData.Count-1 do begin
|
||||
FileN:=fSortedData[i];
|
||||
if fShowDirHierarchy then begin
|
||||
TVClearUnneededAndCreateHierachy(FileN);
|
||||
TVNode:=TTreeNode(fTVNodeStack[fTVNodeStack.Count-1]);
|
||||
end
|
||||
else if Assigned(fRootNode) then
|
||||
TVNode:=fFilteredTreeview.Items.AddChild(fRootNode,FileN)
|
||||
else
|
||||
TVNode:=fFilteredTreeview.Items.Add(Nil,FileN);
|
||||
if fFilenameMap.Count > 0 then begin
|
||||
s:=FileN;
|
||||
if fFilenameMap.Contains(FileN) then
|
||||
s:=fFilenameMap[FileN]; // Full file name.
|
||||
TVNode.Data:=TFileNameItem.Create(s);
|
||||
end;
|
||||
ena := True;
|
||||
if Assigned(OnGetImageIndex) then
|
||||
fImgIndex:=OnGetImageIndex(FileN, fSortedData.Objects[i], ena);
|
||||
TVNode.ImageIndex:=fImgIndex;
|
||||
TVNode.SelectedIndex:=fImgIndex;
|
||||
if Assigned(fSelectedPart) then
|
||||
TVNode.Selected:=fSelectedPart=fSortedData.Objects[i];
|
||||
if Assigned(fBranches) then begin // Filter the brances
|
||||
for i:=0 to fBranches.Count-1 do
|
||||
fBranches[i].ApplyFilter;
|
||||
end
|
||||
else begin // Filter the whole tree.
|
||||
fFilteredTreeview.Items.Clear;
|
||||
// ToDo ...
|
||||
end;
|
||||
if fShowDirHierarchy then // TVDeleteUnneededNodes(0); ?
|
||||
fTVNodeStack.Free;
|
||||
if Assigned(fRootNode) then
|
||||
fRootNode.Expanded:=True;
|
||||
fFilteredTreeview.EndUpdate;
|
||||
end;
|
||||
|
||||
function TTreeFilterEdit.CompareFNs(AFilename1,AFilename2: string): integer;
|
||||
begin
|
||||
if SortData then
|
||||
Result:=CompareFilenames(AFilename1, AFilename2)
|
||||
else if fShowDirHierarchy then
|
||||
Result:=CompareFilenames(ExtractFilePath(AFilename1), ExtractFilePath(AFilename2))
|
||||
else
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
procedure TTreeFilterEdit.SortAndFilter;
|
||||
// Copy data from fOriginalData to fSortedData in sorted order
|
||||
var
|
||||
Origi, i: Integer;
|
||||
FileN: string;
|
||||
begin
|
||||
fSortedData.Clear;
|
||||
for Origi:=0 to fOriginalData.Count-1 do begin
|
||||
FileN:=fOriginalData[Origi];
|
||||
if (Filter='') or (Pos(Filter,lowercase(FileN))>0) then begin
|
||||
i:=fSortedData.Count-1;
|
||||
while i>=0 do begin
|
||||
if CompareFNs(FileN,fSortedData[i])>=0 then break;
|
||||
dec(i);
|
||||
end;
|
||||
fSortedData.InsertObject(i+1,FileN, fOriginalData.Objects[Origi]);
|
||||
end;
|
||||
if Assigned(fBranches) then begin // Filter the brances
|
||||
for i:=0 to fBranches.Count-1 do
|
||||
fBranches[i].SortAndFilter;
|
||||
end
|
||||
else begin // Filter the whole tree.
|
||||
// ToDo ...
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -247,8 +403,31 @@ begin
|
||||
fFilteredTreeview.Selected:=ANode;
|
||||
end;
|
||||
|
||||
function TTreeFilterEdit.GetBranch(ARootNode: TTreeNode): TBranch;
|
||||
// Get a new or existing branch for a node.
|
||||
var
|
||||
branch: TBranch;
|
||||
i: Integer;
|
||||
begin
|
||||
if not Assigned(fBranches) then
|
||||
fBranches := TBranchList.Create;
|
||||
branch := Nil;
|
||||
for i := 0 to fBranches.Count-1 do
|
||||
if fBranches[i].fRootNode = ARootNode then begin
|
||||
branch := fBranches[i];
|
||||
branch.fOriginalData.Clear;
|
||||
Break;
|
||||
end;
|
||||
if branch = Nil then begin
|
||||
branch := TBranch.Create(Self, ARootNode);
|
||||
fBranches.Add(branch);
|
||||
end;
|
||||
Result := branch;
|
||||
end;
|
||||
|
||||
procedure TTreeFilterEdit.MoveNext;
|
||||
var tn: TTreeNode;
|
||||
var
|
||||
tn: TTreeNode;
|
||||
begin
|
||||
tn := fFilteredTreeview.Selected;
|
||||
if not Assigned(tn) then
|
||||
@ -264,7 +443,8 @@ begin
|
||||
end;
|
||||
|
||||
procedure TTreeFilterEdit.MovePrev;
|
||||
var tn: TTreeNode;
|
||||
var
|
||||
tn: TTreeNode;
|
||||
begin
|
||||
tn := fFilteredTreeview.Selected;
|
||||
if not Assigned(tn) then Exit;
|
||||
@ -273,95 +453,5 @@ begin
|
||||
fFilteredTreeview.Selected := tn;
|
||||
end;
|
||||
|
||||
procedure TTreeFilterEdit.FreeTVNodeData(Node: TTreeNode);
|
||||
var
|
||||
Child: TTreeNode;
|
||||
begin
|
||||
if Node=nil then exit;
|
||||
if (Node.Data<>nil) then begin
|
||||
TObject(Node.Data).Free;
|
||||
Node.Data:=nil;
|
||||
end;
|
||||
Child:=Node.GetFirstChild;
|
||||
while Child<>nil do
|
||||
begin
|
||||
FreeTVNodeData(Child);
|
||||
Child:=Child.GetNextSibling;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTreeFilterEdit.TVDeleteUnneededNodes(p: integer);
|
||||
// delete all nodes behind the nodes in the stack, and depth>=p
|
||||
var
|
||||
i: Integer;
|
||||
Node: TTreeNode;
|
||||
begin
|
||||
for i:=fTVNodeStack.Count-1 downto p do begin
|
||||
Node:=TTreeNode(fTVNodeStack[i]);
|
||||
while Node.GetNextSibling<>nil do
|
||||
Node.GetNextSibling.Free;
|
||||
end;
|
||||
fTVNodeStack.Count:=p;
|
||||
end;
|
||||
|
||||
procedure TTreeFilterEdit.TVClearUnneededAndCreateHierachy(Filename: string);
|
||||
// TVNodeStack contains a path of TTreeNode for the last filename
|
||||
var
|
||||
DelimPos: Integer;
|
||||
FilePart: String;
|
||||
Node: TTreeNode;
|
||||
p: Integer;
|
||||
begin
|
||||
p:=0;
|
||||
while Filename<>'' do begin
|
||||
// get the next file name part
|
||||
DelimPos:=System.Pos(PathDelim,Filename);
|
||||
if DelimPos>0 then begin
|
||||
FilePart:=copy(Filename,1,DelimPos-1);
|
||||
Filename:=copy(Filename,DelimPos+1,length(Filename));
|
||||
end else begin
|
||||
FilePart:=Filename;
|
||||
Filename:='';
|
||||
end;
|
||||
//debugln(['ClearUnneededAndCreateHierachy FilePart=',FilePart,' Filename=',Filename,' p=',p]);
|
||||
if p < fTVNodeStack.Count then begin
|
||||
Node:=TTreeNode(fTVNodeStack[p]);
|
||||
if (FilePart=Node.Text) and (Node.Data=nil) then begin
|
||||
// same sub directory
|
||||
end
|
||||
else begin
|
||||
// change directory => last directory is complete
|
||||
// => delete unneeded nodes after last path
|
||||
TVDeleteUnneededNodes(p+1);
|
||||
if Node.GetNextSibling<>nil then begin
|
||||
Node:=Node.GetNextSibling;
|
||||
Node.Text:=FilePart;
|
||||
end
|
||||
else
|
||||
Node:=fFilteredTreeview.Items.Add(Node,FilePart);
|
||||
fTVNodeStack[p]:=Node;
|
||||
end;
|
||||
end else begin
|
||||
// new sub node
|
||||
if p>0 then
|
||||
Node:=TTreeNode(fTVNodeStack[p-1])
|
||||
else
|
||||
Node:=fRootNode;
|
||||
if Node.GetFirstChild<>nil then begin
|
||||
Node:=Node.GetFirstChild;
|
||||
Node.Text:=FilePart;
|
||||
end
|
||||
else
|
||||
Node:=fFilteredTreeview.Items.AddChild(Node,FilePart);
|
||||
fTVNodeStack.Add(Node);
|
||||
end;
|
||||
if (Filename<>'') then begin
|
||||
Node.ImageIndex:=fImageIndexDirectory;
|
||||
Node.SelectedIndex:=Node.ImageIndex;
|
||||
end;
|
||||
inc(p);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -22,6 +22,7 @@ object ProjectInspectorForm: TProjectInspectorForm
|
||||
RightClickSelect = True
|
||||
TabOrder = 0
|
||||
OnDblClick = ItemsTreeViewDblClick
|
||||
OnGetImageIndex = ItemsTreeViewGetImageIndex
|
||||
OnKeyDown = ItemsTreeViewKeyDown
|
||||
OnSelectionChanged = ItemsTreeViewSelectionChanged
|
||||
Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoRightClickSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
|
||||
|
@ -102,8 +102,8 @@ type
|
||||
procedure DirectoryHierarchySpeedButtonClick(Sender: TObject);
|
||||
procedure ItemsPopupMenuPopup(Sender: TObject);
|
||||
procedure ItemsTreeViewDblClick(Sender: TObject);
|
||||
procedure ItemsTreeViewKeyDown(Sender: TObject; var Key: Word;
|
||||
Shift: TShiftState);
|
||||
procedure ItemsTreeViewGetImageIndex(Sender: TObject; Node: TTreeNode);
|
||||
procedure ItemsTreeViewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure ItemsTreeViewSelectionChanged(Sender: TObject);
|
||||
procedure MoveDependencyUpClick(Sender: TObject);
|
||||
procedure MoveDependencyDownClick(Sender: TObject);
|
||||
@ -211,6 +211,11 @@ begin
|
||||
OpenBitBtnClick(Self);
|
||||
end;
|
||||
|
||||
procedure TProjectInspectorForm.ItemsTreeViewGetImageIndex(Sender: TObject; Node: TTreeNode);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TProjectInspectorForm.ItemsTreeViewKeyDown(Sender: TObject;
|
||||
var Key: Word; Shift: TShiftState);
|
||||
begin
|
||||
@ -614,6 +619,7 @@ procedure TProjectInspectorForm.UpdateProjectFiles(Immediately: boolean);
|
||||
var
|
||||
CurFile: TUnitInfo;
|
||||
Filename: String;
|
||||
FilteredBranch: TBranch;
|
||||
begin
|
||||
if (not Immediately) or (FUpdateLock>0) or (not Visible) then begin
|
||||
Include(FFlags,pifFilesChanged);
|
||||
@ -622,20 +628,17 @@ begin
|
||||
end;
|
||||
Exclude(FFlags,pifFilesChanged);
|
||||
if LazProject=nil then Exit;
|
||||
FilterEdit.RootNode:=FFilesNode;
|
||||
FilteredBranch := FilterEdit.GetBranch(FFilesNode);
|
||||
FilterEdit.SelectedPart:=FNextSelectedPart;
|
||||
FilterEdit.ShowDirHierarchy:=ShowDirectoryHierarchy;
|
||||
FilterEdit.SortData:=SortAlphabetically;
|
||||
FilterEdit.ImageIndexDirectory:=ImageIndexDirectory;
|
||||
FilterEdit.Data.Clear;
|
||||
// collect and sort files
|
||||
CurFile:=LazProject.FirstPartOfProject;
|
||||
while CurFile<>nil do begin
|
||||
Filename:=CurFile.GetShortFilename(true);
|
||||
if Filename<>'' then begin
|
||||
FilterEdit.Data.AddObject(Filename, CurFile);
|
||||
FilterEdit.MapShortToFullFilename(Filename, CurFile.Filename);
|
||||
end;
|
||||
if Filename<>'' then
|
||||
FilteredBranch.AddNodeData(Filename, CurFile, CurFile.Filename);
|
||||
CurFile:=CurFile.NextPartOfProject;
|
||||
end;
|
||||
FilterEdit.InvalidateFilter; // Data is shown by FilterEdit.
|
||||
|
@ -146,7 +146,7 @@ begin
|
||||
InstallPkgSetDialog:=TInstallPkgSetDialog.Create(nil);
|
||||
try
|
||||
InstallPkgSetDialog.OldInstalledPackages:=OldInstalledPackages;
|
||||
InstallPkgSetDialog.UpdateAvailablePackages;
|
||||
// InstallPkgSetDialog.UpdateAvailablePackages;
|
||||
InstallPkgSetDialog.UpdateButtonStates;
|
||||
InstallPkgSetDialog.OnCheckInstallPackageList:=CheckInstallPackageList;
|
||||
Result:=InstallPkgSetDialog.ShowModal;
|
||||
@ -306,8 +306,7 @@ begin
|
||||
AddToUninstall;
|
||||
end;
|
||||
|
||||
procedure TInstallPkgSetDialog.SetOldInstalledPackages(
|
||||
const AValue: TPkgDependency);
|
||||
procedure TInstallPkgSetDialog.SetOldInstalledPackages(const AValue: TPkgDependency);
|
||||
begin
|
||||
if FOldInstalledPackages=AValue then exit;
|
||||
FOldInstalledPackages:=AValue;
|
||||
@ -373,25 +372,34 @@ var
|
||||
ANode: TAVLTreeNode;
|
||||
Pkg: TLazPackageID;
|
||||
PkgName: String;
|
||||
DuplCheck: TStringList; // Add pkg names also here to filter out duplicates.
|
||||
FilteredBranch: TBranch;
|
||||
begin
|
||||
if fAvailablePackages.Count=0 then
|
||||
PackageGraph.IteratePackages(fpfSearchAllExisting,@OnIteratePackages);
|
||||
AvailableFilterEdit.Data.Clear;
|
||||
ANode:=fAvailablePackages.FindLowest;
|
||||
while ANode<>nil do begin
|
||||
Pkg:=TLazPackageID(ANode.Data);
|
||||
if (not (Pkg is TLazPackage))
|
||||
or (TLazPackage(Pkg).PackageType in [lptDesignTime,lptRunAndDesignTime])
|
||||
then begin
|
||||
if (not PackageInInstallList(Pkg.Name)) then begin
|
||||
PkgName:=Pkg.IDAsString;
|
||||
if (AvailableFilterEdit.Data.IndexOf(PkgName)<0) then
|
||||
AvailableFilterEdit.Data.AddObject(PkgName,Pkg);
|
||||
DuplCheck:=TStringList.Create;
|
||||
try
|
||||
if fAvailablePackages.Count=0 then
|
||||
PackageGraph.IteratePackages(fpfSearchAllExisting,@OnIteratePackages);
|
||||
FilteredBranch := AvailableFilterEdit.GetBranch(Nil); // All items are top level.
|
||||
ANode:=fAvailablePackages.FindLowest;
|
||||
while ANode<>nil do begin
|
||||
Pkg:=TLazPackageID(ANode.Data);
|
||||
if (not (Pkg is TLazPackage))
|
||||
or (TLazPackage(Pkg).PackageType in [lptDesignTime,lptRunAndDesignTime])
|
||||
then begin
|
||||
if (not PackageInInstallList(Pkg.Name)) then begin
|
||||
PkgName:=Pkg.IDAsString;
|
||||
if (DuplCheck.IndexOf(PkgName)<0) then begin
|
||||
DuplCheck.Add(PkgName);
|
||||
FilteredBranch.AddNodeData(PkgName, Pkg);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
ANode:=fAvailablePackages.FindSuccessor(ANode);
|
||||
end;
|
||||
ANode:=fAvailablePackages.FindSuccessor(ANode);
|
||||
AvailableFilterEdit.InvalidateFilter;
|
||||
finally
|
||||
DuplCheck.Free;
|
||||
end;
|
||||
AvailableFilterEdit.InvalidateFilter;
|
||||
end;
|
||||
|
||||
procedure TInstallPkgSetDialog.UpdateNewInstalledPackages;
|
||||
|
@ -1635,24 +1635,22 @@ var
|
||||
CurFile: TPkgFile;
|
||||
CurNode: TTreeNode;
|
||||
NextNode: TTreeNode;
|
||||
FilteredBranch: TBranch;
|
||||
Filename: String;
|
||||
ena: Boolean;
|
||||
begin
|
||||
if LazPackage=nil then exit;
|
||||
FilterEdit.RootNode:=FFilesNode;
|
||||
FilteredBranch := FilterEdit.GetBranch(FFilesNode);
|
||||
FilterEdit.SelectedPart:=FNextSelectedPart;
|
||||
FilterEdit.ShowDirHierarchy:=ShowDirectoryHierarchy;
|
||||
FilterEdit.SortData:=SortAlphabetically;
|
||||
FilterEdit.ImageIndexDirectory:=ImageIndexDirectory;
|
||||
FilterEdit.Data.Clear;
|
||||
// collect and sort files
|
||||
for i:=0 to LazPackage.FileCount-1 do begin
|
||||
CurFile:=LazPackage.Files[i];
|
||||
Filename:=CurFile.GetShortFilename(true);
|
||||
if Filename<>'' then begin
|
||||
FilterEdit.Data.AddObject(Filename, CurFile);
|
||||
FilterEdit.MapShortToFullFilename(Filename, CurFile.Filename);
|
||||
end;
|
||||
if Filename<>'' then
|
||||
FilteredBranch.AddNodeData(Filename, CurFile, CurFile.Filename);
|
||||
end;
|
||||
FilterEdit.InvalidateFilter; // Data is shown by FilterEdit.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user