[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: */
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;
}

View File

@ -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

View File

@ -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
{