Skip to content

Commit 2b5815c

Browse files
authored
Merge branch 'main' into dev/lubl/trashhandler
2 parents 1fb1332 + ed9f1b3 commit 2b5815c

File tree

5 files changed

+168
-138
lines changed

5 files changed

+168
-138
lines changed

src/Files.App/UserControls/Widgets/DrivesWidget.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public sealed partial class DrivesWidget : UserControl, IWidgetItemModel, INotif
8181

8282
public event PropertyChangedEventHandler PropertyChanged;
8383

84-
public static ObservableCollection<DriveCardItem> ItemsAdded = new ObservableCollection<DriveCardItem>();
84+
public static ObservableCollection<DriveCardItem> ItemsAdded = new();
8585

8686
private IShellPage associatedInstance;
8787

src/Files.App/UserControls/Widgets/FolderWidget.xaml.cs

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
using Files.App.Filesystem;
2-
using Files.App.Helpers;
3-
using Files.Backend.Services.Settings;
4-
using Files.App.ViewModels.Widgets;
5-
using Files.App.Extensions;
61
using CommunityToolkit.Mvvm.ComponentModel;
72
using CommunityToolkit.Mvvm.DependencyInjection;
83
using CommunityToolkit.Mvvm.Input;
94
using CommunityToolkit.WinUI;
5+
using Files.App.Extensions;
6+
using Files.App.DataModels.NavigationControlItems;
7+
using Files.App.Filesystem;
8+
using Files.App.Helpers;
9+
using Files.App.Helpers.XamlHelpers;
10+
using Files.App.ViewModels.Widgets;
11+
using Files.Backend.Services.Settings;
12+
using Microsoft.UI.Xaml;
13+
using Microsoft.UI.Xaml.Controls;
14+
using Microsoft.UI.Xaml.Controls.Primitives;
15+
using Microsoft.UI.Xaml.Input;
16+
using Microsoft.UI.Xaml.Media.Imaging;
1017
using System;
18+
using System.Collections.ObjectModel;
1119
using System.ComponentModel;
1220
using System.Linq;
1321
using System.Runtime.CompilerServices;
@@ -16,13 +24,6 @@
1624
using Windows.Storage;
1725
using Windows.System;
1826
using Windows.UI.Core;
19-
using Microsoft.UI.Xaml;
20-
using Microsoft.UI.Xaml.Controls;
21-
using Microsoft.UI.Xaml.Input;
22-
using Microsoft.UI.Xaml.Media.Imaging;
23-
using Files.App.DataModels.NavigationControlItems;
24-
using Files.App.Helpers.XamlHelpers;
25-
using Microsoft.UI.Xaml.Controls.Primitives;
2627

2728
namespace Files.App.UserControls.Widgets
2829
{
@@ -75,10 +76,10 @@ public async Task LoadCardThumbnailAsync()
7576
if (thumbnailData == null || thumbnailData.Length == 0)
7677
{
7778
thumbnailData = await FileThumbnailHelper.LoadIconFromPathAsync(Path, Convert.ToUInt32(Constants.Widgets.WidgetIconSize), Windows.Storage.FileProperties.ThumbnailMode.SingleItem);
78-
if (thumbnailData != null && thumbnailData.Length > 0)
79-
{
80-
Thumbnail = await App.Window.DispatcherQueue.EnqueueAsync(() => thumbnailData.ToBitmapAsync(Constants.Widgets.WidgetIconSize));
81-
}
79+
}
80+
if (thumbnailData != null && thumbnailData.Length > 0)
81+
{
82+
Thumbnail = await App.Window.DispatcherQueue.EnqueueAsync(() => thumbnailData.ToBitmapAsync(Constants.Widgets.WidgetIconSize));
8283
}
8384
}
8485
}
@@ -87,7 +88,8 @@ public sealed partial class FolderWidget : UserControl, IWidgetItemModel, INotif
8788
{
8889
private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetRequiredService<IUserSettingsService>();
8990

90-
public BulkConcurrentObservableCollection<FolderCardItem> ItemsAdded = new BulkConcurrentObservableCollection<FolderCardItem>();
91+
public ObservableCollection<FolderCardItem> ItemsAdded = new();
92+
9193
private bool showMultiPaneControls;
9294

9395
public FolderWidget()
@@ -152,7 +154,6 @@ private async void FolderWidget_Loaded(object sender, RoutedEventArgs e)
152154
{
153155
Loaded -= FolderWidget_Loaded;
154156

155-
ItemsAdded.BeginBulkOperation();
156157
ItemsAdded.Add(new FolderCardItem("Desktop".GetLocalizedResource())
157158
{
158159
Path = UserDataPaths.GetDefault().Desktop,
@@ -184,12 +185,8 @@ private async void FolderWidget_Loaded(object sender, RoutedEventArgs e)
184185
SelectCommand = LibraryCardCommand
185186
});
186187

187-
foreach (var cardItem in ItemsAdded.ToList()) // ToList() is necessary
188-
{
189-
await cardItem.LoadCardThumbnailAsync();
190-
}
191-
192-
ItemsAdded.EndBulkOperation();
188+
var cardLoadTasks = ItemsAdded.Select(cardItem => cardItem.LoadCardThumbnailAsync());
189+
await Task.WhenAll(cardLoadTasks);
193190
}
194191

195192
private void FolderWidget_Unloaded(object sender, RoutedEventArgs e)

src/Files.App/ViewModels/Pages/YourHomeViewModel.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1+
using CommunityToolkit.Mvvm.ComponentModel;
2+
using CommunityToolkit.Mvvm.Input;
13
using Files.App.EventArguments.Bundles;
24
using Files.App.Helpers;
35
using Files.App.ViewModels.Widgets;
46
using Files.App.ViewModels.Widgets.Bundles;
5-
using CommunityToolkit.Mvvm.ComponentModel;
6-
using CommunityToolkit.Mvvm.Input;
7-
using System;
8-
using System.Windows.Input;
7+
using Files.Shared.Extensions;
98
using Microsoft.UI.Xaml;
10-
using System.Threading.Tasks;
9+
using System;
1110
using System.Collections.Generic;
12-
using Files.Shared.Extensions;
1311
using System.Text.Json;
12+
using System.Threading.Tasks;
13+
using System.Windows.Input;
1414

1515
namespace Files.App.ViewModels.Pages
1616
{

src/Files.App/Views/Pages/PropertiesGeneral.xaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
<TextBox
7979
x:Name="ItemFileName"
8080
x:Load="{x:Bind ViewModel.ItemNameVisibility, Mode=OneWay}"
81+
GettingFocus="ItemFileName_GettingFocus"
82+
LosingFocus="ItemFileName_LosingFocus"
8183
PlaceholderText="{helpers:ResourceString Name=PropertiesItemFileName/PlaceholderText}"
8284
Text="{x:Bind ViewModel.ItemName, Mode=TwoWay}" />
8385
<TextBlock
@@ -308,9 +310,9 @@
308310
Height="60"
309311
HorizontalAlignment="Left"
310312
x:Load="{x:Bind ViewModel.DriveCapacityVisibility, Mode=OneWay}"
313+
Background="{ThemeResource ProgressRingBackgroundThemeBrush}"
311314
IsIndeterminate="False"
312-
Value="{x:Bind ViewModel.DrivePercentageValue, Mode=OneWay}"
313-
Background="{ThemeResource ProgressRingBackgroundThemeBrush}">
315+
Value="{x:Bind ViewModel.DrivePercentageValue, Mode=OneWay}">
314316

315317
<ProgressRing.Template>
316318
<ControlTemplate TargetType="ProgressRing">
Lines changed: 136 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,144 @@
1-
using Files.Shared;
1+
using CommunityToolkit.WinUI;
2+
using Files.App.DataModels.NavigationControlItems;
23
using Files.App.Filesystem;
34
using Files.App.Helpers;
4-
using Files.Shared.Enums;
5+
using Files.App.Shell;
56
using Files.App.ViewModels.Properties;
6-
using CommunityToolkit.WinUI;
7+
using Files.Shared;
8+
using Files.Shared.Enums;
9+
using Microsoft.UI.Xaml;
10+
using Microsoft.UI.Xaml.Input;
11+
using System.Collections.Generic;
712
using System.IO;
13+
using System.Text.RegularExpressions;
814
using System.Threading.Tasks;
9-
using Windows.Foundation.Collections;
10-
using Files.App.Shell;
15+
using Windows.Storage;
1116

1217
namespace Files.App.Views
1318
{
14-
public sealed partial class PropertiesGeneral : PropertiesTab
15-
{
16-
public PropertiesGeneral()
17-
{
18-
this.InitializeComponent();
19-
}
20-
21-
public override async Task<bool> SaveChangesAsync(ListedItem item)
22-
{
23-
if (BaseProperties is DriveProperties driveProps)
24-
{
25-
var drive = driveProps.Drive;
26-
ViewModel.ItemName = ItemFileName.Text; // Make sure Name is updated
27-
if (!string.IsNullOrWhiteSpace(ViewModel.ItemName) && ViewModel.OriginalItemName != ViewModel.ItemName)
28-
{
29-
var remDrive = new System.Text.RegularExpressions.Regex(@"\s*\(\w:\)$");
30-
ViewModel.ItemName = remDrive.Replace(ViewModel.ItemName, ""); // Remove "(C:)" from the new label
31-
if (AppInstance.FilesystemViewModel != null)
32-
{
33-
Win32API.SetVolumeLabel(drive.Path, ViewModel.ItemName);
34-
_ = App.Window.DispatcherQueue.EnqueueAsync(async () =>
35-
{
36-
await drive.UpdateLabelAsync();
37-
await AppInstance.FilesystemViewModel?.SetWorkingDirectoryAsync(drive.Path);
38-
});
39-
return true;
40-
}
41-
}
42-
}
43-
else if (BaseProperties is LibraryProperties libProps)
44-
{
45-
var library = libProps.Library;
46-
ViewModel.ItemName = ItemFileName.Text; // Make sure Name is updated
47-
var newName = ViewModel.ItemName;
48-
if (!string.IsNullOrWhiteSpace(newName) && ViewModel.OriginalItemName != newName)
49-
{
50-
if (AppInstance.FilesystemViewModel != null && App.LibraryManager.CanCreateLibrary(newName).result)
51-
{
52-
var libraryPath = library.ItemPath;
53-
var renamed = await AppInstance.FilesystemHelpers.RenameAsync(new StorageFileWithPath(null, libraryPath), $"{newName}{ShellLibraryItem.EXTENSION}", Windows.Storage.NameCollisionOption.FailIfExists, false);
54-
if (renamed == ReturnResult.Success)
55-
{
56-
var newPath = Path.Combine(Path.GetDirectoryName(libraryPath), $"{newName}{ShellLibraryItem.EXTENSION}");
57-
_ = App.Window.DispatcherQueue.EnqueueAsync(async () =>
58-
{
59-
await AppInstance.FilesystemViewModel?.SetWorkingDirectoryAsync(newPath);
60-
});
61-
return true;
62-
}
63-
}
64-
}
65-
}
66-
else if (BaseProperties is CombinedProperties combinedProps)
67-
{
68-
// Handle the visibility attribute for multiple files
69-
if (AppInstance?.SlimContentPage?.ItemManipulationModel != null) // null on homepage
70-
{
71-
foreach (var fileOrFolder in combinedProps.List)
72-
{
73-
await App.Window.DispatcherQueue.EnqueueAsync(() => UIFilesystemHelpers.SetHiddenAttributeItem(fileOrFolder, ViewModel.IsHidden, AppInstance.SlimContentPage.ItemManipulationModel));
74-
}
75-
}
76-
return true;
77-
}
78-
else
79-
{
80-
// Handle the visibility attribute for a single file
81-
if (AppInstance?.SlimContentPage?.ItemManipulationModel != null) // null on homepage
82-
{
83-
await App.Window.DispatcherQueue.EnqueueAsync(() => UIFilesystemHelpers.SetHiddenAttributeItem(item, ViewModel.IsHidden, AppInstance.SlimContentPage.ItemManipulationModel));
84-
}
85-
86-
ViewModel.ItemName = ItemFileName.Text; // Make sure Name is updated
87-
if (!string.IsNullOrWhiteSpace(ViewModel.ItemName) && ViewModel.OriginalItemName != ViewModel.ItemName)
88-
{
89-
return await App.Window.DispatcherQueue.EnqueueAsync(() => UIFilesystemHelpers.RenameFileItemAsync(item,
90-
ViewModel.ItemName,
91-
AppInstance));
92-
}
93-
return true;
94-
}
95-
96-
return false;
97-
}
98-
99-
public override void Dispose()
100-
{
101-
}
102-
103-
private void DiskCleanupButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
104-
{
105-
if (BaseProperties is DriveProperties driveProps)
106-
{
107-
var drive = driveProps.Drive;
108-
109-
StorageSenseHelper.OpenStorageSense(drive.Path);
110-
}
111-
}
112-
}
113-
}
19+
public sealed partial class PropertiesGeneral : PropertiesTab
20+
{
21+
private readonly Regex letterRegex = new(@"\s*\(\w:\)$");
22+
23+
public PropertiesGeneral() => InitializeComponent();
24+
25+
public override async Task<bool> SaveChangesAsync(ListedItem item)
26+
{
27+
ViewModel.ItemName = ItemFileName.Text; // Make sure Name is updated
28+
29+
string newName = ViewModel.ItemName;
30+
string oldName = ViewModel.OriginalItemName;
31+
bool hasNewName = !string.IsNullOrWhiteSpace(newName) && newName != oldName;
32+
33+
return BaseProperties switch
34+
{
35+
DriveProperties properties => SaveDrive(properties.Drive),
36+
LibraryProperties properties => await SaveLibraryAsync(properties.Library),
37+
CombinedProperties properties => await SaveCombinedAsync(properties.List),
38+
_ => await SaveBaseAsync(),
39+
};
40+
41+
bool SaveDrive(DriveItem drive)
42+
{
43+
var fsVM = AppInstance.FilesystemViewModel;
44+
if (!hasNewName || fsVM is null)
45+
return false;
46+
47+
newName = letterRegex.Replace(newName, string.Empty); // Remove "(C:)" from the new label
48+
49+
Win32API.SetVolumeLabel(drive.Path, newName);
50+
_ = App.Window.DispatcherQueue.EnqueueAsync(async () =>
51+
{
52+
await drive.UpdateLabelAsync();
53+
await fsVM.SetWorkingDirectoryAsync(drive.Path);
54+
});
55+
return true;
56+
}
57+
58+
async Task<bool> SaveLibraryAsync(LibraryItem library)
59+
{
60+
var fsVM = AppInstance.FilesystemViewModel;
61+
if (!hasNewName || fsVM is null || !App.LibraryManager.CanCreateLibrary(newName).result)
62+
return false;
63+
64+
newName = $"{newName}{ShellLibraryItem.EXTENSION}";
65+
66+
var file = new StorageFileWithPath(null, library.ItemPath);
67+
var renamed = await AppInstance!.FilesystemHelpers.RenameAsync(file, newName, NameCollisionOption.FailIfExists, false);
68+
if (renamed is ReturnResult.Success)
69+
{
70+
var newPath = Path.Combine(Path.GetDirectoryName(library.ItemPath)!, newName);
71+
_ = App.Window.DispatcherQueue.EnqueueAsync(async () =>
72+
{
73+
await fsVM.SetWorkingDirectoryAsync(newPath);
74+
});
75+
return true;
76+
}
77+
78+
return false;
79+
}
80+
81+
async Task<bool> SaveCombinedAsync(IList<ListedItem> fileOrFolders)
82+
{
83+
// Handle the visibility attribute for multiple files
84+
var itemMM = AppInstance?.SlimContentPage?.ItemManipulationModel;
85+
if (itemMM is not null) // null on homepage
86+
{
87+
foreach (var fileOrFolder in fileOrFolders)
88+
{
89+
await App.Window.DispatcherQueue.EnqueueAsync(() =>
90+
UIFilesystemHelpers.SetHiddenAttributeItem(fileOrFolder, ViewModel.IsHidden, itemMM)
91+
);
92+
}
93+
}
94+
return true;
95+
}
96+
97+
async Task<bool> SaveBaseAsync()
98+
{
99+
// Handle the visibility attribute for a single file
100+
var itemMM = AppInstance?.SlimContentPage?.ItemManipulationModel;
101+
if (itemMM is not null) // null on homepage
102+
{
103+
await App.Window.DispatcherQueue.EnqueueAsync(() =>
104+
UIFilesystemHelpers.SetHiddenAttributeItem(item, ViewModel.IsHidden, itemMM)
105+
);
106+
}
107+
108+
if (!hasNewName)
109+
return true;
110+
111+
return await App.Window.DispatcherQueue.EnqueueAsync(() =>
112+
UIFilesystemHelpers.RenameFileItemAsync(item, ViewModel.ItemName, AppInstance)
113+
);
114+
}
115+
}
116+
117+
public override void Dispose()
118+
{
119+
}
120+
121+
private void ItemFileName_GettingFocus(UIElement _, GettingFocusEventArgs e)
122+
{
123+
ItemFileName.Text = letterRegex.Replace(ItemFileName.Text, string.Empty);
124+
}
125+
private void ItemFileName_LosingFocus(UIElement _, LosingFocusEventArgs e)
126+
{
127+
if (string.IsNullOrWhiteSpace(ItemFileName.Text))
128+
{
129+
ItemFileName.Text = ViewModel.ItemName;
130+
return;
131+
}
132+
133+
var match = letterRegex.Match(ViewModel.OriginalItemName);
134+
if (match.Success)
135+
ItemFileName.Text += match.Value;
136+
}
137+
138+
private void DiskCleanupButton_Click(object _, RoutedEventArgs e)
139+
{
140+
if (BaseProperties is DriveProperties driveProps)
141+
StorageSenseHelper.OpenStorageSense(driveProps.Drive.Path);
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)