Blame gspell/gspell-checker.c

Packit aa0600
/*
Packit aa0600
 * This file is part of gspell, a spell-checking library.
Packit aa0600
 *
Packit aa0600
 * Copyright 2002-2006 - Paolo Maggi
Packit aa0600
 * Copyright 2015, 2016 - Sébastien Wilmet
Packit aa0600
 *
Packit aa0600
 * This library is free software; you can redistribute it and/or
Packit aa0600
 * modify it under the terms of the GNU Lesser General Public
Packit aa0600
 * License as published by the Free Software Foundation; either
Packit aa0600
 * version 2.1 of the License, or (at your option) any later version.
Packit aa0600
 *
Packit aa0600
 * This library is distributed in the hope that it will be useful,
Packit aa0600
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit aa0600
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit aa0600
 * Lesser General Public License for more details.
Packit aa0600
 *
Packit aa0600
 * You should have received a copy of the GNU Lesser General Public License
Packit aa0600
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit aa0600
 */
Packit aa0600
Packit aa0600
#ifdef HAVE_CONFIG_H
Packit aa0600
#include <config.h>
Packit aa0600
#endif
Packit aa0600
Packit aa0600
#include "gspell-checker.h"
Packit aa0600
#include "gspell-checker-private.h"
Packit aa0600
#include <glib/gi18n-lib.h>
Packit aa0600
#include <string.h>
Packit aa0600
#include "gspell-utils.h"
Packit aa0600
Packit aa0600
#ifdef OS_OSX
Packit aa0600
#include "gspell-osx.h"
Packit aa0600
#endif
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * SECTION:checker
Packit aa0600
 * @Short_description: Spell checker
Packit aa0600
 * @Title: GspellChecker
Packit aa0600
 * @See_also: #GspellLanguage
Packit aa0600
 *
Packit aa0600
 * #GspellChecker is a spell checker.
Packit aa0600
 *
Packit aa0600
 * If the #GspellChecker:language property is %NULL, it means that no
Packit aa0600
 * dictonaries are available, in which case the #GspellChecker is in a
Packit aa0600
 * “disabled” (but allowed) state.
Packit aa0600
 *
Packit aa0600
 * gspell uses the [Enchant](https://abiword.github.io/enchant/) library. The
Packit aa0600
 * use of Enchant is part of the gspell API, #GspellChecker exposes the
Packit aa0600
 * EnchantDict with the gspell_checker_get_enchant_dict() function.
Packit aa0600
 */
Packit aa0600
Packit aa0600
typedef struct _GspellCheckerPrivate GspellCheckerPrivate;
Packit aa0600
Packit aa0600
struct _GspellCheckerPrivate
Packit aa0600
{
Packit aa0600
	EnchantBroker *broker;
Packit aa0600
	EnchantDict *dict;
Packit aa0600
	const GspellLanguage *active_lang;
Packit aa0600
};
Packit aa0600
Packit aa0600
enum
Packit aa0600
{
Packit aa0600
	PROP_0,
Packit aa0600
	PROP_LANGUAGE,
Packit aa0600
};
Packit aa0600
Packit aa0600
enum
Packit aa0600
{
Packit aa0600
	SIGNAL_WORD_ADDED_TO_PERSONAL,
Packit aa0600
	SIGNAL_WORD_ADDED_TO_SESSION,
Packit aa0600
	SIGNAL_SESSION_CLEARED,
Packit aa0600
	LAST_SIGNAL
Packit aa0600
};
Packit aa0600
Packit aa0600
static guint signals[LAST_SIGNAL] = { 0 };
Packit aa0600
Packit aa0600
G_DEFINE_TYPE_WITH_PRIVATE (GspellChecker, gspell_checker, G_TYPE_OBJECT)
Packit aa0600
Packit aa0600
GQuark
Packit aa0600
gspell_checker_error_quark (void)
Packit aa0600
{
Packit aa0600
	static GQuark quark = 0;
Packit aa0600
Packit aa0600
	if (G_UNLIKELY (quark == 0))
Packit aa0600
	{
Packit aa0600
		quark = g_quark_from_static_string ("gspell-checker-error-quark");
Packit aa0600
	}
Packit aa0600
Packit aa0600
	return quark;
Packit aa0600
}
Packit aa0600
Packit aa0600
static void
Packit aa0600
gspell_checker_set_property (GObject      *object,
Packit aa0600
			     guint         prop_id,
Packit aa0600
			     const GValue *value,
Packit aa0600
			     GParamSpec   *pspec)
Packit aa0600
{
Packit aa0600
	GspellChecker *checker = GSPELL_CHECKER (object);
Packit aa0600
Packit aa0600
	switch (prop_id)
Packit aa0600
	{
Packit aa0600
		case PROP_LANGUAGE:
Packit aa0600
			gspell_checker_set_language (checker, g_value_get_boxed (value));
Packit aa0600
			break;
Packit aa0600
Packit aa0600
		default:
Packit aa0600
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit aa0600
			break;
Packit aa0600
	}
Packit aa0600
}
Packit aa0600
Packit aa0600
static void
Packit aa0600
gspell_checker_get_property (GObject    *object,
Packit aa0600
			     guint       prop_id,
Packit aa0600
			     GValue     *value,
Packit aa0600
			     GParamSpec *pspec)
Packit aa0600
{
Packit aa0600
	GspellChecker *checker = GSPELL_CHECKER (object);
Packit aa0600
Packit aa0600
	switch (prop_id)
Packit aa0600
	{
Packit aa0600
		case PROP_LANGUAGE:
Packit aa0600
			g_value_set_boxed (value, gspell_checker_get_language (checker));
Packit aa0600
			break;
Packit aa0600
Packit aa0600
		default:
Packit aa0600
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit aa0600
			break;
Packit aa0600
	}
Packit aa0600
}
Packit aa0600
Packit aa0600
static void
Packit aa0600
gspell_checker_finalize (GObject *object)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (GSPELL_CHECKER (object));
Packit aa0600
Packit aa0600
	if (priv->dict != NULL)
Packit aa0600
	{
Packit aa0600
		enchant_broker_free_dict (priv->broker, priv->dict);
Packit aa0600
	}
Packit aa0600
Packit aa0600
	if (priv->broker != NULL)
Packit aa0600
	{
Packit aa0600
		enchant_broker_free (priv->broker);
Packit aa0600
	}
Packit aa0600
Packit aa0600
	G_OBJECT_CLASS (gspell_checker_parent_class)->finalize (object);
Packit aa0600
}
Packit aa0600
Packit aa0600
static void
Packit aa0600
gspell_checker_class_init (GspellCheckerClass *klass)
Packit aa0600
{
Packit aa0600
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit aa0600
Packit aa0600
	object_class->set_property = gspell_checker_set_property;
Packit aa0600
	object_class->get_property = gspell_checker_get_property;
Packit aa0600
	object_class->finalize = gspell_checker_finalize;
Packit aa0600
Packit aa0600
	/**
Packit aa0600
	 * GspellChecker:language:
Packit aa0600
	 *
Packit aa0600
	 * The #GspellLanguage used.
Packit aa0600
	 */
Packit aa0600
	g_object_class_install_property (object_class,
Packit aa0600
					 PROP_LANGUAGE,
Packit aa0600
					 g_param_spec_boxed ("language",
Packit aa0600
							     "Language",
Packit aa0600
							     "",
Packit aa0600
							     GSPELL_TYPE_LANGUAGE,
Packit aa0600
							     G_PARAM_READWRITE |
Packit aa0600
							     G_PARAM_CONSTRUCT |
Packit aa0600
							     G_PARAM_STATIC_STRINGS));
Packit aa0600
Packit aa0600
	/**
Packit aa0600
	 * GspellChecker::word-added-to-personal:
Packit aa0600
	 * @spell_checker: the #GspellChecker.
Packit aa0600
	 * @word: the added word.
Packit aa0600
	 *
Packit aa0600
	 * Emitted when a word is added to the personal dictionary.
Packit aa0600
	 */
Packit aa0600
	signals[SIGNAL_WORD_ADDED_TO_PERSONAL] =
Packit aa0600
		g_signal_new ("word-added-to-personal",
Packit aa0600
			      G_OBJECT_CLASS_TYPE (object_class),
Packit aa0600
			      G_SIGNAL_RUN_LAST,
Packit aa0600
			      G_STRUCT_OFFSET (GspellCheckerClass, word_added_to_personal),
Packit aa0600
			      NULL, NULL, NULL,
Packit aa0600
			      G_TYPE_NONE,
Packit aa0600
			      1,
Packit aa0600
			      G_TYPE_STRING);
Packit aa0600
Packit aa0600
	/**
Packit aa0600
	 * GspellChecker::word-added-to-session:
Packit aa0600
	 * @spell_checker: the #GspellChecker.
Packit aa0600
	 * @word: the added word.
Packit aa0600
	 *
Packit aa0600
	 * Emitted when a word is added to the session dictionary. See
Packit aa0600
	 * gspell_checker_add_word_to_session().
Packit aa0600
	 */
Packit aa0600
	signals[SIGNAL_WORD_ADDED_TO_SESSION] =
Packit aa0600
		g_signal_new ("word-added-to-session",
Packit aa0600
			      G_OBJECT_CLASS_TYPE (object_class),
Packit aa0600
			      G_SIGNAL_RUN_LAST,
Packit aa0600
			      G_STRUCT_OFFSET (GspellCheckerClass, word_added_to_session),
Packit aa0600
			      NULL, NULL, NULL,
Packit aa0600
			      G_TYPE_NONE,
Packit aa0600
			      1,
Packit aa0600
			      G_TYPE_STRING);
Packit aa0600
Packit aa0600
	/**
Packit aa0600
	 * GspellChecker::session-cleared:
Packit aa0600
	 * @spell_checker: the #GspellChecker.
Packit aa0600
	 *
Packit aa0600
	 * Emitted when the session dictionary is cleared.
Packit aa0600
	 */
Packit aa0600
	signals[SIGNAL_SESSION_CLEARED] =
Packit aa0600
		g_signal_new ("session-cleared",
Packit aa0600
			      G_OBJECT_CLASS_TYPE (object_class),
Packit aa0600
			      G_SIGNAL_RUN_LAST,
Packit aa0600
			      G_STRUCT_OFFSET (GspellCheckerClass, session_cleared),
Packit aa0600
			      NULL, NULL, NULL,
Packit aa0600
			      G_TYPE_NONE,
Packit aa0600
			      0);
Packit aa0600
}
Packit aa0600
Packit aa0600
static void
Packit aa0600
gspell_checker_init (GspellChecker *checker)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	priv->broker = enchant_broker_init ();
Packit aa0600
	priv->dict = NULL;
Packit aa0600
	priv->active_lang = NULL;
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_new:
Packit aa0600
 * @language: (nullable): the #GspellLanguage to use, or %NULL.
Packit aa0600
 *
Packit aa0600
 * Creates a new #GspellChecker. If @language is %NULL, the default language is
Packit aa0600
 * picked with gspell_language_get_default().
Packit aa0600
 *
Packit aa0600
 * Returns: a new #GspellChecker object.
Packit aa0600
 */
Packit aa0600
GspellChecker *
Packit aa0600
gspell_checker_new (const GspellLanguage *language)
Packit aa0600
{
Packit aa0600
	return g_object_new (GSPELL_TYPE_CHECKER,
Packit aa0600
			     "language", language,
Packit aa0600
			     NULL);
Packit aa0600
}
Packit aa0600
Packit aa0600
static void
Packit aa0600
create_new_dictionary (GspellChecker *checker)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
	const gchar *language_code;
Packit aa0600
	const gchar *app_name;
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	if (priv->dict != NULL)
Packit aa0600
	{
Packit aa0600
		enchant_broker_free_dict (priv->broker, priv->dict);
Packit aa0600
		priv->dict = NULL;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	if (priv->active_lang == NULL)
Packit aa0600
	{
Packit aa0600
		return;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	language_code = gspell_language_get_code (priv->active_lang);
Packit aa0600
	priv->dict = enchant_broker_request_dict (priv->broker, language_code);
Packit aa0600
Packit aa0600
	if (priv->dict == NULL)
Packit aa0600
	{
Packit aa0600
		/* Should never happen, no need to return a GError. */
Packit aa0600
		g_warning ("Impossible to create an Enchant dictionary for the language code '%s'.",
Packit aa0600
			   language_code);
Packit aa0600
Packit aa0600
		priv->active_lang = NULL;
Packit aa0600
		return;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	app_name = g_get_application_name ();
Packit aa0600
	gspell_checker_add_word_to_session (checker, app_name, -1);
Packit aa0600
}
Packit aa0600
Packit aa0600
/* Used for unit tests. Useful to force a NULL language. */
Packit aa0600
void
Packit aa0600
_gspell_checker_force_set_language (GspellChecker        *checker,
Packit aa0600
				    const GspellLanguage *language)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
Packit aa0600
	g_return_if_fail (GSPELL_IS_CHECKER (checker));
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	if (priv->active_lang != language)
Packit aa0600
	{
Packit aa0600
		priv->active_lang = language;
Packit aa0600
		create_new_dictionary (checker);
Packit aa0600
		g_object_notify (G_OBJECT (checker), "language");
Packit aa0600
	}
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_set_language:
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 * @language: (nullable): the #GspellLanguage to use, or %NULL.
Packit aa0600
 *
Packit aa0600
 * Sets the language to use for the spell checking. If @language is %NULL, the
Packit aa0600
 * default language is picked with gspell_language_get_default().
Packit aa0600
 */
Packit aa0600
void
Packit aa0600
gspell_checker_set_language (GspellChecker        *checker,
Packit aa0600
			     const GspellLanguage *language)
Packit aa0600
{
Packit aa0600
	g_return_if_fail (GSPELL_IS_CHECKER (checker));
Packit aa0600
Packit aa0600
	if (language == NULL)
Packit aa0600
	{
Packit aa0600
		language = gspell_language_get_default ();
Packit aa0600
	}
Packit aa0600
Packit aa0600
	_gspell_checker_force_set_language (checker, language);
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_get_language:
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 *
Packit aa0600
 * Returns: (nullable): the #GspellLanguage currently used, or %NULL
Packit aa0600
 * if no dictionaries are available.
Packit aa0600
 */
Packit aa0600
const GspellLanguage *
Packit aa0600
gspell_checker_get_language (GspellChecker *checker)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
Packit aa0600
	g_return_val_if_fail (GSPELL_IS_CHECKER (checker), NULL);
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	return priv->active_lang;
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_check_word:
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 * @word: the word to check.
Packit aa0600
 * @word_length: the byte length of @word, or -1 if @word is nul-terminated.
Packit aa0600
 * @error: (out) (optional): a location to a %NULL #GError, or %NULL.
Packit aa0600
 *
Packit aa0600
 * If the #GspellChecker:language is %NULL, i.e. when no dictonaries are
Packit aa0600
 * available, this function returns %TRUE to limit the damage.
Packit aa0600
 *
Packit aa0600
 * Returns: %TRUE if @word is correctly spelled, %FALSE otherwise.
Packit aa0600
 */
Packit aa0600
gboolean
Packit aa0600
gspell_checker_check_word (GspellChecker  *checker,
Packit aa0600
			   const gchar    *word,
Packit aa0600
			   gssize          word_length,
Packit aa0600
			   GError        **error)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
	gint enchant_result;
Packit aa0600
	gboolean correctly_spelled;
Packit aa0600
	gchar *sanitized_word;
Packit aa0600
Packit aa0600
	g_return_val_if_fail (GSPELL_IS_CHECKER (checker), FALSE);
Packit aa0600
	g_return_val_if_fail (word != NULL, FALSE);
Packit aa0600
	g_return_val_if_fail (word_length >= -1, FALSE);
Packit aa0600
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	if (priv->dict == NULL)
Packit aa0600
	{
Packit aa0600
		return TRUE;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	if (_gspell_utils_is_number (word, word_length))
Packit aa0600
	{
Packit aa0600
		return TRUE;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	if (_gspell_utils_str_to_ascii_apostrophe (word, word_length, &sanitized_word))
Packit aa0600
	{
Packit aa0600
		enchant_result = enchant_dict_check (priv->dict, sanitized_word, -1);
Packit aa0600
		g_free (sanitized_word);
Packit aa0600
	}
Packit aa0600
	else
Packit aa0600
	{
Packit aa0600
		enchant_result = enchant_dict_check (priv->dict, word, word_length);
Packit aa0600
	}
Packit aa0600
Packit aa0600
	correctly_spelled = enchant_result == 0;
Packit aa0600
Packit aa0600
	if (enchant_result < 0)
Packit aa0600
	{
Packit aa0600
		gchar *nul_terminated_word;
Packit aa0600
Packit aa0600
		if (word_length == -1)
Packit aa0600
		{
Packit aa0600
			word_length = strlen (word);
Packit aa0600
		}
Packit aa0600
Packit aa0600
		nul_terminated_word = g_strndup (word, word_length);
Packit aa0600
Packit aa0600
		g_set_error (error,
Packit aa0600
			     GSPELL_CHECKER_ERROR,
Packit aa0600
			     GSPELL_CHECKER_ERROR_DICTIONARY,
Packit aa0600
			     _("Error when checking the spelling of word “%s”: %s"),
Packit aa0600
			     nul_terminated_word,
Packit aa0600
			     enchant_dict_get_error (priv->dict));
Packit aa0600
Packit aa0600
		g_free (nul_terminated_word);
Packit aa0600
	}
Packit aa0600
Packit aa0600
	return correctly_spelled;
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_get_suggestions:
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 * @word: a misspelled word.
Packit aa0600
 * @word_length: the byte length of @word, or -1 if @word is nul-terminated.
Packit aa0600
 *
Packit aa0600
 * Gets the suggestions for @word. Free the return value with
Packit aa0600
 * g_slist_free_full(suggestions, g_free).
Packit aa0600
 *
Packit aa0600
 * Returns: (transfer full) (element-type utf8): the list of suggestions.
Packit aa0600
 */
Packit aa0600
GSList *
Packit aa0600
gspell_checker_get_suggestions (GspellChecker *checker,
Packit aa0600
				const gchar   *word,
Packit aa0600
				gssize         word_length)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
	gchar *sanitized_word;
Packit aa0600
	gchar **suggestions;
Packit aa0600
	GSList *suggestions_list = NULL;
Packit aa0600
	gint i;
Packit aa0600
Packit aa0600
	g_return_val_if_fail (GSPELL_IS_CHECKER (checker), NULL);
Packit aa0600
	g_return_val_if_fail (word != NULL, NULL);
Packit aa0600
	g_return_val_if_fail (word_length >= -1, NULL);
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	if (priv->dict == NULL)
Packit aa0600
	{
Packit aa0600
		return NULL;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	if (_gspell_utils_str_to_ascii_apostrophe (word, word_length, &sanitized_word))
Packit aa0600
	{
Packit aa0600
		suggestions = enchant_dict_suggest (priv->dict, sanitized_word, -1, NULL);
Packit aa0600
		g_free (sanitized_word);
Packit aa0600
	}
Packit aa0600
	else
Packit aa0600
	{
Packit aa0600
		suggestions = enchant_dict_suggest (priv->dict, word, word_length, NULL);
Packit aa0600
	}
Packit aa0600
Packit aa0600
	if (suggestions == NULL)
Packit aa0600
	{
Packit aa0600
		return NULL;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	for (i = 0; suggestions[i] != NULL; i++)
Packit aa0600
	{
Packit aa0600
		suggestions_list = g_slist_prepend (suggestions_list, suggestions[i]);
Packit aa0600
	}
Packit aa0600
Packit aa0600
	/* The array/list elements will be freed by the caller. */
Packit aa0600
	g_free (suggestions);
Packit aa0600
Packit aa0600
	return g_slist_reverse (suggestions_list);
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_add_word_to_personal:
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 * @word: a word.
Packit aa0600
 * @word_length: the byte length of @word, or -1 if @word is nul-terminated.
Packit aa0600
 *
Packit aa0600
 * Adds a word to the personal dictionary. It is typically saved in the user's
Packit aa0600
 * home directory.
Packit aa0600
 */
Packit aa0600
void
Packit aa0600
gspell_checker_add_word_to_personal (GspellChecker *checker,
Packit aa0600
				     const gchar   *word,
Packit aa0600
				     gssize         word_length)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
Packit aa0600
	g_return_if_fail (GSPELL_IS_CHECKER (checker));
Packit aa0600
	g_return_if_fail (word != NULL);
Packit aa0600
	g_return_if_fail (word_length >= -1);
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	if (priv->dict == NULL)
Packit aa0600
	{
Packit aa0600
		return;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	enchant_dict_add (priv->dict, word, word_length);
Packit aa0600
Packit aa0600
	if (word_length == -1)
Packit aa0600
	{
Packit aa0600
		g_signal_emit (G_OBJECT (checker),
Packit aa0600
			       signals[SIGNAL_WORD_ADDED_TO_PERSONAL], 0,
Packit aa0600
			       word);
Packit aa0600
	}
Packit aa0600
	else
Packit aa0600
	{
Packit aa0600
		gchar *nul_terminated_word = g_strndup (word, word_length);
Packit aa0600
Packit aa0600
		g_signal_emit (G_OBJECT (checker),
Packit aa0600
			       signals[SIGNAL_WORD_ADDED_TO_PERSONAL], 0,
Packit aa0600
			       nul_terminated_word);
Packit aa0600
Packit aa0600
		g_free (nul_terminated_word);
Packit aa0600
	}
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_add_word_to_session:
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 * @word: a word.
Packit aa0600
 * @word_length: the byte length of @word, or -1 if @word is nul-terminated.
Packit aa0600
 *
Packit aa0600
 * Adds a word to the session dictionary. Each #GspellChecker instance has a
Packit aa0600
 * different session dictionary. The session dictionary is lost when the
Packit aa0600
 * #GspellChecker:language property changes or when @checker is destroyed or
Packit aa0600
 * when gspell_checker_clear_session() is called.
Packit aa0600
 *
Packit aa0600
 * This function is typically called for an “Ignore All” action.
Packit aa0600
 */
Packit aa0600
void
Packit aa0600
gspell_checker_add_word_to_session (GspellChecker *checker,
Packit aa0600
				    const gchar   *word,
Packit aa0600
				    gssize         word_length)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
Packit aa0600
	g_return_if_fail (GSPELL_IS_CHECKER (checker));
Packit aa0600
	g_return_if_fail (word != NULL);
Packit aa0600
	g_return_if_fail (word_length >= -1);
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	if (priv->dict == NULL)
Packit aa0600
	{
Packit aa0600
		return;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	enchant_dict_add_to_session (priv->dict, word, word_length);
Packit aa0600
Packit aa0600
	if (word_length == -1)
Packit aa0600
	{
Packit aa0600
		g_signal_emit (G_OBJECT (checker),
Packit aa0600
			       signals[SIGNAL_WORD_ADDED_TO_SESSION], 0,
Packit aa0600
			       word);
Packit aa0600
	}
Packit aa0600
	else
Packit aa0600
	{
Packit aa0600
		gchar *nul_terminated_word = g_strndup (word, word_length);
Packit aa0600
Packit aa0600
		g_signal_emit (G_OBJECT (checker),
Packit aa0600
			       signals[SIGNAL_WORD_ADDED_TO_SESSION], 0,
Packit aa0600
			       nul_terminated_word);
Packit aa0600
Packit aa0600
		g_free (nul_terminated_word);
Packit aa0600
	}
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_clear_session:
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 *
Packit aa0600
 * Clears the session dictionary.
Packit aa0600
 */
Packit aa0600
void
Packit aa0600
gspell_checker_clear_session (GspellChecker *checker)
Packit aa0600
{
Packit aa0600
	g_return_if_fail (GSPELL_IS_CHECKER (checker));
Packit aa0600
Packit aa0600
	/* Free and re-request dictionary. */
Packit aa0600
	create_new_dictionary (checker);
Packit aa0600
Packit aa0600
	g_signal_emit (G_OBJECT (checker), signals[SIGNAL_SESSION_CLEARED], 0);
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_set_correction:
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 * @word: a word.
Packit aa0600
 * @word_length: the byte length of @word, or -1 if @word is nul-terminated.
Packit aa0600
 * @replacement: the replacement word.
Packit aa0600
 * @replacement_length: the byte length of @replacement, or -1 if @replacement
Packit aa0600
 *   is nul-terminated.
Packit aa0600
 *
Packit aa0600
 * Informs the spell checker that @word is replaced/corrected by @replacement.
Packit aa0600
 */
Packit aa0600
void
Packit aa0600
gspell_checker_set_correction (GspellChecker *checker,
Packit aa0600
			       const gchar   *word,
Packit aa0600
			       gssize         word_length,
Packit aa0600
			       const gchar   *replacement,
Packit aa0600
			       gssize         replacement_length)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
Packit aa0600
	g_return_if_fail (GSPELL_IS_CHECKER (checker));
Packit aa0600
	g_return_if_fail (word != NULL);
Packit aa0600
	g_return_if_fail (word_length >= -1);
Packit aa0600
	g_return_if_fail (replacement != NULL);
Packit aa0600
	g_return_if_fail (replacement_length >= -1);
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
Packit aa0600
	if (priv->dict == NULL)
Packit aa0600
	{
Packit aa0600
		return;
Packit aa0600
	}
Packit aa0600
Packit aa0600
	enchant_dict_store_replacement (priv->dict,
Packit aa0600
					word, word_length,
Packit aa0600
					replacement, replacement_length);
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_checker_get_enchant_dict: (skip)
Packit aa0600
 * @checker: a #GspellChecker.
Packit aa0600
 *
Packit aa0600
 * Gets the EnchantDict currently used by @checker. It permits to extend
Packit aa0600
 * #GspellChecker with more features. Note that by doing so, the other classes
Packit aa0600
 * in gspell may no longer work well.
Packit aa0600
 *
Packit aa0600
 * #GspellChecker re-creates a new EnchantDict when the #GspellChecker:language
Packit aa0600
 * is changed and when the session is cleared.
Packit aa0600
 *
Packit aa0600
 * Returns: (transfer none) (nullable): the EnchantDict currently used by
Packit aa0600
 * @checker.
Packit aa0600
 * Since: 1.6
Packit aa0600
 */
Packit aa0600
EnchantDict *
Packit aa0600
gspell_checker_get_enchant_dict (GspellChecker *checker)
Packit aa0600
{
Packit aa0600
	GspellCheckerPrivate *priv;
Packit aa0600
Packit aa0600
	g_return_val_if_fail (GSPELL_IS_CHECKER (checker), NULL);
Packit aa0600
Packit aa0600
	priv = gspell_checker_get_instance_private (checker);
Packit aa0600
	return priv->dict;
Packit aa0600
}
Packit aa0600
Packit aa0600
/* ex:set ts=8 noet: */