From f8f804cf7ff9a62404b843cf303c762101572784 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 9 Mar 2016 13:55:20 +0100 Subject: Reorganized the whole code dealing with dockable panels. --- ChangeLog | 47 ++ configure.ac | 1 + plugins/pychrysa/gui/panels/panel.c | 11 +- src/analysis/project.c | 14 +- src/gui/Makefile.am | 5 +- src/gui/core/Makefile.am | 14 + src/gui/core/panels.c | 199 +++++++ src/gui/core/panels.h | 53 ++ src/gui/dialogs/Makefile.am | 6 +- src/gui/editor.c | 777 +++++++++++++++++++++++++- src/gui/menus/view.c | 2 +- src/gui/panels/bookmarks.c | 51 +- src/gui/panels/bookmarks.h | 5 +- src/gui/panels/glance.c | 45 +- src/gui/panels/glance.h | 5 +- src/gui/panels/history.c | 51 +- src/gui/panels/history.h | 5 +- src/gui/panels/log.c | 54 +- src/gui/panels/log.h | 5 +- src/gui/panels/panel-int.h | 57 +- src/gui/panels/panel.c | 1030 ++--------------------------------- src/gui/panels/panel.h | 40 +- src/gui/panels/regedit.c | 51 +- src/gui/panels/regedit.h | 5 +- src/gui/panels/strings.c | 51 +- src/gui/panels/strings.h | 5 +- src/gui/panels/symbols.c | 51 +- src/gui/panels/symbols.h | 5 +- 28 files changed, 1288 insertions(+), 1357 deletions(-) create mode 100755 src/gui/core/Makefile.am create mode 100644 src/gui/core/panels.c create mode 100644 src/gui/core/panels.h diff --git a/ChangeLog b/ChangeLog index ca1655f..84f6ffc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +16-03-09 Cyrille Bagard + + * configure.ac: + Add the new Makefile from the 'src/gui/core' directory. + + * plugins/pychrysa/gui/panels/panel.c: + * src/analysis/project.c: + Update code. + + * src/gui/Makefile.am: + Add core/libguicore.la to libgui_la_LIBADD and core to SUBDIRS. + + * src/gui/core/Makefile.am: + * src/gui/core/panels.c: + * src/gui/core/panels.h: + New entries: handle a global list of dockable panels. + + * src/gui/dialogs/Makefile.am: + Typo. + + * src/gui/editor.c: + Reorganize the whole code dealing with dockable panels. + + * src/gui/menus/view.c: + * src/gui/panels/bookmarks.c: + * src/gui/panels/bookmarks.h: + * src/gui/panels/glance.c: + * src/gui/panels/glance.h: + * src/gui/panels/history.c: + * src/gui/panels/history.h: + * src/gui/panels/log.c: + * src/gui/panels/log.h: + Update code. + + * src/gui/panels/panel-int.h: + * src/gui/panels/panel.c: + * src/gui/panels/panel.h: + Reorganize the whole code dealing with dockable panels. + + * src/gui/panels/regedit.c: + * src/gui/panels/regedit.h: + * src/gui/panels/strings.c: + * src/gui/panels/strings.h: + * src/gui/panels/symbols.c: + * src/gui/panels/symbols.h: + Update code. + 16-03-08 Cyrille Bagard * plugins/pychrysa/gui/panels/panel.c: diff --git a/configure.ac b/configure.ac index b5a33c0..bbd7cba 100644 --- a/configure.ac +++ b/configure.ac @@ -368,6 +368,7 @@ AC_CONFIG_FILES([Makefile src/gtkext/graph/Makefile src/gtkext/graph/nodes/Makefile src/gui/Makefile + src/gui/core/Makefile src/gui/dialogs/Makefile src/gui/menus/Makefile src/gui/panels/Makefile diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c index 8046c0e..1246717 100644 --- a/plugins/pychrysa/gui/panels/panel.c +++ b/plugins/pychrysa/gui/panels/panel.c @@ -28,6 +28,7 @@ #include +#include #include @@ -70,14 +71,17 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds) PyGObject *widget; /* Composant visuel du panneau */ const char *path; /* Placement à l'affichage */ int ret; /* Bilan de lecture des args. */ - GEditorItem *item; /* Elément de l'éditeur */ + GPanelItem *item; /* Elément de l'éditeur */ ret = PyArg_ParseTuple(args, "kssOs", &personality, &name, &lname, &widget, &path); if (!ret) return -1; - item = g_panel_item_new(personality, get_internal_ref(), name, lname, + item = g_panel_item_new(personality, name, lname, GTK_WIDGET(pygobject_get(widget)), path); + /* FIXME ? Est-ce à l'utilisateur de s'enregistrer ? */ + register_panel_item(item, get_internal_ref()); + /* Enregistrement auprès de PyGObject */ ((PyGObject *)self)->obj = G_OBJECT(item); @@ -108,7 +112,8 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) item = G_PANEL_ITEM(pygobject_get(self)); - g_panel_item_dock(item); + /* FIXME : les panneaux sont incrustés d'office ! */ + //g_panel_item_dock(item); Py_RETURN_NONE; diff --git a/src/analysis/project.c b/src/analysis/project.c index 623779b..08df9d8 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -41,6 +41,7 @@ #include "../gtkext/gtkblockview.h" #include "../gtkext/gtkgraphview.h" #include "../gtkext/gtksourceview.h" +#include "../gui/core/panels.h" #include "../gui/panels/log.h" #include "../gui/panels/panel.h" @@ -64,7 +65,7 @@ typedef struct _loaded_binary GtkViewPanel *views[BVW_COUNT]; /* Composants pour l'affichage */ GtkWidget *scrollwindows[BVW_COUNT]; /* Supports pour l'affichage */ - GEditorItem *item; /* Support d'affichage final */ + GPanelItem *item; /* Support d'affichage final */ } loaded_binary; @@ -594,7 +595,8 @@ void g_study_project_add_loaded_binary(GLoadedBinary *binary, GStudyProject *pro g_signal_connect(project->binaries[index]->views[BVW_BLOCK], "size-allocate", G_CALLBACK(scroll_for_the_first_time), binary); - g_panel_item_dock(G_PANEL_ITEM(project->binaries[index]->item)); + /* FIXME : les panneaux sont incrustés d'office ! */ + //g_panel_item_dock(project->binaries[index]->item); } @@ -666,7 +668,8 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina name = g_loaded_binary_get_name(binary, false); lname = g_loaded_binary_get_name(binary, true); - loaded->item = g_panel_item_new(PIP_BINARY_VIEW, project->ref, name, lname, scroll, "N"); + loaded->item = g_panel_item_new(PIP_BINARY_VIEW, name, lname, scroll, "N"); + register_panel_item(loaded->item, project->ref); /* Enregistrement dans le projet */ @@ -781,7 +784,8 @@ void g_study_project_display(const GStudyProject *project) size_t i; /* Boucle de parcours */ for (i = 0; i < project->binaries_count; i++) - g_panel_item_dock(G_PANEL_ITEM(project->binaries[i]->item)); + /* FIXME : les panneaux sont incrustés d'office ! */ + ;//g_panel_item_dock(project->binaries[i]->item); } @@ -803,7 +807,7 @@ static void g_study_project_hide(const GStudyProject *project) size_t i; /* Boucle de parcours */ for (i = 0; i < project->binaries_count; i++) - g_panel_item_undock(G_PANEL_ITEM(project->binaries[i]->item)); + g_panel_item_undock(project->binaries[i]->item); } diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 8c6311b..911adb9 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -8,7 +8,8 @@ libgui_la_SOURCES = \ status.h status.c libgui_la_LIBADD = \ - dialogs/libdialogs.la \ + core/libguicore.la \ + dialogs/libguidialogs.la \ menus/libguimenus.la \ panels/libguipanels.la \ tb/libguitb.la @@ -20,4 +21,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = dialogs menus panels tb +SUBDIRS = core dialogs menus panels tb diff --git a/src/gui/core/Makefile.am b/src/gui/core/Makefile.am new file mode 100755 index 0000000..948bd24 --- /dev/null +++ b/src/gui/core/Makefile.am @@ -0,0 +1,14 @@ + +noinst_LTLIBRARIES = libguicore.la + +libguicore_la_SOURCES = \ + panels.h panels.c + +libguicore_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/src/gui/core/panels.c b/src/gui/core/panels.c new file mode 100644 index 0000000..6b77e92 --- /dev/null +++ b/src/gui/core/panels.c @@ -0,0 +1,199 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * panels.c - gestion d'ensemble de tous les panneaux pour l'éditeur + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 "panels.h" + + +#include "../panels/bookmarks.h" +#include "../panels/glance.h" +#include "../panels/history.h" +#include "../panels/log.h" +#include "../panels/panel-int.h" +#include "../panels/regedit.h" +#include "../panels/strings.h" +#include "../panels/symbols.h" +#include "../../gtkext/gtkdockable.h" + + + +/* Liste des panneaux en place. */ +static GPanelItem *_panels_list = NULL; + + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Charge les principaux panneaux de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void load_main_panels(GObject *ref) +{ + GPanelItem *item; /* Panneau de base à charger */ + + item = g_log_panel_new(); + register_panel_item(item, ref); + + item = g_regedit_panel_new(); + register_panel_item(item, ref); + + item = g_symbols_panel_new(); + register_panel_item(item, ref); + + item = g_history_panel_new(); + register_panel_item(item, ref); + + item = g_strings_panel_new(); + register_panel_item(item, ref); + + item = g_glance_panel_new(); + register_panel_item(item, ref); + + item = g_bookmarks_panel_new(); + register_panel_item(item, ref); + +} + + +/****************************************************************************** +* * +* Paramètres : item = composant à présenter à l'affichage. * +* ref = espace de référencement global. * +* * +* Description : Enregistre un panneau comme partie intégrante de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_panel_item(GPanelItem *item, GObject *ref) +{ + GEditorItem *parent; /* Autre version de l'élément */ + + parent = G_EDITOR_ITEM(item); + + g_object_ref(ref); + parent->ref = ref; + + /* Enregistre correctement le tout */ + register_editor_item(parent); + panels_list_add_tail(item, &_panels_list); + + extern void on_panel_item_dock_request(GPanelItem *item, void *data); + extern void on_panel_item_undock_request(GPanelItem *item, void *data); + + g_signal_connect(item, "dock-request", G_CALLBACK(on_panel_item_dock_request), NULL); + g_signal_connect(item, "undock-request", G_CALLBACK(on_panel_item_undock_request), NULL); + + gtk_dockable_setup_dnd(GTK_DOCKABLE(item)); + + g_panel_item_dock(item); + +} + + +/****************************************************************************** +* * +* Paramètres : handle = routine à appeler pour chaque panneau. * +* data = données fournies pour accompagner cet appel. * +* * +* Description : Effectue le parcours de tous les panneaux chargés. * +* * +* Retour : true si le parcours a été total, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool browse_all_item_panels(handle_panel_item_fc handle, void *data) +{ + bool result; /* Résultat à renvoyer */ + GPanelItem *iter; /* Boucle de parcours */ + + result = true; + + panels_list_for_each(iter, _panels_list) + { + result = handle(iter, data); + + if (!result) break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : name = désignation courte servant de clef. * +* * +* Description : Recherche un panneau à partir de son nom court. * +* * +* Retour : Panneau trouvé ou NULL si aucun. * +* * +* Remarques : Le parcours peut se faire aussi depuis la classe parente, * +* mais il est plus rapide par ici. * +* * +******************************************************************************/ + +GPanelItem *get_panel_item_by_name(const char *name) +{ + GPanelItem *result; /* Trouvaille à retourner */ + + bool look_for_named_panel(GPanelItem *item, GPanelItem **found) + { + const char *key; /* Clef à utiliser */ + bool status; /* Bilan de la comparaison */ + + key = g_editor_item_get_name(G_EDITOR_ITEM(item)); + + if (strcmp(key, name) == 0) + { + *found = item; + status = false; + } + else + status = true; + + return status; + + } + + result = NULL; + + browse_all_item_panels((handle_panel_item_fc)look_for_named_panel, &result); + + return result; + +} diff --git a/src/gui/core/panels.h b/src/gui/core/panels.h new file mode 100644 index 0000000..1a8f9d8 --- /dev/null +++ b/src/gui/core/panels.h @@ -0,0 +1,53 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * panels.h - prototypes pour la gestion d'ensemble de tous les panneaux pour l'éditeur + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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_CORE_PANELS_H +#define _GUI_CORE_PANELS_H + + +#include + + +#include "../panels/panel.h" + + + +/* Charge les principaux panneaux de l'éditeur. */ +void load_main_panels(GObject *); + +/* Enregistre un panneau comme partie intégrante de l'éditeur. */ +void register_panel_item(GPanelItem *, GObject *); + +/* Réalise un traitement sur un panneau de l'éditeur. */ +typedef bool (* handle_panel_item_fc) (GPanelItem *, void *); + +/* Effectue le parcours de tous les panneaux chargés. */ +bool browse_all_item_panels(handle_panel_item_fc, void *); + +/* Recherche un panneau à partir de son nom court. */ +GPanelItem *get_panel_item_by_name(const char *); + + + +#endif /* _GUI_CORE_PANELS_H */ diff --git a/src/gui/dialogs/Makefile.am b/src/gui/dialogs/Makefile.am index 1fe821a..a75701f 100644 --- a/src/gui/dialogs/Makefile.am +++ b/src/gui/dialogs/Makefile.am @@ -1,7 +1,7 @@ -noinst_LTLIBRARIES = libdialogs.la +noinst_LTLIBRARIES = libguidialogs.la -libdialogs_la_SOURCES = \ +libguidialogs_la_SOURCES = \ about.h about.c \ bookmark.h bookmark.c \ export.h export.c \ @@ -11,7 +11,7 @@ libdialogs_la_SOURCES = \ shellcode.h shellcode.c \ storage.h storage.c -libdialogs_la_LDFLAGS = +libguidialogs_la_LDFLAGS = AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) diff --git a/src/gui/editor.c b/src/gui/editor.c index 6f5ef7a..bcbdfe1 100644 --- a/src/gui/editor.c +++ b/src/gui/editor.c @@ -25,6 +25,10 @@ #include "editor.h" +#include +#include + + #include @@ -34,6 +38,7 @@ #include "tb/portions.h" #include "tb/source.h" #include "../analysis/project.h" +#include "../common/extstr.h" #include "../core/params.h" #include "../gtkext/easygtk.h" #include "../gtkext/gtkdockable.h" @@ -80,6 +85,95 @@ static GtkWidget *build_editor_toolbar(GObject *); +/* -------------------- MECANISMES DE (DE)PLACEMENT DES PANNEAUX -------------------- */ + + +/* Elément de la hiérarchie des panneaux */ +typedef struct _panel_node +{ + struct _panel_node *parent; /* Noeud parent */ + + union + { + GtkWidget *widget; /* Accès généraliste */ + GtkWidget *station; /* Station d'accueil simple */ + GtkWidget *paned; /* Station d'accueil composée */ + + }; + + union + { + /* Version simple */ + struct + { + char *path; /* Chemin du nom courant */ + }; + + /* Version composée */ + struct + { + struct _panel_node *first; /* Premier sous élément */ + struct _panel_node *second; /* Second sous élément */ + }; + + }; + +} panel_node; + + +#define IS_SIMPLE_NODE(nd) \ + ({ \ + bool __result; \ + __result = GTK_IS_DOCK_STATION(nd->station); \ + assert(__result || GTK_IS_PANED(nd->paned)); \ + __result; \ + }) + + +/* Support de fond pour les composants. */ +static GObject *_global_ref = NULL; +static GtkWidget *_support = NULL; +static panel_node *_nodes = NULL; + + +/* Crée un nouveau noeud pour un panneau particulier. */ +static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *); + +/* Prépare une nouvelle sous-division pour deux panneaux. */ +static void switch_panel_node_into_paned(panel_node *, bool, bool); + +/* Met en place un nouveau noeud dans une division. */ +static void attach_panel_node_to_paned(panel_node *, panel_node *, bool); + +/* Obtient la désignation d'un élément hiérarchie des noeuds. */ +static char *get_panel_node_path(const panel_node *); + +/* Détermine la plus grande longueur commune entre éléments. */ +static size_t compute_path_common_length(const panel_node *, const char *); + +/* Place au bon endroit un panneau donné. */ +static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t); + +/* Tente de mettre la main sur une station d'accueil. */ +static panel_node *find_node_for_station(panel_node *, GtkWidget *); + +/* Efface de l'organisation un noeud donné en place. */ +static void delete_panel_node(panel_node *); + + + +/* ------------------- INTERACTIONS GRAPHIQUES LIEES AUX PANNEAUX ------------------- */ + + +/* Réagit à une demande de placement d'un panneau d'affichage. */ +void on_panel_item_dock_request(GPanelItem *, void *); + +/* Réagit à une demande de suppression d'un panneau d'affichage. */ +void on_panel_item_undock_request(GPanelItem *, void *); + + + + /****************************************************************************** * * @@ -204,10 +298,12 @@ GtkWidget *create_editor(void) do { - GtkWidget *support; + _global_ref = ref; + _support = gtk_event_box_new(); + gtk_widget_show(_support); - support = init_panels2(G_CALLBACK(on_dock_item_switch), ref); - gtk_box_pack_start(GTK_BOX(vbox1), support, TRUE, TRUE, 0); + //_support = init_panels2(G_CALLBACK(on_dock_item_switch), ref); + gtk_box_pack_start(GTK_BOX(vbox1), _support, TRUE, TRUE, 0); load_main_panels(ref); @@ -324,6 +420,11 @@ static void on_destroy_editor(GtkWidget *widget, gpointer data) project = get_current_project(); if (project != NULL) g_object_unref(G_OBJECT(project)); + //if (!result) + save_panel_nodes(); + + + /* Fermeture propre */ /* ... */ @@ -448,3 +549,673 @@ static GtkWidget *build_editor_toolbar(GObject *ref) return result; } + + + + + + + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* MECANISMES DE (DE)PLACEMENT DES PANNEAUX */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : item = composant à présenter à l'affichage. * +* path = partie du chemin représentée ici. * +* * +* Description : Crée un nouveau noeud pour un panneau particulier. * +* * +* Retour : Structure d'accueil mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path) +{ + panel_node *result; /* Structure à retourner */ + GtkWidget *station; /* Premier support concentré */ + + /* Partie graphique */ + + station = gtk_dock_station_new(); + g_signal_connect(station, "switch-widget", G_CALLBACK(on_dock_item_switch), _global_ref); + gtk_widget_show(station); + + gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item)); + + /* Partie invisible */ + + result = (panel_node *)calloc(1, sizeof(panel_node)); + + result->station = station; + + result->path = strdup(path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud à diviser. * +* horiz = indique le type d'orientation désiré. * +* first = indication sur l'emplacement à utiliser. * +* * +* Description : Prépare une nouvelle sous-division pour deux panneaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool first) +{ + GtkWidget *widget; /* Composant à traiter */ + panel_node *parent; /* Lien de parenté à conserver */ + panel_node *moved; /* Noeud descendu d'un étage */ + + /* Décroche graphiquement le support */ + + widget = node->widget; + + g_object_ref(G_OBJECT(widget)); + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); + + /* Descend l'élément actuel */ + + parent = node->parent; + + moved = (panel_node *)calloc(1, sizeof(panel_node)); + + memcpy(moved, node, sizeof(panel_node)); + + if (!IS_SIMPLE_NODE(moved)) + { + moved->first->parent = moved; + moved->second->parent = moved; + } + + /* Création du nouveau niveau intermédiaire */ + + if (horiz) + node->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); + else + node->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL); + + gtk_widget_show(node->paned); + + if (parent == NULL) + attach_panel_node_to_paned(parent, node, true); + else + attach_panel_node_to_paned(parent, node, parent->first == node); + + + + + /* Premier ajustement */ + + void split_paned_support(GtkWidget *support, GdkRectangle *alloc, gpointer data) + { + GtkOrientation orientation; + gint position; + + orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(support)); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + position = alloc->width / 2; + else + position = alloc->height / 2; + + /* + if (position < 50) + position *= 2; + */ + + gtk_paned_set_position(GTK_PANED(support), position); + + fprintf(stderr, "widget size is currently %dx%d\n", alloc->width, alloc->height); + + + fprintf(stderr, "position = %d\n", position); + + fprintf(stderr, "---\n"); + + + g_signal_handlers_disconnect_by_func(support, G_CALLBACK(split_paned_support), NULL); + + } + + //g_signal_connect(current->paned, "size-allocate", G_CALLBACK(split_paned_support), NULL); + + static int __counter = 0; + + + + if (++__counter == 4) + gtk_paned_set_position(GTK_PANED(node->paned), 100); + + + + + /* Replace le composant d'origine */ + + attach_panel_node_to_paned(node, moved, first); + +} + + +/****************************************************************************** +* * +* Paramètres : parent = noeud d'accueil pour le nouveau noeud. * +* node = nouveau noeud à intégrer dans l'ensemble. * +* first = indication sur l'emplacement à utiliser. * +* * +* Description : Met en place un nouveau noeud dans une division. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, bool first) +{ + node->parent = parent; + + /* On se trouve à la racine... */ + + if (parent == NULL) + gtk_container_add(GTK_CONTAINER(_support), node->widget); + + else + { + /* Raccordement hiérarchique */ + + if (first) + parent->first = node; + else + parent->second = node; + + /* Raccordement graphique */ + + assert(!IS_SIMPLE_NODE(parent)); + + if (first) + gtk_paned_pack1(GTK_PANED(parent->paned), node->widget, TRUE, FALSE); + else + gtk_paned_pack2(GTK_PANED(parent->paned), node->widget, TRUE, FALSE); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud dont la désignation est à obtenir. * +* * +* Description : Obtient la désignation d'un élément hiérarchie des noeuds. * +* * +* Retour : Chaîne construite à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *get_panel_node_path(const panel_node *node) +{ + char *result; /* Valeur à retourner */ + char *extra; /* Complément à ajouter */ + + if (IS_SIMPLE_NODE(node)) + result = strdup(node->path); + + else + { + result = get_panel_node_path(node->first); + + extra = get_panel_node_path(node->second); + result = stradd(result, "-"); + result = stradd(result, extra); + free(extra); + + result = strprep(result, "("); + result = stradd(result, ")"); + + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud d'où lancer les recherches. * +* target = identifiant de la position visée. * +* * +* Description : Détermine la plus grande longueur commune entre éléments. * +* * +* Retour : Bilan de l'évaluation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t compute_path_common_length(const panel_node *node, const char *target) +{ + size_t result; /* Taille à retourner */ + size_t len; /* Longueur de comparaison */ + size_t common1; /* Tron common avec le côté #1 */ + size_t common2; /* Tron common avec le côté #2 */ + + if (IS_SIMPLE_NODE(node)) + { + len = MIN(strlen(node->path), strlen(target)); + + /** + * Il n'y a pas forcément de base commune entre deux branches, + * donc on parcourt les chemins depuis leur base respective. + */ + for (result = 0; result < len; result++) + if (node->path[result] != target[result]) + break; + + } + + else + { + common1 = compute_path_common_length(node->first, target); + common2 = compute_path_common_length(node->second, target); + + result = MAX(common1, common2); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = composant à présenter à l'affichage. * +* node = point d'insertion courant. * +* path = partie du chemin représentée ici. * +* consumed = profondeur du chemin utilisé. * +* * +* Description : Place au bon endroit un panneau donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t consumed) +{ + char div; /* Division demandée */ + bool horiz; /* Traduction en composant */ + bool first; /* Point d'insertion */ + panel_node *new; /* Nouveau noeud créé */ + size_t common1; /* Tron common avec le côté #1 */ + size_t common2; /* Tron common avec le côté #2 */ + + + fprintf(stderr, "=== INSERTING '%s' (%zu)... -> '%s'\n", path, consumed, + IS_SIMPLE_NODE(node) ? node->path : "-"); + + + + if (IS_SIMPLE_NODE(node)) + { + /* Le parcours s'arrête ici ! */ + if (strcmp(node->path, path) == 0) + gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item)); + + /* On ne peut aller plus loin, on doit diviser... */ + else + { + div = toupper(path[consumed]); + first = (div == 'W' || div == 'N'); + horiz = (div == 'W' || div == 'E'); + + fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz); + + fprintf(stderr, "--- cutting %p\n", node->station); + + switch_panel_node_into_paned(node, horiz, !first); + + new = create_simple_panel_node_for_item(item, path); + + attach_panel_node_to_paned(node, new, first); + + + fprintf(stderr, "1# [%p] widget = %p --- split :: %p // %p\n", + node, node->station, node->first, node->second); + + } + + } + + /* On regarde des autres côtés... */ + + else + { + common1 = compute_path_common_length(node->first, path); + common2 = compute_path_common_length(node->second, path); + + + fprintf(stderr, " - L1 :: %zu <-> '%s'\n", common1, get_panel_node_path(node->first)); + fprintf(stderr, " - L2 :: %zu <-> '%s'\n", common2, get_panel_node_path(node->second)); + + + /* Si une descente est possible... */ + if (common1 > 0 || common2 > 0) + { + if (common1 > common2) + insert_item_as_panel_node(item, node->first, path, common1); + + else + insert_item_as_panel_node(item, node->second, path, common2); + + } + + /* Sinon, on doit diviser qqch... */ + else + { + div = toupper(path[consumed]); + first = (div == 'W' || div == 'N'); + horiz = (div == 'W' || div == 'E'); + + fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz); + + switch_panel_node_into_paned(node, horiz, !first); + + new = create_simple_panel_node_for_item(item, path); + + attach_panel_node_to_paned(node, new, first); + + + fprintf(stderr, "2# [%p] split :: %p-%p // %p-%p\n", node, + node->first, node->first->widget, + node->second, node->second->widget); + + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : node = point de départ des recherches locales. * +* * +* Description : Tente de mettre la main sur une station d'accueil. * +* * +* Retour : Eventuel noeud trouvé ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static panel_node *find_node_for_station(panel_node *node, GtkWidget *station) +{ + panel_node *result; /* Bilan à remonter */ + + if (IS_SIMPLE_NODE(node)) + result = (node->station == station ? node : NULL); + + else + { + result = find_node_for_station(node->first, station); + + if (result == NULL) + result = find_node_for_station(node->second, station); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud à supprimer de l'arbre des noeuds. * +* * +* Description : Efface de l'organisation un noeud donné en place. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void delete_panel_node(panel_node *node) +{ + panel_node *parent; /* Noeud parent à transformer */ + GtkWidget *widget; /* Composant à traiter */ + panel_node *grandparent; /* Noeud supérieur au parent */ + panel_node *remaining; /* Noeud restant */ + + assert(IS_SIMPLE_NODE(node)); + + parent = node->parent; + + /* Destruction du noeud */ + + widget = node->station; + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); + + free(node->path); + + free(node); + + /* Suppression du niveau intermédiaire */ + + if (parent != NULL) + { + remaining = (node == parent->first ? parent->second : parent->first); + + /* Décroche graphiquement le support */ + + widget = remaining->widget; + + g_object_ref(G_OBJECT(widget)); + gtk_container_remove(GTK_CONTAINER(parent->paned), widget); + + /* Supprime le composant graphique intermédiaire */ + + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(parent->paned)), parent->paned); + + /* Réinsère la partie restante */ + + grandparent = parent->parent; + + memcpy(parent, remaining, sizeof(panel_node)); + + if (!IS_SIMPLE_NODE(parent)) + { + parent->first->parent = parent; + parent->second->parent = parent; + } + + free(remaining); + + if (grandparent == NULL) + attach_panel_node_to_paned(grandparent, parent, true); + else + attach_panel_node_to_paned(grandparent, parent, grandparent->first == parent); + + } + +} + + + + + + + + + + + + + + +#if 1 + + +#include "../core/params.h" + + + +/****************************************************************************** +* * +* Paramètres : current = point de départ de la réorganisation graphique. * +* * +* Description : Met à jour l'affichage suite à un changement hiérarchique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void save_panel_nodes(void) +{ + + + fprintf(stderr, "Passage avec %p\n", _nodes); + + return; + void store_handle_position(panel_node *node, GGenConfig *config) + { + + size_t i; + + for (i = 0; i < 0/*node->depth*/; i++) + fprintf(stderr, " "); + + + ///fprintf(stderr, "[%s] %s\n", node->path, node->simple ? "[+]" : ">>"); + + + if (0/*!node->simple*/) + { + store_handle_position(node->first, config); + store_handle_position(node->second, config); + } + + + } + + + //get_main_configuration() + + + store_handle_position(_nodes, NULL); + + fflush(NULL); + + +} + +#endif + + + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERACTIONS GRAPHIQUES LIEES AUX PANNEAUX */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : item = composant à retirer de l'affichage. * +* unused = adresse non utilisée ici. * +* * +* Description : Réagit à une demande de placement d'un panneau d'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void on_panel_item_dock_request(GPanelItem *item, void *unused) +{ + const char *path; /* Chemin d'accès */ + + path = gtk_panel_item_get_path(item); + + /* Tout est à faire... */ + if (_nodes == NULL) + { + _nodes = create_simple_panel_node_for_item(item, path); + gtk_container_add(GTK_CONTAINER(_support), _nodes->widget); + } + else insert_item_as_panel_node(item, _nodes, path, 0); + + g_panel_item_set_dock_status(item, true); + +} + + +/****************************************************************************** +* * +* Paramètres : item = composant à retirer de l'affichage. * +* unused = adresse non utilisée ici. * +* * +* Description : Réagit à une demande de suppression d'un panneau d'affichage.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void on_panel_item_undock_request(GPanelItem *item, void *unused) +{ + GtkWidget *station; /* Support courant */ + panel_node *node; /* Noeud à supprimer */ + + gtk_dockable_decompose(GTK_DOCKABLE(item), &station); + + gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item)); + + if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0) + { + node = find_node_for_station(_nodes, station); + assert(node != NULL); + + delete_panel_node(node); + + } + + g_panel_item_set_dock_status(item, false); + +} diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c index e80077a..def1859 100644 --- a/src/gui/menus/view.c +++ b/src/gui/menus/view.c @@ -29,7 +29,7 @@ #include "../editem-int.h" -#include "../panels/panel.h" +#include "../core/panels.h" #include "../../analysis/project.h" #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkdockstation.h" diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c index 9eaa1df..87789b6 100644 --- a/src/gui/panels/bookmarks.c +++ b/src/gui/panels/bookmarks.c @@ -245,8 +245,20 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel) GtkTreeSortable *sortable; /* Autre vision de la liste */ GtkTreeSelection *select; /* Sélection dans 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->path = "SE"; + + /* Représentation graphique */ + base->widget = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(base->widget); @@ -256,10 +268,6 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel) ref = G_OBJECT(base->widget); g_object_set_data(ref, "panel", panel); - pitem = G_PANEL_ITEM(panel); - - pitem->personality = PIP_SINGLETON; - /* Partie signets */ store = gtk_tree_store_new(BMC_COUNT, G_TYPE_OBJECT, @@ -409,7 +417,7 @@ static void g_bookmarks_panel_finalize(GBookmarksPanel *panel) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : - * * * * Description : Crée un panneau d'affichage des paramètres de configuration. * * * @@ -419,15 +427,12 @@ static void g_bookmarks_panel_finalize(GBookmarksPanel *panel) * * ******************************************************************************/ -GEditorItem *g_bookmarks_panel_new(GObject *ref) +GPanelItem *g_bookmarks_panel_new(void) { - GEditorItem *result; /* Structure à retourner */ + GPanelItem *result; /* Structure à retourner */ result = g_object_new(G_TYPE_BOOKMARKS_PANEL, NULL); - g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_BOOKMARKS_ID, - _("Bookmarks"), G_EDITOR_ITEM(result)->widget, "SE"); - //reload_config_into_treeview(G_BOOKMARKS_PANEL(result), get_main_configuration()); @@ -441,32 +446,6 @@ GEditorItem *g_bookmarks_panel_new(GObject *ref) } -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Construit le panneau d'affichage des signets courants. * -* * -* Retour : Adresse du panneau mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *create_bookmarks_panel(GObject *ref) -{ - GEditorItem *result; /* Elément réactif à renvoyer */ - - result = g_bookmarks_panel_new(ref); - - /* Enregistre correctement le tout */ - register_editor_item(result); - - return G_PANEL_ITEM(result); - -} - - /* ---------------------------------------------------------------------------------- */ /* AFFICHAGE A L'AIDE D'UNE LISTE */ diff --git a/src/gui/panels/bookmarks.h b/src/gui/panels/bookmarks.h index 507cc09..7b65730 100644 --- a/src/gui/panels/bookmarks.h +++ b/src/gui/panels/bookmarks.h @@ -55,10 +55,7 @@ typedef struct _GBookmarksPanelClass GBookmarksPanelClass; GType g_bookmarks_panel_get_type(void); /* Crée un panneau d'affichage des paramètres de configuration. */ -GEditorItem *g_bookmarks_panel_new(GObject *); - -/* Construit le panneau d'affichage des signets courants. */ -GPanelItem *create_bookmarks_panel(GObject *); +GPanelItem *g_bookmarks_panel_new(void); diff --git a/src/gui/panels/glance.c b/src/gui/panels/glance.c index 6373edd..1dab8b4 100644 --- a/src/gui/panels/glance.c +++ b/src/gui/panels/glance.c @@ -176,18 +176,22 @@ static void g_glance_panel_init(GGlancePanel *panel) GPanelItem *pitem; /* Version parente du panneau */ GtkWidget *area; /* Surface de dessin réelle */ - base = G_EDITOR_ITEM(panel); + /* Eléments de base */ - base->name = _("Glance"); + base = G_EDITOR_ITEM(panel); - base->widget = gtk_event_box_new(); + base->name = PANEL_GLANCE_ID; pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; + pitem->lname = _("Glance"); + pitem->path = "es"; /* Support de dessin */ + base->widget = gtk_event_box_new(); + area = gtk_drawing_area_new(); gtk_widget_show(area); @@ -252,7 +256,7 @@ static void g_glance_panel_finalize(GGlancePanel *panel) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : - * * * * Description : Crée un panneau d'aperçu rapide. * * * @@ -262,15 +266,12 @@ static void g_glance_panel_finalize(GGlancePanel *panel) * * ******************************************************************************/ -GEditorItem *g_glance_panel_new(GObject *ref) +GPanelItem *g_glance_panel_new(void) { - GEditorItem *result; /* Structure à retourner */ + GPanelItem *result; /* Structure à retourner */ result = g_object_new(G_TYPE_GLANCE_PANEL, NULL); - g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_GLANCE_ID, - _("Glance"), G_EDITOR_ITEM(result)->widget, "es"); - return result; } @@ -278,32 +279,6 @@ GEditorItem *g_glance_panel_new(GObject *ref) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Construit et intègre un panneau d'affichage des symboles. * -* * -* Retour : Adresse du panneau mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *create_glance_panel(GObject *ref) -{ - GEditorItem *result; /* Elément réactif à renvoyer */ - - result = g_glance_panel_new(ref); - - /* Enregistre correctement le tout */ - register_editor_item(result); - - return G_PANEL_ITEM(result); - -} - - -/****************************************************************************** -* * * Paramètres : panel = panneau à actualiser. * * view = nouveau panneau d'affichage actif. * * * diff --git a/src/gui/panels/glance.h b/src/gui/panels/glance.h index 9a98bdb..b61b485 100644 --- a/src/gui/panels/glance.h +++ b/src/gui/panels/glance.h @@ -57,10 +57,7 @@ typedef struct _GGlancePanelClass GGlancePanelClass; GType g_glance_panel_get_type(void); /* Crée un panneau d'aperçu rapide. */ -GEditorItem *g_glance_panel_new(GObject *); - -/* Construit et intègre un panneau d'aperçu rapide. */ -GPanelItem *create_glance_panel(GObject *); +GPanelItem *g_glance_panel_new(void); diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c index 4d4be0c..526a775 100644 --- a/src/gui/panels/history.c +++ b/src/gui/panels/history.c @@ -166,18 +166,26 @@ static void g_history_panel_init(GHistoryPanel *panel) GtkWidget *button; /* Bouton de cette même barre */ GtkTreeSelection *select; /* Sélection dans la liste */ + /* 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->path = "eN"; + + /* Représentation graphique */ + base->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); gtk_container_set_border_width(GTK_CONTAINER(base->widget), 8); gtk_widget_show(base->widget); ref = G_OBJECT(panel); - pitem = G_PANEL_ITEM(panel); - - pitem->personality = PIP_SINGLETON; - /* Liste des éléments d'évolution */ scrollwnd = gtk_scrolled_window_new(NULL, NULL); @@ -293,7 +301,7 @@ static void g_history_panel_finalize(GHistoryPanel *panel) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : - * * * * Description : Crée un panneau d'affichage des symboles. * * * @@ -303,15 +311,12 @@ static void g_history_panel_finalize(GHistoryPanel *panel) * * ******************************************************************************/ -GEditorItem *g_history_panel_new(GObject *ref) +GPanelItem *g_history_panel_new(void) { - GEditorItem *result; /* Structure à retourner */ + GPanelItem *result; /* Structure à retourner */ result = g_object_new(G_TYPE_HISTORY_PANEL, NULL); - g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_HISTORY_ID, - _("Change history"), G_EDITOR_ITEM(result)->widget, "eN"); - return result; } @@ -319,32 +324,6 @@ GEditorItem *g_history_panel_new(GObject *ref) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Construit et intègre un panneau d'affichage des symboles. * -* * -* Retour : Adresse du panneau mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *create_history_panel(GObject *ref) -{ - GEditorItem *result; /* Elément réactif à renvoyer */ - - result = g_history_panel_new(ref); - - /* Enregistre correctement le tout */ - register_editor_item(result); - - return G_PANEL_ITEM(result); - -} - - -/****************************************************************************** -* * * Paramètres : panel = panneau à mettre à jour. * * binary = nouvelle instance de binaire analysé. * * * diff --git a/src/gui/panels/history.h b/src/gui/panels/history.h index 5b5b83b..f4c112e 100644 --- a/src/gui/panels/history.h +++ b/src/gui/panels/history.h @@ -55,10 +55,7 @@ typedef struct _GHistoryPanelClass GHistoryPanelClass; GType g_history_panel_get_type(void); /* Crée un panneau d'affichage des symboles. */ -GEditorItem *g_history_panel_new(GObject *); - -/* Construit et intègre un panneau d'affichage des symboles. */ -GPanelItem *create_history_panel(GObject *); +GPanelItem *g_history_panel_new(void); diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c index 7893666..1b8c6bc 100644 --- a/src/gui/panels/log.c +++ b/src/gui/panels/log.c @@ -33,6 +33,7 @@ #include "panel-int.h" +#include "../core/panels.h" @@ -157,16 +158,24 @@ static void g_log_panel_init(GLogPanel *panel) GtkCellRenderer *renderer; /* Moteur de rendu de colonne */ GtkTreeViewColumn *column; /* Colonne de la liste */ - base = G_EDITOR_ITEM(panel); + /* Eléments de base */ - scrolled = gtk_scrolled_window_new(NULL, NULL); - gtk_widget_show(scrolled); + base = G_EDITOR_ITEM(panel); - base->widget = scrolled; + base->name = PANEL_LOG_ID; pitem = G_PANEL_ITEM(panel); pitem->personality = PIP_SINGLETON; + pitem->lname = _("Misc information"); + pitem->path = "S"; + + /* Représentation graphique */ + + scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolled); + + base->widget = scrolled; /* Construction graphique */ @@ -244,7 +253,7 @@ static void g_log_panel_finalize(GLogPanel *panel) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : - * * * * Description : Crée un panneau d'affichage des messages système. * * * @@ -254,15 +263,12 @@ static void g_log_panel_finalize(GLogPanel *panel) * * ******************************************************************************/ -GEditorItem *g_log_panel_new(GObject *ref) +GPanelItem *g_log_panel_new(void) { - GEditorItem *result; /* Structure à retourner */ + GPanelItem *result; /* Structure à retourner */ result = g_object_new(G_TYPE_LOG_PANEL, NULL); - g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_LOG_ID, - _("Misc information"), G_EDITOR_ITEM(result)->widget, "S"); - return result; } @@ -270,32 +276,6 @@ GEditorItem *g_log_panel_new(GObject *ref) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Construit le panneau d'affichage des messages système. * -* * -* Retour : Adresse du panneau mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *create_log_panel(GObject *ref) -{ - GEditorItem *result; /* Elément réactif à renvoyer */ - - result = g_log_panel_new(ref); - - /* Enregistre correctement le tout */ - register_editor_item(result); - - return G_PANEL_ITEM(result); - -} - - -/****************************************************************************** -* * * Paramètres : type = espèce du message à ajouter. * * msg = message à faire apparaître à l'écran. * * * @@ -332,7 +312,7 @@ static void _log_simple_message(LogMessageType type, char *msg) GPanelItem *item; /* Intermédiaire mis en place */ log_data *data; /* Paramètres à joindre */ - item = g_panel_item_get(PANEL_LOG_ID); + item = get_panel_item_by_name(PANEL_LOG_ID); data = (log_data *)calloc(1, sizeof(log_data)); diff --git a/src/gui/panels/log.h b/src/gui/panels/log.h index ebd3579..3957b56 100644 --- a/src/gui/panels/log.h +++ b/src/gui/panels/log.h @@ -73,10 +73,7 @@ typedef enum _LogMessageType GType g_log_panel_get_type(void); /* Crée un panneau d'affichage des messages système. */ -GEditorItem *g_log_panel_new(GObject *); - -/* Construit le panneau d'affichage des messages système. */ -GPanelItem *create_log_panel(GObject *); +GPanelItem *g_log_panel_new(void); /* Affiche un message dans le journal des messages système. */ void log_simple_message(LogMessageType, const char *); diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h index e902722..5e906f0 100644 --- a/src/gui/panels/panel-int.h +++ b/src/gui/panels/panel-int.h @@ -54,52 +54,6 @@ struct _GPanelItem }; - -/* Elément de la hiérarchie des panneaux */ -typedef struct _panel_node -{ - struct _panel_node *parent; /* Noeud parent */ - - union - { - GtkWidget *widget; /* Accès généraliste */ - GtkWidget *station; /* Station d'accueil simple */ - GtkWidget *paned; /* Station d'accueil composée */ - - }; - - union - { - /* Version simple */ - struct - { - char *path; /* Chemin du nom courant */ - }; - - /* Version composée */ - struct - { - struct _panel_node *first; /* Premier sous élément */ - struct _panel_node *second; /* Second sous élément */ - }; - - }; - -} panel_node; - - - -#define IS_SIMPLE_NODE(nd) \ - ({ \ - bool __result; \ - __result = GTK_IS_DOCK_STATION(nd->station); \ - assert(__result || GTK_IS_PANED(nd->paned)); \ - __result; \ - }) - - - - /* Elément réactif pour panneaux de l'éditeur (classe) */ struct _GPanelItemClass { @@ -108,7 +62,12 @@ struct _GPanelItemClass bool unique; /* Panneau instanciable ? */ const char *bindings; /* Raccourci clavier éventuel */ - GtkBin *first; /* Elément racine */ + //GtkBin *first; /* Elément racine */ + + /* Signaux */ + + void (* dock_request) (GPanelItem); + void (* undock_request) (GPanelItem); }; @@ -117,9 +76,5 @@ struct _GPanelItemClass #define panels_list_for_each(pos, head) dl_list_for_each(pos, head, GPanelItem, link) -/* Initialise dynamique les propriétés de l'instance. */ -void g_panel_item_init_ext(GPanelItem *, GObject *, const char *, const char *, GtkWidget *, const char *); - - #endif /* _GUI_PANELS_PANEL_INT_H */ diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index 8af8672..00a4eea 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * panel.c - prototypes pour la gestion des éléments réactifs spécifiques aux panneaux + * panel.c - gestion des éléments réactifs spécifiques aux panneaux * * Copyright (C) 2012-2014 Cyrille Bagard * @@ -26,38 +26,13 @@ #include -#include -#include -#include -#include "bookmarks.h" -#include "glance.h" -#include "history.h" -#include "log.h" #include "panel-int.h" -#include "regedit.h" -#include "strings.h" -#include "symbols.h" -#include "../../common/extstr.h" -#include "../../gtkext/easygtk.h" #include "../../gtkext/gtkdockable-int.h" -#include "../../gtkext/gtkdockstation.h" -/* Support de fond pour les composants. */ -static GtkWidget *_support; -static panel_node *_nodes = NULL; - -/* Procédure à appeler lors des changements de panneaux. */ -static GCallback _handler; -static gpointer _data; - -/* Liste des panneaux en place. */ -static GPanelItem *_panels_list = NULL; - - /* Initialise la classe des éléments réactifs de l'éditeur. */ static void g_panel_item_class_init(GPanelItemClass *); @@ -78,51 +53,6 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *); -/* ---------------------- MECANISMES DE PLACEMENT DES PANNEAUX ---------------------- */ - - -/* Crée un nouveau noeud pour un panneau particulier. */ -//static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t); - -/* Prépare une nouvelle sous-division pour deux panneaux. */ -static void switch_panel_node_into_paned(panel_node *, bool, bool); - -/* Met en place un nouveau noeud dans une division. */ -static void attach_panel_node_to_paned(panel_node *, panel_node *, bool); - - - - -/* Crée un nouveau noeud pour un panneau particulier. */ -static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *); - - - - -/* Obtient la désignation d'un élément hiérarchie des noeuds. */ -static char *get_panel_node_path(const panel_node *); - -/* Détermine la plus grande longueur commune entre éléments. */ -static size_t compute_path_common_length(const panel_node *, const char *); - -/* Détermine la plus grande profondeur d'un noeud de panneaux. */ -static unsigned int compute_deepest_depth(const panel_node *); - -/* Place au bon endroit un panneau donné. */ -static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t); - -/* Tente de mettre la main sur une station d'accueil. */ -static panel_node *find_node_for_station(panel_node *, GtkWidget *); - -/* Efface de l'organisation un noeud donné en place. */ -static void delete_panel_node(panel_node *); - - - - - - - /* Indique le type défini pour un élément destiné à un panneau. */ G_DEFINE_TYPE_WITH_CODE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM, G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_panel_item_dockable_interface_init)) @@ -142,6 +72,21 @@ G_DEFINE_TYPE_WITH_CODE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM, static void g_panel_item_class_init(GPanelItemClass *klass) { + g_signal_new("dock-request", + G_TYPE_PANEL_ITEM, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GPanelItemClass, dock_request), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + g_signal_new("undock-request", + G_TYPE_PANEL_ITEM, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GPanelItemClass, undock_request), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } @@ -194,50 +139,7 @@ static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface) /****************************************************************************** * * -* Paramètres : item = composant à présenter à l'affichage. * -* ref = espace de référencement global. * -* name = nom associé à l'élément. * -* lname = description longue du panneau. * -* widget = composant à présenter à l'affichage. * -* path = chemin vers la place idéale pour le futur panneau. * -* * -* Description : Initialise dynamique les propriétés de l'instance. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path) -{ - GEditorItem *parent; /* Autre version de l'élément */ - - parent = G_EDITOR_ITEM(item); - - g_object_ref(ref); - parent->ref = ref; - - parent->name = name; - item->lname = lname; - - g_object_ref(widget); - parent->widget = widget; - g_object_set_data(G_OBJECT(widget), "pitem", item); - - item->path = path; - - panels_list_add_tail(item, &_panels_list); - - gtk_dockable_setup_dnd(GTK_DOCKABLE(item)); - -} - - -/****************************************************************************** -* * * Paramètres : personality = nature du panneau à mettre en place. * -* ref = espace de référencement global. * * name = nom associé à l'élément. * * lname = description longue du panneau. * * widget = composant à présenter à l'affichage. * @@ -251,18 +153,26 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con * * ******************************************************************************/ -GEditorItem *g_panel_item_new(PanelItemPersonality personality, GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path) +GPanelItem *g_panel_item_new(PanelItemPersonality personality, const char *name, const char *lname, GtkWidget *widget, 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 = name; + parent->widget = widget; + assert(personality > PIP_INVALID && personality < PIP_COUNT); result->personality = personality; - g_panel_item_init_ext(result, ref, name, lname, widget, path); + result->lname = lname; - return G_EDITOR_ITEM(result); + result->path = path; + + return result; } @@ -345,48 +255,38 @@ PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *item) /****************************************************************************** * * -* Paramètres : item = instance GTK dont l'interface est à consulter. * +* Paramètres : item = instance GTK à consulter. * * * -* Description : Indique la définition d'un éventuel raccourci clavier. * +* Description : Fournit le chemin d'accès à utiliser pour les encapsulations.* * * -* Retour : Description d'un raccourci ou NULL si aucun de défini. * +* Retour : Chemin d'accès défini. * * * * Remarques : - * * * ******************************************************************************/ -const char *gtk_panel_item_get_key_bindings(const GPanelItem *item) +const char *gtk_panel_item_get_path(const GPanelItem *item) { - return G_PANEL_ITEM_GET_CLASS(item)->bindings; + return item->path; } /****************************************************************************** * * -* Paramètres : name = désignation courte servant de clef. * +* Paramètres : item = instance GTK dont l'interface est à consulter. * * * -* Description : Recherche un panneau à partir de son nom court. * +* Description : Indique la définition d'un éventuel raccourci clavier. * * * -* Retour : Panneau trouvé ou NULL si aucun. * +* Retour : Description d'un raccourci ou NULL si aucun de défini. * * * -* Remarques : Le parcours peut se faire aussi depuis la classe parente, * -* mais il est plus rapide par ici. * +* Remarques : - * * * ******************************************************************************/ -GPanelItem *g_panel_item_get(const char *name) +const char *gtk_panel_item_get_key_bindings(const GPanelItem *item) { - GPanelItem *iter; /* Boucle de parcours */ - - panels_list_for_each(iter, _panels_list) - { - if (strcmp(G_EDITOR_ITEM(iter)->name, name) == 0) - return iter; - - } - - return NULL; + return G_PANEL_ITEM_GET_CLASS(item)->bindings; } @@ -403,177 +303,21 @@ GPanelItem *g_panel_item_get(const char *name) * * ******************************************************************************/ -static void dump_tree(GtkWidget *root, unsigned int level) -{ - unsigned int i; - GList *list; - GList *iter; - - if (strcmp(G_OBJECT_TYPE_NAME(G_OBJECT(root)), "GtkButton") == 0) - return; - - for (i = 0; i < level; i++) - fprintf(stderr, " "); - - fprintf(stderr, "%s (%p)\n", G_OBJECT_TYPE_NAME(G_OBJECT(root)), root); - - if (GTK_IS_CONTAINER(root)) - { - list = gtk_container_get_children(GTK_CONTAINER(root)); - - for (iter = list; iter != NULL; iter = g_list_next(iter)) - dump_tree(GTK_WIDGET(iter->data), level + 1); - - } - -} - - -void dump_node(panel_node *node, unsigned int level) -{ - unsigned i; - - for (i = 0; i < level; i++) - fprintf(stderr, " "); - - fprintf(stderr, "%p %p -- widget %p -- '%s'\n", node->parent, node, node->station, - IS_SIMPLE_NODE(node) ? node->path : "-"); - - if (!IS_SIMPLE_NODE(node)) - { - dump_node(node->first, level + 1); - dump_node(node->second, level + 1); - } - - -} - - - void g_panel_item_dock(GPanelItem *item) { assert(!item->docked); - fprintf(stderr, "\n---------\n\n"); - - /* Tout est à faire... */ - if (_nodes == NULL) - { - _nodes = create_simple_panel_node_for_item(item, item->path); - gtk_container_add(GTK_CONTAINER(_support), _nodes->widget); - } - else insert_item_as_panel_node(item, _nodes, item->path, 0); - - item->docked = true; - - - - dump_tree(_support, 0); - fprintf(stderr, "\n"); - dump_node(_nodes, 0); - - -} - - -/****************************************************************************** -* * -* Paramètres : item = composant d'affichage à consulter. * -* * -* Description : Indique si le composant repose sur un support de l'éditeur. * -* * -* Retour : true si le composant est bien incrusté quelque part. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_panel_item_is_docked(const GPanelItem *item) -{ - return item->docked; - -} - - -/****************************************************************************** -* * -* Paramètres : item = composant à retirer de l'affichage. * -* * -* Description : Supprime un panneau de l'ensemble affiché. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_panel_item_undock(GPanelItem *item) -{ - GtkWidget *station; /* Support courant */ - panel_node *node; /* Noeud à supprimer */ - - assert(item->docked); - - gtk_dockable_decompose(GTK_DOCKABLE(item), &station); - - gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item)); - - if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0) - { - node = find_node_for_station(_nodes, station); - assert(node != NULL); - - delete_panel_node(node); - - } - - item->docked = false; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* PLACEMENTS DES DIFFERENTS PANNEAUX */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : handler = procédure à réveiller en cas de changements. * -* data = donnée à faire suivre. * -* * -* Description : Prépare le terrain pour l'affichage central. * -* * -* Retour : Composant de support sur lequel tout va se placer. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *init_panels2(GCallback handler, gpointer data) -{ - GtkWidget *result; /* Support à retourner */ - - result = gtk_event_box_new(); - gtk_widget_show(result); - - //g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL); - - _support = result; - _handler = handler; - _data = data; - - return result; + g_signal_emit_by_name(item, "dock-request"); } /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : item = composant d'affichage à mettre à jour. * +* status = nouvel état d'encapsulation. * * * -* Description : Charge les principaux panneaux de l'éditeur. * +* Description : Définit si le composant repose sur un support de l'éditeur. * * * * Retour : - * * * @@ -581,81 +325,37 @@ GtkWidget *init_panels2(GCallback handler, gpointer data) * * ******************************************************************************/ -void load_main_panels(GObject *ref) +void g_panel_item_set_dock_status(GPanelItem *item, bool status) { - GPanelItem *item; /* Panneau de base à charger */ - - item = create_log_panel(ref); - g_panel_item_dock(item); - - item = create_regedit_panel(ref); - g_panel_item_dock(item); - - item = create_symbols_panel(ref); - g_panel_item_dock(item); - - item = create_history_panel(ref); - g_panel_item_dock(item); - - item = create_strings_panel(ref); - g_panel_item_dock(item); - - item = create_glance_panel(ref); - g_panel_item_dock(item); - - item = create_bookmarks_panel(ref); - g_panel_item_dock(item); + item->docked = status; } /****************************************************************************** * * -* Paramètres : handle = routine à appeler pour chaque panneau. * -* data = données fournies pour accompagner cet appel. * +* Paramètres : item = composant d'affichage à consulter. * * * -* Description : Effectue le parcours de tous les panneaux chargés. * +* Description : Indique si le composant repose sur un support de l'éditeur. * * * -* Retour : true si le parcours a été total, false sinon. * +* Retour : true si le composant est bien incrusté quelque part. * * * * Remarques : - * * * ******************************************************************************/ -bool browse_all_item_panels(handle_panel_item_fc handle, void *data) +bool g_panel_item_is_docked(const GPanelItem *item) { - bool result; /* Résultat à renvoyer */ - GPanelItem *iter; /* Boucle de parcours */ - - result = true; - - panels_list_for_each(iter, _panels_list) - { - result = handle(iter, data); - - if (!result) break; - - } - - return result; + return item->docked; } - -/* ---------------------------------------------------------------------------------- */ -/* MECANISMES DE PLACEMENT DES PANNEAUX */ -/* ---------------------------------------------------------------------------------- */ - - - /****************************************************************************** * * -* Paramètres : node = noeud à diviser. * -* horiz = indique le type d'orientation désiré. * -* first = indication sur l'emplacement à utiliser. * +* Paramètres : item = composant à retirer de l'affichage. * * * -* Description : Prépare une nouvelle sous-division pour deux panneaux. * +* Description : Supprime un panneau de l'ensemble affiché. * * * * Retour : - * * * @@ -663,632 +363,10 @@ bool browse_all_item_panels(handle_panel_item_fc handle, void *data) * * ******************************************************************************/ -static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool first) +void g_panel_item_undock(GPanelItem *item) { - GtkWidget *widget; /* Composant à traiter */ - panel_node *parent; /* Lien de parenté à conserver */ - panel_node *moved; /* Noeud descendu d'un étage */ - - /* Décroche graphiquement le support */ - - widget = node->widget; - - g_object_ref(G_OBJECT(widget)); - gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); - - /* Descend l'élément actuel */ - - parent = node->parent; - - moved = (panel_node *)calloc(1, sizeof(panel_node)); - - memcpy(moved, node, sizeof(panel_node)); - - if (!IS_SIMPLE_NODE(moved)) - { - moved->first->parent = moved; - moved->second->parent = moved; - } - - /* Création du nouveau niveau intermédiaire */ - - if (horiz) - node->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); - else - node->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL); - - gtk_widget_show(node->paned); - - if (parent == NULL) - attach_panel_node_to_paned(parent, node, true); - else - attach_panel_node_to_paned(parent, node, parent->first == node); - - - - - /* Premier ajustement */ - - void split_paned_support(GtkWidget *support, GdkRectangle *alloc, gpointer data) - { - GtkOrientation orientation; - gint position; - - orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(support)); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - position = alloc->width / 2; - else - position = alloc->height / 2; - - /* - if (position < 50) - position *= 2; - */ - - gtk_paned_set_position(GTK_PANED(support), position); - - fprintf(stderr, "widget size is currently %dx%d\n", alloc->width, alloc->height); - - - fprintf(stderr, "position = %d\n", position); - - fprintf(stderr, "---\n"); - - - g_signal_handlers_disconnect_by_func(support, G_CALLBACK(split_paned_support), NULL); - - } - - //g_signal_connect(current->paned, "size-allocate", G_CALLBACK(split_paned_support), NULL); - - static int __counter = 0; - - - - if (++__counter == 4) - gtk_paned_set_position(GTK_PANED(node->paned), 100); - - - - - /* Replace le composant d'origine */ + assert(item->docked); - attach_panel_node_to_paned(node, moved, first); + g_signal_emit_by_name(item, "undock-request"); } - - -/****************************************************************************** -* * -* Paramètres : parent = noeud d'accueil pour le nouveau noeud. * -* node = nouveau noeud à intégrer dans l'ensemble. * -* first = indication sur l'emplacement à utiliser. * -* * -* Description : Met en place un nouveau noeud dans une division. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, bool first) -{ - node->parent = parent; - - /* On se trouve à la racine... */ - - if (parent == NULL) - gtk_container_add(GTK_CONTAINER(_support), node->widget); - - else - { - /* Raccordement hiérarchique */ - - if (first) - parent->first = node; - else - parent->second = node; - - /* Raccordement graphique */ - - assert(!IS_SIMPLE_NODE(parent)); - - if (first) - gtk_paned_pack1(GTK_PANED(parent->paned), node->widget, TRUE, FALSE); - else - gtk_paned_pack2(GTK_PANED(parent->paned), node->widget, TRUE, FALSE); - - } - -} - - - - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : item = composant à présenter à l'affichage. * -* path = partie du chemin représentée ici. * -* * -* Description : Crée un nouveau noeud pour un panneau particulier. * -* * -* Retour : Structure d'accueil mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path) -{ - panel_node *result; /* Structure à retourner */ - GtkWidget *station; /* Premier support concentré */ - - /* Partie graphique */ - - station = gtk_dock_station_new(); - g_signal_connect(station, "switch-widget", _handler, _data); - gtk_widget_show(station); - - gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item)); - - /* Partie invisible */ - - result = (panel_node *)calloc(1, sizeof(panel_node)); - - result->station = station; - - result->path = strdup(path); - - return result; - -} - - - - - - - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : node = noeud dont la désignation est à obtenir. * -* * -* Description : Obtient la désignation d'un élément hiérarchie des noeuds. * -* * -* Retour : Chaîne construite à libérer de la mémoire après usage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *get_panel_node_path(const panel_node *node) -{ - char *result; /* Valeur à retourner */ - char *extra; /* Complément à ajouter */ - - if (IS_SIMPLE_NODE(node)) - result = strdup(node->path); - - else - { - result = get_panel_node_path(node->first); - - extra = get_panel_node_path(node->second); - result = stradd(result, "-"); - result = stradd(result, extra); - free(extra); - - result = strprep(result, "("); - result = stradd(result, ")"); - - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud d'où lancer les recherches. * -* target = identifiant de la position visée. * -* * -* Description : Détermine la plus grande longueur commune entre éléments. * -* * -* Retour : Bilan de l'évaluation. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static size_t compute_path_common_length(const panel_node *node, const char *target) -{ - size_t result; /* Taille à retourner */ - size_t len; /* Longueur de comparaison */ - size_t common1; /* Tron common avec le côté #1 */ - size_t common2; /* Tron common avec le côté #2 */ - - if (IS_SIMPLE_NODE(node)) - { - len = MIN(strlen(node->path), strlen(target)); - - /** - * Il n'y a pas forcément de base commune entre deux branches, - * donc on parcourt les chemins depuis leur base respective. - */ - for (result = 0; result < len; result++) - if (node->path[result] != target[result]) - break; - - } - - else - { - common1 = compute_path_common_length(node->first, target); - common2 = compute_path_common_length(node->second, target); - - result = MAX(common1, common2); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud d'où lancer les mesures. * -* * -* Description : Détermine la plus grande profondeur d'un noeud de panneaux. * -* * -* Retour : Valeur strictement positive. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static unsigned int compute_deepest_depth(const panel_node *node) -{ - unsigned int result; /* Profondeur à renvoyer */ - unsigned int depth1; /* Profondeur du côté #1 */ - unsigned int depth2; /* Profondeur du côté #2 */ - - if (IS_SIMPLE_NODE(node)) - result = 1; - - else - { - depth1 = compute_deepest_depth(node->first); - depth2 = compute_deepest_depth(node->second); - - result = MAX(depth1, depth2); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = composant à présenter à l'affichage. * -* node = point d'insertion courant. * -* path = partie du chemin représentée ici. * -* consumed = profondeur du chemin utilisé. * -* * -* Description : Place au bon endroit un panneau donné. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t consumed) -{ - char div; /* Division demandée */ - bool horiz; /* Traduction en composant */ - bool first; /* Point d'insertion */ - panel_node *new; /* Nouveau noeud créé */ - size_t common1; /* Tron common avec le côté #1 */ - size_t common2; /* Tron common avec le côté #2 */ - - - fprintf(stderr, "=== INSERTING '%s' (%zu)... -> '%s'\n", path, consumed, - IS_SIMPLE_NODE(node) ? node->path : "-"); - - - - if (IS_SIMPLE_NODE(node)) - { - /* Le parcours s'arrête ici ! */ - if (strcmp(node->path, path) == 0) - gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item)); - - /* On ne peut aller plus loin, on doit diviser... */ - else - { - div = toupper(path[consumed]); - first = (div == 'W' || div == 'N'); - horiz = (div == 'W' || div == 'E'); - - fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz); - - fprintf(stderr, "--- cutting %p\n", node->station); - - switch_panel_node_into_paned(node, horiz, !first); - - new = create_simple_panel_node_for_item(item, path); - - attach_panel_node_to_paned(node, new, first); - - - fprintf(stderr, "1# [%p] widget = %p --- split :: %p // %p\n", - node, node->station, node->first, node->second); - - } - - } - - /* On regarde des autres côtés... */ - - else - { - common1 = compute_path_common_length(node->first, path); - common2 = compute_path_common_length(node->second, path); - - - fprintf(stderr, " - L1 :: %zu <-> '%s'\n", common1, get_panel_node_path(node->first)); - fprintf(stderr, " - L2 :: %zu <-> '%s'\n", common2, get_panel_node_path(node->second)); - - - /* Si une descente est possible... */ - if (common1 > 0 || common2 > 0) - { - if (common1 > common2) - insert_item_as_panel_node(item, node->first, path, common1); - - else - insert_item_as_panel_node(item, node->second, path, common2); - - } - - /* Sinon, on doit diviser qqch... */ - else - { - div = toupper(path[consumed]); - first = (div == 'W' || div == 'N'); - horiz = (div == 'W' || div == 'E'); - - fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz); - - switch_panel_node_into_paned(node, horiz, !first); - - new = create_simple_panel_node_for_item(item, path); - - attach_panel_node_to_paned(node, new, first); - - - fprintf(stderr, "2# [%p] split :: %p-%p // %p-%p\n", node, - node->first, node->first->widget, - node->second, node->second->widget); - - } - - } - -} - - -/****************************************************************************** -* * -* Paramètres : node = point de départ des recherches locales. * -* * -* Description : Tente de mettre la main sur une station d'accueil. * -* * -* Retour : Eventuel noeud trouvé ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static panel_node *find_node_for_station(panel_node *node, GtkWidget *station) -{ - panel_node *result; /* Bilan à remonter */ - - if (IS_SIMPLE_NODE(node)) - result = (node->station == station ? node : NULL); - - else - { - result = find_node_for_station(node->first, station); - - if (result == NULL) - result = find_node_for_station(node->second, station); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud à supprimer de l'arbre des noeuds. * -* * -* Description : Efface de l'organisation un noeud donné en place. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void delete_panel_node(panel_node *node) -{ - panel_node *parent; /* Noeud parent à transformer */ - GtkWidget *widget; /* Composant à traiter */ - panel_node *grandparent; /* Noeud supérieur au parent */ - panel_node *remaining; /* Noeud restant */ - - assert(IS_SIMPLE_NODE(node)); - - parent = node->parent; - - /* Destruction du noeud */ - - widget = node->station; - gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); - - free(node->path); - - free(node); - - /* Suppression du niveau intermédiaire */ - - if (parent != NULL) - { - remaining = (node == parent->first ? parent->second : parent->first); - - /* Décroche graphiquement le support */ - - widget = remaining->widget; - - g_object_ref(G_OBJECT(widget)); - gtk_container_remove(GTK_CONTAINER(parent->paned), widget); - - /* Supprime le composant graphique intermédiaire */ - - gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(parent->paned)), parent->paned); - - /* Réinsère la partie restante */ - - grandparent = parent->parent; - - memcpy(parent, remaining, sizeof(panel_node)); - - if (!IS_SIMPLE_NODE(parent)) - { - parent->first->parent = parent; - parent->second->parent = parent; - } - - free(remaining); - - if (grandparent == NULL) - attach_panel_node_to_paned(grandparent, parent, true); - else - attach_panel_node_to_paned(grandparent, parent, grandparent->first == parent); - - } - -} - - - - - - - - - - - - - - -#if 1 - - -#include "../../core/params.h" - - - -/****************************************************************************** -* * -* Paramètres : current = point de départ de la réorganisation graphique. * -* * -* Description : Met à jour l'affichage suite à un changement hiérarchique. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void save_panel_nodes(void) -{ - - - fprintf(stderr, "Passage avec %p\n", _nodes); - - return; - void store_handle_position(panel_node *node, GGenConfig *config) - { - - size_t i; - - for (i = 0; i < 0/*node->depth*/; i++) - fprintf(stderr, " "); - - - ///fprintf(stderr, "[%s] %s\n", node->path, node->simple ? "[+]" : ">>"); - - - if (0/*!node->simple*/) - { - store_handle_position(node->first, config); - store_handle_position(node->second, config); - } - - - } - - - //get_main_configuration() - - - store_handle_position(_nodes, NULL); - - fflush(NULL); - - -} - -#endif - - diff --git a/src/gui/panels/panel.h b/src/gui/panels/panel.h index baf5fe7..bb46c5a 100644 --- a/src/gui/panels/panel.h +++ b/src/gui/panels/panel.h @@ -66,20 +66,23 @@ typedef enum _PanelItemPersonality GType g_panel_item_get_type(void); /* Crée un élément de panneau réactif. */ -GEditorItem *g_panel_item_new(PanelItemPersonality, GObject *, const char *, const char *, GtkWidget *, const char *); +GPanelItem *g_panel_item_new(PanelItemPersonality, const char *, const char *, GtkWidget *, const char *); /* Fournit une indication sur la personnalité du panneau. */ PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *); +/* Fournit le chemin d'accès à utiliser pour les encapsulations. */ +const char *gtk_panel_item_get_path(const GPanelItem *); + /* Indique la définition d'un éventuel raccourci clavier. */ const char *gtk_panel_item_get_key_bindings(const GPanelItem *); -/* Recherche un panneau à partir de son nom court. */ -GPanelItem *g_panel_item_get(const char *); - /* Place un panneau dans l'ensemble affiché. */ void g_panel_item_dock(GPanelItem *); +/* Définit si le composant repose sur un support de l'éditeur. */ +void g_panel_item_set_dock_status(GPanelItem *, bool); + /* Indique si le composant repose sur un support de l'éditeur. */ bool g_panel_item_is_docked(const GPanelItem *); @@ -88,33 +91,4 @@ void g_panel_item_undock(GPanelItem *); - - - - -void save_panel_nodes(void); - - - - - - -/* ----------------------- PLACEMENTS DES DIFFERENTS PANNEAUX ----------------------- */ - - -/* Prépare le terrain pour l'affichage central. */ -GtkWidget *init_panels2(GCallback, gpointer); - -/* Charge les principaux panneaux de l'éditeur. */ -void load_main_panels(GObject *); - - -/* Réalise un traitement sur un panneau de l'éditeur. */ -typedef bool (* handle_panel_item_fc) (GPanelItem *, void *); - -/* Effectue le parcours de tous les panneaux chargés. */ -bool browse_all_item_panels(handle_panel_item_fc, void *); - - - #endif /* _GUI_PANELS_PANEL_H */ diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c index cb4fe85..a62f824 100644 --- a/src/gui/panels/regedit.c +++ b/src/gui/panels/regedit.c @@ -215,8 +215,20 @@ static void g_regedit_panel_init(GRegeditPanel *panel) GtkTreeViewColumn *column; /* Colonne de la liste */ GtkTreeSortable *sortable; /* Autre vision de la liste */ + /* 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->path = "N"; + + /* Représentation graphique */ + base->widget = gtk_grid_new(); gtk_widget_show(base->widget); @@ -225,10 +237,6 @@ static void g_regedit_panel_init(GRegeditPanel *panel) ref = G_OBJECT(base->widget); g_object_set_data(ref, "panel", panel); - pitem = G_PANEL_ITEM(panel); - - pitem->personality = PIP_SINGLETON; - /* Partie recherche */ label = qck_create_label(NULL, NULL, _("Look for:")); @@ -374,7 +382,7 @@ static void g_regedit_panel_finalize(GRegeditPanel *panel) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : - * * * * Description : Crée un panneau d'affichage des paramètres de configuration. * * * @@ -384,15 +392,12 @@ static void g_regedit_panel_finalize(GRegeditPanel *panel) * * ******************************************************************************/ -GEditorItem *g_regedit_panel_new(GObject *ref) +GPanelItem *g_regedit_panel_new(void) { - GEditorItem *result; /* Structure à retourner */ + GPanelItem *result; /* Structure à retourner */ result = g_object_new(G_TYPE_REGEDIT_PANEL, NULL); - g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_REGEDIT_ID, - _("Configuration parameters"), G_EDITOR_ITEM(result)->widget, "N"); - reload_config_into_treeview(G_REGEDIT_PANEL(result), get_main_configuration()); return result; @@ -400,32 +405,6 @@ GEditorItem *g_regedit_panel_new(GObject *ref) } -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Construit le panneau d'affichage des messages système. * -* * -* Retour : Adresse du panneau mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *create_regedit_panel(GObject *ref) -{ - GEditorItem *result; /* Elément réactif à renvoyer */ - - result = g_regedit_panel_new(ref); - - /* Enregistre correctement le tout */ - register_editor_item(result); - - return G_PANEL_ITEM(result); - -} - - /* ---------------------------------------------------------------------------------- */ /* AFFICHAGE A L'AIDE D'UNE LISTE */ diff --git a/src/gui/panels/regedit.h b/src/gui/panels/regedit.h index 7166168..1cf5842 100644 --- a/src/gui/panels/regedit.h +++ b/src/gui/panels/regedit.h @@ -55,10 +55,7 @@ typedef struct _GRegeditPanelClass GRegeditPanelClass; GType g_regedit_panel_get_type(void); /* Crée un panneau d'affichage des paramètres de configuration. */ -GEditorItem *g_regedit_panel_new(GObject *); - -/* Construit le panneau d'affichage des messages système. */ -GPanelItem *create_regedit_panel(GObject *); +GPanelItem *g_regedit_panel_new(void); diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c index 9759e71..0c39b4b 100644 --- a/src/gui/panels/strings.c +++ b/src/gui/panels/strings.c @@ -223,8 +223,20 @@ static void g_strings_panel_init(GStringsPanel *panel) GtkTreeSelection *select; /* Sélection dans la liste */ bool display; /* Affichage si sélection ? */ + /* 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->path = "SE"; + + /* Représentation graphique */ + base->widget = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(base->widget); @@ -234,10 +246,6 @@ static void g_strings_panel_init(GStringsPanel *panel) ref = G_OBJECT(base->widget); g_object_set_data(ref, "panel", panel); - pitem = G_PANEL_ITEM(panel); - - pitem->personality = PIP_SINGLETON; - /* Partie chaînes */ store = gtk_tree_store_new(STC_COUNT, G_TYPE_OBJECT, @@ -408,7 +416,7 @@ static void g_strings_panel_finalize(GStringsPanel *panel) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : - * * * * Description : Crée un panneau d'affichage des chaînes. * * * @@ -418,46 +426,17 @@ static void g_strings_panel_finalize(GStringsPanel *panel) * * ******************************************************************************/ -GEditorItem *g_strings_panel_new(GObject *ref) +GPanelItem *g_strings_panel_new(void) { - GEditorItem *result; /* Structure à retourner */ + GPanelItem *result; /* Structure à retourner */ result = g_object_new(G_TYPE_STRINGS_PANEL, NULL); - g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_STRINGS_ID, - _("Strings"), G_EDITOR_ITEM(result)->widget, "SE"); - return result; } -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Construit et intègre un panneau d'affichage des chaînes. * -* * -* Retour : Adresse du panneau mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *create_strings_panel(GObject *ref) -{ - GEditorItem *result; /* Elément réactif à renvoyer */ - - result = g_strings_panel_new(ref); - - /* Enregistre correctement le tout */ - register_editor_item(result); - - return G_PANEL_ITEM(result); - -} - - /* ---------------------------------------------------------------------------------- */ /* AFFICHAGE A L'AIDE D'UNE LISTE */ diff --git a/src/gui/panels/strings.h b/src/gui/panels/strings.h index 556dcbe..4655cf7 100644 --- a/src/gui/panels/strings.h +++ b/src/gui/panels/strings.h @@ -55,10 +55,7 @@ typedef struct _GStringsPanelClass GStringsPanelClass; GType g_strings_panel_get_type(void); /* Crée un panneau d'affichage des chaînes. */ -GEditorItem *g_strings_panel_new(GObject *); - -/* Construit et intègre un panneau d'affichage des chaînes. */ -GPanelItem *create_strings_panel(GObject *); +GPanelItem *g_strings_panel_new(void); diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index eebfc4c..1b7453b 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -249,18 +249,26 @@ static void g_symbols_panel_init(GSymbolsPanel *panel) GtkTreeViewColumn *column; /* Colonne de la liste */ GtkTreeSelection *select; /* Sélection dans la liste */ + /* 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->path = "eN"; + + /* Représentation graphique */ + base->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); gtk_widget_show(base->widget); ref = G_OBJECT(base->widget); g_object_set_data(ref, "panel", panel); - pitem = G_PANEL_ITEM(panel); - - pitem->personality = PIP_SINGLETON; - /* Barre d'outils supérieure */ box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); @@ -429,7 +437,7 @@ static void g_symbols_panel_finalize(GSymbolsPanel *panel) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : - * * * * Description : Crée un panneau d'affichage des symboles. * * * @@ -439,15 +447,12 @@ static void g_symbols_panel_finalize(GSymbolsPanel *panel) * * ******************************************************************************/ -GEditorItem *g_symbols_panel_new(GObject *ref) +GPanelItem *g_symbols_panel_new(void) { - GEditorItem *result; /* Structure à retourner */ + GPanelItem *result; /* Structure à retourner */ result = g_object_new(G_TYPE_SYMBOLS_PANEL, NULL); - g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_SYMBOLS_ID, - _("Binary symbols"), G_EDITOR_ITEM(result)->widget, "eN"); - return result; } @@ -455,32 +460,6 @@ GEditorItem *g_symbols_panel_new(GObject *ref) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Construit et intègre un panneau d'affichage des symboles. * -* * -* Retour : Adresse du panneau mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *create_symbols_panel(GObject *ref) -{ - GEditorItem *result; /* Elément réactif à renvoyer */ - - result = g_symbols_panel_new(ref); - - /* Enregistre correctement le tout */ - register_editor_item(result); - - return G_PANEL_ITEM(result); - -} - - -/****************************************************************************** -* * * Paramètres : button = bouton de la barre activé. * * panel = structure contenant les informations maîtresses. * * * diff --git a/src/gui/panels/symbols.h b/src/gui/panels/symbols.h index 3da964c..ea947ea 100644 --- a/src/gui/panels/symbols.h +++ b/src/gui/panels/symbols.h @@ -55,10 +55,7 @@ typedef struct _GSymbolsPanelClass GSymbolsPanelClass; GType g_symbols_panel_get_type(void); /* Crée un panneau d'affichage des symboles. */ -GEditorItem *g_symbols_panel_new(GObject *); - -/* Construit et intègre un panneau d'affichage des symboles. */ -GPanelItem *create_symbols_panel(GObject *); +GPanelItem *g_symbols_panel_new(void); -- cgit v0.11.2-87-g4458