diff --git a/libgnucash/engine/CMakeLists.txt b/libgnucash/engine/CMakeLists.txt index 8dde8461bc..b9d11b8779 100644 --- a/libgnucash/engine/CMakeLists.txt +++ b/libgnucash/engine/CMakeLists.txt @@ -93,6 +93,7 @@ set (engine_HEADERS qof-backend.hpp qofbackend.h qofbook.h + qofbook.hpp qofbookslots.h qofchoice.h qofclass.h @@ -145,7 +146,7 @@ set (engine_SOURCES gnc-datetime.cpp gnc-engine.c gnc-event.c - gnc-features.c + gnc-features.cpp gnc-hooks.c gnc-int128.cpp gnc-lot.c diff --git a/libgnucash/engine/gnc-features.c b/libgnucash/engine/gnc-features.cpp similarity index 53% rename from libgnucash/engine/gnc-features.c rename to libgnucash/engine/gnc-features.cpp index f710677d2b..5e2823a3c3 100644 --- a/libgnucash/engine/gnc-features.c +++ b/libgnucash/engine/gnc-features.cpp @@ -19,28 +19,22 @@ * * \********************************************************************/ +#include +#include +#include + #include #include #include -#include -#include -#include -#include -#include +#include "qofbook.hpp" -#include "qof.h" -#include "gnc-features.h" -#include "gnc-glib-utils.h" - -typedef struct +extern "C" { - const gchar *key; - const gchar *desc; -} gncFeature; +#include "gnc-features.h" +} -static GHashTable *features_table = NULL; -static gncFeature known_features[] = +static const FeaturesTable features_table { { GNC_FEATURE_CREDIT_NOTES, "Customer and vendor credit notes (requires at least GnuCash 2.5.0)" }, { GNC_FEATURE_NUM_FIELD_SOURCE, "User specifies source of 'num' field'; either transaction number or split action (requires at least GnuCash 2.5.0)" }, @@ -53,7 +47,6 @@ static gncFeature known_features[] = { GNC_FEATURE_BUDGET_UNREVERSED, "Store budget amounts unreversed (i.e. natural) signs (requires at least Gnucash 3.8)"}, { GNC_FEATURE_BUDGET_SHOW_EXTRA_ACCOUNT_COLS, "Show extra account columns in the Budget View (requires at least Gnucash 3.8)"}, { GNC_FEATURE_EQUITY_TYPE_OPENING_BALANCE, GNC_FEATURE_EQUITY_TYPE_OPENING_BALANCE " (requires at least Gnucash 4.3)" }, - { NULL }, }; /* This static indicates the debugging module that this .o belongs to. */ @@ -62,40 +55,11 @@ static QofLogModule log_module = G_LOG_DOMAIN; /********************************************************************\ \********************************************************************/ -static void gnc_features_init () -{ - gint i; - - if (features_table) - return; - - features_table = g_hash_table_new (g_str_hash, g_str_equal); - for (i = 0; known_features[i].key; i++) - g_hash_table_insert (features_table, - g_strdup (known_features[i].key), - g_strdup (known_features[i].desc)); -} - -static void gnc_features_test_one(gpointer pkey, gpointer value, - gpointer data) -{ - const gchar *key = (const gchar*)pkey; - const gchar *feature_desc = (const gchar*)value; - GList **unknown_features; - - g_assert(data); - unknown_features = (GList**) data; - - /* Check if this feature is in the known features list. */ - if (g_hash_table_lookup_extended (features_table, key, NULL, NULL)) - return; - - /* It is unknown, so add the description to the unknown features list: */ - g_assert(feature_desc); - - *unknown_features = g_list_prepend(*unknown_features, - (gpointer)feature_desc); -} +static const char* +header = N_("This Dataset contains features not supported " + "by this version of GnuCash. You must use a " + "newer version of GnuCash in order to support " + "the following features:"); /* Check if the session requires features unknown to this version of GnuCash. * @@ -104,78 +68,31 @@ static void gnc_features_test_one(gpointer pkey, gpointer value, */ gchar *gnc_features_test_unknown (QofBook *book) { - - GList* features_list = NULL; - GHashTable *features_used = qof_book_get_features (book); - - /* Setup the known_features hash table */ - gnc_features_init(); - - /* Iterate over the members of this frame for unknown features */ - g_hash_table_foreach (features_used, &gnc_features_test_one, - &features_list); - if (features_list) - { - const char* sep = "\n* "; - const char* header = _("This Dataset contains features not supported " - "by this version of GnuCash. You must use a " - "newer version of GnuCash in order to support " - "the following features:"); - - char *features_str = gnc_g_list_stringjoin (features_list, sep); - char *msg = g_strconcat (header, sep, features_str, NULL); - g_free (features_str); - g_list_free(features_list); - return msg; - } - g_hash_table_unref (features_used); - return NULL; + auto unknowns {qof_book_get_unknown_features (book, features_table)}; + auto accum = [](const auto& a, const auto& b){ return a + "\n* " + b; }; + return unknowns.empty() ? nullptr : + g_strdup (std::accumulate (unknowns.begin(), unknowns.end(), + std::string (_(header)), accum).c_str()); } void gnc_features_set_used (QofBook *book, const gchar *feature) { - const gchar *description; - g_return_if_fail (book); g_return_if_fail (feature); - gnc_features_init(); - /* Can't set an unknown feature */ - description = g_hash_table_lookup (features_table, feature); - if (!description) + auto iter = features_table.find (feature); + if (iter == features_table.end ()) { PWARN("Tried to set unknown feature as used."); return; } - qof_book_set_feature (book, feature, description); -} - -struct CheckFeature -{ - gchar const * checked_feature; - gboolean found; -}; - -static void gnc_features_check_feature_cb (gpointer pkey, gpointer value, - gpointer data) -{ - const gchar *key = (const gchar*)pkey; - struct CheckFeature * check_data = data; - g_assert(data); - if (!g_strcmp0 (key, check_data->checked_feature)) - check_data->found = TRUE; + qof_book_set_feature (book, feature, iter->second.c_str()); } gboolean gnc_features_check_used (QofBook *book, const gchar * feature) { - GHashTable *features_used = qof_book_get_features (book); - struct CheckFeature check_data = {feature, FALSE}; - /* Setup the known_features hash table */ - gnc_features_init(); - g_hash_table_foreach (features_used, &gnc_features_check_feature_cb, &check_data); - g_hash_table_unref (features_used); - return check_data.found; + return qof_book_test_feature (book, feature); } diff --git a/libgnucash/engine/qofbook.cpp b/libgnucash/engine/qofbook.cpp index ab2b012319..da4e2c843a 100644 --- a/libgnucash/engine/qofbook.cpp +++ b/libgnucash/engine/qofbook.cpp @@ -61,6 +61,8 @@ extern "C" // For GNC_ID_ROOT_ACCOUNT: #include "AccountP.h" +#include "qofbook.hpp" + static QofLogModule log_module = QOF_MOD_ENGINE; #define AB_KEY "hbci" #define AB_TEMPLATES "template-list" @@ -1255,6 +1257,32 @@ qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr) } } +std::vector +qof_book_get_unknown_features (QofBook *book, const FeaturesTable& features) +{ + std::vector rv; + auto test_feature = [&](const KvpFrameImpl::map_type::value_type& feature) + { + if (features.find (feature.first) == features.end ()) + rv.push_back (feature.second->get()); + }; + auto frame = qof_instance_get_slots (QOF_INSTANCE (book)); + auto slot = frame->get_slot({GNC_FEATURES}); + if (slot != nullptr) + { + frame = slot->get(); + std::for_each (frame->begin (), frame->end (), test_feature); + } + return rv; +} + +bool +qof_book_test_feature (QofBook *book, const char *feature) +{ + auto frame = qof_instance_get_slots (QOF_INSTANCE (book)); + return (frame->get_slot({GNC_FEATURES, feature}) != nullptr); +} + void qof_book_load_options (QofBook *book, GNCOptionLoad load_cb, GNCOptionDB *odb) { diff --git a/libgnucash/engine/qofbook.hpp b/libgnucash/engine/qofbook.hpp new file mode 100644 index 0000000000..402de17119 --- /dev/null +++ b/libgnucash/engine/qofbook.hpp @@ -0,0 +1,36 @@ +/********************************************************************\ + * 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 __QOF_BOOK__HPP__ +#define __QOF_BOOK__HPP__ + +#include +#include +#include + +#include "qof.h" + +using FeaturesTable = std::unordered_map; + +std::vector +qof_book_get_unknown_features (QofBook *book, const FeaturesTable& features); +bool qof_book_test_feature (QofBook*, const char*); + +#endif /* QOF_BOOK_HPP */ diff --git a/po/POTFILES.in b/po/POTFILES.in index 6c9be8e2c2..3d2a0e7b38 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -641,7 +641,7 @@ libgnucash/engine/gncEmployee.c libgnucash/engine/gnc-engine.c libgnucash/engine/gncEntry.c libgnucash/engine/gnc-event.c -libgnucash/engine/gnc-features.c +libgnucash/engine/gnc-features.cpp libgnucash/engine/gnc-hooks.c libgnucash/engine/gncIDSearch.c libgnucash/engine/gnc-int128.cpp