aboutsummaryrefslogtreecommitdiff
path: root/src/mainwindow/widgets
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2019-11-03 00:18:10 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2019-11-03 00:20:41 +0200
commitf3a4607d6a722a862af0eb9747a15dcdf624b6fb (patch)
tree9885709cdff55a865be6c03c591a9757680b0396 /src/mainwindow/widgets
parentChange spdlog from makedepends to depends (diff)
downloadsmolbote-f3a4607d6a722a862af0eb9747a15dcdf624b6fb.tar.xz
Drop boost dependency
- wrote not-invented-here config file parser and conf class - spent obscene amount of time plugging in said conf class
Diffstat (limited to 'src/mainwindow/widgets')
-rw-r--r--src/mainwindow/widgets/completer.cpp81
-rw-r--r--src/mainwindow/widgets/completer.h35
-rw-r--r--src/mainwindow/widgets/navigationbar.cpp18
-rw-r--r--src/mainwindow/widgets/navigationbar.h2
-rw-r--r--src/mainwindow/widgets/urllineedit.cpp157
-rw-r--r--src/mainwindow/widgets/urllineedit.h51
6 files changed, 335 insertions, 9 deletions
diff --git a/src/mainwindow/widgets/completer.cpp b/src/mainwindow/widgets/completer.cpp
new file mode 100644
index 0000000..578f745
--- /dev/null
+++ b/src/mainwindow/widgets/completer.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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/gitea/aqua/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#include "completer.h"
+#include <QKeyEvent>
+
+Completer::Completer(QWidget *parent)
+ : QListView(parent)
+{
+ setObjectName("Completer");
+ setWindowFlags(Qt::ToolTip);
+ setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ connect(this, &Completer::activated, [=](const QModelIndex &index) {
+ hide();
+ emit completionActivated(index.data().toString());
+ });
+}
+
+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;
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ hide();
+ emit completionActivated(currentIndex.data().toString());
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/mainwindow/widgets/completer.h b/src/mainwindow/widgets/completer.h
new file mode 100644
index 0000000..656a80f
--- /dev/null
+++ b/src/mainwindow/widgets/completer.h
@@ -0,0 +1,35 @@
+/*
+ * 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/gitea/aqua/smolbote
+ *
+ * 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);
+
+signals:
+ void completionActivated(const QString &url);
+
+private:
+ QStringListModel *completionModel = nullptr;
+};
+
+#endif //SMOLBOTE_COMPLETER_H
diff --git a/src/mainwindow/widgets/navigationbar.cpp b/src/mainwindow/widgets/navigationbar.cpp
index e77ce6d..f57d678 100644
--- a/src/mainwindow/widgets/navigationbar.cpp
+++ b/src/mainwindow/widgets/navigationbar.cpp
@@ -20,12 +20,14 @@
#include <QWebEngineHistory>
#include "webprofile.h"
-NavigationBar::NavigationBar(const Configuration *config, QWidget *parent)
+NavigationBar::NavigationBar(QWidget *parent)
: QToolBar(parent)
{
+ Configuration config;
+
// Back button
backAction = addAction(Util::icon(QStyle::SP_ArrowBack), tr("Back"));
- config->setShortcut(backAction, "navigation.shortcuts.back");
+ setShortcut(backAction, "shortcuts.navigation.back");
connect(backAction, &QAction::triggered, this, [this]() {
m_view->history()->back();
});
@@ -43,7 +45,7 @@ NavigationBar::NavigationBar(const Configuration *config, QWidget *parent)
});
backAction->setMenu(backMenu);
- auto *backMenuShortcut = new QShortcut(QKeySequence(config->value<QString>("navigation.shortcuts.backMenu").value()), this);
+ auto *backMenuShortcut = new QShortcut(QKeySequence(config.value<QString>("shortcuts.navigation.backmenu").value()), this);
connect(backMenuShortcut, &QShortcut::activated, backMenu, [this, backMenu]() {
if(backAction->isEnabled()) {
auto *widget = this->widgetForAction(backAction);
@@ -53,7 +55,7 @@ NavigationBar::NavigationBar(const Configuration *config, QWidget *parent)
// Forward button
forwardAction = addAction(Util::icon(QStyle::SP_ArrowForward), tr("Forward"));
- config->setShortcut(forwardAction, "navigation.shortcuts.forward");
+ setShortcut(forwardAction, "shortcuts.navigation.forward");
connect(forwardAction, &QAction::triggered, this, [this]() {
m_view->history()->forward();
});
@@ -71,7 +73,7 @@ NavigationBar::NavigationBar(const Configuration *config, QWidget *parent)
});
forwardAction->setMenu(forwardMenu);
- auto *forwardMenuShortcut = new QShortcut(QKeySequence(config->value<QString>("navigation.shortcuts.forwardMenu").value()), this);
+ auto *forwardMenuShortcut = new QShortcut(QKeySequence(config.value<QString>("shortcuts.navigation.forwardmenu").value()), this);
connect(forwardMenuShortcut, &QShortcut::activated, forwardMenu, [this, forwardMenu]() {
if(forwardAction->isEnabled()) {
auto *widget = this->widgetForAction(forwardAction);
@@ -81,7 +83,7 @@ NavigationBar::NavigationBar(const Configuration *config, QWidget *parent)
// Stop/Refresh button
stopReloadAction = addAction(Util::icon(QStyle::SP_BrowserReload), tr("Refresh"));
- config->setShortcut(stopReloadAction, "navigation.shortcuts.refresh");
+ setShortcut(stopReloadAction, "shortcuts.navigation.refresh");
connect(stopReloadAction, &QAction::triggered, this, [this]() {
if(m_view->isLoaded())
m_view->reload();
@@ -89,14 +91,14 @@ NavigationBar::NavigationBar(const Configuration *config, QWidget *parent)
m_view->stop();
});
- auto *reloadShortcut = new QShortcut(QKeySequence(config->value<QString>("navigation.shortcuts.reload").value()), this);
+ auto *reloadShortcut = new QShortcut(QKeySequence(config.value<QString>("shortcuts.navigation.reload").value()), this);
connect(reloadShortcut, &QShortcut::activated, this, [this]() {
m_view->triggerPageAction(QWebEnginePage::ReloadAndBypassCache);
});
// Home button
homeAction = addAction(Util::icon(QStyle::SP_DirHomeIcon), tr("Home"));
- config->setShortcut(homeAction, "navigation.shortcuts.home");
+ setShortcut(homeAction, "shortcuts.navigation.home");
connect(homeAction, &QAction::triggered, this, [this]() {
m_view->load(m_view->profile()->homepage());
});
diff --git a/src/mainwindow/widgets/navigationbar.h b/src/mainwindow/widgets/navigationbar.h
index 0b5a319..b8c73e1 100644
--- a/src/mainwindow/widgets/navigationbar.h
+++ b/src/mainwindow/widgets/navigationbar.h
@@ -18,7 +18,7 @@ class NavigationBar : public QToolBar
Q_OBJECT
public:
- explicit NavigationBar(const Configuration *config, QWidget *parent = nullptr);
+ explicit NavigationBar(QWidget *parent = nullptr);
public slots:
void connectWebView(WebView *view);
diff --git a/src/mainwindow/widgets/urllineedit.cpp b/src/mainwindow/widgets/urllineedit.cpp
new file mode 100644
index 0000000..378945f
--- /dev/null
+++ b/src/mainwindow/widgets/urllineedit.cpp
@@ -0,0 +1,157 @@
+/*
+ * 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/gitea/aqua/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#include "urllineedit.h"
+#include <QMenu>
+#include <QShortcut>
+#include <QApplication>
+#include <QClipboard>
+#include "../addressbar.h"
+
+UrlLineEdit::UrlLineEdit(QWidget *parent)
+ : QLineEdit(parent)
+ , m_listView(new Completer(this))
+{
+ setObjectName("UrlBar");
+ setPlaceholderText(tr("Enter address"));
+
+ m_listView->setVisible(false);
+ connect(m_listView, &Completer::completionActivated, this, &UrlLineEdit::setText);
+
+ addressbar = qobject_cast<AddressBar *>(parent);
+ Q_CHECK_PTR(addressbar);
+
+ auto *copyAction = new QAction(tr("Copy URL"), this);
+ connect(copyAction, &QAction::triggered, this, [this]() {
+ qApp->clipboard()->setText(this->text());
+ });
+ actions.append(copyAction);
+
+ auto *pasteAction = new QAction(tr("Paste URL"), this);
+ connect(pasteAction, &QAction::triggered, this, [this]() {
+ this->setText(qApp->clipboard()->text());
+ this->setFocus();
+ });
+ actions.append(pasteAction);
+
+ auto *loadAction = new QAction(tr("Paste and load"), this);
+ connect(loadAction, &QAction::triggered, this, [=]() {
+ emit addressbar->load(QUrl::fromUserInput(qApp->clipboard()->text()));
+ });
+ actions.append(loadAction);
+
+ auto *searchAction = new QAction(tr("Paste and search"), this);
+ connect(searchAction, &QAction::triggered, this, [=]() {
+ emit addressbar->search(qApp->clipboard()->text());
+ });
+ actions.append(searchAction);
+
+ menuAction = addAction(style()->standardIcon(QStyle::SP_DriveNetIcon), QLineEdit::LeadingPosition);
+ connect(menuAction, &QAction::triggered, this, [this]() {
+ auto *menu = new QMenu();
+ menu->setAttribute(Qt::WA_DeleteOnClose, true);
+ menu->setMinimumWidth(240);
+ menu->addActions(actions);
+
+ menu->exec(this->mapToGlobal(QPoint(0, height())));
+ });
+
+ auto *goAction = addAction(style()->standardIcon(QStyle::SP_DialogOkButton), QLineEdit::TrailingPosition);
+ connect(goAction, &QAction::triggered, this, [this]() {
+ emit returnPressed();
+ });
+
+ 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)
+{
+ // a context menu event also causes a focusInEvent, so if text is selected
+ // skip the formatting step
+ if(event->reason() == Qt::PopupFocusReason) {
+ QLineEdit::focusInEvent(event);
+ return;
+ }
+
+ clearTextFormat();
+ QLineEdit::focusInEvent(event);
+}
+
+void UrlLineEdit::focusOutEvent(QFocusEvent *event)
+{
+ // a context menu event causes a focusOutEvent, and setUrl will clear the
+ // selection, and this would prevent the menu from working properly
+ if(event->reason() == Qt::PopupFocusReason) {
+ QLineEdit::focusOutEvent(event);
+ return;
+ }
+
+ const QUrl url = QUrl::fromUserInput(text());
+ if(url.isValid())
+ setUrl(url);
+
+ emit addressbar->giveFocus();
+ QLineEdit::focusOutEvent(event);
+}
+
+void UrlLineEdit::keyPressEvent(QKeyEvent *event)
+{
+ if(m_listView->keyPressed(event)) {
+ 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/src/mainwindow/widgets/urllineedit.h b/src/mainwindow/widgets/urllineedit.h
new file mode 100644
index 0000000..88780a1
--- /dev/null
+++ b/src/mainwindow/widgets/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/gitea/aqua/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#ifndef SMOLBOTE_URLLINEEDIT_H
+#define SMOLBOTE_URLLINEEDIT_H
+
+#include "completer.h"
+#include <QAction>
+#include <QLineEdit>
+#include <QTextLayout>
+
+class AddressBar;
+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:
+ QAction *menuAction = 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();
+
+ QList<QAction *> actions;
+
+ QTextLayout::FormatRange m_hostFormat;
+
+ // completer
+ Completer *m_listView;
+ AddressBar *addressbar;
+};
+
+#endif // SMOLBOTE_URLLINEEDIT_H