mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 06:39:12 +02:00
Improve ListFilterEdit component.
git-svn-id: trunk@31492 -
This commit is contained in:
parent
3c82aaa518
commit
2dbcbcd191
@ -33,17 +33,14 @@
|
|||||||
</Files>
|
</Files>
|
||||||
<LazDoc Paths="docs"/>
|
<LazDoc Paths="docs"/>
|
||||||
<Type Value="RunAndDesignTime"/>
|
<Type Value="RunAndDesignTime"/>
|
||||||
<RequiredPkgs Count="3">
|
<RequiredPkgs Count="2">
|
||||||
<Item1>
|
<Item1>
|
||||||
<PackageName Value="CodeTools"/>
|
<PackageName Value="LCL"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
<Item2>
|
<Item2>
|
||||||
<PackageName Value="LCL"/>
|
|
||||||
</Item2>
|
|
||||||
<Item3>
|
|
||||||
<PackageName Value="FCL"/>
|
<PackageName Value="FCL"/>
|
||||||
<MinVersion Major="1" Valid="True"/>
|
<MinVersion Major="1" Valid="True"/>
|
||||||
</Item3>
|
</Item2>
|
||||||
</RequiredPkgs>
|
</RequiredPkgs>
|
||||||
<UsageOptions>
|
<UsageOptions>
|
||||||
<UnitPath Value="$(PkgOutDir)\"/>
|
<UnitPath Value="$(PkgOutDir)\"/>
|
||||||
|
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Forms, LResources, Graphics, StdCtrls, ComCtrls, EditBtn,
|
Classes, SysUtils, Forms, LResources, Graphics, StdCtrls, ComCtrls, EditBtn,
|
||||||
CodeToolsStructs;
|
FileUtil, AvgLvlTree;
|
||||||
|
|
||||||
resourcestring
|
resourcestring
|
||||||
lisCEFilter = '(Filter)';
|
lisCEFilter = '(Filter)';
|
||||||
@ -29,14 +29,19 @@ type
|
|||||||
fIdleConnected: boolean;
|
fIdleConnected: boolean;
|
||||||
fSelectedPart: TObject; // Select this node on next update
|
fSelectedPart: TObject; // Select this node on next update
|
||||||
fSelectionList: TStringList; // or store/restore the old selections here.
|
fSelectionList: TStringList; // or store/restore the old selections here.
|
||||||
fShowDirHierarchy: Boolean;
|
fShowDirHierarchy: Boolean; // Show direcories / files as a tree structure.
|
||||||
fSortData: Boolean;
|
fSortData: Boolean; // Data needs to be sorted.
|
||||||
fStoreFilenameInNode: boolean;
|
// 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;
|
fFilenameMap: TStringToStringTree;
|
||||||
fTVNodeStack: TFPList;
|
fTVNodeStack: TFPList;
|
||||||
// Data to be filtered. Objects property can contain data, too.
|
// Data supplied by caller through Data property.
|
||||||
fData: TStringList;
|
// Objects property is passed to OnGetImageIndex.
|
||||||
|
fOriginalData: TStringList;
|
||||||
|
// Data sorted for viewing.
|
||||||
|
fSortedData: TStringList;
|
||||||
fRootNode: TTreeNode; // The filtered items are under this node.
|
fRootNode: TTreeNode; // The filtered items are under this node.
|
||||||
|
// A control showing the (filtered) data. These are exclusive, only one is used.
|
||||||
fFilteredTreeview: TTreeview;
|
fFilteredTreeview: TTreeview;
|
||||||
fFilteredListbox: TListbox;
|
fFilteredListbox: TListbox;
|
||||||
fOnGetImageIndex: TImageIndexEvent;
|
fOnGetImageIndex: TImageIndexEvent;
|
||||||
@ -50,6 +55,8 @@ type
|
|||||||
procedure FreeTVNodeData(Node: TTreeNode);
|
procedure FreeTVNodeData(Node: TTreeNode);
|
||||||
procedure TVDeleteUnneededNodes(p: integer);
|
procedure TVDeleteUnneededNodes(p: integer);
|
||||||
procedure TVClearUnneededAndCreateHierachy(Filename: string);
|
procedure TVClearUnneededAndCreateHierachy(Filename: string);
|
||||||
|
function CompareFNs(AFilename1,AFilename2: string): integer;
|
||||||
|
procedure SortForView;
|
||||||
procedure ApplyFilterToTreeview;
|
procedure ApplyFilterToTreeview;
|
||||||
procedure SetIdleConnected(const AValue: boolean);
|
procedure SetIdleConnected(const AValue: boolean);
|
||||||
protected
|
protected
|
||||||
@ -69,8 +76,7 @@ type
|
|||||||
property SelectedPart: TObject read fSelectedPart write fSelectedPart;
|
property SelectedPart: TObject read fSelectedPart write fSelectedPart;
|
||||||
property ShowDirHierarchy: Boolean read fShowDirHierarchy write fShowDirHierarchy;
|
property ShowDirHierarchy: Boolean read fShowDirHierarchy write fShowDirHierarchy;
|
||||||
property SortData: Boolean read fSortData write fSortData;
|
property SortData: Boolean read fSortData write fSortData;
|
||||||
property StoreFilenameInNode: boolean read fStoreFilenameInNode write fStoreFilenameInNode;
|
property Data: TStringList read fOriginalData;
|
||||||
property Data: TStringList read fData;
|
|
||||||
property RootNode: TTreeNode read fRootNode write fRootNode;
|
property RootNode: TTreeNode read fRootNode write fRootNode;
|
||||||
published
|
published
|
||||||
// TListFilterEdit properties.
|
// TListFilterEdit properties.
|
||||||
@ -81,7 +87,6 @@ type
|
|||||||
property ButtonWidth;
|
property ButtonWidth;
|
||||||
property DirectInput;
|
property DirectInput;
|
||||||
property ButtonOnlyWhenFocused;
|
property ButtonOnlyWhenFocused;
|
||||||
// property Glyph;
|
|
||||||
property NumGlyphs;
|
property NumGlyphs;
|
||||||
property Flat;
|
property Flat;
|
||||||
// Other properties
|
// Other properties
|
||||||
@ -162,9 +167,11 @@ end;
|
|||||||
constructor TListFilterEdit.Create(AOwner: TComponent);
|
constructor TListFilterEdit.Create(AOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner);
|
inherited Create(AOwner);
|
||||||
fData:=TStringList.Create;
|
fOriginalData:=TStringList.Create;
|
||||||
|
fSortedData:=TStringList.Create;
|
||||||
fSelectionList:=TStringList.Create;
|
fSelectionList:=TStringList.Create;
|
||||||
fFilenameMap:=TStringToStringTree.Create(True);
|
fFilenameMap:=TStringToStringTree.Create(True);
|
||||||
|
fImageIndexDirectory := -1;
|
||||||
Button.Enabled:=False;
|
Button.Enabled:=False;
|
||||||
Font.Color:=clBtnShadow;
|
Font.Color:=clBtnShadow;
|
||||||
Text:=lisCEFilter;
|
Text:=lisCEFilter;
|
||||||
@ -178,7 +185,8 @@ begin
|
|||||||
FreeTVNodeData(fRootNode);
|
FreeTVNodeData(fRootNode);
|
||||||
fFilenameMap.Free;
|
fFilenameMap.Free;
|
||||||
fSelectionList.Free;
|
fSelectionList.Free;
|
||||||
fData.Free;
|
fSortedData.Free;
|
||||||
|
fOriginalData.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -355,10 +363,7 @@ begin
|
|||||||
p:=0;
|
p:=0;
|
||||||
while Filename<>'' do begin
|
while Filename<>'' do begin
|
||||||
// get the next file name part
|
// get the next file name part
|
||||||
if fShowDirHierarchy then
|
DelimPos:=System.Pos(PathDelim,Filename);
|
||||||
DelimPos:=System.Pos(PathDelim,Filename)
|
|
||||||
else
|
|
||||||
DelimPos:=0;
|
|
||||||
if DelimPos>0 then begin
|
if DelimPos>0 then begin
|
||||||
FilePart:=copy(Filename,1,DelimPos-1);
|
FilePart:=copy(Filename,1,DelimPos-1);
|
||||||
Filename:=copy(Filename,DelimPos+1,length(Filename));
|
Filename:=copy(Filename,DelimPos+1,length(Filename));
|
||||||
@ -406,57 +411,86 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TListFilterEdit.CompareFNs(AFilename1,AFilename2: string): integer;
|
||||||
|
begin
|
||||||
|
if fSortData then
|
||||||
|
Result:=CompareFilenames(AFilename1, AFilename2)
|
||||||
|
else if fShowDirHierarchy then
|
||||||
|
Result:=CompareFilenames(ExtractFilePath(AFilename1), ExtractFilePath(AFilename2))
|
||||||
|
else
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TListFilterEdit.SortForView;
|
||||||
|
// 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];
|
||||||
|
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;
|
||||||
|
|
||||||
procedure TListFilterEdit.ApplyFilterToTreeview;
|
procedure TListFilterEdit.ApplyFilterToTreeview;
|
||||||
var
|
var
|
||||||
TVNode: TTreeNode;
|
TVNode: TTreeNode;
|
||||||
ImgIndex, i: Integer;
|
ImgIndex, i: Integer;
|
||||||
s: string;
|
FileN, s: string;
|
||||||
begin
|
begin
|
||||||
fNeedUpdate:=false;
|
fNeedUpdate:=false;
|
||||||
ImgIndex:=-1;
|
ImgIndex:=-1;
|
||||||
fData.Sorted:=SortData;
|
SortForView;
|
||||||
fFilteredTreeview.BeginUpdate;
|
|
||||||
if fSelectedPart=Nil then
|
if fSelectedPart=Nil then
|
||||||
StoreTreeSelection;
|
StoreTreeSelection;
|
||||||
if Assigned(fRootNode) then begin
|
if fFilenameMap.Count > 0 then
|
||||||
if fStoreFilenameInNode then
|
FreeTVNodeData(fRootNode); // Free node data now, it will be filled later.
|
||||||
FreeTVNodeData(fRootNode);
|
if Assigned(fRootNode) then // Delete old tree nodes.
|
||||||
fRootNode.DeleteChildren;
|
fRootNode.DeleteChildren
|
||||||
fTVNodeStack:=TFPList.Create;
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
fFilteredTreeview.Items.Clear;
|
fFilteredTreeview.Items.Clear;
|
||||||
for i:=0 to fData.Count-1 do
|
if fShowDirHierarchy then
|
||||||
if PassesFilter(fData[i]) then begin
|
fTVNodeStack:=TFPList.Create;
|
||||||
if Assigned(fRootNode) then begin
|
fFilteredTreeview.BeginUpdate;
|
||||||
TVClearUnneededAndCreateHierachy(fData[i]);
|
for i:=0 to fSortedData.Count-1 do begin
|
||||||
|
FileN:=fSortedData[i];
|
||||||
|
if PassesFilter(FileN) then begin
|
||||||
|
if fShowDirHierarchy then begin
|
||||||
|
TVClearUnneededAndCreateHierachy(FileN);
|
||||||
TVNode:=TTreeNode(fTVNodeStack[fTVNodeStack.Count-1]);
|
TVNode:=TTreeNode(fTVNodeStack[fTVNodeStack.Count-1]);
|
||||||
end
|
end
|
||||||
else begin
|
else if Assigned(fRootNode) then
|
||||||
TVNode:=fFilteredTreeview.Items.Add(nil,fData[i]);
|
TVNode:=fFilteredTreeview.Items.AddChild(fRootNode,FileN)
|
||||||
end;
|
else
|
||||||
if fStoreFilenameInNode then begin
|
TVNode:=fFilteredTreeview.Items.Add(Nil,FileN);
|
||||||
s:=fData[i];
|
if fFilenameMap.Count > 0 then begin
|
||||||
if fFilenameMap.Contains(fData[i]) then
|
s:=FileN;
|
||||||
s:=fFilenameMap[fData[i]]; // Full file name.
|
if fFilenameMap.Contains(FileN) then
|
||||||
|
s:=fFilenameMap[FileN]; // Full file name.
|
||||||
TVNode.Data:=TFileNameItem.Create(s);
|
TVNode.Data:=TFileNameItem.Create(s);
|
||||||
end;
|
end;
|
||||||
if Assigned(OnGetImageIndex) then
|
if Assigned(OnGetImageIndex) then
|
||||||
ImgIndex:=OnGetImageIndex(fData[i], fData.Objects[i]);
|
ImgIndex:=OnGetImageIndex(FileN, fSortedData.Objects[i]);
|
||||||
TVNode.ImageIndex:=ImgIndex;
|
TVNode.ImageIndex:=ImgIndex;
|
||||||
TVNode.SelectedIndex:=ImgIndex;
|
TVNode.SelectedIndex:=ImgIndex;
|
||||||
if Assigned(fSelectedPart) then
|
if Assigned(fSelectedPart) then
|
||||||
TVNode.Selected:=fSelectedPart=fData.Objects[i];
|
TVNode.Selected:=fSelectedPart=fSortedData.Objects[i];
|
||||||
end;
|
end;
|
||||||
if Assigned(fRootNode) then begin
|
|
||||||
TVDeleteUnneededNodes(0);
|
|
||||||
fTVNodeStack.Free;
|
|
||||||
fRootNode.Expanded:=True;
|
|
||||||
end;
|
end;
|
||||||
|
if fShowDirHierarchy then // TVDeleteUnneededNodes(0); ?
|
||||||
|
fTVNodeStack.Free;
|
||||||
|
if Assigned(fRootNode) then
|
||||||
|
fRootNode.Expanded:=True;
|
||||||
if fSelectedPart=Nil then
|
if fSelectedPart=Nil then
|
||||||
RestoreTreeSelection;
|
RestoreTreeSelection;
|
||||||
fFilteredTreeview.EndUpdate;
|
fFilteredTreeview.EndUpdate;
|
||||||
fData.Sorted:=False;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TListFilterEdit.ApplyFilter(Immediately: Boolean);
|
procedure TListFilterEdit.ApplyFilter(Immediately: Boolean);
|
||||||
@ -482,6 +516,5 @@ begin
|
|||||||
IdleConnected:=true;
|
IdleConnected:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user