#include #include #include #include #include #include #include // 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("qt.koriolan.shipheart", 1, 0, "Bdd"); qmlRegisterType ("qt.koriolan.shipheart", 1, 0, "TbMesuresModel"); qmlRegisterType("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(); }