Files
RRJServer/LibServer/serverlmswidget.cpp
2026-02-09 11:45:04 +03:00

636 lines
19 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <QThread>
#include "serverlmswidget.h"
#include "dialogsettingstray.h"
#include "specialmessagebox.h"
#include "metatypes.h"
#include "ui_serverlmswidget.h"
const QString ServerLMSWidget::languageENG = "en_EN";
const QString ServerLMSWidget::languageRUS = "ru_RU";
ServerLMSWidget::ServerLMSWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ServerLMSWidget),
waitAnimationWidget(nullptr),
updateThread(nullptr),
loggerThread(nullptr),
serverThread(nullptr),
server(nullptr),
dataParser(nullptr),
processingSystem(nullptr),
commonClientHandler(nullptr),
chatSystem(nullptr),
providerDBLMS(nullptr),
updateController(nullptr),
assetsManager(nullptr),
docsUpdater(nullptr),
cfiController(nullptr),
language(languageENG),
errorCode(0),
state_VersionMaterials("..."),
state_dbIsConnected(false),
state_Server(EStateServer::stoped),
state_BlockAutorization(EStateBlockAutorization::unblocked),
flStartInitialization(false),
flTryConnectionToDB(false),
flNeedReconnectDB(false),
flTryUpdateDocs(false)
{
ui->setupUi(this);
qDebug() << "ServerLMSWidget init thread ID " << QThread::currentThreadId();
ui->widget_Control->setObjectName("widgetControl");
ui->btnStopServer->setObjectName("btnStopServer");
ui->btnStartServer->setObjectName("btnStartServer");
ui->btnSettings->setObjectName("btnSettings");
registerMetaType();
updateMyStyleSheet();
initLanguageInterfase();
waitAnimationWidget = new WaitAnimationWidget;
QMovie *movie = new QMovie(":/resources/icons/762.gif");
waitAnimationWidget->setParent(this);
waitAnimationWidget->initialize(movie,this);
}
ServerLMSWidget::~ServerLMSWidget()
{
if(server)
emit signal_StopServer();
if(updateThread)
{
updateThread->quit();
updateThread->wait();
delete updateThread;
}
if(serverThread)
{
serverThread->quit();
serverThread->wait();
delete serverThread;
}
if(server)
delete server;
if(commonClientHandler)
delete commonClientHandler;
if(dataParser)
delete dataParser;
if(processingSystem)
delete processingSystem;
if(updateController)
delete updateController;
if(cfiController)
delete cfiController;
if(docsUpdater)
delete docsUpdater;
if(assetsManager)
delete assetsManager;
if(chatSystem)
delete chatSystem;
if(loggerThread)
{
loggerThread->quit();
loggerThread->wait();
delete loggerThread;
}
if(providerDBLMS)
delete providerDBLMS;
if(waitAnimationWidget)
{
waitAnimationWidget->hideWithStop();
delete waitAnimationWidget;
}
delete ui;
}
//INTERFACE
void ServerLMSWidget::startInitialization()
{
startInitialization_step0();
}
QString ServerLMSWidget::getLanguage()
{
return language;
}
//EVENT
void ServerLMSWidget::changeEvent(QEvent *event)
{
// В случае получения события изменения языка приложения
if (event->type() == QEvent::LanguageChange)
{
ui->retranslateUi(this); // переведём окно заново
//И все состояния
updateStateOnlyServer();
updateStateOnlyDB();
updateStateOnlyVersionMaterials();
}
}
void ServerLMSWidget::resizeEvent(QResizeEvent *event)
{
QSize size = event->size();
waitAnimationWidget->resize(size);
}
//STYLESHEET
void ServerLMSWidget::updateMyStyleSheet()
{
QString styleSheet = loadStyleSheet();
styleSheet = styleSheet.replace("\n", "");
this->setStyleSheet(styleSheet);
}
QString ServerLMSWidget::loadStyleSheet()
{
QString fileName = "./resources/css/styleSheetMain.css";
QFile styleSheetFile(fileName);
if (!styleSheetFile.open(QFile::ReadOnly | QFile::Text))
{
SpecMsgBox::WarningClose(this, tr("The file could not be opened ") + fileName);
return QStringLiteral("");
}
else
{
QByteArray byteArray = styleSheetFile.readAll();
styleSheetFile.close();
QString style = byteArray;
return style;
}
}
//LANGUAGE
void ServerLMSWidget::initLanguageInterfase()
{
ServerDBSettings settings;
DialogSettingsTray::loadSettings(&settings);
if(settings.Language == "ENG")
{
qtLanguageTranslator.load(QString("translations/RRJServer_") + languageENG, ".");
language = languageENG;
}
else
{
qtLanguageTranslator.load(QString("translations/RRJServer_") + languageRUS, ".");
language = languageRUS;
}
qApp->installTranslator(&qtLanguageTranslator);
emit signal_LanguageChanged(language);
}
//UPDATE STATES
void ServerLMSWidget::updateStateOnlyServer()
{
if(state_Server == EStateServer::started)
{
if(state_BlockAutorization == EStateBlockAutorization::unblocked)
{
ui->lblOnOffText->setText(tr("started"));
ui->lblOnOff->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGreen.png")));
}
else
{
ui->lblOnOffText->setText(tr("started") + ", " + tr("locked"));
ui->lblOnOff->setPixmap(QPixmap(QStringLiteral(":/resources/icons/lock.png")));
}
}
else
{
ui->lblOnOffText->setText(tr("stoped"));
ui->lblOnOff->setPixmap(QPixmap(QStringLiteral(":/resources/icons/stoped.png")));
}
emit signal_Tray_UpdateStateServer(state_Server, state_BlockAutorization);
}
void ServerLMSWidget::updateStateOnlyDB()
{
if(state_dbIsConnected)
{
//Настройки БД
QString strDBsettings = tr("connected") + QString(" [%1 (%2) %3 : %4]").arg(state_dbSettings.dbName,
state_dbSettings.dbType,
state_dbSettings.dbHostName,
QString::number(state_dbSettings.dbPort));
ui->lblDBsettings->setText(strDBsettings);
ui->lblDBisConnected->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGreen.png")));
}
else
{
ui->lblDBsettings->setText(tr("not connected"));
ui->lblDBisConnected->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGray.png")));
ui->btnStopServer->setEnabled(false);
ui->btnStartServer->setEnabled(false);
}
}
void ServerLMSWidget::updateStateOnlyVersionMaterials()
{
ui->lblVersionText->setText(state_VersionMaterials);
}
//SLOTS
void ServerLMSWidget::slot_UpdateListClients(QStringList listFullName)
{
//Очищаем список
ui->listWidget_Clients->clear();
for (const QString clientFullName : listFullName)
{
ui->listWidget_Clients->addItem(clientFullName);
ui->listWidget_Clients->scrollToBottom();
ui->listWidget_Clients->setCurrentRow(ui->listWidget_Clients->count() - 1);
}
int countClients = listFullName.count();
Logger::instance().log("SERVER: countClients = " + QString::number(countClients));
}
void ServerLMSWidget::slot_AddMessageToLog(QString message)
{
ui->loggerTextField->appendHtml(message);
}
void ServerLMSWidget::slot_ErrorPostgreSQL(QString text)
{
emit signal_Menu_ShowWindow();
SpecMsgBox::CriticalClose(this, tr("Error PostgreSQL!") + "\n" + text);
}
void ServerLMSWidget::slot_StateConnectionToDB(bool dbIsConnected, DataBaseSettings dbSettings)
{
this->state_dbIsConnected = dbIsConnected;
this->state_dbSettings = dbSettings;
updateStateOnlyDB();
}
void ServerLMSWidget::slot_StateServer(EStateServer stateServer, EStateBlockAutorization stateBlockAutorization)
{
if(this->state_Server != stateServer)
{
this->state_Server = stateServer;
this->state_BlockAutorization = stateBlockAutorization;
updateStateOnlyServer();
if(stateServer == EStateServer::started)
{
ui->btnStartServer->setEnabled(false);
ui->btnStopServer->setEnabled(true);
emit signal_Tray_ShowMessage(tr("Server is started!"));
}
else
{
ui->btnStopServer->setEnabled(false);
ui->btnStartServer->setEnabled(true);
emit signal_Tray_ShowMessage(tr("Server is stoped!"));
}
}
else
{
this->state_Server = stateServer;
this->state_BlockAutorization = stateBlockAutorization;
updateStateOnlyServer();
}
}
void ServerLMSWidget::slot_StateVersionMaterials(QString versionStr)
{
this->state_VersionMaterials = versionStr;
updateStateOnlyVersionMaterials();
}
void ServerLMSWidget::slot_ResultTryConnectDb(bool result)
{
if(flTryConnectionToDB)
{
flTryConnectionToDB = false;
if(result)
{
//Настройки БД
DataBaseSettings dbSettings = providerDBLMS->getDBSettings();
QString strDBsettings = QString("%1 (%2) %3 : %4").arg(dbSettings.dbName,
dbSettings.dbType,
dbSettings.dbHostName,
QString::number(dbSettings.dbPort));
Logger::instance().log("Connection to DB completed!");
emit signal_Tray_ShowMessage(tr("Database connection OK!") + "\n" + strDBsettings);
on_btnStartServer_clicked();
if(flStartInitialization)
{
flStartInitialization = false;
startInitialization_step3();
}
}
else
{
Logger::instance().log("Database connection error!");
emit signal_Tray_ShowMessage(tr("Database connection error!"), QSystemTrayIcon::Critical);
emit signal_Menu_ShowWindow();
SpecMsgBox::CriticalClose(this, tr("Database connection error!"));
on_btnSettings_clicked();
}
}
}
void ServerLMSWidget::slot_ResultTryDisConnectDb(bool result)
{
if(flNeedReconnectDB)
{
flNeedReconnectDB = false;
SpecMsgBox::WarningClose(this, tr("Database settings have been changed.\nThe server will be restarted."));
tryConnectionToDB();
}
}
void ServerLMSWidget::slot_SetError(int code)
{
if(code == 100)
{
QString textError = tr("No Client files found!") + "\n\n" +
tr("* check Application for the presence of a folder with a build \n"
"* check SharedData for a folder with the base version and the name base");
SpecMsgBox::CriticalClose(this, textError);
}
errorCode = code;
emit signal_StartInitHasError(code);
}
void ServerLMSWidget::slot_UpdateDocsCompleted()
{
if(flTryUpdateDocs)
{
flTryUpdateDocs = false;
startInitialization_step2();
}
}
void ServerLMSWidget::slot_UpdateControllerInitializeFinished()
{
startInitialization_step1();
}
void ServerLMSWidget::slot_BlockAutorizationIndicate(bool block, QString blocker, QString types)
{
if(block)
{
Logger::instance().log(QString("BLOCK from: %1").arg(blocker), LogLevel::INFO);
Logger::instance().log(QString("Blockers: %1").arg(types), LogLevel::DEBUG);
}
else
{
Logger::instance().log(QString("UNBLOCK from: %1").arg(blocker), LogLevel::INFO);
Logger::instance().log(QString("Blockers: %1").arg(types), LogLevel::DEBUG);
}
updateStateOnlyServer();
}
void ServerLMSWidget::slot_LanguageChanged(QString language)
{
qtLanguageTranslator.load(QString("translations/RRJServer_") + language, ".");
qApp->installTranslator(&qtLanguageTranslator);
emit signal_LanguageChanged(language);
}
//ON_BTN
void ServerLMSWidget::on_btnStartServer_clicked()
{
emit signal_StartServer();
ui->btnStartServer->setEnabled(false);
ui->btnStopServer->setEnabled(true);
}
void ServerLMSWidget::on_btnStopServer_clicked()
{
emit signal_StopServer();
ui->btnStopServer->setEnabled(false);
ui->btnStartServer->setEnabled(true);
}
void ServerLMSWidget::on_btnSettings_clicked()
{
ServerDBSettings settingsTemp;
if(!DialogSettingsTray::loadSettings(&settingsTemp))
{
SpecMsgBox::CriticalClose(this, tr("Settings file could not be opened:") + "'config/settings.xml'");
return;
}
DialogSettingsTray dlg(providerDBLMS, this);
dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowContextHelpButtonHint);
connect(&dlg, &DialogSettingsTray::signal_LanguageChanged, this, &ServerLMSWidget::slot_LanguageChanged);
connect(&dlg, &DialogSettingsTray::signal_UpdateDocs, docsUpdater, &DocsUpdater::slot_updateDocsXML);
switch( dlg.exec() )
{
case QDialog::Accepted:
{
language = dlg.getSettings().Language;
if(dlg.settingsDBisChanged())
{
on_btnStopServer_clicked();
flNeedReconnectDB = true;
flTryConnectionToDB = false;
emit signal_TryDisConnectionFromDB();
break;
}
break;
}
case QDialog::Rejected:
break;
default:
break;
}
}
//INIT
void ServerLMSWidget::startInitialization_step0()
{
emit signal_Tray_ShowMessage(tr("Starting the server..."));
waitAnimationWidget->showWithPlay();
updateThread = new QThread;
loggerThread = new QThread;
serverThread = new QThread;
providerDBLMS = new ProviderDBLMS();
providerDBLMS->moveToThread(serverThread);
connect(providerDBLMS, &ProviderDBLMS::signal_ErrorPostgreSQL, this, &ServerLMSWidget::slot_ErrorPostgreSQL);
connect(providerDBLMS, &ProviderDBLMS::signal_StateConnectionToDB, this, &ServerLMSWidget::slot_StateConnectionToDB);
connect(this, &ServerLMSWidget::signal_TryConnectionToDB, providerDBLMS, &ProviderDBLMS::slot_TryConnectionToDB);
connect(this, &ServerLMSWidget::signal_TryDisConnectionFromDB, providerDBLMS, &ProviderDBLMS::slot_TryDisConnectionFromDB);
connect(providerDBLMS, &ProviderDBLMS::signal_ResultTryConnectDb, this, &ServerLMSWidget::slot_ResultTryConnectDb);
connect(providerDBLMS, &ProviderDBLMS::signal_ResultTryDisConnectDb, this, &ServerLMSWidget::slot_ResultTryDisConnectDb);
chatSystem = new ChatSystem();
chatSystem->moveToThread(serverThread);
assetsManager = new AssetsManager;
assetsManager->moveToThread(updateThread);
updateController = new UpdateController;
updateController->moveToThread(updateThread);
docsUpdater = new DocsUpdater(updateController);
docsUpdater->moveToThread(updateThread);
connect(docsUpdater, &DocsUpdater::signal_UpdateDocsCompleted, this, &ServerLMSWidget::slot_UpdateDocsCompleted);
cfiController = new CfiController(updateController);
cfiController->moveToThread(updateThread);
processingSystem = new ProcessingSystem(providerDBLMS, updateController, docsUpdater, cfiController);
processingSystem->moveToThread(serverThread);
dataParser = new DataParser(assetsManager, processingSystem);
dataParser->moveToThread(serverThread);
commonClientHandler = new CommonClientHandler;
commonClientHandler->moveToThread(serverThread);
connect(docsUpdater, &DocsUpdater::signal_DocsChanged, commonClientHandler, &CommonClientHandler::slot_DocsChanged);
server = new MultiThreadServer(updateController, docsUpdater, processingSystem, dataParser, 6000);
server->moveToThread(serverThread);
connect(server, &MultiThreadServer::signal_StateServer, this, &ServerLMSWidget::slot_StateServer);
connect(server, &MultiThreadServer::signal_UpdateListClients, this, &ServerLMSWidget::slot_UpdateListClients);
connect(this, &ServerLMSWidget::signal_StartServer, server, &MultiThreadServer::slot_StartServer);
connect(this, &ServerLMSWidget::signal_StopServer, server, &MultiThreadServer::slot_StopServer);
connect(server, &MultiThreadServer::signal_BlockAutorizationIndicate, this, &ServerLMSWidget::slot_BlockAutorizationIndicate);
connect(providerDBLMS, &ProviderDBLMS::signal_BlockAutorization, server, &MultiThreadServer::slot_BlockAutorization, Qt::DirectConnection /*Тут именно DirectConnection!*/);
connect(updateController, &UpdateController::signal_BlockAutorization, server, &MultiThreadServer::slot_BlockAutorization/*, Qt::DirectConnection*/);
connect(server, &MultiThreadServer::signal_sendPacketToAllClients, commonClientHandler, &CommonClientHandler::slot_sendPacketToAllClients);
loggerThread->start();
updateThread->start();
serverThread->start();
commonClientHandler->initialize(server->getClientsMap(), processingSystem, dataParser);
processingSystem->initialize(server, dataParser, commonClientHandler, updateController, chatSystem);
chatSystem->initialize(commonClientHandler, dataParser, server->getClientsMap());
Logger::instance().moveToThread(loggerThread);
Logger::instance().setLoggingType(LoggingType::WIDGET);
Logger::instance().setLogToFile(true);
connect(this, &ServerLMSWidget::signal_UpdateControllerInitialize, updateController, &UpdateController::initialize);
connect(updateController, &UpdateController::sigInitializeFinished, this, &ServerLMSWidget::slot_UpdateControllerInitializeFinished);
connect(updateController, &UpdateController::sigErrorRequired, this, &ServerLMSWidget::slot_SetError);
connect(updateController, &UpdateController::sigUpdateDocs, docsUpdater, &DocsUpdater::slot_updateDocsXML, Qt::AutoConnection);
connect(&Logger::instance(), &Logger::sigLogToWidget, this, &ServerLMSWidget::slot_AddMessageToLog, Qt::QueuedConnection);
connect(assetsManager, &AssetsManager::signal_setVersion, this, &ServerLMSWidget::slot_StateVersionMaterials);
connect(this, &ServerLMSWidget::signal_UpdateDocsXML, docsUpdater, &DocsUpdater::slot_updateDocsXML);
emit signal_UpdateControllerInitialize(commonClientHandler, dataParser, assetsManager);
}
void ServerLMSWidget::startInitialization_step1()
{
if(errorCode == 100)
return;
Logger::instance().log("Update docs.xml...");
flTryUpdateDocs = true;
emit signal_UpdateDocsXML();
}
void ServerLMSWidget::startInitialization_step2()
{
Logger::instance().log("Update docs.xml completed!");
ui->btnStopServer->setEnabled(false);
ui->btnStartServer->setEnabled(true);
flStartInitialization = true;
updateStateOnlyServer();
updateStateOnlyDB();
updateStateOnlyVersionMaterials();
Logger::instance().log("Try connection to DB...");
tryConnectionToDB();
}
void ServerLMSWidget::startInitialization_step3()
{
waitAnimationWidget->hideWithStop();
emit signal_StartInitFinished();
}
//CONNECT DB
void ServerLMSWidget::tryConnectionToDB()
{
flTryConnectionToDB = true;
flNeedReconnectDB = false;
emit signal_TryConnectionToDB();
return;
}