aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--configure.ac66
-rw-r--r--data/default-prefs-common.js5
-rw-r--r--embed/mozilla/GeckoSpellCheckEngine.cpp201
-rw-r--r--embed/mozilla/GeckoSpellCheckEngine.h52
-rw-r--r--embed/mozilla/Makefile.am7
-rw-r--r--embed/mozilla/MozRegisterComponents.cpp16
-rw-r--r--lib/Makefile.am12
-rwxr-xr-xlib/ephy-spell-check.c275
-rw-r--r--lib/ephy-spell-check.h76
10 files changed, 719 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index ee84deee2..9eed3b847 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2006-06-09 Christian Persch <chpe@cvs.gnome.org>
+
+ * configure.ac:
+
+ Check for enchant, and output an overview of the configured
+ options on successful configure.
+
+ * data/default-prefs-common.js:
+ * embed/mozilla/GeckoSpellCheckEngine.cpp:
+ * embed/mozilla/GeckoSpellCheckEngine.h:
+ * embed/mozilla/Makefile.am:
+ * embed/mozilla/MozRegisterComponents.cpp:
+ * lib/Makefile.am:
+ * lib/ephy-spell-check.c:
+ * lib/ephy-spell-check.h:
+
+ Spell check support using the gecko 'spellchecker' extension.
+ No corrections context menu or language switching yet.
+
2006-06-08 Wouter Bolsterlee <uws+gnome@xs4all.nl>
* configure.ac: Remove AM_GLIB_DEFINE_LOCALEDIR. Bug
diff --git a/configure.ac b/configure.ac
index 4f4574f94..f8eda2db4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -277,8 +277,8 @@ AC_ARG_ENABLE([filepicker],
fi])
AC_MSG_RESULT([$enable_filepicker])
-AM_CONDITIONAL([ENABLE_FILEPICKER],[test "x$enable_filepicker" = "xyes"])
-if test "x$enable_filepicker" = "xyes"; then
+AM_CONDITIONAL([ENABLE_FILEPICKER],[test "$enable_filepicker" = "yes"])
+if test "$enable_filepicker" = "yes"; then
AC_DEFINE([ENABLE_FILEPICKER],[1],[Define to enable the native filepicker])
fi
@@ -301,17 +301,17 @@ GECKO_CHECK_HEADERS([necko],[nsIIOService2.h])
# Split out into its own header in 1.9
GECKO_CHECK_HEADERS([xpcom],[nsIMutableArray.h])
-
+
+# Check for spell check extension
+
+GECKO_CHECK_HEADERS([spellchecker],[mozISpellCheckingEngine.h],
+ [have_gecko_spell_checker=yes],[have_gecko_spell_checker=no])
+
# Check for some contractIDs that we need but are provided by extensions
# which may or may not have been built.
-REQUIRED_CONTRACTS="@mozilla.org/permissionmanager;1 @mozilla.org/PopupWindowManager;1 @mozilla.org/cookie/permission;1"
-REQUIRED_EXTENSIONS="cookie"
-
-if test "$gecko_cv_gecko_version_int" -ge "1008000"; then
- REQUIRED_CONTRACTS="$REQUIRED_CONTRACTS @mozilla.org/permissions/contentblocker;1"
- REQUIRED_EXTENSIONS="$REQUIRED_EXTENSIONS,permissions"
-fi
+REQUIRED_CONTRACTS="@mozilla.org/permissionmanager;1 @mozilla.org/PopupWindowManager;1 @mozilla.org/cookie/permission;1 @mozilla.org/permissions/contentblocker;1"
+REQUIRED_EXTENSIONS="cookie,permissions"
GECKO_CHECK_CONTRACTIDS([$REQUIRED_CONTRACTS],
[],[AC_MSG_ERROR([$gecko_cv_gecko needs to be compiled with at least --enable-extensions=default,$REQUIRED_EXTENSIONS])])
@@ -536,6 +536,36 @@ fi
AM_CONDITIONAL([ENABLE_NETWORK_MANAGER],[test "$enable_network_manager" = "yes"])
+# Enchant spell checking
+
+AC_MSG_CHECKING([whether spell checking support is requested])
+AC_ARG_ENABLE([spell-checker],
+ AS_HELP_STRING([--enable-spell-checker],[Whether to enable spell checking using enchant])
+ [],
+ [if test "$gecko_cv_gecko_version_int" -ge "1008001"; then
+ enable_spell_checker=yes
+ else
+ enable_spellchecker="$have_gecko_spell_checker"
+ fi])
+AC_MSG_RESULT([$enable_spell_checker])
+
+if test "$enable_spell_checker" = "yes" -a "$have_gecko_spell_checker" != "yes"; then
+ AC_MSG_ERROR([Spell check support requested but $gecko_cv_gecko was not compiled with 'spellchecker' extension enabled.])
+fi
+
+if test "$enable_spell_checker" -a "$have_gecko_spell_checker" = "yes"; then
+ # FIXME check which version we really need
+ ENCHANT_REQUIRED=1.0
+
+ PKG_CHECK_MODULES([SPELLCHECKER],[enchant >= $ENCHANT_REQUIRED])
+ AC_SUBST([SPELLCHECKER_CFLAGS])
+ AC_SUBST([SPELLCHECKER_LIBS])
+
+ AC_DEFINE([ENABLE_SPELLCHECKER],[1],[Define to enable the spell checker])
+fi
+
+AM_CONDITIONAL([ENABLE_SPELLCHECKER],[test "$enable_spell_checker" = "yes" -a "$have_gecko_spell_checker" = "yes"])
+
# ************
# Misc defines
# ************
@@ -632,3 +662,19 @@ po/Makefile.in
[EPIPHANY_API_VERSION=$EPIPHANY_API_VERSION])
AC_OUTPUT
+
+# *************************************
+# *************************************
+
+echo "Epiphany was configured with the following options:"
+echo ""
+echo "Gecko backend : $gecko_cv_gecko version $gecko_cv_gecko_version"
+echo "PSM support : $enable_psm"
+echo "Zeroconf bookmarks support : $enable_zeroconf"
+echo "NetworkManager support : $enable_network_manager"
+echo "Certificate manager : $enable_certificate_manager (experimental)"
+echo "Python support : $enable_python"
+echo "Desktop file plugin : $enable_desktop_file_plugin"
+echo "Spellchecker : $enable_spell_checker"
+echo "Debug mode : $enable_debug"
+echo ""
diff --git a/data/default-prefs-common.js b/data/default-prefs-common.js
index dd1b16ddd..afa94d411 100644
--- a/data/default-prefs-common.js
+++ b/data/default-prefs-common.js
@@ -105,3 +105,8 @@ pref("browser.blink_allowed", false);
// enable spatial navigation (only works if the extension is built with gecko)
pref("snav.enabled", true);
+
+// spellcheck
+// pref("extensions.spellcheck.inline.max-misspellings", -1);
+// 0: disabled, 1: only textareas, 2: check textareas and single-line input fields
+pref("layout.spellcheckDefault", 1);
diff --git a/embed/mozilla/GeckoSpellCheckEngine.cpp b/embed/mozilla/GeckoSpellCheckEngine.cpp
new file mode 100644
index 000000000..ef652c0d4
--- /dev/null
+++ b/embed/mozilla/GeckoSpellCheckEngine.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2006 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#include "mozilla-config.h"
+#include "config.h"
+
+//#include <bonobo.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <nsStringAPI.h>
+
+#include <mozIPersonalDictionary.h>
+#include <nsMemory.h>
+
+#include "ephy-debug.h"
+
+#include "GeckoSpellCheckEngine.h"
+
+GeckoSpellCheckEngine::GeckoSpellCheckEngine ()
+{
+ LOG ("GeckoSpellCheckEngine ctor [%p]", (void*) this);
+ mSpeller = ephy_spell_check_get_default ();
+}
+
+GeckoSpellCheckEngine::~GeckoSpellCheckEngine ()
+{
+ LOG ("GeckoSpellCheckEngine dtor [%p]", (void*) this);
+ g_object_unref (mSpeller);
+}
+
+NS_IMPL_ISUPPORTS1 (GeckoSpellCheckEngine,
+ mozISpellCheckingEngine)
+
+/* nsISpellCheckEngine implementation */
+
+/* attribute wstring dictionary; */
+NS_IMETHODIMP GeckoSpellCheckEngine::GetDictionary (PRUnichar * *aDictionary)
+{
+ /* Gets the identifier of the current dictionary */
+ char *code = ephy_spell_check_get_language (mSpeller);
+ if (!code) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aDictionary = ToNewUnicode (NS_ConvertUTF8toUTF16 (code));
+ g_free (code);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP GeckoSpellCheckEngine::SetDictionary (const PRUnichar * aDictionary)
+{
+ return NS_OK;
+}
+
+/* readonly attribute wstring language; */
+NS_IMETHODIMP GeckoSpellCheckEngine::GetLanguage (PRUnichar * *aLanguage)
+{
+ /* Gets the identifier of the current dictionary */
+ char *code = ephy_spell_check_get_language (mSpeller);
+ if (!code) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aLanguage = ToNewUnicode (NS_ConvertUTF8toUTF16 (code));
+ g_free (code);
+
+ return NS_OK;
+}
+
+/* readonly attribute boolean providesPersonalDictionary; */
+NS_IMETHODIMP GeckoSpellCheckEngine::GetProvidesPersonalDictionary (PRBool *aProvidesPersonalDictionary)
+{
+ *aProvidesPersonalDictionary = PR_FALSE;
+ return NS_OK;
+}
+
+/* readonly attribute boolean providesWordUtils; */
+NS_IMETHODIMP GeckoSpellCheckEngine::GetProvidesWordUtils (PRBool *aProvidesWordUtils)
+{
+ *aProvidesWordUtils = PR_FALSE;
+ return NS_OK;
+}
+
+/* readonly attribute wstring name; */
+NS_IMETHODIMP GeckoSpellCheckEngine::GetName (PRUnichar * *aName)
+{
+ /* It's fine to leave this unimplemented */
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* readonly attribute wstring copyright; */
+NS_IMETHODIMP GeckoSpellCheckEngine::GetCopyright (PRUnichar * *aCopyright)
+{
+ /* It's fine to leave this unimplemented */
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute mozIPersonalDictionary personalDictionary; */
+NS_IMETHODIMP GeckoSpellCheckEngine::GetPersonalDictionary (mozIPersonalDictionary * *aPersonalDictionary)
+{
+ NS_IF_ADDREF (*aPersonalDictionary = mPersonalDictionary);
+ return NS_OK;
+}
+
+NS_IMETHODIMP GeckoSpellCheckEngine::SetPersonalDictionary (mozIPersonalDictionary * aPersonalDictionary)
+{
+ mPersonalDictionary = aPersonalDictionary;
+ return NS_OK;
+}
+
+/* void getDictionaryList ([array, size_is (count)] out wstring dictionaries, out PRUint32 count); */
+NS_IMETHODIMP
+GeckoSpellCheckEngine::GetDictionaryList (PRUnichar ***_dictionaries,
+ PRUint32 *_count)
+{
+ *_count = 1;
+ *_dictionaries = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *)); // only one entry
+ *_dictionaries[0] = ToNewUnicode (NS_LITERAL_STRING ("en"));
+ return NS_OK;
+}
+
+/* boolean check (in wstring word); */
+NS_IMETHODIMP GeckoSpellCheckEngine::Check (const PRUnichar *word,
+ PRBool *_retval)
+{
+ NS_ENSURE_STATE (mSpeller);
+ NS_ENSURE_ARG (word);
+
+ NS_ConvertUTF16toUTF8 converted (word);
+
+ gboolean correct = FALSE;
+ if (!ephy_spell_check_check_word (mSpeller,
+ converted.get (),
+ converted.Length (),
+ &correct))
+ return NS_ERROR_FAILURE;
+
+ *_retval = correct != FALSE;
+
+ return NS_OK;
+}
+
+/* void suggest (in wstring word, [array, size_is (count)] out wstring suggestions, out PRUint32 count); */
+NS_IMETHODIMP GeckoSpellCheckEngine::Suggest (const PRUnichar *word,
+ PRUnichar ***_suggestions,
+ PRUint32 *_count)
+{
+#if 0
+ NS_ENSURE_STATE (mSpeller);
+ NS_ENSURE_ARG (word);
+
+ NS_ConvertUTF16toUTF8 converted (word);
+
+ gsize count;
+ char **suggestions = ephy_spell_check_get_suggestions (mSpeller,
+ converted.get (),
+ converted.Length (),
+ &count);
+
+ *_count = count;
+ *_suggestions = nsnull;
+
+ PRUnichar **array = nsnull;
+ if (count > 0) {
+ NS_ASSERTION (suggestions, "Count > 0 but suggestions are NULL?");
+ array = (PRUnichar **) nsMemory::Alloc (count * sizeof (PRUnichar *));
+ if (array) {
+ *_suggestions = array;
+
+ for (gsize i = 0; i < count; ++i) {
+ NS_ConvertUTF8toUTF16 sugg (suggestions[i]);
+ array[i] = ToNewUnicode (sugg);
+ }
+ }
+
+ ephy_spell_check_free_suggestions (mSpeller, suggestions);
+ }
+
+ return array ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+#endif
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/embed/mozilla/GeckoSpellCheckEngine.h b/embed/mozilla/GeckoSpellCheckEngine.h
new file mode 100644
index 000000000..d31e93603
--- /dev/null
+++ b/embed/mozilla/GeckoSpellCheckEngine.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2006 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef GECKO_SPELL_CHECK_ENGINE_H
+#define GECKO_SPELL_CHECK_ENGINE_H
+
+#include <nsCOMPtr.h>
+#include <mozISpellCheckingEngine.h>
+
+#include "ephy-spell-check.h"
+
+class mozIPersonalDictionary;
+
+/* 26948b8b-d136-4a78-a9c5-3a145812b649 */
+#define GECKO_SPELL_CHECK_ENGINE_IID \
+{ 0x26948b8b, 0xd136, 0x4a78, { 0xa9, 0xc5, 0x3a, 0x14, 0x58, 0x12, 0xb6, 0x49 } }
+
+#define GECKO_SPELL_CHECK_ENGINE_CONTRACTID "@mozilla.org/spellchecker/myspell;1"
+#define GECKO_SPELL_CHECK_ENGINE_CLASSNAME "Gecko Print Settings"
+
+class GeckoSpellCheckEngine : public mozISpellCheckingEngine
+{
+ public:
+ GeckoSpellCheckEngine();
+ virtual ~GeckoSpellCheckEngine();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_MOZISPELLCHECKINGENGINE
+
+ private:
+ nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
+ EphySpellCheck *mSpeller;
+};
+
+#endif /* GECKO_SPELL_CHECK_ENGINE_H */
diff --git a/embed/mozilla/Makefile.am b/embed/mozilla/Makefile.am
index 2e0063272..2e25a2a27 100644
--- a/embed/mozilla/Makefile.am
+++ b/embed/mozilla/Makefile.am
@@ -82,6 +82,12 @@ libephymozillaembed_la_SOURCES += \
mozilla-x509-cert.h
endif
+if ENABLE_SPELLCHECKER
+libephymozillaembed_la_SOURCES += \
+ GeckoSpellCheckEngine.cpp \
+ GeckoSpellCheckEngine.h
+endif
+
mozilla_include_subdirs = \
. \
caps \
@@ -111,6 +117,7 @@ mozilla_include_subdirs = \
pref \
shistory \
sidebar \
+ spellchecker \
uriloader \
uconv \
wallet \
diff --git a/embed/mozilla/MozRegisterComponents.cpp b/embed/mozilla/MozRegisterComponents.cpp
index 6c76541a2..b2fb94b02 100644
--- a/embed/mozilla/MozRegisterComponents.cpp
+++ b/embed/mozilla/MozRegisterComponents.cpp
@@ -61,6 +61,10 @@
#include "FilePicker.h"
#endif
+#ifdef ENABLE_SPELLCHECKER
+#include "GeckoSpellCheckEngine.h"
+#endif
+
#ifdef HAVE_MOZILLA_PSM
#include "GtkNSSClientAuthDialogs.h"
#include "GtkNSSDialogs.h"
@@ -81,6 +85,10 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(MozGlobalHistory)
NS_GENERIC_FACTORY_CONSTRUCTOR(GFilePicker)
#endif
+#ifdef ENABLE_SPELLCHECKER
+NS_GENERIC_FACTORY_CONSTRUCTOR(GeckoSpellCheckEngine)
+#endif
+
#ifdef HAVE_MOZILLA_PSM
NS_GENERIC_FACTORY_CONSTRUCTOR(GtkNSSClientAuthDialogs)
NS_GENERIC_FACTORY_CONSTRUCTOR(GtkNSSDialogs)
@@ -246,6 +254,14 @@ static const nsModuleComponentInfo sAppComps[] = {
EphyPromptServiceConstructor
},
#endif /* HAVE_NSINONBLOCKINGALERTSERVICE_H */
+#ifdef ENABLE_SPELLCHECKER
+ {
+ GECKO_SPELL_CHECK_ENGINE_CLASSNAME,
+ GECKO_SPELL_CHECK_ENGINE_IID,
+ GECKO_SPELL_CHECK_ENGINE_CONTRACTID,
+ GeckoSpellCheckEngineConstructor
+ }
+#endif /* ENABLE_SPELLCHECK */
};
gboolean
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 697213940..439c356bb 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -82,6 +82,18 @@ libephymisc_la_CFLAGS = \
libephymisc_la_LIBADD =
+if ENABLE_SPELLCHECKER
+libephymisc_la_SOURCES += \
+ ephy-spell-check.c \
+ ephy-spell-check.h
+
+libephymisc_la_CFLAGS += \
+ $(SPELLCHECKER_CFLAGS)
+
+libephymisc_la_LIBADD += \
+ $(SPELLCHECKER_LIBS)
+endif
+
BUILT_SOURCES = \
ephy-lib-type-builtins.c \
ephy-lib-type-builtins.h \
diff --git a/lib/ephy-spell-check.c b/lib/ephy-spell-check.c
new file mode 100755
index 000000000..aa09916fa
--- /dev/null
+++ b/lib/ephy-spell-check.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2006 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+#include <enchant.h>
+
+#include "ephy-debug.h"
+
+#include "ephy-spell-check.h"
+
+#define EPHY_SPELL_CHECK_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SPELL_CHECK, EphySpellCheckPrivate))
+
+struct _EphySpellCheckPrivate
+{
+ EnchantBroker *broker;
+ EnchantDict *dict;
+};
+
+enum
+{
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+static GObjectClass *parent_class;
+
+/* Helper functions */
+
+/* Class implementation */
+
+static void
+ephy_spell_check_init (EphySpellCheck *speller)
+{
+ EphySpellCheckPrivate *priv;
+
+ priv = speller->priv = EPHY_SPELL_CHECK_GET_PRIVATE (speller);
+
+ priv->broker = enchant_broker_init ();
+
+ /* FIXME */
+ priv->dict = enchant_broker_request_dict (priv->broker, "en");
+ if(priv->dict == NULL)
+ g_warning(enchant_broker_get_error (priv->broker));
+}
+
+static void
+ephy_spell_check_finalize (GObject *object)
+{
+ EphySpellCheck *speller = EPHY_SPELL_CHECK (object);
+ EphySpellCheckPrivate *priv = speller->priv;
+
+
+ LOG ("EphySpellCheck finalised");
+
+ if (priv->dict != NULL)
+ {
+ enchant_broker_free_dict (priv->broker, priv->dict);
+ priv->dict = NULL;
+ }
+
+ enchant_broker_free (priv->broker);
+
+ parent_class->finalize (object);
+}
+
+static void
+ephy_spell_check_class_init (EphySpellCheckClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = ephy_spell_check_finalize;
+
+#if 0
+ signals[CANCEL] =
+ g_signal_new ("cancel",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EphySpellCheckClass, cancel),
+ g_signal_accumulator_true_handled, NULL,
+ ephy_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN,
+ 0);
+#endif
+
+ g_type_class_add_private (object_class, sizeof (EphySpellCheckPrivate));
+}
+
+GType
+ephy_spell_check_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphySpellCheckClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) ephy_spell_check_class_init,
+ NULL,
+ NULL,
+ sizeof (EphySpellCheck),
+ 0,
+ (GInstanceInitFunc) ephy_spell_check_init
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "EphySpellCheck",
+ &our_info, 0);
+ }
+
+ return type;
+}
+
+/* Public API */
+
+/**
+ * ephy_spell_check_get_default:
+ *
+ * Returns: a reference to the default #EphySpellCheck object
+ */
+EphySpellCheck *
+ephy_spell_check_get_default (void)
+{
+ static EphySpellCheck *instance = NULL;
+
+ if (instance == NULL)
+ {
+ EphySpellCheck **instanceptr = &instance;
+
+ instance = g_object_new (EPHY_TYPE_SPELL_CHECK, NULL);
+ g_object_add_weak_pointer (G_OBJECT (instance),
+ (gpointer) instanceptr);
+
+ return instance;
+ }
+
+ return g_object_ref (instance);
+}
+
+int
+ephy_spell_check_check_word (EphySpellCheck *speller,
+ const char *word,
+ gssize len,
+ gboolean *correct)
+{
+ EphySpellCheckPrivate *priv = speller->priv;
+ int result;
+
+ g_return_val_if_fail (word != NULL, -1);
+
+ g_print ("ephy_spell_check_check_word: '%s'\n", word);
+
+ if (priv->dict == NULL)
+ return FALSE;
+
+ if (len < 0)
+ len = strlen (word);
+
+ result = enchant_dict_check (priv->dict, word, len);
+ if (result < 0)
+ return FALSE;
+
+ *correct = result == 0;
+
+ return TRUE;
+}
+
+char **
+ephy_spell_check_get_suggestions (EphySpellCheck *speller,
+ const char *word,
+ gssize len,
+ gsize *_count)
+{
+ EphySpellCheckPrivate *priv = speller->priv;
+ char **suggestions;
+ size_t count;
+
+ g_return_val_if_fail (word != NULL, NULL);
+
+ if (priv->dict == NULL)
+ return FALSE;
+
+ if (len < 0)
+ len = strlen (word);
+
+ suggestions = enchant_dict_suggest (priv->dict, word, len, &count);
+
+ *_count = count;
+ return suggestions;
+}
+
+void
+ephy_spell_check_free_suggestions (EphySpellCheck *speller,
+ char **suggestions)
+{
+ EphySpellCheckPrivate *priv = speller->priv;
+
+ if (suggestions != NULL)
+ {
+ g_return_if_fail (priv->dict != NULL);
+
+ /* FIXME!! What if inbetween there has been a change of dict!? */
+ enchant_dict_free_suggestions (priv->dict, suggestions);
+ }
+}
+
+gboolean
+ephy_spell_check_set_language (EphySpellCheck *speller,
+ const char *lang)
+{
+ EphySpellCheckPrivate *priv = speller->priv;
+ char *code;
+
+ if (priv->dict != NULL)
+ {
+ enchant_broker_free_dict (priv->broker, priv->dict);
+ priv->dict = NULL;
+ }
+
+ /* Enchant expects ab_CD codes, not ab-CD */
+ code = g_strdup (lang);
+ g_strdelimit (code, "-", '_');
+ priv->dict = enchant_broker_request_dict (priv->broker, code);
+ g_free (code);
+
+ return priv->dict != NULL;
+}
+
+static void
+describe_cb (const char * const lang_tag,
+ const char * const provider_name,
+ const char * const provider_desc,
+ const char * const provider_file,
+ char **_language)
+{
+ *_language = g_strdup (lang_tag);
+}
+
+char *
+ephy_spell_check_get_language (EphySpellCheck *speller)
+{
+ EphySpellCheckPrivate *priv = speller->priv;
+ char *code = NULL;
+
+ if (priv->dict == NULL) return NULL;
+
+ enchant_dict_describe (priv->dict, (EnchantDictDescribeFn) describe_cb, &code);
+ return code;
+} \ No newline at end of file
diff --git a/lib/ephy-spell-check.h b/lib/ephy-spell-check.h
new file mode 100644
index 000000000..34b80df9a
--- /dev/null
+++ b/lib/ephy-spell-check.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2006 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_SPELL_CHECK_H
+#define EPHY_SPELL_CHECK_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_SPELL_CHECK (ephy_spell_check_get_type ())
+#define EPHY_SPELL_CHECK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_SPELL_CHECK, EphySpellCheck))
+#define EPHY_SPELL_CHECK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EPHY_TYPE_SPELL_CHECK, EphySpellCheckClass))
+#define EPHY_IS_SPELL_CHECK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_SPELL_CHECK))
+#define EPHY_IS_SPELL_CHECK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_SPELL_CHECK))
+#define EPHY_SPELL_CHECK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_SPELL_CHECK, EphySpellCheckClass))
+
+typedef struct _EphySpellCheck EphySpellCheck;
+typedef struct _EphySpellCheckPrivate EphySpellCheckPrivate;
+typedef struct _EphySpellCheckClass EphySpellCheckClass;
+
+struct _EphySpellCheck
+{
+ GObject parent_instance;
+
+ /*< private >*/
+ EphySpellCheckPrivate *priv;
+};
+
+struct _EphySpellCheckClass
+{
+ GObjectClass parent_class;
+};
+
+GType ephy_spell_check_get_type (void);
+
+EphySpellCheck *ephy_spell_check_get_default (void);
+
+gboolean ephy_spell_check_check_word (EphySpellCheck *speller,
+ const char *word,
+ gssize len,
+ gboolean *correct);
+
+char **ephy_spell_check_get_suggestions (EphySpellCheck *speller,
+ const char *word,
+ gssize len,
+ gsize *count);
+
+void ephy_spell_check_free_suggestions (EphySpellCheck *speller,
+ char **suggestions);
+
+gboolean ephy_spell_check_set_language (EphySpellCheck *speller,
+ const char *lang);
+
+char *ephy_spell_check_get_language (EphySpellCheck *speller);
+
+G_END_DECLS
+
+#endif