*
* You should have received a copy of the GNU 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.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Martyn Russell <martyn@imendio.com>
* Richard Hult <richard@imendio.com>
*/
#include "config.h"
+#include "empathy-spell.h"
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib/gi18n.h>
+#include <glib/gi18n-lib.h>
-#ifdef HAVE_ASPELL
-#include <aspell.h>
+#ifdef HAVE_ENCHANT
+#include <enchant.h>
#endif
-#include <libempathy/empathy-debug.h>
-#include <libempathy/empathy-conf.h>
+#include "empathy-gsettings.h"
-#include "empathy-spell.h"
-#include "empathy-preferences.h"
+#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
+#include "empathy-debug.h"
-#define DEBUG_DOMAIN "Spell"
-
-#ifdef HAVE_ASPELL
-
-/* Note: We could use aspell_reset_cache (NULL); periodically if we wanted
- * to...
- */
+#ifdef HAVE_ENCHANT
typedef struct {
- AspellConfig *spell_config;
- AspellCanHaveError *spell_possible_err;
- AspellSpeller *spell_checker;
+ EnchantBroker *config;
+ EnchantDict *speller;
} SpellLanguage;
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
+/* Language code (gchar *) -> language name (gchar *) */
static GHashTable *iso_code_names = NULL;
-static GList *languages = NULL;
-static gboolean empathy_conf_notify_inited = FALSE;
+/* Contains only _enabled_ languages
+ * Language code (gchar *) -> language (SpellLanguage *) */
+static GHashTable *languages = NULL;
static void
spell_iso_codes_parse_start_tag (GMarkupParseContext *ctx,
}
static void
-spell_notify_languages_cb (EmpathyConf *conf,
+spell_notify_languages_cb (GSettings *gsettings,
const gchar *key,
gpointer user_data)
{
- GList *l;
-
- empathy_debug (DEBUG_DOMAIN, "Resetting languages due to config change");
+ DEBUG ("Resetting languages due to config change");
/* We just reset the languages list. */
- for (l = languages; l; l = l->next) {
- SpellLanguage *lang;
-
- lang = l->data;
-
- delete_aspell_config (lang->spell_config);
- delete_aspell_speller (lang->spell_checker);
-
- g_slice_free (SpellLanguage, lang);
+ if (languages != NULL) {
+ g_hash_table_unref (languages);
+ languages = NULL;
}
+}
+
+static void
+empathy_spell_free_language (SpellLanguage *lang)
+{
+ enchant_broker_free_dict (lang->config, lang->speller);
+ enchant_broker_free (lang->config);
- g_list_free (languages);
- languages = NULL;
+ g_slice_free (SpellLanguage, lang);
}
static void
spell_setup_languages (void)
{
+ static GSettings *gsettings = NULL;
gchar *str;
- if (!empathy_conf_notify_inited) {
- empathy_conf_notify_add (empathy_conf_get (),
- EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES,
- spell_notify_languages_cb, NULL);
+ if (gsettings == NULL) {
+ /* FIXME: this is never uninitialised */
+ gsettings = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA);
- empathy_conf_notify_inited = TRUE;
+ g_signal_connect (gsettings,
+ "changed::" EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES,
+ G_CALLBACK (spell_notify_languages_cb), NULL);
}
if (languages) {
return;
}
- if (empathy_conf_get_string (empathy_conf_get (),
- EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES,
- &str) && str) {
+ languages = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) empathy_spell_free_language);
+
+ str = g_settings_get_string (gsettings,
+ EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES);
+
+ if (str != NULL) {
gchar **strv;
gint i;
while (strv && strv[i]) {
SpellLanguage *lang;
- empathy_debug (DEBUG_DOMAIN, "Setting up language:'%s'", strv[i]);
+ DEBUG ("Setting up language:'%s'", strv[i]);
lang = g_slice_new0 (SpellLanguage);
- lang->spell_config = new_aspell_config();
-
- aspell_config_replace (lang->spell_config, "encoding", "utf-8");
- aspell_config_replace (lang->spell_config, "lang", strv[i++]);
-
- lang->spell_possible_err = new_aspell_speller (lang->spell_config);
+ lang->config = enchant_broker_init ();
+ lang->speller = enchant_broker_request_dict (lang->config, strv[i]);
- if (aspell_error_number (lang->spell_possible_err) == 0) {
- lang->spell_checker = to_aspell_speller (lang->spell_possible_err);
- languages = g_list_append (languages, lang);
+ if (lang->speller == NULL) {
+ DEBUG ("language '%s' has no valid dict", strv[i]);
} else {
- delete_aspell_config (lang->spell_config);
- g_slice_free (SpellLanguage, lang);
+ g_hash_table_insert (languages,
+ g_strdup (strv[i]),
+ lang);
}
+
+ i++;
}
if (strv) {
}
}
-const char *
-empathy_spell_get_language_name (const char *code)
+const gchar *
+empathy_spell_get_language_name (const gchar *code)
{
const gchar *name;
return dgettext ("iso_639", name);
}
+static void
+enumerate_dicts (const gchar * const lang_tag,
+ const gchar * const provider_name,
+ const gchar * const provider_desc,
+ const gchar * const provider_file,
+ gpointer user_data)
+{
+ GList **list = user_data;
+ gchar *lang = g_strdup (lang_tag);
+
+ if (strchr (lang, '_')) {
+ /* cut country part out of language */
+ strchr (lang, '_')[0] = '\0';
+ }
+
+ if (g_list_find_custom (*list, lang, (GCompareFunc) strcmp)) {
+ /* this language is already part of the list */
+ g_free (lang);
+ return;
+ }
+
+ *list = g_list_append (*list, lang);
+}
+
GList *
empathy_spell_get_language_codes (void)
{
- AspellConfig *config;
- AspellDictInfoList *dlist;
- AspellDictInfoEnumeration *dels;
- const AspellDictInfo *entry;
- GList *codes = NULL;
-
- config = new_aspell_config ();
- dlist = get_aspell_dict_info_list (config);
- dels = aspell_dict_info_list_elements (dlist);
-
- while ((entry = aspell_dict_info_enumeration_next (dels)) != 0) {
- if (g_list_find_custom (codes, entry->code, (GCompareFunc) strcmp)) {
- continue;
- }
+ EnchantBroker *broker;
+ GList *list_langs = NULL;
- codes = g_list_append (codes, g_strdup (entry->code));
- }
+ broker = enchant_broker_init ();
+ enchant_broker_list_dicts (broker, enumerate_dicts, &list_langs);
+ enchant_broker_free (broker);
- delete_aspell_dict_info_enumeration (dels);
- delete_aspell_config (config);
+ return list_langs;
+}
- return codes;
+GList *
+empathy_spell_get_enabled_language_codes (void)
+{
+ spell_setup_languages ();
+ return g_hash_table_get_keys (languages);
}
void
gboolean
empathy_spell_check (const gchar *word)
{
- GList *l;
- gint n_langs;
- gboolean correct = FALSE;
- gint len;
+ gint enchant_result = 1;
const gchar *p;
- gunichar c;
gboolean digit;
+ gunichar c;
+ gint len;
+ GHashTableIter iter;
+ SpellLanguage *lang;
g_return_val_if_fail (word != NULL, FALSE);
spell_setup_languages ();
if (!languages) {
- empathy_debug (DEBUG_DOMAIN, "No languages to check against");
return TRUE;
}
if (digit) {
/* We don't spell check digits. */
- empathy_debug (DEBUG_DOMAIN, "Not spell checking word:'%s', it is all digits", word);
+ DEBUG ("Not spell checking word:'%s', it is all digits", word);
return TRUE;
}
len = strlen (word);
- n_langs = g_list_length (languages);
- for (l = languages; l; l = l->next) {
- SpellLanguage *lang;
+ g_hash_table_iter_init (&iter, languages);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &lang)) {
+ enchant_result = enchant_dict_check (lang->speller, word, len);
- lang = l->data;
-
- correct = aspell_speller_check (lang->spell_checker, word, len);
- if (n_langs > 1 && correct) {
+ if (enchant_result == 0) {
break;
}
}
- return correct;
+ return (enchant_result == 0);
}
GList *
-empathy_spell_get_suggestions (const gchar *word)
+empathy_spell_get_suggestions (const gchar *code,
+ const gchar *word)
{
- GList *l1;
- GList *l2 = NULL;
- const AspellWordList *suggestions;
- AspellStringEnumeration *elements;
- const char *next;
- gint len;
+ gint len;
+ GList *suggestion_list = NULL;
+ SpellLanguage *lang;
+ gchar **suggestions;
+ gsize i, number_of_suggestions;
+ g_return_val_if_fail (code != NULL, NULL);
g_return_val_if_fail (word != NULL, NULL);
spell_setup_languages ();
- len = strlen (word);
-
- for (l1 = languages; l1; l1 = l1->next) {
- SpellLanguage *lang;
+ if (!languages) {
+ return NULL;
+ }
- lang = l1->data;
+ len = strlen (word);
- suggestions = aspell_speller_suggest (lang->spell_checker,
- word, len);
+ lang = g_hash_table_lookup (languages, code);
+ if (!lang) {
+ return NULL;
+ }
- elements = aspell_word_list_elements (suggestions);
+ suggestions = enchant_dict_suggest (lang->speller, word, len,
+ &number_of_suggestions);
- while ((next = aspell_string_enumeration_next (elements))) {
- l2 = g_list_append (l2, g_strdup (next));
- }
+ for (i = 0; i < number_of_suggestions; i++) {
+ suggestion_list = g_list_append (suggestion_list,
+ g_strdup (suggestions[i]));
+ }
- delete_aspell_string_enumeration (elements);
+ if (suggestions) {
+ enchant_dict_free_string_list (lang->speller, suggestions);
}
- return l2;
+ return suggestion_list;
}
gboolean
empathy_spell_supported (void)
{
if (g_getenv ("EMPATHY_SPELL_DISABLED")) {
- empathy_debug (DEBUG_DOMAIN, "EMPATHY_SPELL_DISABLE env variable defined");
+ DEBUG ("EMPATHY_SPELL_DISABLE env variable defined");
return FALSE;
}
return TRUE;
}
-#else /* not HAVE_ASPELL */
+void
+empathy_spell_add_to_dictionary (const gchar *code,
+ const gchar *word)
+{
+ SpellLanguage *lang;
+
+ g_return_if_fail (code != NULL);
+ g_return_if_fail (word != NULL);
+
+ spell_setup_languages ();
+ if (languages == NULL)
+ return;
+
+ lang = g_hash_table_lookup (languages, code);
+ if (lang == NULL)
+ return;
+
+ enchant_dict_add_to_pwl (lang->speller, word, strlen (word));
+}
+
+#else /* not HAVE_ENCHANT */
gboolean
empathy_spell_supported (void)
}
GList *
-empathy_spell_get_suggestions (const gchar *word)
+empathy_spell_get_suggestions (const gchar *code,
+ const gchar *word)
{
- empathy_debug (DEBUG_DOMAIN, "Support disabled, could not get suggestions");
+ DEBUG ("Support disabled, could not get suggestions");
return NULL;
}
gboolean
empathy_spell_check (const gchar *word)
{
- empathy_debug (DEBUG_DOMAIN, "Support disabled, could not check spelling");
+ DEBUG ("Support disabled, could not check spelling");
return TRUE;
}
-const char *
-empathy_spell_get_language_name (const char *lang)
+const gchar *
+empathy_spell_get_language_name (const gchar *lang)
{
- empathy_debug (DEBUG_DOMAIN, "Support disabled, could not get language name");
+ DEBUG ("Support disabled, could not get language name");
return NULL;
}
GList *
empathy_spell_get_language_codes (void)
{
- empathy_debug (DEBUG_DOMAIN, "Support disabled, could not get language codes");
+ DEBUG ("Support disabled, could not get language codes");
return NULL;
}
{
}
-#endif /* HAVE_ASPELL */
+void
+empathy_spell_add_to_dictionary (const gchar *code,
+ const gchar *word)
+{
+ DEBUG ("Support disabled, could not expand the dictionary");
+}
+
+GList *
+empathy_spell_get_enabled_language_codes (void)
+{
+ DEBUG ("Support disabled, could not get enabled language codes");
+
+ return NULL;
+}
+
+#endif /* HAVE_ENCHANT */
void