diff options
Diffstat (limited to 'plugins/pychrysalide/gui/core')
-rw-r--r-- | plugins/pychrysalide/gui/core/items.c | 35 | ||||
-rw-r--r-- | plugins/pychrysalide/gui/core/panels.c | 65 |
2 files changed, 64 insertions, 36 deletions
diff --git a/plugins/pychrysalide/gui/core/items.c b/plugins/pychrysalide/gui/core/items.c index ce3eaee..95842fc 100644 --- a/plugins/pychrysalide/gui/core/items.c +++ b/plugins/pychrysalide/gui/core/items.c @@ -66,29 +66,36 @@ static PyObject *py_items_update_project(PyObject *, PyObject *); * * ******************************************************************************/ -static PyObject *py_items_find_editor_item_by_key(PyObject *self, PyObject *args) +static PyObject *py_items_find_editor_item_by_type(PyObject *self, PyObject *args) { PyObject *result; /* Trouvaille à retourner */ - const char *key; /* Objet des recherches */ + GType type; /* Type d'élément à traiter */ int ret; /* Bilan de lecture des args. */ GEditorItem *found; /* Instance retrouvée ou NULL */ -#define ITEMS_FIND_EDITOR_ITEM_BY_KEY_METHOD PYTHON_METHOD_DEF \ -( \ - find_editor_item_by_key, "key", \ - METH_VARARGS, py_items, \ - "Find the editor component belonging to a given key." \ - "\n" \ - "The key has to be provided as a simple (short) string, and the" \ - " result is a pychrysalide.gui.EditorItem instance or None if no" \ - " component is found for the given key." \ +#define ITEMS_FIND_EDITOR_ITEM_BY_TYPE_METHOD PYTHON_METHOD_DEF \ +( \ + find_editor_item_by_type, "cls", \ + METH_VARARGS, py_items, \ + "Find the editor component belonging to a given class." \ + "\n" \ + "The provided *cls* has to be an pychrysalide.gui.EditorItem" \ + " derived class." \ + "\n" \ + "The result is an pychrysalide.gui.EditorItem instance or None" \ + " if no component is found for the given key." \ ) - ret = PyArg_ParseTuple(args, "s", &key); + ret = PyArg_ParseTuple(args, "O&", convert_to_gtype, &type); if (!ret) return NULL; + if (!g_type_is_a(type, G_TYPE_EDITOR_ITEM)) + { + PyErr_SetString(PyExc_TypeError, "the argument must be a class derived from pychrysalide.gui.EditorItem"); + return NULL; + } - found = find_editor_item_by_key(key); + found = find_editor_item_by_type(type); if (found == NULL) { @@ -276,7 +283,7 @@ bool populate_gui_core_module_with_items(void) PyObject *module; /* Module à recompléter */ static PyMethodDef py_items_methods[] = { - ITEMS_FIND_EDITOR_ITEM_BY_KEY_METHOD, + ITEMS_FIND_EDITOR_ITEM_BY_TYPE_METHOD, ITEMS_CHANGE_CURRENT_CONTENT_METHOD, ITEMS_CHANGE_CURRENT_VIEW_METHOD, ITEMS_UPDATE_CURRENT_VIEW_METHOD, 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; |