Adding apply/discard/reset functionality to settings dialog

This commit is contained in:
Dan Paulat 2022-12-22 00:16:59 -06:00
parent a6974e31a2
commit 87f611e026
10 changed files with 276 additions and 13 deletions

View file

@ -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

View file

@ -48,7 +48,8 @@ public:
};
template<class T>
SettingsInterface<T>::SettingsInterface() : p(std::make_unique<Impl>())
SettingsInterface<T>::SettingsInterface() :
SettingsInterfaceBase(), p(std::make_unique<Impl>())
{
}
template<class T>
@ -66,6 +67,28 @@ void SettingsInterface<T>::SetSettingsVariable(SettingsVariable<T>& variable)
p->variable_ = &variable;
}
template<class T>
bool SettingsInterface<T>::Commit()
{
return p->variable_->Commit();
}
template<class T>
void SettingsInterface<T>::Reset()
{
p->variable_->Reset();
p->UpdateEditWidget();
p->UpdateResetButton();
}
template<class T>
void SettingsInterface<T>::StageDefault()
{
p->variable_->StageDefault();
p->UpdateEditWidget();
p->UpdateResetButton();
}
template<class T>
void SettingsInterface<T>::SetEditWidget(QWidget* widget)
{

View file

@ -1,13 +1,12 @@
#pragma once
#include <scwx/qt/settings/settings_interface_base.hpp>
#include <functional>
#include <memory>
#include <string>
#include <vector>
class QAbstractButton;
class QWidget;
namespace scwx
{
namespace qt
@ -19,7 +18,7 @@ template<class T>
class SettingsVariable;
template<class T>
class SettingsInterface
class SettingsInterface : public SettingsInterfaceBase
{
public:
explicit SettingsInterface();
@ -39,19 +38,38 @@ public:
*/
void SetSettingsVariable(SettingsVariable<T>& 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

View file

@ -0,0 +1,34 @@
#include <scwx/qt/settings/settings_interface_base.hpp>
#include <string>
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<Impl>()) {}
SettingsInterfaceBase::~SettingsInterfaceBase() = default;
SettingsInterfaceBase::SettingsInterfaceBase(SettingsInterfaceBase&&) noexcept =
default;
SettingsInterfaceBase&
SettingsInterfaceBase::operator=(SettingsInterfaceBase&&) noexcept = default;
} // namespace settings
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,67 @@
#pragma once
#include <memory>
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<Impl> p;
};
} // namespace settings
} // namespace qt
} // namespace scwx

View file

@ -122,6 +122,19 @@ void SettingsVariable<T>::SetValueToDefault()
p->value_ = p->default_;
}
template<class T>
void SettingsVariable<T>::StageDefault()
{
if (p->value_ != p->default_)
{
p->staged_ = p->default_;
}
else
{
p->staged_.reset();
}
}
template<class T>
bool SettingsVariable<T>::StageValue(const T& value)
{
@ -144,13 +157,18 @@ bool SettingsVariable<T>::StageValue(const T& value)
}
template<class T>
void SettingsVariable<T>::Commit()
bool SettingsVariable<T>::Commit()
{
bool committed = false;
if (p->staged_.has_value())
{
p->value_ = std::move(*p->staged_);
p->staged_.reset();
committed = true;
}
return committed;
}
template<class T>

View file

@ -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.

View file

@ -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,

View file

@ -6,6 +6,7 @@
#include <scwx/qt/manager/settings_manager.hpp>
#include <scwx/qt/settings/settings_interface.hpp>
#include <scwx/qt/ui/radar_site_dialog.hpp>
#include <scwx/util/logger.hpp>
#include <format>
@ -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<awips::Phenomenon, 5> 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<settings::SettingsInterfaceBase*> {
&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<config::RadarSite>& radarSite);
@ -73,6 +89,8 @@ public:
std::unordered_map<std::string, settings::SettingsInterface<std::string>>
colorTables_ {};
std::vector<settings::SettingsInterfaceBase*> 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<config::RadarSite>& radarSite)
{

View file

@ -351,7 +351,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Discard|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>