-
Notifications
You must be signed in to change notification settings - Fork 34
/
uTreeeUtils.pas
110 lines (102 loc) · 3.83 KB
/
uTreeeUtils.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
unit uTreeeUtils;
interface
uses
System.IOUtils, System.SysUtils, System.Generics.Collections,
FMX.Types;
type
TTreeUtils = class
private
FCancel : Boolean;
FFiles : TArray<string>;
FDirFunc : TFunc<string, string, TObject, TObject>;
FFileProc : TProc<string, string, Integer, TObject>;
function Stopped : Boolean; inline;
public
procedure BuildTreeFromFiles(AParent : TObject); overload;
procedure BuildTreeFromFiles(AParent : TObject; AFiles : TArray<string>);
overload;
public
class function GetTreeUtils(const AFiles : TArray<string>;
ADirFunc : TFunc<string, string, TObject, TObject>;
AFileProc : TProc<string, string, Integer, TObject>) : TTreeUtils;
public
property Cancel : Boolean read FCancel write FCancel;
property DirFunc : TFunc<string, string, TObject, TObject>
read FDirFunc write FDirFunc;
property FileProc : TProc<string, string, Integer, TObject>
read FFileProc write FFileProc;
end;
implementation
{ TTreeUtils }
procedure TTreeUtils.BuildTreeFromFiles(AParent : TObject);
var
lFullFileName, lFileName, lFullDirName, lDirName, lSplitDir : string;
i, count : integer;
lParent, item : TObject;
lDirectories : TArray<string>;
lDircDirectories : TDictionary<string,TObject>;
begin
self.FCancel := False;
lDircDirectories := TDictionary<string,TObject>.Create;
try
count := High(FFiles);
for i := Low(FFiles) to count do
begin
if Stopped then
exit;
lFullFileName := FFiles[i];
lFileName := system.IOUtils.TPath.GetFileName(lFullFileName);
lFullDirName := system.IOUtils.TPath.GetDirectoryName(lFullFileName);
lFullDirName := StringReplace(lFullDirName, System.IOUtils.TPath.AltDirectorySeparatorChar,
System.IOUtils.TPath.DirectorySeparatorChar, [rfReplaceAll]);
lParent := AParent;
if not lFullDirName.IsEmpty then
begin
LDirectories := lFullDirName.Split(System.IOUtils.TPath.DirectorySeparatorChar);
lDirName := string.Empty;
for lSplitDir in LDirectories do
begin
if Stopped then
exit;
case lDirName.IsEmpty of
True : lDirName := lSplitDir;
False : lDirName := IncludeTrailingPathDelimiter(lDirName) + lSplitDir;
end;
if not lDircDirectories.ContainsKey(lDirName) then
begin
item := DirFunc(lSplitDir, lDirName, lParent);
lDircDirectories.AddOrSetValue(lDirName, item);
end;
lParent := lDircDirectories.Items[lDirName];
end;
end;
if lFileName.IsEmpty then
Continue;
FileProc(lFileName, lFullFileName, i, lParent);
end;
finally
lDircDirectories.Free;
end;
end;
procedure TTreeUtils.BuildTreeFromFiles(AParent: TObject;
AFiles: TArray<string>);
begin
self.FFiles := AFiles;
Self.BuildTreeFromFiles(AParent);
end;
class function TTreeUtils.GetTreeUtils(const AFiles: TArray<string>;
ADirFunc: TFunc<string, string, TObject, TObject>;
AFileProc: TProc<string, string, Integer, TObject>): TTreeUtils;
begin
Result := TTreeUtils.Create;
Result.FFiles := AFiles;
Result.FDirFunc := ADirFunc;
Result.FFileProc := AFileProc;
Result.FCancel := False;
end;
function TTreeUtils.Stopped: Boolean;
begin
Result := FCancel or (not Assigned(DirFunc)) or
(not Assigned(FileProc));
end;
end.