mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Provide for multiple selections in GncOptionMultichoiceValue
To support the GncOptionUIType::LIST. This UI type is unused in GnuCash code but might be used in user custom reports.
This commit is contained in:
parent
16da3208fc
commit
a995343a8b
@ -32,6 +32,9 @@ extern "C"
|
|||||||
#include "gnc-ui-util.h"
|
#include "gnc-ui-util.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string GncOptionMultichoiceValue::c_empty_string{""};
|
||||||
|
const std::string GncOptionMultichoiceValue::c_list_string{"multiple values"};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GncOptionAccountValue::validate(const GncOptionAccountList& values) const
|
GncOptionAccountValue::validate(const GncOptionAccountList& values) const
|
||||||
{
|
{
|
||||||
|
@ -412,13 +412,14 @@ private:
|
|||||||
ValueType m_step;
|
ValueType m_step;
|
||||||
};
|
};
|
||||||
|
|
||||||
using GncMultiChoiceOptionEntry = std::tuple<const std::string,
|
using GncMultichoiceOptionEntry = std::tuple<const std::string,
|
||||||
const std::string,
|
const std::string,
|
||||||
const std::string>;
|
const std::string>;
|
||||||
using GncMultiChoiceOptionChoices = std::vector<GncMultiChoiceOptionEntry>;
|
using GncMultichoiceOptionIndexVec = std::vector<std::size_t>;
|
||||||
|
using GncMultichoiceOptionChoices = std::vector<GncMultichoiceOptionEntry>;
|
||||||
|
|
||||||
/** MultiChoice options have a vector of valid options
|
/** Multichoice options have a vector of valid options
|
||||||
* (GncMultiChoiceOptionChoices) and validate the selection as being one of
|
* (GncMultichoiceOptionChoices) and validate the selection as being one of
|
||||||
* those values. The value is the index of the selected item in the vector. The
|
* those values. The value is the index of the selected item in the vector. The
|
||||||
* tuple contains three strings, a key, a display
|
* tuple contains three strings, a key, a display
|
||||||
* name and a brief description for the tooltip. Both name and description
|
* name and a brief description for the tooltip. Both name and description
|
||||||
@ -433,22 +434,48 @@ public:
|
|||||||
GncOptionMultichoiceValue(const char* section, const char* name,
|
GncOptionMultichoiceValue(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
const char* value,
|
const char* value,
|
||||||
GncMultiChoiceOptionChoices&& choices,
|
GncMultichoiceOptionChoices&& choices,
|
||||||
GncOptionUIType ui_type = GncOptionUIType::MULTICHOICE) :
|
GncOptionUIType ui_type = GncOptionUIType::MULTICHOICE) :
|
||||||
OptionClassifier{section, name, key, doc_string},
|
OptionClassifier{section, name, key, doc_string},
|
||||||
m_ui_type{ui_type},
|
m_ui_type{ui_type},
|
||||||
m_value{}, m_default_value{}, m_choices{std::move(choices)} {
|
m_value{}, m_default_value{}, m_choices{std::move(choices)}
|
||||||
if (value)
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
if (auto index = find_key(value);
|
||||||
|
index != size_t_max)
|
||||||
{
|
{
|
||||||
if (auto index = find_key(value);
|
m_value.push_back(index);
|
||||||
index != size_t_max)
|
m_default_value.push_back(index);
|
||||||
{
|
|
||||||
m_value = index;
|
|
||||||
m_default_value = index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GncOptionMultichoiceValue(const char* section, const char* name,
|
||||||
|
const char* key, const char* doc_string,
|
||||||
|
size_t index,
|
||||||
|
GncMultichoiceOptionChoices&& choices,
|
||||||
|
GncOptionUIType ui_type = GncOptionUIType::MULTICHOICE) :
|
||||||
|
OptionClassifier{section, name, key, doc_string},
|
||||||
|
m_ui_type{ui_type},
|
||||||
|
m_value{}, m_default_value{}, m_choices{std::move(choices)}
|
||||||
|
{
|
||||||
|
if (index < m_choices.size())
|
||||||
|
{
|
||||||
|
m_value.push_back(index);
|
||||||
|
m_default_value.push_back(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GncOptionMultichoiceValue(const char* section, const char* name,
|
||||||
|
const char* key, const char* doc_string,
|
||||||
|
GncMultichoiceOptionIndexVec&& indices,
|
||||||
|
GncMultichoiceOptionChoices&& choices,
|
||||||
|
GncOptionUIType ui_type = GncOptionUIType::LIST) :
|
||||||
|
OptionClassifier{section, name, key, doc_string},
|
||||||
|
m_ui_type{ui_type},
|
||||||
|
m_value{indices}, m_default_value{std::move(indices)},
|
||||||
|
m_choices{std::move(choices)} {}
|
||||||
GncOptionMultichoiceValue(const GncOptionMultichoiceValue&) = default;
|
GncOptionMultichoiceValue(const GncOptionMultichoiceValue&) = default;
|
||||||
GncOptionMultichoiceValue(GncOptionMultichoiceValue&&) = default;
|
GncOptionMultichoiceValue(GncOptionMultichoiceValue&&) = default;
|
||||||
GncOptionMultichoiceValue& operator=(const GncOptionMultichoiceValue&) = default;
|
GncOptionMultichoiceValue& operator=(const GncOptionMultichoiceValue&) = default;
|
||||||
@ -456,27 +483,84 @@ public:
|
|||||||
|
|
||||||
const std::string& get_value() const
|
const std::string& get_value() const
|
||||||
{
|
{
|
||||||
return std::get<0>(m_choices.at(m_value));
|
auto vec{m_value.size() > 0 ? m_value : m_default_value};
|
||||||
|
if (vec.size() == 0)
|
||||||
|
return c_empty_string;
|
||||||
|
if (vec.size() == 1)
|
||||||
|
return std::get<0>(m_choices.at(vec[0]));
|
||||||
|
else
|
||||||
|
return c_list_string;
|
||||||
}
|
}
|
||||||
const std::string& get_default_value() const
|
const std::string& get_default_value() const
|
||||||
{
|
{
|
||||||
return std::get<0>(m_choices.at(m_default_value));
|
if (m_default_value.size() == 1)
|
||||||
|
return std::get<0>(m_choices.at(m_default_value[0]));
|
||||||
|
else if (m_default_value.size() == 0)
|
||||||
|
return c_empty_string;
|
||||||
|
else
|
||||||
|
return c_list_string;
|
||||||
}
|
}
|
||||||
bool validate(const std::string& value) const noexcept
|
|
||||||
|
size_t get_index() const
|
||||||
|
{
|
||||||
|
if (m_value.size() > 0)
|
||||||
|
return m_value[0];
|
||||||
|
if (m_default_value.size() > 0)
|
||||||
|
return m_default_value[0];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const GncMultichoiceOptionIndexVec& get_multiple() const noexcept
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
const GncMultichoiceOptionIndexVec& get_default_multiple() const noexcept
|
||||||
|
{
|
||||||
|
return m_default_value;
|
||||||
|
}
|
||||||
|
bool validate(const std::string& value) const noexcept
|
||||||
{
|
{
|
||||||
auto index = find_key(value);
|
auto index = find_key(value);
|
||||||
return index != size_t_max;
|
return index != size_t_max;
|
||||||
|
|
||||||
|
}
|
||||||
|
bool validate(const GncMultichoiceOptionIndexVec& indexes) const noexcept
|
||||||
|
{
|
||||||
|
for (auto index : indexes)
|
||||||
|
if (index >= m_choices.size())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
void set_value(const std::string& value)
|
void set_value(const std::string& value)
|
||||||
{
|
{
|
||||||
auto index = find_key(value);
|
auto index = find_key(value);
|
||||||
if (index != size_t_max)
|
if (index != size_t_max)
|
||||||
m_value = index;
|
{
|
||||||
|
m_value.clear();
|
||||||
|
m_value.push_back(index);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw std::invalid_argument("Value not a valid choice.");
|
throw std::invalid_argument("Value not a valid choice.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
void set_value(size_t index)
|
||||||
|
{
|
||||||
|
if (index < m_choices.size())
|
||||||
|
{
|
||||||
|
m_value.clear();
|
||||||
|
m_value.push_back(index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::invalid_argument("Value not a valid choice.");
|
||||||
|
|
||||||
|
}
|
||||||
|
void set_multiple(const GncMultichoiceOptionIndexVec& indexes)
|
||||||
|
{
|
||||||
|
if (validate(indexes))
|
||||||
|
m_value = indexes;
|
||||||
|
else
|
||||||
|
throw std::invalid_argument("One of the supplied indexes was out of range.");
|
||||||
|
}
|
||||||
std::size_t num_permissible_values() const noexcept
|
std::size_t num_permissible_values() const noexcept
|
||||||
{
|
{
|
||||||
return m_choices.size();
|
return m_choices.size();
|
||||||
@ -513,11 +597,119 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
GncOptionUIType m_ui_type;
|
GncOptionUIType m_ui_type;
|
||||||
std::size_t m_value;
|
GncMultichoiceOptionIndexVec m_value;
|
||||||
std::size_t m_default_value;
|
GncMultichoiceOptionIndexVec m_default_value;
|
||||||
GncMultiChoiceOptionChoices m_choices;
|
GncMultichoiceOptionChoices m_choices;
|
||||||
|
static const std::string c_empty_string;
|
||||||
|
static const std::string c_list_string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<> inline std::ostream&
|
||||||
|
operator<< <GncOptionMultichoiceValue>(std::ostream& oss,
|
||||||
|
const GncOptionMultichoiceValue& opt)
|
||||||
|
{
|
||||||
|
auto vec{opt.get_multiple()};
|
||||||
|
bool first{true};
|
||||||
|
for (auto index : vec)
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
oss << " ";
|
||||||
|
oss << opt.permissible_value(index);
|
||||||
|
}
|
||||||
|
return oss;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline std::istream&
|
||||||
|
operator>> <GncOptionMultichoiceValue>(std::istream& iss,
|
||||||
|
GncOptionMultichoiceValue& opt)
|
||||||
|
{
|
||||||
|
GncMultichoiceOptionIndexVec values;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
std::getline(iss, str, ' ');
|
||||||
|
if (!str.empty())
|
||||||
|
{
|
||||||
|
auto index = opt.permissible_value_index(str.c_str());
|
||||||
|
if (index != size_t_max)
|
||||||
|
values.push_back(index);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string err = str + " is not one of ";
|
||||||
|
err += opt.m_name;
|
||||||
|
err += "'s permissible values.";
|
||||||
|
throw std::invalid_argument(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opt.set_multiple(values);
|
||||||
|
iss.clear();
|
||||||
|
return iss;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OptType, typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>, GncOptionMultichoiceValue>, int> = 0>
|
||||||
|
inline std::ostream&
|
||||||
|
gnc_option_to_scheme(std::ostream& oss, const OptType& opt)
|
||||||
|
{
|
||||||
|
auto indexes{opt.get_multiple()};
|
||||||
|
if (indexes.size() > 1)
|
||||||
|
oss << "'(";
|
||||||
|
bool first = true;
|
||||||
|
for (auto index : indexes)
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
oss << " ";
|
||||||
|
oss << "'" << opt.permissible_value(index);
|
||||||
|
}
|
||||||
|
if (indexes.size() > 1)
|
||||||
|
oss << ')';
|
||||||
|
return oss;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OptType, typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>, GncOptionMultichoiceValue>, int> = 0>
|
||||||
|
inline std::istream&
|
||||||
|
gnc_option_from_scheme(std::istream& iss, OptType& opt)
|
||||||
|
{
|
||||||
|
iss.ignore(3, '\'');
|
||||||
|
auto c{iss.peek()};
|
||||||
|
if (static_cast<char>(c) == '(')
|
||||||
|
{
|
||||||
|
GncMultichoiceOptionIndexVec values;
|
||||||
|
iss.ignore(3, '\'');
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
std::getline(iss, str, ' ');
|
||||||
|
if (!str.empty())
|
||||||
|
{
|
||||||
|
if (str.back() == ')')
|
||||||
|
{
|
||||||
|
str.pop_back();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
values.push_back(opt.permissible_value_index(str.c_str()));
|
||||||
|
iss.ignore(2, '\'');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opt.set_multiple(values);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
std::getline(iss, str, ' ');
|
||||||
|
opt.set_value(str);
|
||||||
|
}
|
||||||
|
return iss;
|
||||||
|
}
|
||||||
|
|
||||||
using GncOptionAccountList = std::vector<const Account*>;
|
using GncOptionAccountList = std::vector<const Account*>;
|
||||||
|
|
||||||
using GncOptionAccountTypeList = std::vector<GNCAccountType>;
|
using GncOptionAccountTypeList = std::vector<GNCAccountType>;
|
||||||
|
@ -58,6 +58,18 @@ GncOption::get_value() const
|
|||||||
std::is_same_v<std::decay_t<ValueType>,
|
std::is_same_v<std::decay_t<ValueType>,
|
||||||
size_t>)
|
size_t>)
|
||||||
return option.get_period_index();
|
return option.get_period_index();
|
||||||
|
if constexpr
|
||||||
|
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
|
GncOptionMultichoiceValue> &&
|
||||||
|
std::is_same_v<std::decay_t<ValueType>,
|
||||||
|
size_t>)
|
||||||
|
return option.get_index();
|
||||||
|
if constexpr
|
||||||
|
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
|
GncOptionMultichoiceValue> &&
|
||||||
|
std::is_same_v<std::decay_t<ValueType>,
|
||||||
|
GncMultichoiceOptionIndexVec>)
|
||||||
|
return option.get_multiple();
|
||||||
return ValueType {};
|
return ValueType {};
|
||||||
}, *m_option);
|
}, *m_option);
|
||||||
}
|
}
|
||||||
@ -78,6 +90,12 @@ GncOption::get_default_value() const
|
|||||||
std::is_same_v<std::decay_t<ValueType>,
|
std::is_same_v<std::decay_t<ValueType>,
|
||||||
size_t>)
|
size_t>)
|
||||||
return option.get_default_period_index();
|
return option.get_default_period_index();
|
||||||
|
if constexpr
|
||||||
|
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
|
GncOptionMultichoiceValue> &&
|
||||||
|
std::is_same_v<std::decay_t<ValueType>,
|
||||||
|
GncMultichoiceOptionIndexVec>)
|
||||||
|
return option.get_default_multiple();
|
||||||
return ValueType {};
|
return ValueType {};
|
||||||
}, *m_option);
|
}, *m_option);
|
||||||
|
|
||||||
@ -96,6 +114,12 @@ GncOption::set_value(ValueType value)
|
|||||||
RelativeDatePeriod> ||
|
RelativeDatePeriod> ||
|
||||||
std::is_same_v<std::decay_t<ValueType>, size_t>)))
|
std::is_same_v<std::decay_t<ValueType>, size_t>)))
|
||||||
option.set_value(value);
|
option.set_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);
|
}, *m_option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +245,10 @@ GncOption::validate(ValueType value) const
|
|||||||
GncOptionMultichoiceValue> &&
|
GncOptionMultichoiceValue> &&
|
||||||
std::is_same_v<std::decay_t<ValueType>,
|
std::is_same_v<std::decay_t<ValueType>,
|
||||||
std::string>) ||
|
std::string>) ||
|
||||||
|
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
|
GncOptionMultichoiceValue> &&
|
||||||
|
std::is_same_v<std::decay_t<ValueType>,
|
||||||
|
GncMultichoiceOptionIndexVec>) ||
|
||||||
std::is_same_v<std::decay_t<decltype(option)>,
|
std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
GncOptionValidatedValue<ValueType>>)
|
GncOptionValidatedValue<ValueType>>)
|
||||||
return option.validate(value);
|
return option.validate(value);
|
||||||
@ -334,19 +362,15 @@ GncOption::to_scheme(std::ostream& oss) const
|
|||||||
{
|
{
|
||||||
return std::visit([&oss](auto& option) ->std::ostream& {
|
return std::visit([&oss](auto& option) ->std::ostream& {
|
||||||
if constexpr
|
if constexpr
|
||||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
((std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
GncOptionAccountValue>)
|
GncOptionAccountValue>) ||
|
||||||
gnc_option_to_scheme(oss, option);
|
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
else if constexpr
|
GncOptionMultichoiceValue>) ||
|
||||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
GncOptionMultichoiceValue>)
|
|
||||||
oss << "'" << option;
|
|
||||||
else if constexpr
|
|
||||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
|
||||||
GncOptionValue<const QofInstance*>> ||
|
GncOptionValue<const QofInstance*>> ||
|
||||||
std::is_same_v<std::decay_t<decltype(option)>,
|
std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
GncOptionValidatedValue<const QofInstance*>>)
|
GncOptionValidatedValue<const QofInstance*>>)
|
||||||
gnc_option_to_scheme(oss, option);
|
gnc_option_to_scheme(oss, option);
|
||||||
else if constexpr
|
else if constexpr
|
||||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
GncOptionDateValue>)
|
GncOptionDateValue>)
|
||||||
@ -366,18 +390,11 @@ GncOption::from_scheme(std::istream& iss)
|
|||||||
{
|
{
|
||||||
return std::visit([&iss](auto& option) -> std::istream& {
|
return std::visit([&iss](auto& option) -> std::istream& {
|
||||||
if constexpr
|
if constexpr
|
||||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
|
||||||
GncOptionAccountValue>)
|
|
||||||
gnc_option_from_scheme(iss, option);
|
|
||||||
else if constexpr
|
|
||||||
((std::is_same_v<std::decay_t<decltype(option)>,
|
((std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
GncOptionMultichoiceValue>))
|
GncOptionAccountValue>) ||
|
||||||
{
|
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
iss.ignore(1, '\'');
|
GncOptionMultichoiceValue>) ||
|
||||||
iss >> option;
|
std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
}
|
|
||||||
else if constexpr
|
|
||||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
|
||||||
GncOptionValue<const QofInstance*>> ||
|
GncOptionValue<const QofInstance*>> ||
|
||||||
std::is_same_v<std::decay_t<decltype(option)>,
|
std::is_same_v<std::decay_t<decltype(option)>,
|
||||||
GncOptionValidatedValue<const QofInstance*>>)
|
GncOptionValidatedValue<const QofInstance*>>)
|
||||||
@ -438,6 +455,7 @@ template std::string GncOption::get_value<std::string>() const;
|
|||||||
template const QofInstance* GncOption::get_value<const QofInstance*>() const;
|
template const QofInstance* GncOption::get_value<const QofInstance*>() const;
|
||||||
template RelativeDatePeriod GncOption::get_value<RelativeDatePeriod>() const;
|
template RelativeDatePeriod GncOption::get_value<RelativeDatePeriod>() const;
|
||||||
template GncOptionAccountList GncOption::get_value<GncOptionAccountList>() const;
|
template GncOptionAccountList GncOption::get_value<GncOptionAccountList>() const;
|
||||||
|
template GncMultichoiceOptionIndexVec GncOption::get_value<GncMultichoiceOptionIndexVec>() const;
|
||||||
|
|
||||||
template bool GncOption::get_default_value<bool>() const;
|
template bool GncOption::get_default_value<bool>() const;
|
||||||
template int GncOption::get_default_value<int>() const;
|
template int GncOption::get_default_value<int>() const;
|
||||||
@ -447,6 +465,7 @@ template const char* GncOption::get_default_value<const char*>() const;
|
|||||||
template std::string GncOption::get_default_value<std::string>() const;
|
template std::string GncOption::get_default_value<std::string>() const;
|
||||||
template const QofInstance* GncOption::get_default_value<const QofInstance*>() const;
|
template const QofInstance* GncOption::get_default_value<const QofInstance*>() const;
|
||||||
template RelativeDatePeriod GncOption::get_default_value<RelativeDatePeriod>() const;
|
template RelativeDatePeriod GncOption::get_default_value<RelativeDatePeriod>() const;
|
||||||
|
template GncMultichoiceOptionIndexVec GncOption::get_default_value<GncMultichoiceOptionIndexVec>() const;
|
||||||
|
|
||||||
template void GncOption::set_value(bool);
|
template void GncOption::set_value(bool);
|
||||||
template void GncOption::set_value(int);
|
template void GncOption::set_value(int);
|
||||||
@ -457,6 +476,7 @@ template void GncOption::set_value(std::string);
|
|||||||
template void GncOption::set_value(const QofInstance*);
|
template void GncOption::set_value(const QofInstance*);
|
||||||
template void GncOption::set_value(RelativeDatePeriod);
|
template void GncOption::set_value(RelativeDatePeriod);
|
||||||
template void GncOption::set_value(size_t);
|
template void GncOption::set_value(size_t);
|
||||||
|
template void GncOption::set_value(GncMultichoiceOptionIndexVec);
|
||||||
|
|
||||||
template bool GncOption::validate(bool) const;
|
template bool GncOption::validate(bool) const;
|
||||||
template bool GncOption::validate(int) const;
|
template bool GncOption::validate(int) const;
|
||||||
@ -466,3 +486,4 @@ template bool GncOption::validate(const char*) const;
|
|||||||
template bool GncOption::validate(std::string) const;
|
template bool GncOption::validate(std::string) const;
|
||||||
template bool GncOption::validate(const QofInstance*) const;
|
template bool GncOption::validate(const QofInstance*) const;
|
||||||
template bool GncOption::validate(RelativeDatePeriod) const;
|
template bool GncOption::validate(RelativeDatePeriod) const;
|
||||||
|
template bool GncOption::validate(GncMultichoiceOptionIndexVec) const;
|
||||||
|
@ -1033,6 +1033,95 @@ TEST_F(GncMultichoiceOption, test_multichoice_scheme_in)
|
|||||||
EXPECT_STREQ("pork", m_option.get_value<std::string>().c_str());
|
EXPECT_STREQ("pork", m_option.get_value<std::string>().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GncOptionListTest : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
GncOptionListTest() :
|
||||||
|
m_option{GncOptionMultichoiceValue{"foo", "bar", "baz",
|
||||||
|
"Phony Option",
|
||||||
|
GncMultichoiceOptionIndexVec{0, 2},
|
||||||
|
{
|
||||||
|
{"plugh", "xyzzy", "thud"},
|
||||||
|
{"waldo", "pepper", "salt"},
|
||||||
|
{"pork", "sausage", "links"},
|
||||||
|
{"corge", "grault", "garply"}
|
||||||
|
}}} {}
|
||||||
|
GncOption m_option;
|
||||||
|
};
|
||||||
|
|
||||||
|
using GncListOption = GncOptionListTest;
|
||||||
|
|
||||||
|
TEST_F(GncListOption, test_option_ui_type)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(GncOptionUIType::LIST, m_option.get_ui_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GncListOption, test_validate)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(m_option.validate(std::string{"pork"}));
|
||||||
|
EXPECT_TRUE(m_option.validate(GncMultichoiceOptionIndexVec{1, 3}));
|
||||||
|
EXPECT_FALSE(m_option.validate(GncMultichoiceOptionIndexVec{2, 6}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GncListOption, test_set_value)
|
||||||
|
{
|
||||||
|
EXPECT_NO_THROW({
|
||||||
|
m_option.set_value(GncMultichoiceOptionIndexVec{1, 3});
|
||||||
|
EXPECT_STREQ("multiple values",
|
||||||
|
m_option.get_value<std::string>().c_str());
|
||||||
|
EXPECT_EQ(1U, m_option.get_value<size_t>());
|
||||||
|
auto vec{m_option.get_value<GncMultichoiceOptionIndexVec>()};
|
||||||
|
ASSERT_EQ(2U, vec.size());
|
||||||
|
EXPECT_EQ(1U, vec[0]);
|
||||||
|
EXPECT_EQ(3U, vec[1]);
|
||||||
|
});
|
||||||
|
EXPECT_THROW({ m_option.set_value(GncMultichoiceOptionIndexVec{2, 5}); }, std::invalid_argument);
|
||||||
|
EXPECT_EQ(1U, m_option.get_value<size_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GncListOption, test_list_out)
|
||||||
|
{
|
||||||
|
auto vec{m_option.get_value<GncMultichoiceOptionIndexVec>()};
|
||||||
|
std::string value{m_option.permissible_value(vec[0])};
|
||||||
|
value += " ";
|
||||||
|
value += m_option.permissible_value(vec[1]);
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << m_option;
|
||||||
|
EXPECT_EQ(oss.str(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GncListOption, test_list_in)
|
||||||
|
{
|
||||||
|
std::istringstream iss{"grault"};
|
||||||
|
EXPECT_THROW({
|
||||||
|
iss >> m_option;
|
||||||
|
}, std::invalid_argument);
|
||||||
|
iss.clear(); //reset failedbit
|
||||||
|
iss.str("pork");
|
||||||
|
iss >> m_option;
|
||||||
|
EXPECT_EQ(iss.str(), m_option.get_value<std::string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GncListOption, test_list_scheme_out)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
m_option.to_scheme(oss);
|
||||||
|
std::string value{"'('"};
|
||||||
|
auto vec{m_option.get_value<GncMultichoiceOptionIndexVec>()};
|
||||||
|
value += m_option.permissible_value(vec[0]);
|
||||||
|
value += " '";
|
||||||
|
value += m_option.permissible_value(vec[1]);
|
||||||
|
value += ")";
|
||||||
|
EXPECT_EQ(value, oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GncListOption, test_list_scheme_in)
|
||||||
|
{
|
||||||
|
std::istringstream iss{"'('pork 'waldo)"};
|
||||||
|
m_option.from_scheme(iss);
|
||||||
|
EXPECT_STREQ("pork", m_option.get_value<std::string>().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
static time64
|
static time64
|
||||||
time64_from_gdate(const GDate* g_date, DayPart when)
|
time64_from_gdate(const GDate* g_date, DayPart when)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user