From 7bcec72d69c5350678ed6350636687c3c29bbc61 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 26 Jan 2012 16:39:48 +0000 Subject: Rewritten the way projects are managed. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@229 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 23 ++ po/fr.po | 2 +- src/dialogs/add_shellcode.c | 4 +- src/dialogs/add_shellcode.h | 4 +- src/editor.c | 72 ++--- src/gui/menus/debug.c | 7 +- src/gui/menus/file.c | 18 +- src/gui/menus/file.h | 2 +- src/gui/menus/view.c | 2 +- src/main.c | 12 +- src/project.c | 623 ++++++++++++++------------------------------ src/project.h | 79 +++--- 12 files changed, 325 insertions(+), 523 deletions(-) diff --git a/ChangeLog b/ChangeLog index 313c06d..754aa5f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +12-01-26 Cyrille Bagard + + * po/fr.po: + Update translations for the File menu. + + * src/dialogs/add_shellcode.c: + * src/dialogs/add_shellcode.h: + * src/editor.c: + * src/gui/menus/debug.c: + Update code. + + * src/gui/menus/file.c: + * src/gui/menus/file.h: + Move recent projects list here. + + * src/gui/menus/view.c: + * src/main.c: + Update code. + + * src/project.c: + * src/project.h: + Rewrite the way projects are managed. + 12-01-16 Cyrille Bagard * po/fr.po: diff --git a/po/fr.po b/po/fr.po index 276b6a1..be4b328 100644 --- a/po/fr.po +++ b/po/fr.po @@ -468,7 +468,7 @@ msgstr "" #: src/editor.c:311 msgid "Recent projects..." -msgstr "" +msgstr "Projets récents..." #: src/editor.c:319 msgid "_View" diff --git a/src/dialogs/add_shellcode.c b/src/dialogs/add_shellcode.c index 6cb4f9d..78bfb9d 100644 --- a/src/dialogs/add_shellcode.c +++ b/src/dialogs/add_shellcode.c @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * export.c - assistant d'exportation de contenu binaire * - * Copyright (C) 2011 Cyrille Bagard + * Copyright (C) 2011-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -120,7 +120,7 @@ static void register_content_panel(GtkAssistant *); * * ******************************************************************************/ -void run_add_shellcode_assistant(openida_project *project, GtkWindow *parent) +void run_add_shellcode_assistant(GStudyProject *project, GtkWindow *parent) { GtkWidget *assistant; /* Fenêtre à afficher */ GObject *ref; /* Espace de référencement */ diff --git a/src/dialogs/add_shellcode.h b/src/dialogs/add_shellcode.h index db30ada..115507c 100644 --- a/src/dialogs/add_shellcode.h +++ b/src/dialogs/add_shellcode.h @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * export.h - prototypes pour l'assistant d'exportation de contenu binaire * - * Copyright (C) 2011 Cyrille Bagard + * Copyright (C) 2011-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -30,7 +30,7 @@ /* Crée et affiche un assistant d'ajout de binaire. */ -void run_add_shellcode_assistant(openida_project *, GtkWindow *); +void run_add_shellcode_assistant(GStudyProject *, GtkWindow *); diff --git a/src/editor.c b/src/editor.c index 01ba64a..68b9c28 100644 --- a/src/editor.c +++ b/src/editor.c @@ -573,8 +573,6 @@ GtkWidget *create_editor(void) - load_recent_openida_projects_list(G_OBJECT(result), G_CALLBACK(mcb_open_recent_project)); - reload_menu_project(G_OBJECT(result)); @@ -602,14 +600,14 @@ GtkWidget *create_editor(void) static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer data) { gboolean result; /* Continuation à retourner */ - openida_project *project; /* Projet courant */ + GStudyProject *project; /* Projet courant */ GtkWidget *dialog; /* Boîte à afficher */ result = FALSE; - project = get_current_openida_project(); + project = get_current_project(); - if (g_openida_project_get_filename(project) == NULL) + if (g_study_project_get_filename(project) == NULL) { dialog = gtk_message_dialog_new(widget, GTK_DIALOG_DESTROY_WITH_PARENT, @@ -661,7 +659,7 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da static void on_destroy_editor(GtkWidget *widget, gpointer data) { - close_openida_project(get_current_openida_project()); + g_object_unref(G_OBJECT(get_current_project())); /* Fermeture propre */ @@ -690,13 +688,13 @@ static void on_destroy_editor(GtkWidget *widget, gpointer data) void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data) { - openida_project *project; /* Nouveau projet courant */ + GStudyProject *project; /* Nouveau projet courant */ - project = create_empty_openida_project(G_OBJECT(data)); + project = g_study_project_new(); - set_current_openida_project(project); + set_current_project(project); - display_openida_project(project, G_OBJECT(data)); + g_study_project_display(project); } @@ -717,7 +715,7 @@ void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data) void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data) { GtkWidget *dialog; /* Boîte à afficher */ - openida_project *project; /* Projet chargé */ + GStudyProject *project; /* Projet chargé */ gchar *filename; /* Nom du fichier à intégrer */ dialog = gtk_file_chooser_dialog_new(_("Open a project"), GTK_WINDOW(data), @@ -726,21 +724,22 @@ void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data) GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - project = get_current_openida_project(); + project = get_current_project(); - if (g_openida_project_get_filename(project) != NULL) - gtk_file_chooser_set_filename(dialog, g_openida_project_get_filename(project)); + if (g_study_project_get_filename(project) != NULL) + gtk_file_chooser_set_filename(dialog, g_study_project_get_filename(project)); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - project = g_openida_project_new_from_xml(G_OBJECT(data), filename); + project = g_study_project_open(filename); if (project != NULL) { - set_current_openida_project(project); - display_openida_project(project, G_OBJECT(data)); + set_current_project(project); + g_study_project_display(project); + push_project_into_recent_list(project); } g_free(filename); @@ -767,14 +766,14 @@ void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data) void mcb_file_save_project(GtkMenuItem *menuitem, gpointer data) { - openida_project *project; /* Projet courant */ + GStudyProject *project; /* Projet courant */ - project = get_current_openida_project(); + project = get_current_project(); - if (g_openida_project_get_filename(project) != NULL) + if (g_study_project_get_filename(project) != NULL) { - if (g_openida_project_save(project, NULL)) - push_openida_project_into_recent_list(project); + if (g_study_project_save(project, NULL)) + push_project_into_recent_list(project); } else @@ -799,7 +798,7 @@ void mcb_file_save_project(GtkMenuItem *menuitem, gpointer data) void mcb_file_save_project_as(GtkMenuItem *menuitem, gpointer data) { GtkWidget *dialog; /* Boîte à afficher */ - openida_project *project; /* Projet courant */ + GStudyProject *project; /* Projet courant */ gchar *filename; /* Nom du fichier à intégrer */ dialog = gtk_file_chooser_dialog_new(_("Save the project as..."), GTK_WINDOW(data), @@ -808,17 +807,17 @@ void mcb_file_save_project_as(GtkMenuItem *menuitem, gpointer data) GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - project = get_current_openida_project(); + project = get_current_project(); - if (g_openida_project_get_filename(project) != NULL) - gtk_file_chooser_set_filename(dialog, g_openida_project_get_filename(project)); + if (g_study_project_get_filename(project) != NULL) + gtk_file_chooser_set_filename(dialog, g_study_project_get_filename(project)); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - if (g_openida_project_save(project, filename)) - push_openida_project_into_recent_list(project); + if (g_study_project_save(project, filename)) + push_project_into_recent_list(project); g_free(filename); @@ -844,6 +843,7 @@ void mcb_file_save_project_as(GtkMenuItem *menuitem, gpointer data) void mcb_open_recent_project(GtkMenuItem *menuitem, GObject *ref) { +#if 0 const gchar *caption; /* Etiquette du menu */ openida_project *project; /* Nouveau projet chargé */ @@ -856,12 +856,12 @@ void mcb_open_recent_project(GtkMenuItem *menuitem, GObject *ref) push_openida_project_into_recent_list(project); load_recent_openida_projects_list(ref, G_CALLBACK(mcb_open_recent_project)); - set_current_openida_project(project); + set_current_project(project); /* TODO ... */ } - +#endif } @@ -900,8 +900,8 @@ void mcb_project_add_binary(GtkMenuItem *menuitem, gpointer data) if (binary != NULL) { - attach_binary_to_openida_project(get_current_openida_project(), binary); - reload_menu_project(G_OBJECT(data)); + g_study_project_attach_binary(get_current_project(), binary); + //reload_menu_project(G_OBJECT(data)); } g_free(filename); @@ -928,7 +928,7 @@ void mcb_project_add_binary(GtkMenuItem *menuitem, gpointer data) static void mcb_project_add_binary_shellcode(GtkMenuItem *menuitem, GObject *ref) { - run_add_shellcode_assistant(get_current_openida_project(), GTK_WINDOW(ref)); + run_add_shellcode_assistant(get_current_project(), GTK_WINDOW(ref)); } @@ -952,10 +952,10 @@ void mcb_project_remove_binary(GtkMenuItem *menuitem, gpointer data) binary = g_object_get_data(G_OBJECT(menuitem), "binary"); - detach_binary_to_openida_project(get_current_openida_project(), binary); + g_study_project_detach_binary(get_current_project(), binary); //unload_binary_file(binary); - reload_menu_project(G_OBJECT(data)); + //reload_menu_project(G_OBJECT(data)); } @@ -1007,7 +1007,7 @@ void reload_menu_project(GObject *ref) /* Ajout des entrées */ - binaries = get_openida_project_binaries(get_current_openida_project(), &count); + binaries = get_openida_project_binaries(get_current_project(), &count); for (i = 0; i < count; i++) { diff --git a/src/gui/menus/debug.c b/src/gui/menus/debug.c index 0d9b41d..963c095 100644 --- a/src/gui/menus/debug.c +++ b/src/gui/menus/debug.c @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * debug.c - gestion du menu 'Débogage' * - * Copyright (C) 2011 Cyrille Bagard + * Copyright (C) 2011-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -30,8 +30,7 @@ #include - -#include "../../project.h" +#include "../../debug/debugger.h" /* REMME ! */ #include "../../gtkext/easygtk.h" #include "../../gui/panels/log.h" @@ -98,7 +97,7 @@ static void mcb_debug_start_stop(GtkMenuItem *menuitem, GObject *ref) GBinaryDebugger *debugger; /* Module prêt à emploi */ binary = (GOpenidaBinary *)g_object_get_data(ref, "current_binary"); - debugger = get_main_debugger_for_binary(get_current_openida_project(), binary); + debugger = NULL;//get_main_debugger_for_binary(get_current_openida_project(), binary); if (debugger == NULL) { diff --git a/src/gui/menus/file.c b/src/gui/menus/file.c index 880fb8a..fade47d 100644 --- a/src/gui/menus/file.c +++ b/src/gui/menus/file.c @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * file.c - gestion du menu 'Fichier' * - * Copyright (C) 2011 Cyrille Bagard + * Copyright (C) 2011-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -28,6 +28,7 @@ #include +#include "../../project.h" #include "../../gtkext/easygtk.h" @@ -54,7 +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 */ + GtkWidget *submenuitem; /* Sous-élément de menu #2 */ + GtkWidget *deepmenuitem; /* Sous-élément de menu #1 */ result = gtk_menu_item_new_with_mnemonic(_("_File")); gtk_widget_show(result); @@ -62,6 +64,18 @@ GtkWidget *build_menu_file(GObject *ref, GtkAccelGroup *accgroup) menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(result), menubar); + submenuitem = qck_create_menu_item(NULL, NULL, _("Recent projects..."), NULL, NULL); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + deepmenuitem = gtk_recent_chooser_menu_new_for_manager(get_projects_manager()); + gtk_recent_chooser_set_sort_type(GTK_RECENT_CHOOSER(deepmenuitem), GTK_RECENT_SORT_MRU); + gtk_recent_chooser_set_show_tips(GTK_RECENT_CHOOSER(deepmenuitem), TRUE); + gtk_recent_chooser_set_show_icons(GTK_RECENT_CHOOSER(deepmenuitem), FALSE); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), deepmenuitem); + + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + submenuitem = qck_create_menu_item(NULL, NULL, _("Quit"), G_CALLBACK(mcb_file_quit), ref); add_accelerator_to_menu_item(submenuitem, "Q", accgroup); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); diff --git a/src/gui/menus/file.h b/src/gui/menus/file.h index 13da6aa..c0802a7 100644 --- a/src/gui/menus/file.h +++ b/src/gui/menus/file.h @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * file.h - prototypes pour la gestion du menu 'Fichier' * - * Copyright (C) 2011 Cyrille Bagard + * Copyright (C) 2011-2012 Cyrille Bagard * * This file is part of OpenIDA. * diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c index 273b41b..19f7e9b 100644 --- a/src/gui/menus/view.c +++ b/src/gui/menus/view.c @@ -198,7 +198,7 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, GMenuBar *bar) station = gtk_widget_get_parent(station); /* DockStation */ binary = g_editor_item_get_current_binary(G_EDITOR_ITEM(bar)); - scroll = get_view_for_openida_project_binary(get_current_openida_project(), + scroll = g_study_project_get_view_for_binary(get_current_project(), binary, view, &vpanel); gtk_dock_panel_change_active_widget(GTK_DOCK_STATION(station), scroll); diff --git a/src/main.c b/src/main.c index 9430541..4146b0a 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * main.c - fichier d'entrée du programme * - * Copyright (C) 2009-2011 Cyrille Bagard + * Copyright (C) 2009-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -56,7 +56,7 @@ * * ******************************************************************************/ -static show_version(void) +static void show_version(void) { printf("\n"); @@ -92,7 +92,7 @@ int main(int argc, char **argv) configuration *config; /* Configuration principale */ GtkWidget *editor; /* Fenêtre graphique */ const char *filename; /* Chemin du dernier projet */ - openida_project *project; /* Nouveau projet courant */ + GStudyProject *project; /* Nouveau projet courant */ if (argc > 1 && strcmp(argv[1], "--version") == 0) @@ -149,10 +149,10 @@ int main(int argc, char **argv) filename = get_string_config_value(config, MPT_RECENT_PROJECT_1); - if (filename == NULL) project = create_empty_openida_project(G_OBJECT(editor)); - else project = g_openida_project_new_from_xml(G_OBJECT(editor), filename); + if (filename == NULL) project = g_study_project_new(); + else project = g_study_project_open(filename); - set_current_openida_project(project); + set_current_project(project); /* Exécution du programme */ diff --git a/src/project.c b/src/project.c index f4f5b1b..f2b02ec 100644 --- a/src/project.c +++ b/src/project.c @@ -24,52 +24,38 @@ #include "project.h" +#include #include #include -#include "params.h" #include "common/xml.h" #include "gtkext/easygtk.h" #include "gtkext/gtkblockview.h" #include "gtkext/gtkdockpanel.h" #include "gtkext/gtkgraphview.h" #include "gtkext/gtksourceview.h" -#include "gtkext/gtkviewpanel.h" #include "gui/panels/panel.h" -#include "panels/panel.h" -/* ----------------------- CACHE INTERMEDIAIRE D'ASSOCIATIONS ----------------------- */ +/* ------------------------- DEFINITION D'UN PROJET INTERNE ------------------------- */ /* Conservation d'un binaire chargé */ typedef struct _loaded_binary { GOpenidaBinary *binary; /* Binaire en question */ - GtkWidget *views[BVW_COUNT]; /* Composants pour l'affichage */ + GtkViewPanel *views[BVW_COUNT]; /* Composants pour l'affichage */ + GtkWidget *scrollwindows[BVW_COUNT]; /* Supports pour l'affichage */ } loaded_binary; -/* Met en place un nouveau binaire pour un projet. */ -static loaded_binary *load_openida_binary(GOpenidaBinary *); - -/* Fournit un support d'affichage donné pour un binaire chargé. */ -GtkWidget *get_loaded_binary_view(const loaded_binary *, BinaryView); - - - -/* --------------------------- GESTION D'UN PROJET ENTIER --------------------------- */ - - - - -/* Propriétés d'un ensemble de fichiers ouverts */ -struct openida_project +/* Projet d'étude regroupant les binaires analysés (instance) */ +struct _GStudyProject { - GObject *ref; /* Espace de référencement */ + GObject parent; /* A laisser en premier */ char *filename; /* Lieu d'enregistrement */ @@ -77,193 +63,103 @@ struct openida_project size_t binaries_count; /* Nombre de ces fichiers */ GMutex *mutex; /* Modification de la liste */ +}; + +/* Projet d'étude regroupant les binaires analysés (classe) */ +struct _GStudyProjectClass +{ + GObjectClass parent; /* A laisser en premier */ }; +/* Initialise la classe des projets d'étude. */ +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. */ -void display_new_binary_of_openida_project(GOpenidaBinary *, openida_project *); +static void g_study_project_add_loaded_binary(GOpenidaBinary *, GStudyProject *); /* ---------------------------------------------------------------------------------- */ -/* CACHE INTERMEDIAIRE D'ASSOCIATIONS */ +/* DEFINITION D'UN PROJET INTERNE */ /* ---------------------------------------------------------------------------------- */ -/****************************************************************************** -* * -* Paramètres : binary = binaire chargé à encadrer. * -* * -* Description : Met en place un nouveau binaire pour un projet. * -* * -* Retour : Adresse de la structure intermédiaire ou NULL si aucune (!). * -* * -* Remarques : - * -* * -******************************************************************************/ - -static loaded_binary *load_openida_binary(GOpenidaBinary *binary) -{ - loaded_binary *result; /* Structure à renvoyer */ - BinaryView i; /* Boucle de parcours */ - GtkWidget *view; /* Affichage du binaire */ - GtkWidget *scrolledwindow; /* Surface d'exposition */ - - result = (loaded_binary *)calloc(1, sizeof(loaded_binary)); - - result->binary = binary; - - for (i = 0; i < BVW_COUNT; i++) - { - /* Préparation du support */ - - gdk_threads_enter(); - - switch (i) - { - case BVW_BLOCK: - view = gtk_block_view_new(/*MRD_BLOCK*/); - break; - case BVW_GRAPH: - view = gtk_graph_view_new(); - break; - case BVW_SOURCE: - view = gtk_source_view_new(); - break; - default: /* GCC ! */ - break; - } - - gtk_widget_show(view); - - gdk_flush(); - gdk_threads_leave(); - - gtk_view_panel_attach_binary(GTK_VIEW_PANEL(view), binary, - g_openida_binary_display_addresses_in_text(binary), - g_openida_binary_display_code_in_text(binary)); - - /* Intégration finale */ - - gdk_threads_enter(); - - scrolledwindow = qck_create_scrolled_window(NULL, NULL); - gtk_container_add(GTK_CONTAINER(scrolledwindow), view); - - result->views[i] = scrolledwindow; - - gdk_flush(); - gdk_threads_leave(); - - } - - return result; - -} - - - - +/* Indique le type défini pour un projet d'étude. */ +G_DEFINE_TYPE(GStudyProject, g_study_project, G_TYPE_OBJECT); /****************************************************************************** * * -* Paramètres : binary = binaire chargé et encadré. * -* view = type d'affichage requis. * +* Paramètres : klass = classe à initialiser. * * * -* Description : Fournit un support d'affichage donné pour un binaire chargé. * +* Description : Initialise la classe des projets d'étude. * * * -* Retour : Composant GTK dédié à un affichage particulier. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *get_loaded_binary_view(const loaded_binary *binary, BinaryView view) +static void g_study_project_class_init(GStudyProjectClass *klass) { - return binary->views[view]; } - - - - - - - - /****************************************************************************** * * -* Paramètres : project = éventuel adresse à renvoyer désormais. * +* Paramètres : project = instance à initialiser. * * * -* Description : Fournit l'adresse du projet courant. * +* Description : Initialise une instance de projet d'étude. * * * -* Retour : Adresse du projet ouvert ou NULL si aucun (!). * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -openida_project *_get_current_openida_project(openida_project *project) +static void g_study_project_init(GStudyProject *project) { - static openida_project *result = NULL; /* Adresse à retourner */ - - if (project != NULL) - { - if (result != NULL) close_openida_project(result); - result = project; - } - - return result; + project->mutex = g_mutex_new(); + if (project->mutex == NULL) /* FIXME */; } /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : - * * * -* Description : Crée un projet vide. * +* Description : Crée un nouveau projet vierge. * * * -* Retour : - * +* Retour : Instance mise en place. * * * * Remarques : - * * * ******************************************************************************/ -openida_project *create_empty_openida_project(GObject *ref) +GStudyProject *g_study_project_new(void) { - openida_project *result; /* Adresse à retourner */ - - result = (openida_project *)calloc(1, sizeof(openida_project)); - - result->ref = ref; + GStudyProject *result; /* Composant à retourner */ - result->mutex = g_mutex_new(); - if (result->mutex == NULL) - goto crop_error; + result = g_object_new(G_TYPE_STUDY_PROJECT, NULL); return result; - crop_error: - - return NULL; - } /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* filename = chemin d'accès au fichier à charger. * +* Paramètres : filename = chemin d'accès au fichier à charger. * * * * Description : Crée un projet à partir du contenu XML d'un fichier. * * * @@ -273,9 +169,9 @@ openida_project *create_empty_openida_project(GObject *ref) * * ******************************************************************************/ -openida_project *g_openida_project_new_from_xml(GObject *ref, const char *filename) +GStudyProject *g_study_project_open(const char *filename) { - openida_project *result; /* Adresse à retourner */ + GStudyProject *result; /* Adresse à retourner */ xmlDocPtr xdoc; /* Structure XML chargée */ xmlXPathContextPtr context; /* Contexte pour les XPath */ xmlXPathObjectPtr xobject; /* Cible d'une recherche */ @@ -286,7 +182,7 @@ openida_project *g_openida_project_new_from_xml(GObject *ref, const char *filena if (!open_xml_file(filename, &xdoc, &context)) return NULL; - result = create_empty_openida_project(ref); + result = g_study_project_new(); result->filename = strdup(filename); @@ -309,7 +205,7 @@ openida_project *g_openida_project_new_from_xml(GObject *ref, const char *filena if (binary != NULL) { g_signal_connect(binary, "disassembly-done", - G_CALLBACK(display_new_binary_of_openida_project), result); + G_CALLBACK(g_study_project_add_loaded_binary), result); g_openida_binary_analyse(binary); } @@ -329,6 +225,43 @@ openida_project *g_openida_project_new_from_xml(GObject *ref, const char *filena /****************************************************************************** * * +* 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.* * * @@ -340,7 +273,7 @@ openida_project *g_openida_project_new_from_xml(GObject *ref, const char *filena * * ******************************************************************************/ -bool g_openida_project_save(openida_project *project, const char *filename) +bool g_study_project_save(GStudyProject *project, const char *filename) { bool result; /* Bilan à retourner */ xmlDocPtr xdoc; /* Document XML à créer */ @@ -361,7 +294,7 @@ bool g_openida_project_save(openida_project *project, const char *filename) + strlen("4294967295" /* UINT_MAX */) + strlen("]") + 1; access = calloc(access_len, sizeof(char)); - snprintf(access, access_len, "/OpenIDAProject/Binaries/Binary[position()=%u]", i + 1); + snprintf(access, access_len, "/OpenIDAProject/Binaries/Binary[position()=%zu]", i + 1); result = g_openida_binary_save(project->binaries[i]->binary, xdoc, context, access); @@ -389,48 +322,6 @@ bool g_openida_project_save(openida_project *project, const char *filename) /****************************************************************************** * * -* Paramètres : project = project à effacer de la mémoire. * -* * -* Description : Ferme un projet et libère la mémoire associée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void close_openida_project(openida_project *project) -{ - size_t max; /* Nombre de binaires chargés */ - size_t i; /* Boucle de parcours */ - - - - - /* TODO : sauvegarde automatique */ - - - - - /* Fermeture propre */ - - - max = project->binaries_count; - - for (i = 0; i < max; i++) - detach_binary_to_openida_project(project, project->binaries[0]->binary); - - - /* ... */ - - - free(project); - -} - - -/****************************************************************************** -* * * Paramètres : project = project à consulter. * * * * Description : Indique le chemin du fichier destiné à la sauvegarde. * @@ -441,15 +332,13 @@ void close_openida_project(openida_project *project) * * ******************************************************************************/ -const char *g_openida_project_get_filename(const openida_project *project) +const char *g_study_project_get_filename(const GStudyProject *project) { return project->filename; } - - /****************************************************************************** * * * Paramètres : project = project à effacer de la mémoire. * @@ -463,9 +352,62 @@ const char *g_openida_project_get_filename(const openida_project *project) * * ******************************************************************************/ -size_t attach_binary_to_openida_project(openida_project *project, GOpenidaBinary *binary) +size_t g_study_project_attach_binary(GStudyProject *project, GOpenidaBinary *binary) { size_t result; /* Indice à retourner */ + loaded_binary *loaded; /* Structure à renvoyer */ + BinaryView i; /* Boucle de parcours */ + GtkWidget *view; /* Affichage du binaire */ + GtkWidget *scrolledwindow; /* Surface d'exposition */ + + loaded = (loaded_binary *)calloc(1, sizeof(loaded_binary)); + + loaded->binary = binary; + + for (i = 0; i < BVW_COUNT; i++) + { + /* Préparation du support visuel */ + + //gdk_threads_enter(); + + switch (i) + { + case BVW_BLOCK: + view = gtk_block_view_new(/*MRD_BLOCK*/); + break; + case BVW_GRAPH: + view = gtk_graph_view_new(); + break; + case BVW_SOURCE: + view = gtk_source_view_new(); + break; + default: /* GCC ! */ + break; + } + + gtk_widget_show(view); + + //gdk_flush(); + //gdk_threads_leave(); + + loaded->views[i] = GTK_VIEW_PANEL(view); + + gtk_view_panel_attach_binary(loaded->views[i], binary, + g_openida_binary_display_addresses_in_text(binary), + g_openida_binary_display_code_in_text(binary)); + + /* Intégration finale dans un support défilant */ + + //gdk_threads_enter(); + + scrolledwindow = qck_create_scrolled_window(NULL, NULL); + gtk_container_add(GTK_CONTAINER(scrolledwindow), view); + + loaded->scrollwindows[i] = scrolledwindow; + + } + + /* Enregistrement dans le projet */ g_mutex_lock(project->mutex); @@ -474,9 +416,10 @@ size_t attach_binary_to_openida_project(openida_project *project, GOpenidaBinary result = project->binaries_count - 1; + project->binaries[result] = loaded; + g_mutex_unlock(project->mutex); - project->binaries[result] = load_openida_binary(binary); return result; @@ -496,13 +439,13 @@ size_t attach_binary_to_openida_project(openida_project *project, GOpenidaBinary * * ******************************************************************************/ -void detach_binary_to_openida_project(openida_project *project, GOpenidaBinary *binary) +void g_study_project_detach_binary(GStudyProject *project, GOpenidaBinary *binary) { - GtkDockPanel *dpanel; /* Support de panneaux */ - GDockItem *ditem; /* Support d'affichage utilisé */ + //GtkDockPanel *dpanel; /* Support de panneaux */ + //GDockItem *ditem; /* Support d'affichage utilisé */ size_t i; /* Boucle de parcours */ - dpanel = GTK_DOCK_PANEL(g_object_get_data(project->ref, "binpanel")); + //dpanel = GTK_DOCK_PANEL(g_object_get_data(project->ref, "binpanel")); //ditem = gtk_dock_panel_get_item_from_binary(project, binary); FIXME !! //gtk_dock_panel_remove_item(dpanel, ditem); @@ -519,48 +462,12 @@ void detach_binary_to_openida_project(openida_project *project, GOpenidaBinary * } - - - - - -/****************************************************************************** -* * -* Paramètres : project = projet à consulter. * -* binary = binaire chargé et encadré. * -* * -* Description : Fournit le support d'affichage principal d'un binaire chargé.* -* * -* Retour : Composant GLib dédié à l'affichage principal. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GDockItem *gtk_dock_panel_get_item_from_binary(const openida_project *project, GOpenidaBinary *binary) -{ - GDockItem *result; /* Panneau avec ses infos. */ - GtkDockPanel *dpanel; /* Support de panneaux */ - const char *title; /* Titre associé au binaire */ - - dpanel = GTK_DOCK_PANEL(g_object_get_data(project->ref, "binpanel")); - - title = g_openida_binary_to_string(binary); - result = gtk_dock_panel_item_from_name(dpanel, strrchr(title, '/') + 1); - - return result; - -} - - - - /****************************************************************************** * * * Paramètres : project = projet à consulter. * * binary = binaire chargé, encadré et concerné. * -* view = type d'affichage requis. * -* panel = afficheur effectif quelconque. [OUT] * +* kind = type d'affichage requis. * +* view = afficheur effectif quelconque. [OUT] * * * * Description : Fournit un support d'affichage donné pour un binaire chargé. * * * @@ -570,18 +477,19 @@ GDockItem *gtk_dock_panel_get_item_from_binary(const openida_project *project, G * * ******************************************************************************/ -GtkWidget *get_view_for_openida_project_binary(const openida_project *project, const GOpenidaBinary *binary, BinaryView view, GtkViewPanel **panel) +GtkWidget *g_study_project_get_view_for_binary(const GStudyProject *project, const GOpenidaBinary *binary, BinaryView kind, GtkViewPanel **view) { GtkWidget *result; /* Composant GTK à retourner */ size_t i; /* Boucle de parcours */ result = NULL; + *view = NULL; for (i = 0; i < project->binaries_count; i++) if (project->binaries[i]->binary == binary) { - result = get_loaded_binary_view(project->binaries[i], view); - *panel = GTK_VIEW_PANEL(gtk_bin_get_child(result)); + result = project->binaries[i]->scrollwindows[kind]; + *view = project->binaries[i]->views[kind]; break; } @@ -592,10 +500,9 @@ GtkWidget *get_view_for_openida_project_binary(const openida_project *project, c /****************************************************************************** * * -* Paramètres : project = project à effacer de la mémoire. * -* count = nombre de binaires pris en compte. [OUT] * +* Paramètres : project = projet dont le contenu est à afficher. * * * -* Description : Fournit l'ensemble des binaires associés à un projet. * +* Description : Met en place un projet à l'écran. * * * * Retour : - * * * @@ -603,196 +510,94 @@ GtkWidget *get_view_for_openida_project_binary(const openida_project *project, c * * ******************************************************************************/ -const GOpenidaBinary **get_openida_project_binaries(const openida_project *project, size_t *count) +void g_study_project_display(const GStudyProject *project) { - *count = project->binaries_count; - - return project->binaries; - -} - - - - - - + size_t i; /* Boucle de parcours */ + GOpenidaBinary *binary; /* Binaire chargé */ + GtkWidget *scroll; /* Affichage du code binaire */ + const char *title; /* Titre associé au binaire */ + GEditorItem *item; /* Panneau avec ses infos. */ + for (i = 0; i < project->binaries_count; i++) + { + binary = project->binaries[i]->binary; + scroll = project->binaries[i]->scrollwindows[BVW_BLOCK]; + title = g_openida_binary_to_string(binary); -/****************************************************************************** -* * -* Paramètres : project = projet à consulter. * -* binary = binaire chargé, encadré et concerné. * -* * -* Description : Fournit un module de débogage prêt à emploi. * -* * -* Retour : Instance prête à devenir effective. * -* * -* Remarques : - * -* * -******************************************************************************/ + item = g_panel_item_new(strrchr(title, G_DIR_SEPARATOR) + 1, title, scroll, "M"); + g_panel_item_dock(G_PANEL_ITEM(item)); -GBinaryDebugger *get_main_debugger_for_binary(const openida_project *project, const GOpenidaBinary *binary) -{ - return g_java_debugger_new(binary, NULL); /* FIXME */ + } } - - - - - - - - - - - - - /* ---------------------------------------------------------------------------------- */ -/* PARTIE GRAPHIQUE DES [DE]CHARGEMENTS */ +/* GESTION GLOBALISEE DES PROJETS */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : project = projet à traiter. * +* Paramètres : project = éventuel adresse à renvoyer désormais. * * * -* Description : Place un projet au sommet de la pile des projets récents. * +* Description : Fournit l'adresse du projet courant. * * * -* Retour : - * +* Retour : Adresse du projet ouvert ou NULL si aucun (!). * * * * Remarques : - * * * ******************************************************************************/ -void push_openida_project_into_recent_list(const openida_project *project) +GStudyProject *_get_current_study_project(GStudyProject *project) { - configuration *config; /* Configuration principale */ - unsigned int i; /* Boucle de parcours */ - const char *filename; /* Chemin d'un projet donné */ - - pop_openida_project_from_recent_list(project); - - config = get_main_configuration(); + static GStudyProject *result = NULL; /* Adresse à retourner */ - for (i = MPT_RECENT_PROJECT_7; i > MPT_RECENT_PROJECT_1; i--) + if (project != NULL) { - filename = get_string_config_value(config, i - 1); - set_string_config_value(config, i, filename); + if (result != NULL) g_object_unref(G_OBJECT(result)); + result = project; } - set_string_config_value(config, MPT_RECENT_PROJECT_1, project->filename); + return result; } /****************************************************************************** * * -* Paramètres : project = projet à traiter. * +* Paramètres : - * * * -* Description : Retire un projet de la pile des projets récents. * +* Description : Fournit le gestionnaire des projets connus. * * * -* Retour : - * +* Retour : Instance de gestion unique. * * * * Remarques : - * * * ******************************************************************************/ -void pop_openida_project_from_recent_list(const openida_project *project) +GtkRecentManager *get_projects_manager(void) { - configuration *config; /* Configuration principale */ - unsigned int i; /* Boucle de parcours #1 */ - const char *filename; /* Chemin d'un projet donné */ - unsigned int k; /* Boucle de parcours #2 */ - - if (project->filename == NULL) return; + static GtkRecentManager *result = NULL; /* Singleton à retourner */ - config = get_main_configuration(); - - for (i = MPT_RECENT_PROJECT_1; i <= MPT_RECENT_PROJECT_7; i++) + if (result == NULL) { - filename = get_string_config_value(config, i); - - if (filename == NULL || strcmp(filename, project->filename) == 0) - { - for (k = i; k <= MPT_RECENT_PROJECT_6; k++) - { - filename = get_string_config_value(config, k + 1); - set_string_config_value(config, k, filename); - } - - set_string_config_value(config, k, NULL); - - } - + result = gtk_recent_manager_new(); + //gtk_recent_manager_purge_items(result, NULL); } -} - - -/****************************************************************************** -* * -* Paramètres : ref = espace global de référencement. * -* func = fonction à appeler lors d'un clic sur les menus. * -* * -* Description : Met en place les menus rechargeant les projets récents. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void load_recent_openida_projects_list(GObject *ref, GCallback func) -{ - gboolean one_entry; /* Au moins en entrée chargée */ - GtkWidget *menuitem; /* Menu principal à compléter */ - GtkWidget *menubar; /* Support pour éléments */ - configuration *config; /* Configuration principale */ - unsigned int i; /* Boucle de parcours */ - const char *filename; /* Nom de fichier à ouvrir */ - GtkWidget *submenuitem; /* Sous-menu à ajouter */ - - one_entry = false; - - menuitem = GTK_WIDGET(g_object_get_data(ref, "menu_recent_prjs")); - menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem)); - - gtk_container_foreach(GTK_CONTAINER(menubar), G_CALLBACK(gtk_widget_destroy), NULL); - - config = get_main_configuration(); - - for (i = MPT_RECENT_PROJECT_1; i <= MPT_RECENT_PROJECT_7; i++) - { - filename = get_string_config_value(config, i); - - if (filename != NULL) - { - submenuitem = qck_create_menu_item(NULL, NULL, filename, func, ref); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - one_entry = true; - - } - - } - - gtk_widget_set_sensitive(menuitem, one_entry); + return result; } /****************************************************************************** * * -* Paramètres : project = projet dont le contenu est à afficher. * -* func = fonction à appeler lors d'un clic sur les menus. * +* Paramètres : project = projet à traiter. * * * -* Description : Met en place un projet à l'écran. * +* Description : Place un projet au sommet de la pile des projets récents. * * * * Retour : - * * * @@ -800,65 +605,37 @@ void load_recent_openida_projects_list(GObject *ref, GCallback func) * * ******************************************************************************/ -void display_openida_project(const openida_project *project, GObject *ref) +void push_project_into_recent_list(const GStudyProject *project) { - GtkDockPanel *dpanel; /* Support de panneaux */ - size_t i; /* Boucle de parcours */ - GOpenidaBinary *binary; /* Binaire chargé */ - GtkWidget *view; /* Affichage du code binaire */ - GDockItem *ditem; /* Panneau avec ses infos. */ + GtkRecentManager *manager; /* Gestionnaire global */ + GtkRecentData *recent; /* Données complètes */ - dpanel = GTK_DOCK_PANEL(g_object_get_data(ref, "binpanel")); - for (i = 0; i < project->binaries_count; i++) - { - binary = project->binaries[i]->binary; - view = get_loaded_binary_view(project->binaries[i], BVW_BLOCK); - ditem = g_dock_item_new(g_openida_binary_to_string(binary), view); - gtk_dock_panel_add_item(dpanel, ditem); + if (project->filename == NULL) + return; - } + manager = get_projects_manager(); -} + /* Recherche un éventuel vestige à remplacer */ -/****************************************************************************** -* * -* 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 display_new_binary_of_openida_project(GOpenidaBinary *binary, openida_project *project) -{ - size_t index; /* Indice du nouveau binaire */ - GtkDockPanel *dpanel; /* Support de panneaux */ - GtkWidget *view; /* Affichage du code binaire */ - char *title; /* Titre associé au binaire */ - GEditorItem *item; /* Panneau avec ses infos. */ - index = attach_binary_to_openida_project(project, binary); - dpanel = GTK_DOCK_PANEL(g_object_get_data(project->ref, "binpanel")); - view = get_loaded_binary_view(project->binaries[index], BVW_BLOCK); - title = g_openida_binary_to_string(binary); + /* Inscrit le projet dans l'actualité */ - gdk_threads_enter(); + recent = g_slice_new0(GtkRecentData); - item = g_panel_item_new(strrchr(title, G_DIR_SEPARATOR) + 1, title, view, "M"); - g_panel_item_dock(G_PANEL_ITEM(item)); + recent->display_name = project->filename; + recent->mime_type = "application/chrysalide.project"; + recent->mime_type = "plain/text"; + recent->app_name = "chrysalide"; + recent->app_exec = "chrysalide %s"; - gdk_flush (); - gdk_threads_leave(); + gtk_recent_manager_add_full(manager, project->filename, recent); } diff --git a/src/project.h b/src/project.h index fa0d01a..6fb0101 100644 --- a/src/project.h +++ b/src/project.h @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * project.h - prototypes pour la gestion d'un groupe de fichiers binaires * - * Copyright (C) 2008-2011 Cyrille Bagard + * Copyright (C) 2008-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -29,12 +29,13 @@ #include "analysis/binary.h" -#include "debug/debugger.h" #include "gtkext/gtkviewpanel.h" -#include "gtkext/gtkdockitem.h" +/* ------------------------- DEFINITION D'UN PROJET INTERNE ------------------------- */ + + /* Type de représentations */ typedef enum _BinaryView { @@ -47,76 +48,64 @@ typedef enum _BinaryView } BinaryView; +#define G_TYPE_STUDY_PROJECT g_study_project_get_type() +#define G_STUDY_PROJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_study_project_get_type(), GStudyProject)) +#define G_IS_STUDY_PROJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_study_project_get_type())) +#define G_STUDY_PROJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STUDY_PROJECT, GStudyProjectClass)) +#define G_IS_STUDY_PROJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STUDY_PROJECT)) +#define G_STUDY_PROJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STUDY_PROJECT, GStudyProjectClass)) -/* Propriétés d'un ensemble de fichiers ouverts */ -typedef struct openida_project openida_project; +/* Projet d'étude regroupant les binaires analysés (instance) */ +typedef struct _GStudyProject GStudyProject; +/* Projet d'étude regroupant les binaires analysés (classe) */ +typedef struct _GStudyProjectClass GStudyProjectClass; -#define set_current_openida_project(prj) _get_current_openida_project(prj) -#define get_current_openida_project() _get_current_openida_project(NULL) +/* Indique le type défini pour un projet d'étude. */ +GType g_study_project_get_type(void); -/* Fournit l'adresse du projet courant. */ -openida_project *_get_current_openida_project(openida_project *); - -/* Crée un projet vide. */ -openida_project *create_empty_openida_project(GObject *); +/* Crée un nouveau projet vierge. */ +GStudyProject *g_study_project_new(void); /* Crée un projet à partir du contenu XML d'un fichier. */ -openida_project *g_openida_project_new_from_xml(GObject *, const char *); +GStudyProject *g_study_project_open(const char *); /* Procède à l'enregistrement d'un projet donné. */ -bool g_openida_project_save(openida_project *, const char *); - -/* Ferme un projet et libère la mémoire associée. */ -void close_openida_project(openida_project *); +bool g_study_project_save(GStudyProject *, const char *); /* Indique le chemin du fichier destiné à la sauvegarde. */ -const char *g_openida_project_get_filename(const openida_project *); - - - +const char *g_study_project_get_filename(const GStudyProject *); /* Attache un fichier donné à un projet donné. */ -size_t attach_binary_to_openida_project(openida_project *, GOpenidaBinary *); +size_t g_study_project_attach_binary(GStudyProject *, GOpenidaBinary *); /* Détache un fichier donné à un projet donné. */ -void detach_binary_to_openida_project(openida_project *, GOpenidaBinary *); - -/* Fournit le support d'affichage principal d'un binaire chargé. */ -GDockItem *gtk_dock_panel_get_item_from_binary(const openida_project *, GOpenidaBinary *); +void g_study_project_detach_binary(GStudyProject *, GOpenidaBinary *); /* Fournit un support d'affichage donné pour un binaire chargé. */ -GtkWidget *get_view_for_openida_project_binary(const openida_project *, const GOpenidaBinary *, BinaryView, GtkViewPanel **); - -/* Fournit l'ensemble des binaires associés à un projet. */ -const GOpenidaBinary **get_openida_project_binaries(const openida_project *, size_t *); - - +GtkWidget *g_study_project_get_view_for_binary(const GStudyProject *, const GOpenidaBinary *, BinaryView, GtkViewPanel **); +/* Met en place un projet à l'écran. */ +void g_study_project_display(const GStudyProject *); -/* Fournit un module de débogage prêt à emploi. */ -GBinaryDebugger *get_main_debugger_for_binary(const openida_project *, const GOpenidaBinary *); +/* ------------------------- GESTION GLOBALISEE DES PROJETS ------------------------- */ +/* Fournit l'adresse du projet courant. */ +GStudyProject *_get_current_study_project(GStudyProject *); -/* ---------------------- PARTIE GRAPHIQUE DES [DE]CHARGEMENTS ---------------------- */ +#define set_current_project(prj) _get_current_study_project(prj) +#define get_current_project() _get_current_study_project(NULL) +/* Fournit le gestionnaire des projets connus. */ +GtkRecentManager *get_projects_manager(void); /* Place un projet au sommet de la pile des projets récents. */ -void push_openida_project_into_recent_list(const openida_project *); - -/* Retire un projet de la pile des projets récents. */ -void pop_openida_project_from_recent_list(const openida_project *); - -/* Met en place les menus rechargeant les projets récents. */ -void load_recent_openida_projects_list(GObject *, GCallback); - -/* Met en place un projet à l'écran. */ -void display_openida_project(const openida_project *, GObject *); +void push_project_into_recent_list(const GStudyProject *); -- cgit v0.11.2-87-g4458