diff --git a/src/tuxclocker-qt/Globals.hpp b/src/tuxclocker-qt/Globals.hpp index a2e026b..db22c29 100644 --- a/src/tuxclocker-qt/Globals.hpp +++ b/src/tuxclocker-qt/Globals.hpp @@ -1,5 +1,7 @@ #pragma once +#include + class DeviceModel; class QStackedWidget; class QWidget; @@ -11,5 +13,7 @@ namespace Globals { extern DeviceModel *g_deviceModel; extern QStackedWidget *g_mainStack; extern QWidget *g_deviceBrowser; +// When applying successfully, we need to know which profile to save changes to +extern SettingsData g_settingsData; } // namespace Globals diff --git a/src/tuxclocker-qt/Utils.cpp b/src/tuxclocker-qt/Utils.cpp index 1063c21..88eb69a 100644 --- a/src/tuxclocker-qt/Utils.cpp +++ b/src/tuxclocker-qt/Utils.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace Utils { @@ -77,4 +78,15 @@ void writeAssignableDefaults(DeviceModel &model) { traverseModel(cb, &model); } +void writeAssignableSetting(SettingsData data, QVariant value, NodePath assignablePath) { + if (!data.currentProfile.has_value()) + return; + + QSettings settings{"tuxclocker"}; + auto profile = data.currentProfile.value(); + settings.beginGroup("profiles"); + settings.beginGroup(profile); + settings.setValue(toSettingsPath(assignablePath), value); +} + } // namespace Utils diff --git a/src/tuxclocker-qt/Utils.hpp b/src/tuxclocker-qt/Utils.hpp index f3b47da..c28ec56 100644 --- a/src/tuxclocker-qt/Utils.hpp +++ b/src/tuxclocker-qt/Utils.hpp @@ -2,6 +2,8 @@ #include +class SettingsData; + namespace Utils { using ModelTraverseCallback = @@ -15,5 +17,6 @@ QString toSettingsPath(NodePath); void traverseModel( const ModelTraverseCallback &, QAbstractItemModel *, const QModelIndex &parent = QModelIndex()); void writeAssignableDefaults(DeviceModel &model); +void writeAssignableSetting(SettingsData, QVariant value, NodePath assignablePath); } // namespace Utils diff --git a/src/tuxclocker-qt/data/AssignableProxy.hpp b/src/tuxclocker-qt/data/AssignableProxy.hpp index 53ab3ea..53b087f 100644 --- a/src/tuxclocker-qt/data/AssignableProxy.hpp +++ b/src/tuxclocker-qt/data/AssignableProxy.hpp @@ -20,7 +20,9 @@ public: void apply(); // Stop connection and clear current connection void stopConnection(); + // TODO: rename to setTargetValue for congruency void setValue(QVariant v) { m_value = v; } + QVariant targetValue() { return m_value; } std::optional currentValue(); QString dbusPath(); signals: diff --git a/src/tuxclocker-qt/data/DeviceModel.cpp b/src/tuxclocker-qt/data/DeviceModel.cpp index 50915f8..b256327 100644 --- a/src/tuxclocker-qt/data/DeviceModel.cpp +++ b/src/tuxclocker-qt/data/DeviceModel.cpp @@ -3,6 +3,8 @@ #include "AssignableProxy.hpp" #include "DynamicReadableProxy.hpp" #include +#include +#include #include #include #include @@ -172,8 +174,16 @@ QStandardItem *DeviceModel::createAssignable( connect(proxy, &AssignableProxy::applied, [=](auto err) { ifaceItem->applyTargetText(); + bool success = !err.has_value(); + + if (success) { + // Write successfully changed value to settings + Utils::writeAssignableSetting( + Globals::g_settingsData, proxy->targetValue(), proxy->dbusPath()); + } + // Fade out result color - auto startColor = (err.has_value()) ? errorColor() : successColor(); + auto startColor = !success ? errorColor() : successColor(); auto anim = new QVariantAnimation; anim->setDuration(fadeOutTime()); anim->setStartValue(startColor); diff --git a/src/tuxclocker-qt/widgets/DeviceBrowser.cpp b/src/tuxclocker-qt/widgets/DeviceBrowser.cpp index e6e9230..5b049b6 100644 --- a/src/tuxclocker-qt/widgets/DeviceBrowser.cpp +++ b/src/tuxclocker-qt/widgets/DeviceBrowser.cpp @@ -58,6 +58,9 @@ DeviceBrowser::DeviceBrowser(DeviceModel &model, QWidget *parent) connect(m_settings, &Settings::cancelled, [=] { Globals::g_mainStack->setCurrentWidget(this); }); + + connect(m_settings, &Settings::settingsSaved, + [=](auto) { Globals::g_mainStack->setCurrentWidget(this); }); } Globals::g_mainStack->setCurrentWidget(m_settings); }); diff --git a/src/tuxclocker-qt/widgets/Settings.cpp b/src/tuxclocker-qt/widgets/Settings.cpp index f00e5a8..56f3cb6 100644 --- a/src/tuxclocker-qt/widgets/Settings.cpp +++ b/src/tuxclocker-qt/widgets/Settings.cpp @@ -1,10 +1,14 @@ #include "Settings.hpp" +#include #include #include #include #include #include +#include + +SettingsData Globals::g_settingsData; Settings::Settings(QWidget *parent) : QWidget(parent) { auto layout = new QGridLayout{this}; @@ -18,15 +22,15 @@ Settings::Settings(QWidget *parent) : QWidget(parent) { label->setFont(biggerPoint); label->setText("Settings"); - auto autoLoadCheck = new QCheckBox{"Apply profile settings automatically", this}; + m_autoLoad = new QCheckBox{"Apply profile settings automatically", this}; auto profileCheck = new QCheckBox{"Use profile", this}; // TODO: add delegate to make deleting a little nicer - auto profileView = new QListWidget{this}; + m_profileView = new QListWidget{this}; auto triggers = QAbstractItemView::SelectedClicked | QAbstractItemView::EditKeyPressed; - profileView->setEditTriggers(triggers); - profileView->setEnabled(false); + m_profileView->setEditTriggers(triggers); + m_profileView->setEnabled(false); auto addButton = new QPushButton{"Add profile"}; addButton->setEnabled(false); @@ -36,17 +40,17 @@ Settings::Settings(QWidget *parent) : QWidget(parent) { connect(addButton, &QPushButton::released, [=] { auto item = new QListWidgetItem{"Unnamed"}; item->setFlags(item->flags() | Qt::ItemIsEditable); - profileView->addItem(item); + m_profileView->addItem(item); }); connect(removeButton, &QPushButton::released, - [=] { profileView->model()->removeRow(profileView->currentRow()); }); + [=] { m_profileView->model()->removeRow(m_profileView->currentRow()); }); connect(profileCheck, &QCheckBox::stateChanged, [=](auto state) { bool enable = (state == Qt::Unchecked) ? false : true; addButton->setEnabled(enable); - profileView->setEnabled(enable); + m_profileView->setEnabled(enable); }); auto cancelButton = new QPushButton{"Cancel", this}; @@ -55,10 +59,20 @@ Settings::Settings(QWidget *parent) : QWidget(parent) { auto saveButton = new QPushButton{"Save", this}; + connect(saveButton, &QPushButton::released, this, [=] { + // TODO: read assignableSettings from disk + auto settingsData = fromUIState(); + writeSettings(fromUIState()); + + Globals::g_settingsData = settingsData; + + emit settingsSaved(settingsData); + }); + layout->addWidget(label, 0, 0, 1, 1, Qt::AlignLeft | Qt::AlignTop); - layout->addWidget(autoLoadCheck, 1, 0, 1, 1, Qt::AlignLeft); + layout->addWidget(m_autoLoad, 1, 0, 1, 1, Qt::AlignLeft); layout->addWidget(profileCheck, 2, 0, 1, 1, Qt::AlignLeft); - layout->addWidget(profileView, 2, 1, 1, 2); + layout->addWidget(m_profileView, 2, 1, 1, 2); layout->addWidget(addButton, 3, 1); layout->addWidget(removeButton, 3, 2); layout->addWidget(cancelButton, 4, 0, 1, 1, Qt::AlignBottom); @@ -66,3 +80,29 @@ Settings::Settings(QWidget *parent) : QWidget(parent) { this->setLayout(layout); } + +SettingsData Settings::fromUIState() { + std::optional currentProfile = std::nullopt; + + auto data = m_profileView->currentItem()->data(Qt::DisplayRole); + if (data.isValid()) + currentProfile = data.toString(); + + return SettingsData{ + .autoApplyProfile = m_autoLoad->isChecked(), + .currentProfile = currentProfile, + }; +} + +void Settings::writeSettings(SettingsData data) { + bool usingProfile = data.currentProfile.has_value() ? true : false; + + QSettings settings{"tuxclocker"}; + settings.beginGroup("general"); + + settings.setValue("autoApplyProfile", data.autoApplyProfile); + settings.setValue("usingProfile", usingProfile); + + if (usingProfile) + settings.setValue("currentProfile", data.currentProfile.value()); +} diff --git a/src/tuxclocker-qt/widgets/Settings.hpp b/src/tuxclocker-qt/widgets/Settings.hpp index edfcccf..474701e 100644 --- a/src/tuxclocker-qt/widgets/Settings.hpp +++ b/src/tuxclocker-qt/widgets/Settings.hpp @@ -4,6 +4,9 @@ #include #include +class QCheckBox; +class QListWidget; + // TODO: duplicate definition struct AssignableSetting { QString assignablePath; @@ -21,6 +24,14 @@ public: explicit Settings(QWidget *parent = nullptr); signals: void cancelled(); + void settingsSaved(SettingsData); private: + SettingsData fromUIState(); + void writeSettings(SettingsData); + + QCheckBox *m_autoLoad; + QCheckBox *m_useProfile; + QListWidget *m_profileView; + Q_OBJECT };