소스 검색

Browser: Add a context menu item to take a screenshot of the current tab

Timothy Flynn 2 년 전
부모
커밋
ce8c34a8c9
3개의 변경된 파일37개의 추가작업 그리고 0개의 파일을 삭제
  1. 31 0
      Userland/Applications/Browser/BrowserWindow.cpp
  2. 4 0
      Userland/Applications/Browser/BrowserWindow.h
  3. 2 0
      Userland/Applications/Browser/Tab.cpp

+ 31 - 0
Userland/Applications/Browser/BrowserWindow.cpp

@@ -14,8 +14,10 @@
 #include "CookieJar.h"
 #include "InspectorWidget.h"
 #include "Tab.h"
+#include <AK/LexicalPath.h>
 #include <Applications/Browser/BrowserWindowGML.h>
 #include <LibConfig/Client.h>
+#include <LibCore/DateTime.h>
 #include <LibCore/StandardPaths.h>
 #include <LibCore/Stream.h>
 #include <LibCore/Version.h>
@@ -33,6 +35,7 @@
 #include <LibGUI/TabWidget.h>
 #include <LibGUI/ToolbarContainer.h>
 #include <LibGUI/Widget.h>
+#include <LibGfx/PNGWriter.h>
 #include <LibJS/Interpreter.h>
 #include <LibWeb/CSS/PreferredColorScheme.h>
 #include <LibWeb/Dump.h>
@@ -240,6 +243,14 @@ void BrowserWindow::build_menus()
         this);
     m_inspect_dom_node_action->set_status_tip("Open inspector for this element");
 
+    m_take_screenshot_action = GUI::Action::create(
+        "&Take Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) {
+            if (auto result = take_screenshot(); result.is_error())
+                GUI::MessageBox::show_error(this, String::formatted("{}", result.error()));
+        },
+        this);
+    m_take_screenshot_action->set_status_tip("Save a screenshot of the current tab to the Downloads directory"sv);
+
     auto& inspect_menu = add_menu("&Inspect");
     inspect_menu.add_action(*m_view_source_action);
     inspect_menu.add_action(*m_inspect_dom_tree_action);
@@ -718,4 +729,24 @@ void BrowserWindow::event(Core::Event& event)
     Window::event(event);
 }
 
+ErrorOr<void> BrowserWindow::take_screenshot()
+{
+    if (!active_tab().on_take_screenshot)
+        return {};
+
+    auto bitmap = active_tab().on_take_screenshot();
+    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(Core::DateTime::now().to_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv));
+
+    auto encoded = Gfx::PNGWriter::encode(*bitmap.bitmap());
+
+    auto screenshot_file = TRY(Core::Stream::File::open(path.string(), Core::Stream::OpenMode::Write));
+    TRY(screenshot_file->write(encoded));
+
+    return {};
+}
+
 }

+ 4 - 0
Userland/Applications/Browser/BrowserWindow.h

@@ -39,6 +39,7 @@ public:
     GUI::Action& view_source_action() { return *m_view_source_action; }
     GUI::Action& inspect_dom_tree_action() { return *m_inspect_dom_tree_action; }
     GUI::Action& inspect_dom_node_action() { return *m_inspect_dom_node_action; }
+    GUI::Action& take_screenshot_action() { return *m_take_screenshot_action; }
 
     void content_filters_changed();
     void proxy_mappings_changed();
@@ -58,6 +59,8 @@ private:
 
     virtual void event(Core::Event&) override;
 
+    ErrorOr<void> take_screenshot();
+
     RefPtr<GUI::Action> m_go_back_action;
     RefPtr<GUI::Action> m_go_forward_action;
     RefPtr<GUI::Action> m_go_home_action;
@@ -67,6 +70,7 @@ private:
     RefPtr<GUI::Action> m_view_source_action;
     RefPtr<GUI::Action> m_inspect_dom_tree_action;
     RefPtr<GUI::Action> m_inspect_dom_node_action;
+    RefPtr<GUI::Action> m_take_screenshot_action;
 
     CookieJar& m_cookie_jar;
     WindowActions m_window_actions;

+ 2 - 0
Userland/Applications/Browser/Tab.cpp

@@ -404,6 +404,8 @@ Tab::Tab(BrowserWindow& window)
     m_page_context_menu->add_action(window.view_source_action());
     m_page_context_menu->add_action(window.inspect_dom_tree_action());
     m_page_context_menu->add_action(window.inspect_dom_node_action());
+    m_page_context_menu->add_separator();
+    m_page_context_menu->add_action(window.take_screenshot_action());
     view().on_context_menu_request = [&](auto& screen_position) {
         m_page_context_menu->popup(screen_position);
     };