301 lines
6.3 KiB
Markdown
301 lines
6.3 KiB
Markdown
# Ticket #031 — Ouvrir une enquête existante depuis GTK
|
||
|
||
## Contexte
|
||
|
||
Les tickets #029 et #030 ont permis de :
|
||
|
||
- créer une enquête depuis GTK ;
|
||
- initialiser son arborescence et sa base SQLite ;
|
||
- ouvrir une `InvestigationSession` ;
|
||
- construire le `InvestigationTreeModel` ;
|
||
- installer la session dans `Application` ;
|
||
- afficher le nom et le chemin de l’enquête dans `MainWindow`.
|
||
|
||
L’application ne permet cependant pas encore d’ouvrir explicitement une enquête existante.
|
||
|
||
L’ancien sélecteur automatique au démarrage a été supprimé afin de ne pas forcer l’utilisateur à choisir un dossier à chaque lancement.
|
||
|
||
## Objectif
|
||
|
||
Ajouter un bouton :
|
||
|
||
```text
|
||
Ouvrir une enquête
|
||
```
|
||
|
||
Ce bouton doit permettre de sélectionner le dossier racine d’une enquête existante, puis de l’ouvrir avec le flux déjà présent :
|
||
|
||
```text
|
||
FolderDialog
|
||
↓
|
||
investigation_session_open()
|
||
↓
|
||
investigation_tree_builder_build()
|
||
↓
|
||
application_install_session()
|
||
↓
|
||
MainWindow mise à jour
|
||
```
|
||
|
||
La logique d’installation d’une session ne doit pas être dupliquée.
|
||
|
||
## Travail à réaliser
|
||
|
||
### 1. Ajouter le bouton dans `MainWindow`
|
||
|
||
Modifier :
|
||
|
||
```text
|
||
include/views/main_window.h
|
||
src/views/main_window.c
|
||
```
|
||
|
||
Ajouter un bouton visible dans la barre d’actions :
|
||
|
||
```text
|
||
Ouvrir une enquête
|
||
```
|
||
|
||
La barre doit contenir au minimum :
|
||
|
||
```text
|
||
[ Nouvelle enquête ] [ Ouvrir une enquête ]
|
||
```
|
||
|
||
Ajouter dans la structure privée :
|
||
|
||
```c
|
||
GtkWidget *open_investigation_button;
|
||
```
|
||
|
||
### 2. Ajouter le type de callback
|
||
|
||
Dans `include/views/main_window.h`, ajouter :
|
||
|
||
```c
|
||
typedef void (*MainWindowOpenInvestigationCallback)(
|
||
gpointer user_data
|
||
);
|
||
```
|
||
|
||
Puis déclarer :
|
||
|
||
```c
|
||
void main_window_set_open_investigation_callback(
|
||
MainWindow *main_window,
|
||
MainWindowOpenInvestigationCallback callback,
|
||
gpointer user_data
|
||
);
|
||
```
|
||
|
||
### 3. Conserver le callback dans `MainWindow`
|
||
|
||
Ajouter dans la structure privée :
|
||
|
||
```c
|
||
MainWindowOpenInvestigationCallback
|
||
open_investigation_callback;
|
||
|
||
gpointer
|
||
open_investigation_user_data;
|
||
```
|
||
|
||
Ajouter un callback privé :
|
||
|
||
```c
|
||
static void main_window_on_open_investigation_clicked(
|
||
GtkButton *button,
|
||
gpointer user_data
|
||
);
|
||
```
|
||
|
||
Il doit appeler le callback configuré uniquement s’il existe.
|
||
|
||
`MainWindow` ne doit pas ouvrir elle-même la session.
|
||
|
||
### 4. Relier le bouton à `Application`
|
||
|
||
Dans `src/core/application.c`, réactiver l’utilisation de :
|
||
|
||
```c
|
||
#include "views/folder_dialog.h"
|
||
```
|
||
|
||
Ajouter :
|
||
|
||
```c
|
||
static void application_on_open_investigation_requested(
|
||
gpointer user_data
|
||
);
|
||
```
|
||
|
||
Cette fonction doit ouvrir le sélecteur avec :
|
||
|
||
```c
|
||
folder_dialog_select_folder(
|
||
main_window_get_window(application->main_window),
|
||
application_on_folder_selected,
|
||
application
|
||
);
|
||
```
|
||
|
||
### 5. Réutiliser `application_on_folder_selected()`
|
||
|
||
La fonction doit :
|
||
|
||
1. accepter l’annulation ;
|
||
2. ouvrir la session avec `investigation_session_open()` ;
|
||
3. récupérer le chemin racine depuis `InvestigationProject` ;
|
||
4. construire l’arbre avec `investigation_tree_builder_build()` ;
|
||
5. installer les objets avec `application_install_session()`.
|
||
|
||
En cas d’échec :
|
||
|
||
```text
|
||
ancienne session conservée
|
||
ancien arbre conservé
|
||
nouvelle session libérée
|
||
nouvel arbre libéré
|
||
warning explicite
|
||
```
|
||
|
||
### 6. Enregistrer le callback dans `application_on_activate()`
|
||
|
||
Après la création de `MainWindow`, appeler :
|
||
|
||
```c
|
||
main_window_set_open_investigation_callback(
|
||
application->main_window,
|
||
application_on_open_investigation_requested,
|
||
application
|
||
);
|
||
```
|
||
|
||
Le sélecteur ne doit pas être lancé automatiquement au démarrage.
|
||
|
||
## Tests manuels
|
||
|
||
### Ouverture valide
|
||
|
||
1. lancer l’application ;
|
||
2. cliquer sur `Ouvrir une enquête` ;
|
||
3. sélectionner une enquête créée avec le ticket #030 ;
|
||
4. vérifier l’affichage de l’arborescence ;
|
||
5. vérifier le titre ;
|
||
6. vérifier la barre d’état ;
|
||
7. vérifier l’absence d’erreur SQLite.
|
||
|
||
### Annulation
|
||
|
||
Ouvrir le sélecteur puis annuler.
|
||
|
||
Vérifier :
|
||
|
||
```text
|
||
aucun crash
|
||
aucun changement de session
|
||
aucun changement d’arbre
|
||
```
|
||
|
||
### Dossier invalide
|
||
|
||
Sélectionner un dossier sans base SQLite.
|
||
|
||
Vérifier :
|
||
|
||
```text
|
||
warning explicite
|
||
aucune base créée
|
||
ancienne session conservée
|
||
```
|
||
|
||
### Remplacement
|
||
|
||
1. ouvrir une enquête A ;
|
||
2. ouvrir une enquête B ;
|
||
3. vérifier que B remplace A.
|
||
|
||
### Échec pendant le remplacement
|
||
|
||
1. ouvrir une enquête valide A ;
|
||
2. tenter d’ouvrir un dossier invalide ;
|
||
3. vérifier que A reste active.
|
||
|
||
## Critères d’acceptation
|
||
|
||
- [ ] Le bouton `Ouvrir une enquête` est visible.
|
||
- [ ] Le bouton ouvre un sélecteur de dossier.
|
||
- [ ] Le sélecteur ne s’ouvre pas automatiquement au démarrage.
|
||
- [ ] Une enquête valide peut être ouverte.
|
||
- [ ] L’arborescence est affichée.
|
||
- [ ] Le titre est mis à jour.
|
||
- [ ] La barre d’état est mise à jour.
|
||
- [ ] L’annulation ne modifie aucun état.
|
||
- [ ] Un dossier invalide est refusé.
|
||
- [ ] Une base absente n’est pas créée.
|
||
- [ ] L’ancienne session reste active en cas d’échec.
|
||
- [ ] L’ancien arbre reste actif en cas d’échec.
|
||
- [ ] `application_install_session()` est réutilisée.
|
||
- [ ] Aucun appel SQLite direct n’est ajouté.
|
||
- [ ] `make` réussit.
|
||
- [ ] `make test` réussit.
|
||
- [ ] `git diff --check` ne retourne aucune erreur.
|
||
|
||
## Audit attendu
|
||
|
||
```bash
|
||
rg -n 'open_investigation|Ouvrir une enquête' include/views/main_window.h src/views/main_window.c src/core/application.c
|
||
```
|
||
|
||
```bash
|
||
rg -n 'folder_dialog_select_folder' src/core/application.c
|
||
```
|
||
|
||
```bash
|
||
rg -n 'sqlite3_|#include <sqlite3.h>' src/core/application.c src/views/main_window.c
|
||
```
|
||
|
||
Résultat attendu pour la dernière commande :
|
||
|
||
```text
|
||
aucune sortie
|
||
```
|
||
|
||
## Fichiers principalement concernés
|
||
|
||
```text
|
||
include/views/main_window.h
|
||
src/views/main_window.c
|
||
src/core/application.c
|
||
```
|
||
|
||
## Résultat attendu
|
||
|
||
À la fin du ticket, l’application doit proposer deux actions explicites :
|
||
|
||
```text
|
||
Nouvelle enquête
|
||
Ouvrir une enquête
|
||
```
|
||
|
||
L’utilisateur doit pouvoir créer une enquête, fermer l’application, puis la rouvrir plus tard depuis GTK.
|
||
|
||
## Commit attendu
|
||
|
||
```bash
|
||
make clean
|
||
make
|
||
make test
|
||
git diff --check
|
||
git status --short
|
||
```
|
||
|
||
```bash
|
||
git add include/views/main_window.h src/views/main_window.c src/core/application.c
|
||
```
|
||
|
||
```bash
|
||
git commit -m "feat(ui): add investigation opening action"
|
||
git push
|
||
```
|
||
|