From bb5574831aef42b2f81979c1df8f706d3956bdca Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Wed, 21 Mar 2018 13:29:41 +0100 Subject: poi-config saving config --- config/main.cpp | 7 +++- config/settingsdialog.cpp | 76 +++++++++++++++++++++++++++++++++---- config/settingsdialog.h | 10 ++++- lib/configuration/configuration.cpp | 17 +++++++-- lib/configuration/configuration.h | 2 + src/commandline.cpp | 16 +------- 6 files changed, 101 insertions(+), 27 deletions(-) diff --git a/config/main.cpp b/config/main.cpp index 25751e6..16ff6db 100644 --- a/config/main.cpp +++ b/config/main.cpp @@ -14,7 +14,12 @@ int main(int argc, char **argv) QApplication app(argc, argv); app.setQuitOnLastWindowClosed(true); - SettingsDialog dlg; + Configuration config; + config.read(Configuration::defaultUserConfigLocation()); + + SettingsDialog dlg(&config); + dlg.configPath = Configuration::defaultUserConfigLocation(); + dlg.setWindowTitle("poi-config: " + Configuration::defaultUserConfigLocation()); dlg.show(); return app.exec(); diff --git a/config/settingsdialog.cpp b/config/settingsdialog.cpp index ef21a47..cc8cb8e 100644 --- a/config/settingsdialog.cpp +++ b/config/settingsdialog.cpp @@ -8,33 +8,95 @@ #include "settingsdialog.h" #include +#include #include +#include #include #include +#include -SettingsDialog::SettingsDialog(QWidget *parent) +SettingsDialog::SettingsDialog(Configuration *config, QWidget *parent) : QMainWindow(parent) { resize(800, 600); // main menu settingsMenu.setTitle(tr("Settings")); - settingsMenu.addAction(tr("Quit"), qApp, &QApplication::quit, QKeySequence("Ctrl+Q")); + + auto *saveAction = settingsMenu.addAction(tr("Save")); + saveAction->setShortcut(QKeySequence::Save); + + auto *saveAsAction = settingsMenu.addAction(tr("Save As")); + saveAsAction->setShortcut(QKeySequence::SaveAs); + + settingsMenu.addAction(tr("Quit"), qApp, &QApplication::quit, QKeySequence::Quit); + menuBar()->addMenu(&settingsMenu); setCentralWidget(&treeWidget); treeWidget.setColumnCount(2); treeWidget.setHeaderLabels({ tr("setting"), tr("value") }); + treeWidget.setEditTriggers(QTreeWidget::NoEditTriggers); + connect(&treeWidget, &QTreeWidget::itemDoubleClicked, this, &SettingsDialog::editItem); - //config.read() - - for(const auto &option : config.options()) { + for(const auto &option : config->options()) { auto *item = new QTreeWidgetItem(&treeWidget); item->setText(0, QString::fromStdString(option->long_name())); - item->setText(1, QString::fromStdString(config.value(option->long_name().c_str()).value_or(std::string()))); + item->setText(1, QString::fromStdString(config->value(option->long_name().c_str()).value_or(std::string()))); + item->setFlags(item->flags() | Qt::ItemIsEditable); } treeWidget.resizeColumnToContents(0); + + // connect signals + connect(saveAction, &QAction::triggered, this, [this]() { + write(configPath); + statusBar()->showMessage(tr("Configuration saved to: ") + configPath, 3000); + }); + + connect(saveAsAction, &QAction::triggered, this, [this]() { + QString path = QFileDialog::getSaveFileName(this, tr("Save Configuration"), configPath, tr("smolbote config (smolbote.cfg)")); + if(!path.isEmpty()) { + write(path); + statusBar()->showMessage(tr("Configuration saved to: ") + path, 3000); + } + }); +} + +SettingsDialog::~SettingsDialog() +{ + if(unsavedChanges) + write(configPath); +} + +void SettingsDialog::editItem(QTreeWidgetItem *item, int column) +{ + if(column == 1) { + treeWidget.editItem(item, column); + unsavedChanges = true; + + if(!windowTitle().endsWith('*')) { + setWindowTitle(windowTitle() + '*'); + } + } } -SettingsDialog::~SettingsDialog() = default; +void SettingsDialog::write(const QString &path) +{ + QFile output(path); + output.open(QIODevice::WriteOnly); + + for(int i = 0; i < treeWidget.topLevelItemCount(); ++i) { + auto *item = treeWidget.topLevelItem(i); + output.write(QString(item->text(0) + " = " + item->text(1) + "\n").toUtf8()); + } + + output.close(); + + unsavedChanges = false; + if(windowTitle().endsWith('*')) { + QString title = windowTitle(); + title.chop(1); + setWindowTitle(title); + } +} diff --git a/config/settingsdialog.h b/config/settingsdialog.h index dc3cc08..d456bc3 100644 --- a/config/settingsdialog.h +++ b/config/settingsdialog.h @@ -19,13 +19,19 @@ class SettingsDialog : public QMainWindow Q_OBJECT public: - explicit SettingsDialog(QWidget *parent = nullptr); + explicit SettingsDialog(Configuration *config, QWidget *parent = nullptr); ~SettingsDialog() override; + QString configPath; + +public slots: + void editItem(QTreeWidgetItem *item, int column); + void write(const QString &path); + private: QMenu settingsMenu; QTreeWidget treeWidget; - Configuration config; + bool unsavedChanges = false; }; #endif // SMOLBOTE_SETTINGSDIALOG_H diff --git a/lib/configuration/configuration.cpp b/lib/configuration/configuration.cpp index c114155..c9bae90 100644 --- a/lib/configuration/configuration.cpp +++ b/lib/configuration/configuration.cpp @@ -81,14 +81,25 @@ Configuration::Configuration() // store the defaults into the vm { - const char* argv[0]; + const char *argv[0]; po::store(po::parse_command_line(0, argv, desc), vm); } - } 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) { std::ifstream f(path.toStdString(), std::ifstream::in); @@ -100,7 +111,7 @@ bool Configuration::parse(int argc, const char **argv) { try { po::store(po::parse_command_line(argc, argv, desc), vm); - } catch (const po::error &e) { + } catch(const po::error &e) { return false; } diff --git a/lib/configuration/configuration.h b/lib/configuration/configuration.h index 4d58a90..c8fcdff 100644 --- a/lib/configuration/configuration.h +++ b/lib/configuration/configuration.h @@ -22,6 +22,8 @@ public: explicit Configuration(); ~Configuration(); + static QString defaultUserConfigLocation(); + bool read(const QString &path); bool parse(int argc, const char **argv); diff --git a/src/commandline.cpp b/src/commandline.cpp index 2a0de69..6f227c0 100644 --- a/src/commandline.cpp +++ b/src/commandline.cpp @@ -8,7 +8,7 @@ #include "commandline.h" #include "version.h" -#include +#include #include #include @@ -21,18 +21,6 @@ void printOption(const QCommandLineOption &option) << std::endl; } -QString defaultUserConfigLocation() -{ - // try to locate an existing config - QString path = QStandardPaths::locate(QStandardPaths::AppConfigLocation, "smolbote.cfg"); - - // it's possible there is no config, so set the path properly - if(path.isEmpty()) - path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/smolbote.cfg"; - - return path; -} - constexpr const char *socketPath() { #ifdef Q_OS_UNIX @@ -49,7 +37,7 @@ CommandLine::CommandLine() , helpOption(addHelpOption()) , versionOption(addVersionOption()) , buildOption("build", "Show build information.") - , configOption({ "c", "config" }, "Set configuration file.", "path", defaultUserConfigLocation()) + , configOption({ "c", "config" }, "Set configuration file.", "path", Configuration::defaultUserConfigLocation()) , profileOption({ "p", "profile" }, "Use this profile.", "profile", "") , socketOption("socket", "Local server socket", "name", socketPath()) , newWindowOption("in-new-window", "Open URL in new window") -- cgit v1.2.1