diff --git a/components/lazcontrols/treefilteredit.pas b/components/lazcontrols/treefilteredit.pas index 2823be1d72..4b96f70c26 100644 --- a/components/lazcontrols/treefilteredit.pas +++ b/components/lazcontrols/treefilteredit.pas @@ -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; + + { 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; + { 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. diff --git a/ide/projectinspector.lfm b/ide/projectinspector.lfm index 756edb2a81..c321112d7e 100644 --- a/ide/projectinspector.lfm +++ b/ide/projectinspector.lfm @@ -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] diff --git a/ide/projectinspector.pas b/ide/projectinspector.pas index 2fdccbb249..bb309a8a53 100644 --- a/ide/projectinspector.pas +++ b/ide/projectinspector.pas @@ -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. diff --git a/packager/installpkgsetdlg.pas b/packager/installpkgsetdlg.pas index d152398ed3..a792eb3734 100644 --- a/packager/installpkgsetdlg.pas +++ b/packager/installpkgsetdlg.pas @@ -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; diff --git a/packager/packageeditor.pas b/packager/packageeditor.pas index 4f595be71d..5d8afc3266 100644 --- a/packager/packageeditor.pas +++ b/packager/packageeditor.pas @@ -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.