diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp index fb514ba6931..d3f547359d1 100644 --- a/libgnucash/engine/Account.cpp +++ b/libgnucash/engine/Account.cpp @@ -327,10 +327,6 @@ gnc_account_init(Account* acc) priv->starting_reconciled_balance = gnc_numeric_zero(); priv->balance_dirty = FALSE; - priv->higher_balance_limit = {}; - priv->lower_balance_limit = {}; - priv->include_sub_account_balances = {}; - new (&priv->children) AccountVec (); new (&priv->splits) SplitsVec (); priv->splits_hash = g_hash_table_new (g_direct_hash, g_direct_equal); @@ -2481,73 +2477,118 @@ xaccAccountSetDescription (Account *acc, const char *str) xaccAccountCommitEdit(acc); } +static void +set_kvp_gnc_numeric_path (Account *acc, const std::vector& path, + std::optional value) +{ + xaccAccountBeginEdit(acc); + qof_instance_set_path_kvp (QOF_INSTANCE(acc), value, path); + xaccAccountCommitEdit(acc); +} + +static std::optional +get_kvp_gnc_numeric_path (const Account *acc, const Path& path) +{ + return qof_instance_get_path_kvp (QOF_INSTANCE(acc), path); +} + static void set_kvp_string_path (Account *acc, std::vector const & path, const char *value) { - g_return_if_fail(GNC_IS_ACCOUNT(acc)); + std::optional val; + if (value && *value) + val = g_strdup(value); xaccAccountBeginEdit(acc); - if (value && *value) - { - GValue v = G_VALUE_INIT; - g_value_init (&v, G_TYPE_STRING); - g_value_set_static_string (&v, value); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path); - g_value_unset (&v); - } - else - { - qof_instance_set_path_kvp (QOF_INSTANCE (acc), nullptr, path); - } - mark_account (acc); + qof_instance_set_path_kvp (QOF_INSTANCE(acc), val, path); xaccAccountCommitEdit(acc); } +static const char* +get_kvp_string_path (const Account *acc, const Path& path) +{ + auto rv{qof_instance_get_path_kvp (QOF_INSTANCE(acc), path)}; + return rv ? *rv : nullptr; +} + static void -set_kvp_string_tag (Account *acc, const char *tag, const char *value) +set_kvp_account_path (Account* acc, const Path& path, const Account* kvp_account) { - set_kvp_string_path (acc, {tag}, value); + std::optional val; + if (kvp_account) + val = guid_copy(xaccAccountGetGUID (kvp_account)); + + xaccAccountBeginEdit(acc); + qof_instance_set_path_kvp (QOF_INSTANCE(acc), val, path); + xaccAccountCommitEdit(acc); } -static const char* -get_kvp_string_path (const Account *acc, std::vector const & path, - GValue *v) +static Account* +get_kvp_account_path (const Account *acc, const Path& path) { - *v = G_VALUE_INIT; - if (acc == nullptr) return nullptr; // how to check path is valid?? - qof_instance_get_path_kvp (QOF_INSTANCE (acc), v, path); - return G_VALUE_HOLDS_STRING (v) ? g_value_get_string (v) : nullptr; + auto val{qof_instance_get_path_kvp (QOF_INSTANCE(acc), path)}; + return val ? xaccAccountLookup (*val, gnc_account_get_book (acc)) : nullptr; } -static const char* -get_kvp_string_tag (const Account *acc, const char *tag, GValue *v) +static void +set_kvp_boolean_path (Account *acc, const Path& path, gboolean option) { - return get_kvp_string_path (acc, {tag}, v); + set_kvp_string_path (acc, path, option ? "true" : nullptr); +} + +static gboolean +get_kvp_boolean_path (const Account *acc, const Path& path) +{ + auto slot{QOF_INSTANCE(acc)->kvp_data->get_slot(path)}; + if (!slot) return false; + switch (slot->get_type()) + { + case KvpValueImpl::Type::INT64: + return slot->get() != 0; + case KvpValueImpl::Type::STRING: + return g_strcmp0 (slot->get(), "true") == 0; + default: + return false; + } +} + +static void +set_kvp_int64_path (Account *acc, const Path& path, std::optional value) +{ + xaccAccountBeginEdit(acc); + qof_instance_set_path_kvp (QOF_INSTANCE(acc), value, path); + xaccAccountCommitEdit(acc); +} + +static const std::optional +get_kvp_int64_path (const Account *acc, const Path& path) +{ + return qof_instance_get_path_kvp (QOF_INSTANCE(acc), path); } void xaccAccountSetColor (Account *acc, const char *str) { - set_kvp_string_tag (acc, "color", str); + set_kvp_string_path (acc, {"color"}, str); } void xaccAccountSetFilter (Account *acc, const char *str) { - set_kvp_string_tag (acc, "filter", str); + set_kvp_string_path (acc, {"filter"}, str); } void xaccAccountSetSortOrder (Account *acc, const char *str) { - set_kvp_string_tag (acc, "sort-order", str); + set_kvp_string_path (acc, {"sort-order"}, str); } void xaccAccountSetSortReversed (Account *acc, gboolean sortreversed) { - set_kvp_string_tag (acc, "sort-reversed", sortreversed ? "true" : nullptr); + set_kvp_boolean_path (acc, {"sort-reversed"}, sortreversed); } static void @@ -2571,7 +2612,7 @@ qofAccountSetParent (Account *acc, QofInstance *parent) void xaccAccountSetNotes (Account *acc, const char *str) { - set_kvp_string_tag (acc, "notes", str); + set_kvp_string_path (acc, {"notes"}, str); } @@ -2581,25 +2622,7 @@ xaccAccountSetAssociatedAccount (Account *acc, const char *tag, const Account* a g_return_if_fail (GNC_IS_ACCOUNT(acc)); g_return_if_fail (tag && *tag); - std::vector path = { "associated-account", tag }; - xaccAccountBeginEdit(acc); - - PINFO ("setting %s assoc %s account = %s", xaccAccountGetName (acc), tag, - assoc_acct ? xaccAccountGetName (assoc_acct) : nullptr); - - if (GNC_IS_ACCOUNT(assoc_acct)) - { - GValue v = G_VALUE_INIT; - g_value_init (&v, GNC_TYPE_GUID); - g_value_set_static_boxed (&v, xaccAccountGetGUID (assoc_acct)); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path); - g_value_unset (&v); - } - else - qof_instance_set_path_kvp (QOF_INSTANCE (acc), nullptr, path); - - mark_account (acc); - xaccAccountCommitEdit(acc); + set_kvp_account_path (acc, {"associated-account", tag}, assoc_acct); } void @@ -2712,29 +2735,17 @@ xaccAccountGetNonStdSCU (const Account * acc) void DxaccAccountSetCurrency (Account * acc, gnc_commodity * currency) { - QofBook *book; - GValue v = G_VALUE_INIT; - const char *s = gnc_commodity_get_unique_name (currency); - gnc_commodity *commodity; - gnc_commodity_table *table; - if ((!acc) || (!currency)) return; - g_value_init (&v, G_TYPE_STRING); - g_value_set_static_string (&v, s); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {"old-currency"}); - mark_account (acc); - xaccAccountCommitEdit(acc); - g_value_unset (&v); - table = gnc_commodity_table_get_table (qof_instance_get_book(acc)); - commodity = gnc_commodity_table_lookup_unique (table, s); + auto s = gnc_commodity_get_unique_name (currency); + set_kvp_string_path (acc, {"old-currency"}, s); + + auto book = qof_instance_get_book(acc); + auto table = gnc_commodity_table_get_table (book); + auto commodity = gnc_commodity_table_lookup_unique (table, s); if (!commodity) - { - book = qof_instance_get_book(acc); - gnc_commodity_table_insert (gnc_commodity_table_get_table (book), - currency); - } + gnc_commodity_table_insert (table, currency); } /********************************************************************\ @@ -2881,16 +2892,10 @@ gnc_account_get_parent (const Account *acc) Account * gnc_account_get_root (Account *acc) { - AccountPrivate *priv; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr); - priv = GET_PRIVATE(acc); - while (priv->parent) - { - acc = priv->parent; - priv = GET_PRIVATE(acc); - } + while (auto parent = gnc_account_get_parent (acc)) + acc = parent; return acc; } @@ -3302,95 +3307,52 @@ xaccAccountGetDescription (const Account *acc) const char * xaccAccountGetColor (const Account *acc) { - GValue v = G_VALUE_INIT; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr); - auto rv = get_kvp_string_tag (acc, "color", &v); - g_value_unset (&v); - return rv; + return get_kvp_string_path (acc, {"color"}); } const char * xaccAccountGetFilter (const Account *acc) { - GValue v = G_VALUE_INIT; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0); - auto rv = get_kvp_string_tag (acc, "filter", &v); - g_value_unset (&v); - return rv; + return get_kvp_string_path (acc, {"filter"}); } const char * xaccAccountGetSortOrder (const Account *acc) { - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0); - GValue v = G_VALUE_INIT; - auto rv = get_kvp_string_tag (acc, "sort-order", &v); - g_value_unset (&v); - return rv; + return get_kvp_string_path (acc, {"sort-order"}); } gboolean xaccAccountGetSortReversed (const Account *acc) { - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - GValue v = G_VALUE_INIT; - auto rv = !g_strcmp0 (get_kvp_string_tag (acc, "sort-reversed", &v), "true"); - g_value_unset (&v); - return rv; + return get_kvp_boolean_path (acc, {"sort-reversed"}); } const char * xaccAccountGetNotes (const Account *acc) { - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr); - GValue v = G_VALUE_INIT; - auto rv = get_kvp_string_tag (acc, "notes", &v); - g_value_unset (&v); - return rv; + return get_kvp_string_path (acc, {"notes"}); } Account* xaccAccountGetAssociatedAccount (const Account *acc, const char *tag) { - g_return_val_if_fail (GNC_IS_ACCOUNT(acc), nullptr); g_return_val_if_fail (tag && *tag, nullptr); - GValue v = G_VALUE_INIT; - qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, { "associated-account", tag }); - - auto guid = static_cast(G_VALUE_HOLDS_BOXED (&v) ? g_value_get_boxed(&v) : nullptr); - g_value_unset (&v); - - if (!guid) - return nullptr; - - auto assoc_acct = xaccAccountLookup (guid, gnc_account_get_book (acc)); - PINFO ("retuning %s assoc %s account = %s", xaccAccountGetName (acc), tag, - xaccAccountGetName (assoc_acct)); - return assoc_acct; + return get_kvp_account_path (acc, {"associated-account", tag}); } gnc_commodity * DxaccAccountGetCurrency (const Account *acc) { - GValue v = G_VALUE_INIT; - const char *s = nullptr; - gnc_commodity_table *table; - gnc_commodity *retval = nullptr; - - if (!acc) return nullptr; - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {"old-currency"}); - if (G_VALUE_HOLDS_STRING (&v)) - s = g_value_get_string (&v); - if (s) + if (auto s = get_kvp_string_path (acc, {"old-currency"})) { - table = gnc_commodity_table_get_table (qof_instance_get_book(acc)); - retval = gnc_commodity_table_lookup_unique (table, s); + auto table = gnc_commodity_table_get_table (qof_instance_get_book(acc)); + return gnc_commodity_table_lookup_unique (table, s); } - g_value_unset (&v); - return retval; + return nullptr; } gnc_commodity * @@ -3403,34 +3365,12 @@ xaccAccountGetCommodity (const Account *acc) gnc_commodity * gnc_account_get_currency_or_parent(const Account* account) { - gnc_commodity * commodity; - g_return_val_if_fail (account, nullptr); + g_return_val_if_fail (GNC_IS_ACCOUNT (account), nullptr); + + for (auto acc = account; acc; acc = gnc_account_get_parent (acc)) + if (auto comm = xaccAccountGetCommodity (acc); gnc_commodity_is_currency (comm)) + return comm; - commodity = xaccAccountGetCommodity (account); - if (gnc_commodity_is_currency(commodity)) - return commodity; - else - { - const Account *parent_account = account; - /* Account commodity is not a currency, walk up the tree until - * we find a parent account that is a currency account and use - * it's currency. - */ - do - { - parent_account = gnc_account_get_parent (parent_account); - if (parent_account) - { - commodity = xaccAccountGetCommodity (parent_account); - if (gnc_commodity_is_currency(commodity)) - { - return commodity; - //break; - } - } - } - while (parent_account); - } return nullptr; // no suitable commodity found. } @@ -3944,7 +3884,8 @@ xaccAccountGetNoclosingBalanceChangeInCurrencyForPeriod (Account *acc, time64 t1 const SplitsVec xaccAccountGetSplits (const Account *account) { - return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits : SplitsVec{}; + g_return_val_if_fail (GNC_IS_ACCOUNT(account), SplitsVec{}); + return GET_PRIVATE(account)->splits; } SplitList * @@ -3959,6 +3900,7 @@ xaccAccountGetSplitList (const Account *acc) size_t xaccAccountGetSplitsSize (const Account *account) { + g_return_val_if_fail (GNC_IS_ACCOUNT(account), 0); return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits.size() : 0; } @@ -4016,52 +3958,16 @@ gpointer xaccAccountForEachLot(const Account *acc, gpointer (*proc)(GNCLot *lot, void *data), void *data) { - AccountPrivate *priv; - LotList *node; - gpointer result = nullptr; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr); g_return_val_if_fail(proc, nullptr); - priv = GET_PRIVATE(acc); - for (node = priv->lots; node; node = node->next) - if ((result = proc((GNCLot *)node->data, data))) - break; - - return result; -} - -static void -set_boolean_key (Account *acc, std::vector const & path, gboolean option) -{ - GValue v = G_VALUE_INIT; - g_return_if_fail(GNC_IS_ACCOUNT(acc)); + for (auto node = GET_PRIVATE(acc)->lots; node; node = node->next) + if (auto result = proc(GNC_LOT(node->data), data)) + return result; - g_value_init (&v, G_TYPE_BOOLEAN); - g_value_set_boolean (&v, option); - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path); - mark_account (acc); - xaccAccountCommitEdit (acc); - g_value_unset (&v); + return nullptr; } -static gboolean -boolean_from_key (const Account *acc, std::vector const & path) -{ - GValue v = G_VALUE_INIT; - gboolean retval = FALSE; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, path); - if (G_VALUE_HOLDS_INT64 (&v)) - retval = (g_value_get_int64 (&v) != 0); - if (G_VALUE_HOLDS_BOOLEAN (&v)) - retval = (g_value_get_boolean (&v)); - if (G_VALUE_HOLDS_STRING (&v)) - retval = !strcmp (g_value_get_string (&v), "true"); - g_value_unset (&v); - return retval; -} /********************************************************************\ \********************************************************************/ @@ -4070,22 +3976,19 @@ boolean_from_key (const Account *acc, std::vector const & path) gboolean xaccAccountGetTaxRelated (const Account *acc) { - return boolean_from_key(acc, {"tax-related"}); + return get_kvp_boolean_path(acc, {"tax-related"}); } void xaccAccountSetTaxRelated (Account *acc, gboolean tax_related) { - set_boolean_key(acc, {"tax-related"}, tax_related); + set_kvp_boolean_path(acc, {"tax-related"}, tax_related); } const char * xaccAccountGetTaxUSCode (const Account *acc) { - GValue v = G_VALUE_INIT; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {"tax-US", "code"}); - return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : nullptr; + return get_kvp_string_path (acc, {"tax-US", "code"}); } void @@ -4097,10 +4000,7 @@ xaccAccountSetTaxUSCode (Account *acc, const char *code) const char * xaccAccountGetTaxUSPayerNameSource (const Account *acc) { - GValue v = G_VALUE_INIT; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {"tax-US", "payer-name-source"}); - return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : nullptr; + return get_kvp_string_path (acc, {"tax-US", "payer-name-source"}); } void @@ -4112,36 +4012,14 @@ xaccAccountSetTaxUSPayerNameSource (Account *acc, const char *source) gint64 xaccAccountGetTaxUSCopyNumber (const Account *acc) { - gint64 copy_number = 0; - GValue v = G_VALUE_INIT; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {"tax-US", "copy-number"}); - if (G_VALUE_HOLDS_INT64 (&v)) - copy_number = g_value_get_int64 (&v); - - g_value_unset (&v); - return (copy_number == 0) ? 1 : copy_number; + auto copy_number = get_kvp_int64_path (acc, {"tax-US", "copy-number"}); + return copy_number ? *copy_number : 1; } void xaccAccountSetTaxUSCopyNumber (Account *acc, gint64 copy_number) { - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - xaccAccountBeginEdit (acc); - if (copy_number != 0) - { - GValue v = G_VALUE_INIT; - g_value_init (&v, G_TYPE_INT64); - g_value_set_int64 (&v, copy_number); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {"tax-US", "copy-number"}); - g_value_unset (&v); - } - else - { - qof_instance_set_path_kvp (QOF_INSTANCE (acc), nullptr, {"tax-US", "copy-number"}); - } - mark_account (acc); - xaccAccountCommitEdit (acc); + set_kvp_int64_path (acc, {"tax-US", "copy-number"}, copy_number); } /*********************************************************************\ @@ -4178,67 +4056,54 @@ const char *gnc_account_get_credit_string (GNCAccountType acct_type) gboolean xaccAccountGetPlaceholder (const Account *acc) { - return boolean_from_key(acc, {"placeholder"}); + return get_kvp_boolean_path(acc, {"placeholder"}); } void xaccAccountSetPlaceholder (Account *acc, gboolean val) { - set_boolean_key(acc, {"placeholder"}, val); + set_kvp_boolean_path(acc, {"placeholder"}, val); } gboolean xaccAccountGetAppendText (const Account *acc) { - return boolean_from_key(acc, {"import-append-text"}); + return get_kvp_boolean_path(acc, {"import-append-text"}); } void xaccAccountSetAppendText (Account *acc, gboolean val) { - set_boolean_key(acc, {"import-append-text"}, val); + set_kvp_boolean_path(acc, {"import-append-text"}, val); } gboolean xaccAccountGetIsOpeningBalance (const Account *acc) { + g_return_val_if_fail (GNC_IS_ACCOUNT(acc), false); if (GET_PRIVATE(acc)->type != ACCT_TYPE_EQUITY) return false; - GValue v = G_VALUE_INIT; - auto rv = !g_strcmp0 (get_kvp_string_tag (acc, "equity-type", &v), - "opening-balance"); - g_value_unset (&v); - return rv; + return !g_strcmp0 (get_kvp_string_path (acc, {"equity-type"}), "opening-balance"); } void xaccAccountSetIsOpeningBalance (Account *acc, gboolean val) { + g_return_if_fail (GNC_IS_ACCOUNT(acc)); if (GET_PRIVATE(acc)->type != ACCT_TYPE_EQUITY) return; - set_kvp_string_tag(acc, "equity-type", val ? "opening-balance" : nullptr); + set_kvp_string_path(acc, {"equity-type"}, val ? "opening-balance" : nullptr); } GNCPlaceholderType xaccAccountGetDescendantPlaceholder (const Account *acc) { - GList *descendants, *node; - GNCPlaceholderType ret = PLACEHOLDER_NONE; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), PLACEHOLDER_NONE); if (xaccAccountGetPlaceholder(acc)) return PLACEHOLDER_THIS; - descendants = gnc_account_get_descendants(acc); - for (node = descendants; node; node = node->next) - if (xaccAccountGetPlaceholder((Account *) node->data)) - { - ret = PLACEHOLDER_CHILD; - break; - } - - g_list_free(descendants); - return ret; + return gnc_account_foreach_descendant_until (acc, (AccountCb2)xaccAccountGetPlaceholder, nullptr) + ? PLACEHOLDER_CHILD : PLACEHOLDER_NONE; } /********************************************************************\ @@ -4247,13 +4112,13 @@ xaccAccountGetDescendantPlaceholder (const Account *acc) gboolean xaccAccountGetAutoInterest (const Account *acc) { - return boolean_from_key (acc, {KEY_RECONCILE_INFO, "auto-interest-transfer"}); + return get_kvp_boolean_path (acc, {KEY_RECONCILE_INFO, "auto-interest-transfer"}); } void xaccAccountSetAutoInterest (Account *acc, gboolean val) { - set_boolean_key (acc, {KEY_RECONCILE_INFO, "auto-interest-transfer"}, val); + set_kvp_boolean_path (acc, {KEY_RECONCILE_INFO, "auto-interest-transfer"}, val); } /********************************************************************\ @@ -4262,13 +4127,13 @@ xaccAccountSetAutoInterest (Account *acc, gboolean val) gboolean xaccAccountGetHidden (const Account *acc) { - return boolean_from_key (acc, {"hidden"}); + return get_kvp_boolean_path (acc, {"hidden"}); } void xaccAccountSetHidden (Account *acc, gboolean val) { - set_boolean_key (acc, {"hidden"}, val); + set_kvp_boolean_path (acc, {"hidden"}, val); } gboolean @@ -4638,22 +4503,15 @@ xaccAccountIsPriced(const Account *acc) gboolean xaccAccountGetReconcileLastDate (const Account *acc, time64 *last_date) { - gint64 date = 0; - GValue v = G_VALUE_INIT; gboolean retval = FALSE; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_RECONCILE_INFO, "last-date"}); - if (G_VALUE_HOLDS_INT64 (&v)) - date = g_value_get_int64 (&v); + auto date = get_kvp_int64_path (acc, {KEY_RECONCILE_INFO, "last-date"}); - g_value_unset (&v); if (date) { if (last_date) - *last_date = date; + *last_date = *date; retval = TRUE; } - g_value_unset (&v); return retval; } @@ -4663,16 +4521,7 @@ xaccAccountGetReconcileLastDate (const Account *acc, time64 *last_date) void xaccAccountSetReconcileLastDate (Account *acc, time64 last_date) { - GValue v = G_VALUE_INIT; - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - - g_value_init (&v, G_TYPE_INT64); - g_value_set_int64 (&v, last_date); - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {KEY_RECONCILE_INFO, "last-date"}); - mark_account (acc); - xaccAccountCommitEdit (acc); - g_value_unset (&v); + set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, "last-date"}, last_date); } /********************************************************************\ @@ -4682,31 +4531,18 @@ gboolean xaccAccountGetReconcileLastInterval (const Account *acc, int *months, int *days) { - GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT; - int64_t m = 0, d = 0; - gboolean retval = FALSE; - if (!acc) return FALSE; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v1, - {KEY_RECONCILE_INFO, "last-interval", "months"}); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v2, - {KEY_RECONCILE_INFO, "last-interval", "days"}); - if (G_VALUE_HOLDS_INT64 (&v1)) - m = g_value_get_int64 (&v1); - if (G_VALUE_HOLDS_INT64 (&v2)) - d = g_value_get_int64 (&v2); + auto m{get_kvp_int64_path (acc, {KEY_RECONCILE_INFO, "last-interval", "months"})}; + auto d{get_kvp_int64_path (acc, {KEY_RECONCILE_INFO, "last-interval", "days"})}; if (m && d) { if (months) - *months = m; + *months = *m; if (days) - *days = d; - retval = TRUE; + *days = *d; + return true; } - g_value_unset (&v1); - g_value_unset (&v2); - return retval; + return false; } /********************************************************************\ @@ -4715,22 +4551,8 @@ xaccAccountGetReconcileLastInterval (const Account *acc, void xaccAccountSetReconcileLastInterval (Account *acc, int months, int days) { - GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT; - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - - g_value_init (&v1, G_TYPE_INT64); - g_value_set_int64 (&v1, months); - g_value_init (&v2, G_TYPE_INT64); - g_value_set_int64 (&v2, days); - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v1, - {KEY_RECONCILE_INFO, "last-interval", "months"}); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v2, - {KEY_RECONCILE_INFO, "last-interval", "days"}); - mark_account (acc); - xaccAccountCommitEdit (acc); - g_value_unset (&v1); - g_value_unset (&v2); + set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, "last-interval", "months"}, months); + set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, "last-interval", "days"}, days); } /********************************************************************\ @@ -4739,23 +4561,13 @@ xaccAccountSetReconcileLastInterval (Account *acc, int months, int days) gboolean xaccAccountGetReconcilePostponeDate (const Account *acc, time64 *postpone_date) { - gint64 date = 0; - gboolean retval = FALSE; - GValue v = G_VALUE_INIT; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, - {KEY_RECONCILE_INFO, KEY_POSTPONE, "date"}); - if (G_VALUE_HOLDS_INT64 (&v)) - date = g_value_get_int64 (&v); - - if (date) + if (auto date = get_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE, "date"})) { if (postpone_date) - *postpone_date = date; - retval = TRUE; + *postpone_date = *date; + return true; } - g_value_unset (&v); - return retval; + return false; } /********************************************************************\ @@ -4764,17 +4576,7 @@ xaccAccountGetReconcilePostponeDate (const Account *acc, time64 *postpone_date) void xaccAccountSetReconcilePostponeDate (Account *acc, time64 postpone_date) { - GValue v = G_VALUE_INIT; - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - - g_value_init (&v, G_TYPE_INT64); - g_value_set_int64 (&v, postpone_date); - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, - {KEY_RECONCILE_INFO, KEY_POSTPONE, "date"}); - mark_account (acc); - xaccAccountCommitEdit (acc); - g_value_unset (&v); + set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE, "date"}, postpone_date); } /********************************************************************\ @@ -4784,24 +4586,13 @@ gboolean xaccAccountGetReconcilePostponeBalance (const Account *acc, gnc_numeric *balance) { - gnc_numeric bal = gnc_numeric_zero (); - GValue v = G_VALUE_INIT; - gboolean retval = FALSE; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, - {KEY_RECONCILE_INFO, KEY_POSTPONE, "balance"}); - if (G_VALUE_HOLDS_BOXED (&v)) + if (auto bal = get_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE, "balance"})) { - bal = *(gnc_numeric*)g_value_get_boxed (&v); - if (bal.denom) - { - if (balance) - *balance = bal; - retval = TRUE; - } + if (balance) + *balance = *bal; + return true; } - g_value_unset (&v); - return retval; + return false; } /********************************************************************\ @@ -4810,17 +4601,7 @@ xaccAccountGetReconcilePostponeBalance (const Account *acc, void xaccAccountSetReconcilePostponeBalance (Account *acc, gnc_numeric balance) { - GValue v = G_VALUE_INIT; - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - - g_value_init (&v, GNC_TYPE_NUMERIC); - g_value_set_boxed (&v, &balance); - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, - {KEY_RECONCILE_INFO, KEY_POSTPONE, "balance"}); - mark_account (acc); - xaccAccountCommitEdit (acc); - g_value_unset (&v); + set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE, "balance"}, balance); } /********************************************************************\ @@ -4830,12 +4611,7 @@ xaccAccountSetReconcilePostponeBalance (Account *acc, gnc_numeric balance) void xaccAccountClearReconcilePostpone (Account *acc) { - if (!acc) return; - - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE(acc), nullptr, {KEY_RECONCILE_INFO, KEY_POSTPONE}); - mark_account (acc); - xaccAccountCommitEdit (acc); + set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE, "balance"}, {}); } /********************************************************************\ @@ -4844,10 +4620,7 @@ xaccAccountClearReconcilePostpone (Account *acc) const char * xaccAccountGetLastNum (const Account *acc) { - GValue v = G_VALUE_INIT; - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {"last-num"}); - return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : nullptr; + return get_kvp_string_path (acc, {"last-num"}); } /********************************************************************\ @@ -4856,250 +4629,78 @@ xaccAccountGetLastNum (const Account *acc) void xaccAccountSetLastNum (Account *acc, const char *num) { - GValue v = G_VALUE_INIT; - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - g_value_init (&v, G_TYPE_STRING); - - g_value_set_static_string (&v, num); - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {"last-num"}); - mark_account (acc); - xaccAccountCommitEdit (acc); + set_kvp_string_path (acc, {"last-num"}, num); } /********************************************************************\ \********************************************************************/ +static bool +get_balance_limit (const Account* acc, const std::string& key, gnc_numeric* balance) +{ + auto limit = get_kvp_gnc_numeric_path (acc, {KEY_BALANCE_LIMIT, key}); + if (limit) + *balance = gnc_numeric_create (limit->num, limit->denom); + return limit.has_value(); +} + +static void +set_balance_limit (Account *acc, const std::string& key, std::optional balance) +{ + if (balance && gnc_numeric_check (*balance)) + return; + set_kvp_gnc_numeric_path (acc, {KEY_BALANCE_LIMIT, key}, balance); +} + gboolean xaccAccountGetHigherBalanceLimit (const Account *acc, gnc_numeric *balance) { - g_return_val_if_fail (GNC_IS_ACCOUNT(acc), false); - - if (GET_PRIVATE(acc)->higher_balance_limit.has_value()) - { - *balance = GET_PRIVATE(acc)->higher_balance_limit.value(); - - if (gnc_numeric_check (*balance) == 0) - return true; - else - return false; - } - else - { - gnc_numeric bal = gnc_numeric_create (1,0); - GValue v = G_VALUE_INIT; - gboolean retval = false; - - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_BALANCE_LIMIT, - KEY_BALANCE_HIGHER_LIMIT_VALUE}); - if (G_VALUE_HOLDS_BOXED(&v)) - { - bal = *(gnc_numeric*)g_value_get_boxed (&v); - if (bal.denom) - { - if (balance) - *balance = bal; - retval = true; - } - } - g_value_unset (&v); - - GET_PRIVATE(acc)->higher_balance_limit = bal; - return retval; - } + return get_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, balance); } gboolean xaccAccountGetLowerBalanceLimit (const Account *acc, gnc_numeric *balance) { - g_return_val_if_fail (GNC_IS_ACCOUNT(acc), false); - - if (GET_PRIVATE(acc)->lower_balance_limit.has_value()) - { - *balance = GET_PRIVATE(acc)->lower_balance_limit.value(); - - if (gnc_numeric_check (*balance) == 0) - return true; - else - return false; - } - else - { - gnc_numeric bal = gnc_numeric_create (1,0); - GValue v = G_VALUE_INIT; - gboolean retval = false; - - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_BALANCE_LIMIT, - KEY_BALANCE_LOWER_LIMIT_VALUE}); - if (G_VALUE_HOLDS_BOXED(&v)) - { - bal = *(gnc_numeric*)g_value_get_boxed (&v); - if (bal.denom) - { - if (balance) - *balance = bal; - retval = true; - } - } - g_value_unset (&v); - - GET_PRIVATE(acc)->lower_balance_limit = bal; - return retval; - } -} - - -static void -set_balance_limits (Account *acc, gnc_numeric balance, gboolean higher) -{ - gnc_numeric balance_limit; - gboolean balance_limit_valid; - std::vector path {KEY_BALANCE_LIMIT}; - - if (higher) - { - path.push_back (KEY_BALANCE_HIGHER_LIMIT_VALUE); - balance_limit_valid = xaccAccountGetHigherBalanceLimit (acc, &balance_limit); - } - else - { - path.push_back (KEY_BALANCE_LOWER_LIMIT_VALUE); - balance_limit_valid = xaccAccountGetLowerBalanceLimit (acc, &balance_limit); - } - - if (!balance_limit_valid || gnc_numeric_compare (balance, balance_limit) != 0) - { - GValue v = G_VALUE_INIT; - g_value_init (&v, GNC_TYPE_NUMERIC); - g_value_set_boxed (&v, &balance); - xaccAccountBeginEdit (acc); - - qof_instance_set_path_kvp (QOF_INSTANCE(acc), &v, path); - if (higher) - { - GET_PRIVATE(acc)->higher_balance_limit = balance; - } - else - { - GET_PRIVATE(acc)->lower_balance_limit = balance; - } - mark_account (acc); - xaccAccountCommitEdit (acc); - g_value_unset (&v); - } + return get_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, balance); } void xaccAccountSetHigherBalanceLimit (Account *acc, gnc_numeric balance) { - g_return_if_fail (GNC_IS_ACCOUNT(acc)); - - if (gnc_numeric_check (balance) != 0) - return; - - set_balance_limits (acc, balance, true); + set_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, balance); } void xaccAccountSetLowerBalanceLimit (Account *acc, gnc_numeric balance) { - g_return_if_fail (GNC_IS_ACCOUNT(acc)); - - if (gnc_numeric_check (balance) != 0) - return; - - set_balance_limits (acc, balance, false); -} - - -static void -clear_balance_limits (Account *acc, gboolean higher) -{ - gnc_numeric balance_limit; - gboolean balance_limit_valid; - std::vector path {KEY_BALANCE_LIMIT}; - - if (higher) - { - path.push_back (KEY_BALANCE_HIGHER_LIMIT_VALUE); - balance_limit_valid = xaccAccountGetHigherBalanceLimit (acc, &balance_limit); - } - else - { - path.push_back (KEY_BALANCE_LOWER_LIMIT_VALUE); - balance_limit_valid = xaccAccountGetLowerBalanceLimit (acc, &balance_limit); - } - - if (balance_limit_valid) - { - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE(acc), nullptr, path); - qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), {KEY_BALANCE_LIMIT}); - if (higher) - GET_PRIVATE(acc)->higher_balance_limit.reset(); - else - GET_PRIVATE(acc)->lower_balance_limit.reset(); - mark_account (acc); - xaccAccountCommitEdit (acc); - } + set_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, balance); } void xaccAccountClearHigherBalanceLimit (Account *acc) { - g_return_if_fail (GNC_IS_ACCOUNT(acc)); - - clear_balance_limits (acc, true); + set_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, {}); } void xaccAccountClearLowerBalanceLimit (Account *acc) { - g_return_if_fail (GNC_IS_ACCOUNT(acc)); - - clear_balance_limits (acc, false); + set_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, {}); } gboolean xaccAccountGetIncludeSubAccountBalances (const Account *acc) { - g_return_val_if_fail (GNC_IS_ACCOUNT(acc), false); - - if (!GET_PRIVATE(acc)->include_sub_account_balances.has_value()) - { - gboolean inc_sub = boolean_from_key (acc, {KEY_BALANCE_LIMIT, - KEY_BALANCE_INCLUDE_SUB_ACCTS}); - - GET_PRIVATE(acc)->include_sub_account_balances = inc_sub; - } - return GET_PRIVATE(acc)->include_sub_account_balances.value(); + return get_kvp_boolean_path (acc, {KEY_BALANCE_LIMIT, KEY_BALANCE_INCLUDE_SUB_ACCTS}); } void xaccAccountSetIncludeSubAccountBalances (Account *acc, gboolean inc_sub) { - g_return_if_fail (GNC_IS_ACCOUNT(acc)); - - if (inc_sub != xaccAccountGetIncludeSubAccountBalances (acc)) - { - GValue v = G_VALUE_INIT; - g_value_init (&v, G_TYPE_BOOLEAN); - g_value_set_boolean (&v, inc_sub); - std::vector path {KEY_BALANCE_LIMIT, - KEY_BALANCE_INCLUDE_SUB_ACCTS}; - xaccAccountBeginEdit (acc); - if (inc_sub) - qof_instance_set_path_kvp (QOF_INSTANCE(acc), &v, path); - else - qof_instance_set_path_kvp (QOF_INSTANCE(acc), nullptr, path); - GET_PRIVATE(acc)->include_sub_account_balances = inc_sub; - mark_account (acc); - xaccAccountCommitEdit (acc); - g_value_unset (&v); - } + set_kvp_boolean_path (acc, {KEY_BALANCE_LIMIT, KEY_BALANCE_INCLUDE_SUB_ACCTS}, inc_sub); } /********************************************************************\ @@ -5153,37 +4754,15 @@ GetOrMakeOrphanAccount (Account *root, gnc_commodity * currency) Account * xaccAccountGainsAccount (Account *acc, gnc_commodity *curr) { - GValue v = G_VALUE_INIT; - std::vector path {KEY_LOT_MGMT, "gains-acct", - gnc_commodity_get_unique_name (curr)}; - GncGUID *guid = nullptr; - Account *gains_account; - - g_return_val_if_fail (acc != nullptr, nullptr); - qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, path); - if (G_VALUE_HOLDS_BOXED (&v)) - guid = (GncGUID*)g_value_get_boxed (&v); - if (guid == nullptr) /* No gains account for this currency */ + Path path {KEY_LOT_MGMT, "gains-acct", gnc_commodity_get_unique_name (curr)}; + auto gains_account = get_kvp_account_path (acc, path); + + if (gains_account == nullptr) /* No gains account for this currency */ { - gains_account = GetOrMakeOrphanAccount (gnc_account_get_root (acc), - curr); - guid = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (gains_account)); - xaccAccountBeginEdit (acc); - { - GValue vr = G_VALUE_INIT; - g_value_init (&vr, GNC_TYPE_GUID); - g_value_set_boxed (&vr, guid); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &vr, path); - qof_instance_set_dirty (QOF_INSTANCE (acc)); - g_value_unset (&vr); - } - xaccAccountCommitEdit (acc); + gains_account = GetOrMakeOrphanAccount (gnc_account_get_root (acc), curr); + set_kvp_account_path (acc, path, gains_account); } - else - gains_account = xaccAccountLookup (guid, - qof_instance_get_book(acc)); - g_value_unset (&v); return gains_account; } @@ -5196,7 +4775,7 @@ dxaccAccountSetPriceSrc(Account *acc, const char *src) if (!acc) return; if (xaccAccountIsPriced(acc)) - set_kvp_string_tag (acc, "old-price-source", src); + set_kvp_string_path (acc, {"old-price-source"}, src); } /********************************************************************\ @@ -5212,10 +4791,7 @@ dxaccAccountGetPriceSrc(const Account *acc) g_free (source); - GValue v = G_VALUE_INIT; - auto rv = get_kvp_string_tag (acc, "old-price-source", &v); - g_value_unset (&v); - return rv; + return get_kvp_string_path (acc, {"old-price-source"}); } /********************************************************************\ @@ -5226,7 +4802,7 @@ dxaccAccountSetQuoteTZ(Account *acc, const char *tz) { if (!acc) return; if (!xaccAccountIsPriced(acc)) return; - set_kvp_string_tag (acc, "old-quote-tz", tz); + set_kvp_string_path (acc, {"old-quote-tz"}, tz); } /********************************************************************\ @@ -5237,10 +4813,7 @@ dxaccAccountGetQuoteTZ(const Account *acc) { if (!acc) return nullptr; if (!xaccAccountIsPriced(acc)) return nullptr; - GValue v = G_VALUE_INIT; - auto rv = get_kvp_string_tag (acc, "old-quote-tz", &v); - g_value_unset (&v); - return rv; + return get_kvp_string_path (acc, {"old-quote-tz"}); } /********************************************************************\ @@ -5249,21 +4822,11 @@ dxaccAccountGetQuoteTZ(const Account *acc) void xaccAccountSetReconcileChildrenStatus(Account *acc, gboolean status) { - GValue v = G_VALUE_INIT; - if (!acc) return; - - xaccAccountBeginEdit (acc); /* Would have been nice to use G_TYPE_BOOLEAN, but the other * boolean kvps save the value as "true" or "false" and that would * be file-incompatible with this. */ - g_value_init (&v, G_TYPE_INT64); - g_value_set_int64 (&v, status); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, - {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN}); - mark_account(acc); - xaccAccountCommitEdit (acc); - g_value_unset (&v); + set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN}, status); } /********************************************************************\ @@ -5276,14 +4839,7 @@ xaccAccountGetReconcileChildrenStatus(const Account *acc) * is found then we can assume not to include the children, that being * the default behaviour */ - GValue v = G_VALUE_INIT; - gboolean retval; - if (!acc) return FALSE; - qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, - {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN}); - retval = G_VALUE_HOLDS_INT64 (&v) ? g_value_get_int64 (&v) : FALSE; - g_value_unset (&v); - return retval; + return get_kvp_boolean_path (acc, {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN}); } /********************************************************************\ @@ -5434,22 +4990,13 @@ xaccTransactionTraverse (Transaction *trans, int stage) return FALSE; } -static void do_one_account (Account *account, gpointer data) -{ - AccountPrivate *priv = GET_PRIVATE(account); - std::for_each (priv->splits.begin(), priv->splits.end(), - [](auto s){ s->parent->marker = 0; }); -} - /* Replacement for xaccGroupBeginStagedTransactionTraversals */ void gnc_account_tree_begin_staged_transaction_traversals (Account *account) { - GList *descendants; - - descendants = gnc_account_get_descendants(account); - g_list_foreach(descendants, (GFunc)do_one_account, nullptr); - g_list_free(descendants); + auto do_one_account = [](auto acc) + { gnc_account_foreach_split (acc, [](auto s){ s->parent->marker = 0; }, false); }; + gnc_account_foreach_descendant (account, do_one_account); } int @@ -5556,20 +5103,12 @@ gnc_account_imap_find_account (Account *acc, const char *category, const char *key) { - GValue v = G_VALUE_INIT; - GncGUID * guid = nullptr; - Account *retval; if (!acc || !key) return nullptr; std::vector path {IMAP_FRAME}; if (category) path.push_back (category); path.push_back (key); - qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, path); - if (G_VALUE_HOLDS_BOXED (&v)) - guid = (GncGUID*)g_value_get_boxed (&v); - retval = xaccAccountLookup (guid, gnc_account_get_book(acc)); - g_value_unset (&v); - return retval; + return get_kvp_account_path (acc, path); } Account* @@ -5604,19 +5143,11 @@ gnc_account_imap_add_account (Account *acc, const char *key, Account *added_acc) { - GValue v = G_VALUE_INIT; - if (!acc || !key || !added_acc || (strlen (key) == 0)) return; - std::vector path {IMAP_FRAME}; - if (category) - path.emplace_back (category); - path.emplace_back (key); - g_value_init (&v, GNC_TYPE_GUID); - g_value_set_boxed (&v, xaccAccountGetGUID (added_acc)); - xaccAccountBeginEdit (acc); - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path); - qof_instance_set_dirty (QOF_INSTANCE (acc)); - xaccAccountCommitEdit (acc); - g_value_unset (&v); + if (!acc || !key || !added_acc || !*key) return; + + auto path = category ? Path{IMAP_FRAME, category, key} : Path{IMAP_FRAME, key}; + + set_kvp_account_path (acc, path, added_acc); } /* Remove a reference to an Account in the map */ @@ -5626,11 +5157,8 @@ gnc_account_imap_delete_account (Account *acc, const char *key) { if (!acc || !key) return; - std::vector path {IMAP_FRAME}; - if (category) - path.emplace_back (category); - path.emplace_back (key); - xaccAccountBeginEdit (acc); + + auto path = category ? Path{IMAP_FRAME, category, key} : Path{IMAP_FRAME, key}; if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path)) { qof_instance_slot_path_delete (QOF_INSTANCE (acc), path); @@ -5639,7 +5167,6 @@ gnc_account_imap_delete_account (Account *acc, qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME}); } qof_instance_set_dirty (QOF_INSTANCE (acc)); - xaccAccountCommitEdit (acc); } /*-------------------------------------------------------------------------- @@ -5958,36 +5485,18 @@ gnc_account_imap_find_account_bayes (Account *acc, GList *tokens) static void change_imap_entry (Account *acc, std::string const & path, int64_t token_count) { - GValue value = G_VALUE_INIT; - PINFO("Source Account is '%s', Count is '%" G_GINT64_FORMAT "'", xaccAccountGetName (acc), token_count); // check for existing guid entry - if (qof_instance_has_slot (QOF_INSTANCE(acc), path.c_str ())) + if (auto existing_token_count = get_kvp_int64_path (acc, {path})) { - int64_t existing_token_count = 0; - - // get the existing_token_count value - qof_instance_get_path_kvp (QOF_INSTANCE (acc), &value, {path}); - - if (G_VALUE_HOLDS_INT64 (&value)) - existing_token_count = g_value_get_int64 (&value); - - PINFO("found existing value of '%" G_GINT64_FORMAT "'", existing_token_count); - - token_count = token_count + existing_token_count; + PINFO("found existing value of '%" G_GINT64_FORMAT "'", *existing_token_count); + token_count += *existing_token_count; } - if (!G_IS_VALUE (&value)) - g_value_init (&value, G_TYPE_INT64); - - g_value_set_int64 (&value, token_count); - // Add or Update the entry based on guid - qof_instance_set_path_kvp (QOF_INSTANCE (acc), &value, {path}); - gnc_features_set_used (gnc_account_get_book(acc), GNC_FEATURE_GUID_FLAT_BAYESIAN); - g_value_unset (&value); + set_kvp_int64_path (acc, {path}, token_count); } /** Updates the imap for a given account using a list of tokens */ @@ -6021,22 +5530,23 @@ gnc_account_imap_add_account_bayes (Account *acc, for (current_token = g_list_first(tokens); current_token; current_token = current_token->next) { + char* token = static_cast(current_token->data); /* Jump to next iteration if the pointer is not valid or if the string is empty. In HBCI import we almost always get an empty string, which doesn't work in the kvp loopkup later. So we skip this case here. */ - if (!current_token->data || (*((char*)current_token->data) == '\0')) + if (!token || !token[0]) continue; /* start off with one token for this account */ token_count = 1; - PINFO("adding token '%s'", (char*)current_token->data); - auto path = std::string {IMAP_FRAME_BAYES} + '/' + static_cast(current_token->data) + '/' + guid_string; + PINFO("adding token '%s'", token); + auto path = std::string {IMAP_FRAME_BAYES} + '/' + token + '/' + guid_string; /* change the imap entry for the account */ change_imap_entry (acc, path, token_count); } /* free up the account fullname and guid string */ - qof_instance_set_dirty (QOF_INSTANCE (acc)); xaccAccountCommitEdit (acc); + gnc_features_set_used (gnc_account_get_book(acc), GNC_FEATURE_GUID_FLAT_BAYESIAN); g_free (account_fullname); g_free (guid_string); LEAVE(" "); @@ -6154,12 +5664,9 @@ gnc_account_imap_get_info (Account *acc, const char *category) gchar * gnc_account_get_map_entry (Account *acc, const char *head, const char *category) { - GValue v = G_VALUE_INIT; - auto rv = g_strdup (category ? - get_kvp_string_path (acc, {head, category}, &v) : - get_kvp_string_path (acc, {head}, &v)); - g_value_unset (&v); - return rv; + return g_strdup (category ? + get_kvp_string_path (acc, {head, category}) : + get_kvp_string_path (acc, {head})); } diff --git a/libgnucash/engine/AccountP.hpp b/libgnucash/engine/AccountP.hpp index 64e6f09bf39..ea617fe0118 100644 --- a/libgnucash/engine/AccountP.hpp +++ b/libgnucash/engine/AccountP.hpp @@ -112,10 +112,6 @@ typedef struct AccountPrivate gnc_numeric noclosing_balance; gnc_numeric cleared_balance; gnc_numeric reconciled_balance; - - std::optional higher_balance_limit; - std::optional lower_balance_limit; - std::optional include_sub_account_balances; gboolean balance_dirty; /* balances in splits incorrect */ diff --git a/libgnucash/engine/qofinstance-p.h b/libgnucash/engine/qofinstance-p.h index 45d4eeb68d7..cf4c676bb59 100644 --- a/libgnucash/engine/qofinstance-p.h +++ b/libgnucash/engine/qofinstance-p.h @@ -36,6 +36,7 @@ #ifdef __cplusplus #include "kvp-frame.hpp" #include +#include extern "C" { #endif @@ -165,6 +166,12 @@ void qof_instance_get_path_kvp (QofInstance *, GValue *, std::vector const &); +template std::optional +qof_instance_get_path_kvp (QofInstance*, const Path&); + +template void +qof_instance_set_path_kvp (QofInstance*, std::optional, const Path&); + bool qof_instance_has_path_slot (QofInstance const *, std::vector const &); void qof_instance_slot_path_delete (QofInstance const *, std::vector const &); diff --git a/libgnucash/engine/qofinstance.cpp b/libgnucash/engine/qofinstance.cpp index 11df55c1e85..1fbe371deec 100644 --- a/libgnucash/engine/qofinstance.cpp +++ b/libgnucash/engine/qofinstance.cpp @@ -1063,6 +1063,32 @@ qof_instance_set_kvp (QofInstance * inst, GValue const * value, unsigned count, delete inst->kvp_data->set_path (path, kvp_value_from_gvalue (value)); } +template std::optional +qof_instance_get_path_kvp (QofInstance* inst, const Path& path) +{ + g_return_val_if_fail (QOF_IS_INSTANCE(inst), std::nullopt); + auto kvp_value{inst->kvp_data->get_slot(path)}; + return kvp_value ? std::make_optional(kvp_value->get()) : std::nullopt; +} + +template void +qof_instance_set_path_kvp (QofInstance* inst, std::optional value, const Path& path) +{ + g_return_if_fail (QOF_IS_INSTANCE(inst)); + delete inst->kvp_data->set_path(path, value ? new KvpValue(*value) : nullptr); + qof_instance_set_dirty (inst); +} + +template std::optional qof_instance_get_path_kvp (QofInstance*, const Path&); +template std::optional qof_instance_get_path_kvp (QofInstance*, const Path&); +template std::optional qof_instance_get_path_kvp (QofInstance*, const Path&); +template std::optional qof_instance_get_path_kvp (QofInstance*, const Path&); + +template void qof_instance_set_path_kvp (QofInstance*, std::optional, const Path& path); +template void qof_instance_set_path_kvp (QofInstance*, std::optional, const Path& path); +template void qof_instance_set_path_kvp (QofInstance*, std::optional, const Path& path); +template void qof_instance_set_path_kvp (QofInstance*, std::optional, const Path& path); + void qof_instance_get_path_kvp (QofInstance * inst, GValue * value, std::vector const & path) { gvalue_from_kvp_value (inst->kvp_data->get_slot (path), value); @@ -1316,17 +1342,16 @@ struct wrap_param static void wrap_gvalue_function (const char* key, KvpValue *val, wrap_param & param) { - GValue *gv; - gv = g_slice_new0 (GValue); + GValue gv; if (val->get_type() != KvpValue::Type::FRAME) - gvalue_from_kvp_value(val, gv); + gvalue_from_kvp_value(val, &gv); else { - g_value_init (gv, G_TYPE_STRING); - g_value_set_string (gv, nullptr); + g_value_init (&gv, G_TYPE_STRING); + g_value_set_string (&gv, nullptr); } - param.proc(key, gv, param.user_data); - g_slice_free (GValue, gv); + param.proc(key, &gv, param.user_data); + g_value_unset (&gv); } void diff --git a/libgnucash/engine/test/utest-Account.cpp b/libgnucash/engine/test/utest-Account.cpp index 1831d911097..7f8585c17de 100644 --- a/libgnucash/engine/test/utest-Account.cpp +++ b/libgnucash/engine/test/utest-Account.cpp @@ -1107,7 +1107,7 @@ test_gnc_account_kvp_setters_getters (Fixture *fixture, gconstpointer pData) g_assert_cmpstr (xaccAccountGetLastNum (account), ==, "red"); xaccAccountSetLastNum (account, ""); - g_assert_cmpstr (xaccAccountGetLastNum (account), ==, ""); + g_assert_cmpstr (xaccAccountGetLastNum (account), ==, nullptr); xaccAccountSetLastNum (account, " "); g_assert_cmpstr (xaccAccountGetLastNum (account), ==, " ");