summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/gui/core/panels.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/gui/core/panels.c')
-rw-r--r--plugins/pychrysalide/gui/core/panels.c65
1 files changed, 43 insertions, 22 deletions
diff --git a/plugins/pychrysalide/gui/core/panels.c b/plugins/pychrysalide/gui/core/panels.c
index 2a3c275..4fdc3f2 100644
--- a/plugins/pychrysalide/gui/core/panels.c
+++ b/plugins/pychrysalide/gui/core/panels.c
@@ -58,38 +58,59 @@ static PyObject *py_panels_register_panel(PyObject *, PyObject *);
static PyObject *py_panels_register_panel(PyObject *self, PyObject *args)
{
- GPanelItem *item; /* Panneau à traiter */
- GGenConfig *config; /* Configuration à consulter */
+ GType type; /* Type de panneau à traiter */
int ret; /* Bilan de lecture des args. */
-
-#define PANELS_REGISTER_PANEL_METHOD PYTHON_METHOD_DEF \
-( \
- register_panel, "panel", \
- METH_VARARGS, py_panels, \
- "Register a panel for the GUI." \
- "\n" \
- "The provided panel has to be a pychrysalide.gui.PanelItem" \
- " instance." \
+ PyObject *meta; /* Type _GObjectMetaBase */
+ PyObject *instance; /* Initialisation forcée */
+
+#define PANELS_REGISTER_PANEL_METHOD PYTHON_METHOD_DEF \
+( \
+ register_panel, "cls", \
+ METH_VARARGS, py_panels, \
+ "Register a panel class for the GUI." \
+ "\n" \
+ "The provided *cls* has to be a pychrysalide.gui.PanelItem" \
+ " derived class." \
)
- config = NULL;
+ ret = PyArg_ParseTuple(args, "O&", convert_to_gtype, &type);
+ if (!ret) return NULL;
+
+ if (!g_type_is_a(type, G_TYPE_PANEL_ITEM))
+ {
+ PyErr_SetString(PyExc_TypeError, "the argument must be a class derived from pychrysalide.gui.PanelItem");
+ return NULL;
+ }
+
+ /**
+ * Si la classe transmise n'a jamais été utilisée pour créer une instance,
+ * py_panel_item_new() n'a donc jamais été exécutée et le type dynamique
+ * associé au panneau n'a jamais été initialisé par Chrysalide.
+ *
+ * Cette création dynamique de type est donc forcée ici.
+ */
- ret = PyArg_ParseTuple(args, "O&", convert_to_panel_item, &item);
+ ret = PyArg_ParseTuple(args, "O", &meta);
if (!ret) return NULL;
- if (config == NULL)
- config = get_main_configuration();
+ instance = PyObject_CallObject(meta, NULL);
+
+ if (instance == NULL)
+ {
+ PyErr_SetString(PyExc_TypeError, "the argument must be a class derived from pychrysalide.gui.PanelItem");
+ return NULL;
+ }
- register_panel_item(item, config);
+ Py_DECREF(instance);
/**
- * Si Python ne voit plus la variable représentant le panneau utilisée,
- * il va la supprimer, ce qui va supprimer le composant GTK.
- *
- * On sera donc en situation de Use-After-Free, dont les conséquences
- * arrivent très vite.
+ * Rechargement du type, afin d'obtenir la version dynamique avec certitude.
*/
- pygobject_new(G_OBJECT(item));
+
+ ret = PyArg_ParseTuple(args, "O&", convert_to_gtype, &type);
+ if (!ret) return NULL;
+
+ register_panel_item(type, get_main_configuration());
Py_RETURN_NONE;