From ecac36fd8d1dc010aa29643aeb75988ca02f9b20 Mon Sep 17 00:00:00 2001 From: grayTerminal-sh Date: Tue, 14 Jul 2026 13:37:12 +0200 Subject: [PATCH] feat(gui): display selected node in workspace --- docs/tickets/closed/TICKET-015.md | 225 ++++++++++++++++++++++++++++++ include/views/main_window.h | 14 ++ include/widgets/workspace.h | 19 +++ labfy-investigation | Bin 95120 -> 97232 bytes src/core/application.c | 5 + src/views/main_window.c | 16 +++ src/widgets/workspace.c | 195 ++++++++++++++++++++++++++ 7 files changed, 474 insertions(+) create mode 100644 docs/tickets/closed/TICKET-015.md diff --git a/docs/tickets/closed/TICKET-015.md b/docs/tickets/closed/TICKET-015.md new file mode 100644 index 0000000..0493f81 --- /dev/null +++ b/docs/tickets/closed/TICKET-015.md @@ -0,0 +1,225 @@ +# Ticket #015 + +## Titre + +Afficher le nœud sélectionné dans le `Workspace`. + +--- + +## Objectif + +Afficher dans la zone de travail les informations principales du nœud sélectionné dans l'arborescence. + +Lorsqu'un dossier ou un fichier est sélectionné, le `Workspace` doit afficher : + +- son nom ; +- son type ; +- son parent éventuel ; +- son nombre d'enfants s'il s'agit d'un dossier. + +Aucun fichier ne doit encore être ouvert. + +--- + +## Architecture + +```text +InvestigationTreeView + │ + ▼ +Application + │ + ▼ +MainWindow + │ + ▼ +Workspace +``` + +`Application` reste le coordinateur. + +`InvestigationTreeView` détecte la sélection. + +`Workspace` affiche les informations reçues. + +--- + +## Responsabilités + +### Application + +Le module doit : + +- recevoir le nœud sélectionné ; +- transmettre ce nœud à `MainWindow` ; +- ne pas modifier ni libérer le nœud. + +### MainWindow + +Le module doit : + +- recevoir un nœud en lecture seule ; +- le transmettre au `Workspace`. + +### Workspace + +Le module doit : + +- recevoir un `InvestigationNode` en lecture seule ; +- afficher son nom ; +- afficher son type ; +- afficher le nom de son parent si disponible ; +- afficher le nombre d'enfants pour un dossier ; +- restaurer la page d'accueil si le nœud vaut `NULL`. + +--- + +## Principe de propriété + +Le nœud sélectionné reste la propriété du `InvestigationTreeModel`. + +`Application`, `MainWindow` et `Workspace` ne reçoivent qu'une référence non propriétaire : + +```c +const InvestigationNode *node; +``` + +Aucun de ces modules ne doit appeler : + +```c +investigation_node_free(node); +``` + +--- + +## Fichiers concernés + +```text +include/widgets/workspace.h +src/widgets/workspace.c + +include/views/main_window.h +src/views/main_window.c + +src/core/application.c +``` + +Aucune modification du Core métier n'est nécessaire. + +--- + +## Interfaces publiques à ajouter + +### Workspace + +```c +void workspace_set_selected_node( + Workspace *workspace, + const InvestigationNode *node +); +``` + +### MainWindow + +```c +void main_window_set_selected_node( + MainWindow *main_window, + const InvestigationNode *node +); +``` + +--- + +## Comportement attendu + +### Aucun nœud sélectionné + +```text +Labfy Investigation + +Aucune enquête ouverte + +Sélectionnez ou créez une enquête +``` + +### Dossier sélectionné + +```text +00_BaseDeDonnees + +Type : dossier +Parent : Template +Enfants : 2 +``` + +### Fichier sélectionné + +```text +Enquete.sqlite + +Type : fichier +Parent : 00_BaseDeDonnees +``` + +--- + +## Hors périmètre + +Ce ticket ne doit pas : + +- ouvrir le contenu d'un fichier ; +- afficher un aperçu ; +- lire les métadonnées du système de fichiers ; +- afficher la taille d'un fichier ; +- communiquer avec SQLite ; +- modifier l'arborescence ; +- gérer plusieurs sélections. + +--- + +## Contraintes techniques + +- C17 ; +- GTK4 uniquement ; +- aucun état global ; +- aucune propriété du nœud transférée au `Workspace` ; +- documentation Doxygen ; +- compilation sans warning ; +- aucun `Gtk-CRITICAL`. + +--- + +## Critères d'acceptation + +- [ ] Le projet compile sans warning. +- [ ] `make test` reste valide. +- [ ] La sélection d'un dossier met à jour le `Workspace`. +- [ ] La sélection d'un fichier met à jour le `Workspace`. +- [ ] Le nom est correct. +- [ ] Le type est correct. +- [ ] Le parent est correct. +- [ ] Le nombre d'enfants est correct pour un dossier. +- [ ] Une sélection `NULL` restaure la page d'accueil. +- [ ] Aucun module graphique ne libère le nœud. +- [ ] Aucun `Gtk-CRITICAL`. + +--- + +## Tests manuels + +1. Ouvrir une enquête. +2. Sélectionner un dossier. +3. Vérifier les informations affichées. +4. Sélectionner un fichier. +5. Vérifier les informations affichées. +6. Changer d'enquête. +7. Vérifier que l'ancien nœud n'est plus affiché. +8. Lancer `make test`. + +--- + +## Commit attendu + +```text +feat(gui): display selected node in workspace +``` diff --git a/include/views/main_window.h b/include/views/main_window.h index b2c9e0a..8253671 100644 --- a/include/views/main_window.h +++ b/include/views/main_window.h @@ -8,6 +8,7 @@ #include "core/investigation_tree_model.h" #include "widgets/investigation_tree_view.h" +#include "core/investigation_node.h" #include @@ -63,6 +64,19 @@ void main_window_set_tree_selection_callback( gpointer user_data ); +/** + * @brief Affiche dans le Workspace les informations du nœud sélectionné. + * + * La fenêtre principale ne devient pas propriétaire du nœud. + * + * @param main_window Fenêtre principale à mettre à jour. + * @param node Nœud sélectionné en lecture seule, ou NULL. + */ +void main_window_set_selected_node( + MainWindow *main_window, + const InvestigationNode *node +); + /** * @brief Libère les ressources de la fenêtre. * diff --git a/include/widgets/workspace.h b/include/widgets/workspace.h index 391f59e..9effabb 100644 --- a/include/widgets/workspace.h +++ b/include/widgets/workspace.h @@ -6,6 +6,9 @@ #ifndef LABFY_INVESTIGATION_WORKSPACE_H #define LABFY_INVESTIGATION_WORKSPACE_H + +#include "core/investigation_node.h" + #include /** @@ -37,6 +40,22 @@ GtkWidget *workspace_get_widget( const Workspace *workspace ); +/** + * @brief Affiche les informations du nœud sélectionné. + * + * Le Workspace ne devient pas propriétaire du nœud. + * Le nœud doit rester valide pendant toute la durée de son affichage. + * + * Passer NULL restaure la page d'accueil. + * + * @param workspace Zone de travail à mettre à jour. + * @param node Nœud sélectionné en lecture seule, ou NULL. + */ +void workspace_set_selected_node( + Workspace *workspace, + const InvestigationNode *node +); + /** * @brief Libère la structure d'encapsulation de la zone de travail. * diff --git a/labfy-investigation b/labfy-investigation index 0aea6e1741930ad585ff7ad3eca7bcb638777b69..66f0a39213a3b4274062e5d818f50ae7d493abb9 100755 GIT binary patch delta 24401 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 B7CZm| delta 20799 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 diff --git a/src/core/application.c b/src/core/application.c index 5e93ce7..1213b1f 100644 --- a/src/core/application.c +++ b/src/core/application.c @@ -129,6 +129,11 @@ static void application_on_tree_node_selected( return; } + main_window_set_selected_node( + application->main_window, + node + ); + if (node == NULL) { g_print("Aucun nœud sélectionné.\n"); diff --git a/src/views/main_window.c b/src/views/main_window.c index 5771933..7157d52 100644 --- a/src/views/main_window.c +++ b/src/views/main_window.c @@ -303,6 +303,22 @@ void main_window_set_tree_selection_callback( ); } +void main_window_set_selected_node( + MainWindow *main_window, + const InvestigationNode *node +) +{ + if (main_window == NULL) + { + return; + } + + workspace_set_selected_node( + main_window->workspace, + node + ); +} + void main_window_free(MainWindow *main_window) { if (main_window == NULL) diff --git a/src/widgets/workspace.c b/src/widgets/workspace.c index a8a6e67..b5d4a01 100644 --- a/src/widgets/workspace.c +++ b/src/widgets/workspace.c @@ -21,8 +21,34 @@ struct Workspace GtkWidget *title_label; GtkWidget *status_label; GtkWidget *instruction_label; + + GtkWidget *node_box; + GtkWidget *node_name_label; + GtkWidget *node_type_label; + GtkWidget *node_parent_label; + GtkWidget *node_children_label; }; +static void workspace_show_welcome( + Workspace *workspace +) +{ + if (workspace == NULL) + { + return; + } + + gtk_widget_set_visible( + workspace->welcome_box, + TRUE + ); + + gtk_widget_set_visible( + workspace->node_box, + FALSE + ); +} + Workspace *workspace_new(void) { Workspace *workspace = NULL; @@ -102,11 +128,64 @@ Workspace *workspace_new(void) workspace->instruction_label ); + workspace->node_box = gtk_box_new( + GTK_ORIENTATION_VERTICAL, + 12 + ); + + if (workspace->node_box == NULL) + { + workspace_free(workspace); + return NULL; + } + + gtk_widget_set_halign( + workspace->node_box, + GTK_ALIGN_CENTER + ); + + gtk_widget_set_valign( + workspace->node_box, + GTK_ALIGN_CENTER + ); + + workspace->node_name_label = gtk_label_new(NULL); + workspace->node_type_label = gtk_label_new(NULL); + workspace->node_parent_label = gtk_label_new(NULL); + workspace->node_children_label = gtk_label_new(NULL); + + gtk_box_append( + GTK_BOX(workspace->node_box), + workspace->node_name_label + ); + + gtk_box_append( + GTK_BOX(workspace->node_box), + workspace->node_type_label + ); + + gtk_box_append( + GTK_BOX(workspace->node_box), + workspace->node_parent_label + ); + + gtk_box_append( + GTK_BOX(workspace->node_box), + workspace->node_children_label + ); + gtk_box_append( GTK_BOX(workspace->root_widget), workspace->welcome_box ); + gtk_box_append( + GTK_BOX(workspace->root_widget), + workspace->node_box + ); + + workspace_show_welcome(workspace); + return workspace; } @@ -122,6 +201,122 @@ GtkWidget *workspace_get_widget( return workspace->root_widget; } +void workspace_set_selected_node( + Workspace *workspace, + const InvestigationNode *node +) +{ + const char *node_name = NULL; + const InvestigationNode *parent_node = NULL; + const char *parent_name = NULL; + InvestigationNodeType node_type; + size_t children_count = 0; + + char *type_text = NULL; + char *parent_text = NULL; + char *children_text = NULL; + + if (workspace == NULL) + { + return; + } + + if (node == NULL) + { + workspace_show_welcome(workspace); + return; + } + + node_name = investigation_node_get_name(node); + node_type = investigation_node_get_type(node); + parent_node = investigation_node_get_parent(node); + + gtk_label_set_text( + GTK_LABEL(workspace->node_name_label), + node_name != NULL ? node_name : "(sans nom)" + ); + + if (node_type == INVESTIGATION_NODE_DIRECTORY) + { + type_text = g_strdup("Type : dossier"); + } + else + { + type_text = g_strdup("Type : fichier"); + } + + gtk_label_set_text( + GTK_LABEL(workspace->node_type_label), + type_text + ); + + if (parent_node != NULL) + { + parent_name = investigation_node_get_name(parent_node); + + parent_text = g_strdup_printf( + "Parent : %s", + parent_name != NULL ? parent_name : "(sans nom)" + ); + } + else + { + parent_text = g_strdup("Parent : aucun"); + } + + gtk_label_set_text( + GTK_LABEL(workspace->node_parent_label), + parent_text + ); + + if (node_type == INVESTIGATION_NODE_DIRECTORY) + { + children_count = + investigation_node_get_children_count(node); + + children_text = g_strdup_printf( + "Enfants : %zu", + children_count + ); + + gtk_label_set_text( + GTK_LABEL(workspace->node_children_label), + children_text + ); + + gtk_widget_set_visible( + workspace->node_children_label, + TRUE + ); + } + else + { + gtk_label_set_text( + GTK_LABEL(workspace->node_children_label), + "" + ); + + gtk_widget_set_visible( + workspace->node_children_label, + FALSE + ); + } + + gtk_widget_set_visible( + workspace->welcome_box, + FALSE + ); + + gtk_widget_set_visible( + workspace->node_box, + TRUE + ); + + g_free(children_text); + g_free(parent_text); + g_free(type_text); +} + void workspace_free(Workspace *workspace) { if (workspace == NULL)