Add a multiselect boolean member to GncOptionAccountValue.

To support a variation available in dialog-options. Even though it's not
used in any GnuCash code nor documented anywhere it might be in some
custom reports.
This commit is contained in:
John Ralls 2020-03-10 14:48:06 -07:00
parent fce33799af
commit 3200bd4966
5 changed files with 50 additions and 25 deletions

View File

@ -37,7 +37,8 @@ GncOptionAccountValue::validate(const GncOptionAccountList& values) const
{
if (values.empty())
return false;
if (get_ui_type() == GncOptionUIType::ACCOUNT_SEL && values.size() != 1)
if ((get_ui_type() == GncOptionUIType::ACCOUNT_SEL || !m_multiselect) &&
values.size() != 1)
return false;
if (m_allowed.empty())
return true;

View File

@ -544,32 +544,32 @@ class GncOptionAccountValue : public OptionClassifier
public:
GncOptionAccountValue(const char* section, const char* name,
const char* key, const char* doc_string,
GncOptionUIType ui_type) :
OptionClassifier{section, name, key, doc_string},
m_ui_type{ui_type}, m_value{}, m_default_value{}, m_allowed{} {}
GncOptionUIType ui_type, bool multi=true) :
OptionClassifier{section, name, key, doc_string}, m_ui_type{ui_type},
m_value{}, m_default_value{}, m_allowed{}, m_multiselect{multi} {}
GncOptionAccountValue(const char* section, const char* name,
const char* key, const char* doc_string,
GncOptionUIType ui_type,
const GncOptionAccountList& value) :
OptionClassifier{section, name, key, doc_string},
m_ui_type{ui_type}, m_value{value},
m_default_value{std::move(value)}, m_allowed{} {}
const GncOptionAccountList& value, bool multi=true) :
OptionClassifier{section, name, key, doc_string}, m_ui_type{ui_type},
m_value{value}, m_default_value{std::move(value)}, m_allowed{},
m_multiselect{multi} {}
GncOptionAccountValue(const char* section, const char* name,
const char* key, const char* doc_string,
GncOptionUIType ui_type,
GncOptionAccountTypeList&& allowed) :
OptionClassifier{section, name, key, doc_string},
m_ui_type{ui_type}, m_value{},
m_default_value{}, m_allowed{std::move(allowed)} {}
GncOptionAccountTypeList&& allowed, bool multi=true) :
OptionClassifier{section, name, key, doc_string}, m_ui_type{ui_type},
m_value{}, m_default_value{}, m_allowed{std::move(allowed)},
m_multiselect{multi} {}
GncOptionAccountValue(const char* section, const char* name,
const char* key, const char* doc_string,
GncOptionUIType ui_type,
const GncOptionAccountList& value,
GncOptionAccountTypeList&& allowed) :
OptionClassifier{section, name, key, doc_string},
m_ui_type{ui_type}, m_value{},
m_default_value{}, m_allowed{std::move(allowed)} {
GncOptionAccountTypeList&& allowed, bool multi=true) :
OptionClassifier{section, name, key, doc_string}, m_ui_type{ui_type},
m_value{}, m_default_value{}, m_allowed{std::move(allowed)},
m_multiselect{multi} {
if (!validate(value))
throw std::invalid_argument("Supplied Value not in allowed set.");
m_value = value;
@ -588,11 +588,13 @@ public:
bool is_changed() const noexcept { return m_value != m_default_value; }
GncOptionUIType get_ui_type() const noexcept { return m_ui_type; }
void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; }
bool is_multiselect() const noexcept { return m_multiselect; }
private:
GncOptionUIType m_ui_type;
GncOptionAccountList m_value;
GncOptionAccountList m_default_value;
GncOptionAccountTypeList m_allowed;
bool m_multiselect;
};
template<> inline std::ostream&

View File

@ -201,6 +201,18 @@ GncOption::is_changed() const noexcept
}, *m_option);
}
bool
GncOption::is_multiselect() const noexcept
{
return std::visit([](const auto& option)->bool {
if constexpr (std::is_same_v<std::decay_t<decltype(option)>,
GncOptionAccountValue>)
return option.is_multiselect();
else
return false;
}, *m_option);
}
template<typename ValueType> bool
GncOption::validate(ValueType value) const
{

View File

@ -86,6 +86,7 @@ public:
void set_option_from_ui_item();
void make_internal();
bool is_changed() const noexcept;
bool is_multiselect() const noexcept;
template <typename ValueType> bool validate(ValueType value) const;
std::size_t num_permissible_values() const;
std::size_t permissible_value_index(const char* value) const;

View File

@ -757,29 +757,34 @@ TEST_F(GncOptionAccountTest, test_option_value_limited_constructor)
EXPECT_THROW({
GncOptionAccountValue option("foo", "bar", "baz", "Bogus Option",
GncOptionUIType::ACCOUNT_LIST,
acclistbad, {ACCT_TYPE_BANK});
acclistbad,
GncOptionAccountTypeList{ACCT_TYPE_BANK});
}, std::invalid_argument);
EXPECT_THROW({
GncOptionAccountValue option("foo", "bar", "baz", "Bogus Option",
GncOptionUIType::ACCOUNT_SEL,
acclistgood, {ACCT_TYPE_BANK});
acclistgood,
GncOptionAccountTypeList{ACCT_TYPE_BANK});
}, std::invalid_argument);
EXPECT_NO_THROW({
GncOptionAccountValue option("foo", "bar", "baz", "Bogus Option",
GncOptionUIType::ACCOUNT_LIST,
acclistgood, {ACCT_TYPE_BANK});
acclistgood,
GncOptionAccountTypeList{ACCT_TYPE_BANK});
});
EXPECT_NO_THROW({
GncOptionAccountList accsel{acclistgood[0]};
GncOptionAccountValue option("foo", "bar", "baz", "Bogus Option",
GncOptionUIType::ACCOUNT_LIST,
accsel, {ACCT_TYPE_BANK});
accsel,
GncOptionAccountTypeList{ACCT_TYPE_BANK});
});
GncOptionAccountValue option {"foo", "bar", "baz", "Bogus Option",
GncOptionUIType::ACCOUNT_LIST, acclistgood, {ACCT_TYPE_BANK}};
GncOptionUIType::ACCOUNT_LIST, acclistgood,
GncOptionAccountTypeList{ACCT_TYPE_BANK}};
EXPECT_FALSE(option.get_value().empty());
EXPECT_FALSE(option.get_default_value().empty());
EXPECT_EQ(true, option.validate(acclistgood));
@ -804,7 +809,8 @@ TEST_F(GncOptionAccountTest, test_account_list_out)
GncOption sel_option{GncOptionAccountValue{"foo", "bar", "baz",
"Bogus Option",
GncOptionUIType::ACCOUNT_LIST,
accsel, {ACCT_TYPE_BANK}}};
accsel,
GncOptionAccountTypeList{ACCT_TYPE_BANK}}};
acc_guids = gnc::GUID{*qof_instance_get_guid(accsel[0])}.to_string();
oss.str("");
@ -830,7 +836,8 @@ TEST_F(GncOptionAccountTest, test_account_list_in)
GncOption sel_option{GncOptionAccountValue{"foo", "bar", "baz",
"Bogus Option",
GncOptionUIType::ACCOUNT_LIST,
accsel, {ACCT_TYPE_BANK}}};
accsel,
GncOptionAccountTypeList{ACCT_TYPE_BANK}}};
GncOptionAccountList acclistbad{list_of_types({ACCT_TYPE_STOCK})};
acc_guids = gnc::GUID{*qof_instance_get_guid(acclistbad[1])}.to_string();
acc_guids += " ";
@ -885,7 +892,8 @@ TEST_F(GncOptionAccountTest, test_account_list_to_scheme)
GncOption sel_option{GncOptionAccountValue{"foo", "bar", "baz",
"Bogus Option",
GncOptionUIType::ACCOUNT_LIST,
accsel, {ACCT_TYPE_BANK}}};
accsel,
GncOptionAccountTypeList{ACCT_TYPE_BANK}}};
acc_guids = make_account_list_SCM_str(accsel);
oss.str("");
@ -909,7 +917,8 @@ TEST_F(GncOptionAccountTest, test_account_list_from_scheme)
GncOption sel_option{GncOptionAccountValue{"foo", "bar", "baz",
"Bogus Option",
GncOptionUIType::ACCOUNT_LIST,
accsel, {ACCT_TYPE_BANK}}};
accsel,
GncOptionAccountTypeList{ACCT_TYPE_BANK}}};
GncOptionAccountList acclistbad{list_of_types({ACCT_TYPE_STOCK})};
acc_guids = make_account_list_SCM_str(acclistbad);
iss.str(acc_guids);