From 6938529fb2cf93c55e7a6d3318ddb5e0dec33e0f Mon Sep 17 00:00:00 2001 From: grayTerminal-sh Date: Tue, 14 Jul 2026 10:19:23 +0200 Subject: [PATCH] feat(gui): add investigation tree selection --- docs/tickets/closed/TICKET-014.md | 244 ++++++++++++++++++++++ include/views/main_window.h | 7 + include/widgets/investigation_tree_view.h | 29 +++ include/widgets/sidebar.h | 16 ++ labfy-investigation | Bin 88504 -> 95120 bytes src/core/application.c | 50 +++++ src/views/main_window.c | 19 ++ src/widgets/investigation_tree_view.c | 140 ++++++++++++- src/widgets/sidebar.c | 18 ++ 9 files changed, 517 insertions(+), 6 deletions(-) create mode 100644 docs/tickets/closed/TICKET-014.md diff --git a/docs/tickets/closed/TICKET-014.md b/docs/tickets/closed/TICKET-014.md new file mode 100644 index 0000000..fd4edb8 --- /dev/null +++ b/docs/tickets/closed/TICKET-014.md @@ -0,0 +1,244 @@ +# Ticket #014 + +## Titre + +Ajouter la sélection d'un nœud dans l'arborescence. + +--- + +## Objectif + +Permettre à l'utilisateur de sélectionner un dossier ou un fichier dans +`InvestigationTreeView`. + +Le nœud sélectionné doit être transmis jusqu'au module `Application`, qui +reste responsable de la coordination entre l'arborescence et le reste de +l'interface. + +Ce ticket ne doit encore ouvrir aucun fichier. + +--- + +## Architecture + +```text +GtkListView + │ + ▼ +InvestigationTreeView + │ + ▼ +Sidebar + │ + ▼ +MainWindow + │ + ▼ +Application +``` + +Le Core reste indépendant de GTK. + +--- + +## Responsabilités + +### InvestigationTreeView + +Le module doit : + +- remplacer `GtkNoSelection` par `GtkSingleSelection` ; +- détecter les changements de sélection ; +- retrouver le `InvestigationNode` métier correspondant ; +- appeler un callback public avec le nœud sélectionné ; +- transmettre `NULL` lorsqu'aucun nœud n'est sélectionné. + +### Sidebar + +Le module doit : + +- recevoir un callback de sélection ; +- le transmettre à `InvestigationTreeView` ; +- ne contenir aucune logique métier liée à la sélection. + +### MainWindow + +Le module doit : + +- recevoir le callback depuis `Application` ; +- le transmettre à `Sidebar`. + +### Application + +Le module doit : + +- recevoir le nœud sélectionné ; +- afficher temporairement son nom et son type dans le terminal ; +- ne pas modifier ni libérer le nœud reçu. + +--- + +## Principe de propriété + +Le nœud sélectionné appartient toujours au +`InvestigationTreeModel`, lui-même possédé par `Application`. + +Le callback reçoit uniquement une référence non propriétaire : + +```c +const InvestigationNode *node; +``` + +Le code appelé ne doit jamais faire : + +```c +investigation_node_free(node); +``` + +La référence reste valide tant que le modèle courant n'est pas remplacé ou +détruit. + +--- + +## Interfaces publiques à ajouter + +### InvestigationTreeView + +```c +typedef void (*InvestigationTreeViewSelectionCallback)( + const InvestigationNode *node, + gpointer user_data +); +``` + +```c +void investigation_tree_view_set_selection_callback( + InvestigationTreeView *tree_view, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +); +``` + +### Sidebar + +```c +void sidebar_set_selection_callback( + Sidebar *sidebar, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +); +``` + +### MainWindow + +```c +void main_window_set_tree_selection_callback( + MainWindow *main_window, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +); +``` + +--- + +## Comportement attendu + +Lorsque l'utilisateur sélectionne : + +```text +Enquete.sqlite +``` + +le terminal affiche temporairement : + +```text +Nœud sélectionné : Enquete.sqlite +Type : fichier +``` + +Pour un dossier : + +```text +Nœud sélectionné : 00_BaseDeDonnees +Type : dossier +``` + +Lorsqu'aucun élément n'est sélectionné, le callback reçoit `NULL`. + +--- + +## Hors périmètre + +Ce ticket ne doit pas : + +- ouvrir un fichier ; +- modifier le Workspace ; +- afficher un aperçu ; +- sélectionner plusieurs nœuds ; +- ajouter un menu contextuel ; +- afficher des icônes ; +- modifier le Core ; +- modifier le système de fichiers. + +--- + +## Contraintes techniques + +- GTK4 uniquement ; +- utiliser `GtkSingleSelection` ; +- aucun `GtkTreeView` ; +- aucun état global ; +- callback documenté avec Doxygen ; +- aucune destruction du nœud sélectionné ; +- compilation sans warning ; +- aucun `Gtk-CRITICAL`. + +--- + +## Gestion des changements de modèle + +Lorsqu'un nouveau modèle est installé : + +- la sélection précédente doit être supprimée ; +- aucun callback ne doit conserver une référence vers un nœud de l'ancien + modèle ; +- la nouvelle vue doit démarrer sans sélection. + +--- + +## Critères d'acceptation + +- [ ] Le projet compile sans warning. +- [ ] `make test` reste entièrement valide. +- [ ] Un seul nœud peut être sélectionné. +- [ ] La sélection d'un dossier est détectée. +- [ ] La sélection d'un fichier est détectée. +- [ ] Le bon `InvestigationNode` est transmis au callback. +- [ ] `Application` reçoit l'événement. +- [ ] Le nom et le type sont affichés dans le terminal. +- [ ] Le changement d'enquête efface l'ancienne sélection. +- [ ] Aucun module graphique ne libère le nœud. +- [ ] Aucun `Gtk-CRITICAL`. + +--- + +## Tests manuels + +1. Lancer l'application. +2. Ouvrir le dossier `Template`. +3. Développer `00_BaseDeDonnees`. +4. Sélectionner `Enquete.sqlite`. +5. Vérifier le nom et le type dans le terminal. +6. Sélectionner un dossier. +7. Vérifier que le type affiché est `dossier`. +8. Ouvrir une autre enquête. +9. Vérifier qu'aucune ancienne sélection n'est conservée. +10. Lancer `make test`. + +--- + +## Commit attendu + +```text +feat(gui): add investigation tree selection +``` diff --git a/include/views/main_window.h b/include/views/main_window.h index 0d3e65f..b2c9e0a 100644 --- a/include/views/main_window.h +++ b/include/views/main_window.h @@ -7,6 +7,7 @@ #define LABFY_INVESTIGATION_MAIN_WINDOW_H #include "core/investigation_tree_model.h" +#include "widgets/investigation_tree_view.h" #include @@ -56,6 +57,12 @@ void main_window_set_tree_model( const InvestigationTreeModel *tree_model ); +void main_window_set_tree_selection_callback( + MainWindow *main_window, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +); + /** * @brief Libère les ressources de la fenêtre. * diff --git a/include/widgets/investigation_tree_view.h b/include/widgets/investigation_tree_view.h index 37fbdbc..c39649a 100644 --- a/include/widgets/investigation_tree_view.h +++ b/include/widgets/investigation_tree_view.h @@ -19,6 +19,35 @@ */ typedef struct InvestigationTreeView InvestigationTreeView; +/** + * @brief Callback appelé lorsqu'un nœud est sélectionné. + * + * @param node Nœud sélectionné, ou NULL si aucune sélection n'est active. + * @param user_data Données privées fournies lors de l'enregistrement + * du callback. + */ +typedef void (*InvestigationTreeViewSelectionCallback)( + const InvestigationNode *node, + gpointer user_data +); + +/** + * @brief Définit le callback de sélection. + * + * Le callback est appelé à chaque changement de sélection. + * + * Le composant ne devient pas propriétaire du callback ni de user_data. + * + * @param tree_view Vue arborescente. + * @param callback Fonction appelée lors d'une sélection. + * @param user_data Données privées transmises au callback. + */ +void investigation_tree_view_set_selection_callback( + InvestigationTreeView *tree_view, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +); + /** * @brief Crée une nouvelle vue arborescente vide. * diff --git a/include/widgets/sidebar.h b/include/widgets/sidebar.h index 8171f99..f69b1fe 100644 --- a/include/widgets/sidebar.h +++ b/include/widgets/sidebar.h @@ -7,6 +7,7 @@ #define LABFY_INVESTIGATION_SIDEBAR_H #include "core/investigation_tree_model.h" +#include "widgets/investigation_tree_view.h" #include @@ -55,6 +56,21 @@ void sidebar_set_tree_model( const InvestigationTreeModel *tree_model ); +/** + * @brief Définit le callback appelé lors de la sélection d'un nœud. + * + * La Sidebar transmet simplement ce callback à InvestigationTreeView. + * + * @param sidebar Barre latérale à configurer. + * @param callback Fonction appelée lors d'un changement de sélection. + * @param user_data Données privées transmises au callback. + */ +void sidebar_set_selection_callback( + Sidebar *sidebar, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +); + /** * @brief Libère la structure d'encapsulation du panneau latéral. * diff --git a/labfy-investigation b/labfy-investigation index 65b1d25b18d81ca7913011dfc09e309fae38b5c7..0aea6e1741930ad585ff7ad3eca7bcb638777b69 100755 GIT binary patch literal 95120 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%0D%qlH(|j)@rMHx@smjMNh~$VVo0j_KfE3MA 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, + application_on_tree_node_selected, + application + ); + main_window_present(application->main_window); folder_dialog_select_folder( diff --git a/src/views/main_window.c b/src/views/main_window.c index c1c00aa..5771933 100644 --- a/src/views/main_window.c +++ b/src/views/main_window.c @@ -6,6 +6,7 @@ #include "views/main_window.h" #include "widgets/sidebar.h" #include "widgets/workspace.h" +#include "widgets/investigation_tree_view.h" #include @@ -284,6 +285,24 @@ void main_window_set_tree_model( ); } +void main_window_set_tree_selection_callback( + MainWindow *main_window, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +) +{ + if (main_window == NULL) + { + return; + } + + sidebar_set_selection_callback( + main_window->sidebar, + callback, + user_data + ); +} + void main_window_free(MainWindow *main_window) { if (main_window == NULL) diff --git a/src/widgets/investigation_tree_view.c b/src/widgets/investigation_tree_view.c index 4c87de9..e8090ca 100644 --- a/src/widgets/investigation_tree_view.c +++ b/src/widgets/investigation_tree_view.c @@ -105,9 +105,11 @@ struct InvestigationTreeView GtkWidget *list_view; GtkListItemFactory *factory; - GtkSelectionModel *selection_model; + GtkSingleSelection *selection_model; const InvestigationTreeModel *tree_model; + InvestigationTreeViewSelectionCallback selection_callback; + gpointer selection_user_data; }; /** @@ -364,6 +366,98 @@ static void investigation_tree_view_factory_unbind( } } +/** + * @brief Transmet le nœud sélectionné au code appelant. + * + * @param tree_view Vue contenant le callback. + * @param node Nœud sélectionné, ou NULL. + */ +static void investigation_tree_view_emit_selection( + InvestigationTreeView *tree_view, + const InvestigationNode *node +) +{ + if (tree_view == NULL) + { + return; + } + + if (tree_view->selection_callback == NULL) + { + return; + } + + tree_view->selection_callback( + node, + tree_view->selection_user_data + ); +} + +/** + * @brief Réagit au changement de l'élément sélectionné. + * + * GtkSingleSelection expose une GtkTreeListRow. Cette fonction récupère + * l'adaptateur privé contenu dans cette ligne, puis le nœud métier associé. + * + * @param selection_model Modèle GTK ayant changé de sélection. + * @param property_spec Propriété ayant déclenché la notification. + * @param user_data Pointeur vers InvestigationTreeView. + */ +static void investigation_tree_view_on_selection_changed( + GObject *selection_model, + GParamSpec *property_spec, + gpointer user_data +) +{ + InvestigationTreeView *tree_view = user_data; + GObject *selected_item = NULL; + GtkTreeListRow *tree_row = NULL; + InvestigationTreeItem *tree_item = NULL; + const InvestigationNode *node = NULL; + + (void)property_spec; + + if (tree_view == NULL) + { + return; + } + + selected_item = gtk_single_selection_get_selected_item( + GTK_SINGLE_SELECTION(selection_model) + ); + + if (selected_item == NULL) + { + investigation_tree_view_emit_selection( + tree_view, + NULL + ); + + return; + } + + tree_row = GTK_TREE_LIST_ROW(selected_item); + + tree_item = gtk_tree_list_row_get_item(tree_row); + + if (tree_item == NULL) + { + investigation_tree_view_emit_selection( + tree_view, + NULL + ); + + return; + } + + node = investigation_tree_item_get_node(tree_item); + + investigation_tree_view_emit_selection( + tree_view, + node + ); +} + /** * @brief Retire le modèle GTK actuellement affiché. */ @@ -386,6 +480,10 @@ static void investigation_tree_view_clear_model( ); tree_view->tree_model = NULL; + investigation_tree_view_emit_selection( + tree_view, + NULL + ); } InvestigationTreeView *investigation_tree_view_new(void) @@ -493,7 +591,7 @@ void investigation_tree_view_set_model( InvestigationTreeItem *root_item = NULL; GListStore *root_store = NULL; GtkTreeListModel *gtk_tree_model = NULL; - GtkNoSelection *selection_model = NULL; + GtkSingleSelection *selection_model = NULL; if (tree_view == NULL) { @@ -562,7 +660,7 @@ void investigation_tree_view_set_model( * * Le constructeur prend possession de gtk_tree_model. */ - selection_model = gtk_no_selection_new( + selection_model = gtk_single_selection_new( G_LIST_MODEL(gtk_tree_model) ); @@ -572,17 +670,47 @@ void investigation_tree_view_set_model( return; } - tree_view->selection_model = - GTK_SELECTION_MODEL(selection_model); + gtk_single_selection_set_autoselect( + selection_model, + FALSE + ); + gtk_single_selection_set_can_unselect( + selection_model, + TRUE + ); + + g_signal_connect( + selection_model, + "notify::selected-item", + G_CALLBACK(investigation_tree_view_on_selection_changed), + tree_view + ); + + tree_view->selection_model = selection_model; tree_view->tree_model = tree_model; gtk_list_view_set_model( GTK_LIST_VIEW(tree_view->list_view), - tree_view->selection_model + GTK_SELECTION_MODEL(tree_view->selection_model) ); } +void investigation_tree_view_set_selection_callback( + InvestigationTreeView *tree_view, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +) +{ + if (tree_view == NULL) + { + return; + } + + tree_view->selection_callback = callback; + tree_view->selection_user_data = user_data; +} + void investigation_tree_view_free( InvestigationTreeView *tree_view ) diff --git a/src/widgets/sidebar.c b/src/widgets/sidebar.c index cdaff3e..b3e0989 100644 --- a/src/widgets/sidebar.c +++ b/src/widgets/sidebar.c @@ -196,6 +196,24 @@ void sidebar_set_tree_model( ); } +void sidebar_set_selection_callback( + Sidebar *sidebar, + InvestigationTreeViewSelectionCallback callback, + gpointer user_data +) +{ + if (sidebar == NULL) + { + return; + } + + investigation_tree_view_set_selection_callback( + sidebar->tree_view, + callback, + user_data + ); +} + void sidebar_free(Sidebar *sidebar) { if (sidebar == NULL)