Blame gspell/gspell-text-buffer.c

Packit aa0600
/*
Packit aa0600
 * This file is part of gspell, a spell-checking library.
Packit aa0600
 *
Packit aa0600
 * Copyright 2015, 2016, 2017 - 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-text-buffer.h"
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * SECTION:text-buffer
Packit aa0600
 * @Title: GspellTextBuffer
Packit aa0600
 * @Short_description: Spell checking support for GtkTextBuffer
Packit aa0600
 *
Packit aa0600
 * #GspellTextBuffer extends the #GtkTextBuffer class but without subclassing
Packit aa0600
 * it, because the GtkSourceView library has already a #GtkTextBuffer subclass.
Packit aa0600
 *
Packit aa0600
 * # Support of the no-spell-check tag defined by GtkSourceView
Packit aa0600
 *
Packit aa0600
 * The syntax highlighting engine of the [GtkSourceView
Packit aa0600
 * library](https://wiki.gnome.org/Projects/GtkSourceView) has a feature called
Packit aa0600
 * “context classes”. One of the standard context classes is
Packit aa0600
 * “<emphasis>no-spell-check</emphasis>”: it defines the regions in the
Packit aa0600
 * #GtkTextBuffer that should not be spell-checked.
Packit aa0600
 *
Packit aa0600
 * GtkSourceView creates a #GtkTextTag named
Packit aa0600
 * `"gtksourceview:context-classes:no-spell-check"`. gspell reads this tag, to
Packit aa0600
 * skip the text contained within the tag.
Packit aa0600
 *
Packit aa0600
 * If you use the GtkSourceView library in your application, keep in mind that
Packit aa0600
 * the #GtkTextTag created by GtkSourceView is for read-only purposes; you
Packit aa0600
 * cannot apply it yourself to other regions.
Packit aa0600
 *
Packit aa0600
 * On the other hand if the GtkSourceView library is not used, you can create a
Packit aa0600
 * #GtkTextTag with the same name to mark certain regions in the text that
Packit aa0600
 * gspell should skip. As it is not a great API, it is
Packit aa0600
 * [planned](https://bugzilla.gnome.org/show_bug.cgi?id=771582) to add an
Packit aa0600
 * explicit API in #GspellTextBuffer to set a #GtkTextTag that gspell should
Packit aa0600
 * skip.
Packit aa0600
 *
Packit aa0600
 * See the class description of #GtkSourceBuffer for more information about
Packit aa0600
 * context classes.
Packit aa0600
 */
Packit aa0600
Packit aa0600
struct _GspellTextBuffer
Packit aa0600
{
Packit aa0600
	GObject parent;
Packit aa0600
Packit aa0600
	GtkTextBuffer *buffer;
Packit aa0600
	GspellChecker *spell_checker;
Packit aa0600
};
Packit aa0600
Packit aa0600
enum
Packit aa0600
{
Packit aa0600
	PROP_0,
Packit aa0600
	PROP_BUFFER,
Packit aa0600
	PROP_SPELL_CHECKER,
Packit aa0600
};
Packit aa0600
Packit aa0600
#define GSPELL_TEXT_BUFFER_KEY "gspell-text-buffer-key"
Packit aa0600
Packit aa0600
G_DEFINE_TYPE (GspellTextBuffer, gspell_text_buffer, G_TYPE_OBJECT)
Packit aa0600
Packit aa0600
static void
Packit aa0600
gspell_text_buffer_get_property (GObject    *object,
Packit aa0600
				 guint       prop_id,
Packit aa0600
				 GValue     *value,
Packit aa0600
				 GParamSpec *pspec)
Packit aa0600
{
Packit aa0600
	GspellTextBuffer *gspell_buffer = GSPELL_TEXT_BUFFER (object);
Packit aa0600
Packit aa0600
	switch (prop_id)
Packit aa0600
	{
Packit aa0600
		case PROP_BUFFER:
Packit aa0600
			g_value_set_object (value, gspell_text_buffer_get_buffer (gspell_buffer));
Packit aa0600
			break;
Packit aa0600
Packit aa0600
		case PROP_SPELL_CHECKER:
Packit aa0600
			g_value_set_object (value, gspell_text_buffer_get_spell_checker (gspell_buffer));
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_text_buffer_set_property (GObject      *object,
Packit aa0600
				 guint         prop_id,
Packit aa0600
				 const GValue *value,
Packit aa0600
				 GParamSpec   *pspec)
Packit aa0600
{
Packit aa0600
	GspellTextBuffer *gspell_buffer = GSPELL_TEXT_BUFFER (object);
Packit aa0600
Packit aa0600
	switch (prop_id)
Packit aa0600
	{
Packit aa0600
		case PROP_BUFFER:
Packit aa0600
			g_assert (gspell_buffer->buffer == NULL);
Packit aa0600
			gspell_buffer->buffer = g_value_get_object (value);
Packit aa0600
			break;
Packit aa0600
Packit aa0600
		case PROP_SPELL_CHECKER:
Packit aa0600
			gspell_text_buffer_set_spell_checker (gspell_buffer, g_value_get_object (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_text_buffer_dispose (GObject *object)
Packit aa0600
{
Packit aa0600
	GspellTextBuffer *gspell_buffer = GSPELL_TEXT_BUFFER (object);
Packit aa0600
Packit aa0600
	gspell_buffer->buffer = NULL;
Packit aa0600
	g_clear_object (&gspell_buffer->spell_checker);
Packit aa0600
Packit aa0600
	G_OBJECT_CLASS (gspell_text_buffer_parent_class)->dispose (object);
Packit aa0600
}
Packit aa0600
Packit aa0600
static void
Packit aa0600
gspell_text_buffer_class_init (GspellTextBufferClass *klass)
Packit aa0600
{
Packit aa0600
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit aa0600
Packit aa0600
	object_class->get_property = gspell_text_buffer_get_property;
Packit aa0600
	object_class->set_property = gspell_text_buffer_set_property;
Packit aa0600
	object_class->dispose = gspell_text_buffer_dispose;
Packit aa0600
Packit aa0600
	/**
Packit aa0600
	 * GspellTextBuffer:buffer:
Packit aa0600
	 *
Packit aa0600
	 * The #GtkTextBuffer.
Packit aa0600
	 */
Packit aa0600
	g_object_class_install_property (object_class,
Packit aa0600
					 PROP_BUFFER,
Packit aa0600
					 g_param_spec_object ("buffer",
Packit aa0600
							      "Buffer",
Packit aa0600
							      "",
Packit aa0600
							      GTK_TYPE_TEXT_BUFFER,
Packit aa0600
							      G_PARAM_READWRITE |
Packit aa0600
							      G_PARAM_CONSTRUCT_ONLY |
Packit aa0600
							      G_PARAM_STATIC_STRINGS));
Packit aa0600
Packit aa0600
	/**
Packit aa0600
	 * GspellTextBuffer:spell-checker:
Packit aa0600
	 *
Packit aa0600
	 * The #GspellChecker.
Packit aa0600
	 */
Packit aa0600
	g_object_class_install_property (object_class,
Packit aa0600
					 PROP_SPELL_CHECKER,
Packit aa0600
					 g_param_spec_object ("spell-checker",
Packit aa0600
							      "Spell Checker",
Packit aa0600
							      "",
Packit aa0600
							      GSPELL_TYPE_CHECKER,
Packit aa0600
							      G_PARAM_READWRITE |
Packit aa0600
							      G_PARAM_STATIC_STRINGS));
Packit aa0600
}
Packit aa0600
Packit aa0600
static void
Packit aa0600
gspell_text_buffer_init (GspellTextBuffer *gspell_buffer)
Packit aa0600
{
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_text_buffer_get_from_gtk_text_buffer:
Packit aa0600
 * @gtk_buffer: a #GtkTextBuffer.
Packit aa0600
 *
Packit aa0600
 * Returns the #GspellTextBuffer of @gtk_buffer. The returned object is
Packit aa0600
 * guaranteed to be the same for the lifetime of @gtk_buffer.
Packit aa0600
 *
Packit aa0600
 * Returns: (transfer none): the #GspellTextBuffer of @gtk_buffer.
Packit aa0600
 */
Packit aa0600
/* Yes I know, the function name is a bit long. But at least there is no
Packit aa0600
 * possible confusions. Other names that came to my mind:
Packit aa0600
 * - get_from_buffer(), but it's confusing: which buffer is it?
Packit aa0600
 * - get_from_sibling(): less clear.
Packit aa0600
 */
Packit aa0600
GspellTextBuffer *
Packit aa0600
gspell_text_buffer_get_from_gtk_text_buffer (GtkTextBuffer *gtk_buffer)
Packit aa0600
{
Packit aa0600
	GspellTextBuffer *gspell_buffer;
Packit aa0600
Packit aa0600
	g_return_val_if_fail (GTK_IS_TEXT_BUFFER (gtk_buffer), NULL);
Packit aa0600
Packit aa0600
	gspell_buffer = g_object_get_data (G_OBJECT (gtk_buffer), GSPELL_TEXT_BUFFER_KEY);
Packit aa0600
Packit aa0600
	if (gspell_buffer == NULL)
Packit aa0600
	{
Packit aa0600
		gspell_buffer = g_object_new (GSPELL_TYPE_TEXT_BUFFER,
Packit aa0600
					      "buffer", gtk_buffer,
Packit aa0600
					      NULL);
Packit aa0600
Packit aa0600
		g_object_set_data_full (G_OBJECT (gtk_buffer),
Packit aa0600
					GSPELL_TEXT_BUFFER_KEY,
Packit aa0600
					gspell_buffer,
Packit aa0600
					g_object_unref);
Packit aa0600
	}
Packit aa0600
Packit aa0600
	g_return_val_if_fail (GSPELL_IS_TEXT_BUFFER (gspell_buffer), NULL);
Packit aa0600
	return gspell_buffer;
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_text_buffer_get_buffer:
Packit aa0600
 * @gspell_buffer: a #GspellTextBuffer.
Packit aa0600
 *
Packit aa0600
 * Returns: (transfer none): the #GtkTextBuffer of @gspell_buffer.
Packit aa0600
 */
Packit aa0600
GtkTextBuffer *
Packit aa0600
gspell_text_buffer_get_buffer (GspellTextBuffer *gspell_buffer)
Packit aa0600
{
Packit aa0600
	g_return_val_if_fail (GSPELL_IS_TEXT_BUFFER (gspell_buffer), NULL);
Packit aa0600
Packit aa0600
	return gspell_buffer->buffer;
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_text_buffer_get_spell_checker:
Packit aa0600
 * @gspell_buffer: a #GspellTextBuffer.
Packit aa0600
 *
Packit aa0600
 * Returns: (nullable) (transfer none): the #GspellChecker if one has been set,
Packit aa0600
 *   or %NULL.
Packit aa0600
 */
Packit aa0600
GspellChecker *
Packit aa0600
gspell_text_buffer_get_spell_checker (GspellTextBuffer *gspell_buffer)
Packit aa0600
{
Packit aa0600
	g_return_val_if_fail (GSPELL_IS_TEXT_BUFFER (gspell_buffer), NULL);
Packit aa0600
Packit aa0600
	return gspell_buffer->spell_checker;
Packit aa0600
}
Packit aa0600
Packit aa0600
/**
Packit aa0600
 * gspell_text_buffer_set_spell_checker:
Packit aa0600
 * @gspell_buffer: a #GspellTextBuffer.
Packit aa0600
 * @spell_checker: (nullable): a #GspellChecker, or %NULL to unset the spell
Packit aa0600
 *   checker.
Packit aa0600
 *
Packit aa0600
 * Sets a #GspellChecker to a #GspellTextBuffer. The @gspell_buffer will own a
Packit aa0600
 * reference to @spell_checker, so you can release your reference to
Packit aa0600
 * @spell_checker if you no longer need it.
Packit aa0600
 */
Packit aa0600
void
Packit aa0600
gspell_text_buffer_set_spell_checker (GspellTextBuffer *gspell_buffer,
Packit aa0600
				      GspellChecker    *spell_checker)
Packit aa0600
{
Packit aa0600
	g_return_if_fail (GSPELL_IS_TEXT_BUFFER (gspell_buffer));
Packit aa0600
	g_return_if_fail (spell_checker == NULL || GSPELL_IS_CHECKER (spell_checker));
Packit aa0600
Packit aa0600
	if (g_set_object (&gspell_buffer->spell_checker, spell_checker))
Packit aa0600
	{
Packit aa0600
		g_object_notify (G_OBJECT (gspell_buffer), "spell-checker");
Packit aa0600
	}
Packit aa0600
}
Packit aa0600
Packit aa0600
/* ex:set ts=8 noet: */