import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Window 2.2 import qt.koriolan.shipheart 1.0 import"fonctions_date_heure.js" as Fonctions_date_heure import"fonctions_historique.js" as Fonctions_historique Shipheart_page { id: page_journal_de_bord // Mise en forme : readonly property double pourcentage_largeur_colonne_gauche: 0.5 readonly property double espace_colonnes_principales: 20 readonly property double espace_colonnes_secondaires: 50 readonly property double pourcentage_hauteur_ligne_haut: 1.0 // 0.7 readonly property double pourcentage_hauteur_ligne_bas: (1 - pourcentage_hauteur_ligne_haut) readonly property double espace_lignes_principales: 20 readonly property int nombre_types_affiches_sur_une_colonne: 10 readonly property int nombre_lignes_historique_visibles: 10 readonly property int nombre_lignes_historique_par_page: 50 readonly property int periode_init_raffraichissement_journal: 1 // En ms readonly property int periode_raffraichissement_journal: 1000 // En ms // Affichage : // Historique property string libelle_type_tous: qsTr("Tous") property string libelle_type_batteries: qsTr("Batteries") property string libelle_type_capteurs: qsTr("Capteurs") property string libelle_type_circuits: qsTr("Circuits") property string libelle_type_reservoirs: qsTr("Réservoirs") property string libelle_type_systeme: qsTr("Système") property string libelle_type_usb: qsTr("Ports USB") property string date_premiere_entree_historique: "" // Contient une chaine (format BDD) représentant la date/heure de l'entrée historique la plus ancienne. Permet de recharger de plus anciennes lors d'un MORE... property string date_derniere_entree_historique: "" // Contient une chaine (format BDD) représentant la date/heure de l'entrée historique la plus récente. Permet de ne recharger que les nouvelles... property int filtre_type: shipheart_historique_type_tous // -1=Tous, 0=Systeme, 1=Circuits, 2=Capteurs, 3=Réservoirs, 4=Batteries, 5=USB property int filtre_id: 0 property bool flag_choix_id: false // Si vrai, indique qu'un choix d'ID est possible. Su Faux, il n'y a pas de choix d'ID property int index_type_en_cours: -1 property int index_id_en_cours: -1 property bool flag_journal_full: false // est positionné à vrai quand il n'y a plus d'enregistrements supplémentaires disponibles pour ce filtre // Données dynamiques : property var circuits: [] // Contient, après l'initialisation, le nom affecté à chaque clé primaire (utile pour afficher en clair l'ID dans l'historique) property var capteurs: [] // Contient, après l'initialisation, le nom affecté à chaque clé primaire (utile pour afficher en clair l'ID dans l'historique) property var reservoirs: [] // Contient, après l'initialisation, le nom affecté à chaque clé primaire (utile pour afficher en clair l'ID dans l'historique) property var batteries: [] // Contient, après l'initialisation, le nom affecté à chaque clé primaire (utile pour afficher en clair l'ID dans l'historique) // Modèles : // Note : les modèles chargés dans 'main.qml' n'ont pas à être rechargés dans les pages suivantes //=========================================================== // Timer periode raffraichissement journal : //=========================================================== Timer { id: timer_raffraichissement_journal interval: periode_init_raffraichissement_journal triggeredOnStart: false running: true repeat: true onTriggered: { if (interval == periode_init_raffraichissement_journal) { // Premier passage, 1ms après le premier chargement interval = periode_raffraichissement_journal; init_page(); } else { // mise_a_jour_filtres(); mise_a_jour_journal("UPDATE"); } } } // Titre de la page : Shipheart_titre_1 {titre:qsTr("Journal de bord"); hauteur: shipheart_hauteur_bandeau_haut} //------------------------------------------------------- // Ecran haut - gauche : Filtres //------------------------------------------------------- Rectangle { id: zone_affichage_haut_gauche x: 0 y: shipheart_hauteur_bandeau_haut + espace_lignes_principales; width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2); height: (shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas - (((pourcentage_hauteur_ligne_bas > 0) ? 3 : 2) * espace_lignes_principales)) * pourcentage_hauteur_ligne_haut; color: "transparent" //--------------------------------- // Liste pour afficher les types : //--------------------------------- ListView { id: liste_principale width: parent.width * 0.4 height: parent.height spacing: 5 snapMode: GridView.SnapToRow // L'arret de l'affichage se fera sur une rangée entière clip: true // Nécessaire pour que les Delegates s'arretent à l'intérieur de la GridView model: modele_choix_type delegate: Rectangle { width:parent.width height: ((liste_principale.height - ((nombre_types_affiches_sur_une_colonne - 1) * liste_principale.spacing)) / nombre_types_affiches_sur_une_colonne) color: "transparent" Rectangle { // c'est le bouton proprement dit... height: parent.height width:parent.width color: (model.index === index_type_en_cours) ? shipheart_couleur_fond_bouton_actif : shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton anchors.bottom: parent.bottom Text { anchors.fill: parent horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignVCenter leftPadding: 20 text: model.libelle color: couleur_blanc_casse font.pixelSize: 18 font.bold: ((index === 0) || (index === index_type_en_cours)) ? true : false wrapMode: Label.Wrap } MouseArea{ anchors.fill : parent onClicked: { shipheart_clic(); mise_a_jour_filtres(model.index, index_id_en_cours); } } } } ListModel { id: modele_choix_type } Label { anchors.fill: parent horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter visible: parent.count === 0 text: qsTr("Aucun type n'est configuré...") color: couleur_rouge_transparent font.pixelSize: 15 font.bold: true wrapMode: Label.Wrap } } //------------------------------------------------------- // Liste pour afficher les IDs correspondant aux types : //------------------------------------------------------- ListView { id: liste_secondaire x: liste_principale.width + 10 width: parent.width - x height: liste_principale.height spacing: 5 snapMode: GridView.SnapToRow // L'arret de l'affichage se fera sur une rangée entière model: modele_choix_id_circuits // Valeur par défaut mise à jour dynamiqueemnt ensuite visible: flag_choix_id // On n'affiche ce choix que si le type en cours permet de choisir un ID spécifique delegate: Rectangle { width:parent.width height: ((liste_secondaire.height - ((nombre_types_affiches_sur_une_colonne - 1) * liste_secondaire.spacing)) / nombre_types_affiches_sur_une_colonne) color: "transparent" Rectangle { // c'est le bouton proprement dit... height: parent.height width:parent.width color: (model.index === index_id_en_cours) ? shipheart_couleur_fond_bouton_actif : shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton anchors.bottom: parent.bottom Text { anchors.fill: parent horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignVCenter leftPadding: 20 text: model.libelle color: couleur_blanc_casse font.pixelSize: 18 font.bold: ((index === 0) || (index === index_id_en_cours)) ? true : false wrapMode: Label.Wrap } MouseArea{ anchors.fill : parent onClicked: { shipheart_clic(); mise_a_jour_filtres(index_type_en_cours, model.index); } } } } ListModel { id: modele_choix_id_circuits } ListModel { id: modele_choix_id_capteurs } ListModel { id: modele_choix_id_reservoirs } ListModel { id: modele_choix_id_batteries } } } //------------------------------------------------------- // Ecran bas - gauche : //------------------------------------------------------- Rectangle { id: zone_affichage_bas_gauche x: 0 y: shipheart_hauteur_bandeau_haut + zone_affichage_haut_gauche.height + (2 * espace_lignes_principales); width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2); height: (shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas - (3 * espace_lignes_principales)) * pourcentage_hauteur_ligne_bas color: "transparent" } //------------------------------------------------------- // Ecran haut - droite : Journal //------------------------------------------------------- Rectangle { id: zone_affichage_haut_droite x: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) + (espace_colonnes_principales / 2); y: shipheart_hauteur_bandeau_haut + espace_lignes_principales; width: (shipheart_largeur_page * (1 - pourcentage_largeur_colonne_gauche)) - (espace_colonnes_principales / 2); height: zone_affichage_haut_gauche.height + zone_affichage_bas_gauche.height + (((pourcentage_hauteur_ligne_bas > 0) ? 1 : 0) * espace_lignes_principales); color: "transparent" ListModel { id: historique } ListView { id: liste_historique anchors.fill: parent model: historique spacing: 5 snapMode: GridView.SnapToRow // L'arret de l'affichage se fera sur une rangée entière footerPositioning: ListView.InlineFooter // Positionne le footer à la fin des enregistrements (pratique pour le bouton MORE...) delegate: Rectangle { width:liste_historique.width height: ((liste_historique.height - ((nombre_lignes_historique_visibles - 1) * liste_historique.spacing)) / nombre_lignes_historique_visibles) color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton Text { id: no_ligne width: parent.width * 0.07; anchors.verticalCenter: parent.verticalCenter horizontalAlignment: Text.AlignRight text: index + 1 font.pixelSize: 14 font.bold: true color: couleur_gris_moyen } Text { id: date_ligne x: no_ligne.width; width: parent.width * 0.3; anchors.verticalCenter: parent.verticalCenter horizontalAlignment: Text.AlignHCenter text: model.date_event font.pixelSize: 14 color: couleur_blanc_casse } Text { id: texte_ligne x: no_ligne.width + date_ligne.width; width: parent.width - no_ligne.width - date_ligne.width; anchors.verticalCenter: parent.verticalCenter horizontalAlignment: Text.AlignJustify text: model.texte_event font.pixelSize: 14 rightPadding: 10 wrapMode: Text.Wrap maximumLineCount: 2 elide: Text.ElideRight color: couleur_gris_moyen } MouseArea{ anchors.fill : parent onClicked: { boite_information_journal.niveau = 0 boite_information_journal.imageTitreSource = "/images/icone_journal_de_bord.png"; boite_information_journal.message = qsTr("%1


%2").arg(Fonctions_date_heure.chaine_date_longue(Fonctions_date_heure.chaine_bdd_date_heure(model.date_event), shipheart_langue) + "

" + Fonctions_date_heure.chaine_heure(Fonctions_date_heure.chaine_bdd_date_heure(model.date_event))).arg(model.texte_event) boite_information_journal.open(); } onPressed: shipheart_clic(); } } footer: Rectangle { // Ce premier rectangle sert juste à créer un espace un peu plu sgrand pour le bouton '+' et le décaler de 'spacing' vers le bas... height: ((liste_historique.height - ((nombre_lignes_historique_visibles - 1) * liste_historique.spacing)) / nombre_lignes_historique_visibles) + liste_historique.spacing width:parent.width - 5 // Le '5' donne la marge droite color: "transparent" visible: !flag_journal_full Rectangle { // c'est le bouton proprement dit... height: ((liste_historique.height - ((nombre_lignes_historique_visibles - 1) * liste_historique.spacing)) / nombre_lignes_historique_visibles) width:parent.width color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton anchors.bottom: parent.bottom Text { anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } text: "+" font.pixelSize: 40 font.bold: true color: couleur_gris_moyen } MouseArea{ anchors.fill : parent onClicked: { mise_a_jour_journal("MORE"); } onPressed: shipheart_clic(); } } } Label { anchors.fill: parent horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter visible: parent.count === 0 text: qsTr("Aucune entrée d'historique n'est disponible pour cette sélection...") color: couleur_rouge_transparent font.pixelSize: 15 font.bold: true wrapMode: Label.Wrap } } } //------------------------------------------------------- // Bandeau bas : //------------------------------------------------------- Row { x: 0 y: shipheart_hauteur_page - shipheart_hauteur_bandeau_bas; width: shipheart_largeur_page; height: shipheart_hauteur_bandeau_bas; spacing: 5 padding: 5 //................................................. // Bouton retour //................................................. Rectangle { id: bandeau_bas_zone_retour width: parent.width - (2 * parent.padding) height: shipheart_hauteur_bandeau_bas - parent.topPadding - parent.bottomPadding; radius: 5 color: shipheart_couleur_fond_bouton Image { source: "/images/icone_retour.png" sourceSize.height: 30 anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } } MouseArea { // Zone d'interaction. On est obligé de la mettre dans la grille pour que Rectangle et MouseArea soient frères ou parent/enfant ET qu'on n'occupe qu'un espace dans la grille. id: mouse_area_bandeau_bas_zone_retour anchors.fill: parent pressAndHoldInterval: shipheart_mouse_press_and_hold_interval_court onClicked: { shipheart_clic(); stackView.pop(); } } } } //------------------------------------------------------- // Boite de détails d'entrée de journal : //------------------------------------------------------- Shipheart_boite_dialogue { id: boite_information_journal } //=========================================================== // Economiseur : Doit être placé en fin de page pour fonctionner //=========================================================== MouseArea { anchors.fill: parent preventStealing: true // Permet que cela fonctionne même si un élément flickable (notamment) soit derrière et "vole" le click enabled: flag_economiseur_actif onClicked: { mise_en_veille(0); } } //============================================================================================================= // Init de la page //============================================================================================================= function init_page() { var req, res; var nb; var i; // Mise à jour du modèle de choix de type : // Simplement commenter les lignes non nécessaires .... modele_choix_type.clear(); modele_choix_type.append({"libelle": libelle_type_tous, "type": shipheart_historique_type_tous }); // Ajout du premier choix "Tous" modele_choix_type.append({"libelle": libelle_type_circuits, "type": shipheart_historique_type_circuits }); modele_choix_type.append({"libelle": libelle_type_reservoirs, "type": shipheart_historique_type_reservoirs }); modele_choix_type.append({"libelle": libelle_type_batteries, "type": shipheart_historique_type_batteries }); modele_choix_type.append({"libelle": libelle_type_capteurs, "type": shipheart_historique_type_capteurs }); if (shipheart_niveau_acces_en_cours >= shipheart_niveau_acces_admin) { modele_choix_type.append({"libelle": libelle_type_systeme, "type": shipheart_historique_type_systeme }); modele_choix_type.append({"libelle": libelle_type_usb, "type": shipheart_historique_type_usb }); } // Mise à jour du modèle des Circuits : modele_choix_id_circuits.clear(); modele_choix_id_circuits.append({"libelle": qsTr("Tous"), "cle_primaire": 0 }); // Ajout du premier choix "Tous" req = 'SELECT Cle_primaire, Nom FROM TB_Circuits '; req += ' WHERE ID_Circuit_esclave>=0 '; // On écarte les circuits esclaves car il n'y a pas d'utilité à les faire apparaitre... req += ' ORDER BY Priorite_affichage_accueil '; // On ne filtre volontairement sur aucune validité ou présence car le journal peut porter sur des éléments qui ne sont plus valables... //console.log("Requête = " + req); nb = bdd.requete(req); for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { modele_choix_id_circuits.append({"libelle": res[1], "cle_primaire": Number(res[0]) }); circuits[res[0]] = res[1]; } } // Mise à jour du modèle des Capteurs : modele_choix_id_capteurs.clear(); modele_choix_id_capteurs.append({"libelle": qsTr("Tous"), "cle_primaire": 0 }); // Ajout du premier choix "Tous" req = 'SELECT Cle_primaire, Nom FROM TB_Capteurs ORDER BY Nom '; // On ne filtre volontairement sur aucune validité ou présence car le journal peut porter sur des éléments qui ne sont plus valables... nb = bdd.requete(req); for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { modele_choix_id_capteurs.append({"libelle": res[1], "cle_primaire": Number(res[0]) }); capteurs[res[0]] = res[1]; } } // Mise à jour du modèle des Réservoirs : modele_choix_id_reservoirs.clear(); modele_choix_id_reservoirs.append({"libelle": qsTr("Tous"), "cle_primaire": 0 }); // Ajout du premier choix "Tous" req = 'SELECT Cle_primaire, Nom FROM TB_Reservoirs ORDER BY Nom '; // On ne filtre volontairement sur aucune validité ou présence car le journal peut porter sur des éléments qui ne sont plus valables... nb = bdd.requete(req); for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { modele_choix_id_reservoirs.append({"libelle": res[1], "cle_primaire": Number(res[0]) }); reservoirs[res[0]] = res[1]; } } // Mise à jour du modèle des Batteries : modele_choix_id_batteries.clear(); modele_choix_id_batteries.append({"libelle": qsTr("Toutes"), "cle_primaire": 0 }); // Ajout du premier choix "Tous" req = 'SELECT Cle_primaire, Nom FROM TB_Batteries ORDER BY Nom '; // On ne filtre volontairement sur aucune validité ou présence car le journal peut porter sur des éléments qui ne sont plus valables... nb = bdd.requete(req); for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { modele_choix_id_batteries.append({"libelle": res[1], "cle_primaire": Number(res[0]) }); batteries[res[0]] = res[1]; } } mise_a_jour_filtres(0, 0); // Cette mise à jour des filtres va générer une maj du journal } //============================================================================================================= // Mise à jour de l'historique // Note importante : tous les paramètres de recherche et de gestion sont en UTC ! La conversion en heure locale // et heure Eté/Hiver est fait eau dernier moment, lors du remplissage du modèle. //============================================================================================================= function mise_a_jour_journal(mode) { var req, res; var nb; var i; var table; var liste_parametres = " Cle_primaire, Type, ID_Source, Valeur, Date, Complement"; var sens; var filtre= ""; var nom_id; //console.time('maj_journal') if (filtre_id !== 0) filtre += " AND ID=" + filtre_id + " "; switch(mode) { case "INIT": historique.clear(); // On remet à 0 le modèle lors d'un nouveau filtre date_premiere_entree_historique = Fonctions_date_heure.chaine_date_heure_bdd(Fonctions_date_heure.date_courante(null, 0, 0)); date_derniere_entree_historique = date_premiere_entree_historique; sens = "DESC"; break; case "UPDATE": filtre += ' AND Date>"' + date_derniere_entree_historique + '"'; // On ne récupère que les nouvelles entrées sens = "ASC"; break; case "MORE": filtre += ' AND Date<"' + date_premiere_entree_historique + '"'; // On ne récupère que les entrées plus ancienne que la plus vieille déjà récupérée sens = "DESC"; break; default : console.log("Fonction 'mise_a_jour_journal' appelée avec un type inconnu..."); return; } if (filtre_type !== shipheart_historique_type_tous) { // req = 'SELECT ' + liste_parametres + ', ' + filtre_type + ' FROM ' + table + ' WHERE ' + filtre + ' ORDER BY Date ' + sens + ' LIMIT ' + nombre_lignes_historique_par_page + ' '; req = 'SELECT ' + liste_parametres + ' FROM TB_Historique WHERE Type_source=' + filtre_type + ' ' + filtre + ' ORDER BY Date ' + sens + ' LIMIT ' + nombre_lignes_historique_par_page + ' '; // !!!!! IL doit être possible de simplifier beaucoup le traitement maintenant que l'on a une seule table d'hostorique. !!! } else { req = 'SELECT ' + liste_parametres + ' FROM TB_Historique WHERE ' + filtre + ' ORDER BY Date ' + sens + ' LIMIT ' + nombre_lignes_historique_par_page + ' '; } //console.log("Requête = " + req); nb = bdd.requete(req); // Récupération des lignes d'historique : for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { switch(Number(res[6])) { case shipheart_historique_type_systeme: nom_id = ""; break; case shipheart_historique_type_circuits: nom_id = circuits[res[2]]; break; case shipheart_historique_type_capteurs: nom_id = capteurs[res[2]]; break; case shipheart_historique_type_reservoirs: nom_id = reservoirs[res[2]]; break; case shipheart_historique_type_batteries: nom_id = batteries[res[2]]; break; case shipheart_historique_type_usb: nom_id = ""; break; default: nom_id = ""; break; } if ((mode === "INIT") || (mode === "MORE")) // Au démarrage et lorsqu'on ajoute des enregistrements, on le fait par ajout à la fin { historique.append( { "date_event": Fonctions_date_heure.chaine_date_heure_bdd(Fonctions_date_heure.date_courante(Fonctions_date_heure.chaine_bdd_date_heure(res[4]), shipheart_fuseau_horaire, shipheart_heure_ete)), "texte_event": Fonctions_historique.historique_libelle(Number(res[6]), Number(res[1]), nom_id, Number(res[3]), res[5]) }); date_premiere_entree_historique = res[4]; } else // Si c'est un Update, on ajoute des évènement récents donc on le fait par INSERT (au début) : { historique.insert(0,{ "date_event": Fonctions_date_heure.chaine_date_heure_bdd(Fonctions_date_heure.date_courante(Fonctions_date_heure.chaine_bdd_date_heure(res[4]), shipheart_fuseau_horaire, shipheart_heure_ete)), "texte_event": Fonctions_historique.historique_libelle(Number(res[6]), Number(res[1]), nom_id, Number(res[3]), res[5]) }); date_derniere_entree_historique = res[4]; } } else break; // Ne devrait pas arriver.... } //console.log("mode = " + mode + " , nb = " + nb + " et date_première_entree = " + date_premiere_entree_historique + " et date_dernière_entrée = " + date_derniere_entree_historique + ". Nb lignes du modèle = " + historique.count); // Traitement de l'affichage de l'historique après la mise à jour du modèle : switch(mode) { case "INIT": if (nb < nombre_lignes_historique_par_page) flag_journal_full = true; // Positionne le flag FULL lorsqu'on n'a pas récupéré autant d'enregistrements que demandé à l'INIT else flag_journal_full = false; liste_historique.positionViewAtBeginning(); // Positionne la liste au début lors d'une INIT break; case "UPDATE": if (nb !== 0) liste_historique.positionViewAtBeginning(); // Positionne la liste au début si au moins une entrée a été ajoutée break; case "MORE": if (nb < nombre_lignes_historique_par_page) flag_journal_full = true; // Positionne le flag FULL lorsqu'on n'a pas récupéré autant d'enregistrements que demandé sur un MORE break; } //console.log("Nombre d'entrées de l'historique = " + historique.count + " premiere clé = " + cle_primaire_premiere_entree_historique + " et dernière clé = " + cle_primaire_derniere_entree_historique); // + " et req =" + req); //console.timeEnd('maj_journal') } //============================================================================================================= // Mise à jour de liste de choix pour les filtres //============================================================================================================= function mise_a_jour_filtres(index_type, index_id) { var tableau; if (index_type_en_cours !== index_type) { index_type_en_cours = index_type index_id_en_cours = 0 filtre_type = modele_choix_type.get(index_type_en_cours).type; //console.log("Tumbler choix type index =" + index_type_en_cours + " et valeur de filtre_type = " + filtre_type ) switch(filtre_type) { case shipheart_historique_type_tous : flag_choix_id = false; break; case shipheart_historique_type_systeme: flag_choix_id = false; break; case shipheart_historique_type_circuits: liste_secondaire.model= modele_choix_id_circuits; flag_choix_id = true; break; case shipheart_historique_type_capteurs: liste_secondaire.model= modele_choix_id_capteurs; flag_choix_id = true; break; case shipheart_historique_type_reservoirs: liste_secondaire.model= modele_choix_id_reservoirs; flag_choix_id = true; break; case shipheart_historique_type_batteries: liste_secondaire.model= modele_choix_id_batteries; flag_choix_id = true; break; case shipheart_historique_type_usb: flag_choix_id = false; break; default: flag_choix_id = false; } filtre_id = 0; mise_a_jour_journal("INIT"); } else if (index_id_en_cours !== index_id) { index_id_en_cours = index_id filtre_id = liste_secondaire.model.get(index_id_en_cours).cle_primaire mise_a_jour_journal("INIT"); } } }