Files

185 lines
8.1 KiB
C++

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QSqlDatabase>
#include <QSqlError>
#include <QtQml>
#include <QTranslator>
#include <unistd.h> // Pour usleep(), msleep() et sleep()
#include "backend.h"
#include "bdd.h"
#include "shipheart.h"
#include "systeme.h"
#include "tb_mesures.h"
#include "_version.h"
// Variables globales :
uint8_t etat_connexion_bdd;
QString TypeInstallation;
QString TailleEcran;
QString AdresseShipBase;
QTranslator translator; // En le déclarant ici, permet d'y accéder dans les fonctions de slot ('backend()' notamment...)
//===================================================================================================
// Fonction : Connexion à la base de données
//===================================================================================================
static void connectToDatabase()
{
QString adresse_host;
QSqlDatabase database = QSqlDatabase::database();
if (!database.isValid()) {
database = QSqlDatabase::addDatabase("QMYSQL");
if (!database.isValid())
qFatal("Cannot add database: %s", qPrintable(database.lastError().text()));
}
// Choix de l'adresse de la BDD :
switch (TypeInstallation.toInt()) // Renvoi 0 si la conversion échoue (ce qui est le cas si aucun paramètre n'est passé au démarrage, comme c'est le cas sur ShipBase)
{
default:
case 0: // Si on est sur ShipBase, on va se connecter sur 'localhost'
adresse_host = BDD_HOST_NAME;
break;
case 1: // Si on est sur un écran déporté, on va se connecter sur l'adresse de ShipBase reçue au lancement.
// SDIR #320 :
if (AdresseShipBase == "192.168.4.1") AdresseShipBase = "192.168.1.1";
adresse_host = AdresseShipBase;
// Fin de SDIR #320
break;
}
database.setHostName(adresse_host);
database.setUserName(BDD_USER_NAME);
database.setPassword(BDD_USER_PWD);
database.setDatabaseName(BDD_BASE_NAME);
int16_t nb_essais;
int16_t max_nb_essais = 20;
etat_connexion_bdd = 0; // Valeur par défaut (déconnecté)
// En pratique, la tentative de connexion qui échoue dure environ 2s. Donc, avec une tempo de 1s d'attente, on fait uen tentative en 3s.
// Exemple : avec un max = 30, le passage à l'écran de défaut de connexion sur ShipRS se fait au bout de 1min 35s après le lancement de Qt.
for (nb_essais = 0; nb_essais < max_nb_essais; nb_essais ++)
{
if (!database.open())
{
qDebug("Erreur : impossible de se connecter à la base de données [%s]", qPrintable(database.lastError().text()));
sleep(1);
}
else
{
etat_connexion_bdd = 1;
qDebug() << "Connection à la base de données à l'adresse " << adresse_host << ", après essai n° " << nb_essais;
break;
}
}
}
//===================================================================================================
// Fonction : Fourni à QML des valeurs accessibles en C via un singleton intégré à
// "qt.koriolan.shipheart" (cf 'main' ci-dessous)
//===================================================================================================
static QJSValue appVersionSingletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
QJSValue appInfo = scriptEngine->newObject();
appInfo.setProperty("adresse_shipbase", AdresseShipBase);
appInfo.setProperty("etat_connexion_bdd", etat_connexion_bdd);
appInfo.setProperty("version", VERSION); // Fourni la version récupérée depuis le fichier .pro afin de la rendre disponible en QML
appInfo.setProperty("type_installation", TypeInstallation);
appInfo.setProperty("taille_ecran", TailleEcran);
return appInfo;
}
//===================================================================================================
// Fonction : Main
//===================================================================================================
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
qputenv("QT_VIRTUALKEYBOARD_LAYOUT_PATH", ":/virtualkeyboard_layouts_koriolan/layouts"); // Ajout en V3.0.17 pour accéder aux layouts personnalisés
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
//-------------------------------------------------------------
// Création de l'application :
QApplication app(argc, argv);
app.setOverrideCursor(Qt::BlankCursor);
QApplication::setApplicationName("ShipHeart_Qt"); // Nom de l'appli si invoqué avec '-v'
QApplication::setApplicationVersion(VERSION); // Version de l'appli si invoqué avec '-v'
//-------------------------------------------------------------
// Parser de ligne de commande :
QCommandLineParser parser;
parser.addHelpOption(); // Autorise l'invocation avec '-h' ou '--help'
parser.addVersionOption(); // Autorise l'invocation avec 'v' ou '--version'
// An option with a value :
QCommandLineOption type_installation(QStringList() << "i" << "installation",
QApplication::translate("main", "Type d'installation :\n0 : ShipBase standard, \n1 : écran déporté"),
QApplication::translate("main", "valeur"));
parser.addOption(type_installation);
QCommandLineOption adresse_shipbase(QStringList() << "a" << "adresse",
QApplication::translate("main", "Adresse IPv4 de ShipBase dans le cas d'une installation déportée"),
QApplication::translate("main", "xxx:xxx:xxx:xxx"));
parser.addOption(adresse_shipbase);
QCommandLineOption taille_ecran(QStringList() << "t" << "taille",
QApplication::translate("main", "Taille de l'écran en pouces : \n7,\n10 (ShipBase standard),\n22"),
QApplication::translate("main", "valeur"));
parser.addOption(taille_ecran);
// Process the actual command line arguments given by the user :
parser.process(app);
TypeInstallation = parser.value(type_installation);
TailleEcran = parser.value(taille_ecran);
AdresseShipBase = parser.value(adresse_shipbase);
qDebug() << "Type d'installation : " << TypeInstallation << ", adresse ShipBase : " << AdresseShipBase << ", taille d'écran : " << TailleEcran << " pouces";
// Fin du parser de commande.
//------------------------------------------------------------
qmlRegisterType<Bdd>("qt.koriolan.shipheart", 1, 0, "Bdd");
qmlRegisterType<TbMesuresModel> ("qt.koriolan.shipheart", 1, 0, "TbMesuresModel");
qmlRegisterType<Systeme>("qt.koriolan.shipheart", 1, 0, "Systeme");
qmlRegisterSingletonType("qt.koriolan.shipheart", 1, 0, "AppInfo", appVersionSingletonProvider);
connectToDatabase();
auto engine = new QQmlApplicationEngine(&app); // Ce type de déclaration est un peu inhabituel mais solution trouvée pour remonter à cette variable depuis l'app (nécessaire pour gérer la mise à jour de la langue dans le backend)
engine->setObjectName("currentEngine");
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl)
{
if (!obj && url == objUrl) QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
Backend backend;
engine->rootContext()->setContextProperty("backend", &backend);
engine->load(url);
if (translator.load(":/shipheart_fr_FR.qm")) // Par défaut, on charge le fichier FR
{
// qDebug() << "Chargement de shipheart_fr_FR.qm par défaut";
}
app.installTranslator(&translator); // ... et on l'installe (il sera éventuellement supprimé si la langue stockée dans la BDD est différente)
return app.exec();
}