mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
GncOptionUIItem from the GncOptionVariant classes to GncOption.
Separating the UI from the data model. Note that the GncOptionVariant classes still have a GncOptionUIType member to ensure that a GncOptionUIItem of the right type is attached.
This commit is contained in:
parent
1bea809cec
commit
99c2c5e439
@ -1,5 +1,5 @@
|
||||
/********************************************************************\
|
||||
* gnc-option-impl.hpp -- Application options system *
|
||||
* gnc-option-impl.hpp -- Application options system *
|
||||
* Copyright (C) 2019 John Ralls <jralls@ceridwen.us> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
@ -107,62 +107,12 @@ struct OptionClassifier
|
||||
std::string m_doc_string;
|
||||
};
|
||||
|
||||
class GncOptionUIItem;
|
||||
|
||||
/**
|
||||
* Holds a pointer to the UI item which will control the option and an enum
|
||||
* representing the type of the option for dispatch purposes; all of that
|
||||
* happens in gnucash/gnome-utils/dialog-options and
|
||||
* gnucash/gnome/business-option-gnome.
|
||||
*
|
||||
* This class takes no ownership responsibility, so calling code is responsible
|
||||
* for ensuring that the UI_Item is alive. For convenience the public
|
||||
* clear_ui_item function can be used as a weak_ptr's destruction callback to
|
||||
* ensure that the ptr will be nulled if the ui_item is destroyed elsewhere.
|
||||
*/
|
||||
class OptionUIItem
|
||||
{
|
||||
public:
|
||||
GncOptionUIType get_ui_type() const { return m_ui_type; }
|
||||
GncOptionUIItem* const get_ui_item() const {return m_ui_item; }
|
||||
void clear_ui_item() { m_ui_item = nullptr; }
|
||||
void set_ui_item(GncOptionUIItem* ui_item)
|
||||
{
|
||||
if (m_ui_type == GncOptionUIType::INTERNAL)
|
||||
{
|
||||
std::string error{"INTERNAL option, setting the UI item forbidden."};
|
||||
throw std::logic_error(std::move(error));
|
||||
}
|
||||
m_ui_item = ui_item;
|
||||
}
|
||||
void make_internal()
|
||||
{
|
||||
if (m_ui_item != nullptr)
|
||||
{
|
||||
std::string error("Option has a UI Element, can't be INTERNAL.");
|
||||
throw std::logic_error(std::move(error));
|
||||
}
|
||||
m_ui_type = GncOptionUIType::INTERNAL;
|
||||
}
|
||||
protected:
|
||||
OptionUIItem(GncOptionUIType ui_type) :
|
||||
m_ui_item{nullptr}, m_ui_type{ui_type} {}
|
||||
OptionUIItem(const OptionUIItem&) = default;
|
||||
OptionUIItem(OptionUIItem&&) = default;
|
||||
~OptionUIItem() = default;
|
||||
OptionUIItem& operator=(const OptionUIItem&) = default;
|
||||
OptionUIItem& operator=(OptionUIItem&&) = default;
|
||||
private:
|
||||
GncOptionUIItem* m_ui_item;
|
||||
GncOptionUIType m_ui_type;
|
||||
};
|
||||
|
||||
#ifndef SWIG
|
||||
auto constexpr size_t_max = std::numeric_limits<std::size_t>::max();
|
||||
#endif
|
||||
|
||||
template <typename ValueType>
|
||||
class GncOptionValue : public OptionClassifier, public OptionUIItem
|
||||
class GncOptionValue : public OptionClassifier
|
||||
{
|
||||
public:
|
||||
GncOptionValue<ValueType>(const char* section, const char* name,
|
||||
@ -170,8 +120,7 @@ public:
|
||||
ValueType value,
|
||||
GncOptionUIType ui_type = GncOptionUIType::INTERNAL) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem(ui_type),
|
||||
m_value{value}, m_default_value{value} {}
|
||||
m_ui_type(ui_type), m_value{value}, m_default_value{value} {}
|
||||
GncOptionValue<ValueType>(const GncOptionValue<ValueType>&) = default;
|
||||
GncOptionValue<ValueType>(GncOptionValue<ValueType>&&) = default;
|
||||
GncOptionValue<ValueType>& operator=(const GncOptionValue<ValueType>&) = default;
|
||||
@ -180,13 +129,16 @@ public:
|
||||
ValueType get_default_value() const { return m_default_value; }
|
||||
void set_value(ValueType new_value) { m_value = new_value; }
|
||||
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; }
|
||||
private:
|
||||
GncOptionUIType m_ui_type;
|
||||
ValueType m_value;
|
||||
ValueType m_default_value;
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
class GncOptionValidatedValue : public OptionClassifier, public OptionUIItem
|
||||
class GncOptionValidatedValue : public OptionClassifier
|
||||
{
|
||||
public:
|
||||
GncOptionValidatedValue<ValueType>() = delete;
|
||||
@ -197,8 +149,8 @@ public:
|
||||
GncOptionUIType ui_type = GncOptionUIType::INTERNAL
|
||||
) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem{ui_type},
|
||||
m_value{value}, m_default_value{value}, m_validator{validator}
|
||||
m_ui_type{ui_type}, m_value{value}, m_default_value{value},
|
||||
m_validator{validator}
|
||||
{
|
||||
if (!this->validate(value))
|
||||
throw std::invalid_argument("Attempt to create GncValidatedOption with bad value.");
|
||||
@ -209,7 +161,7 @@ public:
|
||||
std::function<bool(ValueType)>validator,
|
||||
ValueType val_data) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem{GncOptionUIType::INTERNAL}, m_value{value},
|
||||
m_ui_type{GncOptionUIType::INTERNAL}, m_value{value},
|
||||
m_default_value{value}, m_validator{validator}, m_validation_data{val_data}
|
||||
{
|
||||
if (!this->validate(value))
|
||||
@ -232,7 +184,10 @@ public:
|
||||
bool is_changed() const noexcept { return m_value != m_default_value; }
|
||||
std::ostream& to_scheme(std::ostream&) const;
|
||||
std::istream& from_scheme(std::istream&);
|
||||
GncOptionUIType get_ui_type() const noexcept { return m_ui_type; }
|
||||
void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; }
|
||||
private:
|
||||
GncOptionUIType m_ui_type;
|
||||
ValueType m_value;
|
||||
ValueType m_default_value;
|
||||
std::function<bool(ValueType)> m_validator; //11
|
||||
@ -419,8 +374,7 @@ gnc_option_from_scheme (std::istream& iss, OptType& opt)
|
||||
*/
|
||||
|
||||
template <typename ValueType>
|
||||
class GncOptionRangeValue :
|
||||
public OptionClassifier, public OptionUIItem
|
||||
class GncOptionRangeValue : public OptionClassifier
|
||||
{
|
||||
public:
|
||||
GncOptionRangeValue<ValueType>(const char* section, const char* name,
|
||||
@ -428,7 +382,6 @@ public:
|
||||
ValueType value, ValueType min,
|
||||
ValueType max, ValueType step) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem(GncOptionUIType::NUMBER_RANGE),
|
||||
m_value{value >= min && value <= max ? value : min},
|
||||
m_default_value{value >= min && value <= max ? value : min},
|
||||
m_min{min}, m_max{max}, m_step{step} {}
|
||||
@ -448,7 +401,10 @@ public:
|
||||
throw std::invalid_argument("Validation failed, value not set.");
|
||||
}
|
||||
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; }
|
||||
private:
|
||||
GncOptionUIType m_ui_type = GncOptionUIType::NUMBER_RANGE;
|
||||
ValueType m_value;
|
||||
ValueType m_default_value;
|
||||
ValueType m_min;
|
||||
@ -471,8 +427,7 @@ using GncMultiChoiceOptionChoices = std::vector<GncMultiChoiceOptionEntry>;
|
||||
*
|
||||
*/
|
||||
|
||||
class GncOptionMultichoiceValue :
|
||||
public OptionClassifier, public OptionUIItem
|
||||
class GncOptionMultichoiceValue : public OptionClassifier
|
||||
{
|
||||
public:
|
||||
GncOptionMultichoiceValue(const char* section, const char* name,
|
||||
@ -481,7 +436,7 @@ public:
|
||||
GncMultiChoiceOptionChoices&& choices,
|
||||
GncOptionUIType ui_type = GncOptionUIType::MULTICHOICE) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem(ui_type),
|
||||
m_ui_type{ui_type},
|
||||
m_value{}, m_default_value{}, m_choices{std::move(choices)} {
|
||||
if (value)
|
||||
{
|
||||
@ -543,6 +498,8 @@ public:
|
||||
return std::get<2>(m_choices.at(index));
|
||||
}
|
||||
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; }
|
||||
private:
|
||||
std::size_t find_key (const std::string& key) const noexcept
|
||||
{
|
||||
@ -555,6 +512,7 @@ private:
|
||||
return size_t_max;
|
||||
|
||||
}
|
||||
GncOptionUIType m_ui_type;
|
||||
std::size_t m_value;
|
||||
std::size_t m_default_value;
|
||||
GncMultiChoiceOptionChoices m_choices;
|
||||
@ -581,31 +539,28 @@ using GncOptionAccountTypeList = std::vector<GNCAccountType>;
|
||||
|
||||
*/
|
||||
|
||||
class GncOptionAccountValue :
|
||||
public OptionClassifier, public OptionUIItem
|
||||
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},
|
||||
OptionUIItem(ui_type), m_value{}, m_default_value{}, m_allowed{} {}
|
||||
m_ui_type{ui_type}, m_value{}, m_default_value{}, m_allowed{} {}
|
||||
|
||||
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},
|
||||
OptionUIItem(ui_type),
|
||||
m_value{value},
|
||||
m_ui_type{ui_type}, m_value{value},
|
||||
m_default_value{std::move(value)}, m_allowed{} {}
|
||||
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},
|
||||
OptionUIItem(ui_type),
|
||||
m_value{},
|
||||
m_ui_type{ui_type}, m_value{},
|
||||
m_default_value{}, m_allowed{std::move(allowed)} {}
|
||||
GncOptionAccountValue(const char* section, const char* name,
|
||||
const char* key, const char* doc_string,
|
||||
@ -613,8 +568,7 @@ public:
|
||||
const GncOptionAccountList& value,
|
||||
GncOptionAccountTypeList&& allowed) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem(ui_type),
|
||||
m_value{},
|
||||
m_ui_type{ui_type}, m_value{},
|
||||
m_default_value{}, m_allowed{std::move(allowed)} {
|
||||
if (!validate(value))
|
||||
throw std::invalid_argument("Supplied Value not in allowed set.");
|
||||
@ -631,7 +585,10 @@ public:
|
||||
m_value = values;
|
||||
}
|
||||
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; }
|
||||
private:
|
||||
GncOptionUIType m_ui_type;
|
||||
GncOptionAccountList m_value;
|
||||
GncOptionAccountList m_default_value;
|
||||
GncOptionAccountTypeList m_allowed;
|
||||
@ -727,13 +684,12 @@ gnc-date-option-absolute-time m_type == DateTyupe::Absolute
|
||||
gnc-date-option-relative-time m_type != DateTyupe::Absolute
|
||||
*/
|
||||
|
||||
class GncOptionDateValue : public OptionClassifier, public OptionUIItem
|
||||
class GncOptionDateValue : public OptionClassifier
|
||||
{
|
||||
public:
|
||||
GncOptionDateValue(const char* section, const char* name,
|
||||
const char* key, const char* doc_string) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem(GncOptionUIType::DATE),
|
||||
m_period{RelativeDatePeriod::END_ACCOUNTING_PERIOD},
|
||||
m_date{INT64_MAX},
|
||||
m_default_period{RelativeDatePeriod::END_ACCOUNTING_PERIOD},
|
||||
@ -742,14 +698,12 @@ public:
|
||||
const char* key, const char* doc_string,
|
||||
time64 time) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem(GncOptionUIType::DATE),
|
||||
m_period{RelativeDatePeriod::ABSOLUTE}, m_date{time},
|
||||
m_default_period{RelativeDatePeriod::ABSOLUTE}, m_default_date{time} {}
|
||||
GncOptionDateValue(const char* section, const char* name,
|
||||
const char* key, const char* doc_string,
|
||||
const RelativeDatePeriod period) :
|
||||
OptionClassifier{section, name, key, doc_string},
|
||||
OptionUIItem(GncOptionUIType::DATE),
|
||||
m_period{period}, m_date{INT64_MAX},
|
||||
m_default_period{period}, m_default_date{INT64_MAX} {}
|
||||
GncOptionDateValue(const GncOptionDateValue&) = default;
|
||||
@ -770,7 +724,10 @@ public:
|
||||
}
|
||||
bool is_changed() const noexcept { return m_period != m_default_period &&
|
||||
m_date != m_default_date; }
|
||||
GncOptionUIType get_ui_type() const noexcept { return m_ui_type; }
|
||||
void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; }
|
||||
private:
|
||||
GncOptionUIType m_ui_type = GncOptionUIType::DATE;
|
||||
RelativeDatePeriod m_period;
|
||||
time64 m_date;
|
||||
RelativeDatePeriod m_default_period;
|
||||
|
93
libgnucash/app-utils/gnc-option-ui.hpp
Normal file
93
libgnucash/app-utils/gnc-option-ui.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/********************************************************************\
|
||||
* gnc-option-ui.hpp -- UI association for GncOption *
|
||||
* Copyright (C) 2019 John Ralls <jralls@ceridwen.us> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef GNC_OPTION_UI_HPP_
|
||||
#define GNC_OPTION_UI_HPP_
|
||||
|
||||
#include "gnc-option-uitype.hpp"
|
||||
template <typename UIType>
|
||||
class GncUIItem
|
||||
{
|
||||
public:
|
||||
GncUIItem(UIType* widget) : m_widget{widget} {}
|
||||
UIType* m_widget;
|
||||
};
|
||||
|
||||
class GncUIType;
|
||||
using OptionUIItem = GncUIItem<GncUIType>;
|
||||
using OptionSyncFunc = std::function<void(OptionUIItem&, GncOption&)>;
|
||||
/**
|
||||
* Holds a pointer to the UI item which will control the option and an enum
|
||||
* representing the type of the option for dispatch purposes; all of that
|
||||
* happens in gnucash/gnome-utils/dialog-options and
|
||||
* gnucash/gnome/business-option-gnome.
|
||||
*
|
||||
* This class takes no ownership responsibility, so calling code is responsible
|
||||
* for ensuring that the UI_Item is alive. For convenience the public
|
||||
* clear_ui_item function can be used as a weak_ptr's destruction callback to
|
||||
* ensure that the ptr will be nulled if the ui_item is destroyed elsewhere.
|
||||
*/
|
||||
class GncOptionUIItem
|
||||
{
|
||||
public:
|
||||
GncOptionUIItem(OptionUIItem&& ui_item, GncOptionUIType type,
|
||||
OptionSyncFunc to_ui, OptionSyncFunc from_ui) :
|
||||
m_ui_item{std::move(ui_item)}, m_ui_type{type},
|
||||
m_set_ui_item_from_option{to_ui}, m_set_option_from_ui_item{from_ui} {}
|
||||
GncOptionUIItem(GncOptionUIType ui_type) :
|
||||
m_ui_item{nullptr}, m_ui_type{ui_type} {}
|
||||
GncOptionUIItem(const GncOptionUIItem&) = default;
|
||||
GncOptionUIItem(GncOptionUIItem&&) = default;
|
||||
~GncOptionUIItem() = default;
|
||||
GncOptionUIItem& operator=(const GncOptionUIItem&) = default;
|
||||
GncOptionUIItem& operator=(GncOptionUIItem&&) = default;
|
||||
GncOptionUIType get_ui_type() const { return m_ui_type; }
|
||||
const OptionUIItem& get_ui_item() const {return m_ui_item; }
|
||||
void clear_ui_item() { m_ui_item = nullptr; }
|
||||
void set_ui_item(OptionUIItem&& ui_item)
|
||||
{
|
||||
if (m_ui_type == GncOptionUIType::INTERNAL)
|
||||
{
|
||||
std::string error{"INTERNAL option, setting the UI item forbidden."};
|
||||
throw std::logic_error(std::move(error));
|
||||
}
|
||||
m_ui_item = std::move(ui_item);
|
||||
}
|
||||
void set_ui_item_from_option(GncOption& option)
|
||||
{
|
||||
m_set_ui_item_from_option(m_ui_item, option);
|
||||
}
|
||||
void set_option_from_ui_item(GncOption& option)
|
||||
{
|
||||
m_set_option_from_ui_item(m_ui_item, option);
|
||||
}
|
||||
private:
|
||||
OptionUIItem m_ui_item;
|
||||
GncOptionUIType m_ui_type;
|
||||
OptionSyncFunc m_set_ui_item_from_option;
|
||||
OptionSyncFunc m_set_option_from_ui_item;
|
||||
};
|
||||
|
||||
using GncOptionUIItemPtr = std::unique_ptr<GncOptionUIItem>;
|
||||
|
||||
#endif //GNC_OPTION_UI_HPP__
|
@ -24,6 +24,14 @@
|
||||
#include "gnc-option.hpp"
|
||||
#include "gnc-option-impl.hpp"
|
||||
#include "gnc-option-uitype.hpp"
|
||||
#include "gnc-option-ui.hpp"
|
||||
|
||||
static const char* log_module{"gnc.app-utils.gnc-option"};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <qoflog.h>
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
GncOption::GncOption(const char* section, const char* name,
|
||||
@ -103,11 +111,21 @@ GncOption::get_docstring() const
|
||||
}
|
||||
|
||||
void
|
||||
GncOption::set_ui_item(GncOptionUIItem* ui_elem)
|
||||
GncOption::set_ui_item(GncOptionUIItemPtr&& ui_item)
|
||||
{
|
||||
std::visit([ui_elem](auto& option) {
|
||||
option.set_ui_item(ui_elem);
|
||||
}, *m_option);
|
||||
|
||||
auto opt_ui_type = std::visit([](const auto& option)->GncOptionUIType {
|
||||
return option.get_ui_type();
|
||||
}, *m_option);
|
||||
|
||||
if (ui_item->get_ui_type() != opt_ui_type)
|
||||
{
|
||||
PERR("Setting option %s:%s UI element failed, mismatched UI types.",
|
||||
get_section().c_str(), get_name().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui_item = std::move(ui_item);
|
||||
}
|
||||
|
||||
const GncOptionUIType
|
||||
@ -118,17 +136,37 @@ GncOption::get_ui_type() const
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
GncOptionUIItem* const
|
||||
const GncOptionUIItem*
|
||||
GncOption::get_ui_item() const
|
||||
{
|
||||
return std::visit([](const auto& option)->GncOptionUIItem* {
|
||||
return option.get_ui_item();
|
||||
}, *m_option);
|
||||
return m_ui_item.get();
|
||||
}
|
||||
|
||||
void
|
||||
GncOption::set_ui_item_from_option()
|
||||
{
|
||||
if (!m_ui_item)
|
||||
return;
|
||||
m_ui_item->set_ui_item_from_option(*this);
|
||||
}
|
||||
|
||||
void
|
||||
GncOption::set_option_from_ui_item()
|
||||
{
|
||||
if (!m_ui_item)
|
||||
return;
|
||||
m_ui_item->set_option_from_ui_item(*this);
|
||||
}
|
||||
|
||||
void
|
||||
GncOption::make_internal()
|
||||
{
|
||||
if (!m_ui_item)
|
||||
{
|
||||
PERR("Option %s:%s has a UI Element, can't be INTERNAL.",
|
||||
get_section().c_str(), get_name().c_str());
|
||||
return;
|
||||
}
|
||||
std::visit([](auto& option) {
|
||||
option.make_internal();
|
||||
}, *m_option);
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "gnc-option-uitype.hpp"
|
||||
|
||||
class GncOptionUIItem;
|
||||
using GncOptionUIItemPtr = std::unique_ptr<GncOptionUIItem>;
|
||||
struct QofInstance_s;
|
||||
using QofInstance = QofInstance_s;
|
||||
template <typename ValueType> class GncOptionValue;
|
||||
@ -72,9 +73,11 @@ public:
|
||||
const std::string& get_name() const;
|
||||
const std::string& get_key() const;
|
||||
const std::string& get_docstring() const;
|
||||
void set_ui_item(GncOptionUIItem* ui_elem);
|
||||
void set_ui_item(GncOptionUIItemPtr&& ui_elem);
|
||||
const GncOptionUIType get_ui_type() const;
|
||||
GncOptionUIItem* const get_ui_item() const;
|
||||
const GncOptionUIItem* get_ui_item() const;
|
||||
void set_ui_item_from_option();
|
||||
void set_option_from_ui_item();
|
||||
void make_internal();
|
||||
bool is_changed() const noexcept;
|
||||
template <typename ValueType> bool validate(ValueType value) const;
|
||||
@ -87,10 +90,11 @@ public:
|
||||
std::istream& in_stream(std::istream& iss);
|
||||
std::ostream& to_scheme(std::ostream& oss) const;
|
||||
std::istream& from_scheme(std::istream& iss);
|
||||
GncOptionVariantPtr& _get_option() { return m_option; }
|
||||
GncOptionVariant* const _get_option() { return m_option.get(); }
|
||||
private:
|
||||
inline static const std::string c_empty_string{""};
|
||||
GncOptionVariantPtr m_option;
|
||||
GncOptionUIItemPtr m_ui_item{nullptr};
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <kvp-value.hpp>
|
||||
#include "gnc-optiondb.hpp"
|
||||
#include "gnc-optiondb-impl.hpp"
|
||||
#include "gnc-option-ui.hpp"
|
||||
|
||||
auto constexpr stream_max = std::numeric_limits<std::streamsize>::max();
|
||||
GncOptionDB::GncOptionDB() : m_default_section{std::nullopt} {}
|
||||
|
@ -206,4 +206,5 @@ void gnc_register_date_interval_option(const GncOptionDBPtr& db,
|
||||
const char* section, const char* name,
|
||||
const char* key, const char* doc_string,
|
||||
RelativeDatePeriod period);
|
||||
|
||||
#endif //GNC_OPTIONDB_HPP_
|
||||
|
@ -181,6 +181,7 @@ gnc_option_test_book_destroy(QofBook* book)
|
||||
%ignore GncOptionDateValue::operator=(GncOptionDateValue&&);
|
||||
%ignore operator<<(std::ostream&, const GncOption&);
|
||||
%ignore operator>>(std::istream&, GncOption&);
|
||||
%ignore GncOption::_get_option();
|
||||
|
||||
%rename(absolute) RelativeDatePeriod::ABSOLUTE;
|
||||
%rename(today) RelativeDatePeriod::TODAY;
|
||||
@ -305,6 +306,9 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB);
|
||||
%include "gnc-option-impl.hpp"
|
||||
%include "gnc-optiondb.hpp"
|
||||
%include "gnc-optiondb-impl.hpp"
|
||||
%inline %{
|
||||
#include "gnc-option-ui.hpp"
|
||||
%}
|
||||
|
||||
%extend GncOption {
|
||||
SCM get_scm_value()
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <gnc-option.hpp>
|
||||
#include <gnc-option-impl.hpp>
|
||||
#include <gnc-option-ui.hpp>
|
||||
#include <guid.hpp>
|
||||
extern "C"
|
||||
{
|
||||
@ -505,7 +506,7 @@ TEST_F(GncOptionCommodityTest, test_commodity_from_scheme)
|
||||
EXPECT_EQ(QOF_INSTANCE(m_hpe), option.get_value<const QofInstance*>());
|
||||
}
|
||||
|
||||
class GncUIItem
|
||||
class GncUIType
|
||||
{
|
||||
public:
|
||||
void set_value(const std::string& value) { m_value = value; }
|
||||
@ -514,20 +515,29 @@ private:
|
||||
std::string m_value;
|
||||
};
|
||||
|
||||
class GncOptionUIItem
|
||||
{
|
||||
public:
|
||||
GncOptionUIItem(GncUIItem* widget) : m_widget{widget} {}
|
||||
GncUIItem* m_widget;
|
||||
};
|
||||
using OptionUIItem = GncUIItem<GncUIType>;
|
||||
|
||||
class GncOptionUITest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
GncOptionUITest() :
|
||||
m_widget{},
|
||||
m_option{"foo", "bar", "baz", "Phony Option", std::string{"waldo"},
|
||||
GncOptionUIType::STRING} {}
|
||||
|
||||
GncOptionUIType::STRING}
|
||||
{
|
||||
auto to_ui = [](OptionUIItem& ui, GncOption& opt) {
|
||||
ui.m_widget->set_value(opt.get_value<std::string>());
|
||||
};
|
||||
auto from_ui = [](OptionUIItem& ui, GncOption& opt) {
|
||||
opt.set_value<std::string>(ui.m_widget->get_value());
|
||||
};
|
||||
auto ui_item{std::make_unique<GncOptionUIItem>(
|
||||
OptionUIItem{&m_widget},
|
||||
GncOptionUIType::STRING,
|
||||
to_ui, from_ui)};
|
||||
m_option.set_ui_item(std::move(ui_item));
|
||||
}
|
||||
GncUIType m_widget;
|
||||
GncOption m_option;
|
||||
};
|
||||
|
||||
@ -540,10 +550,24 @@ TEST_F(GncOptionUI, test_option_ui_type)
|
||||
|
||||
TEST_F(GncOptionUI, test_set_option_ui_item)
|
||||
{
|
||||
GncUIItem ui_item;
|
||||
GncOptionUIItem option_ui_item{&ui_item};
|
||||
m_option.set_ui_item(&option_ui_item);
|
||||
EXPECT_EQ(&ui_item, m_option.get_ui_item()->m_widget);
|
||||
EXPECT_EQ(&m_widget, m_option.get_ui_item()->get_ui_item().m_widget);
|
||||
}
|
||||
|
||||
TEST_F(GncOptionUI, test_ui_value_from_option)
|
||||
{
|
||||
const char* value{"waldo"};
|
||||
|
||||
m_option.set_value(value);
|
||||
m_option.set_ui_item_from_option();
|
||||
EXPECT_STREQ(value, m_widget.get_value().c_str());
|
||||
}
|
||||
|
||||
TEST_F(GncOptionUI, test_option_value_from_ui)
|
||||
{
|
||||
const char* value{"pepper"};
|
||||
m_widget.set_value(value);
|
||||
m_option.set_option_from_ui_item();
|
||||
EXPECT_STREQ(value, m_option.get_value<std::string>().c_str());
|
||||
}
|
||||
|
||||
class GncOptionRangeTest : public ::testing::Test
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <gnc-optiondb.hpp>
|
||||
#include <gnc-optiondb-impl.hpp>
|
||||
#include <gnc-option-ui.hpp>
|
||||
#include <kvp-value.hpp>
|
||||
extern "C"
|
||||
{
|
||||
@ -205,6 +206,7 @@ TEST_F(GncOptionDBTest, test_register_date_interval_option)
|
||||
ASSERT_TRUE(m_db->set_option("foo", "bar", time));
|
||||
EXPECT_EQ(time, m_db->find_option("foo", "bar")->get().get_value<time64>());
|
||||
}
|
||||
|
||||
class GncOptionDBIOTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user