From 3bf49ed8d7c806a550d07fc2d803b64c2e78f196 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Mon, 23 Aug 2021 18:05:08 +0800 Subject: [PATCH] [Account.cpp] GValue string must be unset --- libgnucash/engine/Account.cpp | 89 +++++++++++++++++++++++++++++++---- libgnucash/engine/AccountP.h | 14 ++++++ 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp index ba09427581..14e4dfd4be 100644 --- a/libgnucash/engine/Account.cpp +++ b/libgnucash/engine/Account.cpp @@ -286,6 +286,8 @@ mark_account (Account *acc) /********************************************************************\ \********************************************************************/ +static constexpr const char* is_unset {"unset"}; + /* GObject Initialization */ G_DEFINE_TYPE_WITH_PRIVATE(Account, gnc_account, QOF_TYPE_INSTANCE) @@ -323,6 +325,13 @@ gnc_account_init(Account* acc) priv->starting_reconciled_balance = gnc_numeric_zero(); priv->balance_dirty = FALSE; + priv->color == is_unset; + priv->sort_order == is_unset; + priv->notes == is_unset; + priv->filter == is_unset; + priv->equity_type == TriState::Unset; + priv->sort_reversed == TriState::Unset; + priv->splits = NULL; priv->sort_dirty = FALSE; } @@ -1365,9 +1374,23 @@ xaccFreeAccount (Account *acc) qof_string_cache_remove(priv->description); priv->accountName = priv->accountCode = priv->description = nullptr; + if (priv->color != is_unset) + g_free (priv->color); + if (priv->sort_order != is_unset) + g_free (priv->sort_order); + if (priv->notes != is_unset) + g_free (priv->notes); + if (priv->filter != is_unset) + g_free (priv->filter); + /* zero out values, just in case stray * pointers are pointing here. */ + priv->color == nullptr; + priv->sort_order == nullptr; + priv->notes == nullptr; + priv->filter == nullptr; + priv->parent = nullptr; priv->children = nullptr; @@ -2476,36 +2499,52 @@ set_kvp_string_tag (Account *acc, const char *tag, const char *value) xaccAccountCommitEdit(acc); } -static const char* +static char* get_kvp_string_tag (const Account *acc, const char *tag) { GValue v = G_VALUE_INIT; if (acc == NULL || tag == NULL) return NULL; qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, {tag}); - return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL; + auto retval = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v) : NULL; + g_value_unset (&v); + return retval; } void xaccAccountSetColor (Account *acc, const char *str) { + auto priv = GET_PRIVATE (acc); + if (priv->color != is_unset) + g_free (priv->color); + priv->color = g_strdup (str); set_kvp_string_tag (acc, "color", str); } void xaccAccountSetFilter (Account *acc, const char *str) { + auto priv = GET_PRIVATE (acc); + if (priv->filter != is_unset) + g_free (priv->filter); + priv->filter = g_strdup (str); set_kvp_string_tag (acc, "filter", str); } void xaccAccountSetSortOrder (Account *acc, const char *str) { + auto priv = GET_PRIVATE (acc); + if (priv->sort_order != is_unset) + g_free (priv->sort_order); + priv->sort_order = g_strdup (str); set_kvp_string_tag (acc, "sort-order", str); } void xaccAccountSetSortReversed (Account *acc, gboolean sortreversed) { + auto priv = GET_PRIVATE (acc); + priv->sort_reversed = sortreversed ? TriState::True : TriState::False; set_kvp_string_tag (acc, "sort-reversed", sortreversed ? "true" : NULL); } @@ -2530,6 +2569,10 @@ qofAccountSetParent (Account *acc, QofInstance *parent) void xaccAccountSetNotes (Account *acc, const char *str) { + auto priv = GET_PRIVATE (acc); + if (priv->notes != is_unset) + g_free (priv->notes); + priv->notes = g_strdup (str); set_kvp_string_tag (acc, "notes", str); } @@ -3250,21 +3293,30 @@ const char * xaccAccountGetColor (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL); - return get_kvp_string_tag (acc, "color"); + auto priv = GET_PRIVATE (acc); + if (priv->color == is_unset) + priv->color = get_kvp_string_tag (acc, "color"); + return priv->color; } const char * xaccAccountGetFilter (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0); - return get_kvp_string_tag (acc, "filter"); + auto priv = GET_PRIVATE (acc); + if (priv->filter == is_unset) + priv->filter = get_kvp_string_tag (acc, "filter"); + return priv->filter; } const char * xaccAccountGetSortOrder (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0); - return get_kvp_string_tag (acc, "sort-order"); + auto priv = GET_PRIVATE (acc); + if (priv->sort_order == is_unset) + priv->sort_order = get_kvp_string_tag (acc, "sort-order"); + return priv->sort_order; } gboolean @@ -3272,14 +3324,25 @@ xaccAccountGetSortReversed (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - return g_strcmp0 (get_kvp_string_tag (acc, "sort-reversed"), "true") == 0; + auto priv = GET_PRIVATE (acc); + if (priv->sort_reversed == TriState::Unset) + { + auto sort_reversed = get_kvp_string_tag (acc, "sort-reversed"); + priv->sort_reversed = g_strcmp0 (sort_reversed, "true") ? + TriState::False : TriState::True; + g_free (sort_reversed); + } + return (priv->sort_reversed == TriState::True); } const char * xaccAccountGetNotes (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL); - return get_kvp_string_tag (acc, "notes"); + auto priv = GET_PRIVATE (acc); + if (priv->notes == is_unset) + priv->notes = get_kvp_string_tag (acc, "notes"); + return priv->notes; } gnc_commodity * @@ -4142,7 +4205,15 @@ xaccAccountGetIsOpeningBalance (const Account *acc) { if (GET_PRIVATE(acc)->type != ACCT_TYPE_EQUITY) return false; - return g_strcmp0(get_kvp_string_tag(acc, "equity-type"), "opening-balance") == 0; + auto priv = GET_PRIVATE(acc); + if (priv->equity_type == TriState::Unset) + { + auto equity_type = get_kvp_string_tag (acc, "equity-type"); + priv->equity_type = g_strcmp0 (equity_type, "true") ? + TriState::False : TriState::True; + g_free (equity_type); + } + return (priv->equity_type == TriState::True); } void @@ -4150,6 +4221,8 @@ xaccAccountSetIsOpeningBalance (Account *acc, gboolean val) { if (GET_PRIVATE(acc)->type != ACCT_TYPE_EQUITY) return; + auto priv = GET_PRIVATE (acc); + priv->equity_type = val ? TriState::True : TriState::False; set_kvp_string_tag(acc, "equity-type", val ? "opening-balance" : ""); } diff --git a/libgnucash/engine/AccountP.h b/libgnucash/engine/AccountP.h index 746a1c5040..250232206d 100644 --- a/libgnucash/engine/AccountP.h +++ b/libgnucash/engine/AccountP.h @@ -55,6 +55,13 @@ extern "C" { * No one outside of the engine should ever include this file. */ +typedef enum +{ + Unset = -1, + False, + True +} TriState; + /** \struct Account */ typedef struct AccountPrivate { @@ -122,6 +129,13 @@ typedef struct AccountPrivate LotList *lots; /* list of lot pointers */ GNCPolicy *policy; /* Cached pointer to policy method */ + TriState sort_reversed; + TriState equity_type; + char *notes; + char *color; + char *sort_order; + char *filter; + /* The "mark" flag can be used by the user to mark this account * in any way desired. Handy for specialty traversals of the * account tree. */