From 8bd7deb3dcccd150df6e1886312358cb95677df4 Mon Sep 17 00:00:00 2001 From: Robert Fewell <14uBobIT@gmail.com> Date: Mon, 17 Jun 2024 14:31:53 +0100 Subject: [PATCH] Reapply filter when number of sub-accounts change When viewing a register that displays sub-accounts, if the number of sub-accounts is changed, the query is rebuilt from the remaining sub-accounts but when a filter is being used it is not applied after. Fixed by checking the original query for a filter and if so applying that after query rebuilt. --- .../register/ledger-core/gnc-ledger-display.c | 24 +++++++++++ libgnucash/engine/Query.cpp | 42 ++++++++++++++++++- libgnucash/engine/Query.h | 2 + libgnucash/engine/qofquerycore.cpp | 12 ++++++ libgnucash/engine/qofquerycore.h | 2 + 5 files changed, 80 insertions(+), 2 deletions(-) diff --git a/gnucash/register/ledger-core/gnc-ledger-display.c b/gnucash/register/ledger-core/gnc-ledger-display.c index 2c0dbf6de2..43e68677cf 100644 --- a/gnucash/register/ledger-core/gnc-ledger-display.c +++ b/gnucash/register/ledger-core/gnc-ledger-display.c @@ -948,10 +948,30 @@ gnc_ledger_display_refresh (GNCLedgerDisplay* ld) GList* accounts = gnc_account_get_descendants (leader); if (g_list_length (accounts) != ld->number_of_subaccounts) + { + time64 start_time, end_time; + xaccQueryGetDateMatchTT (ld->query, &start_time, &end_time); + + cleared_match_t cleared_match = xaccQueryGetClearedMatch (ld->query); + gnc_ledger_display_make_query (ld, gnc_prefs_get_float (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_MAX_TRANS), gnc_get_reg_type (leader, ld->ld_type)); + qof_query_destroy (ld->pre_filter_query); + ld->pre_filter_query = qof_query_copy (ld->query); + + if (cleared_match != CLEARED_ALL) + xaccQueryAddClearedMatch (ld->query, cleared_match, QOF_QUERY_AND); + + if (start_time || end_time) + { + xaccQueryAddDateMatchTT (ld->query, + start_time != 0, start_time, + end_time != 0, end_time, + QOF_QUERY_AND); + } + } g_list_free (accounts); } @@ -963,8 +983,12 @@ gnc_ledger_display_refresh (GNCLedgerDisplay* ld) * -- jsled */ // Exclude any template accounts for search register and gl if (!ld->reg->is_template && (ld->reg->type == SEARCH_LEDGER || ld->ld_type == LD_GL)) + { exclude_template_accounts (ld->query, ld->excluded_template_acc_hash); + qof_query_destroy (ld->pre_filter_query); + ld->pre_filter_query = qof_query_copy (ld->query); + } gnc_ledger_display_refresh_internal (ld); LEAVE (" "); } diff --git a/libgnucash/engine/Query.cpp b/libgnucash/engine/Query.cpp index 38e9f4f77a..a1e307b5b4 100644 --- a/libgnucash/engine/Query.cpp +++ b/libgnucash/engine/Query.cpp @@ -502,6 +502,44 @@ xaccQueryAddClearedMatch(QofQuery * q, cleared_match_t how, QofQueryOp op) qof_query_add_term (q, param_list, pred_data, op); } +cleared_match_t +xaccQueryGetClearedMatch(QofQuery * q) +{ + QofQueryPredData *term_data; + cleared_match_t cleared_match = CLEARED_ALL; + GSList *param_list; + GSList *terms, *tmp; + char *chars = nullptr; + + param_list = qof_query_build_param_list (SPLIT_RECONCILE, nullptr); + terms = qof_query_get_term_type (q, param_list); + g_slist_free (param_list); + + for (tmp = terms; tmp; tmp = g_slist_next (tmp)) + { + term_data = static_cast(tmp->data); + + if (qof_query_char_predicate_get_char (term_data, &chars)) + { + cleared_match = CLEARED_NONE; + + if (strstr (chars, "c")) + cleared_match = (cleared_match_t)(cleared_match | CLEARED_CLEARED); + if (strstr (chars, "y")) + cleared_match = (cleared_match_t)(cleared_match | CLEARED_RECONCILED); + if (strstr (chars, "f")) + cleared_match = (cleared_match_t)(cleared_match | CLEARED_FROZEN); + if (strstr (chars, "n")) + cleared_match = (cleared_match_t)(cleared_match | CLEARED_NO); + if (strstr (chars, "v")) + cleared_match = (cleared_match_t)(cleared_match | CLEARED_VOIDED); + } + } + g_slist_free (terms); + + return cleared_match; +} + void xaccQueryAddGUIDMatch(QofQuery * q, const GncGUID *guid, QofIdType id_type, QofQueryOp op) @@ -532,8 +570,8 @@ xaccQueryAddGUIDMatch(QofQuery * q, const GncGUID *guid, void xaccQueryAddClosingTransMatch(QofQuery *q, gboolean value, QofQueryOp op) { - GSList *param_list; - + GSList *param_list; + param_list = qof_query_build_param_list(SPLIT_TRANS, TRANS_IS_CLOSING, nullptr); qof_query_add_boolean_match(q, param_list, value, op); } diff --git a/libgnucash/engine/Query.h b/libgnucash/engine/Query.h index 096e4f6af8..e23ff604a6 100644 --- a/libgnucash/engine/Query.h +++ b/libgnucash/engine/Query.h @@ -180,6 +180,8 @@ typedef enum } cleared_match_t; void xaccQueryAddClearedMatch(QofQuery * q, cleared_match_t how, QofQueryOp op); +cleared_match_t xaccQueryGetClearedMatch(QofQuery * q); + void xaccQueryAddGUIDMatch(QofQuery * q, const GncGUID *guid, QofIdType id_type, QofQueryOp op); diff --git a/libgnucash/engine/qofquerycore.cpp b/libgnucash/engine/qofquerycore.cpp index 4b4aeec279..4d67271bcf 100644 --- a/libgnucash/engine/qofquerycore.cpp +++ b/libgnucash/engine/qofquerycore.cpp @@ -1205,6 +1205,18 @@ qof_query_char_predicate (QofCharMatch options, const char *chars) return ((QofQueryPredData*)pdata); } +gboolean +qof_query_char_predicate_get_char (const QofQueryPredData *pd, char **chars) +{ + const query_char_t pdata = (const query_char_t)pd; + + if (pdata->pd.type_name != query_char_type) + return FALSE; + + *chars = g_strdup (pdata->char_list); + return TRUE; +} + static char * char_to_string (gpointer object, QofParam *getter) { diff --git a/libgnucash/engine/qofquerycore.h b/libgnucash/engine/qofquerycore.h index 152fb0aa12..a92b47b1bc 100644 --- a/libgnucash/engine/qofquerycore.h +++ b/libgnucash/engine/qofquerycore.h @@ -184,6 +184,8 @@ void qof_query_core_predicate_free (QofQueryPredData *pdata); /** Retrieve a predicate. */ gboolean qof_query_date_predicate_get_date (const QofQueryPredData *pd, time64 *date); +gboolean qof_query_char_predicate_get_char (const QofQueryPredData *pd, char **chars); + /** Return a printable string for a core data object. Caller needs * to g_free() the returned string. */