mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-01 22:19:39 +01:00
LCL, LazControls: use DoFilterItem in all filter edits.
git-svn-id: trunk@52266 -
This commit is contained in:
parent
67f550a5ef
commit
385bdd0d4e
@ -160,27 +160,12 @@ procedure TListFilterEdit.SortAndFilter;
|
||||
var
|
||||
Origi, i: Integer;
|
||||
Capt, FilterLC: string;
|
||||
Pass, Done: Boolean;
|
||||
begin
|
||||
Done:=False;
|
||||
fSortedData.Clear;
|
||||
FilterLC:=UTF8LowerCase(Filter);
|
||||
for Origi:=0 to fOriginalData.Count-1 do begin
|
||||
Capt:=fOriginalData[Origi];
|
||||
|
||||
// Filter with event handler if there is one.
|
||||
if Assigned(fOnFilterItemEx) then
|
||||
Pass:=fOnFilterItemEx(Capt, fOriginalData.Objects[Origi], Done)
|
||||
else
|
||||
Pass:=False;
|
||||
// Support also the old filter event without a caption.
|
||||
if (not (Pass and Done)) and Assigned(fOnFilterItem) then
|
||||
Pass:=fOnFilterItem(fOriginalData.Objects[Origi], Done);
|
||||
|
||||
// Filter by item's caption text if needed.
|
||||
if not (Pass or Done) then
|
||||
Pass:=(FilterLC='') or (Pos(FilterLC,UTF8LowerCase(Capt))>0);
|
||||
if Pass then begin
|
||||
if DoFilterItem(Capt, fOriginalData.Objects[Origi], FilterLC) then begin
|
||||
i:=fSortedData.Count-1; // Always sort the data.
|
||||
while i>=0 do begin
|
||||
if CompareFNs(Capt,fSortedData[i])>=0 then break;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
unit ListViewFilterEdit;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$modeswitch advancedrecords}
|
||||
|
||||
interface
|
||||
|
||||
@ -24,7 +25,13 @@ type
|
||||
//TImageIndexEvent = function (Str: String; Data: TObject;
|
||||
// var IsEnabled: Boolean): Integer of object;
|
||||
TStringArray = array of string;
|
||||
TListViewDataList = specialize TFPGList<TStringArray>;
|
||||
TListViewDataItem = record
|
||||
Data: Pointer;
|
||||
StringArray: TStringArray;
|
||||
|
||||
class operator =(a,b : TListViewDataItem) : Boolean;
|
||||
end;
|
||||
TListViewDataList = specialize TFPGList<TListViewDataItem>;
|
||||
|
||||
{ TListViewFilterEdit }
|
||||
|
||||
@ -40,7 +47,7 @@ type
|
||||
fOriginalData: TListViewDataList;
|
||||
// Data sorted for viewing.
|
||||
fFilteredData: TListViewDataList;
|
||||
function MatchesFilter(aData: TStringArray): Boolean;
|
||||
function MatchesFilter(aData: TListViewDataItem; const FilterLC: string): Boolean;
|
||||
procedure SetFilteredListview(const AValue: TCustomListView);
|
||||
protected
|
||||
procedure MoveTo(AIndex: Integer; ASelect: Boolean);
|
||||
@ -73,6 +80,13 @@ var
|
||||
|
||||
implementation
|
||||
|
||||
{ TListViewDataItem }
|
||||
|
||||
class operator TListViewDataItem. = (a, b: TListViewDataItem): Boolean;
|
||||
begin
|
||||
Result := (a.Data=b.Data) and (a.StringArray=b.StringArray);
|
||||
end;
|
||||
|
||||
{ TListViewFilterEdit }
|
||||
|
||||
constructor TListViewFilterEdit.Create(AOwner: TComponent);
|
||||
@ -104,23 +118,25 @@ begin
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
function ListItem2Data(AItem: TListItem): TStringArray;
|
||||
function ListItem2Data(AItem: TListItem): TListViewDataItem;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
SetLength(Result, AItem.SubItems.Count+1);
|
||||
Result[0] := AItem.Caption;
|
||||
Result.Data := AItem.Data;
|
||||
SetLength(Result.StringArray, AItem.SubItems.Count+1);
|
||||
Result.StringArray[0] := AItem.Caption;
|
||||
for i := 0 to AItem.SubItems.Count-1 do
|
||||
Result[i+1] := AItem.SubItems[i];
|
||||
Result.StringArray[i+1] := AItem.SubItems[i];
|
||||
end;
|
||||
|
||||
procedure Data2ListItem(AData: TStringArray; AItem: TListItem);
|
||||
procedure Data2ListItem(AData: TListViewDataItem; AItem: TListItem);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
AItem.Caption := AData[0];
|
||||
for i := 1 to Length(AData)-1 do
|
||||
AItem.SubItems.Add(AData[i]);
|
||||
AItem.Data := AData.Data;
|
||||
AItem.Caption := AData.StringArray[0];
|
||||
for i := 1 to Length(AData.StringArray)-1 do
|
||||
AItem.SubItems.Add(AData.StringArray[i]);
|
||||
end;
|
||||
|
||||
procedure TListViewFilterEdit.SetFilteredListview(const AValue: TCustomListView);
|
||||
@ -134,23 +150,18 @@ begin
|
||||
fOriginalData.Add(ListItem2Data(fFilteredListview.Items[i]));
|
||||
end;
|
||||
|
||||
function TListViewFilterEdit.MatchesFilter(aData: TStringArray): Boolean;
|
||||
function TListViewFilterEdit.MatchesFilter(aData: TListViewDataItem;
|
||||
const FilterLC: string): Boolean;
|
||||
var
|
||||
i, EndInd: Integer;
|
||||
FilterLC: string;
|
||||
begin
|
||||
if Filter='' then
|
||||
Exit(True);
|
||||
FilterLC := UTF8LowerCase(Filter);
|
||||
if fByAllFields then
|
||||
EndInd := Pred(Length(aData))
|
||||
EndInd := Pred(Length(aData.StringArray))
|
||||
else
|
||||
EndInd := 0;
|
||||
for i := 0 to EndInd do begin
|
||||
// ToDo: Use OnFilterItemEx event.
|
||||
Result := Pos(FilterLC,UTF8LowerCase(aData[i]))>0;
|
||||
if Result then
|
||||
Exit;
|
||||
if DoFilterItem(aData.StringArray[i], TObject(aData.Data), FilterLC) then
|
||||
Exit(True);
|
||||
end;
|
||||
Result := False;
|
||||
end;
|
||||
@ -173,12 +184,14 @@ procedure TListViewFilterEdit.SortAndFilter;
|
||||
// Copy data from fOriginalData to fSortedData in sorted order
|
||||
var
|
||||
Origi: Integer;
|
||||
Data: TStringArray;
|
||||
Data: TListViewDataItem;
|
||||
FilterLC: string;
|
||||
begin
|
||||
fFilteredData.Clear;
|
||||
FilterLC := UTF8LowerCase(Filter);
|
||||
for Origi:=0 to fOriginalData.Count-1 do begin
|
||||
Data:=fOriginalData[Origi];
|
||||
if MatchesFilter(Data) then
|
||||
if MatchesFilter(Data, FilterLC) then
|
||||
fFilteredData.Add(Data);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -460,26 +460,14 @@ function TTreeFilterEdit.FilterTree(Node: TTreeNode): Boolean;
|
||||
// Filter all tree branches recursively, setting Node.Visible as needed.
|
||||
// Returns True if Node or its siblings or child nodes have visible items.
|
||||
var
|
||||
Pass, Done: Boolean;
|
||||
Pass: Boolean;
|
||||
FilterLC: string;
|
||||
begin
|
||||
Result:=False;
|
||||
Done:=False;
|
||||
FilterLC:=UTF8LowerCase(Filter);
|
||||
while Node<>nil do
|
||||
begin
|
||||
// Filter with event handler if there is one.
|
||||
if Assigned(fOnFilterItemEx) then
|
||||
Pass:=fOnFilterItemEx(Node.Text, TObject(Node.Data), Done)
|
||||
else
|
||||
Pass:=False;
|
||||
// Support also the old filter event without a caption.
|
||||
if (not (Pass and Done)) and Assigned(fOnFilterItem) then
|
||||
Pass:=fOnFilterItem(TObject(Node.Data), Done);
|
||||
|
||||
// Filter by item's caption text if needed.
|
||||
if not (Pass or Done) then
|
||||
Pass:=(FilterLC='') or (Pos(FilterLC,UTF8LowerCase(Node.Text))>0);
|
||||
Pass := DoFilterItem(Node.Text, TObject(Node.Data), FilterLC);
|
||||
if Pass and (fFirstPassedNode=Nil) then
|
||||
fFirstPassedNode:=Node;
|
||||
// Recursive call for child nodes.
|
||||
|
||||
@ -222,6 +222,10 @@ type
|
||||
fOnFilterItem: TFilterItemEvent;
|
||||
fOnFilterItemEx: TFilterItemExEvent;
|
||||
fOnCheckItem: TCheckItemEvent;
|
||||
function DoFilterItem(const ACaption: string; const Item: TObject;
|
||||
const FilterLC: string): Boolean; virtual;
|
||||
function DoDefaultFilterItem(const ACaption: string; const Item: TObject;
|
||||
const FilterLC: string): Boolean; virtual;
|
||||
procedure EditKeyDown(var Key: Word; Shift: TShiftState); override;
|
||||
procedure EditChange; override;
|
||||
procedure EditEnter; override;
|
||||
@ -1118,6 +1122,33 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TCustomControlFilterEdit.DoDefaultFilterItem(const ACaption: string;
|
||||
const Item: TObject; const FilterLC: string): Boolean;
|
||||
begin
|
||||
Result := (FilterLC='') or (Pos(FilterLC,UTF8LowerCase(ACaption))>0);
|
||||
end;
|
||||
|
||||
function TCustomControlFilterEdit.DoFilterItem(const ACaption: string;
|
||||
const Item: TObject; const FilterLC: string): Boolean;
|
||||
var
|
||||
Done: Boolean;
|
||||
begin
|
||||
Done := False;
|
||||
|
||||
// Filter with event handler if there is one.
|
||||
if Assigned(fOnFilterItemEx) then
|
||||
Result:=fOnFilterItemEx(ACaption, Item, Done)
|
||||
else
|
||||
Result:=False;
|
||||
// Support also the old filter event without a caption.
|
||||
if (not (Result and Done)) and Assigned(fOnFilterItem) then
|
||||
Result:=fOnFilterItem(Item, Done);
|
||||
|
||||
// Filter by item's caption text if needed.
|
||||
if not (Result or Done) then
|
||||
Result:=DoDefaultFilterItem(ACaption, Item, FilterLC);
|
||||
end;
|
||||
|
||||
procedure TCustomControlFilterEdit.OnIdle(Sender: TObject; var Done: Boolean);
|
||||
begin
|
||||
if fNeedUpdate then
|
||||
|
||||
Loading…
Reference in New Issue
Block a user