Skip to content

Commit 988453b

Browse files
authored
Fix copy/paste for shortcuts (#6109)
1 parent d590ef8 commit 988453b

File tree

8 files changed

+89
-95
lines changed

8 files changed

+89
-95
lines changed

Files/DataModels/FilesystemItemsOperationDataModel.cs

+8-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Files.Enums;
22
using Files.Helpers;
33
using Files.ViewModels.Dialogs;
4+
using Microsoft.Toolkit.Uwp;
45
using System;
56
using System.Collections.Concurrent;
67
using System.Collections.Generic;
@@ -58,51 +59,38 @@ public FilesystemItemsOperationDataModel(FilesystemOperationType operationType,
5859
this.ConflictingItems = conflictingItems;
5960
}
6061

61-
public async Task<List<FilesystemOperationItemViewModel>> ToItems(Action updatePrimaryButtonEnabled, Action optionGenerateNewName, Action optionReplaceExisting, Action optionSkip)
62+
public List<FilesystemOperationItemViewModel> ToItems(Action updatePrimaryButtonEnabled, Action optionGenerateNewName, Action optionReplaceExisting, Action optionSkip)
6263
{
63-
ConcurrentBag<(int Index, FilesystemOperationItemViewModel Model)> items = new ConcurrentBag<(int Index, FilesystemOperationItemViewModel Model)>();
64-
64+
List<FilesystemOperationItemViewModel> items = new List<FilesystemOperationItemViewModel>();
6565
List<FilesystemItemsOperationItemModel> nonConflictingItems = IncomingItems.Except(ConflictingItems).ToList();
6666

6767
// Add conflicting items first
68-
await Task.WhenAll(ConflictingItems.Select(async (item, index) =>
69-
{
70-
var iconData = await FileThumbnailHelper.LoadIconFromPathAsync(item.SourcePath, 64u, Windows.Storage.FileProperties.ThumbnailMode.ListView);
71-
72-
items.Add((index, new FilesystemOperationItemViewModel(updatePrimaryButtonEnabled, optionGenerateNewName, optionReplaceExisting, optionSkip)
68+
items.AddRange(ConflictingItems.Select((item, index) =>
69+
new FilesystemOperationItemViewModel(updatePrimaryButtonEnabled, optionGenerateNewName, optionReplaceExisting, optionSkip)
7370
{
7471
IsConflict = true,
75-
ItemIcon = iconData != null ? await iconData.ToBitmapAsync() : null,
7672
SourcePath = item.SourcePath,
7773
DestinationPath = item.DestinationPath,
7874
DisplayFileName = item.DisplayFileName,
7975
ConflictResolveOption = FileNameConflictResolveOptionType.GenerateNewName,
8076
ItemOperation = item.OperationType,
8177
ActionTaken = false
8278
}));
83-
}));
84-
85-
var baseIndex = ConflictingItems.Count;
8679

8780
// Then add non-conflicting items
88-
await Task.WhenAll(nonConflictingItems.Select(async (item, index) =>
89-
{
90-
var iconData = await FileThumbnailHelper.LoadIconFromPathAsync(item.SourcePath, 64u, Windows.Storage.FileProperties.ThumbnailMode.ListView);
91-
92-
items.Add((baseIndex + index, new FilesystemOperationItemViewModel(updatePrimaryButtonEnabled, optionGenerateNewName, optionReplaceExisting, optionSkip)
81+
items.AddRange(nonConflictingItems.Select((item, index) =>
82+
new FilesystemOperationItemViewModel(updatePrimaryButtonEnabled, optionGenerateNewName, optionReplaceExisting, optionSkip)
9383
{
9484
IsConflict = false,
95-
ItemIcon = iconData != null ? await iconData.ToBitmapAsync() : null,
9685
SourcePath = item.SourcePath,
9786
DestinationPath = item.DestinationPath,
9887
DisplayFileName = item.DisplayFileName,
9988
ConflictResolveOption = FileNameConflictResolveOptionType.NotAConflict,
10089
ItemOperation = item.OperationType,
10190
ActionTaken = true
10291
}));
103-
}));
10492

105-
return items.OrderBy(i => i.Index).Select(i => i.Model).ToList();
93+
return items;
10694
}
10795

10896
private string GetOperationIconGlyph(FilesystemOperationType operationType)

Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public async Task<ReturnResult> DeleteItemsAsync(IEnumerable<IStorageItemWithPat
126126
}
127127
}
128128

129-
FilesystemOperationDialog dialog = await FilesystemOperationDialogViewModel.GetDialog(new FilesystemItemsOperationDataModel(
129+
FilesystemOperationDialog dialog = FilesystemOperationDialogViewModel.GetDialog(new FilesystemItemsOperationDataModel(
130130
FilesystemOperationType.Delete,
131131
false,
132132
canBeSentToBin ? permanently : true,
@@ -313,7 +313,7 @@ public async Task<ReturnResult> DeleteItemAsync(IStorageItemWithPath source, boo
313313
incomingItems.Add(new FilesystemItemsOperationItemModel(FilesystemOperationType.Delete, srcPath, null));
314314
}
315315

316-
FilesystemOperationDialog dialog = await FilesystemOperationDialogViewModel.GetDialog(new FilesystemItemsOperationDataModel(
316+
FilesystemOperationDialog dialog = FilesystemOperationDialogViewModel.GetDialog(new FilesystemItemsOperationDataModel(
317317
FilesystemOperationType.Delete,
318318
false,
319319
canBeSentToBin ? permanently : true,
@@ -1005,7 +1005,7 @@ public async Task<ReturnResult> RecycleItemsFromClipboard(DataPackageView packag
10051005

10061006
if (mustResolveConflicts || forceDialog)
10071007
{
1008-
FilesystemOperationDialog dialog = await FilesystemOperationDialogViewModel.GetDialog(new FilesystemItemsOperationDataModel(
1008+
FilesystemOperationDialog dialog = FilesystemOperationDialogViewModel.GetDialog(new FilesystemItemsOperationDataModel(
10091009
operationType,
10101010
mustResolveConflicts,
10111011
false,

Files/Helpers/UIFilesystemHelpers.cs

+33-42
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ public static async void CutItem(IShellPage associatedInstance)
3939
{
4040
await Task.WhenAll(associatedInstance.SlimContentPage.SelectedItems.ToList().Select(async listedItem =>
4141
{
42-
// FTP don't support cut, fallback to copy
43-
if (listedItem is not FtpItem)
42+
// FTP don't support cut, fallback to copy
43+
if (listedItem is not FtpItem)
4444
{
45-
// Dim opacities accordingly
46-
listedItem.Opacity = Constants.UI.DimItemOpacity;
45+
// Dim opacities accordingly
46+
listedItem.Opacity = Constants.UI.DimItemOpacity;
4747
}
4848

4949
if (listedItem is FtpItem ftpItem)
@@ -80,31 +80,24 @@ await Task.WhenAll(associatedInstance.SlimContentPage.SelectedItems.ToList().Sel
8080
}
8181
catch
8282
{
83-
return;
84-
}
85-
86-
if (result.ErrorCode == FileSystemStatusCode.NotFound)
87-
{
88-
associatedInstance.SlimContentPage.ItemManipulationModel.RefreshItemsOpacity();
89-
return;
90-
}
91-
else if (result.ErrorCode == FileSystemStatusCode.Unauthorized)
92-
{
93-
// Try again with fulltrust process
94-
var connection = await AppServiceConnectionHelper.Instance;
95-
if (connection != null)
83+
if (result.ErrorCode == FileSystemStatusCode.Unauthorized)
9684
{
97-
string filePaths = string.Join('|', associatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath));
98-
AppServiceResponseStatus status = await connection.SendMessageAsync(new ValueSet()
99-
{
100-
{ "Arguments", "FileOperation" },
101-
{ "fileop", "Clipboard" },
102-
{ "filepath", filePaths },
103-
{ "operation", (int)DataPackageOperation.Move }
104-
});
105-
if (status == AppServiceResponseStatus.Success)
85+
// Try again with fulltrust process
86+
var connection = await AppServiceConnectionHelper.Instance;
87+
if (connection != null)
10688
{
107-
return;
89+
string filePaths = string.Join('|', associatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath));
90+
AppServiceResponseStatus status = await connection.SendMessageAsync(new ValueSet()
91+
{
92+
{ "Arguments", "FileOperation" },
93+
{ "fileop", "Clipboard" },
94+
{ "filepath", filePaths },
95+
{ "operation", (int)DataPackageOperation.Move }
96+
});
97+
if (status == AppServiceResponseStatus.Success)
98+
{
99+
return;
100+
}
108101
}
109102
}
110103
associatedInstance.SlimContentPage.ItemManipulationModel.RefreshItemsOpacity();
@@ -188,23 +181,21 @@ await Task.WhenAll(associatedInstance.SlimContentPage.SelectedItems.ToList().Sel
188181
}
189182
catch
190183
{
191-
return;
192-
}
193-
194-
if (result.ErrorCode == FileSystemStatusCode.Unauthorized)
195-
{
196-
// Try again with fulltrust process
197-
var connection = await AppServiceConnectionHelper.Instance;
198-
if (connection != null)
184+
if (result.ErrorCode == FileSystemStatusCode.Unauthorized)
199185
{
200-
string filePaths = string.Join('|', associatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath));
201-
await connection.SendMessageAsync(new ValueSet()
186+
// Try again with fulltrust process
187+
var connection = await AppServiceConnectionHelper.Instance;
188+
if (connection != null)
202189
{
203-
{ "Arguments", "FileOperation" },
204-
{ "fileop", "Clipboard" },
205-
{ "filepath", filePaths },
206-
{ "operation", (int)DataPackageOperation.Copy }
207-
});
190+
string filePaths = string.Join('|', associatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath));
191+
await connection.SendMessageAsync(new ValueSet()
192+
{
193+
{ "Arguments", "FileOperation" },
194+
{ "fileop", "Clipboard" },
195+
{ "filepath", filePaths },
196+
{ "operation", (int)DataPackageOperation.Copy }
197+
});
198+
}
208199
}
209200
return;
210201
}

Files/Interacts/BaseLayoutCommandImplementationModel.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ await FilesystemHelpers.RestoreFromTrashAsync(StorageItemHelpers.FromPathAndType
199199

200200
public virtual async void DeleteItem(RoutedEventArgs e)
201201
{
202-
var items = await Task.WhenAll(SlimContentPage.SelectedItems.Select((item) => Task.Run(() => StorageItemHelpers.FromPathAndType(
203-
item.ItemPath,
204-
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory))));
202+
var items = await Task.Run(() => SlimContentPage.SelectedItems.ToList().Select((item) => StorageItemHelpers.FromPathAndType(
203+
item.ItemPath,
204+
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory)));
205205
await FilesystemHelpers.DeleteItemsAsync(items, true, false, true);
206206
}
207207

Files/UserControls/Widgets/FolderWidget.xaml.cs

+6-12
Original file line numberDiff line numberDiff line change
@@ -140,23 +140,18 @@ public void Dispose()
140140

141141
private async Task GetItemsAddedIcon()
142142
{
143-
try
143+
foreach (var item in ItemsAdded.ToList()) // ToList() is necessary
144144
{
145-
foreach (var item in ItemsAdded.ToList()) // ToList() is necessary
146-
{
147-
item.SelectCommand = LibraryCardClicked;
148-
item.AutomationProperties = item.Text;
149-
await this.LoadLibraryIcon(item);
150-
}
151-
}
152-
catch
153-
{
154-
// Collection modified
145+
item.SelectCommand = LibraryCardClicked;
146+
item.AutomationProperties = item.Text;
147+
await this.LoadLibraryIcon(item);
155148
}
156149
}
157150

158151
private async void FolderWidget_Loaded(object sender, RoutedEventArgs e)
159152
{
153+
Loaded -= FolderWidget_Loaded;
154+
160155
ItemsAdded.BeginBulkOperation();
161156
ItemsAdded.Add(new LibraryCardItem
162157
{
@@ -192,7 +187,6 @@ private async void FolderWidget_Loaded(object sender, RoutedEventArgs e)
192187
await GetItemsAddedIcon();
193188

194189
ItemsAdded.EndBulkOperation();
195-
Loaded -= FolderWidget_Loaded;
196190
}
197191

198192
private void FolderWidget_Unloaded(object sender, RoutedEventArgs e)

Files/ViewModels/Dialogs/FilesystemOperationDialogViewModel.cs

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using Files.DataModels;
22
using Files.Dialogs;
33
using Files.Enums;
4+
using Files.Helpers;
45
using Microsoft.Toolkit.Mvvm.ComponentModel;
56
using Microsoft.Toolkit.Mvvm.Input;
67
using Microsoft.Toolkit.Uwp;
8+
using System;
79
using System.Collections.Generic;
810
using System.Collections.ObjectModel;
911
using System.Linq;
@@ -191,7 +193,7 @@ public List<IFilesystemOperationItemModel> GetResult()
191193
return Items.Cast<IFilesystemOperationItemModel>().ToList();
192194
}
193195

194-
public static async Task<FilesystemOperationDialog> GetDialog(FilesystemItemsOperationDataModel itemsData)
196+
public static FilesystemOperationDialog GetDialog(FilesystemItemsOperationDataModel itemsData)
195197
{
196198
string titleText = null;
197199
string subtitleText = null;
@@ -280,12 +282,31 @@ public static async Task<FilesystemOperationDialog> GetDialog(FilesystemItemsOpe
280282
PermanentlyDeleteEnabled = itemsData.PermanentlyDeleteEnabled,
281283
MustResolveConflicts = itemsData.MustResolveConflicts
282284
};
283-
viewModel.Items = new ObservableCollection<FilesystemOperationItemViewModel>(await itemsData.ToItems(
285+
viewModel.Items = new ObservableCollection<FilesystemOperationItemViewModel>(itemsData.ToItems(
284286
viewModel.UpdatePrimaryButtonEnabled, viewModel.OptionGenerateNewName, viewModel.OptionReplaceExisting, viewModel.OptionSkip));
285-
287+
_ = LoadItemsIcon(viewModel.Items);
286288
FilesystemOperationDialog dialog = new FilesystemOperationDialog(viewModel);
287289

288290
return dialog;
289291
}
292+
293+
private static async Task LoadItemsIcon(IEnumerable<FilesystemOperationItemViewModel> items)
294+
{
295+
await Task.Run(() => Task.WhenAll(items.ToList().Select(async (item) =>
296+
{
297+
try
298+
{
299+
var iconData = await FileThumbnailHelper.LoadIconFromPathAsync(item.SourcePath, 64u, Windows.Storage.FileProperties.ThumbnailMode.ListView);
300+
if (iconData != null)
301+
{
302+
await Windows.ApplicationModel.Core.CoreApplication.MainView.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, async () =>
303+
{
304+
item.ItemIcon = await iconData.ToBitmapAsync();
305+
});
306+
}
307+
}
308+
catch { }
309+
})));
310+
}
290311
}
291312
}

Files/Views/ColumnShellPage.xaml.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -616,9 +616,9 @@ private async void KeyboardAccelerator_Invoked(KeyboardAccelerator sender, Keybo
616616
case (false, true, false, true, VirtualKey.Delete): // shift + delete, PermanentDelete
617617
if (ContentPage.IsItemSelected && !NavToolbarViewModel.IsEditModeEnabled && !InstanceViewModel.IsPageTypeSearchResults)
618618
{
619-
var items = await Task.WhenAll(ContentPage.SelectedItems.Select((item) => Task.Run(() => StorageItemHelpers.FromPathAndType(
620-
item.ItemPath,
621-
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory))));
619+
var items = await Task.Run(() => SlimContentPage.SelectedItems.ToList().Select((item) => StorageItemHelpers.FromPathAndType(
620+
item.ItemPath,
621+
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory)));
622622
await FilesystemHelpers.DeleteItemsAsync(items, true, true, true);
623623
}
624624

@@ -660,9 +660,9 @@ private async void KeyboardAccelerator_Invoked(KeyboardAccelerator sender, Keybo
660660
case (false, false, false, true, VirtualKey.Delete): // delete, delete item
661661
if (ContentPage.IsItemSelected && !ContentPage.IsRenamingItem && !InstanceViewModel.IsPageTypeSearchResults)
662662
{
663-
var items = await Task.WhenAll(ContentPage.SelectedItems.Select((item) => Task.Run(() => StorageItemHelpers.FromPathAndType(
664-
item.ItemPath,
665-
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory))));
663+
var items = await Task.Run(() => SlimContentPage.SelectedItems.ToList().Select((item) => StorageItemHelpers.FromPathAndType(
664+
item.ItemPath,
665+
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory)));
666666
await FilesystemHelpers.DeleteItemsAsync(items, true, false, true);
667667
}
668668

0 commit comments

Comments
 (0)