? gnome_spell.patch
? mkinstalldirs
? startup-druid.patch
? protocols/Makefile
? protocols/Makefile.in
? src/Spell-common.c
? src/Spell-skels.c
? src/Spell-stubs.c
? src/Spell.h
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gossip/ChangeLog,v
retrieving revision 1.394
diff -u -b -B -p -r1.394 ChangeLog
--- ChangeLog	28 Sep 2004 18:55:47 -0000	1.394
+++ ChangeLog	17 Oct 2004 22:47:05 -0000
@@ -1,3 +1,10 @@
+2004-10-17  Martyn Russell  <mr@gnome.org>
+
+	* src/gossip-chat.c: 
+	* src/Makefile.am: 
+	* configure.in: 
+	- Added basic support for Gnome Spell.
+
 2004-09-28  Abel Cheung  <maddog@linuxhall.org>
 
 	* configure.in: Added "tr" to ALL_LINGUAS.
Index: configure.in
===================================================================
RCS file: /cvs/gnome/gossip/configure.in,v
retrieving revision 1.71
diff -u -b -B -p -r1.71 configure.in
--- configure.in	28 Sep 2004 18:55:47 -0000	1.71
+++ configure.in	17 Oct 2004 22:47:05 -0000
@@ -60,6 +60,7 @@ LOUDMOUTH_REQUIRED=0.17
 GCONF_REQUIRED=1.2.0
 LIBGNOMEUI_REQUIRED=2.0.0
 LIBGNOMEVFS_REQUIRED=2.0.0
+LIBBONOBO_REQUIRED=1.112.1
 DESKTOP_FILE_UTILS_REQUIRED=0.2.90
 
 AC_SUBST(LIBXML_REQUIRED)
@@ -71,6 +72,7 @@ AC_SUBST(LOUDMOUTH_REQUIRED)
 AC_SUBST(GCONF_REQUIRED)
 AC_SUBST(LIBGNOMEUI_REQUIRED)
 AC_SUBST(LIBGNOMEVFS_REQUIRED)
+AC_SUBST(LIBBONOBO_REQUIRED)
 AC_SUBST(DESKTOP_FILE_UTILS_REQUIRED)
 
 dnl To make the egg stuff build properly, should have a real test...
@@ -92,8 +94,24 @@ PKG_CHECK_MODULES(GOSSIP,
 	gconf-2.0 >= $GCONF_REQUIRED
 	libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED
 	gnome-vfs-2.0 >= $LIBGNOMEVFS_REQUIRED
+	libbonobo-2.0 >= $LIBBONOBO_REQUIRED
 	$dbus_pkgconfig
 ])
+
+
+dnl -----------------------------------------------------------
+dnl gnome spell bonobo stuff
+dnl -----------------------------------------------------------
+ORBIT_IDL="`$PKG_CONFIG --variable=orbit_idl ORBit-2.0`"
+AC_SUBST(ORBIT_IDL)
+
+BONOBO_IDL_INCLUDES="-I`$PKG_CONFIG --variable=idldir libbonobo-2.0` -I`$PKG_CONFIG --variable=idldir bonobo-activation-2.0`"
+AC_SUBST(BONOBO_IDL_INCLUDES)
+
+PKG_CHECK_MODULES(PANGO, [pango >= 1.3.5],
+   [AC_DEFINE(HAVE_PANGO_UNDERLINE_ERROR, 1, [Define to 1 if PANGO_UNDERLINE_ERROR is available.])],
+   [AC_MSG_WARN([Disabling new error underlining since pango < 1.3.5])])           
+
 
 # Sucks that we need to do this
 GOSSIP_LIBS="$GOSSIP_LIBS -lexslt"
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/gossip/src/Makefile.am,v
retrieving revision 1.30
diff -u -b -B -p -r1.30 Makefile.am
--- src/Makefile.am	16 Sep 2004 13:08:58 -0000	1.30
+++ src/Makefile.am	17 Oct 2004 22:47:06 -0000
@@ -100,7 +100,7 @@ gossip_SOURCES = 				\
 	eggtrayicon.c				\
 	eggtrayicon.h
 	
-gossip_LDADD = @GOSSIP_LIBS@
+gossip_LDADD = @GOSSIP_LIBS@ libgnome-spell-idl.la
 gossip_LDFLAGS = -export-dynamic
 
 gossip-marshal.h: gossip-marshal.list
@@ -127,6 +127,28 @@ stylesheet_DATA = gossip-log.xsl
 EXTRA_DIST =						\
 	gossip-marshal.list				\
 	gossip-log.xsl					\
+	$(SPELL_IDL)					\
 	$(dbus_sources)
 
-CLEANFILES = $(BUILT_SOURCES)
+CLEANFILES = $(BUILT_SOURCES) $(IDL_GENERATED)
+
+# 
+# gnome spell
+#
+SPELL_IDL = Spell.idl
+
+IDL_GENERATED = 		\
+	Spell.h			\
+	Spell-common.c		\
+	Spell-skels.c		\
+	Spell-stubs.c
+
+$(IDL_GENERATED): $(SPELL_IDL)
+	$(ORBIT_IDL) $(BONOBO_IDL_INCLUDES) $(srcdir)/Spell.idl
+
+noinst_LTLIBRARIES = libgnome-spell-idl.la
+
+libgnome_spell_idl_la_SOURCES =	\
+	$(IDL_GENERATED)	\
+	$(END)
+
Index: src/Spell.idl
===================================================================
RCS file: src/Spell.idl
diff -N src/Spell.idl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/Spell.idl	17 Oct 2004 22:47:06 -0000
@@ -0,0 +1,71 @@
+/*  This file is part of gnome-spell bonobo component
+
+    Copyright (C) 1999, 2000 Helix Code, Inc.
+    Authors:                 Radek Doulik <rodo@helixcode.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.
+*/
+
+#include <Bonobo.idl>
+
+module GNOME {
+	module Spell {
+
+		typedef sequence<string> StringSeq;
+		struct Language {
+			string name;
+			string abbreviation;
+		};
+		typedef sequence<Language> LanguageSeq;
+
+		interface Dictionary : Bonobo::Unknown {
+
+			exception Error {
+				string error;
+			};
+
+			LanguageSeq getLanguages ();
+
+			/**
+			 * sets language(s), language string could contain more languages separated by space
+			 */
+			void setLanguage (in string language);
+		
+			/**
+			 * checks word
+			 *
+			 * returns true if word is valid
+			 */
+			boolean checkWord (in string word) raises (Error);
+
+			/**
+			 * returns suggestions for word
+			 */
+			StringSeq getSuggestions (in string word) raises (Error);
+
+			/**
+			 * add to session/personal dictionary
+			 */
+			void addWordToSession  (in string word) raises (Error);
+			void addWordToPersonal (in string word, in string language) raises (Error);
+
+			/**
+			 * informs dictionary, that word 'word' will be replaced/corrected by word 'replacement'
+			 */
+			void setCorrection (in string word, in string replacement, in string language);
+		};
+	};
+};
Index: src/gossip-chat.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-chat.c,v
retrieving revision 1.90
diff -u -b -B -p -r1.90 gossip-chat.c
--- src/gossip-chat.c	16 Sep 2004 14:18:34 -0000	1.90
+++ src/gossip-chat.c	17 Oct 2004 22:47:06 -0000
@@ -19,11 +19,21 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <string.h>
 #include <config.h>
 #include <gtk/gtk.h>
+#include <bonobo.h>
+#include <libgnome/gnome-i18n.h>
 #include "gossip-chat.h"
 #include "gossip-marshal.h"
 #include "gossip-chat-window.h"
+#include "Spell.h"
+
+#define d(x) x
+
+#define GNOME_SPELL_API_VERSION "0.3"
+#define GNOME_SPELL_OAFIID      "OAFIID:GNOME_Spell_Dictionary:" GNOME_SPELL_API_VERSION
+
 
 struct _GossipChatPriv {
 	GossipChatWindow *window;
@@ -33,6 +43,12 @@ struct _GossipChatPriv {
 	gint              padding_height;
 	gint              default_window_height;
 	gint              last_input_height;
+
+	/* gnome spell */
+	GNOME_Spell_Dictionary  dict;
+	CORBA_Environment       ev;
+	
+	gboolean                using_gnome_spell;
 };
 
 static void     chat_class_init                   (GossipChatClass *klass);
@@ -139,6 +158,9 @@ chat_init (GossipChat *chat)
 	GossipChatPriv *priv;
 	GtkTextBuffer  *buffer;
 
+	GList          *languages;
+	gchar          *lang_used = NULL;
+
 	chat->view = gossip_chat_view_new ();
 	chat->input_text_view = gtk_text_view_new ();
 	chat->is_first_char = TRUE;
@@ -169,6 +191,76 @@ chat_init (GossipChat *chat)
 			  chat);
 
 	gossip_chat_view_set_margin (chat->view, 3);
+
+	/* create misspelt words identification tag */
+	gtk_text_buffer_create_tag (buffer,
+				    "misspelled",
+#ifdef HAVE_PANGO_UNDERLINE_ERROR
+				    "underline", PANGO_UNDERLINE_ERROR,
+#else
+				    "foreground", "red", 
+				    "underline", PANGO_UNDERLINE_SINGLE,
+#endif
+				    NULL);
+
+	/* gnome spell */
+	if (!bonobo_ui_init (PACKAGE, VERSION, 0, NULL)) {
+		d(g_print (_("I could not initialize Bonobo")));
+		return;
+	}
+
+	bonobo_activate ();
+
+	priv->dict = bonobo_get_object (GNOME_SPELL_OAFIID, 
+					"GNOME/Spell/Dictionary", 
+					0);
+
+	if (priv->dict == CORBA_OBJECT_NIL) {
+		d(g_print (_("Could not create an instance of the spell component")));
+		return;
+	}
+
+	CORBA_exception_init (&priv->ev);
+
+	/* FIXME: need to sort out the language, is using the $LANG
+	   env var the right way to do it? */
+	languages = (GList*) gnome_i18n_get_language_list ("LANG");
+
+	/* FIXME: should really check if the language specified is
+	   actually available from installed languages. */
+	if (languages) {
+		GList *l;
+
+		for (l=languages; l && !lang_used; l=l->next) {
+			const gchar *lang;
+			const gchar *underscore;
+
+			lang = l->data;
+
+			if (!lang) {
+				return;
+			}
+	     
+			underscore = strstr (lang, "_");
+			
+			if (underscore) {
+				lang_used = g_strndup (lang, underscore - lang);
+			} else {
+				lang_used = g_strdup (lang);
+			}
+		}
+	}
+
+	if (lang_used) {
+		d(g_print ("using language:'%s' for gnome spell\n", lang_used));
+		GNOME_Spell_Dictionary_setLanguage (priv->dict, lang_used, &priv->ev); 
+	} else {
+		/* default to english ? */
+		d(g_print ("using default language:'en' for gnome spell\n"));
+		GNOME_Spell_Dictionary_setLanguage (priv->dict, "en", &priv->ev); 
+	}
+
+	priv->using_gnome_spell = TRUE;
 }
 
 static void
@@ -182,17 +274,49 @@ chat_finalize (GObject *object)
 	chat = GOSSIP_CHAT (object);
 	priv = chat->priv;
 
+	/* gnome spell */
+	if (priv->using_gnome_spell) { 
+		CORBA_exception_free (&priv->ev);
+		
+		bonobo_object_release_unref (priv->dict, NULL);
+		
+		priv->using_gnome_spell = FALSE;
+	}
+
 	g_free (priv);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static void
+chat_gnome_spell_init (void)
+{
+	static gboolean inited = FALSE;
+
+	if (inited) {
+		return;
+	}
+
+	inited = TRUE;
+
+}
+
+#if 0
+static void
+chat_gnome_spell_cleanup (void)
+{
+}
+#endif
+
+static void
 chat_input_text_buffer_changed_cb (GtkTextBuffer     *buffer,
 		                   GossipChat        *chat)
 {
 	GossipChatPriv *priv;
 
+	GtkTextIter     start, end;
+	gchar          *str;
+
 	priv = chat->priv;
 
 	if (chat->is_first_char) {
@@ -215,6 +339,51 @@ chat_input_text_buffer_changed_cb (GtkTe
 		priv->padding_height = window_height - req.height - allocation->height;
 
 		chat->is_first_char = FALSE;
+	}
+
+	/* show anything misspelled */
+	chat_gnome_spell_init ();
+
+	gtk_text_buffer_get_start_iter (buffer, &start);
+	
+	/* NOTE: this is really inefficient, we shouldn't have to
+	   reiterate the whole buffer each time and check each work
+	   every time. */
+	while (priv->using_gnome_spell) {
+		gboolean correct = FALSE;
+
+		/* if at start */
+		if (gtk_text_iter_is_start (&start)) {
+			end = start;
+
+			if (!gtk_text_iter_forward_word_end (&end)) {
+				/* no whole word yet */
+				break;
+			}
+		} else {
+			if (!gtk_text_iter_forward_word_end (&end)) {
+				/* must be the end of the buffer */
+				break;
+			}
+
+			start = end; 
+			gtk_text_iter_backward_word_start (&start);
+		}
+	
+		str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+	
+		/* spell check string */
+		correct = GNOME_Spell_Dictionary_checkWord (priv->dict, str, &priv->ev);
+		if (!correct) {
+			gtk_text_buffer_apply_tag_by_name (buffer, "misspelled", &start, &end);
+		} else {
+			gtk_text_buffer_remove_tag_by_name (buffer, "misspelled", &start, &end);
+		}
+
+		g_free (str);
+
+		/* set start iter to the end iters position */
+		start = end; 
 	}
 }
 
