diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2020-12-05 00:39:57 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2020-12-05 00:39:57 (GMT) |
commit | 1e3fa9b79ebe55698e2aa7d5484baec7e8400a8f (patch) | |
tree | c3581ceb7f8586f2f6822de563927a1246dd33a5 /plugins/pychrysalide/gui/core/panels.c | |
parent | 6122bb7f34b178d4c07285adae16afcc55294b1f (diff) |
Rewritten the whole API dealing with panels.
Diffstat (limited to 'plugins/pychrysalide/gui/core/panels.c')
-rw-r--r-- | plugins/pychrysalide/gui/core/panels.c | 65 |
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; |