plugin_animation/dialog_saisie.py
2026-04-27 15:40:40 +02:00

719 lines
29 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
from datetime import date
from qgis.PyQt.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QFormLayout,
QLabel, QLineEdit, QPushButton, QMessageBox, QComboBox,
QDateEdit, QSpinBox, QCheckBox, QScrollArea, QWidget,
QListWidget, QListWidgetItem, QInputDialog, QSizePolicy,
QFrame, QGroupBox
)
from qgis.PyQt.QtCore import Qt, QDate
from qgis.PyQt.QtGui import QFont, QColor
from qgis.core import QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsProject
from qgis.utils import iface
from .map_point_tool import PointCaptureTool
# ---------------------------------------------------------------------------
# Widgets utilitaires
# ---------------------------------------------------------------------------
class ComboWithAdd(QWidget):
def __init__(self, add_callback, parent=None):
super().__init__(parent)
self._add_callback = add_callback
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
self.combo = QComboBox()
self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.btn_add = QPushButton("+")
self.btn_add.setFixedWidth(30)
self.btn_add.setToolTip("Ajouter un nouvel élément")
self.btn_add.clicked.connect(lambda: self._add_callback(self))
layout.addWidget(self.combo)
layout.addWidget(self.btn_add)
def current_data(self):
return self.combo.currentData()
def current_text(self):
return self.combo.currentText()
def populate(self, items, placeholder=None):
self.combo.clear()
if placeholder:
self.combo.addItem(placeholder, None)
for code, label in items:
self.combo.addItem(label, code)
def add_item(self, code, label):
self.combo.addItem(label, code)
self.combo.setCurrentIndex(self.combo.count() - 1)
def set_by_text(self, text):
idx = self.combo.findText(text)
if idx >= 0:
self.combo.setCurrentIndex(idx)
def set_by_data(self, data):
idx = self.combo.findData(data)
if idx >= 0:
self.combo.setCurrentIndex(idx)
class AnimateursWidget(QWidget):
def __init__(self, db, parent=None):
super().__init__(parent)
self.db = db
layout = QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
self.list_widget = QListWidget()
self.list_widget.setMaximumHeight(90)
layout.addWidget(self.list_widget)
btn_layout = QHBoxLayout()
self.combo = QComboBox()
self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
btn_add = QPushButton("Ajouter")
btn_add.clicked.connect(self._add_existing)
btn_new = QPushButton("+ Nouveau")
btn_new.clicked.connect(self._add_new)
btn_remove = QPushButton("Retirer")
btn_remove.clicked.connect(self._remove_selected)
btn_layout.addWidget(self.combo)
btn_layout.addWidget(btn_add)
btn_layout.addWidget(btn_new)
btn_layout.addWidget(btn_remove)
layout.addLayout(btn_layout)
self.load_animateurs()
def load_animateurs(self):
self.combo.clear()
for code, nom in self.db.get_animateurs():
self.combo.addItem(nom, code)
def _add_existing(self):
code = self.combo.currentData()
nom = self.combo.currentText()
if code is None:
return
for i in range(self.list_widget.count()):
if self.list_widget.item(i).data(Qt.UserRole) == code:
return
item = QListWidgetItem(nom)
item.setData(Qt.UserRole, code)
self.list_widget.addItem(item)
def _add_new(self):
nom, ok = QInputDialog.getText(self, "Nouvel animateur", "Nom :")
if ok and nom.strip():
try:
code, label = self.db.add_animateur(nom.strip())
self.combo.addItem(label, code)
item = QListWidgetItem(label)
item.setData(Qt.UserRole, code)
self.list_widget.addItem(item)
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def _remove_selected(self):
for item in self.list_widget.selectedItems():
self.list_widget.takeItem(self.list_widget.row(item))
def get_value(self):
result = []
for i in range(self.list_widget.count()):
item = self.list_widget.item(i)
result.append({"code": item.data(Qt.UserRole), "nom": item.text()})
return json.dumps(result, ensure_ascii=False) if result else None
def set_value(self, json_str):
self.list_widget.clear()
if not json_str:
return
try:
data = json.loads(json_str) if isinstance(json_str, str) else json_str
for entry in data:
item = QListWidgetItem(entry.get("nom", ""))
item.setData(Qt.UserRole, entry.get("code"))
self.list_widget.addItem(item)
except Exception:
pass
# ---------------------------------------------------------------------------
# Dialogue principal
# ---------------------------------------------------------------------------
class SaisieDialog(QDialog):
def __init__(self, db, parent=None):
super().__init__(parent)
self.db = db
self._etab_map = {} # code -> (nom, commune)
self._edit_mode = False # True = on édite une animation existante
self._edit_code = None # code_animation en cours d'édition
self._pending_geom = None # (x, y, crs) en attente pour ajout lieu/etab
self._pending_geom_type = None # 'lieu' ou 'etab'
self._point_tool = None
self.setWindowTitle("Animation Saisie / Édition")
self.setMinimumWidth(720)
self.setMinimumHeight(820)
self._build_ui()
self._load_reference_data()
# -----------------------------------------------------------------------
# Construction UI
# -----------------------------------------------------------------------
def _build_ui(self):
main_layout = QVBoxLayout(self)
main_layout.setSpacing(6)
# --- Bandeau titre ---
self.title_label = QLabel("<h2>Nouvelle animation</h2>")
self.title_label.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.title_label)
# --- Sélecteur d'animation existante ---
grp_sel = QGroupBox("Charger / modifier une animation existante")
sel_layout = QHBoxLayout(grp_sel)
self.anim_combo = QComboBox()
self.anim_combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.anim_combo.setPlaceholderText("── Nouvelle saisie ──")
self.anim_combo.addItem("── Nouvelle saisie ──", None)
self.anim_combo.currentIndexChanged.connect(self._on_anim_selected)
sel_layout.addWidget(QLabel("Animation :"))
sel_layout.addWidget(self.anim_combo)
btn_refresh = QPushButton("🔄")
btn_refresh.setFixedWidth(32)
btn_refresh.setToolTip("Rafraîchir la liste")
btn_refresh.clicked.connect(self._reload_animations_list)
sel_layout.addWidget(btn_refresh)
main_layout.addWidget(grp_sel)
# --- Zone scrollable du formulaire ---
scroll = QScrollArea()
scroll.setWidgetResizable(True)
container = QWidget()
self.fl = QFormLayout(container)
self.fl.setLabelAlignment(Qt.AlignRight)
self.fl.setSpacing(8)
scroll.setWidget(container)
main_layout.addWidget(scroll)
fl = self.fl
# ---- Date & Durée ----
self._section(fl, "Date et durée")
self.date_edit = QDateEdit(QDate.currentDate())
self.date_edit.setCalendarPopup(True)
self.date_edit.setDisplayFormat("dd/MM/yyyy")
fl.addRow("Date *:", self.date_edit)
dur_w = QWidget()
dur_l = QHBoxLayout(dur_w)
dur_l.setContentsMargins(0, 0, 0, 0)
self.duree_h = QSpinBox()
self.duree_h.setRange(0, 24)
self.duree_h.setSuffix(" h")
self.duree_min = QSpinBox()
self.duree_min.setRange(0, 59)
self.duree_min.setSuffix(" min")
dur_l.addWidget(self.duree_h)
dur_l.addWidget(self.duree_min)
dur_l.addStretch()
fl.addRow("Durée :", dur_w)
self.prepa_spin = QSpinBox()
self.prepa_spin.setRange(0, 9999)
self.prepa_spin.setSuffix(" min")
for w in (self.duree_h, self.duree_min, self.prepa_spin):
w.valueChanged.connect(self._update_temps_total)
fl.addRow("Prépa / déplacement :", self.prepa_spin)
self.temps_total_label = QLabel("0 min")
fl.addRow("Temps total (calculé) :", self.temps_total_label)
# ---- Animateurs ----
self._sep(fl)
self._section(fl, "Animateurs")
self.animateurs_widget = AnimateursWidget(self.db)
fl.addRow("Animateurs :", self.animateurs_widget)
# ---- Groupe ----
self._sep(fl)
self._section(fl, "Groupe")
self.type_groupe_combo = ComboWithAdd(self._add_type_groupe)
fl.addRow("Type de groupe :", self.type_groupe_combo)
self.precisions_groupe_edit = QLineEdit()
fl.addRow("Précisions groupe :", self.precisions_groupe_edit)
# ---- Établissement ----
self._sep(fl)
self._section(fl, "Établissement / Provenance")
self.etab_combo = ComboWithAdd(self._add_etablissement)
self.etab_combo.combo.currentIndexChanged.connect(self._on_etab_changed)
fl.addRow("Établissement :", self.etab_combo)
self.commune_label = QLabel("")
self.commune_label.setStyleSheet("color:#555; font-style:italic;")
fl.addRow("Commune (auto) :", self.commune_label)
# ---- Participants ----
self._sep(fl)
self._section(fl, "Participants")
self.enfants_spin = QSpinBox()
self.enfants_spin.setRange(0, 9999)
self.enfants_spin.valueChanged.connect(self._update_total_pers)
fl.addRow("Enfants :", self.enfants_spin)
self.adultes_spin = QSpinBox()
self.adultes_spin.setRange(0, 9999)
self.adultes_spin.valueChanged.connect(self._update_total_pers)
fl.addRow("Adultes :", self.adultes_spin)
self.total_pers_label = QLabel("0")
fl.addRow("Total (calculé) :", self.total_pers_label)
# ---- Lieu ----
self._sep(fl)
self._section(fl, "Lieu")
self.lieux_combo = ComboWithAdd(self._add_lieu)
fl.addRow("Lieu :", self.lieux_combo)
self.precisions_lieux_edit = QLineEdit()
fl.addRow("Précisions lieu :", self.precisions_lieux_edit)
self.accueil_pin_check = QCheckBox("Oui")
fl.addRow("Accueil PIN :", self.accueil_pin_check)
# ---- Thème ----
self._sep(fl)
self._section(fl, "Thème")
self.theme_combo = ComboWithAdd(self._add_theme)
fl.addRow("Thème :", self.theme_combo)
self.theme_detaille_edit = QLineEdit()
fl.addRow("Thème détaillé :", self.theme_detaille_edit)
# ---- Statuts ----
self._sep(fl)
self._section(fl, "Statuts")
self.payant_check = QCheckBox("Oui")
fl.addRow("Payant :", self.payant_check)
self.annul_combo = ComboWithAdd(self._add_annulation)
fl.addRow("Annulation :", self.annul_combo)
self.dossier_combo = ComboWithAdd(self._add_dossier)
fl.addRow("Dossier enseignant :", self.dossier_combo)
self.tiers_check = QCheckBox("Oui")
self.tiers_check.stateChanged.connect(self._on_tiers_changed)
fl.addRow("Réalisé par tiers :", self.tiers_check)
self.detail_tiers_edit = QLineEdit()
self.detail_tiers_edit.setEnabled(False)
fl.addRow("Détail tiers :", self.detail_tiers_edit)
# ---- Remarques ----
self._sep(fl)
self.remarques_edit = QLineEdit()
fl.addRow("Remarques :", self.remarques_edit)
# --- Boutons d'action ---
btn_layout = QHBoxLayout()
btn_cancel = QPushButton("Fermer")
btn_cancel.clicked.connect(self.reject)
self.btn_new_form = QPushButton("✚ Nouveau")
self.btn_new_form.setToolTip("Réinitialiser pour une nouvelle saisie")
self.btn_new_form.clicked.connect(self._new_form)
self.btn_save_new = QPushButton("Enregistrer et nouveau")
self.btn_save_new.clicked.connect(self._save_and_new)
self.btn_save = QPushButton("Enregistrer")
self.btn_save.setDefault(True)
self.btn_save.clicked.connect(self._save)
btn_layout.addWidget(btn_cancel)
btn_layout.addWidget(self.btn_new_form)
btn_layout.addStretch()
btn_layout.addWidget(self.btn_save_new)
btn_layout.addWidget(self.btn_save)
main_layout.addLayout(btn_layout)
def _section(self, fl, title):
lbl = QLabel(f"<b>{title}</b>")
fl.addRow(lbl)
def _sep(self, fl):
line = QFrame()
line.setFrameShape(QFrame.HLine)
line.setStyleSheet("color:#ccc;")
fl.addRow(line)
# -----------------------------------------------------------------------
# Chargement données de référence
# -----------------------------------------------------------------------
def _load_reference_data(self):
try:
self.type_groupe_combo.populate(self.db.get_types_groupe(), "-- Sélectionner --")
etabs = self.db.get_etablissements()
self._etab_map = {c: (n, com) for c, n, com in etabs}
self.etab_combo.populate(
[(c, f"{n} ({com})" if com else n) for c, n, com in etabs],
"-- Sélectionner --"
)
self.lieux_combo.populate(self.db.get_lieux(), "-- Sélectionner --")
self.theme_combo.populate(self.db.get_themes(), "-- Sélectionner --")
self.annul_combo.populate(self.db.get_codes_annulation(), "Non")
self._set_default(self.annul_combo, "Non")
self.dossier_combo.populate(self.db.get_type_dossier_ens(), "Non")
self._set_default(self.dossier_combo, "Non")
self._reload_animations_list()
except Exception as e:
QMessageBox.critical(self, "Erreur chargement", str(e))
def _set_default(self, combo_widget, text):
idx = combo_widget.combo.findText(text)
if idx >= 0:
combo_widget.combo.setCurrentIndex(idx)
def _reload_animations_list(self):
self.anim_combo.blockSignals(True)
self.anim_combo.clear()
self.anim_combo.addItem("── Nouvelle saisie ──", None)
try:
rows = self.db.get_all_animations()
for code, date_anim, lieux, theme in rows:
date_str = date_anim.strftime("%d/%m/%Y") if date_anim else "?"
lieux_str = lieux or "Lieu ?"
theme_str = theme or "Thème ?"
label = f"{date_str} | {lieux_str} | {theme_str} [#{code}]"
self.anim_combo.addItem(label, code)
except Exception as e:
QMessageBox.warning(self, "Erreur", f"Impossible de charger les animations : {e}")
self.anim_combo.blockSignals(False)
# -----------------------------------------------------------------------
# Événements
# -----------------------------------------------------------------------
def _on_anim_selected(self, idx):
code = self.anim_combo.itemData(idx)
if code is None:
self._new_form()
return
try:
data = self.db.get_animation_by_id(code)
if data:
self._edit_mode = True
self._edit_code = code
self.title_label.setText(f"<h2>Édition animation #{code}</h2>")
self.btn_save.setText("Mettre à jour")
self.btn_save_new.setVisible(False)
self._populate_form(data)
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def _populate_form(self, data):
"""Remplit le formulaire avec les données d'une animation existante."""
if data.get('date_anim'):
d = data['date_anim']
self.date_edit.setDate(QDate(d.year, d.month, d.day))
duree = data.get('duree_anim', '0h00') or '0h00'
try:
if 'h' in duree:
h, m = duree.split('h')
self.duree_h.setValue(int(h))
self.duree_min.setValue(int(m) if m else 0)
except Exception:
pass
self.prepa_spin.setValue(data.get('prepa_deplacemt') or 0)
self.animateurs_widget.set_value(data.get('animateurs'))
self.type_groupe_combo.set_by_data(data.get('code_groupe'))
self.precisions_groupe_edit.setText(data.get('precisions_type_de_groupe') or '')
# Établissement : chercher par nom
nom_etab = data.get('nom_etablissement') or ''
for code, (nom, com) in self._etab_map.items():
if nom == nom_etab:
self.etab_combo.set_by_data(code)
break
self.enfants_spin.setValue(data.get('nbre_pers_enfants') or 0)
self.adultes_spin.setValue(data.get('nbre_pers_adultes') or 0)
self.lieux_combo.set_by_text(data.get('lieux') or '')
self.precisions_lieux_edit.setText(data.get('precisions_lieux_anim') or '')
self.accueil_pin_check.setChecked(bool(data.get('accueil_pin')))
self.theme_detaille_edit.setText(data.get('theme_detaille') or '')
self.theme_combo.set_by_data(data.get('code_type_anim'))
self.payant_check.setChecked(bool(data.get('payant')))
self.annul_combo.set_by_text(data.get('type_annul') or 'Non')
self.remarques_edit.setText(data.get('remarques') or '')
self.dossier_combo.set_by_text(data.get('type_dossier_ens') or 'Non')
realise = bool(data.get('realise_par_tiers'))
self.tiers_check.setChecked(realise)
self.detail_tiers_edit.setText(data.get('detail_tiers') or '')
self.detail_tiers_edit.setEnabled(realise)
def _new_form(self):
self._edit_mode = False
self._edit_code = None
self.title_label.setText("<h2>Nouvelle animation</h2>")
self.btn_save.setText("Enregistrer")
self.btn_save_new.setVisible(True)
self.anim_combo.blockSignals(True)
self.anim_combo.setCurrentIndex(0)
self.anim_combo.blockSignals(False)
self._reset_form()
def _on_etab_changed(self, idx):
code = self.etab_combo.combo.itemData(idx)
if code and code in self._etab_map:
self.commune_label.setText(self._etab_map[code][1] or "")
else:
self.commune_label.setText("")
def _on_tiers_changed(self, state):
self.detail_tiers_edit.setEnabled(state == Qt.Checked)
def _update_temps_total(self):
total = self.duree_h.value() * 60 + self.duree_min.value() + self.prepa_spin.value()
self.temps_total_label.setText(f"{total} min")
def _update_total_pers(self):
self.total_pers_label.setText(str(self.enfants_spin.value() + self.adultes_spin.value()))
# -----------------------------------------------------------------------
# Capture géométrie sur carte
# -----------------------------------------------------------------------
def _start_point_capture(self, geom_type, on_captured_callback):
"""
Lance l'outil de clic sur la carte. geom_type = 'lieu' ou 'etab'.
Après le clic, appelle on_captured_callback(wkt, srid).
"""
canvas = iface.mapCanvas()
if not canvas:
QMessageBox.warning(self, "Erreur", "Impossible d'accéder à la carte QGIS.")
return
prev_tool = canvas.mapTool()
tool = PointCaptureTool(canvas, prev_tool)
def on_point(x, y, crs):
# Convertir en WGS84 (4326) si nécessaire
wgs84 = QgsCoordinateReferenceSystem("EPSG:4326")
if crs != wgs84:
transform = QgsCoordinateTransform(crs, wgs84, QgsProject.instance())
from qgis.core import QgsPointXY
pt = transform.transform(x, y)
x, y = pt.x(), pt.y()
wkt = f"POINT({x} {y})"
on_captured_callback(wkt, 4326)
self.setWindowState(self.windowState() & ~Qt.WindowMinimized | Qt.WindowActive)
self.activateWindow()
tool.pointCaptured.connect(on_point)
self._point_tool = tool
# Minimiser le dialogue et activer l'outil
self.showMinimized()
canvas.setMapTool(tool)
# -----------------------------------------------------------------------
# Callbacks ajout nouveaux éléments
# -----------------------------------------------------------------------
def _add_type_groupe(self, widget):
QMessageBox.information(self, "Info",
"L'ajout d'un type de groupe nécessite un code entier.\n"
"Veuillez contacter l'administrateur de la base.")
def _add_lieu(self, widget):
val, ok = QInputDialog.getText(self, "Nouveau lieu", "Nom du lieu :")
if not ok or not val.strip():
return
nom = val.strip()
reply = QMessageBox.question(self, "Géométrie",
"Souhaitez-vous localiser ce lieu sur la carte ?",
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
def on_geom(wkt, srid):
try:
code, label = self.db.add_lieux(nom, geom_wkt=wkt, srid=srid)
widget.add_item(code, label)
QMessageBox.information(self, "Succès", f"Lieu « {label} » ajouté avec géométrie.")
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
self._start_point_capture('lieu', on_geom)
else:
try:
code, label = self.db.add_lieux(nom)
widget.add_item(code, label)
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def _add_theme(self, widget):
val, ok = QInputDialog.getText(self, "Nouveau thème", "Libellé :")
if ok and val.strip():
try:
code, label = self.db.add_theme(val.strip())
widget.add_item(code, label)
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def _add_annulation(self, widget):
val, ok = QInputDialog.getText(self, "Nouveau type d'annulation", "Libellé :")
if ok and val.strip():
try:
code, label = self.db.add_annulation(val.strip())
widget.add_item(code, label)
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def _add_dossier(self, widget):
val, ok = QInputDialog.getText(self, "Nouveau type de dossier", "Libellé :")
if ok and val.strip():
try:
code, label = self.db.add_type_dossier(val.strip())
widget.add_item(code, label)
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def _add_etablissement(self, widget):
nom, ok = QInputDialog.getText(self, "Nouvel établissement", "Nom :")
if not ok or not nom.strip():
return
commune, ok2 = QInputDialog.getText(self, "Nouvel établissement", "Commune :")
if not ok2:
return
nom = nom.strip()
commune = commune.strip()
reply = QMessageBox.question(self, "Géométrie",
"Souhaitez-vous localiser cet établissement sur la carte ?",
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
def on_geom(wkt, srid):
try:
code, label, com = self.db.add_etablissement(nom, commune, geom_wkt=wkt, srid=srid)
self._etab_map[code] = (label, com)
display = f"{label} ({com})" if com else label
widget.add_item(code, display)
QMessageBox.information(self, "Succès", f"Établissement « {label} » ajouté avec géométrie.")
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
self._start_point_capture('etab', on_geom)
else:
try:
code, label, com = self.db.add_etablissement(nom, commune)
self._etab_map[code] = (label, com)
display = f"{label} ({com})" if com else label
widget.add_item(code, display)
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
# -----------------------------------------------------------------------
# Collecte, validation, enregistrement
# -----------------------------------------------------------------------
def _collect_data(self):
duree_str = f"{self.duree_h.value()}h{self.duree_min.value():02d}"
duree_min_total = self.duree_h.value() * 60 + self.duree_min.value()
temps_total = duree_min_total + self.prepa_spin.value() or None
etab_code = self.etab_combo.current_data()
nom_etab, commune_prov = (None, None)
if etab_code and etab_code in self._etab_map:
nom_etab, commune_prov = self._etab_map[etab_code]
lieux_txt = self.lieux_combo.current_text() if self.lieux_combo.current_data() else None
type_annul = self.annul_combo.current_text() if self.annul_combo.current_data() else None
type_dossier = self.dossier_combo.current_text() if self.dossier_combo.current_data() else None
realise_tiers = self.tiers_check.isChecked()
return {
"date_anim": self.date_edit.date().toPyDate(),
"duree_anim": duree_str,
"animateurs": self.animateurs_widget.get_value(),
"prepa_deplacemt": self.prepa_spin.value() or None,
"temps_total": temps_total,
"code_groupe": self.type_groupe_combo.current_data(),
"precisions_type_de_groupe": self.precisions_groupe_edit.text().strip() or None,
"commune_provenance": commune_prov,
"nom_etablissement": nom_etab,
"nbre_pers_enfants": self.enfants_spin.value() or None,
"nbre_pers_adultes": self.adultes_spin.value() or None,
"nbre_pers_total": (self.enfants_spin.value() + self.adultes_spin.value()) or None,
"lieux": lieux_txt,
"precisions_lieux_anim": self.precisions_lieux_edit.text().strip() or None,
"accueil_pin": self.accueil_pin_check.isChecked(),
"theme_detaille": self.theme_detaille_edit.text().strip() or None,
"code_type_anim": self.theme_combo.current_data(),
"payant": self.payant_check.isChecked(),
"type_annul": type_annul,
"remarques": self.remarques_edit.text().strip() or None,
"type_dossier_ens": type_dossier,
"realise_par_tiers": realise_tiers,
"detail_tiers": self.detail_tiers_edit.text().strip() if realise_tiers else None,
}
def _reset_form(self):
self.date_edit.setDate(QDate.currentDate())
self.duree_h.setValue(0)
self.duree_min.setValue(0)
self.prepa_spin.setValue(0)
self.animateurs_widget.list_widget.clear()
self.type_groupe_combo.combo.setCurrentIndex(0)
self.precisions_groupe_edit.clear()
self.etab_combo.combo.setCurrentIndex(0)
self.commune_label.setText("")
self.enfants_spin.setValue(0)
self.adultes_spin.setValue(0)
self.lieux_combo.combo.setCurrentIndex(0)
self.precisions_lieux_edit.clear()
self.accueil_pin_check.setChecked(False)
self.theme_combo.combo.setCurrentIndex(0)
self.theme_detaille_edit.clear()
self.payant_check.setChecked(False)
self.annul_combo.combo.setCurrentIndex(0)
self.remarques_edit.clear()
self.dossier_combo.combo.setCurrentIndex(0)
self.tiers_check.setChecked(False)
self.detail_tiers_edit.clear()
def _save(self):
try:
data = self._collect_data()
if self._edit_mode:
self.db.update_donnees_animation(self._edit_code, data)
QMessageBox.information(self, "Succès", f"Animation #{self._edit_code} mise à jour.")
self._reload_animations_list()
else:
code = self.db.get_next_code_animation()
data['code_animation'] = code
self.db.insert_donnees_animation(data)
QMessageBox.information(self, "Succès", f"Animation #{code} enregistrée.")
self._reload_animations_list()
self.accept()
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def _save_and_new(self):
try:
data = self._collect_data()
code = self.db.get_next_code_animation()
data['code_animation'] = code
self.db.insert_donnees_animation(data)
QMessageBox.information(self, "Succès", f"Animation #{code} enregistrée.")
self._reload_animations_list()
self._new_form()
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))