Files
qt-migration-legatus/qt5-before/dlbo/Lts/Application/AarApp/aar_application.cpp
T
torstenandCopilot 7173785915 Qt6 Migration: Complete migration with DDS/RTI support and build validation
Major Changes:
- Merged latest Qt5 devel content from dlbo (292 files changed, 7 new dirs)
- Consolidated forward-declarations and include folders
- Removed unneeded modules per Niklas' repo check list

Build System Fixes:
- Fixed CMake VERSION_GREATER syntax in ParticipantManagement/CMakeLists.txt
- Added VLC packages (libvlc-dev, vlc-plugin-base) to docker_build.sh
- Added PostgreSQL dev packages (libpq-dev, postgresql-server-dev-all) to Dockerfile
- Fixed locale warnings (ANSI_X3.4-1968 → C.UTF-8)
- Fixed ArcGIS SDK path warnings when BUILD_ARCGIS=OFF

Code Generation Fixes:
- Fixed IDL enum collisions (PortType→CorePortType/DdsutPortType, PdmEventType)
- Fixed Grantlee template svc_translation.cpp.grantlee:
  - Changed {{ idl_enum.name }}_def:: to {{ idl_enum.name }}::
  - Fixed .underlying() calls for C++11 scoped enums (enum class)
- Removed generated files from repo (moc_*, *_dtc.h, *_ftc.h)

Validation:
- BUILD_RTI=ON: SUCCESS
- BUILD_RTI=OFF: SUCCESS
- C++17 standard maintained for RTI 7.7 compatibility
- Ubuntu 26.04 Docker environment verified

Remaining Warnings (expected):
- BgViewer, KDChart, KDReports, Poppler-Qt6 not found (optional features)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-15 18:20:26 +00:00

502 lines
15 KiB
C++

/*
* @RDE_HEADER@
* <short description>
* $Id$
* $HeadURL$
* $Author$
* Created by Malte Schröder, SLSE, 2016-06-08
*/
#include "aar_application.h"
#include "ui_aarApp.h"
#include "databases_model.h"
#include <ngldb/dbconnection.h>
#include <ngldb/nsqlquery.h>
#include <nglsettings/nglsettings_settings.h>
#include <ngltools/ngltools_filesystem.h>
#include <QMessageBox>
#include <QTimer>
#include <QMenu>
#include <QSettings>
#include <QDir>
#include <QThread>
#include <QScreen>
#include <QSqlError>
#define DEFAULT_DB "lts_ets_pro"
namespace AARApplication
{
AarApplication::AarApplication(QWidget *parent)
: QMainWindow(parent)
, m_ui(new Ui::AarApplication)
, m_stopping(false)
, m_proc(nullptr)
, m_progressDialog(nullptr)
, m_logger(getLogger("AarApplication"))
{
setAttribute(Qt::WA_DeleteOnClose);
m_ui->setupUi(this);
const QList<QScreen*> &screenList = QGuiApplication::screens();
m_widgets.reserve(screenList.size());
for (QScreen *s : qAsConst(screenList))
{
QWidget *w = new QWidget(); // no parent
w->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
w->setGeometry(s->geometry());
w->activateWindow();
w->show();
m_widgets.append(w);
}
m_databasesModel = new DatabasesModel(this);
m_proxyModel = new DatabasesProxyModel(this);
m_proxyModel->setSourceModel(m_databasesModel);
m_ui->tableViewDatabases->setModel(m_proxyModel);
connect(m_ui->pbClose, &QPushButton::clicked, this, &AarApplication::onClosedClicked);
connect(m_ui->pbRemove, &QPushButton::clicked, this, &AarApplication::onRemoveClicked);
connect(m_ui->pbActivate, &QPushButton::clicked, this, &AarApplication::onActivateClicked);
connect(m_ui->pbActivateNetwork, &QPushButton::clicked, this, &AarApplication::onActivateNetworkClicked);
connect(m_ui->tableViewDatabases->selectionModel(), &QItemSelectionModel::selectionChanged, this, &AarApplication::enaDisa);
setWindowTitle(QLatin1String("AarApplication"));
enaDisa();
m_progressDialog = new QProgressDialog(this);
m_progressDialog->setLabelText(tr("Stopping server software ..."));
m_progressDialog->setMinimum(0);
m_progressDialog->setMaximum(0);
m_progressDialog->show();
onStopApp();
}
AarApplication::~AarApplication()
{
delete m_ui;
delete m_databasesModel;
delete m_progressDialog;
for (QSqlDatabase db : qAsConst(m_dbMap))
db.close();
m_dbPostgres.close();
if (m_proc)
m_proc->deleteLater();
qDeleteAll(m_widgets);
}
bool AarApplication::init()
{
m_ui->lblStatus->setText(tr("No active database"));
m_dbPostgres = DBConnection::open(m_logger,
QStringLiteral("postgres"),
QStringLiteral("postgres"),
QStringLiteral("QPSQL"),
QStringLiteral("localhost"),
QStringLiteral("postgres"),
QString(),
QStringLiteral("localhost_postgres"));
if (!m_dbPostgres.open())
{
ERROR_LOG(m_logger) << "Error opening postgres database" << m_dbPostgres.lastError().databaseText();
return false;
}
NSqlQuery q(m_dbPostgres);
QString stmt = QStringLiteral("SELECT datname FROM pg_database WHERE datname = '") + QStringLiteral(DEFAULT_DB) + QStringLiteral("'");
if (!q.execAndFetch(stmt))
{
NOTICE_LOG(m_logger) << "Database does not exist: " << DEFAULT_DB;
}
else
{
QSqlDatabase db_lts = DBConnection::open(m_logger,
QStringLiteral("ctc_sv"),
QStringLiteral("ctc11de"),
QStringLiteral("QPSQL"),
QStringLiteral("localhost"),
QStringLiteral(DEFAULT_DB),
QString(),
QStringLiteral("localhost_")+QStringLiteral(DEFAULT_DB));
if (!db_lts.open())
{
ERROR_LOG(m_logger) << "Error opening database " << DEFAULT_DB << " : "<< db_lts.lastError().databaseText();
m_dbPostgres.close();
return false;
}
NSqlQuery ql(db_lts);
stmt = QStringLiteral("SELECT id FROM exm.exercise");
if (!ql.execAndFetch(stmt))
{
ERROR_LOG(m_logger) << "No entry for exercise found in database " << DEFAULT_DB;
}
else
{
int dbId = ql.value(0).toInt();
db_lts.close();
QString dbName = QStringLiteral("lts_db_") + QString::number(dbId);
INFO_LOG(m_logger) << "New dbName for " << DEFAULT_DB << ": " << dbName;
stmt = QStringLiteral("ALTER DATABASE ") + QStringLiteral(DEFAULT_DB) + QStringLiteral(" RENAME TO ") + dbName;
if (!q.exec(stmt))
{
ERROR_LOG(m_logger) << "Error renaming database " << DEFAULT_DB << " : " << db_lts.lastError().databaseText();
m_dbPostgres.close();
return false;
}
}
}
stmt = QStringLiteral("SELECT datname FROM pg_database WHERE datname ilike 'lts_db_%';");
if (!q.exec(stmt))
{
ERROR_LOG(m_logger) << "Error while reading dbnames from database";
return false;
}
while (q.next())
{
QString dbName = q.value(0).toString();
QSqlDatabase db = DBConnection::open(m_logger,
QStringLiteral("ctc_sv"),
QStringLiteral("ctc11de"),
QStringLiteral("QPSQL"),
QStringLiteral("localhost"),
dbName,
QString(),
QStringLiteral("localhost_") + dbName);
if (!db.open())
{
ERROR_LOG(m_logger) << "Error while opening database " << dbName << ", error: " << db.lastError().databaseText();
continue;
}
m_databasesModel->initModel(db);
m_dbMap.insert(dbName, db);
}
m_ui->tableViewDatabases->resizeColumnsToContents();
return true;
}
void AarApplication::onClosedClicked()
{
handleProcInit(QStringLiteral("/usr/bin/openbox"), {QStringLiteral("--exit")});
m_proc->start();
m_proc->waitForFinished();
QThread::sleep(2);
close();
}
void AarApplication::onRemoveClicked()
{
disableButtons();
m_databaseToRemove = m_databasesModel->getRowData(m_ui->tableViewDatabases->currentIndex().row());
QString strMsg = QStringLiteral("Do you really want to remove the database '%1'?").arg (m_databaseToRemove.dbName);
int result = QMessageBox::question(this, tr("Remove Database"), strMsg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
if (result == QMessageBox::No)
{
enableButtons();
return;
}
DEBUG_LOG(m_logger) << "onRemoveClicked: dbName = " << m_databaseToRemove.dbName;
QSqlDatabase db = m_dbMap.value(m_databaseToRemove.dbName);
db.close();
const QStringList args({QStringLiteral("-U"),
QStringLiteral("postgres"),
QStringLiteral("-h"),
QStringLiteral("localhost"),
m_databaseToRemove.dbName
});
QString errStr;
const QString exePath = NGL::postgresExecutablePath(QStringLiteral("dropdb"), errStr);
if (!errStr.isEmpty())
WARNING_LOG(m_logger) << errStr;
handleProcInit(exePath, args);
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &AarApplication::onDropDbFinished);
// start process
m_proc->start();
}
void AarApplication::onActivateClicked()
{
const QString fileName = QStringLiteral("/shd/CTC/WS/lts-cc.conf.org");
WARNING_LOG(m_logger) << "FileName: " << fileName;
QFile ltsConfig(fileName);
if (ltsConfig.exists())
ltsConfig.rename(QStringLiteral("/shd/CTC/WS/lts-cc.conf.org"), QStringLiteral("/shd/CTC/WS/lts-cc.conf"));
Exercise ex = m_databasesModel->getRowData(m_ui->tableViewDatabases->currentIndex().row());
QString strMsg = tr("Do you really want to activate database '%1'?").arg(ex.name);
int result = QMessageBox::question(this, tr("Activate local database"), strMsg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
if (result == QMessageBox::No)
return;
INFO_LOG(m_logger) << "onActivateClicked: dbName = " << ex.dbName;
QSqlDatabase db = m_dbMap.value(ex.dbName);
db.close();
NSqlQuery q(m_dbPostgres);
QString stmt = QStringLiteral("ALTER DATABASE ") + ex.dbName + QStringLiteral(" RENAME TO ") + QStringLiteral(DEFAULT_DB);
if (!q.exec(stmt))
ERROR_LOG(m_logger) << "Error renaming " << ex.dbName << " to " << DEFAULT_DB << " "<< m_dbPostgres.lastError().databaseText();
else
INFO_LOG(m_logger) << "Database " << ex.dbName << " renamed to " << DEFAULT_DB;
QString status = ex.name + QStringLiteral(" (") + ex.dbName + QStringLiteral(") ") + tr("active");
m_ui->lblStatus->setText(status);
onStartApp();
}
void AarApplication::onActivateNetworkClicked()
{
onStopApp();
//const QString fileName = QDir::homePath()+ QStringLiteral("/lts-cc.conf");
const QString fileName = QStringLiteral("/shd/CTC/WS") + QStringLiteral("/lts-cc.conf");
WARNING_LOG(m_logger) << "FileName: " << fileName;
QFile ltsConfig(fileName);
if (!ltsConfig.exists())
{
QMessageBox::critical(this, tr ("Activate network database"), tr("Network database active"), QMessageBox::Ok);
m_ui->lblStatus->setText(tr("Network database active"));
return;
}
ltsConfig.rename(QStringLiteral("/shd/CTC/WS/lts-cc.conf"), QStringLiteral("/shd/CTC/WS/lts-cc.conf.org"));
m_ui->lblStatus->setText(tr("Network database active"));
}
void AarApplication::enaDisa()
{
if (!m_ui)
return;
int selected = m_ui->tableViewDatabases->selectionModel()->selectedRows().size();
m_ui->pbRemove->setEnabled(selected > 0);
m_ui->pbActivate->setEnabled(selected > 0);
}
void AarApplication::onDropDbFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
INFO_LOG(m_logger) << "onDropDbFinished: exitCode: " << exitCode << ", exitStatus: " << exitStatus;
static const QString s_title = tr("Remove Database");
static const QString s_msgFailure = tr("Removing database failed.");
static const QString s_msgSuccess = tr("Removing database successful.");
if (exitCode > 0)
{
const QString str = QString::fromLocal8Bit(m_proc->readAllStandardError()) + QLatin1Char('\n') +
QString::fromLocal8Bit(m_proc->readAllStandardOutput());
ERROR_LOG(m_logger) << "Cannot drop database: " << str;
QString msg = s_msgFailure;
QString db0 = QLatin1String("ERROR: database \"") + m_databaseToRemove.dbName + QLatin1String("\" does not exist");
if (!str.contains(db0))
msg += tr(" Database cannot be removed:\n%1.").arg(str);
QMessageBox::critical(this, s_title, msg, QMessageBox::Ok);
}
else
{
m_databasesModel->onDataChanged(m_databaseToRemove, DataModification::eRemoved);
QMessageBox::information(this, s_title, s_msgSuccess);
}
enableButtons();
}
void AarApplication::onErrorOccured(QProcess::ProcessError error)
{
ERROR_LOG(m_logger) << "error: " << error;
}
void AarApplication::onStartApp()
{
handleProcInit(QStringLiteral("ps"), {QStringLiteral("aux")});
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &AarApplication::onPsauxFinished);
m_proc->start();
}
void AarApplication::onPsauxFinished()
{
enableButtons();
QByteArray output = m_proc->readAllStandardOutput();
if (output.contains("svcServiceManagement"))
{
ERROR_LOG(m_logger) << "ServiceManagement already started";
}
else
{
ERROR_LOG(m_logger) << "Start svcServiceManagement";
handleProcInit(QCoreApplication::applicationDirPath() + QStringLiteral("/svcServiceManagement"), {QStringLiteral("-z")});
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &AarApplication::onStartAppFinished);
m_proc->start();
m_proc->waitForFinished();
}
}
void AarApplication::onStartAppFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
handleProcFinished(exitCode, exitStatus);
}
void AarApplication::onStopApp()
{
disableButtons();
handleProcInit(QStringLiteral("ps"), {QStringLiteral("aux")});
m_proc->start();
if (m_proc->waitForFinished())
onPsauxStopFinished();
}
void AarApplication::onPsauxStopFinished()
{
DEBUG_LOG(m_logger) << "IN onPsauxStopFinished";
enableButtons();
QByteArray output = m_proc->readAllStandardOutput();
if (output.contains("svcServiceManagement"))
{
if (m_stopping)
{
QThread::sleep(3);
onStopApp();
}
else
{
ERROR_LOG(m_logger) << "ServiceManagement started - stopping";
handleProcInit(QCoreApplication::applicationDirPath() + QStringLiteral("/svcServiceManagement"), {QStringLiteral("-s")});
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &AarApplication::onStopAppFinished);
m_proc->start();
m_stopping = true;
}
}
else
{
INFO_LOG(m_logger) << "ServiceManagement already stopped";
m_stopping = false;
m_progressDialog->hide();
}
m_proc->waitForFinished();
}
void AarApplication::onStopAppFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
if (m_stopping)
onPsauxStopFinished();
handleProcFinished(exitCode, exitStatus);
}
void AarApplication::handleProcInit(const QString &program, const QStringList &args)
{
if (m_proc)
{
m_proc->disconnect(this);
m_proc->deleteLater();
}
m_proc = new QProcess(this);
NOTICE_LOG(m_logger) << "Starting process '" << program << "' with args '"
<< args.join(QLatin1Char(' ')) << "'";
m_proc->setProgram(program);
m_proc->setArguments(args);
connect(m_proc, &QProcess::errorOccurred, this, &AarApplication::onErrorOccured);
disableButtons();
}
void AarApplication::handleProcFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
enableButtons();
if (!m_proc)
return;
if (exitCode != 0 || exitStatus != 0)
{
QByteArray out = m_proc->readAllStandardError();
if (!out.isEmpty())
out += '\n';
out += m_proc->readAllStandardOutput();
ERROR_LOG(m_logger) << "Process finished - exitCode: " << exitCode << ", exitStatus = " << exitStatus << ", " << out;
QMessageBox::critical(this,
tr ("Execute process"), tr("Error executing process, exitCode: %1, exitStatus: %2, output: %3")
.arg(exitCode).arg(exitStatus).arg(QString::fromLocal8Bit(out)),
QMessageBox::Ok);
}
m_proc->disconnect(this);
m_proc->deleteLater();
m_proc = nullptr;
if (m_progressDialog)
m_progressDialog->hide();
}
void AarApplication::enaDisaButtons(bool bEnable)
{
{
const QList<QPushButton*> l = findChildren<QPushButton*>();
for (QPushButton *pb : l)
pb->setEnabled(bEnable);
}
{
const QList<QAction*> l = findChildren<QAction*>();
for (QAction *a : l)
a->setEnabled(bEnable);
}
if (bEnable)
enaDisa();
}
} // namespace AarApplication