From 95773bfde8a6915fcd206286b433dca38883b736 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 1 Jun 2020 19:06:10 +0200
Subject: Updated the Python bindings for the GtkDockable interface.

---
 plugins/pychrysalide/arch/processor.c  |   2 +-
 plugins/pychrysalide/gtkext/dockable.c | 603 ++++++++++++++++++++++++++++++++-
 plugins/pychrysalide/gtkext/dockable.h |   9 +-
 plugins/pychrysalide/gtkext/module.c   |   2 +-
 plugins/pychrysalide/gui/panel.c       |   4 +-
 src/gtkext/gtkdockable-int.h           |  16 +-
 src/gtkext/gtkdockable.c               |  49 ++-
 src/gtkext/gtkdockable.h               |  10 +-
 src/gtkext/gtkdockstation.c            |  15 +-
 src/gtkext/tiledgrid.c                 |   6 +-
 src/gui/panel.c                        |  70 ++--
 11 files changed, 705 insertions(+), 81 deletions(-)

diff --git a/plugins/pychrysalide/arch/processor.c b/plugins/pychrysalide/arch/processor.c
index 10fcf03..43e42ce 100644
--- a/plugins/pychrysalide/arch/processor.c
+++ b/plugins/pychrysalide/arch/processor.c
@@ -808,7 +808,7 @@ static PyObject *py_arch_processor_get_desc(PyObject *self, void *closure)
 #define ARCH_PROCESSOR_DESC_ATTRIB PYTHON_GET_DEF_FULL      \
 (                                                           \
     desc, py_arch_processor,                                \
-    "Provide a a human readable description of the new"     \
+    "Provide a human readable description of the new"       \
     " architecture, as a simple string."                    \
 )
 
diff --git a/plugins/pychrysalide/gtkext/dockable.c b/plugins/pychrysalide/gtkext/dockable.c
index b9787f9..8bb26b7 100644
--- a/plugins/pychrysalide/gtkext/dockable.c
+++ b/plugins/pychrysalide/gtkext/dockable.c
@@ -28,7 +28,7 @@
 #include <pygobject.h>
 
 
-#include <gtkext/gtkdockable.h>
+#include <gtkext/gtkdockable-int.h>
 
 
 #include "../access.h"
@@ -36,6 +36,519 @@
 
 
 
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Procède à l'initialisation de l'interface d'incrustation. */
+static void py_dockable_interface_init(GtkDockableInterface *, gpointer *);
+
+/* Fournit le nom court du composant encapsulable. */
+static char *py_dockable_get_name_wrapper(const GtkDockable *);
+
+/* Fournit le nom long du composant encapsulable. */
+static char *py_dockable_get_desc_wrapper(const GtkDockable *);
+
+/* Indique si le composant représenté à du contenu à fouiller. */
+static bool py_dockable_can_search_wrapper(const GtkDockable *);
+
+/* Fournit le composant graphique intégrable dans un ensemble. */
+static GtkWidget *py_dockable_get_widget_wrapper(const GtkDockable *);
+
+/* Applique un nouveau filtre sur un composant intégré. */
+static void py_dockable_update_filter_wrapper(GtkDockable *, const char *);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
+
+/* Fournit le nom court du composant encapsulable. */
+static PyObject *py_dockable_get_name(PyObject *, void *);
+
+/* Fournit le nom long du composant encapsulable. */
+static PyObject *py_dockable_get_desc(PyObject *, void *);
+
+/* Indique si le composant représenté à du contenu à fouiller. */
+static PyObject *py_dockable_get_can_search(PyObject *, void *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface  = interface GLib à initialiser.                       *
+*                unused = adresse non utilisée ici.                           *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface d'incrustation.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void py_dockable_interface_init(GtkDockableInterface *iface, gpointer *unused)
+{
+
+#define DOCKABLE_DOC                                                        \
+    "Dockable defines an interface for all Gtk dockable widgets.\n"         \
+    "\n"                                                                    \
+    "A typical class declaration for a new implementation looks like:\n"    \
+    "\n"                                                                    \
+    "    class NewImplem(GObject.Object, Dockable):\n"                      \
+    "        ...\n"                                                         \
+    "\n"                                                                    \
+    "\n"                                                                    \
+    "Several items have to be defined as class attributes in the final"     \
+    " class:\n"                                                             \
+    "* *_name*: a string providing a short name for the dockable item;\n"   \
+    "* *_desc*: a string for a human readable description of the dockable"  \
+    " item;\n"                                                              \
+    "* *_can_search*: a boolean value indicating if a search widget is"     \
+    " suitable for the dockable item.\n"                                    \
+    "\n"                                                                    \
+    "The following methods have to be defined for new implementations:\n"   \
+    "* pychrysalide.gtkext.Dockable._get_widget();\n"                       \
+    "* pychrysalide.gtkext.Dockable._update_filter();\n"                    \
+
+    iface->get_name = py_dockable_get_name_wrapper;
+    iface->get_desc = py_dockable_get_desc_wrapper;
+    iface->can_search = py_dockable_can_search_wrapper;
+
+    iface->get_widget = py_dockable_get_widget_wrapper;
+    iface->update_filtered = py_dockable_update_filter_wrapper;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Fournit le nom court du composant encapsulable.              *
+*                                                                             *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *py_dockable_get_name_wrapper(const GtkDockable *dockable)
+{
+    char *result;                           /* Désignation à retourner     */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyname;                       /* Désignation en objet Python */
+    int ret;                                /* Bilan d'une conversion      */
+
+    result = NULL;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(dockable));
+
+    if (PyObject_HasAttrString(pyobj, "_name"))
+    {
+        pyname = PyObject_GetAttrString(pyobj, "_name");
+
+        if (pyname != NULL)
+        {
+            ret = PyUnicode_Check(pyname);
+
+            if (ret)
+                result = strdup(PyUnicode_AsUTF8(pyname));
+
+            Py_DECREF(pyname);
+
+        }
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Fournit le nom long du composant encapsulable.               *
+*                                                                             *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *py_dockable_get_desc_wrapper(const GtkDockable *dockable)
+{
+    char *result;                           /* Description à retourner     */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pydesc;                       /* Description en objet Python */
+    int ret;                                /* Bilan d'une conversion      */
+
+    result = NULL;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(dockable));
+
+    if (PyObject_HasAttrString(pyobj, "_desc"))
+    {
+        pydesc = PyObject_GetAttrString(pyobj, "_desc");
+
+        if (pydesc != NULL)
+        {
+            ret = PyUnicode_Check(pydesc);
+
+            if (ret)
+                result = strdup(PyUnicode_AsUTF8(pydesc));
+
+            Py_DECREF(pydesc);
+
+        }
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Indique si le composant représenté à du contenu à fouiller.  *
+*                                                                             *
+*  Retour      : Etat de la capacité.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_dockable_can_search_wrapper(const GtkDockable *dockable)
+{
+    bool result;                            /* Indication à retourner      */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Retour d'un appel           */
+    int ret;                                /* Bilan d'une conversion      */
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(dockable));
+
+    if (PyObject_HasAttrString(pyobj, "_can_search"))
+    {
+        pyret = PyObject_GetAttrString(pyobj, "_can_search");
+
+        if (pyret != NULL)
+        {
+            ret = PyBool_Check(pyret);
+
+            if (ret)
+                result = (pyret == Py_True);
+
+            Py_DECREF(pyret);
+
+        }
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Fournit le composant graphique intégrable dans un ensemble.  *
+*                                                                             *
+*  Retour      : Composant graphique prêt à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GtkWidget *py_dockable_get_widget_wrapper(const GtkDockable *dockable)
+{
+    GtkWidget *result;                      /* Composant à retourner       */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+    PyObject *gtk_mod;                      /* Module Python Gtk           */
+    PyObject *widget_type;                  /* Module "GtkWidget"          */
+    int ret;                                /* Bilan d'une conversion      */
+
+#define DOCKABLE_GET_WIDGET_WRAPPER PYTHON_WRAPPER_DEF              \
+(                                                                   \
+    _get_widget, "$self, /",                                        \
+    METH_NOARGS,                                                    \
+    "Abstract method used to get the widget for a dockable item.\n" \
+    "\n"                                                            \
+    "The result has to be a Gtk.Widget instance."                   \
+)
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(dockable));
+
+    if (has_python_method(pyobj, "_get_widget"))
+    {
+        pyret = run_python_method(pyobj, "_get_widget", NULL);
+
+        if (pyret != NULL)
+        {
+            gtk_mod = PyImport_ImportModule("gi.repository.Gtk");
+
+            if (gtk_mod == NULL)
+            {
+                PyErr_SetString(PyExc_TypeError, "unable to find the Gtk Python module");
+                goto done;
+            }
+
+            widget_type = PyObject_GetAttrString(gtk_mod, "Widget");
+
+            Py_DECREF(gtk_mod);
+
+            ret = PyObject_TypeCheck(pyret, (PyTypeObject *)widget_type);
+
+            Py_DECREF(widget_type);
+
+            if (!ret)
+            {
+                PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to GTK widget");
+                goto done;
+            }
+
+            result = GTK_WIDGET(pygobject_get(pyret));
+            g_object_ref(G_OBJECT(result));
+
+ done:
+
+            Py_DECREF(pyret);
+
+        }
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à manipuler.    *
+*                filter   = nouveau filtre à appliquer.                       *
+*                                                                             *
+*  Description : Applique un nouveau filtre sur un composant intégré.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void py_dockable_update_filter_wrapper(GtkDockable *dockable, const char *filter)
+{
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyret;                        /* Bilan de consultation       */
+
+#define DOCKABLE_UPDATE_FILTER_WRAPPER PYTHON_WRAPPER_DEF           \
+(                                                                   \
+    _update_filter, "$self, filter, /",                             \
+    METH_VARARGS,                                                   \
+    "Abstract method used to update the content of a dockable item" \
+    " according to a given filter string."                          \
+)
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(dockable));
+
+    if (has_python_method(pyobj, "_update_filter"))
+    {
+        args = PyTuple_New(1);
+        PyTuple_SetItem(args, 0, PyUnicode_FromString(filter));
+
+        pyret = run_python_method(pyobj, "_update_filter", args);
+
+        Py_XDECREF(pyret);
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           CONNEXION AVEC L'API DE PYTHON                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit le nom court du composant encapsulable.              *
+*                                                                             *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_dockable_get_name(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Instance Python à retourner */
+    GtkDockable *dockable;                  /* Version GLib du composant   */
+    char *name;                             /* Désignation du composant    */
+
+#define DOCKABLE_NAME_ATTRIB PYTHON_GET_DEF_FULL        \
+(                                                       \
+    name, py_dockable,                                  \
+    "Provide the short name of a dockable item, as"     \
+    " a simple string."                                 \
+)
+
+    dockable = GTK_DOCKABLE(pygobject_get(self));
+
+    name = gtk_dockable_get_name(dockable);
+
+    if (name != NULL)
+    {
+        result = PyUnicode_FromString(name);
+        free(name);
+    }
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit le nom long du composant encapsulable.               *
+*                                                                             *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_dockable_get_desc(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Instance Python à retourner */
+    GtkDockable *dockable;                  /* Version GLib du composant   */
+    char *desc;                             /* Description du composant    */
+
+#define DOCKABLE_DESC_ATTRIB PYTHON_GET_DEF_FULL    \
+(                                                   \
+    desc, py_dockable,                              \
+    "Provide a human readable description of the"   \
+    " dockable item, as a string."                  \
+)
+
+    dockable = GTK_DOCKABLE(pygobject_get(self));
+
+    desc = gtk_dockable_get_desc(dockable);
+
+    if (desc != NULL)
+    {
+        result = PyUnicode_FromString(desc);
+        free(desc);
+    }
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Indique si le composant représenté à du contenu à fouiller.  *
+*                                                                             *
+*  Retour      : Etat de la capacité.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_dockable_get_can_search(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Instance Python à retourner */
+    GtkDockable *dockable;                  /* Version GLib du composant   */
+    bool status;                            /* Capacité à faire suivre     */
+
+#define DOCKABLE_CAN_SEARCH_ATTRIB PYTHON_GET_DEF_FULL      \
+(                                                           \
+    can_search, py_dockable,                                \
+    "Status of a search support for the dockable item."     \
+)
+
+    dockable = GTK_DOCKABLE(pygobject_get(self));
+
+    status = gtk_dockable_can_search(dockable);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : -                                                            *
@@ -48,33 +561,38 @@
 *                                                                             *
 ******************************************************************************/
 
-PyTypeObject *get_python_gtk_dockable_type(void)
+PyTypeObject *get_python_dockable_type(void)
 {
-    static PyMethodDef py_gtk_dockable_methods[] = {
+    static PyMethodDef py_dockable_methods[] = {
+        DOCKABLE_GET_WIDGET_WRAPPER,
+        DOCKABLE_UPDATE_FILTER_WRAPPER,
         { NULL }
     };
 
-    static PyGetSetDef py_gtk_dockable_getseters[] = {
+    static PyGetSetDef py_dockable_getseters[] = {
+        DOCKABLE_NAME_ATTRIB,
+        DOCKABLE_DESC_ATTRIB,
+        DOCKABLE_CAN_SEARCH_ATTRIB,
         { NULL }
     };
 
-    static PyTypeObject py_gtk_dockable_type = {
+    static PyTypeObject py_dockable_type = {
 
         PyVarObject_HEAD_INIT(NULL, 0)
 
-        .tp_name        = "pychrysalide.gtkext.GtkDockable",
-        //.tp_basicsize   = sizeof(PyGObject),
+        .tp_name        = "pychrysalide.gtkext.Dockable",
+        .tp_basicsize   = sizeof(PyObject),
 
         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 
-        .tp_doc         = "PyChrysalide interface for Gtk dockable widgets",
+        .tp_doc         = DOCKABLE_DOC,
 
-        .tp_methods     = py_gtk_dockable_methods,
-        .tp_getset      = py_gtk_dockable_getseters,
+        .tp_methods     = py_dockable_methods,
+        .tp_getset      = py_dockable_getseters,
 
     };
 
-    return &py_gtk_dockable_type;
+    return &py_dockable_type;
 
 }
 
@@ -83,7 +601,7 @@ PyTypeObject *get_python_gtk_dockable_type(void)
 *                                                                             *
 *  Paramètres  : module = module dont la définition est à compléter.          *
 *                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide.gtkext.GtkDockable'.   *
+*  Description : Prend en charge l'objet 'pychrysalide.gtkext.Dockable'.      *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -91,13 +609,21 @@ PyTypeObject *get_python_gtk_dockable_type(void)
 *                                                                             *
 ******************************************************************************/
 
-bool ensure_python_gtk_dockable_is_registered(void)
+bool ensure_python_dockable_is_registered(void)
 {
-    PyTypeObject *type;                     /* Type Python 'GtkDockable'   */
+    PyTypeObject *type;                     /* Type Python 'Dockable'      */
     PyObject *module;                       /* Module à recompléter        */
     PyObject *dict;                         /* Dictionnaire du module      */
 
-    type = get_python_gtk_dockable_type();
+    static GInterfaceInfo info = {          /* Paramètres d'inscription    */
+
+        .interface_init = (GInterfaceInitFunc)py_dockable_interface_init,
+        .interface_finalize = NULL,
+        .interface_data = NULL,
+
+    };
+
+    type = get_python_dockable_type();
 
     if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
     {
@@ -105,7 +631,7 @@ bool ensure_python_gtk_dockable_is_registered(void)
 
         dict = PyModule_GetDict(module);
 
-        if (!register_interface_for_pygobject(dict, GTK_TYPE_DOCKABLE, type))
+        if (!register_interface_for_pygobject_2(dict, GTK_TYPE_DOCKABLE, type, &info))
             return false;
 
     }
@@ -113,3 +639,48 @@ bool ensure_python_gtk_dockable_is_registered(void)
     return true;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en élément incrustable.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_dockable(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_dockable_type());
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to dockable item");
+            break;
+
+        case 1:
+            *((GtkDockable **)dst) = GTK_DOCKABLE(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/gtkext/dockable.h b/plugins/pychrysalide/gtkext/dockable.h
index eb5cbbf..6b7db63 100644
--- a/plugins/pychrysalide/gtkext/dockable.h
+++ b/plugins/pychrysalide/gtkext/dockable.h
@@ -32,10 +32,13 @@
 
 
 /* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_gtk_dockable_type(void);
+PyTypeObject *get_python_dockable_type(void);
 
-/* Prend en charge l'objet 'pychrysalide.gtkext.GtkDockable'. */
-bool ensure_python_gtk_dockable_is_registered(void);
+/* Prend en charge l'objet 'pychrysalide.gtkext.Dockable'. */
+bool ensure_python_dockable_is_registered(void);
+
+/* Tente de convertir en élément incrustable. */
+int convert_to_dockable(PyObject *, void *);
 
 
 
diff --git a/plugins/pychrysalide/gtkext/module.c b/plugins/pychrysalide/gtkext/module.c
index 4b4b247..7c684e4 100644
--- a/plugins/pychrysalide/gtkext/module.c
+++ b/plugins/pychrysalide/gtkext/module.c
@@ -100,7 +100,7 @@ bool populate_gtkext_module(void)
     if (result) result = ensure_python_block_display_is_registered();
     if (result) result = ensure_python_buffer_display_is_registered();
     if (result) result = ensure_python_display_panel_is_registered();
-    if (result) result = ensure_python_gtk_dockable_is_registered();
+    if (result) result = ensure_python_dockable_is_registered();
 
     if (result) result = populate_gtkext_graph_module();
 
diff --git a/plugins/pychrysalide/gui/panel.c b/plugins/pychrysalide/gui/panel.c
index fd31ef8..33ff4e3 100644
--- a/plugins/pychrysalide/gui/panel.c
+++ b/plugins/pychrysalide/gui/panel.c
@@ -561,11 +561,11 @@ bool ensure_python_panel_item_is_registered(void)
         if (!ensure_python_editor_item_is_registered())
             return false;
 
-        if (!ensure_python_gtk_dockable_is_registered())
+        if (!ensure_python_dockable_is_registered())
             return false;
 
         if (!_register_class_for_pygobject(dict, G_TYPE_PANEL_ITEM, type,
-                                           get_python_editor_item_type(), get_python_gtk_dockable_type(), NULL))
+                                           get_python_editor_item_type(), get_python_dockable_type(), NULL))
             return false;
 
         if (!define_panel_item_constants(type))
diff --git a/src/gtkext/gtkdockable-int.h b/src/gtkext/gtkdockable-int.h
index 7390913..656e16c 100644
--- a/src/gtkext/gtkdockable-int.h
+++ b/src/gtkext/gtkdockable-int.h
@@ -32,20 +32,20 @@
 
 
 
-/* Indique si le composant représenté à du contenu à fouiller. */
-typedef bool (* can_dockable_search_fc) (const GtkDockable *);
-
 /* Fournit le nom court du composant encapsulable. */
-typedef const char * (* get_dockable_name_fc) (const GtkDockable *);
+typedef char * (* get_dockable_name_fc) (const GtkDockable *);
 
 /* Fournit le nom court du composant encapsulable. */
-typedef const char * (* get_dockable_desc_fc) (const GtkDockable *);
+typedef char * (* get_dockable_desc_fc) (const GtkDockable *);
+
+/* Indique si le composant représenté à du contenu à fouiller. */
+typedef bool (* can_dockable_search_fc) (const GtkDockable *);
 
 /* Fournit le composant principal à encapsuler au besoin. */
 typedef GtkWidget * (* get_dockable_widget_fc) (const GtkDockable *);
 
 /* Démarre l'actualisation du filtrage des paramètres. */
-typedef void (* update_filtered_data_fc) (GtkDockable *, char *);
+typedef void (* update_filtered_data_fc) (GtkDockable *, const char *);
 
 
 /* Elément accepté dans les rassemblements (interface) */
@@ -53,10 +53,10 @@ struct _GtkDockableIface
 {
     GTypeInterface base_iface;              /* A laisser en premier        */
 
-    can_dockable_search_fc can_search;      /* Contenu fouillable ?        */
-
     get_dockable_name_fc get_name;          /* Nom pour titre              */
     get_dockable_desc_fc get_desc;          /* Description humaine         */
+    can_dockable_search_fc can_search;      /* Contenu fouillable ?        */
+
     get_dockable_widget_fc get_widget;      /* Composant à représenter     */
     update_filtered_data_fc update_filtered;/* Mise à jour du filtrage     */
 
diff --git a/src/gtkext/gtkdockable.c b/src/gtkext/gtkdockable.c
index c4291b7..26feb95 100644
--- a/src/gtkext/gtkdockable.c
+++ b/src/gtkext/gtkdockable.c
@@ -44,6 +44,9 @@
 /* Procède à l'initialisation de l'interface de rassemblement. */
 static void gtk_dockable_default_init(GtkDockableInterface *);
 
+/* Applique un nouveau filtre sur un composant intégré. */
+static void gtk_dockable_update_filter(GtkDockable *, const char *);
+
 
 
 /* ------------------------ FONCTIONS DE RECHERCHE INTEGREES ------------------------ */
@@ -151,13 +154,16 @@ static void gtk_dockable_default_init(GtkDockableInterface *iface)
 *                                                                             *
 ******************************************************************************/
 
-const char *gtk_dockable_get_name(const GtkDockable *dockable)
+char *gtk_dockable_get_name(const GtkDockable *dockable)
 {
+    char *result;                           /* Désignation à retourner     */
     GtkDockableIface *iface;                /* Interface utilisée          */
 
     iface = GTK_DOCKABLE_GET_IFACE(dockable);
 
-    return iface->get_name(dockable);
+    result = iface->get_name(dockable);
+
+    return result;
 
 }
 
@@ -174,13 +180,16 @@ const char *gtk_dockable_get_name(const GtkDockable *dockable)
 *                                                                             *
 ******************************************************************************/
 
-const char *gtk_dockable_get_desc(const GtkDockable *dockable)
+char *gtk_dockable_get_desc(const GtkDockable *dockable)
 {
+    char *result;                           /* Description à retourner     */
     GtkDockableIface *iface;                /* Interface utilisée          */
 
     iface = GTK_DOCKABLE_GET_IFACE(dockable);
 
-    return iface->get_desc(dockable);
+    result = iface->get_desc(dockable);
+
+    return result;
 
 }
 
@@ -191,7 +200,7 @@ const char *gtk_dockable_get_desc(const GtkDockable *dockable)
 *                                                                             *
 *  Description : Indique si le composant représenté à du contenu à fouiller.  *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Etat de la capacité.                                         *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
@@ -234,7 +243,6 @@ GtkWidget *gtk_dockable_build_widget(GtkDockable *dockable)
     iface = GTK_DOCKABLE_GET_IFACE(dockable);
 
     widget = iface->get_widget(dockable);
-    g_object_ref(G_OBJECT(widget));
 
     /* Encapsulation avec un panneau coulissant ? */
 
@@ -267,6 +275,30 @@ GtkWidget *gtk_dockable_build_widget(GtkDockable *dockable)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à manipuler.    *
+*                filter   = nouveau filtre à appliquer.                       *
+*                                                                             *
+*  Description : Applique un nouveau filtre sur un composant intégré.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_dockable_update_filter(GtkDockable *dockable, const char *filter)
+{
+    GtkDockableIface *iface;                /* Interface utilisée          */
+
+    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+    iface->update_filtered(dockable, filter);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
 *                support  = composant à partir duquel décrocher ou NULL. [OUT]*
 *                                                                             *
@@ -392,15 +424,14 @@ static GtkWidget *build_search_area(GtkDockable *dockable, GtkWidget **search)
 static void on_dockable_search_changed(GtkSearchEntry *entry, GtkDockable *dockable)
 {
     char *filter;                           /* Nouveau filtre à considérer */
-    GtkDockableIface *iface;                /* Interface utilisée          */
 
     filter = NULL;
 
     update_regex_on_search_entry_changed(entry, &filter);
 
-    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+    gtk_dockable_update_filter(dockable, filter);
 
-    iface->update_filtered(dockable, filter);
+    free(filter);
 
 }
 
diff --git a/src/gtkext/gtkdockable.h b/src/gtkext/gtkdockable.h
index 9f98312..0e08070 100644
--- a/src/gtkext/gtkdockable.h
+++ b/src/gtkext/gtkdockable.h
@@ -49,14 +49,14 @@ typedef struct _GtkDockableIface GtkDockableIface;
 /* Détermine le type d'une interface pour rassemblement. */
 GType gtk_dockable_get_type(void) G_GNUC_CONST;
 
-/* Indique si le composant représenté à du contenu à fouiller. */
-bool gtk_dockable_can_search(const GtkDockable *);
-
 /* Fournit le nom court du composant encapsulable. */
-const char *gtk_dockable_get_name(const GtkDockable *);
+char *gtk_dockable_get_name(const GtkDockable *);
 
 /* Fournit le nom long du composant encapsulable. */
-const char *gtk_dockable_get_desc(const GtkDockable *);
+char *gtk_dockable_get_desc(const GtkDockable *);
+
+/* Indique si le composant représenté à du contenu à fouiller. */
+bool gtk_dockable_can_search(const GtkDockable *);
 
 /* Fournit le composant graphique intégrable dans un ensemble. */
 GtkWidget *gtk_dockable_build_widget(GtkDockable *);
diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c
index 314467e..1757542 100644
--- a/src/gtkext/gtkdockstation.c
+++ b/src/gtkext/gtkdockstation.c
@@ -257,10 +257,9 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p
 void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable)
 {
     GtkWidget *widget;                      /* Composant GTK à intégrer    */
-    const char *caption;                    /* Nom à donner à l'onglet     */
-    const char *desc;                       /* Description à y associer    */
+    char *name;                             /* Nom à donner à l'onglet     */
+    char *desc;                             /* Description à y associer    */
     int max;                                /* Taille maximale des titres  */
-    char *str;                              /* Titre des prochaines fois   */
     GtkWidget *label;                       /* Etiquette d'onglet          */
     GtkNotebook *notebook;                  /* Autre version du composant  */
 
@@ -280,7 +279,7 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
 
     g_object_set_data(G_OBJECT(widget), "dockable", dockable);
 
-    caption = gtk_dockable_get_name(dockable);
+    name = gtk_dockable_get_name(dockable);
     desc = gtk_dockable_get_desc(dockable);
 
     /* Mise en place de la page */
@@ -288,9 +287,9 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
     if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_TAB, &max))
         max = -1;
 
-    str = ellipsis(strdup(caption), max);
-    label = qck_create_label(NULL, NULL, str);
-    free(str);
+    name = ellipsis(name, max);
+    label = qck_create_label(NULL, NULL, name);
+    free(name);
 
     notebook = GTK_NOTEBOOK(station);
 
@@ -302,6 +301,8 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
 
     gtk_widget_set_tooltip_text(label, desc);
 
+    free(desc);
+
     if (gtk_notebook_get_n_pages(notebook) > 1)
     g_signal_connect(notebook, "switch-page",
                      G_CALLBACK(gtk_dock_station_switch_panel), station);
diff --git a/src/gtkext/tiledgrid.c b/src/gtkext/tiledgrid.c
index e04685c..5287352 100644
--- a/src/gtkext/tiledgrid.c
+++ b/src/gtkext/tiledgrid.c
@@ -885,14 +885,16 @@ void gtk_tiled_grid_set_default_main_panel(GtkTiledGrid *tgrid, GPanelItem *pane
 void gtk_tiled_grid_add(GtkTiledGrid *tgrid, GPanelItem *panel)
 {
     const char *path;                       /* Chemin d'accès              */
+    char *name;                             /* Nom à donner à l'onglet     */
     grid_tile_t *tile;                      /* Tuile d'accueil             */
 
     path = gtk_panel_item_get_path(panel);
 
     if (!is_valid_tile_path(path))
     {
-        log_variadic_message(LMT_ERROR, _("Invalid path '%s' for panel '%s'"),
-                             path, gtk_dockable_get_name(GTK_DOCKABLE(panel)));
+        name = gtk_dockable_get_name(GTK_DOCKABLE(panel));
+        log_variadic_message(LMT_ERROR, _("Invalid path '%s' for panel '%s'"), path, name);
+        free(name);
     }
 
     else
diff --git a/src/gui/panel.c b/src/gui/panel.c
index b6ef26f..a98119f 100644
--- a/src/gui/panel.c
+++ b/src/gui/panel.c
@@ -27,6 +27,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <string.h>
 
 
 #include "panel-int.h"
@@ -45,7 +46,7 @@ static void g_panel_item_class_init(GPanelItemClass *);
 /* Initialise une instance d'élément réactif pour l'éditeur. */
 static void g_panel_item_init(GPanelItem *);
 
-/* Procède à l'initialisation de l'interface de rassemblement. */
+/* Procède à l'initialisation de l'interface d'incrustation. */
 static void g_panel_item_dockable_interface_init(GtkDockableInterface *);
 
 /* Supprime toutes les références externes. */
@@ -54,20 +55,20 @@ static void g_panel_item_dispose(GPanelItem *);
 /* Procède à la libération totale de la mémoire. */
 static void g_panel_item_finalize(GPanelItem *);
 
-/* Détermine si un panneau peut être filtré. */
-static bool gtk_panel_item_can_search(const GPanelItem *);
-
 /* Fournit le nom court du composant encapsulable. */
-static const char *gtk_panel_item_get_name(const GPanelItem *);
+static char *gtk_panel_item_get_name(const GPanelItem *);
 
 /* Fournit le nom long du composant encapsulable. */
-static const char *gtk_panel_item_get_desc(const GPanelItem *);
+static char *gtk_panel_item_get_desc(const GPanelItem *);
+
+/* Détermine si un panneau peut être filtré. */
+static bool gtk_panel_item_can_search(const GPanelItem *);
 
 /* Fournit le composant graphique intégrable dans un ensemble. */
 static GtkWidget *gtk_panel_item_get_widget(GPanelItem *);
 
 /* Démarre l'actualisation du filtrage du contenu. */
-static void gtk_panel_item_update_filtered(GPanelItem *, char *);
+static void gtk_panel_item_update_filtered(GPanelItem *, const char *);
 
 /* Construit la chaîne d'accès à un élément de configuration. */
 static char *gtk_panel_item_build_configuration_key(const GPanelItem *, const char *);
@@ -163,7 +164,7 @@ static void g_panel_item_init(GPanelItem *item)
 *                                                                             *
 *  Paramètres  : iface = interface GTK à initialiser.                         *
 *                                                                             *
-*  Description : Procède à l'initialisation de l'interface de rassemblement.  *
+*  Description : Procède à l'initialisation de l'interface d'incrustation.    *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -173,9 +174,10 @@ static void g_panel_item_init(GPanelItem *item)
 
 static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface)
 {
-    iface->can_search = (can_dockable_search_fc)gtk_panel_item_can_search;
     iface->get_name = (get_dockable_name_fc)gtk_panel_item_get_name;
     iface->get_desc = (get_dockable_desc_fc)gtk_panel_item_get_desc;
+    iface->can_search = (can_dockable_search_fc)gtk_panel_item_can_search;
+
     iface->get_widget = (get_dockable_widget_fc)gtk_panel_item_get_widget;
     iface->update_filtered = (update_filtered_data_fc)gtk_panel_item_update_filtered;
 
@@ -340,22 +342,19 @@ GtkBuilder *g_panel_item_build_full(GPanelItem *item, const char *path)
 *                                                                             *
 *  Paramètres  : item = instance GTK dont l'interface est à consulter.        *
 *                                                                             *
-*  Description : Détermine si un panneau peut être filtré.                    *
+*  Description : Fournit le nom court du composant encapsulable.              *
 *                                                                             *
-*  Retour      : Bilan de la consultation.                                    *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static bool gtk_panel_item_can_search(const GPanelItem *item)
+static char *gtk_panel_item_get_name(const GPanelItem *item)
 {
-    bool result;                            /* Indication à retourner      */
-    GPanelItemClass *class;                 /* Classe de l'élément visé    */
+    char *result;                           /* Désignation à retourner     */
 
-    class = G_PANEL_ITEM_GET_CLASS(item);
-
-    result = class->can_search;
+    result = strdup(G_EDITOR_ITEM(item)->name);
 
     return result;
 
@@ -366,7 +365,7 @@ static bool gtk_panel_item_can_search(const GPanelItem *item)
 *                                                                             *
 *  Paramètres  : item = instance GTK dont l'interface est à consulter.        *
 *                                                                             *
-*  Description : Fournit le nom court du composant encapsulable.              *
+*  Description : Fournit le nom long du composant encapsulable.               *
 *                                                                             *
 *  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
 *                                                                             *
@@ -374,9 +373,13 @@ static bool gtk_panel_item_can_search(const GPanelItem *item)
 *                                                                             *
 ******************************************************************************/
 
-static const char *gtk_panel_item_get_name(const GPanelItem *item)
+static char *gtk_panel_item_get_desc(const GPanelItem *item)
 {
-    return G_EDITOR_ITEM(item)->name;
+    char *result;                           /* Description à retourner     */
+
+    result = strdup(item->lname);
+
+    return result;
 
 }
 
@@ -385,17 +388,24 @@ static const char *gtk_panel_item_get_name(const GPanelItem *item)
 *                                                                             *
 *  Paramètres  : item = instance GTK dont l'interface est à consulter.        *
 *                                                                             *
-*  Description : Fournit le nom long du composant encapsulable.               *
+*  Description : Détermine si un panneau peut être filtré.                    *
 *                                                                             *
-*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*  Retour      : Bilan de la consultation.                                    *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static const char *gtk_panel_item_get_desc(const GPanelItem *item)
+static bool gtk_panel_item_can_search(const GPanelItem *item)
 {
-    return item->lname;
+    bool result;                            /* Indication à retourner      */
+    GPanelItemClass *class;                 /* Classe de l'élément visé    */
+
+    class = G_PANEL_ITEM_GET_CLASS(item);
+
+    result = class->can_search;
+
+    return result;
 
 }
 
@@ -414,7 +424,13 @@ static const char *gtk_panel_item_get_desc(const GPanelItem *item)
 
 static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item)
 {
-    return G_EDITOR_ITEM(item)->widget;
+    GtkWidget *result;                      /* Composant à retourner       */
+
+    result = G_EDITOR_ITEM(item)->widget;
+
+    g_object_ref(G_OBJECT(result));
+
+    return result;
 
 }
 
@@ -431,14 +447,14 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item)
 *                                                                             *
 ******************************************************************************/
 
-static void gtk_panel_item_update_filtered(GPanelItem *item, char *filter)
+static void gtk_panel_item_update_filtered(GPanelItem *item, const char *filter)
 {
     assert(gtk_panel_item_can_search(item));
 
     if (item->filter != NULL)
         free(item->filter);
 
-    item->filter = filter;
+    item->filter = strdup(filter);
 
     G_PANEL_ITEM_GET_CLASS(item)->update_filtered(item);
 
-- 
cgit v0.11.2-87-g4458