diff options
Diffstat (limited to 'src/gui/dialogs')
| -rw-r--r-- | src/gui/dialogs/Makefile.am | 22 | ||||
| -rw-r--r-- | src/gui/dialogs/gresource.xml | 8 | ||||
| -rw-r--r-- | src/gui/dialogs/preferences-int.h | 62 | ||||
| -rw-r--r-- | src/gui/dialogs/preferences.c | 399 | ||||
| -rw-r--r-- | src/gui/dialogs/preferences.h | 16 | ||||
| -rw-r--r-- | src/gui/dialogs/preferences.ui | 247 | ||||
| -rw-r--r-- | src/gui/dialogs/prefs/Makefile.am | 31 | ||||
| -rw-r--r-- | src/gui/dialogs/prefs/gresource.xml | 6 | ||||
| -rw-r--r-- | src/gui/dialogs/prefs/security-int.h | 64 | ||||
| -rw-r--r-- | src/gui/dialogs/prefs/security.c | 400 | ||||
| -rw-r--r-- | src/gui/dialogs/prefs/security.h | 41 | ||||
| -rw-r--r-- | src/gui/dialogs/prefs/security.ui | 170 | 
12 files changed, 1121 insertions, 345 deletions
diff --git a/src/gui/dialogs/Makefile.am b/src/gui/dialogs/Makefile.am index 5a77b99..e910c96 100644 --- a/src/gui/dialogs/Makefile.am +++ b/src/gui/dialogs/Makefile.am @@ -3,21 +3,23 @@ BUILT_SOURCES = resources.h resources.c  noinst_LTLIBRARIES  = libguidialogs.la -UI_FILES =								\ -	about.ui +UI_FILES =									\ +	about.ui								\ +	preferences.ui  # bookmark.ui							\  # export_graph.ui						\  # identity.ui							\  # loading.ui							\ -# preferences.ui						\  # prefs_fgraph.ui						\  # prefs_labels.ui						\  # snapshots.ui						\  # storage.ui -libguidialogs_la_SOURCES =				\ -	about-int.h							\ -	about.h about.c						\ +libguidialogs_la_SOURCES =					\ +	about-int.h								\ +	about.h about.c							\ +	preferences-int.h						\ +	preferences.h preferences.c				\  	resources.h resources.c  # bookmark.h bookmark.c				\  # export_disass.h export_disass.c		\ @@ -26,12 +28,15 @@ libguidialogs_la_SOURCES =				\  # gotox.h gotox.c						\  # identity.h identity.c				\  # loading.h loading.c					\ -# preferences.h preferences.c			\ +# 			\  # prefs_fgraph.h prefs_fgraph.c		\  # prefs_labels.h prefs_labels.c		\  # snapshots.h snapshots.c				\  # storage.h storage.c +libguidialogs_la_LIBADD =					\ +	prefs/libguidialogsprefs.la +  libguidialogs_la_CFLAGS = $(LIBGTK4_CFLAGS) @@ -40,6 +45,9 @@ devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)  dev_HEADERS = $(libguidialogs_la_SOURCES:%c=) +SUBDIRS = prefs + +  resources.c: gresource.xml $(UI_FILES)  	glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name gui_dialogs gresource.xml diff --git a/src/gui/dialogs/gresource.xml b/src/gui/dialogs/gresource.xml index b9bc7e2..169f440 100644 --- a/src/gui/dialogs/gresource.xml +++ b/src/gui/dialogs/gresource.xml @@ -2,15 +2,7 @@  <gresources>      <gresource prefix="/re/chrysalide/framework/gui/dialogs">          <file compressed="true">about.ui</file> -        <file compressed="true">bookmark.ui</file> -        <file compressed="true">export_graph.ui</file> -        <file compressed="true">identity.ui</file> -        <file compressed="true">loading.ui</file>          <file compressed="true">preferences.ui</file> -        <file compressed="true">prefs_fgraph.ui</file> -        <file compressed="true">prefs_labels.ui</file> -        <file compressed="true">snapshots.ui</file> -        <file compressed="true">storage.ui</file>      </gresource>      <gresource prefix="/org/chrysalide/gui/dialogs/about">        <file compressed="true" alias="chrysalide-full.png">../../../pixmaps/chrysalide-full.png</file> diff --git a/src/gui/dialogs/preferences-int.h b/src/gui/dialogs/preferences-int.h new file mode 100644 index 0000000..806f5f6 --- /dev/null +++ b/src/gui/dialogs/preferences-int.h @@ -0,0 +1,62 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * preferences-int.h - définitions internes pour la boîte de dialogue d'édition des préférences de l'utilisateur + * + * Copyright (C) 2025 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GUI_DIALOGS_PREFERENCES_INT_H +#define _GUI_DIALOGS_PREFERENCES_INT_H + + +#include <stdbool.h> + + +#include "preferences.h" + + + +/* Fenêtre d'édition générale de la configuration (instance) */ +struct _GtkPreferencesDialog +{ +    GtkWindow parent;                       /* A laisser en premier        */ + +    GtkLabel *side_title;                   /* Titre principal             */ +    GtkScrolledWindow *side_content;        /* Liste des sections          */ +    GtkLabel *main_title;                   /* Titre de section            */ +    GtkScrolledWindow *main_content;        /* Page de configuration       */ + +    GHashTable *navigations;                /* Liste de sections en place  */ + +}; + +/* Fenêtre d'édition générale de la configuration (classe) */ +struct _GtkPreferencesDialogClass +{ +    GtkWindowClass parent;                  /* A laisser en premier        */ + +}; + + +/* Met en place la boîte de dialogue pour les préférences. */ +bool gtk_preferences_dialog_create(GtkPreferencesDialog *, GtkWindow *); + + + +#endif  /* _GUI_DIALOGS_PREFERENCES_INT_H */ diff --git a/src/gui/dialogs/preferences.c b/src/gui/dialogs/preferences.c index 4a3fb7c..aca562a 100644 --- a/src/gui/dialogs/preferences.c +++ b/src/gui/dialogs/preferences.c @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * preferences.c - (re)définition de l'identité de l'utilisateur + * preferences.c - boîte de dialogue d'édition des préférences de l'utilisateur   * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2025 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -24,129 +24,160 @@  #include "preferences.h" -#include <i18n.h> +#include <assert.h> +#include <math.h> +#include <stdio.h> +#include <gdk/gdkkeysyms.h> -#include "prefs_fgraph.h" -#include "prefs_labels.h" -#include "../../core/params.h" -#include "../../gtkext/easygtk.h" +#include <config.h> +#include "preferences-int.h" +#include "prefs/security.h" +#include "../../common/cpp.h" +#include "../../gtkext/tweak.h" -/* Constructeur de panneau de paramétrage */ -typedef GtkWidget * (* prefs_panel_creation_cb) (GtkBuilder **); -/* Chargement de la configuration */ -typedef void (* prefs_config_update_cb) (GtkBuilder *, GGenConfig *); -/* Description d'un noeud de préférences */ -typedef struct _pref_node_desc_t -{ -    prefs_panel_creation_cb create;         /* Procédure de création       */ -    prefs_config_update_cb load;            /* Procédure de chargement     */ -    prefs_config_update_cb store;           /* Procédure d'enregistrement  */ +/* --------------------------- BASES DE BOITE DE DIALOGUE --------------------------- */ -    const char *name;                       /* Désignation interne         */ -    const char *title;                      /* Désignation humaine         */ -    GtkBuilder *builder;                    /* Constructeur GTK            */ -    GtkWidget *panel;                       /* Panneau GTK                 */ +/* Procède à l'initialisation de la fenêtre des paramètres. */ +static void gtk_preferences_dialog_class_init(GtkPreferencesDialogClass *); -    struct _pref_node_desc_t *children;     /* Sous-arborescence           */ +/* Procède à l'initialisation de la fenêtre des paramètres. */ +static void gtk_preferences_dialog_init(GtkPreferencesDialog *); -} pref_node_desc_t; +/* Supprime toutes les références externes. */ +static void gtk_preferences_dialog_dispose(GObject *); +/* Procède à la libération totale de la mémoire. */ +static void gtk_preferences_dialog_finalize(GObject *); -#define PREF_NODE_NULL_ENTRY { .title = NULL } +/* Fournit la liste de section désignée par un nom. */ +static GtkListBox *gtk_preferences_dialog_get_navigation(GtkPreferencesDialog *, const char *, bool); +/* Réagit à un changement de sélection dans les sections. */ +static void gtk_preferences_dialog_on_row_selected(GtkListBox *, GtkListBoxRow *, GtkPreferencesDialog *); -/* Liste des paramétrages à afficher */ -static pref_node_desc_t _prefs_nodes[] = { -    { -        .create = NULL, -        .title = "Analysis", +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -        .children = (pref_node_desc_t []){ -            { -                .create = create_labels_preferences, -                .load = load_labels_configuration, -                .store = store_labels_configuration, -                .name = "labels", -                .title = "Colored labels", -            }, -            PREF_NODE_NULL_ENTRY +/* ---------------------------------------------------------------------------------- */ +/*                             BASES DE BOITE DE DIALOGUE                             */ +/* ---------------------------------------------------------------------------------- */ -        } -    }, +/* Détermine le type du composant d'affichage générique. */ +G_DEFINE_TYPE(GtkPreferencesDialog, gtk_preferences_dialog, GTK_TYPE_WINDOW); -    { -        .create = NULL, -        .title = "Editor", +/****************************************************************************** +*                                                                             * +*  Paramètres  : class = classe GTK à initialiser.                            * +*                                                                             * +*  Description : Procède à l'initialisation de la fenêtre des paramètres.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -        .children = (pref_node_desc_t []){ +static void gtk_preferences_dialog_class_init(GtkPreferencesDialogClass *class) +{ +    GObjectClass *object;                   /* Plus haut niveau équivalent */ +    GtkWidgetClass *widget;                 /* Classe de haut niveau       */ -            { -                .create = create_fgraph_preferences, -                .load = load_fgraph_configuration, -                .store = store_fgraph_configuration, +    object = G_OBJECT_CLASS(class); -                .name = "fgraph", -                .title = "Function graph", +    object->dispose = gtk_preferences_dialog_dispose; +    object->finalize = gtk_preferences_dialog_finalize; -            }, +    widget = GTK_WIDGET_CLASS(class); -            PREF_NODE_NULL_ENTRY +    gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gui/dialogs/preferences.ui"); -        } +    gtk_widget_class_bind_template_child(widget, GtkPreferencesDialog, side_title); +    gtk_widget_class_bind_template_child(widget, GtkPreferencesDialog, side_content); +    gtk_widget_class_bind_template_child(widget, GtkPreferencesDialog, main_title); +    gtk_widget_class_bind_template_child(widget, GtkPreferencesDialog, main_content); -    }, +    /* Active une action native (cf. https://docs.gtk.org/gtk4/class.Window.html#actions) */ +    gtk_widget_class_add_binding_action(widget, GDK_KEY_Escape, 0 /* GDK 4.14 : GDK_NO_MODIFIER_MASK */, "window.close", NULL); -    PREF_NODE_NULL_ENTRY +} -}; +/****************************************************************************** +*                                                                             * +*  Paramètres  : dialog = composant GTK à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de la fenêtre des paramètres.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -/* Eléments de la liste de sections */ -typedef enum _PrefListItem +static void gtk_preferences_dialog_init(GtkPreferencesDialog *dialog)  { -    PLI_TITLE,                              /* Etiquette de la section     */ -    PLI_PANEL,                              /* Panneau graphique associé   */ +    size_t i;                               /* Boucle de parcours          */ +    const tweak_info_t *info;               /* Informations à considérer   */ +    GtkListBox *navigation;                 /* Liste de sections à afficher*/ +    GtkTweakSection *section;               /* Nouvelle section à présenter*/ -} PrefListItem; +    tweak_info_t infos[] = { +        TWEAK_SIMPLE_DEF("root", "Basics", +                         "security-high-symbolic", "security", "Security", GTK_TYPE_SECURITY_TWEAK_PANEL), +    }; +    gtk_widget_init_template(GTK_WIDGET(dialog)); -/* Ajoute un panneau de paramétrage à la boîte de dialogue. */ -static void add_preferences_node(GtkTreeStore *, GtkTreeIter *, GGenConfig *, GtkStack *, pref_node_desc_t *); +    dialog->navigations = g_hash_table_new_full(g_str_hash, g_str_equal, free, g_object_unref); -/* Affiche le panneau correspondant au noeud sélectionné. */ -static void on_prefs_selection_changed(GtkTreeSelection *, GtkBuilder *); +    /* Chargement des sections fixes */ -/* Lance la sauvegarde d'éléments de paramétrage. */ -static void store_preferences_node(GGenConfig *, pref_node_desc_t *); +    for (i = 0; i < ARRAY_SIZE(infos); i++) +    { +        info = &infos[i]; + +        navigation = gtk_preferences_dialog_get_navigation(dialog, info->parent, true); +        assert(navigation != NULL); + +        section = gtk_tweak_section_new(info); + +        gtk_list_box_append(navigation, GTK_WIDGET(section)); + +    } -/* Sauvegarde l'ensemble des paramètres de configuration. */ -static void on_prefs_apply_button_clicked(GtkButton *, GtkBuilder *); +    /* Affichage de la liste racine */ +    navigation = gtk_preferences_dialog_get_navigation(dialog, "root", false); +    assert(navigation != NULL); + +    g_signal_connect(navigation, "row-selected", +                     G_CALLBACK(gtk_preferences_dialog_on_row_selected), dialog); + +    gtk_scrolled_window_set_child(dialog->side_content, GTK_WIDGET(navigation)); + +    unref_object(navigation); + +}  /******************************************************************************  *                                                                             * -*  Paramètres  : store  = arborescence des sections à compléter.              * -*                parent = point d'insertion du parent.                        * -*                config = configuration globale à charger.                    * -*                stack  = pile de composants GTK à constituer.                * -*                node   = noeud de description courant à traiter.             * +*  Paramètres  : object = instance d'objet GLib à traiter.                    *  *                                                                             * -*  Description : Ajoute un panneau de paramétrage à la boîte de dialogue.     * +*  Description : Supprime toutes les références externes.                     *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -154,95 +185,96 @@ static void on_prefs_apply_button_clicked(GtkButton *, GtkBuilder *);  *                                                                             *  ******************************************************************************/ -static void add_preferences_node(GtkTreeStore *store, GtkTreeIter *parent, GGenConfig *config, GtkStack *stack, pref_node_desc_t *node) +static void gtk_preferences_dialog_dispose(GObject *object)  { -    GtkTreeIter iter;                       /* Point d'insertion           */ -    pref_node_desc_t *child;                /* Sous-élément à traiter      */ - -    if (node->create == NULL) -    { -        node->builder = NULL; -        node->panel = NULL; -    } -    else -    { -        node->panel = node->create(&node->builder); +    GtkPreferencesDialog *dialog;           /* Version spécialisée         */ -        node->load(node->builder, config); +    dialog = GTK_PREFERENCES_DIALOG(object); -        gtk_widget_show(node->panel); +    if (dialog->navigations != NULL) +    { +        /** +         * Cf. documentation de g_hash_table_new_full(). +         */ +        g_hash_table_remove_all(dialog->navigations); -        gtk_stack_add_named(stack, node->panel, node->name); +        g_hash_table_unref(dialog->navigations); +        dialog->navigations = NULL;      } -    gtk_tree_store_append(store, &iter, parent); - -    gtk_tree_store_set(store, &iter, -                       PLI_TITLE, _(node->title), -                       PLI_PANEL, node->panel, -                       -1); +    gtk_widget_dispose_template(GTK_WIDGET(dialog), GTK_TYPE_PREFERENCES_DIALOG); -    if (node->children != NULL) -        for (child = node->children; child->title != NULL; child++) -            add_preferences_node(store, &iter, config, stack, child); +    G_OBJECT_CLASS(gtk_preferences_dialog_parent_class)->dispose(object);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : parent = fenêtre principale de l'éditeur.                    * -*                outb   = constructeur à détruire après usage. [OUT]          * +*  Paramètres  : object = instance d'objet GLib à traiter.                    *  *                                                                             * -*  Description : Propose une boîte de dialogue pour la configuration générale.* +*  Description : Procède à la libération totale de la mémoire.                *  *                                                                             * -*  Retour      : Adresse de la fenêtre mise en place.                         * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GtkWidget *create_preferences_dialog(GtkWindow *parent, GtkBuilder **outb) +static void gtk_preferences_dialog_finalize(GObject *object)  { -    GtkWidget *result;                      /* Fenêtre à renvoyer          */ -    GtkBuilder *builder;                    /* Constructeur utilisé        */ -    GGenConfig *config;                     /* Configuration globale       */ -    GtkStack *stack;                        /* Pile à mettre à jour        */ -    GtkTreeStore *store;                    /* Arborescence des sections   */ -    pref_node_desc_t *iter;                 /* Boucle de parcours          */ -    GtkTreeView *treeview;                  /* Arborescence principale     */ +    G_OBJECT_CLASS(gtk_preferences_dialog_parent_class)->finalize(object); -    builder = gtk_builder_new_from_resource("/org/chrysalide/gui/dialogs/preferences.ui"); -    *outb = builder; +} -    result = GTK_WIDGET(gtk_builder_get_object(builder, "window")); -    gtk_window_set_transient_for(GTK_WINDOW(result), parent); +/****************************************************************************** +*                                                                             * +*  Paramètres  : parent = fenêtre parente à surpasser.                        * +*                                                                             * +*  Description : Construit une boîte de dialogue pour les préférences.        * +*                                                                             * +*  Retour      : Adresse de la fenêtre mise en place.                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    /* Intégration des différentes sections */ +GtkWindow *gtk_preferences_dialog_new(GtkWindow *parent) +{ +    GtkWindow *result;                      /* Boite de dialogue à renvoyer*/ -    config = get_main_configuration(); +    result = g_object_new(GTK_TYPE_PREFERENCES_DIALOG, NULL); -    stack = GTK_STACK(gtk_builder_get_object(builder, "stack")); +    if (!gtk_preferences_dialog_create(GTK_PREFERENCES_DIALOG(result), parent)) +        g_clear_object(&result); -    store = GTK_TREE_STORE(gtk_builder_get_object(builder, "pref_list")); +    return result; -    for (iter = _prefs_nodes; iter->title != NULL; iter++) -        add_preferences_node(store, NULL, config, stack, iter); +} -    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); -    gtk_tree_view_expand_all(treeview); +/****************************************************************************** +*                                                                             * +*  Paramètres  : dialog = boîte de dialogue à initialiser pleinement.         * +*                parent = fenêtre parente à surpasser.                        * +*                                                                             * +*  Description : Met en place la boîte de dialogue pour les préférences.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    /* Connexion des signaux */ +bool gtk_preferences_dialog_create(GtkPreferencesDialog *dialog, GtkWindow *parent) +{ +    bool result;                            /* Bilan à retourner           */ -    gtk_builder_add_callback_symbols(builder, -                                     BUILDER_CALLBACK(on_prefs_selection_changed), -                                     BUILDER_CALLBACK(on_prefs_apply_button_clicked), -                                     NULL); +    result = true; -    gtk_builder_connect_signals(builder, builder); +    gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);      return result; @@ -251,52 +283,59 @@ GtkWidget *create_preferences_dialog(GtkWindow *parent, GtkBuilder **outb)  /******************************************************************************  *                                                                             * -*  Paramètres  : selection = sélection courante de l'arborescence des options.* -*                builder = constructeur GTK avec toutes les références.       * +*  Paramètres  : dialog = boîte de dialogue à initialiser pleinement.         * +*                key    = désignation de la liste à fournir.                  * +*                create = autorisation d'une création si besoin est.          *  *                                                                             * -*  Description : Affiche le panneau correspondant au noeud sélectionné.       * +*  Description : Fournit la liste de section désignée par un nom.             *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Composant graphique à utiliser.                              *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void on_prefs_selection_changed(GtkTreeSelection *selection, GtkBuilder *builder) +static GtkListBox *gtk_preferences_dialog_get_navigation(GtkPreferencesDialog *dialog, const char *key, bool create)  { -    GtkTreeModel *model;                    /* Gestionnaire de données     */ -    GtkTreeIter iter;                       /* Position courante           */ -    GtkWidget *panel;                       /* Panneau à mettre en avant   */ -    GtkStack *stack;                        /* Pile à mettre à jour        */ +    GtkListBox *result;                     /* Instance à retourner        */ +#ifndef NDEBUG +    gboolean status;                        /* Bilan d'une insertion       */ +#endif -    if (gtk_tree_selection_get_selected(selection, &model, &iter)) -    { -        gtk_tree_model_get(model, &iter, PLI_PANEL, &panel, -1); +    result = g_hash_table_lookup(dialog->navigations, key); -        stack = GTK_STACK(gtk_builder_get_object(builder, "stack")); +    if (result == NULL && create) +    { +        result = GTK_LIST_BOX(gtk_list_box_new()); +        g_object_ref_sink(G_OBJECT(result)); -        if (panel == NULL) -            gtk_stack_set_visible_child_name(stack, "empty"); +        gtk_list_box_set_selection_mode(result, GTK_SELECTION_BROWSE); +        gtk_widget_add_css_class(GTK_WIDGET(result), "navigation-sidebar"); -        else -        { -            gtk_stack_set_visible_child(stack, panel); +#ifndef NDEBUG +        status = g_hash_table_insert(dialog->navigations, strdup(key), result); +        assert(status); +#else +        g_hash_table_insert(dialog->navigations, key, result); +#endif -            g_object_unref(G_OBJECT(panel)); +    } -        } +    if (result != NULL) +        ref_object(result); -    } +    return result;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : config = configuration globale à actualiser.                 * -*                node   = noeud de description courant à traiter.             * +*  Paramètres  : navigation = liste concernée par l'événement.                * +*                selected   = élément sélectionné (voire NULL).               * +*                dialog     = boîte de dialogue à initialiser pleinement.     *  *                                                                             * -*  Description : Lance la sauvegarde d'éléments de paramétrage.               * +*  Description : Réagit à un changement de sélection dans les sections.       *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -304,41 +343,41 @@ static void on_prefs_selection_changed(GtkTreeSelection *selection, GtkBuilder *  *                                                                             *  ******************************************************************************/ -static void store_preferences_node(GGenConfig *config, pref_node_desc_t *node) +static void gtk_preferences_dialog_on_row_selected(GtkListBox *navigation, GtkListBoxRow *selected, GtkPreferencesDialog *dialog)  { -    pref_node_desc_t *child;                /* Sous-élément à traiter      */ +    GtkTweakSection *section;               /* Nature réelle sélectionnée  */ +    GType type;                             /* Type de panneau de config.  */ +    GtkWidget *panel;                       /* Nouveau panneau à présenter */ -    if (node->create != NULL) -        node->store(node->builder, config); +    if (selected != NULL) +    { +        if (!gtk_tweak_section_has_sub_section(GTK_TWEAK_SECTION(selected))) +        { +            section = GTK_TWEAK_SECTION(selected); -    if (node->children != NULL) -        for (child = node->children; child->title != NULL; child++) -            store_preferences_node(config, child); +            gtk_label_set_text(dialog->main_title, gtk_tweak_section_get_label(section)); -} +            type = gtk_tweak_section_get_panel(section); +            panel = g_object_new(type, NULL); +            gtk_scrolled_window_set_child(dialog->main_content, panel); -/****************************************************************************** -*                                                                             * -*  Paramètres  : button  = bouton GTK à l'origine de l'opération.             * -*                builder = constructeur GTK avec toutes les références.       * -*                                                                             * -*  Description : Sauvegarde l'ensemble des paramètres de configuration.       * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +        } -static void on_prefs_apply_button_clicked(GtkButton *button, GtkBuilder *builder) -{ -    GGenConfig *config;                     /* Configuration globale       */ -    pref_node_desc_t *iter;                 /* Boucle de parcours          */ +        else +        { + +            // TODO -    config = get_main_configuration(); +        } -    for (iter = _prefs_nodes; iter->title != NULL; iter++) -        store_preferences_node(config, iter); +    }  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + diff --git a/src/gui/dialogs/preferences.h b/src/gui/dialogs/preferences.h index d04af72..e291ea8 100644 --- a/src/gui/dialogs/preferences.h +++ b/src/gui/dialogs/preferences.h @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * preferences.h - prototypes pour la (re)définition de l'identité de l'utilisateur + * preferences.h - prototypes pour la boîte de dialogue d'édition des préférences de l'utilisateur   * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2025 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -28,9 +28,17 @@  #include <gtk/gtk.h> +#include "../../glibext/helpers.h" -/* Propose une boîte de dialogue pour la configuration générale. */ -GtkWidget *create_preferences_dialog(GtkWindow *, GtkBuilder **); + + +#define GTK_TYPE_PREFERENCES_DIALOG (gtk_preferences_dialog_get_type()) + +DECLARE_GTYPE(GtkPreferencesDialog, gtk_preferences_dialog, GTK, PREFERENCES_DIALOG); + + +/* Construit une boîte de dialogue pour les préférences. */ +GtkWindow *gtk_preferences_dialog_new(GtkWindow *); diff --git a/src/gui/dialogs/preferences.ui b/src/gui/dialogs/preferences.ui index 251ef46..950242a 100644 --- a/src/gui/dialogs/preferences.ui +++ b/src/gui/dialogs/preferences.ui @@ -1,156 +1,111 @@  <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.21.0 -->  <interface> -  <requires lib="gtk+" version="3.20"/> -  <object class="GtkTreeStore" id="pref_list"> -    <columns> -      <!-- column-name title --> -      <column type="gchararray"/> -      <!-- column-name panel --> -      <column type="GObject"/> -    </columns> -  </object> -  <object class="GtkDialog" id="window"> -    <property name="can_focus">False</property> -    <property name="title" translatable="yes">General preferences</property> -    <property name="modal">True</property> -    <property name="default_width">800</property> -    <property name="default_height">500</property> -    <property name="type_hint">dialog</property> -    <child internal-child="vbox"> -      <object class="GtkBox"> -        <property name="can_focus">False</property> -        <property name="orientation">vertical</property> -        <property name="spacing">2</property> -        <child internal-child="action_area"> -          <object class="GtkButtonBox"> -            <property name="can_focus">False</property> -            <property name="margin_left">8</property> -            <property name="margin_right">8</property> -            <property name="margin_top">8</property> -            <property name="margin_bottom">8</property> -            <property name="layout_style">end</property> -            <child> -              <object class="GtkButton" id="button1"> -                <property name="label">gtk-cancel</property> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -                <property name="receives_default">True</property> -                <property name="use_stock">True</property> -              </object> -              <packing> -                <property name="expand">True</property> -                <property name="fill">True</property> -                <property name="position">0</property> -              </packing> -            </child> -            <child> -              <object class="GtkButton" id="button2"> -                <property name="label">gtk-apply</property> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -                <property name="receives_default">True</property> -                <property name="use_stock">True</property> -                <signal name="clicked" handler="on_prefs_apply_button_clicked" swapped="no"/> -              </object> -              <packing> -                <property name="expand">True</property> -                <property name="fill">True</property> -                <property name="position">1</property> -              </packing> -            </child> -          </object> -          <packing> -            <property name="expand">False</property> -            <property name="fill">False</property> -            <property name="position">0</property> -          </packing> + +    <template class="GtkPreferencesDialog" parent="GtkWindow"> + +        <property name="default-width">980</property> +        <property name="default-height">640</property> +        <property name="modal">true</property> +        <property name="resizable">true</property> + +        <child type="titlebar"> +            <object class="GtkBox"> +                <child> +                    <object class="GtkHeaderBar" id="sidebar-header"> +                        <property name="decoration-layout">:</property> + +                        <property name="title-widget"> +                            <object class="GtkLabel" id="side_title"> +                                <property name="label" translatable="yes">Parameters</property> +                                <property name="single-line-mode">True</property> +                                <property name="ellipsize">end</property> +                                <property name="width-chars">5</property> +                                <style> +                                    <class name="title"/> +                                </style> +                            </object> +                        </property> + +                        <child type="start"> +                            <object class="GtkToggleButton"> +                                <property name="icon-name">edit-find-symbolic</property> +                                <property name="valign">center</property> +                            </object> +                        </child> +                    </object> +                </child> + +                <!-- Séparation centrale --> +                <child> +                    <object class="GtkSeparator"> +                        <property name="orientation">vertical</property> +                        <property name="css-name">sidebar</property> +                    </object> +                </child> + +                <child> +                    <object class="GtkHeaderBar" id="main-header"> +                        <property name="hexpand">1</property> + +                        <property name="title-widget"> +                            <object class="GtkLabel" id="main_title"> +                                <property name="label" translatable="yes"></property> +                                <property name="single-line-mode">True</property> +                                <property name="ellipsize">end</property> +                                <property name="width-chars">5</property> +                                <style> +                                    <class name="title"/> +                                </style> +                            </object> +                        </property> + +                    </object> +                </child> +            </object>          </child> +          <child> -          <object class="GtkPaned"> -            <property name="visible">True</property> -            <property name="can_focus">True</property> -            <property name="position">200</property> -            <property name="wide_handle">True</property> -            <child> -              <object class="GtkScrolledWindow"> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -                <property name="margin_left">8</property> -                <property name="margin_right">8</property> -                <property name="margin_top">8</property> -                <property name="shadow_type">in</property> +            <object class="GtkBox">                  <child> -                  <object class="GtkTreeView" id="treeview"> -                    <property name="visible">True</property> -                    <property name="can_focus">True</property> -                    <property name="model">pref_list</property> -                    <property name="headers_visible">False</property> -                    <child internal-child="selection"> -                      <object class="GtkTreeSelection"> -                        <signal name="changed" handler="on_prefs_selection_changed" swapped="no"/> -                      </object> -                    </child> -                    <child> -                      <object class="GtkTreeViewColumn"> -                        <property name="title" translatable="yes">column</property> -                        <child> -                          <object class="GtkCellRendererText"/> -                          <attributes> -                            <attribute name="text">0</attribute> -                          </attributes> -                        </child> -                      </object> -                    </child> -                  </object> +                    <object class="GtkScrolledWindow" id="side_content"> +                        <property name="hexpand">false</property> +                        <property name="vexpand">true</property> +                        <property name="hscrollbar-policy">never</property> +                        <property name="vscrollbar-policy">automatic</property> +                    </object> +                </child> + +                <!-- Séparation centrale --> +                <child> +                    <object class="GtkSeparator"> +                        <property name="orientation">vertical</property> +                        <property name="css-name">sidebar</property> +                    </object>                  </child> -              </object> -              <packing> -                <property name="resize">False</property> -                <property name="shrink">True</property> -              </packing> -            </child> -            <child> -              <object class="GtkStack" id="stack"> -                <property name="visible">True</property> -                <property name="can_focus">False</property> -                <property name="margin_left">8</property> -                <property name="margin_right">8</property> -                <property name="margin_top">8</property> +                  <child> -                  <object class="GtkBox"> -                    <property name="visible">True</property> -                    <property name="can_focus">False</property> -                    <property name="orientation">vertical</property> -                    <child> -                      <placeholder/> -                    </child> -                  </object> -                  <packing> -                    <property name="name">empty</property> -                  </packing> +                    <object class="GtkScrolledWindow" id="main_content"> +                        <property name="hexpand">1</property> +                        <property name="vexpand">1</property> +                        <property name="hscrollbar-policy">never</property> +                        <property name="vscrollbar-policy">automatic</property> +                    </object>                  </child> -              </object> -              <packing> -                <property name="resize">True</property> -                <property name="shrink">True</property> -              </packing> -            </child> -          </object> -          <packing> -            <property name="expand">True</property> -            <property name="fill">True</property> -            <property name="position">1</property> -          </packing> +            </object>          </child> -      </object> -    </child> -    <action-widgets> -      <action-widget response="-6">button1</action-widget> -      <action-widget response="-10">button2</action-widget> -    </action-widgets> -    <child> -      <placeholder/> -    </child> -  </object> + +        <object class="GtkSizeGroup"> +            <widgets> +                <widget name="sidebar-header"/> +                <widget name="side_content"/> +            </widgets> +        </object> +        <object class="GtkSizeGroup"> +            <widgets> +                <widget name="main-header"/> +                <widget name="main_content"/> +            </widgets> +        </object> + +    </template>  </interface> diff --git a/src/gui/dialogs/prefs/Makefile.am b/src/gui/dialogs/prefs/Makefile.am new file mode 100644 index 0000000..fa1af96 --- /dev/null +++ b/src/gui/dialogs/prefs/Makefile.am @@ -0,0 +1,31 @@ + +BUILT_SOURCES = resources.h resources.c + +noinst_LTLIBRARIES  = libguidialogsprefs.la + +UI_FILES =									\ +	security.ui + +libguidialogsprefs_la_SOURCES =				\ +	resources.h resources.c					\ +	security-int.h							\ +	security.h security.c + +libguidialogsprefs_la_CFLAGS = $(LIBGTK4_CFLAGS) + + +devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) + +dev_HEADERS = $(libguidialogsprefs_la_SOURCES:%c=) + + +resources.c: gresource.xml $(UI_FILES) +	glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name gui_dialogs_prefs gresource.xml + +resources.h: gresource.xml +	glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name gui_dialogs_prefs gresource.xml + + +CLEANFILES = resources.h resources.c + +EXTRA_DIST = gresource.xml $(UI_FILES) diff --git a/src/gui/dialogs/prefs/gresource.xml b/src/gui/dialogs/prefs/gresource.xml new file mode 100644 index 0000000..7b18143 --- /dev/null +++ b/src/gui/dialogs/prefs/gresource.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<gresources> +    <gresource prefix="/re/chrysalide/framework/gui/dialogs/prefs"> +        <file compressed="true">security.ui</file> +    </gresource> +</gresources> diff --git a/src/gui/dialogs/prefs/security-int.h b/src/gui/dialogs/prefs/security-int.h new file mode 100644 index 0000000..c693fdb --- /dev/null +++ b/src/gui/dialogs/prefs/security-int.h @@ -0,0 +1,64 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * security-int.h - définitions internes pour la configuration des paramètres liés à la sécurité + * + * Copyright (C) 2025 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GUI_DIALOGS_PREFS_SECURITY_INT_H +#define _GUI_DIALOGS_PREFS_SECURITY_INT_H + + +#include "security.h" +#include "../../../glibext/secstorage.h" + + + +/* Fenêtre d'édition générale de la configuration (instance) */ +struct _GtkSecurityTweakPanel +{ +    GtkBox parent;                          /* A laisser en premier        */ + +    /* Stockage sécurisé */ + +    GSecretStorage *storage;                /* Stockage des secrets        */ + +    GtkWidget *current_primary_passwd;      /* Mot de passe courant        */ + +    GtkWidget *new_primary_passwd;          /* Nouveau mot de passe        */ +    GtkWidget *new_primary_passwd_lbl;      /* Etiquette associée          */ +    GtkWidget *new_primary_passwd_2;        /* Nouveau mot de passe (#2)   */ +    GtkWidget *new_primary_passwd_2_lbl;    /* Etiquette associée (#2)     */ + +    GtkWidget *set_password;                /* Bouton de définition de mdp */ +    GtkWidget *change_password;             /* Bouton de changement de mdp */ +    GtkWidget *remove_password;             /* Bouton de suppression de mdp*/ + +}; + +/* Fenêtre d'édition générale de la configuration (classe) */ +struct _GtkSecurityTweakPanelClass +{ +    GtkBoxClass parent;                     /* A laisser en premier        */ + +}; + + + +#endif  /* _GUI_DIALOGS_PREFS_SECURITY_INT_H */ diff --git a/src/gui/dialogs/prefs/security.c b/src/gui/dialogs/prefs/security.c new file mode 100644 index 0000000..cf2f6c8 --- /dev/null +++ b/src/gui/dialogs/prefs/security.c @@ -0,0 +1,400 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * security.h - configuration des paramètres liés à la sécurité + * + * Copyright (C) 2025 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 <http://www.gnu.org/licenses/>. + */ + + +#include "security.h" + + +#include <i18n.h> + + +#include "security-int.h" +#include "../../../core/global.h" +#include "../../../core/logs.h" +#include "../../../gtkext/helpers.h" + + + +/* ---------------------- GESTION DE L'ENSEMBLE DES PARAMETRES ---------------------- */ + + +/* Procède à l'initialisation de classe des configurations. */ +static void gtk_security_tweak_panel_class_init(GtkSecurityTweakPanelClass *); + +/* Procède à l'initialisation des configurations de sécurité. */ +static void gtk_security_tweak_panel_init(GtkSecurityTweakPanel *); + +/* Supprime toutes les références externes. */ +static void gtk_security_tweak_panel_dispose(GObject *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_security_tweak_panel_finalize(GObject *); + + + +/* ---------------------- CONSERVATION SECURISEE DE PARAMETRES ---------------------- */ + + +/* Initalise la partie relative au stockage sécurisé. */ +static void gtk_security_tweak_panel_init_secret_storage(GtkSecurityTweakPanel *); + +/* Supprime toutes les références externes. */ +static void gtk_security_tweak_panel_dispose_secret_storage(GtkSecurityTweakPanel *); + +/* Note le changement de verrouillage du stockage sécurisé. */ +static void gtk_security_tweak_panel_on_secret_storage_lock_update(GSecretStorage *, GtkSecurityTweakPanel *); + +/* Réagit à un changement dans l'édition d'un mot de passe. */ +static void gtk_security_tweak_panel_on_new_passwords_changed(GtkEditable *, GtkSecurityTweakPanel *); + +/* Réagit à une demande de création de mot de passe. */ +static void gtk_security_tweak_panel_on_set_password_clicked(GtkButton *, GtkSecurityTweakPanel *); + +/* Réagit à une demande de changement de mot de passe. */ +static void gtk_security_tweak_panel_on_change_password_clicked(GtkButton *, GtkSecurityTweakPanel *); + +/* Réagit à une demande de suppression de mot de passe. */ +static void gtk_security_tweak_panel_on_remove_password_clicked(GtkButton *, GtkSecurityTweakPanel *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                        GESTION DE L'ENSEMBLE DES PARAMETRES                        */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type du composant d'affichage générique. */ +G_DEFINE_TYPE(GtkSecurityTweakPanel, gtk_security_tweak_panel, GTK_TYPE_BOX); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class = classe GTK à initialiser.                            * +*                                                                             * +*  Description : Procède à l'initialisation de classe des configurations.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_class_init(GtkSecurityTweakPanelClass *class) +{ +    GObjectClass *object;                   /* Plus haut niveau équivalent */ +    GtkWidgetClass *widget;                 /* Classe de haut niveau       */ + +    object = G_OBJECT_CLASS(class); + +    object->dispose = gtk_security_tweak_panel_dispose; +    object->finalize = gtk_security_tweak_panel_finalize; + +    widget = GTK_WIDGET_CLASS(class); + +    gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gui/dialogs/prefs/security.ui"); + +    /* Stockage sécurisé */ + +    gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_security_tweak_panel_on_new_passwords_changed)); +    gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_security_tweak_panel_on_set_password_clicked)); +    gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_security_tweak_panel_on_change_password_clicked)); +    gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_security_tweak_panel_on_remove_password_clicked)); + +    gtk_widget_class_bind_template_child(widget, GtkSecurityTweakPanel, current_primary_passwd); +    gtk_widget_class_bind_template_child(widget, GtkSecurityTweakPanel, new_primary_passwd); +    gtk_widget_class_bind_template_child(widget, GtkSecurityTweakPanel, new_primary_passwd_lbl); +    gtk_widget_class_bind_template_child(widget, GtkSecurityTweakPanel, new_primary_passwd_2); +    gtk_widget_class_bind_template_child(widget, GtkSecurityTweakPanel, new_primary_passwd_2_lbl); +    gtk_widget_class_bind_template_child(widget, GtkSecurityTweakPanel, set_password); +    gtk_widget_class_bind_template_child(widget, GtkSecurityTweakPanel, change_password); +    gtk_widget_class_bind_template_child(widget, GtkSecurityTweakPanel, remove_password); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : panel = composant GTK à initialiser.                         * +*                                                                             * +*  Description : Procède à l'initialisation des configurations de sécurité.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_init(GtkSecurityTweakPanel *panel) +{ +    gtk_widget_init_template(GTK_WIDGET(panel)); + +    gtk_security_tweak_panel_init_secret_storage(panel); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : object = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_dispose(GObject *object) +{ +    GtkSecurityTweakPanel *panel;           /* Version spécialisée         */ + +    panel = GTK_SECURITY_TWEAK_PANEL(object); + +    gtk_security_tweak_panel_dispose_secret_storage(panel); + +    gtk_widget_dispose_template(GTK_WIDGET(panel), GTK_TYPE_SECURITY_TWEAK_PANEL); + +    G_OBJECT_CLASS(gtk_security_tweak_panel_parent_class)->dispose(object); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : object = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_finalize(GObject *object) +{ +    G_OBJECT_CLASS(gtk_security_tweak_panel_parent_class)->finalize(object); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                        CONSERVATION SECURISEE DE PARAMETRES                        */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : panel = composant GTK à initialiser.                         * +*                                                                             * +*  Description : Initalise la partie relative au stockage sécurisé.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_init_secret_storage(GtkSecurityTweakPanel *panel) +{ +    panel->storage = get_secret_storage(); + +    g_signal_connect(panel->storage, "lock-update", +                     G_CALLBACK(gtk_security_tweak_panel_on_secret_storage_lock_update), panel); + +    gtk_security_tweak_panel_on_secret_storage_lock_update(panel->storage, panel); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : panel = instance d'objet GLib à traiter.                     * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_dispose_secret_storage(GtkSecurityTweakPanel *panel) +{ +    if (panel->storage != NULL) +        g_signal_handlers_disconnect_by_func(panel->storage, +                                             gtk_security_tweak_panel_on_secret_storage_lock_update, panel); + +    g_clear_object(&panel->storage); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : storage = gardien des secrets impliqué.                      * +*                panel   = support de la partie relative au stockage sécurisé.* +*                                                                             * +*  Description : Note le changement de verrouillage du stockage sécurisé.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_on_secret_storage_lock_update(GSecretStorage *storage, GtkSecurityTweakPanel *panel) +{ +    bool has_key;                           /* Existence d'une clef ?      */ + +    has_key = g_secret_storage_has_key(panel->storage); + +    gtk_widget_set_visible(panel->new_primary_passwd, has_key); +    gtk_widget_set_visible(panel->new_primary_passwd_lbl, has_key); + +    gtk_widget_set_visible(panel->new_primary_passwd_2, has_key); +    gtk_widget_set_visible(panel->new_primary_passwd_2_lbl, has_key); + +    gtk_widget_set_visible(panel->set_password, !has_key); +    gtk_widget_set_visible(panel->change_password, has_key); +    gtk_widget_set_visible(panel->remove_password, has_key); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : editable = zone de saisie bouton GTK concerné par l'appel.   * +*                panel    = support de la partie liée au stockage sécurisé.   * +*                                                                             * +*  Description : Réagit à un changement dans l'édition d'un mot de passe.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_on_new_passwords_changed(GtkEditable *editable, GtkSecurityTweakPanel *panel) +{ +    const char *new_passwd;                 /* Nouveau mot de passe #1     */ +    const char *new_passwd_2;               /* Nouveau mot de passe #2     */ +    bool status;                            /* Bilan de l'opération        */ + +    new_passwd = gtk_editable_get_text(GTK_EDITABLE(panel->new_primary_passwd)); + +    new_passwd_2 = gtk_editable_get_text(GTK_EDITABLE(panel->new_primary_passwd_2)); + +    status = (strcmp(new_passwd, new_passwd_2) == 0); + +    gtk_widget_set_sensitive(panel->change_password, status); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : button = bouton GTK concerné par l'appel.                    * +*                panel  = support de la partie relative au stockage sécurisé. * +*                                                                             * +*  Description : Réagit à une demande de création de mot de passe.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_on_set_password_clicked(GtkButton *button, GtkSecurityTweakPanel *panel) +{ +    const char *passwd;                     /* Mot de passe à considérer   */ +    bool status;                            /* Bilan de l'opération        */ + +    passwd = gtk_editable_get_text(GTK_EDITABLE(panel->current_primary_passwd)); + +    status = g_secret_storage_set_password(panel->storage, passwd); + +    log_variadic_message(LMT_INFO, _("Setting password for secret storage: %s"), +                         status ? _("success") : _("failed")); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : button = bouton GTK concerné par l'appel.                    * +*                panel  = support de la partie relative au stockage sécurisé. * +*                                                                             * +*  Description : Réagit à une demande de changement de mot de passe.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_on_change_password_clicked(GtkButton *button, GtkSecurityTweakPanel *panel) +{ +    const char *old_passwd;                 /* Ancien mot de passe         */ +    const char *new_passwd;                 /* Nouveau mot de passe        */ +    bool status;                            /* Bilan de l'opération        */ + +    old_passwd = gtk_editable_get_text(GTK_EDITABLE(panel->current_primary_passwd)); + +    new_passwd = gtk_editable_get_text(GTK_EDITABLE(panel->new_primary_passwd)); + +    status = g_secret_storage_change_password(panel->storage, old_passwd, new_passwd); + +    log_variadic_message(LMT_INFO, _("Changed password for secret storage: %s"), +                         status ? _("success") : _("failed")); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : button = bouton GTK concerné par l'appel.                    * +*                panel  = support de la partie relative au stockage sécurisé. * +*                                                                             * +*  Description : Réagit à une demande de suppression de mot de passe.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_security_tweak_panel_on_remove_password_clicked(GtkButton *button, GtkSecurityTweakPanel *panel) +{ +    const char *passwd;                     /* Mot de passe à considérer   */ +    bool status;                            /* Bilan de l'opération        */ + +    passwd = gtk_editable_get_text(GTK_EDITABLE(panel->current_primary_passwd)); + +    status = g_secret_storage_remove_password(panel->storage, passwd); + +    log_variadic_message(LMT_INFO, _("Removed password for secret storage: %s"), +                         status ? _("success") : _("failed")); + +} diff --git a/src/gui/dialogs/prefs/security.h b/src/gui/dialogs/prefs/security.h new file mode 100644 index 0000000..206a123 --- /dev/null +++ b/src/gui/dialogs/prefs/security.h @@ -0,0 +1,41 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * security.h - prototypes pour la configuration des paramètres liés à la sécurité + * + * Copyright (C) 2025 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GUI_DIALOGS_PREFS_SECURITY_H +#define _GUI_DIALOGS_PREFS_SECURITY_H + + +#include <gtk/gtk.h> + + +#include "../../../glibext/helpers.h" + + + +#define GTK_TYPE_SECURITY_TWEAK_PANEL (gtk_security_tweak_panel_get_type()) + +DECLARE_GTYPE(GtkSecurityTweakPanel, gtk_security_tweak_panel, GTK, SECURITY_TWEAK_PANEL); + + + +#endif  /* _GUI_DIALOGS_PREFS_SECURITY_H */ diff --git a/src/gui/dialogs/prefs/security.ui b/src/gui/dialogs/prefs/security.ui new file mode 100644 index 0000000..ccf2d39 --- /dev/null +++ b/src/gui/dialogs/prefs/security.ui @@ -0,0 +1,170 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + +    <template class="GtkSecurityTweakPanel" parent="GtkBox"> + +        <property name="orientation">vertical</property> + +        <!-- Conservation de paramètres sécurisée --> +        <child> +            <object class="GtkGrid"> +                <property name="margin-start">20</property> +                <property name="margin-end">20</property> +                <property name="margin-top">20</property> +                <property name="margin-bottom">20</property> +                <property name="row-spacing">10</property> +                <property name="column-spacing">10</property> + +                <child> +                    <object class="GtkLabel"> +                        <property name="label">Secret storage</property> +                        <property name="use-markup">true</property> +                        <property name="xalign">0</property> +                        <layout> +                            <property name="column">0</property> +                            <property name="row">0</property> +                            <property name="column-span">2</property> +                        </layout> +                        <style> +                            <class name="heading"/> +                        </style> +                    </object> +                </child> + +                <child> +                    <object class="GtkLabel"> +                        <property name="label">Configuration may handle sensitive data (such as passwords or API keys) which can be saved in plain text or stored encrypted using a Primary Password. + +If encryption is activated, entering the Primary Password will be asked on need once per session.</property> +                        <property name="wrap">true</property> +                        <property name="xalign">0</property> +                        <layout> +                            <property name="column">0</property> +                            <property name="row">1</property> +                            <property name="column-span">2</property> +                        </layout> +                        <style> +                            <class name="dim-label"/> +                        </style> +                    </object> +                </child> + +                <!-- Mot de passe courant --> + +                <child> +                    <object class="GtkLabel"> +                        <property name="label">Enter current password:</property> +                        <property name="xalign">0</property> +                        <layout> +                            <property name="column">0</property> +                            <property name="row">2</property> +                        </layout> +                    </object> +                </child> + +                <child> +                    <object class="GtkPasswordEntry" id="current_primary_passwd"> +                        <property name="hexpand">true</property> +                        <property name="show-peek-icon">true</property> +                        <layout> +                            <property name="column">1</property> +                            <property name="row">2</property> +                        </layout> +                    </object> +                </child> + +                <!-- Nouveau mot de passe --> + +                <child> +                    <object class="GtkLabel" id="new_primary_passwd_lbl"> +                        <property name="label">Enter new password:</property> +                        <property name="xalign">0</property> +                        <layout> +                            <property name="column">0</property> +                            <property name="row">3</property> +                        </layout> +                    </object> +                </child> + +                <child> +                    <object class="GtkPasswordEntry" id="new_primary_passwd"> +                        <property name="hexpand">true</property> +                        <property name="show-peek-icon">true</property> +                        <signal name="changed" handler="gtk_security_tweak_panel_on_new_passwords_changed"/> +                        <layout> +                            <property name="column">1</property> +                            <property name="row">3</property> +                        </layout> +                    </object> +                </child> + +                <!-- Confirmation de mot de passe --> + +                <child> +                    <object class="GtkLabel" id="new_primary_passwd_2_lbl"> +                        <property name="label">Re-enter new password:</property> +                        <property name="xalign">0</property> +                        <layout> +                            <property name="column">0</property> +                            <property name="row">4</property> +                        </layout> +                    </object> +                </child> + +                <child> +                    <object class="GtkPasswordEntry" id="new_primary_passwd_2"> +                        <property name="hexpand">true</property> +                        <property name="show-peek-icon">true</property> +                        <signal name="changed" handler="gtk_security_tweak_panel_on_new_passwords_changed"/> +                        <layout> +                            <property name="column">1</property> +                            <property name="row">4</property> +                        </layout> +                    </object> +                </child> + +                <!-- Boutons de contrôle --> + +                <child> +                    <object class="GtkBox"> +                        <property name="halign">center</property> +                        <property name="homogeneous">true</property> +                        <property name="spacing">8</property> +                        <layout> +                            <property name="column">0</property> +                            <property name="row">5</property> +                            <property name="column-span">2</property> +                        </layout> + +                        <child> +                            <object class="GtkButton" id="set_password"> +                                <property name="label">Set</property> +                                <signal name="clicked" handler="gtk_security_tweak_panel_on_set_password_clicked"/> +                            </object> +                        </child> + +                        <child> +                            <object class="GtkButton" id="change_password"> +                                <property name="label">Change</property> +                                <signal name="clicked" handler="gtk_security_tweak_panel_on_change_password_clicked"/> +                            </object> +                        </child> + +                        <child> +                            <object class="GtkButton" id="remove_password"> +                                <property name="label">Remove</property> +                                <signal name="clicked" handler="gtk_security_tweak_panel_on_remove_password_clicked"/> +                                <style> +                                    <class name="destructive-action"/> +                                </style> +                            </object> +                        </child> + +                    </object> +                </child> + +            </object> +        </child> + +    </template> +</interface>  | 
