summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/gui/core
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-12-05 00:39:57 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-12-05 00:39:57 (GMT)
commit1e3fa9b79ebe55698e2aa7d5484baec7e8400a8f (patch)
treec3581ceb7f8586f2f6822de563927a1246dd33a5 /plugins/pychrysalide/gui/core
parent6122bb7f34b178d4c07285adae16afcc55294b1f (diff)
Rewritten the whole API dealing with panels.
Diffstat (limited to 'plugins/pychrysalide/gui/core')
-rw-r--r--plugins/pychrysalide/gui/core/items.c35
-rw-r--r--plugins/pychrysalide/gui/core/panels.c65
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;