diff --git a/libgnucash/app-utils/gnc-optiondb.cpp b/libgnucash/app-utils/gnc-optiondb.cpp index 0cdaf0db42..f6750b1a39 100644 --- a/libgnucash/app-utils/gnc-optiondb.cpp +++ b/libgnucash/app-utils/gnc-optiondb.cpp @@ -34,6 +34,69 @@ constexpr const char* log_module{G_LOG_DOMAIN}; constexpr auto stream_max = std::numeric_limits::max(); +using AliasedOption = std::pair; +using OptionAlias = std::pair; +using OptionAliases = std::vector; +class Aliases +{ + static const OptionAliases c_option_aliases; +public: + static const AliasedOption* find_alias (const char* old_name) + { + if (!old_name) return nullptr; + const auto alias = + std::find_if(c_option_aliases.begin(), c_option_aliases.end(), + [old_name](auto alias){ + return std::strcmp(old_name, alias.first) == 0; + }); + if (alias == c_option_aliases.end()) + { + std::cerr << "No alias for " << old_name << " found.\n"; + return nullptr; + } + std::cerr << "Found " << alias->second.second << " as alias for " << old_name << ".\n"; + return &alias->second; + } +}; + +const OptionAliases Aliases::c_option_aliases +{ + {"Accounts to include", {nullptr, "Accounts"}}, + {"Exclude transactions between selected accounts?", + {nullptr, "Exclude transactions between selected accounts"}}, + {"Filter Accounts", {nullptr, "Filter By..."}}, + {"Flatten list to depth limit?", + {nullptr, "Flatten list to depth limit"}}, + {"From", {nullptr, "Start Date"}}, + {"Report Accounts", {nullptr, "Accounts"}}, + {"Report Currency", {nullptr, "Report's currency"}}, + {"Show Account Code?", {nullptr, "Show Account Code"}}, + {"Show Full Account Name?", {nullptr, "Show Full Account Name"}}, + {"Show Multi-currency Totals?", + {nullptr, "Show Multi-currency Totals"}}, + {"Show zero balance items?", {nullptr, "Show zero balance items"}}, + {"Sign Reverses?", {nullptr, "Sign Reverses"}}, + {"To", {nullptr, "End Date"}}, + {"Charge Type", {nullptr, "Action"}}, // easy-invoice.scm, renamed June 2018 + // the following 4 options in income-gst-statement.scm renamed Dec 2018 + {"Individual income columns", {nullptr, "Individual sales columns"}}, + {"Individual expense columns", + {nullptr, "Individual purchases columns"}}, + {"Remittance amount", {nullptr, "Gross Balance"}}, + {"Net Income", {nullptr, "Net Balance"}}, + // transaction.scm: + {"Use Full Account Name?", {nullptr, "Use Full Account Name"}}, + {"Use Full Other Account Name?", + {nullptr, "Use Full Other Account Name"}}, + {"Void Transactions?", {"Filter", "Void Transactions"}}, + {"Void Transactions", {"Filter", "Void Transactions"}}, + {"Account Substring", {"Filter", "Account Name Filter"}}, + {"Enable links", {nullptr, "Enable Links"}}, + // invoice.scm, renamed November 2018 + {"Individual Taxes", {nullptr, "Use Detailed Tax Summary"}}, + // income-gst-statement.scm + {"default format", {nullptr, "Default Format"}} +}; static bool operator==(const std::string& str, const char* cstr) @@ -76,7 +139,13 @@ GncOptionSection::find_option(const char* name) const [name](auto& option) -> bool { return option.get_name() == name; }); - return (option == m_options.end() ? nullptr : &*option); + if (option != m_options.end()) + return &*option; + + auto alias = Aliases::find_alias(name); + if (!alias || alias->first) // No alias or the alias + return nullptr; // is in a different section. + return find_option(alias->second); } GncOptionDB::GncOptionDB() : m_default_section{} {} @@ -133,9 +202,19 @@ const GncOption* GncOptionDB::find_option(const std::string& section, const char* name) const { auto db_section = const_cast(this)->find_section(section); - if (!db_section) + const GncOption* option = nullptr; + if (db_section) + option = db_section->find_option(name); + if (option) + return option; + auto alias = Aliases::find_alias(name); + /* Only try again if alias.first isn't + * nullptr. GncOptionSection::find_option already checked if the alias + * should have been in the same section. + */ + if (alias && alias->first) + return find_option(alias->first, alias->second); return nullptr; - return db_section->find_option(name); } std::string diff --git a/libgnucash/app-utils/gnc-optiondb.i b/libgnucash/app-utils/gnc-optiondb.i index a698fb5745..7ccc7214e0 100644 --- a/libgnucash/app-utils/gnc-optiondb.i +++ b/libgnucash/app-utils/gnc-optiondb.i @@ -446,6 +446,13 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); auto db_ptr{std::make_unique()}; return db_ptr; } + + GncOption* + gnc_lookup_option(const GncOptionDBPtr& optiondb, const char* section, + const char* name) + { + return optiondb->find_option(section, name); + } %} #endif //SWIGGUILE diff --git a/libgnucash/app-utils/test/test-options.scm b/libgnucash/app-utils/test/test-options.scm index 27b970692d..f7e55eeb3c 100644 --- a/libgnucash/app-utils/test/test-options.scm +++ b/libgnucash/app-utils/test/test-options.scm @@ -1,4 +1,9 @@ -(use-modules (gnucash app-utils)) +;;(use-modules (gnucash app-utils)) +;; Load the C++ option implementation, avoiding the options.scm ones. +(eval-when + (compile load eval expand) + (load-extension "libgnc-app-utils" "scm_init_sw_app_utils_module")) +(use-modules (sw_app_utils)) (use-modules (srfi srfi-64)) (use-modules (tests srfi64-extras)) @@ -9,19 +14,17 @@ (test-end "test-options")) (define (test-lookup-option) - (let ((options (gnc:new-options))) - (gnc:register-option - options - (gnc:make-simple-boolean-option - "Section" "Start Date" "sort-tag" "docstring" 'default-val)) + (let* ((options (new-gnc-optiondb)) + (string-opt (gnc-register-string-option (GncOptionDBPtr-get options) + "Section" "Start Date" + "sort-tag" "docstring" "waldo") + )) - (gnc:register-option - options - (gnc:make-simple-boolean-option - "Filter" "Void Transactions" "sort-tag" "docstring" 'default-val)) - - (test-assert "lookup-option changed name" - (gnc:lookup-option options "Section" "From")) - - (test-assert "lookup-option changed section and name" - (gnc:lookup-option options "Section" "Void Transactions?")))) + (gnc-register-simple-boolean-option + (GncOptionDBPtr-get options) + "Filter" "Void Transactions" "sort-tag" "docstring" 'default-val) + ;; Testing that the old option name aliases work. + (let ((option (gnc-lookup-option options "Section" "From"))) + (test-assert "lookup-option changed name" option)) + (let ((option (gnc-lookup-option options "Section" "Void Transactions?"))) + (test-assert "lookup-option changed section and name" option))))