-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
Copy pathWindowsQuickAccessService.cs
116 lines (94 loc) · 3.89 KB
/
WindowsQuickAccessService.cs
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
// Copyright (c) Files Community
// Licensed under the MIT License.
using Files.App.Utils.Shell;
using Files.App.UserControls.Widgets;
using Files.App.Helpers;
namespace Files.App.Services
{
internal sealed class QuickAccessService : IQuickAccessService
{
// Quick access shell folder (::{679f85cb-0220-4080-b29b-5540cc05aab6}) contains recent files
// which are unnecessary for getting pinned folders, so we use frequent places shell folder instead.
private readonly static string guid = "::{3936e9e4-d92c-4eee-a85a-bc16d5ea0819}";
public async Task<IEnumerable<ShellFileItem>> GetPinnedFoldersAsync()
{
var result = (await Win32Helper.GetShellFolderAsync(guid, false, true, 0, int.MaxValue, "System.Home.IsPinned")).Enumerate
.Where(link => link.IsFolder);
return result;
}
public Task PinToSidebarAsync(string folderPath) => PinToSidebarAsync(new[] { folderPath });
public Task PinToSidebarAsync(string[] folderPaths) => PinToSidebarAsync(folderPaths, true);
private async Task PinToSidebarAsync(string[] folderPaths, bool doUpdateQuickAccessWidget)
{
foreach (string folderPath in folderPaths)
{
// make sure that the item has not yet been pinned
// the verb 'pintohome' is for both adding and removing
if (!IsItemPinned(folderPath))
await ContextMenu.InvokeVerb("pintohome", folderPath);
}
await App.QuickAccessManager.Model.LoadAsync();
if (doUpdateQuickAccessWidget)
App.QuickAccessManager.UpdateQuickAccessWidget?.Invoke(this, new ModifyQuickAccessEventArgs(folderPaths, true));
}
public Task UnpinFromSidebarAsync(string folderPath) => UnpinFromSidebarAsync(new[] { folderPath });
public Task UnpinFromSidebarAsync(string[] folderPaths) => UnpinFromSidebarAsync(folderPaths, true);
private async Task UnpinFromSidebarAsync(string[] folderPaths, bool doUpdateQuickAccessWidget)
{
Type? shellAppType = Type.GetTypeFromProgID("Shell.Application");
object? shell = Activator.CreateInstance(shellAppType);
dynamic? f2 = shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, [$"shell:{guid}"]);
if (folderPaths.Length == 0)
folderPaths = (await GetPinnedFoldersAsync())
.Where(link => (bool?)link.Properties["System.Home.IsPinned"] ?? false)
.Select(link => link.FilePath).ToArray();
foreach (dynamic? fi in f2.Items())
{
string pathStr = (string)fi.Path;
if (ShellStorageFolder.IsShellPath(pathStr))
{
var folder = await ShellStorageFolder.FromPathAsync(pathStr);
var path = folder?.Path;
if (path is not null &&
(folderPaths.Contains(path) ||
(path.StartsWith(@"\\SHELL\\") && folderPaths.Any(x => x.StartsWith(@"\\SHELL\\")))))
{
await Win32Helper.StartSTATask(async () =>
{
fi.InvokeVerb("unpinfromhome");
});
continue;
}
}
if (folderPaths.Contains(pathStr))
{
await Win32Helper.StartSTATask(async () =>
{
fi.InvokeVerb("unpinfromhome");
});
}
}
await App.QuickAccessManager.Model.LoadAsync();
if (doUpdateQuickAccessWidget)
App.QuickAccessManager.UpdateQuickAccessWidget?.Invoke(this, new ModifyQuickAccessEventArgs(folderPaths, false));
}
public bool IsItemPinned(string folderPath)
{
return App.QuickAccessManager.Model.PinnedFolders.Contains(folderPath);
}
public async Task SaveAsync(string[] items)
{
if (Equals(items, App.QuickAccessManager.Model.PinnedFolders.ToArray()))
return;
App.QuickAccessManager.PinnedItemsWatcher.EnableRaisingEvents = false;
// Unpin every item that is below this index and then pin them all in order
await UnpinFromSidebarAsync([], false);
await PinToSidebarAsync(items, false);
App.QuickAccessManager.PinnedItemsWatcher.EnableRaisingEvents = true;
App.QuickAccessManager.UpdateQuickAccessWidget?.Invoke(this, new ModifyQuickAccessEventArgs(items, true)
{
Reorder = true
});
}
}
}