2022-07-05 22:18:21 +00:00
|
|
|
/*
|
2022-07-19 10:23:11 +00:00
|
|
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
2022-07-05 22:18:21 +00:00
|
|
|
* Copyright (c) 2022, Matthew Costa <ucosty@gmail.com>
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Tab.h"
|
|
|
|
#include "BrowserWindow.h"
|
2022-07-06 13:38:50 +00:00
|
|
|
#include "History.h"
|
2022-07-14 03:41:13 +00:00
|
|
|
#include "Settings.h"
|
2022-07-05 22:18:21 +00:00
|
|
|
#include <QCoreApplication>
|
2022-09-09 12:23:36 +00:00
|
|
|
#include <QFont>
|
|
|
|
#include <QFontMetrics>
|
2022-07-13 02:39:38 +00:00
|
|
|
#include <QPoint>
|
2022-09-09 12:23:36 +00:00
|
|
|
#include <QResizeEvent>
|
2022-07-05 22:18:21 +00:00
|
|
|
|
|
|
|
extern String s_serenity_resource_root;
|
2022-07-14 03:41:13 +00:00
|
|
|
extern Browser::Settings* s_settings;
|
2022-07-05 22:18:21 +00:00
|
|
|
|
|
|
|
Tab::Tab(QMainWindow* window)
|
|
|
|
: m_window(window)
|
|
|
|
{
|
|
|
|
m_layout = new QBoxLayout(QBoxLayout::Direction::TopToBottom, this);
|
2022-09-09 12:27:59 +00:00
|
|
|
m_layout->setSpacing(0);
|
2022-07-05 22:18:21 +00:00
|
|
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
|
|
m_view = new WebView;
|
|
|
|
m_toolbar = new QToolBar;
|
|
|
|
m_location_edit = new QLineEdit;
|
|
|
|
|
2022-09-09 12:23:36 +00:00
|
|
|
m_hover_label = new QLabel(this);
|
2022-09-09 13:19:18 +00:00
|
|
|
m_hover_label->hide();
|
2022-09-09 12:23:36 +00:00
|
|
|
m_hover_label->setFrameShape(QFrame::Shape::Box);
|
|
|
|
m_hover_label->setAutoFillBackground(true);
|
|
|
|
|
2022-09-12 07:12:04 +00:00
|
|
|
auto* focus_location_editor_action = new QAction("Edit Location");
|
|
|
|
focus_location_editor_action->setShortcut(QKeySequence("Ctrl+L"));
|
|
|
|
addAction(focus_location_editor_action);
|
2022-07-07 00:56:09 +00:00
|
|
|
|
2022-07-05 22:18:21 +00:00
|
|
|
m_layout->addWidget(m_toolbar);
|
|
|
|
m_layout->addWidget(m_view);
|
|
|
|
|
2022-07-06 13:38:50 +00:00
|
|
|
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());
|
2022-07-05 22:18:21 +00:00
|
|
|
auto reload_icon_path = QString("%1/res/icons/16x16/reload.png").arg(s_serenity_resource_root.characters());
|
2022-07-06 13:38:50 +00:00
|
|
|
m_back_action = make<QAction>(QIcon(back_icon_path), "Back");
|
|
|
|
m_back_action->setShortcut(QKeySequence("Alt+Left"));
|
|
|
|
m_forward_action = make<QAction>(QIcon(forward_icon_path), "Forward");
|
|
|
|
m_forward_action->setShortcut(QKeySequence("Alt+Right"));
|
|
|
|
m_home_action = make<QAction>(QIcon(home_icon_path), "Home");
|
|
|
|
m_reload_action = make<QAction>(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);
|
2022-07-05 22:18:21 +00:00
|
|
|
m_toolbar->addWidget(m_location_edit);
|
|
|
|
|
2022-09-12 07:04:51 +00:00
|
|
|
QObject::connect(m_view, &WebView::link_hovered, [this](QString const& title) {
|
2022-09-09 12:23:36 +00:00
|
|
|
m_hover_label->setText(title);
|
|
|
|
update_hover_label();
|
|
|
|
m_hover_label->show();
|
2022-07-13 02:39:38 +00:00
|
|
|
});
|
2022-09-12 07:04:51 +00:00
|
|
|
QObject::connect(m_view, &WebView::link_unhovered, [this] {
|
2022-09-09 12:23:36 +00:00
|
|
|
m_hover_label->hide();
|
2022-07-13 02:39:38 +00:00
|
|
|
});
|
2022-07-05 22:18:21 +00:00
|
|
|
|
2022-09-12 07:04:51 +00:00
|
|
|
QObject::connect(m_view, &WebView::load_started, [this](const URL& url) {
|
2022-07-06 13:38:50 +00:00
|
|
|
m_location_edit->setText(url.to_string().characters());
|
|
|
|
m_history.push(url, m_title.toUtf8().data());
|
|
|
|
});
|
2022-07-05 22:18:21 +00:00
|
|
|
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);
|
|
|
|
|
2022-07-06 13:38:50 +00:00
|
|
|
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);
|
2022-09-12 07:12:04 +00:00
|
|
|
QObject::connect(focus_location_editor_action, &QAction::triggered, this, &Tab::focus_location_editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Tab::focus_location_editor()
|
|
|
|
{
|
|
|
|
m_location_edit->setFocus();
|
|
|
|
m_location_edit->selectAll();
|
2022-07-06 13:38:50 +00:00
|
|
|
}
|
|
|
|
|
2022-07-14 15:32:51 +00:00
|
|
|
void Tab::navigate(QString url)
|
2022-07-06 13:38:50 +00:00
|
|
|
{
|
2022-07-19 18:08:02 +00:00
|
|
|
if (!url.startsWith("http://", Qt::CaseInsensitive) && !url.startsWith("https://", Qt::CaseInsensitive) && !url.startsWith("file://", Qt::CaseInsensitive))
|
2022-07-14 15:32:51 +00:00
|
|
|
url = "http://" + url;
|
2022-07-06 13:38:50 +00:00
|
|
|
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()
|
|
|
|
{
|
2022-07-14 03:41:13 +00:00
|
|
|
navigate(s_settings->homepage());
|
2022-07-05 22:18:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Tab::reload()
|
|
|
|
{
|
|
|
|
view().reload();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Tab::location_edit_return_pressed()
|
|
|
|
{
|
2022-07-06 13:38:50 +00:00
|
|
|
navigate(m_location_edit->text());
|
2022-07-05 22:18:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Tab::page_title_changed(QString title)
|
|
|
|
{
|
2022-07-06 13:38:50 +00:00
|
|
|
m_title = title;
|
2022-07-05 22:18:21 +00:00
|
|
|
emit title_changed(tab_index(), std::move(title));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Tab::page_favicon_changed(QIcon icon)
|
|
|
|
{
|
|
|
|
emit favicon_changed(tab_index(), std::move(icon));
|
|
|
|
}
|
|
|
|
|
|
|
|
int Tab::tab_index()
|
|
|
|
{
|
|
|
|
// FIXME: I hear you like footguns...
|
|
|
|
// There has to be a better way of doing this
|
|
|
|
auto browser_window = reinterpret_cast<BrowserWindow*>(m_window);
|
|
|
|
return browser_window->tab_index(this);
|
|
|
|
}
|
2022-07-08 12:14:40 +00:00
|
|
|
|
|
|
|
void Tab::debug_request(String const& request, String const& argument)
|
|
|
|
{
|
|
|
|
m_view->debug_request(request, argument);
|
|
|
|
}
|
2022-09-09 12:23:36 +00:00
|
|
|
|
|
|
|
void Tab::resizeEvent(QResizeEvent* event)
|
|
|
|
{
|
|
|
|
QWidget::resizeEvent(event);
|
|
|
|
if (m_hover_label->isVisible())
|
|
|
|
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->move(6, height() - m_hover_label->height() - 8);
|
|
|
|
m_hover_label->raise();
|
|
|
|
}
|