diff --git a/gnucash/gnome/dialog-sx-editor.c b/gnucash/gnome/dialog-sx-editor.c index 4c1a54ee91..f8144effed 100644 --- a/gnucash/gnome/dialog-sx-editor.c +++ b/gnucash/gnome/dialog-sx-editor.c @@ -1509,7 +1509,7 @@ schedXact_editor_populate (GncSxEditorDialog *sxed) if (splitList) { splitReg = gnc_ledger_display_get_split_register (sxed->ledger); - gnc_split_register_load (splitReg, splitList, NULL); + gnc_split_register_load (splitReg, splitList, NULL, NULL); } /* otherwise, use the existing stuff. */ g_list_free (splitList); } diff --git a/gnucash/register/ledger-core/gnc-ledger-display.c b/gnucash/register/ledger-core/gnc-ledger-display.c index bf0f48a183..ae632ef782 100644 --- a/gnucash/register/ledger-core/gnc-ledger-display.c +++ b/gnucash/register/ledger-core/gnc-ledger-display.c @@ -59,6 +59,7 @@ struct gnc_ledger_display GncGUID leader; Query* query; + Query* pre_filter_query; GNCLedgerDisplayType ld_type; @@ -444,7 +445,6 @@ gnc_ledger_display_gl (void) { Query* query; time64 start; - struct tm tm; GNCLedgerDisplay* ld; GHashTable *exclude_template_accounts_hash; @@ -463,11 +463,12 @@ gnc_ledger_display_gl (void) * See Gnome Bug 86302. * -- jsled */ // Exclude any template accounts for search register and gl - exclude_template_accounts (query, exclude_template_accounts_hash); + exclude_template_accounts (query, exclude_template_accounts_hash); + + // the default is to show last 30 days + static const time64 secs_per_thirty_days = 2592000; + start = gnc_time64_get_today_start () - secs_per_thirty_days; - gnc_tm_get_today_start (&tm); - tm.tm_mon--; /* Default the register to the last month's worth of transactions. */ - start = gnc_mktime (&tm); xaccQueryAddDateMatchTT (query, TRUE, start, FALSE, 0, @@ -655,6 +656,9 @@ close_handler (gpointer user_data) qof_query_destroy (ld->query); ld->query = NULL; + qof_query_destroy (ld->pre_filter_query); + ld->pre_filter_query = NULL; + g_free (ld); } @@ -834,6 +838,8 @@ gnc_ledger_display_internal (Account* lead_account, Query* q, else gnc_ledger_display_make_query (ld, limit, reg_type); + ld->pre_filter_query = qof_query_copy (ld->query); + ld->component_id = gnc_register_gui_component (klass, refresh_handler, close_handler, ld); @@ -854,7 +860,7 @@ gnc_ledger_display_internal (Account* lead_account, Query* q, * the query when we're not in focus yet. */ ld->loading = TRUE; - gnc_split_register_load (ld->reg, NULL, gnc_ledger_display_leader (ld)); + gnc_split_register_load (ld->reg, NULL, NULL, gnc_ledger_display_leader (ld)); ld->loading = FALSE; return ld; } @@ -888,6 +894,7 @@ static void gnc_ledger_display_refresh_internal (GNCLedgerDisplay* ld) { GList* splits; + GList* pre_filter_splits = NULL; if (ld->loading) return; @@ -899,6 +906,9 @@ gnc_ledger_display_refresh_internal (GNCLedgerDisplay* ld) */ splits = qof_query_run (ld->query); + if (!qof_query_equal (ld->query, ld->pre_filter_query)) + pre_filter_splits = qof_query_run (ld->pre_filter_query); + gnc_ledger_display_set_watches (ld, splits); if (!gnc_split_register_full_refresh_ok (ld->reg)) @@ -906,7 +916,7 @@ gnc_ledger_display_refresh_internal (GNCLedgerDisplay* ld) ld->loading = TRUE; - gnc_split_register_load (ld->reg, splits, + gnc_split_register_load (ld->reg, splits, pre_filter_splits, gnc_ledger_display_leader (ld)); ld->needs_refresh = FALSE; @@ -938,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); } @@ -953,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/gnucash/register/ledger-core/split-register-load.c b/gnucash/register/ledger-core/split-register-load.c index 1f756e07b0..d6963ed316 100644 --- a/gnucash/register/ledger-core/split-register-load.c +++ b/gnucash/register/ledger-core/split-register-load.c @@ -256,8 +256,9 @@ _find_split_with_parent_txn (gconstpointer a, gconstpointer b) return xaccSplitGetParent (split) == txn ? 0 : 1; } -static void add_quickfill_completions (TableLayout* layout, Transaction* trans, - Split* split, gboolean has_last_num) +static void +add_quickfill_completions (TableLayout* layout, Transaction* trans, + Split* split, gboolean has_last_num) { gnc_quickfill_cell_add_completion ( (QuickFillCell*) gnc_table_layout_get_cell (layout, NOTES_CELL), @@ -365,9 +366,30 @@ update_info (SRInfo* info, SplitRegister* reg) info->reg_loaded = TRUE; } +static void +add_completions_from_pre_filter_slist (TableLayout* layout, GList *pre_filter_slist, + gboolean first_pass, gboolean quickfill_setup, + gboolean has_last_num) +{ + GList *node; + + for (node = pre_filter_slist; node; node = node->next) + { + Split *split = node->data; + Transaction *trans = xaccSplitGetParent (split); + + gnc_completion_cell_add_menu_item ( + (CompletionCell*) gnc_table_layout_get_cell (layout, DESC_CELL), + xaccTransGetDescription (trans)); + + if (!first_pass && !quickfill_setup) + add_quickfill_completions (layout, trans, split, has_last_num); + } +} + void gnc_split_register_load (SplitRegister* reg, GList* slist, - Account* default_account) + GList* pre_filter_slist, Account* default_account) { SRInfo* info; Transaction* pending_trans; @@ -635,6 +657,13 @@ gnc_split_register_load (SplitRegister* reg, GList* slist, (CompletionCell*) gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), table->model->reverse_sort); + if (!info->first_pass && pre_filter_slist) + { + add_completions_from_pre_filter_slist (reg->table->layout, pre_filter_slist, + info->first_pass, info->quickfill_setup, + has_last_num); + } + /* populate the table */ for (node = slist; node; node = node->next) { @@ -752,12 +781,15 @@ gnc_split_register_load (SplitRegister* reg, GList* slist, /* On first load the split list is empty so fill up the quickfill cells * only on the next load. */ - if (!info->first_pass && !info->quickfill_setup) + if (!info->first_pass && !pre_filter_slist && !info->quickfill_setup) add_quickfill_completions (reg->table->layout, trans, split, has_last_num); - gnc_completion_cell_add_menu_item ( - (CompletionCell*) gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), - xaccTransGetDescription (trans)); + if (!info->first_pass && !pre_filter_slist) + { + gnc_completion_cell_add_menu_item ( + (CompletionCell*) gnc_table_layout_get_cell (reg->table->layout, DESC_CELL), + xaccTransGetDescription (trans)); + } if (trans == find_trans) new_trans_row = vcell_loc.virt_row; diff --git a/gnucash/register/ledger-core/split-register.h b/gnucash/register/ledger-core/split-register.h index 5274c6aaec..99b2a79cd8 100644 --- a/gnucash/register/ledger-core/split-register.h +++ b/gnucash/register/ledger-core/split-register.h @@ -530,10 +530,12 @@ void gnc_split_register_cancel_cursor_trans_changes (SplitRegister* reg); * * @param slist a list of splits * + * @param pre_filter_slist the list of splits before applying filter + * * @param default_account an account to provide defaults for the blank split */ void gnc_split_register_load (SplitRegister* reg, GList* slist, - Account* default_account); + GList* pre_filter_slist, Account* default_account); /** Copy the contents of the current cursor to a split. The split and * transaction that are updated are the ones associated with the 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. */