aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-05-01 15:54:49 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2018-05-01 15:54:49 +0200
commit1ee841364215042f1f284e692ae191ebf7a64156 (patch)
tree48c1f49e29fe6b13cef68cd73dd2cab039fea822 /lib
parentWindow::session (diff)
downloadsmolbote-1ee841364215042f1f284e692ae191ebf7a64156.tar.xz
Split off addressbar into lib/
Diffstat (limited to 'lib')
-rw-r--r--lib/addressbar/CMakeLists.txt21
-rw-r--r--lib/addressbar/addressbar.cpp94
-rw-r--r--lib/addressbar/addressbar.h44
-rw-r--r--lib/addressbar/completer.cpp68
-rw-r--r--lib/addressbar/completer.h32
-rw-r--r--lib/addressbar/urllineedit.cpp126
-rw-r--r--lib/addressbar/urllineedit.h51
7 files changed, 436 insertions, 0 deletions
diff --git a/lib/addressbar/CMakeLists.txt b/lib/addressbar/CMakeLists.txt
new file mode 100644
index 0000000..1122bc3
--- /dev/null
+++ b/lib/addressbar/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Find includes in corresponding build directories
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+# Instruct CMake to run moc automatically when needed.
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+add_library(addressbar
+ addressbar.cpp
+ addressbar.h
+ completer.cpp
+ completer.h
+ urllineedit.cpp
+ urllineedit.h
+)
+
+#target_include_directories(addressbar
+# PRIVATE ${Boost_INCLUDE_DIRS})
+
+target_link_libraries(addressbar Qt5::Widgets Qt5::WebEngineWidgets)
diff --git a/lib/addressbar/addressbar.cpp b/lib/addressbar/addressbar.cpp
new file mode 100644
index 0000000..9b3970d
--- /dev/null
+++ b/lib/addressbar/addressbar.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 "addressbar.h"
+#include "urllineedit.h"
+#include <QWebEngineView>
+#include <QProgressBar>
+#include <QShortcut>
+#include <QVBoxLayout>
+
+AddressBar::AddressBar(const QHash<QString, QString> &config, QWidget *parent)
+ : QWidget(parent)
+{
+ setLayout(new QVBoxLayout());
+ layout()->setContentsMargins(0, 0, 0, 0);
+ layout()->setSpacing(0);
+
+ urlBar = new UrlLineEdit(this);
+ layout()->addWidget(urlBar);
+
+ auto *focusShortcut = new QShortcut(QKeySequence(config.value("addressbar.shortcuts.focus")), parent);
+ connect(focusShortcut, &QShortcut::activated, urlBar, [=]() {
+ urlBar->setFocus();
+ urlBar->selectAll();
+ });
+
+ urlBar->pageMenu_action->setShortcut(QKeySequence(config.value("addressbar.shortcuts.pageMenu")));
+ urlBar->pageMenu_action->setToolTip(tr("Page Actions (%1)").arg(urlBar->pageMenu_action->shortcut().toString()));
+
+ urlBar->toolsMenu_action->setShortcut(QKeySequence(config.value("addressbar.shortcuts.toolsMenu")));
+ urlBar->toolsMenu_action->setToolTip(tr("Tools (%1)").arg(urlBar->toolsMenu_action->shortcut().toString()));
+
+ connect(urlBar, &UrlLineEdit::textEdited, [=](const QString &text) {
+ std::function<void(QStringList &)> callback = std::bind(&UrlLineEdit::updateCompleter, urlBar, std::placeholders::_1);
+ emit complete(text, callback);
+ });
+
+ progressBar = new QProgressBar(this);
+ progressBar->setMaximumHeight(5);
+ progressBar->setTextVisible(false);
+ layout()->addWidget(progressBar);
+}
+
+AddressBar::~AddressBar()
+{
+ disconnect(urlChangedConnection);
+ disconnect(loadUrlConnection);
+ disconnect(progressBarConnection);
+}
+
+void AddressBar::setView(QWebEngineView *view)
+{
+ disconnect(urlChangedConnection);
+ disconnect(loadUrlConnection);
+ disconnect(progressBarConnection);
+
+ progressBar->setValue(100);
+
+ if(view == nullptr) {
+ urlBar->clear();
+ urlBar->pageMenu_action->setMenu(nullptr);
+ urlBar->toolsMenu_action->setMenu(nullptr);
+ return;
+ }
+
+ urlBar->setUrl(view->url());
+ urlChangedConnection = connect(view, &QWebEngineView::urlChanged, urlBar, &UrlLineEdit::setUrl);
+ loadUrlConnection = connect(urlBar, &UrlLineEdit::returnPressed, [=]() {
+ if(urlBar->text().startsWith('#')) {
+ emit search(urlBar->text().mid(1));
+ } else {
+ view->load(QUrl::fromUserInput(urlBar->text()));
+ }
+ view->setFocus();
+ });
+
+ //progressBar->setValue(view->loadProgress());
+ progressBarConnection = connect(view, &QWebEngineView::loadProgress, progressBar, &QProgressBar::setValue);
+}
+
+void AddressBar::setPageMenu(QMenu *menu)
+{
+ urlBar->pageMenu_action->setMenu(menu);
+}
+
+void AddressBar::setToolsMenu(QMenu *menu)
+{
+ urlBar->toolsMenu_action->setMenu(menu);
+}
diff --git a/lib/addressbar/addressbar.h b/lib/addressbar/addressbar.h
new file mode 100644
index 0000000..861f985
--- /dev/null
+++ b/lib/addressbar/addressbar.h
@@ -0,0 +1,44 @@
+/*
+ * 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
+ */
+
+#ifndef SMOLBOTE_ADDRESSBAR_H
+#define SMOLBOTE_ADDRESSBAR_H
+
+#include <QWidget>
+#include <functional>
+
+class QWebEngineView;
+class UrlLineEdit;
+class QProgressBar;
+class QMenu;
+class AddressBar : public QWidget
+{
+ Q_OBJECT
+
+public:
+ AddressBar(const QHash<QString, QString> &config, QWidget *parent = nullptr);
+ ~AddressBar() override;
+
+signals:
+ void complete(const QString &term, std::function<void(QStringList &)> callback);
+ void search(const QString &term);
+
+public slots:
+ void setView(QWebEngineView *view);
+ void setPageMenu(QMenu *menu);
+ void setToolsMenu(QMenu *menu);
+
+private:
+ UrlLineEdit *urlBar;
+ QProgressBar *progressBar;
+
+ QMetaObject::Connection urlChangedConnection, loadUrlConnection;
+ QMetaObject::Connection progressBarConnection;
+};
+
+#endif // SMOLBOTE_ADDRESSBAR_H
diff --git a/lib/addressbar/completer.cpp b/lib/addressbar/completer.cpp
new file mode 100644
index 0000000..9b95ac0
--- /dev/null
+++ b/lib/addressbar/completer.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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 "completer.h"
+#include <QKeyEvent>
+
+Completer::Completer(QWidget *parent)
+ : QListView(parent)
+{
+ setWindowFlags(Qt::ToolTip);
+}
+
+bool Completer::updateItems(const QStringList &list)
+{
+ if(list.isEmpty())
+ return false;
+
+ auto *model = new QStringListModel(list, this);
+ setModel(model);
+
+ delete completionModel;
+ completionModel = model;
+
+ return true;
+}
+
+bool Completer::keyPressed(QKeyEvent *event)
+{
+ if(isHidden())
+ return false;
+
+ Q_CHECK_PTR(completionModel);
+
+ int count = completionModel->rowCount();
+ const QModelIndex currentIndex = this->currentIndex();
+
+ switch(event->key()) {
+ case Qt::Key_Down:
+ if(currentIndex.row() + 1 >= count) {
+ setCurrentIndex(completionModel->index(0, 0));
+ } else {
+ setCurrentIndex(completionModel->index(currentIndex.row() + 1, 0));
+ }
+ break;
+
+ case Qt::Key_Up:
+ if(currentIndex.row() == 0) {
+ setCurrentIndex(completionModel->index(count - 1, 0));
+ } else {
+ setCurrentIndex(completionModel->index(currentIndex.row() - 1, 0));
+ }
+ break;
+
+ case Qt::Key_Escape:
+ hide();
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
diff --git a/lib/addressbar/completer.h b/lib/addressbar/completer.h
new file mode 100644
index 0000000..03ff317
--- /dev/null
+++ b/lib/addressbar/completer.h
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+#ifndef SMOLBOTE_COMPLETER_H
+#define SMOLBOTE_COMPLETER_H
+
+#include <QListView>
+#include <QStringListModel>
+#include <QTreeWidgetItem>
+
+class Completer : public QListView
+{
+
+ Q_OBJECT
+
+public:
+ explicit Completer(QWidget *parent = nullptr);
+
+ bool updateItems(const QStringList &list);
+
+ bool keyPressed(QKeyEvent *event);
+
+private:
+ QStringListModel *completionModel = nullptr;
+};
+
+#endif //SMOLBOTE_COMPLETER_H
diff --git a/lib/addressbar/urllineedit.cpp b/lib/addressbar/urllineedit.cpp
new file mode 100644
index 0000000..27acf60
--- /dev/null
+++ b/lib/addressbar/urllineedit.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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 <QLabel>
+#include <QMenu>
+#include <QShortcut>
+#include <QTimer>
+#include <QWidgetAction>
+
+UrlLineEdit::UrlLineEdit(QWidget *parent)
+ : QLineEdit(parent)
+ , m_listView(new Completer(this))
+{
+ setPlaceholderText(tr("Enter address"));
+
+ m_listView->setVisible(false);
+
+ pageMenu_action = addAction(style()->standardIcon(QStyle::SP_DriveNetIcon), QLineEdit::LeadingPosition);
+ connect(pageMenu_action, &QAction::triggered, pageMenu_action, [&]() {
+ if(pageMenu_action->menu()) {
+ pageMenu_action->menu()->exec(this->mapToGlobal(QPoint(0, height())));
+ }
+ });
+
+ toolsMenu_action = addAction(style()->standardIcon(QStyle::SP_FileIcon), QLineEdit::TrailingPosition);
+ connect(toolsMenu_action, &QAction::triggered, toolsMenu_action, [&]() {
+ if(toolsMenu_action->menu()) {
+ toolsMenu_action->menu()->exec(this->mapToGlobal(QPoint(width(), height())));
+ }
+ });
+
+ QTextCharFormat hostnameFormat;
+ hostnameFormat.setFontWeight(QFont::Bold);
+ m_hostFormat.format = hostnameFormat;
+}
+
+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::updateCompleter(const 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<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/addressbar/urllineedit.h b/lib/addressbar/urllineedit.h
new file mode 100644
index 0000000..f27addc
--- /dev/null
+++ b/lib/addressbar/urllineedit.h
@@ -0,0 +1,51 @@
+/*
+ * 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
+ */
+
+#ifndef SMOLBOTE_URLLINEEDIT_H
+#define SMOLBOTE_URLLINEEDIT_H
+
+#include "completer.h"
+#include <QAction>
+#include <QLineEdit>
+#include <QTextLayout>
+
+class QMenu;
+class WebView;
+class UrlLineEdit : public QLineEdit
+{
+ Q_OBJECT
+public:
+ explicit UrlLineEdit(QWidget *parent = nullptr);
+
+public slots:
+ void setUrl(const QUrl &url);
+
+ void updateCompleter(const QStringList &l);
+
+public:
+ // pageMenu action: zoom, print
+ QAction *pageMenu_action = nullptr;
+ // devMenu action: scripts, etc
+ QAction *toolsMenu_action = nullptr;
+
+protected:
+ void focusInEvent(QFocusEvent *event) override;
+ void focusOutEvent(QFocusEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+
+private:
+ void setTextFormat(const QTextLayout::FormatRange &format);
+ void clearTextFormat();
+
+ QTextLayout::FormatRange m_hostFormat;
+
+ // completer
+ Completer *m_listView;
+};
+
+#endif // SMOLBOTE_URLLINEEDIT_H