mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Add filter for currency symbol for GNCAmountEdit widget
When pasting an amount that includes the currency symbol the validation will silently fail which may lead to unusual behaviour.
This commit is contained in:
parent
db6f233705
commit
7ee9dac2e9
@ -246,6 +246,45 @@ gnc_amount_edit_new (void)
|
||||
return GTK_WIDGET(gae);
|
||||
}
|
||||
|
||||
static gint
|
||||
get_original_error_position (const gchar *string, const gchar *symbol,
|
||||
gint error_pos)
|
||||
{
|
||||
gint original_error_pos = error_pos;
|
||||
gint text_len;
|
||||
gint symbol_len;
|
||||
|
||||
if (error_pos == 0)
|
||||
return 0;
|
||||
|
||||
if (!string || !symbol)
|
||||
return error_pos;
|
||||
|
||||
if (g_strrstr (string, symbol) == NULL)
|
||||
return error_pos;
|
||||
|
||||
if (!g_utf8_validate (string, -1, NULL))
|
||||
return error_pos;
|
||||
|
||||
text_len = g_utf8_strlen (string, -1);
|
||||
symbol_len = g_utf8_strlen (symbol, -1);
|
||||
|
||||
for (gint x = 0; x < text_len; x++)
|
||||
{
|
||||
gchar *temp = g_utf8_offset_to_pointer (string, x);
|
||||
|
||||
if (g_str_has_prefix (temp, symbol))
|
||||
original_error_pos = original_error_pos + symbol_len;
|
||||
|
||||
if (x >= original_error_pos)
|
||||
break;
|
||||
|
||||
if (g_strrstr (temp, symbol) == NULL)
|
||||
break;
|
||||
}
|
||||
return original_error_pos;
|
||||
}
|
||||
|
||||
static inline GQuark
|
||||
exp_validate_quark (void)
|
||||
{
|
||||
@ -261,12 +300,20 @@ gnc_amount_edit_expr_is_valid (GNCAmountEdit *gae, gnc_numeric *amount,
|
||||
gboolean ok;
|
||||
gchar *err_msg = NULL;
|
||||
gint err_code;
|
||||
const gnc_commodity *comm;
|
||||
char *filtered_string;
|
||||
const gchar *symbol;
|
||||
|
||||
g_return_val_if_fail (gae != NULL, -1);
|
||||
g_return_val_if_fail (GNC_IS_AMOUNT_EDIT(gae), -1);
|
||||
|
||||
string = gtk_entry_get_text (GTK_ENTRY(gae));
|
||||
if (!string || *string == '\0')
|
||||
|
||||
comm = gae->print_info.commodity;
|
||||
|
||||
filtered_string = gnc_filter_text_for_currency_commodity (comm, string, &symbol);
|
||||
|
||||
if (!filtered_string || *filtered_string == '\0')
|
||||
{
|
||||
*amount = gnc_numeric_zero ();
|
||||
if (empty_ok)
|
||||
@ -276,15 +323,20 @@ gnc_amount_edit_expr_is_valid (GNCAmountEdit *gae, gnc_numeric *amount,
|
||||
}
|
||||
|
||||
error_loc = NULL;
|
||||
ok = gnc_exp_parser_parse (string, amount, &error_loc);
|
||||
ok = gnc_exp_parser_parse (filtered_string, amount, &error_loc);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
g_free (filtered_string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Not ok */
|
||||
if (error_loc != NULL)
|
||||
{
|
||||
err_code = error_loc - string;
|
||||
err_code = get_original_error_position (string, symbol,
|
||||
(error_loc - filtered_string));
|
||||
|
||||
err_msg = g_strdup_printf (_("An error occurred while processing '%s' at position %d"),
|
||||
string, err_code);
|
||||
}
|
||||
@ -298,6 +350,7 @@ gnc_amount_edit_expr_is_valid (GNCAmountEdit *gae, gnc_numeric *amount,
|
||||
if (error)
|
||||
g_set_error_literal (error, exp_validate_quark(), err_code, err_msg);
|
||||
|
||||
g_free (filtered_string);
|
||||
g_free (err_msg);
|
||||
return 1;
|
||||
}
|
||||
@ -332,6 +385,7 @@ gnc_amount_edit_evaluate (GNCAmountEdit *gae, GError **error)
|
||||
if (!gnc_numeric_equal (amount, old_amount))
|
||||
g_signal_emit (gae, amount_edit_signals [AMOUNT_CHANGED], 0);
|
||||
|
||||
gtk_editable_set_position (GTK_EDITABLE(gae), -1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2784,3 +2784,28 @@ gnc_filter_text_for_currency_symbol (const gchar *incoming_text,
|
||||
g_strfreev (split);
|
||||
return ret_text;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gnc_filter_text_for_currency_commodity (const gnc_commodity *comm,
|
||||
const gchar *incoming_text,
|
||||
const gchar **symbol)
|
||||
{
|
||||
if (!incoming_text)
|
||||
{
|
||||
*symbol = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!gnc_commodity_is_currency (comm))
|
||||
{
|
||||
*symbol = NULL;
|
||||
return g_strdup (incoming_text);
|
||||
}
|
||||
|
||||
if (comm)
|
||||
*symbol = gnc_commodity_get_nice_symbol (comm);
|
||||
else
|
||||
*symbol = gnc_commodity_get_nice_symbol (gnc_default_currency ());
|
||||
|
||||
return gnc_filter_text_for_currency_symbol (incoming_text, *symbol);
|
||||
}
|
||||
|
@ -433,6 +433,20 @@ void gnc_filter_text_set_cursor_position (const gchar *incoming_text,
|
||||
gchar * gnc_filter_text_for_currency_symbol (const gchar *incoming_text,
|
||||
const gchar *symbol);
|
||||
|
||||
/** Returns the incoming text removed of currency symbol
|
||||
*
|
||||
* @param comm commodity of entry if known
|
||||
*
|
||||
* @param incoming_text The text to filter
|
||||
*
|
||||
* @param symbol return the symbol used
|
||||
*
|
||||
* @return The incoming text with symbol removed to be freed by the caller
|
||||
*/
|
||||
gchar * gnc_filter_text_for_currency_commodity (const gnc_commodity *comm,
|
||||
const gchar *incoming_text,
|
||||
const gchar **symbol);
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
Loading…
Reference in New Issue
Block a user