//======================================================================================================================================================================== // CONFIG_EVENT.QML // Ce fichier traite la configuration d'un évènement. La page permet notamment de : // - Modifier la config de l'évènement (ou de le créer la première fois), // - Supprimer l'évènement // La page est appelée depuis la page config_events.qml, en cliquant sur l'évènement à modifier (ou sur le '+' en vue d'une création) //======================================================================================================================================================================== import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQml.Models import qt.koriolan.shipheart 1.0 import"fonctions.js" as Fonctions import"fonctions_date_heure.js" as Fonctions_date_heure Shipheart_page { id: page_config_evenement // Mise en forme - Largeur : readonly property double pourcentage_largeur_colonne_gauche: 0.75 readonly property double espace_colonnes_principales: 20 readonly property double pourcentage_largeur_labels_formulaire: 0.5 readonly property double pourcentage_largeur_unites_formulaire: 0.1 readonly property int largeur_bouton_suite: 15 readonly property double pourcentage_bandeau_bas_largeur_zone_retour: 1 readonly property int nombre_widgets_heure_par_ligne: 12 // Mise en forme - Hauteur : readonly property double pourcentage_hauteur_ligne_haut: 1 readonly property int hauteur_ligne_formulaire: 60 readonly property int hauteur_bouton_droit: 80 readonly property int espace_lignes_principales: 20 readonly property double affichage_hauteur_utile: shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas // Timings : readonly property int periode_init_raffraichissement_parametres: 1 // En ms readonly property int periode_raffraichissement_parametres: 1000 // En ms readonly property int step_timer_appui_long: 30 // en ms // Affichage : property bool flag_init: true // Permet de bloquer certains affichage tant que l'init n'est pas terminée // Données : property int valeur_timer_appui_long: 0 property int id_event: 0 property string nom: "" property int type_source: 0 property int id_source: 0 property int id_variable: 0 property int test: 0 property double seuil: 0 property string seuil_unite: "" property int tempo: 0 property string conditions_horaires: "" property string action_circuits: "" property int index_condition_horaire_en_cours: -1 property int index_circuit_en_cours: -1 property bool flag_test_binaire: false // Indique si l'évènement porte sur une condition binaire ou non (exemple: Capteur>Entrée AUX) property int nombre_action_circuits: 0 // Stocke le nombre d'actions sur des circuits (autre que "Aucune action") car on est limité à 'shipheart_max_nombre_action_circuits_par_event' // Modèles : // Note : les modèles chargés dans 'main.qml' n'ont pas à être rechargés dans les pages suivantes //=========================================================== // Timer periode raffraichissement parametres : //=========================================================== Timer { id: timer_raffraichissement_parametres interval: periode_init_raffraichissement_parametres triggeredOnStart: false running: true repeat: true onTriggered: { if (interval == periode_init_raffraichissement_parametres) { // Premier passage, 1ms après le premier chargement interval = periode_raffraichissement_parametres; init_page(); } else { } } } //=========================================================== // Timer pour gérer les appuis longs : //=========================================================== Timer { id: timer_appui_long interval: step_timer_appui_long triggeredOnStart: false repeat: true onTriggered: { if (valeur_timer_appui_long < shipheart_mouse_press_and_hold_interval_tres_long) valeur_timer_appui_long+= step_timer_appui_long; else // Le fait de ne pas utilise le OnPressandHold permet d'être sût que la sortie se fait au même moment que la fin du comptage (sinon, on peut avoir de petits décalages) { timer_appui_long.running = false; valeur_timer_appui_long = 0; if (mousearea_bouton_supprimer.pressed) { suppression_event(); timer_tempo_reconfiguration.restart(); // Lancement du timer pour attendre la fin de la reconfiguration } } } } // Titre de la page : Shipheart_titre_1 {titre: (id_event === 0) ? qsTr("Création d'un évènement") : qsTr("Configuration de l'évènement"); hauteur: shipheart_hauteur_bandeau_haut} //------------------------------------------------------- // Ecran Haut - Gauche : //------------------------------------------------------- Rectangle { id: zone_affichage_haut_gauche x: 0 y: shipheart_hauteur_bandeau_haut; width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: (affichage_hauteur_utile * pourcentage_hauteur_ligne_haut) - (espace_lignes_principales / 2); color: "transparent" ListView { id: grille_principale width: parent.width height: parent.height // 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_grille_principale footer: Rectangle { // Permet de dégager la place suffisante en fin de GridView pour accéder même au dernier élément lorsque que clavier est déplié height: affichage_hauteur_utile - hauteur_ligne_formulaire // Cette valeur permet de bien remonter les drniers champs (utile dans le cas de Textarea notamment) en laissant toujours une hauteur de lugne de formulaire au moins (évite qu'on "perde" l'affichage qui serait trop décalé vers le haut) color: "transparent" } ObjectModel { id: modele_grille_principale //------------------------------------------------------------------------------- // Ligne de formulaire : Nom Rectangle { id: ligne_nom width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" Shipheart_formulaire_label { text: qsTr("Nom de l'évènement") width: parent.width * pourcentage_largeur_labels_formulaire couleur: (champ_formulaire_Nom.text !== "") ? shipheart_formulaire_couleur_texte_par_defaut : shipheart_formulaire_couleur_texte_en_erreur } Shipheart_formulaire_textfield { id: champ_formulaire_Nom width: parent.width * (1 - pourcentage_largeur_labels_formulaire) x: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Type_source Rectangle { id: ligne_type_source width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" Shipheart_formulaire_label { text: qsTr("Type de la source") width: parent.width * pourcentage_largeur_labels_formulaire couleur: (champ_formulaire_Type_source.currentIndex !== 0) ? shipheart_formulaire_couleur_texte_par_defaut : shipheart_formulaire_couleur_texte_en_erreur } Shipheart_formulaire_combobox { id: champ_formulaire_Type_source model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); if (type_source !== champ_formulaire_Type_source.model.get(champ_formulaire_Type_source.currentIndex).valeur) { type_source = champ_formulaire_Type_source.model.get(champ_formulaire_Type_source.currentIndex).valeur; id_source = 0; id_variable = 0; if (type_source > 0) mise_a_jour_source(); else if (type_source === 0) mise_a_jour_parametres_generaux(); // Conditions horaires seulement... } } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : ID_Source Rectangle { id: ligne_source width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: (champ_formulaire_Type_source.currentIndex !== 0) && (type_source !== 0) Shipheart_formulaire_label { text: qsTr("Source") width: parent.width * pourcentage_largeur_labels_formulaire couleur: (champ_formulaire_Source.currentIndex !== 0) ? shipheart_formulaire_couleur_texte_par_defaut : shipheart_formulaire_couleur_texte_en_erreur } Shipheart_formulaire_combobox { id: champ_formulaire_Source model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); id_source = champ_formulaire_Source.model.get(champ_formulaire_Source.currentIndex).valeur; mise_a_jour_variable(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : ID_Variable Rectangle { id: ligne_variable width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: ligne_source.visible && (champ_formulaire_Source.currentIndex !== 0) && (type_source !== 0) && (champ_formulaire_Variable.model.count > 2) // Comme on a toujours "Non défini", si Count<=2, c'est qu'on n'a qu'un seul choix qu'il n'est pas nécessaire d'afficher... Shipheart_formulaire_label { text: qsTr("Variable de la source") width: parent.width * pourcentage_largeur_labels_formulaire couleur: (champ_formulaire_Variable.currentIndex !== 0) ? shipheart_formulaire_couleur_texte_par_defaut : shipheart_formulaire_couleur_texte_en_erreur } Shipheart_formulaire_combobox { id: champ_formulaire_Variable model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); id_variable = champ_formulaire_Variable.model.get(champ_formulaire_Variable.currentIndex).valeur; seuil_unite = champ_formulaire_Variable.model.get(champ_formulaire_Variable.currentIndex).unite; mise_a_jour_parametres_generaux(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Test Rectangle { id: ligne_test width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: (ligne_variable.visible || ( ligne_source.visible && (champ_formulaire_Source.currentIndex !== 0) && (type_source !== 0) && (champ_formulaire_Variable.model.count <= 2)) ) && (champ_formulaire_Variable.currentIndex !== 0) && (type_source !== 0) Shipheart_formulaire_label { text: qsTr("Déclenchement si") width: parent.width * pourcentage_largeur_labels_formulaire couleur: (champ_formulaire_Test.currentIndex !== 0) ? shipheart_formulaire_couleur_texte_par_defaut : shipheart_formulaire_couleur_texte_en_erreur } Shipheart_formulaire_combobox { id: champ_formulaire_Test model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); test = champ_formulaire_Test.model.get(champ_formulaire_Test.currentIndex).valeur; } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Seuil Rectangle { id: ligne_seuil width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: ligne_test.visible && (champ_formulaire_Test.currentIndex !== 0) && (type_source !== 0) && (!flag_test_binaire) // Si on est sur un test binaire, il est inutile d'afficher le seuil... Shipheart_formulaire_label { // Label : text: qsTr("Seuil de déclenchement") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_textfield { // Champ de saisie : id: champ_formulaire_Seuil width: parent.width * (1 - pourcentage_largeur_labels_formulaire - pourcentage_largeur_unites_formulaire) x: parent.width * pourcentage_largeur_labels_formulaire flag_num_only: true } Shipheart_formulaire_unite { // Unités : text: seuil_unite; width: parent.width * pourcentage_largeur_unites_formulaire } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Tempo Rectangle { id: ligne_tempo width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: ligne_test.visible // NB : On remonte au niveau du Test car le Seuil peut ne pas être affiché (cas des tests binaires) && (champ_formulaire_Test.currentIndex !== 0) && (type_source !== 0) Shipheart_formulaire_label { // Label : text: qsTr("Temporisation de déclenchement") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_textfield { // Champ de saisie : id: champ_formulaire_Tempo width: parent.width * (1 - pourcentage_largeur_labels_formulaire - pourcentage_largeur_unites_formulaire) x: parent.width * pourcentage_largeur_labels_formulaire flag_num_only: true } Shipheart_formulaire_unite { // Unités : text: qsTr("s") width: parent.width * pourcentage_largeur_unites_formulaire } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Visibilite Rectangle { id: ligne_visibilite width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: (ligne_tempo.visible) || (type_source === 0) // SDIR #240 Shipheart_formulaire_label { text: qsTr("Masquer sur la page d'accueil") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Visibilite width: parent.width * (1 - pourcentage_largeur_labels_formulaire) } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //=========================================================== // Séparation : //=========================================================== Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: 20 color: "transparent" Shipheart_formulaire_ligne_separation { visible: zone_conditions_horaires.visible haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse epaisseur_ligne: 3 force: shipheart_formulaire_ligne_separation_force_elevee } } Shipheart_titre_2 { titre:qsTr("Conditions horaire"); hauteur: shipheart_hauteur_bandeau_haut visible: zone_conditions_horaires.visible } //=========================================================== // Conditions horaires de la commande : //=========================================================== Rectangle { id: zone_conditions_horaires width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: grille_conditions_horaires.model.count * (hauteur_ligne_formulaire + spacing) color: "transparent" visible: ((type_source !== 0) && (ligne_tempo.visible)) || (type_source === 0) GridView { id: grille_conditions_horaires width: parent.width height: parent.height cellWidth: parent.width; cellHeight: hauteur_ligne_formulaire 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 interactive: false // (cf SDIR #223). Comme on affiche tous les éléments du modèle, il est inutile de la laisser interactive (ce qui peut compliquer le défilement entre la liste principale et celle-ci). model: ListModel { } delegate: Rectangle { width: grille_conditions_horaires.cellWidth height: grille_conditions_horaires.cellHeight color: "transparent" Rectangle { height: parent.height - 10 width: parent.width - 10 visible: (!model.bouton) || // On n'afficha pas le bouton '+'... ((grille_conditions_horaires.model.count - 1) < shipheart_max_nombre_conditions_horaires_par_event) // ... si le nombre de conditions est trop important color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton anchors { left: parent.left verticalCenter: parent.verticalCenter } Text { anchors.fill: parent verticalAlignment: Qt.AlignVCenter horizontalAlignment: (!model.bouton) ? Qt.AlignLeft : Qt.AlignHCenter leftPadding: (!model.bouton) ? 20 : 0 text: model.libelle color: couleur_blanc_casse font.pixelSize: (!model.bouton) ? 18 : (hauteur_ligne_formulaire * 0.8) } MouseArea{ anchors.fill : parent onClicked: { shipheart_clic(); if (model.bouton) // Cas du bouton '+' { index_condition_horaire_en_cours = -1; // Marqueur pour indiquer l'ajout d'un élément boite_selection_condition_horaire.valeur_tumbler_jour = 8; // Tous les jours par défaut boite_selection_condition_horaire.valeur_tumbler_heure = 0; boite_selection_condition_horaire.valeur_tumbler_minute = 0; boite_selection_condition_horaire.boutonSupprimer = false; } else // Cas d'une modification de condition existante : { index_condition_horaire_en_cours = index; boite_selection_condition_horaire.valeur_tumbler_jour = model.jour; boite_selection_condition_horaire.valeur_tumbler_heure = model.heure; boite_selection_condition_horaire.valeur_tumbler_minute = model.minute; boite_selection_condition_horaire.boutonSupprimer = true; } boite_selection_condition_horaire.open(); } } } Text { anchors.fill: parent visible: (model.bouton) && // Affiche à la place du bouton '+'... ((grille_conditions_horaires.model.count - 1) >= shipheart_max_nombre_conditions_horaires_par_event) // ... et si le nombre de conditions est trop important verticalAlignment: Qt.AlignVCenter horizontalAlignment: Qt.AlignHCenter text: qsTr("Le nombre maximal de conditions horaires [%1] est atteint : ajout impossible...").arg(shipheart_max_nombre_conditions_horaires_par_event) color: couleur_orange font.pixelSize: 15 opacity: 0.7 } } Label { anchors.fill: parent horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter visible: parent.count === 0 text: qsTr("Aucune condition horaire n'est configurée pour cet évènement...") color: couleur_rouge_transparent font.pixelSize: 15 font.bold: true wrapMode: Label.Wrap } } // Fin de Gridview } // Fin des conditions horaires //=========================================================== // Séparation : //=========================================================== Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: 20 color: "transparent" Shipheart_formulaire_ligne_separation { visible: zone_conditions_horaires.visible haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse epaisseur_ligne: 3 force: shipheart_formulaire_ligne_separation_force_elevee } } Shipheart_titre_2 { titre:qsTr("Signalisation"); hauteur: shipheart_hauteur_bandeau_haut visible: zone_conditions_horaires.visible } //=========================================================== // Alarmes : //=========================================================== //------------------------------------------------------------------------------- // Ligne de formulaire : Alarme_son Rectangle { id: ligne_alarme_son width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: zone_conditions_horaires.visible Shipheart_formulaire_label { text: qsTr("Alarme sonore") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Alarme_son width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onCheckedChanged: { if (!flag_init && champ_formulaire_Alarme_son.checked) // Si on veut une alarme sur son... { if (!champ_formulaire_Alarme_message.checked) { champ_formulaire_Alarme_message.checked = true; // ... il FAUT que l'alarme par message soit validée boite_information.niveau = 0; boite_information.imageTitreSource = "/images/ampoule.png" boite_information.message = qsTr("La validation des alarmes sonores a nécessité de valider également l'affichage des messages liés à cet évènement.

Cet affichage est en effet nécessaire au fonctionnement des alarmes sonores, afin de pouvoir les acquitter."); boite_information.alignementMessage = Text.AlignHCenter boite_information.open(); } } } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Alarme_led Rectangle { id: ligne_alarme_led width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: ligne_alarme_son.visible Shipheart_formulaire_label { text: qsTr("Alarme sur LED") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Alarme_led width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onCheckedChanged: { if (!flag_init && champ_formulaire_Alarme_led.checked) // Si on veut une alarme sur led... { if (!champ_formulaire_Alarme_message.checked) { champ_formulaire_Alarme_message.checked = true; // ... il FAUT que l'alarme par message soit validée boite_information.niveau = 0; boite_information.imageTitreSource = "/images/ampoule.png" boite_information.message = qsTr("La validation des alarmes sur LED a nécessité de valider également l'affichage des messages liés à cet évènement.

Cet affichage est en effet nécessaire au fonctionnement des alarmes sur LED, afin de pouvoir les acquitter."); boite_information.alignementMessage = Text.AlignHCenter boite_information.open(); } } } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Alarme_soutien Rectangle { id: ligne_alarme_soutien width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" // visible: ligne_alarme_son.visible visible: false Shipheart_formulaire_label { text: qsTr("Alarme sur sortie(s) de soutien") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Alarme_soutien width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onCheckedChanged: { if (!flag_init && champ_formulaire_Alarme_led.checked) // Si on veut une alarme sur soutien... { if (!champ_formulaire_Alarme_message.checked) { champ_formulaire_Alarme_message.checked = true; // ... il FAUT que l'alarme par message soit validée boite_information.niveau = 0; boite_information.imageTitreSource = "/images/ampoule.png" boite_information.message = qsTr("La validation des alarmes sur sortie(s) de soutien a nécessité de valider également l'affichage des messages liés à cet évènement.

Cet affichage est en effet nécessaire au fonctionnement des alarmes sur sortie(s) de soutien, afin de pouvoir les acquitter."); boite_information.alignementMessage = Text.AlignHCenter boite_information.open(); } } } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Alarme_source Rectangle { id: ligne_alarme_source width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: ligne_alarme_son.visible Shipheart_formulaire_label { text: qsTr("Alarme sur la source") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Alarme_source width: parent.width * (1 - pourcentage_largeur_labels_formulaire) } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Alarme_message Rectangle { id: ligne_alarme_message_checkbox width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: ligne_alarme_son.visible Shipheart_formulaire_label { text: qsTr("Affichage message sur ShipBase") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Alarme_message width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onCheckedChanged: { if (!flag_init && !champ_formulaire_Alarme_message.checked) // Si l'alarme par message est dévalidée... { if (champ_formulaire_Alarme_son.checked || champ_formulaire_Alarme_led.checked || champ_formulaire_Alarme_soutien.checked) { champ_formulaire_Alarme_son.checked = false; // ... on est obligé de dévaliser l'alarme son champ_formulaire_Alarme_led.checked = false; // ... et l'alarme LED champ_formulaire_Alarme_soutien.checked = false; // ... et l'alarme soutien car on ne pourrait pas ensuite les acquitter... boite_information.niveau = 0; boite_information.imageTitreSource = "/images/ampoule.png" boite_information.message = qsTr("La dévalidation de l'affichage des messages a nécessité de dévalider également :
L'affichage de message est en effet nécessaire à leur fonctionnement, afin de pouvoir les acquitter."); boite_information.alignementMessage = Text.AlignLeft boite_information.open(); } } } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Texte_message Rectangle { id: ligne_alarme_message width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) implicitHeight: champ_formulaire_Texte_message.implicitHeight height: visible ? undefined : 0 // Le 'undefined' permet de ne pas perturber le 'implicitHeight' en temps normal. Le 0 mpermet de forcer la hauteur si non visible. color: "transparent" visible: ligne_alarme_message_checkbox.visible && champ_formulaire_Alarme_message.checked Shipheart_formulaire_label { text: qsTr("Texte du message à afficher") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_textarea { id: champ_formulaire_Texte_message width: parent.width * (1 - pourcentage_largeur_labels_formulaire) horizontalAlignment: Text.AlignJustify wrapMode: Label.Wrap } } //------------------------------------------------------------------------------- // Ligne de formulaire : Alarme_sms Rectangle { id: ligne_alarme_sms_checkbox width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" // visible: ligne_alarme_son.visible visible: false Shipheart_formulaire_label { text: qsTr("Emission SMS") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Alarme_sms width: parent.width * (1 - pourcentage_largeur_labels_formulaire) } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Texte_sms Rectangle { id: ligne_alarme_sms width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) implicitHeight: champ_formulaire_Texte_sms.implicitHeight height: visible ? undefined : 0 // Le 'undefined' permet de ne pas perturber le 'implicitHeight' en temps normal. Le 0 mpermet de forcer la hauteur si non visible. color: "transparent" // visible: ligne_alarme_sms_checkbox.visible // && champ_formulaire_Alarme_sms_checkbox.checked visible: false Shipheart_formulaire_label { text: qsTr("Texte du SMS à envoyer") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_textarea { id: champ_formulaire_Texte_sms width: parent.width * (1 - pourcentage_largeur_labels_formulaire) horizontalAlignment: Text.AlignJustify wrapMode: Label.Wrap } } //------------------------------------------------------------------------------- // Ligne de formulaire : Alarme_email Rectangle { id: ligne_alarme_email_checkbox width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" // visible: ligne_alarme_son.visible visible: false Shipheart_formulaire_label { text: qsTr("Emission Email") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Alarme_email width: parent.width * (1 - pourcentage_largeur_labels_formulaire) } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Texte_email Rectangle { id: ligne_alarme_email width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) implicitHeight: champ_formulaire_Texte_email.implicitHeight height: visible ? undefined : 0 // Le 'undefined' permet de ne pas perturber le 'implicitHeight' en temps normal. Le 0 mpermet de forcer la hauteur si non visible. color: "transparent" // visible: ligne_alarme_email_checkbox.visible // && champ_formulaire_Alarme_email_checkbox.checked visible: false Shipheart_formulaire_label { text: qsTr("Texte de l'email à envoyer") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_textarea { id: champ_formulaire_Texte_email width: parent.width * (1 - pourcentage_largeur_labels_formulaire) horizontalAlignment: Text.AlignJustify wrapMode: Label.Wrap } } //=========================================================== // Séparation : //=========================================================== Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: 20 color: "transparent" Shipheart_formulaire_ligne_separation { id: ligne_separation_bas_alarme visible: zone_conditions_horaires.visible haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse epaisseur_ligne: 3 force: shipheart_formulaire_ligne_separation_force_elevee } } Shipheart_titre_2 { titre:qsTr("Action sur circuits"); hauteur: shipheart_hauteur_bandeau_haut visible: zone_conditions_horaires.visible width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) } //=========================================================== // Actions : //=========================================================== Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: (grille_actions.model.count + 1) * (hauteur_ligne_formulaire + spacing) color: "transparent" visible: zone_conditions_horaires.visible ListView { id: grille_actions width: parent.width height: parent.height spacing: 5 interactive: false // SDIR # 223 : Permet de bloquer le 'flickable' de la ListView et facilite le déroulé de la liste principale (sinon, on a deux listes, l'une dans l'autre et le déroulé peut-être compliqué parfois). model: ListModel { } delegate: Rectangle { id: bouton_action // Ligne de nom de famille : Shipheart_titre_3 {titre:model.nom_famille; hauteur: hauteur_ligne_formulaire; visible: (model.nom_famille !== "")} width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: ligne_alarme_son.visible Shipheart_formulaire_label { visible: (model.nom_famille === "") text: model.nom_circuit width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_bouton { visible: (model.nom_famille === "") titre: (model.action === -2) ? // Affichage en clair de l'action configure pour ce circuit qsTr("Aucune") : (model.action === -1) ? qsTr("Le circuit \"bascule\" ") : (model.action === 0) ? qsTr("Le circuit passe à OFF") : qsTr("Le circuit passe à ON") + ( (model.action === 100) ? "" : (" @" + model.action + "%") ) actif: (model.action !== -2) // Affichzg du bouton en mode ACTIF si l'action est différente de Aucune couleur_titre: (model.action !== -2) ? couleur_blanc_casse : couleur_gris_moyen width: parent.width * (1 - pourcentage_largeur_labels_formulaire) x: parent.width * pourcentage_largeur_labels_formulaire MouseArea{ anchors.fill : parent onClicked: { shipheart_clic(); // Ouverture de la boite de dialogue pour sélectionner une action sur le circuit : if ((nombre_action_circuits < shipheart_max_nombre_action_circuits_par_event) || // Si le nombre d'actions sur circuits n'a pas atteint son maxi... (model.action > -2)) // ... ou que le circuit sélectionné est déjà affecté à une action (autre que "Aucune") : { index_circuit_en_cours = index; // Permet de retrouver l'index à mettre à jour au retour du popup boite_selection_action_circuit.nom_circuit = model.nom_circuit; // Permet l'affichage du nom du circuit dans le popup boite_selection_action_circuit.mode_cde = model.mode_cde_circuit; // Permet d'afficher les valeurs intermédiaires de consigne (10%, 25%,...) dans le cas d'un circuit configuré en Variateur boite_selection_action_circuit.action_en_cours = model.action; // Contient l'action actuellement configurée boite_selection_action_circuit.open(); } // Ouverture de la boite d'info si le nombre d'actions sur circuits est trop élevée : else { boite_information.niveau = 1; boite_information.imageTitreSource = "/images/attention.png" boite_information.message = qsTr("Le nombre de circuits commandés par un évènement est limité à %1.

Vous ne pouvez pas ajouter d'action sur un nouveau circuit avant d'en avoir supprimé préalablement.").arg(shipheart_max_nombre_action_circuits_par_event); boite_information.alignementMessage = Text.AlignHCenter boite_information.open(); } } } } Shipheart_formulaire_ligne_separation { visible: (model.nom_famille === "") haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } } } // Fin de Actions } // Fin de Grille principale } } //------------------------------------------------------- // Ecran Droite : //------------------------------------------------------- Rectangle { id: zone_affichage_droite x: zone_affichage_haut_gauche.width + espace_colonnes_principales y: shipheart_hauteur_bandeau_haut; width: (shipheart_largeur_page * (1 - pourcentage_largeur_colonne_gauche)) - (espace_colonnes_principales / 2) height: (affichage_hauteur_utile * pourcentage_hauteur_ligne_haut) - (espace_lignes_principales / 2); color: "transparent" Column { anchors.fill: parent spacing: 10 //....................................................... // Bouton Enregistrer/créer : //....................................................... Rectangle { id: bouton_enregistrer_creer width: parent.width height: hauteur_bouton_droit color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton visible: // !clavier.active && // Si le clavier est déplié, // SDIR #255 (champ_formulaire_Nom.text !== "") && // ... ou si le nom est vide, (champ_formulaire_Type_source.currentIndex !== 0) && // ... ou si aucune affectation à un capteur n'a été faite, ((type_source !== 0) || ((grille_conditions_horaires.model.count - 1) > 0)) // ... ou si l'affectations est "Condition horaire seule" et qu'aucune condition horaire n'a été complètement renseignée. Text { anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } font.pixelSize: 20 text: (id_event === 0) ? qsTr("Créer l'évènement") : qsTr("Enregistrer") color: couleur_blanc_casse } MouseArea { anchors.fill: parent onClicked: { shipheart_clic(); if (id_event !== 0) mise_a_jour_event(); // Mise à jour des données saisies dans la BDD et reconfiguration par l'application pour prise en compte. else creation_event(); timer_tempo_reconfiguration.restart(); } } } //....................................................... // Bouton de suppression //....................................................... Rectangle { width: parent.width height: hauteur_bouton_droit color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton visible: (id_event !== 0) Rectangle { // Barre grandissante pour montrer durée d'appui vs tempo nécessaire : width: (valeur_timer_appui_long / shipheart_mouse_press_and_hold_interval_tres_long) * parent.width height: parent.height color: couleur_rouge_transparent radius: shipheart_rayon_bouton visible: mousearea_bouton_supprimer.pressed } Text { anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } font.pixelSize: 20 text: qsTr("Supprimer") color: couleur_blanc_casse } MouseArea { id: mousearea_bouton_supprimer anchors.fill: parent onPressed: { // Déclenché lors de l'appui inital timer_appui_long.running = true; valeur_timer_appui_long = 0; shipheart_clic(); } onClicked: { // Déclenché si l'appui n'a pas été suffisement long pour avoir un Press&Hold : timer_appui_long.running = false; valeur_timer_appui_long = 0; } onExited: { // Déclenché si le doigt sort de la zone du bouton (sinon, on continue à compter alors qu'on est sorti de la zone et même relaché le doigt !!) timer_appui_long.running = false; valeur_timer_appui_long = 0; } } } //....................................................... // Timer de reconfiguration : //....................................................... Timer { id: timer_tempo_reconfiguration interval: 250 // Cette tempo n'est utilisée que pour le premier cycle triggeredOnStart: false running: false repeat: true onTriggered: { if (bdd.check_fin_configuration()) { timer_tempo_reconfiguration.stop(); stackView.pop(); // Retour à la page de config des évènements } else timer_tempo_reconfiguration.interval = 100 // Tempo plus courte pour les lectures suivantes } } } } //------------------------------------------------------- // 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 * pourcentage_bandeau_bas_largeur_zone_retour) - (2 * parent.padding) height: shipheart_hauteur_bandeau_bas - parent.topPadding - parent.bottomPadding; radius: shipheart_rayon_bouton 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 onClicked: { shipheart_clic(); stackView.pop() } } } } //------------------------------------------------------- // Boite de sélection d'une condition horaire : //------------------------------------------------------- Shipheart_boite_dialogue_condition_horaire { id: boite_selection_condition_horaire boutonOk: true boutonAnnuler: true onClicked: { //console.log("Le Bouton [" + bouton + "] est appuyé"); //------------------- // Bouton Ok : //------------------- if (bouton === shipheart_boite_dialogue_bouton_1) { //console.log("Jour = " + jour + ", Heure="+heure+" et Minute="+minute); //---------------------------------------- // Cas d'une mise à jour : if (index_condition_horaire_en_cours !== -1) { // Mise à jour de l'entrée du modèle avec les données saisies : grille_conditions_horaires.model.set(index_condition_horaire_en_cours, { "libelle": Fonctions_date_heure.nom_jour_semaine(jour) + " @ " + Fonctions_date_heure.nom_heure(heure, minute), "jour": jour, "heure": heure, "minute": minute} ); } //---------------------------------------- // Cas de l'ajout d'une condition : else { grille_conditions_horaires.model.insert( (grille_conditions_horaires.model.count - 1), { // Insertion juste avant le '+' "libelle": Fonctions_date_heure.nom_jour_semaine(jour) + " @ " + Fonctions_date_heure.nom_heure(heure, minute), "jour": jour, "heure": heure, "minute": minute, "bouton": false }); } } //------------------- // Bouton Annuler : //------------------- if (bouton === shipheart_boite_dialogue_bouton_2) ; // Aucune action... //------------------- // Bouton Supprimer : //------------------- if (bouton === shipheart_boite_dialogue_bouton_3) { grille_conditions_horaires.model.remove(index_condition_horaire_en_cours, 1); } boite_selection_condition_horaire.close(); // Dans tous les cas... (notamment si ANNULER) } } //------------------------------------------------------- // Boite de sélection action circuit : //------------------------------------------------------- Shipheart_boite_dialogue_action_circuit { id: boite_selection_action_circuit boutonAnnuler: true boutonAnnulerTexte: "Annuler" onClicked: { //console.log("Le Bouton [" + bouton + "] est appuyé"); if (bouton === shipheart_boite_dialogue_bouton_1) { //console.log("Action = " + action); // Mise à jour du nombre d'action sur circuits : if (grille_actions.model.get(index_circuit_en_cours).action === -2) // Si l'action précédente du circuit était "Aucune"... { if (action > -2) nombre_action_circuits ++; // ... et que la nouvelle est toggle ou une consigne, on incrémente le nb d'actions. } else // Si l'action précédente n'était PAS "Aucune"... { if (action === -2) nombre_action_circuits --; // ... et que la nouvelle est "Aucune", on décrémente le nb d'actions } // Mise à jour de la nouvelle action dans la grille : grille_actions.model.set(index_circuit_en_cours, {"action": action}); } boite_selection_action_circuit.close(); // Dans tous les cas... (notamment si ANNULER) } } //------------------------------------------------------- // Boite de validation : //------------------------------------------------------- Shipheart_boite_dialogue { id: boite_information } //=========================================================== // Busy Indicator : //=========================================================== Shipheart_busy_indicator { id: busy_indicator running: timer_tempo_reconfiguration.running } // Note : il est inutile de prévoir un Mousearea pour sortir de l'économiseur sur cette page puisqu'il // est systématiquement bloqué pour toutes les pages lancées depuis 'Paramètres Avancés'. //============================================================================================================= // Init de la page //============================================================================================================= function init_page() { var req, res; var i; //console.log("Id de l'évènement = " + id_event); //--------------------------------------------------------------------------------------- // Caractéristiques de l'évènement en cours : //--------------------------------------------------------------------------------------- nom = ""; type_source = -1; id_source = 0; id_variable = 0; test = 0; seuil = 0; tempo = 0; champ_formulaire_Seuil.text = 0; champ_formulaire_Tempo.text = 0; champ_formulaire_Visibilite.checked = false; conditions_horaires = ""; champ_formulaire_Alarme_son.checked = false; champ_formulaire_Alarme_led.checked = false; champ_formulaire_Alarme_soutien.checked = false; champ_formulaire_Alarme_source.checked = false; champ_formulaire_Texte_sms.text = ""; champ_formulaire_Alarme_sms.checked = false; champ_formulaire_Texte_email.text = ""; champ_formulaire_Alarme_email.checked = false; champ_formulaire_Texte_message.text = ""; champ_formulaire_Alarme_message.checked = false; action_circuits = ""; if (id_event > 0) // Cas d'une modification de capteur existant : { req = 'SELECT '; req += 'Visibilite, '; req += 'Nom, '; req += 'Type_Source, '; req += 'ID_Source, '; req += 'ID_Variable, '; req += 'Test, '; req += 'Seuil, '; req += 'Tempo, '; req += 'Conditions_horaires, '; req += 'Alarme_son, '; req += 'Alarme_led, '; req += 'Alarme_soutien, '; req += 'Alarme_source, '; req += 'Alarme_message, '; req += 'Alarme_sms, '; req += 'Alarme_email, '; req += 'Texte_message, '; req += 'Texte_sms, '; req += 'Texte_email, '; req += 'Action_circuits '; req += 'FROM TB_Events WHERE Cle_primaire=' + id_event + ' '; //console.log("Requête = [ " + req + "; ]"); res = bdd.requete_unique(req); // Récupération des données : i = 0; champ_formulaire_Visibilite.checked = (Number(res[i ++]) === 1) ? false : true; // Comme il s'agit d'un intitulé "masquage", on inverse la logique nom = res[i ++]; type_source = Number(res[i ++]); id_source = Number(res[i ++]); id_variable = Number(res[i ++]); test = Number(res[i ++]); seuil = Number(res[i ++]); tempo = Number(res[i ++]); conditions_horaires = res[i ++]; champ_formulaire_Alarme_son.checked = (Number(res[i ++]) === 1) ? true : false; champ_formulaire_Alarme_led.checked = (Number(res[i ++]) === 1) ? true : false; champ_formulaire_Alarme_soutien.checked = (Number(res[i ++]) === 1) ? true : false; champ_formulaire_Alarme_source.checked = (Number(res[i ++]) === 1) ? true : false; champ_formulaire_Alarme_message.checked = (Number(res[i ++]) === 1) ? true : false; champ_formulaire_Alarme_sms.checked = (Number(res[i ++]) === 1) ? true : false; champ_formulaire_Alarme_email.checked = (Number(res[i ++]) === 1) ? true : false; champ_formulaire_Texte_message.text = res[i ++]; champ_formulaire_Texte_sms.text = res[i ++]; champ_formulaire_Texte_email.text = res[i ++]; action_circuits = res[i ++]; } // Remplissage des modèles de type texte : champ_formulaire_Nom.text = nom; champ_formulaire_Seuil.text = seuil; champ_formulaire_Tempo.text = tempo; // Remplissage des différents modèles, dans l'ordre des priorités : mise_a_jour_type_source(); flag_init = false; // Indique que l'init est terminée } //============================================================================================================= // MAJ du type de source //============================================================================================================= function mise_a_jour_type_source() { var i; // Effacement du modèle et premier enregistrement avec 'Non défini' : champ_formulaire_Type_source.model.clear(); champ_formulaire_Type_source.model.append( { "valeur": -1, "texte": qsTr("Non défini"), "actif": true }); champ_formulaire_Type_source.model.append( { "valeur": 0, "texte": qsTr("Condition horaire seule"), "actif": true }); champ_formulaire_Type_source.model.append( { "valeur": shipheart_source_mesure_circuit, "texte": qsTr("Circuit"), "actif": true }); champ_formulaire_Type_source.model.append( { "valeur": shipheart_source_mesure_capteur, "texte": qsTr("Capteur"), "actif": true }); champ_formulaire_Type_source.model.append( { "valeur": shipheart_source_mesure_reservoir, "texte": qsTr("Réservoir"), "actif": true }); champ_formulaire_Type_source.model.append( { "valeur": shipheart_source_mesure_batterie, "texte": qsTr("Batterie"), "actif": true }); // Mise à jour de l'index courant du modèle champ_formulaire_Type_source : i = recherche_index_valeur_modele(type_source, champ_formulaire_Type_source.model, "Type_source"); if (i === -1) champ_formulaire_Type_source.currentIndex = recherche_index_valeur_modele(-1, champ_formulaire_Type_source.model, "Type_source"); else champ_formulaire_Type_source.currentIndex = i; // Appel du remplissage des modèles de niveau inférieur si cela est possible : if (type_source > 0) mise_a_jour_source(); else if (type_source === 0) mise_a_jour_parametres_generaux(); // Conditions horaires seulement... } //============================================================================================================= // MAJ de la source //============================================================================================================= function mise_a_jour_source() { var req, res; var nb; var i; // Effacement du modèle et premier enregistrement avec 'Non défini' : champ_formulaire_Source.model.clear(); champ_formulaire_Source.model.append( { "valeur": 0, "texte": qsTr("Non défini"), "actif": true }); switch(type_source) { case shipheart_source_mesure_circuit: req = 'SELECT Cle_primaire, '; req += 'Nom, '; req += 'Nom_famille '; req += 'FROM TB_Circuits, '; req += ' (SELECT Cle_primaire AS Cle_famille, Nom AS Nom_famille, Priorite_affichage AS Priorite_famille FROM TB_Familles WHERE Type_source=' + shipheart_type_source_circuits + ') AS TB_Familles '; req += ' WHERE ID_Famille=Cle_famille '; req += ' ORDER BY Priorite_famille, ABS(Priorite_affichage_accueil)'; break; case shipheart_source_mesure_capteur: req = 'SELECT Cle_primaire, '; req += 'Nom, '; req += 'Nom_famille '; req += 'FROM TB_Capteurs, '; req += ' (SELECT Cle_primaire AS Cle_famille, Nom AS Nom_famille, Priorite_affichage AS Priorite_famille FROM TB_Familles WHERE Type_source=' + shipheart_type_source_capteurs + ') AS TB_Familles '; req += ' WHERE ID_Famille=Cle_famille '; req += ' ORDER BY Priorite_famille, ABS(Priorite_affichage_accueil)'; break; case shipheart_source_mesure_reservoir: req = 'SELECT Cle_primaire, '; req += 'Nom, '; req += 'Nom_famille '; req += 'FROM TB_Reservoirs, '; req += ' (SELECT Cle_primaire AS Cle_famille, Nom AS Nom_famille, Priorite_affichage AS Priorite_famille FROM TB_Familles WHERE Type_source=' + shipheart_type_source_reservoirs + ') AS TB_Familles '; req += ' WHERE ID_Famille=Cle_famille '; req += ' ORDER BY Priorite_famille, ABS(Priorite_affichage_accueil)'; break; case shipheart_source_mesure_batterie: req = 'SELECT Cle_primaire, '; req += 'Nom, '; req += '"" AS Nom_famille '; // Permet de passer le traitement des familles sans erreur et ajout de ligne inutile (les batteries n'ont pas de notion de famille) req += 'FROM TB_Batteries '; req += ' ORDER BY ABS(Priorite_affichage_accueil)'; break; default: table = ""; break; } if (req !== "") { //console.log("Requête = [ " + req + "; ]"); nb = bdd.requete(req); var prec_famille = ""; for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { // Ajout de le ligne de famille : if (prec_famille !== res[2]) { champ_formulaire_Source.model.append( { "groupe": true, "valeur": 0, "texte": res[2], "actif": false }); prec_famille = res[2]; } // Ajout de la ligne normale : champ_formulaire_Source.model.append( { "groupe": false, "valeur": Number(res[0]), "texte": res[1], "actif": true }); } } } // Mise à jour de l'index courant du modèle : i = recherche_index_valeur_modele(id_source, champ_formulaire_Source.model, "id_source"); if (i === -1) champ_formulaire_Source.currentIndex = recherche_index_valeur_modele(0, champ_formulaire_Source.model, "id_source"); else champ_formulaire_Source.currentIndex = i; // Appel du remplissage des modèles de niveau inférieur si cela est possible : if (id_source !== 0) mise_a_jour_variable(); } //============================================================================================================= // MAJ de la variable à utiliser //============================================================================================================= function mise_a_jour_variable() { var req, res; var nb; var i; var libelle; // Effacement du modèle et premier enregistrement avec 'Non défini' :: champ_formulaire_Variable.model.clear(); champ_formulaire_Variable.model.append( { "valeur": 0, "texte": qsTr("Non défini"), "unite": "", "actif": true }); switch(type_source) { //---------------------------------------- case shipheart_source_mesure_circuit: // Recherche du type de circuit : req = 'SELECT Type FROM TB_Modules_config WHERE Adresse_k_bus IN (SELECT Adresse_module FROM TB_Circuits WHERE Cle_primaire=' + id_source + ')'; //console.log("Requête = [ " + req + "; ]"); res = bdd.requete_unique(req); var type_circuit = Number(res[0]); // Recherche des entrées de TB_Variables applicables à la source sélectionnée : req = "SELECT Cle_primaire, Unite, Code FROM TB_Variables WHERE Type=" + type_source + "; "; //console.log("Requête = [ " + req + "; ]"); nb = bdd.requete(req); for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { switch(res[2]) { //--------------------- case "Circ_tension": if (type_circuit === shipheart_type_module_shippower4AC) continue; break; //--------------------- case "Circ_frequence": if (type_circuit !== shipheart_type_module_shippower4AC) continue; break; //--------------------- case "Circ_tension_secteur": if (type_circuit !== shipheart_type_module_shippower4AC) continue; break; } libelle = Fonctions.nom_variable(res[2]); champ_formulaire_Variable.model.append( { "valeur": Number(res[0]), "texte": libelle, "unite": res[1], "actif": true }); } } // Mise à jour du flag de test binaire : flag_test_binaire = false; break; //---------------------------------------- case shipheart_source_mesure_capteur: // Recherche de la variable du capteur : req = "SELECT ID_Variable, Type_entrees FROM TB_Capteurs WHERE Cle_primaire=" + id_source + "; "; //console.log("Requête = [ " + req + "; ]"); res = bdd.requete_unique(req); var type = Number(res[1]); // Recherche des informations de la varoable du capteur dans TB_Variables : req = "SELECT Cle_primaire, Nom, Unite FROM TB_Variables WHERE Cle_primaire=" + Number(res[0]) + "; "; //console.log("Requête = [ " + req + "; ]"); res = bdd.requete_unique(req); champ_formulaire_Variable.model.append( { "valeur": Number(res[0]), "texte": res[1], "unite": res[2], "actif": true }); // Mise à jour de la variable car on n'a pas le choix : id_variable = Number(res[0]); // Mise à jour du flag de test binaire : if ((type == shipheart_capteur_type_entrees_aux) || (type == shipheart_capteur_type_entrees_calculee_booleen) ) flag_test_binaire = true; else flag_test_binaire = false; break; //---------------------------------------- case shipheart_source_mesure_reservoir: // Recherche des entrées de TB_Variables applicables à la source sélectionnée : req = "SELECT Cle_primaire, Nom, Unite FROM TB_Variables WHERE Code='Res_niveau'; "; //console.log("Requête = [ " + req + "; ]"); res = bdd.requete_unique(req); champ_formulaire_Variable.model.append( { "valeur": Number(res[0]), "texte": res[1], "unite": res[2], "actif": true }); // Mise à jour de la variable car on n'a pas le choix : id_variable = Number(res[0]); // Mise à jour du flag de test binaire : flag_test_binaire = false; break; //---------------------------------------- case shipheart_source_mesure_batterie: // Recherche du type de capteur de batterie : req = "SELECT Type_entrees FROM TB_Batteries WHERE Cle_primaire=" + id_source + "; "; //console.log("Requête = [ " + req + "; ]"); res = bdd.requete_unique(req); var type_entrees = Number(res[0]); // Recherche des entrées de TB_Variables applicables à la source sélectionnée : req = "SELECT Cle_primaire, Unite, Code FROM TB_Variables WHERE Type=" + type_source + "; "; //console.log("Requête = [ " + req + "; ]"); nb = bdd.requete(req); for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { switch(res[2]) { //--------------------- case "Batt_temperature": if (type_entrees !== shipheart_capteur_type_entrees_ibs) continue; break; //--------------------- case "Batt_courant_differentiel": if (type_entrees !== shipheart_capteur_type_entrees_ibs) continue; break; //--------------------- case "Batt_courant_charge": if (type_entrees !== shipheart_capteur_type_entrees_ibs) continue; break; //--------------------- case "Batt_soh": if (type_entrees !== shipheart_capteur_type_entrees_ibs) continue; break; //--------------------- /* case "Batt_autonomie": if (type_entrees !== shipheart_capteur_type_entrees_ibs) continue; break; */ } libelle = Fonctions.nom_variable(res[2]); champ_formulaire_Variable.model.append( { "valeur": Number(res[0]), "texte": libelle, "unite": res[1], "actif": true }); } } // Mise à jour du flag de test binaire : flag_test_binaire = false; break; //---------------------------------------- default: break; } // Mise à jour de l'index courant du modèle : i = recherche_index_valeur_modele(id_variable, champ_formulaire_Variable.model, "id_variable"); if (i === -1) champ_formulaire_Variable.currentIndex = recherche_index_valeur_modele(0, champ_formulaire_Variable.model, "id_variable"); else champ_formulaire_Variable.currentIndex = i; // Mise à jour de l'unité correspondant à la variable en cours : seuil_unite = champ_formulaire_Variable.model.get(champ_formulaire_Variable.currentIndex).unite; // Appel du remplissage des modèles de niveau inférieur si cela est possible : if (id_variable !== 0) mise_a_jour_parametres_generaux(); } //============================================================================================================= // MAJ des paramètres généraux //============================================================================================================= function mise_a_jour_parametres_generaux() { var i; //----------------------------------------------- // Test : //----------------------------------------------- champ_formulaire_Test.model.clear(); champ_formulaire_Test.model.append( { "valeur": 0, "texte": qsTr("Non défini"), "actif": true }); if (flag_test_binaire) { champ_formulaire_Test.model.append( { "valeur": 5, "texte": qsTr("Passage à actif"), "actif": true }); champ_formulaire_Test.model.append( { "valeur": 1, "texte": qsTr("Passage à inactif"), "actif": true }); } else { champ_formulaire_Test.model.append( { "valeur": 1, "texte": qsTr("< au seuil"), "actif": true }); champ_formulaire_Test.model.append( { "valeur": 2, "texte": qsTr("≤ au seuil"), "actif": true }); champ_formulaire_Test.model.append( { "valeur": 3, "texte": qsTr("= au seuil"), "actif": true }); champ_formulaire_Test.model.append( { "valeur": 4, "texte": qsTr("≥ au seuil"), "actif": true }); champ_formulaire_Test.model.append( { "valeur": 5, "texte": qsTr("> au seuil"), "actif": true }); } // Mise à jour de l'index courant du modèle : i = recherche_index_valeur_modele(test, champ_formulaire_Test.model, "Test"); if (i === -1) champ_formulaire_Test.currentIndex = recherche_index_valeur_modele(0, champ_formulaire_Test.model, "Test"); else champ_formulaire_Test.currentIndex = i; //----------------------------------------------- // Condition horaire : //----------------------------------------------- var conditions; var condition var jour; var heure; var minute; grille_conditions_horaires.model.clear(); // Décomposition de la la chaine de conditions : if (conditions_horaires !== "") { conditions = conditions_horaires.split(';'); for (i = 0; i < conditions.length; i ++) { condition = conditions[i].split('/'); if (condition.length === 3) { jour = Number(condition[0]); heure = Number(condition[1]); minute = Number(condition[2]); //console.log("Condition #"+(i+1)+" : jour="+Fonctions_date_heure.nom_jour_semaine(jour)+" à "+ Fonctions_date_heure.nom_heure(heure, minute) ); grille_conditions_horaires.model.append( { "libelle": Fonctions_date_heure.nom_jour_semaine(jour) + " @ " + Fonctions_date_heure.nom_heure(heure, minute), "jour": jour, "heure": heure, "minute": minute, "bouton": false }); } } } // Ajout du bouton "+" : // NB : le bouton est toujours créé [permet simplement qu'il soit réaffiché dynamiquement si on supprime des conditions], // mais n'est affiché que si le nombre de conditions horaires n'est pas trop important. grille_conditions_horaires.model.append( { "libelle": "+", "jour": 0, "heure": 0, "minute": 0, "bouton": true }); // Fin des condtions horaires mise_a_jour_actions(); } //============================================================================================================= // MAJ du modèle des actions //============================================================================================================= function mise_a_jour_actions() { var req, res; var nb; var i; var chaines; var liste_circuits = []; var liste_actions = []; grille_actions.model.clear(); nombre_action_circuits = 0; // Décomposition de la la chaine des actions sur les circuits : if (action_circuits !== "") { chaines = action_circuits.split(';'); i = 0; for (var chaine of chaines) // Balayage de tous les couples 'ID_circuit/Action' { // Récupération des informations sur la commande : var couple = chaine.split('/'); // Recherche des 2 éléments du couple 'ID_circuit/Action' liste_circuits[i] = Number(couple[0]); liste_actions[i] = Number(couple[1]); i ++; if ((liste_actions[i] >= -1) && (liste_actions[i] <= 100)) nombre_action_circuits ++; } } // NB : l'utilisation de ABS dans la requete ci-dessous permet de trier correctement même les capteurs masqués... req = 'SELECT Cle_primaire, '; req += 'Nom, '; req += 'Mode_commande, '; req += 'Nom_famille '; req += 'FROM TB_Circuits, '; req += ' (SELECT Cle_primaire AS Cle_famille, Nom AS Nom_famille, Priorite_affichage AS Priorite_famille FROM TB_Familles WHERE Type_source=' + shipheart_type_source_circuits + ') AS TB_Familles '; req += ' WHERE ID_Famille=Cle_famille '; req += ' ORDER BY Priorite_famille, ABS(Priorite_affichage_accueil)' //console.log("req = [ " + req + " ;]"); nb = bdd.requete(req); var prec_famille = ""; for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { // Recherche de l'index dans la liste des actions déjà existantes : var index = liste_circuits.indexOf(Number(res[0])); // Si l'ID du circuit est trouvé dans la liste, l'index dans la liste est retournée. Sinon, le retour est -1. // Ajout de le ligne de famille : if (prec_famille !== res[3]) { grille_actions.model.append( { "nom_famille": res[3], "id_circuit": 0, "nom_circuit": "", "mode_cde_circuit": 0, "action": 0 }); prec_famille = res[3]; } // Entrée normale : grille_actions.model.append( { "nom_famille": "", "id_circuit": Number(res[0]), "nom_circuit": res[1], "mode_cde_circuit": Number(res[2]), "action": (index !== -1) ? liste_actions[index] : -2 }); // '-2' est la valeur de "Aucune action" } } } //============================================================================================================= // Mise à jour des valeurs saisies de l'évènement //============================================================================================================= function mise_a_jour_event() { var req, res; var i; var flag_first; nom = champ_formulaire_Nom.text; // type_source = champ_formulaire_Type_source.model.get(champ_formulaire_Type_source.currentIndex).valeur; // id_source = champ_formulaire_Source.model.get(champ_formulaire_Source.currentIndex).valeur; // id_variable = champ_formulaire_Variable.model.get(champ_formulaire_Variable.currentIndex).valeur; // test = champ_formulaire_Test.model.get(champ_formulaire_Test.currentIndex).valeur; seuil = champ_formulaire_Seuil.text; tempo = champ_formulaire_Tempo.text; //---------------------------------------------------- // Traitement particulier des Tests de type binaire : if (flag_test_binaire) seuil = 0.5 //---------------------------------------------------- // Création de la chaine de conditions horaires, si besoin : conditions_horaires = ""; if ((grille_conditions_horaires.model.count - 1) > 0) // Le '-1' permet de neutraliser le bouton '+' qui est toujours présents (mais parfois, pas affiché) { flag_first = true; for (i = 0; i < grille_conditions_horaires.model.count; i ++) // Parcours du modèle existant { if (!grille_conditions_horaires.model.get(i).bouton) // Ne prend pas en compte le bouton '+' { if (flag_first) flag_first = false; else conditions_horaires += ";" conditions_horaires += grille_conditions_horaires.model.get(i).jour; conditions_horaires += "/"; conditions_horaires += grille_conditions_horaires.model.get(i).heure; conditions_horaires += "/"; conditions_horaires += grille_conditions_horaires.model.get(i).minute; } } } else console.log("Aucune condition horaire n'a été configurée. La chaine 'Conditions_horaires' est laissée vide.") //console.log("Conditions horaires = [ " + conditions_horaires + " ]") //---------------------------------------------------- // Calcul de la chaine des actions sur les circuits : action_circuits = ""; flag_first = true; for (i = 0; i < grille_actions.model.count; i ++) // Parcours du modèle existant { if ((grille_actions.model.get(i).nom_famille === "") && // On ne prend pas en compte les entêtes de famille... (grille_actions.model.get(i).action !== -2)) // ... ni les circuits pour lesquels l'action vaut '-2', qui signifie "Aucune action" { if (flag_first) flag_first = false; else action_circuits += ";" action_circuits += grille_actions.model.get(i).id_circuit; action_circuits += "/"; action_circuits += grille_actions.model.get(i).action; } } //console.log("Action sur circuits = [ " + action_circuits + " ]") //---------------------------------------------------- // Mise à jour de l'évènement dans la BDD : req = 'UPDATE TB_Events SET '; req += ' Visibilite=' + (champ_formulaire_Visibilite.checked ? 0 : 1) + ', '; // Comme il s'agit d'un intitulé "masquage", on inverse la logique req += ' Nom="' + nom + '", '; req += ' Type_source=' + type_source + ', '; req += ' ID_Source=' + id_source + ', '; req += ' ID_Variable=' + id_variable + ', '; req += ' Test=' + test + ', '; req += ' Seuil=' + seuil + ', '; req += ' Tempo=' + tempo + ', '; req += ' Conditions_horaires="' + conditions_horaires + '", '; req += ' Alarme_son=' + (champ_formulaire_Alarme_son.checked ? 1 : 0) + ', '; req += ' Alarme_led=' + (champ_formulaire_Alarme_led.checked ? 1 : 0) + ', '; req += ' Alarme_soutien=' + (champ_formulaire_Alarme_soutien.checked ? 1 : 0) + ', '; req += ' Alarme_source=' + (champ_formulaire_Alarme_source.checked ? 1 : 0) + ', '; req += ' Alarme_message=' + (champ_formulaire_Alarme_message.checked ? 1 : 0) + ', '; req += ' Alarme_sms=' + (champ_formulaire_Alarme_sms.checked ? 1 : 0) + ', '; req += ' Alarme_email=' + (champ_formulaire_Alarme_email.checked ? 1 : 0) + ', '; req += ' Texte_message="' + champ_formulaire_Texte_message.text + '", '; req += ' Texte_sms="' + champ_formulaire_Texte_sms.text + '", '; req += ' Texte_email="' + champ_formulaire_Texte_email.text + '", '; req += ' Action_circuits="' + action_circuits + '" '; req += ' WHERE Cle_primaire=' + id_event + ' ' //console.log("Requête = [ " + req + '; ]') bdd.requete_unique(req); // Demande de reconfiguration système via la BDD car on a modifié des valeurs de configuration : synchro_bdd(shipheart_type_synchro_config); } //============================================================================================================= // Création de l'évènement //============================================================================================================= function creation_event() { var req, res; var i; var flag_first; nom = champ_formulaire_Nom.text; // type_source = champ_formulaire_Type_source.model.get(champ_formulaire_Type_source.currentIndex).valeur; // id_source = champ_formulaire_Source.model.get(champ_formulaire_Source.currentIndex).valeur; // id_variable = champ_formulaire_Variable.model.get(champ_formulaire_Variable.currentIndex).valeur; // test = champ_formulaire_Test.model.get(champ_formulaire_Test.currentIndex).valeur; seuil = champ_formulaire_Seuil.text; tempo = champ_formulaire_Tempo.text; //---------------------------------------------------- // Traitement particulier des Tests de type binaire : if (flag_test_binaire) seuil = 0.5 // SDIR #335 //---------------------------------------------------- // Création de la chaine de condition horaire, si besoin : conditions_horaires = ""; if ((grille_conditions_horaires.model.count - 1) > 0) // Le '-1' permet de neutraliser le bouton '+' qui est toujours présents (mais parfois, pas affiché) { flag_first = true; for (i = 0; i < grille_conditions_horaires.model.count; i ++) // Parcours du modèle existant { if (!grille_conditions_horaires.model.get(i).bouton) // Ne prend pas en compte le bouton '+' { if (flag_first) flag_first = false; else conditions_horaires += ";" conditions_horaires += grille_conditions_horaires.model.get(i).jour; conditions_horaires += "/"; conditions_horaires += grille_conditions_horaires.model.get(i).heure; conditions_horaires += "/"; conditions_horaires += grille_conditions_horaires.model.get(i).minute; } } } else console.log("Aucune condition horaire n'a été configurée. La chaine 'Conditions_horaires' est laissée vide.") //console.log("Conditions horaires = [ " + conditions_horaires + " ]") //---------------------------------------------------- // Calcul de la chaine des actions sur les circuits : action_circuits = ""; flag_first = true; for (i = 0; i < grille_actions.model.count; i ++) // Parcours du modèle existant { if ((grille_actions.model.get(i).nom_famille === "") && // On ne prend pas en compte les entêtes de famille... (grille_actions.model.get(i).action !== -2)) // ... ni les circuits pour lesquels l'action vaut '-2', qui signifie "Aucune action" { if (flag_first) flag_first = false; else action_circuits += ";" action_circuits += grille_actions.model.get(i).id_circuit; action_circuits += "/"; action_circuits += grille_actions.model.get(i).action; } } //console.log("Action sur circuits = [ " + action_circuits + " ]") //---------------------------------------------------- // Création dans la BDD : req = 'INSERT INTO TB_Events ('; req += ' Visibilite, '; req += ' Nom, '; req += ' Type_source, '; req += ' ID_Source, '; req += ' ID_Variable, '; req += ' Test, '; req += ' Seuil, '; req += ' Tempo, '; req += ' Conditions_horaires, '; req += 'Alarme_son, '; req += 'Alarme_led, '; req += 'Alarme_soutien, '; req += 'Alarme_source, '; req += 'Alarme_message, '; req += 'Alarme_sms, '; req += 'Alarme_email, '; req += 'Texte_message, '; req += 'Texte_sms, '; req += 'Texte_email, '; req += 'Action_circuits) ' req += ' VALUES ('; req += ' ' + (champ_formulaire_Visibilite.checked ? 0 : 1); // Comme il s'agit d'un intitulé "masquage", on inverse la logique req += ', "' + nom + '"'; req += ', ' + type_source; req += ', ' + id_source; req += ', ' + id_variable ; req += ', ' + test + ' '; req += ', ' + seuil + ' '; req += ', ' + tempo + ' '; req += ', "' + conditions_horaires + '"'; req += ', ' + (champ_formulaire_Alarme_son.checked ? 1 : 0); req += ', ' + (champ_formulaire_Alarme_led.checked ? 1 : 0); req += ', ' + (champ_formulaire_Alarme_soutien.checked ? 1 : 0); req += ', ' + (champ_formulaire_Alarme_source.checked ? 1 : 0); req += ', ' + (champ_formulaire_Alarme_message.checked ? 1 : 0); req += ', ' + (champ_formulaire_Alarme_sms.checked ? 1 : 0); req += ', ' + (champ_formulaire_Alarme_email.checked ? 1 : 0); req += ', "' + champ_formulaire_Texte_message.text + '"'; req += ', "' + champ_formulaire_Texte_sms.text + '"'; req += ', "' + champ_formulaire_Texte_email.text + '"'; req += ', "' + action_circuits + '"'; req += ') '; console.log("Requête = [ " + req + '; ]') bdd.requete_unique(req); // Demande de reconfiguration système via la BDD car on a modifié des valeurs de configuration : synchro_bdd(shipheart_type_synchro_config); } //============================================================================================================= // Suppression de l'évènement //============================================================================================================= function suppression_event() { var req; // Suppression de l'évènement : req = 'DELETE FROM TB_Events WHERE Cle_primaire=' + id_event + ' '; //console.log("Requête = [ " + req + '; ]') bdd.requete_unique(req); // Demande de reconfiguration système via la BDD car on a modifié des valeurs de configuration : synchro_bdd(shipheart_type_synchro_config); } //============================================================================================================= // Recherche de l'index d'une certaine valeur dans un modele //============================================================================================================= function recherche_index_valeur_modele(cible, modele, nom_modele) { var i; for (i=0; i