diff --git a/Userland/Applications/Magnifier/CMakeLists.txt b/Userland/Applications/Magnifier/CMakeLists.txt index 1aad903524..caf2a97e95 100644 --- a/Userland/Applications/Magnifier/CMakeLists.txt +++ b/Userland/Applications/Magnifier/CMakeLists.txt @@ -11,4 +11,4 @@ set(SOURCES ) serenity_app(Magnifier ICON app-magnifier) -target_link_libraries(Magnifier LibGfx LibGUI LibMain) +target_link_libraries(Magnifier LibGfx LibGUI LibMain LibFileSystemAccessClient) diff --git a/Userland/Applications/Magnifier/MagnifierWidget.h b/Userland/Applications/Magnifier/MagnifierWidget.h index b19b991f16..8e3c6a5a78 100644 --- a/Userland/Applications/Magnifier/MagnifierWidget.h +++ b/Userland/Applications/Magnifier/MagnifierWidget.h @@ -18,6 +18,7 @@ public: virtual ~MagnifierWidget() override = default; void set_scale_factor(int scale_factor); void set_color_filter(OwnPtr); + void pause_capture(bool pause) { m_pause_capture = pause; @@ -26,6 +27,7 @@ public: } void display_previous_frame(); void display_next_frame(); + RefPtr current_bitmap() const { return m_grabbed_bitmap; }; private: MagnifierWidget(); diff --git a/Userland/Applications/Magnifier/main.cpp b/Userland/Applications/Magnifier/main.cpp index 47bf2926ce..20010c4acf 100644 --- a/Userland/Applications/Magnifier/main.cpp +++ b/Userland/Applications/Magnifier/main.cpp @@ -5,23 +5,43 @@ */ #include "MagnifierWidget.h" +#include #include +#include #include #include #include #include #include +#include #include +#include #include +#include +#include #include +static ErrorOr dump_bitmap(RefPtr bitmap, AK::StringView extension) +{ + if (extension == "bmp") { + Gfx::BMPWriter dumper; + return dumper.dump(bitmap); + } else if (extension == "png") { + return Gfx::PNGWriter::encode(*bitmap); + } else if (extension == "qoi") { + return Gfx::QOIWriter::encode(*bitmap); + } else { + return Error::from_string_literal("invalid image format"); + } +} + ErrorOr serenity_main(Main::Arguments arguments) { TRY(Core::System::pledge("stdio cpath rpath recvfd sendfd unix")); auto app = TRY(GUI::Application::try_create(arguments)); - TRY(Core::System::pledge("stdio cpath rpath recvfd sendfd")); TRY(Core::System::unveil("/res", "r")); + TRY(Core::System::unveil("/tmp/user/%uid/portal/filesystemaccess", "rw")); TRY(Core::System::unveil(nullptr, nullptr)); auto app_icon = GUI::Icon::default_icon("app-magnifier"sv); @@ -40,6 +60,27 @@ ErrorOr serenity_main(Main::Arguments arguments) app->quit(); }))); + TRY(file_menu->try_add_action(GUI::CommonActions::make_save_as_action([&](auto&) { + AK::String filename = "file for saving"; + auto do_save = [&]() -> ErrorOr { + auto file = TRY(FileSystemAccessClient::Client::the().try_save_file(window, "Capture", "png")); + auto path = AK::LexicalPath(file->filename()); + filename = path.basename(); + auto encoded = TRY(dump_bitmap(magnifier->current_bitmap(), path.extension())); + + if (!file->write(encoded.data(), encoded.size())) { + return Error::from_errno(file->error()); + } + return {}; + }; + + auto result = do_save(); + if (result.is_error()) { + GUI::MessageBox::show(window, "Unable to save file.\n"sv, "Error"sv, GUI::MessageBox::Type::Error); + warnln("Error saving bitmap to {}: {}", filename, result.error().string_literal()); + } + }))); + auto size_action_group = make(); auto two_x_action = GUI::Action::create_checkable(