Files
shipheart-qt/config_events.qml

429 lines
18 KiB
QML

//========================================================================================================================================================================
// 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.<br /><br />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);
}
}