@@ -38,6 +38,7 @@ public class MainForm : Form
38
38
private readonly CheckBox chkContentSingleLine ;
39
39
private readonly NumericStepper nudContentTimeout ;
40
40
private readonly FilePicker fpSearchPath ;
41
+ private readonly ComboBox cboSubdirectories ;
41
42
private readonly Button btnStartSearch ;
42
43
private readonly FilePicker fpOpenWith ;
43
44
private readonly Button btnSelectAll ;
@@ -91,6 +92,9 @@ public class MainForm : Form
91
92
private static readonly object _locker = new object ( ) ;
92
93
private bool _matchNumberOrdering ;
93
94
private DateTime _lastTreeGridViewRefresh = DateTime . UtcNow ;
95
+ private int _searchDepth = - 1 ;
96
+ private string _contentPattern ;
97
+ private string _filenamePattern ;
94
98
95
99
public MainForm ( )
96
100
{
@@ -119,6 +123,7 @@ public MainForm()
119
123
chkContentSingleLine = FindChild < CheckBox > ( "chkContentSingleLine" ) ;
120
124
nudContentTimeout = FindChild < NumericStepper > ( "nudContentTimeout" ) ;
121
125
fpSearchPath = FindChild < FilePicker > ( "fpSearchPath" ) ;
126
+ cboSubdirectories = FindChild < ComboBox > ( "cboSubdirectories" ) ;
122
127
btnStartSearch = FindChild < Button > ( "btnStartSearch" ) ;
123
128
fpOpenWith = FindChild < FilePicker > ( "fpOpenWith" ) ;
124
129
btnSelectAll = FindChild < Button > ( "btnSelectAll" ) ;
@@ -131,6 +136,29 @@ public MainForm()
131
136
lblStatus = FindChild < Label > ( "lblStatus" ) ;
132
137
#endregion // Initialize Controls
133
138
139
+ AddSubdirectoriesItems ( ) ;
140
+ AddTestResultExplorerColumns ( ) ;
141
+ }
142
+
143
+ private void AddSubdirectoriesItems ( )
144
+ {
145
+ cboSubdirectories . SuspendLayout ( ) ;
146
+ cboSubdirectories . Items . Add ( "all (unlimited depth)" , "-1" ) ;
147
+ cboSubdirectories . Items . Add ( "current dir only" , "0" ) ;
148
+ cboSubdirectories . Items . Add ( "1 level" , "1" ) ;
149
+ for ( int i = 2 ; i <= 32 ; i ++ )
150
+ {
151
+ cboSubdirectories . Items . Add ( $ "{ i } levels", i . ToString ( ) ) ;
152
+ }
153
+
154
+ cboSubdirectories . SelectedKey = "-1" ;
155
+ cboSubdirectories . ReadOnly = true ;
156
+ cboSubdirectories . ResumeLayout ( ) ;
157
+ cboSubdirectories . Invalidate ( ) ;
158
+ }
159
+
160
+ private void AddTestResultExplorerColumns ( )
161
+ {
134
162
tvwResultExplorer . Columns . Add ( new GridColumn ( )
135
163
{
136
164
HeaderText = "Select" ,
@@ -197,12 +225,15 @@ private void OpenInEditor(string path)
197
225
198
226
private async void HandleStartSearch ( object sender , EventArgs e )
199
227
{
228
+ string searchPath = fpSearchPath . FilePath ? . Trim ( ) ;
229
+ if ( string . IsNullOrWhiteSpace ( searchPath ) )
230
+ return ;
231
+
232
+ if ( ! Directory . Exists ( searchPath ) )
233
+ return ;
234
+
200
235
try
201
236
{
202
- string searchPath = fpSearchPath . FilePath . Trim ( ) ;
203
- if ( ! Directory . Exists ( searchPath ) )
204
- return ;
205
-
206
237
lock ( _locker )
207
238
{
208
239
if ( _isSearching )
@@ -219,6 +250,10 @@ private async void HandleStartSearch(object sender, EventArgs e)
219
250
_isSearching = true ;
220
251
}
221
252
253
+ _filenamePattern = txtFilenameRegex . Text ;
254
+ _contentPattern = txtContentRegex . Text ;
255
+ _searchDepth = int . Parse ( cboSubdirectories . SelectedKey ) ;
256
+
222
257
_filenameRegex = FilenameRegex ;
223
258
_contentRegex = ContentRegex ;
224
259
@@ -230,7 +265,7 @@ private async void HandleStartSearch(object sender, EventArgs e)
230
265
btnOrderByMatches . Enabled = false ;
231
266
_cancellationTokenSource = new CancellationTokenSource ( ) ;
232
267
CancellationToken token = _cancellationTokenSource . Token ;
233
- await Task . Factory . StartNew ( ( ) => SearchDirectory ( searchPath , treeGridItemCollection ) ,
268
+ await Task . Factory . StartNew ( ( ) => SearchDirectory ( 0 , searchPath , treeGridItemCollection ) ,
234
269
token ,
235
270
TaskCreationOptions . LongRunning ,
236
271
TaskScheduler . Default ) ;
@@ -249,19 +284,33 @@ await Task.Factory.StartNew(() => SearchDirectory(searchPath, treeGridItemCollec
249
284
}
250
285
}
251
286
252
- private void SearchDirectory ( string path , TreeGridItemCollection treeGridItemCollection )
287
+ private void SearchDirectory ( int level , string path , TreeGridItemCollection treeGridItemCollection )
253
288
{
254
289
if ( _cancellationTokenSource . IsCancellationRequested )
255
290
return ;
256
291
292
+ if ( _searchDepth != - 1 && level > _searchDepth )
293
+ return ;
294
+
257
295
Application . Instance . Invoke ( ( ) => lblStatus . Text = path ) ;
258
296
List < string > filePaths = GetMatchingFiles ( path ) ;
259
297
foreach ( string filePath in filePaths . OrderBy ( f => f ) )
260
298
{
261
299
try
262
300
{
263
- MatchCollection matches = _contentRegex . Matches ( File . ReadAllText ( filePath ) ) ;
264
- if ( matches . Count > 0 )
301
+ int count = 0 ;
302
+ bool add = false ;
303
+ if ( string . IsNullOrWhiteSpace ( _contentPattern ) )
304
+ {
305
+ add = true ;
306
+ }
307
+ else
308
+ {
309
+ MatchCollection matches = _contentRegex . Matches ( File . ReadAllText ( filePath ) ) ;
310
+ count = matches . Count ;
311
+ add = count > 0 ;
312
+ }
313
+ if ( add )
265
314
{
266
315
treeGridItemCollection . Add (
267
316
new TreeGridItem ( )
@@ -270,7 +319,7 @@ private void SearchDirectory(string path, TreeGridItemCollection treeGridItemCol
270
319
{
271
320
false , // column 0: Selected checkbox
272
321
null , // column 1: Open link
273
- matches . Count ,
322
+ count ,
274
323
filePath
275
324
}
276
325
} ) ;
@@ -284,29 +333,43 @@ private void SearchDirectory(string path, TreeGridItemCollection treeGridItemCol
284
333
285
334
UpdateResultExplorer ( ) ;
286
335
287
- foreach ( string directoryPath in Directory . GetDirectories ( path ) )
336
+ try
337
+ {
338
+ foreach ( string directoryPath in Directory . GetDirectories ( path ) )
339
+ {
340
+ SearchDirectory ( level + 1 , directoryPath , treeGridItemCollection ) ;
341
+ }
342
+ }
343
+ catch
288
344
{
289
- SearchDirectory ( directoryPath , treeGridItemCollection ) ;
345
+ // No permission to list directories, etc.
290
346
}
291
347
}
292
348
293
349
private List < string > GetMatchingFiles ( string path )
294
350
{
295
351
List < string > filePaths = new List < string > ( ) ;
296
- foreach ( string filePath in Directory . GetFiles ( path ) )
352
+ try
297
353
{
298
- string filename = Path . GetFileName ( filePath ) ;
299
- try
354
+ foreach ( string filePath in Directory . GetFiles ( path ) )
300
355
{
301
- if ( _filenameRegex . IsMatch ( filename ) )
356
+ string filename = Path . GetFileName ( filePath ) ;
357
+ try
302
358
{
303
- filePaths . Add ( filePath ) ;
359
+ if ( string . IsNullOrWhiteSpace ( _filenamePattern ) || _filenameRegex . IsMatch ( filename ) )
360
+ {
361
+ filePaths . Add ( filePath ) ;
362
+ }
363
+ }
364
+ catch
365
+ {
366
+ // Regex timeout
304
367
}
305
368
}
306
- catch
307
- {
308
- // Regex timeout
309
- }
369
+ }
370
+ catch
371
+ {
372
+ // No permission to list files, etc.
310
373
}
311
374
312
375
return filePaths ;
0 commit comments