feat(gui): add GUI V6 G2 — onglet Utilisation + runner injectable

Onglet Utilisation fonctionnel (couche présentation only) :
- processing_runner: runner testable sans display/moteur lourd, process_fn
  injectable (défaut = process_document en import paresseux), découverte
  fichier/dossier, sorties anonymise/ comme V5 (arbo préservée), progression,
  journal, résumé OK/KO, arrêt coopératif entre documents, anti double-lancement
- tabs/tab_usage: sélection fichier/dossier + nb PDF détectés, dossier sortie
  (défaut anonymise/), Lancer/Arrêter, barre de progression, statut, journal,
  résumé ; worker threadé, file d'événements drainée par after() ; aucun réseau
- app.py: onglet Utilisation câblé (placeholder G2 retiré)
- self-test: couvre processing_runner + tab_usage

Tests: +11 (runner) — discovery, sorties, échec partiel, arrêt, anti-double-run,
callbacks. self-test exit 0, 32 tests gui_v6, 179 tests/unit (0 régression).
Moteur/V5/managers/specs intacts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 18:58:10 +02:00
parent d265cd3269
commit c2c40543e5
5 changed files with 534 additions and 7 deletions

View File

@@ -17,6 +17,7 @@ import customtkinter as ctk
from gui_v6 import theme as theme_mod
from gui_v6.license_client import LicenseClient, LicenseStatus
from gui_v6.tabs.tab_about import AboutTab
from gui_v6.tabs.tab_usage import UsageTab
_TABS = ("Utilisation", "Configuration", "À propos")
@@ -77,16 +78,15 @@ class AnonymisationApp(ctk.CTk):
for name in _TABS:
tabview.add(name)
self._usage = UsageTab(tabview.tab("Utilisation"))
self._usage.pack(fill="both", expand=True)
self._about = AboutTab(
tabview.tab("À propos"), status=status, theme_name=self._theme_name
)
self._about.pack(fill="both", expand=True)
# Placeholders G2/G3.
ctk.CTkLabel(
tabview.tab("Utilisation"),
text="Onglet Utilisation — disponible au lot G2.",
).pack(padx=16, pady=16, anchor="w")
# Placeholder G3.
ctk.CTkLabel(
tabview.tab("Configuration"),
text="Onglet Configuration — disponible au lot G3.",