mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-03 08:08:43 +00:00
Ladybird/Qt: Add a find in page widget
This commit is contained in:
parent
7aea87c9df
commit
389a55fe36
Notes:
sideshowbarker
2024-07-17 18:23:22 +09:00
Author: https://github.com/tcl3
Commit: 389a55fe36
Pull-request: https://github.com/SerenityOS/serenity/pull/24480
Reviewed-by: https://github.com/awesomekling
10 changed files with 199 additions and 2 deletions
|
@ -115,6 +115,7 @@ if (ENABLE_QT)
|
||||||
Qt/BrowserWindow.cpp
|
Qt/BrowserWindow.cpp
|
||||||
Qt/EventLoopImplementationQt.cpp
|
Qt/EventLoopImplementationQt.cpp
|
||||||
Qt/EventLoopImplementationQtEventTarget.cpp
|
Qt/EventLoopImplementationQtEventTarget.cpp
|
||||||
|
Qt/FindInPageWidget.cpp
|
||||||
Qt/Icon.cpp
|
Qt/Icon.cpp
|
||||||
Qt/InspectorWidget.cpp
|
Qt/InspectorWidget.cpp
|
||||||
Qt/LocationEdit.cpp
|
Qt/LocationEdit.cpp
|
||||||
|
|
BIN
Ladybird/Icons/down.tvg
Normal file
BIN
Ladybird/Icons/down.tvg
Normal file
Binary file not shown.
BIN
Ladybird/Icons/up.tvg
Normal file
BIN
Ladybird/Icons/up.tvg
Normal file
Binary file not shown.
|
@ -152,6 +152,15 @@ BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, WebView::Cook
|
||||||
|
|
||||||
edit_menu->addSeparator();
|
edit_menu->addSeparator();
|
||||||
|
|
||||||
|
m_find_in_page_action = new QAction("&Find in Page...", this);
|
||||||
|
m_find_in_page_action->setIcon(load_icon_from_uri("resource://icons/16x16/find.png"sv));
|
||||||
|
m_find_in_page_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Find));
|
||||||
|
|
||||||
|
edit_menu->addAction(m_find_in_page_action);
|
||||||
|
QObject::connect(m_find_in_page_action, &QAction::triggered, this, &BrowserWindow::show_find_in_page);
|
||||||
|
|
||||||
|
edit_menu->addSeparator();
|
||||||
|
|
||||||
auto* settings_action = new QAction("&Settings", this);
|
auto* settings_action = new QAction("&Settings", this);
|
||||||
settings_action->setIcon(load_icon_from_uri("resource://icons/16x16/settings.png"sv));
|
settings_action->setIcon(load_icon_from_uri("resource://icons/16x16/settings.png"sv));
|
||||||
settings_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Preferences));
|
settings_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Preferences));
|
||||||
|
@ -894,6 +903,14 @@ void BrowserWindow::select_all()
|
||||||
m_current_tab->view().select_all();
|
m_current_tab->view().select_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::show_find_in_page()
|
||||||
|
{
|
||||||
|
if (!m_current_tab)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_current_tab->show_find_in_page();
|
||||||
|
}
|
||||||
|
|
||||||
void BrowserWindow::paste()
|
void BrowserWindow::paste()
|
||||||
{
|
{
|
||||||
if (!m_current_tab)
|
if (!m_current_tab)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tab.h"
|
#include "Tab.h"
|
||||||
|
#include <Ladybird/Qt/FindInPageWidget.h>
|
||||||
#include <Ladybird/Types.h>
|
#include <Ladybird/Types.h>
|
||||||
#include <LibCore/Forward.h>
|
#include <LibCore/Forward.h>
|
||||||
#include <LibWeb/HTML/ActivateTab.h>
|
#include <LibWeb/HTML/ActivateTab.h>
|
||||||
|
@ -78,6 +79,11 @@ public:
|
||||||
return *m_select_all_action;
|
return *m_select_all_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAction& find_action()
|
||||||
|
{
|
||||||
|
return *m_find_in_page_action;
|
||||||
|
}
|
||||||
|
|
||||||
QAction& paste_action()
|
QAction& paste_action()
|
||||||
{
|
{
|
||||||
return *m_paste_action;
|
return *m_paste_action;
|
||||||
|
@ -119,6 +125,7 @@ public slots:
|
||||||
void reset_zoom();
|
void reset_zoom();
|
||||||
void update_zoom_menu();
|
void update_zoom_menu();
|
||||||
void select_all();
|
void select_all();
|
||||||
|
void show_find_in_page();
|
||||||
void paste();
|
void paste();
|
||||||
void copy_selected_text();
|
void copy_selected_text();
|
||||||
|
|
||||||
|
@ -172,6 +179,7 @@ private:
|
||||||
QAction* m_copy_selection_action { nullptr };
|
QAction* m_copy_selection_action { nullptr };
|
||||||
QAction* m_paste_action { nullptr };
|
QAction* m_paste_action { nullptr };
|
||||||
QAction* m_select_all_action { nullptr };
|
QAction* m_select_all_action { nullptr };
|
||||||
|
QAction* m_find_in_page_action { nullptr };
|
||||||
QAction* m_view_source_action { nullptr };
|
QAction* m_view_source_action { nullptr };
|
||||||
QAction* m_inspect_dom_node_action { nullptr };
|
QAction* m_inspect_dom_node_action { nullptr };
|
||||||
|
|
||||||
|
|
104
Ladybird/Qt/FindInPageWidget.cpp
Normal file
104
Ladybird/Qt/FindInPageWidget.cpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FindInPageWidget.h"
|
||||||
|
#include "Icon.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
#include <Ladybird/Qt/Tab.h>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
|
||||||
|
namespace Ladybird {
|
||||||
|
|
||||||
|
FindInPageWidget::FindInPageWidget(Tab* tab, WebContentView* content_view)
|
||||||
|
: QWidget(static_cast<QWidget*>(tab), Qt::Widget)
|
||||||
|
, m_tab(tab)
|
||||||
|
, m_content_view(content_view)
|
||||||
|
{
|
||||||
|
setFocusPolicy(Qt::FocusPolicy::StrongFocus);
|
||||||
|
|
||||||
|
auto* layout = new QHBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
layout->setContentsMargins(5, 5, 5, 5);
|
||||||
|
layout->setAlignment(Qt::AlignmentFlag::AlignLeft);
|
||||||
|
|
||||||
|
m_find_text = new QLineEdit(this);
|
||||||
|
m_find_text->setFocusPolicy(Qt::FocusPolicy::StrongFocus);
|
||||||
|
m_find_text->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);
|
||||||
|
m_find_text->setMinimumWidth(50);
|
||||||
|
m_find_text->setMaximumWidth(250);
|
||||||
|
connect(m_find_text, &QLineEdit::textChanged, this, &FindInPageWidget::find_text_changed);
|
||||||
|
|
||||||
|
m_previous_button = new QPushButton(this);
|
||||||
|
m_previous_button->setFixedWidth(30);
|
||||||
|
m_previous_button->setIcon(create_tvg_icon_with_theme_colors("up", palette()));
|
||||||
|
connect(m_previous_button, &QPushButton::clicked, this, [this] {
|
||||||
|
m_content_view->find_in_page_previous_match();
|
||||||
|
});
|
||||||
|
|
||||||
|
m_next_button = new QPushButton(this);
|
||||||
|
m_next_button->setFixedWidth(30);
|
||||||
|
m_next_button->setIcon(create_tvg_icon_with_theme_colors("down", palette()));
|
||||||
|
connect(m_next_button, &QPushButton::clicked, this, [this] {
|
||||||
|
m_content_view->find_in_page_next_match();
|
||||||
|
});
|
||||||
|
|
||||||
|
m_exit_button = new QPushButton(this);
|
||||||
|
m_exit_button->setFixedWidth(30);
|
||||||
|
m_exit_button->setIcon(create_tvg_icon_with_theme_colors("close", palette()));
|
||||||
|
connect(m_exit_button, &QPushButton::clicked, this, [this] {
|
||||||
|
setVisible(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
layout->addWidget(m_find_text, 1);
|
||||||
|
layout->addWidget(m_previous_button);
|
||||||
|
layout->addWidget(m_next_button);
|
||||||
|
layout->addStretch(1);
|
||||||
|
layout->addWidget(m_exit_button);
|
||||||
|
}
|
||||||
|
|
||||||
|
FindInPageWidget::~FindInPageWidget() = default;
|
||||||
|
|
||||||
|
void FindInPageWidget::find_text_changed()
|
||||||
|
{
|
||||||
|
auto converted_text = ak_string_from_qstring(m_find_text->text());
|
||||||
|
m_content_view->find_in_page(converted_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindInPageWidget::keyPressEvent(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
switch (event->key()) {
|
||||||
|
case Qt::Key_Escape:
|
||||||
|
setVisible(false);
|
||||||
|
break;
|
||||||
|
case Qt::Key_Return:
|
||||||
|
m_next_button->click();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
event->ignore();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindInPageWidget::focusInEvent(QFocusEvent* event)
|
||||||
|
{
|
||||||
|
QWidget::focusInEvent(event);
|
||||||
|
m_find_text->setFocus();
|
||||||
|
m_find_text->selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindInPageWidget::showEvent(QShowEvent*)
|
||||||
|
{
|
||||||
|
if (m_tab && m_tab->isVisible())
|
||||||
|
m_tab->update_hover_label();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindInPageWidget::hideEvent(QHideEvent*)
|
||||||
|
{
|
||||||
|
if (m_tab && m_tab->isVisible())
|
||||||
|
m_tab->update_hover_label();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
Ladybird/Qt/FindInPageWidget.h
Normal file
47
Ladybird/Qt/FindInPageWidget.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WebContentView.h"
|
||||||
|
#include <LibWebView/Forward.h>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace Ladybird {
|
||||||
|
|
||||||
|
class WebContentView;
|
||||||
|
|
||||||
|
class FindInPageWidget final : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FindInPageWidget(Tab* tab, WebContentView* content_view);
|
||||||
|
|
||||||
|
virtual ~FindInPageWidget() override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void keyPressEvent(QKeyEvent*) override;
|
||||||
|
virtual void focusInEvent(QFocusEvent*) override;
|
||||||
|
virtual void showEvent(QShowEvent*) override;
|
||||||
|
virtual void hideEvent(QHideEvent*) override;
|
||||||
|
|
||||||
|
void find_text_changed();
|
||||||
|
|
||||||
|
Tab* m_tab { nullptr };
|
||||||
|
WebContentView* m_content_view { nullptr };
|
||||||
|
|
||||||
|
QLineEdit* m_find_text { nullptr };
|
||||||
|
QPushButton* m_previous_button { nullptr };
|
||||||
|
QPushButton* m_next_button { nullptr };
|
||||||
|
QPushButton* m_exit_button { nullptr };
|
||||||
|
QAction* m_copy_attribute_value_action { nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -56,6 +56,8 @@ Tab::Tab(BrowserWindow* window, WebContentOptions const& web_content_options, St
|
||||||
m_layout->setContentsMargins(0, 0, 0, 0);
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
m_view = new WebContentView(this, web_content_options, webdriver_content_ipc_path, parent_client, page_index);
|
m_view = new WebContentView(this, web_content_options, webdriver_content_ipc_path, parent_client, page_index);
|
||||||
|
m_find_in_page = new FindInPageWidget(this, m_view);
|
||||||
|
m_find_in_page->setVisible(false);
|
||||||
m_toolbar = new QToolBar(this);
|
m_toolbar = new QToolBar(this);
|
||||||
m_location_edit = new LocationEdit(this);
|
m_location_edit = new LocationEdit(this);
|
||||||
|
|
||||||
|
@ -70,6 +72,7 @@ Tab::Tab(BrowserWindow* window, WebContentOptions const& web_content_options, St
|
||||||
|
|
||||||
m_layout->addWidget(m_toolbar);
|
m_layout->addWidget(m_toolbar);
|
||||||
m_layout->addWidget(m_view);
|
m_layout->addWidget(m_view);
|
||||||
|
m_layout->addWidget(m_find_in_page);
|
||||||
|
|
||||||
m_hamburger_button = new QToolButton(m_toolbar);
|
m_hamburger_button = new QToolButton(m_toolbar);
|
||||||
m_hamburger_button->setText("Show &Menu");
|
m_hamburger_button->setText("Show &Menu");
|
||||||
|
@ -887,7 +890,11 @@ void Tab::resizeEvent(QResizeEvent* event)
|
||||||
void Tab::update_hover_label()
|
void Tab::update_hover_label()
|
||||||
{
|
{
|
||||||
m_hover_label->resize(QFontMetrics(m_hover_label->font()).boundingRect(m_hover_label->text()).adjusted(-4, -2, 4, 2).size());
|
m_hover_label->resize(QFontMetrics(m_hover_label->font()).boundingRect(m_hover_label->text()).adjusted(-4, -2, 4, 2).size());
|
||||||
m_hover_label->move(6, height() - m_hover_label->height() - 8);
|
auto hover_label_height = height() - m_hover_label->height() - 8;
|
||||||
|
if (m_find_in_page->isVisible())
|
||||||
|
hover_label_height -= m_find_in_page->height() - 4;
|
||||||
|
|
||||||
|
m_hover_label->move(6, hover_label_height);
|
||||||
m_hover_label->raise();
|
m_hover_label->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -933,6 +940,12 @@ void Tab::show_inspector_window(InspectorTarget inspector_target)
|
||||||
m_inspector_widget->select_default_node();
|
m_inspector_widget->select_default_node();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tab::show_find_in_page()
|
||||||
|
{
|
||||||
|
m_find_in_page->setVisible(true);
|
||||||
|
m_find_in_page->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
void Tab::close_sub_widgets()
|
void Tab::close_sub_widgets()
|
||||||
{
|
{
|
||||||
auto close_widget_window = [](auto* widget) {
|
auto close_widget_window = [](auto* widget) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "LocationEdit.h"
|
#include "LocationEdit.h"
|
||||||
#include "WebContentView.h"
|
#include "WebContentView.h"
|
||||||
|
#include <Ladybird/Qt/FindInPageWidget.h>
|
||||||
#include <LibWeb/HTML/AudioPlayState.h>
|
#include <LibWeb/HTML/AudioPlayState.h>
|
||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
@ -51,6 +52,8 @@ public:
|
||||||
};
|
};
|
||||||
void show_inspector_window(InspectorTarget = InspectorTarget::Document);
|
void show_inspector_window(InspectorTarget = InspectorTarget::Document);
|
||||||
|
|
||||||
|
void show_find_in_page();
|
||||||
|
|
||||||
QIcon const& favicon() const { return m_favicon; }
|
QIcon const& favicon() const { return m_favicon; }
|
||||||
QString const& title() const { return m_title; }
|
QString const& title() const { return m_title; }
|
||||||
|
|
||||||
|
@ -60,6 +63,8 @@ public:
|
||||||
|
|
||||||
QToolButton* hamburger_button() const { return m_hamburger_button; }
|
QToolButton* hamburger_button() const { return m_hamburger_button; }
|
||||||
|
|
||||||
|
void update_hover_label();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void focus_location_editor();
|
void focus_location_editor();
|
||||||
void location_edit_return_pressed();
|
void location_edit_return_pressed();
|
||||||
|
@ -76,7 +81,6 @@ private:
|
||||||
virtual bool event(QEvent*) override;
|
virtual bool event(QEvent*) override;
|
||||||
|
|
||||||
void recreate_toolbar_icons();
|
void recreate_toolbar_icons();
|
||||||
void update_hover_label();
|
|
||||||
|
|
||||||
void open_link(URL::URL const&);
|
void open_link(URL::URL const&);
|
||||||
void open_link_in_new_tab(URL::URL const&);
|
void open_link_in_new_tab(URL::URL const&);
|
||||||
|
@ -92,6 +96,7 @@ private:
|
||||||
QAction* m_reset_zoom_button_action { nullptr };
|
QAction* m_reset_zoom_button_action { nullptr };
|
||||||
LocationEdit* m_location_edit { nullptr };
|
LocationEdit* m_location_edit { nullptr };
|
||||||
WebContentView* m_view { nullptr };
|
WebContentView* m_view { nullptr };
|
||||||
|
FindInPageWidget* m_find_in_page { nullptr };
|
||||||
BrowserWindow* m_window { nullptr };
|
BrowserWindow* m_window { nullptr };
|
||||||
QString m_title;
|
QString m_title;
|
||||||
QLabel* m_hover_label { nullptr };
|
QLabel* m_hover_label { nullptr };
|
||||||
|
|
|
@ -7,5 +7,7 @@
|
||||||
<file>../Icons/hamburger.tvg</file>
|
<file>../Icons/hamburger.tvg</file>
|
||||||
<file>../Icons/new_tab.tvg</file>
|
<file>../Icons/new_tab.tvg</file>
|
||||||
<file>../Icons/reload.tvg</file>
|
<file>../Icons/reload.tvg</file>
|
||||||
|
<file>../Icons/up.tvg</file>
|
||||||
|
<file>../Icons/down.tvg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue