Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 106 additions & 79 deletions Files/Filesystem/Search/FolderSearch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,114 @@ namespace Files.Filesystem.Search
{
internal class FolderSearch
{
public static async Task<ObservableCollection<ListedItem>> SearchForUserQueryTextAsync(string userText, string WorkingDirectory, int maxItemCount = 10)
public static async Task<ObservableCollection<ListedItem>> SearchForUserQueryTextAsync(string userText, string WorkingDirectory, IShellPage associatedInstance, int maxItemCount = 10)
{
var returnedItems = new ObservableCollection<ListedItem>();
maxItemCount = maxItemCount < 0 ? int.MaxValue : maxItemCount;

var hiddenOnlyFromWin32 = false;
var workingDir = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(WorkingDirectory);
if (workingDir)
{
foreach (var item in await SearchWithStorageFolder(userText, workingDir, maxItemCount))
{
returnedItems.Add(item);
}
hiddenOnlyFromWin32 = true;
}
if (!hiddenOnlyFromWin32 || App.AppSettings.AreHiddenItemsVisible)
{
foreach (var item in await SearchWithWin32(userText, WorkingDirectory, hiddenOnlyFromWin32,
maxItemCount - returnedItems.Count))
{
returnedItems.Add(item);
}
}

return returnedItems;
}

private static async Task<IList<ListedItem>> SearchWithWin32(string userText, string WorkingDirectory, bool hiddenOnly, int maxItemCount = 10)
{
var returnedItems = new List<ListedItem>();
(IntPtr hFile, WIN32_FIND_DATA findData) = await Task.Run(() =>
{
FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
int additionalFlags = FIND_FIRST_EX_LARGE_FETCH;
IntPtr hFileTsk = FindFirstFileExFromApp(WorkingDirectory + $"\\*{userText}*.*", findInfoLevel, out WIN32_FIND_DATA findDataTsk, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero,
additionalFlags);
return (hFileTsk, findDataTsk);
}).WithTimeoutAsync(TimeSpan.FromSeconds(5));

if (hFile != IntPtr.Zero)
{
await Task.Run(() =>
{
var hasNextFile = false;
do
{
if (returnedItems.Count >= maxItemCount)
{
break;
}
var itemPath = Path.Combine(WorkingDirectory, findData.cFileName);
if (((FileAttributes)findData.dwFileAttributes & FileAttributes.System) != FileAttributes.System || !App.AppSettings.AreSystemItemsHidden)
{
var isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden;
if ((!isHidden && !hiddenOnly) || (isHidden && App.AppSettings.AreHiddenItemsVisible))
{
if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) != FileAttributes.Directory)
{
returnedItems.Add(new ListedItem(null)
{
PrimaryItemAttribute = StorageItemTypes.File,
ItemName = findData.cFileName,
ItemPath = itemPath,
IsHiddenItem = true,
LoadFileIcon = false,
LoadUnknownTypeGlyph = true,
LoadFolderGlyph = false,
ItemPropertiesInitialized = true
});
}
else if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
{
if (findData.cFileName != "." && findData.cFileName != "..")
{
returnedItems.Add(new ListedItem(null)
{
PrimaryItemAttribute = StorageItemTypes.Folder,
ItemName = findData.cFileName,
ItemPath = itemPath,
IsHiddenItem = true,
LoadFileIcon = false,
LoadUnknownTypeGlyph = false,
LoadFolderGlyph = true,
ItemPropertiesInitialized = true
});
}
}
}
}

hasNextFile = FindNextFile(hFile, out findData);
} while (hasNextFile);

FindClose(hFile);
});
}
return returnedItems;
}

private static async Task<IList<ListedItem>> SearchWithStorageFolder(string userText, StorageFolder workingDir, int maxItemCount = 10)
{
var workingDir = await StorageFolder.GetFolderFromPathAsync(WorkingDirectory);
QueryOptions options = new QueryOptions()
{
FolderDepth = FolderDepth.Deep,
IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties,
UserSearchFilter = string.IsNullOrWhiteSpace(userText) ? null : userText,
};
options.SortOrder.Clear();
options.SortOrder.Add(new SortEntry()
{
PropertyName = "System.Search.Rank",
Expand All @@ -31,9 +130,9 @@ public static async Task<ObservableCollection<ListedItem>> SearchForUserQueryTex
options.SetPropertyPrefetch(Windows.Storage.FileProperties.PropertyPrefetchOptions.None, null);
options.SetThumbnailPrefetch(Windows.Storage.FileProperties.ThumbnailMode.ListView, 24, Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale);
var itemQueryResult = workingDir.CreateItemQueryWithOptions(options);
uint stepSize = maxItemCount == 10 ? (uint)maxItemCount : 500;
uint stepSize = Math.Min(500, (uint)maxItemCount);
IReadOnlyList<IStorageItem> items = await itemQueryResult.GetItemsAsync(0, stepSize);
var returnedItems = new ObservableCollection<ListedItem>();
var returnedItems = new List<ListedItem>();
uint index = 0;
while (items.Count > 0)
{
Expand Down Expand Up @@ -88,82 +187,10 @@ public static async Task<ObservableCollection<ListedItem>> SearchForUserQueryTex
}
}
}
if (maxItemCount != 10)
{
index += stepSize;
items = await itemQueryResult.GetItemsAsync(index, stepSize);
}
else
{
break;
}
index += (uint)items.Count;
stepSize = Math.Min(500, (uint)(maxItemCount - returnedItems.Count));
items = await itemQueryResult.GetItemsAsync(index, stepSize);
}

if (App.AppSettings.AreHiddenItemsVisible)
{
(IntPtr hFile, WIN32_FIND_DATA findData) = await Task.Run(() =>
{
FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
int additionalFlags = FIND_FIRST_EX_LARGE_FETCH;
IntPtr hFileTsk = FindFirstFileExFromApp(WorkingDirectory + "\\*.*", findInfoLevel, out WIN32_FIND_DATA findDataTsk, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero,
additionalFlags);
return (hFileTsk, findDataTsk);
}).WithTimeoutAsync(TimeSpan.FromSeconds(5));

if (hFile != IntPtr.Zero)
{
await Task.Run(() =>
{
var hasNextFile = false;
do
{
var itemPath = Path.Combine(WorkingDirectory, findData.cFileName);
if (((FileAttributes)findData.dwFileAttributes & FileAttributes.System) != FileAttributes.System || !App.AppSettings.AreSystemItemsHidden)
{
if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden)
{
if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) != FileAttributes.Directory)
{
returnedItems.Add(new ListedItem(null)
{
PrimaryItemAttribute = StorageItemTypes.File,
ItemName = findData.cFileName,
ItemPath = itemPath,
IsHiddenItem = true,
LoadFileIcon = false,
LoadUnknownTypeGlyph = true,
LoadFolderGlyph = false,
ItemPropertiesInitialized = true
});
}
else if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
{
if (findData.cFileName != "." && findData.cFileName != "..")
{
returnedItems.Add(new ListedItem(null)
{
PrimaryItemAttribute = StorageItemTypes.Folder,
ItemName = findData.cFileName,
ItemPath = itemPath,
IsHiddenItem = true,
LoadFileIcon = false,
LoadUnknownTypeGlyph = false,
LoadFolderGlyph = true,
ItemPropertiesInitialized = true
});
}
}
}
}

hasNextFile = FindNextFile(hFile, out findData);
} while (hasNextFile);

FindClose(hFile);
});
}
}

return returnedItems;
}
}
Expand Down
2 changes: 1 addition & 1 deletion Files/MultilingualResources/Files.hu-HU.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1933,4 +1933,4 @@
</group>
</body>
</file>
</xliff>
</xliff>
4 changes: 2 additions & 2 deletions Files/Views/ModernShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ private async void ModernShellPage_SearchTextChanged(AutoSuggestBox sender, Auto
{
if (!string.IsNullOrWhiteSpace(sender.Text))
{
sender.ItemsSource = await FolderSearch.SearchForUserQueryTextAsync(sender.Text, FilesystemViewModel.WorkingDirectory);
sender.ItemsSource = await FolderSearch.SearchForUserQueryTextAsync(sender.Text, FilesystemViewModel.WorkingDirectory, this);
}
else
{
Expand All @@ -183,7 +183,7 @@ private async void ModernShellPage_SearchQuerySubmitted(AutoSuggestBox sender, A
AssociatedTabInstance = this,
IsSearchResultPage = true,
SearchPathParam = FilesystemViewModel.WorkingDirectory,
SearchResults = await FolderSearch.SearchForUserQueryTextAsync(args.QueryText, FilesystemViewModel.WorkingDirectory, -1)
SearchResults = await FolderSearch.SearchForUserQueryTextAsync(args.QueryText, FilesystemViewModel.WorkingDirectory, this, -1)
});
App.InteractionViewModel.IsContentLoadingIndicatorVisible = false;
}
Expand Down