Skip to content

Feature: Added an option for "smart" extract #14205

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 1 commit into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Actions
{
internal sealed class DecompressArchiveHereSmart : BaseDecompressArchiveAction
{
public override string Label
=> "ExtractHereSmart".GetLocalizedResource();

public override string Description
=> "DecompressArchiveHereSmartDescription".GetLocalizedResource();

public override HotKey HotKey
=> new(Keys.E, KeyModifiers.CtrlShift);

public DecompressArchiveHereSmart()
{
}

public override Task ExecuteAsync()
{
return DecompressHelper.DecompressArchiveHereAsync(context.ShellPage, true);
}
}
}
1 change: 1 addition & 0 deletions src/Files.App/Data/Commands/CommandCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public enum CommandCodes
CompressIntoZip,
DecompressArchive,
DecompressArchiveHere,
DecompressArchiveHereSmart,
DecompressArchiveToChildFolder,

// Image Manipulation
Expand Down
2 changes: 2 additions & 0 deletions src/Files.App/Data/Commands/Manager/CommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public IRichCommand this[HotKey hotKey]
public IRichCommand CompressIntoZip => commands[CommandCodes.CompressIntoZip];
public IRichCommand DecompressArchive => commands[CommandCodes.DecompressArchive];
public IRichCommand DecompressArchiveHere => commands[CommandCodes.DecompressArchiveHere];
public IRichCommand DecompressArchiveHereSmart => commands[CommandCodes.DecompressArchiveHereSmart];
public IRichCommand DecompressArchiveToChildFolder => commands[CommandCodes.DecompressArchiveToChildFolder];
public IRichCommand RotateLeft => commands[CommandCodes.RotateLeft];
public IRichCommand RotateRight => commands[CommandCodes.RotateRight];
Expand Down Expand Up @@ -259,6 +260,7 @@ public CommandManager()
[CommandCodes.CompressIntoZip] = new CompressIntoZipAction(),
[CommandCodes.DecompressArchive] = new DecompressArchive(),
[CommandCodes.DecompressArchiveHere] = new DecompressArchiveHere(),
[CommandCodes.DecompressArchiveHereSmart] = new DecompressArchiveHereSmart(),
[CommandCodes.DecompressArchiveToChildFolder] = new DecompressArchiveToChildFolderAction(),
[CommandCodes.RotateLeft] = new RotateLeftAction(),
[CommandCodes.RotateRight] = new RotateRightAction(),
Expand Down
1 change: 1 addition & 0 deletions src/Files.App/Data/Commands/Manager/ICommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public interface ICommandManager : IEnumerable<IRichCommand>
IRichCommand CompressIntoZip { get; }
IRichCommand DecompressArchive { get; }
IRichCommand DecompressArchiveHere { get; }
IRichCommand DecompressArchiveHereSmart { get; }
IRichCommand DecompressArchiveToChildFolder { get; }

IRichCommand RotateLeft { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ public static List<ContextMenuFlyoutItemViewModel> GetBaseItemMenuItems(
Items = new List<ContextMenuFlyoutItemViewModel>
{
new ContextMenuFlyoutItemViewModelBuilder(commands.DecompressArchive).Build(),
new ContextMenuFlyoutItemViewModelBuilder(commands.DecompressArchiveHereSmart).Build(),
new ContextMenuFlyoutItemViewModelBuilder(commands.DecompressArchiveHere).Build(),
new ContextMenuFlyoutItemViewModelBuilder(commands.DecompressArchiveToChildFolder).Build(),
},
Expand Down
8 changes: 7 additions & 1 deletion src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -3638,4 +3638,10 @@
<data name="Login" xml:space="preserve">
<value>Login</value>
</data>
</root>
<data name="DecompressArchiveHereSmartDescription" xml:space="preserve">
<value>Extract items from selected archive(s) to current folder for single-item archive, or to new folder for multi-item archive</value>
</data>
<data name="ExtractHereSmart" xml:space="preserve">
<value>Extract here (Smart)</value>
</data>
</root>
7 changes: 7 additions & 0 deletions src/Files.App/UserControls/InnerNavigationToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,13 @@
KeyboardAcceleratorTextOverride="{x:Bind Commands.DecompressArchive.HotKeyText, Mode=OneWay}"
Text="{x:Bind Commands.DecompressArchive.Label}"
Visibility="{x:Bind ViewModel.IsMultipleArchivesSelected, Mode=OneWay, Converter={StaticResource NegatedBoolToVisibilityConverter}}" />
<MenuFlyoutItem
x:Name="ExtractHereSmart"
Command="{x:Bind Commands.DecompressArchiveHereSmart, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.IsSelectionArchivesOnly, Mode=OneWay, FallbackValue=False}"
KeyboardAcceleratorTextOverride="{x:Bind Commands.DecompressArchiveHereSmart.HotKeyText, Mode=OneWay}"
Text="{x:Bind Commands.DecompressArchiveHereSmart.Label}"
Visibility="{x:Bind ViewModel.IsArchiveOpened, Mode=OneWay, Converter={StaticResource NegatedBoolToVisibilityConverter}}" />
<MenuFlyoutItem
x:Name="ExtractHere"
Command="{x:Bind Commands.DecompressArchiveHere, Mode=OneWay}"
Expand Down
19 changes: 17 additions & 2 deletions src/Files.App/Utils/Archives/DecompressHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public static async Task DecompressArchiveAsync(IShellPage associatedInstance)
await NavigationHelpers.OpenPath(destinationFolderPath, associatedInstance, FilesystemItemType.Directory);
}

public static async Task DecompressArchiveHereAsync(IShellPage associatedInstance)
public static async Task DecompressArchiveHereAsync(IShellPage associatedInstance, bool smart = false)
{
if (associatedInstance?.SlimContentPage?.SelectedItems == null)
return;
Expand Down Expand Up @@ -210,7 +210,13 @@ public static async Task DecompressArchiveHereAsync(IShellPage associatedInstanc
password = Encoding.UTF8.GetString(decompressArchiveViewModel.Password);
}

await DecompressArchiveAsync(archive, currentFolder, password);
if (smart && currentFolder is not null && await FilesystemTasks.Wrap(() => IsMultipleItems(archive)))
{
var destinationFolder = await FilesystemTasks.Wrap(() => currentFolder.CreateFolderAsync(Path.GetFileNameWithoutExtension(archive.Path), CreationCollisionOption.GenerateUniqueName).AsTask());
await DecompressArchiveAsync(archive, destinationFolder, password);
}
else
await DecompressArchiveAsync(archive, currentFolder, password);
}
}

Expand Down Expand Up @@ -274,5 +280,14 @@ private static async Task<bool> IsArchiveEncrypted(BaseStorageFile archive)

return zipFile.ArchiveFileData.Any(file => file.Encrypted || file.Method.Contains("Crypto") || file.Method.Contains("AES"));
}

private static async Task<bool> IsMultipleItems(BaseStorageFile archive)
{
using SevenZipExtractor? zipFile = await GetZipFile(archive);
if (zipFile is null)
return true;

return zipFile.ArchiveFileData.Count > 1;
}
}
}