summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-07-03 20:54:53 +0200
committerAndreas Kling <kling@serenityos.org>2020-07-03 21:34:12 +0200
commitf7ef6c65b4ca843cf658e3a336dcdcd5755354cf (patch)
tree8d3752ae4d93e162bda2b4fa02752f406d11ebf0
parenteec22acb8e3a640f1d6a3020ef550aeb2c35cf20 (diff)
downloadserenity-f7ef6c65b4ca843cf658e3a336dcdcd5755354cf.zip
LibWeb: Add a "select all" action to the Web::PageView
This works by finding the very first and very last LayoutText nodes in the layout tree and then setting the selection bounds to those two nodes. For some reason it gets glitchy if we set the very first and very last *LayoutNode* as the selection bounds, but I didn't feel like investigating that too closely right now.
-rw-r--r--Libraries/LibWeb/PageView.cpp39
-rw-r--r--Libraries/LibWeb/PageView.h4
2 files changed, 43 insertions, 0 deletions
diff --git a/Libraries/LibWeb/PageView.cpp b/Libraries/LibWeb/PageView.cpp
index ac82db9e8e..0bce94c408 100644
--- a/Libraries/LibWeb/PageView.cpp
+++ b/Libraries/LibWeb/PageView.cpp
@@ -67,12 +67,51 @@ PageView::PageView()
m_copy_action = GUI::CommonActions::make_copy_action([this](auto&) {
GUI::Clipboard::the().set_data(selected_text(), "text/plain");
});
+
+ m_select_all_action = GUI::CommonActions::make_select_all_action([this](auto&) {
+ select_all();
+ });
}
PageView::~PageView()
{
}
+void PageView::select_all()
+{
+ auto* layout_root = this->layout_root();
+ if (!layout_root)
+ return;
+
+ const LayoutNode* first_layout_node = layout_root;
+
+ for (;;) {
+ auto* next = first_layout_node->next_in_pre_order();
+ if (!next)
+ break;
+ first_layout_node = next;
+ if (is<LayoutText>(*first_layout_node))
+ break;
+ }
+
+ const LayoutNode* last_layout_node = first_layout_node;
+
+ for (const LayoutNode* layout_node = first_layout_node; layout_node; layout_node = layout_node->next_in_pre_order()) {
+ if (is<LayoutText>(*layout_node))
+ last_layout_node = layout_node;
+ }
+
+ ASSERT(first_layout_node);
+ ASSERT(last_layout_node);
+
+ int last_layout_node_index_in_node = 0;
+ if (is<LayoutText>(*last_layout_node))
+ last_layout_node_index_in_node = to<LayoutText>(*last_layout_node).text_for_rendering().length() - 1;
+
+ layout_root->selection().set({ first_layout_node, 0 }, { last_layout_node, last_layout_node_index_in_node });
+ update();
+}
+
String PageView::selected_text() const
{
StringBuilder builder;
diff --git a/Libraries/LibWeb/PageView.h b/Libraries/LibWeb/PageView.h
index e45900fa1a..4bcb7db072 100644
--- a/Libraries/LibWeb/PageView.h
+++ b/Libraries/LibWeb/PageView.h
@@ -73,8 +73,11 @@ public:
virtual bool accepts_focus() const override { return true; }
+ GUI::Action& select_all_action() { return *m_select_all_action; }
GUI::Action& copy_action() { return *m_copy_action; }
+
String selected_text() const;
+ void select_all();
private:
PageView();
@@ -119,6 +122,7 @@ private:
NonnullOwnPtr<Page> m_page;
RefPtr<GUI::Action> m_copy_action;
+ RefPtr<GUI::Action> m_select_all_action;
};
}