Skip to content

Fix: Fixed an issue where the restore option was missing from recycle bin #10004

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
502be38
Moved the functions to restore and delete items in the recycle bin he…
QuaintMako Sep 10, 2022
db7633c
Added recycle bin restoration in flyout menu.
QuaintMako Sep 10, 2022
ae77a99
Added the restore action in the inner toolbar for the recycle bin only.
QuaintMako Sep 10, 2022
5a1c8b5
Merge branch 'main' into 9561_RestoreEmptyEnhancedRecycleBin
QuaintMako Sep 12, 2022
840604a
Merge branch 'files-community:main' into 9561_RestoreEmptyEnhancedRec…
QuaintMako Sep 14, 2022
e8392fe
Restore selection and restore recycle bin now correctly refresh in re…
QuaintMako Sep 15, 2022
08cdf96
Can now restore selection in recycle bin through inner toolbar.
QuaintMako Sep 15, 2022
f7e0883
Emptying selection now has a dedicated button in the recycle bin.
QuaintMako Sep 15, 2022
4e0bd93
Emptying selection is now functionnal in recycle bin.
QuaintMako Sep 15, 2022
f0bbe21
Added the Empty selection action to the flyout menu
QuaintMako Sep 16, 2022
6f9aaad
Merge branch 'files-community:main' into 9561_RestoreEmptyEnhancedRec…
QuaintMako Sep 16, 2022
4722a68
Reworked some localizations.
QuaintMako Sep 16, 2022
3e51536
Merge branch '9561_RestoreEmptyEnhancedRecycleBin' of https://github.…
QuaintMako Sep 16, 2022
842f1b0
Reworked some more localizations.
QuaintMako Sep 16, 2022
3aecd4f
Replaced spaces by tabulations.
QuaintMako Sep 16, 2022
959749b
Update src/Files.App/Strings/en-US/Resources.resw
yaira2 Sep 16, 2022
e28787c
Update src/Files.App/Strings/en-US/Resources.resw
yaira2 Sep 16, 2022
2ce5c8e
Removed the 'Empty Selection' action for it was redundant with an alr…
QuaintMako Sep 16, 2022
8c596e4
Add forgotten file to previous commit.
QuaintMako Sep 16, 2022
69c23b6
Removed a forgotten empty line.
QuaintMako Sep 16, 2022
e711092
Merged main into 9561_RestoreEmptyEnhancedRecycleBin and solved confl…
QuaintMako Sep 16, 2022
4f0499c
Fixed issues in the resources loading after merge process.
QuaintMako Sep 19, 2022
4bc11ff
Removed forgotten removed action in flyout menu.
QuaintMako Sep 19, 2022
dba89b3
Merge branch 'main' into pr/10004
yaira2 Sep 20, 2022
d86bb99
Changed the restore icon for a better suited one.
QuaintMako Sep 20, 2022
57a1fdf
Merge branch 'main' into 9561_RestoreEmptyEnhancedRecycleBin
QuaintMako Sep 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/Files.App/Helpers/ContextFlyoutItemHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media.Imaging;
using System.Threading;
using System.Runtime.CompilerServices;

namespace Files.App.Helpers
{
Expand Down Expand Up @@ -599,6 +600,14 @@ public static List<ContextMenuFlyoutItemViewModel> GetBaseLayoutMenuItems(Curren
ShowInRecycleBin = true,
},
new ContextMenuFlyoutItemViewModel()
{
Text = "RestoreAllItems".GetLocalizedResource(),
Glyph = "\xE777",
Command = commandsViewModel.RestoreRecycleBinCommand,
ShowItem = currentInstanceViewModel.IsPageTypeRecycleBin,
ShowInRecycleBin = true,
},
new ContextMenuFlyoutItemViewModel()
{
ItemType = ItemType.Separator,
Tag = "OverflowSeparator",
Expand All @@ -625,7 +634,7 @@ public static List<ContextMenuFlyoutItemViewModel> GetBaseItemMenuItems(BaseLayo
new ContextMenuFlyoutItemViewModel()
{
Text = "BaseLayoutItemContextFlyoutRestore/Text".GetLocalizedResource(),
Glyph = "\uE8E5",
Glyph = "\xE777",
Command = commandsViewModel.RestoreItemCommand,
ShowInRecycleBin = true,
ShowItem = selectedItems.All(x => x.IsRecycleBinItem)
Expand Down
80 changes: 80 additions & 0 deletions src/Files.App/Helpers/RecycleBinHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.UI.Xaml.Controls;
using Files.App.Shell;
using Vanara.PInvoke;
using Files.App.Filesystem;

namespace Files.App.Helpers
{
Expand Down Expand Up @@ -78,6 +79,55 @@ public async Task EmptyRecycleBin()
}
}

public static async Task S_RestoreRecycleBin(IShellPage associatedInstance)
{
await new RecycleBinHelpers().RestoreRecycleBin(associatedInstance);
}

public async Task RestoreRecycleBin(IShellPage associatedInstance)
{
var ConfirmEmptyBinDialog = new ContentDialog()
{
Title = "ConfirmRestoreBinDialogTitle".GetLocalizedResource(),
Content = "ConfirmRestoreBinDialogContent".GetLocalizedResource(),
PrimaryButtonText = "Yes".GetLocalizedResource(),
SecondaryButtonText = "Cancel".GetLocalizedResource(),
DefaultButton = ContentDialogButton.Primary
};

ContentDialogResult result = await this.SetContentDialogRoot(ConfirmEmptyBinDialog).ShowAsync();

if (result == ContentDialogResult.Primary)
{
associatedInstance.SlimContentPage.ItemManipulationModel.SelectAllItems();
await this.RestoreItem(associatedInstance);
}
}

public static async Task S_RestoreSelectionRecycleBin(IShellPage associatedInstance)
{
await new RecycleBinHelpers().RestoreSelectionRecycleBin(associatedInstance);
}

public async Task RestoreSelectionRecycleBin(IShellPage associatedInstance)
{
var ConfirmEmptyBinDialog = new ContentDialog()
{
Title = "ConfirmRestoreSelectionBinDialogTitle".GetLocalizedResource(),
Content = string.Format("ConfirmRestoreSelectionBinDialogContent".GetLocalizedResource(), associatedInstance.SlimContentPage.SelectedItems.Count),
PrimaryButtonText = "Yes".GetLocalizedResource(),
SecondaryButtonText = "Cancel".GetLocalizedResource(),
DefaultButton = ContentDialogButton.Primary
};

ContentDialogResult result = await this.SetContentDialogRoot(ConfirmEmptyBinDialog).ShowAsync();

if (result == ContentDialogResult.Primary)
{
await this.RestoreItem(associatedInstance);
}
}

//WINUI3
private ContentDialog SetContentDialogRoot(ContentDialog contentDialog)
{
Expand Down Expand Up @@ -115,5 +165,35 @@ public bool RecycleBinHasItems()
{
return Win32Shell.QueryRecycleBin().NumItems > 0;
}

public static async Task S_RestoreItem(IShellPage associatedInstance)
{
await new RecycleBinHelpers().RestoreItem(associatedInstance);
}

private async Task RestoreItem(IShellPage associatedInstance)
{
var items = associatedInstance.SlimContentPage.SelectedItems.ToList().Where(x => x is RecycleBinItem).Select((item) => new
{
Source = StorageHelpers.FromPathAndType(
item.ItemPath,
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory),
Dest = ((RecycleBinItem)item).ItemOriginalPath
});
await associatedInstance.FilesystemHelpers.RestoreItemsFromTrashAsync(items.Select(x => x.Source), items.Select(x => x.Dest), true);
}

public static async Task S_DeleteItem(IShellPage associatedInstance)
{
await new RecycleBinHelpers().DeleteItem(associatedInstance);
}

public virtual async Task DeleteItem(IShellPage associatedInstance)
{
var items = associatedInstance.SlimContentPage.SelectedItems.ToList().Select((item) => StorageHelpers.FromPathAndType(
item.ItemPath,
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory));
await associatedInstance.FilesystemHelpers.DeleteItemsAsync(items, true, false, true);
}
}
}
24 changes: 12 additions & 12 deletions src/Files.App/Interacts/BaseLayoutCommandImplementationModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@ public virtual async void EmptyRecycleBin(RoutedEventArgs e)
await RecycleBinHelpers.S_EmptyRecycleBin();
}

public virtual async void RestoreRecycleBin(RoutedEventArgs e)
{
await RecycleBinHelpers.S_RestoreRecycleBin(associatedInstance);
}

public virtual async void RestoreSelectionRecycleBin(RoutedEventArgs e)
{
await RecycleBinHelpers.S_RestoreSelectionRecycleBin(associatedInstance);
}

public virtual async void QuickLook(RoutedEventArgs e)
{
await QuickLookHelpers.ToggleQuickLook(associatedInstance);
Expand All @@ -176,22 +186,12 @@ public virtual void CutItem(RoutedEventArgs e)

public virtual async void RestoreItem(RoutedEventArgs e)
{
var items = SlimContentPage.SelectedItems.ToList().Where(x => x is RecycleBinItem).Select((item) => new
{
Source = StorageHelpers.FromPathAndType(
item.ItemPath,
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory),
Dest = (item as RecycleBinItem).ItemOriginalPath
});
await FilesystemHelpers.RestoreItemsFromTrashAsync(items.Select(x => x.Source), items.Select(x => x.Dest), true);
await RecycleBinHelpers.S_RestoreItem(associatedInstance);
}

public virtual async void DeleteItem(RoutedEventArgs e)
{
var items = SlimContentPage.SelectedItems.ToList().Select((item) => StorageHelpers.FromPathAndType(
item.ItemPath,
item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory));
await FilesystemHelpers.DeleteItemsAsync(items, true, false, true);
await RecycleBinHelpers.S_DeleteItem(associatedInstance);
}

public virtual void ShowFolderProperties(RoutedEventArgs e)
Expand Down
6 changes: 6 additions & 0 deletions src/Files.App/Interacts/BaseLayoutCommandsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ private void InitializeCommands()
UnpinDirectoryFromFavoritesCommand = new RelayCommand<RoutedEventArgs>(CommandsModel.UnpinDirectoryFromFavorites);
OpenItemCommand = new RelayCommand<RoutedEventArgs>(CommandsModel.OpenItem);
EmptyRecycleBinCommand = new RelayCommand<RoutedEventArgs>(CommandsModel.EmptyRecycleBin);
RestoreRecycleBinCommand = new RelayCommand<RoutedEventArgs>(CommandsModel.RestoreRecycleBin);
RestoreSelectionRecycleBinCommand = new RelayCommand<RoutedEventArgs>(CommandsModel.RestoreSelectionRecycleBin);
QuickLookCommand = new RelayCommand<RoutedEventArgs>(CommandsModel.QuickLook);
CopyItemCommand = new RelayCommand<RoutedEventArgs>(CommandsModel.CopyItem);
CutItemCommand = new RelayCommand<RoutedEventArgs>(CommandsModel.CutItem);
Expand Down Expand Up @@ -107,6 +109,10 @@ private void InitializeCommands()

public ICommand EmptyRecycleBinCommand { get; private set; }

public ICommand RestoreRecycleBinCommand { get; private set; }

public ICommand RestoreSelectionRecycleBinCommand { get; private set; }

public ICommand QuickLookCommand { get; private set; }

public ICommand CopyItemCommand { get; private set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public interface IBaseLayoutCommandImplementationModel : IDisposable

void EmptyRecycleBin(RoutedEventArgs e);

void RestoreRecycleBin(RoutedEventArgs e);

void RestoreSelectionRecycleBin(RoutedEventArgs e);

void QuickLook(RoutedEventArgs e);

void CopyItem(RoutedEventArgs e);
Expand Down
18 changes: 18 additions & 0 deletions src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -2828,4 +2828,22 @@ We use App Center to track which settings are being used, find bugs, and fix cra
<data name="SelectFilesAndFoldersOnHover" xml:space="preserve">
<value>Select files and folders when hovering over them</value>
</data>
<data name="ConfirmRestoreBinDialogContent" xml:space="preserve">
<value>Are you sure you want to restore all items in the recycle bin?</value>
</data>
<data name="ConfirmRestoreBinDialogTitle" xml:space="preserve">
<value>Restore all items</value>
</data>
<data name="ConfirmRestoreSelectionBinDialogContent" xml:space="preserve">
<value>Do you want to restore the {0} selected item(s)?</value>
</data>
<data name="ConfirmRestoreSelectionBinDialogTitle" xml:space="preserve">
<value>Restore selection</value>
</data>
<data name="RestoreAllItems" xml:space="preserve">
<value>Restore All Items</value>
</data>
<data name="RestoreSelection" xml:space="preserve">
<value>Restore</value>
</data>
</root>
38 changes: 32 additions & 6 deletions src/Files.App/UserControls/InnerNavigationToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,45 @@
</AppBarButton.Content>
</AppBarButton>
<AppBarSeparator x:Name="AdditionalActionSeparator" x:Load="{x:Bind ViewModel.HasAdditionalAction, Mode=OneWay}" />
<AppBarButton
<AppBarButton
x:Name="EmptyRecycleBinButton"
x:Load="{x:Bind ViewModel.InstanceViewModel.IsPageTypeRecycleBin, Mode=OneWay, FallbackValue=False}"
AccessKey="B"
Command="{x:Bind ViewModel.EmptyRecycleBinCommand, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.CanEmptyRecycleBin, Mode=OneWay}"
Label="{helpers:ResourceString Name=EmptyRecycleBin}"
ToolTipService.ToolTip="{helpers:ResourceString Name=EmptyRecycleBin}">
<AppBarButton.Icon>
<FontIcon FontFamily="{StaticResource RecycleBinIcons}" Glyph="&#xEF88;" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton
<AppBarButton.Icon>
<FontIcon FontFamily="{StaticResource RecycleBinIcons}" Glyph="&#xEF88;" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton
x:Name="RestoreRecycleBinButton"
x:Load="{x:Bind ViewModel.InstanceViewModel.IsPageTypeRecycleBin, Mode=OneWay, FallbackValue=False}"
AccessKey="R"
Command="{x:Bind ViewModel.RestoreRecycleBinCommand, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.CanRestoreRecycleBin, Mode=OneWay}"
Visibility="{x:Bind ViewModel.CanRestoreRecycleBin, Mode=OneWay}"
Label="{helpers:ResourceString Name=RestoreAllItems}"
ToolTipService.ToolTip="{helpers:ResourceString Name=RestoreAllItems}">
<AppBarButton.Icon>
<FontIcon Glyph="&#xE777;" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton
x:Name="RestoreSelectionRecycleBinButton"
x:Load="{x:Bind ViewModel.InstanceViewModel.IsPageTypeRecycleBin, Mode=OneWay, FallbackValue=False}"
AccessKey="R"
Command="{x:Bind ViewModel.RestoreSelectionRecycleBinCommand, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.CanRestoreSelectionRecycleBin, Mode=OneWay}"
Visibility="{x:Bind ViewModel.CanRestoreSelectionRecycleBin, Mode=OneWay}"
Label="{helpers:ResourceString Name=RestoreSelection}"
ToolTipService.ToolTip="{helpers:ResourceString Name=RestoreSelection}">
<AppBarButton.Icon>
<FontIcon Glyph="&#xE777;" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton
x:Name="ExtractButton"
Width="Auto"
MinWidth="40"
Expand Down
13 changes: 13 additions & 0 deletions src/Files.App/ViewModels/ToolbarViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,8 @@ public void UpdateAdditionalActions()
{
OnPropertyChanged(nameof(HasAdditionalAction));
OnPropertyChanged(nameof(CanEmptyRecycleBin));
OnPropertyChanged(nameof(CanRestoreRecycleBin));
OnPropertyChanged(nameof(CanRestoreSelectionRecycleBin));
}

private AddressToolbar AddressToolbar => (App.Window.Content as Frame).FindDescendant<AddressToolbar>();
Expand Down Expand Up @@ -880,6 +882,10 @@ public void SearchRegion_LostFocus(object sender, RoutedEventArgs e)

public ICommand EmptyRecycleBinCommand { get; set; }

public ICommand RestoreRecycleBinCommand { get; set; }

public ICommand RestoreSelectionRecycleBinCommand { get; set; }

public ICommand PropertiesCommand { get; set; }

public ICommand ExtractCommand { get; set; }
Expand Down Expand Up @@ -1186,6 +1192,8 @@ public bool HasItem
if (SetProperty(ref hasItem, value))
{
OnPropertyChanged(nameof(CanEmptyRecycleBin));
OnPropertyChanged(nameof(CanRestoreRecycleBin));
OnPropertyChanged(nameof(CanRestoreSelectionRecycleBin));
}
}
}
Expand All @@ -1212,6 +1220,9 @@ public List<ListedItem> SelectedItems
OnPropertyChanged(nameof(IsMultipleImageSelected));
OnPropertyChanged(nameof(IsFont));
OnPropertyChanged(nameof(HasAdditionalAction));
OnPropertyChanged(nameof(CanEmptyRecycleBin));
OnPropertyChanged(nameof(CanRestoreRecycleBin));
OnPropertyChanged(nameof(CanRestoreSelectionRecycleBin));
}
}
}
Expand All @@ -1222,6 +1233,8 @@ public List<ListedItem> SelectedItems
public bool CanRename => SelectedItems is not null && SelectedItems.Count == 1;
public bool CanViewProperties => SelectedItems is not null && SelectedItems.Any();
public bool CanEmptyRecycleBin => InstanceViewModel.IsPageTypeRecycleBin && HasItem;
public bool CanRestoreRecycleBin => InstanceViewModel.IsPageTypeRecycleBin && HasItem && (SelectedItems is null || SelectedItems.Count == 0);
public bool CanRestoreSelectionRecycleBin => InstanceViewModel.IsPageTypeRecycleBin && HasItem && SelectedItems is not null && SelectedItems.Count > 0;
public bool CanExtract => SelectedItems is not null && SelectedItems.Any() && SelectedItems.All(x => FileExtensionHelpers.IsZipFile(x.FileExtension)) && !InstanceViewModel.IsPageTypeRecycleBin;
public string ExtractToText => CanExtract ? SelectedItems.Count > 1 ? string.Format("ExtractToChildFolder".GetLocalizedResource(), $"*{Path.DirectorySeparatorChar}") : string.Format("ExtractToChildFolder".GetLocalizedResource() + "\\", Path.GetFileNameWithoutExtension(selectedItems.First().ItemName)) : "ExtractToChildFolder".GetLocalizedResource();
public bool IsMultipleArchivesSelected => CanExtract && SelectedItems.Count > 1;
Expand Down
2 changes: 2 additions & 0 deletions src/Files.App/Views/ColumnShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ private void InitToolbarCommands()
ToolbarViewModel.DeleteCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DeleteItemCommand.Execute(null));
ToolbarViewModel.CutCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.CutItemCommand.Execute(null));
ToolbarViewModel.EmptyRecycleBinCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.EmptyRecycleBinCommand.Execute(null));
ToolbarViewModel.RestoreRecycleBinCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.RestoreRecycleBinCommand.Execute(null));
ToolbarViewModel.RestoreSelectionRecycleBinCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.RestoreSelectionRecycleBinCommand.Execute(null));
ToolbarViewModel.RunWithPowerShellCommand = new RelayCommand(async () => await Win32Helpers.InvokeWin32ComponentAsync("powershell", this, PathNormalization.NormalizePath(SlimContentPage?.SelectedItem.ItemPath)));
ToolbarViewModel.PropertiesCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.ShowPropertiesCommand.Execute(null));
ToolbarViewModel.SetAsBackgroundCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.SetAsDesktopBackgroundItemCommand.Execute(null));
Expand Down
2 changes: 2 additions & 0 deletions src/Files.App/Views/ModernShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ private void InitToolbarCommands()
ToolbarViewModel.DeleteCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DeleteItemCommand.Execute(null));
ToolbarViewModel.CutCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.CutItemCommand.Execute(null));
ToolbarViewModel.EmptyRecycleBinCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.EmptyRecycleBinCommand.Execute(null));
ToolbarViewModel.RestoreRecycleBinCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.RestoreRecycleBinCommand.Execute(null));
ToolbarViewModel.RestoreSelectionRecycleBinCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.RestoreSelectionRecycleBinCommand.Execute(null));
ToolbarViewModel.RunWithPowerShellCommand = new RelayCommand(async () => await Win32Helpers.InvokeWin32ComponentAsync("powershell", this, PathNormalization.NormalizePath(SlimContentPage?.SelectedItem.ItemPath)));
ToolbarViewModel.PropertiesCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.ShowPropertiesCommand.Execute(null));
ToolbarViewModel.SetAsBackgroundCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.SetAsDesktopBackgroundItemCommand.Execute(null));
Expand Down