Add function GncOption::set_default_value.

Allows reports to derive from other reports and then change the option
default values to suit. If they change only the values and not the defaults
then it's possible to create saved report configs that don't include the
options whose values are changed to the base report's default value. See
https://bugs.gnucash.org/show_bug.cgi?id=642292.
This commit is contained in:
John Ralls 2021-03-05 15:56:34 -08:00
parent c04f4a00e0
commit 5c74337810
5 changed files with 191 additions and 1 deletions

View File

@ -131,6 +131,15 @@ GncOptionDateValue::set_value(size_t index) noexcept
m_period = m_period_set[index];
}
void
GncOptionDateValue::set_default_value(size_t index) noexcept
{
assert(!m_period_set.empty());
assert(index < m_period_set.size());
m_date = m_default_date = INT64_MAX;
m_period = m_default_period = m_period_set[index];
}
size_t
GncOptionDateValue::permissible_value_index(const char* key) const noexcept
{

View File

@ -91,7 +91,6 @@ protected:
};
*/
static const char* commodity_scm_intro{"'(commodity-scm "};
#ifndef SWIG
size_t constexpr classifier_size_max{50};
@ -129,6 +128,9 @@ public:
ValueType get_value() const { return m_value; }
ValueType get_default_value() const { return m_default_value; }
void set_value(ValueType new_value) { m_value = new_value; }
void set_default_value(ValueType new_value) {
m_value = m_default_value = new_value;
}
void reset_default_value() { m_value = m_default_value; }
bool is_changed() const noexcept { return m_value != m_default_value; }
GncOptionUIType get_ui_type() const noexcept { return m_ui_type; }
@ -183,6 +185,13 @@ public:
else
throw std::invalid_argument("Validation failed, value not set.");
}
void set_default_value(ValueType value)
{
if (this->validate(value))
m_value = m_default_value = value;
else
throw std::invalid_argument("Validation failed, value not set.");
}
void reset_default_value() { m_value = m_default_value; }
bool is_changed() const noexcept { return m_value != m_default_value; }
std::ostream& to_scheme(std::ostream&) const;
@ -426,6 +435,13 @@ public:
else
throw std::invalid_argument("Validation failed, value not set.");
}
void set_default_value(ValueType value)
{
if (this->validate(value))
m_value = m_default_value = value;
else
throw std::invalid_argument("Validation failed, value not set.");
}
void get_limits(ValueType& upper, ValueType& lower, ValueType& step) const noexcept
{
upper = m_max;
@ -649,6 +665,40 @@ public:
else
throw std::invalid_argument("One of the supplied indexes was out of range.");
}
void set_default_value(const std::string& value)
{
auto index = find_key(value);
if (index != size_t_max)
{
m_value.clear();
m_value.push_back(index);
m_default_value.clear();
m_default_value.push_back(index);
}
else
throw std::invalid_argument("Value not a valid choice.");
}
void set_default_value(size_t index)
{
if (index < m_choices.size())
{
m_value.clear();
m_value.push_back(index);
m_default_value.clear();
m_default_value.push_back(index);
}
else
throw std::invalid_argument("Value not a valid choice.");
}
void set_default_multiple(const GncMultichoiceOptionIndexVec& indexes)
{
if (validate(indexes))
m_value = m_default_value = indexes;
else
throw std::invalid_argument("One of the supplied indexes was out of range.");
}
std::size_t num_permissible_values() const noexcept
{
return m_choices.size();
@ -866,6 +916,11 @@ public:
//throw!
m_value = values;
}
void set_default_value (const GncOptionAccountList& values) {
if (validate(values))
//throw!
m_value = m_default_value = values;
}
GList* account_type_list() const noexcept;
void reset_default_value() { m_value = m_default_value; }
bool is_changed() const noexcept { return m_value != m_default_value; }
@ -1039,6 +1094,21 @@ public:
}
}
void set_value(size_t index) noexcept;
void set_default_value(RelativeDatePeriod value) {
if (validate(value))
{
m_period = m_default_period = value;
m_date = m_default_date = INT64_MAX;
}
}
void set_default_value(time64 time) {
if (validate(time))
{
m_period = m_default_period = RelativeDatePeriod::ABSOLUTE;
m_date = m_default_date = time;
}
}
void set_default_value(size_t index) noexcept;
std::size_t num_permissible_values() const noexcept
{
return m_period_set.size();

View File

@ -126,6 +126,27 @@ GncOption::set_value(ValueType value)
}, *m_option);
}
template <typename ValueType> void
GncOption::set_default_value(ValueType value)
{
std::visit([value](auto& option) {
if constexpr
(std::is_same_v<std::decay_t<decltype(option.get_value())>,
std::decay_t<ValueType>> ||
(std::is_same_v<std::decay_t<decltype(option)>,
GncOptionDateValue> &&
(std::is_same_v<std::decay_t<ValueType>,
RelativeDatePeriod> ||
std::is_same_v<std::decay_t<ValueType>, size_t>)))
option.set_default_value(value);
if constexpr
(std::is_same_v<std::decay_t<decltype(option)>,
GncOptionMultichoiceValue> &&
std::is_same_v<std::decay_t<ValueType>,
GncMultichoiceOptionIndexVec>)
option.set_multiple(value);
}, *m_option);
}
void
GncOption::reset_default_value()
{
@ -590,6 +611,20 @@ template void GncOption::set_value(GncOptionAccountList);
template void GncOption::set_value(GncMultichoiceOptionIndexVec);
template void GncOption::set_value(SCM);
template void GncOption::set_default_value(bool);
template void GncOption::set_default_value(int);
template void GncOption::set_default_value(int64_t);
template void GncOption::set_default_value(double);
template void GncOption::set_default_value(char*);
template void GncOption::set_default_value(const char*);
template void GncOption::set_default_value(std::string);
template void GncOption::set_default_value(const QofInstance*);
template void GncOption::set_default_value(RelativeDatePeriod);
template void GncOption::set_default_value(size_t);
template void GncOption::set_default_value(GncOptionAccountList);
template void GncOption::set_default_value(GncMultichoiceOptionIndexVec);
template void GncOption::set_default_value(SCM);
template void GncOption::get_limits(double&, double&, double&) const noexcept;
template void GncOption::get_limits(int&, int&, int&) const noexcept;
template bool GncOption::validate(bool) const;

View File

@ -88,6 +88,7 @@ public:
ValueType value,
GncOptionUIType ui_type = GncOptionUIType::INTERNAL);
template <typename ValueType> void set_value(ValueType value);
template <typename ValueType> void set_default_value(ValueType value);
template <typename ValueType> ValueType get_default_value() const;
template <typename ValueType> ValueType get_value() const;
void reset_default_value();

View File

@ -735,6 +735,81 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB);
option.set_value(value);
}, swig_get_option($self));
}
void set_default_value_from_scm(SCM new_value)
{
if (!$self)
return;
auto reldate_values{get_reldate_values()};
std::visit([new_value, reldate_values](auto& option) {
if constexpr (std::is_same_v<std::decay_t<decltype(option)>,
GncOptionDateValue>)
{
if (scm_is_pair(new_value))
{
auto car{scm_to_utf8_string(scm_symbol_to_string(scm_car(new_value)))};
if (strcmp(car, "relative") == 0)
{
auto lookup{scm_assq_ref(reldate_values,
scm_cdr(new_value))};
auto reldate{scm_primitive_eval(lookup)};
option.set_default_value(static_cast<RelativeDatePeriod>(scm_to_int(reldate)));
}
else
{
option.set_value(scm_to_int64(scm_cdr(new_value)));
}
}
else
option.set_default_value(scm_to_int64(new_value));
return;
}
if constexpr (std::is_same_v<std::decay_t<decltype(option)>,
GncOptionMultichoiceValue>)
{
if (scm_is_integer(new_value))
{
option.set_default_value(scm_to_int(new_value));
return;
}
std::string new_value_str{};
if (scm_is_symbol(new_value))
new_value_str = scm_to_utf8_string(scm_symbol_to_string(new_value));
else if (scm_is_string(new_value))
new_value_str = scm_to_utf8_string(new_value);
if (!new_value_str.empty())
option.set_default_value(new_value_str);
return;
}
if constexpr (std::is_same_v<std::decay_t<decltype(option)>,
GncOptionRangeValue<int>>)
{
if (scm_is_pair(new_value))
option.set_default_value(scm_to_int(scm_cdr(new_value)));
else
option.set_default_value(scm_to_int(new_value));
return;
}
auto value{scm_to_value<std::decay_t<decltype(option.get_value())>>(new_value)}; //Can't inline, set_value takes arg by reference.
option.set_default_value(value);
}, swig_get_option($self));
}
SCM get_type()
{
if (!self)
return SCM_BOOL_F;
return std::visit([](const auto& option)->SCM {
if constexpr (std::is_same_v<std::decay_t<decltype(option)>,
GncOptionMultichoiceValue>)
return scm_c_eval_string("'multichoice");
else if constexpr (std::is_same_v<decltype(option.get_value()),
bool>)
return scm_c_eval_string("'boolean");
else
return SCM_BOOL_F;
}, swig_get_option($self));
}
};
%extend GncOptionDB {