-
Notifications
You must be signed in to change notification settings - Fork 6
/
mmpFolderNavigation.pas
121 lines (100 loc) · 5.06 KB
/
mmpFolderNavigation.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
111
112
113
114
115
116
117
118
119
120
121
{ MMP: Minimalist Media Player
Copyright (C) 2021-2024 Baz Cuda
https://github.com/BazzaCuda/MinimalistMediaPlayerX
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
}
unit mmpFolderNavigation;
interface
type
TNextFolderDirection = (nfForwards, nfBackwards);
function mmpNextFolder(const aFolderPath: string; const aDirection: TNextFolderDirection; const bAllowIntoWindows: boolean; const aPrevFolderPath: string = ''): string;
implementation
uses
system.classes, system.sysUtils,
mmpFolderUtils, mmpUtils,
_debugWindow;
function naturalSort(aList: TStringList; index1: integer; index2: integer): integer;
begin
result := mmpCompareStr(mmpRTBS(lowerCase(aList[index1])), mmpRTBS(lowerCase(aList[index2]))); // lowercase: sort aFolder with AFolder, not after ZFolder
end;
procedure findSubFolders(const aFolderList: TStringList; const aFolderPath: string; const bAllowIntoWindows: boolean);
var
rc: integer;
sr: TSearchRec;
begin
aFolderList.clear;
aFolderList.sorted := FALSE;
rc := findFirst(aFolderPath + '*.*', faDirectory, sr);
while rc = 0 do begin
case ((sr.attr AND faDirectory) <> 0) and ((sr.attr AND faSysFile) = 0) of TRUE: begin // faSysFile also applies to system folders
case (sr.name = 'Windows') and bAllowIntoWindows of TRUE: aFolderList.add(aFolderPath + sr.name + '\'); end;
case (sr.name <> '.') and (sr.name <> '..') and (sr.name <> 'Windows') and (sr.name <> 'WinSxS')
of TRUE: aFolderList.add(aFolderPath + sr.name + '\'); end;end;end;
rc := findNext(sr);
end;
findClose(sr);
aFolderList.customSort(naturalSort);
end;
function mmpNextFolder(const aFolderPath: string; const aDirection: TNextFolderDirection; const bAllowIntoWindows: boolean; const aPrevFolderPath: string = ''): string;
var
folderList: TStringList;
ix: integer;
function deepestSubFolder(aFolderPath: string): string;
var
folderList: TStringList;
begin
folderList := TStringList.Create;
try
findSubFolders(folderList, aFolderPath, bAllowIntoWindows);
case folderList.count > 0 of
TRUE: result := deepestSubFolder(folderList[folderList.count - 1]);
FALSE: result := aFolderPath; end;
finally
folderList.Free;
end;
end;
begin
case (aDirection = nfForwards) and (aFolderPath = aPrevFolderPath) of TRUE: EXIT; end; // reached the end of the folders on this drive
folderList := TStringList.Create;
try
case aDirection = nfForwards of
TRUE: begin
findSubFolders(folderList, aFolderPath, bAllowIntoWindows); // does this folder have subfolders ?
case folderList.count <> 0 of // if it does.....
TRUE: begin
case aPrevFolderPath = '' of // ... and we haven't used any so far....
TRUE: result := folderList[0]; // ... just return the first in the list
FALSE: begin
ix := folderList.indexOf(aPrevFolderPath); // ... otherwise find the previous used in the list of subfolders...
case ix + 1 <= folderList.Count - 1 of // ... and return the next one if there is one...
TRUE: result := folderList[ix + 1];
FALSE: result := mmpNextFolder(extractFilePath(mmpRTBS(aFolderPath)), aDirection, bAllowIntoWindows, aFolderPath); end; // ...if this is the end of the subfolders go back up a level
end;
end;
end;
FALSE: result := mmpNextFolder(extractFilePath(mmpRTBS(aFolderPath)), aDirection, bAllowIntoWindows, aFolderPath); end; // no subfolders so go back up a level
end;
FALSE:
case aDirection = nfBackwards of TRUE: begin
findSubFolders(folderList, extractFilePath(mmpRTBS(aFolderPath)), bAllowIntoWindows); // get this subfolder's siblings
ix := folderList.indexOf(aFolderPath); // find this subfolder's position in the list
case ix - 1 >= 0 of // if there is a previous sibling, get its deepest subfolder
TRUE: result := deepestSubFolder(folderList[ix - 1]);
FALSE: result := extractFilePath(mmpRTBS(aFolderPath)); end; // otherwise just go up one level
end;end;
end;
finally
folderList.Free;
end;
end;
end.