aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--Kconfig173
-rw-r--r--include/browserinterface.h5
-rw-r--r--lib/about/aboutdialog.cpp3
-rw-r--r--lib/addressbar/meson.build15
-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
-rw-r--r--linux/.config101
-rw-r--r--linux/makepkg/PKGBUILD4
-rw-r--r--meson.build33
-rw-r--r--meson_options.txt1
-rw-r--r--src/browser.cpp91
-rw-r--r--src/browser.h7
-rw-r--r--src/conf.hpp.in32
-rw-r--r--src/main.cpp98
-rw-r--r--src/mainwindow/addressbar.cpp (renamed from lib/addressbar/addressbar.cpp)8
-rw-r--r--src/mainwindow/addressbar.h (renamed from lib/addressbar/addressbar.h)2
-rw-r--r--src/mainwindow/addressbar.ui (renamed from lib/addressbar/addressbar.ui)2
-rw-r--r--src/mainwindow/mainwindow.cpp29
-rw-r--r--src/mainwindow/mainwindow.h3
-rw-r--r--src/mainwindow/menubar.cpp42
-rw-r--r--src/mainwindow/menubar.h3
-rw-r--r--src/mainwindow/widgets/completer.cpp (renamed from lib/addressbar/completer.cpp)0
-rw-r--r--src/mainwindow/widgets/completer.h (renamed from lib/addressbar/completer.h)0
-rw-r--r--src/mainwindow/widgets/navigationbar.cpp18
-rw-r--r--src/mainwindow/widgets/navigationbar.h2
-rw-r--r--src/mainwindow/widgets/urllineedit.cpp (renamed from lib/addressbar/urllineedit.cpp)3
-rw-r--r--src/mainwindow/widgets/urllineedit.h (renamed from lib/addressbar/urllineedit.h)2
-rw-r--r--src/meson.build11
-rw-r--r--src/session/sessiondialog.cpp4
-rw-r--r--src/subwindow/subwindow.cpp5
-rw-r--r--src/subwindow/subwindow.h3
-rw-r--r--src/webengine/webview.cpp2
-rw-r--r--test/conf/main.cpp54
-rw-r--r--test/conf/meson.build6
-rw-r--r--test/conf/smolbote.cfg5
41 files changed, 645 insertions, 655 deletions
diff --git a/Kconfig b/Kconfig
index c7c0a1e..31ea895 100644
--- a/Kconfig
+++ b/Kconfig
@@ -5,19 +5,180 @@ menu "Application"
config POI_ICON
string "Path to icon"
default ":/icons/poi.svg"
+ config POI_CFG_PATH
+ string "Configuration location"
+ default "~/.config/smolbote/smolbote.cfg"
endmenu
-source 'lib/configuration/Kconfig'
+menu "Keyboard shortcuts"
+ comment "Main Window shortcuts"
+ config shortcuts.session.save
+ string "Save Session shortcut"
+ default "Ctrl+S,S"
+ config shortcuts.session.open
+ string "Load Session shortcut"
+ default "Ctrl+S,O"
+ config shortcuts.window.newgroup
+ string "New Group shortcut"
+ default "Ctrl+G"
+ config shortcuts.window.newwindow
+ string "New Window shortcut"
+ default "Ctrl+N"
+ config shortcuts.window.about
+ string "Show About Dialog"
+ default "Ctrl+H"
+ config shortcuts.window.quit
+ string "Quit shortcut"
+ default "Ctrl+Q"
+ config shortcuts.window.search
+ string "Show or hide search box"
+ default "F3"
+ config shortcuts.window.bookmarks.show
+ string "Show bookmarks dialog in this window"
+ default "Ctrl+B"
+ config shortcuts.window.downloads.show
+ string "Show downloads dialog in this window"
+ default "Ctrl+D"
-# Plugin loading
-source 'lib/pluginloader/Kconfig'
+ comment "Navigation Bar shortcuts"
+ config shortcuts.navigation.back
+ string "Go back in history"
+ default "Ctrl+Left"
+ config shortcuts.navigation.backmenu
+ string "Show Back history menu"
+ default "Ctrl+Down"
+ config shortcuts.navigation.forward
+ string "Go forward in history"
+ default "Ctrl+Right"
+ config shortcuts.navigation.forwardmenu
+ string "Show Forward history menu"
+ default "Ctrl+Up"
+ config shortcuts.navigation.refresh
+ string "Refresh the page"
+ default "F5"
+ config shortcuts.navigation.reload
+ string "Reload the page"
+ default "Ctrl+F5"
+ config shortcuts.navigation.home
+ string "Load homepage"
+ default "Ctrl+Home"
+
+ comment "Address Bar shortcuts"
+ config shortcuts.address.focus
+ string "Focus the Address Bar"
+ default "F4"
+ config shortcuts.address.menu
+ string "Show Address Bar menu"
+ default "F2"
+
+ comment "Subwindow shortcuts"
+ config shortcuts.subwindow.menu
+ string "Subwindow context menu"
+ default "F1"
+ config shortcuts.subwindow.tile
+ string "Tile subwindows"
+ default "F9"
+ config shortcuts.subwindow.cascade
+ string "Cascade subwindow"
+ default "F10"
+ config shortcuts.subwindow.fullscreen
+ string "Make current subwindow fullscreen"
+ default "F11"
+ config shortcuts.subwindow.newtab
+ string "Create new tab"
+ default "Ctrl+T"
+ config shortcuts.subwindow.closetab
+ string "Close current tab"
+ default "Ctrl+X"
+ config shortcuts.subwindow.restoretab
+ string "Restore last closed tab"
+ default "Ctrl+Shift+T"
+ config shortcuts.subwindow.tableft
+ string "Switch to the tab on the left"
+ default "Ctrl+O"
+ config shortcuts.subwindow.movetableft
+ string "Move tab to the left"
+ default "Ctrl+Shift+O"
+ config shortcuts.subwindow.tabright
+ string "Switch to the tab on the right"
+ default "Ctrl+P"
+ config shortcuts.subwindow.movetabright
+ string "Move tab to the right"
+ default "Ctrl+Shift+P"
+
+endmenu
+
+menu "Main Window"
+ config mainwindow.title
+ string "Main window title"
+ default "smolbote"
+ config mainwindow.width
+ int "Main window width"
+ default 1280
+ config mainwindow.height
+ int "Main window height"
+ default 720
+endmenu
+
+menu "Profile Settings"
+ config profile.path
+ string "Profile load location"
+ default "~/.config/smolbote/profiles.d"
+ config profile.default
+ string "Default profile"
+ default ""
+ config profile.search
+ string "Search engine"
+ default "https://duckduckgo.com/?q=%1&ia=web"
+ config profile.homepage
+ string "Homepage"
+ default "about:blank"
+ config profile.newtab
+ string "New tab page"
+ default "about:blank"
+endmenu
+
+config USEPLUGINS
+ bool "Enable plugins"
+ default y
+
+menu "Plugin Settings"
+ depends on USEPLUGINS
+ config plugins.path
+ string "Plugin load location"
+ default "~/.config/smolbote/plugins.d"
+ 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
+
+comment "Default paths"
+config filter.path
+ string "Host filter path"
+ default "~/.config/smolbote/hosts.d"
+config bookmarks.path
+ string "Bookmarks location"
+ default "~/.config/smolbote/bookmarks.xbel"
+config downloads.path
+ string "Downloads location"
+ default "~/Downloads"
+config session.path
+ string "Session location"
+ default "~/.config/smolbote/session.d"
config USEPLASMA
bool "Enable KDE Frameworks integration"
default n
- select SHOW_KDE_INTEGRATION
- help
- This is a help message
menu "KDE Integration"
depends on USEPLASMA
diff --git a/include/browserinterface.h b/include/browserinterface.h
index ef89456..4cdc63b 100644
--- a/include/browserinterface.h
+++ b/include/browserinterface.h
@@ -14,11 +14,6 @@ class BrowserInterface
public:
virtual ~BrowserInterface() = default;
- // configuration access
- virtual const QStringList configurationOptions() const = 0;
- virtual const QString configuration(const QString &key) const = 0;
- virtual void setConfiguration(const QString &key, const QString &value) = 0;
-
// profile access
virtual const QList<QPair<QString, Profile *>> profileList() const = 0;
virtual QPair<QString, Profile *> loadProfile(const QString &id, bool isOffTheRecord = true) = 0;
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/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/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
diff --git a/linux/.config b/linux/.config
index 3e8d40c..eea58d5 100644
--- a/linux/.config
+++ b/linux/.config
@@ -5,17 +5,8 @@
#
CONFIG_POI_NAME="smolbote"
CONFIG_POI_ICON=":/icon.svg"
-
-#
-# Configuration defaults
-#
-CONFIG_PATH_CONFIG="~/.config/smolbote/smolbote.cfg"
-CONFIG_PATH_FILTER="~/.config/smolbote/hosts.d"
-CONFIG_PATH_PLUGINS="~/.config/smolbote/plugins.d"
-CONFIG_PATH_PROFILES="~/.config/smolbote/profiles.d"
-CONFIG_PATH_BOOKMARKS="~/.config/smolbote/bookmarks.xbel"
-CONFIG_PATH_DOWNLOADS="~/Downloads"
-CONFIG_PATH_SESSION="~/.config/smolbote/session.d"
+CONFIG_POI_CFG_PATH="~/.config/smolbote/smolbote.cfg"
+# end of Application
#
# Keyboard shortcuts
@@ -24,61 +15,86 @@ CONFIG_PATH_SESSION="~/.config/smolbote/session.d"
#
# Main Window shortcuts
#
-CONFIG_SHORTCUT_WINDOW_NEWGROUP="Ctrl+G"
-CONFIG_SHORTCUT_WINDOW_NEWWINDOW="Ctrl+N"
-CONFIG_SHORTCUT_WINDOW_ABOUT="F1"
-CONFIG_SHORTCUT_WINDOW_QUIT="Ctrl+Q"
-CONFIG_SHORTCUT_WINDOW_SEARCH="F3"
-CONFIG_SHORTCUT_WINDOW_BOOKMARKS="Ctrl+B"
-CONFIG_SHORTCUT_WINDOW_DOWNLOADS="Ctrl+D"
+CONFIG_shortcuts.session.save="Ctrl+S,S"
+CONFIG_shortcuts.session.open="Ctrl+S,O"
+CONFIG_shortcuts.window.newgroup="Ctrl+G"
+CONFIG_shortcuts.window.newwindow="Ctrl+N"
+CONFIG_shortcuts.window.about="Ctrl+H"
+CONFIG_shortcuts.window.quit="Ctrl+Q"
+CONFIG_shortcuts.window.search="F3"
+CONFIG_shortcuts.window.bookmarks.show="Ctrl+B"
+CONFIG_shortcuts.window.downloads.show="Ctrl+D"
#
# Navigation Bar shortcuts
#
-CONFIG_SHORTCUT_NAVIGATION_BACK="Ctrl+Left"
-CONFIG_SHORTCUT_NAVIGATION_BACKMENU="Ctrl+Down"
-CONFIG_SHORTCUT_NAVIGATION_FORWARD="Ctrl+Right"
-CONFIG_SHORTCUT_NAVIGATION_FORWARDMENU="Ctrl+Up"
-CONFIG_SHORTCUT_NAVIGATION_REFRESH="F5"
-CONFIG_SHORTCUT_NAVIGATION_RELOAD="Ctrl+F5"
-CONFIG_SHORTCUT_NAVIGATION_HOME="Ctrl+Home"
+CONFIG_shortcuts.navigation.back="Ctrl+Left"
+CONFIG_shortcuts.navigation.backmenu="Ctrl+Down"
+CONFIG_shortcuts.navigation.forward="Ctrl+Right"
+CONFIG_shortcuts.navigation.forwardmenu="Ctrl+Up"
+CONFIG_shortcuts.navigation.refresh="F5"
+CONFIG_shortcuts.navigation.reload="Ctrl+F5"
+CONFIG_shortcuts.navigation.home="Ctrl+Home"
#
# Address Bar shortcuts
#
-CONFIG_SHORTCUT_ADDRESS_FOCUS="F4"
-CONFIG_SHORTCUT_ADDRESS_MENU="F2"
+CONFIG_shortcuts.address.focus="F4"
+CONFIG_shortcuts.address.menu="F2"
#
# Subwindow shortcuts
#
-CONFIG_SHORTCUT_SUBWINDOW_MENU="Ctrl+M"
-CONFIG_SHORTCUT_SUBWINDOW_TILE="F9"
-CONFIG_SHORTCUT_SUBWINDOW_CASCADE="F10"
-CONFIG_SHORTCUT_SUBWINDOW_FULLSCREEN="F11"
-CONFIG_SHORTCUT_SUBWINDOW_NEWTAB="Ctrl+T"
-CONFIG_SHORTCUT_SUBWINDOW_CLOSETAB="Ctrl+X"
-CONFIG_SHORTCUT_SUBWINDOW_TABLEFT="Ctrl+O"
-CONFIG_SHORTCUT_SUBWINDOW_MOVETABLEFT="Ctrl+Shift+O"
-CONFIG_SHORTCUT_SUBWINDOW_TABRIGHT="Ctrl+P"
-CONFIG_SHORTCUT_SUBWINDOW_MOVETABRIGHT="Ctrl+Shift+P"
+CONFIG_shortcuts.subwindow.menu="F1"
+CONFIG_shortcuts.subwindow.tile="F9"
+CONFIG_shortcuts.subwindow.cascade="F10"
+CONFIG_shortcuts.subwindow.fullscreen="F11"
+CONFIG_shortcuts.subwindow.newtab="Ctrl+T"
+CONFIG_shortcuts.subwindow.closetab="Ctrl+X"
+CONFIG_shortcuts.subwindow.restoretab="Ctrl+Shift+T"
+CONFIG_shortcuts.subwindow.tableft="Ctrl+O"
+CONFIG_shortcuts.subwindow.movetableft="Ctrl+Shift+O"
+CONFIG_shortcuts.subwindow.tabright="Ctrl+P"
+CONFIG_shortcuts.subwindow.movetabright="Ctrl+Shift+P"
+# end of Keyboard shortcuts
+
+#
+# Main Window
+#
+CONFIG_mainwindow.title="smolbote"
+CONFIG_mainwindow.width=1280
+CONFIG_mainwindow.height=720
+# end of Main Window
#
-# Profile defaults
+# Profile Settings
#
-CONFIG_PROFILE_DEFAULT=""
-CONFIG_PROFILE_DEFAULT_SEARCH="https://duckduckgo.com/?q=%1&ia=web"
-CONFIG_PROFILE_DEFAULT_HOMEPAGE="about:blank"
-CONFIG_PROFILE_DEFAULT_NEWTAB="about:blank"
+CONFIG_profile.path="~/.config/smolbote/profiles.d"
+CONFIG_profile.default=""
+CONFIG_profile.search="https://duckduckgo.com/?q=%1&ia=web"
+CONFIG_profile.homepage="about:blank"
+CONFIG_profile.newtab="about:blank"
+# end of Profile Settings
+
CONFIG_USEPLUGINS=y
#
# Plugin Settings
#
+CONFIG_plugins.path="~/.config/smolbote/plugins.d"
# CONFIG_PLUGIN_SIGNATURE_IGNORED is not set
CONFIG_PLUGIN_SIGNATURE_CHECKED=y
# CONFIG_PLUGIN_SIGNATURE_ENFORCED is not set
CONFIG_PLUGIN_SIGNATURE_HASH="SHA256"
+# end of Plugin Settings
+
+#
+# Default paths
+#
+CONFIG_filter.path="~/.config/smolbote/hosts.d"
+CONFIG_bookmarks.path="~/.config/smolbote/bookmarks.xbel"
+CONFIG_downloads.path="~/Downloads"
+CONFIG_session.path="~/.config/smolbote/session.d"
# CONFIG_USEPLASMA is not set
# CONFIG_USEBREAKPAD is not set
@@ -86,3 +102,4 @@ CONFIG_PLUGIN_SIGNATURE_HASH="SHA256"
# Workarounds
#
CONFIG_QTBUG_65223=y
+# end of Workarounds
diff --git a/linux/makepkg/PKGBUILD b/linux/makepkg/PKGBUILD
index 59f454d..9243405 100644
--- a/linux/makepkg/PKGBUILD
+++ b/linux/makepkg/PKGBUILD
@@ -12,9 +12,9 @@ install="smolbote.install"
arch=('x86_64')
license=('GPL3')
-depends=('qt5-webengine>=5.11.0' 'boost-libs>=1.66.0' 'spdlog')
+depends=('qt5-webengine>=5.11.0' 'spdlog')
optdepends=('firejail: launch a sandboxed instance')
-makedepends=('git' 'meson' 'boost' 'python-kconfiglib' 'openssl' 'qt5-tools' 'scdoc')
+makedepends=('git' 'meson' 'python-kconfiglib' 'openssl' 'qt5-tools' 'scdoc')
# this is the central repository
source=("git+https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote.git"
diff --git a/meson.build b/meson.build
index af2dd63..4092f5e 100644
--- a/meson.build
+++ b/meson.build
@@ -6,8 +6,24 @@ project('smolbote', 'cpp',
)
kconfig = import('unstable-kconfig')
-cdata = configuration_data(kconfig.load(host_machine.system() + '/.config'))
-config_h = configure_file(output: 'config.h', configuration: cdata)
+kconf = kconfig.load(host_machine.system() + '/.config')
+
+cdata = configuration_data(kconf)
+
+conf_init_list = '\n'
+foreach key, value : kconf
+ n = key.split('_')[1]
+ if n.contains('.')
+ if n.endswith('.width') or n.endswith('.height')
+ conf_init_list += ' { "@0@", @1@ },\n'.format(n.to_lower(), value.to_int())
+ else
+ conf_init_list += ' { "@0@", std::string(@1@) },\n'.format(n.to_lower(), value)
+ endif
+ endif
+endforeach
+cdata.set('conf_init_list', conf_init_list)
+
+configure_file(input: 'src/conf.hpp.in', output: 'conf.hpp', configuration: cdata)
version_h = vcs_tag(
command: [find_program('git').path(), 'describe', '--long', '--abbrev=40'],
@@ -16,11 +32,6 @@ version_h = vcs_tag(
output: 'version.h'
)
-autogen_config = declare_dependency(
- include_directories: include_directories('.'),
- sources: [config_h]
-)
-
# add -DQT_NO_DEBUG to non-debug builds
if not get_option('debug')
add_project_arguments('-DQT_NO_DEBUG', language: 'cpp')
@@ -37,14 +48,13 @@ add_project_arguments(cxx.get_supported_arguments([
'-mspeculative-load-hardening', # Spectre v1 mitigation
+ '-Wconsumed',
'-Wimplicit-fallthrough',
]), language: 'cpp')
mod_qt5 = import('qt5')
dep_qt5 = dependency('qt5', modules: ['Core', 'Network', 'Widgets', 'WebEngineWidgets', 'Concurrent'])
-dep_boost = dependency('boost', modules: ['program_options'])
-
dep_spdlog = dependency('spdlog', fallback: ['spdlog', 'spdlog_dep'], version: '>=1.3.1')
optional_deps = []
@@ -72,7 +82,6 @@ interfaces_moc = mod_qt5.preprocess(
)
subdir('lib/about')
-subdir('lib/addressbar')
subdir('lib/bookmarks')
subdir('lib/configuration')
subdir('lib/downloads')
@@ -87,6 +96,8 @@ subdir('src')
subdir('lang')
subdir('doc')
-subdir('plugins/ConfigurationEditor')
+#subdir('plugins/ConfigurationEditor')
subdir('plugins/ProfileEditor')
+subdir('test/conf')
+
diff --git a/meson_options.txt b/meson_options.txt
index 5f56ec2..8a3dfea 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -15,5 +15,4 @@ option('translations', description: 'Generate and install translations', type: '
option('Breakpad', description: 'Enable breakpad crash reporting', type: 'feature', value: 'auto')
option('Plasma', description: 'Enable KDE plasma integration', type: 'feature', value: 'auto')
option('Python', description: 'Enable Python interpreter', type: 'feature', value: 'auto')
-option('testing', description: 'Build tests (requires gtest)', type: 'feature', value: 'auto')
diff --git a/src/browser.cpp b/src/browser.cpp
index 0b076ca..d677997 100644
--- a/src/browser.cpp
+++ b/src/browser.cpp
@@ -9,9 +9,9 @@
#include "browser.h"
#include "aboutdialog.h"
#include "aboutplugin.h"
-#include "addressbar.h"
+#include "mainwindow/addressbar.h"
#include "bookmarkswidget.h"
-#include "config.h"
+#include "conf.hpp"
#include "configuration.h"
#include "downloadswidget.h"
#include "mainwindow/mainwindow.h"
@@ -39,6 +39,8 @@
#include "hostlist/hostlist.h"
#include <spdlog/spdlog.h>
#include <pluginloader.h>
+#include <QLibraryInfo>
+#include <QTranslator>
Browser::Browser(int &argc, char *argv[], bool allowSecondary)
: SingleApplication(argc, argv, allowSecondary, SingleApplication::User | SingleApplication::SecondaryNotification | SingleApplication::ExcludeAppVersion)
@@ -46,6 +48,29 @@ Browser::Browser(int &argc, char *argv[], bool allowSecondary)
setApplicationName(CONFIG_POI_NAME);
setWindowIcon(QIcon(CONFIG_POI_ICON));
setApplicationVersion(QVersionNumber::fromString(QLatin1String(poi_Version)).toString());
+
+ Configuration conf;
+
+ if(const auto _translation = conf.value<QString>("browser.translation")) {
+ auto *translator = new QTranslator(this);
+ if(translator->load(_translation.value()))
+ installTranslator(translator);
+ else
+ delete translator;
+ }
+
+ if(const auto _locale = conf.value<QString>("browser.locale")) {
+ auto *locale = new QTranslator(this);
+ if(locale->load("qt_" + _locale.value(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ installTranslator(locale);
+ else
+ delete locale;
+ }
+
+ if(auto iconTheme = conf.value<QString>("browser.iconTheme")) {
+ QIcon::setThemeName(iconTheme.value());
+ }
+
}
Browser::~Browser()
@@ -66,25 +91,6 @@ void Browser::about()
dlg->exec();
}
-const QStringList Browser::configurationOptions() const
-{
- QStringList options;
- for(const auto &option : m_config->description().options()) {
- options.append(QString::fromStdString(option->long_name()));
- }
- return options;
-}
-
-const QString Browser::configuration(const QString &key) const
-{
- return m_config->value<QString>(qUtf8Printable(key)).value_or(QString());
-}
-
-void Browser::setConfiguration(const QString &key, const QString &value)
-{
- m_config->setValue(qUtf8Printable(key), value);
-}
-
const QList<QPair<QString, Profile *>> Browser::profileList() const
{
QList<QPair<QString, Profile *>> profiles;
@@ -96,6 +102,8 @@ const QList<QPair<QString, Profile *>> Browser::profileList() const
QPair<QString, Profile *> Browser::loadProfile(const QString &id, bool isOffTheRecord)
{
+ Configuration conf;
+
const QString _id = [id](){
// if id contains a separator, it should be a path
if(id.contains(QDir::separator())) {
@@ -112,7 +120,7 @@ QPair<QString, Profile *> Browser::loadProfile(const QString &id, bool isOffTheR
for(UrlFilter *filter : m_filters) {
interceptor->addFilter(filter);
}
- const auto headers = m_config->value<QStringList>("filter.header").value_or(QStringList());
+ const auto headers = conf.value<QStringList>("filter.header").value_or(QStringList());
for(const QString &header : headers) {
const auto h = header.split(QLatin1Literal(":"));
if(h.length() == 2)
@@ -129,18 +137,6 @@ void Browser::removeProfile(const QString &id)
m_profileManager->deleteProfile(id);
}
-void Browser::setConfiguration(std::unique_ptr<Configuration> &config)
-{
- Q_ASSERT(config);
- m_config = std::move(config);
-}
-
-Configuration *Browser::getConfiguration() const
-{
- Q_ASSERT(m_config);
- return m_config.get();
-}
-
WebProfileManager *Browser::getProfileManager()
{
return m_profileManager;
@@ -172,13 +168,13 @@ QPluginLoader *Browser::addPlugin(const QString &path)
void Browser::setup(QVector<QPluginLoader *> plugins)
{
- Q_ASSERT(m_config);
+ Configuration conf;
+
for(QPluginLoader *loader : plugins) {
m_plugins.append(new PluginInfo(loader));
}
- auto stylesheet = m_config->value<QString>("browser.stylesheet");
- if(stylesheet) {
+ if(auto stylesheet = conf.value<QString>("browser.stylesheet")) {
QFile f(stylesheet.value());
if(f.open(QIODevice::ReadOnly)) {
setStyleSheet(f.readAll());
@@ -187,16 +183,17 @@ void Browser::setup(QVector<QPluginLoader *> plugins)
}
// downloads
- m_downloads = std::make_unique<DownloadsWidget>(m_config->value<QString>("downloads.path").value());
+ m_downloads = std::make_unique<DownloadsWidget>(conf.value<QString>("downloads.path").value());
+
// url request filter
- for(const QString &hostlist : Util::files(m_config->value<QString>("filter.hosts").value_or(QString()))) {
+ for(const QString &hostlist : Util::files(conf.value<QString>("filter.hosts").value_or(QString()))) {
QFile f(hostlist);
if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_filters.append(new HostList(&f));
f.close();
}
}
- for(const QString &adblock : Util::files(m_config->value<QString>("filter.adblock").value_or(QString()))) {
+ for(const QString &adblock : Util::files(conf.value<QString>("filter.adblock").value_or(QString()))) {
QFile f(adblock);
if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_filters.append(new AdBlockList(&f));
@@ -206,14 +203,18 @@ void Browser::setup(QVector<QPluginLoader *> plugins)
// cookie request filter
// load profiles
- m_profileManager = new WebProfileManager(m_config->section("profile"), this);
- for(const QString &profilePath : Util::files(m_config->value<QString>("profile.path").value(), { "*.profile" })) {
+ ProfileDefault_t p;
+ p.search = conf.value<QString>("profile.search").value();
+ p.homepage = conf.value<QString>("profile.homepage").value();
+ p.newtab = conf.value<QString>("profile.newtab").value();
+ m_profileManager = new WebProfileManager(p, this);
+ for(const QString &profilePath : Util::files(conf.value<QString>("profile.path").value(), { "*.profile" })) {
this->loadProfile(profilePath);
}
// set default profile
{
- const QString id = m_config->value<QString>("profile.default").value();
+ const QString id = conf.value<QString>("profile.default").value();
auto *profile = m_profileManager->profile(id);
if(profile == nullptr) {
profile = qobject_cast<WebProfile *>(loadProfile(id).second);
@@ -223,7 +224,7 @@ void Browser::setup(QVector<QPluginLoader *> plugins)
}
// bookmarks
- m_bookmarks = std::make_shared<BookmarksWidget>(QString::fromStdString(m_config->value<std::string>("bookmarks.path").value()));
+ m_bookmarks = std::make_shared<BookmarksWidget>(QString::fromStdString(conf.value<std::string>("bookmarks.path").value()));
connect(m_bookmarks.get(), &BookmarksWidget::showContextMenu, this, [this](const QUrl &url, const QPoint &pos) {
auto *subwindow = m_windows.last()->currentSubWindow();
if(subwindow == nullptr)
@@ -276,7 +277,7 @@ void Browser::showWidget(QWidget *widget, MainWindow *where) const
MainWindow *Browser::createWindow()
{
// the window will delete itself when it closes, so we don't need to delete it
- auto *window = new MainWindow(m_config);
+ auto *window = new MainWindow();
connect(window->addressBar, &AddressBar::complete, m_bookmarks.get(), &BookmarksWidget::search);
for(auto *info : m_plugins) {
diff --git a/src/browser.h b/src/browser.h
index a005513..1faf210 100644
--- a/src/browser.h
+++ b/src/browser.h
@@ -38,18 +38,12 @@ public slots:
public:
// interface
- Configuration *getConfiguration() const;
- const QStringList configurationOptions() const override;
- const QString configuration(const QString &key) const override;
- void setConfiguration(const QString &key, const QString &value) override;
-
WebProfileManager *getProfileManager();
const QList<QPair<QString, Profile *>> profileList() const override;
QPair<QString, Profile *> loadProfile(const QString &id, bool isOffTheRecord = true) override;
void removeProfile(const QString &id) override;
QPluginLoader *addPlugin(const QString &path = QString());
- void setConfiguration(std::unique_ptr<Configuration> &config);
void setup(QVector<QPluginLoader *> plugins);
@@ -87,7 +81,6 @@ private:
Q_DISABLE_COPY(Browser)
- std::unique_ptr<Configuration> m_config;
std::shared_ptr<BookmarksWidget> m_bookmarks;
std::unique_ptr<DownloadsWidget> m_downloads;
WebProfileManager *m_profileManager = nullptr;
diff --git a/src/conf.hpp.in b/src/conf.hpp.in
new file mode 100644
index 0000000..f509eb2
--- /dev/null
+++ b/src/conf.hpp.in
@@ -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/gitea/aqua/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#include "configuration.h"
+#include <fstream>
+
+#mesondefine CONFIG_POI_NAME
+#mesondefine CONFIG_POI_ICON
+#mesondefine CONFIG_POI_CFG_PATH
+
+#mesondefine CONFIG_QTBUG_65223
+
+inline void init_conf(const std::string &path)
+{
+ std::fstream fs;
+ fs.open(path, std::fstream::in);
+ assert(fs.is_open());
+
+ auto value_map = std::make_unique<Configuration, std::initializer_list<std::pair<std::string, conf_value_t>>>({
+ @conf_init_list@
+ });
+ value_map->read(fs);
+
+ Configuration::move_global(std::move(value_map));
+ fs.close();
+}
+
diff --git a/src/main.cpp b/src/main.cpp
index 02a1168..c6f4120 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -15,15 +15,15 @@
#include "util.h"
#include "version.h"
#include <QFile>
-#include <QLibraryInfo>
#include <QPluginLoader>
-#include <QTranslator>
#include <args.hxx>
#include <iostream>
#include <memory>
#include <plugininterface.h>
#include <pluginloader.h>
#include <spdlog/spdlog.h>
+#include "conf.hpp"
+#include <QStandardPaths>
typedef std::function<void(const std::string &, std::vector<std::string>::const_iterator, std::vector<std::string>::const_iterator)> subcommand_func;
typedef std::unordered_map<std::string, subcommand_func> command_map;
@@ -42,24 +42,6 @@ inline std::string join_keys(const command_map &map, const std::string sep = ",
return k;
}
-#include <QStandardPaths>
-inline std::string defaultUserConfigLocation()
-{
-#ifdef CONFIG_PATH_CONFIG
- return CONFIG_PATH_CONFIG;
-#else
- // try to locate an existing config
- QString path = QStandardPaths::locate(QStandardPaths::ConfigLocation, "smolbote/smolbote.cfg");
-
- // 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
-}
-
-#include "config.h"
#if defined(CONFIG_USEPLASMA) && !defined(PLASMA)
#error "You have enabled Plasma integration, but Frameworks was not found."
#endif
@@ -94,7 +76,7 @@ int main(int argc, char **argv)
args::PositionalList<std::string> cmd_args(parser, "URL(s)", "List of URLs to open");
try {
- auto next = parser.ParseArgs(args);
+ /*auto next = */parser.ParseArgs(args);
if(cmd_version)
return builtins::version();
@@ -121,52 +103,48 @@ int main(int argc, char **argv)
// create and load configuration
const std::string config_path = [&]() {
+ std::string path;
if(cmd_config)
- return args::get(cmd_config);
+ path = args::get(cmd_config);
else
- return defaultUserConfigLocation();
+ path = std::string(CONFIG_POI_CFG_PATH);
+
+ if(path.front() == '~')
+ path.replace(0, 1, QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString());
+
+ return path;
}();
- std::unique_ptr<Configuration> config = std::make_unique<Configuration>(argc, argv, config_path);
- QTranslator translator;
- if(config->exists("browser.translation")) {
- translator.load(config->value<QString>("browser.translation").value());
- }
+ spdlog::debug("Opening config file {}", config_path);
+ init_conf(config_path);
+
QVector<QPluginLoader *> plugins;
CommandHash_t pluginCommands;
// Load plugins
- for(const QString &path : Util::files(config->value<QString>("plugins.path").value(), { "*.so", "*.dll" })) {
- auto *loader = new PluginLoader(path);
- const bool loaded = loader->load();
- spdlog::info("{} plugin {}", loaded ? "Loaded" : "Failed to load", qUtf8Printable(path));
-
- if(loaded) {
- plugins.append(loader);
- auto *plugin = qobject_cast<PluginInterface *>(loader->instance());
- pluginCommands.unite(plugin->commands());
- } else {
- spdlog::warn("{}", qUtf8Printable(loader->errorString()));
- delete loader;
- }
+ [&]() {
+ Configuration conf;
+ spdlog::debug("plugins.path={}", conf.value<std::string>("plugins.path").value());
+ for(const QString &path : Util::files(conf.value<QString>("plugins.path").value(), { "*.so", "*.dll" })) {
+ auto *loader = new PluginLoader(path);
+ const bool loaded = loader->load();
+ spdlog::info("{} plugin {}", loaded ? "Loaded" : "Failed to load", qUtf8Printable(path));
+
+ if(loaded) {
+ plugins.append(loader);
+ auto *plugin = qobject_cast<PluginInterface *>(loader->instance());
+ pluginCommands.unite(plugin->commands());
+ } else {
+ spdlog::warn("{}", qUtf8Printable(loader->errorString()));
+ delete loader;
+ }
}
+ }();
// argc, argv, allowSecondary
Browser app(argc, argv);
// set this, otherwise the webview becomes black when using a stylesheet
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
- app.installTranslator(&translator);
- if(config->exists("browser.locale")) {
- auto *locale = new QTranslator(&app);
- if(locale->load("qt_" + config->value<QString>("browser.locale").value(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
- app.installTranslator(locale);
- else
- delete locale;
- }
-
- if(auto iconTheme = config->value<QString>("browser.iconTheme")) {
- QIcon::setThemeName(iconTheme.value());
- }
#ifdef CONFIG_USEBREAKPAD
const std::string crashpath = config->value<std::string>("browser.crash.path").value_or("/tmp");
@@ -186,14 +164,14 @@ int main(int argc, char **argv)
// minidump descriptor, filter callback, minidump callback, callback_context, install handler, server_fd
google_breakpad::ExceptionHandler eh(descriptor, nullptr, CrashHandler::dumpCallback, &ctx, true, -1);
-#ifdef QT_DEBUG
- spdlog::info("Installed breakpad exception handler (path {})", crashpath);
-#endif
+ spdlog::debug("Installed breakpad exception handler (path {})", crashpath);
#endif // CONFIG_USEBREAKPAD
- const auto profile = config->value<QString>("profile.default");
+ const auto profile = [](){
+ Configuration c;
+ return c.value<QString>("profile.default").value();
+ }();
- app.setConfiguration(config); // app takes ownership of config
app.setup(plugins);
QStringList urls;
@@ -225,7 +203,7 @@ int main(int argc, char **argv)
if(const auto pick = dlg->pickSession())
sessionData = pick.value();
else
- sessionData = Session::fromCommandLine(profile.value(), urls);
+ sessionData = Session::fromCommandLine(profile, urls);
} else if(cmd_session) {
QFile sessionJson(QString::fromStdString(args::get(cmd_session)));
if(sessionJson.open(QIODevice::ReadOnly | QIODevice::Text)) {
@@ -233,7 +211,7 @@ int main(int argc, char **argv)
sessionJson.close();
}
} else {
- sessionData = Session::fromCommandLine(profile.value(), urls);
+ sessionData = Session::fromCommandLine(profile, urls);
}
if(app.isPrimary() || cmd_noRemote) {
diff --git a/lib/addressbar/addressbar.cpp b/src/mainwindow/addressbar.cpp
index 2ea6d5e..42fa890 100644
--- a/lib/addressbar/addressbar.cpp
+++ b/src/mainwindow/addressbar.cpp
@@ -9,16 +9,18 @@
#include "addressbar.h"
#include "ui_addressbar.h"
#include <QShortcut>
+#include "configuration.h"
-AddressBar::AddressBar(const QHash<QString, QString> &config, QWidget *parent)
+AddressBar::AddressBar(QWidget *parent)
: QWidget(parent)
, ui(new Ui::AddressBar)
{
ui->setupUi(this);
- ui->urlBar->menuAction->setShortcut(QKeySequence(config.value("addressbar.shortcuts.menu")));
+ Configuration conf;
+ ui->urlBar->menuAction->setShortcut(QKeySequence(conf.value<QString>("shortcuts.address.menu").value()));
- auto *focusShortcut = new QShortcut(QKeySequence(config.value("addressbar.shortcuts.focus")), parent);
+ auto *focusShortcut = new QShortcut(QKeySequence(conf.value<QString>("shortcuts.address.focus").value()), parent);
connect(focusShortcut, &QShortcut::activated, ui->urlBar, [=]() {
ui->urlBar->setFocus();
ui->urlBar->selectAll();
diff --git a/lib/addressbar/addressbar.h b/src/mainwindow/addressbar.h
index 4609ac1..61d00e9 100644
--- a/lib/addressbar/addressbar.h
+++ b/src/mainwindow/addressbar.h
@@ -21,7 +21,7 @@ class AddressBar : public QWidget
Q_OBJECT
public:
- AddressBar(const QHash<QString, QString> &config, QWidget *parent = nullptr);
+ AddressBar(QWidget *parent = nullptr);
~AddressBar() override;
signals:
diff --git a/lib/addressbar/addressbar.ui b/src/mainwindow/addressbar.ui
index a5b4a4d..1af1689 100644
--- a/lib/addressbar/addressbar.ui
+++ b/src/mainwindow/addressbar.ui
@@ -51,7 +51,7 @@
<customwidget>
<class>UrlLineEdit</class>
<extends>QLineEdit</extends>
- <header>urllineedit.h</header>
+ <header>mainwindow/widgets/urllineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp
index 7fb7d9e..fa8b23a 100644
--- a/src/mainwindow/mainwindow.cpp
+++ b/src/mainwindow/mainwindow.cpp
@@ -9,7 +9,7 @@
#include "mainwindow.h"
#include "addressbar.h"
#include "browser.h"
-#include "config.h"
+#include "conf.hpp"
#include "configuration.h"
#include "menubar.h"
#include "webprofilemanager.h"
@@ -39,14 +39,11 @@
#include <KWindowEffects>
#endif
-MainWindow::MainWindow(const std::unique_ptr<Configuration> &config, QWidget *parent)
+MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
- , configuration(config.get())
, mdiArea(new QMdiArea(this))
{
- Q_ASSERT(config);
-
- m_menuBar = new MenuBar(config.get(), this);
+ m_menuBar = new MenuBar(this);
this->setMenuBar(m_menuBar);
#ifdef CONFIG_PLASMA_BLUR
@@ -54,10 +51,12 @@ MainWindow::MainWindow(const std::unique_ptr<Configuration> &config, QWidget *pa
KWindowEffects::enableBlurBehind(this->winId(), true);
#endif
+ Configuration config;
+
// create UI
- setWindowTitle(config->value<QString>("mainwindow.title").value());
- resize(config->value<int>("mainwindow.width").value(), config->value<int>("mainwindow.height").value());
- if(config->value<bool>("mainwindow.maximized").value()) {
+ setWindowTitle(config.value<QString>("mainwindow.title").value());
+ resize(config.value<int>("mainwindow.width").value(), config.value<int>("mainwindow.height").value());
+ if(config.value<bool>("mainwindow.maximized").value_or(false)) {
setWindowState(Qt::WindowMaximized);
}
show();
@@ -66,7 +65,7 @@ MainWindow::MainWindow(const std::unique_ptr<Configuration> &config, QWidget *pa
{
QAction *subwindowMenuAction = new QAction(this);
QMainWindow::addAction(subwindowMenuAction);
- config->setShortcut(subwindowMenuAction, "subwindow.shortcuts.menu");
+ setShortcut(subwindowMenuAction, "shortcuts.subwindow.menu");
connect(subwindowMenuAction, &QAction::triggered, this, [this]() {
QMdiSubWindow *window = mdiArea->currentSubWindow();
if(window != nullptr) {
@@ -78,12 +77,12 @@ MainWindow::MainWindow(const std::unique_ptr<Configuration> &config, QWidget *pa
});
}
- navigationToolBar = new NavigationBar(config.get(), this);
- navigationToolBar->setMovable(config->value<bool>("navigation.movable").value());
+ navigationToolBar = new NavigationBar(this);
+ navigationToolBar->setMovable(config.value<bool>("navigation.movable").value_or(false));
addToolBar(Qt::TopToolBarArea, navigationToolBar);
navigationToolBar->connectWebView(nullptr);
- addressBar = new AddressBar(config->section("addressbar"), this);
+ addressBar = new AddressBar(this);
navigationToolBar->addWidget(addressBar);
mdiArea->setBackground(Qt::NoBrush);
@@ -134,7 +133,7 @@ MainWindow::MainWindow(const std::unique_ptr<Configuration> &config, QWidget *pa
// search box
auto *searchAction = new QAction(this);
- config->setShortcut(searchAction, "mainwindow.shortcuts.search");
+ setShortcut(searchAction, "shortcuts.window.search");
connect(searchAction, &QAction::triggered, this, [=]() {
/* QTBUG-18665
* When focusing out of the search box and hiding it, the first
@@ -224,7 +223,7 @@ SubWindow *MainWindow::createSubWindow(WebProfile *profile, bool openProfileNewt
shouldMaximize = currentWindow->isMaximized();
}
- auto *w = new SubWindow(configuration, this);
+ auto *w = new SubWindow(this);
m_menuBar->insertSubWindow(w);
w->setProfile(profile);
diff --git a/src/mainwindow/mainwindow.h b/src/mainwindow/mainwindow.h
index 44ee633..dc185da 100644
--- a/src/mainwindow/mainwindow.h
+++ b/src/mainwindow/mainwindow.h
@@ -35,7 +35,7 @@ public:
ToolsMenu
};
- explicit MainWindow(const std::unique_ptr<Configuration> &config, QWidget *parent = nullptr);
+ explicit MainWindow(QWidget *parent = nullptr);
Q_DISABLE_COPY(MainWindow)
~MainWindow() override;
@@ -56,7 +56,6 @@ protected:
void closeEvent(QCloseEvent *event) override;
private:
- const Configuration *configuration = nullptr;
MenuBar *m_menuBar = nullptr;
QMenu *toolsMenu = nullptr;
QMenu *pageLoadProfileMenu = nullptr;
diff --git a/src/mainwindow/menubar.cpp b/src/mainwindow/menubar.cpp
index 7b7d912..2ce87f7 100644
--- a/src/mainwindow/menubar.cpp
+++ b/src/mainwindow/menubar.cpp
@@ -67,7 +67,7 @@ inline QDialog *createDevToolsDialog(QWebEnginePage *page)
return popup;
}
-MenuBar::MenuBar(const Configuration *config, MainWindow *parent)
+MenuBar::MenuBar(MainWindow *parent)
: QMenuBar(parent)
{
auto *browser = qobject_cast<Browser *>(qApp);
@@ -108,30 +108,31 @@ MenuBar::MenuBar(const Configuration *config, MainWindow *parent)
smolbote->addSeparator();
- const QString sessionPath = config->value<QString>("browser.session.path").value();
+ Configuration conf;
+ const QString sessionPath = conf.value<QString>("session.path").value();
auto *actionSaveSession = smolbote->addAction(tr("Save Session"), parent, [sessionPath]() {
auto *sessionDialog = new SaveSessionDialog(nullptr);
if(sessionDialog->exec() == QDialog::Accepted)
sessionDialog->save(sessionPath);
});
- config->setShortcut(actionSaveSession, "mainwindow.shortcuts.saveSession");
+ setShortcut(actionSaveSession, "shortcuts.session.save");
auto *actionOpenSession = smolbote->addAction(tr("Open Session"), parent, [parent]() {
auto *sessionDialog = new SessionDialog(parent);
sessionDialog->exec();
});
- config->setShortcut(actionOpenSession, "mainwindow.shortcuts.openSession");
+ setShortcut(actionOpenSession, "shortcuts.session.open");
smolbote->addSeparator();
auto *actionBookmarks = smolbote->addAction(tr("Bookmarks"), browser, [browser, parent]() {
browser->showWidget(browser->bookmarks(), parent);
});
- config->setShortcut(actionBookmarks, "bookmarks.shortcut");
+ setShortcut(actionBookmarks, "shortcuts.window.bookmarks.show");
auto *actionDownloads = smolbote->addAction(tr("Downloads"), browser, [browser, parent]() {
browser->showWidget(browser->downloads(), parent);
});
- config->setShortcut(actionDownloads, "downloads.shortcut");
+ setShortcut(actionDownloads, "shortcuts.window.downloads.show");
smolbote->addSeparator();
smolbote->addAction(tr("Load Plugin"), browser, [browser]() {
@@ -142,34 +143,31 @@ MenuBar::MenuBar(const Configuration *config, MainWindow *parent)
pluginInsertLocation = smolbote->addSeparator();
auto *actionAbout = smolbote->addAction(tr("About"), browser, &Browser::about);
- config->setShortcut(actionAbout, "mainwindow.shortcuts.about");
-
-// smolbote->addAction(tr("Help"));
-// smolbote->addAction(tr("Check for updates"));
+ setShortcut(actionAbout, "shortcuts.window.about");
smolbote->addSeparator();
auto *actionQuit = smolbote->addAction(tr("Quit"), qApp, &QApplication::quit);
- config->setShortcut(actionQuit, "mainwindow.shortcuts.quit");
+ setShortcut(actionQuit, "shortcuts.window.quit");
}
window = this->addMenu(tr("&Window"));
{
auto *actionNewWindow = window->addAction(tr("New Window"), browser, &Browser::createWindow);
- config->setShortcut(actionNewWindow, "mainwindow.shortcuts.newWindow");
+ setShortcut(actionNewWindow, "shortcuts.window.newwindow");
auto *actionNewSubwindow = window->addAction(tr("New Subwindow"), parent, [parent]() {
parent->createSubWindow(nullptr, true);
});
- config->setShortcut(actionNewSubwindow, "mainwindow.shortcuts.newGroup");
+ setShortcut(actionNewSubwindow, "shortcuts.window.newgroup");
window->addSeparator();
auto *actionTileSubwindows = window->addAction(tr("Tile Subwindows"), parent->mdiArea, &QMdiArea::tileSubWindows);
- config->setShortcut(actionTileSubwindows, "mainwindow.shortcuts.tileWindows");
+ setShortcut(actionTileSubwindows, "shortcuts.subwindow.tile");
auto *actionCascadeSubwindows = window->addAction(tr("Cascade Subwindows"), parent->mdiArea, &QMdiArea::cascadeSubWindows);
- config->setShortcut(actionCascadeSubwindows, "mainwindow.shortcuts.cascadeWindows");
+ setShortcut(actionCascadeSubwindows, "shortcuts.subwindow.cascade");
window->addSeparator()->setText(tr("Subwindows"));
}
@@ -182,7 +180,7 @@ MenuBar::MenuBar(const Configuration *config, MainWindow *parent)
_subwindow->setCurrentTab(index);
});
});
- config->setShortcut(actionNewTab, "subwindow.shortcuts.new");
+ setShortcut(actionNewTab, "shortcuts.subwindow.newtab");
subwindow->addSeparator();
@@ -192,7 +190,7 @@ MenuBar::MenuBar(const Configuration *config, MainWindow *parent)
_subwindow->setCurrentTab(index);
});
});
- config->setShortcut(actionRestoreTab, "subwindow.shortcuts.restoreTab");
+ setShortcut(actionRestoreTab, "shortcuts.subwindow.restoretab");
auto *restoreTabsMenu = subwindow->addMenu(tr("Restore previous tab"));
connect(restoreTabsMenu, &QMenu::aboutToShow, parent, [parent, restoreTabsMenu]() {
@@ -242,28 +240,28 @@ MenuBar::MenuBar(const Configuration *config, MainWindow *parent)
_subwindow->setCurrentTab(qMax(0, currentIdx - 1));
});
});
- config->setShortcut(leftTab, "subwindow.shortcuts.left");
+ setShortcut(leftTab, "shortcuts.subwindow.tableft");
auto *moveTabLeft = subwindow->addAction(tr("Move tab left"), parent, [parent]() {
run_if(parent->currentSubWindow(), [](SubWindow *_subwindow, int currentIdx) {
_subwindow->moveTab(currentIdx, currentIdx - 1);
});
});
- config->setShortcut(moveTabLeft, "subwindow.shortcuts.moveLeft");
+ setShortcut(moveTabLeft, "shortcuts.subwindow.movetableft");
auto *rightTab = subwindow->addAction(tr("Switch to tab on the right"), parent, [parent]() {
run_if(parent->currentSubWindow(), [](SubWindow *_subwindow, int currentIdx) {
_subwindow->setCurrentTab(qMin(currentIdx + 1, _subwindow->tabCount() - 1));
});
});
- config->setShortcut(rightTab, "subwindow.shortcuts.right");
+ setShortcut(rightTab, "shortcuts.subwindow.tabright");
auto *moveTabRight = subwindow->addAction(tr("Move tab right"), parent, [parent]() {
run_if(parent->currentSubWindow(), [](SubWindow *_subwindow, int currentIdx) {
_subwindow->moveTab(currentIdx, currentIdx + 1);
});
});
- config->setShortcut(moveTabRight, "subwindow.shortcuts.moveRight");
+ setShortcut(moveTabRight, "shortcuts.subwindow.movetabright");
subwindow->addSeparator();
@@ -272,7 +270,7 @@ MenuBar::MenuBar(const Configuration *config, MainWindow *parent)
_subwindow->closeTab(currentIdx);
});
});
- config->setShortcut(closeTab, "subwindow.shortcuts.close");
+ setShortcut(closeTab, "shortcuts.subwindow.closetab");
subwindow->addAction(tr("Close tabs to the left"), parent, [parent]() {
run_if(parent->currentSubWindow(), [](SubWindow *_subwindow, int currentIdx) {
diff --git a/src/mainwindow/menubar.h b/src/mainwindow/menubar.h
index 0d94f30..f4d39c5 100644
--- a/src/mainwindow/menubar.h
+++ b/src/mainwindow/menubar.h
@@ -11,7 +11,6 @@
#include <QMenuBar>
-class Configuration;
class MainWindow;
class SubWindow;
class MenuBar : public QMenuBar
@@ -19,7 +18,7 @@ class MenuBar : public QMenuBar
Q_OBJECT
public:
- MenuBar(const Configuration *config, MainWindow *parent = nullptr);
+ MenuBar(MainWindow *parent = nullptr);
QAction *insertPlugin(QMenu *menu);
void insertSubWindow(SubWindow *subwindow);
diff --git a/lib/addressbar/completer.cpp b/src/mainwindow/widgets/completer.cpp
index 578f745..578f745 100644
--- a/lib/addressbar/completer.cpp
+++ b/src/mainwindow/widgets/completer.cpp
diff --git a/lib/addressbar/completer.h b/src/mainwindow/widgets/completer.h
index 656a80f..656a80f 100644
--- a/lib/addressbar/completer.h
+++ b/src/mainwindow/widgets/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/lib/addressbar/urllineedit.cpp b/src/mainwindow/widgets/urllineedit.cpp
index 1084f25..378945f 100644
--- a/lib/addressbar/urllineedit.cpp
+++ b/src/mainwindow/widgets/urllineedit.cpp
@@ -11,8 +11,7 @@
#include <QShortcut>
#include <QApplication>
#include <QClipboard>
-
-#include "addressbar.h"
+#include "../addressbar.h"
UrlLineEdit::UrlLineEdit(QWidget *parent)
: QLineEdit(parent)
diff --git a/lib/addressbar/urllineedit.h b/src/mainwindow/widgets/urllineedit.h
index 4df8d21..88780a1 100644
--- a/lib/addressbar/urllineedit.h
+++ b/src/mainwindow/widgets/urllineedit.h
@@ -10,11 +10,11 @@
#define SMOLBOTE_URLLINEEDIT_H
#include "completer.h"
-#include "addressbar.h"
#include <QAction>
#include <QLineEdit>
#include <QTextLayout>
+class AddressBar;
class WebView;
class UrlLineEdit : public QLineEdit
{
diff --git a/src/meson.build b/src/meson.build
index d2ff9ad..b263b5f 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,11 +1,11 @@
# poi
poi_moc = mod_qt5.preprocess(
moc_headers: ['browser.h',
- 'mainwindow/mainwindow.h', 'mainwindow/menubar.h', 'mainwindow/widgets/dockwidget.h', 'mainwindow/widgets/menusearch.h', 'mainwindow/widgets/navigationbar.h', 'mainwindow/widgets/searchform.h',
+ 'mainwindow/mainwindow.h', 'mainwindow/addressbar.h', 'mainwindow/menubar.h', 'mainwindow/widgets/completer.h', 'mainwindow/widgets/urllineedit.h', 'mainwindow/widgets/dockwidget.h', 'mainwindow/widgets/menusearch.h', 'mainwindow/widgets/navigationbar.h', 'mainwindow/widgets/searchform.h',
'session/savesessiondialog.h', 'session/sessiondialog.h', 'session/sessionform.h',
'subwindow/subwindow.h', 'subwindow/tabwidget.h',
'webengine/urlinterceptor.h', 'webengine/webpage.h', 'webengine/webview.h'],
- ui_files: ['mainwindow/widgets/searchform.ui', 'session/savesessiondialog.ui', 'session/sessiondialog.ui', 'session/sessionform.ui'],
+ ui_files: ['mainwindow/addressbar.ui', 'mainwindow/widgets/searchform.ui', 'session/savesessiondialog.ui', 'session/sessiondialog.ui', 'session/sessionform.ui'],
qresources: '../data/resources.qrc',
rcc_extra_arguments: ['--format-version=1'],
dependencies: dep_qt5
@@ -13,15 +13,18 @@ poi_moc = mod_qt5.preprocess(
poi = executable(get_option('poiName'), install: true,
cpp_args: ['-DQAPPLICATION_CLASS=QApplication'],
- dependencies: [dep_qt5, dep_boost, dep_spdlog, dep_SingleApplication, dep_args, optional_deps,
- dep_about, dep_addressbar, dep_bookmarks, dep_configuration, dep_downloads, dep_pluginloader, dep_urlfilter, dep_webprofile],
+ dependencies: [dep_qt5, dep_spdlog, dep_SingleApplication, dep_args, optional_deps,
+ dep_about, dep_bookmarks, dep_configuration, dep_downloads, dep_pluginloader, dep_urlfilter, dep_webprofile],
include_directories: [include],
sources: ['main.cpp', 'builtins.cpp', 'crashhandler.cpp', poi_moc, version_h,
'browser.cpp',
'util.cpp', 'util.h',
'mainwindow/mainwindow.cpp',
+ 'mainwindow/addressbar.cpp',
'mainwindow/menubar.cpp',
+ 'mainwindow/widgets/completer.cpp',
+ 'mainwindow/widgets/urllineedit.cpp',
'mainwindow/widgets/dockwidget.cpp',
'mainwindow/widgets/menusearch.cpp',
'mainwindow/widgets/navigationbar.cpp',
diff --git a/src/session/sessiondialog.cpp b/src/session/sessiondialog.cpp
index b734088..301b4b6 100644
--- a/src/session/sessiondialog.cpp
+++ b/src/session/sessiondialog.cpp
@@ -16,6 +16,7 @@
#include <QFileDialog>
#include <QToolButton>
#include <QStyle>
+#include "configuration.h"
SessionDialog::SessionDialog(QWidget *parent)
: QDialog(parent)
@@ -27,7 +28,8 @@ SessionDialog::SessionDialog(QWidget *parent)
auto *browser = qobject_cast<Browser *>(qApp);
Q_CHECK_PTR(browser);
- for(const QString &path : Util::files(browser->configuration("browser.session.path"), { "*.json" })) {
+ Configuration conf;
+ for(const QString &path : Util::files(conf.value<QString>("session.path").value(), { "*.json" })) {
addItem(path);
}
diff --git a/src/subwindow/subwindow.cpp b/src/subwindow/subwindow.cpp
index 31b49b9..869a453 100644
--- a/src/subwindow/subwindow.cpp
+++ b/src/subwindow/subwindow.cpp
@@ -22,7 +22,7 @@
#include "configuration.h"
#include "webprofile.h"
-SubWindow::SubWindow(const Configuration *config, QWidget *parent, Qt::WindowFlags flags)
+SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags flags)
: QMdiSubWindow(parent, flags)
, tabWidget(new TabWidget(this))
{
@@ -34,7 +34,8 @@ SubWindow::SubWindow(const Configuration *config, QWidget *parent, Qt::WindowFla
m_profile = WebProfile::defaultProfile();
- auto *fullScreen_shortcut = new QShortcut(QKeySequence(config->value<QString>("subwindow.shortcuts.fullscreen").value()), this);
+ Configuration config;
+ auto *fullScreen_shortcut = new QShortcut(QKeySequence(config.value<QString>("shortcuts.subwindow.fullscreen").value()), this);
connect(fullScreen_shortcut, &QShortcut::activated, this, [=]() {
auto *w = this->window();
if(w->isFullScreen())
diff --git a/src/subwindow/subwindow.h b/src/subwindow/subwindow.h
index eb7973f..c4f96c0 100644
--- a/src/subwindow/subwindow.h
+++ b/src/subwindow/subwindow.h
@@ -16,7 +16,6 @@
class TabWidget;
class WebView;
class WebProfile;
-class Configuration;
class SubWindow : public QMdiSubWindow
{
Q_OBJECT
@@ -28,7 +27,7 @@ public:
bool refreshLocked = false;
};
- explicit SubWindow(const Configuration *config, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
+ explicit SubWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
~SubWindow() override;
int currentTabIndex() const;
diff --git a/src/webengine/webview.cpp b/src/webengine/webview.cpp
index 5c9ab26..5307291 100644
--- a/src/webengine/webview.cpp
+++ b/src/webengine/webview.cpp
@@ -24,7 +24,7 @@
#include "webprofile.h"
#include "browser.h"
#include "wallet/wallet.h"
-#include "config.h"
+#include "conf.hpp"
inline QAction *historyAction(QWebEngineView *view, const QWebEngineHistoryItem &item)
{
diff --git a/test/conf/main.cpp b/test/conf/main.cpp
new file mode 100644
index 0000000..e499a4d
--- /dev/null
+++ b/test/conf/main.cpp
@@ -0,0 +1,54 @@
+#include <fstream>
+#include <iostream>
+#include <string>
+#include "configuration.h"
+#include <cassert>
+
+int main(int, char**)
+{
+ std::fstream fs;
+ fs.open("smolbote.cfg", std::fstream::in);
+ assert(fs.is_open());
+
+ {
+ auto value_map = std::make_unique<Configuration, std::initializer_list<std::pair<std::string, conf_value_t>>>({
+ { "test", std::string("unknown") },
+ { "integer-1", 20 },
+ { "integer-2", 30 }
+ });
+ value_map->read(fs);
+
+ Configuration::move_global(std::move(value_map));
+ fs.close();
+ }
+
+ {
+ Configuration g;
+ assert(g.value<std::string>("test") == "value");
+ assert(g.value<std::string>("plugins.path") == "/usr/local/lib/smolbote/plugins");
+ assert(g.value<int>("integer-1") == 20);
+ assert(g.value<int>("integer-2") == 22);
+ }
+
+/*
+ {
+ const Configuration conf(std::move(value_map));
+
+ assert(conf.value<std::string>("test") == "value");
+ assert(conf.value<std::string>("plugins.path") == "/usr/local/lib/smolbote/plugins");
+ assert(conf.value<int>("integer-1") == 20);
+ assert(conf.value<int>("integer-2") == 22);
+ }
+*/
+ // Configuration is now destroyed
+
+
+ // This should be a compiler warning
+ //const Configuration c(std::move(value_map));
+ //assert(c.value<std::string>("test") == "value");
+
+ // This should be a compiler warning and runtime error
+ //assert(value_map.value<std::string>("test").value() == "value");
+
+ return 0;
+}
diff --git a/test/conf/meson.build b/test/conf/meson.build
new file mode 100644
index 0000000..de67db7
--- /dev/null
+++ b/test/conf/meson.build
@@ -0,0 +1,6 @@
+e = executable('conf_test',
+ dependencies: [dep_qt5, dep_configuration],
+ sources: 'main.cpp'
+)
+
+test('conf_test', e, workdir : meson.source_root()/'test/conf')
diff --git a/test/conf/smolbote.cfg b/test/conf/smolbote.cfg
new file mode 100644
index 0000000..25467ef
--- /dev/null
+++ b/test/conf/smolbote.cfg
@@ -0,0 +1,5 @@
+# this is a comment
+test = value
+plugins.path = /usr/local/lib/smolbote/plugins
+
+integer-2 = 22