/* * 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: git://neueland.iserlohn-fortress.net/smolbote.git * * SPDX-License-Identifier: GPL-3.0 */ #include "urllineedit.h" #include #include #include #include // ssl menu #include #include #include UrlLineEdit::UrlLineEdit(QWidget *parent) : QLineEdit(parent), m_listView(new QListView(this)) { setPlaceholderText(tr("Enter address")); m_listView->setWindowFlags(Qt::ToolTip); m_listView->setVisible(false); connect(this, &UrlLineEdit::textEdited, this, &UrlLineEdit::updateCompleter); // ssl menu m_sslMenu = new QMenu(this); m_sslLabel = new QLabel(m_sslMenu); QWidgetAction *sslErrorAction = new QWidgetAction(m_sslMenu); sslErrorAction->setDefaultWidget(m_sslLabel); m_sslMenu->addAction(sslErrorAction); m_sslAction = addAction(style()->standardIcon(QStyle::SP_DriveNetIcon), QLineEdit::LeadingPosition); m_sslAction->setToolTip(tr("TODO: Display SSL Status popup here")); m_sslAction->setMenu(m_sslMenu); connect(m_sslAction, &QAction::triggered, this, [this]() { m_sslMenu->exec(this->mapToGlobal(QPoint(0, height()))); }); m_pageAction = addAction(style()->standardIcon(QStyle::SP_FileIcon), QLineEdit::TrailingPosition); m_pageAction->setShortcut(QKeySequence("F10")); m_pageAction->setToolTip(tr("Page Actions")); connect(m_pageAction, &QAction::triggered, m_pageAction, [&]() { //this->deselect(); if(m_pageAction->menu() != nullptr) { m_pageAction->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('#')) { emit searchTermEntered(this->text().mid(1)); } else { emit addressEntered(QUrl::fromUserInput(this->text())); } this->clearFocus(); }); } QAction *UrlLineEdit::pageAction() { Q_CHECK_PTR(m_pageAction); return m_pageAction; } void UrlLineEdit::setCompleterModel(QAbstractItemModel *model) { Q_CHECK_PTR(model); m_bookmarksModel = model; } 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::showSslError(const QString &message) { m_sslLabel->setText(message); m_sslAction->trigger(); } void UrlLineEdit::updateCompleter(const QString &text) { if(m_bookmarksModel == nullptr) { return; } const QModelIndexList res = m_bookmarksModel->match(QModelIndex(), Qt::EditRole, text, 7); QStringList l; for(const QModelIndex &idx : res) { l.append(idx.data(Qt::EditRole).toString()); } if(!text.isEmpty()) { l.append(text); } QStringListModel *m = new QStringListModel(l, this); m_listView->setModel(m); // 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::keyPressEvent(QKeyEvent *event) { if(!m_listView->isHidden()) { int key = event->key(); int count = m_listView->model()->rowCount(); QModelIndex currentIndex = m_listView->currentIndex(); switch (key) { case Qt::Key_Down: if(currentIndex.row() + 1 >= count) { m_listView->setCurrentIndex(m_listView->model()->index(0, 0)); } else { m_listView->setCurrentIndex(m_listView->model()->index(currentIndex.row() + 1, 0)); } break; case Qt::Key_Up: if(currentIndex.row() == 0) { m_listView->setCurrentIndex(m_listView->model()->index(count - 1, 0)); } else { m_listView->setCurrentIndex(m_listView->model()->index(currentIndex.row() - 1, 0)); } break; case Qt::Key_Enter: case Qt::Key_Return: if(currentIndex.isValid()) { setText(currentIndex.data().toString()); } m_listView->hide(); return; case Qt::Key_Escape: m_listView->hide(); break; default: break; } } 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()); }