aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/main.cpp8
-rw-r--r--lib/configuration/configuration.cpp83
-rw-r--r--lib/configuration/configuration.h23
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/browser.cpp3
-rw-r--r--src/commandline.cpp135
-rw-r--r--src/commandline.h38
-rw-r--r--src/main.cpp26
8 files changed, 96 insertions, 222 deletions
diff --git a/config/main.cpp b/config/main.cpp
index 16ff6db..2ebad8d 100644
--- a/config/main.cpp
+++ b/config/main.cpp
@@ -15,12 +15,12 @@ int main(int argc, char **argv)
app.setQuitOnLastWindowClosed(true);
Configuration config;
- config.read(Configuration::defaultUserConfigLocation());
+ config.parseConfigFile(config.value<std::string>("config").value());
SettingsDialog dlg(&config);
- dlg.configPath = Configuration::defaultUserConfigLocation();
- dlg.setWindowTitle("poi-config: " + Configuration::defaultUserConfigLocation());
+ dlg.configPath = QString::fromStdString(config.value<std::string>("config").value());
+ dlg.setWindowTitle("poi-config: " + dlg.configPath);
dlg.show();
return app.exec();
-} \ No newline at end of file
+}
diff --git a/lib/configuration/configuration.cpp b/lib/configuration/configuration.cpp
index 48f051d..7032a1d 100644
--- a/lib/configuration/configuration.cpp
+++ b/lib/configuration/configuration.cpp
@@ -10,16 +10,49 @@
#include <QStandardPaths>
#include <fstream>
#include <boost/algorithm/string/predicate.hpp>
+#include <iostream>
+#include <QCoreApplication>
namespace po = boost::program_options;
+inline std::string defaultUserConfigLocation()
+{
+ // 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();
+}
+
+constexpr const char *defaultSocketPath()
+{
+#if defined(Q_OS_UNIX)
+ // could be a path such as "/tmp/foo"
+ return "/tmp/smolbote.socket";
+#elif defined(Q_OS_WIN32)
+ // could be a pipe path such as "\\.\pipe\foo"
+ return "\\\\.\\pipe\\smolbote_socket";
+#endif
+}
+
Configuration::Configuration()
{
m_homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString();
- // create description
- desc.add_options()
+ commandLine_desc.add_options()
+ ("help,h", "Display this help.")
+ ("version,v", "Display version information.")
+
+ ("config,c", po::value<std::string>()->default_value(defaultUserConfigLocation()), "Set the configuration file.")
+ ("socket,s", po::value<std::string>()->default_value(defaultSocketPath()), "Local server socket")
+
+ ("url", po::value<std::vector<std::string>>(), "URLs")
+ ;
+ configuration_desc.add_options()
// main window ui
("mainwindow.height", po::value<int>()->default_value(720))
("mainwindow.width", po::value<int>()->default_value(1280))
@@ -82,46 +115,56 @@ Configuration::Configuration()
("downloads.path", po::value<std::string>()->default_value("~/Downloads"))
("downloads.shortcut", po::value<std::string>()->default_value("Ctrl+D"))
;
+
+ arguments_desc.add("url", -1);
}
Configuration::~Configuration() = default;
-QString Configuration::defaultUserConfigLocation()
-{
- // 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;
-}
-
-bool Configuration::read(const QString &path)
+bool Configuration::parseConfigFile(const std::string &path)
{
- std::ifstream f(path.toStdString(), std::ifstream::in);
+ std::ifstream f(path, std::ifstream::in);
// parse_config_file(file, options_description, allow_unregistered)
- po::store(po::parse_config_file(f, desc, true), vm);
+ po::store(po::parse_config_file(f, configuration_desc, true), vm);
return true;
}
-bool Configuration::parse(int argc, char **argv)
+bool Configuration::parseCommandLine(int argc, char **argv)
{
try {
- po::store(po::parse_command_line(argc, argv, desc), vm);
+ auto cmd = po::command_line_parser(argc, argv);
+ po::options_description desc;
+ desc.add(commandLine_desc).add(configuration_desc);
+ cmd.options(desc);
+ cmd.positional(arguments_desc);
+ po::store(cmd.run(), vm);
} catch(const po::error &e) {
+ qWarning("Error parsing command line: %s", e.what());
return false;
}
+ if(vm.count("help")) {
+ std::cout << qUtf8Printable(qApp->applicationName()) << " " << qUtf8Printable(qApp->applicationVersion()) << ": yet another no-frills browser" << std::endl;
+ std::cout << "Usage: " << qUtf8Printable(qApp->arguments().at(0)) << " [options] URL(s)" << std::endl;
+
+ std::cout << std::endl << "Command-line Options: " << std::endl << commandLine_desc << std::endl;
+ std::cout << std::endl << "Configuration Options: " << std::endl << configuration_desc << std::endl;
+ exit(0);
+ }
+
+ if(vm.count("version")) {
+ std::cout << qUtf8Printable(qApp->applicationName()) << " " << qUtf8Printable(qApp->applicationVersion()) << std::endl;
+ exit(0);
+ }
+
return true;
}
QHash<QString, QString> Configuration::section(const std::string &prefix) const
{
QHash<QString, QString> v;
- for(auto &s : desc.options()) {
+ 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());
}
diff --git a/lib/configuration/configuration.h b/lib/configuration/configuration.h
index 5b59766..5bb9f5d 100644
--- a/lib/configuration/configuration.h
+++ b/lib/configuration/configuration.h
@@ -23,10 +23,8 @@ public:
explicit Configuration();
~Configuration();
- static QString defaultUserConfigLocation();
-
- bool read(const QString &path);
- bool parse(int argc, char **argv);
+ bool parseConfigFile(const std::string &path);
+ bool parseCommandLine(int argc, char **argv);
template <typename T>
std::optional<T> value(const char *path) const
@@ -66,13 +64,26 @@ public:
const std::vector<boost::shared_ptr<boost::program_options::option_description>> &options()
{
- return desc.options();
+ return configuration_desc.options();
}
QHash<QString, QString> section(const std::string &prefix) const;
+ QStringList positionalArguments() const
+ {
+ QStringList l;
+ if(vm.count("url")) {
+ std::vector<std::string> urls = vm["url"].as<std::vector<std::string>>();
+ for(const std::string &s : urls) {
+ l.append(QString::fromStdString(s));
+ }
+ }
+ return l;
+ }
private:
- boost::program_options::options_description desc;
+ boost::program_options::options_description commandLine_desc;
+ boost::program_options::options_description configuration_desc;
+ boost::program_options::positional_options_description arguments_desc;
boost::program_options::variables_map vm;
std::string m_homePath;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1321604..dd325ec 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,8 +13,6 @@ add_executable(poi
singleapplication.h
browser.cpp
browser.h
- commandline.cpp
- commandline.h
../data/resources.qrc
# main window
diff --git a/src/browser.cpp b/src/browser.cpp
index 9b691e4..3f4805a 100644
--- a/src/browser.cpp
+++ b/src/browser.cpp
@@ -28,7 +28,8 @@ Browser::Browser(int &argc, char *argv[])
Browser::~Browser()
{
- m_bookmarks->save();
+ if(m_bookmarks)
+ m_bookmarks->save();
qDeleteAll(m_windows);
m_windows.clear();
}
diff --git a/src/commandline.cpp b/src/commandline.cpp
deleted file mode 100644
index 6082686..0000000
--- a/src/commandline.cpp
+++ /dev/null
@@ -1,135 +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/smolbote.hg
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#include "commandline.h"
-#include "version.h"
-#include <configuration.h>
-#include <iomanip>
-#include <iostream>
-
-inline std::string optionText(const QStringList &opts)
-{
- std::string r;
- for(auto i = opts.constBegin(); i != opts.constEnd(); ) {
- if(i->length() == 1) {
- r.append("-" + i->toStdString());
- } else {
- r.append("--" + i->toStdString());
- }
-
- ++i;
- if(i != opts.constEnd()) {
- r.append(", ");
- }
- }
- return r;
-}
-
-inline void printOption(const QCommandLineOption &option)
-{
- std::cout << " "
- << std::setw(18) << std::left << optionText(option.names())
- << std::setw(32) << std::left << option.description().toStdString()
- << std::setw(18) << std::left << option.defaultValues().join(", ").toStdString()
- << std::endl;
-}
-
-constexpr const char *socketPath()
-{
-#if defined(Q_OS_UNIX)
- // could be a path such as "/tmp/foo"
- return "/tmp/smolbote.socket";
-#elif defined(Q_OS_WIN32)
- // could be a pipe path such as "\\.\pipe\foo"
- return "\\\\.\\pipe\\smolbote_socket";
-#endif
-}
-
-CommandLine::CommandLine()
- : QCommandLineParser()
- , helpOption(addHelpOption())
- , versionOption(addVersionOption())
- , buildOption("build", "Displays build information.")
- , configOption({ "c", "config" }, "Sets configuration file.", "path", Configuration::defaultUserConfigLocation())
- , profileOption({ "p", "profile" }, "Sets default profile.", "profile", "")
- , socketOption("socket", "Sets local socket.", "name", socketPath())
- , newWindowOption("in-new-window", "Open URL in new window")
-{
- setApplicationDescription("yet another no-frills browser");
-
- addOption(buildOption);
- addOption(configOption);
- addOption(profileOption);
- addOption(socketOption);
- addOption(newWindowOption);
-
- addPositionalArgument("URL", "URL(s) to open");
-}
-
-void CommandLine::parseCommandLine(const QCoreApplication &app)
-{
- QCommandLineParser::parse(app.arguments());
-
- application = const_cast<QCoreApplication *>(&app);
-
- if(isSet(helpOption)) {
- printHelp();
- }
-
- if(isSet(versionOption)) {
- printVersion();
- }
-
- if(isSet(buildOption)) {
- printBuild();
- }
-}
-
-void CommandLine::printHelp(int exitCode)
-{
- std::cout << "Usage: " << application->arguments().at(0).toStdString() << " [options] URL" << std::endl;
- std::cout << application->applicationName().toStdString() << " " << SMOLBOTE_DESCRIBE << ": "
- << applicationDescription().toStdString() << std::endl
- << std::endl;
-
- std::cout << "Options: " << std::endl;
- printOption(helpOption);
- printOption(versionOption);
- printOption(buildOption);
- printOption(configOption);
- printOption(profileOption);
- printOption(socketOption);
- printOption(newWindowOption);
- std::cout << std::endl;
-
- std::cout << "You can also overwrite configuration options using the syntax: " << std::endl
- << "--browser.setting.path=value" << std::endl
- << "More information on available keys can be found on the manual page." << std::endl
- << std::endl;
-
- std::cout << "Arguments: " << std::endl;
- std::cout << "- "
- << std::setw(20) << std::left << "URL"
- << std::setw(40) << std::left << "URL(s) to open"
- << std::endl
- << std::endl;
-
- exit(exitCode);
-}
-
-void CommandLine::printVersion(int exitCode)
-{
- std::cout << application->applicationName().toStdString() << " " << SMOLBOTE_DESCRIBE << std::endl;
- exit(exitCode);
-}
-
-void CommandLine::printBuild(int exitCode)
-{
- std::cout << SMOLBOTE_BRANCH << ":" << SMOLBOTE_COMMIT << std::endl;
- exit(exitCode);
-}
diff --git a/src/commandline.h b/src/commandline.h
deleted file mode 100644
index cb2f334..0000000
--- a/src/commandline.h
+++ /dev/null
@@ -1,38 +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/smolbote.hg
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#ifndef SMOLBOTE_COMMANDLINE_H
-#define SMOLBOTE_COMMANDLINE_H
-
-#include <QCommandLineParser>
-
-class CommandLine : public QCommandLineParser
-{
-public:
- CommandLine();
-
- void parseCommandLine(const QCoreApplication &app);
-
- void printHelp(int exitCode = 0);
- void printVersion(int exitCode = 0);
- void printBuild(int exitCode = 0);
-
- const QCommandLineOption helpOption;
- const QCommandLineOption versionOption;
- const QCommandLineOption buildOption;
-
- const QCommandLineOption configOption;
- const QCommandLineOption profileOption;
- const QCommandLineOption socketOption;
- const QCommandLineOption newWindowOption;
-
-private:
- QCoreApplication *application;
-};
-
-#endif // SMOLBOTE_COMMANDLINE_H
diff --git a/src/main.cpp b/src/main.cpp
index 52df7ac..bfe4ecd 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -7,7 +7,6 @@
*/
#include "browser.h"
-#include "commandline.h"
#include "mainwindow/mainwindow.h"
#include "version.h"
#include "webengine/webprofile.h"
@@ -18,36 +17,31 @@ int main(int argc, char **argv)
{
Browser app(argc, argv);
- CommandLine parser;
- parser.parseCommandLine(app);
-
// create and load configuration
std::shared_ptr<Configuration> config = std::make_shared<Configuration>();
- config->read(parser.value(parser.configOption));
-
- if(!parser.unknownOptionNames().isEmpty()) {
- qDebug("config->parse: %s", config->parse(argc, argv) ? "true" : "false");
+ if(!config->parseCommandLine(argc, argv)) {
+ qWarning("Check --help for usage.");
+ return -1;
+ }
+ if(!config->parseConfigFile(config->value<std::string>("config").value())) {
+ qWarning("Error parsing config file.");
}
app.setConfiguration(config);
// set up socket
- bool isSingleInstance = app.bindLocalSocket(parser.value(parser.socketOption));
+ bool isSingleInstance = app.bindLocalSocket(QString::fromStdString(config->value<std::string>("socket").value()));
#ifdef QT_DEBUG
- qDebug("bindLocalSocket(%s) = %s", qUtf8Printable(parser.value(parser.socketOption)), isSingleInstance ? "true" : "false");
+ qDebug("bindLocalSocket(%s) = %s", qUtf8Printable(QString::fromStdString(config->value<std::string>("socket").value())), isSingleInstance ? "true" : "false");
#endif
// if we are the only instance, set up the browser
if(isSingleInstance) {
- if(parser.isSet(parser.profileOption))
- app.setup(parser.value(parser.profileOption));
- else
- app.setup(QString::fromStdString(config->value<std::string>("profile.default").value()));
-
+ app.setup(QString::fromStdString(config->value<std::string>("profile.default").value()));
QObject::connect(&app, &Browser::messageAvailable, &app, &Browser::createSession);
}
- app.sendMessage(parser.value(parser.profileOption), parser.isSet(parser.newWindowOption), parser.positionalArguments());
+ app.sendMessage("", false, config->positionalArguments());
if(isSingleInstance)
return app.exec();