2023-01-18 14:12:13 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2023, Cameron Youell <cameronyouell@gmail.com>
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "LocationEdit.h"
|
2023-05-31 01:44:16 +00:00
|
|
|
#include "Settings.h"
|
2023-08-05 16:42:26 +00:00
|
|
|
#include "StringUtils.h"
|
2024-03-18 03:22:27 +00:00
|
|
|
#include <LibURL/URL.h>
|
2023-10-13 13:52:06 +00:00
|
|
|
#include <LibWebView/URL.h>
|
2023-05-31 01:44:16 +00:00
|
|
|
#include <QApplication>
|
2023-01-23 03:11:01 +00:00
|
|
|
#include <QPalette>
|
|
|
|
#include <QTextLayout>
|
2023-05-20 15:13:45 +00:00
|
|
|
#include <QTimer>
|
2023-01-18 14:12:13 +00:00
|
|
|
|
2023-08-02 17:52:59 +00:00
|
|
|
namespace Ladybird {
|
|
|
|
|
2023-01-23 03:11:01 +00:00
|
|
|
LocationEdit::LocationEdit(QWidget* parent)
|
|
|
|
: QLineEdit(parent)
|
2023-01-18 14:12:13 +00:00
|
|
|
{
|
2024-06-12 02:24:39 +00:00
|
|
|
update_placeholder();
|
|
|
|
QObject::connect(Settings::the(), &Settings::enable_search_changed, this, &LocationEdit::update_placeholder);
|
|
|
|
QObject::connect(Settings::the(), &Settings::search_engine_changed, this, &LocationEdit::update_placeholder);
|
|
|
|
|
2023-05-31 01:44:16 +00:00
|
|
|
m_autocomplete = make<AutoComplete>(this);
|
|
|
|
this->setCompleter(m_autocomplete);
|
|
|
|
|
|
|
|
connect(m_autocomplete, &AutoComplete::activated, [&](QModelIndex const&) {
|
|
|
|
emit returnPressed();
|
|
|
|
});
|
|
|
|
|
|
|
|
connect(this, &QLineEdit::returnPressed, [&] {
|
|
|
|
clearFocus();
|
|
|
|
|
2023-10-19 20:08:31 +00:00
|
|
|
Optional<StringView> search_engine_url;
|
|
|
|
if (Settings::the()->enable_search())
|
|
|
|
search_engine_url = Settings::the()->search_engine().query_url;
|
2023-05-31 01:44:16 +00:00
|
|
|
|
2023-12-04 15:08:16 +00:00
|
|
|
auto query = ak_string_from_qstring(text());
|
2023-10-13 13:52:06 +00:00
|
|
|
|
2023-10-19 20:08:31 +00:00
|
|
|
if (auto url = WebView::sanitize_url(query, search_engine_url); url.has_value())
|
2024-06-10 09:33:35 +00:00
|
|
|
set_url(url.release_value());
|
2023-05-31 01:44:16 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
connect(this, &QLineEdit::textEdited, [this] {
|
|
|
|
if (!Settings::the()->enable_autocomplete()) {
|
|
|
|
m_autocomplete->clear_suggestions();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto cursor_position = cursorPosition();
|
|
|
|
|
2023-12-04 15:08:16 +00:00
|
|
|
m_autocomplete->get_search_suggestions(ak_string_from_qstring(text()));
|
2023-05-31 01:44:16 +00:00
|
|
|
setCursorPosition(cursor_position);
|
|
|
|
});
|
|
|
|
|
2023-05-29 09:05:49 +00:00
|
|
|
connect(this, &QLineEdit::textChanged, this, &LocationEdit::highlight_location);
|
2023-01-23 03:11:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LocationEdit::focusInEvent(QFocusEvent* event)
|
|
|
|
{
|
|
|
|
QLineEdit::focusInEvent(event);
|
|
|
|
highlight_location();
|
2023-05-20 15:13:45 +00:00
|
|
|
QTimer::singleShot(0, this, &QLineEdit::selectAll);
|
2023-01-23 03:11:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LocationEdit::focusOutEvent(QFocusEvent* event)
|
|
|
|
{
|
|
|
|
QLineEdit::focusOutEvent(event);
|
2024-06-10 09:33:35 +00:00
|
|
|
if (m_url_is_hidden) {
|
|
|
|
m_url_is_hidden = false;
|
|
|
|
if (text().isEmpty())
|
|
|
|
setText(qstring_from_ak_string(m_url.serialize()));
|
|
|
|
}
|
2023-01-23 03:11:01 +00:00
|
|
|
highlight_location();
|
|
|
|
}
|
|
|
|
|
2024-06-12 02:24:39 +00:00
|
|
|
void LocationEdit::update_placeholder()
|
|
|
|
{
|
|
|
|
if (Settings::the()->enable_search())
|
|
|
|
setPlaceholderText(qstring_from_ak_string(
|
|
|
|
MUST(String::formatted("Search with {} or enter web address",
|
|
|
|
Settings::the()->search_engine().name))));
|
|
|
|
else
|
|
|
|
setPlaceholderText("Enter web address");
|
|
|
|
}
|
|
|
|
|
2023-01-23 03:11:01 +00:00
|
|
|
void LocationEdit::highlight_location()
|
|
|
|
{
|
2023-12-04 15:08:16 +00:00
|
|
|
auto url = ak_string_from_qstring(text());
|
2023-01-23 03:11:01 +00:00
|
|
|
QList<QInputMethodEvent::Attribute> attributes;
|
2023-10-17 15:45:55 +00:00
|
|
|
|
|
|
|
if (auto url_parts = WebView::break_url_into_parts(url); url_parts.has_value()) {
|
|
|
|
auto darkened_text_color = QPalette().color(QPalette::Text);
|
|
|
|
darkened_text_color.setAlpha(127);
|
|
|
|
|
|
|
|
QTextCharFormat dark_attributes;
|
|
|
|
dark_attributes.setForeground(darkened_text_color);
|
|
|
|
|
|
|
|
QTextCharFormat highlight_attributes;
|
|
|
|
highlight_attributes.setForeground(QPalette().color(QPalette::Text));
|
|
|
|
|
|
|
|
attributes.append({
|
|
|
|
QInputMethodEvent::TextFormat,
|
|
|
|
-cursorPosition(),
|
|
|
|
static_cast<int>(url_parts->scheme_and_subdomain.length()),
|
|
|
|
dark_attributes,
|
|
|
|
});
|
|
|
|
|
|
|
|
attributes.append({
|
|
|
|
QInputMethodEvent::TextFormat,
|
|
|
|
static_cast<int>(url_parts->scheme_and_subdomain.length() - cursorPosition()),
|
|
|
|
static_cast<int>(url_parts->effective_tld_plus_one.length()),
|
|
|
|
highlight_attributes,
|
|
|
|
});
|
|
|
|
|
|
|
|
attributes.append({
|
|
|
|
QInputMethodEvent::TextFormat,
|
|
|
|
static_cast<int>(url_parts->scheme_and_subdomain.length() + url_parts->effective_tld_plus_one.length() - cursorPosition()),
|
|
|
|
static_cast<int>(url_parts->remainder.length()),
|
|
|
|
dark_attributes,
|
|
|
|
});
|
2023-01-23 03:11:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QInputMethodEvent event(QString(), attributes);
|
|
|
|
QCoreApplication::sendEvent(this, &event);
|
2023-01-18 14:12:13 +00:00
|
|
|
}
|
2023-08-02 17:52:59 +00:00
|
|
|
|
2024-06-10 09:33:35 +00:00
|
|
|
void LocationEdit::set_url(URL::URL const& url)
|
|
|
|
{
|
|
|
|
m_url = url;
|
|
|
|
if (m_url_is_hidden) {
|
|
|
|
clear();
|
|
|
|
} else {
|
|
|
|
setText(qstring_from_ak_string(url.serialize()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-02 17:52:59 +00:00
|
|
|
}
|