summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--configure.ac22
-rw-r--r--src/common/cfgfiles.c52
-rw-r--r--src/common/hexchat.h1
-rw-r--r--src/fe-gtk/Makefile.am6
-rw-r--r--src/fe-gtk/maingui.c1
-rw-r--r--src/fe-gtk/setup.c2
-rw-r--r--src/fe-gtk/sexy-spell-entry.c197
-rw-r--r--src/fe-gtk/sexy-spell-entry.h1
8 files changed, 206 insertions, 76 deletions
diff --git a/configure.ac b/configure.ac
index 01162dac..976bba37 100644
--- a/configure.ac
+++ b/configure.ac
@@ -150,6 +150,10 @@ AC_ARG_ENABLE(libproxy,
 	[AS_HELP_STRING([--disable-libproxy],[disable libproxy support (default: auto)])],
         libproxy=$enableval, libproxy=auto)
 
+AC_ARG_ENABLE(isocodes,
+	[AS_HELP_STRING([--disable-isocodes],[disable iso-codes with spell-check])],
+        isocodes=$enableval, isocodes=yes)
+
 AC_ARG_ENABLE(minimal-flags,
 	[AS_HELP_STRING([--enable-minimal-flags],[only add those CFLAGS that are really needed or not intrusive (default: no)])],
         minimalflags=$enableval, minimalflags=no)
@@ -534,12 +538,17 @@ dnl *********************************************************************
 dnl ** SPELL ************************************************************
 dnl *********************************************************************
 
-if test "$gtkfe" = "xyes" ; then
-	iso_codes_prefix=`$PKG_CONFIG --variable=prefix iso-codes 2>/dev/null || echo /usr`
-    AC_MSG_NOTICE([iso-codes prefix: $iso_codes_prefix])
-    AC_DEFINE_UNQUOTED([ISO_CODES_PREFIX], ["$iso_codes_prefix"], [ISO codes prefix])
-    AC_DEFINE_UNQUOTED([ISO_CODES_LOCALEDIR], ["$iso_codes_prefix/share/locale"], [ISO codes locale dir])
-    AC_DEFINE([HAVE_ISO_CODES], [1], [iso-codes available])
+if test "x$isocodes" = "xyes" ; then
+	PKG_CHECK_MODULES(ISOCODES, "iso-codes", [
+		iso_codes_prefix=`$PKG_CONFIG --variable=prefix iso-codes 2>/dev/null || echo /usr`
+    	AC_MSG_NOTICE([iso-codes prefix: $iso_codes_prefix])
+    	AC_DEFINE_UNQUOTED([ISO_CODES_PREFIX], ["$iso_codes_prefix"], [ISO codes prefix])
+    	AC_DEFINE_UNQUOTED([ISO_CODES_LOCALEDIR], ["$iso_codes_prefix/share/locale"], [ISO codes locale dir])
+    	AC_DEFINE([HAVE_ISO_CODES], [1], [iso-codes available])
+    	], [
+    	isocodes=no
+    	AC_MSG_WARN(iso-codes not found!)
+    ])
 fi
 
 dnl *********************************************************************
@@ -559,6 +568,7 @@ AM_CONDITIONAL(DO_DOAT, test "x$doat" = "xyes")
 AM_CONDITIONAL(DO_FISHLIM, test "x$fishlim" = "xyes")
 AM_CONDITIONAL(DO_SYSINFO, test "x$sysinfo" = "xyes")
 AM_CONDITIONAL(USE_DBUS, test "x$dbus" = "xyes")
+AM_CONDITIONAL(HAVE_ISO_CODES, test "x$isocodes" = "xyes")
 AM_CONDITIONAL(WITH_TM, test "x$theme_manager" != "xno")
 
 dnl *********************************************************************
diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c
index 93f1d147..63745869 100644
--- a/src/common/cfgfiles.c
+++ b/src/common/cfgfiles.c
@@ -425,6 +425,7 @@ const struct prefs vars[] =
 	{"gui_dialog_width", P_OFFINT (hex_gui_dialog_width), TYPE_INT},
 	{"gui_focus_omitalerts", P_OFFINT (hex_gui_focus_omitalerts), TYPE_BOOL},
 	{"gui_hide_menu", P_OFFINT (hex_gui_hide_menu), TYPE_BOOL},
+	{"gui_input_attr", P_OFFINT (hex_gui_input_attr), TYPE_BOOL},
 	{"gui_input_icon", P_OFFINT (hex_gui_input_icon), TYPE_BOOL},
 	{"gui_input_nick", P_OFFINT (hex_gui_input_nick), TYPE_BOOL},
 	{"gui_input_spell", P_OFFINT (hex_gui_input_spell), TYPE_BOOL},
@@ -668,6 +669,53 @@ get_default_language (void)
 	return lang_no >= 0 ? lang_no : find_language_number ("en");
 }
 
+static char *
+get_default_spell_languages (void)
+{
+	const gchar* const *langs = g_get_language_names ();
+	char *last = NULL;
+	char *p;
+	char lang_list[64];
+	char *ret = lang_list;
+	int i;
+
+	if (langs != NULL)
+	{
+		memset (lang_list, 0, sizeof(lang_list));
+
+		for (i = 0; langs[i]; i++)
+		{
+			if (g_ascii_strncasecmp (langs[i], "C", 1) != 0 && strlen (langs[i]) >= 2)
+			{
+				/* Avoid duplicates */
+				if (!last || !g_str_has_prefix (langs[i], last))
+				{
+					if (last != NULL)
+					{
+						g_free(last);
+						g_strlcat (lang_list, ",", sizeof(lang_list));
+					}
+
+					/* ignore .utf8 */
+					if ((p = strchr (langs[i], '.')))
+						*p='\0';
+
+					last = g_strndup (langs[i], 2);
+
+					g_strlcat (lang_list, langs[i], sizeof(lang_list));
+				}
+			}
+		}
+		if (last != NULL)
+			g_free(last);
+
+		if (lang_list[0])
+			return ret;
+	}
+
+	return "en";
+}
+
 void
 load_default_config(void)
 {
@@ -705,6 +753,7 @@ load_default_config(void)
 	prefs.hex_gui_autoopen_dialog = 1;
 	prefs.hex_gui_autoopen_recv = 1;
 	prefs.hex_gui_autoopen_send = 1;
+	prefs.hex_gui_input_attr = 1;
 	prefs.hex_gui_input_icon = 1;
 	prefs.hex_gui_input_nick = 1;
 	prefs.hex_gui_input_spell = 1;
@@ -844,7 +893,8 @@ load_default_config(void)
 	strcpy (prefs.hex_text_font_main, DEF_FONT);
 #endif
 	strcpy (prefs.hex_text_font_alternative, DEF_FONT_ALTER);
-	strcpy (prefs.hex_text_spell_langs, g_getenv ("LC_ALL") ? g_getenv ("LC_ALL") : "en_US");
+	strcpy (prefs.hex_text_spell_langs, get_default_spell_languages ());
+
 
 	/* private variables */
 	prefs.local_ip = 0xffffffff;
diff --git a/src/common/hexchat.h b/src/common/hexchat.h
index 82ebd28d..e1e402c2 100644
--- a/src/common/hexchat.h
+++ b/src/common/hexchat.h
@@ -151,6 +151,7 @@ struct hexchatprefs
 	unsigned int hex_gui_compact;
 	unsigned int hex_gui_focus_omitalerts;
 	unsigned int hex_gui_hide_menu;
+	unsigned int hex_gui_input_attr;
 	unsigned int hex_gui_input_icon;
 	unsigned int hex_gui_input_nick;
 	unsigned int hex_gui_input_spell;
diff --git a/src/fe-gtk/Makefile.am b/src/fe-gtk/Makefile.am
index 259d2c89..2e95232e 100644
--- a/src/fe-gtk/Makefile.am
+++ b/src/fe-gtk/Makefile.am
@@ -18,10 +18,14 @@ if DO_PLUGIN
 plugingui_c = plugingui.c
 endif
 
+if HAVE_ISO_CODES
+iso_codes_c = sexy-iso-codes.c
+endif
+
 hexchat_SOURCES = ascii.c banlist.c chanlist.c chanview.c custom-list.c \
 	dccgui.c editlist.c fe-gtk.c fkeys.c gtkutil.c ignoregui.c joind.c menu.c \
 	maingui.c notifygui.c palette.c pixmaps.c plugin-tray.c $(plugingui_c) \
-	rawlog.c resources.c servlistgui.c setup.c sexy-iso-codes.c sexy-marshal.c \
+	rawlog.c resources.c servlistgui.c setup.c $(iso_codes_c) sexy-marshal.c \
 	sexy-spell-entry.c textgui.c urlgrab.c userlistgui.c xtext.c
 
 resources.c: ../../data/hexchat.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=../../data --generate-dependencies ../../data/hexchat.gresource.xml)
diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c
index 6b7bf61c..4177514e 100644
--- a/src/fe-gtk/maingui.c
+++ b/src/fe-gtk/maingui.c
@@ -2971,6 +2971,7 @@ mg_create_entry (session *sess, GtkWidget *box)
 
 	gui->input_box = entry = sexy_spell_entry_new ();
 	sexy_spell_entry_set_checked ((SexySpellEntry *)entry, prefs.hex_gui_input_spell);
+	sexy_spell_entry_set_parse_attributes ((SexySpellEntry *)entry, prefs.hex_gui_input_attr);
 
 	gtk_entry_set_max_length (GTK_ENTRY (gui->input_box), 0);
 	g_signal_connect (G_OBJECT (entry), "activate",
diff --git a/src/fe-gtk/setup.c b/src/fe-gtk/setup.c
index 99fb9434..72c3bb35 100644
--- a/src/fe-gtk/setup.c
+++ b/src/fe-gtk/setup.c
@@ -187,6 +187,7 @@ static const setting inputbox_settings[] =
 {
 	{ST_HEADER, N_("Input Box"),0,0,0},
 	{ST_TOGGLE, N_("Use the Text box font and colors"), P_OFFINTNL(hex_gui_input_style),0,0,0},
+	{ST_TOGGLE, N_("Show attributes"), P_OFFINTNL (hex_gui_input_attr),0,0,0},
 	{ST_TOGGLE, N_("Show nick box"), P_OFFINTNL(hex_gui_input_nick),0,0,1},
 	{ST_TOGGLE, N_("Show user mode icon in nick box"), P_OFFINTNL(hex_gui_input_icon),0,0,0},
 	{ST_TOGGLE, N_("Spell checking"), P_OFFINTNL(hex_gui_input_spell),0,0,1},
@@ -2024,6 +2025,7 @@ setup_apply_to_sess (session_gui *gui)
 	sexy_spell_entry_activate_default_languages((SexySpellEntry *)gui->input_box);
 
 	sexy_spell_entry_set_checked ((SexySpellEntry *)gui->input_box, prefs.hex_gui_input_spell);
+	sexy_spell_entry_set_parse_attributes ((SexySpellEntry *)gui->input_box, prefs.hex_gui_input_attr);
 }
 
 static void
diff --git a/src/fe-gtk/sexy-spell-entry.c b/src/fe-gtk/sexy-spell-entry.c
index 044a6610..24424c17 100644
--- a/src/fe-gtk/sexy-spell-entry.c
+++ b/src/fe-gtk/sexy-spell-entry.c
@@ -19,7 +19,7 @@
  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 #ifdef HAVE_CONFIG_H
-# include "config.h"
+#include "config.h"
 #endif
 
 #include <gtk/gtk.h>
@@ -86,6 +86,7 @@ struct _SexySpellEntryPriv
 	gint                 *word_starts;
 	gint                 *word_ends;
 	gboolean              checked;
+	gboolean              parseattr;
 };
 
 static void sexy_spell_entry_class_init(SexySpellEntryClass *klass);
@@ -122,6 +123,10 @@ static void       entry_strsplit_utf8                         (GtkEntry
 
 static GtkEntryClass *parent_class = NULL;
 
+#ifdef HAVE_ISO_CODES
+static int codetable_ref = 0;
+#endif
+
 G_DEFINE_TYPE_EXTENDED(SexySpellEntry, sexy_spell_entry, GTK_TYPE_ENTRY, 0, G_IMPLEMENT_INTERFACE(GTK_TYPE_EDITABLE, sexy_spell_entry_editable_init));
 
 enum
@@ -352,12 +357,19 @@ static void
 insert_color (SexySpellEntry *entry, guint start, int fgcolor, int bgcolor)
 {
 	PangoAttribute *fgattr;
+	PangoAttribute *ulattr;
 	PangoAttribute *bgattr;
 
 	if (fgcolor < 0 || fgcolor > MAX_COL)
+	{
 		fgattr = pango_attr_foreground_new (colors[COL_FG].red, colors[COL_FG].green, colors[COL_FG].blue);
+		ulattr = pango_attr_underline_color_new (colors[COL_FG].red, colors[COL_FG].green, colors[COL_FG].blue);
+	}
 	else
+	{
 		fgattr = pango_attr_foreground_new (colors[fgcolor].red, colors[fgcolor].green, colors[fgcolor].blue);
+		ulattr = pango_attr_underline_color_new (colors[fgcolor].red, colors[fgcolor].green, colors[fgcolor].blue);
+	}
 
 	if (bgcolor < 0 || bgcolor > MAX_COL)
 		bgattr = pango_attr_background_new (colors[COL_BG].red, colors[COL_BG].green, colors[COL_BG].blue);
@@ -367,6 +379,9 @@ insert_color (SexySpellEntry *entry, guint start, int fgcolor, int bgcolor)
 	fgattr->start_index = start;
 	fgattr->end_index = PANGO_ATTR_INDEX_TO_TEXT_END;
 	pango_attr_list_change (entry->priv->attr_list, fgattr);
+	ulattr->start_index = start;
+	ulattr->end_index = PANGO_ATTR_INDEX_TO_TEXT_END;
+	pango_attr_list_change (entry->priv->attr_list, ulattr);
 	bgattr->start_index = start;
 	bgattr->end_index = PANGO_ATTR_INDEX_TO_TEXT_END;
 	pango_attr_list_change (entry->priv->attr_list, bgattr);
@@ -431,7 +446,7 @@ add_to_dictionary(GtkWidget *menuitem, SexySpellEntry *entry)
 		g_free(entry->priv->word_ends);
 	}
 	entry_strsplit_utf8(GTK_ENTRY(entry), &entry->priv->words, &entry->priv->word_starts, &entry->priv->word_ends);
-	sexy_spell_entry_recheck_all(entry);
+	sexy_spell_entry_recheck_all (entry);
 }
 
 static void
@@ -703,15 +718,19 @@ sexy_spell_entry_init(SexySpellEntry *entry)
 	entry->priv->dict_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
 
 	if (have_enchant)
-		sexy_spell_entry_activate_default_languages(entry);
-
+	{
 #ifdef HAVE_ISO_CODES
-	codetable_init ();
+		if (codetable_ref == 0)
+			codetable_init ();
+		codetable_ref++;
 #endif
+		sexy_spell_entry_activate_default_languages(entry);
+	}
 
 	entry->priv->attr_list = pango_attr_list_new();
 
 	entry->priv->checked = TRUE;
+	entry->priv->parseattr = TRUE;
 
 	g_signal_connect(G_OBJECT(entry), "popup-menu", G_CALLBACK(sexy_spell_entry_popup_menu), entry);
 	g_signal_connect(G_OBJECT(entry), "populate-popup", G_CALLBACK(sexy_spell_entry_populate_popup), NULL);
@@ -754,7 +773,9 @@ sexy_spell_entry_finalize(GObject *obj)
 
 	g_free(entry->priv);
 #ifdef HAVE_ISO_CODES
-	codetable_free ();
+	codetable_ref--;
+	if (codetable_ref == 0)
+		codetable_free ();
 #endif
 
 	if (G_OBJECT_CLASS(parent_class)->finalize)
@@ -859,17 +880,16 @@ check_word(SexySpellEntry *entry, int start, int end)
 }
 
 static void
-check_attributes (SexySpellEntry *entry, char *text, int len)
+check_attributes (SexySpellEntry *entry, const char *text, int len)
 {
-	PangoAttribute *attr;
-	PangoAttrList *attr_list = entry->priv->attr_list;
 	gboolean bold = FALSE;
 	gboolean italic = FALSE;
 	gboolean underline = FALSE;
 	int parsing_color = 0;
 	char fg_color[3];
 	char bg_color[3];
-	int i, bg_offset, fg_offset = 0;
+	int i, bg_offset = 0;
+	int fg_offset = 0;
 
 	memset (bg_color, 0, sizeof(bg_color));
 	memset (fg_color, 0, sizeof(fg_color));
@@ -882,28 +902,40 @@ check_attributes (SexySpellEntry *entry, char *text, int len)
 			insert_hiddenchar (entry, i, i + 1);
 			insert_bold (entry, i, bold);
 			bold = !bold;
-			break;
+			goto check_color;
 
 		case ATTR_ITALICS:
+			insert_hiddenchar (entry, i, i + 1);
 			insert_italic (entry, i, italic);
 			italic = !italic;
-			break;
+			goto check_color;
 
 		case ATTR_UNDERLINE:
+			insert_hiddenchar (entry, i, i + 1);
 			insert_underline (entry, i, underline);
 			underline = !underline;
-			break;
+			goto check_color;
 
 		case ATTR_RESET:
 			insert_hiddenchar (entry, i, i + 1);
 			insert_reset (entry, i);
-			break;
+			goto check_color;
+
+		case ATTR_HIDDEN:
+			insert_hiddenchar (entry, i, i + 1);
+			goto check_color;
+
+		case ATTR_REVERSE:
+			insert_hiddenchar (entry, i, i + 1);
+			insert_color (entry, i, COL_BG, COL_FG);
+			goto check_color;
 
 		case ATTR_COLOR:
 			parsing_color = 1;
 			break;
 
 		default:
+check_color:
 			if (!parsing_color)
 				continue;
 
@@ -974,15 +1006,24 @@ static void
 sexy_spell_entry_recheck_all(SexySpellEntry *entry)
 {
 	GdkRectangle rect;
+	GtkAllocation allocation;
 	GtkWidget *widget = GTK_WIDGET(entry);
 	PangoLayout *layout;
 	int length, i, text_len;
-	char *text;
+	const char *text;
 
 	/* Remove all existing pango attributes.  These will get readded as we check */
 	pango_attr_list_unref(entry->priv->attr_list);
 	entry->priv->attr_list = pango_attr_list_new();
 
+	if (entry->priv->parseattr)
+	{
+		/* Check for attributes */
+		text = gtk_entry_get_text (GTK_ENTRY (entry));
+		text_len = gtk_entry_get_text_length (GTK_ENTRY (entry));
+		check_attributes (entry, text, text_len);
+	}
+
 	if (have_enchant && entry->priv->checked
 		&& g_slist_length (entry->priv->dict_list) != 0)
 	{
@@ -996,18 +1037,16 @@ sexy_spell_entry_recheck_all(SexySpellEntry *entry)
 		}
 	}
 
-	/* Check for attributes */
-	text = gtk_entry_get_text (GTK_ENTRY (entry));
-	text_len = gtk_entry_get_text_length (GTK_ENTRY (entry));
-	check_attributes (entry, text, text_len);
-
 	layout = gtk_entry_get_layout(GTK_ENTRY(entry));
 	pango_layout_set_attributes(layout, entry->priv->attr_list);
 
-	if (GTK_WIDGET_REALIZED(GTK_WIDGET(entry))) {
+	if (gtk_widget_get_realized (GTK_WIDGET(entry)))
+	{
+		gtk_widget_get_allocation (GTK_WIDGET(entry), &allocation);
+		
 		rect.x = 0; rect.y = 0;
-		rect.width  = widget->allocation.width;
-		rect.height = widget->allocation.height;
+		rect.width  = allocation.width;
+		rect.height = allocation.height;
 		gdk_window_invalidate_rect(gtk_widget_get_window (widget), &rect, TRUE);
 	}
 }
@@ -1052,7 +1091,7 @@ static void
 entry_strsplit_utf8(GtkEntry *entry, gchar ***set, gint **starts, gint **ends)
 {
 	PangoLayout   *layout;
-	PangoLogAttr  *log_attrs;
+	const PangoLogAttr  *log_attrs;
 	const gchar   *text;
 	gint           n_attrs, n_strings, i, j;
 
@@ -1110,35 +1149,33 @@ sexy_spell_entry_changed(GtkEditable *editable, gpointer data)
 	sexy_spell_entry_recheck_all(entry);
 }
 
-#if 0
 static gboolean
 enchant_has_lang(const gchar *lang, GSList *langs) {
 	GSList *i;
-	for (i = langs; i; i = g_slist_next(i)) {
-		if (strcmp(lang, i->data) == 0) {
+	for (i = langs; i; i = g_slist_next(i))
+	{
+		if (strcmp(lang, i->data) == 0)
+		{
 			return TRUE;
 		}
 	}
 	return FALSE;
 }
-#endif
 
 /**
  * sexy_spell_entry_activate_default_languages:
  * @entry: A #SexySpellEntry.
  *
- * Activate spell checking for languages specified in the $LANG
- * or $LANGUAGE environment variables.  These languages are
+ * Activate spell checking for languages specified in the 
+ * text_spell_langs setting. These languages are
  * activated by default, so this function need only be called
  * if they were previously deactivated.
  */
 void
 sexy_spell_entry_activate_default_languages(SexySpellEntry *entry)
 {
-	/*const gchar* const *langs;
-	int i;
-	gchar *lastprefix = NULL;*/
-	GSList *enchant_langs, *i;
+	GSList *enchant_langs;
+	char *lang, *langs;
 
 	if (!have_enchant)
 		return;
@@ -1146,43 +1183,29 @@ sexy_spell_entry_activate_default_languages(SexySpellEntry *entry)
 	if (!entry->priv->broker)
 		entry->priv->broker = enchant_broker_init();
 
-
-	/*langs = g_get_language_names ();
-
-	if (langs == NULL)
-		return;*/
-
 	enchant_langs = sexy_spell_entry_get_languages(entry);
 
-	/*for (i = 0; langs[i]; i++) {
-		if ((g_ascii_strncasecmp(langs[i], "C", 1) != 0) &&
-		    (strlen(langs[i]) >= 2) &&
-		    enchant_has_lang(langs[i], enchant_langs)) {
-			if ((lastprefix == NULL) || (g_str_has_prefix(langs[i], lastprefix) == FALSE))
-				sexy_spell_entry_activate_language_internal(entry, langs[i], NULL);
-			if (lastprefix != NULL)
-				g_free(lastprefix);
-			lastprefix = g_strndup(langs[i], 2);
-		}
-	}
-	if (lastprefix != NULL)
-		g_free(lastprefix);*/
+	langs = g_strdup (prefs.hex_text_spell_langs);
 
-	for (i = enchant_langs; i; i = g_slist_next (i))
+	lang = strtok (langs, ",");
+	while (lang != NULL)
 	{
-		if (strstr (prefs.hex_text_spell_langs, i->data) != NULL)
+		if (enchant_has_lang (lang, enchant_langs))
 		{
-			sexy_spell_entry_activate_language_internal (entry, i->data, NULL);
+			sexy_spell_entry_activate_language_internal (entry, lang, NULL);
 		}
+		lang = strtok (NULL, ",");
 	}
 
 	g_slist_foreach(enchant_langs, (GFunc) g_free, NULL);
 	g_slist_free(enchant_langs);
-	g_slist_free (i);
+	g_free (langs);
 
 	/* If we don't have any languages activated, use "en" */
 	if (entry->priv->dict_list == NULL)
 		sexy_spell_entry_activate_language_internal(entry, "en", NULL);
+
+	sexy_spell_entry_recheck_all (entry);
 }
 
 static void
@@ -1292,8 +1315,14 @@ sexy_spell_entry_get_language_name(const SexySpellEntry *entry,
 
 	g_return_val_if_fail (have_enchant, NULL);
 
+	if (codetable_ref == 0)
+		codetable_init ();
+		
 	codetable_lookup (lang, &lang_name, &country_name);
 
+	if (codetable_ref == 0)
+		codetable_free ();
+
 	if (strlen (country_name) != 0)
 		return g_strdup_printf ("%s (%s)", lang_name, country_name);
 	else
@@ -1518,19 +1547,15 @@ sexy_spell_entry_set_checked(SexySpellEntry *entry, gboolean checked)
 	entry->priv->checked = checked;
 	widget = GTK_WIDGET(entry);
 
-	if (checked == FALSE && GTK_WIDGET_REALIZED(widget)) {
-		PangoLayout *layout;
-		GdkRectangle rect;
-
+	if (checked == FALSE && gtk_widget_get_realized (widget))
+	{
 		/* This will unmark any existing */
 		sexy_spell_entry_recheck_all (entry);
-
-		rect.x = 0; rect.y = 0;
-		rect.width  = widget->allocation.width;
-		rect.height = widget->allocation.height;
-		gdk_window_invalidate_rect(gtk_widget_get_window (widget), &rect, TRUE);
-	} else {
-		if (entry->priv->words) {
+	}
+	else
+	{
+		if (entry->priv->words)
+		{
 			g_strfreev(entry->priv->words);
 			g_free(entry->priv->word_starts);
 			g_free(entry->priv->word_ends);
@@ -1539,3 +1564,39 @@ sexy_spell_entry_set_checked(SexySpellEntry *entry, gboolean checked)
 		sexy_spell_entry_recheck_all(entry);
 	}
 }
+
+/**
+* sexy_spell_entry_set_parse_attributes:
+* @entry: A #SexySpellEntry.
+* @parse: Whether to enable showing attributes
+*
+* Sets whether to enable showing attributes is enabled.
+*/
+void
+sexy_spell_entry_set_parse_attributes (SexySpellEntry *entry, gboolean parse)
+{
+	GtkWidget *widget;
+
+	if (entry->priv->parseattr == parse)
+		return;
+
+	entry->priv->parseattr = parse;
+	widget = GTK_WIDGET (entry);
+
+	if (parse == FALSE && gtk_widget_get_realized (widget))
+	{
+		/* This will remove current attrs */
+		sexy_spell_entry_recheck_all (entry);
+	}
+	else
+	{
+		if (entry->priv->words)
+		{
+			g_strfreev (entry->priv->words);
+			g_free (entry->priv->word_starts);
+			g_free (entry->priv->word_ends);
+		}
+		entry_strsplit_utf8 (GTK_ENTRY (entry), &entry->priv->words, &entry->priv->word_starts, &entry->priv->word_ends);
+		sexy_spell_entry_recheck_all (entry);
+	}
+}
\ No newline at end of file
diff --git a/src/fe-gtk/sexy-spell-entry.h b/src/fe-gtk/sexy-spell-entry.h
index 1c761235..1e6fd1f2 100644
--- a/src/fe-gtk/sexy-spell-entry.h
+++ b/src/fe-gtk/sexy-spell-entry.h
@@ -77,6 +77,7 @@ gboolean   sexy_spell_entry_set_active_languages(SexySpellEntry *entry, GSList *
 GSList    *sexy_spell_entry_get_active_languages(SexySpellEntry *entry);
 gboolean   sexy_spell_entry_is_checked(SexySpellEntry *entry);
 void       sexy_spell_entry_set_checked(SexySpellEntry *entry, gboolean checked);
+void       sexy_spell_entry_set_parse_attributes (SexySpellEntry *entry, gboolean parse);
 void       sexy_spell_entry_activate_default_languages(SexySpellEntry *entry);
 
 G_END_DECLS