From c0528230469b10d606b9d1fa66a18696b2584fed Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 9 Jan 2020 23:54:59 +0100 Subject: Updated the Python documentation for GUI items. --- plugins/pychrysalide/gui/Makefile.am | 1 + plugins/pychrysalide/gui/constants.c | 73 +++++++++ plugins/pychrysalide/gui/constants.h | 39 +++++ plugins/pychrysalide/gui/editem.c | 126 +++++++++++++++- plugins/pychrysalide/gui/module.c | 6 +- plugins/pychrysalide/gui/panel.c | 276 ++++++++++++++++++++++++++++++----- plugins/python/liveconv/panel.py | 2 +- src/gui/editem.c | 9 +- src/gui/editor.c | 2 + src/gui/tb/portions.c | 2 + 10 files changed, 492 insertions(+), 44 deletions(-) create mode 100644 plugins/pychrysalide/gui/constants.c create mode 100644 plugins/pychrysalide/gui/constants.h diff --git a/plugins/pychrysalide/gui/Makefile.am b/plugins/pychrysalide/gui/Makefile.am index f471a60..7f983d9 100644 --- a/plugins/pychrysalide/gui/Makefile.am +++ b/plugins/pychrysalide/gui/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libpychrysagui.la libpychrysagui_la_SOURCES = \ + constants.h constants.c \ editem.h editem.c \ module.h module.c \ panel.h panel.c diff --git a/plugins/pychrysalide/gui/constants.c b/plugins/pychrysalide/gui/constants.c new file mode 100644 index 0000000..03fde19 --- /dev/null +++ b/plugins/pychrysalide/gui/constants.c @@ -0,0 +1,73 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constants.c - équivalent Python partiel du fichier "plugins/dex/dex_def.h" + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "constants.h" + + +#include + + +#include "../helpers.h" + + + +/****************************************************************************** +* * +* Paramètres : type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes pour les panneaux graphiques. * +* * +* Retour : true en cas de succès de l'opération, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_panel_item_constants(PyTypeObject *type) +{ + bool result; /* Bilan à retourner */ + PyObject *values; /* Groupe de valeurs à établir */ + + values = PyDict_New(); + + result = add_const_to_group(values, "INVALID", PIP_INVALID); + if (result) result = add_const_to_group(values, "SINGLETON", PIP_SINGLETON); + if (result) result = add_const_to_group(values, "BINARY_VIEW", PIP_BINARY_VIEW); + if (result) result = add_const_to_group(values, "OTHER", PIP_OTHER); + if (result) result = add_const_to_group(values, "COUNT", PIP_COUNT); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_type(type, false, "PanelItemPersonality", values, + "Types of panel items."); + + exit: + + return result; + +} diff --git a/plugins/pychrysalide/gui/constants.h b/plugins/pychrysalide/gui/constants.h new file mode 100644 index 0000000..2b6a37e --- /dev/null +++ b/plugins/pychrysalide/gui/constants.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constants.h - prototypes pour l'ajout des constantes liées à l'interface graphique + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_GUI_CONSTANTS_H +#define _PLUGINS_PYCHRYSALIDE_GUI_CONSTANTS_H + + +#include +#include + + + +/* Définit les constantes pour les panneaux graphiques. */ +bool define_panel_item_constants(PyTypeObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_GUI_CONSTANTS_H */ diff --git a/plugins/pychrysalide/gui/editem.c b/plugins/pychrysalide/gui/editem.c index 71bf316..683a0d1 100644 --- a/plugins/pychrysalide/gui/editem.c +++ b/plugins/pychrysalide/gui/editem.c @@ -39,6 +39,30 @@ +#define EDITOR_ITEM_DOC \ + "EditorItem is an abstract class for all items belonging to main interface" \ + " of Chrysalide: panels, menus, aso.\n" \ + "\n" \ + "These objets do not offer functions as the pychrysalide.gui.core module" \ + " is aimed to deal with all editor items at once. Thus such functions are" \ + " located in this module." \ + "\n" \ + "The following special method can be overridden:\n" \ + "* _change_content(self, old, new): get notified about a" \ + " pychrysalide.analysis.LoadedContent change.\n" \ + "* _change_view(self, old, new): get notified about a" \ + " pychrysalide.glibext.LoadedPanel change.\n" \ + "* _update_view(self, panel): get notified about a" \ + " pychrysalide.glibext.LoadedPanel change.\n" \ + "* _track_cursor(self, panel, cursor): get notified when the position of a" \ + " pychrysalide.glibext.LineCursor evolves in a" \ + " pychrysalide.glibext.LoadedPanel.\n" \ + "* _focus_cursor(self, content, cursor): place the current caret to a given"\ + " pychrysalide.glibext.LineCursor inside a rendered" \ + " pychrysalide.analysis.LoadedContent." + + + /* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ @@ -59,6 +83,17 @@ static void py_editor_item_focus_cursor_wrapper(GEditorItem *, GLoadedContent *, +/* -------------------------- FONCTIONNALITES D'UN ELEMENT -------------------------- */ + + +/* Fournit le nom humain attribué à l'élément réactif. */ +static PyObject *py_editor_item_get_name(PyObject *, void *); + +/* Fournit le composant GTK associé à l'élément réactif. */ +static PyObject *py_editor_item_get_widget(PyObject *, void *); + + + /* ---------------------------------------------------------------------------------- */ /* GLUE POUR CREATION DEPUIS PYTHON */ /* ---------------------------------------------------------------------------------- */ @@ -366,6 +401,93 @@ static void py_editor_item_focus_cursor_wrapper(GEditorItem *item, GLoadedConten /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le nom humain attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_get_name(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GEditorItem *item; /* Elément à consulter */ + const char *name; /* Désignation humaine */ + +#define EDITOR_ITEM_NAME_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + name, py_editor_item, \ + "Human name given to the editor item." \ +) + + item = G_EDITOR_ITEM(pygobject_get(self)); + name = g_editor_item_get_name(item); + + if (name != NULL) + result = PyUnicode_FromString(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 composant GTK associé à l'élément réactif. * +* * +* Retour : Instance de composant graphique chargé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_get_widget(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GEditorItem *item; /* Elément à consulter */ + GtkWidget *widget; /* Composant GTK employé */ + +#define EDITOR_ITEM_WIDGET_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + widget, py_editor_item, \ + "Base GTK widget involed in the editor item." \ +) + + item = G_EDITOR_ITEM(pygobject_get(self)); + widget = g_editor_item_get_widget(item); + + if (widget != NULL) + { + result = pygobject_new(G_OBJECT(widget)); + g_object_unref(G_OBJECT(widget)); + } + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -383,6 +505,8 @@ PyTypeObject *get_python_editor_item_type(void) }; static PyGetSetDef py_editor_item_getseters[] = { + EDITOR_ITEM_NAME_ATTRIB, + EDITOR_ITEM_WIDGET_ATTRIB, { NULL } }; @@ -394,7 +518,7 @@ PyTypeObject *get_python_editor_item_type(void) .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_doc = "PyChrysalide editor item", + .tp_doc = EDITOR_ITEM_DOC, .tp_methods = py_editor_item_methods, .tp_getset = py_editor_item_getseters, diff --git a/plugins/pychrysalide/gui/module.c b/plugins/pychrysalide/gui/module.c index 59fb39f..edb6fb9 100644 --- a/plugins/pychrysalide/gui/module.c +++ b/plugins/pychrysalide/gui/module.c @@ -53,12 +53,16 @@ bool add_gui_module(PyObject *super) bool result; /* Bilan à retourner */ PyObject *module; /* Sous-module mis en place */ +#define PYCHRYSALIDE_GUI_DOC \ + "This module contains all the items useful for dealing with the GUI" \ + " of Chrysalide." + static PyModuleDef py_chrysalide_gui_module = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "pychrysalide.gui", - .m_doc = "Python module for Chrysalide.gui", + .m_doc = PYCHRYSALIDE_GUI_DOC, .m_size = -1, diff --git a/plugins/pychrysalide/gui/panel.c b/plugins/pychrysalide/gui/panel.c index ccc4dc5..bbcd8f8 100644 --- a/plugins/pychrysalide/gui/panel.c +++ b/plugins/pychrysalide/gui/panel.c @@ -35,6 +35,7 @@ #include +#include "constants.h" #include "editem.h" #include "../access.h" #include "../helpers.h" @@ -62,8 +63,20 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds); /* Place un panneau dans l'ensemble affiché. */ static PyObject *py_panel_item_dock(PyObject *, PyObject *); -/* Définit les constantes pour les panneaux. */ -static bool py_panel_item_define_constants(PyTypeObject *); +/* Supprime un panneau de l'ensemble affiché. */ +static PyObject *py_panel_item_undock(PyObject *, PyObject *); + +/* Fournit une indication sur la personnalité du panneau. */ +static PyObject *py_panel_item_get_personality(PyObject *, void *); + +/* Fournit le chemin d'accès à utiliser pour les encapsulations. */ +static PyObject *py_panel_item_get_path(PyObject *, void *); + +/* Définit le chemin d'accès à utiliser pour les encapsulations. */ +static int py_panel_item_set_path(PyObject *, PyObject *, void *); + +/* Indique si le composant repose sur un support de l'éditeur. */ +static PyObject *py_panel_item_get_docked(PyObject *, void *); @@ -184,6 +197,40 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds) static char *kwlist[] = { "name", "widget", "personality", "lname", "dock", "path", NULL }; +#define PANEL_ITEM_DOC \ + "PanelItem is an abstract class for panels available in the main GUI" \ + " interface.\n" \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " PanelItem(name=str, widget=Gtk.Widget," \ + " personality=PanelItemPersonality, lname=str, dock=bool, path=str)" \ + "\n" \ + "Where:\n" \ + "* name is the displayed label on the notebook tab when docked.\n" \ + "* widget is the main widget inside the panel.\n" \ + "* personality defines how many instances of the panels can be created" \ + " at the same time.\n" \ + "* lname is the long description used for the tooltip.\n" \ + "* dock defines if the panel is docked by default.\n" \ + "* path states the location of the panel inside the main GUI.\n" \ + "\n" \ + "The easiest way to pass all this information is probably to use a" \ + " transitional dictionary inside the panel *__init__()* constructor:\n" \ + "\n" \ + " params = {\n" \ + " 'name' : 'Tab label',\n" \ + " 'widget' : self._my_gtk_widget,\n" \ + " 'personality' : PanelItemPersonality.PIP_SINGLETON,\n" \ + " 'lname' : 'Long description for tooltip',\n" \ + " 'dock' : True,\n" \ + " 'path' : 'MES'\n" \ + " }\n" \ + " super(MyPanel, self).__init__(**params)\n" \ + "\n" \ + "For more details about the panel path, please refer to" \ + " pychrysalide.gtkext.GtkDockable." + /* Récupération des paramètres */ ret = PyArg_ParseTupleAndKeywords(args, kwds, "sOksps", kwlist, @@ -251,6 +298,13 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) { GPanelItem *item; /* Panneau à manipuler */ +#define PANEL_ITEM_DOCK_METHOD PYTHON_METHOD_DEF \ +( \ + dock, "$self, /", \ + METH_NOARGS, py_panel_item, \ + "Display the panel item in the right place." \ +) + item = G_PANEL_ITEM(pygobject_get(self)); g_panel_item_dock(item); @@ -262,6 +316,179 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) /****************************************************************************** * * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Supprime un panneau de l'ensemble affiché. * +* * +* Retour : Py_None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_panel_item_undock(PyObject *self, PyObject *args) +{ + GPanelItem *item; /* Panneau à manipuler */ + +#define PANEL_ITEM_UNDOCK_METHOD PYTHON_METHOD_DEF \ +( \ + undock, "$self, /", \ + METH_NOARGS, py_panel_item, \ + "Hide the panel item from the main interface." \ +) + + item = G_PANEL_ITEM(pygobject_get(self)); + + g_panel_item_undock(item); + + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit une indication sur la personnalité du panneau. * +* * +* Retour : Identifiant lié à la nature du panneau. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_panel_item_get_personality(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GPanelItem *item; /* Panneau à consulter */ + PanelItemPersonality personality; /* Valeur native à convertir */ + +#define PANEL_ITEM_PERSONALITY_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + personality, py_panel_item, \ + "Rule for handling panel creations, as a" \ + " pychrysalide.gui.PanelItem.PanelItemPersonality value." \ +) + + item = G_PANEL_ITEM(pygobject_get(self)); + personality = gtk_panel_item_get_personality(item); + + result = cast_with_constants_group_from_type(get_python_panel_item_type(), "PanelItemPersonality", personality); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le chemin d'accès à utiliser pour les encapsulations.* +* * +* Retour : Chemin d'accès défini. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_panel_item_get_path(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GPanelItem *item; /* Panneau à consulter */ + const char *path; /* Chemin d'accès courant */ + +#define PANEL_ITEM_PATH_ATTRIB PYTHON_GETSET_DEF_FULL \ +( \ + path, py_panel_item, \ + "Get or define the current path of the panel item." \ +) + + item = G_PANEL_ITEM(pygobject_get(self)); + path = gtk_panel_item_get_path(item); + + result = PyUnicode_FromString(path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = adresse non utilisée ici. * +* * +* Description : Définit le chemin d'accès à utiliser pour les encapsulations.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_panel_item_set_path(PyObject *self, PyObject *value, void *closure) +{ + GPanelItem *item; /* Panneau à manipuler */ + const char *path; /* Nouveau chemin d'accès */ + + if (!PyUnicode_Check(value)) + return -1; + + item = G_PANEL_ITEM(pygobject_get(self)); + + path = PyUnicode_DATA(value); + + gtk_panel_item_set_path(item, path); + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique si le composant repose sur un support de l'éditeur. * +* * +* Retour : True si le composant est bien incrusté quelque part. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_panel_item_get_docked(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GPanelItem *item; /* Panneau à consulter */ + bool docked; /* Statut de l'ancrage */ + +#define PANEL_ITEM_DOCKED_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + docked, py_panel_item, \ + "Dock status of the panel item." \ +) + + item = G_PANEL_ITEM(pygobject_get(self)); + docked = g_panel_item_is_docked(item); + + result = docked ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -275,15 +502,15 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) PyTypeObject *get_python_panel_item_type(void) { static PyMethodDef py_panel_item_methods[] = { - { - "dock", py_panel_item_dock, - METH_NOARGS, - "dock($self, /)\n--\n\nDisplay the panel item in the right place." - }, + PANEL_ITEM_DOCK_METHOD, + PANEL_ITEM_UNDOCK_METHOD, { NULL } }; static PyGetSetDef py_panel_item_getseters[] = { + PANEL_ITEM_PERSONALITY_ATTRIB, + PANEL_ITEM_PATH_ATTRIB, + PANEL_ITEM_DOCKED_ATTRIB, { NULL } }; @@ -296,7 +523,7 @@ PyTypeObject *get_python_panel_item_type(void) .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_doc = "PyChrysalide panel item.", + .tp_doc = PANEL_ITEM_DOC, .tp_methods = py_panel_item_methods, .tp_getset = py_panel_item_getseters, @@ -313,37 +540,6 @@ PyTypeObject *get_python_panel_item_type(void) /****************************************************************************** * * -* Paramètres : obj_type = type dont le dictionnaire est à compléter. * -* * -* Description : Définit les constantes pour les panneaux. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool py_panel_item_define_constants(PyTypeObject *obj_type) -{ - bool result; /* Bilan à retourner */ - - result = true; - - result &= PyDict_AddULongMacro(obj_type, PIP_INVALID); - - result &= PyDict_AddULongMacro(obj_type, PIP_SINGLETON); - result &= PyDict_AddULongMacro(obj_type, PIP_BINARY_VIEW); - result &= PyDict_AddULongMacro(obj_type, PIP_OTHER); - - result &= PyDict_AddULongMacro(obj_type, PIP_COUNT); - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : module = module dont la définition est à compléter. * * * * Description : Prend en charge l'objet 'pychrysalide.gui.panels.PanelItem'. * @@ -378,7 +574,7 @@ bool ensure_python_panel_item_is_registered(void) get_python_editor_item_type(), get_python_gtk_dockable_type(), NULL)) return false; - if (!py_panel_item_define_constants(type)) + if (!define_panel_item_constants(type)) return false; } diff --git a/plugins/python/liveconv/panel.py b/plugins/python/liveconv/panel.py index 644bfa9..0fee3cf 100644 --- a/plugins/python/liveconv/panel.py +++ b/plugins/python/liveconv/panel.py @@ -23,7 +23,7 @@ class ConvPanel(PanelItem): 'name' : 'Converter', 'widget' : self._builder.get_object('content'), - 'personality' : PanelItem.PIP_SINGLETON, + 'personality' : PanelItem.PanelItemPersonality.SINGLETON, 'lname' : 'Data live converter', 'dock' : True, 'path' : 'MES' diff --git a/src/gui/editem.c b/src/gui/editem.c index ef7cb30..96d63c7 100644 --- a/src/gui/editem.c +++ b/src/gui/editem.c @@ -129,7 +129,14 @@ const char *g_editor_item_get_name(const GEditorItem *item) GtkWidget *g_editor_item_get_widget(const GEditorItem *item) { - return item->widget; + GtkWidget *result; /* Composant à retourner */ + + result = item->widget; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; } diff --git a/src/gui/editor.c b/src/gui/editor.c index 60e4095..6a270fb 100644 --- a/src/gui/editor.c +++ b/src/gui/editor.c @@ -262,6 +262,7 @@ GtkWidget *create_editor(void) menuboard = g_editor_item_get_widget(editem); gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0); + g_object_unref(G_OBJECT(menuboard)); g_object_set_data(ref, "menubar", editem); g_object_set_data(ref, "menuboard", menuboard); @@ -291,6 +292,7 @@ GtkWidget *create_editor(void) widget = g_editor_item_get_widget(editem); gtk_box_pack_start(GTK_BOX(vbox1), widget, FALSE, FALSE, 0); + g_object_unref(G_OBJECT(widget)); /* Autre */ diff --git a/src/gui/tb/portions.c b/src/gui/tb/portions.c index a8eb606..af7fc6c 100644 --- a/src/gui/tb/portions.c +++ b/src/gui/tb/portions.c @@ -241,6 +241,8 @@ static void change_portions_tbitem_current_content(GEditorItem *item, GLoadedCon else gtk_widget_hide(GTK_WIDGET(widget)); + g_object_unref(G_OBJECT(widget)); + } -- cgit v0.11.2-87-g4458