gnucash stable: Multiple changes pushed
Christopher Lam
clam at code.gnucash.org
Sat Sep 16 08:51:00 EDT 2023
Updated via https://github.com/Gnucash/gnucash/commit/d38bfe0e (commit)
via https://github.com/Gnucash/gnucash/commit/5a8ee33f (commit)
via https://github.com/Gnucash/gnucash/commit/49c3c5dc (commit)
via https://github.com/Gnucash/gnucash/commit/757c1cac (commit)
via https://github.com/Gnucash/gnucash/commit/0191b5f7 (commit)
from https://github.com/Gnucash/gnucash/commit/a81bc72f (commit)
commit d38bfe0e9d78f238af68775b0d6707b4239e02a6
Merge: a81bc72fb1 5a8ee33f06
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Sat Sep 16 20:50:17 2023 +0800
Merge branch 'stable-autoclear' into stable #1769
commit 5a8ee33f064de69d2a7da537377dd76349d72046
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Thu Sep 14 22:30:48 2023 +0800
[test-autoclear] plug memory leaks
diff --git a/gnucash/gnome-utils/test/test-autoclear.cpp b/gnucash/gnome-utils/test/test-autoclear.cpp
index 6a41b267ca..a13d92512e 100644
--- a/gnucash/gnome-utils/test/test-autoclear.cpp
+++ b/gnucash/gnome-utils/test/test-autoclear.cpp
@@ -145,12 +145,15 @@ TEST_P(AutoClearTest, DoesAutoClear) {
xaccSplitSetReconcile(split, CREC);
}
+ g_list_free (splits_to_clear);
+
ASSERT_STREQ(err, t.expectedErr);
if (t.expectedErr == NULL) {
gnc_numeric c = xaccAccountGetClearedBalance(m_account);
ASSERT_EQ(c.num, t.amount);
ASSERT_EQ(c.denom, DENOM);
}
+ g_free (err);
}
}
commit 49c3c5dc2ebffb9246062942ac20d37152c46caf
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Wed Sep 13 07:20:39 2023 +0800
[gnc-autoclear] Store gnc_numeric.num only in GHashTable
no need for extra alloc
diff --git a/gnucash/gnome-utils/gnc-autoclear.c b/gnucash/gnome-utils/gnc-autoclear.c
index 05a370e525..b2c249d744 100644
--- a/gnucash/gnome-utils/gnc-autoclear.c
+++ b/gnucash/gnome-utils/gnc-autoclear.c
@@ -47,19 +47,6 @@ typedef enum
#define log_module "autoclear"
-static gboolean
-numeric_equal (gnc_numeric *n1, gnc_numeric *n2)
-{
- return gnc_numeric_equal (*n1, *n2);
-}
-
-static guint
-numeric_hash (gnc_numeric *n1)
-{
- gdouble d1 = gnc_numeric_to_double (*n1);
- return g_double_hash (&d1);
-}
-
typedef struct
{
GList *worklist;
@@ -81,7 +68,7 @@ make_workitem (GHashTable *hash, gnc_numeric amount,
{
WorkItem *item = g_new0 (WorkItem, 1);
item->reachable_amount = amount;
- if (g_hash_table_lookup (hash, &amount) || splits == DUP_LIST)
+ if (g_hash_table_lookup (hash, GINT_TO_POINTER (amount.num)) || splits == DUP_LIST)
item->list_of_splits = DUP_LIST;
else
item->list_of_splits = g_list_prepend (g_list_copy (splits), split);
@@ -89,19 +76,19 @@ make_workitem (GHashTable *hash, gnc_numeric amount,
}
static void
-sack_foreach_func (gnc_numeric *thisvalue, GList *splits, sack_data *data)
+sack_foreach_func (gint thisvalue_num, GList *splits, sack_data *data)
{
gnc_numeric itemval = xaccSplitGetAmount (data->split);
- gnc_numeric new_value = gnc_numeric_add_fixed (*thisvalue, itemval);
+ gnc_numeric this_value = gnc_numeric_create (thisvalue_num, itemval.denom);
+ gnc_numeric new_value = gnc_numeric_add_fixed (this_value, itemval);
WorkItem *item = make_workitem (data->sack, new_value, data->split, splits);
data->worklist = g_list_prepend (data->worklist, item);
}
static void
-sack_free (gnc_numeric *thisvalue, GList *splits, sack_data *data)
+sack_free (gpointer thisvalue_num, GList *splits, sack_data *data)
{
- g_free (thisvalue);
if (splits != DUP_LIST)
g_list_free (splits);
}
@@ -109,14 +96,14 @@ sack_free (gnc_numeric *thisvalue, GList *splits, sack_data *data)
static void
process_work (WorkItem *item, GHashTable *sack)
{
- GList *existing = g_hash_table_lookup (sack, &item->reachable_amount);
+ GList *existing = g_hash_table_lookup (sack, GINT_TO_POINTER(item->reachable_amount.num));
if (existing && existing != DUP_LIST)
{
DEBUG ("removing existing for %6.2f\n",
gnc_numeric_to_double (item->reachable_amount));
g_list_free (existing);
}
- g_hash_table_insert (sack, &item->reachable_amount, item->list_of_splits);
+ g_hash_table_insert (sack, GINT_TO_POINTER(item->reachable_amount.num), item->list_of_splits);
}
gboolean
@@ -131,18 +118,23 @@ gnc_autoclear_get_splits (Account *account, gnc_numeric toclear_value,
g_return_val_if_fail (GNC_IS_ACCOUNT (account), FALSE);
g_return_val_if_fail (splits != NULL, FALSE);
- sack = g_hash_table_new ((GHashFunc) numeric_hash, (GEqualFunc) numeric_equal);
+ sack = g_hash_table_new (NULL, NULL);
DUP_LIST = g_list_prepend (NULL, NULL);
/* Extract which splits are not cleared and compute the amount we have to clear */
for (GList *node = xaccAccountGetSplitList (account); node; node = node->next)
{
Split *split = (Split *)node->data;
+ gnc_numeric amount = xaccSplitGetAmount (split);
+ if (amount.denom != toclear_value.denom)
+ {
+ g_set_error (error, autoclear_quark, AUTOCLEAR_NOP, "Split amount and toclear amount have different denoms");
+ goto skip_knapsack;
+ }
if (xaccSplitGetReconcile (split) != NREC)
- toclear_value = gnc_numeric_sub_fixed
- (toclear_value, xaccSplitGetAmount (split));
- else if (gnc_numeric_zero_p (xaccSplitGetAmount (split)))
+ toclear_value = gnc_numeric_sub_fixed (toclear_value, amount);
+ else if (gnc_numeric_zero_p (amount))
DEBUG ("skipping zero-amount split %p", split);
else if (end_date != INT64_MAX &&
xaccTransGetDate (xaccSplitGetParent (split)) > end_date)
@@ -179,7 +171,7 @@ gnc_autoclear_get_splits (Account *account, gnc_numeric toclear_value,
_("Too many uncleared splits"));
goto skip_knapsack;
}
- else if (g_hash_table_lookup (sack, &toclear_value) == DUP_LIST)
+ else if (g_hash_table_lookup (sack, GINT_TO_POINTER(toclear_value.num)) == DUP_LIST)
{
g_set_error (error, autoclear_quark, AUTOCLEAR_MULTIPLE,
_("Cannot uniquely clear splits. Found multiple possibilities."));
@@ -187,7 +179,7 @@ gnc_autoclear_get_splits (Account *account, gnc_numeric toclear_value,
}
}
- toclear_list = g_hash_table_lookup (sack, &toclear_value);
+ toclear_list = g_hash_table_lookup (sack, GINT_TO_POINTER(toclear_value.num));
/* Check solution */
if (!toclear_list)
commit 757c1cac3156ade45458333fabf677948bc04eaa
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Wed Sep 13 07:02:12 2023 +0800
[gnc-autoclear] [upgrade] add ability to clear same-amount splits
diff --git a/gnucash/gnome-utils/gnc-autoclear.c b/gnucash/gnome-utils/gnc-autoclear.c
index fbd5a2dffa..05a370e525 100644
--- a/gnucash/gnome-utils/gnc-autoclear.c
+++ b/gnucash/gnome-utils/gnc-autoclear.c
@@ -2,6 +2,7 @@
* gnc-autoclear.c -- Knapsack algorithm functions *
* *
* Copyright 2020 Cristian Klein <cristian at kleinlabs.eu> *
+ * Modified 2021 Christopher Lam to clear same-amount splits *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -27,6 +28,7 @@
#include "Account.h"
#include "Split.h"
+#include "Transaction.h"
#include "gncOwner.h"
#include "qof.h"
#include "gnc-autoclear.h"
@@ -43,36 +45,78 @@ typedef enum
#define MAXIMUM_SACK_SIZE 1000000
+#define log_module "autoclear"
+
static gboolean
-ght_gnc_numeric_equal(gconstpointer v1, gconstpointer v2)
+numeric_equal (gnc_numeric *n1, gnc_numeric *n2)
{
- gnc_numeric n1 = *(gnc_numeric *)v1, n2 = *(gnc_numeric *)v2;
- return gnc_numeric_equal(n1, n2);
+ return gnc_numeric_equal (*n1, *n2);
}
static guint
-ght_gnc_numeric_hash(gconstpointer v1)
+numeric_hash (gnc_numeric *n1)
{
- gnc_numeric n1 = *(gnc_numeric *)v1;
- gdouble d1 = gnc_numeric_to_double(n1);
+ gdouble d1 = gnc_numeric_to_double (*n1);
return g_double_hash (&d1);
}
-typedef struct _sack_foreach_data_t
+typedef struct
+{
+ GList *worklist;
+ GHashTable *sack;
+ Split *split;
+} sack_data;
+
+typedef struct
{
- gnc_numeric split_value;
- GList *reachable_list;
-} *sack_foreach_data_t;
+ gnc_numeric reachable_amount;
+ GList *list_of_splits;
+} WorkItem;
+
+static GList *DUP_LIST;
+
+static WorkItem *
+make_workitem (GHashTable *hash, gnc_numeric amount,
+ Split *split, GList *splits)
+{
+ WorkItem *item = g_new0 (WorkItem, 1);
+ item->reachable_amount = amount;
+ if (g_hash_table_lookup (hash, &amount) || splits == DUP_LIST)
+ item->list_of_splits = DUP_LIST;
+ else
+ item->list_of_splits = g_list_prepend (g_list_copy (splits), split);
+ return item;
+}
+
+static void
+sack_foreach_func (gnc_numeric *thisvalue, GList *splits, sack_data *data)
+{
+ gnc_numeric itemval = xaccSplitGetAmount (data->split);
+ gnc_numeric new_value = gnc_numeric_add_fixed (*thisvalue, itemval);
+ WorkItem *item = make_workitem (data->sack, new_value, data->split, splits);
+
+ data->worklist = g_list_prepend (data->worklist, item);
+}
-static void sack_foreach_func(gpointer key, gpointer value, gpointer user_data)
+static void
+sack_free (gnc_numeric *thisvalue, GList *splits, sack_data *data)
{
- sack_foreach_data_t data = (sack_foreach_data_t) user_data;
- gnc_numeric thisvalue = *(gnc_numeric *) key;
- gnc_numeric reachable_value = gnc_numeric_add_fixed (thisvalue, data->split_value);
- gnc_numeric* new_value = g_new(gnc_numeric, 1);
+ g_free (thisvalue);
+ if (splits != DUP_LIST)
+ g_list_free (splits);
+}
- *new_value = reachable_value;
- data->reachable_list = g_list_prepend(data->reachable_list, new_value);
+static void
+process_work (WorkItem *item, GHashTable *sack)
+{
+ GList *existing = g_hash_table_lookup (sack, &item->reachable_amount);
+ if (existing && existing != DUP_LIST)
+ {
+ DEBUG ("removing existing for %6.2f\n",
+ gnc_numeric_to_double (item->reachable_amount));
+ g_list_free (existing);
+ }
+ g_hash_table_insert (sack, &item->reachable_amount, item->list_of_splits);
}
gboolean
@@ -82,25 +126,29 @@ gnc_autoclear_get_splits (Account *account, gnc_numeric toclear_value,
{
GList *nc_list = NULL, *toclear_list = NULL;
GHashTable *sack;
- gboolean success = FALSE;
GQuark autoclear_quark = g_quark_from_static_string ("autoclear");
- guint sack_size = 0;
g_return_val_if_fail (GNC_IS_ACCOUNT (account), FALSE);
+ g_return_val_if_fail (splits != NULL, FALSE);
- sack = g_hash_table_new_full (ght_gnc_numeric_hash, ght_gnc_numeric_equal,
- g_free, NULL);
+ sack = g_hash_table_new ((GHashFunc) numeric_hash, (GEqualFunc) numeric_equal);
+ DUP_LIST = g_list_prepend (NULL, NULL);
/* Extract which splits are not cleared and compute the amount we have to clear */
for (GList *node = xaccAccountGetSplitList (account); node; node = node->next)
{
Split *split = (Split *)node->data;
- if (xaccSplitGetReconcile (split) == NREC)
- nc_list = g_list_prepend (nc_list, split);
- else
+ if (xaccSplitGetReconcile (split) != NREC)
toclear_value = gnc_numeric_sub_fixed
(toclear_value, xaccSplitGetAmount (split));
+ else if (gnc_numeric_zero_p (xaccSplitGetAmount (split)))
+ DEBUG ("skipping zero-amount split %p", split);
+ else if (end_date != INT64_MAX &&
+ xaccTransGetDate (xaccSplitGetParent (split)) > end_date)
+ DEBUG ("skipping split after statement_date %p", split);
+ else
+ nc_list = g_list_prepend (nc_list, split);
}
if (gnc_numeric_zero_p (toclear_value))
@@ -109,95 +157,55 @@ gnc_autoclear_get_splits (Account *account, gnc_numeric toclear_value,
_("Account is already at Auto-Clear Balance."));
goto skip_knapsack;
}
-
- /* Run knapsack */
- /* Entries in the hash table are:
- * - key = amount to which we know how to clear (freed by GHashTable)
- * - value = last split we used to clear this amount (not managed by GHashTable)
- */
- for (GList *node = nc_list; node; node = node->next)
+ else if (!nc_list)
{
- Split *split = (Split *)node->data;
- gnc_numeric split_value = xaccSplitGetAmount (split);
- gnc_numeric *new_value = g_new(gnc_numeric, 1);
-
- struct _sack_foreach_data_t s_data[1];
- s_data->split_value = split_value;
- s_data->reachable_list = NULL;
-
- /* For each value in the sack, compute a new reachable value */
- g_hash_table_foreach (sack, sack_foreach_func, s_data);
-
- /* Add the value of the split itself to the reachable_list */
- *new_value = split_value;
- s_data->reachable_list = g_list_prepend
- (s_data->reachable_list, new_value);
-
- /* Add everything to the sack, looking out for duplicates */
- for (GList *s_node = s_data->reachable_list; s_node; s_node = s_node->next)
- {
- gnc_numeric *reachable_value = s_node->data;
-
- /* Check if it already exists */
- if (g_hash_table_lookup_extended (sack, reachable_value, NULL, NULL))
- {
- /* If yes, we are in trouble, we reached an amount
- using two solutions */
- g_hash_table_insert (sack, reachable_value, NULL);
- }
- else
- {
- g_hash_table_insert (sack, reachable_value, split);
- sack_size++;
-
- if (sack_size > MAXIMUM_SACK_SIZE)
- {
- g_set_error (error, autoclear_quark, AUTOCLEAR_OVERLOAD,
- _("Too many uncleared splits"));
- goto skip_knapsack;
- }
- }
- }
- g_list_free (s_data->reachable_list);
+ g_set_error (error, autoclear_quark, AUTOCLEAR_NOP,
+ _("No uncleared splits found."));
+ goto skip_knapsack;
}
- /* Check solution */
- while (!gnc_numeric_zero_p (toclear_value))
+ for (GList *node = nc_list; node; node = node->next)
{
- Split *split = NULL;
+ Split *split = (Split *)node->data;
+ WorkItem *item = make_workitem (sack, xaccSplitGetAmount (split), split, NULL);
+ sack_data s_data = { g_list_prepend (NULL, item), sack, split };
- if (!g_hash_table_lookup_extended (sack, &toclear_value,
- NULL, (gpointer) &split))
+ g_hash_table_foreach (sack, (GHFunc) sack_foreach_func, &s_data);
+ g_list_foreach (s_data.worklist, (GFunc) process_work, sack);
+ g_list_free_full (s_data.worklist, g_free);
+ if (g_hash_table_size (sack) > MAXIMUM_SACK_SIZE)
{
- g_set_error (error, autoclear_quark, AUTOCLEAR_UNABLE,
- _("The selected amount cannot be cleared."));
+ g_set_error (error, autoclear_quark, AUTOCLEAR_OVERLOAD,
+ _("Too many uncleared splits"));
goto skip_knapsack;
}
-
- if (!split)
+ else if (g_hash_table_lookup (sack, &toclear_value) == DUP_LIST)
{
g_set_error (error, autoclear_quark, AUTOCLEAR_MULTIPLE,
_("Cannot uniquely clear splits. Found multiple possibilities."));
goto skip_knapsack;
}
+ }
- toclear_list = g_list_prepend (toclear_list, split);
- toclear_value = gnc_numeric_sub_fixed (toclear_value,
- xaccSplitGetAmount (split));
+ toclear_list = g_hash_table_lookup (sack, &toclear_value);
+
+ /* Check solution */
+ if (!toclear_list)
+ {
+ g_set_error (error, autoclear_quark, AUTOCLEAR_UNABLE,
+ _("The selected amount cannot be cleared."));
+ goto skip_knapsack;
}
- success = TRUE;
+ else
+ /* copy GList because GHashTable value will be freed */
+ *splits = g_list_copy (toclear_list);
skip_knapsack:
+ g_hash_table_foreach (sack, (GHFunc) sack_free, NULL);
g_hash_table_destroy (sack);
g_list_free (nc_list);
+ g_list_free (DUP_LIST);
- if (!success)
- {
- g_list_free (toclear_list);
- toclear_list = NULL;
- }
-
- *splits = toclear_list;
return (toclear_list != NULL);
}
@@ -209,8 +217,8 @@ gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
GError *error = NULL;
GList *splits = NULL;
- gnc_autoclear_get_splits (account, toclear_value,
- &splits, &error);
+ gnc_autoclear_get_splits (account, toclear_value, INT64_MAX,
+ &splits, &error, NULL);
if (error)
{
diff --git a/gnucash/gnome-utils/test/test-autoclear.cpp b/gnucash/gnome-utils/test/test-autoclear.cpp
index 288074e900..6a41b267ca 100644
--- a/gnucash/gnome-utils/test/test-autoclear.cpp
+++ b/gnucash/gnome-utils/test/test-autoclear.cpp
@@ -100,9 +100,8 @@ TestCase ambiguousTestCase = {
{ -10, "Cannot uniquely clear splits. Found multiple possibilities." },
{ -20, "Cannot uniquely clear splits. Found multiple possibilities." },
- // Forbid auto-clear to be too smart. We expect the user to manually deal
- // with such situations.
- { -30, "Cannot uniquely clear splits. Found multiple possibilities." },
+ // -30 can be cleared by returning all three -10 splits
+ { -30, nullptr },
},
};
commit 0191b5f70b20eb8118775163bfbd408289d91333
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Fri Oct 29 22:28:09 2021 +0800
[gnc-autoclear] use GError to signal errors
diff --git a/gnucash/gnome-utils/gnc-autoclear.c b/gnucash/gnome-utils/gnc-autoclear.c
index 34cb35b8ac..fbd5a2dffa 100644
--- a/gnucash/gnome-utils/gnc-autoclear.c
+++ b/gnucash/gnome-utils/gnc-autoclear.c
@@ -33,6 +33,14 @@
/* the following functions are used in window-autoclear: */
+typedef enum
+{
+ AUTOCLEAR_OVERLOAD = 1,
+ AUTOCLEAR_UNABLE,
+ AUTOCLEAR_MULTIPLE,
+ AUTOCLEAR_NOP,
+} autoclear_error_type;
+
#define MAXIMUM_SACK_SIZE 1000000
static gboolean
@@ -67,16 +75,18 @@ static void sack_foreach_func(gpointer key, gpointer value, gpointer user_data)
data->reachable_list = g_list_prepend(data->reachable_list, new_value);
}
-GList *
-gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
- gchar **errmsg)
+gboolean
+gnc_autoclear_get_splits (Account *account, gnc_numeric toclear_value,
+ time64 end_date,
+ GList **splits, GError **error, GtkLabel *label)
{
GList *nc_list = NULL, *toclear_list = NULL;
GHashTable *sack;
- gchar *msg = NULL;
+ gboolean success = FALSE;
+ GQuark autoclear_quark = g_quark_from_static_string ("autoclear");
guint sack_size = 0;
- g_return_val_if_fail (GNC_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (GNC_IS_ACCOUNT (account), FALSE);
sack = g_hash_table_new_full (ght_gnc_numeric_hash, ght_gnc_numeric_equal,
g_free, NULL);
@@ -95,7 +105,8 @@ gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
if (gnc_numeric_zero_p (toclear_value))
{
- msg = _("Account is already at Auto-Clear Balance.");
+ g_set_error (error, autoclear_quark, AUTOCLEAR_NOP,
+ _("Account is already at Auto-Clear Balance."));
goto skip_knapsack;
}
@@ -141,7 +152,8 @@ gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
if (sack_size > MAXIMUM_SACK_SIZE)
{
- msg = _("Too many uncleared splits");
+ g_set_error (error, autoclear_quark, AUTOCLEAR_OVERLOAD,
+ _("Too many uncleared splits"));
goto skip_knapsack;
}
}
@@ -157,13 +169,15 @@ gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
if (!g_hash_table_lookup_extended (sack, &toclear_value,
NULL, (gpointer) &split))
{
- msg = _("The selected amount cannot be cleared.");
+ g_set_error (error, autoclear_quark, AUTOCLEAR_UNABLE,
+ _("The selected amount cannot be cleared."));
goto skip_knapsack;
}
if (!split)
{
- msg = _("Cannot uniquely clear splits. Found multiple possibilities.");
+ g_set_error (error, autoclear_quark, AUTOCLEAR_MULTIPLE,
+ _("Cannot uniquely clear splits. Found multiple possibilities."));
goto skip_knapsack;
}
@@ -171,18 +185,40 @@ gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
toclear_value = gnc_numeric_sub_fixed (toclear_value,
xaccSplitGetAmount (split));
}
+ success = TRUE;
skip_knapsack:
g_hash_table_destroy (sack);
g_list_free (nc_list);
- if (msg)
+ if (!success)
{
- *errmsg = g_strdup (msg);
g_list_free (toclear_list);
+ toclear_list = NULL;
+ }
+
+ *splits = toclear_list;
+ return (toclear_list != NULL);
+}
+
+
+GList *
+gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
+ gchar **errmsg)
+{
+ GError *error = NULL;
+ GList *splits = NULL;
+
+ gnc_autoclear_get_splits (account, toclear_value,
+ &splits, &error);
+
+ if (error)
+ {
+ *errmsg = g_strdup (error->message);
+ g_error_free (error);
return NULL;
}
*errmsg = NULL;
- return toclear_list;
+ return splits;
}
diff --git a/gnucash/gnome-utils/gnc-autoclear.h b/gnucash/gnome-utils/gnc-autoclear.h
index ac9807d12e..1f53629748 100644
--- a/gnucash/gnome-utils/gnc-autoclear.h
+++ b/gnucash/gnome-utils/gnc-autoclear.h
@@ -25,6 +25,8 @@
#define GNC_AUTOCLEAR_H
#include <glib.h>
+#include <stdint.h>
+#include <gtk/gtk.h>
#include <Account.h>
#ifdef __cplusplus
@@ -40,6 +42,12 @@ extern "C" {
GList * gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
gchar **errmsg);
+/* same as above, but returns TRUE if successful, and FALSE if
+ unsuccessful and sets GError appropriately */
+gboolean gnc_autoclear_get_splits (Account *account, gnc_numeric toclear_value,
+ time64 end_date,
+ GList **splits, GError **error, GtkLabel *label);
+
#ifdef __cplusplus
}
#endif
diff --git a/gnucash/gnome/window-autoclear.c b/gnucash/gnome/window-autoclear.c
index 8434872191..7f9cc18cf1 100644
--- a/gnucash/gnome/window-autoclear.c
+++ b/gnucash/gnome/window-autoclear.c
@@ -124,18 +124,12 @@ gnc_autoclear_window_ok_cb (GtkWidget *widget,
{
GList *toclear_list = NULL;
gnc_numeric toclear_value = gnc_numeric_error (GNC_ERROR_ARG);
- gchar *errmsg = NULL;
GError* error = NULL;
g_return_if_fail (widget && data);
/* test for valid value */
- if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT(data->end_value), &error))
- {
- errmsg = g_strdup (error->message);
- g_error_free (error);
- }
- else
+ if (gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT(data->end_value), &error))
{
toclear_value = gnc_amount_edit_get_amount(data->end_value);
@@ -145,19 +139,19 @@ gnc_autoclear_window_ok_cb (GtkWidget *widget,
toclear_value = gnc_numeric_convert
(toclear_value, xaccAccountGetCommoditySCU(data->account), GNC_HOW_RND_ROUND);
- toclear_list = gnc_account_get_autoclear_splits
- (data->account, toclear_value, &errmsg);
+ gnc_autoclear_get_splits (data->account, toclear_value, INT64_MAX,
+ &toclear_list, &error, data->status_label);
}
- if (errmsg)
+ if (error && error->message)
{
GtkWidget *entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT(data->end_value));
- gtk_label_set_text (data->status_label, errmsg);
+ gtk_label_set_text (data->status_label, error->message);
if (gnc_numeric_check (toclear_value) == 0)
gnc_amount_edit_set_amount (data->end_value, toclear_value);
gtk_widget_grab_focus (GTK_WIDGET(entry));
gnc_amount_edit_select_region (GNC_AMOUNT_EDIT(data->end_value), 0, -1);
- g_free (errmsg);
+ g_error_free (error);
}
else
{
Summary of changes:
gnucash/gnome-utils/gnc-autoclear.c | 232 ++++++++++++++++------------
gnucash/gnome-utils/gnc-autoclear.h | 8 +
gnucash/gnome-utils/test/test-autoclear.cpp | 8 +-
gnucash/gnome/window-autoclear.c | 18 +--
4 files changed, 153 insertions(+), 113 deletions(-)
More information about the gnucash-changes
mailing list