fix(gui): rendre les profils lisibles sous windows

This commit is contained in:
2026-06-17 23:01:27 +02:00
parent ea1752d4a7
commit 19c4934de3
2 changed files with 36 additions and 31 deletions

View File

@@ -224,6 +224,7 @@ class ConfigTab(ctk.CTkFrame):
self._profiles_path = None
self._pro_edit_key: str | None = None
self._pro_term_lists: dict = {}
self._profile_scroll = None
self._build()
@@ -491,10 +492,10 @@ class ConfigTab(ctk.CTkFrame):
p = self._p
from gui_v6.editable_list import EditableTermList
content = ctk.CTkScrollableFrame(parent, fg_color="transparent")
content.pack(fill="both", expand=True)
self._profile_scroll = content
parent = content
# L'application fournit déjà un scroll vertical global. Un second
# CTkScrollableFrame imbriqué coupe la page Profils sous Windows et
# laisse un grand bloc vide en bas de fenêtre.
self._profile_scroll = None
self._section_intro(
parent,
@@ -547,8 +548,25 @@ class ConfigTab(ctk.CTkFrame):
ctk.CTkLabel(ident, text="Description", text_color=p["text_muted"], font=ui_kit.font(11), anchor="w").pack(fill="x", padx=12, pady=(0, 2))
self._pro_desc_entry.pack(fill="x", padx=12, pady=(0, 12))
eng = ui_kit.Card(
right, p, title="🧠 Moteurs",
help_text=_HELP_PROFIL_MOTEURS, help_title="Moteurs du profil",
)
eng.pack(fill="x", pady=(0, 8))
self._pro_disable_vlm_var = ctk.BooleanVar(value=False)
self._pro_vlm_switch = ctk.CTkSwitch(eng, text="Désactiver le moteur VLM (images)", variable=self._pro_disable_vlm_var, progress_color=p["primary"], text_color=p["text"], font=ui_kit.font(12))
self._pro_vlm_switch.pack(anchor="w", padx=12, pady=(0, 6))
# Note honnête : reflète les moteurs réellement embarqués par ce build.
caps_pro = engine_capabilities.capabilities_map()
opt = [c.label.split(" (")[0] for c in (caps_pro["eds"], caps_pro["gliner"]) if c.available]
if opt:
moteurs_note = "CamemBERT-bio (standard) toujours actif ; " + " / ".join(opt) + " disponibles (optionnels)."
else:
moteurs_note = "CamemBERT-bio (standard) toujours actif ; EDS-Pseudo / GLiNER non embarqués dans cette version."
ctk.CTkLabel(eng, text=moteurs_note, text_color=p["text_muted"], font=ui_kit.font(11), anchor="w", wraplength=300, justify="left").pack(fill="x", padx=12, pady=(0, 12))
mask = ui_kit.Card(
left, p, title="⬛ Masquage",
right, p, title="⬛ Masquage",
help_text=_HELP_PROFIL_MASQUAGE, help_title="Masquage manuel",
)
mask.pack(fill="x", pady=(0, 8))
@@ -591,32 +609,15 @@ class ConfigTab(ctk.CTkFrame):
variable=self._mask_rounded_var, command=self._on_rounded_corners,
).pack(fill="x", padx=12, pady=(2, 12))
eng = ui_kit.Card(
left, p, title="🧠 Moteurs",
help_text=_HELP_PROFIL_MOTEURS, help_title="Moteurs du profil",
)
eng.pack(fill="x")
self._pro_disable_vlm_var = ctk.BooleanVar(value=False)
self._pro_vlm_switch = ctk.CTkSwitch(eng, text="Désactiver le moteur VLM (images)", variable=self._pro_disable_vlm_var, progress_color=p["primary"], text_color=p["text"], font=ui_kit.font(12))
self._pro_vlm_switch.pack(anchor="w", padx=12, pady=(0, 6))
# Note honnête : reflète les moteurs réellement embarqués par ce build.
caps_pro = engine_capabilities.capabilities_map()
opt = [c.label.split(" (")[0] for c in (caps_pro["eds"], caps_pro["gliner"]) if c.available]
if opt:
moteurs_note = "CamemBERT-bio (standard) toujours actif ; " + " / ".join(opt) + " disponibles (optionnels)."
else:
moteurs_note = "CamemBERT-bio (standard) toujours actif ; EDS-Pseudo / GLiNER non embarqués dans cette version."
ctk.CTkLabel(eng, text=moteurs_note, text_color=p["text_muted"], font=ui_kit.font(11), anchor="w", wraplength=300, justify="left").pack(fill="x", padx=12, pady=(0, 12))
words = ui_kit.Card(
right, p, title="📝 Mots du profil",
parent, p, title="📝 Mots du profil",
help_text=_HELP_PROFIL_MOTS, help_title="Mots du profil",
)
words.pack(fill="both", expand=True)
words.pack(fill="x", pady=(8, 0))
self._pro_term_lists = {
"blacklist": EditableTermList(words, p, title="À masquer", height=104),
"whitelist": EditableTermList(words, p, title="À conserver", height=104),
"stopwords": EditableTermList(words, p, title="À ignorer", height=88),
"blacklist": EditableTermList(words, p, title="À masquer", height=78),
"whitelist": EditableTermList(words, p, title="À conserver", height=78),
"stopwords": EditableTermList(words, p, title="À ignorer", height=66),
}
for tl in self._pro_term_lists.values():
tl.pack(fill="x", padx=12, pady=(0, 8))

View File

@@ -162,8 +162,8 @@ def test_profils_editor_creates_and_persists(ctk_root, tmp_path, monkeypatch):
tab.destroy()
def test_profils_panel_has_dedicated_mouse_scroll(ctk_root, tmp_path, monkeypatch):
"""Retour Dom : le formulaire Profils doit pouvoir défiler à la molette."""
def test_profils_panel_uses_outer_scroll_without_nested_scroll(ctk_root, tmp_path, monkeypatch):
"""Retour Dom : le formulaire Profils ne doit pas être coupé par un scroll imbriqué."""
import customtkinter as ctk
from gui_v6.tabs import tab_config
@@ -173,8 +173,12 @@ def test_profils_panel_has_dedicated_mouse_scroll(ctk_root, tmp_path, monkeypatc
tab._show_sub("pro")
tab.update_idletasks()
assert isinstance(tab._profile_scroll, ctk.CTkScrollableFrame)
assert hasattr(tab._profile_scroll, "_parent_canvas")
assert tab._profile_scroll is None
assert not any(isinstance(child, ctk.CTkScrollableFrame) for child in tab._panels["pro"].winfo_children())
texts = " | ".join(_all_texts(tab._panels["pro"]))
assert "Masque manuel obligatoire" in texts
assert "Désactiver le moteur VLM" in texts
assert "Règles d'anonymisation portées par ce profil" in texts
tab.destroy()