summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analysis/project.c109
-rw-r--r--src/analysis/project.h16
-rw-r--r--src/gui/editor.c96
-rw-r--r--src/gui/menus/file.c3
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);
}