/* Chrysalide - Outil d'analyse de fichiers binaires
* storage.c - définition des modes d'enregistrement pour binaires
*
* Copyright (C) 2015-2019 Cyrille Bagard
*
* This file is part of Chrysalide.
*
* Chrysalide is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Chrysalide is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chrysalide. If not, see .
*/
#include "storage.h"
#include
#include
#include
#include "../../gtkext/easygtk.h"
/* 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 *);
/* 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 *);
/******************************************************************************
* *
* Paramètres : binary = binaire chargé en mémoire à traiter. *
* parent = fenêtre principale de l'éditeur. *
* outb = constructeur à détruire après usage. [OUT] *
* *
* Description : Propose une définition des propriétés d'enregistrement. *
* *
* Retour : Adresse de la fenêtre mise en place. *
* *
* Remarques : - *
* *
******************************************************************************/
GtkWidget *create_storage_dialog(GLoadedBinary *binary, GtkWindow *parent, GtkBuilder **outb)
{
GtkWidget *result; /* Fenêtre à renvoyer */
GtkBuilder *builder; /* Constructeur utilisé */
GtkToggleButton *use_remote; /* Choix du serveur distant */
const char *host; /* Serveur distant à contacter */
const char *port; /* Port d'écoute du serveur */
GObject *widget; /* Composant à mettre à jour */
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;
result = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
gtk_window_set_transient_for(GTK_WINDOW(result), parent);
/* Mise à jour de l'interface */
use_remote = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "use_remote"));
if (g_loaded_binary_use_remote_storage(binary))
gtk_toggle_button_set_active(use_remote, TRUE);
else
gtk_toggle_button_set_active(use_remote, FALSE);
g_loaded_binary_get_remote_server(binary, &host, &port);
widget = gtk_builder_get_object(builder, "server");
gtk_entry_set_text(GTK_ENTRY(widget), host);
widget = gtk_builder_get_object(builder, "port");
gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), atoi(port));
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_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,
BUILDER_CALLBACK(on_server_use_toggled),
BUILDER_CALLBACK(on_local_feature_toggled),
BUILDER_CALLBACK(on_remote_feature_toggled),
NULL);
gtk_builder_connect_signals(builder, builder);
return result;
}
/******************************************************************************
* *
* Paramètres : button = bouton à l'origine de la procédure. *
* builder = espace de référencement global. *
* *
* Description : Réagit à un changement dans le choix du type de serveur. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void on_server_use_toggled(GtkToggleButton *button, GtkBuilder *builder)
{
gboolean active; /* Etat du choix du distant */
GtkWidget *widget; /* Composant à modifier */
active = gtk_toggle_button_get_active(button);
widget = GTK_WIDGET(gtk_builder_get_object(builder, "server_label"));
gtk_widget_set_sensitive(widget, active);
widget = GTK_WIDGET(gtk_builder_get_object(builder, "server"));
gtk_widget_set_sensitive(widget, active);
widget = GTK_WIDGET(gtk_builder_get_object(builder, "port_label"));
gtk_widget_set_sensitive(widget, active);
widget = GTK_WIDGET(gtk_builder_get_object(builder, "port"));
gtk_widget_set_sensitive(widget, active);
}
/******************************************************************************
* *
* 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. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void update_binary_storage(GtkBuilder *builder, GLoadedBinary *binary)
{
GObject *widget; /* Composant à mettre à jour */
const gchar *host; /* Serveur distant à contacter */
gint raw_port; /* Port d'écoute du serveur */
char *port; /* Port d'écoute du serveur */
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 */
widget = gtk_builder_get_object(builder, "server");
host = gtk_entry_get_text(GTK_ENTRY(widget));
widget = gtk_builder_get_object(builder, "port");
raw_port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
asprintf(&port, "%d", raw_port);
g_loaded_binary_set_remote_server(binary, host, port);
free(port);
/* Choix final du serveur */
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);
g_object_unref(G_OBJECT(collec));
}
}