//======================================================================================================================================================================== // CONFIG_EVENTS.QML // Ce fichier traite la configuration des évènements. La page permet notamment de : // - Afficher tous les évènements déjà configurés (et donc d'accéder à la configuration détaillée de l'un d'eux ; ou sa création) // La page est appelée depuis la page PARAMETRES_AVANCES, en cliquant sur "Evènements" //======================================================================================================================================================================== import QtQuick 2.12 import QtQuick.Controls 2.12 import qt.koriolan.shipheart 1.0 Shipheart_page { id: page_config_evenements // Mis en forme : readonly property double affichage_hauteur_utile: shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas readonly property int hauteur_bouton_droit: 80 readonly property double pourcentage_largeur_colonne_gauche: 0.75 readonly property double pourcentage_largeur_bouton_auto_dans_colonne_gauche: 0.15 readonly property int espace_colonnes_principales: 20 readonly property double pourcentage_bandeau_bas_largeur_zone_retour: 1.0 readonly property int nombre_capteurs_affiches_sur_une_colonne: 8 readonly property int periode_init_raffraichissement_parametres: 1 // En ms readonly property int periode_raffraichissement_parametres: 1000 // En ms /!\ Laisser à 1s afin que le compteur secondes fonctionne correctement... // Données : property int nombre_events: 0 // 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(); } } } //=========================================================== // Lorsque la page est sur le point d'être affichée dans la pile : //=========================================================== StackView.onActivating: { mise_a_jour_donnees(); // Permet que lors du retour sur la page, l'état des différentes variables soit mise à jour avant l'affichage proprement dit. } // Titre de la page : Shipheart_titre_1 {titre:qsTr("Configuration des évènements"); hauteur: shipheart_hauteur_bandeau_haut} //------------------------------------------------------- // Ecran de gauche (liste des capteurs) : //------------------------------------------------------- Rectangle { id: zone_affichage_gauche x: 0 y: shipheart_hauteur_bandeau_haut; width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: affichage_hauteur_utile color: "transparent" //------------------------------------------------------------------- // Grille pour afficher les évènements : GridView { id: grille_principale width: parent.width height: parent.height cellWidth: parent.width; cellHeight: height / nombre_capteurs_affiches_sur_une_colonne 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 highlightRangeMode: ListView.StrictlyEnforceRange // Permet de faire défiler la liste jusqu'à ne garder que le dernier élément affiché (et comme la liste des modules physiques est obligée d'utiliser ce paramètre, on fait pareil sur cette liste pour que les deux soient synchro) model: modele_grille_principale delegate: Rectangle { width: grille_principale.cellWidth height: grille_principale.cellHeight color: "transparent" // Ajout d'une ligne de sous-titre avec le nom du type d'event si c'est le premier event du type : Shipheart_titre_3 {titre:model.nom_famille; hauteur: (affichage_hauteur_utile / nombre_capteurs_affiches_sur_une_colonne); visible: model.famille} //------------------------------------ // Bouton avec le nom de l'event : //------------------------------------ Rectangle { height: parent.height - 10 width: (parent.width * (1 - pourcentage_largeur_bouton_auto_dans_colonne_gauche)) - 10 color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton anchors { left: parent.left verticalCenter: parent.verticalCenter } visible: !model.famille Text { anchors.fill: parent horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignVCenter leftPadding: 20 text: model.nom color: couleur_blanc_casse font.pixelSize: 18 wrapMode: Label.Wrap } MouseArea{ anchors.fill : parent onClicked: { shipheart_clic(); stackView.push("config_event.qml", {"id_event": model.id}) } } } //------------------------------------ // Bouton AUTO : //------------------------------------ Rectangle { x: (parent.width * (1 - pourcentage_largeur_bouton_auto_dans_colonne_gauche)) height: parent.height - 10 width:(parent.width * pourcentage_largeur_bouton_auto_dans_colonne_gauche) anchors { right: parent.right verticalCenter: parent.verticalCenter } radius: shipheart_rayon_bouton color: shipheart_couleur_fond_bouton visible: !model.famille Image { source: (model.validite === 0) ? "/images/faux.png" : "/images/vrai.png" sourceSize.height: parent.height * 0.5 anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } } MouseArea { id: mouse_area_cdes_auto x: 0 y: 0 width: parent.width height: parent.height pressAndHoldInterval: shipheart_mouse_press_and_hold_interval_long onPressed: { } onReleased: { } onPressAndHold: { shipheart_clic(); toggle_validite(model.index); } } } } ListModel { id: modele_grille_principale } Label { anchors.fill: parent horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter visible: parent.count === 0 text: qsTr("Aucun évènement n'est encore configuré...") color: couleur_rouge_transparent font.pixelSize: 15 font.bold: true wrapMode: Label.Wrap } } } //------------------------------------------------------- // Ecran Droite : //------------------------------------------------------- Rectangle { id: zone_affichage_droite x: zone_affichage_gauche.width + espace_colonnes_principales y: shipheart_hauteur_bandeau_haut + 5; // Le +5 permet d'aligner le haut du premier bouton de droite avec le haut du premier bouton de la liste de gauche ( width: (shipheart_largeur_page * (1 - pourcentage_largeur_colonne_gauche)) - (espace_colonnes_principales / 2) height: affichage_hauteur_utile color: "transparent" Column { anchors.fill: parent spacing: 10 //---------------------- // Bouton + : Rectangle { width: parent.width height: hauteur_bouton_droit color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton visible: !clavier.active Text { anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } font.pixelSize: 40 text: "+" color: couleur_blanc_casse } MouseArea { anchors.fill: parent onClicked: { shipheart_clic(); if (nombre_events < shipheart_max_nombre_events) stackView.push("config_event.qml"); else { boite_information.niveau = 1; boite_information.imageTitreSource = "/images/ampoule.png" boite_information.message = qsTr("Le nombre total d'évènements est limité à %1.

Vous ne pouvez pas ajouter de nouvel évènement avant d'en avoir supprimé préalablement.").arg(shipheart_max_nombre_events); boite_information.open(); } } } } } } //------------------------------------------------------- // Bandeau bas : //------------------------------------------------------- Row { x: 0 y: shipheart_hauteur_page - shipheart_hauteur_bandeau_bas; width: shipheart_largeur_page; height: shipheart_hauteur_bandeau_bas; padding: 5 spacing: 5 //................................................. // Bouton retour //................................................. Rectangle { id: bandeau_bas_zone_retour width: (parent.width * pourcentage_bandeau_bas_largeur_zone_retour) - parent.leftPadding - (parent.spacing / 2) 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 validation : //------------------------------------------------------- Shipheart_boite_dialogue { id: boite_information } // 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() { mise_a_jour_donnees(); } //============================================================================================================= // Mise à jour des données //============================================================================================================= function mise_a_jour_donnees() { var req, res; var sous_req, sous_res; var i; var nb_events; //======================================================================= // Grille principale (liste des évènements configurés) : modele_grille_principale.clear(); // RAZ des valeurs existantes nombre_events = 0; req = "SELECT TB_Events.Cle_primaire AS cle_event, TB_Events.Nom AS nom_event, Type_source, TB_Events.Validite"; req += " FROM TB_Events"; req += " WHERE Type_source=0"; req += " UNION"; req += " SELECT TB_Events.Cle_primaire AS cle_event, CONCAT(tb_source.Nom, ' - ', TB_Events.Nom) AS nom_event, Type_source, TB_Events.Validite"; req += " FROM TB_Events"; req += " INNER JOIN TB_Circuits AS tb_source ON TB_Events.ID_Source=tb_source.Cle_primaire"; req += " WHERE Type_source=1"; req += " UNION"; req += " SELECT TB_Events.Cle_primaire AS cle_event, CONCAT(tb_source.Nom, ' - ', TB_Events.Nom) AS nom_event, Type_source, TB_Events.Validite"; req += " FROM TB_Events"; req += " INNER JOIN TB_Capteurs AS tb_source ON TB_Events.ID_Source=tb_source.Cle_primaire"; req += " WHERE Type_source=2"; req += " UNION"; req += " SELECT TB_Events.Cle_primaire AS cle_event, CONCAT(tb_source.Nom, ' - ', TB_Events.Nom) AS nom_event, Type_source, TB_Events.Validite"; req += " FROM TB_Events"; req += " INNER JOIN TB_Reservoirs AS tb_source ON TB_Events.ID_Source=tb_source.Cle_primaire"; req += " WHERE Type_source=3"; req += " UNION"; req += " SELECT TB_Events.Cle_primaire AS cle_event, CONCAT(tb_source.Nom, ' - ', TB_Events.Nom) AS nom_event, Type_source, TB_Events.Validite"; req += " FROM TB_Events"; req += " INNER JOIN TB_Batteries AS tb_source ON TB_Events.ID_Source=tb_source.Cle_primaire"; req += " WHERE Type_source=4 ORDER BY Type_source, nom_event "; //console.log("req = [ " + req + "; ]"); nb_events = bdd.requete(req); var prec_type = -1; for (i = 0; i < nb_events; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { // Ajout de le ligne de Type : if (prec_type !== Number(res[2])) { modele_grille_principale.append({"famille":true, "nom": "", "id": 0, "nom_famille": nom_type_source(Number(res[2])), "validite": 0 }); prec_type = Number(res[2]); } // Entrée normale : modele_grille_principale.append({"famille":false, "nom": res[1], "id": Number(res[0]), "nom_famille": nom_type_source(Number(res[2])), "validite": Number(res[3]) }); nombre_events ++; } else break; // Ne devrait pas arriver.... } } //============================================================================================================= // Nom type de source //============================================================================================================= function nom_type_source(source) { switch(source) { case shipheart_source_mesure_circuit: return(qsTr("Sur circuits")); case shipheart_source_mesure_capteur: return(qsTr("Sur capteurs")); case shipheart_source_mesure_reservoir: return(qsTr("Sur réservoirs")); case shipheart_source_mesure_batterie: return(qsTr("Sur batteries")); default: return(qsTr("Horaire seulement")); } } //============================================================================================================= // Bascule de la visibilité d'un évènement //============================================================================================================= function toggle_validite(index) { var req; var validite; // Recherche de la valeur actuelle et calcul de la nouvelle : validite = modele_grille_principale.get(index).validite; if (validite === 0) validite = 1; else validite = 0; // Mise à jour de la nouvelle valeur dans le modèle : modele_grille_principale.set(index, {"validite": validite}); // Mis eà jour de la nouvelle valeur dans la BDD : req = 'UPDATE TB_Events SET Validite=' + validite + ' WHERE Cle_primaire=' + modele_grille_principale.get(index).id + ' '; //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); } }