Skip to content

Commit 3b2c656

Browse files
lukeblevinsyaira2
andauthored
Added a file progress UI (#1919)
Co-authored-by: Yair Aichenbaum <[email protected]>
1 parent 7f63050 commit 3b2c656

31 files changed

+849
-485
lines changed

Files/BaseLayout.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Files.Common;
1+
using Files.Commands;
2+
using Files.Common;
23
using Files.Filesystem;
34
using Files.Helpers;
45
using Files.Interacts;
@@ -583,13 +584,13 @@ protected async void List_DragOver(object sender, DragEventArgs e)
583584
deferral.Complete();
584585
}
585586

586-
protected async void List_Drop(object sender, DragEventArgs e)
587+
protected void List_Drop(object sender, DragEventArgs e)
587588
{
588589
var deferral = e.GetDeferral();
589590

590591
if (e.DataView.Contains(StandardDataFormats.StorageItems))
591592
{
592-
await AssociatedInteractions.PasteItems(e.DataView, App.CurrentInstance.FilesystemViewModel.WorkingDirectory, e.AcceptedOperation);
593+
ItemOperations.PasteItemWithStatus(e.DataView, App.CurrentInstance.FilesystemViewModel.WorkingDirectory, e.AcceptedOperation);
593594
e.Handled = true;
594595
}
595596

@@ -659,13 +660,13 @@ protected async void Item_DragOver(object sender, DragEventArgs e)
659660
deferral.Complete();
660661
}
661662

662-
protected async void Item_Drop(object sender, DragEventArgs e)
663+
protected void Item_Drop(object sender, DragEventArgs e)
663664
{
664665
var deferral = e.GetDeferral();
665666

666667
e.Handled = true;
667668
ListedItem rowItem = GetItemFromElement(sender);
668-
await App.CurrentInstance.InteractionOperations.PasteItems(e.DataView, (rowItem as ShortcutItem)?.TargetPath ?? rowItem.ItemPath, e.AcceptedOperation);
669+
ItemOperations.PasteItemWithStatus(e.DataView, (rowItem as ShortcutItem)?.TargetPath ?? rowItem.ItemPath, e.AcceptedOperation);
669670
deferral.Complete();
670671
}
671672

Files/Commands/Delete.cs

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
using Files.Dialogs;
2+
using Files.Filesystem;
3+
using Files.Helpers;
4+
using Files.UserControls;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Diagnostics;
8+
using System.IO;
9+
using System.Threading.Tasks;
10+
using Windows.Foundation.Collections;
11+
using Windows.Storage;
12+
using static Files.Dialogs.ConfirmDeleteDialog;
13+
14+
namespace Files.Commands
15+
{
16+
public partial class ItemOperations
17+
{
18+
public static async void DeleteItemWithStatus(StorageDeleteOption deleteOption)
19+
{
20+
var deleteFromRecycleBin = App.CurrentInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath);
21+
if (deleteFromRecycleBin)
22+
{
23+
// Permanently delete if deleting from recycle bin
24+
deleteOption = StorageDeleteOption.PermanentDelete;
25+
}
26+
27+
// Get selected items before showing the prompt to prevent deleting items selected after the prompt
28+
var CurrentInstance = App.CurrentInstance;
29+
30+
PostedStatusBanner bannerResult = null;
31+
if (deleteOption == StorageDeleteOption.PermanentDelete)
32+
{
33+
bannerResult = App.CurrentInstance.StatusBarControl.OngoingTasksControl.PostBanner(null,
34+
CurrentInstance.FilesystemViewModel.WorkingDirectory,
35+
0,
36+
StatusBanner.StatusBannerSeverity.Ongoing,
37+
StatusBanner.StatusBannerOperation.Delete);
38+
}
39+
else
40+
{
41+
bannerResult = App.CurrentInstance.StatusBarControl.OngoingTasksControl.PostBanner(null,
42+
CurrentInstance.FilesystemViewModel.WorkingDirectory,
43+
0,
44+
StatusBanner.StatusBannerSeverity.Ongoing,
45+
StatusBanner.StatusBannerOperation.Recycle);
46+
}
47+
48+
try
49+
{
50+
Stopwatch sw = new Stopwatch();
51+
sw.Start();
52+
53+
await DeleteItem(deleteOption, CurrentInstance, bannerResult.Progress);
54+
bannerResult.Remove();
55+
56+
sw.Stop();
57+
58+
if (sw.Elapsed.TotalSeconds >= 10)
59+
{
60+
if (deleteOption == StorageDeleteOption.PermanentDelete)
61+
{
62+
App.CurrentInstance.StatusBarControl.OngoingTasksControl.PostBanner(
63+
"Deletion Complete",
64+
"The operation has completed.",
65+
0,
66+
StatusBanner.StatusBannerSeverity.Success,
67+
StatusBanner.StatusBannerOperation.Delete);
68+
}
69+
else
70+
{
71+
App.CurrentInstance.StatusBarControl.OngoingTasksControl.PostBanner(
72+
"Recycle Complete",
73+
"The operation has completed.",
74+
0,
75+
StatusBanner.StatusBannerSeverity.Success,
76+
StatusBanner.StatusBannerOperation.Recycle);
77+
}
78+
}
79+
80+
App.CurrentInstance.NavigationToolbar.CanGoForward = false;
81+
}
82+
catch (UnauthorizedAccessException)
83+
{
84+
bannerResult.Remove();
85+
App.CurrentInstance.StatusBarControl.OngoingTasksControl.PostBanner(
86+
ResourceController.GetTranslation("AccessDeniedDeleteDialog/Title"),
87+
ResourceController.GetTranslation("AccessDeniedDeleteDialog/Text"),
88+
0,
89+
StatusBanner.StatusBannerSeverity.Error,
90+
StatusBanner.StatusBannerOperation.Delete);
91+
}
92+
catch (FileNotFoundException)
93+
{
94+
bannerResult.Remove();
95+
App.CurrentInstance.StatusBarControl.OngoingTasksControl.PostBanner(
96+
ResourceController.GetTranslation("FileNotFoundDialog/Title"),
97+
ResourceController.GetTranslation("FileNotFoundDialog/Text"),
98+
0,
99+
StatusBanner.StatusBannerSeverity.Error,
100+
StatusBanner.StatusBannerOperation.Delete);
101+
}
102+
catch (IOException)
103+
{
104+
bannerResult.Remove();
105+
App.CurrentInstance.StatusBarControl.OngoingTasksControl.PostActionBanner(
106+
ResourceController.GetTranslation("FileInUseDeleteDialog/Title"),
107+
ResourceController.GetTranslation("FileInUseDeleteDialog/Text"),
108+
ResourceController.GetTranslation("FileInUseDeleteDialog/PrimaryButtonText"),
109+
ResourceController.GetTranslation("FileInUseDeleteDialog/SecondaryButtonText"), () => { DeleteItemWithStatus(deleteOption); });
110+
}
111+
}
112+
113+
private static async Task DeleteItem(StorageDeleteOption deleteOption, IShellPage AppInstance, IProgress<uint> progress)
114+
{
115+
var deleteFromRecycleBin = AppInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath);
116+
117+
List<ListedItem> selectedItems = new List<ListedItem>();
118+
foreach (ListedItem selectedItem in AppInstance.ContentPage.SelectedItems)
119+
{
120+
selectedItems.Add(selectedItem);
121+
}
122+
123+
if (App.AppSettings.ShowConfirmDeleteDialog == true) //check if the setting to show a confirmation dialog is on
124+
{
125+
var dialog = new ConfirmDeleteDialog(deleteFromRecycleBin, deleteOption);
126+
await dialog.ShowAsync();
127+
128+
if (dialog.Result != MyResult.Delete) //delete selected item(s) if the result is yes
129+
{
130+
return; //return if the result isn't delete
131+
}
132+
deleteOption = dialog.PermanentlyDelete;
133+
}
134+
135+
int itemsDeleted = 0;
136+
foreach (ListedItem storItem in selectedItems)
137+
{
138+
uint progressValue = (uint)(itemsDeleted * 100.0 / selectedItems.Count);
139+
if (selectedItems.Count > 3) { progress.Report((uint)progressValue); }
140+
141+
IStorageItem item;
142+
try
143+
{
144+
if (storItem.PrimaryItemAttribute == StorageItemTypes.File)
145+
{
146+
item = await ItemViewModel.GetFileFromPathAsync(storItem.ItemPath, AppInstance);
147+
}
148+
else
149+
{
150+
item = await ItemViewModel.GetFolderFromPathAsync(storItem.ItemPath, AppInstance);
151+
}
152+
153+
await item.DeleteAsync(deleteOption);
154+
}
155+
catch (UnauthorizedAccessException)
156+
{
157+
if (deleteOption == StorageDeleteOption.Default)
158+
{
159+
// Try again with fulltrust process
160+
if (App.Connection != null)
161+
{
162+
var result = await App.Connection.SendMessageAsync(new ValueSet() {
163+
{ "Arguments", "FileOperation" },
164+
{ "fileop", "MoveToBin" },
165+
{ "filepath", storItem.ItemPath } });
166+
}
167+
}
168+
else
169+
{
170+
// Try again with DeleteFileFromApp
171+
if (!NativeDirectoryChangesHelper.DeleteFileFromApp(storItem.ItemPath))
172+
{
173+
Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());
174+
}
175+
}
176+
}
177+
catch (FileLoadException)
178+
{
179+
// try again
180+
if (storItem.PrimaryItemAttribute == StorageItemTypes.File)
181+
{
182+
item = await ItemViewModel.GetFileFromPathAsync(storItem.ItemPath, AppInstance);
183+
}
184+
else
185+
{
186+
item = await ItemViewModel.GetFolderFromPathAsync(storItem.ItemPath, AppInstance);
187+
}
188+
189+
await item.DeleteAsync(deleteOption);
190+
}
191+
192+
if (deleteFromRecycleBin)
193+
{
194+
// Recycle bin also stores a file starting with $I for each item
195+
var iFilePath = Path.Combine(Path.GetDirectoryName(storItem.ItemPath), Path.GetFileName(storItem.ItemPath).Replace("$R", "$I"));
196+
await (await ItemViewModel.GetFileFromPathAsync(iFilePath)).DeleteAsync(StorageDeleteOption.PermanentDelete);
197+
}
198+
199+
AppInstance.FilesystemViewModel.RemoveFileOrFolder(storItem);
200+
itemsDeleted++;
201+
}
202+
}
203+
}
204+
}

0 commit comments

Comments
 (0)