/********************************************************************\ * gnc-option.cpp -- Application options system * * Copyright (C) 2020 John Ralls * * * * 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 * * * \********************************************************************/ #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 } template , int>> GncOption::GncOption(const char* section, const char* name, const char* key, const char* doc_string, ValueType value, GncOptionUIType ui_type) : m_option{std::make_unique( std::in_place_type>, section, name, key, doc_string, value, ui_type)} { } template ValueType GncOption::get_value() const { return std::visit( [](const auto option)->ValueType { if constexpr (is_same_decayed_v) return option.get_value(); if constexpr (is_same_decayed_v) { if constexpr (is_same_decayed_v) return option.get_period(); if constexpr (std::is_same_v) return option.get_period_index(); return ValueType{}; } if constexpr (is_same_decayed_v) { if constexpr (std::is_same_v) return option.get_index(); if constexpr (is_same_decayed_v) return option.get_multiple(); } return ValueType {}; }, *m_option); } template ValueType GncOption::get_default_value() const { return std::visit( [](const auto option)->ValueType { if constexpr (is_same_decayed_v) return option.get_default_value(); if constexpr (is_same_decayed_v) { if constexpr (is_same_decayed_v) return option.get_default_period(); if constexpr (std::is_same_v) return option.get_default_period_index(); return ValueType{}; } if constexpr (is_same_decayed_v && is_same_decayed_v) return option.get_default_multiple(); return ValueType {}; }, *m_option); } template void GncOption::set_value(ValueType value) { std::visit( [value](auto& option) { if constexpr (is_same_decayed_v || (is_same_decayed_v && (is_same_decayed_v || std::is_same_v))) option.set_value(value); if constexpr (is_same_decayed_v) { if constexpr (is_same_decayed_v) option.set_multiple(value); else if constexpr (std::is_same_v || is_same_decayed_v || std::is_same_v, char*>) option.set_value(value); } }, *m_option); } template void GncOption::set_default_value(ValueType value) { std::visit( [value](auto& option) { if constexpr (is_same_decayed_v|| (is_same_decayed_v && (is_same_decayed_v || std::is_same_v))) option.set_default_value(value); if constexpr (is_same_decayed_v) { if constexpr (is_same_decayed_v) option.set_default_multiple(value); else if constexpr (std::is_same_v || is_same_decayed_v || std::is_same_v, char*>) option.set_default_value(value); } }, *m_option); } void GncOption::reset_default_value() { std::visit([](auto& option) { option.reset_default_value(); }, *m_option); } template void GncOption::get_limits(ValueType& max, ValueType& min, ValueType& step) const noexcept { std::visit([&max, &min, &step](const auto& option) { if constexpr (is_same_decayed_v>) option.get_limits(max, min, step); }, *m_option); } const std::string& GncOption::get_section() const { return std::visit([](const auto& option)->const std::string& { return option.m_section; }, *m_option); } const std::string& GncOption::get_name() const { return std::visit([](const auto& option)->const std::string& { return option.m_name; }, *m_option); } const std::string& GncOption::get_key() const { return std::visit([](const auto& option)->const std::string& { return option.m_sort_tag; }, *m_option); } const std::string& GncOption::get_docstring() const { return std::visit([](const auto& option)->const std::string& { return option.m_doc_string; }, *m_option); } void GncOption::set_ui_item(GncOptionUIItemPtr&& ui_item) { 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); } void GncOption::set_ui_item_selectable(bool selectable) const noexcept { if (m_ui_item) m_ui_item->set_selectable(selectable); } const GncOptionUIType GncOption::get_ui_type() const { return std::visit([](const auto& option)->GncOptionUIType { return option.get_ui_type(); }, *m_option); } GncOptionUIItem* const GncOption::get_ui_item() const { 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); } bool GncOption::is_changed() const noexcept { return std::visit([](const auto& option)->bool { return option.is_changed(); }, *m_option); } bool GncOption::is_multiselect() const noexcept { return std::visit( [](const auto& option)->bool { if constexpr (is_same_decayed_v) return option.is_multiselect(); else return false; }, *m_option); } template bool GncOption::validate(ValueType value) const { return std::visit( [value] (const auto& option) -> bool { if constexpr ((is_same_decayed_v && is_same_decayed_v) || (is_same_decayed_v && is_same_decayed_v) || (is_same_decayed_v && is_same_decayed_v)) return option.validate(value); else return false; }, *m_option); } std::size_t GncOption::num_permissible_values() const { return std::visit( [] (const auto& option) -> size_t { if constexpr (is_same_decayed_v || is_same_decayed_v) return option.num_permissible_values(); else return size_t_max; }, *m_option); } std::size_t GncOption::permissible_value_index(const char* value) const { return std::visit( [&value] (const auto& option) -> size_t { if constexpr (is_same_decayed_v || is_same_decayed_v) return option.permissible_value_index(value); else return size_t_max; }, *m_option); } const char* GncOption::permissible_value(std::size_t index) const { return std::visit([index] (const auto& option) -> const char* { if constexpr (std::is_same_v, GncOptionMultichoiceValue> || std::is_same_v, GncOptionDateValue>) return option.permissible_value(index); else return ""; }, *m_option); } const char* GncOption::permissible_value_name(std::size_t index) const { return std::visit([index] (const auto& option) -> const char* { if constexpr (std::is_same_v, GncOptionMultichoiceValue> || std::is_same_v, GncOptionDateValue>) return option.permissible_value_name(index); else return ""; }, *m_option); } GList* GncOption::account_type_list() const noexcept { return std::visit([] (const auto& option) -> GList* { if constexpr (std::is_same_v, GncOptionAccountListValue>) return option.account_type_list(); else return nullptr; }, *m_option); } bool GncOption::is_alternate() const noexcept { return std::visit([](auto& option) -> bool { if constexpr(is_RangeValue_v) return option.is_alternate(); return false; }, *m_option); } void GncOption::set_alternate(bool alt) noexcept { std::visit([alt](auto& option) { if constexpr(is_RangeValue_v) option.set_alternate(alt); }, *m_option); } std::string GncOption::serialize() const { if (m_option->valueless_by_exception()) return "Valueless Option"; return std::visit([&](auto& option) -> std::string { return option.serialize(); }, *m_option); } bool GncOption::deserialize(const std::string& str) { return std::visit([&str](auto& option) -> bool { return option.deserialize(str); }, *m_option); } std::istream& GncOption::in_stream(std::istream& iss) { return std::visit([&iss](auto& option) -> std::istream& { iss >> option; return iss; }, *m_option); } /* We must instantiate all of the templates we need here because we don't expose * the template implementation in the public header. */ template GncOption::GncOption(const char*, const char*, const char*, const char*, bool, GncOptionUIType); //template GncOption::GncOption(const char*, const char*, const char*, // const char*, int, GncOptionUIType); template GncOption::GncOption(const char*, const char*, const char*, const char*, int64_t, GncOptionUIType); //template GncOption::GncOption(const char*, const char*, const char*, // const char*, const char*, GncOptionUIType); //template GncOption::GncOption(const char*, const char*, const char*, // const char*, double, GncOptionUIType); template GncOption::GncOption(const char*, const char*, const char*, const char*, std::string, GncOptionUIType); template GncOption::GncOption(const char*, const char*, const char*, const char*, const QofQuery*, GncOptionUIType); template GncOption::GncOption(const char*, const char*, const char*, const char*, const GncOwner*, GncOptionUIType); template bool GncOption::get_value() const; template int GncOption::get_value() const; template int64_t GncOption::get_value() const; template double GncOption::get_value() const; template size_t GncOption::get_value() const; template const char* GncOption::get_value() const; template std::string GncOption::get_value() const; template const QofInstance* GncOption::get_value() const; template gnc_commodity* GncOption::get_value() const; template const Account* GncOption::get_value() const; template RelativeDatePeriod GncOption::get_value() const; template GncOptionAccountList GncOption::get_value() const; template GncMultichoiceOptionIndexVec GncOption::get_value() const; template GncOptionReportPlacementVec GncOption::get_value() const; template bool GncOption::get_default_value() const; template int GncOption::get_default_value() const; template int64_t GncOption::get_default_value() const; template double GncOption::get_default_value() const; template const char* GncOption::get_default_value() const; template std::string GncOption::get_default_value() const; template const QofInstance* GncOption::get_default_value() const; template gnc_commodity* GncOption::get_default_value() const; template const Account* GncOption::get_default_value() const; template RelativeDatePeriod GncOption::get_default_value() const; template GncOptionAccountList GncOption::get_default_value() const; template GncMultichoiceOptionIndexVec GncOption::get_default_value() const; template GncOptionReportPlacementVec GncOption::get_default_value() const; template void GncOption::set_value(bool); template void GncOption::set_value(int); template void GncOption::set_value(int64_t); template void GncOption::set_value(double); template void GncOption::set_value(char*); template void GncOption::set_value(const char*); template void GncOption::set_value(std::string); template void GncOption::set_value(const QofInstance*); template void GncOption::set_value(gnc_commodity*); template void GncOption::set_value(const Account*); template void GncOption::set_value(RelativeDatePeriod); template void GncOption::set_value(size_t); template void GncOption::set_value(GncOptionAccountList); template void GncOption::set_value(GncMultichoiceOptionIndexVec); template void GncOption::set_value(GncOptionReportPlacementVec); 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(const Account*); 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(GncOptionReportPlacementVec); 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; template bool GncOption::validate(int) const; template bool GncOption::validate(int64_t) const; template bool GncOption::validate(double) const; template bool GncOption::validate(const char*) const; template bool GncOption::validate(std::string) const; template bool GncOption::validate(const QofInstance*) const; template bool GncOption::validate(gnc_commodity*) const; template bool GncOption::validate(const Account*) const; template bool GncOption::validate(const QofQuery*) const; template bool GncOption::validate(RelativeDatePeriod) const; template bool GncOption::validate(GncMultichoiceOptionIndexVec) const; template bool GncOption::validate(GncOptionReportPlacementVec) const; template GncOption* gnc_make_option(const char*, const char*, const char*, const char*, const std::string&, GncOptionUIType); template GncOption* gnc_make_option(const char*, const char*, const char*, const char*, bool, GncOptionUIType); template GncOption* gnc_make_option(const char*, const char*, const char*, const char*, int64_t, GncOptionUIType);