diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index acf30d3f..df9d37fd 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -113,6 +113,7 @@ set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp source/scwx/qt/settings/settings_category.hpp source/scwx/qt/settings/settings_container.hpp source/scwx/qt/settings/settings_interface.hpp + source/scwx/qt/settings/settings_interface_base.hpp source/scwx/qt/settings/settings_variable.hpp source/scwx/qt/settings/settings_variable_base.hpp) set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp @@ -121,6 +122,7 @@ set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp source/scwx/qt/settings/settings_category.cpp source/scwx/qt/settings/settings_container.cpp source/scwx/qt/settings/settings_interface.cpp + source/scwx/qt/settings/settings_interface_base.cpp source/scwx/qt/settings/settings_variable.cpp source/scwx/qt/settings/settings_variable_base.cpp) set(HDR_TYPES source/scwx/qt/types/qt_types.hpp diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp index 2cd1a298..3a267129 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp +++ b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp @@ -48,7 +48,8 @@ public: }; template -SettingsInterface::SettingsInterface() : p(std::make_unique()) +SettingsInterface::SettingsInterface() : + SettingsInterfaceBase(), p(std::make_unique()) { } template @@ -66,6 +67,28 @@ void SettingsInterface::SetSettingsVariable(SettingsVariable& variable) p->variable_ = &variable; } +template +bool SettingsInterface::Commit() +{ + return p->variable_->Commit(); +} + +template +void SettingsInterface::Reset() +{ + p->variable_->Reset(); + p->UpdateEditWidget(); + p->UpdateResetButton(); +} + +template +void SettingsInterface::StageDefault() +{ + p->variable_->StageDefault(); + p->UpdateEditWidget(); + p->UpdateResetButton(); +} + template void SettingsInterface::SetEditWidget(QWidget* widget) { diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface.hpp b/scwx-qt/source/scwx/qt/settings/settings_interface.hpp index 4c9eec92..cb177555 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_interface.hpp +++ b/scwx-qt/source/scwx/qt/settings/settings_interface.hpp @@ -1,13 +1,12 @@ #pragma once +#include + #include #include #include #include -class QAbstractButton; -class QWidget; - namespace scwx { namespace qt @@ -19,7 +18,7 @@ template class SettingsVariable; template -class SettingsInterface +class SettingsInterface : public SettingsInterfaceBase { public: explicit SettingsInterface(); @@ -39,19 +38,38 @@ public: */ void SetSettingsVariable(SettingsVariable& variable); + /** + * Sets the current value of the associated settings variable to the staged + * value. + * + * @return true if the staged value was committed, false if no staged value + * is present. + */ + bool Commit() override; + + /** + * Clears the staged value of the associated settings variable. + */ + void Reset() override; + + /** + * Stages the default value of the associated settings variable. + */ + void StageDefault() override; + /** * Sets the edit widget from the settings dialog. * * @param widget Edit widget */ - void SetEditWidget(QWidget* widget); + void SetEditWidget(QWidget* widget) override; /** * Sets the reset button from the settings dialog. * * @param button Reset button */ - void SetResetButton(QAbstractButton* button); + void SetResetButton(QAbstractButton* button) override; /** * If the edit widget displays a different value than what is stored in the diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface_base.cpp b/scwx-qt/source/scwx/qt/settings/settings_interface_base.cpp new file mode 100644 index 00000000..37e1ec25 --- /dev/null +++ b/scwx-qt/source/scwx/qt/settings/settings_interface_base.cpp @@ -0,0 +1,34 @@ +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace settings +{ + +static const std::string logPrefix_ = + "scwx::qt::settings::settings_interface_base"; + +class SettingsInterfaceBase::Impl +{ +public: + explicit Impl() {} + ~Impl() {} +}; + +SettingsInterfaceBase::SettingsInterfaceBase() : p(std::make_unique()) {} + +SettingsInterfaceBase::~SettingsInterfaceBase() = default; + +SettingsInterfaceBase::SettingsInterfaceBase(SettingsInterfaceBase&&) noexcept = + default; + +SettingsInterfaceBase& +SettingsInterfaceBase::operator=(SettingsInterfaceBase&&) noexcept = default; + +} // namespace settings +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface_base.hpp b/scwx-qt/source/scwx/qt/settings/settings_interface_base.hpp new file mode 100644 index 00000000..97ae442d --- /dev/null +++ b/scwx-qt/source/scwx/qt/settings/settings_interface_base.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include + +class QAbstractButton; +class QWidget; + +namespace scwx +{ +namespace qt +{ +namespace settings +{ + +class SettingsInterfaceBase +{ +public: + explicit SettingsInterfaceBase(); + ~SettingsInterfaceBase(); + + SettingsInterfaceBase(const SettingsInterfaceBase&) = delete; + SettingsInterfaceBase& operator=(const SettingsInterfaceBase&) = delete; + + SettingsInterfaceBase(SettingsInterfaceBase&&) noexcept; + SettingsInterfaceBase& operator=(SettingsInterfaceBase&&) noexcept; + + /** + * Sets the current value of the associated settings variable to the staged + * value. + * + * @return true if the staged value was committed, false if no staged value + * is present. + */ + virtual bool Commit() = 0; + + /** + * Clears the staged value of the associated settings variable. + */ + virtual void Reset() = 0; + + /** + * Stages the default value of the associated settings variable. + */ + virtual void StageDefault() = 0; + + /** + * Sets the edit widget from the settings dialog. + * + * @param widget Edit widget + */ + virtual void SetEditWidget(QWidget* widget) = 0; + + /** + * Sets the reset button from the settings dialog. + * + * @param button Reset button + */ + virtual void SetResetButton(QAbstractButton* button) = 0; + +private: + class Impl; + std::unique_ptr p; +}; + +} // namespace settings +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/settings/settings_variable.cpp b/scwx-qt/source/scwx/qt/settings/settings_variable.cpp index 6efa9497..dca7005a 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_variable.cpp +++ b/scwx-qt/source/scwx/qt/settings/settings_variable.cpp @@ -122,6 +122,19 @@ void SettingsVariable::SetValueToDefault() p->value_ = p->default_; } +template +void SettingsVariable::StageDefault() +{ + if (p->value_ != p->default_) + { + p->staged_ = p->default_; + } + else + { + p->staged_.reset(); + } +} + template bool SettingsVariable::StageValue(const T& value) { @@ -144,13 +157,18 @@ bool SettingsVariable::StageValue(const T& value) } template -void SettingsVariable::Commit() +bool SettingsVariable::Commit() { + bool committed = false; + if (p->staged_.has_value()) { p->value_ = std::move(*p->staged_); p->staged_.reset(); + committed = true; } + + return committed; } template diff --git a/scwx-qt/source/scwx/qt/settings/settings_variable.hpp b/scwx-qt/source/scwx/qt/settings/settings_variable.hpp index 40c974ae..14940d8d 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_variable.hpp +++ b/scwx-qt/source/scwx/qt/settings/settings_variable.hpp @@ -61,6 +61,11 @@ public: */ void SetValueToDefault() override; + /** + * Stages the default value of the settings variable. + */ + void StageDefault() override; + /** * Sets the staged value of the settings variable. * @@ -73,8 +78,11 @@ public: /** * Sets the current value of the settings variable to the staged value. + * + * @return true if the staged value was committed, false if no staged value + * is present. */ - void Commit(); + bool Commit(); /** * Clears the staged value of the settings variable. diff --git a/scwx-qt/source/scwx/qt/settings/settings_variable_base.hpp b/scwx-qt/source/scwx/qt/settings/settings_variable_base.hpp index 87607a8c..f0444f45 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_variable_base.hpp +++ b/scwx-qt/source/scwx/qt/settings/settings_variable_base.hpp @@ -36,9 +36,17 @@ public: virtual void SetValueToDefault() = 0; /** - * Sets the current value of the settings variable to the staged value. + * Stages the default value of the settings variable. */ - virtual void Commit() = 0; + virtual void StageDefault() = 0; + + /** + * Sets the current value of the settings variable to the staged value. + * + * @return true if the staged value was committed, false if no staged value + * is present. + */ + virtual bool Commit() = 0; /** * Reads the value from the JSON object. If the read value is out of range, diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp index 2df86120..49620724 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -18,6 +19,9 @@ namespace qt namespace ui { +static const std::string logPrefix_ = "scwx::qt::ui::settings_dialog"; +static const auto logger_ = util::Logger::Create(logPrefix_); + static const std::array kAlertPhenomena_ { awips::Phenomenon::FlashFlood, awips::Phenomenon::Marine, @@ -48,7 +52,15 @@ class SettingsDialogImpl { public: explicit SettingsDialogImpl(SettingsDialog* self) : - self_ {self}, radarSiteDialog_ {new RadarSiteDialog(self)} + self_ {self}, + radarSiteDialog_ {new RadarSiteDialog(self)}, + settings_ {std::initializer_list { + &defaultRadarSite_, + &fontSizes_, + &gridWidth_, + &gridHeight_, + &mapboxApiKey_, + &debugEnabled_}} { } ~SettingsDialogImpl() = default; @@ -58,6 +70,10 @@ public: void SetupPalettesColorTablesTab(); void SetupPalettesAlertsTab(); + void ApplyChanges(); + void DiscardChanges(); + void ResetToDefault(); + static std::string RadarSiteLabel(std::shared_ptr& radarSite); @@ -73,6 +89,8 @@ public: std::unordered_map> colorTables_ {}; + + std::vector settings_; }; SettingsDialog::SettingsDialog(QWidget* parent) : @@ -130,6 +148,33 @@ void SettingsDialogImpl::ConnectSignals() // TODO: HandleMapUpdate for RadarSiteDialog, based on currently selected // radar site + + QObject::connect( + self_->ui->buttonBox, + &QDialogButtonBox::clicked, + self_, + [this](QAbstractButton* button) + { + QDialogButtonBox::ButtonRole role = + self_->ui->buttonBox->buttonRole(button); + + switch (role) + { + case QDialogButtonBox::ButtonRole::AcceptRole: // OK + case QDialogButtonBox::ButtonRole::ApplyRole: // Apply + ApplyChanges(); + break; + + case QDialogButtonBox::ButtonRole::DestructiveRole: // Discard + case QDialogButtonBox::ButtonRole::RejectRole: // Cancel + DiscardChanges(); + break; + + case QDialogButtonBox::ButtonRole::ResetRole: // Restore Defaults + ResetToDefault(); + break; + } + }); } void SettingsDialogImpl::SetupGeneralTab() @@ -240,6 +285,9 @@ void SettingsDialogImpl::SetupPalettesColorTablesTab() auto& pair = *result.first; auto& colorTable = pair.second; + // Add to settings list + settings_.push_back(&colorTable); + colorTable.SetSettingsVariable( paletteSettings.palette(colorTableType.first)); colorTable.SetEditWidget(lineEdit); @@ -305,6 +353,43 @@ void SettingsDialogImpl::SetupPalettesAlertsTab() } } +void SettingsDialogImpl::ApplyChanges() +{ + logger_->info("Apply settings changes"); + + bool committed = false; + + for (auto& setting : settings_) + { + committed |= setting->Commit(); + } + + if (committed) + { + logger_->info("Saving changes"); + } +} + +void SettingsDialogImpl::DiscardChanges() +{ + logger_->info("Discard settings changes"); + + for (auto& setting : settings_) + { + setting->Reset(); + } +} + +void SettingsDialogImpl::ResetToDefault() +{ + logger_->info("Restoring settings to default"); + + for (auto& setting : settings_) + { + setting->StageDefault(); + } +} + std::string SettingsDialogImpl::RadarSiteLabel( std::shared_ptr& radarSite) { diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui index 44b7456a..28bb1733 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui @@ -351,7 +351,7 @@ Qt::Horizontal - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Discard|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults