Upload FastSeekWpf/MainWindow.xaml.cs
Browse files- FastSeekWpf/MainWindow.xaml.cs +59 -21
FastSeekWpf/MainWindow.xaml.cs
CHANGED
|
@@ -32,12 +32,10 @@ public partial class MainWindow : Window, INotifyPropertyChanged
|
|
| 32 |
private readonly System.Collections.Concurrent.ConcurrentQueue<IndexEvent> _eventQueue = new();
|
| 33 |
private CancellationTokenSource? _cts;
|
| 34 |
private List<string> _excludedDirs = new();
|
| 35 |
-
private bool _caseSensitive;
|
| 36 |
private int _selectedIndex;
|
| 37 |
private bool _initialized;
|
| 38 |
private bool _isVisible;
|
| 39 |
|
| 40 |
-
// Debounced search
|
| 41 |
private CancellationTokenSource? _searchDebounceCts;
|
| 42 |
private readonly object _searchLock = new();
|
| 43 |
|
|
@@ -98,8 +96,9 @@ public partial class MainWindow : Window, INotifyPropertyChanged
|
|
| 98 |
{
|
| 99 |
ResultsScroll.Visibility = Visibility.Collapsed;
|
| 100 |
EmptyHint.Visibility = Visibility.Visible;
|
|
|
|
| 101 |
StatusBar.Visibility = Visibility.Visible;
|
| 102 |
-
StatusText.Text = "
|
| 103 |
SepLine.Visibility = Visibility.Collapsed;
|
| 104 |
});
|
| 105 |
}
|
|
@@ -116,10 +115,9 @@ public partial class MainWindow : Window, INotifyPropertyChanged
|
|
| 116 |
{
|
| 117 |
Dispatcher.Invoke(() =>
|
| 118 |
{
|
| 119 |
-
|
| 120 |
-
|
| 121 |
});
|
| 122 |
-
ShowError("No NTFS drives found. Make sure you are running as Administrator.");
|
| 123 |
return;
|
| 124 |
}
|
| 125 |
|
|
@@ -186,16 +184,49 @@ public partial class MainWindow : Window, INotifyPropertyChanged
|
|
| 186 |
lock (_indexLock)
|
| 187 |
{
|
| 188 |
_index = new IndexStore();
|
|
|
|
| 189 |
foreach (var drive in _drives)
|
| 190 |
{
|
| 191 |
try
|
| 192 |
{
|
| 193 |
Logger.Log($"Scanning {drive.Letter}...");
|
|
|
|
|
|
|
| 194 |
using var reader = new MftReader(drive);
|
| 195 |
-
|
| 196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
_index.PopulateFromScan(scan, drive.Root);
|
| 198 |
-
|
|
|
|
|
|
|
| 199 |
}
|
| 200 |
catch (Exception ex)
|
| 201 |
{
|
|
@@ -229,7 +260,16 @@ public partial class MainWindow : Window, INotifyPropertyChanged
|
|
| 229 |
|
| 230 |
Dispatcher.Invoke(() =>
|
| 231 |
{
|
| 232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
StatusBar.Visibility = Visibility.Visible;
|
| 234 |
});
|
| 235 |
Logger.Log("InitializeAsync done.");
|
|
@@ -237,18 +277,14 @@ public partial class MainWindow : Window, INotifyPropertyChanged
|
|
| 237 |
catch (Exception ex)
|
| 238 |
{
|
| 239 |
Logger.Log($"InitializeAsync fatal: {ex}");
|
| 240 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
}
|
| 242 |
}
|
| 243 |
|
| 244 |
-
private void ShowError(string message)
|
| 245 |
-
{
|
| 246 |
-
Dispatcher.Invoke(() =>
|
| 247 |
-
{
|
| 248 |
-
MessageBox.Show(message, "FastSeek Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
| 249 |
-
});
|
| 250 |
-
}
|
| 251 |
-
|
| 252 |
private void LiveUpdateLoop(CancellationToken ct)
|
| 253 |
{
|
| 254 |
while (!ct.IsCancellationRequested)
|
|
@@ -414,7 +450,9 @@ public partial class MainWindow : Window, INotifyPropertyChanged
|
|
| 414 |
Results = new List<ResultItem>();
|
| 415 |
ResultsScroll.Visibility = Visibility.Collapsed;
|
| 416 |
EmptyHint.Visibility = Visibility.Visible;
|
| 417 |
-
EmptyHint.Text =
|
|
|
|
|
|
|
| 418 |
SepLine.Visibility = Visibility.Collapsed;
|
| 419 |
StatusText.Text = $"{_index.Count:N0} files indexed";
|
| 420 |
});
|
|
@@ -445,7 +483,7 @@ public partial class MainWindow : Window, INotifyPropertyChanged
|
|
| 445 |
List<SearchResult> results;
|
| 446 |
lock (_indexLock)
|
| 447 |
{
|
| 448 |
-
results = SearchEngine.Search(_index, query, 50,
|
| 449 |
}
|
| 450 |
|
| 451 |
Logger.Log($"Search '{query}': {results.Count} results returned to UI");
|
|
|
|
| 32 |
private readonly System.Collections.Concurrent.ConcurrentQueue<IndexEvent> _eventQueue = new();
|
| 33 |
private CancellationTokenSource? _cts;
|
| 34 |
private List<string> _excludedDirs = new();
|
|
|
|
| 35 |
private int _selectedIndex;
|
| 36 |
private bool _initialized;
|
| 37 |
private bool _isVisible;
|
| 38 |
|
|
|
|
| 39 |
private CancellationTokenSource? _searchDebounceCts;
|
| 40 |
private readonly object _searchLock = new();
|
| 41 |
|
|
|
|
| 96 |
{
|
| 97 |
ResultsScroll.Visibility = Visibility.Collapsed;
|
| 98 |
EmptyHint.Visibility = Visibility.Visible;
|
| 99 |
+
EmptyHint.Text = "Indexing...";
|
| 100 |
StatusBar.Visibility = Visibility.Visible;
|
| 101 |
+
StatusText.Text = "Starting scan...";
|
| 102 |
SepLine.Visibility = Visibility.Collapsed;
|
| 103 |
});
|
| 104 |
}
|
|
|
|
| 115 |
{
|
| 116 |
Dispatcher.Invoke(() =>
|
| 117 |
{
|
| 118 |
+
EmptyHint.Text = "No NTFS drives found.\nRun as Administrator.";
|
| 119 |
+
StatusText.Text = "Error: no drives";
|
| 120 |
});
|
|
|
|
| 121 |
return;
|
| 122 |
}
|
| 123 |
|
|
|
|
| 184 |
lock (_indexLock)
|
| 185 |
{
|
| 186 |
_index = new IndexStore();
|
| 187 |
+
long totalRecords = 0;
|
| 188 |
foreach (var drive in _drives)
|
| 189 |
{
|
| 190 |
try
|
| 191 |
{
|
| 192 |
Logger.Log($"Scanning {drive.Letter}...");
|
| 193 |
+
Dispatcher.Invoke(() => StatusText.Text = $"Scanning {drive.Letter}: ...");
|
| 194 |
+
|
| 195 |
using var reader = new MftReader(drive);
|
| 196 |
+
ScanResult? scan = null;
|
| 197 |
+
string method = "direct";
|
| 198 |
+
|
| 199 |
+
try
|
| 200 |
+
{
|
| 201 |
+
scan = reader.ScanDirect();
|
| 202 |
+
Logger.Log($"Direct scan OK for {drive.Letter}");
|
| 203 |
+
}
|
| 204 |
+
catch (Exception ex1)
|
| 205 |
+
{
|
| 206 |
+
Logger.Log($"Direct scan failed for {drive.Letter}: {ex1.Message}");
|
| 207 |
+
method = "fallback";
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
if (scan == null)
|
| 211 |
+
{
|
| 212 |
+
try
|
| 213 |
+
{
|
| 214 |
+
scan = reader.Scan();
|
| 215 |
+
Logger.Log($"Fallback scan OK for {drive.Letter}");
|
| 216 |
+
method = "fallback";
|
| 217 |
+
}
|
| 218 |
+
catch (Exception ex2)
|
| 219 |
+
{
|
| 220 |
+
Logger.Log($"Fallback scan failed for {drive.Letter}: {ex2.Message}");
|
| 221 |
+
Dispatcher.Invoke(() => StatusText.Text = $"Scan failed for {drive.Letter}");
|
| 222 |
+
continue;
|
| 223 |
+
}
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
_index.PopulateFromScan(scan, drive.Root);
|
| 227 |
+
totalRecords += scan.Records.Count;
|
| 228 |
+
Logger.Log($"Scanned {drive.Letter}: {scan.Records.Count} files ({method})");
|
| 229 |
+
Dispatcher.Invoke(() => StatusText.Text = $"Scanned {drive.Letter}: {scan.Records.Count:N0} files");
|
| 230 |
}
|
| 231 |
catch (Exception ex)
|
| 232 |
{
|
|
|
|
| 260 |
|
| 261 |
Dispatcher.Invoke(() =>
|
| 262 |
{
|
| 263 |
+
if (_index.Count == 0)
|
| 264 |
+
{
|
| 265 |
+
EmptyHint.Text = "Index is empty.\nRun CLI diagnostics:\nFastSeekWpf.exe --cli";
|
| 266 |
+
StatusText.Text = "0 files indexed — check diagnostics";
|
| 267 |
+
}
|
| 268 |
+
else
|
| 269 |
+
{
|
| 270 |
+
EmptyHint.Text = "Start typing to search your files...";
|
| 271 |
+
StatusText.Text = $"{_index.Count:N0} files indexed";
|
| 272 |
+
}
|
| 273 |
StatusBar.Visibility = Visibility.Visible;
|
| 274 |
});
|
| 275 |
Logger.Log("InitializeAsync done.");
|
|
|
|
| 277 |
catch (Exception ex)
|
| 278 |
{
|
| 279 |
Logger.Log($"InitializeAsync fatal: {ex}");
|
| 280 |
+
Dispatcher.Invoke(() =>
|
| 281 |
+
{
|
| 282 |
+
EmptyHint.Text = $"Initialization failed:\n{ex.Message}\n\nCheck log at %LOCALAPPDATA%\\FastSeek\\log.txt";
|
| 283 |
+
StatusText.Text = "Error — check log";
|
| 284 |
+
});
|
| 285 |
}
|
| 286 |
}
|
| 287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
private void LiveUpdateLoop(CancellationToken ct)
|
| 289 |
{
|
| 290 |
while (!ct.IsCancellationRequested)
|
|
|
|
| 450 |
Results = new List<ResultItem>();
|
| 451 |
ResultsScroll.Visibility = Visibility.Collapsed;
|
| 452 |
EmptyHint.Visibility = Visibility.Visible;
|
| 453 |
+
EmptyHint.Text = _index.Count == 0
|
| 454 |
+
? "Index is empty.\nRun CLI diagnostics: FastSeekWpf.exe --cli"
|
| 455 |
+
: "Start typing to search your files...";
|
| 456 |
SepLine.Visibility = Visibility.Collapsed;
|
| 457 |
StatusText.Text = $"{_index.Count:N0} files indexed";
|
| 458 |
});
|
|
|
|
| 483 |
List<SearchResult> results;
|
| 484 |
lock (_indexLock)
|
| 485 |
{
|
| 486 |
+
results = SearchEngine.Search(_index, query, 50, false, _excludedDirs);
|
| 487 |
}
|
| 488 |
|
| 489 |
Logger.Log($"Search '{query}': {results.Count} results returned to UI");
|