From 4370d2d77d623f560c7df94a3bc15b1395e4878b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 8 Aug 2020 23:37:21 +0200 Subject: Updated all the code relative to GUI items. --- plugins/pychrysalide/analysis/loaded.c | 4 + plugins/pychrysalide/glibext/Makefile.am | 3 +- plugins/pychrysalide/glibext/module.c | 2 + plugins/pychrysalide/glibext/named.c | 531 +++++++++++++++++++++++ plugins/pychrysalide/glibext/named.h | 45 ++ plugins/pychrysalide/gtkext/Makefile.am | 3 +- plugins/pychrysalide/gtkext/module.c | 2 + plugins/pychrysalide/gtkext/named.c | 327 ++++++++++++++ plugins/pychrysalide/gtkext/named.h | 42 ++ plugins/pychrysalide/gui/Makefile.am | 2 +- plugins/pychrysalide/gui/constants.c | 56 +++ plugins/pychrysalide/gui/constants.h | 3 + plugins/pychrysalide/gui/editem.c | 566 ------------------------ plugins/pychrysalide/gui/editem.h | 56 --- plugins/pychrysalide/gui/item.c | 723 +++++++++++++++++++++++++++++++ plugins/pychrysalide/gui/item.h | 56 +++ plugins/pychrysalide/gui/module.c | 2 +- plugins/pychrysalide/gui/panel.c | 89 ++-- plugins/pychrysalide/helpers.c | 35 +- plugins/pychrysalide/helpers.h | 11 + plugins/python/liveconv/panel.py | 22 +- plugins/python/liveconv/panel.ui | 381 +++++++++------- src/analysis/binary.c | 3 +- src/analysis/loaded.c | 23 +- src/analysis/loaded.h | 4 + src/glibext/Makefile.am | 2 + src/glibext/named-int.h | 55 +++ src/glibext/named.c | 108 +++++ src/glibext/named.h | 60 +++ src/gtkext/Makefile.am | 2 + src/gtkext/gtkstatusstack.c | 8 +- src/gtkext/gtkstatusstack.h | 2 +- src/gtkext/named-int.h | 65 +++ src/gtkext/named.c | 333 ++++++++++++++ src/gtkext/named.h | 62 +++ src/gui/Makefile.am | 4 +- src/gui/core/items.c | 106 +++-- src/gui/core/items.h | 6 +- src/gui/core/panels.c | 9 +- src/gui/editem-int.h | 94 ---- src/gui/editem.c | 251 ----------- src/gui/editem.h | 79 ---- src/gui/editor.c | 109 +++-- src/gui/item-int.h | 90 ++++ src/gui/item.c | 289 ++++++++++++ src/gui/item.h | 83 ++++ src/gui/menus/binary.c | 2 +- src/gui/menus/menubar.c | 108 +++-- src/gui/menus/menubar.h | 2 +- src/gui/menus/options.c | 2 +- src/gui/menus/project.c | 2 +- src/gui/menus/view.c | 10 +- src/gui/panel-int.h | 26 +- src/gui/panel.c | 114 ++--- src/gui/panel.h | 8 +- src/gui/panels/bintree.c | 83 +++- src/gui/panels/bintree.h | 2 +- src/gui/panels/bookmarks.c | 69 ++- src/gui/panels/bookmarks.h | 2 +- src/gui/panels/errors.c | 74 +++- src/gui/panels/errors.h | 2 +- src/gui/panels/glance.c | 73 +++- src/gui/panels/glance.h | 3 +- src/gui/panels/history.c | 85 +++- src/gui/panels/history.h | 2 +- src/gui/panels/log.c | 51 ++- src/gui/panels/log.h | 2 +- src/gui/panels/regedit.c | 111 +++-- src/gui/panels/regedit.h | 2 +- src/gui/panels/strings.c | 82 +++- src/gui/panels/strings.h | 2 +- src/gui/panels/symbols.c | 96 +++- src/gui/panels/symbols.h | 2 +- src/gui/panels/welcome.c | 59 ++- src/gui/panels/welcome.h | 2 +- src/gui/status.c | 96 +++- src/gui/status.h | 5 +- src/gui/tb/portions.c | 99 ++++- src/gui/tb/portions.h | 5 +- src/gui/tb/tbitem-int.h | 4 +- src/gui/tb/tbitem.c | 17 +- src/gui/tb/tbitem.h | 2 +- 82 files changed, 4399 insertions(+), 1715 deletions(-) create mode 100644 plugins/pychrysalide/glibext/named.c create mode 100644 plugins/pychrysalide/glibext/named.h create mode 100644 plugins/pychrysalide/gtkext/named.c create mode 100644 plugins/pychrysalide/gtkext/named.h delete mode 100644 plugins/pychrysalide/gui/editem.c delete mode 100644 plugins/pychrysalide/gui/editem.h create mode 100644 plugins/pychrysalide/gui/item.c create mode 100644 plugins/pychrysalide/gui/item.h create mode 100644 src/glibext/named-int.h create mode 100644 src/glibext/named.c create mode 100644 src/glibext/named.h create mode 100644 src/gtkext/named-int.h create mode 100644 src/gtkext/named.c create mode 100644 src/gtkext/named.h delete mode 100644 src/gui/editem-int.h delete mode 100644 src/gui/editem.c delete mode 100644 src/gui/editem.h create mode 100644 src/gui/item-int.h create mode 100644 src/gui/item.c create mode 100644 src/gui/item.h diff --git a/plugins/pychrysalide/analysis/loaded.c b/plugins/pychrysalide/analysis/loaded.c index 3eaed81..3ed51d5 100644 --- a/plugins/pychrysalide/analysis/loaded.c +++ b/plugins/pychrysalide/analysis/loaded.c @@ -40,6 +40,7 @@ #include "content.h" #include "../access.h" #include "../helpers.h" +#include "../glibext/named.h" @@ -1445,6 +1446,9 @@ bool ensure_python_loaded_content_is_registered(void) dict = PyModule_GetDict(module); + if (!ensure_python_named_widget_is_registered()) + return false; + if (!register_interface_for_pygobject(dict, G_TYPE_LOADED_CONTENT, type, &info)) return false; diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am index c5fee67..9faff31 100644 --- a/plugins/pychrysalide/glibext/Makefile.am +++ b/plugins/pychrysalide/glibext/Makefile.am @@ -12,7 +12,8 @@ libpychrysaglibext_la_SOURCES = \ linecursor.h linecursor.c \ linegen.h linegen.c \ loadedpanel.h loadedpanel.c \ - module.h module.c + module.h module.c \ + named.h named.c libpychrysaglibext_la_LDFLAGS = diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c index b45da4d..176d815 100644 --- a/plugins/pychrysalide/glibext/module.c +++ b/plugins/pychrysalide/glibext/module.c @@ -37,6 +37,7 @@ #include "linecursor.h" #include "linegen.h" #include "loadedpanel.h" +#include "named.h" #include "../helpers.h" @@ -114,6 +115,7 @@ bool populate_glibext_module(void) if (result) result = ensure_python_line_cursor_is_registered(); if (result) result = ensure_python_line_generator_is_registered(); if (result) result = ensure_python_loaded_panel_is_registered(); + if (result) result = ensure_python_named_widget_is_registered(); assert(result); diff --git a/plugins/pychrysalide/glibext/named.c b/plugins/pychrysalide/glibext/named.c new file mode 100644 index 0000000..4f21064 --- /dev/null +++ b/plugins/pychrysalide/glibext/named.c @@ -0,0 +1,531 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named.c - équivalent Python du fichier "glibext/named.h" + * + * Copyright (C) 2018-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 + */ + + +#include "named.h" + + +#include +#include + + +#include + + +#include "../access.h" +#include "../helpers.h" + + + +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ + + +/* Procède à l'initialisation de l'interface de génération. */ +static void py_named_widget_interface_init(GNamedWidgetIface *, gpointer *); + +/* Fournit le désignation associée à un composant nommé. */ +static char *py_named_widget_get_name_wrapper(const GNamedWidget *, bool); + +/* Fournit le composant associé à un composant nommé. */ +static GtkWidget *py_named_widget_get_widget_wrapper(const GNamedWidget *); + + + +/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */ + + +/* Fournit le désignation associée à un composant nommé. */ +static PyObject *py_named_widget_get_name(PyObject *, void *); + +/* Fournit le désignation associée à un composant nommé. */ +static PyObject *py_named_widget_get_long_name(PyObject *, void *); + +/* Fournit le composant associé à un composant nommé. */ +static PyObject *py_named_widget_get_widget(PyObject *, void *); + + + +/* ---------------------------------------------------------------------------------- */ +/* GLUE POUR CREATION DEPUIS PYTHON */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* unused = adresse non utilisée ici. * +* * +* Description : Procède à l'initialisation de l'interface de génération. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_named_widget_interface_init(GNamedWidgetIface *iface, gpointer *unused) +{ + +#define NAMED_WIDGET_DOC \ + "NamedWidget is an interface linking GTK widget to short and long" \ + " descriptions. Such interface is mainly used when inserting widgets" \ + " into the main window as panels.\n" \ + "\n" \ + "A typical class declaration for a new implementation looks like:\n" \ + "\n" \ + " class NewImplem(GObject.Object, NamedWidget):\n" \ + " ...\n" \ + "\n" \ + "Several items have to be defined as class attributes in the final" \ + " class:\n" \ + "* pychrysalide.glibext.NamedWidget._name;\n" \ + "* pychrysalide.glibext.NamedWidget._long_name;\n" \ + "* pychrysalide.glibext.NamedWidget._widget;\n" + + iface->get_name = py_named_widget_get_name_wrapper; + iface->get_widget = py_named_widget_get_widget_wrapper; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant nommé à consulter. * +* lname = précise s'il s'agit d'une version longue ou non. * +* * +* Description : Fournit le désignation associée à un composant nommé. * +* * +* Retour : Description courante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *py_named_widget_get_name_wrapper(const GNamedWidget *widget, bool lname) +{ + char *result; /* Désignation à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pyname; /* Nom en objet Python */ + int ret; /* Bilan d'une conversion */ + +#define NAMED_WIDGET_NAME_ATTRIB_WRAPPER PYTHON_GETTER_WRAPPER_DEF \ +( \ + _name, \ + "Provide the short name used to describe a named widget.\n" \ + "\n" \ + "The result has to be a string." \ +) + +#define NAMED_WIDGET_LONG_NAME_ATTRIB_WRAPPER PYTHON_GETTER_WRAPPER_DEF \ +( \ + _long_name, \ + "Provide the long name used to describe a named widget.\n" \ + "\n" \ + "The result has to be a string." \ +) + + result = NULL; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(widget)); + + if (PyObject_HasAttrString(pyobj, lname ? "_name" : "_long_name")) + { + pyname = PyObject_GetAttrString(pyobj, lname ? "_name" : "_long_name"); + + if (pyname != NULL) + { + ret = PyUnicode_Check(pyname); + + if (ret) + result = strdup(PyUnicode_AsUTF8(pyname)); + + Py_DECREF(pyname); + + } + + } + + Py_DECREF(pyobj); + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant nommé à consulter. * +* * +* Description : Fournit le composant associé à un composant nommé. * +* * +* Retour : Composant graphique GTK. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *py_named_widget_get_widget_wrapper(const GNamedWidget *widget) +{ + GtkWidget *result; /* Composant GTK à renvoyer */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pywidget; /* Composant en objet Python */ + PyObject *gtk_mod; /* Module Python Gtk */ + PyObject *type; /* Module "GtkWidget" */ + int ret; /* Bilan d'une conversion */ + +#define NAMED_WIDGET_WIDGET_ATTRIB_WRAPPER PYTHON_GETTER_WRAPPER_DEF \ +( \ + _widget, \ + "Provide the internal widget usable for a named widget.\n" \ + "\n" \ + "The result has to be a GTK.Widget instance." \ +) + + result = NULL; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(widget)); + + if (PyObject_HasAttrString(pyobj, "_widget")) + { + pywidget = PyObject_GetAttrString(pyobj, "_widget"); + + if (pywidget != NULL) + { + gtk_mod = PyImport_ImportModule("gi.repository.Gtk"); + + if (gtk_mod == NULL) + { + PyErr_SetString(PyExc_TypeError, "unable to find the Gtk Python module"); + goto exit; + } + + type = PyObject_GetAttrString(gtk_mod, "Widget"); + + Py_DECREF(gtk_mod); + + ret = PyObject_TypeCheck(pywidget, (PyTypeObject *)type); + + Py_DECREF(type); + + if (ret) + result = GTK_WIDGET(pygobject_get(pywidget)); + + Py_DECREF(pywidget); + + } + + } + + exit: + + Py_DECREF(pyobj); + + PyGILState_Release(gstate); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* CONNEXION AVEC L'API DE PYTHON */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un composant nommé à manipuler.* +* closure = non utilisé ici. * +* * +* Description : Fournit le désignation associée à un composant nommé. * +* * +* Retour : Description courante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_named_widget_get_name(PyObject *self, void *closure) +{ + PyObject *result; /* Décompte à retourner */ + GNamedWidget *widget; /* Version native */ + char *name; /* Désignation à convertir */ + +#define NAMED_WIDGET_NAME_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + name, py_named_widget, \ + "Short name used to describe a named widget.\n" \ + "\n" \ + "The result has to be a string." \ +) + + widget = G_NAMED_WIDGET(pygobject_get(self)); + + name = g_named_widget_get_name(widget, false); + + if (name == NULL) + { + result = Py_None; + Py_INCREF(result); + } + else + { + result = PyUnicode_FromString(name); + free(name); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un composant nommé à manipuler.* +* closure = non utilisé ici. * +* * +* Description : Fournit le désignation associée à un composant nommé. * +* * +* Retour : Description courante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_named_widget_get_long_name(PyObject *self, void *closure) +{ + PyObject *result; /* Décompte à retourner */ + GNamedWidget *widget; /* Version native */ + char *name; /* Désignation à convertir */ + +#define NAMED_WIDGET_LONG_NAME_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + long_name, py_named_widget, \ + "Long name used to describe a named widget.\n" \ + "\n" \ + "The result has to be a string." \ +) + + widget = G_NAMED_WIDGET(pygobject_get(self)); + + name = g_named_widget_get_name(widget, true); + + if (name == NULL) + { + result = Py_None; + Py_INCREF(result); + } + else + { + result = PyUnicode_FromString(name); + free(name); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un composant nommé à manipuler.* +* closure = non utilisé ici. * +* * +* Description : Fournit le composant associé à un composant nommé. * +* * +* Retour : Composant graphique GTK. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_named_widget_get_widget(PyObject *self, void *closure) +{ + PyObject *result; /* Décompte à retourner */ + GNamedWidget *widget; /* Version native */ + GtkWidget *instance; /* Composant interne natif */ + +#define NAMED_WIDGET_WIDGET_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + widget, py_named_widget, \ + "Internal widget usable for a named widget.\n" \ + "\n" \ + "The result has to be a GTK *widget*." \ +) + + widget = G_NAMED_WIDGET(pygobject_get(self)); + + instance = g_named_widget_get_widget(widget); + + result = pygobject_new(G_OBJECT(instance)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_named_widget_type(void) +{ + static PyMethodDef py_named_widget_methods[] = { + { NULL } + }; + + static PyGetSetDef py_named_widget_getseters[] = { + NAMED_WIDGET_NAME_ATTRIB_WRAPPER, + NAMED_WIDGET_LONG_NAME_ATTRIB_WRAPPER, + NAMED_WIDGET_WIDGET_ATTRIB_WRAPPER, + NAMED_WIDGET_NAME_ATTRIB, + NAMED_WIDGET_LONG_NAME_ATTRIB, + NAMED_WIDGET_WIDGET_ATTRIB, + { NULL } + }; + + static PyTypeObject py_named_widget_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.glibext.NamedWidget", + .tp_basicsize = sizeof(PyObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = NAMED_WIDGET_DOC, + + .tp_methods = py_named_widget_methods, + .tp_getset = py_named_widget_getseters, + + }; + + return &py_named_widget_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.glibext.NamedWidget'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_named_widget_is_registered(void) +{ + PyTypeObject *type; /* Type Python 'NamedWidget' */ + PyObject *module; /* Module à recompléter */ + PyObject *dict; /* Dictionnaire du module */ + + static GInterfaceInfo info = { /* Paramètres d'inscription */ + + .interface_init = (GInterfaceInitFunc)py_named_widget_interface_init, + .interface_finalize = NULL, + .interface_data = NULL, + + }; + + type = get_python_named_widget_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.glibext"); + + dict = PyModule_GetDict(module); + + if (!register_interface_for_pygobject(dict, G_TYPE_NAMED_WIDGET, type, &info)) + return false; + + } + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en composant nommé. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_named_widget(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_named_widget_type()); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to named widget"); + break; + + case 1: + *((GNamedWidget **)dst) = G_NAMED_WIDGET(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/glibext/named.h b/plugins/pychrysalide/glibext/named.h new file mode 100644 index 0000000..846df82 --- /dev/null +++ b/plugins/pychrysalide/glibext/named.h @@ -0,0 +1,45 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named.h - prototypes pour l'équivalent Python du fichier "glibext/named.h" + * + * Copyright (C) 2020 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_GLIBEXT_NAMED_H +#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_NAMED_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_named_widget_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.NamedWidget'. */ +bool ensure_python_named_widget_is_registered(void); + +/* Tente de convertir en composant nommé. */ +int convert_to_named_widget(PyObject *, void *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_NAMED_H */ diff --git a/plugins/pychrysalide/gtkext/Makefile.am b/plugins/pychrysalide/gtkext/Makefile.am index 5895f24..6e1a259 100644 --- a/plugins/pychrysalide/gtkext/Makefile.am +++ b/plugins/pychrysalide/gtkext/Makefile.am @@ -6,7 +6,8 @@ libpychrysagtkext_la_SOURCES = \ bufferdisplay.h bufferdisplay.c \ displaypanel.h displaypanel.c \ dockable.h dockable.c \ - module.h module.c + module.h module.c \ + named.h named.c libpychrysagtkext_la_LIBADD = \ graph/libpychrysagtkextgraph.la diff --git a/plugins/pychrysalide/gtkext/module.c b/plugins/pychrysalide/gtkext/module.c index 7c684e4..245dc3c 100644 --- a/plugins/pychrysalide/gtkext/module.c +++ b/plugins/pychrysalide/gtkext/module.c @@ -32,6 +32,7 @@ #include "bufferdisplay.h" #include "displaypanel.h" #include "dockable.h" +#include "named.h" #include "graph/module.h" #include "../helpers.h" @@ -101,6 +102,7 @@ bool populate_gtkext_module(void) if (result) result = ensure_python_buffer_display_is_registered(); if (result) result = ensure_python_display_panel_is_registered(); if (result) result = ensure_python_dockable_is_registered(); + if (result) result = ensure_python_built_named_widget_is_registered(); if (result) result = populate_gtkext_graph_module(); diff --git a/plugins/pychrysalide/gtkext/named.c b/plugins/pychrysalide/gtkext/named.c new file mode 100644 index 0000000..e272097 --- /dev/null +++ b/plugins/pychrysalide/gtkext/named.c @@ -0,0 +1,327 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named.c - prototypes pour l'équivalent Python du fichier "gtkext/named.c" + * + * Copyright (C) 2020 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 "named.h" + + +#include + + +#include +#include + + +#include "../access.h" +#include "../helpers.h" +#include "../glibext/named.h" + + + +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ + + +/* Accompagne la création d'une instance dérivée en Python. */ +static PyObject *py_built_named_widget_new(PyTypeObject *, PyObject *, PyObject *); + +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_built_named_widget_init(PyObject *, PyObject *, PyObject *); + + + +/* --------------------------- MANIPULATION DE COMPOSANTS --------------------------- */ + + +/* Fournit le constructeur facilitant l'affichage. */ +static PyObject *py_built_named_widget_get_builder(PyObject *, void *); + + + +/* ---------------------------------------------------------------------------------- */ +/* GLUE POUR CREATION DEPUIS PYTHON */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : type = type du nouvel objet à mettre en place. * +* args = éventuelle liste d'arguments. * +* kwds = éventuel dictionnaire de valeurs mises à disposition. * +* * +* Description : Accompagne la création d'une instance dérivée en Python. * +* * +* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_built_named_widget_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Objet à retourner */ + PyTypeObject *base; /* Type de base à dériver */ + bool first_time; /* Evite les multiples passages*/ + GType gtype; /* Nouveau type de processeur */ + bool status; /* Bilan d'un enregistrement */ + + /* Validations diverses */ + + base = get_python_built_named_widget_type(); + + if (type == base) + goto simple_way; + + /* Mise en place d'un type dédié */ + + first_time = (g_type_from_name(type->tp_name) == 0); + + gtype = build_dynamic_type(GTK_TYPE_BUILT_NAMED_WIDGET, type->tp_name, NULL, NULL, NULL); + + if (first_time) + { + status = register_class_for_dynamic_pygobject(gtype, type, base); + + if (!status) + { + result = NULL; + goto exit; + } + + } + + /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ + + simple_way: + + result = PyType_GenericNew(type, args, kwds); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet à initialiser (théoriquement). * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Initialise une instance sur la base du dérivé de GObject. * +* * +* Retour : 0. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_built_named_widget_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + const char *name; /* Désignation courte à lier */ + const char *lname; /* Description longue associée */ + const char *path; /* Fichier à charger */ + int ret; /* Bilan de lecture des args. */ + GtkBuiltNamedWidget *widget; /* Instance native à consulter */ + +#define BUILT_NAMED_WIDGET_DOC \ + "The BuiltNamedWidget object offers a quick way to get a working" \ + " implementation of the pychrysalide.glibext.NamedWidget interface by" \ + " relying on an external resource file for widgets.\n" \ + "\n" \ + "These widgets are managed using a Gtk.Builder instance internally.\n" \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " BuiltNamedWidget(name, lname, filename)" \ + "\n" \ + "Where *name* is a short description to link to the result, *lname* is" \ + " a longer version of this description and *filename* points to the" \ + " file containing the widgets definition to load." \ + + /* Récupération des paramètres */ + + ret = PyArg_ParseTuple(args, "sss", &name, &lname, &path); + if (!ret) return -1; + + /* Initialisation d'un objet GLib */ + + ret = forward_pygobjet_init(self); + if (ret == -1) return -1; + + /* Eléments de base */ + + widget = GTK_BUILT_NAMED_WIDGET(pygobject_get(self)); + + widget->name = strdup(name); + widget->lname = strdup(lname); + + widget->builder = gtk_builder_new_from_file(path); + + return 0; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION DE COMPOSANTS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le constructeur facilitant l'affichage. * +* * +* Retour : Constructeur mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_built_named_widget_get_builder(PyObject *self, void *closure) +{ + PyObject *result; /* Contenu binaire à retourner */ + GtkBuiltNamedWidget *widget; /* Instance native à consulter */ + GtkBuilder *builder; /* Constructeur à retourner */ + +#define BUILT_NAMED_WIDGET_BUILDER_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + builder, py_built_named_widget, \ + "Gtk.Builder instance handling all the widgets loaded from a" \ + " resource file, or None in case of loading errors." \ +) + + widget = GTK_BUILT_NAMED_WIDGET(pygobject_get(self)); + + builder = gtk_built_named_widget_get_builder(widget); + + if (builder != NULL) + { + result = pygobject_new(G_OBJECT(builder)); + g_object_unref(G_OBJECT(builder)); + } + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_built_named_widget_type(void) +{ + static PyMethodDef py_built_named_widget_methods[] = { + { NULL } + }; + + static PyGetSetDef py_built_named_widget_getseters[] = { + BUILT_NAMED_WIDGET_BUILDER_ATTRIB, + { NULL } + }; + + static PyTypeObject py_built_named_widget_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.gtkext.BuiltNamedWidget", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = BUILT_NAMED_WIDGET_DOC, + + .tp_methods = py_built_named_widget_methods, + .tp_getset = py_built_named_widget_getseters, + + .tp_init = py_built_named_widget_init, + .tp_new = py_built_named_widget_new + + }; + + static PyTypeObject *result = NULL; + + if (result == NULL) + result = define_python_dynamic_type(&py_built_named_widget_type); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide....BuiltNamedWidget'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_built_named_widget_is_registered(void) +{ + PyTypeObject *type; /* Type 'BuiltNamedWidget' */ + PyObject *module; /* Module à recompléter */ + PyObject *dict; /* Dictionnaire du module */ + + type = get_python_built_named_widget_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.gtkext"); + + dict = PyModule_GetDict(module); + + if (!ensure_python_named_widget_is_registered()) + return false; + + if (!register_class_for_pygobject(dict, GTK_TYPE_BUILT_NAMED_WIDGET, type, &PyGObject_Type)) + return false; + + } + + return true; + +} diff --git a/plugins/pychrysalide/gtkext/named.h b/plugins/pychrysalide/gtkext/named.h new file mode 100644 index 0000000..71421f4 --- /dev/null +++ b/plugins/pychrysalide/gtkext/named.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named.h - prototypes pour l'équivalent Python du fichier "gtkext/named.h" + * + * Copyright (C) 2020 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_GTKEXT_NAMED_H +#define _PLUGINS_PYCHRYSALIDE_GTKEXT_NAMED_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_built_named_widget_type(void); + +/* Prend en charge l'objet 'pychrysalide.gtkext.BuiltNamedWidget'. */ +bool ensure_python_built_named_widget_is_registered(void); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_GTKEXT_NAMED_H */ diff --git a/plugins/pychrysalide/gui/Makefile.am b/plugins/pychrysalide/gui/Makefile.am index 7f983d9..06c9db9 100644 --- a/plugins/pychrysalide/gui/Makefile.am +++ b/plugins/pychrysalide/gui/Makefile.am @@ -3,7 +3,7 @@ noinst_LTLIBRARIES = libpychrysagui.la libpychrysagui_la_SOURCES = \ constants.h constants.c \ - editem.h editem.c \ + item.h item.c \ module.h module.c \ panel.h panel.c diff --git a/plugins/pychrysalide/gui/constants.c b/plugins/pychrysalide/gui/constants.c index 40942f6..3cd943c 100644 --- a/plugins/pychrysalide/gui/constants.c +++ b/plugins/pychrysalide/gui/constants.c @@ -71,3 +71,59 @@ bool define_panel_item_constants(PyTypeObject *type) return result; } + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en constante PanelItemPersonality. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_panel_item_personality(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + unsigned long value; /* Valeur transcrite */ + + result = PyObject_IsInstance(arg, (PyObject *)&PyLong_Type); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to PanelItemPersonality"); + break; + + case 1: + value = PyLong_AsUnsignedLong(arg); + + if (value > PIP_COUNT) + { + PyErr_SetString(PyExc_TypeError, "invalid value for PanelItemPersonality"); + result = 0; + } + + else + *((PanelItemPersonality *)dst) = value; + + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/gui/constants.h b/plugins/pychrysalide/gui/constants.h index 8810ee1..247546c 100644 --- a/plugins/pychrysalide/gui/constants.h +++ b/plugins/pychrysalide/gui/constants.h @@ -34,6 +34,9 @@ /* Définit les constantes pour les panneaux graphiques. */ bool define_panel_item_constants(PyTypeObject *); +/* Tente de convertir en constante PanelItemPersonality. */ +int convert_to_panel_item_personality(PyObject *, void *); + #endif /* _PLUGINS_PYCHRYSALIDE_GUI_CONSTANTS_H */ diff --git a/plugins/pychrysalide/gui/editem.c b/plugins/pychrysalide/gui/editem.c deleted file mode 100644 index 504f074..0000000 --- a/plugins/pychrysalide/gui/editem.c +++ /dev/null @@ -1,566 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * editem.c - prototypes pour l'équivalent Python du fichier "gui/editem.c" - * - * Copyright (C) 2018-2020 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 "editem.h" - - -#include - - -#include - - -#include "../access.h" -#include "../helpers.h" -#include "../pychrysa.h" -#include "../analysis/binary.h" -#include "../gtkext/displaypanel.h" - - - -#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 ------------------------ */ - - -/* Réagit à un changement de contenu chargé en cours d'analyse. */ -static void py_editor_item_change_content_wrapper(GEditorItem *, GLoadedContent *, GLoadedContent *); - -/* Réagit à un changement de vue du contenu en cours d'analyse. */ -static void py_editor_item_change_view_wrapper(GEditorItem *, GLoadedPanel *, GLoadedPanel *); - -/* Réagit à une modification de la vue du contenu analysé. */ -static void py_editor_item_update_view_wrapper(GEditorItem *, GLoadedPanel *); - -/* Réagit à une modification de la vue du contenu analysé. */ -static void py_editor_item_track_cursor_wrapper(GEditorItem *, GLoadedPanel *, const GLineCursor *); - -/* Réagit à une modification de la vue du contenu analysé. */ -static void py_editor_item_focus_cursor_wrapper(GEditorItem *, GLoadedContent *, const GLineCursor *); - - - -/* -------------------------- 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 */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : class = classe à initialiser. * -* unused = données non utilisées ici. * -* * -* Description : Initialise la classe des éléménts pour l'interface graphique.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void py_editor_item_init_gclass(GEditorItemClass *class, gpointer unused) -{ - class->change_content = py_editor_item_change_content_wrapper; - class->change_view = py_editor_item_change_view_wrapper; - class->update_view = py_editor_item_update_view_wrapper; - - class->track_cursor = py_editor_item_track_cursor_wrapper; - class->focus_cursor = py_editor_item_focus_cursor_wrapper; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* old = ancien contenu chargé analysé. * -* new = nouveau contenu chargé à analyser. * -* * -* Description : Réagit à un changement de contenu chargé en cours d'analyse. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void py_editor_item_change_content_wrapper(GEditorItem *item, GLoadedContent *old, GLoadedContent *new) -{ - PyObject *pyobj; /* Objet Python concerné */ - PyThreadState *tstate; /* Contexte d'environnement */ - PyObject *pyold; /* Conversion ou None */ - PyObject *pynew; /* Conversion ou None */ - PyObject *args; /* Arguments pour l'appel */ - PyObject *pyret; /* Retour de Python */ - - pyobj = pygobject_new(G_OBJECT(item)); - - tstate = get_pychrysalide_main_tstate(); - - if (tstate != NULL) - PyEval_RestoreThread(tstate); - - if (has_python_method(pyobj, "_change_content")) - { - if (old != NULL) - pyold = pygobject_new(G_OBJECT(old)); - else - { - pyold = Py_None; - Py_INCREF(pyold); - } - - if (new != NULL) - pynew = pygobject_new(G_OBJECT(new)); - else - { - pynew = Py_None; - Py_INCREF(pynew); - } - - args = PyTuple_New(2); - PyTuple_SetItem(args, 0, pyold); - PyTuple_SetItem(args, 1, pynew); - - pyret = run_python_method(pyobj, "_change_content", args); - - Py_DECREF(args); - Py_DECREF(pyret); - - } - - if (tstate != NULL) - PyEval_SaveThread(); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* old = ancienne vue du contenu chargé analysé. * -* new = nouvelle vue du contenu chargé analysé. * -* * -* Description : Réagit à un changement de vue du contenu en cours d'analyse. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void py_editor_item_change_view_wrapper(GEditorItem *item, GLoadedPanel *old, GLoadedPanel *new) -{ - PyObject *pyobj; /* Objet Python concerné */ - PyThreadState *tstate; /* Contexte d'environnement */ - PyObject *pyold; /* Conversion ou None */ - PyObject *pynew; /* Conversion ou None */ - PyObject *args; /* Arguments pour l'appel */ - PyObject *pyret; /* Retour de Python */ - - pyobj = pygobject_new(G_OBJECT(item)); - - tstate = get_pychrysalide_main_tstate(); - - if (tstate != NULL) - PyEval_RestoreThread(tstate); - - if (has_python_method(pyobj, "_change_view")) - { - if (old != NULL) - pyold = pygobject_new(G_OBJECT(old)); - else - { - pyold = Py_None; - Py_INCREF(pyold); - } - - if (new != NULL) - pynew = pygobject_new(G_OBJECT(new)); - else - { - pynew = Py_None; - Py_INCREF(pynew); - } - - args = PyTuple_New(2); - PyTuple_SetItem(args, 0, pyold); - PyTuple_SetItem(args, 1, pynew); - - pyret = run_python_method(pyobj, "_change_view", args); - - Py_DECREF(args); - Py_DECREF(pyret); - - } - - if (tstate != NULL) - PyEval_SaveThread(); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* panel = vue du contenu chargé analysé modifiée. * -* * -* Description : Réagit à une modification de la vue du contenu analysé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void py_editor_item_update_view_wrapper(GEditorItem *item, GLoadedPanel *panel) -{ - PyObject *pyobj; /* Objet Python concerné */ - PyThreadState *tstate; /* Contexte d'environnement */ - PyObject *args; /* Arguments pour l'appel */ - PyObject *pyret; /* Retour de Python */ - - pyobj = pygobject_new(G_OBJECT(item)); - - tstate = get_pychrysalide_main_tstate(); - - if (tstate != NULL) - PyEval_RestoreThread(tstate); - - if (has_python_method(pyobj, "_update_view")) - { - args = PyTuple_New(1); - PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(panel))); - - pyret = run_python_method(pyobj, "_update_view", args); - - Py_DECREF(args); - Py_DECREF(pyret); - - } - - if (tstate != NULL) - PyEval_SaveThread(); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* panel = composant d'affichage parcouru. * -* cursor = nouvel emplacement du curseur courant. * -* * -* Description : Réagit à une modification de la vue du contenu analysé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void py_editor_item_track_cursor_wrapper(GEditorItem *item, GLoadedPanel *panel, const GLineCursor *cursor) -{ - PyObject *pyobj; /* Objet Python concerné */ - PyThreadState *tstate; /* Contexte d'environnement */ - PyObject *args; /* Arguments pour l'appel */ - PyObject *pyret; /* Retour de Python */ - - pyobj = pygobject_new(G_OBJECT(item)); - - tstate = get_pychrysalide_main_tstate(); - - if (tstate != NULL) - PyEval_RestoreThread(tstate); - - if (has_python_method(pyobj, "_track_cursor")) - { - args = PyTuple_New(2); - PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(panel))); - PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(cursor))); - - pyret = run_python_method(pyobj, "_track_cursor", args); - - Py_DECREF(args); - Py_DECREF(pyret); - - } - - if (tstate != NULL) - PyEval_SaveThread(); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* content = contenu contenant le curseur à représenter. * -* cursor = nouvel emplacement du curseur courant. * -* * -* Description : Réagit à une modification de la vue du contenu analysé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void py_editor_item_focus_cursor_wrapper(GEditorItem *item, GLoadedContent *content, const GLineCursor *cursor) -{ - PyObject *pyobj; /* Objet Python concerné */ - PyThreadState *tstate; /* Contexte d'environnement */ - PyObject *args; /* Arguments pour l'appel */ - PyObject *pyret; /* Retour de Python */ - - pyobj = pygobject_new(G_OBJECT(item)); - - tstate = get_pychrysalide_main_tstate(); - - if (tstate != NULL) - PyEval_RestoreThread(tstate); - - if (has_python_method(pyobj, "_focus_cursor")) - { - args = PyTuple_New(2); - PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(content))); - PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(cursor))); - - pyret = run_python_method(pyobj, "_focus_cursor", args); - - Py_DECREF(args); - Py_DECREF(pyret); - - } - - if (tstate != NULL) - PyEval_SaveThread(); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* FONCTIONNALITES D'UN ELEMENT */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* 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. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_editor_item_type(void) -{ - static PyMethodDef py_editor_item_methods[] = { - { NULL } - }; - - static PyGetSetDef py_editor_item_getseters[] = { - EDITOR_ITEM_NAME_ATTRIB, - EDITOR_ITEM_WIDGET_ATTRIB, - { NULL } - }; - - static PyTypeObject py_editor_item_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.gui.EditorItem", - - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - - .tp_doc = EDITOR_ITEM_DOC, - - .tp_methods = py_editor_item_methods, - .tp_getset = py_editor_item_getseters, - - }; - - return &py_editor_item_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.gui.EditorItem'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool ensure_python_editor_item_is_registered(void) -{ - PyTypeObject *type; /* Type Python 'EditorItem' */ - PyObject *module; /* Module à recompléter */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_editor_item_type(); - - if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) - { - module = get_access_to_python_module("pychrysalide.gui"); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_EDITOR_ITEM, type, &PyGObject_Type)) - return false; - - } - - return true; - -} diff --git a/plugins/pychrysalide/gui/editem.h b/plugins/pychrysalide/gui/editem.h deleted file mode 100644 index 6af3b18..0000000 --- a/plugins/pychrysalide/gui/editem.h +++ /dev/null @@ -1,56 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * editem.h - prototypes pour l'équivalent Python du fichier "gui/editem.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 - */ - - -#ifndef _PLUGINS_PYCHRYSALIDE_GUI_EDITEM_H -#define _PLUGINS_PYCHRYSALIDE_GUI_EDITEM_H - - -#include -#include - - -#include - - - -/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ - - -/* Initialise la classe des éléments pour l'interface graphique. */ -void py_editor_item_init_gclass(GEditorItemClass *, gpointer); - - - -/* -------------------------- FONCTIONNALITES D'UN ELEMENT -------------------------- */ - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_editor_item_type(void); - -/* Prend en charge l'objet 'pychrysalide.gui.EditorItem'. */ -bool ensure_python_editor_item_is_registered(void); - - - -#endif /* _PLUGINS_PYCHRYSALIDE_GUI_EDITEM_H */ diff --git a/plugins/pychrysalide/gui/item.c b/plugins/pychrysalide/gui/item.c new file mode 100644 index 0000000..45190e4 --- /dev/null +++ b/plugins/pychrysalide/gui/item.c @@ -0,0 +1,723 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * item.c - prototypes pour l'équivalent Python du fichier "gui/item.c" + * + * Copyright (C) 2018-2020 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 "item.h" + + +#include +#include + + +#include + + +#include "../access.h" +#include "../helpers.h" +#include "../pychrysa.h" +#include "../analysis/binary.h" +#include "../gtkext/displaypanel.h" + + + +#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" \ + "Several items have to be defined as class attributes in the final" \ + " class:\n" \ + "* *_key*: a string providing a small name used to identify the item;\n" \ + "* *_widget*: a Gtk.Widget instance for the content to display.\n" \ + "\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 ------------------------ */ + + +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *py_editor_item_get_key_wrapper(const GEditorItem *); + +/* Fournit le composant GTK associé à l'élément réactif. */ +static GtkWidget *py_editor_item_get_widget_wrapper(const GEditorItem *); + +/* Réagit à un changement de contenu chargé en cours d'analyse. */ +static void py_editor_item_change_content_wrapper(GEditorItem *, GLoadedContent *, GLoadedContent *); + +/* Réagit à un changement de vue du contenu en cours d'analyse. */ +static void py_editor_item_change_view_wrapper(GEditorItem *, GLoadedPanel *, GLoadedPanel *); + +/* Réagit à une modification de la vue du contenu analysé. */ +static void py_editor_item_update_view_wrapper(GEditorItem *, GLoadedPanel *); + +/* Réagit à une modification de la vue du contenu analysé. */ +static void py_editor_item_track_cursor_wrapper(GEditorItem *, GLoadedPanel *, const GLineCursor *); + +/* Réagit à une modification de la vue du contenu analysé. */ +static void py_editor_item_focus_cursor_wrapper(GEditorItem *, GLoadedContent *, const GLineCursor *); + + + +/* -------------------------- FONCTIONNALITES D'UN ELEMENT -------------------------- */ + + +/* Fournit le nom interne attribué à l'élément réactif. */ +static PyObject *py_editor_item_get_key(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 */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : class = classe à initialiser. * +* unused = données non utilisées ici. * +* * +* Description : Initialise la classe des éléménts pour l'interface graphique.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void py_editor_item_init_gclass(GEditorItemClass *class, gpointer unused) +{ + class->get_key = py_editor_item_get_key_wrapper; + class->get_widget = py_editor_item_get_widget_wrapper; + + class->change_content = py_editor_item_change_content_wrapper; + class->change_view = py_editor_item_change_view_wrapper; + class->update_view = py_editor_item_update_view_wrapper; + + class->track_cursor = py_editor_item_track_cursor_wrapper; + class->focus_cursor = py_editor_item_focus_cursor_wrapper; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *py_editor_item_get_key_wrapper(const GEditorItem *item) +{ + char *result; /* Désignation à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pykey; /* Clef en objet Python */ + int ret; /* Bilan d'une conversion */ + +#define EDITOR_ITEM_KEY_ATTRIB_WRAPPER PYTHON_GETTER_WRAPPER_DEF \ +( \ + _key, \ + "Provide the internal name to use for the editor item.\n" \ + "\n" \ + "The result has to be a string." \ +) + + result = NULL; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(item)); + + if (PyObject_HasAttrString(pyobj, "_key")) + { + pykey = PyObject_GetAttrString(pyobj, "_key"); + + if (pykey != NULL) + { + ret = PyUnicode_Check(pykey); + + if (ret) + result = strdup(PyUnicode_AsUTF8(pykey)); + + Py_DECREF(pykey); + + } + + } + + Py_DECREF(pyobj); + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* * +* Description : Fournit le composant GTK associé à l'élément réactif. * +* * +* Retour : Instance de composant graphique chargé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *py_editor_item_get_widget_wrapper(const GEditorItem *item) +{ + GtkWidget *result; /* Composant GTK à renvoyer */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pywidget; /* Composant en objet Python */ + PyObject *gtk_mod; /* Module Python Gtk */ + PyObject *type; /* Module "GtkWidget" */ + int ret; /* Bilan d'une conversion */ + +#define EDITOR_ITEM_WIDGET_ATTRIB_WRAPPER PYTHON_GETTER_WRAPPER_DEF \ +( \ + _widget, \ + "Provide the Gtk widget base involved in the editor item.\n" \ + "\n" \ + "The result has to be a Gtk.Widget instance." \ +) + + result = NULL; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(item)); + + if (PyObject_HasAttrString(pyobj, "_widget")) + { + pywidget = PyObject_GetAttrString(pyobj, "_widget"); + + if (pywidget != NULL) + { + gtk_mod = PyImport_ImportModule("gi.repository.Gtk"); + + if (gtk_mod == NULL) + { + PyErr_SetString(PyExc_TypeError, "unable to find the Gtk Python module"); + goto exit; + } + + type = PyObject_GetAttrString(gtk_mod, "Widget"); + + Py_DECREF(gtk_mod); + + ret = PyObject_TypeCheck(pywidget, (PyTypeObject *)type); + + Py_DECREF(type); + + if (ret) + result = GTK_WIDGET(pygobject_get(pywidget)); + + Py_DECREF(pywidget); + + } + + } + + exit: + + Py_DECREF(pyobj); + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* old = ancien contenu chargé analysé. * +* new = nouveau contenu chargé à analyser. * +* * +* Description : Réagit à un changement de contenu chargé en cours d'analyse. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_editor_item_change_content_wrapper(GEditorItem *item, GLoadedContent *old, GLoadedContent *new) +{ + PyObject *pyobj; /* Objet Python concerné */ + PyThreadState *tstate; /* Contexte d'environnement */ + PyObject *pyold; /* Conversion ou None */ + PyObject *pynew; /* Conversion ou None */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Retour de Python */ + + pyobj = pygobject_new(G_OBJECT(item)); + + tstate = get_pychrysalide_main_tstate(); + + if (tstate != NULL) + PyEval_RestoreThread(tstate); + + if (has_python_method(pyobj, "_change_content")) + { + if (old != NULL) + pyold = pygobject_new(G_OBJECT(old)); + else + { + pyold = Py_None; + Py_INCREF(pyold); + } + + if (new != NULL) + pynew = pygobject_new(G_OBJECT(new)); + else + { + pynew = Py_None; + Py_INCREF(pynew); + } + + args = PyTuple_New(2); + PyTuple_SetItem(args, 0, pyold); + PyTuple_SetItem(args, 1, pynew); + + pyret = run_python_method(pyobj, "_change_content", args); + + Py_DECREF(args); + Py_DECREF(pyret); + + } + + if (tstate != NULL) + PyEval_SaveThread(); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* old = ancienne vue du contenu chargé analysé. * +* new = nouvelle vue du contenu chargé analysé. * +* * +* Description : Réagit à un changement de vue du contenu en cours d'analyse. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_editor_item_change_view_wrapper(GEditorItem *item, GLoadedPanel *old, GLoadedPanel *new) +{ + PyObject *pyobj; /* Objet Python concerné */ + PyThreadState *tstate; /* Contexte d'environnement */ + PyObject *pyold; /* Conversion ou None */ + PyObject *pynew; /* Conversion ou None */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Retour de Python */ + + pyobj = pygobject_new(G_OBJECT(item)); + + tstate = get_pychrysalide_main_tstate(); + + if (tstate != NULL) + PyEval_RestoreThread(tstate); + + if (has_python_method(pyobj, "_change_view")) + { + if (old != NULL) + pyold = pygobject_new(G_OBJECT(old)); + else + { + pyold = Py_None; + Py_INCREF(pyold); + } + + if (new != NULL) + pynew = pygobject_new(G_OBJECT(new)); + else + { + pynew = Py_None; + Py_INCREF(pynew); + } + + args = PyTuple_New(2); + PyTuple_SetItem(args, 0, pyold); + PyTuple_SetItem(args, 1, pynew); + + pyret = run_python_method(pyobj, "_change_view", args); + + Py_DECREF(args); + Py_DECREF(pyret); + + } + + if (tstate != NULL) + PyEval_SaveThread(); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* panel = vue du contenu chargé analysé modifiée. * +* * +* Description : Réagit à une modification de la vue du contenu analysé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_editor_item_update_view_wrapper(GEditorItem *item, GLoadedPanel *panel) +{ + PyObject *pyobj; /* Objet Python concerné */ + PyThreadState *tstate; /* Contexte d'environnement */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Retour de Python */ + + pyobj = pygobject_new(G_OBJECT(item)); + + tstate = get_pychrysalide_main_tstate(); + + if (tstate != NULL) + PyEval_RestoreThread(tstate); + + if (has_python_method(pyobj, "_update_view")) + { + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(panel))); + + pyret = run_python_method(pyobj, "_update_view", args); + + Py_DECREF(args); + Py_DECREF(pyret); + + } + + if (tstate != NULL) + PyEval_SaveThread(); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* panel = composant d'affichage parcouru. * +* cursor = nouvel emplacement du curseur courant. * +* * +* Description : Réagit à une modification de la vue du contenu analysé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_editor_item_track_cursor_wrapper(GEditorItem *item, GLoadedPanel *panel, const GLineCursor *cursor) +{ + PyObject *pyobj; /* Objet Python concerné */ + PyThreadState *tstate; /* Contexte d'environnement */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Retour de Python */ + + pyobj = pygobject_new(G_OBJECT(item)); + + tstate = get_pychrysalide_main_tstate(); + + if (tstate != NULL) + PyEval_RestoreThread(tstate); + + if (has_python_method(pyobj, "_track_cursor")) + { + args = PyTuple_New(2); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(panel))); + PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(cursor))); + + pyret = run_python_method(pyobj, "_track_cursor", args); + + Py_DECREF(args); + Py_DECREF(pyret); + + } + + if (tstate != NULL) + PyEval_SaveThread(); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* content = contenu contenant le curseur à représenter. * +* cursor = nouvel emplacement du curseur courant. * +* * +* Description : Réagit à une modification de la vue du contenu analysé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_editor_item_focus_cursor_wrapper(GEditorItem *item, GLoadedContent *content, const GLineCursor *cursor) +{ + PyObject *pyobj; /* Objet Python concerné */ + PyThreadState *tstate; /* Contexte d'environnement */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Retour de Python */ + + pyobj = pygobject_new(G_OBJECT(item)); + + tstate = get_pychrysalide_main_tstate(); + + if (tstate != NULL) + PyEval_RestoreThread(tstate); + + if (has_python_method(pyobj, "_focus_cursor")) + { + args = PyTuple_New(2); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(content))); + PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(cursor))); + + pyret = run_python_method(pyobj, "_focus_cursor", args); + + Py_DECREF(args); + Py_DECREF(pyret); + + } + + if (tstate != NULL) + PyEval_SaveThread(); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* FONCTIONNALITES D'UN ELEMENT */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_get_key(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GEditorItem *item; /* Elément à consulter */ + char *key; /* Désignation humaine */ + +#define EDITOR_ITEM_KEY_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + key, py_editor_item, \ + "Internal name given to the editor item." \ +) + + item = G_EDITOR_ITEM(pygobject_get(self)); + key = g_editor_item_get_key(item); + + if (key != NULL) + { + result = PyUnicode_FromString(key); + free(key); + } + 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, \ + "GTK widget base 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. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_editor_item_type(void) +{ + static PyMethodDef py_editor_item_methods[] = { + { NULL } + }; + + static PyGetSetDef py_editor_item_getseters[] = { + EDITOR_ITEM_KEY_ATTRIB_WRAPPER, + EDITOR_ITEM_WIDGET_ATTRIB_WRAPPER, + EDITOR_ITEM_KEY_ATTRIB, + EDITOR_ITEM_WIDGET_ATTRIB, + { NULL } + }; + + static PyTypeObject py_editor_item_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.gui.EditorItem", + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = EDITOR_ITEM_DOC, + + .tp_methods = py_editor_item_methods, + .tp_getset = py_editor_item_getseters, + + }; + + return &py_editor_item_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.gui.EditorItem'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_editor_item_is_registered(void) +{ + PyTypeObject *type; /* Type Python 'EditorItem' */ + PyObject *module; /* Module à recompléter */ + PyObject *dict; /* Dictionnaire du module */ + + type = get_python_editor_item_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.gui"); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_EDITOR_ITEM, type, &PyGObject_Type)) + return false; + + } + + return true; + +} diff --git a/plugins/pychrysalide/gui/item.h b/plugins/pychrysalide/gui/item.h new file mode 100644 index 0000000..2b54963 --- /dev/null +++ b/plugins/pychrysalide/gui/item.h @@ -0,0 +1,56 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * item.h - prototypes pour l'équivalent Python du fichier "gui/item.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 + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_GUI_ITEM_H +#define _PLUGINS_PYCHRYSALIDE_GUI_ITEM_H + + +#include +#include + + +#include + + + +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ + + +/* Initialise la classe des éléments pour l'interface graphique. */ +void py_editor_item_init_gclass(GEditorItemClass *, gpointer); + + + +/* -------------------------- FONCTIONNALITES D'UN ELEMENT -------------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_editor_item_type(void); + +/* Prend en charge l'objet 'pychrysalide.gui.EditorItem'. */ +bool ensure_python_editor_item_is_registered(void); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_GUI_ITEM_H */ diff --git a/plugins/pychrysalide/gui/module.c b/plugins/pychrysalide/gui/module.c index 9c06940..66f0f24 100644 --- a/plugins/pychrysalide/gui/module.c +++ b/plugins/pychrysalide/gui/module.c @@ -29,7 +29,7 @@ -#include "editem.h" +#include "item.h" #include "panel.h" #include "core/module.h" #include "../helpers.h" diff --git a/plugins/pychrysalide/gui/panel.c b/plugins/pychrysalide/gui/panel.c index 33ff4e3..d9a2bc5 100644 --- a/plugins/pychrysalide/gui/panel.c +++ b/plugins/pychrysalide/gui/panel.c @@ -36,9 +36,10 @@ #include "constants.h" -#include "editem.h" +#include "item.h" #include "../access.h" #include "../helpers.h" +#include "../glibext/named.h" #include "../gtkext/dockable.h" @@ -66,6 +67,9 @@ static PyObject *py_panel_item_dock(PyObject *, PyObject *); /* Supprime un panneau de l'ensemble affiché. */ static PyObject *py_panel_item_undock(PyObject *, PyObject *); +/* Fournit le chemin d'accès à utiliser pour les encapsulations. */ +static PyObject *py_panel_item_get_named_widget(PyObject *, void *); + /* Fournit une indication sur la personnalité du panneau. */ static PyObject *py_panel_item_get_personality(PyObject *, void *); @@ -184,17 +188,14 @@ static void py_panel_item_init_gclass(GPanelItemClass *class, gpointer unused) static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds) { - unsigned long personality; /* Nature du panneau */ - const char *name; /* Désignation humaine */ - const char *lname; /* Nom version longue */ - PyGObject *widget; /* Composant visuel du panneau */ + PanelItemPersonality personality; /* Nature du panneau */ + GNamedWidget *widget; /* Composant visuel du panneau */ int startup; /* Recommandation au démarrage */ const char *path; /* Placement à l'affichage */ int ret; /* Bilan de lecture des args. */ GPanelItem *panel; /* Panneau à manipuler */ - GEditorItem *item; /* Version basique d'instance */ - static char *kwlist[] = { "name", "widget", "personality", "lname", "dock", "path", NULL }; + static char *kwlist[] = { "personality", "widget", "dock", "path", NULL }; #define PANEL_ITEM_DOC \ "PanelItem is an abstract class for panels available in the main GUI" \ @@ -202,15 +203,14 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds) "\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)" \ + " PanelItem(personality, widget, dock, path)" \ "\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" \ + "* widget is an implementation of the pychrysalide.glibext.NamedWidget" \ + " interface (see pychrysalide.gtkext.BuiltNamedWidget for a ready-to-use" \ + " helper).\n" \ "* dock defines if the panel is docked by default.\n" \ "* path states the location of the panel inside the main GUI.\n" \ "\n" \ @@ -218,22 +218,25 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds) " 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" \ + " 'widget' : my_named_widget_instance,\n" \ " 'dock' : True,\n" \ " 'path' : 'MES'\n" \ " }\n" \ " super(MyPanel, self).__init__(**params)\n" \ "\n" \ + "The PanelItem definition handles internally the supply of the *_widget*" \ + " attribute for pychrysalide.gui.EditorItem.\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, - &name, &widget, &personality, &lname, &startup, &path); + ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&O&ps", kwlist, + convert_to_panel_item_personality, &personality, + convert_to_named_widget, &widget, + &startup, &path); if (!ret) return -1; /* Initialisation d'un objet GLib */ @@ -245,15 +248,7 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds) panel = G_PANEL_ITEM(pygobject_get(self)); - item = G_EDITOR_ITEM(panel); - - item->name = strdup(name);; - item->widget = GTK_WIDGET(pygobject_get(widget)); - panel->personality = personality; - panel->lname = strdup(lname); - panel->dock_at_startup = startup; - panel->path = strdup(path); /** * Si Python ne voit plus la variable représentant le panneau utilisée, @@ -262,7 +257,11 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds) * On sera donc en situation de Use-After-Free, dont les conséquences * arrivent très vite. */ - g_object_ref(G_OBJECT(item->widget)); + panel->widget = widget; + g_object_ref(G_OBJECT(widget)); + + panel->dock_at_startup = startup; + panel->path = strdup(path); return 0; @@ -346,6 +345,43 @@ static PyObject *py_panel_item_undock(PyObject *self, PyObject *args) * 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_named_widget(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GPanelItem *item; /* Panneau à consulter */ + GNamedWidget *widget; /* Composant nommé à transférer*/ + +#define PANEL_ITEM_NAMED_WIDGET_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + named_widget, py_panel_item, \ + "Named widget as core component of the panel item." \ +) + + item = G_PANEL_ITEM(pygobject_get(self)); + widget = gtk_panel_item_get_named_widget(item); + + result = pygobject_new(G_OBJECT(widget)); + + g_object_unref(G_OBJECT(widget)); + + return result; + +} + + +/****************************************************************************** +* * +* 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. * @@ -502,6 +538,7 @@ PyTypeObject *get_python_panel_item_type(void) }; static PyGetSetDef py_panel_item_getseters[] = { + PANEL_ITEM_NAMED_WIDGET_ATTRIB, PANEL_ITEM_PERSONALITY_ATTRIB, PANEL_ITEM_PATH_ATTRIB, PANEL_ITEM_DOCKED_ATTRIB, diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c index 1e83ac7..e9f65a9 100644 --- a/plugins/pychrysalide/helpers.c +++ b/plugins/pychrysalide/helpers.c @@ -60,7 +60,10 @@ static bool include_python_type_into_features(PyObject *, PyTypeObject *); #define NO_CONSTRUCTOR_MSG _("Chrysalide does not allow building this kind of object from Python") /* Message d'erreur affiché puis recherché. */ -#define NOT_IMPLEMENTED_MSG _("Chrysalide method implementation is missing") +#define NOT_IMPLEMENTED_ROUTINE_MSG _("Chrysalide method implementation is missing") + +/* Message d'erreur affiché puis recherché. */ +#define NOT_IMPLEMENTED_GETTER_MSG _("Chrysalide getter implementation is missing") /* Détermine une documentation adaptée à un type interne. */ @@ -252,7 +255,7 @@ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args if (type != NULL && type == PyExc_NotImplementedError \ && value != NULL && PyUnicode_Check(value)) { - refmsg = PyUnicode_FromString(NOT_IMPLEMENTED_MSG); + refmsg = PyUnicode_FromString(NOT_IMPLEMENTED_ROUTINE_MSG); if (PyUnicode_Compare(value, refmsg) == 0) { @@ -611,7 +614,7 @@ PyObject *not_yet_implemented_method(PyObject *self, PyObject *args) result = NULL; - PyErr_SetString(PyExc_NotImplementedError, NOT_IMPLEMENTED_MSG); + PyErr_SetString(PyExc_NotImplementedError, NOT_IMPLEMENTED_ROUTINE_MSG); return result; @@ -645,6 +648,32 @@ PyObject *py_return_none(PyObject *self, PyObject *args) /****************************************************************************** * * +* Paramètres : self = objet quelconque dont le code Python hérite. * +* closure = non utilisé ici. * +* * +* Description : Marque l'absence d'implémentation pour un attribut donné. * +* * +* Retour : NULL pour la levée d'exception. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *not_yet_implemented_getter(PyObject *self, void *closure) +{ + PyObject *result; /* Exception à retourner */ + + result = NULL; + + PyErr_SetString(PyExc_NotImplementedError, NOT_IMPLEMENTED_GETTER_MSG); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : spec = définition à mettre en place dynamiquement. * * * * Description : Définit dans le tas de Python un nouveau type. * diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h index c3ae535..f2a9a1d 100644 --- a/plugins/pychrysalide/helpers.h +++ b/plugins/pychrysalide/helpers.h @@ -124,6 +124,14 @@ bool register_python_module_object(PyObject *, PyTypeObject *); #define PYTHON_GETSET_DEF_FULL(name, base, doc) \ PYTHON_GETSET_DEF(#name, base ## _get_ ## name, base ## _set_ ## name, doc, NULL) +#define PYTHON_GETTER_WRAPPER_DEF(name, doc) \ + { \ + #name, \ + (getter)not_yet_implemented_getter, \ + NULL, \ + doc, NULL \ + } + /** * Quelque chose est mal fait au niveau de l'abstraction GObject. * Du coup, Py_TPFLAGS_IS_ABSTRACT n'est pas pris en compte. @@ -143,6 +151,9 @@ PyObject *not_yet_implemented_method(PyObject *, PyObject *); /* Retourne toujours rien. */ PyObject *py_return_none(PyObject *, PyObject *); +/* Marque l'absence d'implémentation pour un attribut donné. */ +PyObject *not_yet_implemented_getter(PyObject *, void *); + /* Définit dans le tas de Python un nouveau type. */ PyTypeObject *define_python_dynamic_type(const PyTypeObject *); diff --git a/plugins/python/liveconv/panel.py b/plugins/python/liveconv/panel.py index 0fee3cf..6503b7b 100644 --- a/plugins/python/liveconv/panel.py +++ b/plugins/python/liveconv/panel.py @@ -2,6 +2,7 @@ import os from gi.repository import Gtk from pychrysalide.analysis import LoadedBinary +from pychrysalide.gtkext import BuiltNamedWidget from pychrysalide.gui import core from pychrysalide.gui import PanelItem @@ -10,21 +11,22 @@ from .converters import * class ConvPanel(PanelItem): + _key = 'liveconv' + + def __init__(self): """Initialize the GUI panel.""" directory = os.path.dirname(os.path.realpath(__file__)) + filename = os.path.join(directory, 'panel.ui') - self._builder = Gtk.Builder() - self._builder.add_from_file(os.path.join(directory, 'panel.ui')) + widget = BuiltNamedWidget('Converter', 'Data live converter', filename) params = { - 'name' : 'Converter', - 'widget' : self._builder.get_object('content'), - 'personality' : PanelItem.PanelItemPersonality.SINGLETON, - 'lname' : 'Data live converter', + 'widget' : widget, + 'dock' : True, 'path' : 'MES' @@ -59,9 +61,11 @@ class ConvPanel(PanelItem): } + builder = self.named_widget.builder + for kind, func in self._conversions.items(): - label = self._builder.get_object('%s_value' % kind) + label = builder.get_object('%s_value' % kind) label.set_text('-') self._order = '@' @@ -73,9 +77,11 @@ class ConvPanel(PanelItem): loaded = core.get_current_content() assert(loaded) + builder = self.named_widget.builder + for kind, func in self._conversions.items(): - label = self._builder.get_object('%s_value' % kind) + label = builder.get_object('%s_value' % kind) try: addr = cursor.retrieve() diff --git a/plugins/python/liveconv/panel.ui b/plugins/python/liveconv/panel.ui index 6c3d05a..326f0b5 100644 --- a/plugins/python/liveconv/panel.ui +++ b/plugins/python/liveconv/panel.ui @@ -1,318 +1,352 @@ - + - + True - True - in + True + in True - False + False True - False + False vertical True - True - 8 - 8 - 8 - 8 + True + 8 + 8 + 8 + 8 True + True - False - 8 - 8 - 4 - 8 + False + 8 + 8 + 4 + 8 True - False + False int8_t: 0 - 0 - 0 + 0 + 0 True - False + False label True 0 - 1 - 0 + 1 + 0 True - False + False uint8_t: 0 - 0 - 1 + 0 + 1 True - False + False label True 0 - 1 - 1 + 1 + 1 True - False + False int16_t: 0 - 0 - 2 + 0 + 2 True - False + False label True 0 - 1 - 2 + 1 + 2 True - False + False uint16_t: 0 - 0 - 3 + 0 + 3 True - False + False label True 0 - 1 - 3 + 1 + 3 True - False + False int32_t: 0 - 0 - 4 + 0 + 4 True - False + False label True 0 - 1 - 4 + 1 + 4 True - False + False uint32_t: 0 - 0 - 5 + 0 + 5 True - False + False label True 0 - 1 - 5 + 1 + 5 True - False + False int64_t: 0 - 0 - 6 + 0 + 6 True - False + False label True 0 - 1 - 6 + 1 + 6 True - False + False uint64_t: 0 - 0 - 7 + 0 + 7 True - False + False label True 0 - 1 - 7 + 1 + 7 True - False + False half-precision float: 0 - 0 - 8 + 0 + 8 True - False + False label True 0 - 1 - 8 + 1 + 8 True - False + False float: 0 - 0 - 9 + 0 + 9 True - False + False label True 0 - 1 - 9 + 1 + 9 True - False + False double: 0 - 0 - 10 + 0 + 10 True - False + False label True 0 - 1 - 10 + 1 + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True - False + False Numbers @@ -326,151 +360,167 @@ True - True - 8 - 8 - 8 - 8 + True + 8 + 8 + 8 + 8 True + True - False - 8 - 8 - 4 - 8 + False + 8 + 8 + 4 + 8 True - False + False time_t: 0 - 0 - 0 + 0 + 0 True - False + False label True 0 - 1 - 0 + 1 + 0 True - False + False time64_t: 0 - 0 - 1 + 0 + 1 True - False + False label True 0 - 1 - 1 + 1 + 1 True - False + False FILETIME: 0 - 0 - 2 + 0 + 2 True - False + False label True 0 - 1 - 2 + 1 + 2 True - False + False MS-DOS time: 0 - 0 - 3 + 0 + 3 True - False + False label True 0 - 1 - 3 + 1 + 3 True - False + False MS-DOS date: 0 - 0 - 4 + 0 + 4 True - False + False label True 0 - 1 - 4 + 1 + 4 + + + + + + + + + + + + + + + True - False + False Timestamps @@ -484,126 +534,139 @@ True - True - 8 - 8 - 8 - 8 + True + 8 + 8 + 8 + 8 True + True - False - 8 - 8 - 4 - 8 + False + 8 + 8 + 4 + 8 True - False + False char: 0 - 0 - 0 + 0 + 0 True - False + False label True 0 - 1 - 0 + 1 + 0 True - False + False ANSI: 0 - 0 - 1 + 0 + 1 True - False + False label True 0 - 1 - 1 + 1 + 1 True - False + False UTF-8: 0 - 0 - 2 + 0 + 2 True - False + False label True 0 - 1 - 2 + 1 + 2 True - False + False UTF-16: 0 - 0 - 3 + 0 + 3 True - False + False label True 0 - 1 - 3 + 1 + 3 + + + + + + + + + + + + True - False + False Strings diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 7957f2e..2eafda9 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -205,7 +205,8 @@ static GDisplayOptions *g_loaded_binary_get_display_options(const GLoadedBinary /* Indique le type défini pour une description de fichier binaire. */ G_DEFINE_TYPE_WITH_CODE(GLoadedBinary, g_loaded_binary, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(G_TYPE_LOADED_CONTENT, g_loaded_binary_interface_init)); + G_IMPLEMENT_INTERFACE(G_TYPE_LOADED_CONTENT, g_loaded_binary_interface_init) + G_IMPLEMENT_INTERFACE(G_TYPE_NAMED_WIDGET, g_loaded_content_named_interface_init)); /****************************************************************************** diff --git a/src/analysis/loaded.c b/src/analysis/loaded.c index 71b1838..c1f6e17 100644 --- a/src/analysis/loaded.c +++ b/src/analysis/loaded.c @@ -32,6 +32,7 @@ #include "../core/queue.h" #include "../glibext/chrysamarshal.h" #include "../glibext/gloadedpanel.h" +#include "../glibext/named-int.h" #include "../plugins/pglist.h" @@ -113,7 +114,7 @@ static void g_loaded_analysis_process(GLoadedAnalysis *, GtkStatusStack *); /* Détermine le type d'une interface pour l'intégration de contenu chargé. */ -G_DEFINE_INTERFACE(GLoadedContent, g_loaded_content, G_TYPE_OBJECT) +G_DEFINE_INTERFACE(GLoadedContent, g_loaded_content, G_TYPE_OBJECT); /****************************************************************************** @@ -143,6 +144,26 @@ static void g_loaded_content_default_init(GLoadedContentInterface *iface) /****************************************************************************** * * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de composant nommé.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_loaded_content_named_interface_init(GNamedWidgetIface *iface) +{ + iface->get_name = (get_named_widget_name_fc)g_loaded_content_describe; + iface->get_widget = (get_named_widget_widget_fc)g_loaded_content_build_default_view; + +} + + +/****************************************************************************** +* * * Paramètres : content = élément chargé à traiter. * * xdoc = structure XML en cours d'édition. * * context = contexte à utiliser pour les recherches. * diff --git a/src/analysis/loaded.h b/src/analysis/loaded.h index 9d446c4..46404e1 100644 --- a/src/analysis/loaded.h +++ b/src/analysis/loaded.h @@ -33,6 +33,7 @@ #include "content.h" #include "../common/xml.h" #include "../glibext/gdisplayoptions.h" +#include "../glibext/named.h" #include "../gtkext/gtkdockstation.h" @@ -58,6 +59,9 @@ typedef struct _GLoadedContentIface GLoadedContentIface; /* Détermine le type d'une interface pour l'intégration de contenu chargé. */ GType g_loaded_content_get_type(void) G_GNUC_CONST; +/* Procède à l'initialisation de l'interface de composant nommé. */ +void g_loaded_content_named_interface_init(GNamedWidgetIface *); + /* Interprète un contenu chargé avec un appui XML. */ bool g_loaded_content_restore(GLoadedContent *, xmlDoc *, xmlXPathContext *, const char *); diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index 118ca39..df05de3 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -25,6 +25,8 @@ libglibext_la_SOURCES = \ linegen-int.h \ linegen.h linegen.c \ linesegment.h linesegment.c \ + named-int.h \ + named.h named.c \ objhole.h \ proto.h \ seq.h seq.c \ diff --git a/src/glibext/named-int.h b/src/glibext/named-int.h new file mode 100644 index 0000000..4019c3b --- /dev/null +++ b/src/glibext/named-int.h @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named-int.h - définitions internes propres aux manipulations de composants nommés + * + * Copyright (C) 2020 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 Chrysalide. If not, see . + */ + + +#ifndef _GLIBEXT_NAMED_INT_H +#define _GLIBEXT_NAMED_INT_H + + +#include "named.h" + + + +/* Fournit le désignation associée à un composant nommé. */ +typedef char * (* get_named_widget_name_fc) (const GNamedWidget *, bool); + +/* Fournit le composant associé à un composant nommé. */ +typedef GtkWidget * (* get_named_widget_widget_fc) (const GNamedWidget *); + + +/* Manipulation d'un composant avec ses noms (interface) */ +struct _GNamedWidgetIface +{ + GTypeInterface base_iface; /* A laisser en premier */ + + get_named_widget_name_fc get_name; /* Obtention d'un nom (long ?) */ + get_named_widget_widget_fc get_widget; /* Fourniture du composant */ + +}; + + +/* Redéfinition */ +typedef GNamedWidgetIface GNamedWidgetInterface; + + + +#endif /* _GLIBEXT_NAMED_INT_H */ diff --git a/src/glibext/named.c b/src/glibext/named.c new file mode 100644 index 0000000..b31c58a --- /dev/null +++ b/src/glibext/named.c @@ -0,0 +1,108 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named.c - manipulation de composants nommés + * + * Copyright (C) 2020 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 Chrysalide. If not, see . + */ + + +#include "named.h" + + +#include "named-int.h" + + + +/* Procède à l'initialisation de l'interface de génération. */ +static void g_named_widget_default_init(GNamedWidgetInterface *); + + + +/* Détermine le type d'une interface pour les composants nommés. */ +G_DEFINE_INTERFACE(GNamedWidget, g_named_widget, G_TYPE_OBJECT) + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de génération. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_named_widget_default_init(GNamedWidgetInterface *iface) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant nommé à consulter. * +* lname = précise s'il s'agit d'une version longue ou non. * +* * +* Description : Fournit le désignation associée à un composant nommé. * +* * +* Retour : Description courante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *g_named_widget_get_name(const GNamedWidget *widget, bool lname) +{ + char *result; /* Désignation à retourner */ + GNamedWidgetIface *iface; /* Interface utilisée */ + + iface = G_NAMED_WIDGET_GET_IFACE(widget); + + result = iface->get_name(widget, lname); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant nommé à consulter. * +* * +* Description : Fournit le composant associé à un composant nommé. * +* * +* Retour : Composant graphique GTK. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *g_named_widget_get_widget(const GNamedWidget *widget) +{ + GtkWidget *result; /* Composant GTK à renvoyer */ + GNamedWidgetIface *iface; /* Interface utilisée */ + + iface = G_NAMED_WIDGET_GET_IFACE(widget); + + result = iface->get_widget(widget); + + return result; + +} diff --git a/src/glibext/named.h b/src/glibext/named.h new file mode 100644 index 0000000..ae172d8 --- /dev/null +++ b/src/glibext/named.h @@ -0,0 +1,60 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named.h - prototypes pour la manipulation de composants nommés + * + * Copyright (C) 2020 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 Chrysalide. If not, see . + */ + + +#ifndef _GLIBEXT_NAMED_H +#define _GLIBEXT_NAMED_H + + +#include +#include +#include + + + +#define G_TYPE_NAMED_WIDGET g_named_widget_get_type() +#define G_NAMED_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_NAMED_WIDGET, GNamedWidget)) +#define G_NAMED_WIDGET_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_NAMED_WIDGET, GNamedWidgetIface)) +#define GTK_IS_NAMED_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_NAMED_WIDGET)) +#define GTK_IS_NAMED_WIDGET_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_NAMED_WIDGET)) +#define G_NAMED_WIDGET_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_NAMED_WIDGET, GNamedWidgetIface)) + + +/* Manipulation d'un composant avec ses noms (coquille vide) */ +typedef struct _GNamedWidget GNamedWidget; + +/* Manipulation d'un composant avec ses noms (interface) */ +typedef struct _GNamedWidgetIface GNamedWidgetIface; + + +/* Détermine le type d'une interface pour les composants nommés. */ +GType g_named_widget_get_type(void) G_GNUC_CONST; + +/* Fournit le désignation associée à un composant nommé. */ +char *g_named_widget_get_name(const GNamedWidget *, bool); + +/* Fournit le composant associé à un composant nommé. */ +GtkWidget *g_named_widget_get_widget(const GNamedWidget *); + + + +#endif /* _GLIBEXT_NAMED_H */ diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index a56cf33..4523d69 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -21,6 +21,8 @@ libgtkext_la_SOURCES = \ gtkgraphdisplay.h gtkgraphdisplay.c \ gtkstatusstack.h gtkstatusstack.c \ hexdisplay.h hexdisplay.c \ + named-int.h \ + named.h named.c \ rendering.h rendering.c \ resources.h resources.c \ support.h support.c \ diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c index 31cc55a..1df5d35 100644 --- a/src/gtkext/gtkstatusstack.c +++ b/src/gtkext/gtkstatusstack.c @@ -308,9 +308,13 @@ static void gtk_status_stack_finalize(GtkStatusStack *stack) * * ******************************************************************************/ -GtkWidget *gtk_status_stack_new(void) +GtkStatusStack *gtk_status_stack_new(void) { - return g_object_new(GTK_TYPE_STATUS_STACK, NULL); + GtkStatusStack *result; /* Instance à retourner */ + + result = g_object_new(GTK_TYPE_STATUS_STACK, NULL); + + return result; } diff --git a/src/gtkext/gtkstatusstack.h b/src/gtkext/gtkstatusstack.h index 7eecc68..b68e387 100644 --- a/src/gtkext/gtkstatusstack.h +++ b/src/gtkext/gtkstatusstack.h @@ -54,7 +54,7 @@ typedef struct _GtkStatusStackClass GtkStatusStackClass; GType gtk_status_stack_get_type(void); /* Crée une nouvelle instance de barre de statut. */ -GtkWidget *gtk_status_stack_new(void); +GtkStatusStack *gtk_status_stack_new(void); diff --git a/src/gtkext/named-int.h b/src/gtkext/named-int.h new file mode 100644 index 0000000..1ae2efe --- /dev/null +++ b/src/gtkext/named-int.h @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named-int.h - définitions internes propres à la préparation de composants à l'affichage avec leurs noms + * + * Copyright (C) 2020 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 Chrysalide. If not, see . + */ + + +#ifndef _GTK_NAMED_INT_H +#define _GTK_NAMED_INT_H + + +#include "named.h" + + + +/* Préparation d'un composant pour affichage avec ses noms (instance) */ +struct _GtkBuiltNamedWidget +{ + GObject parent; /* A laisser en premier */ + + char *name; /* Description courte */ + char *lname; /* Description longue */ + + /** + * La gestion générique du constructeur repose sur quelques + * prérequis quant à l'enregistrement de composants : + * + * - "box" doit être le support de panneau à intégrer. + * + * - pour les contenus actualisables, une pile de composants + * "stack" doit contenir un support "content" pour le + * contenu principal et un support "mask" qui prend le + * relais pendant les opérations de mise à jour. + */ + + GtkBuilder *builder; /* Constructeur utilisé */ + +}; + +/* Préparation d'un composant pour affichage avec ses noms (classe) */ +struct _GtkBuiltNamedWidgetClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + + +#endif /* _GTK_NAMED_INT_H */ diff --git a/src/gtkext/named.c b/src/gtkext/named.c new file mode 100644 index 0000000..de0dd3f --- /dev/null +++ b/src/gtkext/named.c @@ -0,0 +1,333 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named.c - préparation de composants à l'affichage avec leurs noms + * + * Copyright (C) 2020 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 Chrysalide. If not, see . + */ + + +#include "named.h" + + +#include +#include + + +#include "named-int.h" +#include "../glibext/named-int.h" + + + +/* ---------------------- PREPARATION VIS A VIS DE L'EXTERIEUR ---------------------- */ + + +/* Procède à l'initialisation de l'afficheur générique. */ +static void gtk_built_named_widget_class_init(GtkBuiltNamedWidgetClass *); + +/* Procède à l'initialisation d'une préparation pour affichage. */ +static void gtk_built_named_widget_init(GtkBuiltNamedWidget *); + +/* Procède à l'initialisation de l'interface de composant nommé. */ +static void gtk_built_named_widget_named_interface_init(GNamedWidgetInterface *); + +/* Supprime toutes les références externes. */ +static void gtk_built_named_widget_dispose(GtkBuiltNamedWidget *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_built_named_widget_finalize(GtkBuiltNamedWidget *); + + + +/* -------------------------- INTERFACE DE COMPOSANT NOMME -------------------------- */ + + +/* Fournit le désignation associée à un composant nommé. */ +static char *gtk_built_named_widget_get_name(const GtkBuiltNamedWidget *, bool); + +/* Fournit le composant associé à un composant nommé. */ +static GtkWidget *gtk_built_named_widget_get_widget(const GtkBuiltNamedWidget *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PREPARATION VIS A VIS DE L'EXTERIEUR */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type des préparations de composant pour affichage avec noms. */ +G_DEFINE_TYPE_WITH_CODE(GtkBuiltNamedWidget, gtk_built_named_widget, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_NAMED_WIDGET, gtk_built_named_widget_named_interface_init)); + + +/****************************************************************************** +* * +* Paramètres : class = classe GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur générique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_built_named_widget_class_init(GtkBuiltNamedWidgetClass *class) +{ + GObjectClass *object; /* Plus haut niveau équivalent */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_built_named_widget_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_built_named_widget_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation d'une préparation pour affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_built_named_widget_init(GtkBuiltNamedWidget *widget) +{ + widget->builder = NULL; + + widget->name = NULL; + widget->lname = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de composant nommé.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_built_named_widget_named_interface_init(GNamedWidgetInterface *iface) +{ + iface->get_name = (get_named_widget_name_fc)gtk_built_named_widget_get_name; + iface->get_widget = (get_named_widget_widget_fc)gtk_built_named_widget_get_widget; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_built_named_widget_dispose(GtkBuiltNamedWidget *widget) +{ + g_clear_object(&widget->builder); + + G_OBJECT_CLASS(gtk_built_named_widget_parent_class)->dispose(G_OBJECT(widget)); + +} + + +/****************************************************************************** +* * +* Paramètres : widget = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_built_named_widget_finalize(GtkBuiltNamedWidget *widget) +{ + if (widget->name != NULL) + free(widget->name); + + if (widget->lname != NULL) + free(widget->lname); + + G_OBJECT_CLASS(gtk_built_named_widget_parent_class)->finalize(G_OBJECT(widget)); + +} + + +/****************************************************************************** +* * +* Paramètres : name = nom associé à l'élément. * +* lname = description longue du panneau. * +* path = chemin vers la description d'un composant graphique. * +* * +* Description : Crée une préparation pour l'affichage d'un composant nommé. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkBuiltNamedWidget *gtk_built_named_widget_new(const char *name, const char *lname, const char *path) +{ + GtkBuiltNamedWidget *result; /* Instance à retourner */ + + result = g_object_new(GTK_TYPE_BUILT_NAMED_WIDGET, NULL); + + result->name = strdup(name); + result->lname = strdup(lname); + + result->builder = gtk_builder_new_from_resource(path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : name = nom associé à l'élément. * +* lname = description longue du panneau. * +* resid = indentificant d'une ressource pour un composant. * +* * +* Description : Crée une préparation pour l'affichage d'un composant nommé. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkBuiltNamedWidget *gtk_built_named_widget_new_for_panel(const char *name, const char *lname, const char *resid) +{ + GtkBuiltNamedWidget *result; /* Instance à retourner */ + char *path; /* Chemin d'accès à constituer */ + + asprintf(&path, "/org/chrysalide/gui/panels/%s.ui", resid); + + result = gtk_built_named_widget_new(name, lname, path); + + free(path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = préparation de composant à consulter. * +* * +* Description : Fournit le constructeur facilitant l'affichage. * +* * +* Retour : Constructeur mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkBuilder *gtk_built_named_widget_get_builder(const GtkBuiltNamedWidget *widget) +{ + GtkBuilder *result; /* Constructeur à retourner */ + + result = widget->builder; + + if (result) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERFACE DE COMPOSANT NOMME */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : widget = composant nommé à consulter. * +* lname = précise s'il s'agit d'une version longue ou non. * +* * +* Description : Fournit le désignation associée à un composant nommé. * +* * +* Retour : Description courante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *gtk_built_named_widget_get_name(const GtkBuiltNamedWidget *widget, bool lname) +{ + char *result; /* Désignation à retourner */ + + if (lname) + result = strdup(widget->lname); + else + result = strdup(widget->name); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant nommé à consulter. * +* * +* Description : Fournit le composant associé à un composant nommé. * +* * +* Retour : Composant graphique GTK. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *gtk_built_named_widget_get_widget(const GtkBuiltNamedWidget *widget) +{ + GtkWidget *result; /* Composant GTK à renvoyer */ + + result = GTK_WIDGET(gtk_builder_get_object(widget->builder, "box")); + + g_object_ref(G_OBJECT(result)); + + if (gtk_widget_get_parent(result)) + gtk_widget_unparent(result); + + return result; + +} diff --git a/src/gtkext/named.h b/src/gtkext/named.h new file mode 100644 index 0000000..bb8d968 --- /dev/null +++ b/src/gtkext/named.h @@ -0,0 +1,62 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * named.h - prototypes pour la préparation de composants à l'affichage avec leurs noms + * + * Copyright (C) 2020 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 Chrysalide. If not, see . + */ + + +#ifndef _GTKEXT_NAMED_H +#define _GTKEXT_NAMED_H + + +#include +#include + + + +#define GTK_TYPE_BUILT_NAMED_WIDGET (gtk_built_named_widget_get_type()) +#define GTK_BUILT_NAMED_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUILT_NAMED_WIDGET, GtkBuiltNamedWidget)) +#define GTK_BUILT_NAMED_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUILT_NAMED_WIDGET, GtkBuiltNamedWidgetClass)) +#define GTK_IS_BUILT_NAMED_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUILT_NAMED_WIDGET)) +#define GTK_IS_BUILT_NAMED_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUILT_NAMED_WIDGET)) +#define GTK_BUILT_NAMED_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUILT_NAMED_WIDGET, GtkBuiltNamedWidgetClass)) + + +/* Préparation d'un composant pour affichage avec ses noms (instance) */ +typedef struct _GtkBuiltNamedWidget GtkBuiltNamedWidget; + +/* Préparation d'un composant pour affichage avec ses noms (classe) */ +typedef struct _GtkBuiltNamedWidgetClass GtkBuiltNamedWidgetClass; + + +/* Détermine le type des préparations de composant pour affichage avec noms. */ +GType gtk_built_named_widget_get_type(void); + +/* Crée une préparation pour l'affichage d'un composant nommé. */ +GtkBuiltNamedWidget *gtk_built_named_widget_new(const char *, const char *, const char *); + +/* Crée une préparation pour l'affichage d'un composant nommé. */ +GtkBuiltNamedWidget *gtk_built_named_widget_new_for_panel(const char *, const char *, const char *); + +/* Fournit le constructeur facilitant l'affichage. */ +GtkBuilder *gtk_built_named_widget_get_builder(const GtkBuiltNamedWidget *); + + + +#endif /* _GTKEXT_NAMED_H */ diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 9aceec7..18bda52 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -3,9 +3,9 @@ noinst_LTLIBRARIES = libgui.la libgui_la_SOURCES = \ agroup.h agroup.c \ - editem-int.h \ - editem.h editem.c \ editor.h editor.c \ + item-int.h \ + item.h item.c \ panel-int.h \ panel.h panel.c \ status.h status.c \ diff --git a/src/gui/core/items.c b/src/gui/core/items.c index 71e7df0..9c82100 100644 --- a/src/gui/core/items.c +++ b/src/gui/core/items.c @@ -24,14 +24,18 @@ #include "items.h" +#include +#include + + #include "global.h" -#include "../editem-int.h" #include "../../analysis/db/items/move.h" /* Liste des éléments enregistrés */ -static GEditorItem *_editem_list = NULL; +static GEditorItem **_item_list = NULL; +static size_t _item_count = 0; /* Initialisations premières de façon unique */ static bool _first_content_change = true; @@ -60,7 +64,50 @@ static void track_cursor_on_view_panel(GLoadedPanel *, const GLineCursor *, gpoi void register_editor_item(GEditorItem *item) { - editem_list_add_tail(item, &_editem_list); + _item_list = realloc(_item_list, ++_item_count * sizeof(GEditorItem *)); + + _item_list[_item_count - 1] = item; + + g_object_ref(G_OBJECT(item)); + +} + + +/****************************************************************************** +* * +* Paramètres : target = désignation de l'élément réactif à retrouver. * +* * +* Description : Retrouve un élément reactif de l'éditeur par son nom clef. * +* * +* Retour : Elément retrouvé ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GEditorItem *find_editor_item_by_key(const char *target) +{ + GEditorItem *result; /* Elément à retourner */ + size_t i; /* Boucle de parcours */ + char *key; /* Nom d'un élément à analyser */ + + result = NULL; + + for (i = 0; i < _item_count && result == NULL; i++) + { + key = g_editor_item_get_key(_item_list[i]); + + if (strcmp(key, target) == 0) + { + result = _item_list[i]; + g_object_ref(G_OBJECT(result)); + } + + free(key); + + } + + return result; } @@ -80,7 +127,7 @@ void register_editor_item(GEditorItem *item) void change_editor_items_current_content(GLoadedContent *content) { GLoadedContent *old; /* Ancien contenu */ - GEditorItem *iter; /* Boucle de parcours */ + size_t i; /* Boucle de parcours */ old = get_current_content(); @@ -93,10 +140,8 @@ void change_editor_items_current_content(GLoadedContent *content) set_current_content(content); - editem_list_for_each(iter, _editem_list) - { - g_editor_item_change_content(iter, old, content); - } + for (i = 0; i < _item_count; i++) + g_editor_item_change_content(_item_list[i], old, content); } @@ -164,12 +209,10 @@ static void start_moving_to_cursor_in_loaded_panel(GLoadedPanel *panel, const GL static void track_cursor_on_view_panel(GLoadedPanel *panel, const GLineCursor *cursor, gpointer unused) { - GEditorItem *iter; /* Boucle de parcours */ + size_t i; /* Boucle de parcours */ - editem_list_for_each(iter, _editem_list) - { - g_editor_item_track_cursor(iter, panel, cursor); - } + for (i = 0; i < _item_count; i++) + g_editor_item_track_cursor(_item_list[i], panel, cursor); } @@ -189,7 +232,7 @@ static void track_cursor_on_view_panel(GLoadedPanel *panel, const GLineCursor *c void change_editor_items_current_view(GLoadedPanel *panel) { GLoadedPanel *old; /* Ancien affichage */ - GEditorItem *iter; /* Boucle de parcours */ + size_t i; /* Boucle de parcours */ /* Suivi des affichages */ @@ -204,10 +247,8 @@ void change_editor_items_current_view(GLoadedPanel *panel) set_current_view(panel); - editem_list_for_each(iter, _editem_list) - { - g_editor_item_change_view(iter, old, panel); - } + for (i = 0; i < _item_count; i++) + g_editor_item_change_view(_item_list[i], old, panel); /* Suivi du curseur */ @@ -254,12 +295,10 @@ void change_editor_items_current_view(GLoadedPanel *panel) void update_editor_items_current_view(GLoadedPanel *panel) { - GEditorItem *iter; /* Boucle de parcours */ + size_t i; /* Boucle de parcours */ - editem_list_for_each(iter, _editem_list) - { - g_editor_item_update_view(iter, panel); - } + for (i = 0; i < _item_count; i++) + g_editor_item_update_view(_item_list[i], panel); } @@ -280,12 +319,12 @@ void update_editor_items_current_view(GLoadedPanel *panel) void focus_cursor_in_editor_items(GLoadedContent *content, const GLineCursor *cursor, GEditorItem *source) { - GEditorItem *iter; /* Boucle de parcours */ + size_t i; /* Boucle de parcours */ - editem_list_for_each(iter, _editem_list) + for (i = 0; i < _item_count; i++) { - if (iter != source) - g_editor_item_focus_cursor(iter, content, cursor); + if (_item_list[i] != source) + g_editor_item_focus_cursor(_item_list[i], content, cursor); } } @@ -305,16 +344,9 @@ void focus_cursor_in_editor_items(GLoadedContent *content, const GLineCursor *cu void update_project_area(GStudyProject *project) { - GEditorItem *iter; /* Boucle de parcours */ - GEditorItemClass *klass; /* Classe correspondante */ - - editem_list_for_each(iter, _editem_list) - { - klass = G_EDITOR_ITEM_GET_CLASS(iter); + size_t i; /* Boucle de parcours */ - if (klass->update_project != NULL) - klass->update_project(iter, project); - - } + for (i = 0; i < _item_count; i++) + g_editor_item_update_project_area(_item_list[i], project); } diff --git a/src/gui/core/items.h b/src/gui/core/items.h index 37ccde8..7509b3b 100644 --- a/src/gui/core/items.h +++ b/src/gui/core/items.h @@ -25,9 +25,8 @@ #define _GUI_CORE_ITEMS_H -#include "../editem.h" +#include "../item.h" #include "../../analysis/loaded.h" -#include "../../analysis/project.h" #include "../../glibext/gloadedpanel.h" @@ -35,6 +34,9 @@ /* Procède à l'enregistrement d'un élément reactif de l'éditeur. */ void register_editor_item(GEditorItem *); +/* Retrouve un élément reactif de l'éditeur par son nom clef. */ +GEditorItem *find_editor_item_by_key(const char *); + /* Lance une actualisation du fait d'un changement de contenu. */ void change_editor_items_current_content(GLoadedContent *); diff --git a/src/gui/core/panels.c b/src/gui/core/panels.c index 9cc0592..8505f37 100644 --- a/src/gui/core/panels.c +++ b/src/gui/core/panels.c @@ -25,6 +25,9 @@ #include "panels.h" +#include + + #include "global.h" #include "items.h" #include "../panel-int.h" @@ -221,10 +224,10 @@ GPanelItem *get_panel_item_by_name(const char *name) bool look_for_named_panel(GPanelItem *item, GPanelItem **found) { - const char *key; /* Clef à utiliser */ + char *key; /* Clef à utiliser */ bool status; /* Bilan de la comparaison */ - key = g_editor_item_get_name(G_EDITOR_ITEM(item)); + key = g_editor_item_get_key(G_EDITOR_ITEM(item)); if (strcmp(key, name) == 0) { @@ -234,6 +237,8 @@ GPanelItem *get_panel_item_by_name(const char *name) else status = true; + free(key); + return status; } diff --git a/src/gui/editem-int.h b/src/gui/editem-int.h deleted file mode 100644 index 69533f7..0000000 --- a/src/gui/editem-int.h +++ /dev/null @@ -1,94 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * editem-int.h - prototypes pour les définitions internes liées aux éléments réactifs de l'éditeur - * - * Copyright (C) 2010-2020 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 _GUI_EDITEM_INT_H -#define _GUI_EDITEM_INT_H - - -#include "editem.h" - - -#include - - -#include "../analysis/project.h" -#include "../common/dllist.h" - - - -/* Réagit à un changement de contenu chargé en cours d'analyse. */ -typedef void (* change_item_content_fc) (GEditorItem *, GLoadedContent *, GLoadedContent *); - -/* Réagit à un changement de vue du contenu en cours d'analyse. */ -typedef void (* change_item_view_fc) (GEditorItem *, GLoadedPanel *, GLoadedPanel *); - -/* Réagit à une modification de la vue du contenu analysé. */ -typedef void (* update_item_view_fc) (GEditorItem *, GLoadedPanel *); - -/* Suit les changements de position dans du code d'assembleur. */ -typedef void (* track_cursor_in_view_fc) (GEditorItem *, GLoadedPanel *, const GLineCursor *); - -/* Concentre l'attention de l'ensemble sur une adresse donnée. */ -typedef void (* focus_cursor_fc) (GEditorItem *, GLoadedContent *, const GLineCursor *); - -/* Lance une actualisation relative à l'étendue du projet. */ -typedef void (* update_project_fc) (GEditorItem *, GStudyProject *); - - -/* Elément réactif quelconque de l'éditeur (instance) */ -struct _GEditorItem -{ - GObject parent; /* A laisser en premier */ - - DL_LIST_ITEM(link); /* Maillon de liste chaînée */ - - const char *name; /* Nom du panneau */ - GtkWidget *widget; /* Composant GTK d'affichage */ - -}; - - -/* Elément réactif quelconque de l'éditeur (classe) */ -struct _GEditorItemClass -{ - GObjectClass parent; /* A laisser en premier */ - - change_item_content_fc change_content; /* Changement de contenu */ - change_item_view_fc change_view; /* Rechargement dû à une vue */ - update_item_view_fc update_view; /* Rechargement dû à évolutions*/ - - track_cursor_in_view_fc track_cursor; /* Suivi des positions */ - focus_cursor_fc focus_cursor; /* Prête attention à une addr. */ - - update_project_fc update_project; /* Actualisation des binaires */ - -}; - - -#define editem_list_add_tail(new, head) dl_list_add_tail(new, head, GEditorItem, link) -#define editem_list_for_each(pos, head) dl_list_for_each(pos, head, GEditorItem, link) - - - -#endif /* _GUI_EDITEM_INT_H */ diff --git a/src/gui/editem.c b/src/gui/editem.c deleted file mode 100644 index c55fb65..0000000 --- a/src/gui/editem.c +++ /dev/null @@ -1,251 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * editem.c - gestion des différents éléments réactifs de l'éditeurs - * - * Copyright (C) 2010-2020 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 "editem.h" - - -#include "editem-int.h" - - - -/* Initialise la classe des éléments réactifs de l'éditeur. */ -static void g_editor_item_class_init(GEditorItemClass *); - -/* Initialise une instance d'élément réactif pour l'éditeur. */ -static void g_editor_item_init(GEditorItem *); - - -/* Indique le type défini pour un élément réactif d'éditeur. */ -G_DEFINE_TYPE(GEditorItem, g_editor_item, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des éléments réactifs de l'éditeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_editor_item_class_init(GEditorItemClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à initialiser. * -* * -* Description : Initialise une instance d'élément réactif pour l'éditeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_editor_item_init(GEditorItem *item) -{ - DL_LIST_ITEM_INIT(&item->link); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* * -* Description : Fournit le nom humain attribué à l'élément réactif. * -* * -* Retour : Désignation (courte) de l'élément de l'éditeur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_editor_item_get_name(const GEditorItem *item) -{ - return item->name; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* * -* Description : Fournit le composant GTK associé à l'élément réactif. * -* * -* Retour : Instance de composant graphique chargé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *g_editor_item_get_widget(const GEditorItem *item) -{ - GtkWidget *result; /* Composant à retourner */ - - result = item->widget; - - if (result != NULL) - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* old = ancien contenu chargé analysé. * -* new = nouveau contenu chargé à analyser. * -* * -* Description : Réagit à un changement de contenu chargé en cours d'analyse. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_editor_item_change_content(GEditorItem *item, GLoadedContent *old, GLoadedContent *new) -{ - GEditorItemClass *klass; /* Classe correspondante */ - - klass = G_EDITOR_ITEM_GET_CLASS(item); - - if (klass->change_content != NULL) - klass->change_content(item, old, new); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* old = ancienne vue du contenu chargé analysé. * -* new = nouvelle vue du contenu chargé analysé. * -* * -* Description : Réagit à un changement de vue du contenu en cours d'analyse. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_editor_item_change_view(GEditorItem *item, GLoadedPanel *old, GLoadedPanel *new) -{ - GEditorItemClass *klass; /* Classe correspondante */ - - klass = G_EDITOR_ITEM_GET_CLASS(item); - - if (klass->change_view != NULL) - klass->change_view(item, old, new); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* panel = vue du contenu chargé analysé modifiée. * -* * -* Description : Réagit à une modification de la vue du contenu analysé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_editor_item_update_view(GEditorItem *item, GLoadedPanel *panel) -{ - GEditorItemClass *klass; /* Classe correspondante */ - - klass = G_EDITOR_ITEM_GET_CLASS(item); - - if (klass->update_view != NULL) - klass->update_view(item, panel); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* panel = composant d'affichage parcouru. * -* cursor = nouvel emplacement du curseur courant. * -* * -* Description : Réagit à une modification de la vue du contenu analysé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_editor_item_track_cursor(GEditorItem *item, GLoadedPanel *panel, const GLineCursor *cursor) -{ - GEditorItemClass *klass; /* Classe correspondante */ - - klass = G_EDITOR_ITEM_GET_CLASS(item); - - if (klass->track_cursor != NULL) - klass->track_cursor(item, panel, cursor); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à consulter. * -* content = contenu contenant le curseur à représenter. * -* cursor = nouvel emplacement du curseur courant. * -* * -* Description : Réagit à une modification de la vue du contenu analysé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_editor_item_focus_cursor(GEditorItem *item, GLoadedContent *content, const GLineCursor *cursor) -{ - GEditorItemClass *klass; /* Classe correspondante */ - - klass = G_EDITOR_ITEM_GET_CLASS(item); - - if (klass->focus_cursor != NULL) - klass->focus_cursor(item, content, cursor); - -} diff --git a/src/gui/editem.h b/src/gui/editem.h deleted file mode 100644 index 3e1fbe8..0000000 --- a/src/gui/editem.h +++ /dev/null @@ -1,79 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * editem.h - prototypes pour la gestion des différents éléments réactifs de l'éditeurs - * - * Copyright (C) 2010-2020 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 _GUI_EDITEM_H -#define _GUI_EDITEM_H - - -#include -#include - - -#include "../analysis/loaded.h" -#include "../glibext/gloadedpanel.h" - - - -#define G_TYPE_EDITOR_ITEM g_editor_item_get_type() -#define G_EDITOR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_editor_item_get_type(), GEditorItem)) -#define G_IS_EDITOR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_editor_item_get_type())) -#define G_EDITOR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), g_editor_item_get_type(), GEditorItemClass)) -#define G_IS_EDITOR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), g_editor_item_get_type())) -#define G_EDITOR_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), g_editor_item_get_type(), GEditorItemClass)) - - -/* Elément réactif quelconque de l'éditeur (instance) */ -typedef struct _GEditorItem GEditorItem; - -/* Elément réactif quelconque de l'éditeur (classe) */ -typedef struct _GEditorItemClass GEditorItemClass; - - -/* Indique le type défini pour un élément réactif d'éditeur. */ -GType g_editor_item_get_type(void); - -/* Fournit le nom humain attribué à l'élément réactif. */ -const char *g_editor_item_get_name(const GEditorItem *); - -/* Fournit le composant GTK associé à l'élément réactif. */ -GtkWidget *g_editor_item_get_widget(const GEditorItem *); - -/* Réagit à un changement de contenu chargé en cours d'analyse. */ -void g_editor_item_change_content(GEditorItem *, GLoadedContent *, GLoadedContent *); - -/* Réagit à un changement de vue du contenu en cours d'analyse. */ -void g_editor_item_change_view(GEditorItem *, GLoadedPanel *, GLoadedPanel *); - -/* Réagit à une modification de la vue du contenu analysé. */ -void g_editor_item_update_view(GEditorItem *, GLoadedPanel *); - -/* Réagit à une modification de la vue du contenu analysé. */ -void g_editor_item_track_cursor(GEditorItem *, GLoadedPanel *, const GLineCursor *); - -/* Réagit à une modification de la vue du contenu analysé. */ -void g_editor_item_focus_cursor(GEditorItem *, GLoadedContent *, const GLineCursor *); - - - -#endif /* _GUI_EDITEM_H */ diff --git a/src/gui/editor.c b/src/gui/editor.c index 8e20cc1..ea650d3 100644 --- a/src/gui/editor.c +++ b/src/gui/editor.c @@ -48,6 +48,7 @@ #include "../core/global.h" #include "../core/params.h" #include "../glibext/chrysamarshal.h" +#include "../glibext/named.h" #include "../glibext/signal.h" #include "../gtkext/easygtk.h" #include "../gtkext/gtkdisplaypanel.h" @@ -115,6 +116,9 @@ static void on_dock_item_switch(GtkDockStation *, GtkWidget *, gpointer); /* Encastre comme demandé un panneau dans l'éditeur. */ static void dock_panel_into_current_station(GtkCheckMenuItem *, GPanelItem *); +/* Ajout d'un panneau dans la liste adaptée des menus. */ +static bool add_side_panel_to_menu(GPanelItem *, GtkContainer *); + /* Réagit à une demande de menu pour rajouter des panneaux. */ static void on_dock_menu_request(GtkDockStation *, GtkWidget *, gpointer); @@ -571,7 +575,7 @@ static GtkWidget *build_editor_toolbar(GObject *ref) gtk_widget_show(result); g_object_set_data(ref, "toolbar", result); - item = create_portions_tb_item(ref); + item = g_portions_tbitem_new(ref); register_editor_item(item); void track_tb_items_visibility(GtkWidget *widget, gpointer unused) @@ -705,11 +709,11 @@ static void dock_panel_into_current_station(GtkCheckMenuItem *menuitem, GPanelIt /****************************************************************************** * * -* Paramètres : station = panneau de support des éléments concerné. * +* Paramètres : panel n = panneau de support des éléments concerné. * * button = bouton à l'origine de la procédure. * * unsued = adresse non utilisée ici. * * * -* Description : Réagit à une demande de menu pour rajouter des panneaux. * +* Description : Ajout d'un panneau dans la liste adaptée des menus. * * * * Retour : - * * * @@ -717,57 +721,74 @@ static void dock_panel_into_current_station(GtkCheckMenuItem *menuitem, GPanelIt * * ******************************************************************************/ -static void on_dock_menu_request(GtkDockStation *station, GtkWidget *button, gpointer unused) +static bool add_side_panel_to_menu(GPanelItem *panel, GtkContainer *support) { - GtkWidget *active; /* Composant actif modèle */ - GPanelItem *model; /* Panneau encapsulé */ - GtkContainer *menu; /* Support à retourner */ - GList *children; /* Composants mis en place */ - GtkWidget *nopanel; /* Sous-élément de menu */ + char *key; /* Désignation de l'entrée */ + GtkWidget *submenuitem; /* Sous-élément de menu */ + const char *bindings; /* Raccourcis clavier bruts */ - menu = GTK_CONTAINER(qck_create_menu(NULL)); + /* Profil qui ne cadre pas ? */ - active = gtk_notebook_get_nth_page(GTK_NOTEBOOK(station), 0); + if (gtk_panel_item_get_personality(panel) != PIP_SINGLETON) + goto exit; - model = G_PANEL_ITEM(g_object_get_data(G_OBJECT(active), "dockable")); + if (g_panel_item_is_docked(panel)) + goto exit; - g_object_set_data_full(G_OBJECT(menu), "path", strdup(gtk_panel_item_get_path(model)), free); + /* Elément de menu */ - /* Ajout des panneaux uniques */ + key = g_editor_item_get_key(G_EDITOR_ITEM(panel)); - bool add_side_panel_to_menu(GPanelItem *panel, GtkContainer *support) - { - const char *name; /* Désignation de l'entrée */ - GtkWidget *submenuitem; /* Sous-élément de menu */ - const char *bindings; /* Raccourcis clavier bruts */ + submenuitem = qck_create_menu_item(NULL, NULL, key, + G_CALLBACK(dock_panel_into_current_station), panel); - /* Profil qui ne cadre pas ? */ + free(key); - if (gtk_panel_item_get_personality(panel) != PIP_SINGLETON) - goto aptm_exit; + bindings = gtk_panel_item_get_key_bindings(panel); - if (g_panel_item_is_docked(panel)) - goto aptm_exit; + if (bindings != NULL) + add_accelerator_to_widget(submenuitem, bindings); - /* Elément de menu */ + gtk_container_add(support, submenuitem); - name = g_editor_item_get_name(G_EDITOR_ITEM(panel)); + exit: - submenuitem = qck_create_menu_item(NULL, NULL, name, - G_CALLBACK(dock_panel_into_current_station), panel); + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : station = panneau de support des éléments concerné. * +* button = bouton à l'origine de la procédure. * +* unsued = adresse non utilisée ici. * +* * +* Description : Réagit à une demande de menu pour rajouter des panneaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - bindings = gtk_panel_item_get_key_bindings(panel); +static void on_dock_menu_request(GtkDockStation *station, GtkWidget *button, gpointer unused) +{ + GtkWidget *active; /* Composant actif modèle */ + GPanelItem *model; /* Panneau encapsulé */ + GtkContainer *menu; /* Support à retourner */ + GList *children; /* Composants mis en place */ + GtkWidget *nopanel; /* Sous-élément de menu */ - if (bindings != NULL) - add_accelerator_to_widget(submenuitem, bindings); + menu = GTK_CONTAINER(qck_create_menu(NULL)); - gtk_container_add(support, submenuitem); + active = gtk_notebook_get_nth_page(GTK_NOTEBOOK(station), 0); - aptm_exit: + model = G_PANEL_ITEM(g_object_get_data(G_OBJECT(active), "dockable")); - return true; + g_object_set_data_full(G_OBJECT(menu), "path", strdup(gtk_panel_item_get_path(model)), free); - } + /* Ajout des panneaux uniques */ browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_menu, menu); @@ -925,25 +946,19 @@ static void on_editor_content_available(GStudyProject *project, GLoadedContent * static void on_editor_loaded_content_added(GStudyProject *project, GLoadedContent *content, void *unused) { - GtkWidget *selected; /* Interface de prédilection */ - char *name; /* Titre associé au binaire */ - char *lname; /* Description du binaire */ GPanelItem *panel; /* Nouveau panneau à integrer */ + GtkWidget *selected; /* Interface de prédilection */ - selected = g_loaded_content_build_default_view(content); - - name = g_loaded_content_describe(content, false); - lname = g_loaded_content_describe(content, true); - - panel = g_panel_item_new(PIP_BINARY_VIEW, name, lname, selected, true, "M"); - - free(lname); - free(name); + panel = g_panel_item_new(PIP_BINARY_VIEW, G_NAMED_WIDGET(content), true, "M"); register_panel_item(panel, get_main_configuration()); + selected = g_editor_item_get_widget(G_EDITOR_ITEM(panel)); + g_signal_connect(selected, "size-allocate", G_CALLBACK(scroll_for_the_first_time), content); + g_object_unref(G_OBJECT(selected)); + g_panel_item_dock(panel); update_project_area(project); diff --git a/src/gui/item-int.h b/src/gui/item-int.h new file mode 100644 index 0000000..a2a6a65 --- /dev/null +++ b/src/gui/item-int.h @@ -0,0 +1,90 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * item-int.h - prototypes pour les définitions internes liées aux éléments réactifs de l'éditeur + * + * Copyright (C) 2010-2020 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 _GUI_ITEM_INT_H +#define _GUI_ITEM_INT_H + + +#include "item.h" + + +#include + + + +/* Fournit le nom interne attribué à l'élément réactif. */ +typedef char * (* get_item_key_fc) (const GEditorItem *); + +/* Fournit le composant GTK associé à l'élément réactif. */ +typedef GtkWidget * (* get_item_widget_fc) (const GEditorItem *); + +/* Réagit à un changement de contenu chargé en cours d'analyse. */ +typedef void (* change_item_content_fc) (GEditorItem *, GLoadedContent *, GLoadedContent *); + +/* Réagit à un changement de vue du contenu en cours d'analyse. */ +typedef void (* change_item_view_fc) (GEditorItem *, GLoadedPanel *, GLoadedPanel *); + +/* Réagit à une modification de la vue du contenu analysé. */ +typedef void (* update_item_view_fc) (GEditorItem *, GLoadedPanel *); + +/* Suit les changements de position dans du code d'assembleur. */ +typedef void (* track_cursor_in_view_fc) (GEditorItem *, GLoadedPanel *, const GLineCursor *); + +/* Concentre l'attention de l'ensemble sur une adresse donnée. */ +typedef void (* focus_cursor_fc) (GEditorItem *, GLoadedContent *, const GLineCursor *); + +/* Lance une actualisation relative à l'étendue du projet. */ +typedef void (* update_project_fc) (GEditorItem *, GStudyProject *); + + +/* Elément réactif quelconque de l'éditeur (instance) */ +struct _GEditorItem +{ + GObject parent; /* A laisser en premier */ + +}; + + +/* Elément réactif quelconque de l'éditeur (classe) */ +struct _GEditorItemClass +{ + GObjectClass parent; /* A laisser en premier */ + + get_item_key_fc get_key; /* Obtention d'un nom clef */ + get_item_widget_fc get_widget; /* Fourniture du composant */ + + change_item_content_fc change_content; /* Changement de contenu */ + change_item_view_fc change_view; /* Rechargement dû à une vue */ + update_item_view_fc update_view; /* Rechargement dû à évolutions*/ + + track_cursor_in_view_fc track_cursor; /* Suivi des positions */ + focus_cursor_fc focus_cursor; /* Prête attention à une addr. */ + + update_project_fc update_project; /* Actualisation des binaires */ + +}; + + + +#endif /* _GUI_ITEM_INT_H */ diff --git a/src/gui/item.c b/src/gui/item.c new file mode 100644 index 0000000..47504d1 --- /dev/null +++ b/src/gui/item.c @@ -0,0 +1,289 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * item.c - gestion des différents éléments réactifs de l'éditeurs + * + * Copyright (C) 2010-2020 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 "item.h" + + +#include + + +#include "item-int.h" + + + +/* Initialise la classe des éléments réactifs de l'éditeur. */ +static void g_editor_item_class_init(GEditorItemClass *); + +/* Initialise une instance d'élément réactif pour l'éditeur. */ +static void g_editor_item_init(GEditorItem *); + + +/* Indique le type défini pour un élément réactif d'éditeur. */ +G_DEFINE_TYPE(GEditorItem, g_editor_item, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des éléments réactifs de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_editor_item_class_init(GEditorItemClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à initialiser. * +* * +* Description : Initialise une instance d'élément réactif pour l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_editor_item_init(GEditorItem *item) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *g_editor_item_get_key(const GEditorItem *item) +{ + char *result; /* Description à renvoyer */ + GEditorItemClass *klass; /* Classe correspondante */ + + klass = G_EDITOR_ITEM_GET_CLASS(item); + + assert(klass->get_key != NULL); + + result = klass->get_key(item); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* * +* Description : Fournit le composant GTK associé à l'élément réactif. * +* * +* Retour : Instance de composant graphique chargé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *g_editor_item_get_widget(const GEditorItem *item) +{ + GtkWidget *result; /* Composant à retourner */ + GEditorItemClass *klass; /* Classe correspondante */ + + klass = G_EDITOR_ITEM_GET_CLASS(item); + + assert(klass->get_widget != NULL); + + result = klass->get_widget(item); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* old = ancien contenu chargé analysé. * +* new = nouveau contenu chargé à analyser. * +* * +* Description : Réagit à un changement de contenu chargé en cours d'analyse. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_editor_item_change_content(GEditorItem *item, GLoadedContent *old, GLoadedContent *new) +{ + GEditorItemClass *klass; /* Classe correspondante */ + + klass = G_EDITOR_ITEM_GET_CLASS(item); + + if (klass->change_content != NULL) + klass->change_content(item, old, new); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* old = ancienne vue du contenu chargé analysé. * +* new = nouvelle vue du contenu chargé analysé. * +* * +* Description : Réagit à un changement de vue du contenu en cours d'analyse. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_editor_item_change_view(GEditorItem *item, GLoadedPanel *old, GLoadedPanel *new) +{ + GEditorItemClass *klass; /* Classe correspondante */ + + klass = G_EDITOR_ITEM_GET_CLASS(item); + + if (klass->change_view != NULL) + klass->change_view(item, old, new); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* panel = vue du contenu chargé analysé modifiée. * +* * +* Description : Réagit à une modification de la vue du contenu analysé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_editor_item_update_view(GEditorItem *item, GLoadedPanel *panel) +{ + GEditorItemClass *klass; /* Classe correspondante */ + + klass = G_EDITOR_ITEM_GET_CLASS(item); + + if (klass->update_view != NULL) + klass->update_view(item, panel); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* panel = composant d'affichage parcouru. * +* cursor = nouvel emplacement du curseur courant. * +* * +* Description : Réagit à une modification de la vue du contenu analysé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_editor_item_track_cursor(GEditorItem *item, GLoadedPanel *panel, const GLineCursor *cursor) +{ + GEditorItemClass *klass; /* Classe correspondante */ + + klass = G_EDITOR_ITEM_GET_CLASS(item); + + if (klass->track_cursor != NULL) + klass->track_cursor(item, panel, cursor); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* content = contenu contenant le curseur à représenter. * +* cursor = nouvel emplacement du curseur courant. * +* * +* Description : Réagit à une modification de la vue du contenu analysé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_editor_item_focus_cursor(GEditorItem *item, GLoadedContent *content, const GLineCursor *cursor) +{ + GEditorItemClass *klass; /* Classe correspondante */ + + klass = G_EDITOR_ITEM_GET_CLASS(item); + + if (klass->focus_cursor != NULL) + klass->focus_cursor(item, content, cursor); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* project = projet concerné par l'évolution. * +* * +* Description : Lance une actualisation relative à l'étendue du projet. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_editor_item_update_project_area(GEditorItem *item, GStudyProject *project) +{ + GEditorItemClass *klass; /* Classe correspondante */ + + klass = G_EDITOR_ITEM_GET_CLASS(item); + + if (klass->update_project != NULL) + klass->update_project(item, project); + +} diff --git a/src/gui/item.h b/src/gui/item.h new file mode 100644 index 0000000..81d5b20 --- /dev/null +++ b/src/gui/item.h @@ -0,0 +1,83 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * item.h - prototypes pour la gestion des différents éléments réactifs de l'éditeurs + * + * Copyright (C) 2010-2020 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 _GUI_ITEM_H +#define _GUI_ITEM_H + + +#include +#include + + +#include "../analysis/loaded.h" +#include "../analysis/project.h" +#include "../glibext/gloadedpanel.h" + + + +#define G_TYPE_EDITOR_ITEM g_editor_item_get_type() +#define G_EDITOR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_editor_item_get_type(), GEditorItem)) +#define G_IS_EDITOR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_editor_item_get_type())) +#define G_EDITOR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), g_editor_item_get_type(), GEditorItemClass)) +#define G_IS_EDITOR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), g_editor_item_get_type())) +#define G_EDITOR_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), g_editor_item_get_type(), GEditorItemClass)) + + +/* Elément réactif quelconque de l'éditeur (instance) */ +typedef struct _GEditorItem GEditorItem; + +/* Elément réactif quelconque de l'éditeur (classe) */ +typedef struct _GEditorItemClass GEditorItemClass; + + +/* Indique le type défini pour un élément réactif d'éditeur. */ +GType g_editor_item_get_type(void); + +/* Fournit le nom interne attribué à l'élément réactif. */ +char *g_editor_item_get_key(const GEditorItem *); + +/* Fournit le composant GTK associé à l'élément réactif. */ +GtkWidget *g_editor_item_get_widget(const GEditorItem *); + +/* Réagit à un changement de contenu chargé en cours d'analyse. */ +void g_editor_item_change_content(GEditorItem *, GLoadedContent *, GLoadedContent *); + +/* Réagit à un changement de vue du contenu en cours d'analyse. */ +void g_editor_item_change_view(GEditorItem *, GLoadedPanel *, GLoadedPanel *); + +/* Réagit à une modification de la vue du contenu analysé. */ +void g_editor_item_update_view(GEditorItem *, GLoadedPanel *); + +/* Réagit à une modification de la vue du contenu analysé. */ +void g_editor_item_track_cursor(GEditorItem *, GLoadedPanel *, const GLineCursor *); + +/* Réagit à une modification de la vue du contenu analysé. */ +void g_editor_item_focus_cursor(GEditorItem *, GLoadedContent *, const GLineCursor *); + +/* Lance une actualisation relative à l'étendue du projet. */ +void g_editor_item_update_project_area(GEditorItem *, GStudyProject *); + + + +#endif /* _GUI_ITEM_H */ diff --git a/src/gui/menus/binary.c b/src/gui/menus/binary.c index b307333..9e85520 100644 --- a/src/gui/menus/binary.c +++ b/src/gui/menus/binary.c @@ -29,7 +29,7 @@ #include "../agroup.h" -#include "../editem-int.h" +#include "../item-int.h" #include "../core/global.h" #include "../dialogs/export_disass.h" #include "../dialogs/export_graph.h" diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c index 08e9e5e..44761b9 100644 --- a/src/gui/menus/menubar.c +++ b/src/gui/menus/menubar.c @@ -25,6 +25,9 @@ #include "menubar.h" +#include + + #include "binary.h" #include "debug.h" #include "edition.h" @@ -34,7 +37,7 @@ #include "plugins.h" #include "project.h" #include "view.h" -#include "../editem-int.h" +#include "../item-int.h" #include "../core/global.h" @@ -44,6 +47,8 @@ struct _GMenuBar { GEditorItem parent; /* A laisser en premier */ + GtkWidget *support; /* Composant principal */ + GtkWidget *file; /* Menu "Fichier" */ GtkWidget *edition; /* Menu "Edition" */ GtkWidget *view; /* Menu "Affichage" */ @@ -77,6 +82,12 @@ static void g_menu_bar_dispose(GMenuBar *); /* Procède à la libération totale de la mémoire. */ static void g_menu_bar_finalize(GMenuBar *); +/* Fournit le nom humain attribué à l'élément réactif. */ +static char *g_menu_bar_get_key(const GMenuBar *); + +/* Fournit le composant GTK associé à l'élément réactif. */ +static GtkWidget *g_menu_bar_get_widget(const GMenuBar *); + /* Réagit à un changement d'affichage principal de contenu. */ static void change_menubar_current_content(GMenuBar *, GLoadedContent *, GLoadedContent *); @@ -110,19 +121,22 @@ G_DEFINE_TYPE(GMenuBar, g_menu_bar, G_TYPE_EDITOR_ITEM); static void g_menu_bar_class_init(GMenuBarClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_menu_bar_dispose; object->finalize = (GObjectFinalizeFunc)g_menu_bar_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_menu_bar_get_key; + item->get_widget = (get_item_widget_fc)g_menu_bar_get_widget; - editem->change_content = (change_item_content_fc)change_menubar_current_content; - editem->change_view = (change_item_view_fc)change_menubar_current_view; - editem->track_cursor = (track_cursor_in_view_fc)track_caret_address_for_menu_bar; - editem->update_project = (update_project_fc)update_menu_bar_for_project; + item->change_content = (change_item_content_fc)change_menubar_current_content; + item->change_view = (change_item_view_fc)change_menubar_current_view; + item->track_cursor = (track_cursor_in_view_fc)track_caret_address_for_menu_bar; + item->update_project = (update_project_fc)update_menu_bar_for_project; } @@ -141,14 +155,8 @@ static void g_menu_bar_class_init(GMenuBarClass *klass) static void g_menu_bar_init(GMenuBar *bar) { - GEditorItem *item; /* Autre version de l'élément */ - - item = G_EDITOR_ITEM(bar); - - item->name = "menus"; - - item->widget = gtk_menu_bar_new(); - gtk_widget_show(item->widget); + bar->support = gtk_menu_bar_new(); + gtk_widget_show(bar->support); } @@ -206,56 +214,53 @@ static void g_menu_bar_finalize(GMenuBar *bar) GEditorItem *g_menu_bar_new(GObject *ref) { GMenuBar *result; /* Structure à retourner */ - GEditorItem *item; /* Autre version de l'élément */ result = g_object_new(G_TYPE_MENU_BAR, NULL); - item = G_EDITOR_ITEM(result); - /* Fichier */ result->file = build_menu_file(); - gtk_container_add(GTK_CONTAINER(item->widget), result->file); + gtk_container_add(GTK_CONTAINER(result->support), result->file); /* Edition */ result->edition = build_menu_edition(ref, result); - gtk_container_add(GTK_CONTAINER(item->widget), result->edition); + gtk_container_add(GTK_CONTAINER(result->support), result->edition); /* Affichage */ result->view = build_menu_view(ref, result); - gtk_container_add(GTK_CONTAINER(item->widget), result->view); + gtk_container_add(GTK_CONTAINER(result->support), result->view); /* Projet */ result->project = build_menu_project(ref, result); - gtk_container_add(GTK_CONTAINER(item->widget), result->project); + gtk_container_add(GTK_CONTAINER(result->support), result->project); /* Binaire */ result->binary = build_menu_binary(ref, result); - gtk_container_add(GTK_CONTAINER(item->widget), result->binary); + gtk_container_add(GTK_CONTAINER(result->support), result->binary); /* Débogage */ result->debug = build_menu_debug(ref); - gtk_container_add(GTK_CONTAINER(item->widget), result->debug); + gtk_container_add(GTK_CONTAINER(result->support), result->debug); /* Options */ result->options = build_menu_options(ref, result); - gtk_container_add(GTK_CONTAINER(item->widget), result->options); + gtk_container_add(GTK_CONTAINER(result->support), result->options); /* Greffons */ result->plugins = build_menu_plugins(ref); - gtk_container_add(GTK_CONTAINER(item->widget), result->plugins); + gtk_container_add(GTK_CONTAINER(result->support), result->plugins); /* Aide */ result->help = build_menu_help(); - gtk_container_add(GTK_CONTAINER(item->widget), result->help); + gtk_container_add(GTK_CONTAINER(result->support), result->help); return G_EDITOR_ITEM(result); @@ -264,6 +269,55 @@ GEditorItem *g_menu_bar_new(GObject *ref) /****************************************************************************** * * +* Paramètres : bar = instance à consulter. * +* * +* Description : Fournit le nom humain attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_menu_bar_get_key(const GMenuBar *bar) +{ + char *result; /* Description à renvoyer */ + + result = strdup("menus"); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : bar = instance à consulter. * +* * +* Description : Fournit le composant GTK associé à l'élément réactif. * +* * +* Retour : Instance de composant graphique chargé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *g_menu_bar_get_widget(const GMenuBar *bar) +{ + GtkWidget *result; /* Composant à retourner */ + + result = bar->support; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : bar = barre de menus à mettre à jour. * * old = ancien contenu chargé analysé. * * new = nouveau contenu chargé à analyser. * diff --git a/src/gui/menus/menubar.h b/src/gui/menus/menubar.h index 4f0a450..5b77dc6 100644 --- a/src/gui/menus/menubar.h +++ b/src/gui/menus/menubar.h @@ -26,7 +26,7 @@ #define _GUI_MENUS_MENUBAR_H -#include "../editem.h" +#include "../item.h" diff --git a/src/gui/menus/options.c b/src/gui/menus/options.c index 981ae91..62f58f5 100644 --- a/src/gui/menus/options.c +++ b/src/gui/menus/options.c @@ -28,7 +28,7 @@ #include -#include "../editem-int.h" +#include "../item-int.h" #include "../core/global.h" #include "../dialogs/identity.h" #include "../dialogs/preferences.h" diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c index a5992bf..e472419 100644 --- a/src/gui/menus/project.c +++ b/src/gui/menus/project.c @@ -31,7 +31,7 @@ #include -#include "../editem-int.h" +#include "../item-int.h" #include "../core/global.h" #include "../../analysis/loading.h" #include "../../analysis/contents/file.h" diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c index b9451e0..c2f3f28 100644 --- a/src/gui/menus/view.c +++ b/src/gui/menus/view.c @@ -34,7 +34,7 @@ #include "../agroup.h" -#include "../editem-int.h" +#include "../item-int.h" #include "../core/global.h" #include "../core/items.h" #include "../core/panels.h" @@ -558,7 +558,7 @@ void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) bool add_side_panel_to_list(GPanelItem *panel, panels_loading_filter *filter) { - const char *name; /* Désignation de l'entrée */ + char *key; /* Désignation de l'entrée */ GtkWidget *submenuitem; /* Sous-élément de menu */ const char *bindings; /* Raccourcis clavier bruts */ @@ -578,11 +578,13 @@ void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) /* Elément de menu */ - name = g_editor_item_get_name(G_EDITOR_ITEM(panel)); + key = g_editor_item_get_key(G_EDITOR_ITEM(panel)); - submenuitem = qck_create_check_menu_item(NULL, NULL, name, + submenuitem = qck_create_check_menu_item(NULL, NULL, key, G_CALLBACK(mcb_view_change_panel_docking), panel); + free(key); + bindings = gtk_panel_item_get_key_bindings(panel); if (bindings != NULL) diff --git a/src/gui/panel-int.h b/src/gui/panel-int.h index f6be8a1..2f7d876 100644 --- a/src/gui/panel-int.h +++ b/src/gui/panel-int.h @@ -32,7 +32,7 @@ #include -#include "editem-int.h" +#include "item-int.h" #include "../common/dllist.h" #include "../glibext/delayed.h" @@ -60,7 +60,8 @@ struct _GPanelItem PanelItemPersonality personality; /* Nature de l'élément */ - const char *lname; /* Description longue */ + GNamedWidget *widget; /* Composant avec noms */ + GtkWidget *cached_widget; /* Composant GTK récupéré */ bool dock_at_startup; /* Recommandation au démarrage */ char *path; /* Chemin vers la place idéale */ @@ -69,20 +70,6 @@ struct _GPanelItem char *filter; /* Eventuel filtre textuel */ - /** - * La gestion générique du constructeur repose sur quelques - * prérequis quant à l'enregistrement de composants : - * - * - "box" doit être le support de panneau à intégrer. - * - * - pour les contenus actualisables, une pile de composants - * "stack" doit contenir un support "content" pour le - * contenu principal et un support "mask" qui prend le - * relais pendant les opérations de mise à jour. - */ - - GtkBuilder *builder; /* Constructeur utilisé */ - cairo_surface_t *surface; /* Copie d'écran préalable */ gdouble hadj_value; /* Sauvegarde de défilement #1 */ gdouble vadj_value; /* Sauvegarde de défilement #2 */ @@ -119,13 +106,6 @@ struct _GPanelItemClass #define panels_list_for_each(pos, head) dl_list_for_each(pos, head, GPanelItem, link) -/* Charge les éléments graphiques du panneau via les ressources. */ -GtkBuilder *g_panel_item_build(GPanelItem *, const char *); - -/* Charge les éléments graphiques du panneau via les ressources. */ -GtkBuilder *g_panel_item_build_full(GPanelItem *, const char *); - - /* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */ diff --git a/src/gui/panel.c b/src/gui/panel.c index 2ebcdad..04f4844 100644 --- a/src/gui/panel.c +++ b/src/gui/panel.c @@ -34,6 +34,7 @@ #include "../common/extstr.h" #include "../core/params.h" #include "../gtkext/gtkdockable-int.h" +#include "../gtkext/named.h" @@ -108,12 +109,18 @@ G_DEFINE_TYPE_WITH_CODE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM, static void g_panel_item_class_init(GPanelItemClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GEditorItemClass *item; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_panel_item_dispose; object->finalize = (GObjectFinalizeFunc)g_panel_item_finalize; + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)gtk_panel_item_get_name; + item->get_widget = (get_item_widget_fc)gtk_panel_item_get_widget; + g_signal_new("dock-request", G_TYPE_PANEL_ITEM, G_SIGNAL_RUN_LAST, @@ -153,6 +160,9 @@ static void g_panel_item_init(GPanelItem *item) item->personality = PIP_INVALID; + item->widget = NULL; + item->cached_widget = NULL; + item->filter = NULL; g_atomic_int_set(&item->switched, 0); @@ -198,7 +208,8 @@ static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface) static void g_panel_item_dispose(GPanelItem *item) { - g_clear_object(&item->builder); + g_clear_object(&item->widget); + g_clear_object(&item->cached_widget); G_OBJECT_CLASS(g_panel_item_parent_class)->dispose(G_OBJECT(item)); @@ -235,9 +246,7 @@ static void g_panel_item_finalize(GPanelItem *item) /****************************************************************************** * * * Paramètres : personality = nature du panneau à mettre en place. * -* name = nom associé à l'élément. * -* lname = description longue du panneau. * -* widget = composant à présenter à l'affichage. * +* widget = composant avec noms à présenter à l'affichage. * * startup = chargement au démarrage ? * * path = chemin vers la place idéale pour le futur panneau. * * * @@ -249,22 +258,17 @@ static void g_panel_item_finalize(GPanelItem *item) * * ******************************************************************************/ -GPanelItem *g_panel_item_new(PanelItemPersonality personality, const char *name, const char *lname, GtkWidget *widget, bool startup, const char *path) +GPanelItem *g_panel_item_new(PanelItemPersonality personality, GNamedWidget *widget, bool startup, const char *path) { GPanelItem *result; /* Structure à retourner */ - GEditorItem *parent; /* Autre version de l'élément */ result = g_object_new(G_TYPE_PANEL_ITEM, NULL); - parent = G_EDITOR_ITEM(result); - - parent->name = strdup(name); - parent->widget = widget; - assert(personality > PIP_INVALID && personality < PIP_COUNT); result->personality = personality; - result->lname = strdup(lname); + result->widget = widget; + g_object_ref(G_OBJECT(widget)); result->dock_at_startup = startup; result->path = strdup(path); @@ -276,62 +280,23 @@ GPanelItem *g_panel_item_new(PanelItemPersonality personality, const char *name, /****************************************************************************** * * -* Paramètres : item = panneau dont la construction est à poursuivre. * -* name = nom associé à l'élément dans les ressources globales. * -* * -* Description : Charge les éléments graphiques du panneau via les ressources.* -* * -* Retour : Constructeur mis en place, afin de faciliter son usage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkBuilder *g_panel_item_build(GPanelItem *item, const char *name) -{ - GtkBuilder *result; /* Constructeur à retourner */ - char *path; /* Chemin d'accès à constituer */ - - asprintf(&path, "/org/chrysalide/gui/panels/%s.ui", name); - - result = g_panel_item_build_full(item, path); - - free(path); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = panneau dont la construction est à poursuivre. * -* path = chemin d'accès complet à la ressource à charger. * +* Paramètres : item = instance de panneau à consulter. * * * -* Description : Charge les éléments graphiques du panneau via les ressources.* +* Description : Indique le composant graphique principal du panneau. * * * -* Retour : Constructeur mis en place, afin de faciliter son usage. * +* Retour : Composant graphique avec nom constituant le panneau. * * * * Remarques : - * * * ******************************************************************************/ -GtkBuilder *g_panel_item_build_full(GPanelItem *item, const char *path) +GNamedWidget *gtk_panel_item_get_named_widget(const GPanelItem *item) { - GtkBuilder *result; /* Constructeur à retourner */ - GEditorItem *base; /* Version basique d'instance */ - - result = gtk_builder_new_from_resource(path); - - item->builder = result; + GNamedWidget *result; /* Composant nommé à retourner */ - base = G_EDITOR_ITEM(item); + result = item->widget; - base->widget = GTK_WIDGET(gtk_builder_get_object(result, "box")); - - g_object_ref(G_OBJECT(base->widget)); - - gtk_widget_unparent(base->widget); + g_object_ref(G_OBJECT(result)); return result; @@ -354,7 +319,7 @@ static char *gtk_panel_item_get_name(const GPanelItem *item) { char *result; /* Désignation à retourner */ - result = strdup(G_EDITOR_ITEM(item)->name); + result = g_named_widget_get_name(G_NAMED_WIDGET(item->widget), false); return result; @@ -377,7 +342,7 @@ static char *gtk_panel_item_get_desc(const GPanelItem *item) { char *result; /* Description à retourner */ - result = strdup(item->lname); + result = g_named_widget_get_name(G_NAMED_WIDGET(item->widget), true); return result; @@ -426,7 +391,10 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item) { GtkWidget *result; /* Composant à retourner */ - result = G_EDITOR_ITEM(item)->widget; + if (item->cached_widget == NULL) + item->cached_widget = g_named_widget_get_widget(G_NAMED_WIDGET(item->widget)); + + result = item->cached_widget; g_object_ref(G_OBJECT(result)); @@ -479,7 +447,7 @@ static char *gtk_panel_item_build_configuration_key(const GPanelItem *item, cons char *result; /* Construction à renvoyer */ const char *name; /* Nom court du panneau */ - name = g_editor_item_get_name(G_EDITOR_ITEM(item)); + name = g_editor_item_get_key(G_EDITOR_ITEM(item)); asprintf(&result, "gui.panels.%s.%s", attrib, name); @@ -851,6 +819,7 @@ static gboolean g_panel_item_draw_mask(GtkWidget *widget, cairo_t *cr, GPanelIte void g_panel_item_switch_to_updating_mask(GPanelItem *item) { + GtkBuilder *builder; /* Constructeur sous-jacent */ GtkWidget *content; /* Composant à faire évoluer */ GdkWindow *window; /* Fenêtre au contenu à copier */ int width; /* Largeur du composant actuel */ @@ -867,7 +836,9 @@ void g_panel_item_switch_to_updating_mask(GPanelItem *item) assert(item->surface == NULL); - content = GTK_WIDGET(gtk_builder_get_object(item->builder, "content")); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(item->widget)); + + content = GTK_WIDGET(gtk_builder_get_object(builder, "content")); window = gtk_widget_get_window(content); @@ -902,9 +873,9 @@ void g_panel_item_switch_to_updating_mask(GPanelItem *item) /* Opération de basculement effectif */ - stack = GTK_STACK(gtk_builder_get_object(item->builder, "stack")); + stack = GTK_STACK(gtk_builder_get_object(builder, "stack")); - mask = GTK_WIDGET(gtk_builder_get_object(item->builder, "mask")); + mask = GTK_WIDGET(gtk_builder_get_object(builder, "mask")); gtk_spinner_start(GTK_SPINNER(mask)); @@ -913,6 +884,8 @@ void g_panel_item_switch_to_updating_mask(GPanelItem *item) gtk_stack_set_visible_child(stack, mask); + g_object_unref(G_OBJECT(builder)); + } @@ -930,6 +903,7 @@ void g_panel_item_switch_to_updating_mask(GPanelItem *item) void g_panel_item_switch_to_updated_content(GPanelItem *item) { + GtkBuilder *builder; /* Constructeur sous-jacent */ GtkWidget *content; /* Composant à faire évoluer */ GtkAdjustment *adj; /* Défilement éventuel */ GtkStack *stack; /* Pile de composants GTK */ @@ -940,7 +914,9 @@ void g_panel_item_switch_to_updated_content(GPanelItem *item) /* Restauration d'une éventuelle position */ - content = GTK_WIDGET(gtk_builder_get_object(item->builder, "content")); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(item->widget)); + + content = GTK_WIDGET(gtk_builder_get_object(builder, "content")); if (GTK_IS_SCROLLED_WINDOW(content)) { @@ -954,11 +930,11 @@ void g_panel_item_switch_to_updated_content(GPanelItem *item) /* Opération de basculement effectif */ - stack = GTK_STACK(gtk_builder_get_object(item->builder, "stack")); + stack = GTK_STACK(gtk_builder_get_object(builder, "stack")); gtk_stack_set_visible_child(stack, content); - mask = GTK_WIDGET(gtk_builder_get_object(item->builder, "mask")); + mask = GTK_WIDGET(gtk_builder_get_object(builder, "mask")); g_signal_handlers_disconnect_by_func(mask, G_CALLBACK(g_panel_item_draw_mask), item); @@ -972,6 +948,8 @@ void g_panel_item_switch_to_updated_content(GPanelItem *item) item->surface = NULL; } + g_object_unref(G_OBJECT(builder)); + skip: g_atomic_int_dec_and_test(&item->switched); diff --git a/src/gui/panel.h b/src/gui/panel.h index 3e2a293..067f076 100644 --- a/src/gui/panel.h +++ b/src/gui/panel.h @@ -27,10 +27,11 @@ #include +#include -#include "editem.h" #include "../glibext/configuration.h" +#include "../glibext/named.h" @@ -67,7 +68,10 @@ typedef enum _PanelItemPersonality GType g_panel_item_get_type(void); /* Crée un élément de panneau réactif. */ -GPanelItem *g_panel_item_new(PanelItemPersonality, const char *, const char *, GtkWidget *, bool, const char *); +GPanelItem *g_panel_item_new(PanelItemPersonality, GNamedWidget *, bool, const char *); + +/* Indique le composant graphique principal du panneau. */ +GNamedWidget *gtk_panel_item_get_named_widget(const GPanelItem *); /* Met en place les bases de la configuration du panneau. */ bool gtk_panel_item_setup_configuration(const GPanelItem *, GGenConfig *); diff --git a/src/gui/panels/bintree.c b/src/gui/panels/bintree.c index a949b0d..c05c4d4 100644 --- a/src/gui/panels/bintree.c +++ b/src/gui/panels/bintree.c @@ -39,12 +39,14 @@ #include "../core/global.h" #include "../../core/queue.h" #include "../../gtkext/gtkdisplaypanel.h" +#include "../../gtkext/named.h" #include "../../gtkext/tmgt.h" /* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */ + /* Origine de la dernière ouverture/fermeture reproductible */ typedef enum _UserActionType { @@ -113,6 +115,9 @@ static void g_bintree_panel_dispose(GBintreePanel *); /* Procède à la libération totale de la mémoire. */ static void g_bintree_panel_finalize(GBintreePanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_bintree_panel_get_key(const GBintreePanel *); + /* Modifie la profondeur affichée des portions présentes. */ static void on_depth_spin_value_changed(GtkSpinButton *, const GBintreePanel *); @@ -222,7 +227,7 @@ G_DEFINE_TYPE_WITH_CODE(GBintreePanel, g_bintree_panel, G_TYPE_PANEL_ITEM, static void g_bintree_panel_class_init(GBintreePanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ GPanelItemClass *panel; /* Version parente de la classe*/ object = G_OBJECT_CLASS(klass); @@ -230,9 +235,11 @@ static void g_bintree_panel_class_init(GBintreePanelClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_bintree_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_bintree_panel_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_bintree_panel_get_key; - editem->change_content = (change_item_content_fc)change_bintree_panel_current_content; + item->change_content = (change_item_content_fc)change_bintree_panel_current_content; panel = G_PANEL_ITEM_CLASS(klass); @@ -255,7 +262,6 @@ static void g_bintree_panel_class_init(GBintreePanelClass *klass) static void g_bintree_panel_init(GBintreePanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeView *treeview; /* Affichage de la liste */ @@ -264,14 +270,14 @@ static void g_bintree_panel_init(GBintreePanel *panel) /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_BINTREE_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Binary tree"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Binary tree"), + _("Tree of the binary layout"), + PANEL_BINTREE_ID)); + pitem->dock_at_startup = true; pitem->path = strdup("MEN"); @@ -283,7 +289,7 @@ static void g_bintree_panel_init(GBintreePanel *panel) /* Représentation graphique */ - builder = g_panel_item_build(pitem, "bintree"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); /* Liste des portions binaires */ @@ -336,6 +342,8 @@ static void g_bintree_panel_init(GBintreePanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -429,6 +437,29 @@ GPanelItem *g_bintree_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_bintree_panel_get_key(const GBintreePanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_BINTREE_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : button = bouton de réglage de l'affichage. * * treeview = arborescence dont l'affichage est à moduler. * * * @@ -462,7 +493,7 @@ static void on_depth_spin_value_changed(GtkSpinButton *button, const GBintreePan } - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -472,6 +503,8 @@ static void on_depth_spin_value_changed(GtkSpinButton *button, const GBintreePan gtk_tree_model_foreach(GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)apply_max_depth, NULL); + g_object_unref(G_OBJECT(builder)); + } @@ -557,12 +590,14 @@ static void change_bintree_panel_current_content(GBintreePanel *panel, GLoadedCo /* Réinitialisation */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); gtk_tree_store_clear(store); + g_object_unref(G_OBJECT(builder)); + /* Si le panneau actif représente un binaire, actualisation de l'affichage */ if (binary != NULL) @@ -612,7 +647,7 @@ static bool populate_tree_with_portion(GBinPortion *portion, GBinPortion *parent { icon = NULL; - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); @@ -634,6 +669,8 @@ static bool populate_tree_with_portion(GBinPortion *portion, GBinPortion *parent update_bintree_node(data, store, &iter, portion); + g_object_unref(G_OBJECT(builder)); + gtk_status_stack_update_activity_value(data->status, data->id, 1); } @@ -693,7 +730,7 @@ static void reload_portions_for_new_tree_view(const GBintreePanel *panel, GtkSta GtkSpinButton *depth_spin; /* Bouton de variation */ GtkTreeView *treeview; /* Arborescence constituée */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); @@ -772,6 +809,8 @@ static void reload_portions_for_new_tree_view(const GBintreePanel *panel, GtkSta } + g_object_unref(G_OBJECT(builder)); + } @@ -984,12 +1023,14 @@ static void do_filtering_on_portions(const GBintreePanel *panel, GtkStatusStack } - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); gtk_tree_model_foreach(GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)filter_portion_panel_iter, NULL); + g_object_unref(G_OBJECT(builder)); + } @@ -1132,7 +1173,7 @@ static const char *g_bintree_panel_setup(const GBintreePanel *panel, unsigned in /* Mémorisation de tous les noeuds ouverts */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1156,6 +1197,8 @@ static const char *g_bintree_panel_setup(const GBintreePanel *panel, unsigned in gtk_tree_view_map_expanded_rows(treeview, (GtkTreeViewMappingFunc)keep_track_of_expanded, *data); + g_object_unref(G_OBJECT(builder)); + return result; } @@ -1185,7 +1228,7 @@ static void g_bintree_panel_introduce(const GBintreePanel *panel, unsigned int u g_panel_item_switch_to_updating_mask(G_PANEL_ITEM(panel)); - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1197,6 +1240,8 @@ static void g_bintree_panel_introduce(const GBintreePanel *panel, unsigned int u gtk_tree_view_set_model(treeview, NULL); } + g_object_unref(G_OBJECT(builder)); + } @@ -1264,7 +1309,7 @@ static void g_bintree_panel_conclude(GBintreePanel *panel, unsigned int uid, bin /* Basculement de l'affichage en ligne */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1283,6 +1328,8 @@ static void g_bintree_panel_conclude(GBintreePanel *panel, unsigned int uid, bin } + g_object_unref(G_OBJECT(builder)); + skip_this_step: g_panel_item_switch_to_updated_content(G_PANEL_ITEM(panel)); diff --git a/src/gui/panels/bintree.h b/src/gui/panels/bintree.h index 2f0c27d..e36b0c0 100644 --- a/src/gui/panels/bintree.h +++ b/src/gui/panels/bintree.h @@ -33,7 +33,7 @@ -#define PANEL_BINTREE_ID _("Bintree") +#define PANEL_BINTREE_ID "bintree" #define G_TYPE_BINTREE_PANEL g_bintree_panel_get_type() diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c index 8b029d0..fe69f35 100644 --- a/src/gui/panels/bookmarks.c +++ b/src/gui/panels/bookmarks.c @@ -48,6 +48,7 @@ #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkdisplaypanel.h" #include "../../gtkext/gtkdockable-int.h" +#include "../../gtkext/named.h" @@ -106,6 +107,9 @@ static void g_bookmarks_panel_dispose(GBookmarksPanel *); /* Procède à la libération totale de la mémoire. */ static void g_bookmarks_panel_finalize(GBookmarksPanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_bookmarks_panel_get_key(const GBookmarksPanel *); + /* Réagit à un changement d'affichage principal de contenu. */ static void change_bookmarks_panel_current_content(GBookmarksPanel *, GLoadedContent *, GLoadedContent *); @@ -199,7 +203,7 @@ G_DEFINE_TYPE(GBookmarksPanel, g_bookmarks_panel, G_TYPE_PANEL_ITEM); static void g_bookmarks_panel_class_init(GBookmarksPanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ GPanelItemClass *panel; /* Version parente de la classe*/ gchar *filename; /* Chemin d'accès à utiliser */ @@ -208,9 +212,11 @@ static void g_bookmarks_panel_class_init(GBookmarksPanelClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_bookmarks_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_bookmarks_panel_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_bookmarks_panel_get_key; - editem->change_content = (change_item_content_fc)change_bookmarks_panel_current_content; + item->change_content = (change_item_content_fc)change_bookmarks_panel_current_content; panel = G_PANEL_ITEM_CLASS(klass); @@ -244,27 +250,26 @@ static void g_bookmarks_panel_class_init(GBookmarksPanelClass *klass) static void g_bookmarks_panel_init(GBookmarksPanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeSortable *sortable; /* Autre vision de la liste */ /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_BOOKMARKS_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Bookmarks"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Bookmarks"), + _("Bookmarks for the current binary"), + PANEL_BOOKMARKS_ID)); + pitem->dock_at_startup = false; pitem->path = strdup("Ms"); /* Représentation graphique */ - builder = g_panel_item_build(pitem, "bookmarks"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); /* Tri de la liste */ @@ -295,6 +300,8 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -371,6 +378,29 @@ GPanelItem *g_bookmarks_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_bookmarks_panel_get_key(const GBookmarksPanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_BOOKMARKS_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : panel = panneau à mettre à jour. * * old = ancien contenu chargé analysé. * * new = nouveau contenu chargé à analyser. * @@ -455,7 +485,7 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary } - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); @@ -505,6 +535,8 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary g_db_collection_runlock(collec); + g_object_unref(G_OBJECT(builder)); + } @@ -541,7 +573,7 @@ static void on_collection_content_changed(GDbCollection *collec, DBAction action GDbBookmark *displayed; /* Elément de collection */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); @@ -596,6 +628,7 @@ static void on_collection_content_changed(GDbCollection *collec, DBAction action } + g_object_unref(G_OBJECT(builder)); } @@ -662,7 +695,7 @@ static void on_config_param_modified(GCfgParam *param, GBookmarksPanel *panel) gboolean looping; /* Autorisation de bouclage */ GCfgParam *item; /* Elément de la liste */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store")); @@ -680,6 +713,8 @@ static void on_config_param_modified(GCfgParam *param, GBookmarksPanel *panel) } + g_object_unref(G_OBJECT(builder)); + } @@ -1139,7 +1174,7 @@ static void mcb_bookmarks_panel_edit(GtkMenuItem *menuitem, GBookmarksPanel *pan GtkTreeModel *model; /* Gestionnaire de données */ GtkTreePath *path; /* Chemin d'accès à ce point */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1157,6 +1192,8 @@ static void mcb_bookmarks_panel_edit(GtkMenuItem *menuitem, GBookmarksPanel *pan g_object_unref(G_OBJECT(mark)); + g_object_unref(G_OBJECT(builder)); + } @@ -1179,7 +1216,7 @@ static void mcb_bookmarks_panel_delete(GtkMenuItem *menuitem, GBookmarksPanel *p GtkTreeView *treeview; /* Affichage de la liste */ GDbBookmark *mark; /* Signet sélectionné */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1190,6 +1227,8 @@ static void mcb_bookmarks_panel_delete(GtkMenuItem *menuitem, GBookmarksPanel *p g_object_unref(G_OBJECT(mark)); + g_object_unref(G_OBJECT(builder)); + } diff --git a/src/gui/panels/bookmarks.h b/src/gui/panels/bookmarks.h index f5730d8..fa3e073 100644 --- a/src/gui/panels/bookmarks.h +++ b/src/gui/panels/bookmarks.h @@ -33,7 +33,7 @@ -#define PANEL_BOOKMARKS_ID _("Bookmarks") +#define PANEL_BOOKMARKS_ID "bookmarks" #define G_TYPE_BOOKMARKS_PANEL g_bookmarks_panel_get_type() diff --git a/src/gui/panels/errors.c b/src/gui/panels/errors.c index b2300eb..17eabef 100644 --- a/src/gui/panels/errors.c +++ b/src/gui/panels/errors.c @@ -42,6 +42,7 @@ #include "../../format/format.h" #include "../../glibext/signal.h" #include "../../gtkext/gtkdisplaypanel.h" +#include "../../gtkext/named.h" @@ -134,6 +135,9 @@ static void g_error_panel_dispose(GErrorPanel *); /* Procède à la libération totale de la mémoire. */ static void g_error_panel_finalize(GErrorPanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_error_panel_get_key(const GErrorPanel *); + /* Organise le tri des erreurs présentées. */ static gint sort_errors_in_panel(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer); @@ -208,7 +212,7 @@ G_DEFINE_TYPE_WITH_CODE(GErrorPanel, g_error_panel, G_TYPE_PANEL_ITEM, static void g_error_panel_class_init(GErrorPanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ gchar *filename; /* Chemin d'accès à utiliser */ GPanelItemClass *panel; /* Version parente de la classe*/ @@ -217,9 +221,11 @@ static void g_error_panel_class_init(GErrorPanelClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_error_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_error_panel_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_error_panel_get_key; - editem->change_content = (change_item_content_fc)change_error_panel_current_content; + item->change_content = (change_item_content_fc)change_error_panel_current_content; filename = find_pixmap_file("error_file.png"); assert(filename != NULL); @@ -261,7 +267,6 @@ static void g_error_panel_class_init(GErrorPanelClass *klass) static void g_error_panel_init(GErrorPanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeSortable *store; /* Gestionnaire des données */ @@ -272,14 +277,14 @@ static void g_error_panel_init(GErrorPanel *panel) /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_ERRORS_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Disassembling errors"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Errors"), + _("Disassembling errors"), + PANEL_ERRORS_ID)); + pitem->dock_at_startup = true; pitem->path = strdup("Ms"); @@ -289,7 +294,7 @@ static void g_error_panel_init(GErrorPanel *panel) /* Représentation graphique */ - builder = g_panel_item_build(pitem, "errors"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); store = GTK_TREE_SORTABLE(gtk_builder_get_object(builder, "store")); gtk_tree_sortable_set_sort_func(store, ETC_ADDR, sort_errors_in_panel, NULL, NULL); @@ -340,6 +345,8 @@ static void g_error_panel_init(GErrorPanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -432,6 +439,29 @@ GPanelItem *g_error_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_error_panel_get_key(const GErrorPanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_ERRORS_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : model = gestionnaire de données. * * a = premier élément à traiter. * * b = second élément à traiter. * @@ -499,12 +529,14 @@ static void change_error_panel_current_content(GErrorPanel *panel, GLoadedConten if (panel->binary != NULL) g_object_ref(G_OBJECT(panel->binary)); - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); gtk_list_store_clear(store); + g_object_unref(G_OBJECT(builder)); + /* Actualisation de l'affichage */ panel->count = 0; @@ -550,7 +582,7 @@ static void update_error_panel(const GErrorPanel *panel, GtkStatusStack *status, bool ret; /* Bilan d'une récupération */ #endif - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); @@ -772,6 +804,8 @@ static void update_error_panel(const GErrorPanel *panel, GtkStatusStack *status, } + g_object_unref(G_OBJECT(builder)); + } @@ -824,7 +858,7 @@ static void filter_error_panel(const GErrorPanel *panel, GtkStatusStack *status, guint errno; /* Code d'erreur associé */ gboolean state; /* Bilan d'un filtrage */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store")); @@ -890,6 +924,8 @@ static void filter_error_panel(const GErrorPanel *panel, GtkStatusStack *status, } + g_object_unref(G_OBJECT(builder)); + } @@ -911,7 +947,7 @@ static void update_error_panel_summary(const GErrorPanel *panel) GtkLabel *summary; /* Etiquette à mettre à jour */ char *msg; /* Bilan à faire afficher */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); summary = GTK_LABEL(gtk_builder_get_object(builder, "summary")); @@ -929,6 +965,8 @@ static void update_error_panel_summary(const GErrorPanel *panel) } + g_object_unref(G_OBJECT(builder)); + } @@ -1081,7 +1119,7 @@ static void g_error_panel_introduce(const GErrorPanel *panel, unsigned int uid, g_panel_item_switch_to_updating_mask(G_PANEL_ITEM(panel)); - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1093,6 +1131,8 @@ static void g_error_panel_introduce(const GErrorPanel *panel, unsigned int uid, gtk_tree_view_set_model(treeview, NULL); } + g_object_unref(G_OBJECT(builder)); + } @@ -1163,7 +1203,7 @@ static void g_error_panel_conclude(GErrorPanel *panel, unsigned int uid, error_u /* Basculement de l'affichage en ligne */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1184,6 +1224,8 @@ static void g_error_panel_conclude(GErrorPanel *panel, unsigned int uid, error_u g_object_ref(G_OBJECT(model)); gtk_tree_view_set_model(treeview, model); + g_object_unref(G_OBJECT(builder)); + skip_this_step: g_panel_item_switch_to_updated_content(G_PANEL_ITEM(panel)); diff --git a/src/gui/panels/errors.h b/src/gui/panels/errors.h index d5b19b5..1aabd08 100644 --- a/src/gui/panels/errors.h +++ b/src/gui/panels/errors.h @@ -33,7 +33,7 @@ -#define PANEL_ERRORS_ID _("Errors") +#define PANEL_ERRORS_ID "errors" #define G_TYPE_ERROR_PANEL g_error_panel_get_type() diff --git a/src/gui/panels/glance.c b/src/gui/panels/glance.c index fa99ceb..c7478b5 100644 --- a/src/gui/panels/glance.c +++ b/src/gui/panels/glance.c @@ -30,6 +30,7 @@ #include "../panel-int.h" +#include "../../gtkext/named.h" @@ -86,6 +87,9 @@ static void g_glance_panel_dispose(GGlancePanel *); /* Procède à la libération totale de la mémoire. */ static void g_glance_panel_finalize(GGlancePanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_glance_panel_get_key(const GGlancePanel *); + /* Lance une actualisation du fait d'un changement de support. */ static void change_glance_panel_current_view(GGlancePanel *, GLoadedPanel *, GLoadedPanel *); @@ -137,7 +141,7 @@ G_DEFINE_TYPE(GGlancePanel, g_glance_panel, G_TYPE_PANEL_ITEM); static void g_glance_panel_class_init(GGlancePanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ GtkIconTheme *theme; /* Thème GTK offrant des icones*/ object = G_OBJECT_CLASS(klass); @@ -145,10 +149,12 @@ static void g_glance_panel_class_init(GGlancePanelClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_glance_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_glance_panel_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_glance_panel_get_key; - editem->change_view = (change_item_view_fc)change_glance_panel_current_view; - editem->update_view = (update_item_view_fc)update_glance_panel_view; + item->change_view = (change_item_view_fc)change_glance_panel_current_view; + item->update_view = (update_item_view_fc)update_glance_panel_view; theme = gtk_icon_theme_get_default(); @@ -173,26 +179,25 @@ static void g_glance_panel_class_init(GGlancePanelClass *klass) static void g_glance_panel_init(GGlancePanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_GLANCE_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Glance"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Glance"), + _("Glimpse of the display content"), + PANEL_GLANCE_ID)); + pitem->dock_at_startup = true; pitem->path = strdup("MEs"); /* Représentation graphique */ - builder = g_panel_item_build(pitem, "glance"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); /* Connexion des signaux */ @@ -206,6 +211,8 @@ static void g_glance_panel_init(GGlancePanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -275,6 +282,29 @@ GPanelItem *g_glance_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_glance_panel_get_key(const GGlancePanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_GLANCE_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : panel = panneau à actualiser. * * old = ancienne vue du contenu chargé analysé. * * new = nouvelle vue du contenu chargé analysé. * @@ -411,6 +441,7 @@ static void on_view_scrolled(GtkAdjustment *adj, GGlancePanel *panel) { GtkAdjustment *hadj; /* Gestionnaire du défilement */ GtkAdjustment *vadj; /* Gestionnaire du défilement */ + GtkWidget *widget; /* Surface de dessin pour GTK */ hadj = gtk_scrolled_window_get_hadjustment(panel->support); vadj = gtk_scrolled_window_get_vadjustment(panel->support); @@ -423,7 +454,11 @@ static void on_view_scrolled(GtkAdjustment *adj, GGlancePanel *panel) panel->visible.width = gtk_adjustment_get_page_size(hadj) * panel->scale; panel->visible.height = gtk_adjustment_get_page_size(vadj) * panel->scale; - gtk_widget_queue_draw(G_EDITOR_ITEM(panel)->widget); + widget = g_named_widget_get_widget(G_PANEL_ITEM(panel)->widget); + + gtk_widget_queue_draw(widget); + + g_object_unref(G_OBJECT(widget)); } @@ -467,6 +502,7 @@ static void on_glance_resize(GtkWidget *widget, GdkRectangle *allocation, GGlanc static void compute_glance_scale(GGlancePanel *panel) { + GtkWidget *widget; /* Surface de dessin pour GTK */ GtkAllocation available; /* Surface disponible totale */ GtkAllocation granted; /* Surface totale accordée */ double sx; /* Echelle sur l'axe X */ @@ -474,7 +510,11 @@ static void compute_glance_scale(GGlancePanel *panel) /* Superficies niveau GTK... */ - gtk_widget_get_allocation(G_EDITOR_ITEM(panel)->widget, &available); + widget = g_named_widget_get_widget(G_PANEL_ITEM(panel)->widget); + + gtk_widget_get_allocation(widget, &available); + + g_object_unref(G_OBJECT(widget)); /* Calcul des ratios et emplacements */ @@ -544,6 +584,7 @@ static void update_glance_panel_view(GGlancePanel *panel, GLoadedPanel *view) { cairo_t *cairo; /* Assistant pour le dessin */ GtkAllocation area; /* Dimension de la surface */ + GtkWidget *widget; /* Surface de dessin pour GTK */ /* Mise en place d'un cache adapté */ @@ -567,7 +608,11 @@ static void update_glance_panel_view(GGlancePanel *panel, GLoadedPanel *view) cairo_destroy(cairo); - gtk_widget_queue_draw(G_EDITOR_ITEM(panel)->widget); + widget = g_named_widget_get_widget(G_PANEL_ITEM(panel)->widget); + + gtk_widget_queue_draw(widget); + + g_object_unref(G_OBJECT(widget)); } diff --git a/src/gui/panels/glance.h b/src/gui/panels/glance.h index 683b745..052d190 100644 --- a/src/gui/panels/glance.h +++ b/src/gui/panels/glance.h @@ -33,8 +33,7 @@ -#define PANEL_GLANCE_ID _("Glance") - +#define PANEL_GLANCE_ID "glance" #define G_TYPE_GLANCE_PANEL g_glance_panel_get_type() diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c index e0744c6..e1ac123 100644 --- a/src/gui/panels/history.c +++ b/src/gui/panels/history.c @@ -36,6 +36,7 @@ #include "../../analysis/binary.h" #include "../../glibext/chrysamarshal.h" #include "../../glibext/signal.h" +#include "../../gtkext/named.h" @@ -82,6 +83,9 @@ static void g_history_panel_dispose(GHistoryPanel *); /* Procède à la libération totale de la mémoire. */ static void g_history_panel_finalize(GHistoryPanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_history_panel_get_key(const GHistoryPanel *); + /* Réagit à un changement d'affichage principal de contenu. */ static void change_history_panel_current_content(GHistoryPanel *, GLoadedContent *, GLoadedContent *); @@ -124,16 +128,18 @@ G_DEFINE_TYPE(GHistoryPanel, g_history_panel, G_TYPE_PANEL_ITEM); static void g_history_panel_class_init(GHistoryPanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_history_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_history_panel_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_history_panel_get_key; - editem->change_content = (change_item_content_fc)change_history_panel_current_content; + item->change_content = (change_item_content_fc)change_history_panel_current_content; } @@ -152,27 +158,26 @@ static void g_history_panel_class_init(GHistoryPanelClass *klass) static void g_history_panel_init(GHistoryPanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ GtkListStore *store; /* Modèle de gestion */ /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_HISTORY_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Change history"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("History"), + _("Change history"), + PANEL_HISTORY_ID)); + pitem->dock_at_startup = true; pitem->path = strdup("MEN"); /* Représentation graphique */ - builder = g_panel_item_build(pitem, "history"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); @@ -189,6 +194,8 @@ static void g_history_panel_init(GHistoryPanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -257,6 +264,29 @@ GPanelItem *g_history_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_history_panel_get_key(const GHistoryPanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_HISTORY_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : panel = panneau à mettre à jour. * * old = ancien contenu chargé analysé. * * new = nouveau contenu chargé à analyser. * @@ -312,12 +342,14 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo if (panel->binary != NULL) g_object_ref(G_OBJECT(binary)); - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); gtk_list_store_clear(store); + g_object_unref(G_OBJECT(builder)); + /* Si le panneau actif ne représente pas un binaire... */ if (binary == NULL) return; @@ -393,7 +425,7 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem * char *label; /* Etiquette de représentation */ GtkTreeIter iter; /* Boucle de parcours */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -503,6 +535,8 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem * on_history_selection_change(selection, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -561,7 +595,7 @@ static void on_history_selection_change(GtkTreeSelection *selection, GHistoryPan GDbItem *item; /* Elément de collection */ GtkWidget *button; /* Bouton de barre de contrôle */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { @@ -587,6 +621,8 @@ static void on_history_selection_change(GtkTreeSelection *selection, GHistoryPan } + g_object_unref(G_OBJECT(builder)); + } @@ -613,7 +649,7 @@ static void do_history_undo(GtkButton *button, GHistoryPanel *panel) GDbItem *item; /* Elément de collection */ GHubClient *client; /* Connexion vers la base */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -621,19 +657,22 @@ static void do_history_undo(GtkButton *button, GHistoryPanel *panel) if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - if (!gtk_tree_model_iter_previous(model, &iter)) - return; + if (gtk_tree_model_iter_previous(model, &iter)) + { + gtk_tree_model_get(model, &iter, HTC_ITEM, &item, -1); - gtk_tree_model_get(model, &iter, HTC_ITEM, &item, -1); + client = g_loaded_binary_get_client(panel->binary, true); + g_hub_client_set_last_active(client, g_db_item_get_timestamp(item)); + g_object_unref(G_OBJECT(client)); - client = g_loaded_binary_get_client(panel->binary, true); - g_hub_client_set_last_active(client, g_db_item_get_timestamp(item)); - g_object_unref(G_OBJECT(client)); + g_object_unref(G_OBJECT(item)); - g_object_unref(G_OBJECT(item)); + } } + g_object_unref(G_OBJECT(builder)); + } @@ -660,7 +699,7 @@ static void do_history_redo(GtkButton *button, GHistoryPanel *panel) GDbItem *item; /* Elément de collection */ GHubClient *client; /* Connexion vers la base */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -678,6 +717,8 @@ static void do_history_redo(GtkButton *button, GHistoryPanel *panel) } + g_object_unref(G_OBJECT(builder)); + } diff --git a/src/gui/panels/history.h b/src/gui/panels/history.h index 87268eb..430d47d 100644 --- a/src/gui/panels/history.h +++ b/src/gui/panels/history.h @@ -33,7 +33,7 @@ -#define PANEL_HISTORY_ID _("History") +#define PANEL_HISTORY_ID "history" #define G_TYPE_HISTORY_PANEL g_history_panel_get_type() diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c index cf79f70..43021cf 100644 --- a/src/gui/panels/log.c +++ b/src/gui/panels/log.c @@ -35,6 +35,7 @@ #include "../panel-int.h" #include "../core/panels.h" #include "../../gtkext/easygtk.h" +#include "../../gtkext/named.h" @@ -87,6 +88,9 @@ static void g_log_panel_dispose(GLogPanel *); /* Procède à la libération totale de la mémoire. */ static void g_log_panel_finalize(GLogPanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_log_panel_get_key(const GLogPanel *); + /* Affiche un message dans le journal des messages système. */ static gboolean log_message(log_data *); @@ -111,6 +115,7 @@ G_DEFINE_TYPE(GLogPanel, g_log_panel, G_TYPE_PANEL_ITEM); static void g_log_panel_class_init(GLogPanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GEditorItemClass *item; /* Encore une autre vision... */ GPanelItemClass *panel; /* Version parente de la classe*/ object = G_OBJECT_CLASS(klass); @@ -118,6 +123,10 @@ static void g_log_panel_class_init(GLogPanelClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_log_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_log_panel_finalize; + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_log_panel_get_key; + panel = G_PANEL_ITEM_CLASS(klass); panel->unique = true; @@ -140,25 +149,20 @@ static void g_log_panel_class_init(GLogPanelClass *klass) static void g_log_panel_init(GLogPanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_LOG_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Misc information"); - pitem->dock_at_startup = true; - pitem->path = strdup("Ms"); - /* Représentation graphique */ + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Messages"), + _("Misc information"), + PANEL_LOG_ID)); - g_panel_item_build(pitem, "log"); + pitem->dock_at_startup = true; + pitem->path = strdup("Ms"); } @@ -226,6 +230,29 @@ GPanelItem *g_log_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_log_panel_get_key(const GLogPanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_LOG_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : panel = instance d'objet GLib à traiter. * * type = espèce du message à ajouter. * * msg = message à faire apparaître à l'écran. * @@ -275,7 +302,7 @@ static gboolean log_message(log_data *data) GtkTreeIter iter; /* Point d'insertion */ GtkTreeView *treeview; /* Affichage de la liste */ - builder = G_PANEL_ITEM(data->item)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(data->item)->widget)); /* Mise en place du message */ @@ -335,6 +362,8 @@ static gboolean log_message(log_data *data) scroll_to_treeview_iter(treeview, GTK_TREE_MODEL(store), &iter); + g_object_unref(G_OBJECT(builder)); + /* Nettoyage de la mémoire */ g_object_unref(G_OBJECT(data->item)); diff --git a/src/gui/panels/log.h b/src/gui/panels/log.h index 1106aae..4d155a2 100644 --- a/src/gui/panels/log.h +++ b/src/gui/panels/log.h @@ -34,7 +34,7 @@ -#define PANEL_LOG_ID _("Messages") +#define PANEL_LOG_ID "log" #define G_TYPE_LOG_PANEL g_log_panel_get_type() diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c index 23543b5..ea324cb 100644 --- a/src/gui/panels/regedit.c +++ b/src/gui/panels/regedit.c @@ -41,6 +41,7 @@ #include "../../common/cpp.h" #include "../../common/extstr.h" #include "../../gtkext/easygtk.h" +#include "../../gtkext/named.h" @@ -96,6 +97,9 @@ static void g_regedit_panel_dispose(GRegeditPanel *); /* Procède à la libération totale de la mémoire. */ static void g_regedit_panel_finalize(GRegeditPanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_regedit_panel_get_key(const GRegeditPanel *); + /* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */ @@ -179,12 +183,16 @@ G_DEFINE_TYPE(GRegeditPanel, g_regedit_panel, G_TYPE_PANEL_ITEM); static void g_regedit_panel_class_init(GRegeditPanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GEditorItemClass *item; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_regedit_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_regedit_panel_finalize; + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_regedit_panel_get_key; } @@ -203,7 +211,6 @@ static void g_regedit_panel_class_init(GRegeditPanelClass *klass) static void g_regedit_panel_init(GRegeditPanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ GObject *vrenderer; /* Moteur de rendu de colonne */ @@ -211,20 +218,20 @@ static void g_regedit_panel_init(GRegeditPanel *panel) /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_REGEDIT_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Configuration parameters"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Configuration"), + _("Configuration parameters"), + PANEL_REGEDIT_ID)); + pitem->dock_at_startup = false; pitem->path = strdup("M"); /* Représentation graphique */ - builder = g_panel_item_build(pitem, "regedit"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); vrenderer = G_OBJECT(gtk_builder_get_object(builder, "vrenderer")); @@ -264,6 +271,8 @@ static void g_regedit_panel_init(GRegeditPanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -336,6 +345,29 @@ GPanelItem *g_regedit_panel_new(void) } +/****************************************************************************** +* * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_regedit_panel_get_key(const GRegeditPanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_REGEDIT_ID); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* AFFICHAGE A L'AIDE D'UNE LISTE */ @@ -365,7 +397,7 @@ static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config char *type_desc; /* Type de paramètre */ GtkTreeIter iter; /* Point d'insertion */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); @@ -425,6 +457,8 @@ static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config g_generic_config_runlock(config); + g_object_unref(G_OBJECT(builder)); + } @@ -450,7 +484,7 @@ static void on_config_param_modified(GCfgParam *param, GRegeditPanel *panel) gboolean looping; /* Autorisation de bouclage */ GCfgParam *item; /* Elément de la liste */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -470,6 +504,8 @@ static void on_config_param_modified(GCfgParam *param, GRegeditPanel *panel) } + g_object_unref(G_OBJECT(builder)); + } @@ -685,12 +721,12 @@ static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gc int ulong; /* Valeur entière positive */ char *end; /* Pointeur vers '\0' final ? */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); tree_path = gtk_tree_path_new_from_string(path); - if (tree_path == NULL) return; + if (tree_path == NULL) goto bad_path; if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, tree_path)) goto opve_bad_iter; @@ -749,6 +785,10 @@ static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gc gtk_tree_path_free(tree_path); + bad_path: + + g_object_unref(G_OBJECT(builder)); + } @@ -965,23 +1005,28 @@ static void mcb_param_panel_copy(GtkMenuItem *menuitem, GRegeditPanel *panel) gint clen; /* Taille de ce contenu */ GtkClipboard *clipboard; /* Presse-papiers à remplir */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); param = get_selected_panel_param(treeview, NULL); - if (param == NULL) return; - content = g_config_param_get_path(param); - clen = g_utf8_strlen(content, -1); + if (param == NULL) + { + content = g_config_param_get_path(param); + clen = g_utf8_strlen(content, -1); - clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_text(clipboard, content, clen); + clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, content, clen); - clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text(clipboard, content, clen); + clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + gtk_clipboard_set_text(clipboard, content, clen); - g_object_unref(G_OBJECT(param)); + g_object_unref(G_OBJECT(param)); + + } + + g_object_unref(G_OBJECT(builder)); } @@ -1005,16 +1050,21 @@ static void mcb_param_panel_empty(GtkMenuItem *menuitem, GRegeditPanel *panel) GtkTreeView *treeview; /* Affichage de la liste */ GCfgParam *param; /* Paramètre sélectionné */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); param = get_selected_panel_param(treeview, NULL); - if (param == NULL) return; - g_config_param_make_empty(param); + if (param == NULL) + { + g_config_param_make_empty(param); - g_object_unref(G_OBJECT(param)); + g_object_unref(G_OBJECT(param)); + + } + + g_object_unref(G_OBJECT(builder)); } @@ -1038,15 +1088,20 @@ static void mcb_param_panel_reset(GtkMenuItem *menuitem, GRegeditPanel *panel) GtkTreeView *treeview; /* Affichage de la liste */ GCfgParam *param; /* Paramètre sélectionné */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); param = get_selected_panel_param(treeview, NULL); - if (param == NULL) return; - g_config_param_reset(param); + if (param == NULL) + { + g_config_param_reset(param); - g_object_unref(G_OBJECT(param)); + g_object_unref(G_OBJECT(param)); + + } + + g_object_unref(G_OBJECT(builder)); } diff --git a/src/gui/panels/regedit.h b/src/gui/panels/regedit.h index 7a87c7c..b562cc7 100644 --- a/src/gui/panels/regedit.h +++ b/src/gui/panels/regedit.h @@ -33,7 +33,7 @@ -#define PANEL_REGEDIT_ID _("Configuration") +#define PANEL_REGEDIT_ID "regedit" #define G_TYPE_REGEDIT_PANEL g_regedit_panel_get_type() diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c index 2eee482..aee5231 100644 --- a/src/gui/panels/strings.c +++ b/src/gui/panels/strings.c @@ -45,6 +45,7 @@ #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkdisplaypanel.h" #include "../../gtkext/gtkdockable-int.h" +#include "../../gtkext/named.h" #include "../../gtkext/tmgt.h" @@ -111,6 +112,9 @@ static void g_strings_panel_dispose(GStringsPanel *); /* Procède à la libération totale de la mémoire. */ static void g_strings_panel_finalize(GStringsPanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_strings_panel_get_key(const GStringsPanel *); + /* Réagit au changement de sélection des chaînes textuelles. */ static void on_strings_selection_change(GtkTreeSelection *, gpointer); @@ -242,7 +246,7 @@ G_DEFINE_TYPE_WITH_CODE(GStringsPanel, g_strings_panel, G_TYPE_PANEL_ITEM, static void g_strings_panel_class_init(GStringsPanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ GPanelItemClass *panel; /* Version parente de la classe*/ object = G_OBJECT_CLASS(klass); @@ -250,9 +254,11 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_strings_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_strings_panel_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_strings_panel_get_key; - editem->change_content = (change_item_content_fc)change_strings_panel_current_content; + item->change_content = (change_item_content_fc)change_strings_panel_current_content; panel = G_PANEL_ITEM_CLASS(klass); @@ -282,7 +288,6 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass) static void g_strings_panel_init(GStringsPanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeModelFilter *filter; /* Filtre pour l'arborescence */ @@ -294,20 +299,20 @@ static void g_strings_panel_init(GStringsPanel *panel) /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_STRINGS_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Strings"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Strings"), + _("Strings contained in the binary"), + PANEL_STRINGS_ID)); + pitem->dock_at_startup = false; pitem->path = strdup("Ms"); /* Représentation graphique */ - builder = g_panel_item_build(pitem, "strings"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); filter = GTK_TREE_MODEL_FILTER(gtk_builder_get_object(builder, "filter")); gtk_tree_model_filter_set_visible_column(filter, STC_MATCHED); @@ -387,6 +392,8 @@ static void g_strings_panel_init(GStringsPanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + /* Préparation du menu contextuel */ panel->menu = build_strings_panel_menu(panel); @@ -484,6 +491,29 @@ GPanelItem *g_strings_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_strings_panel_get_key(const GStringsPanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_STRINGS_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : selection = sélection modifiée. * * unused = adresse non utilisée ici. * * * @@ -681,12 +711,14 @@ static void change_strings_panel_current_content(GStringsPanel *panel, GLoadedCo /* Réinitialisation */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); gtk_list_store_clear(store); + g_object_unref(G_OBJECT(builder)); + /* Si le panneau actif représente un binaire, actualisation de l'affichage */ if (binary != NULL) @@ -750,7 +782,7 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat char *real_text; /* Texte avec octet nul final */ GtkTreeIter iter; /* Point d'insertion */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); @@ -821,6 +853,8 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat g_object_unref(G_OBJECT(portions)); g_object_unref(G_OBJECT(format)); + g_object_unref(G_OBJECT(builder)); + } @@ -1002,12 +1036,14 @@ static void do_filtering_on_strings(const GStringsPanel *panel, GtkStatusStack * } - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); gtk_tree_model_foreach(GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)filter_string_panel_iter, NULL); + g_object_unref(G_OBJECT(builder)); + } @@ -1146,7 +1182,7 @@ static GBinSymbol *get_selected_panel_symbol(GStringsPanel *panel, GtkTreeIter * result = NULL; - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1158,6 +1194,8 @@ static GBinSymbol *get_selected_panel_symbol(GStringsPanel *panel, GtkTreeIter * if (save != NULL) *save = iter; + g_object_unref(G_OBJECT(builder)); + return result; } @@ -1188,7 +1226,7 @@ static void mcb_strings_panel_edit(GtkMenuItem *menuitem, GStringsPanel *panel) symbol = get_selected_panel_symbol(panel, &iter); if (symbol == NULL) return; - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1201,6 +1239,8 @@ static void mcb_strings_panel_edit(GtkMenuItem *menuitem, GStringsPanel *panel) gtk_tree_path_free(path); + g_object_unref(G_OBJECT(builder)); + g_object_unref(G_OBJECT(symbol)); } @@ -1229,7 +1269,7 @@ static void mcb_strings_panel_copy(GtkMenuItem *menuitem, GStringsPanel *panel) gchar *string; /* Chaîne sélectionnée */ GtkClipboard *clipboard; /* Presse-papiers d'arrivée */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1251,6 +1291,8 @@ static void mcb_strings_panel_copy(GtkMenuItem *menuitem, GStringsPanel *panel) } + g_object_unref(G_OBJECT(builder)); + } @@ -1535,7 +1577,7 @@ static void g_strings_panel_introduce(const GStringsPanel *panel, unsigned int u g_panel_item_switch_to_updating_mask(G_PANEL_ITEM(panel)); - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1547,6 +1589,8 @@ static void g_strings_panel_introduce(const GStringsPanel *panel, unsigned int u gtk_tree_view_set_model(treeview, NULL); } + g_object_unref(G_OBJECT(builder)); + } @@ -1612,7 +1656,7 @@ static void g_strings_panel_conclude(GStringsPanel *panel, unsigned int uid, str /* Basculement de l'affichage en ligne */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1621,6 +1665,8 @@ static void g_strings_panel_conclude(GStringsPanel *panel, unsigned int uid, str g_object_ref(G_OBJECT(model)); gtk_tree_view_set_model(treeview, model); + g_object_unref(G_OBJECT(builder)); + skip_this_step: g_panel_item_switch_to_updated_content(G_PANEL_ITEM(panel)); diff --git a/src/gui/panels/strings.h b/src/gui/panels/strings.h index b856dc2..3dec55e 100644 --- a/src/gui/panels/strings.h +++ b/src/gui/panels/strings.h @@ -33,7 +33,7 @@ -#define PANEL_STRINGS_ID _("Strings") +#define PANEL_STRINGS_ID "strings" #define G_TYPE_STRINGS_PANEL g_strings_panel_get_type() diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index 2cb2b34..ec85479 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -47,6 +47,7 @@ #include "../../format/symiter.h" #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkdisplaypanel.h" +#include "../../gtkext/named.h" #include "../../gtkext/tmgt.h" #include "../../mangling/demangler.h" @@ -119,6 +120,9 @@ static void g_symbols_panel_dispose(GSymbolsPanel *); /* Procède à la libération totale de la mémoire. */ static void g_symbols_panel_finalize(GSymbolsPanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_symbols_panel_get_key(const GSymbolsPanel *); + /* Bascule d'affichage des symboles en liste. */ static void on_symbols_list_display_toggle(GtkToggleToolButton *, GSymbolsPanel *); @@ -249,7 +253,7 @@ G_DEFINE_TYPE_WITH_CODE(GSymbolsPanel, g_symbols_panel, G_TYPE_PANEL_ITEM, static void g_symbols_panel_class_init(GSymbolsPanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ GPanelItemClass *panel; /* Version parente de la classe*/ gchar *filename; /* Chemin d'accès à utiliser */ @@ -258,9 +262,11 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_symbols_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_symbols_panel_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_symbols_panel_get_key; - editem->change_content = (change_item_content_fc)change_symbols_panel_current_content; + item->change_content = (change_item_content_fc)change_symbols_panel_current_content; panel = G_PANEL_ITEM_CLASS(klass); @@ -314,7 +320,6 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass) static void g_symbols_panel_init(GSymbolsPanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeModelFilter *filter; /* Filtre pour l'arborescence */ @@ -324,20 +329,20 @@ static void g_symbols_panel_init(GSymbolsPanel *panel) /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_SYMBOLS_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Binary symbols"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Symbols"), + _("Binary symbols"), + PANEL_SYMBOLS_ID)); + pitem->dock_at_startup = true; pitem->path = strdup("MEN"); /* Représentation graphique */ - builder = g_panel_item_build(pitem, "symbols"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); filter = GTK_TREE_MODEL_FILTER(gtk_builder_get_object(builder, "filter")); gtk_tree_model_filter_set_visible_column(filter, SBC_MATCHED); @@ -387,6 +392,8 @@ static void g_symbols_panel_init(GSymbolsPanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -480,6 +487,29 @@ GPanelItem *g_symbols_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_symbols_panel_get_key(const GSymbolsPanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_SYMBOLS_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : button = bouton de la barre activé. * * panel = structure contenant les informations maîtresses. * * * @@ -501,7 +531,7 @@ static void on_symbols_list_display_toggle(GtkToggleToolButton *button, GSymbols { /* Accès aux boutons complémentaires */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); other = GTK_WIDGET(gtk_builder_get_object(builder, "collapse")); gtk_widget_set_sensitive(other, FALSE); @@ -512,6 +542,8 @@ static void on_symbols_list_display_toggle(GtkToggleToolButton *button, GSymbols other = GTK_WIDGET(gtk_builder_get_object(builder, "classes")); gtk_widget_set_sensitive(other, FALSE); + g_object_unref(G_OBJECT(builder)); + /* Actualisation de l'affichage */ if (panel->binary != NULL) @@ -552,7 +584,7 @@ static void on_symbols_tree_display_toggle(GtkToggleToolButton *button, GSymbols { /* Accès aux boutons complémentaires */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); other = GTK_WIDGET(gtk_builder_get_object(builder, "collapse")); gtk_widget_set_sensitive(other, TRUE); @@ -563,6 +595,8 @@ static void on_symbols_tree_display_toggle(GtkToggleToolButton *button, GSymbols other = GTK_WIDGET(gtk_builder_get_object(builder, "classes")); gtk_widget_set_sensitive(other, TRUE); + g_object_unref(G_OBJECT(builder)); + /* Actualisation de l'affichage */ if (panel->binary != NULL) @@ -671,7 +705,7 @@ static void change_symbols_panel_current_content(GSymbolsPanel *panel, GLoadedCo /* Réinitialisation */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); @@ -721,6 +755,8 @@ static void change_symbols_panel_current_content(GSymbolsPanel *panel, GLoadedCo } + g_object_unref(G_OBJECT(builder)); + } @@ -744,7 +780,7 @@ static void reload_symbols_panel_content(const GSymbolsPanel *panel, GtkStatusSt GtkBuilder *builder; /* Constructeur utilisé */ GtkToggleToolButton *button; /* Mode de représentation */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); button = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(builder, "list_display")); @@ -754,6 +790,8 @@ static void reload_symbols_panel_content(const GSymbolsPanel *panel, GtkStatusSt else reload_symbols_for_new_tree_view(panel, status, id, data); + g_object_unref(G_OBJECT(builder)); + } @@ -796,7 +834,7 @@ static void reload_symbols_for_new_list_view(const GSymbolsPanel *panel, GtkStat VMPA_BUFFER(virt); /* Version humainement lisible */ GtkTreeIter iter; /* Point d'insertion */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); @@ -878,6 +916,8 @@ static void reload_symbols_for_new_list_view(const GSymbolsPanel *panel, GtkStat g_object_unref(G_OBJECT(format)); + g_object_unref(G_OBJECT(builder)); + } @@ -947,7 +987,7 @@ static GtkTreeIter ensure_symbol_node_exist(const GSymbolsPanel *panel, GtkTreeI gchar *string; /* Chaîne sélectionnée */ char *name; /* Etiquette mise en relief */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); @@ -984,6 +1024,8 @@ static GtkTreeIter ensure_symbol_node_exist(const GSymbolsPanel *panel, GtkTreeI } + g_object_unref(G_OBJECT(builder)); + return iter; } @@ -1077,7 +1119,7 @@ static void reload_symbols_for_new_tree_view(const GSymbolsPanel *panel, GtkStat char virt[VMPA_MAX_LEN]; /* Version humainement lisible */ GtkTreeIter iter; /* Point d'insertion */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); @@ -1195,7 +1237,7 @@ static void reorganize_symbols_tree_view(GtkToolButton *button, const GSymbolsPa GtkToolButton *ref_expand; /* Bouton de référence #2 */ GtkTreeStore *store; /* Modèle de gestion */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1218,6 +1260,8 @@ static void reorganize_symbols_tree_view(GtkToolButton *button, const GSymbolsPa } + g_object_unref(G_OBJECT(builder)); + } @@ -1451,7 +1495,7 @@ static void do_filtering_on_symbols(const GSymbolsPanel *panel, GtkStatusStack * } - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store")); button = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(builder, "list_display")); @@ -1460,6 +1504,8 @@ static void do_filtering_on_symbols(const GSymbolsPanel *panel, GtkStatusStack * gtk_tree_model_foreach(GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)filter_symbol_panel_iter, &as_list); + g_object_unref(G_OBJECT(builder)); + } @@ -1594,7 +1640,7 @@ static const char *g_symbols_panel_setup(const GSymbolsPanel *panel, unsigned in /* Mémorisation de tous les noeuds ouverts */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1618,6 +1664,8 @@ static const char *g_symbols_panel_setup(const GSymbolsPanel *panel, unsigned in gtk_tree_view_map_expanded_rows(treeview, (GtkTreeViewMappingFunc)keep_track_of_expanded, *data); + g_object_unref(G_OBJECT(builder)); + return result; } @@ -1647,7 +1695,7 @@ static void g_symbols_panel_introduce(const GSymbolsPanel *panel, unsigned int u g_panel_item_switch_to_updating_mask(G_PANEL_ITEM(panel)); - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1659,6 +1707,8 @@ static void g_symbols_panel_introduce(const GSymbolsPanel *panel, unsigned int u gtk_tree_view_set_model(treeview, NULL); } + g_object_unref(G_OBJECT(builder)); + } @@ -1727,7 +1777,7 @@ static void g_symbols_panel_conclude(GSymbolsPanel *panel, unsigned int uid, sym /* Basculement de l'affichage en ligne */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); @@ -1753,6 +1803,8 @@ static void g_symbols_panel_conclude(GSymbolsPanel *panel, unsigned int uid, sym if (!gtk_toggle_tool_button_get_active(button)) reorganize_symbols_tree_view(NULL, panel); + g_object_unref(G_OBJECT(builder)); + skip_this_step: g_panel_item_switch_to_updated_content(G_PANEL_ITEM(panel)); diff --git a/src/gui/panels/symbols.h b/src/gui/panels/symbols.h index 6b782dc..f589d7f 100644 --- a/src/gui/panels/symbols.h +++ b/src/gui/panels/symbols.h @@ -33,7 +33,7 @@ -#define PANEL_SYMBOLS_ID _("Symbols") +#define PANEL_SYMBOLS_ID "symbols" #define G_TYPE_SYMBOLS_PANEL g_symbols_panel_get_type() diff --git a/src/gui/panels/welcome.c b/src/gui/panels/welcome.c index 2693b9a..02649e1 100644 --- a/src/gui/panels/welcome.c +++ b/src/gui/panels/welcome.c @@ -45,6 +45,7 @@ #include "../../core/global.h" #include "../../core/params.h" #include "../../core/paths.h" +#include "../../gtkext/named.h" @@ -94,6 +95,9 @@ static void g_welcome_panel_dispose(GWelcomePanel *); /* Procède à la libération totale de la mémoire. */ static void g_welcome_panel_finalize(GWelcomePanel *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_welcome_panel_get_key(const GWelcomePanel *); + /* Place un panneau dans l'ensemble affiché. */ static void g_welcome_panel_dock(GWelcomePanel *); @@ -150,6 +154,7 @@ G_DEFINE_TYPE(GWelcomePanel, g_welcome_panel, G_TYPE_PANEL_ITEM); static void g_welcome_panel_class_init(GWelcomePanelClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GEditorItemClass *item; /* Encore une autre vision... */ GPanelItemClass *parent; /* Version parente de classe */ object = G_OBJECT_CLASS(klass); @@ -157,6 +162,10 @@ static void g_welcome_panel_class_init(GWelcomePanelClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_welcome_panel_dispose; object->finalize = (GObjectFinalizeFunc)g_welcome_panel_finalize; + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_welcome_panel_get_key; + parent = G_PANEL_ITEM_CLASS(klass); parent->ack_dock = (ack_undock_process_fc)g_welcome_panel_dock; @@ -178,7 +187,6 @@ static void g_welcome_panel_class_init(GWelcomePanelClass *klass) static void g_welcome_panel_init(GWelcomePanel *panel) { - GEditorItem *base; /* Version basique d'instance */ GPanelItem *pitem; /* Version parente du panneau */ GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeView *treeview; /* Affichage de la liste */ @@ -190,14 +198,14 @@ static void g_welcome_panel_init(GWelcomePanel *panel) /* Eléments de base */ - base = G_EDITOR_ITEM(panel); - - base->name = PANEL_WELCOME_ID; - pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; - pitem->lname = _("Welcome"); + + pitem->widget = G_NAMED_WIDGET(gtk_built_named_widget_new_for_panel(_("Welcome"), + _("Welcome panel"), + PANEL_WELCOME_ID)); + pitem->dock_at_startup = false; pitem->path = strdup("M"); @@ -205,7 +213,7 @@ static void g_welcome_panel_init(GWelcomePanel *panel) /* Représentation graphique */ - builder = g_panel_item_build(pitem, "welcome"); + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget)); /* Liste des projets récents */ @@ -248,6 +256,8 @@ static void g_welcome_panel_init(GWelcomePanel *panel) gtk_builder_connect_signals(builder, panel); + g_object_unref(G_OBJECT(builder)); + } @@ -329,6 +339,29 @@ GPanelItem *g_welcome_panel_new(void) /****************************************************************************** * * +* Paramètres : panel = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_welcome_panel_get_key(const GWelcomePanel *panel) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PANEL_WELCOME_ID); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : panel = composant à présenter à l'affichage. * * * * Description : Place un panneau dans l'ensemble affiché. * @@ -519,7 +552,7 @@ static void g_welcome_panel_reload_project_list(GWelcomePanel *panel, GtkRecentM /* Réinitialisation */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); @@ -570,6 +603,8 @@ static void g_welcome_panel_reload_project_list(GWelcomePanel *panel, GtkRecentM } + g_object_unref(G_OBJECT(builder)); + } @@ -711,7 +746,7 @@ static void g_welcome_panel_check_version(GWelcomePanel *panel) /* Affichage */ - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); label = GTK_LABEL(gtk_builder_get_object(builder, "version")); @@ -753,6 +788,8 @@ static void g_welcome_panel_check_version(GWelcomePanel *panel) free(msg); + g_object_unref(G_OBJECT(builder)); + } @@ -825,12 +862,14 @@ static void g_welcome_panel_refresh_tip(GWelcomePanel *panel) assert(panel->current < panel->count); - builder = G_PANEL_ITEM(panel)->builder; + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(G_PANEL_ITEM(panel)->widget)); label = GTK_LABEL(gtk_builder_get_object(builder, "tip")); gtk_label_set_markup(label, panel->tips[panel->current]); + g_object_unref(G_OBJECT(builder)); + } diff --git a/src/gui/panels/welcome.h b/src/gui/panels/welcome.h index 1a227ca..5cdd6a1 100644 --- a/src/gui/panels/welcome.h +++ b/src/gui/panels/welcome.h @@ -33,7 +33,7 @@ -#define PANEL_WELCOME_ID _("Welcome") +#define PANEL_WELCOME_ID "welcome" #define G_TYPE_WELCOME_PANEL g_welcome_panel_get_type() diff --git a/src/gui/status.c b/src/gui/status.c index 15a296f..79f47ea 100644 --- a/src/gui/status.c +++ b/src/gui/status.c @@ -33,7 +33,7 @@ #include -#include "editem-int.h" +#include "item-int.h" #include "core/global.h" #include "../common/extstr.h" #include "../gtkext/gtkbufferdisplay.h" @@ -46,6 +46,8 @@ struct _GStatusInfo { GEditorItem parent; /* A laisser en premier */ + GtkStatusStack *stack; /* Composant GTK associé */ + }; @@ -69,6 +71,12 @@ static void g_status_info_dispose(GStatusInfo *); /* Procède à la libération totale de la mémoire. */ static void g_status_info_finalize(GStatusInfo *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_status_info_get_key(const GStatusInfo *); + +/* Fournit le composant GTK associé à l'élément réactif. */ +static GtkWidget *g_status_info_get_widget(const GStatusInfo *); + /* Imprime la position du parcours courant dans le statut. */ static void track_cursor_for_status_info(GStatusInfo *, GLoadedPanel *, const GLineCursor *); @@ -96,24 +104,27 @@ G_DEFINE_TYPE(GStatusInfo, g_status_info, G_TYPE_EDITOR_ITEM); static void g_status_info_class_init(GStatusInfoClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *editem; /* Encore une autre vision... */ + GEditorItemClass *item; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_status_info_dispose; object->finalize = (GObjectFinalizeFunc)g_status_info_finalize; - editem = G_EDITOR_ITEM_CLASS(klass); + item = G_EDITOR_ITEM_CLASS(klass); - editem->track_cursor = (track_cursor_in_view_fc)track_cursor_for_status_info; - editem->focus_cursor = (focus_cursor_fc)focus_cursor_in_status_info; + item->get_key = (get_item_key_fc)g_status_info_get_key; + item->get_widget = (get_item_widget_fc)g_status_info_get_widget; + + item->track_cursor = (track_cursor_in_view_fc)track_cursor_for_status_info; + item->focus_cursor = (focus_cursor_fc)focus_cursor_in_status_info; } /****************************************************************************** * * -* Paramètres : bar = instance à initialiser. * +* Paramètres : info = instance à initialiser. * * * * Description : Initialise une instance de la barre de statut pour l'éditeur.* * * @@ -123,16 +134,10 @@ static void g_status_info_class_init(GStatusInfoClass *klass) * * ******************************************************************************/ -static void g_status_info_init(GStatusInfo *bar) +static void g_status_info_init(GStatusInfo *info) { - GEditorItem *item; /* Autre version de l'élément */ - - item = G_EDITOR_ITEM(bar); - - item->name = "status"; - - item->widget = gtk_status_stack_new(); - gtk_widget_show(item->widget); + info->stack = gtk_status_stack_new(); + gtk_widget_show(GTK_WIDGET(info->stack)); } @@ -151,6 +156,8 @@ static void g_status_info_init(GStatusInfo *bar) static void g_status_info_dispose(GStatusInfo *info) { + g_clear_object(&info->stack); + G_OBJECT_CLASS(g_status_info_parent_class)->dispose(G_OBJECT(info)); } @@ -190,13 +197,10 @@ static void g_status_info_finalize(GStatusInfo *info) GEditorItem *g_status_info_new(void) { GStatusInfo *result; /* Structure à retourner */ - GEditorItem *item; /* Autre version de l'élément */ result = g_object_new(G_TYPE_STATUS_INFO, NULL); - item = G_EDITOR_ITEM(result); - - set_global_status(GTK_STATUS_STACK(item->widget)); + set_global_status(result->stack); return G_EDITOR_ITEM(result); @@ -205,6 +209,54 @@ GEditorItem *g_status_info_new(void) /****************************************************************************** * * +* Paramètres : info = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_status_info_get_key(const GStatusInfo *info) +{ + char *result; /* Description à renvoyer */ + + result = strdup(STATUS_INFO_ID); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : info = instance à consulter. * +* * +* Description : Fournit le composant GTK associé à l'élément réactif. * +* * +* Retour : Instance de composant graphique chargé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *g_status_info_get_widget(const GStatusInfo *info) +{ + GtkWidget *result; /* Composant à retourner */ + + result = GTK_WIDGET(info->stack); + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : info = barre de statut présentant les informations. * * panel = composant d'affichage parcouru. * * cursor = nouvel emplacement du curseur courant. * @@ -246,10 +298,6 @@ static void track_cursor_for_status_info(GStatusInfo *info, GLoadedPanel *panel, static void focus_cursor_in_status_info(GStatusInfo *info, GLoadedContent *content, const GLineCursor *cursor) { - GEditorItem *item; /* Autre version de l'élément */ - - item = G_EDITOR_ITEM(info); - - g_line_cursor_show_status(cursor, GTK_STATUS_STACK(item->widget), content); + g_line_cursor_show_status(cursor, info->stack, content); } diff --git a/src/gui/status.h b/src/gui/status.h index 6939c76..439c754 100644 --- a/src/gui/status.h +++ b/src/gui/status.h @@ -26,10 +26,13 @@ #define _GUI_STATUS_H -#include "editem.h" +#include "item.h" +#define STATUS_INFO_ID "status" + + #define G_TYPE_STATUS_INFO g_status_info_get_type() #define G_STATUS_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_status_info_get_type(), GStatusInfo)) #define G_IS_STATUS_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_status_info_get_type())) diff --git a/src/gui/tb/portions.c b/src/gui/tb/portions.c index 1823bda..f8b2b92 100644 --- a/src/gui/tb/portions.c +++ b/src/gui/tb/portions.c @@ -43,6 +43,8 @@ struct _GPortionsTbItem { GToolbarItem parent; /* A laisser en premier */ + GtkWidget *support; /* Composant GTK de support */ + }; @@ -67,8 +69,14 @@ static void g_portions_tbitem_dispose(GPortionsTbItem *); /* Procède à la libération totale de la mémoire. */ static void g_portions_tbitem_finalize(GPortionsTbItem *); +/* Fournit le nom interne attribué à l'élément réactif. */ +static char *g_portions_tbitem_get_key(const GPortionsTbItem *); + +/* Fournit le composant GTK associé à l'élément réactif. */ +static GtkWidget *g_portions_tbitem_get_widget(const GPortionsTbItem *); + /* Réagit à un changement du binaire courant. */ -static void change_portions_tbitem_current_content(GEditorItem *, GLoadedContent *, GLoadedContent *); +static void change_portions_tbitem_current_content(GPortionsTbItem *, GLoadedContent *, GLoadedContent *); /* Fait suivre un changement d'adresse dans la barre. */ static void track_address_on_binary_strip(GtkBinaryStrip *, GEditorItem *); @@ -97,12 +105,16 @@ static void g_portions_tbitem_class_init(GPortionsTbItemClass *klass) GEditorItemClass *item; /* Encore une autre vision */ object = G_OBJECT_CLASS(klass); - item = G_EDITOR_ITEM_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_portions_tbitem_dispose; object->finalize = (GObjectFinalizeFunc)g_portions_tbitem_finalize; - item->change_content = change_portions_tbitem_current_content; + item = G_EDITOR_ITEM_CLASS(klass); + + item->get_key = (get_item_key_fc)g_portions_tbitem_get_key; + item->get_widget = (get_item_widget_fc)g_portions_tbitem_get_widget; + + item->change_content = (change_item_content_fc)change_portions_tbitem_current_content; } @@ -121,20 +133,18 @@ static void g_portions_tbitem_class_init(GPortionsTbItemClass *klass) static void g_portions_tbitem_init(GPortionsTbItem *item) { - GtkWidget *widget; /* Composant principal */ GtkWidget *strip; /* Bande pour binaire */ - widget = GTK_WIDGET(gtk_tool_item_new()); - gtk_tool_item_set_expand(GTK_TOOL_ITEM(widget), TRUE); - gtk_widget_show(widget); + item->support = GTK_WIDGET(gtk_tool_item_new()); - G_EDITOR_ITEM(item)->widget = widget; + gtk_tool_item_set_expand(GTK_TOOL_ITEM(item->support), TRUE); + gtk_widget_show(item->support); strip = gtk_binary_strip_new(); gtk_widget_show(strip); - gtk_container_add(GTK_CONTAINER(widget), strip); + gtk_container_add(GTK_CONTAINER(item->support), strip); - g_object_set_data(G_OBJECT(widget), "strip", strip); + g_object_set_data(G_OBJECT(item->support), "strip", strip); g_signal_connect(strip, "select-address", G_CALLBACK(track_address_on_binary_strip), @@ -157,6 +167,8 @@ static void g_portions_tbitem_init(GPortionsTbItem *item) static void g_portions_tbitem_dispose(GPortionsTbItem *item) { + g_clear_object(&item->support); + G_OBJECT_CLASS(g_portions_tbitem_parent_class)->dispose(G_OBJECT(item)); } @@ -193,13 +205,63 @@ static void g_portions_tbitem_finalize(GPortionsTbItem *item) * * ******************************************************************************/ -GEditorItem *create_portions_tb_item(GObject *ref) +GEditorItem *g_portions_tbitem_new(GObject *ref) { GPortionsTbItem *result; /* Structure à retourner */ result = g_object_new(G_TYPE_PORTIONS_TBITEM, NULL); - return g_toolbar_item_setup(G_TOOLBAR_ITEM(result), ref, "portions", _("Portions")); + g_toolbar_item_setup(G_TOOLBAR_ITEM(result), ref); + + return G_EDITOR_ITEM(result); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* * +* Description : Fournit le nom interne attribué à l'élément réactif. * +* * +* Retour : Désignation (courte) de l'élément de l'éditeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_portions_tbitem_get_key(const GPortionsTbItem *item) +{ + char *result; /* Description à renvoyer */ + + result = strdup(PORTIONS_TBITEM_ID); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* * +* Description : Fournit le composant GTK associé à l'élément réactif. * +* * +* Retour : Instance de composant graphique chargé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *g_portions_tbitem_get_widget(const GPortionsTbItem *item) +{ + GtkWidget *result; /* Composant à retourner */ + + result = item->support; + + g_object_ref(G_OBJECT(result)); + + return result; } @@ -218,10 +280,9 @@ GEditorItem *create_portions_tb_item(GObject *ref) * * ******************************************************************************/ -static void change_portions_tbitem_current_content(GEditorItem *item, GLoadedContent *old, GLoadedContent *new) +static void change_portions_tbitem_current_content(GPortionsTbItem *item, GLoadedContent *old, GLoadedContent *new) { GLoadedBinary *binary; /* Autre version de l'instance */ - GtkWidget *widget; /* Elément graphique principal */ GtkBinaryStrip *strip; /* Bande pour binaire */ if (G_IS_LOADED_BINARY(new)) @@ -229,19 +290,15 @@ static void change_portions_tbitem_current_content(GEditorItem *item, GLoadedCon else binary = NULL; - widget = g_editor_item_get_widget(item); - - strip = GTK_BINARY_STRIP(g_object_get_data(G_OBJECT(widget), "strip")); + strip = GTK_BINARY_STRIP(g_object_get_data(G_OBJECT(item->support), "strip")); if (binary != NULL) { gtk_binary_strip_attach(strip, binary); - gtk_widget_show(GTK_WIDGET(widget)); + gtk_widget_show(item->support); } else - gtk_widget_hide(GTK_WIDGET(widget)); - - g_object_unref(G_OBJECT(widget)); + gtk_widget_hide(item->support); } diff --git a/src/gui/tb/portions.h b/src/gui/tb/portions.h index db1d4b4..b7457e7 100644 --- a/src/gui/tb/portions.h +++ b/src/gui/tb/portions.h @@ -30,6 +30,9 @@ +#define PORTIONS_TBITEM_ID "portions" + + #define G_TYPE_PORTIONS_TBITEM g_portions_tbitem_get_type() #define G_PORTIONS_TBITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_portions_tbitem_get_type(), GToolbarItem)) #define G_IS_PORTIONS_TBITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_portions_tbitem_get_type())) @@ -49,7 +52,7 @@ typedef struct _GPortionsTbItemClass GPortionsTbItemClass; GType g_portions_tbitem_get_type(void); /* Crée une sélection de fichier réactive pour barre d'outils. */ -GEditorItem *create_portions_tb_item(GObject *ref); +GEditorItem *g_portions_tbitem_new(GObject *ref); diff --git a/src/gui/tb/tbitem-int.h b/src/gui/tb/tbitem-int.h index 4d519f2..4cc4778 100644 --- a/src/gui/tb/tbitem-int.h +++ b/src/gui/tb/tbitem-int.h @@ -26,7 +26,7 @@ #define _GUI_TBITEM_INT_H -#include "../editem-int.h" +#include "../item-int.h" @@ -48,7 +48,7 @@ struct _GToolbarItemClass /* Termine la préparation d'un élément de barre d'outils. */ -GEditorItem *g_toolbar_item_setup(GToolbarItem *, GObject *, const char *, const char *); +void g_toolbar_item_setup(GToolbarItem *, GObject *); diff --git a/src/gui/tb/tbitem.c b/src/gui/tb/tbitem.c index f7f3ec8..e46702e 100644 --- a/src/gui/tb/tbitem.c +++ b/src/gui/tb/tbitem.c @@ -84,31 +84,26 @@ static void g_toolbar_item_init(GToolbarItem *item) * * * Paramètres : tbitem = élément de barre d'outils à finaliser. * * ref = espace de référencement global. * -* name = nom associé à l'élément. * -* label = étiquette destinée au menu. * * * * Description : Termine la préparation d'un élément de barre d'outils. * * * -* Retour : Adresse de la structure mise en place. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GEditorItem *g_toolbar_item_setup(GToolbarItem *tbitem, GObject *ref, const char *name, const char *label) +void g_toolbar_item_setup(GToolbarItem *tbitem, GObject *ref) { - GEditorItem *result; /* Structure à retourner */ GtkContainer *toolbar; /* Barre d'outils visée */ - - result = G_EDITOR_ITEM(tbitem); - - result->name = name; + GtkWidget *widget; /* Composant GTK à intégrer */ /* Intégration dans la barre */ toolbar = GTK_CONTAINER(g_object_get_data(ref, "toolbar")); - gtk_container_add(toolbar, result->widget); - return result; + widget = g_editor_item_get_widget(G_EDITOR_ITEM(tbitem)); + + gtk_container_add(toolbar, widget); } diff --git a/src/gui/tb/tbitem.h b/src/gui/tb/tbitem.h index 2a9c61a..260bfc3 100644 --- a/src/gui/tb/tbitem.h +++ b/src/gui/tb/tbitem.h @@ -26,7 +26,7 @@ #define _GUI_TBITEM_H -#include "../editem.h" +#include "../item.h" -- cgit v0.11.2-87-g4458