diff options
Diffstat (limited to 'lib/navigation')
-rw-r--r-- | lib/navigation/CMakeLists.txt | 11 | ||||
-rw-r--r-- | lib/navigation/navigationbutton.cpp | 141 | ||||
-rw-r--r-- | lib/navigation/navigationbutton.h | 49 | ||||
-rw-r--r-- | lib/navigation/urlcompleter.cpp | 26 | ||||
-rw-r--r-- | lib/navigation/urlcompleter.h | 25 | ||||
-rw-r--r-- | lib/navigation/urllineedit.cpp | 136 | ||||
-rw-r--r-- | lib/navigation/urllineedit.h | 59 |
7 files changed, 447 insertions, 0 deletions
diff --git a/lib/navigation/CMakeLists.txt b/lib/navigation/CMakeLists.txt new file mode 100644 index 0000000..4a4cf94 --- /dev/null +++ b/lib/navigation/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.1.0) + +add_library(navigation + navigationbutton.cpp + navigationbutton.h + urlcompleter.cpp + urlcompleter.h + urllineedit.cpp + urllineedit.h) + +target_link_libraries(navigation Qt5::Widgets Qt5::WebEngineWidgets)
\ No newline at end of file diff --git a/lib/navigation/navigationbutton.cpp b/lib/navigation/navigationbutton.cpp new file mode 100644 index 0000000..13daebc --- /dev/null +++ b/lib/navigation/navigationbutton.cpp @@ -0,0 +1,141 @@ +/* + * 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 "navigationbutton.h" + +#include <QStyle> +#include <QWebEngineHistory> +#include <QMenu> + +NavigationButton::NavigationButton(Type type, QWidget *parent) : + QToolButton(parent) +{ + m_type = type; + menu = new QMenu(this); + + switch (type) { + case BackButton: + setIcon(style()->standardIcon(QStyle::SP_ArrowBack)); + setMenu(menu); + connect(menu, &QMenu::aboutToShow, this, &NavigationButton::prepareMenu); + break; + case ForwardButton: + setIcon(style()->standardIcon(QStyle::SP_ArrowForward)); + setMenu(menu); + connect(menu, &QMenu::aboutToShow, this, &NavigationButton::prepareMenu); + break; + case ReloadButton: + setIcon(style()->standardIcon(QStyle::SP_BrowserReload)); + break; + case StopButton: + setIcon(style()->standardIcon(QStyle::SP_BrowserStop)); + break; + } + + connect(this, &NavigationButton::clicked, this, &NavigationButton::doAction); + +} + + +void NavigationButton::setView(WebView *view) +{ + disconnect(loadStartedConnection); + disconnect(loadFinishedConnection); + + m_view = view; + if(m_type == BackButton || m_type == ForwardButton) { + updateOnLoadFinished(); + } + + loadStartedConnection = connect(view, &WebView::loadStarted, this, &NavigationButton::updateOnLoadStarted); + loadFinishedConnection = connect(view, &WebView::loadFinished, this, &NavigationButton::updateOnLoadFinished); +} + +void NavigationButton::updateOnLoadStarted() +{ + switch (m_type) { + case BackButton: + break; + case ForwardButton: + break; + case ReloadButton: + m_type = StopButton; + setIcon(style()->standardIcon(QStyle::SP_BrowserStop)); + break; + case StopButton: + break; + } +} + +void NavigationButton::updateOnLoadFinished() +{ + switch (m_type) { + case BackButton: + if(m_view->history()->canGoBack()) { + setEnabled(true); + } else { + setEnabled(false); + } + break; + case ForwardButton: + if(m_view->history()->canGoForward()) { + setEnabled(true); + } else { + setEnabled(false); + } + break; + case ReloadButton: + break; + case StopButton: + m_type = ReloadButton; + setIcon(style()->standardIcon(QStyle::SP_BrowserReload)); + break; + } +} + +void NavigationButton::doAction() +{ + switch (m_type) { + case BackButton: + m_view->history()->back(); + break; + case ForwardButton: + m_view->history()->forward(); + break; + case ReloadButton: + m_view->reload(); + break; + case StopButton: + m_view->stop(); + break; + } +} + +void NavigationButton::prepareMenu() +{ + menu->clear(); + + QList<QWebEngineHistoryItem> items; + switch (m_type) { + case BackButton: + items = m_view->history()->backItems(10); + break; + case ForwardButton: + items = m_view->history()->forwardItems(10); + break; + default: + break; + } + + for(QWebEngineHistoryItem i : items) { + QAction *a = menu->addAction(i.title()); + connect(a, &QAction::triggered, [i, this]() { + m_view->history()->goToItem(i); + }); + } +} diff --git a/lib/navigation/navigationbutton.h b/lib/navigation/navigationbutton.h new file mode 100644 index 0000000..7c76b9c --- /dev/null +++ b/lib/navigation/navigationbutton.h @@ -0,0 +1,49 @@ +/* + * 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 + */ + +#ifndef NAVIGATIONBUTTON_H +#define NAVIGATIONBUTTON_H + +#include <QToolButton> +#include "../../src/webengine/webview.h" + +class QMenu; + +class NavigationButton : public QToolButton +{ + Q_OBJECT +public: + + enum Type { + BackButton, + ForwardButton, + ReloadButton, + StopButton + }; + + explicit NavigationButton(Type type, QWidget *parent = nullptr); + + void setView(WebView *view); + +signals: + +private slots: + void updateOnLoadStarted(); + void updateOnLoadFinished(); + void doAction(); + void prepareMenu(); + +private: + Type m_type; + QMenu *menu; + WebView *m_view; + + QMetaObject::Connection loadStartedConnection, loadFinishedConnection; +}; + +#endif // NAVIGATIONBUTTON_H diff --git a/lib/navigation/urlcompleter.cpp b/lib/navigation/urlcompleter.cpp new file mode 100644 index 0000000..bbde297 --- /dev/null +++ b/lib/navigation/urlcompleter.cpp @@ -0,0 +1,26 @@ +/* + * 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 "urlcompleter.h" + +UrlCompleter::UrlCompleter(QAbstractItemModel *model, QObject *parent) : + QCompleter(model, parent) +{ + setCompletionMode(QCompleter::PopupCompletion); + setFilterMode(Qt::MatchContains); +} + +QStringList UrlCompleter::splitPath(const QString &path) const +{ + return path.split('.'); +} + +QString UrlCompleter::pathFromIndex(const QModelIndex &index) const +{ + return model()->data(index, completionRole()).toString(); +} diff --git a/lib/navigation/urlcompleter.h b/lib/navigation/urlcompleter.h new file mode 100644 index 0000000..f2c52ff --- /dev/null +++ b/lib/navigation/urlcompleter.h @@ -0,0 +1,25 @@ +/* + * 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 + */ + +#ifndef URLCOMPLETER_H +#define URLCOMPLETER_H + +#include <QCompleter> + +class UrlCompleter : public QCompleter +{ + Q_OBJECT +public: + explicit UrlCompleter(QAbstractItemModel *model, QObject *parent = nullptr); + +protected: + QStringList splitPath(const QString &path) const override; + QString pathFromIndex(const QModelIndex &index) const override; +}; + +#endif // URLCOMPLETER_H diff --git a/lib/navigation/urllineedit.cpp b/lib/navigation/urllineedit.cpp new file mode 100644 index 0000000..24924bb --- /dev/null +++ b/lib/navigation/urllineedit.cpp @@ -0,0 +1,136 @@ +/* + * 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 <QUrl> +#include <QTimer> +#include <QMenu> +#include <QAction> +#include <QStyle> + +#include <QWidgetAction> + +// ssl menu +#include <QLabel> + +#include "../bookmarks/bookmarkswidget.h" + +#include <QCompleter> + +UrlLineEdit::UrlLineEdit(QWidget *parent) : + QLineEdit(parent) +{ + setPlaceholderText(tr("Enter address")); + + // 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::sslAction() +{ + Q_CHECK_PTR(m_sslAction); + return m_sslAction; +} + +QAction *UrlLineEdit::pageAction() +{ + Q_CHECK_PTR(m_pageAction); + return m_pageAction; +} + +void UrlLineEdit::setCompleterModel(QAbstractItemModel *model) +{ + Q_CHECK_PTR(model); + m_completer = new UrlCompleter(model, this); + m_completer->setCompletionColumn(1); + this->setCompleter(m_completer); +} + +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::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())); +} + +// formatting taken from: https://forum.qt.io/topic/60962/setting-qlineedit-text-bold +void UrlLineEdit::setTextFormat(const QTextLayout::FormatRange &format) +{ + QList<QInputMethodEvent::Attribute> 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()); +} diff --git a/lib/navigation/urllineedit.h b/lib/navigation/urllineedit.h new file mode 100644 index 0000000..46366a7 --- /dev/null +++ b/lib/navigation/urllineedit.h @@ -0,0 +1,59 @@ +/* + * 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 + */ + +#ifndef URLLINEEDIT_H +#define URLLINEEDIT_H + +#include <QLineEdit> +#include <QTextLayout> +#include <QAction> + +#include "urlcompleter.h" + +class QAbstractItemModel; +class QMenu; +class QLabel; +class UrlLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit UrlLineEdit(QWidget *parent = nullptr); + + QAction *sslAction(); + QAction *pageAction(); + + void setCompleterModel(QAbstractItemModel *model); + +signals: + void addressEntered(const QUrl &url); + void searchTermEntered(const QString &term); + +public slots: + void setUrl(const QUrl &url); + void showSslError(const QString &message); + +protected: + void focusInEvent(QFocusEvent *event); + +private: + void setTextFormat(const QTextLayout::FormatRange &format); + void clearTextFormat(); + + QTextLayout::FormatRange m_hostFormat; + + QAction *m_sslAction = nullptr; + QAction *m_pageAction = nullptr; + + // ssl menu + QMenu *m_sslMenu; + QLabel *m_sslLabel; + + UrlCompleter *m_completer; +}; + +#endif // URLLINEEDIT_H |