From 87bfb47d1f1c0bb8b53a190a8063ce1a22bb4e6f Mon Sep 17 00:00:00 2001 From: Caoimhe Date: Sat, 18 Mar 2023 00:15:16 +0000 Subject: [PATCH] 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. --- Base/res/apps/FileManager.af | 3 +++ Userland/Applications/FileManager/main.cpp | 31 ++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Base/res/apps/FileManager.af b/Base/res/apps/FileManager.af index 75be86b29a..aafaa44d95 100644 --- a/Base/res/apps/FileManager.af +++ b/Base/res/apps/FileManager.af @@ -2,3 +2,6 @@ Name=File Manager Executable=/bin/FileManager Category=Utilities + +[Launcher] +FileTypes=zip diff --git a/Userland/Applications/FileManager/main.cpp b/Userland/Applications/FileManager/main.cpp index 341c2103c2..6e67a5d90a 100644 --- a/Userland/Applications/FileManager/main.cpp +++ b/Userland/Applications/FileManager/main.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -105,12 +106,39 @@ ErrorOr 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 serenity_main(Main::Arguments arguments) DeprecatedString focused_entry; if (is_selection_mode) { - LexicalPath path(initial_location); initial_location = path.dirname(); focused_entry = path.basename(); }