From 7681ef25da7118465927de3d8d8ba055264e5196 Mon Sep 17 00:00:00 2001 From: Matthew Costa Date: Wed, 6 Jul 2022 14:38:50 +0100 Subject: [PATCH] Ladybird: Expanded toolbar with browser history and home button This patch takes the browser history code from the Serenity browser and wires it up to the QT interface. This is tied in with a few extra toolbar buttons associated with each tab. --- Ladybird/CMakeLists.txt | 1 + Ladybird/History.cpp | 81 +++++++++++++++++++++++++++++++++++++++++ Ladybird/History.h | 41 +++++++++++++++++++++ Ladybird/Tab.cpp | 61 +++++++++++++++++++++++++++---- Ladybird/Tab.h | 15 ++++++++ Ladybird/WebView.cpp | 2 +- Ladybird/WebView.h | 2 +- 7 files changed, 194 insertions(+), 9 deletions(-) create mode 100644 Ladybird/History.cpp create mode 100644 Ladybird/History.h diff --git a/Ladybird/CMakeLists.txt b/Ladybird/CMakeLists.txt index ccc78718ff..ce3ccf8770 100644 --- a/Ladybird/CMakeLists.txt +++ b/Ladybird/CMakeLists.txt @@ -37,6 +37,7 @@ set(SOURCES RequestManagerQt.cpp main.cpp WebView.cpp + History.cpp Tab.cpp ) diff --git a/Ladybird/History.cpp b/Ladybird/History.cpp new file mode 100644 index 0000000000..64e66633a9 --- /dev/null +++ b/Ladybird/History.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "History.h" + +namespace Browser { + +void History::dump() const +{ + dbgln("Dump {} items(s)", m_items.size()); + int i = 0; + for (auto& item : m_items) { + dbgln("[{}] {} '{}' {}", i, item.url, item.title, m_current == i ? '*' : ' '); + ++i; + } +} + +void History::push(const URL& url, String const& title) +{ + if (!m_items.is_empty() && m_items[m_current].url == url) + return; + m_items.shrink(m_current + 1); + m_items.append(URLTitlePair { + .url = url, + .title = title, + }); + m_current++; +} + +History::URLTitlePair History::current() const +{ + if (m_current == -1) + return {}; + return m_items[m_current]; +} + +void History::go_back(int steps) +{ + VERIFY(can_go_back(steps)); + m_current -= steps; +} + +void History::go_forward(int steps) +{ + VERIFY(can_go_forward(steps)); + m_current += steps; +} + +void History::clear() +{ + m_items = {}; + m_current = -1; +} + +void History::update_title(String const& title) +{ + m_items[m_current].title = title; +} + +Vector History::get_back_title_history() +{ + Vector back_title_history; + for (int i = m_current - 1; i >= 0; i--) { + back_title_history.append(m_items[i].title); + } + return back_title_history; +} + +Vector History::get_forward_title_history() +{ + Vector forward_title_history; + for (int i = m_current + 1; i < static_cast(m_items.size()); i++) { + forward_title_history.append(m_items[i].title); + } + return forward_title_history; +} + +} diff --git a/Ladybird/History.h b/Ladybird/History.h new file mode 100644 index 0000000000..4449944c72 --- /dev/null +++ b/Ladybird/History.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Browser { + +class History { +public: + struct URLTitlePair { + URL url; + String title; + }; + void dump() const; + + void push(const URL& url, String const& title); + void update_title(String const& title); + URLTitlePair current() const; + + Vector get_back_title_history(); + Vector get_forward_title_history(); + + void go_back(int steps = 1); + void go_forward(int steps = 1); + + bool can_go_back(int steps = 1) { return (m_current - steps) >= 0; } + bool can_go_forward(int steps = 1) { return (m_current + steps) < static_cast(m_items.size()); } + void clear(); + +private: + Vector m_items; + int m_current { -1 }; +}; + +} diff --git a/Ladybird/Tab.cpp b/Ladybird/Tab.cpp index 906e059173..75f823894c 100644 --- a/Ladybird/Tab.cpp +++ b/Ladybird/Tab.cpp @@ -7,9 +7,9 @@ #include "Tab.h" #include "BrowserWindow.h" +#include "History.h" #include #include -#include extern String s_serenity_resource_root; @@ -26,21 +26,67 @@ Tab::Tab(QMainWindow* window) m_layout->addWidget(m_toolbar); m_layout->addWidget(m_view); + auto back_icon_path = QString("%1/res/icons/16x16/go-back.png").arg(s_serenity_resource_root.characters()); + auto forward_icon_path = QString("%1/res/icons/16x16/go-forward.png").arg(s_serenity_resource_root.characters()); + auto home_icon_path = QString("%1/res/icons/16x16/go-home.png").arg(s_serenity_resource_root.characters()); auto reload_icon_path = QString("%1/res/icons/16x16/reload.png").arg(s_serenity_resource_root.characters()); - auto* reload_action = new QAction(QIcon(reload_icon_path), "Reload"); - reload_action->setShortcut(QKeySequence("Ctrl+R")); - m_toolbar->addAction(reload_action); + m_back_action = make(QIcon(back_icon_path), "Back"); + m_back_action->setShortcut(QKeySequence("Alt+Left")); + m_forward_action = make(QIcon(forward_icon_path), "Forward"); + m_forward_action->setShortcut(QKeySequence("Alt+Right")); + m_home_action = make(QIcon(home_icon_path), "Home"); + m_reload_action = make(QIcon(reload_icon_path), "Reload"); + m_reload_action->setShortcut(QKeySequence("Ctrl+R")); + + m_toolbar->addAction(m_back_action); + m_toolbar->addAction(m_forward_action); + m_toolbar->addAction(m_reload_action); + m_toolbar->addAction(m_home_action); m_toolbar->addWidget(m_location_edit); QObject::connect(m_view, &WebView::linkHovered, m_window->statusBar(), &QStatusBar::showMessage); QObject::connect(m_view, &WebView::linkUnhovered, m_window->statusBar(), &QStatusBar::clearMessage); - QObject::connect(m_view, &WebView::loadStarted, m_location_edit, &QLineEdit::setText); + QObject::connect(m_view, &WebView::loadStarted, [this](const URL& url) { + m_location_edit->setText(url.to_string().characters()); + m_history.push(url, m_title.toUtf8().data()); + }); QObject::connect(m_location_edit, &QLineEdit::returnPressed, this, &Tab::location_edit_return_pressed); QObject::connect(m_view, &WebView::title_changed, this, &Tab::page_title_changed); QObject::connect(m_view, &WebView::favicon_changed, this, &Tab::page_favicon_changed); - QObject::connect(reload_action, &QAction::triggered, this, &Tab::reload); + QObject::connect(m_back_action, &QAction::triggered, this, &Tab::back); + QObject::connect(m_forward_action, &QAction::triggered, this, &Tab::forward); + QObject::connect(m_home_action, &QAction::triggered, this, &Tab::home); + QObject::connect(m_reload_action, &QAction::triggered, this, &Tab::reload); +} + +void Tab::navigate(QString const& url) +{ + view().load(url.toUtf8().data()); +} + +void Tab::back() +{ + if (!m_history.can_go_back()) + return; + + m_history.go_back(); + view().load(m_history.current().url.to_string()); +} + +void Tab::forward() +{ + if (!m_history.can_go_forward()) + return; + + m_history.go_forward(); + view().load(m_history.current().url.to_string()); +} + +void Tab::home() +{ + navigate("https://www.serenityos.org/"); } void Tab::reload() @@ -50,11 +96,12 @@ void Tab::reload() void Tab::location_edit_return_pressed() { - view().load(m_location_edit->text().toUtf8().data()); + navigate(m_location_edit->text()); } void Tab::page_title_changed(QString title) { + m_title = title; emit title_changed(tab_index(), std::move(title)); } diff --git a/Ladybird/Tab.h b/Ladybird/Tab.h index 9e01c9e4c0..511715232d 100644 --- a/Ladybird/Tab.h +++ b/Ladybird/Tab.h @@ -7,6 +7,9 @@ #pragma once +#define AK_DONT_REPLACE_STD + +#include "History.h" #include "WebView.h" #include #include @@ -20,10 +23,15 @@ public: WebView& view() { return *m_view; } + void navigate(QString const&); + public slots: void location_edit_return_pressed(); void page_title_changed(QString); void page_favicon_changed(QIcon); + void back(); + void forward(); + void home(); void reload(); signals: @@ -36,6 +44,13 @@ private: QLineEdit* m_location_edit { nullptr }; WebView* m_view { nullptr }; QMainWindow* m_window { nullptr }; + Browser::History m_history; + QString m_title; + + OwnPtr m_back_action; + OwnPtr m_forward_action; + OwnPtr m_home_action; + OwnPtr m_reload_action; int tab_index(); }; diff --git a/Ladybird/WebView.cpp b/Ladybird/WebView.cpp index 1a66cce55d..bd6ce779df 100644 --- a/Ladybird/WebView.cpp +++ b/Ladybird/WebView.cpp @@ -148,7 +148,7 @@ public: virtual void page_did_start_loading(AK::URL const& url) override { - emit m_view.loadStarted(url.to_string().characters()); + emit m_view.loadStarted(url); } virtual void page_did_finish_loading(AK::URL const&) override diff --git a/Ladybird/WebView.h b/Ladybird/WebView.h index a38e7e165f..c4a542cdb2 100644 --- a/Ladybird/WebView.h +++ b/Ladybird/WebView.h @@ -33,7 +33,7 @@ public: signals: void linkHovered(QString, int timeout = 0); void linkUnhovered(); - void loadStarted(QString); + void loadStarted(const URL&); void title_changed(QString); void favicon_changed(QIcon);