/* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original * location: https://neueland.iserlohn-fortress.net/smolbote.hg * * SPDX-License-Identifier: GPL-3.0 */ #include "urllineedit.h" #include "webengine/webview.h" #include #include #include #include #include #include UrlLineEdit::UrlLineEdit(const QHash &config, QWidget *parent) : QLineEdit(parent) , suggestionTimer(new QTimer(this)) , m_listView(new Completer(this)) { setPlaceholderText(tr("Enter address")); suggestionTimer->setSingleShot(true); connect(suggestionTimer, &QTimer::timeout, this, &UrlLineEdit::search); m_listView->setVisible(false); connect(this, &QLineEdit::textEdited, this, [this]() { if(suggestionTimer->isActive()) suggestionTimer->stop(); suggestionTimer->start(100); }); m_pageMenuAction = addAction(style()->standardIcon(QStyle::SP_DriveNetIcon), QLineEdit::LeadingPosition); m_pageMenuAction->setShortcut(QKeySequence("F2")); m_pageMenuAction->setToolTip(tr("Page Actions (%1)").arg(m_pageMenuAction->shortcut().toString())); connect(m_pageMenuAction, &QAction::triggered, m_pageMenuAction, [&]() { if(m_pageMenuAction->menu()) { m_pageMenuAction->menu()->exec(this->mapToGlobal(QPoint(0, height()))); } }); m_toolsMenuAction = addAction(style()->standardIcon(QStyle::SP_FileIcon), QLineEdit::TrailingPosition); m_toolsMenuAction->setShortcut(QKeySequence("F10")); m_toolsMenuAction->setToolTip(tr("Tools (%1)").arg(m_toolsMenuAction->shortcut().toString())); connect(m_toolsMenuAction, &QAction::triggered, m_toolsMenuAction, [&]() { if(m_toolsMenuAction->menu()) { m_toolsMenuAction->menu()->exec(this->mapToGlobal(QPoint(width(), height()))); } }); QTextCharFormat hostnameFormat; hostnameFormat.setFontWeight(QFont::Bold); m_hostFormat.format = hostnameFormat; // connect signals connect(this, &QLineEdit::returnPressed, [this]() { if(this->text().startsWith('#')) {; m_view->search(this->text().mid(1)); } else { if(m_view) { m_view->load(QUrl::fromUserInput(this->text())); } else { this->clear(); } } this->clearFocus(); }); } UrlLineEdit::~UrlLineEdit() { suggestionTimer->stop(); } void UrlLineEdit::connectWebView(WebView *view) { disconnect(urlChangedConnection); if(view == nullptr) { clear(); m_pageMenuAction->setMenu(nullptr); m_toolsMenuAction->setMenu(nullptr); return; } m_view = view; setUrl(view->url()); m_pageMenuAction->setMenu(view->pageMenu()); m_toolsMenuAction->setMenu(view->toolsMenu()); urlChangedConnection = connect(view, &WebView::urlChanged, this, &UrlLineEdit::setUrl); } void UrlLineEdit::setUrl(const QUrl &url) { QString urlText = url.toString(); QString domain = url.host(); m_hostFormat.start = urlText.indexOf(domain); m_hostFormat.length = domain.length(); clear(); clearTextFormat(); setTextFormat(m_hostFormat); setText(urlText); } void UrlLineEdit::search() { Q_ASSERT_X(bookmarks != nullptr, "UrlLineEdit::search", "bookmarks is nullptr"); updateCompleter(bookmarks->search(text())); } void UrlLineEdit::updateCompleter(QStringList l) { if(!m_listView->updateItems(l)) { m_listView->hide(); return; } // positioning m_listView->setFixedWidth(width()); m_listView->move(mapToGlobal(QPoint(0, height()))); m_listView->show(); } void UrlLineEdit::focusInEvent(QFocusEvent *event) { clearTextFormat(); QLineEdit::focusInEvent(event); // select the contents when receiving focus // http://stackoverflow.com/a/35725950/1054406 // mousePressEvent triggers right after focusInEvent so text selected in focusInEvent unselects by mousePressEvent //QTimer::singleShot(0, this, SLOT(selectAll())); } void UrlLineEdit::focusOutEvent(QFocusEvent *event) { if(!text().startsWith('#')) setUrl(QUrl::fromUserInput(text())); QLineEdit::focusOutEvent(event); } void UrlLineEdit::keyPressEvent(QKeyEvent *event) { if(m_listView->keyPressed(event)) { int key = event->key(); QModelIndex currentIndex = m_listView->currentIndex(); if(key == Qt::Key::Key_Enter || key == Qt::Key_Return) { if(currentIndex.isValid()) { setText(currentIndex.data().toString()); } m_listView->hide(); event->accept(); return; } } else if(event->key() == Qt::Key::Key_Escape) { clearFocus(); event->accept(); return; } QLineEdit::keyPressEvent(event); } // formatting taken from: https://forum.qt.io/topic/60962/setting-qlineedit-text-bold void UrlLineEdit::setTextFormat(const QTextLayout::FormatRange &format) { QList attributes; attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, format.start, format.length, format.format)); QInputMethodEvent ev(QString(), attributes); event(&ev); } void UrlLineEdit::clearTextFormat() { setTextFormat(QTextLayout::FormatRange()); }