diff options
author | Timothy Flynn <trflynn89@pm.me> | 2023-05-16 07:56:12 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-05-16 19:47:18 +0200 |
commit | b0edc7b6e4785f0754560dbcc1f5294bc31654cb (patch) | |
tree | f1ad2b378ad9456e879304f5eed1bece2bbad0fa | |
parent | 374284d0d8ac81aa1949c4fc5a52854a33f4898b (diff) | |
download | serenity-b0edc7b6e4785f0754560dbcc1f5294bc31654cb.zip |
Ladybird: Add screenshot actions to the page context menu
Browser on Serenity has these actions already.
-rw-r--r-- | Ladybird/Tab.cpp | 53 | ||||
-rw-r--r-- | Ladybird/Tab.h | 6 | ||||
-rw-r--r-- | Ladybird/WebContentView.cpp | 12 | ||||
-rw-r--r-- | Ladybird/WebContentView.h | 3 |
4 files changed, 74 insertions, 0 deletions
diff --git a/Ladybird/Tab.cpp b/Ladybird/Tab.cpp index ee19ef1593..26186eff59 100644 --- a/Ladybird/Tab.cpp +++ b/Ladybird/Tab.cpp @@ -9,8 +9,12 @@ #include "BrowserWindow.h" #include "Settings.h" #include "Utilities.h" +#include <AK/LexicalPath.h> #include <Browser/History.h> +#include <LibCore/DateTime.h> +#include <LibCore/StandardPaths.h> #include <LibGfx/ImageFormats/BMPWriter.h> +#include <LibGfx/ImageFormats/PNGWriter.h> #include <QClipboard> #include <QCoreApplication> #include <QFont> @@ -18,6 +22,7 @@ #include <QGuiApplication> #include <QImage> #include <QMenu> +#include <QMessageBox> #include <QPainter> #include <QPlainTextEdit> #include <QPoint> @@ -183,6 +188,24 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView:: return Gfx::IntRect { m_window->x(), m_window->y(), m_window->width(), m_window->height() }; }); + auto* take_visible_screenshot_action = new QAction("Take &Visible Screenshot", this); + take_visible_screenshot_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-image.png").arg(s_serenity_resource_root.characters()))); + QObject::connect(take_visible_screenshot_action, &QAction::triggered, this, [this]() { + if (auto result = take_screenshot(ScreenshotType::Visible); result.is_error()) { + auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors(); + QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error)); + } + }); + + auto* take_full_screenshot_action = new QAction("Take &Full Screenshot", this); + take_full_screenshot_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-image.png").arg(s_serenity_resource_root.characters()))); + QObject::connect(take_full_screenshot_action, &QAction::triggered, this, [this]() { + if (auto result = take_screenshot(ScreenshotType::Full); result.is_error()) { + auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors(); + QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error)); + } + }); + m_page_context_menu = make<QMenu>("Context menu", this); m_page_context_menu->addAction(&m_window->go_back_action()); m_page_context_menu->addAction(&m_window->go_forward_action()); @@ -191,6 +214,9 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView:: m_page_context_menu->addAction(&m_window->copy_selection_action()); m_page_context_menu->addAction(&m_window->select_all_action()); m_page_context_menu->addSeparator(); + m_page_context_menu->addAction(take_visible_screenshot_action); + m_page_context_menu->addAction(take_full_screenshot_action); + m_page_context_menu->addSeparator(); m_page_context_menu->addAction(&m_window->view_source_action()); m_page_context_menu->addAction(&m_window->inspect_dom_node_action()); @@ -424,6 +450,33 @@ void Tab::copy_link_url(URL const& url) clipboard->setText(qstring_from_ak_deprecated_string(url.to_deprecated_string())); } +ErrorOr<void> Tab::take_screenshot(ScreenshotType type) +{ + Gfx::ShareableBitmap bitmap; + + switch (type) { + case ScreenshotType::Visible: + bitmap = view().take_screenshot(); + break; + case ScreenshotType::Full: + bitmap = view().take_document_screenshot(); + break; + } + + if (!bitmap.is_valid()) + return Error::from_string_view("Failed to take a screenshot of the current tab"sv); + + LexicalPath path { Core::StandardPaths::downloads_directory() }; + path = path.append(TRY(Core::DateTime::now().to_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv))); + + auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap())); + + auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write)); + TRY(screenshot_file->write_until_depleted(encoded)); + + return {}; +} + void Tab::location_edit_return_pressed() { navigate(m_location_edit->text()); diff --git a/Ladybird/Tab.h b/Ladybird/Tab.h index 77598303dc..0f313681d0 100644 --- a/Ladybird/Tab.h +++ b/Ladybird/Tab.h @@ -60,6 +60,12 @@ private: void open_link_in_new_tab(URL const&); void copy_link_url(URL const&); + enum class ScreenshotType { + Visible, + Full, + }; + ErrorOr<void> take_screenshot(ScreenshotType); + QBoxLayout* m_layout; QToolBar* m_toolbar { nullptr }; QToolButton* m_reset_zoom_button { nullptr }; diff --git a/Ladybird/WebContentView.cpp b/Ladybird/WebContentView.cpp index e1470f4205..a09ac93458 100644 --- a/Ladybird/WebContentView.cpp +++ b/Ladybird/WebContentView.cpp @@ -637,6 +637,18 @@ void WebContentView::create_client(WebView::EnableCallgrindProfiling enable_call client().async_connect_to_webdriver(m_webdriver_content_ipc_path); } +Gfx::ShareableBitmap WebContentView::take_screenshot() const +{ + if (auto* bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr()) + return bitmap->to_shareable_bitmap(); + return {}; +} + +Gfx::ShareableBitmap WebContentView::take_document_screenshot() +{ + return client().take_document_screenshot(); +} + void WebContentView::handle_web_content_process_crash() { dbgln("WebContent process crashed!"); diff --git a/Ladybird/WebContentView.h b/Ladybird/WebContentView.h index 0d96d15f1b..9ac0bc9837 100644 --- a/Ladybird/WebContentView.h +++ b/Ladybird/WebContentView.h @@ -113,6 +113,9 @@ public: Gfx::IntPoint to_content(Gfx::IntPoint) const; Gfx::IntPoint to_widget(Gfx::IntPoint) const; + Gfx::ShareableBitmap take_screenshot() const; + Gfx::ShareableBitmap take_document_screenshot(); + enum class PaletteMode { Default, Dark, |