LCL: Use TMaskList always for ShellListView.Mask. Enable all TMask syntax including sets.

git-svn-id: trunk@64660 -
This commit is contained in:
juha 2021-02-24 20:04:15 +00:00
parent 3cce8bdb2b
commit 98045780a1
3 changed files with 30 additions and 58 deletions

View File

@ -24,9 +24,9 @@ uses
Types, Classes, SysUtils, Types, Classes, SysUtils,
// LCL // LCL
LResources, LCLType, LCLStrConsts, LCLPlatformDef, InterfaceBase, Controls, LResources, LCLType, LCLStrConsts, LCLPlatformDef, InterfaceBase, Controls,
Dialogs, Graphics, ExtCtrls, StdCtrls, Forms, Calendar, Buttons, Masks, CalcForm, Dialogs, Graphics, ExtCtrls, StdCtrls, Forms, Calendar, Buttons, CalcForm,
// LazUtils // LazUtils
GraphType, FileUtil, LazFileUtils; GraphType, FileUtil, LazFileUtils, Masks;
type type

View File

@ -29,8 +29,9 @@ interface
{$endif} {$endif}
uses uses
Classes, SysUtils, StdCtrls, FileUtil, LazFileUtils, Masks, Graphics, Classes, SysUtils,
ShellCtrls; StdCtrls, Graphics, ShellCtrls,
FileUtil, LazFileUtils, Masks;
Type Type

View File

@ -31,7 +31,7 @@ uses
{$if defined(Windows) or defined(darwin) or defined(HASAMIGA))} {$if defined(Windows) or defined(darwin) or defined(HASAMIGA))}
{$define CaseInsensitiveFilenames} {$define CaseInsensitiveFilenames}
{$endif} {$endif}
{$IF defined(CaseInsensitiveFilenames) or defined(darwin)} {$IF defined(CaseInsensitiveFilenames)}
{$DEFINE NotLiteralFilenames} {$DEFINE NotLiteralFilenames}
{$ENDIF} {$ENDIF}
@ -101,9 +101,6 @@ type
{ Methods specific to Lazarus - useful for other classes } { Methods specific to Lazarus - useful for other classes }
class function GetBasePath: string; class function GetBasePath: string;
function GetRootPath: string; function GetRootPath: string;
class procedure GetFilesInDir(const ABaseDir: string;
AMask: string; AObjectTypes: TObjectTypes; AResult: TStrings; AFileSortType: TFileSortType = fstNone;
ACaseSensitivity: TMaskCaseSensitivity = mcsPlatformDefault);
{ Other methods specific to Lazarus } { Other methods specific to Lazarus }
function GetPathFromNode(ANode: TTreeNode): string; function GetPathFromNode(ANode: TTreeNode): string;
procedure PopulateWithBaseFiles; procedure PopulateWithBaseFiles;
@ -640,7 +637,6 @@ begin
inherited Destroy; inherited Destroy;
end; end;
function FilesSortAlphabet(p1, p2: Pointer): Integer; function FilesSortAlphabet(p1, p2: Pointer): Integer;
var var
f1, f2: TFileItem; f1, f2: TFileItem;
@ -673,13 +669,14 @@ end;
AMask may contain multiple file masks separated by ; AMask may contain multiple file masks separated by ;
} }
class procedure TCustomShellTreeView.GetFilesInDir(const ABaseDir: string; procedure GetFilesInDir(const ABaseDir: string; AMask: string;
AMask: string; AObjectTypes: TObjectTypes; AResult: TStrings; AFileSortType: TFileSortType; ACaseSensitivity: TMaskCaseSensitivity); AObjectTypes: TObjectTypes; AResult: TStrings; AFileSortType: TFileSortType;
ACaseSensitivity: TMaskCaseSensitivity = mcsPlatformDefault);
var var
DirInfo: TSearchRec; DirInfo: TSearchRec;
FindResult, i: Integer; FindResult, i: Integer;
IsDirectory, IsValidDirectory, IsHidden, AddFile, UseMaskList: Boolean; IsDirectory, IsValidDirectory, IsHidden, AddFile: Boolean;
SearchStr, MaskStr, ShortFilename: string; SearchStr, ShortFilename: string;
MaskList: TMaskList; MaskList: TMaskList;
Files: TList; Files: TList;
FileItem: TFileItem; FileItem: TFileItem;
@ -695,56 +692,32 @@ begin
ErrMode:=SetErrorMode(SEM_FAILCRITICALERRORS or SEM_NOALIGNMENTFAULTEXCEPT or SEM_NOGPFAULTERRORBOX or SEM_NOOPENFILEERRORBOX); ErrMode:=SetErrorMode(SEM_FAILCRITICALERRORS or SEM_NOALIGNMENTFAULTEXCEPT or SEM_NOGPFAULTERRORBOX or SEM_NOOPENFILEERRORBOX);
try try
{$endif} {$endif}
while (Length(AMask) > 0) and (AMask[Length(AMask)] = ';') do
MaskStr := Trim(AMask); Delete(AMask, Length(AMask), 1);
while (Length(MaskStr) > 0) and (MaskStr[Length(MaskStr)] = ';') do if Trim(AMask) = '' then
System.Delete(MaskStr, Length(MaskStr), 1); AMask := AllFilesMask;
if Trim(MaskStr) = '' then MaskOptions := []; // was moDisableSets
MaskStr := AllFilesMask; {$ifdef NotLiteralFilenames}
//Use a TMaksList if more than 1 mask is specified or if MaskCaseSensitivity differs from the platform default behaviour if (ACaseSensitivity = mcsCaseSensitive) then
UseMaskList := (Pos(';', MaskStr) > 0) or {$else}
{$ifdef NotLiteralFilenames} if (ACaseSensitivity <> mcsCaseInsensitive) then
(ACaseSensitivity = mcsCaseSensitive) {$endif}
{$else} Include(MaskOptions, moCaseSensitive);
(ACaseSensitivity = mcsCaseInsensitive) MaskList := TMaskList.Create(AMask, ';', MaskOptions);
{$endif}
;
if UseMaskList then
begin
//Disable the use of sets in the masklist.
//this behaviour would be incompatible with the situation if no MaskList was used
//and it would break backwards compatibilty and could raise unexpected EConvertError where it did not in the past.
//If you need sets in the MaskList, use the OnAddItem event for that. (BB)
MaskOptions := [moDisableSets];
{$ifdef NotLiteralFilenames}
if (ACaseSensitivity = mcsCaseSensitive) then
MaskOptions := [moDisableSets, moCaseSensitive];
{$else}
if (ACaseSensitivity <> mcsCaseInsensitive) then
MaskOptions := [moDisableSets, moCaseSensitive];
{$endif}
MaskList := TMaskList.Create(MaskStr, ';', MaskOptions); //False by default
end;
try try
if AFileSortType = fstNone then if AFileSortType = fstNone then
Files:=nil Files:=nil
else else
Files := TList.Create; Files := TList.Create;
i := 0; i := 0;
if UseMaskList then SearchStr := IncludeTrailingPathDelimiter(ABaseDir) + AllFilesMask;
SearchStr := IncludeTrailingPathDelimiter(ABaseDir) + AllFilesMask
else
SearchStr := IncludeTrailingPathDelimiter(ABaseDir) + MaskStr; //single mask, let FindFirst/FindNext handle matching
FindResult := FindFirstUTF8(SearchStr, faAnyFile, DirInfo); FindResult := FindFirstUTF8(SearchStr, faAnyFile, DirInfo);
while (FindResult = 0) do while (FindResult = 0) do
begin begin
ShortFilename := DirInfo.Name; ShortFilename := DirInfo.Name;
IsValidDirectory := (ShortFilename <> '.') and (ShortFilename <> '..'); IsValidDirectory := (ShortFilename <> '.') and (ShortFilename <> '..');
//no need to call MaskListMatches (which loops through all masks) if ShortFileName is '.' or '..' since we never process this //no need to call MaskListMatches (which loops through all masks) if ShortFileName is '.' or '..' since we never process this
if ((not UseMaskList) or MaskList.Matches(DirInfo.Name)) and IsValidDirectory then if MaskList.Matches(DirInfo.Name) and IsValidDirectory then
begin begin
inc(i); inc(i);
if i = 100 then if i = 100 then
@ -770,11 +743,10 @@ begin
// AddFile identifies if the file is valid or not // AddFile identifies if the file is valid or not
if AddFile then if AddFile then
begin begin
if not Assigned(Files) then if Assigned(Files) then
begin Files.Add(TFileItem.Create(DirInfo, ABaseDir))
else
AResult.AddObject(ShortFilename, TFileItem.Create(DirInfo, ABaseDir)); AResult.AddObject(ShortFilename, TFileItem.Create(DirInfo, ABaseDir));
end else
Files.Add(TFileItem.Create(DirInfo, ABaseDir));
end; end;
end;// Filename matches the mask end;// Filename matches the mask
FindResult := FindNextUTF8(DirInfo); FindResult := FindNextUTF8(DirInfo);
@ -782,8 +754,7 @@ begin
FindCloseUTF8(DirInfo); FindCloseUTF8(DirInfo);
finally finally
if UseMaskList then MaskList.Free;
MaskList.Free;
end; end;
if Assigned(Files) then if Assigned(Files) then
@ -1546,7 +1517,7 @@ begin
Files := TStringList.Create; Files := TStringList.Create;
try try
Files.OwnsObjects := True; Files.OwnsObjects := True;
TCustomShellTreeView.GetFilesInDir(FRoot, FMask, FObjectTypes, Files, fstNone, FMaskCaseSensitivity); GetFilesInDir(FRoot, Trim(FMask), FObjectTypes, Files, fstNone, FMaskCaseSensitivity);
for i := 0 to Files.Count - 1 do for i := 0 to Files.Count - 1 do
begin begin