Files
shipheart-qt/config_fichiers.qml
T

2149 lines
107 KiB
QML

//========================================================================================================================================================================
// CONFIG_FICHIER.QML
// Ce fichier permet de gérer d'une part des fichier sur ShipBase, dans un répertpoire interne et, d'autre part, des fichiers sur une clé externe.
// Il peut être utilisé dans plusieurs configurations différentes :
// - image d'accueil ('shipheart_mode_config_fichiers_image_accueil')
// - silhouette d'une page personnalisée ('shipheart_mode_config_fichiers_silhouette')
// - rapports d'installation ('shipheart_mode_config_fichiers_rapports')
// - Sauvegardes ('shipheart_mode_config_fichiers_sauvegardes')
// Le choix de l'un de ces modes se fait en passant la propriété 'mode_config_fichiers' qui peut prendre l'une des valeurs indquées ci-dessus.
//========================================================================================================================================================================
import QtQuick 2.12
import QtQuick.Controls 2.12
import Qt.labs.folderlistmodel 2.12
import qt.koriolan.shipheart 1.0
import"fonctions.js" as Fonctions
Shipheart_page {
id: page_config_fichiers
// Mis en forme :
readonly property double pourcentage_largeur_colonne_gauche: 0.40
readonly property double pourcentage_largeur_colonne_centre: (1 - pourcentage_largeur_colonne_gauche - pourcentage_largeur_colonne_droite)
readonly property double pourcentage_largeur_colonne_droite: 0.40
readonly property double espace_colonnes_principales: 20
readonly property double espace_colonnes_secondaires: 10
readonly property double affichage_hauteur_utile: shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas
readonly property double pourcentage_largeur_labels_formulaire: 0.4
readonly property double pourcentage_bandeau_bas_largeur_zone_retour: 1
readonly property int hauteur_ligne_formulaire: 60
readonly property int hauteur_bouton: 80
readonly property int periode_init_raffraichissement_parametres: 500 // En ms Cette durée est volontairement longue car cela permet l'affichage du fond de la page avant la première mise à jour (qui peut être "bloquante" sir la clé est déjà là est qu'un montage est demandé)
readonly property int periode_raffraichissement_parametres_montage_port_usb: 1 // En ms Doit être une valeur différente des autres tempo utilisées
readonly property int periode_raffraichissement_parametres: 1000 // En ms
readonly property int step_timer_appui_long: 30 // en ms
readonly property int etat_cle_absente: 0
readonly property int etat_cle_presente: 1
readonly property int etat_cle_presente_partition: 2
readonly property int etat_cle_presente_montee: 3
readonly property int etat_cle_presente_demontee: 4
// Données :
property bool flag_init: true
property int mode_config_fichiers: shipheart_mode_config_fichiers_inconnu
property int id_page: 0
property int valeur_timer_appui_long: 0
property int port_usb_en_cours: -1
property int etat_initial_port_usb_avant: -1
property int etat_initial_port_usb_arrière: -1
property int etat_cle: 0 // Cf les différente svaleurs possibles ci-dessus ('etat_cle_absente', etc...)
property bool flag_sortie_en_attente: false;
property bool flag_new_file_en_attente: false;
property string sous_repertoire_cle: ""
property string sens: "" // Soit vide, soit "cle_vers_shipheart", soit "shipheart_vers_cle"
property int index_fichier_local_actif: -1
property int index_fichier_cle_actif: -1
property string nom_fichier_local_selectionne: ""
property string titre_page: ""
property string nom_repertoire_local: ""
property bool flag_selection_locale_multiple_enabled: true
property string texte_bouton_action_sens_vide: ""
property string texte_bouton_action_sens_non_vide: ""
property int max_taille_fichier: 0
property string texte_types_fichiers_valides: ""
// Modèles :
// Note : les modèles chargés dans 'main.qml' n'ont pas à être rechargés dans les pages suivantes
//===========================================================
// Modèles de lecture de répertoire :
// Attention : pour que les modèles maintiennent à jour leur données,
// il faut que le répertoire cible (le contenant) ne soient pas modifié.
// Par exemple, le fait de supprimer le répertoire (pour le vider)
// puis de le recréer avec le même nom fait perdre le lien au modèle
// qui ne se met alors plus à jour...
//===========================================================
FolderListModel {
id: repertoire_local
// nameFilters: ["*.png", "*.PNG", "*.jpg", "*.JPG", "*.jpeg", "*.JPEG"]
// nameFilters: ["*.enc"]
showDirs: false
sortField: FolderListModel.Time // Tri sur l'heure du fichier
folder: "file://" + nom_repertoire_local // Pour un fichier, il faut obligatoirement ajouter 'file:' devant. Ou 'qrc:' pour une URL. Le message d'alerte de QT Creator est toujours là...
onStatusChanged: {
if ((status === FolderListModel.Ready) &&
(!flag_init) &&
(!boite_information.opened)) mise_a_jour_modele_fichiers_locaux();
}
onRowsInserted: (parent, first, last) => { // Ce sont les 3 arguments du signel : le parent n'est pas utulisé en l'occurence car FolderListModel est un modèle "à plat" mais les 2ème et 3ème sont les index des nouveaux enregistrement dans le répertoire.
if ((!flag_init) && (flag_new_file_en_attente))
{
var nom_fichier_cree;
flag_new_file_en_attente = false; // Pour utilisation ultérieure
mise_a_jour_modele_fichiers_locaux(); // Comme 'onRowsInserted' est généralement déclenché AVANT OnStatusChanged, on fait une mise à jour du modèle sinon on ne trouvera pas le nouveau fichier créé à la fin de cette fonction...
busy_indicator_centre.running = false; // Arrêt du sablier
var i;
for (i = first; i <= last; i ++) // En pratique, si on attend un nouveau fichier en cours de cration, on ne va probablement recevoir qu'UN fichier (et si plusieurs, on ne traitera que le dernier...)
{
nom_fichier_cree = repertoire_local.get(i, "fileName").replace(/\s\s+/g, ''); // Le REPLACE permet la suppression de tous les espaces, TAB, etc....
}
// Affichage du fichier généré dans le popup d'info :
switch(mode_config_fichiers) // Le message à afficher dépend du contexte d'utilisation du fichier :
{
//----------------------------------------------------
case shipheart_mode_config_fichiers_rapports:
{
boite_information.message = qsTr("Le rapport d'installation<br /><br /><b>%1</b><br /><br />a été généré.").arg(nom_fichier_cree);
boite_information.niveau = 0;
boite_information.imageTitreSource = "/images/ampoule.png"
boite_information.open();
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_sauvegardes:
{
boite_information.message = qsTr("La sauvegarde<br /><br /><b>%1</b><br /><br />a été générée.").arg(nom_fichier_cree.replace(".tar.gz.enc", "")); // La suppression de l'extension est juste plus facile à lire
boite_information.niveau = 0;
boite_information.imageTitreSource = "/images/ampoule.png"
boite_information.open();
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_image_accueil:
case shipheart_mode_config_fichiers_silhouette:
case shipheart_mode_config_fichiers_inconnu:
default:
{
break;
}
}
// Activation du nouveau fichier créé (pour l'identifier simplement) :
if (nom_fichier_cree !== "")
{
for (i = 0; i < modele_fichiers_locaux.count; i ++)
{
if (modele_fichiers_locaux.get(i).nom === nom_fichier_cree)
{
modele_fichiers_locaux.set(i, {"actif": true});
nom_fichier_local_selectionne = modele_fichiers_locaux.get(i).nom;
sens = "shipheart_vers_cle";
break;
}
}
}
}
}
}
//===========================================================
// Timer periode raffraichissement parametres :
//===========================================================
Timer {
id: timer_raffraichissement_parametres
interval: periode_init_raffraichissement_parametres
triggeredOnStart: false
running: true
repeat: true
onTriggered: {
//--------------------------------------------------------------
// Init :
if (interval === periode_init_raffraichissement_parametres) {
interval = periode_raffraichissement_parametres;
init_page();
}
//------------------------------------------------------------------------
// Demande de montage d'un port USB (permet de lancer le Busy Indicator) :
else if (interval === periode_raffraichissement_parametres_montage_port_usb)
{
if (shipheart_type_installation === shipheart_type_installation_shipbase) // SDIR #317
{
monter_port_usb(shipheart_port_usb_avant_bas);
check_ports_usb(); // Permets de mettre à jour les données du port sans attendre
etat_cle = etat_cle_presente_montee;
busy_indicator_droite.running = false;
interval = periode_raffraichissement_parametres;
}
}
//------------------------------------------------------------------------
// Période normale :
else {
if (shipheart_type_installation === shipheart_type_installation_shipbase) // SDIR #317
{
mise_a_jour();
}
}
}
}
//===========================================================
// 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)
{
shipheart_clic();
suppression_fichiers();
}
else if (mousearea_bouton_restaurer.pressed)
{
shipheart_clic();
boite_validation_securisee.niveau = 2;
boite_validation_securisee.boutonOk = false
boite_validation_securisee.boutonAnnuler = true
boite_validation_securisee.boutonSecurise = true
boite_validation_securisee.boutonSecuriseTexte = qsTr("Confirmer");
boite_validation_securisee.imageTitreSource = "/images/attention.png";
boite_validation_securisee.message = qsTr("<b>Restauration de la sauvegarde</b><br /><br />Si vous confirmez, cette mise à jour peut nécessiter <u>quelques minutes</u> pendant lesquelles <b>votre système ShipHeart ne sera pas accessible</b>.<br /><br />Vous ne devez confirmer l'installation que si vous êtes en situation sûre (au port, au mouillage, ...) et que la perte de contrôle de vos systèmes de bord pendant ce laps de temps est sans aucun danger !<br /><br />Cliquez sur Annuler pour revenir en arrière et effectuer cette installation ultérieurement.")
boite_validation_securisee.alignementMessage = Text.AlignLeft
boite_validation_securisee.affichageAscenseur = true;
boite_validation_securisee.open();
}
}
}
}
//===========================================================
// Titre de la page :
//===========================================================
Shipheart_titre_1 {titre: titre_page; hauteur: shipheart_hauteur_bandeau_haut}
//-------------------------------------------------------
// Ecran Gauche :
//-------------------------------------------------------
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 fichiers locaux :
GridView {
id: grille_locale
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: modele_fichiers_locaux
delegate: Rectangle {
width: grille_locale.cellWidth
height: grille_locale.cellHeight - 5
color: "transparent"
Rectangle { // c'est le bouton proprement dit...
height: parent.height
width:parent.width
color: (model.actif) ? shipheart_couleur_fond_bouton_actif : shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
anchors.bottom: parent.bottom
// Nom du fichier :
Text {
anchors {
top: parent.top
left: parent.left
}
width: parent.width - 70 // Le '-70' permet de garder l'espace nécessaire à la taille du fichier à droite
height: parent.height
horizontalAlignment: Qt.AlignLeft
verticalAlignment: Qt.AlignVCenter
leftPadding: 20
text: model.nom
color: couleur_blanc_casse
font.pixelSize: 18
font.bold: false
wrapMode: Label.Wrap
}
// Taille du fichier :
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignRight
verticalAlignment: Qt.AlignVCenter
rightPadding: 10
text: "[" + model.taille + "]"
color: couleur_gris_moyen
font.pixelSize: 15
}
// Triangle bleu indiquant le fichier sélectionné :
Image {
id: image_selectionnee
source: "/images/coin_bas_droite_bleu_koriolan.png"
sourceSize.height: 20
anchors {
bottom: parent.bottom
right: parent.right
}
visible: ((mode_config_fichiers === shipheart_mode_config_fichiers_image_accueil) &&
(nom_fichier_local_selectionne === modele_fichiers_locaux.get(index).nom)) ||
((mode_config_fichiers === shipheart_mode_config_fichiers_silhouette) &&
(nom_fichier_local_selectionne === modele_fichiers_locaux.get(index).nom))
}
MouseArea{
anchors.fill : parent
onClicked: {
shipheart_clic();
var i;
var flag_actifs = false;
// Mise à jour de l'état Actif/Inactif de l'entrée cliquée (et mise à jour des autres entrées si besoin) !
if (flag_selection_locale_multiple_enabled) // Dans ce cas, on fait juste un toggle d'activatuion du fichier cliqué :
{
if (modele_fichiers_locaux.get(index).actif) modele_fichiers_locaux.set(index, { "actif": false } );
else modele_fichiers_locaux.set(index, { "actif": true } );
}
else // Dans ce cas, il faut passer à 1 ou 0 fichiers actifs :
{
if (modele_fichiers_locaux.get(index).actif) // S'il était actif, il devient inactif (et on est sûr qu'il n'y en n'a pas d'autres)
{
index_fichier_local_actif = -1;
modele_fichiers_locaux.set(index, { "actif": false } );
}
else // S'il était inactif, il faut désactiver tous les autres (a priori, un seul) puis activer celui qui vient d'être cliqué
{
// Désactivation de tous fichiers locaux :
for (i=0; i<modele_fichiers_locaux.count; i++) modele_fichiers_locaux.set(i, { "actif": false } );
// Ativation de celui qui vient d'être cliqué :
index_fichier_local_actif = index;
modele_fichiers_locaux.set(index, { "actif": true } );
}
}
// Recherche de la présence d'au moins une entrée active :
for (i=0; i<modele_fichiers_locaux.count; i++)
{
if (modele_fichiers_locaux.get(i).actif)
{
flag_actifs = true;
break;
}
}
// Si au moins une entrée est active localement, mise à jour du sens et dévalidation des boutons actifs sur la clé s'il y en a :
if (flag_actifs)
{
if (sens !== "shipheart_vers_cle")
{
sens = "shipheart_vers_cle";
for (i=0; i<modele_fichiers_cle.count; i++) modele_fichiers_cle.set(i, {"actif": false}); // Deséctivation de toutes les entrées de la clé
}
}
else if (sens === "shipheart_vers_cle") sens = "";
}
}
}
}
ListModel {
id: modele_fichiers_locaux
}
}
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignCenter
verticalAlignment: Qt.AlignVCenter
padding: 20
text: qsTr("Aucun fichier n'a encore été chargé...")
color: couleur_rouge
font.pixelSize: 18
wrapMode: Text.Wrap
visible: (!flag_init) && (modele_fichiers_locaux.count === 0)
}
//---------------------------
// Busy Indicator de gauche :
Shipheart_busy_indicator {
id: busy_indicator_gauche
running: flag_init
}
}
//-------------------------------------------------------
// Ecran Centre :
//-------------------------------------------------------
Rectangle {
id: zone_affichage_centre
x: zone_affichage_gauche.x + zone_affichage_gauche.width + espace_colonnes_principales
y: shipheart_hauteur_bandeau_haut;
width: (shipheart_largeur_page * pourcentage_largeur_colonne_centre) - espace_colonnes_principales
height: affichage_hauteur_utile
color: "transparent"
Column {
width: parent.width
height: parent.height
spacing: 5
//---------------------------------------
// Bouton action :
// Le type d'action dépend du contexte (cf entete de la fonction 'action()' pour les différents modes)
Rectangle {
width: parent.width
height: hauteur_bouton - parent.spacing
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
visible: !flag_init
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
rightPadding: 20
verticalAlignment: Qt.AlignVCenter
text: (sens === "")
? texte_bouton_action_sens_vide // Mis à jour dans INIT, selon le mode dans lequel on est
: texte_bouton_action_sens_non_vide
color: mousearea_action.enabled ? couleur_blanc_casse : couleur_gris_moyen
font.pixelSize: 18
wrapMode: Text.Wrap
}
MouseArea {
id: mousearea_action
anchors.fill: parent
enabled: {
if (mode_config_fichiers === shipheart_mode_config_fichiers_image_accueil)
{
if (index_fichier_local_actif < 0 || index_fichier_local_actif >= modele_fichiers_locaux.count) return false;
let item = modele_fichiers_locaux.get(index_fichier_local_actif);
if (!item) return false;
return ((sens === "shipheart_vers_cle") && (nom_fichier_local_selectionne !== item.nom))
}
else if (mode_config_fichiers === shipheart_mode_config_fichiers_silhouette)
{
if (sens === "") return true; // Permet d'accéder à "Acune image"
else if (sens === "cle_vers_shipheart") return false; // Si aucune image à gauche n'est sélectionnée, on ne peut rien faire
else if (sens === "shipheart_vers_cle") // Si une image est sélectionnée à gauche :
{
if (index_fichier_local_actif < 0 || index_fichier_local_actif >= modele_fichiers_locaux.count) return false;
let item = modele_fichiers_locaux.get(index_fichier_local_actif);
if (!item) return false;
return (nom_fichier_local_selectionne !== item.nom)
}
else return false; // Ne devrait pas arriver
}
else if (mode_config_fichiers === shipheart_mode_config_fichiers_rapports) return true;
else if (mode_config_fichiers === shipheart_mode_config_fichiers_sauvegardes) return true;
}
onClicked: {
shipheart_clic();
action();
if ((mode_config_fichiers === shipheart_mode_config_fichiers_image_accueil) ||
(mode_config_fichiers === shipheart_mode_config_fichiers_silhouette) ) sortie();
}
}
}
//---------------------------------------
// Bouton Copier :
Rectangle {
width: parent.width
height: hauteur_bouton - parent.spacing
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
visible: !flag_init
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
rightPadding: 20
verticalAlignment: Qt.AlignVCenter
text: qsTr("Copier")
color: (mousearea_copier.enabled) ? couleur_blanc_casse : couleur_gris_moyen
font.pixelSize: 18
}
Image {
source: "/images/right.png"
visible: mousearea_copier.enabled && (sens === "shipheart_vers_cle")
sourceSize.height: 25
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: 20
}
}
Image {
source: "/images/left.png"
visible: mousearea_copier.enabled && (sens === "cle_vers_shipheart")
sourceSize.height: 25
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: 20
}
}
MouseArea {
id: mousearea_copier
anchors.fill: parent
enabled: (sens !== "") && (etat_cle === etat_cle_presente_montee)
onClicked: {
shipheart_clic();
copie_fichiers();
}
}
}
//---------------------------------------
// Bouton Supprimer :
Rectangle {
width: parent.width
height: hauteur_bouton - parent.spacing
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
visible: !flag_init
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.fill: parent
horizontalAlignment: Qt.AlignHCenter
rightPadding: 20
verticalAlignment: Qt.AlignVCenter
text: qsTr("Supprimer")
color: (mousearea_bouton_supprimer.enabled) ? couleur_blanc_casse : couleur_gris_moyen
font.pixelSize: 18
}
MouseArea {
id: mousearea_bouton_supprimer
anchors.fill: parent
enabled: {
//--------------------------------------------------------------------------------
if ((mode_config_fichiers === shipheart_mode_config_fichiers_image_accueil) ||
(mode_config_fichiers === shipheart_mode_config_fichiers_silhouette))
{
//-----------------------------------
if (sens === "cle_vers_shipheart")
{
if (index_fichier_cle_actif < 0 || index_fichier_cle_actif >= modele_fichiers_cle.count) return false;
let item = modele_fichiers_cle.get(index_fichier_cle_actif);
if (!item) return false;
return (item.type !== "dir");
}
//-----------------------------------
else if (sens === "shipheart_vers_cle")
{
if (index_fichier_local_actif < 0 || index_fichier_local_actif >= modele_fichiers_locaux.count) return false;
let item = modele_fichiers_locaux.get(index_fichier_local_actif);
if (!item) return false;
return (nom_fichier_local_selectionne !== item.nom); // On n'autorise pas la suppression de l'image en cours
}
//-----------------------------------
else return false; // Sens = ""
}
//--------------------------------------------------------------------------------
else if ((mode_config_fichiers === shipheart_mode_config_fichiers_rapports) ||
(mode_config_fichiers === shipheart_mode_config_fichiers_sauvegardes))
{
let flag_actifs = false;
let i;
//-----------------------------------
if (sens === "cle_vers_shipheart")
{
// Recherche de la présence d'au moins une entrée active sur la clé :
for (i=0; i<modele_fichiers_cle.count; i++)
{
if ((modele_fichiers_cle.get(i).type !== "dir") && // On ne prend pas en compte les répertoires (normalement, ils ne doivent pas pouvoir être actifs)
(modele_fichiers_cle.get(i).actif))
{
flag_actifs = true;
break;
}
}
return flag_actifs;
}
//-----------------------------------
else if (sens === "shipheart_vers_cle")
{
// Recherche de la présence d'au moins une entrée active :
for (i=0; i<modele_fichiers_locaux.count; i++)
{
if (modele_fichiers_locaux.get(i).actif)
{
flag_actifs = true;
break;
}
}
return flag_actifs;
}
//-----------------------------------
else return false; // Sens = ""
}
else return false; // Ne devrait pas arriver...
}
onPressed: { // Déclenché lors de l'appui inital
shipheart_clic();
timer_appui_long.running = true;
valeur_timer_appui_long = 0;
}
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;
}
}
}
//---------------------------------------
// Bouton Restaurer :
// Affiché uniquement pour les Sauvegardes.
Rectangle {
width: parent.width
height: hauteur_bouton - parent.spacing
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
visible: !flag_init && (mode_config_fichiers === shipheart_mode_config_fichiers_sauvegardes)
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_restaurer.pressed
}
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
rightPadding: 20
verticalAlignment: Qt.AlignVCenter
text: qsTr("Restaurer")
color: (mousearea_bouton_restaurer.enabled) ? couleur_blanc_casse : couleur_gris_moyen
font.pixelSize: 18
}
MouseArea {
id: mousearea_bouton_restaurer
anchors.fill: parent
enabled: {
let flag_actifs = 0;
let i;
//-----------------------------------
if (sens === "shipheart_vers_cle")
{
// Recherche de la présence d'au moins une entrée active :
for (i=0; i<modele_fichiers_locaux.count; i++)
{
if (modele_fichiers_locaux.get(i).actif) flag_actifs ++;
}
return (flag_actifs === 1);
}
//-----------------------------------
else return false; // Sens = ""
}
onPressed: { // Déclenché lors de l'appui inital
shipheart_clic();
timer_appui_long.running = true;
valeur_timer_appui_long = 0;
}
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;
}
}
}
//---------------------------------------
// Bouton Installateur :
// affiché uniquement pour Rapports.
Rectangle {
width: parent.width
height: hauteur_bouton - parent.spacing
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
visible: !flag_init && (mode_config_fichiers === shipheart_mode_config_fichiers_rapports)
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
rightPadding: 20
verticalAlignment: Qt.AlignVCenter
text: qsTr("Installateur")
color: couleur_blanc_casse
font.pixelSize: 18
}
MouseArea {
anchors.fill: parent
onClicked: {
shipheart_clic();
stackView.push("config_installateur.qml");
}
}
}
//---------------------------------------
// Miniature :
Rectangle {
width: parent.width
height: affichage_hauteur_utile - y - parent.spacing
color: "transparent"
visible: !flag_init &&
(sens !== "") &&
((mode_config_fichiers === shipheart_mode_config_fichiers_image_accueil) ||
(mode_config_fichiers === shipheart_mode_config_fichiers_silhouette))
Image {
source: {
//--------------------------------------------------------------------------------
if ((mode_config_fichiers === shipheart_mode_config_fichiers_image_accueil) ||
(mode_config_fichiers === shipheart_mode_config_fichiers_silhouette))
{
if (sens === "shipheart_vers_cle")
{
if (index_fichier_local_actif < 0 || index_fichier_local_actif >= modele_fichiers_locaux.count) return "";
let item = modele_fichiers_locaux.get(index_fichier_local_actif);
if (!item) return "";
return "file://" + nom_repertoire_local + "/" + item.nom;
}
else
{
if (index_fichier_cle_actif < 0 || index_fichier_cle_actif >= modele_fichiers_cle.count) return "";
let item = modele_fichiers_cle.get(index_fichier_cle_actif);
if (!item) return "";
return "file://" + shipheart_repertoire_cle_usb + ((sous_repertoire_cle === "") ? "" : "/" + sous_repertoire_cle) + "/" + item.nom;
}
}
else return "";
}
anchors.fill: parent
fillMode: Image.PreserveAspectFit
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
}
}
}
//---------------------------
// Busy Indicator au centre (utilisé pendant le traitement d'une commande longue (rapport, sauvegarde, ...) :
Shipheart_busy_indicator {
id: busy_indicator_centre
anchors.verticalCenterOffset: 100 // Permet de placer le sablier en-dessous des boutons centraux
}
}
//-------------------------------------------------------
// Ecran Droite :
//-------------------------------------------------------
Rectangle {
id: zone_affichage_droite
x: zone_affichage_centre.x + zone_affichage_centre.width + espace_colonnes_principales
y: 0
width: (shipheart_largeur_page * pourcentage_largeur_colonne_droite) - (espace_colonnes_principales / 2)
height: affichage_hauteur_utile + shipheart_hauteur_bandeau_haut
color: "transparent"
visible: (shipheart_type_installation === shipheart_type_installation_shipbase) // Sur ShipRS, on n'affiche pas la partie Clé car elle n'est pas acessible physiquement
// L'utilisation d'une ListView pour afficher une seule ligne peut paraitre étrange mais si on ne le fait pas, le lien entre le modèle et
// l'affichage n'est pas fait et l'affichage ne prend que la valeur initiale du modèle (pas les mises à jour ultérieures).
ListView {
id: grille_cle
width: parent.width
height: parent.height
model: modele_ports_usb
//====================================
// Infos sur la clé :
delegate: Rectangle {
id: zone_port_avant_bas
width: parent.width
height: visible ? shipheart_hauteur_bandeau_haut : 0
color: "transparent"
visible: !flag_init
&& (etat_cle !== etat_cle_absente)
&& (index === shipheart_port_usb_avant_bas)
//-----------------------------------
// Label de la clé :
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignLeft
verticalAlignment: Qt.AlignVCenter
topPadding: -20
leftPadding: 20
text: flag_init
? ""
: model.label
color: couleur_blanc_casse
font.pixelSize: 18
}
//-----------------------------------
// Taille et % d'utilisation :
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignLeft
verticalAlignment: Qt.AlignVCenter
topPadding: 25
leftPadding: 20
text: flag_init
? ""
: model.size + " [" + model.used + "]"
color: couleur_gris_moyen
font.pixelSize: 15
visible: (etat_cle === etat_cle_presente_montee)
}
//-----------------------------------
// Bouton de démontage manuel :
Rectangle {
id: zone_port_avant_bas_bouton_ejection
width: 200
height: shipheart_hauteur_bandeau_haut - 10
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
}
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
visible: !flag_init && etat_cle === etat_cle_presente_montee
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
rightPadding: 20
verticalAlignment: Qt.AlignVCenter
text: qsTr("Ejection")
color: couleur_blanc_casse
font.pixelSize: 18
}
Image {
source: "/images/down.png"
sourceSize.height: 15
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
rightMargin: 20
}
}
MouseArea {
anchors.fill: parent
onClicked: {
shipheart_clic();
if (etat_cle === etat_cle_presente_montee)
{
demonter_port_usb(port_usb_en_cours);
modele_fichiers_cle.clear(); // Effacement du modèle si le device est démonté
etat_cle = etat_cle_presente_demontee;
}
}
}
}
}
//====================================================
// Affichage lorsqu'aucune clé n'est encore reconnue :
// Etat 0 ou 3 : Aucune clé dans port Avant Bas :
Image {
source: (etat_cle === etat_cle_absente) ? "/images/right.png" : "/images/left.png"
visible: texte_entree_sortie_cle.visible
sourceSize.height: 30
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
verticalCenterOffset: -90 // Attention : cet offset est directement lié au montage mécanique de l'écran...
rightMargin: 30
SequentialAnimation on rightMargin {
loops: Animation.Infinite
NumberAnimation {
to: 100;
duration: (etat_cle === etat_cle_absente) ? 300 : 2000;
easing.type: (etat_cle === etat_cle_absente) ? Easing.Linear : Easing.OutElastic; }
PauseAnimation { duration: (etat_cle === etat_cle_absente) ? 0 : 1000 }
NumberAnimation {
to: 30;
duration: (etat_cle === etat_cle_absente) ? 2000 : 300;
easing.type: (etat_cle === etat_cle_absente) ? Easing.OutElastic : Easing.Linear; }
PauseAnimation { duration: (etat_cle === etat_cle_absente) ? 1000 : 0 }
}
}
}
Text {
id: texte_entree_sortie_cle
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
text: (etat_cle === etat_cle_absente)
? qsTr("Insérer une clé USB dans le port <u>du bas</u>, à droite")
: qsTr("Vous pouvez retirer la clé en toute sécurité...")
color: couleur_blanc_casse
font.pixelSize: 18
visible: !flag_init &&
( (etat_cle === etat_cle_absente)
|| (etat_cle === etat_cle_presente_demontee) )
}
//---------------------------
ListModel {
id: modele_ports_usb;
}
}
//-----------------------------------------------
// Grille des fichiers de la clé :
GridView {
id: liste_fichiers_cle
y: shipheart_hauteur_bandeau_haut
width: parent.width
height: affichage_hauteur_utile
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: modele_fichiers_cle
visible: (shipheart_type_installation === shipheart_type_installation_shipbase)
// Bouton d'un fichier ou répertoire :
delegate: Rectangle {
width: liste_fichiers_cle.cellWidth
height: liste_fichiers_cle.cellHeight - 5
color: "transparent"
Rectangle { // c'est le bouton proprement dit...
height: parent.height
width:parent.width
color: (model.actif) ? shipheart_couleur_fond_bouton_actif : shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
anchors.bottom: parent.bottom
// Nom du fichier :
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignLeft
verticalAlignment: Qt.AlignVCenter
leftPadding: 20
text: model.nom
color: (model.type === "fic") ? (model.autorise ? couleur_blanc_casse : couleur_gris_moyen) : couleur_bleu_koriolan
font.pixelSize: 18
font.bold: (model.type === "fic") ? false : true
wrapMode: Label.Wrap
visible: (model.type !== "dir") || (model.nom !== "..")
}
Image {
source: "/images/up_bleu.png"
sourceSize.height: 15
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
leftMargin: 20
}
visible: (model.type === "dir") && (model.nom === "..")
}
// Taille du fichier :
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignRight
verticalAlignment: Qt.AlignVCenter
rightPadding: 10
text: "[" + model.taille + "]"
color: ((max_taille_fichier === 0) || (model.taille_octets <= max_taille_fichier)) ? couleur_gris_moyen : couleur_rouge
font.pixelSize: 15
visible: (model.type === "fic")
}
MouseArea{
anchors.fill : parent
onClicked: {
shipheart_clic();
var i;
var flag_actifs = false;
// Si l'entrée cliquée est un répertoire :
if (modele_fichiers_cle.get(index).type === "dir")
{
if (modele_fichiers_cle.get(index).nom === "..")
{
var dirs = sous_repertoire_cle.split('/');
sous_repertoire_cle = "";
for (i=0; i<(dirs.length-1); i++)
{
if (sous_repertoire_cle !== "") sous_repertoire_cle += "/";
sous_repertoire_cle += dirs[i];
//console.log("Repertoire cle = [ " + sous_repertoire_cle + " ]" );
}
}
else sous_repertoire_cle += ((sous_repertoire_cle === "") ? "" : "/") + modele_fichiers_cle.get(index).nom; // Descente dans le sous-répertoire
ls(shipheart_repertoire_cle_usb + ((sous_repertoire_cle === "") ? "" : "/" + sous_repertoire_cle)); // Rechargement du modèle avec le contenu du sous-répertoire// Rechargement du modèle avec le contenu du sous-répertoire
}
else // Sinon, c'est que c'est un fichier :
{
if ((modele_fichiers_cle.get(index).autorise) && (model.taille_octets <= max_taille_fichier))
{
if (modele_fichiers_cle.get(index).actif)
{
index_fichier_cle_actif = -1;
modele_fichiers_cle.set(index, { "actif": false } );
}
else
{
// Désactivation de tous les boutons sur la clé :
for (i=0; i<modele_fichiers_cle.count; i++) modele_fichiers_cle.set(i, { "actif": false } );
// Activation de celui qui vient d'être cliqué :
modele_fichiers_cle.set(index, { "actif": true } );
index_fichier_cle_actif = index;
}
// Recherche de la présence d'au moins une entrée active :
for (i=0; i<modele_fichiers_cle.count; i++)
{
if (modele_fichiers_cle.get(i).actif)
{
flag_actifs = true;
break;
}
}
// Si au moins une entrée est active sur la clé, mise à jour du sens et dévalidation des boutons actifs localement s'il y en a :
if (flag_actifs)
{
if (sens !== "cle_vers_shipheart")
{
sens = "cle_vers_shipheart";
for (i=0; i<modele_fichiers_locaux.count; i++) modele_fichiers_locaux.set(i, {"actif": false}); // Deséctivation de toutes les entrées locales
}
}
else if (sens === "cle_vers_shipheart") sens = "";
}
else
{
boite_information.niveau = 0;
boite_information.imageTitreSource = "/images/ampoule.png"
boite_information.message = qsTr("Seuls les fichiers avec une extension [ %1 ] et de taille inférieure à %2 sont autorisés.").arg(texte_types_fichiers_valides).arg(Fonctions.taille_fichier((max_taille_fichier), shipheart_langue));
boite_information.open();
}
}
}
}
}
}
ListModel {
id: modele_fichiers_cle;
}
}
//---------------------------
// Busy Indicator de droite :
Shipheart_busy_indicator {
id: busy_indicator_droite
}
}
//-------------------------------------------------------
// 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();
if (etat_cle === etat_cle_presente_montee)
{
demonter_port_usb(port_usb_en_cours); // En cas de sortie du menu et que la clé n'a pas été démontée, elle l'est automatiquement
boite_information.niveau = 0;
boite_information.imageTitreSource = "/images/ampoule.png"
boite_information.message = qsTr("La clé USB a été <i>éjectée</i> automatiquement.<br />Vous pouvez la retirer dès maintenant en toute sécurité...");
boite_information.open();
flag_sortie_en_attente = true; // Permettra de sortir de la page lors de la fermeture de la boite de dialogue
}
else sortie();
}
}
}
}
//===========================================================
// Boit d'information
//===========================================================
Shipheart_boite_dialogue {
id: boite_information
onClicked: {
//--------------------------------------------------------------------
// Info avant sortie :
if (flag_sortie_en_attente) sortie();
}
}
//-------------------------------------------------------
// Boite d'information :
//-------------------------------------------------------
Shipheart_boite_dialogue_validation_securisee {
id: boite_validation_securisee
onClicked: {
switch(bouton)
{
case shipheart_boite_dialogue_bouton_4: // Confirmation sécurisée :
restauration();
break;
case shipheart_boite_dialogue_bouton_2: // Annuler : on revient sur la page pour que l'on puisse enregistrer.
break;
default:
}
boite_validation_securisee.close();
}
}
// 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 nb;
var i;
var nom_champ, valeur_champ;
//----------------------------------------------------------------
// Alimentation des ports USB : (SDIR #303)
//----------------------------------------------------------------
// Récupération de la consigne actuelle de l'alim des ports USB :
req = 'SELECT Cle_primaire, Consigne FROM TB_Circuits WHERE Adresse_module=0 AND No_circuit=1 ';
//console.log("Requête = [ " + req + "; ]");
res = bdd.requete_unique(req);
etat_initial_port_usb_avant = Number(res[1]);
if (etat_initial_port_usb_avant === 0)
{
req = 'UPDATE TB_Circuits SET New_consigne=100 WHERE Adresse_module=0 AND No_circuit=1 ';
//console.log("Requête = [ " + req + "; ]");
bdd.requete_unique(req);
}
req = 'SELECT Cle_primaire, Consigne FROM TB_Circuits WHERE Adresse_module=0 AND No_circuit=2 ';
//console.log("Requête = [ " + req + "; ]");
res = bdd.requete_unique(req);
etat_initial_port_usb_arrière = Number(res[1]);
if (etat_initial_port_usb_arrière === 0)
{
req = 'UPDATE TB_Circuits SET New_consigne=100 WHERE Adresse_module=0 AND No_circuit=2 ';
//console.log("Requête = [ " + req + "; ]");
bdd.requete_unique(req);
}
//----------------------------------------------------------------
// Préparation des paramètres généraux, selon le contecte d'usage :
//----------------------------------------------------------------
switch(mode_config_fichiers)
{
//----------------------------------------------------
case shipheart_mode_config_fichiers_image_accueil:
{
titre_page = qsTr("Image d'accueil");
nom_repertoire_local = shipheart_repertoire_config + shipheart_sous_repertoire_images_accueil;
flag_selection_locale_multiple_enabled = false;
texte_bouton_action_sens_vide = qsTr("Sélectionner cette image");
texte_bouton_action_sens_non_vide = texte_bouton_action_sens_vide;
max_taille_fichier = shipheart_taille_maxi_image_accueil;
texte_types_fichiers_valides = ".PNG | .png | .JPG | .jpg";
// Récupération du nom de fichier configuré :
req = 'SELECT Valeur ';
req += ' FROM TB_Configuration ';
req += ' WHERE Nom="Fichier_image_accueil" ';
//console.log("req = [ " + req + "; ]");
res = bdd.requete_unique(req);
nom_fichier_local_selectionne = res[0];
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_silhouette:
{
if (id_page === 0) sortie();
titre_page = qsTr("Silhouette de la page");
nom_repertoire_local = shipheart_repertoire_config + shipheart_sous_repertoire_images_silhouette;
flag_selection_locale_multiple_enabled = false;
texte_bouton_action_sens_vide = qsTr("Aucune image");
texte_bouton_action_sens_non_vide = qsTr("Sélectionner cette image");
max_taille_fichier = shipheart_taille_maxi_silhouette;
texte_types_fichiers_valides = ".PNG | .png | .JPG | .jpg";
// Récupération du nom de fichier configuré :
req = 'SELECT Fichier ';
req += ' FROM TB_Pages ';
req += ' WHERE Cle_primaire=' + id_page + ' ';
//console.log("req = [ " + req + "; ]");
res = bdd.requete_unique(req);
nom_fichier_local_selectionne = res[0];
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_rapports:
{
titre_page = qsTr("Rapports d'installation");
nom_repertoire_local = shipheart_repertoire_config + shipheart_sous_repertoire_rapports;
flag_selection_locale_multiple_enabled = true;
texte_bouton_action_sens_vide = qsTr("Nouveau rapport d'installation");
texte_bouton_action_sens_non_vide = texte_bouton_action_sens_vide;
max_taille_fichier = shipheart_taille_maxi_rapport;
texte_types_fichiers_valides = ".PDF | .pdf";
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_sauvegardes:
{
titre_page = qsTr("Sauvegardes");
nom_repertoire_local = shipheart_repertoire_config + shipheart_sous_repertoire_sauvegardes;
flag_selection_locale_multiple_enabled = true;
texte_bouton_action_sens_vide = qsTr("Nouvelle sauvegarde");
texte_bouton_action_sens_non_vide = texte_bouton_action_sens_vide;
max_taille_fichier = shipheart_taille_maxi_sauvegarde;
texte_types_fichiers_valides = ".ENC | .enc";
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_inconnu:
default:
{
sortie();
break;
}
}
//----------------------------------------------------
// Pour ShipRS : mise à jour des fichiers locaux à partir de ShipBase
if (shipheart_type_installation !== shipheart_type_installation_shipbase) synchro_repertoires_shiprs(); // Permet d'avoir les derniers fichiers mis à jour dans ShipBase...
//----------------------------------------------------
// Valeurs par défait du répertoire local :
// mise_a_jour_modele_fichiers_locaux();
sens = "shipheart_vers_cle"; // Permet que le fichier sélectionné à l'init soit affiché avec les boutons dans les bonnes positions.
//----------------------------------------------------
// Mise à jour de la liste des ports USB :
etat_cle = etat_cle_absente;
modele_ports_usb.clear();
modele_ports_usb.append({
"nom": qsTr("USB Arrière"),
"presence": false,
"disk": "",
"partition": "",
"monte": false,
"size": "",
"used": "",
"label": "",
"manufacturer": "",
"product": "",
"serial_number": "" } );
modele_ports_usb.append({
"nom": qsTr("Spare"),
"presence": false,
"disk": "",
"partition": "",
"monte": false,
"size": "",
"used": "",
"label": "",
"manufacturer": "",
"product": "",
"serial_number": "" } );
modele_ports_usb.append({
"nom": qsTr("USB Avant"),
"presence": false,
"disk": "",
"partition": "",
"monte": false,
"size": "",
"used": "",
"label": "",
"manufacturer": "",
"product": "",
"serial_number": "" } );
modele_ports_usb.append({
"nom": qsTr("Touch pad"),
"presence": false,
"disk": "",
"partition": "",
"monte": false,
"size": "",
"used": "",
"label": "",
"manufacturer": "",
"product": "",
"serial_number": "" } );
//----------------------------------------------------
// Note : A ce stade, on considère que seul le port Avant Bas est utilisé.
// Si besoin détendre au port arrière par exemple, il faut 'juste' gérer ce paramètre dynamiquement.
// Les données des 4 ports présents sur ShipBase sont d'ores et déjà mises à jour.
port_usb_en_cours = shipheart_port_usb_avant_bas;
//----------------------------------------------------
// Mise à jour initiale :
if (shipheart_type_installation === shipheart_type_installation_shipbase) // SDIR #317
{
mise_a_jour();
}
flag_init = false;
}
//=============================================================================================================
// Mise à jour toutes les secondes :
//=============================================================================================================
function mise_a_jour_modele_fichiers_locaux()
{
var i;
var nom;
var actif;
modele_fichiers_locaux.clear();
index_fichier_local_actif = -1;
for (i = 0; i < repertoire_local.count; i ++)
{
nom = repertoire_local.get(i, "fileName");
if ((sens === "shipheart_vers_cle") &&
(nom === nom_fichier_local_selectionne)) // on cherche le fichier qui correspond à la config en cours
{
actif = true;
index_fichier_local_actif = i;
}
else actif = false;
modele_fichiers_locaux.append({
"nom": nom,
"taille": Fonctions.taille_fichier(repertoire_local.get(i, "fileSize"), shipheart_langue),
"actif": actif } );
}
if ((sens === "shipheart_vers_cle") && (index_fichier_local_actif === -1)) sens = "";
}
//=============================================================================================================
// Mise à jour toutes les secondes :
//=============================================================================================================
function mise_a_jour()
{
var i;
if (shipheart_type_installation === shipheart_type_installation_shipbase) check_ports_usb(); // SDIR #317
// Note : à ce stade, on ne prend en compte que le port Avant Bas.
// Si besoin, ajouter ici une boucle pour étudier les autres ports (qui sont déjà mis à jour)
switch(etat_cle)
{
//----------------------------
case etat_cle_absente:
if (modele_ports_usb.get(shipheart_port_usb_avant_bas).presence) etat_cle = etat_cle_presente;
else break;
// break; // Volontairement pas de break;
//----------------------------
case etat_cle_presente:
if (!modele_ports_usb.get(shipheart_port_usb_avant_bas).presence)
{
etat_cle = etat_cle_absente;
break;
}
if (modele_ports_usb.get(shipheart_port_usb_avant_bas).partition !== "") etat_cle = etat_cle_presente_partition;
else break;
// break; // Volontairement pas de break;
//----------------------------
case etat_cle_presente_partition:
if (!modele_ports_usb.get(shipheart_port_usb_avant_bas).presence)
{
etat_cle = etat_cle_absente;
break;
}
if (modele_ports_usb.get(shipheart_port_usb_avant_bas).partition === "")
{
etat_cle = etat_cle_presente;
break;
}
// Lancement du montage :
busy_indicator_droite.running = true;
timer_raffraichissement_parametres.interval = periode_raffraichissement_parametres_montage_port_usb;
break;
//----------------------------
case etat_cle_presente_montee:
if (!modele_ports_usb.get(shipheart_port_usb_avant_bas).presence)
{
boite_information.niveau = 2;
boite_information.imageTitreSource = "/images/attention.png"
boite_information.message = qsTr("La clé USB a été retirée sans avoir préalablement été <i>éjectée</i> !<br />Cela peut conduire à des pertes de données sur la clé, voire sur ShipHeart.<br /><br />Lors de vos prochaines utilisations, pensez à <i>éjecter</i> la clé avec le bouton en haut de page avant de la retirer... Merci !");
boite_information.open();
etat_cle = etat_cle_absente;
modele_fichiers_cle.clear(); // Effacement du modèle si le device est retirée
break;
}
if (modele_ports_usb.get(shipheart_port_usb_avant_bas).partition === "")
{
etat_cle = etat_cle_presente;
break;
}
if (modele_ports_usb.get(shipheart_port_usb_avant_bas).montee)
{
etat_cle = etat_cle_presente_partition;
break;
}
break;
//----------------------------
case etat_cle_presente_demontee:
if (!modele_ports_usb.get(shipheart_port_usb_avant_bas).presence) etat_cle = etat_cle_absente;
break;
//----------------------------
default:
console.log("Etat_clé a une valeur anormale [" + etat_cle + "] ; elle est remise à 0.");
etat_cle = etat_cle_absente;
break;
}
}
//=============================================================================================================
// Action demandée par le bouton du haut de la zone centrale :
// - si Image_accueil : Enregistre l'image en cours de sélection comme l'image de la page d'accueil
// - si Silhouette : Enregistre l'image en cours de sélection comme l'image de la silhouette
// - si Rapport : Lance l'utilitaire de génération de rapport d'installation
// - si Sauvegarde : Lance l'utilitaire de génération d'une sauvegarde
//=============================================================================================================
function action()
{
var req, res;
var i;
var commande;
switch(mode_config_fichiers)
{
//----------------------------------------------------
case shipheart_mode_config_fichiers_image_accueil:
{
if (index_fichier_local_actif === -1) // Cas où aucun fichier n'est sélectionné :
{
nom_fichier_local_selectionne = "";
}
else nom_fichier_local_selectionne = modele_fichiers_locaux.get(index_fichier_local_actif).nom;
shipheart_fichier_image_accueil = nom_fichier_local_selectionne;
// Enregistrement dans la BDD :
req = 'UPDATE TB_Configuration ';
req += ' SET Valeur="' + nom_fichier_local_selectionne + '" ';
req += ' WHERE Nom="Fichier_image_accueil" ';
//console.log("Requête = [ " + req + "; ]");
bdd.requete_unique(req);
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_silhouette:
{
if (index_fichier_local_actif === -1) nom_fichier_local_selectionne = ""
else nom_fichier_local_selectionne = modele_fichiers_locaux.get(index_fichier_local_actif).nom;
// Enregistrement dans la BDD :
req = 'UPDATE TB_Pages ';
req += ' SET Fichier="' + nom_fichier_local_selectionne + '" ';
req += ' WHERE Cle_primaire= ' + id_page + ' ';
//console.log("Requête = [ " + req + "; ]");
bdd.requete_unique(req);
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_rapports:
{
busy_indicator_centre.running = true; // Lance le sablier (il sera arrêté lors de l'apparition du nouveau fichier par le gestionnaire FolderListModel
// Commande d'exécution du script :
commande = "sudo php " + shipheart_repertoire_utils + "/" + shipheart_nom_fichier_rapport_installation;
systeme.commande_shell_non_bloquante(commande);
//console.log("Exécution de la commande [ " + commande + " ]");
flag_new_file_en_attente = true; // Permet de lancer un traitement spécifique lorsque le fichier de sauvegarde sera détecté dans le répertoire
if (shipheart_type_installation !== shipheart_type_installation_shipbase) synchro_repertoires_shiprs();
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_sauvegardes:
{
busy_indicator_centre.running = true; // Lance le sablier (il sera arrêté lors de l'apparition du nouveau fichier par le gestionnaire FolderListModel
// Commande d'exécution du script :
commande = "sudo php " + shipheart_repertoire_utils + "/" + shipheart_nom_fichier_sauvegarde;
systeme.commande_shell_non_bloquante(commande);
//console.log("Exécution de la commande [ " + commande + " ]");
flag_new_file_en_attente = true; // Permet de lancer un traitement spécifique lorsque le fichier de sauvegarde sera détecté dans le répertoire
if (shipheart_type_installation !== shipheart_type_installation_shipbase) synchro_repertoires_shiprs();
break;
}
//----------------------------------------------------
case shipheart_mode_config_fichiers_inconnu:
default:
{
break;
}
}
}
//=============================================================================================================
// Monte le port USB dont le n° est passé en paramètre
//=============================================================================================================
function monter_port_usb(port)
{
var commande, retour;
commande = "sudo mount /dev/" + modele_ports_usb.get(port).partition + " " + shipheart_repertoire_cle_usb;
retour = systeme.commande_shell(commande, "");
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
sous_repertoire_cle = ""; // Par défaut, on se positionne à la racine de la clé lorsqu'elle est montée
}
//=============================================================================================================
// Démonte le port USB dont le n° est passé en paramètre
//=============================================================================================================
function demonter_port_usb(port)
{
var commande, retour;
commande = "sudo sync";
retour = systeme.commande_shell(commande, "");
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
retour = systeme.commande_shell(commande, ""); // Il semble que la première commande SYNC retourne immédiatement, avant que la commande elle-meme soit traitée. Une seconde permet d'être sûr que la première est terminée...
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
commande = "sudo umount -l /dev/" + modele_ports_usb.get(port).partition;
retour = systeme.commande_shell(commande, "");
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
}
//=============================================================================================================
// Vérifie la présence d'un device sur les 4 ports USB de ShipBase et met à jour le modèle correspondant
//=============================================================================================================
function check_ports_usb()
{
var commande, retour;
var i, j;
var port_en_cours = shipheart_port_usb_aucun;
var etat_sequenceur;
var flag_devices_presents;
var lignes;
var params;
var param_levs;
var param_ports;
var param_products;
//-------------------------------------------------------------------------------------------
// Copie du fichier des devices USB vers le répertoire temporaire (impossible à lire sinon) :
commande = "sudo cp " + shipheart_repertoire_sys_usb + "/" + shipheart_nom_fichier_usb_devices + " " + shipheart_repertoire_tmp_usb + "/" + shipheart_nom_fichier_usb_devices;
retour = systeme.commande_shell(commande, "");
//console.log("Exécution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
//-------------------------------------------------------------------------------------------
// RAZ des valeurs par défaut (pour prendre en compte le faitq que le device a pu être retiré) :
for (i = 0; i < modele_ports_usb.count; i ++)
{
modele_ports_usb.set(i, {
"presence": false,
"disk": "",
"partition": "",
"monte": false,
"size": "",
"used": "",
"label": "",
"manufacturer": "",
"product": "",
"serial_number": "" } );
}
//-------------------------------------------------------------------------------------------
// Lecture du fichier des devices :
// Note : on ne peut pas lire directement le fichier qui est protégé ; on en fait donc une copie dans le répertoire TMP.
// Voir le contenu, qui est assez explicite, par 'sudo cat /sys/kernel/debug/usb/devices'
lignes = systeme.lecture_fichier(shipheart_repertoire_tmp_usb + "/" + shipheart_nom_fichier_usb_devices);
// ATTENTION : la première ligne renvoyée par la fonction n'est PAS lue dans le fichier mais indique si la lecture s'est déroulée correctement ("Ok") ou pas ("Nok").
//console.log("Résultat de la lecture du fichier = " + lignes[0]);
if (lignes[0] === "Ok")
{
etat_sequenceur = 0;
for (i = 1; i < lignes.length; i ++)
{
//console.log(i + " : " + lignes[i]);
if (lignes[i] !== "")
{
lignes[i] = lignes[i].replace(/\s\s+/g, ' '); // Remplace les espaces multiples, tabulations, etc... par un seul espace
params = lignes[i].split(' ');
if (params.length > 0)
{
switch(etat_sequenceur)
{
//----------------------------
// Etat de repos (attente d'un "T: ") :
// Exemple : 'T: Bus=01 Lev=03 Prnt=27 Port=00 Cnt=01 Dev#= 31 Spd=12 MxCh= 0'
case 0:
if (params[0] === "T:")
{
param_levs = params[2].split('=');
param_ports = params[4].split('=');
// NOTE : on considère que la clé est branchée directement, sans passer par un hub. Sinon, son LEVEL sera > 2.
// Si besoin de prendre en compte l'utilisation de HUB, c'est possible mais il faudra affiner l'algorithme en utilisant
// les champs 'Dev#=' contenant le n° de device du HUB et le champ 'Prnt=' contenant le n° du parent.
// Il faut donc attraper le 'Dev#' du Hub au 'Level=02' & 'Port=00' (arrière) ou 'Port=02' (avant) puis traiter les autres
// entrées avec 'Level' > 2 et dont le 'Prnt' === le 'Dev#' du hub...
// A noter qu'on peut aussi traiter tout cela de façon récusrive si on veut traiter les empilements de hub...!
if (Number(param_levs[1]) === 2)
{
// On ne traite que les ports qui nous interressent :
if ((Number(param_ports[1]) >= shipheart_port_usb_arriere)
&& (Number(param_ports[1]) <= shipheart_port_usb_touchpad))
{
port_en_cours = Number(param_ports[1]);
modele_ports_usb.set(port_en_cours, { "presence": true});
etat_sequenceur = 1;
}
}
}
break;
//----------------------------
// Attente des lignes de type "S: "
case 1:
if (params[0] === "S:")
{
param_products = params[1].split('=');
switch(param_products[0])
{
//---------------------
case "Manufacturer":
// ports_usb[port_en_cours]['manufacturer'] = lignes[i].substring(lignes[i].indexOf('=')+1);
modele_ports_usb.set(port_en_cours, { "manufacturer": lignes[i].substring(lignes[i].indexOf('=')+1)}); // Récupère tout ce qui est après le '=' car il peut y avoir des espaces...
break;
//---------------------
case "Product":
// ports_usb[port_en_cours]['product'] = lignes[i].substring(lignes[i].indexOf('=')+1); // Récupère tout ce qui est après le '=' car il peut y avoir des espaces...
modele_ports_usb.set(port_en_cours, { "product": lignes[i].substring(lignes[i].indexOf('=')+1)}); // Récupère tout ce qui est après le '=' car il peut y avoir des espaces...
break;
//---------------------
case "SerialNumber":
// ports_usb[port_en_cours]['serial_number'] = lignes[i].substring(lignes[i].indexOf('=')+1); // Récupère tout ce qui est après le '=' car il peut y avoir des espaces...
modele_ports_usb.set(port_en_cours, { "serial_number": lignes[i].substring(lignes[i].indexOf('=')+1)}); // Récupère tout ce qui est après le '=' car il peut y avoir des espaces...
break;
}
}
break;
//----------------------------
default:
etat_sequenceur = 0;
break;
}
}
}
else etat_sequenceur = 0;
}
}
//-------------------------------------------------------------------------------------------
// Synthèse des devices trouvés :
flag_devices_presents = false;
for (i = 0; i < modele_ports_usb.count; i ++)
{
if (!modele_ports_usb.get(i).presence) continue;
// On ne prend en compte que les ports accessibles de l'éxtérieur :
// NB : pour les V1, le port Arrière n'est pas accessible mais il ne sera donc jamais détecté...
if ((i === shipheart_port_usb_arriere) || (i === shipheart_port_usb_avant_bas)) flag_devices_presents = true;
}
//-------------------------------------------------------------------------------------------
// Recherche des disque et partitions présentes :
if (flag_devices_presents)
{
//-------------------------------------------------------------------------------------------
// génération de la commande LSBLK qui permet d'obtenir un lien entre disque/partition et n° de série du device :
// La commande permet d'obtenir quelque chose comme :
// disk sda 4C530001130622100112
// part sda1 Koriolan
// disk sdb 4C531001530726109585
// part sdb1 KORIOLAN /home/koriolan/cle_usb 7.4G 35%
// Où '-I 8' permet de n'inclure que les drivers de Major Code = 8, soit les 'sdxx'
// 'TYPE,KNAME,LABEL,SERIAL,MOUNTPOINT,FSSIZE,FSUSE%' est la liste des paramètres attendus
// '-n' supprime la ligne de titres de espace_colonnes_principales
// '-r' donne une sortie "raw" dans laquelle les TAB sont remplacées par des espaces.
commande = "sudo lsblk -I 8 -o TYPE,KNAME,LABEL,SERIAL,MOUNTPOINT,FSSIZE,FSUSE% -n -r ";
retour = systeme.commande_shell(commande, shipheart_repertoire_tmp_usb + "/" + shipheart_nom_fichier_usb_lsblk); // Le second argument est la redirection de la sortie.
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
//-------------------------------------------------------------------------------------------
// Lecture du fichier 'resultat_lsblk' :
lignes = systeme.lecture_fichier(shipheart_repertoire_tmp_usb + "/" + shipheart_nom_fichier_usb_lsblk);
// ATTENTION : la première ligne renvoyée par la fonction n'est PAS lue dans le fichier mais indique si la lecture s'est déroulée correctement ("Ok") ou pas ("Nok").
//console.log("Résultat de la lecture du fichier = " + lignes[0]);
if (lignes[0] === "Ok")
{
port_en_cours = -1;
for (i = 1; i < lignes.length; i ++)
{
//console.log(i + " : " + lignes[i]);
if (lignes[i] !== "")
{
lignes[i] = lignes[i].replace(/\s\s+/g, ' '); // Remplace les espaces multiples, tabulations, etc... par un seul espace
params = lignes[i].split(' ');
if (params.length > 0)
{
//--------------------------------------------
// Lecture de la ligne commençant par 'disk' :
if (params[0] === "disk")
{
for (j = 0; j < modele_ports_usb.count; j ++)
{
if (!modele_ports_usb.get(j).presence) continue;
if (modele_ports_usb.get(j).serial_number === params[2])
{
modele_ports_usb.set(j, { "disk": params[1] });
port_en_cours = j;
}
}
}
//--------------------------------------------
// Lecture de la ligne commençant par 'part' :
else if (params[0] === "part")
{
if (port_en_cours !== -1) // Ne devrait pas arriver si les lignes sont bien ordonnées : 'disk' puis 'part'
{
if (modele_ports_usb.get(port_en_cours).disk[2] === params[1][2]) // On compare la lettre X de 'sdX' du disk et de 'sdX1' de la partition
{
modele_ports_usb.set(port_en_cours, { "partition": params[1] });
modele_ports_usb.set(port_en_cours, { "label": params[2] });
if (params.length >= 4) modele_ports_usb.set(port_en_cours, { "monte": (params[3] !== "") });
if (params.length >= 5) modele_ports_usb.set(port_en_cours, { "size": params[4] });
if (params.length >= 6) modele_ports_usb.set(port_en_cours, { "used": params[5] });
port_en_cours = -1;
}
}
}
}
}
}
}
}
// Boucle sur tous les ports présents :
for (i = 0; i < modele_ports_usb.count; i ++)
{
if (!modele_ports_usb.get(i).presence) continue;
if ((i !== shipheart_port_usb_arriere) && (i !== shipheart_port_usb_avant_bas)) continue;
/* console.log(i+"=Port [" + modele_ports_usb.get(i).nom + "] détecté :
Disk=" + modele_ports_usb.get(i).disk + ",
Part=" + modele_ports_usb.get(i).partition + ",
Label=" + modele_ports_usb.get(i).label + ",
Monté=" + modele_ports_usb.get(i).monte + ",
Size=" + modele_ports_usb.get(i).size + ",
Used=" + modele_ports_usb.get(i).used + ",
Manufacturer=" + modele_ports_usb.get(i).manufacturer + ",
Product=" + modele_ports_usb.get(i).product + ",
SerialNumber=" + modele_ports_usb.get(i).serial_number );
*/
// Mise à jour du modèle de la clé si elle est montée mais n'a jamais été mise à jour :
if ((modele_ports_usb.get(i).monte) && (modele_fichiers_cle.count === 0))
{
ls(shipheart_repertoire_cle_usb + ((sous_repertoire_cle === "") ? "" : "/" + sous_repertoire_cle)); // Rechargement du modèle avec le contenu du sous-répertoire
}
}
}
//=============================================================================================================
// Liste les fichiers et répertoires présents dans le répertoire dont le chemin complet est passé en paramètres
//=============================================================================================================
function ls(dir)
{
var commande, retour;
var i;
var lignes;
var params;
//-------------------------------------------------------------------------------------------
// génération de la commande 'ls <dir> -lh' permet d'obtenir quelque chose comme :
// total 1271152
// -rwxr-xr-x 1 root root 1.5K Jun 16 2023 backend.cpp
// -rwxr-xr-x 1 root root 99K Apr 15 2024 batterie.qml
// -rwxr-xr-x 1 root root 7.8K Apr 14 2024 bdd.cpp
// -rwxr-xr-x 1 root root 651 Apr 14 2024 bdd.h
// drwxr-xr-x 3 root root 4.0k Jun 21 2023 Projets_Qt
// -rwxr-xr-x 1 root root 1.3G Jul 11 2023 shiprs_cm4_2023_06_17.img.gz
// drwxr-xr-x 2 root root 4.0K Jul 5 2023 System Volume Information
commande = "sudo ls " + dir + " -l";
retour = systeme.commande_shell(commande, shipheart_repertoire_tmp_usb + "/" + shipheart_nom_fichier_usb_ls); // Le second argument est la redirection de la sortie.
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
//-------------------------------------------------------------------------------------------
// Lecture du fichier 'resultat_ls' :
lignes = systeme.lecture_fichier(shipheart_repertoire_tmp_usb + "/" + shipheart_nom_fichier_usb_ls);
// ATTENTION : la première ligne renvoyée par la fonction n'est PAS lue dans le fichier mais indique si la lecture s'est déroulée correctement ("Ok") ou pas ("Nok").
//console.log("Résultat de la lecture du fichier = " + lignes[0]);
if (lignes[0] === "Ok")
{
modele_fichiers_cle.clear();
// Ajout du bouton de remontée vers le répertoire parent si on n'est pas à la racine de la clé :
if (sous_repertoire_cle !== "")
{
modele_fichiers_cle.append( {
"type": "dir",
"nom": "..",
"taille": "",
"taille_octets": 0,
"actif": false,
"autorise": false } );
}
for (i = 1; i < lignes.length; i ++)
{
//console.log(i + " : " + lignes[i]);
if (lignes[i] !== "")
{
lignes[i] = lignes[i].replace(/\s\s+/g, ' '); // Remplace les espaces multiples, tabulations, etc... par un seul espace
params = lignes[i].split(' ');
if (params.length === 9)
{
//--------------------------------------------
// Lecture de la ligne commençant par '-' :
if (params[0][0] === '-') // Cas d'un fichier (exemple : "-rwxr-xr-x 1 root root 1536 Jun 16 2023 backend.cpp")
{
// Recherche de l'extensio du fichier et teste s'il est autorisé dans la liste :
var pos_extension = params[8].lastIndexOf('.')
var autorise = false;
if (pos_extension !== -1)
{
autorise = texte_types_fichiers_valides.includes(params[8].slice(pos_extension));
}
//console.log("Fichier "+params[8]+", taille="+params[4]+", texte_types_fichiers_valides="+texte_types_fichiers_valides+", Extension="+ params[8].slice(pos_extension))
modele_fichiers_cle.append( {
"type": "fic",
"nom": params[8],
"taille": Fonctions.taille_fichier(Number(params[4]), shipheart_langue),
"taille_octets": Number(params[4]),
"actif": false,
"autorise": autorise } );
}
//--------------------------------------------
// Lecture de la ligne commençant par 'd' :
else if (params[0][0] === 'd') // Cas d'une répertoire (exemple : "drwxr-xr-x 3 root root 4096 Jun 21 2023 Projets_Qt")
{
//console.log("Répertoire "+params[8]+", taille="+params[4] )
modele_fichiers_cle.append( {
"type": "dir",
"nom": params[8],
"taille": Fonctions.taille_fichier(Number(params[4]), shipheart_langue),
"taille_octets": Number(params[4]),
"actif": false,
"autorise": false } );
}
}
}
}
}
}
//=============================================================================================================
// Copie les fichier sélectionnés (le 'sens' indiquant où sont situés les fichiers à copier et vers où les copier)
//=============================================================================================================
function copie_fichiers()
{
var commande, retour;
var i;
//console.log("Demande de copie de fichiers dans le sens : " + sens)
if (sens === "shipheart_vers_cle")
{
for (i = 0; i < modele_fichiers_locaux.count; i ++)
{
if (modele_fichiers_locaux.get(i).actif)
{
commande = "cp " + nom_repertoire_local + "/" + modele_fichiers_locaux.get(i).nom + " " + shipheart_repertoire_cle_usb + ((sous_repertoire_cle === "") ? "" : "/" + sous_repertoire_cle) + "/" + modele_fichiers_locaux.get(i).nom;
retour = systeme.commande_shell(commande, "");
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
}
}
// Mise à jour du modèle du répertoire de la clé :
ls(shipheart_repertoire_cle_usb + ((sous_repertoire_cle === "") ? "" : "/" + sous_repertoire_cle));
}
else if (sens === "cle_vers_shipheart")
{
for (i = 0; i < modele_fichiers_cle.count; i ++)
{
if (modele_fichiers_cle.get(i).actif)
{
commande = "cp " + shipheart_repertoire_cle_usb + ((sous_repertoire_cle === "") ? "" : "/" + sous_repertoire_cle) + "/" + modele_fichiers_cle.get(i).nom + " " + nom_repertoire_local + "/" + modele_fichiers_cle.get(i).nom;
retour = systeme.commande_shell(commande, "");
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
}
}
// NB : la mise à jour du modèle local se fait automatiquement par FolderListModel
}
}
//=============================================================================================================
// Supprime les fichier sélectionnés (le 'sens' indiquant où sont situés les fichiers à supprimer
//=============================================================================================================
function suppression_fichiers()
{
var commande, retour;
var i;
//console.log("Demande de suppression de fichiers dans le sens : " + sens)
if (sens === "shipheart_vers_cle")
{
for (i = 0; i < modele_fichiers_locaux.count; i ++) // NB : on pourrait utiliser 'index_fichier_local_selectionne' mais on garde le principe général qui accepte la suppression multiple...
{
if (modele_fichiers_locaux.get(i).actif)
{
commande = "rm " + nom_repertoire_local + "/" + modele_fichiers_locaux.get(i).nom;
retour = systeme.commande_shell(commande, "");
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
// Remise à la valeur par défaaut si on vient de supprimer le fichier sélectionné :
modele_fichiers_locaux.get(i).actif = false; // Permet que la 'selectionner_image()' qui suit fonctionne alors que la synchro du modèle n'est pas encore faite...
}
}
// NB : la mise à jour du modèle local se fait automatiquement par FolderListModel
}
else if (sens === "cle_vers_shipheart")
{
for (i = 0; i < modele_fichiers_cle.count; i ++)
{
if (modele_fichiers_cle.get(i).actif)
{
commande = "rm " + shipheart_repertoire_cle_usb + ((sous_repertoire_cle === "") ? "" : "/" + sous_repertoire_cle) + "/" + modele_fichiers_cle.get(i).nom;
retour = systeme.commande_shell(commande, "");
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
}
}
ls(shipheart_repertoire_cle_usb + ((sous_repertoire_cle === "") ? "" : "/" + sous_repertoire_cle));
}
}
//=============================================================================================================
// Lance le process de restauration du fichier sélectionnés (le fichier est forcément sur ShipBase !)
//=============================================================================================================
function restauration()
{
var commande, retour;
var i;
var flag_reboot = false;
if (sens === "shipheart_vers_cle")
{
for (i = 0; i < modele_fichiers_locaux.count; i ++)
{
if (modele_fichiers_locaux.get(i).actif)
{
commande = "sudo cp " + nom_repertoire_local + "/" + modele_fichiers_locaux.get(i).nom + " " + shipheart_repertoire_versions_a_charger + "/" + modele_fichiers_locaux.get(i).nom;
retour = systeme.commande_shell(commande, "");
//console.log("Excution de la commande [ " + commande + " ]. Retour = [ " + retour + " ]");
flag_reboot = true;
break;
}
}
if (flag_reboot) rebooter();
}
}
//=============================================================================================================
// Synchroniser répertoire docs ShipRS
//=============================================================================================================
function synchro_repertoires_shiprs()
{
var commande;
commande = "rsync -aPs --delete -e \"ssh -p 2022 -o StrictHostKeyChecking=no \" koriolan@" + AppInfo.adresse_shipbase + ":" + shipheart_repertoire_config + "/ " + shipheart_repertoire_config + "/";
systeme.commande_shell(commande, "");
}
//=============================================================================================================
// Sortie
// Cette fonction remet dans l'état initial les alimentations de ports USB avant de sortir (SDIR #303)
//=============================================================================================================
function sortie()
{
// Remise à l'état initial de l'alim des ports USB :
if (etat_initial_port_usb_avant === 0)
{
bdd.requete_unique('UPDATE TB_Circuits SET New_consigne=0 WHERE Adresse_module=0 AND No_circuit=1 ');
}
if (etat_initial_port_usb_arrière === 0)
{
bdd.requete_unique('UPDATE TB_Circuits SET New_consigne=0 WHERE Adresse_module=0 AND No_circuit=2 ');
}
// Demande de prise en compte des nouvelles consignes :
synchro_bdd(shipheart_type_synchro_data);
// Sortie effective de la page :
stackView.pop();
}
}