From eacb69625d51707ac0a158815a53f71fb70968ce Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 30 Jan 2012 02:19:38 +0000
Subject: Provided a new working Project menu.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@230 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                    |  40 ++++++++
 src/editor.c                 | 197 +------------------------------------
 src/gtkext/gtkextstatusbar.c |  18 ++--
 src/gui/editem-int.h         |   6 +-
 src/gui/editem.c             |  23 +++++
 src/gui/editem.h             |   4 +
 src/gui/menus/Makefile.am    |   1 +
 src/gui/menus/file.c         |   4 +-
 src/gui/menus/menubar.c      |  31 ++++++
 src/gui/menus/project.c      | 227 +++++++++++++++++++++++++++++++++++++++++++
 src/gui/menus/project.h      |  45 +++++++++
 src/gui/menus/view.c         |   2 +-
 src/gui/menus/view.h         |   2 +-
 src/gui/tb/source.c          |   2 +-
 src/main.c                   |   4 +-
 src/project.c                | 113 +++++++++++++--------
 src/project.h                |   6 ++
 17 files changed, 470 insertions(+), 255 deletions(-)
 create mode 100644 src/gui/menus/project.c
 create mode 100644 src/gui/menus/project.h

diff --git a/ChangeLog b/ChangeLog
index 754aa5f..8c4a867 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+12-01-30  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/editor.c:
+	Remove all dead code relative to the Project menu.
+
+	* src/gtkext/gtkextstatusbar.c:
+	Do not use GDK threads lock anymore (FIXME).
+
+	* src/gui/editem.c:
+	* src/gui/editem.h:
+	* src/gui/editem-int.h:
+	Update on project content change.
+
+	* src/gui/menus/file.c:
+	Typo.
+
+	* src/gui/menus/Makefile.am:
+	Add the project.[ch] files to libguimenus_la_SOURCES.
+
+	* src/gui/menus/menubar.c:
+	Load the Project menu and update it when needed.
+
+	* src/gui/menus/project.c:
+	* src/gui/menus/project.h:
+	New entries: provide a Project menu.
+
+	* src/gui/menus/view.c:
+	* src/gui/menus/view.h:
+	Typo.
+
+	* src/gui/tb/source.c:
+	Disable all updates of the toolbar item.
+
+	* src/main.c:
+	Do not use GDK threads lock anymore (FIXME).
+
+	* src/project.c:
+	* src/project.h:
+	Reorganize the code. Do not use GDK threads lock anymore (FIXME).
+
 12-01-26  Cyrille Bagard <nocbos@gmail.com>
 
 	* po/fr.po:
diff --git a/src/editor.c b/src/editor.c
index 68b9c28..728e7ca 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -52,7 +52,7 @@
 #include "gtkext/gtkviewpanel.h"
 
 #include "debug/debugger.h"
-#include "dialogs/add_shellcode.h"
+//#include "dialogs/add_shellcode.h"
 #include "dialogs/binparts.h"
 #include "dialogs/export.h"
 #include "dialogs/plugins.h"
@@ -90,21 +90,7 @@ void mcb_file_save_project_as(GtkMenuItem *, gpointer);
 /* Charge un projet récent et met à jour la liste. */
 void mcb_open_recent_project(GtkMenuItem *, GObject *);
 
-/* Affiche la boîte d'ajout d'un binaire au projet courant. */
-void mcb_project_add_binary(GtkMenuItem *, gpointer);
 
-/* Réagit au menu "Projet -> Ajouter un binaire -> Shellcode". */
-static void mcb_project_add_binary_shellcode(GtkMenuItem *, GObject *);
-
-/* Retire un binaire du projet courant. */
-void mcb_project_remove_binary(GtkMenuItem *, gpointer);
-
-
-
-
-
-/* Met à jour le contenu du menu 'Projet'. */
-void reload_menu_project(GObject *);
 
 
 /* Réagit avec le menu "Binaire -> Sélectionner les parties...". */
@@ -332,38 +318,6 @@ GtkWidget *create_editor(void)
 
 
 
-    /* Projet */
-
-    menuitem = gtk_menu_item_new_with_mnemonic(_("_Project"));
-    gtk_widget_show(menuitem);
-    gtk_container_add(GTK_CONTAINER(menuboard), menuitem);
-
-    menubar = gtk_menu_new();
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar);
-
-    submenuitem = qck_create_menu_item(NULL, NULL, _("Add a binary..."), G_CALLBACK(mcb_project_add_binary), result);
-    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
-    submenuitem = qck_create_menu_item(NULL, NULL, _("Add a binary"), NULL, NULL);
-    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
-    submenubar = gtk_menu_new();
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), submenubar);
-
-    submenuitem = qck_create_menu_item(NULL, NULL, _("Shellcode"), G_CALLBACK(mcb_project_add_binary_shellcode), result);
-    gtk_container_add(GTK_CONTAINER(submenubar), submenuitem);
-
-    submenuitem = qck_create_menu_item(G_OBJECT(result), "menu_prj_remove_bin", _("Remove a binary"), NULL, NULL);
-    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
-    submenubar = gtk_menu_new();
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), submenubar);
-
-    submenuitem = qck_create_menu_separator();
-    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
-
-
     menuitem = gtk_menu_item_new_with_mnemonic(_("_Binary"));
     gtk_widget_show(menuitem);
     gtk_container_add(GTK_CONTAINER(menuboard), menuitem);
@@ -425,9 +379,6 @@ GtkWidget *create_editor(void)
 
 
 
-    menuitem = gtk_menu_item_new_with_mnemonic(_("_Plugins"));
-    gtk_widget_show(menuitem);
-    gtk_container_add(GTK_CONTAINER(menuboard), menuitem);
 
 
 
@@ -574,8 +525,6 @@ GtkWidget *create_editor(void)
 
 
 
-    reload_menu_project(G_OBJECT(result));
-
 
 
     return result;
@@ -867,97 +816,12 @@ void mcb_open_recent_project(GtkMenuItem *menuitem, GObject *ref)
 
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : menuitem = élément de menu sélectionné.                      *
-*                data     = adresse de l'espace de référencement global.      *
-*                                                                             *
-*  Description : Affiche la boîte d'ajout d'un binaire au projet courant.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void mcb_project_add_binary(GtkMenuItem *menuitem, gpointer data)
-{
-    GtkWidget *dialog;                      /* Boîte à afficher            */
-    gchar *filename;                        /* Nom du fichier à intégrer   */
-    GOpenidaBinary *binary;                 /* Représentation chargée      */
-
-    dialog = gtk_file_chooser_dialog_new(_("Open a binary file"), GTK_WINDOW(data),
-                                         GTK_FILE_CHOOSER_ACTION_OPEN,
-                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-                                         NULL);
-
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
-
-        binary = g_openida_binary_new_from_file(filename);
-
-        if (binary != NULL)
-        {
-            g_study_project_attach_binary(get_current_project(), binary);
-            //reload_menu_project(G_OBJECT(data));
-        }
-
-        g_free(filename);
-
-    }
-
-    gtk_widget_destroy(dialog);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : menuitem = élément de menu sélectionné.                      *
-*                ref      = adresse de l'espace de référencement global.      *
-*                                                                             *
-*  Description : Réagit au menu "Projet -> Ajouter un binaire -> Shellcode".  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void mcb_project_add_binary_shellcode(GtkMenuItem *menuitem, GObject *ref)
-{
-    run_add_shellcode_assistant(get_current_project(), GTK_WINDOW(ref));
-
-}
-
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : menuitem = élément de menu sélectionné.                      *
-*                data     = adresse de l'espace de référencement global.      *
-*                                                                             *
-*  Description : Retire un binaire du projet courant.                         *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
 
-void mcb_project_remove_binary(GtkMenuItem *menuitem, gpointer data)
-{
-    GOpenidaBinary *binary;                 /* Représentation chargée      */
 
-    binary = g_object_get_data(G_OBJECT(menuitem), "binary");
 
-    g_study_project_detach_binary(get_current_project(), binary);
-    //unload_binary_file(binary);
 
-    //reload_menu_project(G_OBJECT(data));
 
-}
 
 
 
@@ -966,65 +830,6 @@ void mcb_project_remove_binary(GtkMenuItem *menuitem, gpointer data)
 
 
 
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : ref = espace de référencements global.                       *
-*                                                                             *
-*  Description : Met à jour le contenu du menu 'Projet'.                      *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void reload_menu_project(GObject *ref)
-{
-#if 0
-    GtkWidget *menuitem;                    /* Menu principal à compléter  */
-    GtkWidget *menubar;                     /* Support pour éléments       */
-    GList *list;                            /* Liste des éléments en place */
-    GList *iter;                            /* Boucle de parcours #1       */
-    size_t count;                           /* Nombre de binaires attachés */
-    const GOpenidaBinary **binaries;        /* Liste de ces binaires       */
-    size_t i;                               /* Boucle de parcours #2       */
-    const char *desc;                       /* Description à afficher      */
-    GtkWidget *submenuitem;                 /* Sous-menu à ajouter         */
-
-    menuitem = GTK_WIDGET(g_object_get_data(ref, "menu_prj_remove_bin"));
-    menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem));
-
-    /* Remise à zéro */
-
-    list = gtk_container_get_children(GTK_CONTAINER(menubar));
-
-    for (iter = list; iter != NULL; iter = g_list_next(iter))
-        gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(iter->data));
-
-    g_list_free(list);
-
-    /* Ajout des entrées */ 
-
-    binaries = get_openida_project_binaries(get_current_project(), &count);
-
-    for (i = 0; i < count; i++)
-    {
-        desc = g_openida_binary_to_string(binaries[i]);
-
-        submenuitem = qck_create_menu_item(NULL, NULL, desc, G_CALLBACK(mcb_project_remove_binary), ref);
-        g_object_set_data(G_OBJECT(submenuitem), "binary", binaries[i]);
-        gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
-    }
-
-    gtk_widget_set_sensitive(menuitem, count > 0);
-#endif
-}
-
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : menuitem = élément de menu sélectionné.                      *
diff --git a/src/gtkext/gtkextstatusbar.c b/src/gtkext/gtkextstatusbar.c
index e0ce43d..c89cfe4 100644
--- a/src/gtkext/gtkextstatusbar.c
+++ b/src/gtkext/gtkextstatusbar.c
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * gtkextstatusbar.h - prototypes pour la barre de statut améliorée
  *
- * Copyright (C) 2009-2010 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -124,7 +124,7 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g
 {
     guint result;                           /* Identifiant à retourner     */
 
-    gdk_threads_enter();
+    //gdk_threads_enter();
 
     result = gtk_statusbar_push(GTK_STATUSBAR(bar), bar->context, message);
 
@@ -145,9 +145,9 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g
     }
     else gtk_widget_hide(GTK_WIDGET(bar->progress));
 
-    gdk_flush ();
+    //gdk_flush ();
 
-    gdk_threads_leave();
+    //gdk_threads_leave();
 
     return result;
 
@@ -181,12 +181,12 @@ void gtk_extended_status_bar_update_activity(GtkExtStatusBar *bar, guint id, gdo
 
         g_snprintf(percent, 5, "%.0f%%", value * 100);
 
-        gdk_threads_enter();
+        //gdk_threads_enter();
 
         gtk_progress_bar_set_fraction(bar->progress, value);
         gtk_progress_bar_set_text(bar->progress, percent);
 
-        gdk_threads_leave();
+        //gdk_threads_leave();
 
     }
 
@@ -210,7 +210,7 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id)
 {
     size_t i;                               /* Boucle de parcours          */
 
-    gdk_threads_enter();
+    //gdk_threads_enter();
 
     gtk_statusbar_remove(GTK_STATUSBAR(bar), bar->context, id);
 
@@ -234,8 +234,8 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id)
     else
         gtk_widget_hide(GTK_WIDGET(bar->progress));
 
-    gdk_flush ();
+    //gdk_flush ();
 
-    gdk_threads_leave();
+    //gdk_threads_leave();
 
 }
diff --git a/src/gui/editem-int.h b/src/gui/editem-int.h
index cdc53ea..0f25147 100644
--- a/src/gui/editem-int.h
+++ b/src/gui/editem-int.h
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * editem-int.h - prototypes pour les définitions internes liées aux éléments réactifs de l'éditeur
  *
- * Copyright (C) 2010 Cyrille Bagard
+ * Copyright (C) 2010-2012 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -42,6 +42,9 @@ typedef void (* update_item_binary_fc) (GEditorItem *, GOpenidaBinary *);
 /* Réagit à un changement d'affichage principal de contenu. */
 typedef void (* update_item_view_fc) (GEditorItem *, GtkViewPanel *);
 
+/* Lance une actualisation relative à l'étendue du projet. */
+typedef void (* update_project_fc) (GEditorItem *, GStudyProject *);
+
 
 /* Elément réactif quelconque de l'éditeur (instance) */
 struct _GEditorItem
@@ -57,6 +60,7 @@ struct _GEditorItem
 
     update_item_binary_fc update_binary;    /* Changement de binaire       */
     update_item_view_fc update_view;        /* Rechargement dû à une vue   */
+    update_project_fc update_project;       /* Actualisation des binaires  */
 
 };
 
diff --git a/src/gui/editem.c b/src/gui/editem.c
index 0516f4d..18102f4 100644
--- a/src/gui/editem.c
+++ b/src/gui/editem.c
@@ -226,3 +226,26 @@ void change_editor_items_current_view(GObject *ref, GtkViewPanel *view)
             iter->update_view(iter, view);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : project = projet concerné par l'évolution.                   *
+*                                                                             *
+*  Description : Lance une actualisation relative à l'étendue du projet.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void update_project_area(GStudyProject *project)
+{
+    GEditorItem *iter;                     /* Boucle de parcours          */
+
+    editem_list_for_each(iter, _editem_list)
+        if (iter->update_project != NULL)
+            iter->update_project(iter, project);
+
+}
diff --git a/src/gui/editem.h b/src/gui/editem.h
index 286013c..0b9989e 100644
--- a/src/gui/editem.h
+++ b/src/gui/editem.h
@@ -29,6 +29,7 @@
 #include <glib-object.h>
 
 
+#include "../project.h"
 #include "../analysis/binary.h"
 #include "../gtkext/gtkviewpanel.h"
 
@@ -78,6 +79,9 @@ void change_editor_items_current_binary(GObject *, GOpenidaBinary *);
 /* Lance une actualisation du fait d'un changement de vue. */
 void change_editor_items_current_view(GObject *, GtkViewPanel *);
 
+/* Lance une actualisation relative à l'étendue du projet. */
+void update_project_area(GStudyProject *);
+
 
 
 #endif  /* _GUI_EDITEM_H */
diff --git a/src/gui/menus/Makefile.am b/src/gui/menus/Makefile.am
index 1275394..4640fd8 100644
--- a/src/gui/menus/Makefile.am
+++ b/src/gui/menus/Makefile.am
@@ -6,6 +6,7 @@ libguimenus_la_SOURCES =				\
 	file.h file.c						\
 	help.h help.c						\
 	menubar.h menubar.c					\
+	project.h project.c					\
 	view.h view.c
 
 libguimenus_la_LDFLAGS = 
diff --git a/src/gui/menus/file.c b/src/gui/menus/file.c
index fade47d..95b50cb 100644
--- a/src/gui/menus/file.c
+++ b/src/gui/menus/file.c
@@ -55,8 +55,8 @@ GtkWidget *build_menu_file(GObject *ref, GtkAccelGroup *accgroup)
 {
     GtkWidget *result;                      /* Support à retourner         */
     GtkWidget *menubar;                     /* Support pour éléments       */
-    GtkWidget *submenuitem;                 /* Sous-élément de menu #2     */
-    GtkWidget *deepmenuitem;                /* Sous-élément de menu #1     */
+    GtkWidget *submenuitem;                 /* Sous-élément de menu #1     */
+    GtkWidget *deepmenuitem;                /* Sous-élément de menu #2     */
 
     result = gtk_menu_item_new_with_mnemonic(_("_File"));
     gtk_widget_show(result);
diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c
index a847d40..a7559cd 100644
--- a/src/gui/menus/menubar.c
+++ b/src/gui/menus/menubar.c
@@ -28,6 +28,7 @@
 #include "debug.h"
 #include "file.h"
 #include "help.h"
+#include "project.h"
 #include "view.h"
 #include "../editem-int.h"
 
@@ -40,6 +41,7 @@ struct _GMenuBar
 
     GtkWidget *file;                        /* Menu "Fichier"              */
     GtkWidget *view;                        /* Menu "Affichage"            */
+    GtkWidget *project;                     /* Menu "Projet"               */
     GtkWidget *debug;                       /* Menu "Débogage"             */
     GtkWidget *help;                        /* Menu "Aide"                 */
 
@@ -63,6 +65,9 @@ static void g_menu_bar_init(GMenuBar *);
 /* Lance une actualisation du fait d'un changement de vue. */
 static void update_menu_bar_for_view(GMenuBar *, GtkViewPanel *);
 
+/* Lance une actualisation relative à l'étendue du projet. */
+static void update_menu_bar_for_project(GMenuBar *, GStudyProject *);
+
 
 
 /* Indique le type défini pour la barre de menus de la fenêtre principale. */
@@ -111,6 +116,7 @@ static void g_menu_bar_init(GMenuBar *bar)
     gtk_widget_show(item->widget);
 
     item->update_view = (update_item_view_fc)update_menu_bar_for_view;
+    item->update_project = (update_project_fc)update_menu_bar_for_project;
 
 }
 
@@ -152,6 +158,11 @@ GEditorItem *g_menu_bar_new(GObject *ref, GtkAccelGroup *accgroup)
     result->view = build_menu_view(ref, accgroup, result);
     gtk_container_add(GTK_CONTAINER(item->widget), result->view);
 
+    /* Projet */
+
+    result->project = build_menu_project(ref, accgroup, result);
+    gtk_container_add(GTK_CONTAINER(item->widget), result->project);
+
     /* Débogage */
 
     result->debug = build_menu_debug(ref, accgroup);
@@ -185,3 +196,23 @@ static void update_menu_bar_for_view(GMenuBar *bar, GtkViewPanel *view)
     update_menu_view_for_view(bar->view, view, bar);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bar     = barre de menus à actualiser.                       *
+*                project = projet visé par la procédure.                      *
+*                                                                             *
+*  Description : Lance une actualisation relative à l'étendue du projet.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void update_menu_bar_for_project(GMenuBar *bar, GStudyProject *project)
+{
+    update_menu_project_for_project(bar->project, project, bar);
+
+}
diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c
new file mode 100644
index 0000000..52a2fbb
--- /dev/null
+++ b/src/gui/menus/project.c
@@ -0,0 +1,227 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * project.c - gestion du menu 'Projet'
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This project is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "project.h"
+
+
+#include <i18n.h>
+
+
+#include "../editem-int.h"
+#include "../../gtkext/easygtk.h"
+
+
+
+/* Affiche la boîte d'ajout d'un binaire au projet courant. */
+static void mcb_project_add_binary_file(GtkMenuItem *, GMenuBar *);
+
+/* Retire un binaire du projet indiqué. */
+static void mcb_project_remove_binary(GtkMenuItem *, GStudyProject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ref      = espace de référencement global.                   *
+*                accgroup = groupe d'accélérateurs pour les menus.            *
+*                bar      = barre de menu parente.                            *
+*                                                                             *
+*  Description : Construit le menu "Projet".                                  *
+*                                                                             *
+*  Retour      : Panneau de menus mis en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *build_menu_project(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
+{
+    GtkWidget *result;                      /* Support à retourner         */
+    GtkWidget *menubar;                     /* Support pour éléments       */
+    GtkWidget *submenuitem;                 /* Sous-élément de menu #1     */
+    GtkWidget *deepmenubar;                 /* Support pour éléments #2    */
+    GtkWidget *deepmenuitem;                /* Sous-élément de menu #2     */
+
+    result = gtk_menu_item_new_with_mnemonic(_("_Project"));
+    gtk_widget_show(result);
+
+    menubar = gtk_menu_new();
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(result), menubar);
+
+    submenuitem = qck_create_menu_item(NULL, NULL, _("Add a binary..."), NULL, NULL);
+    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+    deepmenubar = gtk_menu_new();
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), deepmenubar);
+
+    deepmenuitem = qck_create_menu_item(NULL, NULL, _("File"),
+                                        G_CALLBACK(mcb_project_add_binary_file), bar);
+    gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem);
+
+    submenuitem = qck_create_menu_item(G_OBJECT(result), "menu_prj_remove_bin", _("Remove a binary"),
+                                       NULL, NULL);
+    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+    deepmenubar = gtk_menu_new();
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), deepmenubar);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = menu principal à actualiser.                        *
+*                project = projet visé par la procédure.                      *
+*                bar    = barre de menu parente.                              *
+*                                                                             *
+*  Description : Lance une actualisation relative à l'étendue du projet.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void update_menu_project_for_project(GtkWidget *widget, GStudyProject *project, GMenuBar *bar)
+{
+    GtkWidget *menuitem;                    /* Menu principal à compléter  */
+    GtkWidget *menubar;                     /* Support pour éléments       */
+    GList *list;                            /* Liste des éléments en place */
+    GList *iter;                            /* Boucle de parcours #1       */
+    size_t count;                           /* Nombre de binaires attachés */
+    GOpenidaBinary **binaries;              /* Liste de ces binaires       */
+    size_t i;                               /* Boucle de parcours #2       */
+    const char *desc;                       /* Description à afficher      */
+    GtkWidget *submenuitem;                 /* Sous-menu à ajouter         */
+
+    menuitem = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "menu_prj_remove_bin"));
+    menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem));
+
+    /* Remise à zéro */
+
+    list = gtk_container_get_children(GTK_CONTAINER(menubar));
+
+    for (iter = list; iter != NULL; iter = g_list_next(iter))
+        gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(iter->data));
+
+    g_list_free(list);
+
+    /* Ajout des entrées */ 
+
+    binaries = g_study_project_get_binaries(project, &count);
+
+    for (i = 0; i < count; i++)
+    {
+        desc = g_openida_binary_to_string(binaries[i]);
+
+        submenuitem = qck_create_menu_item(NULL, NULL, desc,
+                                           G_CALLBACK(mcb_project_remove_binary), project);
+        g_object_set_data(G_OBJECT(submenuitem), "binary", binaries[i]);
+        gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+        g_object_unref(G_OBJECT(binaries[i]));
+
+    }
+
+    if (binaries != NULL)
+        free(binaries);
+
+    gtk_widget_set_sensitive(menuitem, count > 0);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : menuitem = élément de menu sélectionné.                      *
+*                bar      = barre de menu parente.                            *
+*                                                                             *
+*  Description : Affiche la boîte d'ajout d'un binaire au projet courant.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void mcb_project_add_binary_file(GtkMenuItem *menuitem, GMenuBar *bar)
+{
+    GtkWidget *dialog;                      /* Boîte à afficher            */
+    gchar *filename;                        /* Nom du fichier à intégrer   */
+    GOpenidaBinary *binary;                 /* Représentation chargée      */
+
+    dialog = gtk_file_chooser_dialog_new(_("Open a binary file"),
+                                         GTK_WINDOW(G_EDITOR_ITEM(bar)->ref),
+                                         GTK_FILE_CHOOSER_ACTION_OPEN,
+                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                         NULL);
+
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+
+        binary = g_openida_binary_new_from_file(filename);
+
+        if (binary != NULL)
+        {
+            g_signal_connect(binary, "disassembly-done",
+                             G_CALLBACK(g_study_project_add_loaded_binary), get_current_project());
+            g_openida_binary_analyse(binary);
+        }
+
+        g_free(filename);
+
+    }
+
+    gtk_widget_destroy(dialog);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : menuitem = élément de menu sélectionné.                      *
+*                project  = projet d'appartenance du binaire à traiter.       *
+*                                                                             *
+*  Description : Retire un binaire du projet indiqué.                         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void mcb_project_remove_binary(GtkMenuItem *menuitem, GStudyProject *project)
+{
+    GOpenidaBinary *binary;                 /* Binaire à retirer           */
+
+    binary = G_OPENIDA_BINARY(g_object_get_data(G_OBJECT(menuitem), "binary"));
+
+    g_study_project_detach_binary(project, binary);
+    g_object_unref(G_OBJECT(binary));
+
+}
diff --git a/src/gui/menus/project.h b/src/gui/menus/project.h
new file mode 100644
index 0000000..06a1e85
--- /dev/null
+++ b/src/gui/menus/project.h
@@ -0,0 +1,45 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * project.h - prototypes pour la gestion du menu 'Projet'
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _GUI_MENUS_PROJECT_H
+#define _GUI_MENUS_PROJECT_H
+
+
+#include <gtk/gtk.h>
+
+
+#include "menubar.h"
+#include "../../project.h"
+
+
+
+/* Construit le menu "Projet". */
+GtkWidget *build_menu_project(GObject *, GtkAccelGroup *, GMenuBar *);
+
+/* Lance une actualisation relative à l'étendue du projet. */
+void update_menu_project_for_project(GtkWidget *, GStudyProject *, GMenuBar *);
+
+
+
+#endif  /* _GUI_MENUS_PROJECT_H */
diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c
index 19f7e9b..e0e7cc4 100644
--- a/src/gui/menus/view.c
+++ b/src/gui/menus/view.c
@@ -52,7 +52,7 @@ static void mcb_view_code(GtkCheckMenuItem *, GMenuBar *);
 *                accgroup = groupe d'accélérateurs pour les menus.            *
 *                bar      = barre de menu parente.                            *
 *                                                                             *
-*  Description : Construit le menu "Fichier".                                 *
+*  Description : Construit le menu "Affichage".                               *
 *                                                                             *
 *  Retour      : Panneau de menus mis en place.                               *
 *                                                                             *
diff --git a/src/gui/menus/view.h b/src/gui/menus/view.h
index 2bdc9b6..e06f519 100644
--- a/src/gui/menus/view.h
+++ b/src/gui/menus/view.h
@@ -33,7 +33,7 @@
 
 
 
-/* Construit le menu "Fichier". */
+/* Construit le menu "Affichage". */
 GtkWidget *build_menu_view(GObject *, GtkAccelGroup *, GMenuBar *);
 
 /* Lance une actualisation du fait d'un changement de vue. */
diff --git a/src/gui/tb/source.c b/src/gui/tb/source.c
index 16f237a..2a1a532 100644
--- a/src/gui/tb/source.c
+++ b/src/gui/tb/source.c
@@ -146,7 +146,7 @@ static void update_source_item_binary(GEditorItem *item, GOpenidaBinary *binary)
     size_t defsrc;                          /* Fichier source principal    */
     const char * const *files;              /* Liste de fichiers source    */
     size_t i;                               /* Boucle de parcours #2       */
-
+    return;     /* FIXME */
     /* Réinitialisation */
 
     combo = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(item->widget), "combo"));
diff --git a/src/main.c b/src/main.c
index 4146b0a..406f762 100644
--- a/src/main.c
+++ b/src/main.c
@@ -156,9 +156,9 @@ int main(int argc, char **argv)
 
     /* Exécution du programme */
 
-    gdk_threads_enter();
+    //gdk_threads_enter();
     gtk_main();
-    gdk_threads_leave();
+    //gdk_threads_leave();
 
     unload_configuration(config);
 
diff --git a/src/project.c b/src/project.c
index f2b02ec..47bbe3e 100644
--- a/src/project.c
+++ b/src/project.c
@@ -80,11 +80,6 @@ static void g_study_project_class_init(GStudyProjectClass *);
 /*Initialise une instance de projet d'étude. */
 static void g_study_project_init(GStudyProject *);
 
-/* Assure l'intégration d'un élément binaire dans un projet. */
-static void g_study_project_add_loaded_binary(GOpenidaBinary *, GStudyProject *);
-
-
-
 
 
 /* ---------------------------------------------------------------------------------- */
@@ -225,43 +220,6 @@ GStudyProject *g_study_project_open(const char *filename)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : binary  = élément binaire tout juste désassemblé.            *
-*                project = projet dont le contenu est à compléter.            *
-*                                                                             *
-*  Description : Assure l'intégration d'un élément binaire dans un projet.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_study_project_add_loaded_binary(GOpenidaBinary *binary, GStudyProject *project)
-{
-    size_t index;                           /* Indice du nouveau binaire   */
-    GtkWidget *view;                        /* Affichage du code binaire   */
-    const char *title;                      /* Titre associé au binaire    */
-    GEditorItem *item;                      /* Panneau avec ses infos.     */
-
-    index = g_study_project_attach_binary(project, binary);
-
-    view = project->binaries[index]->scrollwindows[BVW_BLOCK];
-
-    title = g_openida_binary_to_string(binary);
-
-    //gdk_threads_enter();
-
-    item = g_panel_item_new(strrchr(title, G_DIR_SEPARATOR) + 1, title, view, "M");
-    g_panel_item_dock(G_PANEL_ITEM(item));
-
-    //gdk_flush ();
-    //gdk_threads_leave();
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : project  = project à sauvegarder.                            *
 *                filename = nom de fichier à utiliser ou NULL pour l'existant.*
 *                                                                             *
@@ -341,6 +299,43 @@ const char *g_study_project_get_filename(const GStudyProject *project)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : binary  = élément binaire tout juste désassemblé.            *
+*                project = projet dont le contenu est à compléter.            *
+*                                                                             *
+*  Description : Assure l'intégration d'un élément binaire dans un projet.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_study_project_add_loaded_binary(GOpenidaBinary *binary, GStudyProject *project)
+{
+    size_t index;                           /* Indice du nouveau binaire   */
+    GtkWidget *view;                        /* Affichage du code binaire   */
+    const char *title;                      /* Titre associé au binaire    */
+    GEditorItem *item;                      /* Panneau avec ses infos.     */
+
+    index = g_study_project_attach_binary(project, binary);
+
+    view = project->binaries[index]->scrollwindows[BVW_BLOCK];
+
+    title = g_openida_binary_to_string(binary);
+
+    //gdk_threads_enter();
+
+    item = g_panel_item_new(strrchr(title, G_DIR_SEPARATOR) + 1, title, view, "M");
+    g_panel_item_dock(G_PANEL_ITEM(item));
+
+    //gdk_flush ();
+    //gdk_threads_leave();
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : project = project à effacer de la mémoire.                   *
 *                binary  = fichier binaire à associer au projet actuel.       *
 *                                                                             *
@@ -420,6 +415,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GOpenidaBinary *bin
 
     g_mutex_unlock(project->mutex);
 
+    update_project_area(project);
 
     return result;
 
@@ -459,6 +455,8 @@ void g_study_project_detach_binary(GStudyProject *project, GOpenidaBinary *binar
     project->binaries = (loaded_binary **)realloc(project->binaries,
                                                    --project->binaries_count * sizeof(loaded_binary *));
 
+    update_project_area(project);
+
 }
 
 
@@ -533,6 +531,37 @@ void g_study_project_display(const GStudyProject *project)
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : project = projet dont le contenu est à afficher.             *
+*                count = nombre de binaires pris en compte. [OUT]             *
+*                                                                             *
+*  Description : Fournit l'ensemble des binaires associés à un projet.        *
+*                                                                             *
+*  Retour      : Liste à libérer de la mémoire.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GOpenidaBinary **g_study_project_get_binaries(const GStudyProject *project, size_t *count)
+{
+    GOpenidaBinary **result;                /* Tableau à retourner         */
+    size_t i;                               /* Boucle de parcours          */
+
+    *count = project->binaries_count;
+    result = (GOpenidaBinary **)calloc(*count, sizeof(GOpenidaBinary *));
+
+    for (i = 0; i < *count; i++)
+    {
+        result[i] = project->binaries[i]->binary;
+        g_object_ref(G_OBJECT(result[i]));
+    }
+
+    return result;
+
+}
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                           GESTION GLOBALISEE DES PROJETS                           */
diff --git a/src/project.h b/src/project.h
index 6fb0101..3fd3dab 100644
--- a/src/project.h
+++ b/src/project.h
@@ -78,6 +78,9 @@ bool g_study_project_save(GStudyProject *, const char *);
 /* Indique le chemin du fichier destiné à la sauvegarde. */
 const char *g_study_project_get_filename(const GStudyProject *);
 
+/* Assure l'intégration d'un élément binaire dans un projet. */
+void g_study_project_add_loaded_binary(GOpenidaBinary *, GStudyProject *);
+
 /* Attache un fichier donné à un projet donné. */
 size_t g_study_project_attach_binary(GStudyProject *, GOpenidaBinary *);
 
@@ -90,6 +93,9 @@ GtkWidget *g_study_project_get_view_for_binary(const GStudyProject *, const GOpe
 /* Met en place un projet à l'écran. */
 void g_study_project_display(const GStudyProject *);
 
+/* Fournit l'ensemble des binaires associés à un projet. */
+GOpenidaBinary **g_study_project_get_binaries(const GStudyProject *, size_t *);
+
 
 
 /* ------------------------- GESTION GLOBALISEE DES PROJETS ------------------------- */
-- 
cgit v0.11.2-87-g4458