Parse the register monetary cells for a currency symbol

Add the ability to strip the currency symbol from a registry monetary
cell if it is pasted with one so it can be validated.
This commit is contained in:
Robert Fewell 2021-05-27 11:34:59 +01:00
parent 5779e72db4
commit 435bb1c76b
4 changed files with 151 additions and 23 deletions

View File

@ -115,8 +115,10 @@ gnc_formula_cell_leave(BasicCell *_cell)
&& strlen(str) != 0
&& !gnc_exp_parser_parse(str, &amount, &error_location))
{
gnc_warning_dialog(NULL, _("An error occurred while processing %s."),
str);//, (error_location - str));
gint error_position = error_location - str;
gnc_warning_dialog (gnc_ui_get_main_window (NULL),
_("An error occurred while processing '%s' at position %d"),
str, error_position);
}
}
@ -142,6 +144,10 @@ gnc_formula_cell_modify_verify( BasicCell *_cell,
const char *c;
gunichar uc;
gchar *filtered_newval;
const gchar *symbol = NULL;
gchar *tokens;
g_debug("%s, %d, %s, %d, %d, %d, %d",
change ? (gchar *)change : "(null)", change_len,
newval ? (gchar *)newval : "(null)", newval_len,
@ -157,30 +163,48 @@ gnc_formula_cell_modify_verify( BasicCell *_cell,
}
if (cell->print_info.monetary)
decimal_point = g_utf8_get_char(lc->mon_decimal_point);
else
decimal_point = g_utf8_get_char(lc->decimal_point);
{
const gnc_commodity *comm = cell->print_info.commodity;
if (cell->print_info.monetary)
decimal_point = g_utf8_get_char(lc->mon_decimal_point);
thousands_sep = g_utf8_get_char(lc->mon_thousands_sep);
if (comm)
symbol = gnc_commodity_get_nice_symbol (comm);
else
symbol = gnc_commodity_get_nice_symbol (gnc_default_currency ());
tokens = g_strconcat (toks, symbol, NULL);
}
else
{
decimal_point = g_utf8_get_char(lc->decimal_point);
thousands_sep = g_utf8_get_char(lc->thousands_sep);
tokens = g_strdup (toks);
}
c = change;
while (*c)
{
uc = g_utf8_get_char (c);
if (!g_unichar_isdigit (uc) &&
!g_unichar_isspace (uc) &&
!g_unichar_isalpha (uc) &&
(decimal_point != uc) &&
(thousands_sep != uc) &&
(g_utf8_strchr (toks, -1, uc) == NULL))
!g_unichar_isspace (uc) &&
!g_unichar_isalpha (uc) &&
(decimal_point != uc) &&
(thousands_sep != uc) &&
(g_utf8_strchr (tokens, -1, uc) == NULL))
{
g_free (tokens);
return;
}
c = g_utf8_next_char (c);
}
gnc_basic_cell_set_value_internal( &cell->cell, newval );
gnc_filter_text_set_cursor_position (newval, symbol, cursor_position);
filtered_newval = gnc_filter_text_for_currency_symbol (newval, symbol);
gnc_basic_cell_set_value_internal (&cell->cell, filtered_newval);
g_free (filtered_newval);
g_free (tokens);
}
static

View File

@ -83,18 +83,32 @@ gnc_price_cell_modify_verify (BasicCell *_cell,
const char *toks = "+-*/=()_";
gunichar decimal_point;
gunichar thousands_sep;
char *new_newval = g_strdup (newval);
gchar *filtered_newval;
const gchar *symbol = NULL;
gchar *tokens;
if (cell->print_info.monetary)
{
const gnc_commodity *comm = cell->print_info.commodity;
decimal_point = g_utf8_get_char(lc->mon_decimal_point);
else
decimal_point = g_utf8_get_char(lc->decimal_point);
if (cell->print_info.monetary)
thousands_sep = g_utf8_get_char(lc->mon_thousands_sep);
if (comm)
symbol = gnc_commodity_get_nice_symbol (comm);
else
symbol = gnc_commodity_get_nice_symbol (gnc_default_currency ());
tokens = g_strconcat (toks, symbol, NULL);
}
else
{
decimal_point = g_utf8_get_char(lc->decimal_point);
thousands_sep = g_utf8_get_char(lc->thousands_sep);
tokens = g_strdup (toks);
}
for (const char *c = change; c && *c; c = g_utf8_next_char (c))
{
gunichar uc = g_utf8_get_char (c);
@ -103,12 +117,18 @@ gnc_price_cell_modify_verify (BasicCell *_cell,
!g_unichar_isalpha (uc) &&
(decimal_point != uc) &&
(thousands_sep != uc) &&
(g_utf8_strchr (toks, -1, uc) == NULL))
(g_utf8_strchr (tokens, -1, uc) == NULL))
{
g_free (tokens);
return;
}
}
gnc_filter_text_set_cursor_position (newval, symbol, cursor_position);
filtered_newval = gnc_filter_text_for_currency_symbol (newval, symbol);
gnc_basic_cell_set_value_internal (_cell, filtered_newval);
g_free (filtered_newval);
g_free (tokens);
gnc_basic_cell_set_value_internal (_cell, new_newval);
g_free (new_newval);
*end_selection = *start_selection = *cursor_position;
cell->need_to_parse = TRUE;
}
@ -169,8 +189,9 @@ gnc_price_cell_leave (BasicCell *_cell)
error_position = gnc_price_cell_parse (cell, TRUE);
if (error_position != -1)
{
gnc_warning_dialog(NULL, _("An error occurred while processing %s."),
cell->cell.value);
gnc_warning_dialog (gnc_ui_get_main_window (NULL),
_("An error occurred while processing '%s' at position %d"),
cell->cell.value, error_position);
}
}

View File

@ -2727,3 +2727,59 @@ gnc_filter_text_for_control_chars (const gchar *text)
g_free (normal_text);
return g_string_free (filtered, FALSE);
}
void
gnc_filter_text_set_cursor_position (const gchar *incoming_text,
const gchar *symbol,
gint *cursor_position)
{
gint text_len;
gint num = 0;
if (*cursor_position == 0)
return;
if (!incoming_text || !symbol)
return;
if (g_strrstr (incoming_text, symbol) == NULL)
return;
text_len = g_utf8_strlen (incoming_text, -1);
for (gint x = 0; x < text_len; x++)
{
gchar *temp = g_utf8_offset_to_pointer (incoming_text, x);
if (g_str_has_prefix (temp, symbol))
num++;
if (g_strrstr (temp, symbol) == NULL)
break;
}
*cursor_position = *cursor_position - (num * g_utf8_strlen (symbol, -1));
}
gchar *
gnc_filter_text_for_currency_symbol (const gchar *incoming_text,
const gchar *symbol)
{
gchar *ret_text = NULL;
gchar **split;
if (!incoming_text)
return NULL;
if (!symbol)
return g_strdup (incoming_text);
if (g_strrstr (incoming_text, symbol) == NULL)
return g_strdup (incoming_text);
split = g_strsplit (incoming_text, symbol, -1);
ret_text = g_strjoinv (NULL, split);
g_strfreev (split);
return ret_text;
}

View File

@ -406,6 +406,33 @@ void gnc_ui_util_remove_registered_prefs (void);
*/
gchar * gnc_filter_text_for_control_chars (const gchar *incoming_text);
/** Updates cursor_position after removal of currency symbols
*
* @param incoming_text The text to filter
*
* @param symbol to remove
*
* @param cursor_position the posistion of cursor in the incoming text
*
* @return nothing
*/
void gnc_filter_text_set_cursor_position (const gchar *incoming_text,
const gchar *symbol,
gint *cursor_position);
/** Returns the incoming text removed of a currency symbol
*
* @param incoming_text The text to filter
*
* @param symbol to remove
*
* @param cursor_position the posistion of cursor in the incoming text
*
* @return The incoming text with symbol removed to be freed by the caller
*/
gchar * gnc_filter_text_for_currency_symbol (const gchar *incoming_text,
const gchar *symbol);
#endif
/** @} */
/** @} */