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> |