From 7b9727379e1c3f2aefc4ac0db0e91d0cfb0a481f Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 3 Dec 2018 14:16:32 +0100 Subject: Built a dialog box to change storage options. --- src/analysis/binary.c | 48 ++++--- src/analysis/binary.h | 15 +-- src/analysis/db/collection.c | 22 +++ src/analysis/db/collection.h | 3 + src/analysis/db/protocol.h | 7 +- src/gui/dialogs/Makefile.am | 4 +- src/gui/dialogs/binadmin.ui | 183 ------------------------- src/gui/dialogs/gresource.xml | 2 +- src/gui/dialogs/storage.c | 195 +++++++++++++++++++++++---- src/gui/dialogs/storage.h | 3 + src/gui/dialogs/storage.ui | 302 ++++++++++++++++++++++++++++++++++++++++++ src/gui/menus/binary.c | 6 +- src/gui/panels/history.c | 37 +++--- 13 files changed, 565 insertions(+), 262 deletions(-) delete mode 100644 src/gui/dialogs/binadmin.ui create mode 100644 src/gui/dialogs/storage.ui diff --git a/src/analysis/binary.c b/src/analysis/binary.c index c327696..6cc3c74 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -69,7 +69,7 @@ struct _GLoadedBinary char *username; /* Identifiant de l'utilisateur*/ bool username_changed; /* Mémorise les changements */ - bool local_storage; /* Enregistrements locaux ? */ + bool use_remote; /* Enregistrements distants ? */ char *remote_host; /* Nom du serveur distant */ unsigned short remote_port; /* Port du serveur distant */ @@ -230,7 +230,7 @@ static void g_loaded_binary_init(GLoadedBinary *binary) { binary->username = strdup("default"); - binary->local_storage = true; + binary->use_remote = false; binary->remote_host = strdup("localhost"); binary->remote_port = 1337; @@ -437,10 +437,10 @@ static bool g_loaded_binary_load_storage(GLoadedBinary *binary, xmlXPathContext storage_path = strdup(path); storage_path = stradd(storage_path, "/Storage"); - value = get_node_prop_value(context, storage_path, "local"); + value = get_node_prop_value(context, storage_path, "remote"); if (value == NULL) goto glbls_no_storage_config; - binary->local_storage = (strcmp(value, "true") == 0); + binary->use_remote = (strcmp(value, "true") == 0); free(value); @@ -559,8 +559,8 @@ static bool g_loaded_binary_save_storage(const GLoadedBinary *binary, xmlDoc *xd storage_path = strdup(path); storage_path = stradd(storage_path, "/Storage"); - result &= add_string_attribute_to_node(xdoc, context, storage_path, "local", - binary->local_storage ? "true" : "false"); + result &= add_string_attribute_to_node(xdoc, context, storage_path, "remote", + binary->use_remote ? "true" : "false"); /* Nom d'utilisateur */ @@ -681,9 +681,9 @@ void g_loaded_binary_set_username(GLoadedBinary *binary, const char *username) * * ******************************************************************************/ -bool g_loaded_binary_get_local_storage(const GLoadedBinary *binary) +bool g_loaded_binary_use_remote_storage(const GLoadedBinary *binary) { - return binary->local_storage; + return binary->use_remote; } @@ -691,7 +691,7 @@ bool g_loaded_binary_get_local_storage(const GLoadedBinary *binary) /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * -* local = statut de l'utilisation du serveur local. * +* use = statut de l'utilisation du serveur distant. * * * * Description : Définit si tous les enregistrements sont locaux ou non. * * * @@ -701,11 +701,11 @@ bool g_loaded_binary_get_local_storage(const GLoadedBinary *binary) * * ******************************************************************************/ -void g_loaded_binary_set_local_storage(GLoadedBinary *binary, bool local) +void g_loaded_binary_set_remote_storage_usage(GLoadedBinary *binary, bool use) { - binary->local_storage = local; + binary->use_remote = use; - if (local) + if (use) /* TODO : reload conn ! */; else /* TODO : stop conn ! */; @@ -1029,18 +1029,36 @@ GDbClient *g_loaded_binary_get_db_client(const GLoadedBinary *binary) /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * +* count = taille de la liste constituée. [OUT] * * * * Description : Fournit l'ensemble des collections utilisées par un binaire. * * * -* Retour : Collections en place. * +* Retour : Liste de collections en place à libérer après usage. * * * * Remarques : - * * * ******************************************************************************/ -GList *g_loaded_binary_get_all_collections(const GLoadedBinary *binary) +GDbCollection **g_loaded_binary_get_all_collections(const GLoadedBinary *binary, size_t *count) { - return binary->collections; + GDbCollection **result; /* Liste à retourner */ + GList *c; /* Boucle de parcours #1 */ + size_t i; /* Boucle de parcours #2 */ + + *count = g_list_length(binary->collections); + + result = malloc(*count * sizeof(GDbCollection *)); + + for (c = g_list_first(binary->collections), i = 0; c != NULL; c = g_list_next(c), i++) + { + assert(i < *count); + + result[i] = G_DB_COLLECTION(c->data); + g_object_ref(G_OBJECT(result[i])); + + } + + return result; } diff --git a/src/analysis/binary.h b/src/analysis/binary.h index 7c2c760..831cade 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -91,10 +91,10 @@ const char *g_loaded_binary_get_username(const GLoadedBinary *); void g_loaded_binary_set_username(GLoadedBinary *, const char *); /* Détermine si tous les enregistrements sont locaux ou non. */ -bool g_loaded_binary_get_local_storage(const GLoadedBinary *); +bool g_loaded_binary_use_remote_storage(const GLoadedBinary *); /* Définit si tous les enregistrements sont locaux ou non. */ -void g_loaded_binary_set_local_storage(GLoadedBinary *, bool); +void g_loaded_binary_set_remote_storage_usage(GLoadedBinary *, bool); /* Identifie le serveur distant associé au binaire courant. */ void g_loaded_binary_get_remote_server(const GLoadedBinary *, const char **, unsigned short *); @@ -120,7 +120,7 @@ bool g_loaded_binary_save_cache(const GLoadedBinary *); GDbClient *g_loaded_binary_get_db_client(const GLoadedBinary *); /* Fournit l'ensemble des collections utilisées par un binaire. */ -GList *g_loaded_binary_get_all_collections(const GLoadedBinary *); +GDbCollection **g_loaded_binary_get_all_collections(const GLoadedBinary *, size_t *); /* Trouve une collection assurant une fonctionnalité donnée. */ GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *, DBFeatures); @@ -139,15 +139,6 @@ bool _g_loaded_binary_remove_from_collection(GLoadedBinary *, DBFeatures, GDbIte -/** - * TODO : - * - * - connect_signal - * - add_obj - * - */ - - diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index a99c2de..adb3ad1 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -30,6 +30,9 @@ #include +#include + + #include "collection-int.h" #include "misc/rlestr.h" #include "../../common/extstr.h" @@ -242,6 +245,25 @@ uint32_t g_db_collection_get_feature(const GDbCollection *collec) } +/****************************************************************************** +* * +* Paramètres : collec = collection générique d'éléments à consulter. * +* * +* Description : Décrit le type de collection manipulée. * +* * +* Retour : Description humaine de la collection. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_db_collection_get_name(const GDbCollection *collec) +{ + return _(collec->name); + +} + + diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h index 5292e89..0f0ad34 100644 --- a/src/analysis/db/collection.h +++ b/src/analysis/db/collection.h @@ -67,6 +67,9 @@ void g_db_collection_link_to_binary(GDbCollection *, GLoadedBinary *); /* Décrit le type des éléments rassemblées dans une collection. */ uint32_t g_db_collection_get_feature(const GDbCollection *); +/* Décrit le type de collection manipulée. */ +const char *g_db_collection_get_name(const GDbCollection *); + diff --git a/src/analysis/db/protocol.h b/src/analysis/db/protocol.h index 202a923..025f92f 100644 --- a/src/analysis/db/protocol.h +++ b/src/analysis/db/protocol.h @@ -46,11 +46,10 @@ /* Comportement vis à vis des éléments */ typedef enum _DBStorage { - DBS_ALL_LOCAL = 0x01, /* Enregistrements locaux */ - DBS_ALL_REMOTE = 0x02, /* Enregistrements distants */ - DBS_LOCAL_AND_REMOTE = 0x03, /* Enreg. locaux + infos dists.*/ + DBS_ALL_LOCAL = 0x00, /* Enregistrements locaux */ + DBS_ALL_REMOTE = 0x01, /* Enregistrements distants */ - DBS_MAX = 3 + DBS_MAX = 0x01 } DBStorage; diff --git a/src/gui/dialogs/Makefile.am b/src/gui/dialogs/Makefile.am index bfda8ad..35dfb0a 100644 --- a/src/gui/dialogs/Makefile.am +++ b/src/gui/dialogs/Makefile.am @@ -4,9 +4,9 @@ BUILT_SOURCES = resources.h resources.c noinst_LTLIBRARIES = libguidialogs.la UI_FILES = \ - binadmin.ui \ bookmark.ui \ - identity.ui + identity.ui \ + storage.ui libguidialogs_la_SOURCES = \ about.h about.c \ diff --git a/src/gui/dialogs/binadmin.ui b/src/gui/dialogs/binadmin.ui deleted file mode 100644 index 0f68228..0000000 --- a/src/gui/dialogs/binadmin.ui +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - 1 - 65535 - 1337 - 1 - 10 - - - False - Storage - False - True - 700 - 300 - dialog - - - False - 8 - 8 - 8 - 8 - vertical - 8 - - - False - 8 - end - - - Cancel - True - True - True - - - True - True - 0 - - - - - Apply - True - True - True - - - True - True - 1 - - - - - False - False - 0 - - - - - True - False - vertical - 8 - - - Use the internal local server. - True - True - False - 0 - True - True - - - False - True - 0 - - - - - Use a remote shared server: - True - True - False - 0 - True - True - local_storage - - - - False - True - 1 - - - - - True - False - 16 - 8 - - - True - False - Server: - - - False - True - 0 - - - - - True - True - localhost - - - True - True - 1 - - - - - True - False - Port: - - - False - True - 2 - - - - - True - True - adjustment1 - 1337 - - - False - True - 3 - - - - - True - True - 2 - - - - - False - True - 1 - - - - - - button1 - button2 - - - diff --git a/src/gui/dialogs/gresource.xml b/src/gui/dialogs/gresource.xml index 4c2f30a..e44045c 100644 --- a/src/gui/dialogs/gresource.xml +++ b/src/gui/dialogs/gresource.xml @@ -1,8 +1,8 @@ - binadmin.ui bookmark.ui identity.ui + storage.ui diff --git a/src/gui/dialogs/storage.c b/src/gui/dialogs/storage.c index 46ef675..4aed524 100644 --- a/src/gui/dialogs/storage.c +++ b/src/gui/dialogs/storage.c @@ -25,11 +25,26 @@ +/* Colonnes de la liste des collections */ +typedef enum _CollecFeatureColumn +{ + CFC_COLLECTION, /* Instance GLib */ + + CFC_NAME, /* Désignation humaine */ + CFC_LOCAL, /* Sauvegarde locale ? */ + CFC_REMOTE, /* Sauvegarde distante ? */ + +} CollecFeatureColumn; + + /* Réagit à un changement dans le choix du type de serveur. */ static void on_server_use_toggled(GtkToggleButton *, GtkBuilder *); -/* Applique les paramètres d'enregistrement pour un binaire. */ -static void update_binary_storage(GtkButton *, GtkBuilder *); +/* Bascule le lieu d'enregistrement d'un type de collection. */ +static void on_local_feature_toggled(GtkCellRendererToggle *, gchar *, GtkBuilder *); + +/* Bascule le lieu d'enregistrement d'un type de collection. */ +static void on_remote_feature_toggled(GtkCellRendererToggle *, gchar *, GtkBuilder *); @@ -51,30 +66,32 @@ GtkWidget *create_storage_dialog(GLoadedBinary *binary, GtkWindow *parent, GtkBu { GtkWidget *result; /* Fenêtre à renvoyer */ GtkBuilder *builder; /* Constructeur utilisé */ - GtkToggleButton *local_button; /* Choix du serveur local */ - GtkToggleButton *remote_button; /* Choix du serveur distant */ + GtkToggleButton *use_remote; /* Choix du serveur distant */ const char *host; /* Serveur distant à contacter */ unsigned short port; /* Port d'écoute du serveur */ GObject *widget; /* Composant à mettre à jour */ - - builder = gtk_builder_new_from_resource("/org/chrysalide/gui/dialogs/binadmin.ui"); + GtkListStore *store; /* Modèle de gestion */ + GDbCollection **collections; /* Ensemble de collections */ + size_t count; /* Taille de cet ensemble */ + size_t i; /* Boucle de parcours */ + uint32_t feature; /* Type d'éléments gérés */ + GtkTreeIter iter; /* Point d'insertion */ + + builder = gtk_builder_new_from_resource("/org/chrysalide/gui/dialogs/storage.ui"); *outb = builder; - g_object_set_data(G_OBJECT(builder), "binary", binary); - result = GTK_WIDGET(gtk_builder_get_object(builder, "window")); gtk_window_set_transient_for(GTK_WINDOW(result), parent); /* Mise à jour de l'interface */ - local_button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "local_storage")); - remote_button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "remote_storage")); + use_remote = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "use_remote")); - if (g_loaded_binary_get_local_storage(binary)) - gtk_toggle_button_set_active(local_button, TRUE); + if (g_loaded_binary_use_remote_storage(binary)) + gtk_toggle_button_set_active(use_remote, TRUE); else - gtk_toggle_button_set_active(remote_button, TRUE); + gtk_toggle_button_set_active(use_remote, FALSE); g_loaded_binary_get_remote_server(binary, &host, &port); @@ -84,13 +101,39 @@ GtkWidget *create_storage_dialog(GLoadedBinary *binary, GtkWindow *parent, GtkBu widget = gtk_builder_get_object(builder, "port"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), port); - on_server_use_toggled(remote_button, builder); + on_server_use_toggled(use_remote, builder); + + /* Intégration des différentes collections */ + + store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store")); + + collections = g_loaded_binary_get_all_collections(binary, &count); + + for (i = 0; i < count; i++) + { + feature = g_db_collection_get_feature(collections[i]); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + CFC_COLLECTION, collections[i], + CFC_NAME, g_db_collection_get_name(collections[i]), + CFC_LOCAL, g_loaded_binary_get_storage(binary, feature) == DBS_ALL_LOCAL, + CFC_REMOTE, g_loaded_binary_get_storage(binary, feature) != DBS_ALL_LOCAL, + -1); + + g_object_unref(G_OBJECT(collections[i])); + + } + + if (collections != NULL) + free(collections); /* Connexion des signaux */ gtk_builder_add_callback_symbols(builder, "on_server_use_toggled", G_CALLBACK(on_server_use_toggled), - "update_binary_storage", G_CALLBACK(update_binary_storage), + "on_local_feature_toggled", G_CALLBACK(on_local_feature_toggled), + "on_remote_feature_toggled", G_CALLBACK(on_remote_feature_toggled), NULL); gtk_builder_connect_signals(builder, builder); @@ -137,8 +180,84 @@ static void on_server_use_toggled(GtkToggleButton *button, GtkBuilder *builder) /****************************************************************************** * * -* Paramètres : button = bouton à l'origine de la procédure. * -* builder = espace de référencement global. * +* Paramètres : renderer = rendu de cellule à l'origine de la procédure. * +* path = chemin d'accès à la ligne éditée. * +* builder = espace de référencement global. * +* * +* Description : Bascule le lieu d'enregistrement d'un type de collection. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_local_feature_toggled(GtkCellRendererToggle *renderer, gchar *path, GtkBuilder *builder) +{ + GtkTreePath *access; /* Véritable chemin d'accès */ + GtkTreeModel *model; /* Modèle de gestion utilisé */ + GtkTreeIter iter; /* Point d'actualisation */ + + access = gtk_tree_path_new_from_string(path); + + model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store")); + + if (gtk_tree_model_get_iter(model, &iter, access)) + { + gtk_list_store_set(GTK_LIST_STORE(model), &iter, + CFC_LOCAL, true, + CFC_REMOTE, false, + -1); + + } + + gtk_tree_path_free(access); + +} + + +/****************************************************************************** +* * +* Paramètres : renderer = rendu de cellule à l'origine de la procédure. * +* path = chemin d'accès à la ligne éditée. * +* builder = espace de référencement global. * +* * +* Description : Bascule le lieu d'enregistrement d'un type de collection. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_remote_feature_toggled(GtkCellRendererToggle *renderer, gchar *path, GtkBuilder *builder) +{ + GtkTreePath *access; /* Véritable chemin d'accès */ + GtkTreeModel *model; /* Modèle de gestion utilisé */ + GtkTreeIter iter; /* Point d'actualisation */ + + access = gtk_tree_path_new_from_string(path); + + model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store")); + + if (gtk_tree_model_get_iter(model, &iter, access)) + { + gtk_list_store_set(GTK_LIST_STORE(model), &iter, + CFC_LOCAL, false, + CFC_REMOTE, true, + -1); + + } + + gtk_tree_path_free(access); + +} + + +/****************************************************************************** +* * +* Paramètres : builder = espace de référencement global. * +* binary = binaire chargé en mémoire à traiter. * * * * Description : Applique les paramètres d'enregistrement pour un binaire. * * * @@ -148,16 +267,19 @@ static void on_server_use_toggled(GtkToggleButton *button, GtkBuilder *builder) * * ******************************************************************************/ -static void update_binary_storage(GtkButton *button, GtkBuilder *builder) +void update_binary_storage(GtkBuilder *builder, GLoadedBinary *binary) { - GLoadedBinary *binary; /* Binaire à mettre à jour */ GObject *widget; /* Composant à mettre à jour */ const gchar *host; /* Serveur distant à contacter */ gint port; /* Port d'écoute du serveur */ - GtkToggleButton *local_button; /* Choix du serveur local */ - gboolean active; /* Etat du choix du local */ - - binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(builder), "binary")); + GtkToggleButton *use_remote; /* Choix du serveur distant */ + gboolean active; /* Etat du choix du distant */ + GtkTreeModel *model; /* Modèle de gestion utilisé */ + GtkTreeIter iter; /* Itérateur de consultation */ + gboolean valid; /* Validité de l'itérateur */ + GDbCollection *collec; /* Collection à traiter */ + gboolean local; /* Conservation locale ? */ + uint32_t feature; /* Type d'éléments gérés */ /* Infos de connexions à distance */ @@ -171,10 +293,31 @@ static void update_binary_storage(GtkButton *button, GtkBuilder *builder) /* Choix final du serveur */ - local_button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "local_storage")); + use_remote = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "use_remote")); + + active = gtk_toggle_button_get_active(use_remote); + + g_loaded_binary_set_remote_storage_usage(binary, active); + + /* Type de conservation des éléments */ + + model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store")); + + for (valid = gtk_tree_model_get_iter_first(model, &iter); + valid; + valid = gtk_tree_model_iter_next(model, &iter)) + { + gtk_tree_model_get(model, &iter, + CFC_COLLECTION, &collec, + CFC_LOCAL, &local, + -1); + + feature = g_db_collection_get_feature(collec); + + g_loaded_binary_set_storage(binary, feature, local ? DBS_ALL_LOCAL : DBS_ALL_REMOTE); - active = gtk_toggle_button_get_active(local_button); + g_object_unref(G_OBJECT(collec)); - g_loaded_binary_set_local_storage(binary, active); + } } diff --git a/src/gui/dialogs/storage.h b/src/gui/dialogs/storage.h index 6e0c9f0..f7cd65a 100644 --- a/src/gui/dialogs/storage.h +++ b/src/gui/dialogs/storage.h @@ -35,6 +35,9 @@ /* Propose une définition des propriétés d'enregistrement. */ GtkWidget *create_storage_dialog(GLoadedBinary *, GtkWindow *, GtkBuilder **); +/* Applique les paramètres d'enregistrement pour un binaire. */ +void update_binary_storage(GtkBuilder *, GLoadedBinary *); + #endif /* _GUI_DIALOGS_STORAGE_H */ diff --git a/src/gui/dialogs/storage.ui b/src/gui/dialogs/storage.ui new file mode 100644 index 0000000..0a65f47 --- /dev/null +++ b/src/gui/dialogs/storage.ui @@ -0,0 +1,302 @@ + + + + + + 1 + 65535 + 0.01 + 1 + 10 + + + + + + + + + + + + + + + False + 4 + 4 + 4 + 4 + Storage + True + center-on-parent + 500 + 350 + dialog + + + False + vertical + 2 + + + False + end + + + gtk-cancel + True + True + True + True + + + True + True + 0 + + + + + gtk-apply + True + True + True + True + + + True + True + 1 + + + + + False + False + 0 + + + + + True + False + vertical + 8 + + + True + False + 0 + none + + + True + False + 12 + + + True + False + vertical + 8 + + + True + False + Note: DB items will use local storage as fallback if this server can not be contacted. + True + 0 + + + False + True + 0 + + + + + True + False + True + 8 + + + True + False + Server: + + + False + True + 0 + + + + + True + True + + + True + True + 1 + + + + + True + False + Port: + + + False + True + 2 + + + + + True + True + 5 + 1 + port_adj + 1 + + + False + True + 3 + + + + + False + True + 1 + + + + + + + + + Use a remote shared server + True + True + False + True + + + + + + False + True + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + True + True + in + + + True + True + store + + + + + + Name + True + + + + 1 + + + + + + + Local + + + True + + + + 2 + + + + + + + Remote + + + True + + + + 3 + + + + + + + + + + + + + True + False + DB items + + + + + True + True + 1 + + + + + True + True + 1 + + + + + + button1 + button2 + + + + + + diff --git a/src/gui/menus/binary.c b/src/gui/menus/binary.c index 954f3d4..c4c4e22 100644 --- a/src/gui/menus/binary.c +++ b/src/gui/menus/binary.c @@ -226,12 +226,16 @@ static void mcb_binary_storage(GtkMenuItem *menuitem, GMenuBar *bar) GLoadedBinary *binary; /* Edition courante */ GtkBuilder *builder; /* Constructeur utilisé */ GtkWidget *dialog; /* Boîte de dialogue à montrer */ + gint ret; /* Retour de confirmation */ binary = G_LOADED_BINARY(get_current_content()); dialog = create_storage_dialog(binary, get_editor_window(), &builder); - gtk_dialog_run(GTK_DIALOG(dialog)); + ret = gtk_dialog_run(GTK_DIALOG(dialog)); + + if (ret == GTK_RESPONSE_APPLY) + update_binary_storage(builder, binary); gtk_widget_destroy(dialog); diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c index a1aa36b..9edd32e 100644 --- a/src/gui/panels/history.c +++ b/src/gui/panels/history.c @@ -272,9 +272,9 @@ GPanelItem *g_history_panel_new(void) static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedContent *old, GLoadedContent *new) { GLoadedBinary *binary; /* Autre version de l'instance */ - GList *collections; /* Ensemble de collections */ - GList *c; /* Boucle de parcours #1 */ - GDbCollection *collec; /* Collection visée manipulée */ + GDbCollection **collections; /* Ensemble de collections */ + size_t count; /* Taille de cet ensemble */ + size_t k; /* Boucle de parcours #1 */ GtkBuilder *builder; /* Constructeur utilisé */ GtkListStore *store; /* Modèle de gestion */ GList *items; /* Liste des éléments groupés */ @@ -291,17 +291,16 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo if (panel->binary != NULL) { - collections = g_loaded_binary_get_all_collections(panel->binary); + collections = g_loaded_binary_get_all_collections(panel->binary, &count); - rlock_collections(collections); - - for (c = g_list_first(collections); c != NULL; c = g_list_next(c)) + for (k = 0; k < count; k++) { - collec = G_DB_COLLECTION(c->data); - g_signal_handlers_disconnect_by_func(collec, G_CALLBACK(on_history_changed), panel); + g_signal_handlers_disconnect_by_func(collections[k], G_CALLBACK(on_history_changed), panel); + g_object_unref(G_OBJECT(collections[k])); } - runlock_collections(collections); + if (collections != NULL) + free(collections); g_object_unref(G_OBJECT(panel->binary)); @@ -324,14 +323,13 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo /* Actualisation de l'affichage */ - collections = g_loaded_binary_get_all_collections(binary); - - rlock_collections(collections); + collections = g_loaded_binary_get_all_collections(binary, &count); - for (c = g_list_first(collections); c != NULL; c = g_list_next(c)) + for (k = 0; k < count; k++) { - collec = G_DB_COLLECTION(c->data); - items = g_db_collection_list_items(collec); + g_db_collection_rlock(collections[k]); + + items = g_db_collection_list_items(collections[k]); for (i = g_list_first(items); i != NULL; i = g_list_next(i)) { @@ -347,12 +345,15 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo } - g_signal_connect_to_main(collec, "content-changed", G_CALLBACK(on_history_changed), panel, + g_signal_connect_to_main(collections[k], "content-changed", G_CALLBACK(on_history_changed), panel, g_cclosure_user_marshal_VOID__ENUM_OBJECT); + g_object_unref(G_OBJECT(collections[k])); + } - runlock_collections(collections); + if (collections != NULL) + free(collections); /* Force une sélection initiale */ on_history_changed(NULL, DBA_COUNT, NULL, panel); -- cgit v0.11.2-87-g4458