Skip to content

Commit 03286c5

Browse files
Feature: Translate shell folders names & avoid possible bugs (#11890)
1 parent e04f087 commit 03286c5

File tree

14 files changed

+118
-61
lines changed

14 files changed

+118
-61
lines changed

src/Files.App/Constants.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ public static class AdaptiveLayout
1515
public const float ExtraSmallThreshold = 15.0f;
1616
}
1717

18-
public static class CommonPaths
19-
{
20-
public const string RecycleBinPath = @"Shell:RecycleBinFolder";
21-
22-
public const string NetworkFolderPath = @"Shell:NetworkPlacesFolder";
23-
24-
public const string MyComputerPath = @"Shell:MyComputerFolder";
25-
}
26-
2718
public static class KnownImageFormats
2819
{
2920
public const string BITMAP_IMAGE_FORMAT = "bitmapimage";

src/Files.App/DataModels/SidebarPinnedModel.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using CommunityToolkit.Mvvm.DependencyInjection;
22
using CommunityToolkit.WinUI;
33
using Files.App.DataModels.NavigationControlItems;
4+
using Files.App.Extensions;
45
using Files.App.Filesystem;
56
using Files.App.Helpers;
67
using Files.App.ServicesImplementation;
@@ -85,8 +86,15 @@ public async Task<LocationItem> CreateLocationItemFromPathAsync(string path)
8586
if (string.Equals(path, CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase))
8687
locationItem = LocationItem.Create<RecycleBinLocationItem>();
8788
else
89+
{
8890
locationItem = LocationItem.Create<LocationItem>();
8991

92+
if (path.Equals(CommonPaths.MyComputerPath, StringComparison.OrdinalIgnoreCase))
93+
locationItem.Text = "ThisPC".GetLocalizedResource();
94+
else if (path.Equals(CommonPaths.NetworkFolderPath, StringComparison.OrdinalIgnoreCase))
95+
locationItem.Text = "Network".GetLocalizedResource();
96+
}
97+
9098
locationItem.Path = path;
9199
locationItem.Section = SectionType.Favorites;
92100
locationItem.MenuOptions = new ContextMenuOptions
@@ -136,7 +144,7 @@ public async Task<LocationItem> CreateLocationItemFromPathAsync(string path)
136144
public async Task AddItemToSidebarAsync(string path)
137145
{
138146
var locationItem = await CreateLocationItemFromPathAsync(path);
139-
147+
140148
AddLocationItemToSidebar(locationItem);
141149
}
142150

src/Files.App/Filesystem/QuickAccessManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
using CommunityToolkit.Mvvm.DependencyInjection;
22
using CommunityToolkit.WinUI.Helpers;
33
using Files.App.DataModels;
4+
using Files.App.Helpers;
45
using Files.App.ServicesImplementation;
56
using Files.App.UserControls.Widgets;
67
using System;
78
using System.IO;
89
using System.Threading.Tasks;
9-
using static Files.App.Constants;
1010

1111
namespace Files.App.Filesystem
1212
{

src/Files.App/Filesystem/StorageFileHelpers/StorageFileExtensions.cs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -270,36 +270,39 @@ public async static Task<IList<StorageFolderWithPath>> GetFoldersWithPathAsync
270270

271271
private static PathBoxItem GetPathItem(string component, string path)
272272
{
273+
var title = string.Empty;
273274
if (component.StartsWith(CommonPaths.RecycleBinPath, StringComparison.Ordinal))
274275
{
275276
// Handle the recycle bin: use the localized folder name
276-
return new PathBoxItem()
277-
{
278-
Title = ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin"),
279-
Path = path,
280-
};
277+
title = "RecycleBin".GetLocalizedResource();
278+
}
279+
else if (component.StartsWith(CommonPaths.MyComputerPath, StringComparison.Ordinal))
280+
{
281+
title = "ThisPC".GetLocalizedResource();
282+
}
283+
else if (component.StartsWith(CommonPaths.NetworkFolderPath, StringComparison.Ordinal))
284+
{
285+
title = "SidebarNetworkDrives".GetLocalizedResource();
281286
}
282287
else if (component.Contains(':', StringComparison.Ordinal))
283288
{
284289
var drives = App.DrivesManager.Drives.Concat(App.NetworkDrivesManager.Drives).Concat(App.CloudDrivesManager.Drives);
285290
var drive = drives.FirstOrDefault(y => y.ItemType is NavigationControlItemType.Drive && y.Path.Contains(component, StringComparison.OrdinalIgnoreCase));
286-
return new PathBoxItem()
287-
{
288-
Title = drive is not null ? drive.Text : $@"Drive ({component})",
289-
Path = path,
290-
};
291+
title = drive is not null ? drive.Text : $@"Drive ({component})";
291292
}
292293
else
293294
{
294295
if (path.EndsWith('\\') || path.EndsWith('/'))
295296
path = path.Remove(path.Length - 1);
296297

297-
return new PathBoxItem
298-
{
299-
Title = component,
300-
Path = path
301-
};
298+
title = component;
302299
}
300+
301+
return new PathBoxItem()
302+
{
303+
Title = title,
304+
Path = path
305+
};
303306
}
304307

305308
private static string GetPathWithoutEnvironmentVariable(string path)
@@ -323,6 +326,9 @@ private static string ResolvePath(string path, bool isFtp)
323326
if (path.StartsWith("Home"))
324327
return "Home";
325328

329+
if (ShellStorageFolder.IsShellPath(path))
330+
return ShellHelpers.ResolveShellPath(path);
331+
326332
var pathBuilder = new StringBuilder(path);
327333
var lastPathIndex = path.Length - 1;
328334
var separatorChar = isFtp || path.Contains('/', StringComparison.Ordinal) ? '/' : '\\';
@@ -333,7 +339,7 @@ private static string ResolvePath(string path, bool isFtp)
333339
if (pathBuilder[i] is not '?' &&
334340
pathBuilder[i] != Path.DirectorySeparatorChar &&
335341
pathBuilder[i] != Path.AltDirectorySeparatorChar &&
336-
i != lastIndex)
342+
i != lastPathIndex)
337343
continue;
338344

339345
if (lastIndex == i)

src/Files.App/Helpers/CommonPaths.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ public static class CommonPaths
1414
public static readonly string LocalAppDataPath = UserDataPaths.GetDefault().LocalAppData;
1515

1616
// Currently is the command to open the folder from cmd ("cmd /c start Shell:RecycleBinFolder")
17-
public static readonly string RecycleBinPath = Constants.CommonPaths.RecycleBinPath;
17+
public const string RecycleBinPath = @"Shell:RecycleBinFolder";
1818

19-
public static readonly string NetworkFolderPath = Constants.CommonPaths.NetworkFolderPath;
19+
public const string NetworkFolderPath = @"Shell:NetworkPlacesFolder";
2020

21-
public static string MyComputerPath = Constants.CommonPaths.MyComputerPath;
21+
public const string MyComputerPath = @"Shell:MyComputerFolder";
2222

2323
public static readonly string TempPath = ApplicationData.Current.LocalSettings.Values.Get("TEMP", "");
2424

@@ -31,11 +31,11 @@ public static class CommonPaths
3131
public static Dictionary<string, string> ShellPlaces = new Dictionary<string, string>() {
3232
{ "::{645FF040-5081-101B-9F08-00AA002F954E}", RecycleBinPath },
3333
{ "::{5E5F29CE-E0A8-49D3-AF32-7A7BDC173478}", "Home" /*MyComputerPath*/ },
34-
{ "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", "Home" /*MyComputerPath*/ },
34+
{ "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", MyComputerPath },
3535
{ "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}", NetworkFolderPath },
3636
{ "::{208D2C60-3AEA-1069-A2D7-08002B30309D}", NetworkFolderPath },
3737
{ RecycleBinPath.ToUpperInvariant(), RecycleBinPath },
38-
{ MyComputerPath.ToUpperInvariant(), "Home" /*MyComputerPath*/ },
38+
{ MyComputerPath.ToUpperInvariant(), MyComputerPath },
3939
{ NetworkFolderPath.ToUpperInvariant(), NetworkFolderPath },
4040
};
4141
}

src/Files.App/Helpers/ShellHelpers.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using Files.App.Extensions;
2+
using Files.Shared;
3+
using System;
4+
using System.IO;
5+
6+
namespace Files.App.Helpers
7+
{
8+
public static class ShellHelpers
9+
{
10+
public static string ResolveShellPath(string shPath)
11+
{
12+
if (shPath.StartsWith(CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase))
13+
return CommonPaths.RecycleBinPath;
14+
15+
if (shPath.StartsWith(CommonPaths.MyComputerPath, StringComparison.OrdinalIgnoreCase))
16+
return CommonPaths.MyComputerPath;
17+
18+
if (shPath.StartsWith(CommonPaths.NetworkFolderPath, StringComparison.OrdinalIgnoreCase))
19+
return CommonPaths.NetworkFolderPath;
20+
21+
return shPath;
22+
}
23+
24+
public static string GetShellNameFromPath(string shPath)
25+
{
26+
return shPath switch
27+
{
28+
"Home" => "Home".GetLocalizedResource(),
29+
CommonPaths.RecycleBinPath => "RecycleBin".GetLocalizedResource(),
30+
CommonPaths.NetworkFolderPath => "SidebarNetworkDrives".GetLocalizedResource(),
31+
CommonPaths.MyComputerPath => "ThisPC".GetLocalizedResource(),
32+
_ => shPath
33+
};
34+
}
35+
36+
public static string GetLibraryFullPathFromShell(string shPath)
37+
{
38+
var partialPath = shPath.Substring(shPath.IndexOf('\\') + 1);
39+
return Path.Combine(ShellLibraryItem.LibrariesPath, partialPath);
40+
}
41+
}
42+
}

src/Files.App/ServicesImplementation/JumpListService.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Files.App.Filesystem;
1+
using Files.App.Extensions;
2+
using Files.App.Filesystem;
23
using Files.App.Helpers;
34
using Files.Shared.Extensions;
45
using Files.Shared.Services;
@@ -122,15 +123,17 @@ private void AddFolder(string path, string group, JumpList instance)
122123

123124
if (displayName is null)
124125
{
126+
var localSettings = ApplicationData.Current.LocalSettings;
125127
if (path.Equals(CommonPaths.DesktopPath, StringComparison.OrdinalIgnoreCase))
126128
displayName = "ms-resource:///Resources/Desktop";
127129
else if (path.Equals(CommonPaths.DownloadsPath, StringComparison.OrdinalIgnoreCase))
128130
displayName = "ms-resource:///Resources/Downloads";
129131
else if (path.Equals(CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase))
130-
{
131-
var localSettings = ApplicationData.Current.LocalSettings;
132-
displayName = localSettings.Values.Get("RecycleBin_Title", "Recycle Bin");
133-
}
132+
displayName = "RecycleBin".GetLocalizedResource();
133+
else if (path.Equals(CommonPaths.MyComputerPath, StringComparison.OrdinalIgnoreCase))
134+
displayName = "ThisPC".GetLocalizedResource();
135+
else if (path.Equals(CommonPaths.NetworkFolderPath, StringComparison.OrdinalIgnoreCase))
136+
displayName = "SidebarNetworkDrives".GetLocalizedResource();
134137
else if (App.LibraryManager.TryGetLibrary(path, out LibraryLocationItem library))
135138
{
136139
var libName = Path.GetFileNameWithoutExtension(library.Path);

src/Files.App/ServicesImplementation/QuickAccessService.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Files.App.Shell;
1+
using Files.App.Helpers;
2+
using Files.App.Shell;
23
using Files.App.UserControls.Widgets;
34
using Files.Shared;
45
using Files.Shared.Extensions;
@@ -53,7 +54,7 @@ public async Task UnpinFromSidebar(string[] folderPaths)
5354
foreach (dynamic? fi in f2.Items())
5455
{
5556
if (folderPaths.Contains((string)fi.Path)
56-
|| (string.Equals(fi.Path, "::{645FF040-5081-101B-9F08-00AA002F954E}") && folderPaths.Contains(Constants.CommonPaths.RecycleBinPath)))
57+
|| (string.Equals(fi.Path, "::{645FF040-5081-101B-9F08-00AA002F954E}") && folderPaths.Contains(CommonPaths.RecycleBinPath)))
5758
{
5859
await SafetyExtensions.IgnoreExceptions(async () =>
5960
{

src/Files.App/Shell/RecycleBinManager.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ private RecycleBinManager()
3131
private void Initialize()
3232
{
3333
// Create shell COM object and get recycle bin folder
34-
using var recycler = new ShellFolder(Shell32.KNOWNFOLDERID.FOLDERID_RecycleBinFolder);
35-
ApplicationData.Current.LocalSettings.Values["RecycleBin_Title"] = recycler.Name;
36-
3734
StartRecycleBinWatcher();
3835
}
3936

src/Files.App/Shell/ShellFolderExtensions.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Files.Shared;
1+
using Files.App.Helpers;
2+
using Files.Shared;
23
using Files.Shared.Extensions;
34
using System;
45
using System.IO;
@@ -57,9 +58,14 @@ public static ShellFileItem GetShellFileItem(ShellItem folderItem)
5758
{
5859
parsingPath = parsingPath switch
5960
{
60-
"::{645FF040-5081-101B-9F08-00AA002F954E}" => "Shell:RecycleBinFolder",
61-
"::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}" => "Shell:NetworkPlacesFolder",
62-
"::{208D2C60-3AEA-1069-A2D7-08002B30309D}" => "Shell:NetworkPlacesFolder",
61+
"::{645FF040-5081-101B-9F08-00AA002F954E}" => CommonPaths.RecycleBinPath,
62+
"::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}" => CommonPaths.NetworkFolderPath,
63+
"::{208D2C60-3AEA-1069-A2D7-08002B30309D}" => CommonPaths.NetworkFolderPath,
64+
"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" => CommonPaths.MyComputerPath,
65+
"::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\\Documents.library-ms" => ShellHelpers.GetLibraryFullPathFromShell(parsingPath),
66+
"::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\\Pictures.library-ms" => ShellHelpers.GetLibraryFullPathFromShell(parsingPath),
67+
"::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\\Music.library-ms" => ShellHelpers.GetLibraryFullPathFromShell(parsingPath),
68+
"::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\\Videos.library-ms" => ShellHelpers.GetLibraryFullPathFromShell(parsingPath),
6369
// Use PIDL as path
6470
// Replace "/" with "_" to avoid confusion with path separator
6571
_ => $@"\\SHELL\{string.Join("\\", folderItem.PIDL.Select(x => x.GetBytes()).Select(x => Convert.ToBase64String(x, 0, x.Length).Replace("/", "_")))}"

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,6 +2857,12 @@
28572857
<data name="ShowFileExtensionWarning" xml:space="preserve">
28582858
<value>Show warning when changing file extensions</value>
28592859
</data>
2860+
<data name="ThisPC" xml:space="preserve">
2861+
<value>This PC</value>
2862+
</data>
2863+
<data name="RecycleBin" xml:space="preserve">
2864+
<value>Recycle Bin</value>
2865+
</data>
28602866
<data name="Untagged" xml:space="preserve">
28612867
<value>Untagged</value>
28622868
</data>

src/Files.App/ViewModels/ItemViewModel.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ private async void RecycleBinItemCreated(object sender, FileSystemEventArgs e)
427427
return;
428428

429429
using var folderItem = SafetyExtensions.IgnoreExceptions(() => new ShellItem(e.FullPath));
430-
if (folderItem is null)
430+
if (folderItem is null)
431431
return;
432432

433433
var shellFileItem = ShellFolderExtensions.GetShellFileItem(folderItem);
@@ -1389,8 +1389,11 @@ public async Task EnumerateItemsFromSpecialFolderAsync(string path)
13891389
{
13901390
PrimaryItemAttribute = StorageItemTypes.Folder,
13911391
ItemPropertiesInitialized = true,
1392-
ItemNameRaw = path.StartsWith(CommonPaths.RecycleBinPath, StringComparison.Ordinal) ? ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin") :
1393-
path.StartsWith(CommonPaths.NetworkFolderPath, StringComparison.Ordinal) ? "Network".GetLocalizedResource() : isFtp ? "FTP" : "Unknown",
1392+
ItemNameRaw =
1393+
path.StartsWith(CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase) ? "RecycleBin".GetLocalizedResource() :
1394+
path.StartsWith(CommonPaths.NetworkFolderPath, StringComparison.OrdinalIgnoreCase) ? "Network".GetLocalizedResource() :
1395+
path.StartsWith(CommonPaths.MyComputerPath, StringComparison.OrdinalIgnoreCase) ? "ThisPC".GetLocalizedResource() :
1396+
isFtp ? "FTP" : "Unknown",
13941397
ItemDateModifiedReal = DateTimeOffset.Now, // Fake for now
13951398
ItemDateCreatedReal = DateTimeOffset.Now, // Fake for now
13961399
ItemType = "Folder".GetLocalizedResource(),

src/Files.App/ViewModels/MainPageViewModel.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,11 @@ public static async Task UpdateTabInfo(TabItem tabItem, object navigationArg)
212212
}
213213
else if (currentPath.Equals(CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase))
214214
{
215-
var localSettings = ApplicationData.Current.LocalSettings;
216-
tabLocationHeader = localSettings.Values.Get("RecycleBin_Title", "Recycle Bin");
215+
tabLocationHeader = "RecycleBin".GetLocalizedResource();
216+
}
217+
else if (currentPath.Equals(CommonPaths.MyComputerPath, StringComparison.OrdinalIgnoreCase))
218+
{
219+
tabLocationHeader = "ThisPC".GetLocalizedResource();
217220
}
218221
else if (currentPath.Equals(CommonPaths.NetworkFolderPath, StringComparison.OrdinalIgnoreCase))
219222
{

src/Files.App/ViewModels/Settings/PreferencesViewModel.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using Files.App.Helpers;
66
using Files.Backend.Services.Settings;
77
using Files.Shared.Enums;
8-
using Files.Shared.Extensions;
98
using Files.Shared.Services.DateTimeFormatter;
109
using System;
1110
using System.Collections.Generic;
@@ -600,15 +599,7 @@ public class PageOnStartupViewModel
600599
{
601600
public string Text
602601
{
603-
get
604-
{
605-
if (Path == "Home")
606-
return "Home".GetLocalizedResource();
607-
608-
return (Path == CommonPaths.RecycleBinPath)
609-
? ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin")
610-
: Path;
611-
}
602+
get => ShellHelpers.GetShellNameFromPath(Path);
612603
}
613604

614605
public string Path { get; }

0 commit comments

Comments
 (0)