Import initial du projet shipheart_cm5

This commit is contained in:
2026-08-13 09:19:38 +02:00
commit 53e47729fb
533 changed files with 127946 additions and 0 deletions
+470
View File
@@ -0,0 +1,470 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import"fonctions_date_heure.js" as Fonctions_date_heure
Popup {
id: boite_dialogue_reveils
// Propriétés fixes :
readonly property double pourcentage_largeur_page_popup: 0.7
readonly property double pourcentage_hauteur_page_popup: 0.8
readonly property int padding_popup: 20
readonly property double pourcentage_zone_titre: 0.20
readonly property double pourcentage_zone_principale: 1 - pourcentage_zone_titre - pourcentage_zone_boutons
readonly property double pourcentage_zone_boutons: 0.15
readonly property int bouton_hauteur: 60
readonly property int hauteur_ligne_formulaire: 60
readonly property double pourcentage_zone_validite: 0.15
readonly property int bouton_largeur: 200
// Propriétés :
property bool flag_init: true
property int index_condition_horaire_en_cours: -1
// Propriétés alias :
//-------------------------------------------------
// Signaux :
//-------------------------------------------------
signal clicked(int bouton) // Valeurs à lire lorsque le "OnClicked' est activé
//-------------------------------------------------
// Ouverture :
//-------------------------------------------------
onAboutToShow: { // Activé une fois quand le popup va être affiché
init(); // L'init n'a d'utilité que lorsqu'on va l'afficher...
}
onOpened: { // Quand la page est affichée
}
//-------------------------------------------------
// Fermeture :
//-------------------------------------------------
onAboutToHide: {
}
x: (shipheart_largeur_page * (1 - pourcentage_largeur_page_popup)) / 2;
y: (shipheart_hauteur_page * (1 - pourcentage_hauteur_page_popup)) / 2;
width: shipheart_largeur_page * pourcentage_largeur_page_popup;
height: shipheart_hauteur_page * pourcentage_hauteur_page_popup;
padding: padding_popup
modal: true
// focus: true // SDIR # 224 : Il ne faut PAS activer le focus. Sinon, à la fermeture, le focus précédent est réactivé (comme le dernier TextField par exemple)
closePolicy: Popup.NoAutoClose //Popup.CloseOnPressOutside
background: Rectangle {
color: shipheart_couleur_fond_boite_dialogue_niveau_0
radius: 20
}
Column {
id: affichage_boite_dialogue
spacing: 20
//=========================================================================
// Titre :
//=========================================================================
Rectangle {
id: titre_boite_dialogue
width: boite_dialogue_reveils.width - (2 * padding_popup)
height: (boite_dialogue_reveils.height - (2 * padding_popup) - (2 * affichage_boite_dialogue.spacing)) * pourcentage_zone_titre
color: "transparent"
Image {
id: image_titre
source: "/images/reveil.png"
sourceSize.height: 100
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
visible: true
}
}
//=========================================================================
// Zone principale :
//=========================================================================
Rectangle {
id: zone_principale
width: boite_dialogue_reveils.width - (2 * padding_popup)
height: (boite_dialogue_reveils.height - (2 * padding_popup) - (2 * affichage_boite_dialogue.spacing)) * pourcentage_zone_principale
color: "transparent"
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
model: ListModel { }
delegate: Rectangle {
width: grille_conditions_horaires.cellWidth
height: grille_conditions_horaires.cellHeight
color: "transparent"
//.......................................................
// Bouton principal :
//.......................................................
Rectangle {
height: parent.height - 10
width: (!model.bouton) ? ((parent.width * (1 - pourcentage_zone_validite)) - 10) : (parent.width)
// visible: (!model.bouton)
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.x = 0; // Bloque le déplacement latéral classique de la boite de dialogue puisqu'on l'appelle d'une boite déjà ouverte...
boite_selection_condition_horaire.y = titre_boite_dialogue.height; // Idem en Y mais avec un décalage permettant de toujours voir le titre de la boite appelante....
boite_selection_condition_horaire.open();
}
}
}
//.......................................................
// Bouton de validite :
//.......................................................
Rectangle {
height: parent.height - 10
width: (parent.width * pourcentage_zone_validite)
visible: (!model.bouton)
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
}
Image {
id: image_info_paramètres
source: (model.validite === 0) ? "/images/cloche_barree.png" : "/images/cloche_verte.png"
sourceSize.height: parent.height * 0.5
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
}
MouseArea{
anchors.fill : parent
onClicked: {
shipheart_clic();
if (grille_conditions_horaires.model.get(index).validite === 0)
{
grille_conditions_horaires.model.set(index, {"validite": 1} );
}
else grille_conditions_horaires.model.set(index, {"validite": 0} );
}
}
}
}
} // Fin de Gridview
}
//=========================================================================
// Boutons de bas de fenêtre :
//=========================================================================
Row {
height: (boite_dialogue_reveils.height - (2 * padding_popup) - (2 * affichage_boite_dialogue.spacing)) * pourcentage_zone_boutons
anchors.horizontalCenter: parent.horizontalCenter
spacing: 20
//.......................................................
// Bouton Annuler :
//.......................................................
Rectangle {
id: bouton_annuler
width: bouton_largeur
height: bouton_hauteur
anchors.verticalCenter: parent.verticalCenter
radius: shipheart_rayon_bouton
color: couleur_gris_tres_fonce
Label {
id: bouton_annuler_label
anchors.centerIn: parent
text: qsTr("Annuler")
color: couleur_blanc_casse
font.pixelSize:20
}
MouseArea {
anchors.fill: parent
onClicked: {
shipheart_clic();
boite_dialogue_reveils.clicked(shipheart_boite_dialogue_bouton_2);
}
}
}
//.......................................................
// Bouton Ok / Enregistrer :
//.......................................................
Rectangle {
id: bouton_ok
width: bouton_largeur
height: bouton_hauteur
anchors.verticalCenter: parent.verticalCenter
radius: shipheart_rayon_bouton
color: couleur_gris_tres_fonce
Label {
anchors.centerIn: parent
text: qsTr("Enregistrer")
color: couleur_blanc_casse
font.pixelSize:20
}
MouseArea {
anchors.fill: parent
onClicked: {
shipheart_clic();
mise_a_jour();
}
}
}
}
}
//-------------------------------------------------------
// 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,
"validite": 1,
"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)
}
}
//=============================================================================================================
// Transitions d'ouverture et de fermeture de la boite de dialogue
//=============================================================================================================
enter: Transition {
ParallelAnimation {
NumberAnimation {
property: "opacity"
from: 0.0
to: 1.0
//easing.type: Easing.InElastic
duration: 200
}
NumberAnimation {
property: "scale"
from: 0.0
to: 1.0
// easing.type: Easing.OutBack
duration: 200
}
}
}
exit: Transition {
ParallelAnimation {
NumberAnimation {
property: "opacity"
from: 1.0
to: 0.0
duration: 200
}
NumberAnimation {
property: "scale"
from: 1.0
to: 0.0
duration: 200
}
}
}
//=============================================================================================================
// Init des données de la boite de dialogue
//=============================================================================================================
function init()
{
var req, res;
var i;
var conditions;
var condition
var jour;
var heure;
var minute;
var validite;
flag_init = true; // On est obligé de le renseigne manuellement car la fonction 'init()' est appelée à chaque ouverture (et la valeur par défaut, qu'à l'ouverture initiale...)
grille_conditions_horaires.model.clear();
req = 'SELECT Valeur FROM TB_Configuration WHERE Nom="Reveils" ';
//console.log("Requête = [ " + req + '; ]')
res = bdd.requete_unique(req);
var conditions_horaires = res[0];
if (conditions_horaires !== "")
{
conditions = conditions_horaires.split(';');
for (i = 0; i < conditions.length; i ++)
{
condition = conditions[i].split('/');
if (condition.length === 4)
{
jour = Number(condition[0]);
heure = Number(condition[1]);
minute = Number(condition[2]);
validite = Number(condition[3]);
//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,
"validite": validite,
"bouton": false });
}
}
}
// Ajout du bouton "+" :
grille_conditions_horaires.model.append( { "libelle": "+", "jour": 0, "heure": 0, "minute": 0, "validite": 0, "bouton": true });
flag_init = false;
}
//=============================================================================================================
// Mise à jour des données de la boite de dialogue
//=============================================================================================================
function mise_a_jour()
{
var req;
var conditions_horaires;
var flag_first;
var i;
conditions_horaires = "";
if ((grille_conditions_horaires.model.count - 1) > 0) // Le '-1' permet de neutraliser le bouton '+' qui est toujours présents
{
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;
conditions_horaires += "/";
conditions_horaires += grille_conditions_horaires.model.get(i).validite;
}
}
}
else console.log("Aucune condition horaire n'a été configurée. La chaine 'Reveils' est laissée vide.")
//console.log("Conditions horaires = [ " + conditions_horaires + " ]")
req = 'UPDATE TB_Configuration SET Valeur="' + conditions_horaires + '" WHERE Nom="Reveils" ';
console.log("Requête = [ " + req + '; ]')
bdd.requete_unique(req);
boite_dialogue_reveils.clicked(shipheart_boite_dialogue_bouton_1);
}
}