Skip to content

Commit

Permalink
Feature: Added an option for "smart" extract (files-community#14205)
Browse files Browse the repository at this point in the history
  • Loading branch information
hishitetsu authored Dec 10, 2023
1 parent 0ccf13e commit 3340637
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 3 deletions.
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;
}
}
}

0 comments on commit 3340637

Please sign in to comment.