feat(gui): add investigation folder selector
This commit is contained in:
parent
df5d9c8b6c
commit
aa2b903487
5 changed files with 236 additions and 0 deletions
38
docs/tickets/closed/TICKET-002.md
Normal file
38
docs/tickets/closed/TICKET-002.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Ticket #002
|
||||
|
||||
## Titre
|
||||
|
||||
Ajouter le sélecteur de dossier d’enquête.
|
||||
|
||||
## Objectif
|
||||
|
||||
Permettre à l’utilisateur de sélectionner un dossier d’enquête au lancement de l’application.
|
||||
|
||||
## Responsabilités
|
||||
|
||||
- afficher un dialogue GTK de sélection de dossier ;
|
||||
- retourner le dossier sélectionné ;
|
||||
- gérer l’annulation sans erreur ;
|
||||
- transmettre le chemin au module Application.
|
||||
|
||||
## Hors périmètre
|
||||
|
||||
- création de `00_BaseDeDonnees` ;
|
||||
- ouverture de SQLite ;
|
||||
- initialisation du schéma ;
|
||||
- validation complète d’une enquête.
|
||||
|
||||
## Critères d’acceptation
|
||||
|
||||
- [ ] Le dialogue s’ouvre au lancement.
|
||||
- [ ] Un dossier peut être sélectionné.
|
||||
- [ ] L’annulation est gérée proprement.
|
||||
- [ ] Le chemin sélectionné est affiché dans la fenêtre.
|
||||
- [ ] Aucun warning.
|
||||
- [ ] Les fonctions publiques sont documentées.
|
||||
- [ ] Aucun état global.
|
||||
|
||||
## Commit attendu
|
||||
|
||||
```text
|
||||
feat(gui): add investigation folder selector
|
||||
46
labfy-investigation/include/views/folder_dialog.h
Normal file
46
labfy-investigation/include/views/folder_dialog.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/******************************************************************************
|
||||
* @file folder_dialog.h
|
||||
* @brief Interface du dialogue de sélection d'un dossier d'enquête.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LABFY_INVESTIGATION_FOLDER_DIALOG_H
|
||||
#define LABFY_INVESTIGATION_FOLDER_DIALOG_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/**
|
||||
* @brief Fonction appelée après la fermeture du dialogue de sélection.
|
||||
*
|
||||
* @param folder_path Chemin du dossier sélectionné, ou NULL si l'utilisateur
|
||||
* a annulé la sélection.
|
||||
* @param user_data Données transmises lors de l'ouverture du dialogue.
|
||||
*
|
||||
* Le chemin reçu reste valide uniquement pendant l'appel de cette fonction.
|
||||
* Il doit être copié si le code appelant souhaite le conserver.
|
||||
*
|
||||
* @param callback
|
||||
* Fonction appelée lorsque le dialogue est fermé.
|
||||
*
|
||||
* Si l'utilisateur annule la sélection,
|
||||
* folder_path vaut NULL.
|
||||
*/
|
||||
typedef void (*FolderDialogCallback)(
|
||||
const char *folder_path,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Ouvre un dialogue permettant de sélectionner un dossier.
|
||||
*
|
||||
* @param parent Fenêtre parente du dialogue.
|
||||
* Peut être NULL.
|
||||
* @param callback Fonction appelée lorsque le dialogue est terminé.
|
||||
* @param user_data Données transmises à la fonction de rappel.
|
||||
*/
|
||||
void folder_dialog_select_folder(
|
||||
GtkWindow *parent,
|
||||
FolderDialogCallback callback,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
#endif
|
||||
Binary file not shown.
|
|
@ -4,6 +4,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include "core/application.h"
|
||||
#include "views/folder_dialog.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
|
@ -39,6 +40,27 @@ struct Application
|
|||
* @param gtk_application Application GTK ayant reçu le signal.
|
||||
* @param user_data Données utilisateur associées au signal.
|
||||
*/
|
||||
|
||||
static void application_on_folder_selected(
|
||||
const char *folder_path,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW(user_data);
|
||||
|
||||
if (folder_path == NULL)
|
||||
{
|
||||
gtk_window_set_title(
|
||||
window,
|
||||
"Labfy Investigation — aucune enquête sélectionnée"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_window_set_title(window, folder_path);
|
||||
}
|
||||
|
||||
static void application_on_activate(GtkApplication *gtk_application,
|
||||
gpointer user_data)
|
||||
{
|
||||
|
|
@ -56,6 +78,12 @@ static void application_on_activate(GtkApplication *gtk_application,
|
|||
);
|
||||
|
||||
gtk_window_present(GTK_WINDOW(window));
|
||||
|
||||
folder_dialog_select_folder(
|
||||
GTK_WINDOW(window),
|
||||
application_on_folder_selected,
|
||||
window
|
||||
);
|
||||
}
|
||||
|
||||
Application *application_new(void)
|
||||
|
|
@ -113,3 +141,5 @@ void application_free(Application *application)
|
|||
|
||||
g_free(application);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
122
labfy-investigation/src/views/folder_dialog.c
Normal file
122
labfy-investigation/src/views/folder_dialog.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/******************************************************************************
|
||||
* @file folder_dialog.c
|
||||
* @brief Implémentation du dialogue de sélection d'un dossier d'enquête.
|
||||
******************************************************************************/
|
||||
|
||||
#include "views/folder_dialog.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
/**
|
||||
* @struct FolderDialogContext
|
||||
* @brief Conserve les données nécessaires pendant l'opération asynchrone.
|
||||
*
|
||||
* Le dialogue GTK ne se termine pas immédiatement. Ce contexte permet donc
|
||||
* de conserver le callback et ses données jusqu'à la fermeture du dialogue.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
FolderDialogCallback callback;
|
||||
gpointer user_data;
|
||||
} FolderDialogContext;
|
||||
|
||||
/**
|
||||
* @brief Libère le contexte associé au dialogue.
|
||||
*
|
||||
* @param context Contexte à libérer.
|
||||
*/
|
||||
static void folder_dialog_context_free(FolderDialogContext *context)
|
||||
{
|
||||
g_free(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Traite le résultat de la sélection du dossier.
|
||||
*
|
||||
* @param source_object Objet ayant lancé l'opération asynchrone.
|
||||
* @param result Résultat transmis par GTK.
|
||||
* @param user_data Contexte du dialogue.
|
||||
*/
|
||||
static void folder_dialog_on_folder_selected(
|
||||
GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
GtkFileDialog *dialog = GTK_FILE_DIALOG(source_object);
|
||||
FolderDialogContext *context = user_data;
|
||||
GError *error = NULL;
|
||||
GFile *folder = NULL;
|
||||
char *folder_path = NULL;
|
||||
|
||||
folder = gtk_file_dialog_select_folder_finish(dialog, result, &error);
|
||||
|
||||
if (folder == NULL)
|
||||
{
|
||||
/*
|
||||
* Une annulation est un comportement normal de l'utilisateur.
|
||||
* Elle est transmise au code appelant sous la forme d'un chemin NULL.
|
||||
*/
|
||||
if (error != NULL &&
|
||||
!g_error_matches(error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_DISMISSED))
|
||||
{
|
||||
g_warning(
|
||||
"Impossible de sélectionner le dossier : %s",
|
||||
error->message
|
||||
);
|
||||
}
|
||||
|
||||
if (context->callback != NULL)
|
||||
{
|
||||
context->callback(NULL, context->user_data);
|
||||
}
|
||||
|
||||
g_clear_error(&error);
|
||||
folder_dialog_context_free(context);
|
||||
return;
|
||||
}
|
||||
|
||||
folder_path = g_file_get_path(folder);
|
||||
|
||||
if (context->callback != NULL)
|
||||
{
|
||||
context->callback(folder_path, context->user_data);
|
||||
}
|
||||
|
||||
g_free(folder_path);
|
||||
g_object_unref(folder);
|
||||
folder_dialog_context_free(context);
|
||||
}
|
||||
|
||||
void folder_dialog_select_folder(
|
||||
GtkWindow *parent,
|
||||
FolderDialogCallback callback,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
GtkFileDialog *dialog = NULL;
|
||||
FolderDialogContext *context = NULL;
|
||||
|
||||
context = g_new0(FolderDialogContext, 1);
|
||||
context->callback = callback;
|
||||
context->user_data = user_data;
|
||||
|
||||
dialog = gtk_file_dialog_new();
|
||||
|
||||
gtk_file_dialog_set_title(
|
||||
dialog,
|
||||
"Sélectionner un dossier d'enquête"
|
||||
);
|
||||
|
||||
gtk_file_dialog_set_modal(dialog, TRUE);
|
||||
|
||||
gtk_file_dialog_select_folder(
|
||||
dialog,
|
||||
parent,
|
||||
NULL,
|
||||
folder_dialog_on_folder_selected,
|
||||
context
|
||||
);
|
||||
|
||||
g_object_unref(dialog);
|
||||
}
|
||||
Loading…
Reference in a new issue