[gspell/wip/text-buffer-class] text-buffer: have a real class



commit 0a0264b10cdbc4caa8269ce0ba7f780e4a49e591
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Fri Mar 11 10:57:40 2016 +0100

    text-buffer: have a real class
    
    The API will be better with a real class. And having the spell-checker
    property (with the notify signal) is cleaner than the BufferNotifier
    singleton hack. (and the notify signal is available to apps, while the
    BufferNotifier was private).

 docs/reference/Makefile.am             |    1 -
 docs/reference/gspell-1.0-sections.txt |    6 +-
 gspell/Makefile.am                     |    2 -
 gspell/gspell-buffer-notifier.c        |   99 -------------
 gspell/gspell-buffer-notifier.h        |   47 -------
 gspell/gspell-init.c                   |   27 ----
 gspell/gspell-text-buffer.c            |  235 ++++++++++++++++++++++++++------
 gspell/gspell-text-buffer.h            |   21 +++-
 po/POTFILES.in                         |    1 -
 tests/test-spell.c                     |   28 +++--
 10 files changed, 231 insertions(+), 236 deletions(-)
---
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index e27c6ef..525e24f 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -20,7 +20,6 @@ CFILE_GLOB = $(top_srcdir)/gspell/*.c
 # Header files or dirs to ignore when scanning. Use base file/dir names
 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
 IGNORE_HFILES =                                        \
-       gspell-buffer-notifier.h                \
        gspell-inline-checker-text-buffer.h     \
        gspell-osx.h                            \
        gspell-text-iter.h                      \
diff --git a/docs/reference/gspell-1.0-sections.txt b/docs/reference/gspell-1.0-sections.txt
index 1eba466..02a0639 100644
--- a/docs/reference/gspell-1.0-sections.txt
+++ b/docs/reference/gspell-1.0-sections.txt
@@ -40,9 +40,11 @@ gspell_language_get_type
 
 <SECTION>
 <FILE>text-buffer</FILE>
-<TITLE>GtkTextBuffer support</TITLE>
-gspell_text_buffer_set_spell_checker
+<TITLE>GspellTextBuffer</TITLE>
+gspell_text_buffer_get_from_buffer
+gspell_text_buffer_get_buffer
 gspell_text_buffer_get_spell_checker
+gspell_text_buffer_set_spell_checker
 </SECTION>
 
 <SECTION>
diff --git a/gspell/Makefile.am b/gspell/Makefile.am
index 99029ef..fce324c 100644
--- a/gspell/Makefile.am
+++ b/gspell/Makefile.am
@@ -43,14 +43,12 @@ gspell_public_c_files =                             \
 
 gspell_private_headers =                       \
        gconstructor.h                          \
-       gspell-buffer-notifier.h                \
        gspell-inline-checker-text-buffer.h     \
        gspell-text-iter.h                      \
        gspell-text-region.h                    \
        gspell-utils.h
 
 gspell_private_c_files =                       \
-       gspell-buffer-notifier.c                \
        gspell-init.c                           \
        gspell-inline-checker-text-buffer.c     \
        gspell-text-iter.c                      \
diff --git a/gspell/gspell-init.c b/gspell/gspell-init.c
index 8c8b006..0631cdb 100644
--- a/gspell/gspell-init.c
+++ b/gspell/gspell-init.c
@@ -27,7 +27,6 @@
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 #include "gconstructor.h"
-#include "gspell-buffer-notifier.h"
 
 #ifdef G_OS_WIN32
 #define WIN32_LEAN_AND_MEAN
@@ -123,18 +122,6 @@ gspell_init (void)
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 }
 
-static void
-gspell_finalize (void)
-{
-       GspellBufferNotifier *notifier;
-
-       /* Destroy singleton, to have less garbage in the output of memory
-        * debugging tools.
-        */
-       notifier = _gspell_buffer_notifier_get_instance ();
-       g_object_unref (notifier);
-}
-
 #if defined (G_OS_WIN32)
 
 BOOL WINAPI DllMain (HINSTANCE hinstDLL,
@@ -154,9 +141,6 @@ DllMain (HINSTANCE hinstDLL,
                        break;
 
                case DLL_THREAD_DETACH:
-                       gspell_finalize ();
-                       break;
-
                default:
                        /* do nothing */
                        break;
@@ -178,17 +162,6 @@ gspell_constructor (void)
        gspell_init ();
 }
 
-#  ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA
-#    pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(gspell_destructor)
-#  endif
-G_DEFINE_DESTRUCTOR (gspell_destructor)
-
-static void
-gspell_destructor (void)
-{
-       gspell_finalize ();
-}
-
 #else
 #  error Your platform/compiler is missing constructor support
 #endif
diff --git a/gspell/gspell-text-buffer.c b/gspell/gspell-text-buffer.c
index f03505d..fa9ab35 100644
--- a/gspell/gspell-text-buffer.c
+++ b/gspell/gspell-text-buffer.c
@@ -1,7 +1,7 @@
 /*
  * This file is part of gspell, a spell-checking library.
  *
- * Copyright 2015 - Sébastien Wilmet
+ * Copyright 2015, 2016 - Sébastien Wilmet
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,77 +18,228 @@
  */
 
 #include "gspell-text-buffer.h"
-#include "gspell-buffer-notifier.h"
 
 /**
  * SECTION:text-buffer
- * @Title: GtkTextBuffer support
- * @See_also: #GspellChecker
+ * @Title: GspellTextBuffer
  *
  * Spell checking support for #GtkTextBuffer.
  */
 
-#define SPELL_CHECKER_KEY "gspell-text-buffer-spell-checker-key"
+struct _GspellTextBuffer
+{
+       GObject parent;
+
+       GtkTextBuffer *buffer;
+       GspellChecker *spell_checker;
+};
+
+enum
+{
+       PROP_0,
+       PROP_BUFFER,
+       PROP_SPELL_CHECKER,
+};
+
+#define GSPELL_TEXT_BUFFER_KEY "gspell-text-buffer-key"
+
+G_DEFINE_TYPE (GspellTextBuffer, gspell_text_buffer, G_TYPE_OBJECT)
+
+static void
+gspell_text_buffer_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+       GspellTextBuffer *buffer = GSPELL_TEXT_BUFFER (object);
+
+       switch (prop_id)
+       {
+               case PROP_BUFFER:
+                       g_value_set_object (value, gspell_text_buffer_get_buffer (buffer));
+                       break;
+
+               case PROP_SPELL_CHECKER:
+                       g_value_set_object (value, gspell_text_buffer_get_spell_checker (buffer));
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                       break;
+       }
+}
+
+static void
+gspell_text_buffer_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+       GspellTextBuffer *buffer = GSPELL_TEXT_BUFFER (object);
+
+       switch (prop_id)
+       {
+               case PROP_BUFFER:
+                       g_assert (buffer->buffer == NULL);
+                       buffer->buffer = g_value_get_object (value);
+                       break;
+
+               case PROP_SPELL_CHECKER:
+                       gspell_text_buffer_set_spell_checker (buffer, g_value_get_object (value));
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                       break;
+       }
+}
+
+static void
+gspell_text_buffer_dispose (GObject *object)
+{
+       GspellTextBuffer *buffer = GSPELL_TEXT_BUFFER (object);
+
+       g_clear_object (&buffer->spell_checker);
+
+       G_OBJECT_CLASS (gspell_text_buffer_parent_class)->dispose (object);
+}
+
+static void
+gspell_text_buffer_class_init (GspellTextBufferClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->get_property = gspell_text_buffer_get_property;
+       object_class->set_property = gspell_text_buffer_set_property;
+       object_class->dispose = gspell_text_buffer_dispose;
+
+       /**
+        * GspellTextBuffer:buffer:
+        *
+        * The #GtkTextBuffer.
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_BUFFER,
+                                        g_param_spec_object ("buffer",
+                                                             "Buffer",
+                                                             "",
+                                                             GTK_TYPE_TEXT_BUFFER,
+                                                             G_PARAM_READWRITE |
+                                                             G_PARAM_CONSTRUCT_ONLY |
+                                                             G_PARAM_STATIC_STRINGS));
+
+       /**
+        * GspellTextBuffer:spell-checker:
+        *
+        * The #GspellChecker.
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_SPELL_CHECKER,
+                                        g_param_spec_object ("spell-checker",
+                                                             "Spell Checker",
+                                                             "",
+                                                             GSPELL_TYPE_CHECKER,
+                                                             G_PARAM_READWRITE |
+                                                             G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gspell_text_buffer_init (GspellTextBuffer *buffer)
+{
+}
+
+static GspellTextBuffer *
+gspell_text_buffer_new (GtkTextBuffer *gtk_buffer)
+{
+       g_return_val_if_fail (GTK_IS_TEXT_BUFFER (gtk_buffer), NULL);
+
+       return g_object_new (GSPELL_TYPE_TEXT_BUFFER,
+                            "buffer", gtk_buffer,
+                            NULL);
+}
 
 /**
- * gspell_text_buffer_set_spell_checker:
- * @buffer: a #GtkTextBuffer.
- * @checker: (nullable): a #GspellChecker, or %NULL to unset the spell checker.
+ * gspell_text_buffer_get_from_buffer:
+ * @gtk_buffer: a #GtkTextBuffer.
  *
- * Associates a spell checker to a #GtkTextBuffer. The @buffer will own a
- * reference to @checker, so you can release your reference to @checker if you
- * no longer need it.
+ * Returns the #GspellTextBuffer of @gtk_buffer. The returned object is
+ * guaranteed to be the same for the lifetime of @gtk_buffer.
+ *
+ * Returns: (transfer none): the #GspellTextBuffer of @gtk_buffer.
  */
-void
-gspell_text_buffer_set_spell_checker (GtkTextBuffer *buffer,
-                                     GspellChecker *checker)
+GspellTextBuffer *
+gspell_text_buffer_get_from_buffer (GtkTextBuffer *gtk_buffer)
 {
-       GspellBufferNotifier *notifier;
+       GspellTextBuffer *gspell_buffer;
 
-       g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
-       g_return_if_fail (checker == NULL || GSPELL_IS_CHECKER (checker));
+       g_return_val_if_fail (GTK_IS_TEXT_BUFFER (gtk_buffer), NULL);
 
-       if (checker != NULL)
+       gspell_buffer = g_object_get_data (G_OBJECT (gtk_buffer), GSPELL_TEXT_BUFFER_KEY);
+       if (gspell_buffer != NULL)
        {
-               g_object_set_data_full (G_OBJECT (buffer),
-                                       SPELL_CHECKER_KEY,
-                                       g_object_ref (checker),
-                                       g_object_unref);
-       }
-       else
-       {
-               g_object_set_data (G_OBJECT (buffer),
-                                  SPELL_CHECKER_KEY,
-                                  NULL);
+               g_return_val_if_fail (GSPELL_IS_TEXT_BUFFER (gspell_buffer), NULL);
+               return gspell_buffer;
        }
 
-       notifier = _gspell_buffer_notifier_get_instance ();
-       _gspell_buffer_notifier_text_buffer_checker_changed (notifier, buffer, checker);
+       gspell_buffer = gspell_text_buffer_new (gtk_buffer);
+       g_object_set_data_full (G_OBJECT (gtk_buffer),
+                               GSPELL_TEXT_BUFFER_KEY,
+                               gspell_buffer,
+                               g_object_unref);
+
+       return gspell_buffer;
+}
+
+/**
+ * gspell_text_buffer_get_buffer:
+ * @gspell_buffer: a #GspellTextBuffer.
+ *
+ * Returns: (transfer none): the #GtkTextBuffer of @gspell_buffer.
+ */
+GtkTextBuffer *
+gspell_text_buffer_get_buffer (GspellTextBuffer *gspell_buffer)
+{
+       g_return_val_if_fail (GSPELL_IS_TEXT_BUFFER (gspell_buffer), NULL);
+
+       return gspell_buffer->buffer;
 }
 
 /**
  * gspell_text_buffer_get_spell_checker:
- * @buffer: a #GtkTextBuffer.
+ * @buffer: a #GspellTextBuffer.
  *
- * Returns: (nullable) (transfer none): the associated #GspellChecker if one has
- * been set, or %NULL.
+ * Returns: (nullable) (transfer none): the #GspellChecker if one has been set,
+ *   or %NULL.
  */
 GspellChecker *
-gspell_text_buffer_get_spell_checker (GtkTextBuffer *buffer)
+gspell_text_buffer_get_spell_checker (GspellTextBuffer *buffer)
 {
-       gpointer data;
+       g_return_val_if_fail (GSPELL_IS_TEXT_BUFFER (buffer), NULL);
 
-       g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
+       return buffer->spell_checker;
+}
 
-       data = g_object_get_data (G_OBJECT (buffer), SPELL_CHECKER_KEY);
+/**
+ * gspell_text_buffer_set_spell_checker:
+ * @buffer: a #GspellTextBuffer.
+ * @spell_checker: (nullable): a #GspellChecker, or %NULL to unset the spell
+ *   checker.
+ *
+ * Sets a #GspellChecker to a #GspellTextBuffer. The @buffer will own a
+ * reference to @spell_checker, so you can release your reference to
+ * @spell_checker if you no longer need it.
+ */
+void
+gspell_text_buffer_set_spell_checker (GspellTextBuffer *buffer,
+                                     GspellChecker    *spell_checker)
+{
+       g_return_if_fail (GSPELL_IS_TEXT_BUFFER (buffer));
+       g_return_if_fail (spell_checker == NULL || GSPELL_IS_CHECKER (spell_checker));
 
-       if (data == NULL)
+       if (g_set_object (&buffer->spell_checker, spell_checker))
        {
-               return NULL;
+               g_object_notify (G_OBJECT (buffer), "spell-checker");
        }
-
-       g_return_val_if_fail (GSPELL_IS_CHECKER (data), NULL);
-       return data;
 }
 
 /* ex:set ts=8 noet: */
diff --git a/gspell/gspell-text-buffer.h b/gspell/gspell-text-buffer.h
index 7d72ad8..564dbc7 100644
--- a/gspell/gspell-text-buffer.h
+++ b/gspell/gspell-text-buffer.h
@@ -1,7 +1,7 @@
 /*
  * This file is part of gspell, a spell-checking library.
  *
- * Copyright 2015 - Sébastien Wilmet
+ * Copyright 2015, 2016 - Sébastien Wilmet
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,10 +27,23 @@
 #include <gspell/gspell-checker.h>
 #include <gtk/gtk.h>
 
-void           gspell_text_buffer_set_spell_checker    (GtkTextBuffer *buffer,
-                                                        GspellChecker *checker);
+G_BEGIN_DECLS
 
-GspellChecker *        gspell_text_buffer_get_spell_checker    (GtkTextBuffer *buffer);
+#define GSPELL_TYPE_TEXT_BUFFER (gspell_text_buffer_get_type ())
+G_DECLARE_FINAL_TYPE (GspellTextBuffer, gspell_text_buffer,
+                     GSPELL, TEXT_BUFFER,
+                     GObject)
+
+GspellTextBuffer *     gspell_text_buffer_get_from_buffer      (GtkTextBuffer *gtk_buffer);
+
+GtkTextBuffer *                gspell_text_buffer_get_buffer           (GspellTextBuffer *gspell_buffer);
+
+GspellChecker *                gspell_text_buffer_get_spell_checker    (GspellTextBuffer *buffer);
+
+void                   gspell_text_buffer_set_spell_checker    (GspellTextBuffer *buffer,
+                                                                GspellChecker    *spell_checker);
+
+G_END_DECLS
 
 #endif /* __GSPELL_TEXT_BUFFER_H__ */
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9cb374b..81bd1ef 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,5 +1,4 @@
 # List of source files containing translatable strings.
-gspell/gspell-buffer-notifier.c
 gspell/gspell-checker.c
 gspell/gspell-checker-dialog.c
 gspell/gspell-inline-checker-text-buffer.c
diff --git a/tests/test-spell.c b/tests/test-spell.c
index 3a497d5..8cfa519 100644
--- a/tests/test-spell.c
+++ b/tests/test-spell.c
@@ -70,18 +70,22 @@ static void
 change_buffer_button_clicked_cb (GtkButton *change_buffer_button,
                                 TestSpell *spell)
 {
-       GtkTextBuffer *old_buffer;
-       GtkTextBuffer *new_buffer;
+       GtkTextBuffer *old_gtk_buffer;
+       GtkTextBuffer *new_gtk_buffer;
+       GspellTextBuffer *old_gspell_buffer;
+       GspellTextBuffer *new_gspell_buffer;
        GspellChecker *checker;
 
-       old_buffer = gtk_text_view_get_buffer (spell->view);
-       checker = gspell_text_buffer_get_spell_checker (old_buffer);
+       old_gtk_buffer = gtk_text_view_get_buffer (spell->view);
+       old_gspell_buffer = gspell_text_buffer_get_from_buffer (old_gtk_buffer);
+       checker = gspell_text_buffer_get_spell_checker (old_gspell_buffer);
 
-       new_buffer = gtk_text_buffer_new (NULL);
-       gspell_text_buffer_set_spell_checker (new_buffer, checker);
+       new_gtk_buffer = gtk_text_buffer_new (NULL);
+       new_gspell_buffer = gspell_text_buffer_get_from_buffer (new_gtk_buffer);
+       gspell_text_buffer_set_spell_checker (new_gspell_buffer, checker);
 
-       gtk_text_view_set_buffer (spell->view, new_buffer);
-       g_object_unref (new_buffer);
+       gtk_text_view_set_buffer (spell->view, new_gtk_buffer);
+       g_object_unref (new_gtk_buffer);
 }
 
 static GtkWidget *
@@ -157,14 +161,16 @@ static void
 test_spell_init (TestSpell *spell)
 {
        GtkWidget *scrolled_window;
-       GtkTextBuffer *buffer;
+       GtkTextBuffer *gtk_buffer;
+       GspellTextBuffer *gspell_buffer;
        GspellChecker *checker;
 
        spell->view = GTK_TEXT_VIEW (gtk_text_view_new ());
-       buffer = gtk_text_view_get_buffer (spell->view);
+       gtk_buffer = gtk_text_view_get_buffer (spell->view);
 
        checker = gspell_checker_new (NULL);
-       gspell_text_buffer_set_spell_checker (buffer, checker);
+       gspell_buffer = gspell_text_buffer_get_from_buffer (gtk_buffer);
+       gspell_text_buffer_set_spell_checker (gspell_buffer, checker);
        g_object_unref (checker);
 
        gtk_orientable_set_orientation (GTK_ORIENTABLE (spell),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]