aboutsummaryrefslogtreecommitdiff
path: root/lib
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 /lib
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 'lib')
-rw-r--r--lib/about/aboutdialog.cpp3
-rw-r--r--lib/addressbar/addressbar.cpp61
-rw-r--r--lib/addressbar/addressbar.h42
-rw-r--r--lib/addressbar/addressbar.ui59
-rw-r--r--lib/addressbar/completer.cpp81
-rw-r--r--lib/addressbar/completer.h35
-rw-r--r--lib/addressbar/meson.build15
-rw-r--r--lib/addressbar/urllineedit.cpp158
-rw-r--r--lib/addressbar/urllineedit.h51
-rw-r--r--lib/configuration/Kconfig131
-rw-r--r--lib/configuration/configuration.cpp205
-rw-r--r--lib/configuration/configuration.h136
-rw-r--r--lib/configuration/meson.build14
-rw-r--r--lib/pluginloader/Kconfig26
-rw-r--r--lib/pluginloader/pluginloader.cpp2
-rw-r--r--lib/webprofile/webprofilemanager.cpp8
-rw-r--r--lib/webprofile/webprofilemanager.h11
17 files changed, 143 insertions, 895 deletions
diff --git a/lib/about/aboutdialog.cpp b/lib/about/aboutdialog.cpp
index 1ca493e..99fb7ce 100644
--- a/lib/about/aboutdialog.cpp
+++ b/lib/about/aboutdialog.cpp
@@ -52,7 +52,8 @@ AboutDialog::AboutDialog(QWidget *parent)
"<p>Compiled with " compiler "</p>"
"<p>Libraries: <ul>"
"<li><a href='https://www.qt.io/'>Qt5</a> " QT_VERSION_STR "</li>"
- "<li><a href='https://www.boost.org/'>Boost</a></li>"
+ "<li>spdlog</li>"
+ "<li><a href='https://github.com/Taywee/args'>args.hxx</a></li>"
"<li><a href='https://github.com/itay-grudev/SingleApplication'>SingleApplication</a></li>"
#ifdef CONFIG_USEPLASMA
"<li><a href='https://community.kde.org/Frameworks'>KDE Frameworks</a></li>"
diff --git a/lib/addressbar/addressbar.cpp b/lib/addressbar/addressbar.cpp
deleted file mode 100644
index 2ea6d5e..0000000
--- a/lib/addressbar/addressbar.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 "addressbar.h"
-#include "ui_addressbar.h"
-#include <QShortcut>
-
-AddressBar::AddressBar(const QHash<QString, QString> &config, QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::AddressBar)
-{
- ui->setupUi(this);
-
- ui->urlBar->menuAction->setShortcut(QKeySequence(config.value("addressbar.shortcuts.menu")));
-
- auto *focusShortcut = new QShortcut(QKeySequence(config.value("addressbar.shortcuts.focus")), parent);
- connect(focusShortcut, &QShortcut::activated, ui->urlBar, [=]() {
- ui->urlBar->setFocus();
- ui->urlBar->selectAll();
- });
-
- connect(ui->urlBar, &UrlLineEdit::textEdited, [=](const QString &text) {
- std::function<void(QStringList &)> callback = std::bind(&UrlLineEdit::updateCompleter, ui->urlBar, std::placeholders::_1);
- emit complete(text, callback);
- });
-
- connect(ui->urlBar, &UrlLineEdit::returnPressed, [=]() {
- const QUrl url = QUrl::fromUserInput(ui->urlBar->text());
-
- // check if url contains \w+:// (matches protocol://) or contains a '.' (matches site.domain)
- // this is because single words are valid URLs for QUrl (searchterm becomes http://searchterm)
- // check for protocol://site because \. wouldn't match it (localhost is a search term; http://localhost is an address)
- if(ui->urlBar->text().contains(QRegularExpression("\\w+://|\\.")) && url.isValid()) {
- emit load(url);
- } else {
- emit search(ui->urlBar->text());
- }
- });
-}
-
-AddressBar::~AddressBar()
-{
- disconnect(this);
-}
-
-void AddressBar::setUrl(const QUrl &url)
-{
- if(url.isEmpty())
- ui->urlBar->clear();
- else
- ui->urlBar->setUrl(url);
-}
-
-void AddressBar::setProgress(int value) {
- ui->loadingBar->setValue(std::min(value, 100));
-}
diff --git a/lib/addressbar/addressbar.h b/lib/addressbar/addressbar.h
deleted file mode 100644
index 4609ac1..0000000
--- a/lib/addressbar/addressbar.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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_ADDRESSBAR_H
-#define SMOLBOTE_ADDRESSBAR_H
-
-#include <QWidget>
-#include <functional>
-
-namespace Ui {
-class AddressBar;
-}
-
-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);
- void load(const QUrl &url);
- void giveFocus();
-
-public slots:
- void setUrl(const QUrl &url);
- void setProgress(int value);
-
-private:
- Ui::AddressBar *ui;
-};
-
-#endif // SMOLBOTE_ADDRESSBAR_H
diff --git a/lib/addressbar/addressbar.ui b/lib/addressbar/addressbar.ui
deleted file mode 100644
index a5b4a4d..0000000
--- a/lib/addressbar/addressbar.ui
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>AddressBar</class>
- <widget class="QWidget" name="AddressBar">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>400</width>
- <height>31</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Form</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="UrlLineEdit" name="urlBar"/>
- </item>
- <item>
- <widget class="QProgressBar" name="loadingBar">
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>5</height>
- </size>
- </property>
- <property name="textVisible">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>UrlLineEdit</class>
- <extends>QLineEdit</extends>
- <header>urllineedit.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/lib/addressbar/completer.cpp b/lib/addressbar/completer.cpp
deleted file mode 100644
index 578f745..0000000
--- a/lib/addressbar/completer.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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/lib/addressbar/completer.h b/lib/addressbar/completer.h
deleted file mode 100644
index 656a80f..0000000
--- a/lib/addressbar/completer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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/lib/addressbar/meson.build b/lib/addressbar/meson.build
deleted file mode 100644
index 486d05d..0000000
--- a/lib/addressbar/meson.build
+++ /dev/null
@@ -1,15 +0,0 @@
-addressbar_inc = include_directories('.')
-addressbar_moc = mod_qt5.preprocess(
- moc_headers: ['addressbar.h', 'completer.h', 'urllineedit.h'],
- ui_files: ['addressbar.ui'],
- dependencies: dep_qt5
-)
-
-addressbar_lib = static_library('addressbar', ['addressbar.cpp', 'completer.cpp', 'urllineedit.cpp', addressbar_moc],
- dependencies: dep_qt5,
-)
-
-dep_addressbar = declare_dependency(
- include_directories: addressbar_inc,
- link_with: addressbar_lib
-)
diff --git a/lib/addressbar/urllineedit.cpp b/lib/addressbar/urllineedit.cpp
deleted file mode 100644
index 1084f25..0000000
--- a/lib/addressbar/urllineedit.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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/lib/addressbar/urllineedit.h b/lib/addressbar/urllineedit.h
deleted file mode 100644
index 4df8d21..0000000
--- a/lib/addressbar/urllineedit.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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 "addressbar.h"
-#include <QAction>
-#include <QLineEdit>
-#include <QTextLayout>
-
-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
diff --git a/lib/configuration/Kconfig b/lib/configuration/Kconfig
deleted file mode 100644
index b165093..0000000
--- a/lib/configuration/Kconfig
+++ /dev/null
@@ -1,131 +0,0 @@
-menu "Configuration defaults"
- config PATH_CONFIG
- string "Configuration location"
- default "~/.config/smolbote/smolbote.cfg"
- config PATH_FILTER
- string "Host filter path"
- default "~/.config/smolbote/hosts.d"
- config PATH_PLUGINS
- string "Plugin load location"
- default "~/.config/smolbote/plugins.d"
- config PATH_PROFILES
- string "Profile load location"
- default "~/.config/smolbote/profiles.d"
- config PATH_BOOKMARKS
- string "Bookmarks location"
- default "~/.config/smolbote/bookmarks.xbel"
- config PATH_DOWNLOADS
- string "Downloads location"
- default "~/Downloads"
- config PATH_SESSION
- string "Session location"
- default "~/.config/smolbote/session.d"
-endmenu
-
-menu "Keyboard shortcuts"
- comment "Main Window shortcuts"
- config SHORTCUT_WINDOW_NEWGROUP
- string "New Group shortcut"
- default "Ctrl+G"
- config SHORTCUT_WINDOW_NEWWINDOW
- string "New Window shortcut"
- default "Ctrl+N"
- config SHORTCUT_WINDOW_ABOUT
- string "Show About Dialog"
- default "Ctrl+H"
- config SHORTCUT_WINDOW_QUIT
- string "Quit shortcut"
- default "Ctrl+Q"
-
- config SHORTCUT_WINDOW_SEARCH
- string "Show or hide search box"
- default "F3"
-
- config SHORTCUT_WINDOW_BOOKMARKS
- string "Show bookmarks dialog in this window"
- default "Ctrl+B"
- config SHORTCUT_WINDOW_DOWNLOADS
- string "Show downloads dialog in this window"
- default "Ctrl+D"
-
- comment "Navigation Bar shortcuts"
- config SHORTCUT_NAVIGATION_BACK
- string "Go back in history"
- default "Ctrl+Left"
- config SHORTCUT_NAVIGATION_BACKMENU
- string "Show Back history menu"
- default "Ctrl+Down"
- config SHORTCUT_NAVIGATION_FORWARD
- string "Go forward in history"
- default "Ctrl+Right"
- config SHORTCUT_NAVIGATION_FORWARDMENU
- string "Show Forward history menu"
- default "Ctrl+Up"
- config SHORTCUT_NAVIGATION_REFRESH
- string "Refresh the page"
- default "F5"
- config SHORTCUT_NAVIGATION_RELOAD
- string "Reload the page"
- default "Ctrl+F5"
- config SHORTCUT_NAVIGATION_HOME
- string "Load homepage"
- default "Ctrl+Home"
-
- comment "Address Bar shortcuts"
- config SHORTCUT_ADDRESS_FOCUS
- string "Focus the Address Bar"
- default "F4"
- config SHORTCUT_ADDRESS_MENU
- string "Show Address Bar menu"
- default "F2"
-
- comment "Subwindow shortcuts"
- config SHORTCUT_SUBWINDOW_MENU
- string "Subwindow context menu"
- default "F1"
- config SHORTCUT_SUBWINDOW_TILE
- string "Tile subwindows"
- default "F9"
- config SHORTCUT_SUBWINDOW_CASCADE
- string "Cascade subwindow"
- default "F10"
- config SHORTCUT_SUBWINDOW_FULLSCREEN
- string "Make current subwindow fullscreen"
- default "F11"
-
- config SHORTCUT_SUBWINDOW_NEWTAB
- string "Create new tab"
- default "Ctrl+T"
- config SHORTCUT_SUBWINDOW_CLOSETAB
- string "Close current tab"
- default "Ctrl+X"
- config SHORTCUT_SUBWINDOW_TABLEFT
- string "Switch to the tab on the left"
- default "Ctrl+O"
- config SHORTCUT_SUBWINDOW_MOVETABLEFT
- string "Move tab to the left"
- default "Ctrl+Shift+O"
- config SHORTCUT_SUBWINDOW_TABRIGHT
- string "Switch to the tab on the right"
- default "Ctrl+P"
- config SHORTCUT_SUBWINDOW_MOVETABRIGHT
- string "Move tab to the right"
- default "Ctrl+Shift+P"
-
-endmenu
-
-menu "Profile defaults"
- config PROFILE_DEFAULT
- string "Default profile"
- default ""
- config PROFILE_DEFAULT_SEARCH
- string "Search engine"
- default "https://duckduckgo.com/?q=%1&ia=web"
- config PROFILE_DEFAULT_HOMEPAGE
- string "Homepage"
- default "about:blank"
- config PROFILE_DEFAULT_NEWTAB
- string "New tab page"
- default "about:blank"
-endmenu
-
diff --git a/lib/configuration/configuration.cpp b/lib/configuration/configuration.cpp
index 952f4b2..bd7700c 100644
--- a/lib/configuration/configuration.cpp
+++ b/lib/configuration/configuration.cpp
@@ -7,146 +7,97 @@
*/
#include "configuration.h"
-#include <QStandardPaths>
-#include <fstream>
-#include <boost/algorithm/string/predicate.hpp>
+#include <sstream>
+#include <algorithm>
+#include <stdexcept>
#include <iostream>
-#include <QCoreApplication>
-#include "config.h"
+#include <QStandardPaths>
-namespace po = boost::program_options;
+static std::unique_ptr<Configuration> s_conf;
-inline std::string defaultUserConfigLocation()
+inline void strip(std::string &value)
{
-#ifdef CONFIG_PATH_CONFIG
- return CONFIG_PATH_CONFIG;
-#else
- // try to locate an existing config
- QString path = QStandardPaths::locate(QStandardPaths::ConfigLocation, "smolbote/smolbote.cfg");
+ value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::bind1st(std::not_equal_to<char>(), ' ')));
+ value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());
+}
- // it's possible there is no config, so set the path properly
- if(path.isEmpty())
- path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/smolbote/smolbote.cfg";
- return path.toStdString();
-#endif
+Configuration::Configuration()
+ : use_global(true)
+{
+ if(!s_conf)
+ throw new std::runtime_error("Trying to use default Configuration, but none has been set!");
}
-Configuration::Configuration(int argc, char **argv, const std::string &path, QObject *parent)
- : QObject(parent)
- , m_homePath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString())
+Configuration::Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept
+ : m_homePath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString())
{
- configuration_desc.add_options()
- ("browser.stylesheet", po::value<std::string>())
- ("browser.iconTheme", po::value<std::string>(), "Icon theme")
- ("browser.locale", po::value<std::string>(), "Set Qt localization.")
- ("browser.translation", po::value<std::string>(), "Set application localization.")
-
- // sessions
- ("browser.session.path", po::value<std::string>()->default_value(CONFIG_PATH_SESSION))
-
-#ifdef CONFIG_USEBREAKPAD
- ("browser.crash.path", po::value<std::string>()->default_value(CONFIG_PATH_CRASHDUMP))
- ("browser.crash.handler", po::value<std::string>()->default_value(CONFIG_PATH_CRASHHANDLER))
-#endif
-
- // main window ui
- ("mainwindow.height", po::value<int>()->default_value(720))
- ("mainwindow.width", po::value<int>()->default_value(1280))
- ("mainwindow.maximized", po::value<bool>()->default_value(true))
- ("mainwindow.title", po::value<std::string>()->default_value(CONFIG_POI_NAME))
-
- // main window shortcuts
- ("mainwindow.shortcuts.saveSession", po::value<std::string>()->default_value("Ctrl+S,S"))
- ("mainwindow.shortcuts.openSession", po::value<std::string>()->default_value("Ctrl+S,O"))
-
- ("mainwindow.shortcuts.newGroup", po::value<std::string>()->default_value(CONFIG_SHORTCUT_WINDOW_NEWGROUP))
- ("mainwindow.shortcuts.newWindow", po::value<std::string>()->default_value(CONFIG_SHORTCUT_WINDOW_NEWWINDOW))
-
- ("mainwindow.shortcuts.about", po::value<std::string>()->default_value(CONFIG_SHORTCUT_WINDOW_ABOUT))
- ("mainwindow.shortcuts.quit", po::value<std::string>()->default_value(CONFIG_SHORTCUT_WINDOW_QUIT))
-
- ("mainwindow.shortcuts.search", po::value<std::string>()->default_value(CONFIG_SHORTCUT_WINDOW_SEARCH))
- ("mainwindow.shortcuts.tileWindows", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_TILE))
- ("mainwindow.shortcuts.cascadeWindows", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_CASCADE))
-
- // navigation
- ("navigation.movable", po::value<bool>()->default_value(false))
- ("navigation.shortcuts.back", po::value<std::string>()->default_value(CONFIG_SHORTCUT_NAVIGATION_BACK))
- ("navigation.shortcuts.backMenu", po::value<std::string>()->default_value(CONFIG_SHORTCUT_NAVIGATION_BACKMENU))
- ("navigation.shortcuts.forward", po::value<std::string>()->default_value(CONFIG_SHORTCUT_NAVIGATION_FORWARD))
- ("navigation.shortcuts.forwardMenu", po::value<std::string>()->default_value(CONFIG_SHORTCUT_NAVIGATION_FORWARDMENU))
- ("navigation.shortcuts.refresh", po::value<std::string>()->default_value(CONFIG_SHORTCUT_NAVIGATION_REFRESH))
- ("navigation.shortcuts.reload", po::value<std::string>()->default_value(CONFIG_SHORTCUT_NAVIGATION_RELOAD))
- ("navigation.shortcuts.home", po::value<std::string>()->default_value(CONFIG_SHORTCUT_NAVIGATION_HOME))
-
- // address bar
- ("addressbar.shortcuts.focus", po::value<std::string>()->default_value(CONFIG_SHORTCUT_ADDRESS_FOCUS))
- ("addressbar.shortcuts.menu", po::value<std::string>()->default_value(CONFIG_SHORTCUT_ADDRESS_MENU))
-
- // subwindow
- ("subwindow.shortcuts.menu", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_MENU))
- ("subwindow.shortcuts.new", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_NEWTAB))
- ("subwindow.shortcuts.close", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_CLOSETAB))
- ("subwindow.shortcuts.restoreTab", po::value<std::string>()->default_value("Ctrl+Shift+T"))
- ("subwindow.shortcuts.left", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_TABLEFT))
- ("subwindow.shortcuts.moveLeft", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_MOVETABLEFT))
- ("subwindow.shortcuts.right", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_TABRIGHT))
- ("subwindow.shortcuts.moveRight", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_MOVETABRIGHT))
- ("subwindow.shortcuts.fullscreen", po::value<std::string>()->default_value(CONFIG_SHORTCUT_SUBWINDOW_FULLSCREEN))
-
- // Filter settings
- ("filter.hosts", po::value<std::string>()->default_value(CONFIG_PATH_FILTER))
- ("filter.adblock", po::value<std::string>())
- ("filter.header", po::value<std::vector<std::string>>())
-// ("filter.cookies.block.all", po::value<bool>()->default_value(false))
-// ("filter.cookies.block.thirdParty", po::value<bool>()->default_value(true))
-// ("filter.cookies.path", po::value<std::string>()->default_value("~/.config/smolbote/cookies.d"))
-
- // Plugin settings
- ("plugins.path", po::value<std::string>()->default_value(CONFIG_PATH_PLUGINS))
-
- // Profile settings
- // default profile name the browser should use; "" is off-the-record
- ("profile.default", po::value<std::string>()->default_value(CONFIG_PROFILE_DEFAULT))
- ("profile.path", po::value<std::string>()->default_value(CONFIG_PATH_PROFILES))
- ("profile.search", po::value<std::string>()->default_value(CONFIG_PROFILE_DEFAULT_SEARCH))
- ("profile.homepage", po::value<std::string>()->default_value(CONFIG_PROFILE_DEFAULT_HOMEPAGE))
- ("profile.newtab", po::value<std::string>()->default_value(CONFIG_PROFILE_DEFAULT_NEWTAB))
-
- // Bookmark settings
- ("bookmarks.path", po::value<std::string>()->default_value(CONFIG_PATH_BOOKMARKS))
- ("bookmarks.shortcut", po::value<std::string>()->default_value(CONFIG_SHORTCUT_WINDOW_BOOKMARKS))
-
- // Downloads settings
- ("downloads.path", po::value<std::string>()->default_value(CONFIG_PATH_DOWNLOADS))
- ("downloads.shortcut", po::value<std::string>()->default_value(CONFIG_SHORTCUT_WINDOW_DOWNLOADS))
- ;
-
- // po::store will only overwrite values that are default, so:
- // 1. parse command line
- {
- auto cmd = po::command_line_parser(argc, argv);
- cmd.allow_unregistered();
- cmd.options(configuration_desc);
- po::store(cmd.run(), vm);
- }
- // 2. parse config file
- {
- std::ifstream f(path, std::ifstream::in);
- // parse_config_file(file, options_description, allow_unregistered)
- po::store(po::parse_config_file(f, configuration_desc, true), vm);
- }
+ for(const auto &i : l) {
+ insert_or_assign(i.first, i.second);
+ }
}
-QHash<QString, QString> Configuration::section(const std::string &prefix) const
+void Configuration::read(std::basic_istream<char> &input)
{
- QHash<QString, QString> v;
- for(auto &s : configuration_desc.options()) {
- if(boost::starts_with(s->long_name(), prefix)) {
- v[s->long_name().c_str()] = QString::fromStdString(value<std::string>(s->long_name().c_str()).value());
+ std::string line, key, value;
+ std::istringstream is_line;
+
+ while(std::getline(input, line)) {
+ if(line[0] == '#' || line.length() == 0)
+ continue;
+
+ is_line.clear();
+ is_line.str(line);
+
+ if(std::getline(is_line, key, '=')) {
+ is_line >> value;
+
+ strip(key);
+ strip(value);
+
+ if(this->count(key) == 0) {
+ // no type has been specified for this key, assuming std::string
+ insert(std::make_pair(key, value));
+ continue;
+ }
+
+ auto v = at(key);
+ if(std::holds_alternative<std::string>(v)) {
+ at(key) = value;
+ } else if(std::holds_alternative<int>(v)) {
+ at(key) = std::stoi(value);
+ } else if(std::holds_alternative<bool>(v)) {
+ at(key) = (value == "true");
+ }
+
}
}
+}
+
- return v;
+void Configuration::move_global(std::unique_ptr<Configuration> &&conf)
+{
+ s_conf = std::move(conf);
+}
+
+Configuration* Configuration::instance()
+{
+ return s_conf.get();
+}
+
+void setShortcut(QAction *action, const char *name)
+{
+ if(!s_conf)
+ throw new std::runtime_error("Trying to set a shortcut, but no configuration has been set!");
+
+ if(const auto shortcutText = s_conf->value<QString>(name)) {
+ const QString tooltip = action->toolTip();
+ action->setShortcut(QKeySequence::fromString(shortcutText.value()));
+ action->setToolTip(QString("%1 (%2)").arg(tooltip, shortcutText.value()));
+ }
+#ifdef QT_DEBUG
+ else {
+ std::cout << "fixme: setShortcut called for " << name << ", but no such value exists!" << std::endl;
+ }
+#endif
}
diff --git a/lib/configuration/configuration.h b/lib/configuration/configuration.h
index 40da50e..bc8f52e 100644
--- a/lib/configuration/configuration.h
+++ b/lib/configuration/configuration.h
@@ -9,121 +9,77 @@
#ifndef SMOLBOTE_CONFIGURATION_H
#define SMOLBOTE_CONFIGURATION_H
-#include <QAction>
-#include <QString>
-#include <QStringList>
-#include <QVariant>
-#include <boost/program_options.hpp>
#include <optional>
#include <string>
#include <vector>
+#include <unordered_map>
+#include <variant>
+#include <initializer_list>
+#include <memory>
+#include <QAction>
+#include <QString>
-class Configuration : public QObject
+typedef std::variant<std::string, int, bool> conf_value_t;
+
+class [[clang::consumable(unconsumed)]] Configuration : private std::unordered_map<std::string, conf_value_t>
{
- Q_OBJECT
public:
- explicit Configuration(int argc, char** argv, const std::string &path, QObject *parent = nullptr);
+ [[clang::return_typestate(unconsumed)]]
+ explicit Configuration();
+
+ [[clang::return_typestate(unconsumed)]]
+ explicit Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept;
+
+ explicit Configuration(Configuration &&other [[clang::param_typestate(unconsumed)]]) = default;
+
~Configuration() = default;
- bool exists(const char *path)
- {
- return vm.count(path) ? true : false;
- }
+ [[clang::callable_when(unconsumed)]]
+ void read(std::basic_istream<char> &input);
template <typename T>
- std::optional<T> value(const char *path) const
+ [[clang::callable_when(unconsumed)]] std::optional<T> value(const char *path) const
{
- // if setting doesn't exist, we crash
- // in debug builds, check if setting exists
-
- if(vm.count(path) == 0) {
+ if(use_global)
+ return instance()->value<T>(path);
+
+ if(this->count(path) == 0) {
return std::nullopt;
}
- // path is guaranteed to exist, so using vm[path] is safe
-
- if constexpr(std::is_same_v<T, QStringList>) {
- QStringList r;
- for(const std::string &item : vm[path].as<std::vector<std::string>>()) {
- r.append(QString::fromStdString(item));
- }
- return std::optional<QStringList>(r);
-
- } else if constexpr(std::is_same_v<T, std::string> || std::is_same_v<T, QString>) {
-
- if(vm[path].value().type() == typeid(int)) {
- if constexpr(std::is_same_v<T, std::string>)
- return std::optional<std::string>(std::to_string(vm[path].as<int>()));
- else if constexpr(std::is_same_v<T, QString>)
- return std::optional<QString>(QString::number(vm[path].as<int>()));
- }
-
- if(vm[path].value().type() == typeid(bool)) {
- return std::optional<T>(vm[path].as<bool>() ? "true" : "false");
- }
-
- std::string r = vm[path].as<std::string>();
+ // path is guaranteed to exist
+ const auto value = at(path);
- // check if it's a path
- if(r.front() == '~') {
+ if constexpr(std::is_same_v<T, QString> || std::is_same_v<T, std::string>) {
+ auto r = std::get<std::string>(value);
+ if(r.front() == '~')
r.replace(0, 1, m_homePath);
- }
- if constexpr(std::is_same_v<T, std::string>)
- return std::optional<std::string>(r);
- else if constexpr(std::is_same_v<T, QString>)
- return std::optional<QString>(QString::fromStdString(r));
+ if constexpr(std::is_same_v<T, QString>)
+ return std::make_optional(QString::fromStdString(r));
+ else
+ return std::make_optional(r);
- } else
- return std::optional<T>(vm[path].as<T>());
- }
-
- template <typename T>
- void setValue(const char *path, const T &value)
- {
- if(vm.count(path) == 0) {
- qWarning("value(%s) does not exist", path);
- }
-
- vm.at(path).value() = value;
-
- emit settingChanged(path, value);
- }
+ } else if constexpr(std::is_same_v<T, QStringList>) {
+ return std::make_optional(QString::fromStdString(std::get<std::string>(value)).split(';'));
- void setShortcut(QAction *action, const char *name) const
- {
- Q_CHECK_PTR(action);
-
- const auto shortcutText = this->value<QString>(name);
- if(shortcutText) {
- const QString tooltip = action->toolTip();
- action->setShortcut(QKeySequence::fromString(shortcutText.value()));
- action->setToolTip(QString("%1 (%2)").arg(tooltip, shortcutText.value()));
-
- connect(this, &Configuration::settingChanged, action, [=](const std::string &path, const QString &value) {
- if(path == name) {
- action->setShortcut(QKeySequence::fromString(value));
- action->setToolTip(QString("%1 (%2)").arg(tooltip, value));
- }
- });
- }
- }
-
- QHash<QString, QString> section(const std::string &prefix) const;
- const boost::program_options::options_description& description() const
- {
- return configuration_desc;
- }
+ } else if (std::holds_alternative<T>(value)) {
+ return std::optional<T>(std::get<T>(value));
+ } else
+ return std::nullopt;
+
+ } // std::optional<T> value(path) const
-signals:
- void settingChanged(const std::string &path, const QString &value);
+ static void move_global(std::unique_ptr<Configuration> &&conf);
private:
- boost::program_options::options_description configuration_desc;
- boost::program_options::variables_map vm;
+ static Configuration *instance();
const std::string m_homePath;
+ const bool use_global = false;
};
+void setShortcut(QAction *action, const char *name);
+
#endif // SMOLBOTE_CONFIGURATION_H
diff --git a/lib/configuration/meson.build b/lib/configuration/meson.build
index 19f57f4..939a493 100644
--- a/lib/configuration/meson.build
+++ b/lib/configuration/meson.build
@@ -1,13 +1,5 @@
-configuration_moc = mod_qt5.preprocess(
- moc_headers: ['configuration.h'],
- dependencies: dep_qt5
-)
-
-configuration_lib = static_library('configuration', ['configuration.cpp', configuration_moc],
- dependencies: [dep_boost, dep_qt5, autogen_config]
-)
-
dep_configuration = declare_dependency(
- include_directories: include_directories('.'),
- link_with: configuration_lib
+ include_directories: include_directories('.'),
+ link_with: static_library('configuration', ['configuration.cpp'], dependencies: dep_qt5)
)
+
diff --git a/lib/pluginloader/Kconfig b/lib/pluginloader/Kconfig
deleted file mode 100644
index 28a3b73..0000000
--- a/lib/pluginloader/Kconfig
+++ /dev/null
@@ -1,26 +0,0 @@
-config USEPLUGINS
- bool "Enable plugins"
- default y
-
-menu "Plugin Settings"
- depends on USEPLUGINS
-
- choice PLUGIN_SIGNATURE_CHECK
- bool "Plugin Signature enforcement"
- default PLUGIN_SIGNATURE_CHECKED
-
- config PLUGIN_SIGNATURE_IGNORED
- bool "Don't check plugin signatures"
-
- config PLUGIN_SIGNATURE_CHECKED
- bool "Don't load plugins with invalid signatures"
-
- config PLUGIN_SIGNATURE_ENFORCED
- bool "Only load plugins with valid signatures"
-
- endchoice
-
- config PLUGIN_SIGNATURE_HASH
- string "Hashing algorithm used by the signature"
- default "SHA256"
-endmenu
diff --git a/lib/pluginloader/pluginloader.cpp b/lib/pluginloader/pluginloader.cpp
index f47c39e..ef17513 100644
--- a/lib/pluginloader/pluginloader.cpp
+++ b/lib/pluginloader/pluginloader.cpp
@@ -56,7 +56,7 @@ PluginLoader::VerifyState PluginLoader::verify(const char *hashName) const
if(rc != 1)
return SignatureComputeFailed;
}
- delete buf;
+ delete[] buf;
plugin.close();
// read signature into DigestVerifyFinal
diff --git a/lib/webprofile/webprofilemanager.cpp b/lib/webprofile/webprofilemanager.cpp
index b0eff93..05808ab 100644
--- a/lib/webprofile/webprofilemanager.cpp
+++ b/lib/webprofile/webprofilemanager.cpp
@@ -11,7 +11,7 @@
#include <QFileInfo>
#include <QWebEngineSettings>
-WebProfileManager::WebProfileManager(const QHash<QString, QString> &profileSection, QObject *parent)
+WebProfileManager::WebProfileManager(const ProfileDefault_t &profileSection, QObject *parent)
: QObject(parent)
, defaults(profileSection)
{
@@ -62,17 +62,17 @@ WebProfile *WebProfileManager::profile(const QString &id, const QString &path, b
profile.settings->setValue("name", name);
});
- profile.ptr->setSearch(profile.value("search", defaults.value("profile.search")).toString());
+ profile.ptr->setSearch(profile.value("search", defaults.search).toString());
connect(profile.ptr, &WebProfile::searchChanged, profile.settings, [profile](const QString &url) {
profile.settings->setValue("search", url);
});
- profile.ptr->setHomepage(profile.value("homepage", defaults.value("profile.homepage")).toUrl());
+ profile.ptr->setHomepage(profile.value("homepage", defaults.homepage).toUrl());
connect(profile.ptr, &WebProfile::homepageChanged, profile.settings, [profile](const QUrl &url) {
profile.settings->setValue("homepage", url);
});
- profile.ptr->setNewtab(profile.value("newtab", defaults.value("profile.newtab")).toUrl());
+ profile.ptr->setNewtab(profile.value("newtab", defaults.newtab).toUrl());
connect(profile.ptr, &WebProfile::newtabChanged, profile.settings, [profile](const QUrl &url) {
profile.settings->setValue("newtab", url);
});
diff --git a/lib/webprofile/webprofilemanager.h b/lib/webprofile/webprofilemanager.h
index f7bf52a..3d86def 100644
--- a/lib/webprofile/webprofilemanager.h
+++ b/lib/webprofile/webprofilemanager.h
@@ -18,11 +18,18 @@
#include <QSettings>
#include <functional>
+struct ProfileDefault_t
+{
+ QString search;
+ QString homepage;
+ QString newtab;
+};
+
class WebProfileManager : public QObject
{
Q_OBJECT
public:
- explicit WebProfileManager(const QHash<QString, QString> &profileSection, QObject *parent);
+ explicit WebProfileManager(const ProfileDefault_t &profileSection, QObject *parent);
~WebProfileManager();
/** Create a profile with specified id
@@ -72,7 +79,7 @@ private:
};
QMap<QString, Profile> profiles;
- const QHash<QString, QString> defaults;
+ const ProfileDefault_t defaults;
};
#endif // SMOLBOTE_PROFILEMANAGER_H