FileManager: Extract .zip files to a temporary folder when opened

Prior to this commit, when you double-click a .zip file to open it, it
gets opened in Text-Editor as there is no other file association.

Now, when FileManager is invoked with a .zip file as the first argument,
a temporary directory will be created and the .zip will be extracted
into it. Once the FileManager window is closed, Core::TempFile will
delete the temporary directory.

This adds something like what we see in other operating systems' file
explorers, except for the fact that most other operating systems will
treat the .zip file as its own independent read-only filesystem. It
would be nice to do that in the future, but I feel like this is
sufficient for now.
This commit is contained in:
Caoimhe 2023-03-18 00:15:16 +00:00 committed by Linus Groh
parent de18485a2f
commit 87bfb47d1f
2 changed files with 32 additions and 2 deletions

View file

@ -2,3 +2,6 @@
Name=File Manager
Executable=/bin/FileManager
Category=Utilities
[Launcher]
FileTypes=zip

View file

@ -23,6 +23,7 @@
#include <LibCore/Process.h>
#include <LibCore/StandardPaths.h>
#include <LibCore/System.h>
#include <LibCore/TempFile.h>
#include <LibDesktop/Launcher.h>
#include <LibGUI/Action.h>
#include <LibGUI/ActionGroup.h>
@ -105,12 +106,39 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
// 3. the user's home directory
// 4. the root directory
LexicalPath path(initial_location);
if (!initial_location.is_empty()) {
if (!ignore_path_resolution)
initial_location = Core::DeprecatedFile::real_path_for(initial_location);
if (!Core::DeprecatedFile::is_directory(initial_location))
if (!Core::DeprecatedFile::is_directory(initial_location)) {
// We want to extract zips to a temporary directory when FileManager is launched with a .zip file as its first argument
if (path.has_extension(".zip"sv)) {
auto temp_directory = Core::TempFile::create_temp_directory();
if (temp_directory.is_error()) {
dbgln("Failed to create temporary directory during zip extraction: {}", temp_directory.error());
GUI::MessageBox::show_error(app->active_window(), "Failed to create temporary directory!"sv);
return -1;
}
auto temp_directory_path = temp_directory.value()->path();
auto result = Core::Process::spawn("/bin/unzip"sv, Array { "-d"sv, temp_directory_path, initial_location });
if (result.is_error()) {
dbgln("Failed to extract {} to {}: {}", initial_location, temp_directory_path, result.error());
auto message = TRY(String::formatted("Failed to extract {} to {}", initial_location, temp_directory_path));
GUI::MessageBox::show_error(app->active_window(), message);
return -1;
}
return run_in_windowed_mode(temp_directory_path.to_deprecated_string(), path.basename());
}
is_selection_mode = true;
}
}
if (initial_location.is_empty())
@ -124,7 +152,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
DeprecatedString focused_entry;
if (is_selection_mode) {
LexicalPath path(initial_location);
initial_location = path.dirname();
focused_entry = path.basename();
}