From 0daafbb6b4c0e845f9e61a28adb0a68bb2d0b582 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 26 Nov 2018 00:18:38 +0100 Subject: Displayed and hidden loaded contents on project change. --- src/analysis/project.c | 109 ++++++++++++++++++++++--------------------------- src/analysis/project.h | 16 +++++--- src/gui/editor.c | 96 ++++++++++++++++++++++++++++++++++++++----- src/gui/menus/file.c | 3 -- 4 files changed, 144 insertions(+), 80 deletions(-) diff --git a/src/analysis/project.c b/src/analysis/project.c index 4a15ea0..4399fc4 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -257,7 +257,7 @@ static void g_study_project_dispose(GStudyProject *project) { size_t i; /* Boucle de parcours */ - g_mutex_lock(&project->mutex); + g_study_project_lock_contents(project); for (i = 0; i < project->count; i++) g_object_unref(G_OBJECT(project->contents[i])); @@ -265,7 +265,7 @@ static void g_study_project_dispose(GStudyProject *project) if (project->contents != NULL) free(project->contents); - g_mutex_unlock(&project->mutex); + g_study_project_unlock_contents(project); g_mutex_clear(&project->mutex); @@ -400,7 +400,7 @@ bool g_study_project_save(GStudyProject *project, const char *filename) root_count = 0; - g_mutex_lock(&project->mutex); + g_study_project_lock_contents(project); for (i = 0; i < project->count && result; i++) { @@ -469,7 +469,7 @@ bool g_study_project_save(GStudyProject *project, const char *filename) } - g_mutex_unlock(&project->mutex); + g_study_project_unlock_contents(project); /* Sauvegarde finale */ @@ -602,6 +602,29 @@ static void on_loaded_content_analyzed(GLoadedContent *content, gboolean success /****************************************************************************** * * * Paramètres : project = project à manipuler. * +* lock = sélection du type de traitement à opérer. * +* * +* Description : Verrouille ou déverrouille l'accès aux contenus chargés. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void _g_study_project_lock_unlock_contents(GStudyProject *project, bool lock) +{ + if (lock) + g_mutex_lock(&project->mutex); + else + g_mutex_unlock(&project->mutex); + +} + + +/****************************************************************************** +* * +* Paramètres : project = project à manipuler. * * content = contenu chargé à associer au projet actuel. * * * * Description : Attache un contenu donné à un projet donné. * @@ -614,7 +637,7 @@ static void on_loaded_content_analyzed(GLoadedContent *content, gboolean success void g_study_project_attach_content(GStudyProject *project, GLoadedContent *content) { - g_mutex_lock(&project->mutex); + g_study_project_lock_contents(project); project->contents = (GLoadedContent **)realloc(project->contents, ++project->count * sizeof(GLoadedContent *)); @@ -622,7 +645,7 @@ void g_study_project_attach_content(GStudyProject *project, GLoadedContent *cont project->contents[project->count - 1] = content; g_object_ref(G_OBJECT(content)); - g_mutex_unlock(&project->mutex); + g_study_project_unlock_contents(project); g_signal_emit_by_name(project, "content-added", content); @@ -646,7 +669,7 @@ void g_study_project_detach_content(GStudyProject *project, GLoadedContent *cont { size_t i; /* Boucle de parcours */ - g_mutex_lock(&project->mutex); + g_study_project_lock_contents(project); for (i = 0; i < project->count; i++) if (project->contents[i] == content) break; @@ -658,7 +681,7 @@ void g_study_project_detach_content(GStudyProject *project, GLoadedContent *cont project->contents = (GLoadedContent **)realloc(project->contents, --project->count * sizeof(GLoadedContent *)); - g_mutex_unlock(&project->mutex); + g_study_project_unlock_contents(project); g_signal_emit_by_name(project, "content-removed", content); @@ -670,62 +693,34 @@ void g_study_project_detach_content(GStudyProject *project, GLoadedContent *cont /****************************************************************************** * * * Paramètres : project = projet dont le contenu est à afficher. * +* count = nombre de contenus pris en compte. [OUT] * * * -* Description : Met en place un projet à l'écran. * +* Description : Fournit l'ensemble des contenus associés à un projet. * * * -* Retour : - * +* Retour : Liste à libérer de la mémoire. * * * * Remarques : - * * * ******************************************************************************/ -void g_study_project_display(const GStudyProject *project) +GLoadedContent **_g_study_project_get_contents(GStudyProject *project, size_t *count) { -#if 0 - size_t i; /* Boucle de parcours #1 */ - loaded_binary *handled; /* Binaire prise en compte */ - size_t j; /* Boucle de parcours #2 */ - - for (i = 0; i < project->binaries_count; i++) - { - handled = project->binaries[i]; - - for (j = 0; j < handled->count; j++) - g_panel_item_dock(handled->items[j]); - - } -#endif -} - + GLoadedContent **result; /* Tableau à retourner */ + size_t i; /* Boucle de parcours */ -/****************************************************************************** -* * -* Paramètres : project = projet dont le contenu est à cacher. * -* * -* Description : Supprime de l'écran un projet en place. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + assert(!g_mutex_trylock(&project->mutex)); -void g_study_project_hide(const GStudyProject *project) -{ -#if 0 - size_t i; /* Boucle de parcours #1 */ - loaded_binary *handled; /* Binaire prise en compte */ - size_t j; /* Boucle de parcours #2 */ + *count = project->count; + result = malloc(*count * sizeof(GLoadedContent *)); - for (i = 0; i < project->binaries_count; i++) + for (i = 0; i < *count; i++) { - handled = project->binaries[i]; + result[i] = project->contents[i]; + g_object_ref(G_OBJECT(result[i])); + } - for (j = 0; j < handled->count; j++) - g_panel_item_undock(handled->items[j]); + return result; - } -#endif } @@ -745,20 +740,12 @@ void g_study_project_hide(const GStudyProject *project) GLoadedContent **g_study_project_get_contents(GStudyProject *project, size_t *count) { GLoadedContent **result; /* Tableau à retourner */ - size_t i; /* Boucle de parcours */ - g_mutex_lock(&project->mutex); + g_study_project_lock_contents(project); - *count = project->count; - result = (GLoadedContent **)calloc(*count, sizeof(GLoadedContent *)); - - for (i = 0; i < *count; i++) - { - result[i] = project->contents[i]; - g_object_ref(G_OBJECT(result[i])); - } + result = _g_study_project_get_contents(project, count); - g_mutex_unlock(&project->mutex); + g_study_project_unlock_contents(project); return result; diff --git a/src/analysis/project.h b/src/analysis/project.h index 2ee178b..c634fb2 100644 --- a/src/analysis/project.h +++ b/src/analysis/project.h @@ -77,17 +77,23 @@ const char *g_study_project_get_filename(const GStudyProject *); /* Assure l'intégration de contenus binaires dans un projet. */ void g_study_project_discover_binary_content(GStudyProject *, GBinContent *); +#define g_study_project_lock_contents(p) \ + _g_study_project_lock_unlock_contents(p, true) + +#define g_study_project_unlock_contents(p) \ + _g_study_project_lock_unlock_contents(p, false) + +/* Verrouille ou déverrouille l'accès aux contenus chargés. */ +void _g_study_project_lock_unlock_contents(GStudyProject *, bool); + /* Attache un contenu donné à un projet donné. */ void g_study_project_attach_content(GStudyProject *, GLoadedContent *); /* Détache un contenu donné d'un projet donné. */ void g_study_project_detach_content(GStudyProject *, GLoadedContent *); -/* Met en place un projet à l'écran. */ -void g_study_project_display(const GStudyProject *); - -/* Supprime de l'écran un projet en place. */ -void g_study_project_hide(const GStudyProject *); +/* Fournit l'ensemble des contenus associés à un projet. */ +GLoadedContent **_g_study_project_get_contents(GStudyProject *, size_t *); /* Fournit l'ensemble des contenus associés à un projet. */ GLoadedContent **g_study_project_get_contents(GStudyProject *, size_t *); diff --git a/src/gui/editor.c b/src/gui/editor.c index 39fd13b..16b7a59 100644 --- a/src/gui/editor.c +++ b/src/gui/editor.c @@ -132,6 +132,8 @@ static gboolean scroll_for_the_first_time(GtkWidget *, GdkEvent *, GLoadedConten /* Affiche le contenu qui vient de rejoindre un projet donné. */ void on_editor_loaded_content_added(GStudyProject *, GLoadedContent *, void *); +/* Recherche et retirer de l'affichage un contenu chargé. */ +static void remove_loaded_content_from_editor(GtkWidget *, GLoadedContent *); @@ -893,32 +895,39 @@ static void on_dock_close_request(GtkDockStation *station, GtkWidget *button, gp static void notify_editor_project_change(GStudyProject *project, bool new) { + GLoadedContent **contents; /* Contenus chargés à traiter */ + size_t count; /* Quantité de ces contenus */ + size_t i; /* Boucle de parcours */ + GtkContainer *root; /* Racine des panneaux */ - if (new) - { + g_study_project_lock_contents(project); + contents = _g_study_project_get_contents(project, &count); + if (new) g_signal_connect_to_main(project, "content-added", G_CALLBACK(on_editor_loaded_content_added), NULL, - g_cclosure_marshal_VOID__OBJECT); - - - + g_cclosure_marshal_VOID__OBJECT); - /* TODO : show_all()... */ + g_study_project_unlock_contents(project); + if (new) + { + for (i = 0; i < count; i++) + on_editor_loaded_content_added(project, contents[i], NULL); } else { + root = GTK_CONTAINER(get_tiled_grid()); - g_study_project_hide(project); - - + for (i = 0; i < count; i++) + gtk_container_foreach(root, (GtkCallback)remove_loaded_content_from_editor, contents[i]); } - + if (contents != NULL) + free(contents); } @@ -1000,3 +1009,68 @@ static gboolean scroll_for_the_first_time(GtkWidget *widget, GdkEvent *event, GL return FALSE; } + + +/****************************************************************************** +* * +* Paramètres : widget = composant d'affichage nouvellement porté à l'écran.* +* content = contenu chargé associé à un composant d'affichage. * +* * +* Description : Recherche et retirer de l'affichage un contenu chargé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void remove_loaded_content_from_editor(GtkWidget *widget, GLoadedContent *content) +{ + GtkNotebook *notebook; /* Série d'onglets à considérer*/ + gint count; /* Quantité de ces onglets */ + gint i; /* Boucle de parcours */ + GtkWidget *tab; /* Composant d'un onglet */ + GPanelItem *panel; /* Panneau encapsulé */ + GLoadedContent *loaded; /* Contenu chargé à comparer */ + GtkWidget *built; /* Composant construit */ + + if (GTK_IS_DOCK_STATION(widget)) + { + /** + * On considère qu'on est le seul à s'exécuter dans le thread d'affichage, + * et que donc aucun ajout ne peut venir modifier la constitution des + * onglets en cours de parcours ! + */ + + notebook = GTK_NOTEBOOK(widget); + + count = gtk_notebook_get_n_pages(notebook); + + for (i = 0; i < count; i++) + { + tab = gtk_notebook_get_nth_page(notebook, i); + + panel = G_PANEL_ITEM(g_object_get_data(G_OBJECT(tab), "dockable")); + + if (gtk_panel_item_get_personality(panel) != PIP_BINARY_VIEW) + continue; + + built = get_loaded_panel_from_built_view(tab); + + assert(G_IS_LOADED_PANEL(built)); + + loaded = g_loaded_panel_get_content(G_LOADED_PANEL(built)); + + if (loaded == content) + g_panel_item_undock(panel); + + g_object_unref(G_OBJECT(loaded)); + + } + + } + + else if (GTK_IS_CONTAINER(widget)) + gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)remove_loaded_content_from_editor, content); + +} diff --git a/src/gui/menus/file.c b/src/gui/menus/file.c index 41b17e1..d9232db 100644 --- a/src/gui/menus/file.c +++ b/src/gui/menus/file.c @@ -146,8 +146,6 @@ static void mcb_file_new_project(GtkMenuItem *menuitem, gpointer unused) set_current_project(project); - g_study_project_display(project); - } @@ -193,7 +191,6 @@ static void mcb_file_open_project(GtkMenuItem *menuitem, gpointer unused) if (project != NULL) { set_current_project(project); - g_study_project_display(project); push_project_into_recent_list(project); } -- cgit v0.11.2-87-g4458