mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Bug 796761 - Control characters can be pasted in register fields
If copied text includes control characters they are inserted when pasted which can cause alignment issues. This commit filters the clipboard text for control characters before it is pasted.
This commit is contained in:
parent
ec9cdd151d
commit
d55060c0fc
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
Loading…
Reference in New Issue
Block a user