[gnc-autoclear] use GError to signal errors

This commit is contained in:
Christopher Lam 2021-10-29 22:28:09 +08:00
parent fa84a8caa1
commit 0191b5f70b
3 changed files with 62 additions and 24 deletions

View File

@ -33,6 +33,14 @@
/* the following functions are used in window-autoclear: */ /* 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 #define MAXIMUM_SACK_SIZE 1000000
static gboolean 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); data->reachable_list = g_list_prepend(data->reachable_list, new_value);
} }
GList * gboolean
gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value, gnc_autoclear_get_splits (Account *account, gnc_numeric toclear_value,
gchar **errmsg) time64 end_date,
GList **splits, GError **error, GtkLabel *label)
{ {
GList *nc_list = NULL, *toclear_list = NULL; GList *nc_list = NULL, *toclear_list = NULL;
GHashTable *sack; GHashTable *sack;
gchar *msg = NULL; gboolean success = FALSE;
GQuark autoclear_quark = g_quark_from_static_string ("autoclear");
guint sack_size = 0; 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, sack = g_hash_table_new_full (ght_gnc_numeric_hash, ght_gnc_numeric_equal,
g_free, NULL); 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)) 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; goto skip_knapsack;
} }
@ -141,7 +152,8 @@ gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
if (sack_size > MAXIMUM_SACK_SIZE) 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; 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, if (!g_hash_table_lookup_extended (sack, &toclear_value,
NULL, (gpointer) &split)) 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; goto skip_knapsack;
} }
if (!split) 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; 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, toclear_value = gnc_numeric_sub_fixed (toclear_value,
xaccSplitGetAmount (split)); xaccSplitGetAmount (split));
} }
success = TRUE;
skip_knapsack: skip_knapsack:
g_hash_table_destroy (sack); g_hash_table_destroy (sack);
g_list_free (nc_list); g_list_free (nc_list);
if (msg) if (!success)
{ {
*errmsg = g_strdup (msg);
g_list_free (toclear_list); 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; return NULL;
} }
*errmsg = NULL; *errmsg = NULL;
return toclear_list; return splits;
} }

View File

@ -25,6 +25,8 @@
#define GNC_AUTOCLEAR_H #define GNC_AUTOCLEAR_H
#include <glib.h> #include <glib.h>
#include <stdint.h>
#include <gtk/gtk.h>
#include <Account.h> #include <Account.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -40,6 +42,12 @@ extern "C" {
GList * gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value, GList * gnc_account_get_autoclear_splits (Account *account, gnc_numeric toclear_value,
gchar **errmsg); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -124,18 +124,12 @@ gnc_autoclear_window_ok_cb (GtkWidget *widget,
{ {
GList *toclear_list = NULL; GList *toclear_list = NULL;
gnc_numeric toclear_value = gnc_numeric_error (GNC_ERROR_ARG); gnc_numeric toclear_value = gnc_numeric_error (GNC_ERROR_ARG);
gchar *errmsg = NULL;
GError* error = NULL; GError* error = NULL;
g_return_if_fail (widget && data); g_return_if_fail (widget && data);
/* test for valid value */ /* test for valid value */
if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT(data->end_value), &error)) if (gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT(data->end_value), &error))
{
errmsg = g_strdup (error->message);
g_error_free (error);
}
else
{ {
toclear_value = gnc_amount_edit_get_amount(data->end_value); 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 = gnc_numeric_convert
(toclear_value, xaccAccountGetCommoditySCU(data->account), GNC_HOW_RND_ROUND); (toclear_value, xaccAccountGetCommoditySCU(data->account), GNC_HOW_RND_ROUND);
toclear_list = gnc_account_get_autoclear_splits gnc_autoclear_get_splits (data->account, toclear_value, INT64_MAX,
(data->account, toclear_value, &errmsg); &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)); 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) if (gnc_numeric_check (toclear_value) == 0)
gnc_amount_edit_set_amount (data->end_value, toclear_value); gnc_amount_edit_set_amount (data->end_value, toclear_value);
gtk_widget_grab_focus (GTK_WIDGET(entry)); gtk_widget_grab_focus (GTK_WIDGET(entry));
gnc_amount_edit_select_region (GNC_AMOUNT_EDIT(data->end_value), 0, -1); gnc_amount_edit_select_region (GNC_AMOUNT_EDIT(data->end_value), 0, -1);
g_free (errmsg); g_error_free (error);
} }
else else
{ {