diff --git a/gnucash/register/register-gnome/gnucash-item-edit.c b/gnucash/register/register-gnome/gnucash-item-edit.c index 3ea0de3103..9fb4f35c04 100644 --- a/gnucash/register/register-gnome/gnucash-item-edit.c +++ b/gnucash/register/register-gnome/gnucash-item-edit.c @@ -40,6 +40,7 @@ #include "gnucash-sheetP.h" #include "gnucash-style.h" +#include "gnc-ui-util.h" /* The arguments we take */ enum @@ -398,7 +399,43 @@ gnc_item_edit_copy_clipboard (GncItemEdit *item_edit) void gnc_item_edit_paste_clipboard (GncItemEdit *item_edit) { - gtk_editable_paste_clipboard(GTK_EDITABLE(item_edit->editor)); + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(item_edit->editor), + GDK_SELECTION_CLIPBOARD); + gchar *text = gtk_clipboard_wait_for_text (clipboard); + gchar *filtered_text; + gint start_pos, end_pos; + gint position; + + if (!text) + return; + + filtered_text = gnc_filter_text_for_control_chars (text); + + if (!filtered_text) + { + g_free (text); + return; + } + + position = gtk_editable_get_position (GTK_EDITABLE(item_edit->editor)); + + if (gtk_editable_get_selection_bounds (GTK_EDITABLE(item_edit->editor), + &start_pos, &end_pos)) + { + position = start_pos; + + gtk_editable_delete_selection (GTK_EDITABLE(item_edit->editor)); + gtk_editable_insert_text (GTK_EDITABLE(item_edit->editor), + filtered_text, -1, &position); + } + else + gtk_editable_insert_text (GTK_EDITABLE(item_edit->editor), + filtered_text, -1, &position); + + gtk_editable_set_position (GTK_EDITABLE(item_edit->editor), position); + + g_free (text); + g_free (filtered_text); } diff --git a/libgnucash/app-utils/gnc-ui-util.c b/libgnucash/app-utils/gnc-ui-util.c index 8ab9dd7fb3..9fc8ae0b12 100644 --- a/libgnucash/app-utils/gnc-ui-util.c +++ b/libgnucash/app-utils/gnc-ui-util.c @@ -2663,3 +2663,67 @@ gnc_ui_util_remove_registered_prefs (void) GNC_PREF_AUTO_DECIMAL_PLACES, gnc_set_auto_decimal_places, NULL); } + +static gboolean +unichar_is_cntrl (gunichar uc) +{ + if (uc < 0x20 || (uc > 0x7e && uc < 0xa0)) + return TRUE; + else + return FALSE; +} + +gchar * +gnc_filter_text_for_control_chars (const gchar *text) +{ + gchar *normal_text, *nt; + GString *filtered; + gboolean cntrl = FALSE; + gboolean text_found = FALSE; + + if (!text) + return NULL; + + if (!g_utf8_validate (text, -1, NULL)) + return NULL; + + normal_text = g_utf8_normalize (text, -1, G_NORMALIZE_ALL_COMPOSE); + + filtered = g_string_sized_new (strlen (normal_text) + 1); + + nt = normal_text; + + while (*nt) + { + gunichar uc = g_utf8_get_char (nt); + + // check for starting with control characters + if (unichar_is_cntrl (uc) && !text_found) + { + nt = g_utf8_next_char (nt); + continue; + } + // check for alpha, num and punctuation + if (!unichar_is_cntrl (uc)) + { + filtered = g_string_append_unichar (filtered, uc); + text_found = TRUE; + } + // check for control characters after text + if (unichar_is_cntrl (uc)) + cntrl = TRUE; + + nt = g_utf8_next_char (nt); + + if (cntrl) // if control characters in text replace with space + { + gunichar uc2 = g_utf8_get_char (nt); + + if (!unichar_is_cntrl (uc2)) + filtered = g_string_append_unichar (filtered, ' '); + } + cntrl = FALSE; + } + g_free (normal_text); + return g_string_free (filtered, FALSE); +} diff --git a/libgnucash/app-utils/gnc-ui-util.h b/libgnucash/app-utils/gnc-ui-util.h index 40c99f7e14..c400c06378 100644 --- a/libgnucash/app-utils/gnc-ui-util.h +++ b/libgnucash/app-utils/gnc-ui-util.h @@ -397,6 +397,15 @@ void gnc_ui_util_init (void); void gnc_ui_util_remove_registered_prefs (void); +/** Returns the incoming text removed of control characters + * + * @param incoming_text The text to filter + * + * @return The incoming text filtered of control characters to be + * freed by the caller. +*/ +gchar * gnc_filter_text_for_control_chars (const gchar *incoming_text); + #endif /** @} */ /** @} */