Skip to content

Commit 2754111

Browse files
committed
Init
1 parent e88e313 commit 2754111

18 files changed

+541
-544
lines changed

src/Files.App.CsWin32/NativeMethods.txt

+15
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,18 @@ PSGetPropertyKeyFromName
135135
ShellExecuteEx
136136
CoTaskMemFree
137137
QueryDosDevice
138+
SHAddToRecentDocs
139+
SHARD
140+
BHID_EnumItems
141+
FOLDERID_RecycleBinFolder
142+
CoTaskMemFree
143+
SHGetIDListFromObject
144+
SHCreateItemFromIDList
145+
BHID_SFUIObject
146+
IContextMenu
147+
CMF_NORMAL
148+
CMF_OPTIMIZEFORINVOKE
149+
IApplicationDestinations
150+
ApplicationDestinations
151+
IApplicationDocumentLists
152+
ApplicationDocumentLists
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) 2024 Files Community
22
// Licensed under the MIT License. See the LICENSE.
33

4-
using System;
54
using System.Runtime.InteropServices;
65
using Windows.Win32.Foundation;
76

@@ -18,17 +17,4 @@ namespace UI.WindowsAndMessaging
1817
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
1918
public delegate LRESULT WNDPROC(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
2019
}
21-
22-
namespace UI.Shell
23-
{
24-
public static partial class FOLDERID
25-
{
26-
public readonly static Guid FOLDERID_RecycleBinFolder = new(0xB7534046, 0x3ECB, 0x4C18, 0xBE, 0x4E, 0x64, 0xCD, 0x4C, 0xB7, 0xD6, 0xAC);
27-
}
28-
29-
public static partial class BHID
30-
{
31-
public readonly static Guid BHID_EnumItems = new(0x94f60519, 0x2850, 0x4924, 0xaa, 0x5a, 0xd1, 0x5e, 0x84, 0x86, 0x80, 0x39);
32-
}
33-
}
3420
}

src/Files.App/App.xaml.cs

-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public static CommandBarFlyout? LastOpenedFlyout
3939
public static QuickAccessManager QuickAccessManager { get; private set; } = null!;
4040
public static StorageHistoryWrapper HistoryWrapper { get; private set; } = null!;
4141
public static FileTagsManager FileTagsManager { get; private set; } = null!;
42-
public static RecentItems RecentItemsManager { get; private set; } = null!;
4342
public static LibraryManager LibraryManager { get; private set; } = null!;
4443
public static AppModel AppModel { get; private set; } = null!;
4544
public static ILogger Logger { get; private set; } = null!;
@@ -114,7 +113,6 @@ async Task ActivateAsync()
114113
QuickAccessManager = Ioc.Default.GetRequiredService<QuickAccessManager>();
115114
HistoryWrapper = Ioc.Default.GetRequiredService<StorageHistoryWrapper>();
116115
FileTagsManager = Ioc.Default.GetRequiredService<FileTagsManager>();
117-
RecentItemsManager = Ioc.Default.GetRequiredService<RecentItems>();
118116
LibraryManager = Ioc.Default.GetRequiredService<LibraryManager>();
119117
Logger = Ioc.Default.GetRequiredService<ILogger<App>>();
120118
AppModel = Ioc.Default.GetRequiredService<AppModel>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
using System.Collections.Specialized;
5+
6+
namespace Files.App.Data.Contracts
7+
{
8+
/// <summary>
9+
/// Provides manager of recent files and folders of File Explorer on Windows.
10+
/// </summary>
11+
public interface IWindowsRecentItemsService
12+
{
13+
/// <summary>
14+
/// Gets recent files of File Explorer.
15+
/// </summary>
16+
IReadOnlyList<RecentItem> RecentFiles { get; }
17+
18+
/// <summary>
19+
/// Gets recent folders of File Explorer.
20+
/// </summary>
21+
IReadOnlyList<RecentItem> RecentFolders { get; }
22+
23+
/// <summary>
24+
/// Gets invoked when recent files of File Explorer have changed.
25+
/// </summary>
26+
event EventHandler<NotifyCollectionChangedEventArgs>? RecentFilesChanged;
27+
28+
/// <summary>
29+
/// Gets invoked when recent folders of File Explorer have changed.
30+
/// </summary>
31+
event EventHandler<NotifyCollectionChangedEventArgs>? RecentFoldersChanged;
32+
33+
/// <summary>
34+
/// Updates recent files of File Explorer.
35+
/// </summary>
36+
Task<bool> UpdateRecentFilesAsync();
37+
38+
/// <summary>
39+
/// Updates recent folders of File Explorer.
40+
/// </summary>
41+
Task<bool> UpdateRecentFoldersAsync();
42+
43+
/// <summary>
44+
/// Adds a recent file for File Explorer.
45+
/// </summary>
46+
bool Add(string path);
47+
48+
/// <summary>
49+
/// Removes a recent folder for File Explorer.
50+
/// </summary>
51+
bool Remove(RecentItem item);
52+
53+
/// <summary>
54+
/// Clears recent files and folders of File Explorer.
55+
/// </summary>
56+
bool Clear();
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
using Microsoft.UI.Xaml.Media.Imaging;
5+
using Windows.Win32;
6+
using Windows.Win32.UI.Shell;
7+
8+
namespace Files.App.Data.Items
9+
{
10+
/// <summary>
11+
/// Represents an item for recent item of File Explorer on Windows.
12+
/// </summary>
13+
public sealed class RecentItem : WidgetCardItem, IEquatable<RecentItem>, IDisposable
14+
{
15+
private BitmapImage? _Icon;
16+
/// <summary>
17+
/// Gets or sets thumbnail icon of the recent item.
18+
/// </summary>
19+
public BitmapImage? Icon
20+
{
21+
get => _Icon;
22+
set => SetProperty(ref _Icon, value);
23+
}
24+
25+
/// <summary>
26+
/// Gets or sets name of the recent item.
27+
/// </summary>
28+
public required string Name { get; set; }
29+
30+
/// <summary>
31+
/// Gets or sets target path of the recent item.
32+
/// </summary>
33+
public required DateTime LastModified { get; set; }
34+
35+
/// <summary>
36+
/// Gets or initializes PIDL of the recent item.
37+
/// </summary>
38+
/// <remarks>
39+
/// This has to be removed in the future.
40+
/// </remarks>
41+
public unsafe required ComPtr<IShellItem> ShellItem { get; init; }
42+
43+
/// <summary>
44+
/// Loads thumbnail icon of the recent item.
45+
/// </summary>
46+
/// <returns></returns>
47+
public async Task LoadRecentItemIconAsync()
48+
{
49+
var result = await FileThumbnailHelper.GetIconAsync(Path, Constants.ShellIconSizes.Small, false, IconOptions.UseCurrentScale);
50+
51+
var bitmapImage = await result.ToBitmapAsync();
52+
if (bitmapImage is not null)
53+
Icon = bitmapImage;
54+
}
55+
56+
public override int GetHashCode() => (Path, Name).GetHashCode();
57+
public override bool Equals(object? other) => other is RecentItem item && Equals(item);
58+
public bool Equals(RecentItem? other) => other is not null && other.Name == Name && other.Path == Path;
59+
60+
public unsafe void Dispose()
61+
{
62+
ShellItem.Dispose();
63+
}
64+
}
65+
}

src/Files.App/GlobalUsings.cs

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
global using global::Files.App.Utils.FileTags;
3030
global using global::Files.App.Utils.Git;
3131
global using global::Files.App.Utils.Library;
32-
global using global::Files.App.Utils.RecentItem;
3332
global using global::Files.App.Utils.Serialization;
3433
global using global::Files.App.Utils.Shell;
3534
global using global::Files.App.Utils.StatusCenter;

src/Files.App/Helpers/Application/AppLifecycleHelper.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ public static IHost ConfigureHost()
169169
.AddSingleton<ITagsContext, TagsContext>()
170170
.AddSingleton<ISidebarContext, SidebarContext>()
171171
// Services
172+
.AddSingleton<IWindowsRecentItemsService, WindowsRecentItemsService>()
172173
.AddSingleton<IWindowsIniService, WindowsIniService>()
173174
.AddSingleton<IWindowsWallpaperService, WindowsWallpaperService>()
174175
.AddSingleton<IWindowsSecurityService, WindowsSecurityService>()
@@ -224,7 +225,6 @@ public static IHost ConfigureHost()
224225
.AddSingleton<QuickAccessManager>()
225226
.AddSingleton<StorageHistoryWrapper>()
226227
.AddSingleton<FileTagsManager>()
227-
.AddSingleton<RecentItems>()
228228
.AddSingleton<LibraryManager>()
229229
.AddSingleton<AppModel>()
230230
).Build();

src/Files.App/Helpers/Navigation/NavigationHelpers.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace Files.App.Helpers
1515
{
1616
public static class NavigationHelpers
1717
{
18+
private static readonly IWindowsRecentItemsService WindowsRecentItemsService = Ioc.Default.GetRequiredService<IWindowsRecentItemsService>();
1819
private static MainPageViewModel MainPageViewModel { get; } = Ioc.Default.GetRequiredService<MainPageViewModel>();
1920
private static DrivesViewModel DrivesViewModel { get; } = Ioc.Default.GetRequiredService<DrivesViewModel>();
2021
private static INetworkService NetworkService { get; } = Ioc.Default.GetRequiredService<INetworkService>();
@@ -527,7 +528,7 @@ private static async Task<FilesystemResult> OpenDirectory(string path, IShellPag
527528
{
528529
// Add location to Recent Items List
529530
if (childFolder.Item is SystemStorageFolder)
530-
App.RecentItemsManager.AddToRecentItems(childFolder.Path);
531+
WindowsRecentItemsService.Add(childFolder.Path);
531532
});
532533
if (!opened)
533534
opened = (FilesystemResult)FolderHelpers.CheckFolderAccessWithWin32(path);
@@ -559,7 +560,7 @@ private static async Task<FilesystemResult> OpenFile(string path, IShellPage ass
559560
StorageFileWithPath childFile = await associatedInstance.ShellViewModel.GetFileWithPathFromPathAsync(shortcutInfo.TargetPath);
560561
// Add location to Recent Items List
561562
if (childFile?.Item is SystemStorageFile)
562-
App.RecentItemsManager.AddToRecentItems(childFile.Path);
563+
WindowsRecentItemsService.Add(childFile.Path);
563564
}
564565
await Win32Helper.InvokeWin32ComponentAsync(shortcutInfo.TargetPath, associatedInstance, $"{args} {shortcutInfo.Arguments}", shortcutInfo.RunAsAdmin, shortcutInfo.WorkingDirectory);
565566
}
@@ -576,7 +577,7 @@ private static async Task<FilesystemResult> OpenFile(string path, IShellPage ass
576577
{
577578
// Add location to Recent Items List
578579
if (childFile.Item is SystemStorageFile)
579-
App.RecentItemsManager.AddToRecentItems(childFile.Path);
580+
WindowsRecentItemsService.Add(childFile.Path);
580581

581582
if (openViaApplicationPicker)
582583
{

src/Files.App/Helpers/UI/UIFilesystemHelpers.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,10 @@ public static async Task CreateFileFromDialogResultTypeAsync(AddItemDialogItemTy
136136

137137
// Add newly created item to recent files list
138138
if (created.Status == ReturnResult.Success && created.Item?.Path is not null)
139-
App.RecentItemsManager.AddToRecentItems(created.Item.Path);
139+
{
140+
IWindowsRecentItemsService windowsRecentItemsService = Ioc.Default.GetRequiredService<IWindowsRecentItemsService>();
141+
windowsRecentItemsService.Add(created.Item.Path);
142+
}
140143
else if (created.Status == ReturnResult.AccessUnauthorized)
141144
{
142145
await DialogDisplayHelper.ShowDialogAsync

src/Files.App/Services/Storage/StorageTrashBinService.cs

+16-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,22 @@ public async Task<bool> RestoreAllTrashesAsync()
8585
{
8686
return await Win32Helper.StartSTATask(() =>
8787
{
88-
try
88+
// Get IShellItem for Recycle Bin
89+
var recycleBinFolderId = PInvoke.FOLDERID_RecycleBinFolder;
90+
var shellItemGuid = typeof(IShellItem).GUID;
91+
PInvoke.SHGetKnownFolderItem(&recycleBinFolderId, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HANDLE.Null, &shellItemGuid, (void**)&recycleBinFolderShellItem);
92+
93+
// Get IEnumShellItems for Recycle Bin
94+
Guid enumShellItemGuid = typeof(IEnumShellItems).GUID;
95+
var enumItemsBHID = PInvoke.BHID_EnumItems;
96+
recycleBinFolderShellItem->BindToHandler(null, &enumItemsBHID, &enumShellItemGuid, (void**)&enumShellItems);
97+
98+
// Initialize how to perform the operation
99+
PInvoke.CoCreateInstance(typeof(FileOperation).GUID, null, CLSCTX.CLSCTX_LOCAL_SERVER, out pFileOperation);
100+
pFileOperation->SetOperationFlags(FILEOPERATION_FLAGS.FOF_NO_UI);
101+
pFileOperation->SetOwnerWindow(new(MainWindow.Instance.WindowHandle));
102+
103+
while (enumShellItems->Next(1, &pShellItem) == HRESULT.S_OK)
89104
{
90105
RestoreAllTrashesInternal();
91106

0 commit comments

Comments
 (0)