diff options
| -rw-r--r-- | ChangeLog | 51 | ||||
| -rw-r--r-- | plugins/pychrysa/gui/panels/panel.c | 43 | ||||
| -rw-r--r-- | plugins/python/welcome/panel.py | 2 | ||||
| -rw-r--r-- | src/analysis/project.c | 2 | ||||
| -rw-r--r-- | src/gtkext/gtkdockable.c | 35 | ||||
| -rw-r--r-- | src/gtkext/gtkdockable.h | 5 | ||||
| -rw-r--r-- | src/gtkext/gtkdockstation.c | 183 | ||||
| -rw-r--r-- | src/gtkext/gtkdockstation.h | 9 | ||||
| -rw-r--r-- | src/gtkext/gtkviewpanel.c | 4 | ||||
| -rw-r--r-- | src/gui/editem.c | 21 | ||||
| -rw-r--r-- | src/gui/editem.h | 3 | ||||
| -rw-r--r-- | src/gui/menus/menubar.c | 2 | ||||
| -rw-r--r-- | src/gui/menus/project.c | 2 | ||||
| -rw-r--r-- | src/gui/menus/view.c | 168 | ||||
| -rw-r--r-- | src/gui/panels/bookmarks.c | 5 | ||||
| -rw-r--r-- | src/gui/panels/glance.c | 10 | ||||
| -rw-r--r-- | src/gui/panels/history.c | 7 | ||||
| -rw-r--r-- | src/gui/panels/log.c | 22 | ||||
| -rw-r--r-- | src/gui/panels/panel-int.h | 38 | ||||
| -rw-r--r-- | src/gui/panels/panel.c | 929 | ||||
| -rw-r--r-- | src/gui/panels/panel.h | 46 | ||||
| -rw-r--r-- | src/gui/panels/regedit.c | 7 | ||||
| -rw-r--r-- | src/gui/panels/strings.c | 11 | ||||
| -rw-r--r-- | src/gui/panels/symbols.c | 13 | 
24 files changed, 1111 insertions, 507 deletions
| @@ -1,3 +1,54 @@ +16-03-08  Cyrille Bagard <nocbos@gmail.com> + +	* plugins/pychrysa/gui/panels/panel.c: +	Register new constants for panels. + +	* plugins/python/welcome/panel.py: +	* src/analysis/project.c: +	Update code. + +	* src/gtkext/gtkdockable.c: +	* src/gtkext/gtkdockable.h: +	Provide references of dockable items for UI. + +	* src/gtkext/gtkdockstation.c: +	* src/gtkext/gtkdockstation.h: +	Inherit from GtkNotebook directly for dock stations. Dock and undock +	widgets. + +	* src/gtkext/gtkviewpanel.c: +	Disable some code. + +	* src/gui/editem.c: +	* src/gui/editem.h: +	Provide editor item name for external usage. + +	* src/gui/menus/menubar.c: +	Store the global accelerator group. + +	* src/gui/menus/project.c: +	Typo. + +	* src/gui/menus/view.c: +	Load a dynamic list of dockable panels in the View menu. Dock and undock +	panels on demand. + +	* src/gui/panels/bookmarks.c: +	* src/gui/panels/glance.c: +	* src/gui/panels/history.c: +	* src/gui/panels/log.c: +	Update code. + +	* src/gui/panels/panel-int.h: +	* src/gui/panels/panel.c: +	* src/gui/panels/panel.h: +	Give a personality to each panel. Rewrite the tree of docked widgets. + +	* src/gui/panels/regedit.c: +	* src/gui/panels/strings.c: +	* src/gui/panels/symbols.c: +	Update code. +  16-03-05  Cyrille Bagard <nocbos@gmail.com>  	* src/arch/arm/v7/helpers.h: diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c index 3170a66..8046c0e 100644 --- a/plugins/pychrysa/gui/panels/panel.c +++ b/plugins/pychrysa/gui/panels/panel.c @@ -32,6 +32,7 @@  #include "../editem.h" +#include "../../helpers.h"  #include "../../quirks.h" @@ -42,6 +43,9 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds);  /* Place un panneau dans l'ensemble affiché. */  static PyObject *py_panel_item_dock(PyObject *, PyObject *); +/* Définit les constantes pour les panneaux. */ +static bool py_panel_item_define_constants(PyTypeObject *); +  /****************************************************************************** @@ -60,6 +64,7 @@ static PyObject *py_panel_item_dock(PyObject *, PyObject *);  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 */ @@ -67,10 +72,10 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds)      int ret;                                /* Bilan de lecture des args.  */      GEditorItem *item;                      /* Elément de l'éditeur        */ -    ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path); +    ret = PyArg_ParseTuple(args, "kssOs", &personality, &name, &lname, &widget, &path);      if (!ret) return -1; -    item = g_panel_item_new(get_internal_ref(), name, lname, +    item = g_panel_item_new(personality, get_internal_ref(), name, lname,                              GTK_WIDGET(pygobject_get(widget)), path);      /* Enregistrement auprès de PyGObject */ @@ -161,6 +166,37 @@ PyTypeObject *get_python_panel_item_type(void)  /******************************************************************************  *                                                                             * +*  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        * +*                                                                             * +*  Description : Définit les constantes pour les panneaux.                    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool py_panel_item_define_constants(PyTypeObject *obj_type) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = true; + +    result &= PyDict_AddIntMacro(obj_type, PIP_INVALID); + +    result &= PyDict_AddIntMacro(obj_type, PIP_SINGLETON); +    result &= PyDict_AddIntMacro(obj_type, PIP_BINARY_VIEW); +    result &= PyDict_AddIntMacro(obj_type, PIP_OTHER); + +    result &= PyDict_AddIntMacro(obj_type, PIP_COUNT); + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : module = module dont la définition est à compléter.          *  *                                                                             *  *  Description : Prend en charge l'objet 'pychrysalide.gui.panels.PanelItem'. * @@ -185,6 +221,9 @@ bool register_python_panel_item(PyObject *module)      if (PyType_Ready(py_panel_item_type) != 0)          return false; +    if (!py_panel_item_define_constants(py_panel_item_type)) +        return false; +      Py_INCREF(py_panel_item_type);      ret = PyModule_AddObject(module, "PanelItem", (PyObject *)py_panel_item_type);      if (ret != 0) return false; diff --git a/plugins/python/welcome/panel.py b/plugins/python/welcome/panel.py index 811f008..7b46c57 100644 --- a/plugins/python/welcome/panel.py +++ b/plugins/python/welcome/panel.py @@ -19,7 +19,7 @@ class WelcomePanel(PanelItem):          content = self._build_panel_content() -        super(WelcomePanel, self).__init__('Welcome', 'First commands', content, 'M') +        super(WelcomePanel, self).__init__(PanelItem.PIP_SINGLETON, 'Welcome', 'First commands', content, 'N')      def _build_panel_content(self): diff --git a/src/analysis/project.c b/src/analysis/project.c index b787262..623779b 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -666,7 +666,7 @@ 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(project->ref, name, lname, scroll, "M"); +    loaded->item = g_panel_item_new(PIP_BINARY_VIEW, project->ref, name, lname, scroll, "N");      /* Enregistrement dans le projet */ diff --git a/src/gtkext/gtkdockable.c b/src/gtkext/gtkdockable.c index 954b651..98b1a04 100644 --- a/src/gtkext/gtkdockable.c +++ b/src/gtkext/gtkdockable.c @@ -241,7 +241,7 @@ bool gtk_dockable_can_be_closed(const GtkDockable *dockable)  *                                                                             *  ******************************************************************************/ -GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable) +GtkWidget *gtk_dockable_build_widget(GtkDockable *dockable)  {      GtkWidget *result;                      /* Composant à retourner       */      GtkDockableIface *iface;                /* Interface utilisée          */ @@ -286,6 +286,39 @@ GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable)  /******************************************************************************  *                                                                             *  *  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    * +*                support  = composant à partir duquel décrocher ou NULL. [OUT]* +*                                                                             * +*  Description : Fournit tous les éléments pour un retrait graphique.         * +*                                                                             * +*  Retour      : Composant graphique à décrocher.                             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GtkWidget *gtk_dockable_decompose(GtkDockable *dockable, GtkWidget **support) +{ +    GtkWidget *result;                      /* Composant à retourner       */ +    GtkDockableIface *iface;                /* Interface utilisée          */ + +    iface = GTK_DOCKABLE_GET_IFACE(dockable); + +    result = iface->get_widget(dockable); + +    if (iface->can_search) +        result = gtk_widget_get_parent(result);     /* GtkBox */ + +    if (support != NULL) +        *support = gtk_widget_get_parent(result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *  *                built    = composant graphique d'encapsulation mis en place. *  *                reveal   = détermine l'action à mener.                       *  *                                                                             * diff --git a/src/gtkext/gtkdockable.h b/src/gtkext/gtkdockable.h index e939fad..31a3310 100644 --- a/src/gtkext/gtkdockable.h +++ b/src/gtkext/gtkdockable.h @@ -62,7 +62,10 @@ const char *gtk_dockable_get_name(const GtkDockable *);  const char *gtk_dockable_get_desc(const GtkDockable *);  /* Fournit le composant graphique intégrable dans un ensemble. */ -GtkWidget *gtk_dockable_get_widget(GtkDockable *); +GtkWidget *gtk_dockable_build_widget(GtkDockable *); + +/* Fournit tous les éléments pour un retrait graphique. */ +GtkWidget *gtk_dockable_decompose(GtkDockable *, GtkWidget **);  /* Révèle ou cache la zone de recherches. */  void gtk_dockable_toggle_revealer(GtkDockable *, GtkWidget *, gboolean); diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c index e10e55f..35006ef 100644 --- a/src/gtkext/gtkdockstation.c +++ b/src/gtkext/gtkdockstation.c @@ -57,7 +57,7 @@ static void on_toggle_revealer(GtkToggleButton *, GtkDockStation *);  /* Détermine le type du composant d'affichage concentré. */ -G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_BOX) +G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_NOTEBOOK)  /****************************************************************************** @@ -115,53 +115,14 @@ static void gtk_dock_station_class_init(GtkDockStationClass *class)  static void gtk_dock_station_init(GtkDockStation *station)  { -    GtkWidget *eventbox;                    /* Réceptacle actif            */ +    GtkNotebook *notebook;                  /* Autre version du composant  */      GtkWidget *hbox;                        /* Division supérieure         */      GtkWidget *button;                      /* Bouton de contrôle          */ -    GtkWidget *image;                       /* Image associée              */ -    gtk_orientable_set_orientation(GTK_ORIENTABLE(station), GTK_ORIENTATION_VERTICAL); +    notebook = GTK_NOTEBOOK(station); -    eventbox = gtk_event_box_new(); -    gtk_widget_show(eventbox); -    //gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0); - -    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); -    gtk_widget_show(hbox); -    gtk_container_add(GTK_CONTAINER(eventbox), hbox); - -    station->title = GTK_LABEL(qck_create_label(NULL, NULL, "<b>titre</b>")); -    gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(station->title), TRUE, TRUE, 0); -    gtk_label_set_use_markup(station->title, TRUE); - -    button = gtk_button_new(); -    gtk_widget_show(button); -    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); -    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - -    image = gtk_image_new_from_icon_name("gtk-media-play", GTK_ICON_SIZE_MENU); -    gtk_widget_show(image); -    gtk_container_add(GTK_CONTAINER(button), image); -    gtk_widget_set_size_request(image, 10, 10); - -    button = gtk_button_new(); -    gtk_widget_show(button); -    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); -    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - -    image = gtk_image_new_from_icon_name("gtk-close", GTK_ICON_SIZE_MENU); -    gtk_widget_show(image); -    gtk_container_add(GTK_CONTAINER(button), image); -    gtk_widget_set_size_request(image, 10, 10); - - - - -    station->notebook = GTK_NOTEBOOK(gtk_notebook_new()); -    gtk_widget_show(GTK_WIDGET(station->notebook)); -    gtk_box_pack_start(GTK_BOX(station), GTK_WIDGET(station->notebook), TRUE, TRUE, 0); -    gtk_notebook_set_show_border(station->notebook, FALSE); -    gtk_notebook_set_scrollable(station->notebook, TRUE); +    gtk_notebook_set_show_border(notebook, FALSE); +    gtk_notebook_set_scrollable(notebook, TRUE);      /* Définition de la zone de contrôle */ @@ -188,9 +149,9 @@ static void gtk_dock_station_init(GtkDockStation *station)      gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);      gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); -    gtk_notebook_set_action_widget(station->notebook, hbox, GTK_PACK_END); +    gtk_notebook_set_action_widget(notebook, hbox, GTK_PACK_END); -    g_signal_connect(station->notebook, "switch-page", +    g_signal_connect(notebook, "switch-page",                       G_CALLBACK(gtk_dock_station_switch_panel), station);  } @@ -267,10 +228,8 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p  /******************************************************************************  *                                                                             * -*  Paramètres  : station = plateforme GTK à compléter.                        * -*                widget  = nouvel élément à intégrer.                         * -*                caption = intitulé court à afficher sur les onglets.         * -*                desc    = intitulé long pour le titre et la description.     * +*  Paramètres  : station  = plateforme GTK à compléter.                       * +*                dockable = nouvel élément à intégrer.                        *  *                                                                             *  *  Description : Ajoute un paquet d'informations à l'affichage centralisé.    *  *                                                                             * @@ -279,7 +238,8 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ - +#include "gtkviewpanel.h" +#include "../gui/panels/history.h"  void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable)  {      GtkWidget *widget;                      /* Composant GTK à intégrer    */ @@ -288,10 +248,34 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl      size_t max;                             /* Taille maximale des titres  */      char *str;                              /* Titre des prochaines fois   */      GtkWidget *label;                       /* Etiquette d'onglet          */ +    GtkNotebook *notebook;                  /* Autre version du composant  */      /* Récupération des éléments utiles */ -    widget = gtk_dockable_get_widget(dockable); +    widget = gtk_dockable_build_widget(dockable); + + +    if (strcmp(gtk_dockable_get_name(dockable), "History") == 0) +    { +        GtkRequisition req; + +        gtk_widget_get_preferred_size(widget, &req, NULL); +        fprintf(stderr, "Histo req :: %d x %d\n", req.width, req.height); + +    } + +    /* +    if (!GTK_IS_SCROLLED_WINDOW(widget) +        && ( +            strcmp(gtk_dockable_get_name(dockable), "History2") != 0 +            ) +        ) +        widget = gtk_button_new_with_label("123"); +    */ + +    //widget = gtk_button_new_with_label("123"); +    gtk_widget_show(widget); +      g_object_set_data(G_OBJECT(widget), "dockable", dockable); @@ -307,24 +291,52 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl      label = qck_create_label(NULL, NULL, str);      free(str); -    if (gtk_notebook_get_n_pages(station->notebook) > 0) -    g_signal_handlers_disconnect_by_func(station->notebook, +    notebook = GTK_NOTEBOOK(station); + +    if (gtk_notebook_get_n_pages(notebook) > 0) +    g_signal_handlers_disconnect_by_func(notebook,                                           G_CALLBACK(gtk_dock_station_switch_panel), station); -    gtk_notebook_insert_page(station->notebook, widget, label, -1); +    gtk_notebook_insert_page(notebook, widget, label, -1);      gtk_widget_set_tooltip_text(label, desc); -    if (gtk_notebook_get_n_pages(station->notebook) > 1) -    g_signal_connect(station->notebook, "switch-page", +    if (gtk_notebook_get_n_pages(notebook) > 1) +    g_signal_connect(notebook, "switch-page",                       G_CALLBACK(gtk_dock_station_switch_panel), station);      /* Lancement des mises à jour */ -    if (gtk_notebook_get_n_pages(station->notebook) > 1) -        gtk_notebook_set_current_page(station->notebook, -1); +    if (gtk_notebook_get_n_pages(notebook) > 1) +        gtk_notebook_set_current_page(notebook, -1); + + +    // Renéociation des tailles +    //gtk_widget_queue_resize(GTK_WIDGET(notebook)); + + +    if (false) +    { +        GtkRequisition req; + +        gtk_widget_get_preferred_size(GTK_WIDGET(notebook), &req, NULL); +        fprintf(stderr, "=== SUPPORT req :: %d x %d\n", req.width, req.height); + + +        gtk_widget_set_size_request(GTK_WIDGET(notebook), req.width, req.height); + + + +    } + + -    g_signal_emit_by_name(station, "dock-widget", widget); + + + + + +    //g_signal_emit_by_name(station, "dock-widget", widget);  } @@ -344,32 +356,35 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl  void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *widget)  { +    GtkNotebook *notebook;                  /* Autre version du composant  */      gint index;                             /* Indice de l'onglet actif    */      GtkWidget *old;                         /* Ancien composant            */      GtkWidget *label;                       /* Etiquette d'onglet          */      char *str;                              /* Titre des prochaines fois   */ -    index = gtk_notebook_get_current_page(station->notebook); +    notebook = GTK_NOTEBOOK(station); + +    index = gtk_notebook_get_current_page(notebook); -    g_signal_handlers_disconnect_by_func(station->notebook, +    g_signal_handlers_disconnect_by_func(notebook,                                           G_CALLBACK(gtk_dock_station_switch_panel), station); -    old = gtk_notebook_get_nth_page(station->notebook, index); -    label = gtk_notebook_get_tab_label(station->notebook, old); +    old = gtk_notebook_get_nth_page(notebook, index); +    label = gtk_notebook_get_tab_label(notebook, old);      g_object_ref(G_OBJECT(old));      g_object_ref(G_OBJECT(label));      str = g_object_get_data(G_OBJECT(old), "title"); -    gtk_notebook_remove_page(station->notebook, index); -    gtk_notebook_insert_page(station->notebook, widget, label, index); +    gtk_notebook_remove_page(notebook, index); +    gtk_notebook_insert_page(notebook, widget, label, index);      g_object_unref(G_OBJECT(label));      g_object_set_data(G_OBJECT(widget), "title", str); -    gtk_notebook_set_current_page(station->notebook, index); +    gtk_notebook_set_current_page(notebook, index); -    g_signal_connect(station->notebook, "switch-page", +    g_signal_connect(notebook, "switch-page",                       G_CALLBACK(gtk_dock_station_switch_panel), station);  } @@ -378,7 +393,7 @@ void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *wid  /******************************************************************************  *                                                                             *  *  Paramètres  : station = plateforme GTK à compléter.                        * -*                widget  = nouvel élément à intégrer.                         * +*                dockable = élément existant à retirer.                       *  *                                                                             *  *  Description : Retire un paquet d'informations de l'affichage centralisé.   *  *                                                                             * @@ -388,26 +403,19 @@ void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *wid  *                                                                             *  ******************************************************************************/ -void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget) +void gtk_dock_station_remove_dockable(GtkDockStation *station, GtkDockable *dockable)  { +    GtkNotebook *notebook;                  /* Autre version du composant  */ +    GtkWidget *widget;                      /* Composant GTK à retirer     */      gint index;                             /* Indice de l'onglet visé     */ -    gint count;                             /* Nombre d'onglets en place   */ +    notebook = GTK_NOTEBOOK(station); -    return; +    widget = gtk_dockable_decompose(dockable, NULL); +    index = gtk_notebook_page_num(notebook, widget); -    index = gtk_notebook_page_num(station->notebook, widget); - -    gtk_notebook_remove_page(station->notebook, index); - -    count = gtk_notebook_get_n_pages(station->notebook); - -    //gtk_notebook_set_show_tabs(station->notebook, count > 1); - -    if (count == 0) -        gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(station))), -                             GTK_WIDGET(station)); +    gtk_notebook_remove_page(notebook, index);  } @@ -427,7 +435,7 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget)  GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index)  { -    return gtk_notebook_get_nth_page(station->notebook, index); +    return gtk_notebook_get_nth_page(GTK_NOTEBOOK(station), index);  } @@ -447,12 +455,15 @@ GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index)  static void on_toggle_revealer(GtkToggleButton *button, GtkDockStation *station)  { +    GtkNotebook *notebook;                  /* Autre version du composant  */      gint index;                             /* Indice de l'onglet courant  */      GtkWidget *widget;                      /* Panneau concerné            */      GtkDockable *dockable;                  /* Elément encapsulé           */ -    index = gtk_notebook_get_current_page(station->notebook); -    widget = gtk_notebook_get_nth_page(station->notebook, index); +    notebook = GTK_NOTEBOOK(station); + +    index = gtk_notebook_get_current_page(notebook); +    widget = gtk_notebook_get_nth_page(notebook, index);      dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); diff --git a/src/gtkext/gtkdockstation.h b/src/gtkext/gtkdockstation.h index d64a0b8..953ceb8 100644 --- a/src/gtkext/gtkdockstation.h +++ b/src/gtkext/gtkdockstation.h @@ -51,17 +51,14 @@ typedef struct _GtkDockStationClass GtkDockStationClass;  /* Station de réception pour concentration d'éléments (instance) */  struct _GtkDockStation  { -    GtkBox vbox;                            /* Présence obligatoire en 1er */ - -    GtkLabel *title;                        /* Title du support principal  */ -    GtkNotebook *notebook;                  /* Support à onglets           */ +    GtkNotebook parent;                     /* A laisser en premier        */  };  /* Station de réception pour concentration d'éléments (classe) */  struct _GtkDockStationClass  { -    GtkBoxClass parent_class;               /* Présence obligatoire en 1er */ +    GtkNotebookClass parent_class;          /* A laisser en premier        */      /* Signaux */ @@ -86,7 +83,7 @@ void gtk_dock_station_add_dockable(GtkDockStation *, GtkDockable *);  void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *);  /* Retire un paquet d'informations de l'affichage centralisé. */ -void gtk_dock_panel_remove_widget(GtkDockStation *, GtkWidget *); +void gtk_dock_station_remove_dockable(GtkDockStation *, GtkDockable *);  /* Renvoie un composant intégré dans l'affichage centralisé. */  GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *, gint); diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c index a347ad8..b7829c2 100644 --- a/src/gtkext/gtkviewpanel.c +++ b/src/gtkext/gtkviewpanel.c @@ -121,8 +121,8 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)      widget_class->realize = gtk_view_panel_realize;      widget_class->size_allocate = gtk_view_panel_size_allocate;      widget_class->draw = gtk_view_panel_draw; -    widget_class->get_preferred_height = gtk_view_panel_get_preferred_height; -    widget_class->get_preferred_width = gtk_view_panel_get_preferred_width; +    //widget_class->get_preferred_height = gtk_view_panel_get_preferred_height; +    //widget_class->get_preferred_width = gtk_view_panel_get_preferred_width;      panel_class->compute_inc = gtk_view_panel_compute_scroll_inc; diff --git a/src/gui/editem.c b/src/gui/editem.c index 1dc77c9..f4d9d71 100644 --- a/src/gui/editem.c +++ b/src/gui/editem.c @@ -131,9 +131,28 @@ GObject *g_editor_item_get_global_ref(const GEditorItem *item)  *                                                                             *  *  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      : -                                                            * +*  Retour      : Instance de composant graphique chargé.                      *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             * diff --git a/src/gui/editem.h b/src/gui/editem.h index 90b1919..08f76fa 100644 --- a/src/gui/editem.h +++ b/src/gui/editem.h @@ -59,6 +59,9 @@ GType g_editor_item_get_type(void);  /* Fournit l'adresse de l'espace de référencement global. */  GObject *g_editor_item_get_global_ref(const GEditorItem *); +/* 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 *); diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c index db1905c..e2ad155 100644 --- a/src/gui/menus/menubar.c +++ b/src/gui/menus/menubar.c @@ -208,6 +208,8 @@ GEditorItem *g_menu_bar_new(GObject *ref, GtkAccelGroup *accgroup)      result = g_object_new(G_TYPE_MENU_BAR, NULL); +    g_object_set_data(G_OBJECT(result), "accgroup", accgroup); +      /* Initialisation générique */      item = G_EDITOR_ITEM(result); diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c index f4f6233..9e43616 100644 --- a/src/gui/menus/project.c +++ b/src/gui/menus/project.c @@ -66,7 +66,7 @@ static void mcb_project_remove_binary(GtkMenuItem *, GStudyProject *);  GtkWidget *build_menu_project(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)  {      GtkWidget *result;                      /* Support à retourner         */ -    GtkWidget *menubar;                     /* Support pour éléments       */ +    GtkWidget *menubar;                     /* Support pour éléments #1    */      GtkWidget *submenuitem;                 /* Sous-élément de menu #1     */      GtkWidget *deepmenubar;                 /* Support pour éléments #2    */      GtkWidget *deepmenuitem;                /* Sous-élément de menu #2     */ diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c index cbfa9bf..e80077a 100644 --- a/src/gui/menus/view.c +++ b/src/gui/menus/view.c @@ -29,12 +29,19 @@  #include "../editem-int.h" +#include "../panels/panel.h"  #include "../../analysis/project.h"  #include "../../gtkext/easygtk.h"  #include "../../gtkext/gtkdockstation.h" +/* Réagit avec le menu "Affichage -> Panneaux latéraux". */ +static void mcb_view_update_side_panels_list(GtkMenuItem *, GMenuBar *); + +/* Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". */ +static void mcb_view_change_panel_docking(GtkCheckMenuItem *, GPanelItem *); +  /* Réagit avec le menu "Affichage -> Vue xxx". */  static void mcb_view_change_support(GtkRadioMenuItem *, GMenuBar *); @@ -63,8 +70,9 @@ static void mcb_view_show_full_screen(GtkCheckMenuItem *, GMenuBar *);  GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)  {      GtkWidget *result;                      /* Support à retourner         */ -    GtkWidget *menubar;                     /* Support pour éléments       */ +    GtkWidget *menubar;                     /* Support pour éléments #1    */      GtkWidget *submenuitem;                 /* Sous-élément de menu        */ +    GtkWidget *deepmenubar;                 /* Support pour éléments #2    */      GSList *rgroup;                         /* Groupe des boutons radio    */      result = gtk_menu_item_new_with_mnemonic(_("_View")); @@ -73,6 +81,20 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)      menubar = gtk_menu_new();      gtk_menu_item_set_submenu(GTK_MENU_ITEM(result), menubar); +    /* Affichage -> Panneaux latéraux */ + +    submenuitem = qck_create_menu_item(NULL, NULL, _("Side panels"), NULL, NULL); +    g_signal_connect(submenuitem, "select", G_CALLBACK(mcb_view_update_side_panels_list), bar); +    gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + +    deepmenubar = gtk_menu_new(); +    gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), deepmenubar); + +    /* - */ + +    submenuitem = qck_create_menu_separator(); +    gtk_container_add(GTK_CONTAINER(menubar), submenuitem); +      submenuitem = qck_create_radio_menu_item(ref, "textview", NULL, _("Text view"),                                               G_CALLBACK(mcb_view_change_support), bar);      add_accelerator_to_menu_item(submenuitem, "F2", accgroup); @@ -113,6 +135,8 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)      g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_BINARY));      gtk_container_add(GTK_CONTAINER(menubar), submenuitem); +    /* - */ +      submenuitem = qck_create_menu_separator();      gtk_container_add(GTK_CONTAINER(menubar), submenuitem); @@ -194,6 +218,148 @@ void update_menu_view_for_view(GtkWidget *widget, GtkViewPanel *view, GMenuBar *  /******************************************************************************  *                                                                             * +*  Paramètres  : menuitem = élément de menu sélectionné.                      * +*                bar      = barre de menu parente.                            * +*                                                                             * +*  Description : Réagit avec le menu "Affichage -> Panneaux latéraux".        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) +{ +    GtkWidget *menubar;                     /* Support pour éléments       */ +    GtkAccelGroup *accgroup;                /* Groupe de raccourcis        */ + +    typedef struct _panels_loading_filter +    { +        GtkContainer *support;              /* Support pour éléments       */ +        GtkAccelGroup *accel;               /* Groupe de raccourcis        */ + +        PanelItemPersonality personality;   /* Nature des éléments attendus*/ +        bool first;                         /* Premier ajout ?             */ + +    } panels_loading_filter; + +    panels_loading_filter pfilter; + + +    menubar = gtk_menu_item_get_submenu(menuitem); + +    /* Réinitialisation */ + +    void remove_panel_menu_item(GtkWidget *widget, GtkContainer *container) +    { +        gtk_container_remove(container, widget); + +    } + +    gtk_container_foreach(GTK_CONTAINER(menubar), (GtkCallback)remove_panel_menu_item, menubar); + +    /* Ajout des panneaux uniques */ + +    bool add_side_panel_to_list(GPanelItem *panel, panels_loading_filter *filter) +    { +        const char *name;                   /* Désignation de l'entrée     */ +        GtkWidget *submenuitem;             /* Sous-élément de menu        */ +        const char *bindings;               /* Raccourcis clavier bruts    */ + +        if (gtk_panel_item_get_personality(panel) != filter->personality) +            goto aptl_exit; + +        /* Séparation */ + +        if (filter->first) +        { +            filter->first = false; + +            submenuitem = qck_create_menu_separator(); +            gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + +        } + +        /* Elément de menu */ + +        name = g_editor_item_get_name(G_EDITOR_ITEM(panel)); + +        submenuitem = qck_create_check_menu_item(NULL, NULL, name, +                                                 G_CALLBACK(mcb_view_change_panel_docking), panel); + +        bindings = gtk_panel_item_get_key_bindings(panel); + +        if (bindings != NULL) +            add_accelerator_to_menu_item(submenuitem, bindings, filter->accel); + +        gtk_container_add(filter->support, submenuitem); + +        /* Statut de la coche */ + +        if (g_panel_item_is_docked(panel)) +        { +            g_signal_handlers_disconnect_by_func(submenuitem, G_CALLBACK(mcb_view_change_panel_docking), panel); + +            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), TRUE); + +            g_signal_connect(submenuitem, "toggled", G_CALLBACK(mcb_view_change_panel_docking), panel); + +        } + +     aptl_exit: + +        return true; + +    } + +    accgroup = GTK_ACCEL_GROUP(g_object_get_data(G_OBJECT(bar), "accgroup")); + +    pfilter.support = GTK_CONTAINER(menubar); +    pfilter.accel = accgroup; + +    pfilter.personality = PIP_SINGLETON; +    pfilter.first = false; + +    browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter); + +    pfilter.personality = PIP_OTHER; +    pfilter.first = true; + +    browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : menuitem = élément de menu ayant basculé.                    * +*                bar      = barre de menu parente.                            * +*                                                                             * +*  Description : Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void mcb_view_change_panel_docking(GtkCheckMenuItem *menuitem, GPanelItem *item) +{ +    gboolean active;                        /* Etat de sélection du menu   */ + +    active = gtk_check_menu_item_get_active(menuitem); + +    if (active) +        g_panel_item_dock(item); +    else +        g_panel_item_undock(item); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : menuitem = élément de menu ayant basculé.                    *  *                bar      = barre de menu parente.                            *  *                                                                             * diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c index e06b891..9eaa1df 100644 --- a/src/gui/panels/bookmarks.c +++ b/src/gui/panels/bookmarks.c @@ -236,6 +236,7 @@ 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  */      GObject *ref;                           /* Espace de référencement     */      GtkTreeStore *store;                    /* Modèle de gestion           */      GtkWidget *treeview;                    /* Affichage de la liste       */ @@ -255,6 +256,10 @@ 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, diff --git a/src/gui/panels/glance.c b/src/gui/panels/glance.c index 306281a..6373edd 100644 --- a/src/gui/panels/glance.c +++ b/src/gui/panels/glance.c @@ -173,16 +173,24 @@ 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  */      GtkWidget *area;                        /* Surface de dessin réelle    */      base = G_EDITOR_ITEM(panel);      base->name = _("Glance"); +    base->widget = gtk_event_box_new(); + +    pitem = G_PANEL_ITEM(panel); + +    pitem->personality = PIP_SINGLETON; + +    /* Support de dessin */ +      area = gtk_drawing_area_new();      gtk_widget_show(area); -    base->widget = gtk_event_box_new();      gtk_container_add(GTK_CONTAINER(base->widget), area);      gtk_widget_show(base->widget); diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c index 74945c7..4d4be0c 100644 --- a/src/gui/panels/history.c +++ b/src/gui/panels/history.c @@ -156,6 +156,7 @@ 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  */      GObject *ref;                           /* Espace de référencement     */      GtkWidget *scrollwnd;                   /* Support défilant            */      GtkWidget *treeview;                    /* Affichage de la liste       */ @@ -173,6 +174,10 @@ static void g_history_panel_init(GHistoryPanel *panel)      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); @@ -305,7 +310,7 @@ GEditorItem *g_history_panel_new(GObject *ref)      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, "eM"); +                          _("Change history"), G_EDITOR_ITEM(result)->widget, "eN");      return result; diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c index ab815e4..7893666 100644 --- a/src/gui/panels/log.c +++ b/src/gui/panels/log.c @@ -120,12 +120,18 @@ 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  */ +    GPanelItemClass *panel;                 /* Version parente de la classe*/      object = G_OBJECT_CLASS(klass);      object->dispose = (GObjectFinalizeFunc/* ! */)g_log_panel_dispose;      object->finalize = (GObjectFinalizeFunc)g_log_panel_finalize; +    panel = G_PANEL_ITEM_CLASS(klass); + +    panel->unique = true; +    panel->bindings = "<Shift>F1"; +  } @@ -143,16 +149,27 @@ 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  */      GtkWidget *scrolled;                    /* Fenêtre avec défilements    */      GtkTreeStore *store;                    /* Modèle de gestion           */      GtkWidget *treeview;                    /* Affichage de la liste       */      GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */      GtkTreeViewColumn *column;              /* Colonne de la liste         */ -    GEditorItem *base;                      /* Version basique d'instance  */ + +    base = G_EDITOR_ITEM(panel);      scrolled = gtk_scrolled_window_new(NULL, NULL);      gtk_widget_show(scrolled); +    base->widget = scrolled; + +    pitem = G_PANEL_ITEM(panel); + +    pitem->personality = PIP_SINGLETON; + +    /* Construction graphique */ +      gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);      gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); @@ -184,9 +201,6 @@ static void g_log_panel_init(GLogPanel *panel)      gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); -    base = G_EDITOR_ITEM(panel); -    base->widget = scrolled; -  } diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h index b3a9f10..e902722 100644 --- a/src/gui/panels/panel-int.h +++ b/src/gui/panels/panel-int.h @@ -29,8 +29,7 @@  #include "panel.h" -#include <gtk/gtkbin.h> -#include <gtk/gtkwidget.h> +#include <gtk/gtk.h>  #include "../editem-int.h" @@ -45,10 +44,14 @@ struct _GPanelItem      DL_LIST_ITEM(link);                     /* Maillon de liste chaînée    */ +    PanelItemPersonality personality;       /* Nature de l'élément         */ +      const char *lname;                      /* Description longue          */      const char *path;                       /* Chemin vers la place idéale */ +    bool docked;                            /* Panneau inscrusté ?         */ +  }; @@ -57,18 +60,25 @@ typedef struct _panel_node  {      struct _panel_node *parent;             /* Noeud parent                */ -    char *path;                             /* Chemin du nom courant       */ -    size_t depth;                           /* Profondeur utilisée         */ +    union +    { +        GtkWidget *widget;                  /* Accès généraliste           */ +        GtkWidget *station;                 /* Station d'accueil simple    */ +        GtkWidget *paned;                   /* Station d'accueil composée  */ -    bool simple;                            /* Noeud sans division         */ +    };      union      { -        GtkWidget *station;                 /* Station d'accueil simple    */ +        /* Version simple */ +        struct +        { +            char *path;                     /* Chemin du nom courant       */ +        }; +        /* Version composée */          struct          { -            GtkWidget *paned;               /* Station d'accueil composée  */              struct _panel_node *first;      /* Premier sous élément        */              struct _panel_node *second;     /* Second sous élément         */          }; @@ -78,7 +88,16 @@ typedef struct _panel_node  } panel_node; -#define GET_PANEL_NODE_WIDGET(node) (node->simple ? node->station : node->paned) + +#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) */ @@ -86,6 +105,9 @@ struct _GPanelItemClass  {      GEditorItemClass parent;                /* A laisser en premier        */ +    bool unique;                            /* Panneau instanciable ?      */ +    const char *bindings;                   /* Raccourci clavier éventuel  */ +      GtkBin *first;                          /* Elément racine              */  }; diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index 01307cb..8af8672 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -25,6 +25,7 @@  #include "panel.h" +#include <assert.h>  #include <ctype.h>  #include <string.h>  #include <sys/param.h> @@ -38,6 +39,7 @@  #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" @@ -80,7 +82,7 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *);  /* Crée un nouveau noeud pour un panneau particulier. */ -static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t); +//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); @@ -88,41 +90,34 @@ 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); -/* Valorise la correspondance entre un noeud et un chemin. */ -static int compute_panel_node_matching_score(const panel_node *, const char *); -/* Calcule la longueur du plus court chemin vers un 'M'. */ -static size_t _compute_panel_node_main_level(const panel_node *); -/* Recherche le noeud constituant la branche principale. */ -static panel_node *find_main_panel_node_branch(panel_node *, panel_node *); -/* Place au bon endroit un panneau donné. */ -static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t); +/* Crée un nouveau noeud pour un panneau particulier. */ +static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *); -/* Met à jour l'affichage suite à un changement hiérarchique. */ -static void rebuild_panels_interface(const panel_node *); -/* ---------------------- REAJUSTEMENT AUTOMATIQUE DE L'ESPACE ---------------------- */ +/* 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 *); -/* Part réservée aux parties principales (en %) */ -#define MAIN_PART_PERCENT 70 +/* Détermine la plus grande profondeur d'un noeud de panneaux. */ +static unsigned int compute_deepest_depth(const panel_node *); -/* Part minimale des petits composants (en %) */ -#define MIN_PART_PERCENT 20 +/* 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 *); -/* Met à jour l'affichage suite à un changement hiérarchique. */ -static void auto_resize_panels(GtkWidget *, GdkRectangle *, gpointer); +/* Efface de l'organisation un noeud donné en place. */ +static void delete_panel_node(panel_node *); -/* S'enquiert de la taille idéale pour un noeud. */ -static void get_panel_node_size_request(const panel_node *, GtkRequisition *); -/* Impose une taille accordée à un noeud. */ -static void set_panel_node_size_request(const panel_node *, const GtkRequisition *); @@ -167,6 +162,8 @@ static void g_panel_item_init(GPanelItem *item)  {      DL_LIST_ITEM_INIT(&item->link); +    item->personality = PIP_INVALID; +  } @@ -239,7 +236,8 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con  /******************************************************************************  *                                                                             * -*  Paramètres  : ref    = espace de référencement global.                     * +*  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.                * @@ -253,12 +251,15 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con  *                                                                             *  ******************************************************************************/ -GEditorItem *g_panel_item_new(GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path) +GEditorItem *g_panel_item_new(PanelItemPersonality personality, GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path)  {      GPanelItem *result;                     /* Structure à retourner       */      result = g_object_new(G_TYPE_PANEL_ITEM, NULL); +    assert(personality > PIP_INVALID && personality < PIP_COUNT); +    result->personality = personality; +      g_panel_item_init_ext(result, ref, name, lname, widget, path);      return G_EDITOR_ITEM(result); @@ -325,6 +326,44 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item)  /******************************************************************************  *                                                                             * +*  Paramètres  : item = instance GTK à consulter.                             * +*                                                                             * +*  Description : Fournit une indication sur la personnalité du panneau.       * +*                                                                             * +*  Retour      : Identifiant lié à la nature du panneau.                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *item) +{ +    return item->personality; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : item = instance GTK dont l'interface est à consulter.        * +*                                                                             * +*  Description : Indique la définition d'un éventuel raccourci clavier.       * +*                                                                             * +*  Retour      : Description d'un raccourci ou NULL si aucun de défini.       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const char *gtk_panel_item_get_key_bindings(const GPanelItem *item) +{ +    return G_PANEL_ITEM_GET_CLASS(item)->bindings; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : name = désignation courte servant de clef.                   *  *                                                                             *  *  Description : Recherche un panneau à partir de son nom court.              * @@ -364,16 +403,95 @@ 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, 0); -        gtk_container_add(GTK_CONTAINER(_support), _nodes->station); +        _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; +  } @@ -391,12 +509,25 @@ void g_panel_item_dock(GPanelItem *item)  void g_panel_item_undock(GPanelItem *item)  { -    GtkWidget *station;                     /* Base du remplacement        */ +    GtkWidget *station;                     /* Support courant             */ +    panel_node *node;                       /* Noeud à supprimer           */ -    station = gtk_widget_get_parent(G_EDITOR_ITEM(item)->widget);   /* NoteBook */ -    station = gtk_widget_get_parent(station);   /* DockStation */ +    assert(item->docked); -    gtk_dock_panel_remove_widget(GTK_DOCK_STATION(station), G_EDITOR_ITEM(item)->widget); +    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;  } @@ -427,7 +558,7 @@ GtkWidget *init_panels2(GCallback handler, gpointer data)      result = gtk_event_box_new();      gtk_widget_show(result); -    g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL); +    //g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);      _support = result;      _handler = handler; @@ -454,10 +585,10 @@ void load_main_panels(GObject *ref)  {      GPanelItem *item;                       /* Panneau de base à charger   */ -    item = create_regedit_panel(ref); +    item = create_log_panel(ref);      g_panel_item_dock(item); -    item = create_log_panel(ref); +    item = create_regedit_panel(ref);      g_panel_item_dock(item);      item = create_symbols_panel(ref); @@ -478,54 +609,49 @@ void load_main_panels(GObject *ref)  } - -/* ---------------------------------------------------------------------------------- */ -/*                        MECANISMES DE PLACEMENT DES PANNEAUX                        */ -/* ---------------------------------------------------------------------------------- */ - -  /******************************************************************************  *                                                                             * -*  Paramètres  : item  = composant à présenter à l'affichage.                 * -*                path  = partie du chemin représentée ici.                    * -*                depth = profondeur du chemin utilisé.                        * +*  Paramètres  : handle = routine à appeler pour chaque panneau.              * +*                data   = données fournies pour accompagner cet appel.        *  *                                                                             * -*  Description : Crée un nouveau noeud pour un panneau particulier.           * +*  Description : Effectue le parcours de tous les panneaux chargés.           *  *                                                                             * -*  Retour      : Structure d'accueil mise en place.                           * +*  Retour      : true si le parcours a été total, false sinon.                *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path, size_t depth) +bool browse_all_item_panels(handle_panel_item_fc handle, void *data)  { -    panel_node *result;                     /* Structure à retourner       */ -    GtkWidget *station;                     /* Premier support concentré   */ - -    result = (panel_node *)calloc(1, sizeof(panel_node)); - -    result->path = strdup(path); -    result->depth = depth; +    bool result;                            /* Résultat à renvoyer         */ +    GPanelItem *iter;                       /* Boucle de parcours          */ -    result->simple = true; +    result = true; -    station = gtk_dock_station_new(); -    g_signal_connect(station, "switch-widget", _handler, _data); -    gtk_widget_show(station); +    panels_list_for_each(iter, _panels_list) +    { +        result = handle(iter, data); -    result->station = station; +        if (!result) break; -    gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item)); +    }      return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                        MECANISMES DE PLACEMENT DES PANNEAUX                        */ +/* ---------------------------------------------------------------------------------- */ + + +  /******************************************************************************  *                                                                             * -*  Paramètres  : item  = composant à présenter à l'affichage.                 * +*  Paramètres  : node  = noeud à diviser.                                     *  *                horiz = indique le type d'orientation désiré.                *  *                first = indication sur l'emplacement à utiliser.             *  *                                                                             * @@ -537,51 +663,98 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha  *                                                                             *  ******************************************************************************/ -static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool first) +static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool first)  { -    panel_node *moved;                      /* Noeud descendu d'un étage   */      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, current, sizeof(panel_node)); -    moved->parent = current; +    memcpy(moved, node, sizeof(panel_node)); -    widget = GET_PANEL_NODE_WIDGET(current); +    if (!IS_SIMPLE_NODE(moved)) +    { +        moved->first->parent = moved; +        moved->second->parent = moved; +    } -    g_object_ref(G_OBJECT(widget)); -    gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); +    /* Création du nouveau niveau intermédiaire */ -    if (first) -        current->first = moved; +    if (horiz) +        node->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);      else -        current->second = moved; +        node->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL); -    /* Achève la transformation */ +    gtk_widget_show(node->paned); -    current->path = NULL; +    if (parent == NULL) +        attach_panel_node_to_paned(parent, node, true); +    else +        attach_panel_node_to_paned(parent, node, parent->first == node); -    current->simple = false; -    current->station = NULL; -    if (horiz) -        current->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); -    else -        current->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL); -    gtk_widget_show(current->paned); +    /* Premier ajustement */ -    /* Replace le composant d'origine */ +    void split_paned_support(GtkWidget *support, GdkRectangle *alloc, gpointer data) +    { +        GtkOrientation orientation; +        gint position; -    if (first) -        gtk_paned_add1(GTK_PANED(current->paned), widget); -    else -        gtk_paned_add2(GTK_PANED(current->paned), widget); +        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 */ -    g_object_unref(G_OBJECT(widget)); +    attach_panel_node_to_paned(node, moved, first);  } @@ -602,67 +775,143 @@ static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool f  static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, bool first)  { -    GtkWidget *widget;                      /* Composant à traiter         */ +    node->parent = parent; + +    /* On se trouve à la racine... */ -    /* Raccordement hiérarchique */ +    if (parent == NULL) +        gtk_container_add(GTK_CONTAINER(_support), node->widget); -    if (first) -        parent->first = node;      else -        parent->second = node; +    { +        /* Raccordement hiérarchique */ -    node->parent = parent; +        if (first) +            parent->first = node; +        else +            parent->second = node; -    /* Raccordement graphique */ +        /* Raccordement graphique */ -    widget = GET_PANEL_NODE_WIDGET(node); +        assert(!IS_SIMPLE_NODE(parent)); -    if (first) -        gtk_paned_add1(GTK_PANED(parent->paned), widget); -    else -        gtk_paned_add2(GTK_PANED(parent->paned), widget); +        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 d'où lancer les recherches.                   * -*                target = identifiant de la position visée.                   * +*  Paramètres  : item = composant à présenter à l'affichage.                  * +*                path = partie du chemin représentée ici.                     *  *                                                                             * -*  Description : Valorise la correspondance entre un noeud et un chemin.      * +*  Description : Crée un nouveau noeud pour un panneau particulier.           *  *                                                                             * -*  Retour      : Bilan de l'évaluation.                                       * +*  Retour      : Structure d'accueil mise en place.                           *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static int compute_panel_node_matching_score(const panel_node *node, const char *target) +static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path)  { -    int result;                             /* Bilan à retourner           */ -    size_t len;                             /* Longueur de comparaison     */ -    size_t i;                               /* Boucle de parcours          */ +    panel_node *result;                     /* Structure à retourner       */ +    GtkWidget *station;                     /* Premier support concentré   */ -    if (node->simple) -    { -        result = 0; +    /* Partie graphique */ -        len = strlen(node->path); -        len = MIN(len, strlen(target)); +    station = gtk_dock_station_new(); +    g_signal_connect(station, "switch-widget", _handler, _data); +    gtk_widget_show(station); -        for (i = 0; i < len; i++) -        { -            if (node->path[i] != target[i]) break; -            else result++; -        } +    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 = compute_panel_node_matching_score(node->first, target); -        result = MAX(result, compute_panel_node_matching_score(node->second, target)); +        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; @@ -673,8 +922,9 @@ static int compute_panel_node_matching_score(const panel_node *node, const char  /******************************************************************************  *                                                                             *  *  Paramètres  : node   = noeud d'où lancer les recherches.                   * +*                target = identifiant de la position visée.                   *  *                                                                             * -*  Description : Calcule la longueur du plus court chemin vers un 'M'.        * +*  Description : Détermine la plus grande longueur commune entre éléments.    *  *                                                                             *  *  Retour      : Bilan de l'évaluation.                                       *  *                                                                             * @@ -682,23 +932,34 @@ static int compute_panel_node_matching_score(const panel_node *node, const char  *                                                                             *  ******************************************************************************/ -static size_t _compute_panel_node_main_level(const panel_node *node) +static size_t compute_path_common_length(const panel_node *node, const char *target)  { -    size_t result;                          /* Plus petit chemin à renvoyer*/ +    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 (node->simple) +    if (IS_SIMPLE_NODE(node))      { -        result = strcspn(&node->path[node->depth], "M"); +        len = MIN(strlen(node->path), strlen(target)); -        if (node->path[node->depth + result] == '\0') -            result = SIZE_MAX; +        /** +         * 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      { -        result = _compute_panel_node_main_level(node->first); -        result = MIN(result, _compute_panel_node_main_level(node->second)); +        common1 = compute_path_common_length(node->first, target); +        common2 = compute_path_common_length(node->second, target); + +        result = MAX(common1, common2); +      }      return result; @@ -708,31 +969,33 @@ static size_t _compute_panel_node_main_level(const panel_node *node)  /******************************************************************************  *                                                                             * -*  Paramètres  : a = première branche à analyser.                             * -*                b = seconde branche à analyser.                              * +*  Paramètres  : node = noeud d'où lancer les mesures.                        *  *                                                                             * -*  Description : Recherche le noeud constituant la branche principale.        * +*  Description : Détermine la plus grande profondeur d'un noeud de panneaux.  *  *                                                                             * -*  Retour      : Branche principale ou NULL si aucune n'est idéale.           * +*  Retour      : Valeur strictement positive.                                 *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b) +static unsigned int compute_deepest_depth(const panel_node *node)  { -    panel_node *result;                     /* Trouvaille à remonter       */ -    size_t main_a;                          /* Proximité du 'M' côté a     */ -    size_t main_b;                          /* Proximité du 'M' côté b     */ - -    main_a = _compute_panel_node_main_level(a); -    main_b = _compute_panel_node_main_level(b); +    unsigned int result;                    /* Profondeur à renvoyer       */ +    unsigned int depth1;                    /* Profondeur du côté #1       */ +    unsigned int depth2;                    /* Profondeur du côté #2       */ -    if (main_a == SIZE_MAX && main_b == SIZE_MAX) -        result = NULL; +    if (IS_SIMPLE_NODE(node)) +        result = 1;      else -        result = (main_a < main_b ? a : b); +    { +        depth1 = compute_deepest_depth(node->first); +        depth2 = compute_deepest_depth(node->second); + +        result = MAX(depth1, depth2); + +    }      return result; @@ -741,10 +1004,10 @@ static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)  /******************************************************************************  *                                                                             * -*  Paramètres  : item  = composant à présenter à l'affichage.                 * -*                node  = point d'insertion courant.                           * -*                path  = partie du chemin représentée ici.                    * -*                depth = profondeur du chemin utilisé.                        * +*  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é.                       *  *                                                                             * @@ -754,58 +1017,47 @@ static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)  *                                                                             *  ******************************************************************************/ -static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t depth) +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éé          */ -    int score1;                             /* Score de la 1ère branche    */ -    int score2;                             /* Score de la 2nde branche    */ -    panel_node *support;                    /* Noeud d'accueil désigné     */ +    size_t common1;                         /* Tron common avec le côté #1 */ +    size_t common2;                         /* Tron common avec le côté #2 */ -    if (node->simple) -    { -        /* Si on est sur la bonne voie... */ -        if (compute_panel_node_matching_score(node, path) > 0) -        { -            /* 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[depth]); -                first = (div == 'E' || div == 'S'); -                horiz = (div == 'W' || div == 'E'); - -                switch_panel_node_into_paned(node, horiz, first); - -                new = create_simple_panel_node_for_item(item, path, depth); +    fprintf(stderr, "=== INSERTING '%s' (%zu)... -> '%s'\n", path, consumed, +            IS_SIMPLE_NODE(node) ? node->path : "-"); -                attach_panel_node_to_paned(node, new, !first); -                rebuild_panels_interface(node); -            } - -        } +    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[depth]); -            first = (div == 'E' || div == 'S'); +            div = toupper(path[consumed]); +            first = (div == 'W' || div == 'N');              horiz = (div == 'W' || div == 'E'); -            switch_panel_node_into_paned(node, horiz, first); +            fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz); -            new = create_simple_panel_node_for_item(item, path, depth); +            fprintf(stderr, "--- cutting %p\n", node->station); -            attach_panel_node_to_paned(node, new, !first); +            switch_panel_node_into_paned(node, horiz, !first); -            rebuild_panels_interface(node); +            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);          } @@ -815,62 +1067,44 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const      else      { -        score1 = compute_panel_node_matching_score(node->first, path); -        score2 = compute_panel_node_matching_score(node->second, path); +        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 (score1 > 0 || score2 > 0) +        if (common1 > 0 || common2 > 0)          { -            if (node->first->simple || node->second->simple) -                depth++; - -            if (score1 > score2) -                insert_item_as_panel_node(item, node->first, path, depth); +            if (common1 > common2) +                insert_item_as_panel_node(item, node->first, path, common1);              else -                insert_item_as_panel_node(item, node->second, path, depth); +                insert_item_as_panel_node(item, node->second, path, common2);          }          /* Sinon, on doit diviser qqch... */          else          { -            /* Si l'élément doit passer en force */ -            if (isupper(path[depth])) -            { -                div = path[depth]; -                first = (div == 'E' || div == 'S'); -                horiz = (div == 'W' || div == 'E'); - -                switch_panel_node_into_paned(node, horiz, first); - -                new = create_simple_panel_node_for_item(item, path, depth); - -                attach_panel_node_to_paned(node, new, !first); - -                rebuild_panels_interface(node); - -            } - -            else -            { -                support = find_main_panel_node_branch(node->first, node->second); -                if (support == NULL) -                    support = node->first; +            div = toupper(path[consumed]); +            first = (div == 'W' || div == 'N'); +            horiz = (div == 'W' || div == 'E'); -                div = toupper(path[depth]); -                first = (div == 'E' || div == 'S'); -                horiz = (div == 'W' || div == 'E'); +            fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz); -                switch_panel_node_into_paned(support, horiz, first); +            switch_panel_node_into_paned(node, horiz, !first); -                new = create_simple_panel_node_for_item(item, path, depth); +            new = create_simple_panel_node_for_item(item, path); -                attach_panel_node_to_paned(support, new, !first); +            attach_panel_node_to_paned(node, new, first); -                rebuild_panels_interface(support); -            } +                fprintf(stderr, "2# [%p] split :: %p-%p // %p-%p\n", node, +                        node->first, node->first->widget, +                        node->second, node->second->widget);          } @@ -881,55 +1115,42 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const  /******************************************************************************  *                                                                             * -*  Paramètres  : current = point de départ de la réorganisation graphique.    * +*  Paramètres  : node = point de départ des recherches locales.               *  *                                                                             * -*  Description : Met à jour l'affichage suite à un changement hiérarchique.   * +*  Description : Tente de mettre la main sur une station d'accueil.           *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Eventuel noeud trouvé ou NULL.                               *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void rebuild_panels_interface(const panel_node *current) +static panel_node *find_node_for_station(panel_node *node, GtkWidget *station)  { -    GtkWidget *widget;                      /* Composant à traiter         */ -    panel_node *parent;                     /* Raccourci confortable       */ - -    widget = GET_PANEL_NODE_WIDGET(current); +    panel_node *result;                     /* Bilan à remonter            */ -    /* On se trouve à la racine... */ -    if (current->parent == NULL) -            gtk_container_add(GTK_CONTAINER(_support), widget); +    if (IS_SIMPLE_NODE(node)) +        result = (node->station == station ? node : NULL); -    /* Sinon, une sous-division ne peut venir que d'une division... */      else      { -        /* BUG_ON(parent->simple) */ - -        parent = current->parent; +        result = find_node_for_station(node->first, station); -        if (current == parent->first) -            gtk_paned_add1(GTK_PANED(parent->paned), widget); -        else -            gtk_paned_add2(GTK_PANED(parent->paned), widget); +        if (result == NULL) +            result = find_node_for_station(node->second, station);      } -} - - +    return result; -/* ---------------------------------------------------------------------------------- */ -/*                        REAJUSTEMENT AUTOMATIQUE DE L'ESPACE                        */ -/* ---------------------------------------------------------------------------------- */ +}  /******************************************************************************  *                                                                             * -*  Paramètres  : current = point de départ de la réorganisation graphique.    * +*  Paramètres  : node = noeud à supprimer de l'arbre des noeuds.              *  *                                                                             * -*  Description : Met à jour l'affichage suite à un changement hiérarchique.   * +*  Description : Efface de l'organisation un noeud donné en place.            *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -937,77 +1158,91 @@ static void rebuild_panels_interface(const panel_node *current)  *                                                                             *  ******************************************************************************/ -static void auto_resize_panels(GtkWidget *support, GdkRectangle *alloc, gpointer data) +static void delete_panel_node(panel_node *node)  { -    GtkRequisition available;               /* Taille disponible           */ +    panel_node *parent;                     /* Noeud parent à transformer  */ +    GtkWidget *widget;                      /* Composant à traiter         */ +    panel_node *grandparent;                /* Noeud supérieur au parent   */ +    panel_node *remaining;                  /* Noeud restant               */ -    //g_signal_handlers_disconnect_by_func(support, G_CALLBACK(auto_resize_panels), NULL); +    assert(IS_SIMPLE_NODE(node)); -    available.width = alloc->width; -    available.height = alloc->height; +    parent = node->parent; -    set_panel_node_size_request(_nodes, &available); +    /* Destruction du noeud */ -    //g_signal_connect(support, "size-allocate", G_CALLBACK(auto_resize_panels), NULL); +    widget = node->station; +    gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); -} +    free(node->path); +    free(node); -/****************************************************************************** -*                                                                             * -*  Paramètres  : node = noeud à consulter.                                    * -*                req  = taille demandée par le noeud. [OUT]                   * -*                                                                             * -*  Description : S'enquiert de la taille idéale pour un noeud.                * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    /* Suppression du niveau intermédiaire */ -static void get_panel_node_size_request(const panel_node *node, GtkRequisition *req) -{ -    gint handle_size;                       /* Taille de la séparation     */ -    GtkRequisition tmp;                     /* Stockage temporaire         */ +    if (parent != NULL) +    { +        remaining = (node == parent->first ? parent->second : parent->first); -    if (node->simple) -        gtk_widget_get_preferred_size(node->station, NULL, req); +        /* Décroche graphiquement le support */ -    else -    { -        gtk_widget_style_get(node->paned, "handle-size", &handle_size, NULL); +        widget = remaining->widget; -        if (HAS_H_ORIENTATION(node->paned)) -        { -            req->width = handle_size; -            req->height = 0; -        } -        else +        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))          { -            req->width = 0; -            req->height = handle_size; +            parent->first->parent = parent; +            parent->second->parent = parent;          } -        get_panel_node_size_request(node->first, &tmp); -        req->width += tmp.width; -        req->height += tmp.height; +        free(remaining); -        get_panel_node_size_request(node->second, &tmp); -        req->width += tmp.width; -        req->height += tmp.height; +        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  : node  = noeud à consulter.                                   * -*                space = taille disponible pour le noeud.                     * +*  Paramètres  : current = point de départ de la réorganisation graphique.    *  *                                                                             * -*  Description : Impose une taille accordée à un noeud.                       * +*  Description : Met à jour l'affichage suite à un changement hiérarchique.   *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -1015,125 +1250,45 @@ static void get_panel_node_size_request(const panel_node *node, GtkRequisition *  *                                                                             *  ******************************************************************************/ -static void set_panel_node_size_request(const panel_node *node, const GtkRequisition *space) +void save_panel_nodes(void)  { -    GtkRequisition first_req;               /* Taille demandée par n°1     */ -    GtkRequisition second_req;              /* Taille demandée par n°2     */ -    gint handle_size;                       /* Taille de la séparation     */ -    panel_node *main_node;                  /* Branche principale          */ -    gint position;                          /* Position de la séparation   */ -    bool can_lower;                         /* Diminution possible ?       */ -    bool can_upper;                         /* Augmentation possible ?     */ -    GtkAllocation allocation;               /* Taille allouée              */ - -    /* Pour les cas simple, GTK gère très bien... */ -    if (node->simple) return; - -    get_panel_node_size_request(node->first, &first_req); -    get_panel_node_size_request(node->second, &second_req); -    gtk_widget_style_get(node->paned, "handle-size", &handle_size, NULL); -    /** -     * Définitions des bornes dans chacun des cas. -     */ +    fprintf(stderr, "Passage avec %p\n", _nodes); -    main_node = find_main_panel_node_branch(node->first, node->second); - -    /* Le premier noeud est le principal... */ -    if (node->first == main_node) +    return; +    void store_handle_position(panel_node *node, GGenConfig *config)      { -        if (HAS_H_ORIENTATION(node->paned)) -            position = (space->width * MAIN_PART_PERCENT) / 100; -        else -            position = (space->height * MAIN_PART_PERCENT) / 100; -        can_lower = false; -        can_upper = true; +        size_t i; -    } +        for (i = 0; i < 0/*node->depth*/; i++) +            fprintf(stderr, "  "); -    /* Le second noeud est le principal... */ -    else if (node->second == main_node) -    { -        if (HAS_H_ORIENTATION(node->paned)) -            position = space->width - (space->width * MAIN_PART_PERCENT) / 100; -        else -            position = space->height - (space->height * MAIN_PART_PERCENT) / 100; -        can_lower = true; -        can_upper = false; +        ///fprintf(stderr, "[%s] %s\n", node->path, node->simple ? "[+]" : ">>"); -    } -    /* Les éléments sont quelconques... */ -    else -    { -        if (HAS_H_ORIENTATION(node->paned)) -            position = space->width / 2; -        else -            position = space->height / 2; - -        can_lower = true; -        can_upper = true; - -    } - -    /** -     * Calcul des valeurs applicables et mise en application. -     */ - -    /* Correctifs éventuels pour les petits composants */ -    if (node->first == main_node) -    { -        if (HAS_H_ORIENTATION(node->paned)) -            second_req.width = MAX(second_req.width, (space->width * MIN_PART_PERCENT) / 100); -        else -            second_req.height = MAX(second_req.height, (space->height * MIN_PART_PERCENT) / 100); -    } -    else if (node->second == main_node) -    { -        if (HAS_H_ORIENTATION(node->paned)) -            first_req.width = MAX(first_req.width, (space->width * MIN_PART_PERCENT) / 100); -        else -            first_req.height = MAX(first_req.height, (space->height * MIN_PART_PERCENT) / 100); -    } +        if (0/*!node->simple*/) +        { +            store_handle_position(node->first, config); +            store_handle_position(node->second, config); +        } -    /* Une partie principale arrive en premier */ -    if (!can_lower && can_upper) -    { -        if (HAS_H_ORIENTATION(node->paned)) -            position = MAX(position, space->width - second_req.width - handle_size); -        else -            position = MAX(position, space->height - second_req.height - handle_size); -    } -    /* Une partie principale arrive en second */ -    else if (can_lower && !can_upper) -    { -        if (HAS_H_ORIENTATION(node->paned)) -            position = MIN(position, second_req.width + handle_size); -        else -            position = MIN(position, second_req.height + handle_size);      } -    /* Chacun pour soit ! */ -    else -    { +    //get_main_configuration() -        /* TODO */; +    store_handle_position(_nodes, NULL); +    fflush(NULL); -    } -    gtk_paned_set_position(GTK_PANED(node->paned), position); +} -    gtk_widget_get_allocation(GET_PANEL_NODE_WIDGET(node->first), &allocation); -    set_panel_node_size_request(node->first, ALLOC_2_REQ(&allocation)); +#endif -    gtk_widget_get_allocation(GET_PANEL_NODE_WIDGET(node->second), &allocation); -    set_panel_node_size_request(node->second, ALLOC_2_REQ(&allocation)); -} diff --git a/src/gui/panels/panel.h b/src/gui/panels/panel.h index 0bf5cb5..baf5fe7 100644 --- a/src/gui/panels/panel.h +++ b/src/gui/panels/panel.h @@ -26,6 +26,9 @@  #define _GUI_PANELS_PANEL_H +#include <stdbool.h> + +  #include "../editem.h" @@ -45,11 +48,31 @@ typedef struct _GPanelItem GPanelItem;  typedef struct _GPanelItemClass GPanelItemClass; +/* Types de panneaux pour éditeur */ +typedef enum _PanelItemPersonality +{ +    PIP_INVALID,                            /* Information non initialisée */ + +    PIP_SINGLETON,                          /* Instance unique             */ +    PIP_BINARY_VIEW,                        /* Affichage d'un binaire      */ +    PIP_OTHER,                              /* Reste du monde              */ + +    PIP_COUNT + +} PanelItemPersonality; + +  /* Indique le type défini pour un élément destiné à un panneau. */  GType g_panel_item_get_type(void);  /* Crée un élément de panneau réactif. */ -GEditorItem *g_panel_item_new(GObject *, const char *, const char *, GtkWidget *, const char *); +GEditorItem *g_panel_item_new(PanelItemPersonality, GObject *, const char *, const char *, GtkWidget *, const char *); + +/* Fournit une indication sur la personnalité du panneau. */ +PanelItemPersonality gtk_panel_item_get_personality(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 *); @@ -57,11 +80,25 @@ GPanelItem *g_panel_item_get(const char *);  /* Place un panneau dans l'ensemble affiché. */  void g_panel_item_dock(GPanelItem *); +/* Indique si le composant repose sur un support de l'éditeur. */ +bool g_panel_item_is_docked(const GPanelItem *); +  /* Supprime un panneau de l'ensemble affiché. */  void g_panel_item_undock(GPanelItem *); + + + + +void save_panel_nodes(void); + + + + + +  /* ----------------------- PLACEMENTS DES DIFFERENTS PANNEAUX ----------------------- */ @@ -72,5 +109,12 @@ GtkWidget *init_panels2(GCallback, gpointer);  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 a187a2d..cb4fe85 100644 --- a/src/gui/panels/regedit.c +++ b/src/gui/panels/regedit.c @@ -204,6 +204,7 @@ 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  */      GObject *ref;                           /* Espace de référencement     */      GtkWidget *label;                       /* Etiquette à utiliser        */      GtkWidget *search;                      /* Zone de recherche           */ @@ -224,6 +225,10 @@ 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:")); @@ -386,7 +391,7 @@ GEditorItem *g_regedit_panel_new(GObject *ref)      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, "M"); +                          _("Configuration parameters"), G_EDITOR_ITEM(result)->widget, "N");      reload_config_into_treeview(G_REGEDIT_PANEL(result), get_main_configuration()); diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c index abbf7ed..9759e71 100644 --- a/src/gui/panels/strings.c +++ b/src/gui/panels/strings.c @@ -179,6 +179,7 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)  {      GObjectClass *object;                   /* Autre version de la classe  */      GEditorItemClass *editem;               /* Encore une autre vision...  */ +    GPanelItemClass *panel;                 /* Version parente de la classe*/      object = G_OBJECT_CLASS(klass); @@ -189,6 +190,11 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)      editem->update_binary = (update_item_binary_fc)change_strings_panel_current_binary; +    panel = G_PANEL_ITEM_CLASS(klass); + +    panel->unique = true; +    panel->bindings = "<Shift>F12"; +  } @@ -207,6 +213,7 @@ 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  */      GObject *ref;                           /* Espace de référencement     */      GtkTreeStore *store;                    /* Modèle de gestion           */      GtkWidget *treeview;                    /* Affichage de la liste       */ @@ -227,6 +234,10 @@ 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, diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index 2a9d612..eebfc4c 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -181,6 +181,7 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)      GObjectClass *object;                   /* Autre version de la classe  */      GEditorItemClass *editem;               /* Encore une autre vision...  */      gchar *filename;                        /* Chemin d'accès à utiliser   */ +    GPanelItemClass *panel;                 /* Version parente de la classe*/      object = G_OBJECT_CLASS(klass); @@ -212,6 +213,11 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)      g_free(filename); +    panel = G_PANEL_ITEM_CLASS(klass); + +    panel->unique = true; +    panel->bindings = "<Shift>F3"; +  } @@ -230,6 +236,7 @@ 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  */      GObject *ref;                           /* Espace de référencement     */      GtkWidget *box;                         /* Séparation horizontale      */      GtkWidget *toolbar;                     /* Barre d'outils              */ @@ -250,6 +257,10 @@ static void g_symbols_panel_init(GSymbolsPanel *panel)      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); @@ -435,7 +446,7 @@ GEditorItem *g_symbols_panel_new(GObject *ref)      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, "eM"); +                          _("Binary symbols"), G_EDITOR_ITEM(result)->widget, "eN");      return result; | 
