From c5fac51a8b6bf316d47bd6e613efaf1f8f277e87 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 3 Oct 2019 13:30:49 -0700 Subject: [PATCH] Change the type of OptionUIItem's m_ui_item from void* to GncOptionUIItem. A locally-opaque class wrapping whatever sort of widget ptr one needs. Thanks, warlord! --- libgnucash/app-utils/gnc-option.hpp | 20 ++++++----- libgnucash/app-utils/gnc-optiondb.cpp | 5 +-- libgnucash/app-utils/gnc-optiondb.hpp | 8 ++--- .../app-utils/test/gtest-gnc-option.cpp | 12 +++++-- .../app-utils/test/gtest-gnc-optiondb.cpp | 36 ++++++++++++++----- 5 files changed, 56 insertions(+), 25 deletions(-) diff --git a/libgnucash/app-utils/gnc-option.hpp b/libgnucash/app-utils/gnc-option.hpp index 7a8032962b..e99c8a2130 100644 --- a/libgnucash/app-utils/gnc-option.hpp +++ b/libgnucash/app-utils/gnc-option.hpp @@ -125,6 +125,8 @@ struct OptionClassifier using GncMultiChoiceOptionEntry = std::pair; using GncMultiChoiceOptionChoices = std::vector; +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 @@ -140,9 +142,9 @@ class OptionUIItem { public: GncOptionUIType get_ui_type() { return m_ui_type; } - void* const get_ui_item() {return m_ui_item; } + GncOptionUIItem* const get_ui_item() {return m_ui_item; } void clear_ui_item() { m_ui_item = nullptr; } - void set_ui_item(void* ui_item) + void set_ui_item(GncOptionUIItem* ui_item) { if (m_ui_type == GncOptionUIType::INTERNAL) { @@ -169,7 +171,7 @@ protected: OptionUIItem& operator=(const OptionUIItem&) = default; OptionUIItem& operator=(OptionUIItem&&) = default; private: - void* m_ui_item; + GncOptionUIItem* m_ui_item; GncOptionUIType m_ui_type; }; @@ -359,7 +361,7 @@ public: { return boost::apply_visitor(GetDocstringVisitor(), m_option); } - void set_ui_item(void* ui_elem) + void set_ui_item(GncOptionUIItem* ui_elem) { return boost::apply_visitor(SetUIItemVisitor(ui_elem), m_option); } @@ -367,7 +369,7 @@ public: { return boost::apply_visitor(GetUITypeVisitor(), m_option); } - void* const get_ui_item() + GncOptionUIItem* const get_ui_item() { return boost::apply_visitor(GetUIItemVisitor(), m_option); } @@ -465,13 +467,13 @@ private: }; struct SetUIItemVisitor : public boost::static_visitor<> { - SetUIItemVisitor(void* ui_item) : m_ui_item{ui_item} {} + SetUIItemVisitor(GncOptionUIItem* ui_item) : m_ui_item{ui_item} {} template void operator()(OptionType& option) const { option.set_ui_item(m_ui_item); } private: - void* m_ui_item; + GncOptionUIItem* m_ui_item; }; struct GetUITypeVisitor : public boost::static_visitor @@ -482,10 +484,10 @@ private: } }; struct GetUIItemVisitor : - public boost::static_visitor + public boost::static_visitor { template - void* const operator()(OptionType& option) const { + GncOptionUIItem* const operator()(OptionType& option) const { return option.get_ui_item(); } }; diff --git a/libgnucash/app-utils/gnc-optiondb.cpp b/libgnucash/app-utils/gnc-optiondb.cpp index 250302aa8a..3dde5739e1 100644 --- a/libgnucash/app-utils/gnc-optiondb.cpp +++ b/libgnucash/app-utils/gnc-optiondb.cpp @@ -80,14 +80,15 @@ GncOptionDB::get_default_section() const noexcept } void -GncOptionDB::set_ui_item(const char* section, const char* name, void* ui_item) +GncOptionDB::set_ui_item(const char* section, const char* name, + GncOptionUIItem* ui_item) { auto option = find_option(section, name); if (!option) return; option->set_ui_item(ui_item); } -void* const +GncOptionUIItem* const GncOptionDB::get_ui_item(const char* section, const char* name) { auto option = find_option(section, name); diff --git a/libgnucash/app-utils/gnc-optiondb.hpp b/libgnucash/app-utils/gnc-optiondb.hpp index 3b723dd265..bf0cdade37 100644 --- a/libgnucash/app-utils/gnc-optiondb.hpp +++ b/libgnucash/app-utils/gnc-optiondb.hpp @@ -52,8 +52,8 @@ public: void unregister_option(const char* section, const char* name); void set_default_section(const char* section); const GncOptionSection* const get_default_section() const noexcept; - void set_ui_item(const char* section, const char* name, void* ui_item); - void* const get_ui_item(const char* section, const char* name); + void set_ui_item(const char* section, const char* name, GncOptionUIItem* ui_item); + GncOptionUIItem* const get_ui_item(const char* section, const char* name); GncOptionUIType get_ui_type(const char* section, const char* name); void set_ui_from_option(const char* section, const char* name, std::function func); @@ -74,8 +74,8 @@ private: std::vector m_sections; bool m_dirty = false; - std::function m_get_ui_value; - std::function m_set_ui_value; + std::function m_get_ui_value; + std::function m_set_ui_value; }; using GncOptionDBPtr = std::unique_ptr; diff --git a/libgnucash/app-utils/test/gtest-gnc-option.cpp b/libgnucash/app-utils/test/gtest-gnc-option.cpp index 6c3a518899..9267ba630f 100644 --- a/libgnucash/app-utils/test/gtest-gnc-option.cpp +++ b/libgnucash/app-utils/test/gtest-gnc-option.cpp @@ -202,6 +202,13 @@ private: std::string m_value; }; +class GncOptionUIItem +{ +public: + GncOptionUIItem(GncUIItem* widget) : m_widget{widget} {} + GncUIItem* m_widget; +}; + class GncOptionUITest : public ::testing::Test { protected: @@ -222,6 +229,7 @@ TEST_F(GncOptionUI, test_option_ui_type) TEST_F(GncOptionUI, test_set_option_ui_item) { GncUIItem ui_item; - m_option.set_ui_item(&ui_item); - EXPECT_EQ(&ui_item, static_cast(m_option.get_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); } diff --git a/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp b/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp index 86a8390e61..be6221f60b 100644 --- a/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp +++ b/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp @@ -78,6 +78,23 @@ private: std::string m_value; }; +class GncOptionUIItem +{ +public: + GncOptionUIItem(GncUIType* widget) : m_widget{widget} {} + GncUIType* m_widget; +}; + +class GncOptionUITest : public ::testing::Test +{ +protected: + GncOptionUITest() : + m_option{"foo", "bar", "baz", "Phony Option", std::string{"waldo"}, + GncOptionUIType::STRING} {} + + GncOption m_option; +}; + class GncOptionDBUITest : public ::testing::Test { protected: @@ -99,18 +116,20 @@ protected: TEST_F(GncOptionDBUITest, test_set_ui_item) { GncUIType entry; - m_db->set_ui_item("foo", "bar", &entry); - EXPECT_EQ(&entry, static_cast(m_db->get_ui_item("foo", "bar"))); + GncOptionUIItem ui_item(&entry); + m_db->set_ui_item("foo", "bar", &ui_item); + EXPECT_EQ(&entry, m_db->get_ui_item("foo", "bar")->m_widget); } TEST_F(GncOptionDBUITest, test_ui_value_from_option) { GncUIType entry; + GncOptionUIItem ui_item(&entry); const char* value{"waldo"}; - m_db->set_ui_item("foo", "bar", &entry); + m_db->set_ui_item("foo", "bar", &ui_item); m_db->set_ui_from_option("foo", "bar", [](GncOption& option){ - auto ui_item = static_cast(option.get_ui_item()); - ui_item->set_value(option.get_value()); + auto new_ui_item = option.get_ui_item(); + new_ui_item->m_widget->set_value(option.get_value()); }); EXPECT_STREQ(value, entry.get_value().c_str()); } @@ -118,12 +137,13 @@ TEST_F(GncOptionDBUITest, test_ui_value_from_option) TEST_F(GncOptionDBUITest, test_option_value_from_ui) { GncUIType entry; + GncOptionUIItem ui_item(&entry); const char* value{"pepper"}; - m_db->set_ui_item("foo", "bar", &entry); + m_db->set_ui_item("foo", "bar", &ui_item); entry.set_value(value); m_db->set_option_from_ui("foo", "bar", [](GncOption& option){ - auto ui_item = static_cast(option.get_ui_item()); - option.set_value(ui_item->get_value()); + auto new_ui_item = option.get_ui_item()->m_widget; + option.set_value(new_ui_item->get_value()); }); EXPECT_STREQ(value, m_db->lookup_string_option("foo", "bar").c_str()); }