Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Hanna Rathje, SLSE, 2017-12-14
#
SET(SRCS
aar_application.cpp
aar_application.h
databases_model.cpp
databases_model.h
logger.cpp
logger.h
main.cpp
)
NGL_WRAP_UI(SRCS aarApp.ui)
NGL_ADD_EXECUTABLE(AAR aarApp ${SRCS})
NGL_TARGET_LINK_LIBRARIES(aarApp
Qt5::Widgets
Qt5::Core
nglapplication
ngldb
nglcoreapplication
ngltools
ngltranslator
nglwidgets
NGLLogger
LtsCommandLineParser
)
NGL_INSTALL_TARGET(aarApp)
NGL_INSTALL(AAR FILES log4cxx_aarApp.props DESTINATION bin)
+162
View File
@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AarApplication</class>
<widget class="QMainWindow" name="AarApplication">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>846</width>
<height>382</height>
</rect>
</property>
<property name="windowTitle">
<string>Database administration</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
</property>
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Status:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblStatus">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>No active database</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lblDatabases">
<property name="text">
<string>Databases:</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="tableViewDatabases">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pbActivateNetwork">
<property name="text">
<string>Activate network database</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbActivate">
<property name="text">
<string>Activate local database</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbRemove">
<property name="text">
<string>Remove database</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbClose">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<action name="actionShow">
<property name="text">
<string>&amp;Show</string>
</property>
</action>
<action name="actionStart">
<property name="text">
<string>&amp;Start</string>
</property>
</action>
<action name="actionStop">
<property name="text">
<string>St&amp;op</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
<slots>
<slot>oeffnenClicked()</slot>
</slots>
</ui>
+501
View File
@@ -0,0 +1,501 @@
/*
* @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
+78
View File
@@ -0,0 +1,78 @@
/*
* @RDE_HEADER@
* <short description>
* $Id$
* $HeadURL$
* $Author$
* Created by Malte Schröder, SLSE, 2016-06-08
*/
#pragma once
#include <QMainWindow>
#include <QMap>
#include <QStandardItemModel>
#include <QVector>
#include <QCloseEvent>
#include <QProcess>
#include <QProgressDialog>
#include <QMenuBar>
#include <QSqlDatabase>
#include "logger.h"
#include "databases_model.h"
namespace Ui {
class AarApplication;
}
namespace AARApplication
{
class AarApplication : public QMainWindow
{
Q_OBJECT
public:
explicit AarApplication(QWidget *parent = nullptr);
~AarApplication();
bool init();
private slots:
void onClosedClicked();
void onRemoveClicked();
void onActivateClicked();
void onActivateNetworkClicked();
void onDropDbFinished(int exitCode, QProcess::ExitStatus exitStatus);
void onPsauxFinished();
void onStartAppFinished(int exitCode, QProcess::ExitStatus exitStatus);
void onPsauxStopFinished();
void onStopAppFinished(int exitCode, QProcess::ExitStatus exitStatus);
void onErrorOccured(QProcess::ProcessError error);
void onStartApp();
void onStopApp();
private:
void enaDisa();
void handleProcInit(const QString &program, const QStringList &args);
void handleProcFinished(int exitCode, QProcess::ExitStatus exitStatus);
void disableButtons() { enaDisaButtons(false); }
void enableButtons() { enaDisaButtons(true); }
void enaDisaButtons(bool bEnable);
private:
Ui::AarApplication *m_ui;
DatabasesModel *m_databasesModel;
DatabasesProxyModel *m_proxyModel;
QMap<QString, QSqlDatabase> m_dbMap;
bool m_stopping;
Exercise m_databaseToRemove;
QProcess *m_proc;
QSqlDatabase m_dbPostgres;
QProgressDialog *m_progressDialog;
QVector<QWidget*> m_widgets;
LOGGER_T m_logger;
};
} // namespace AARApplication
+214
View File
@@ -0,0 +1,214 @@
/**
* @RDE_HEADER@
* PresentationManangement - Script Overview Dialog Model
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2017-03-15
*/
#include "databases_model.h"
#include <ngltools/ngltools_dtg.h>
#include <ngldb/nsqlquery.h>
#include <QDateTime>
#include <QPalette>
namespace AARApplication
{
DatabasesModel::DatabasesModel(QObject *parent)
: QAbstractTableModel(parent)
, m_logger(getLogger("DatabasesModel"))
{
beginResetModel();
m_vecData.clear();
endResetModel();
}
bool DatabasesModel::initModel(const QSqlDatabase &db)
{
NSqlQuery q(db);
QString stmt = QStringLiteral("SELECT id, name, begin_time, end_time, exercise_state_id FROM exm.exercise");
if (!q.prepare(stmt))
{
ERROR_LOG(m_logger) << "Preparing statement '" << stmt << "' failed.";
return false;
}
if (!q.exec(stmt))
{
ERROR_LOG(m_logger) << "Executing statement '" << stmt << "' failed.";
return false;
}
int count = 0;
while (q.next())
{
if (count > 0)
{
WARNING_LOG(m_logger) << "More than one exercise detected. There should be only one exercise per database.";
break;
}
Exercise exercise;
exercise.id = q.value(0).toInt();
exercise.name = q.value(1).toString();
exercise.startTime = q.value(2).toLongLong();
exercise.endTime = q.value(3).toLongLong();
exercise.dbName = QStringLiteral("lts_db_") + QString::number(exercise.id);
exercise.stateId = q.value(4).toInt();
TRACE_LOG(m_logger) << "Found exercise with id=" << exercise.id << ", name=" << exercise.name << ", startTime="
<< exercise.startTime << ", endTime=" << exercise.endTime << ", dbName=" << exercise.dbName
<< ", stateId=" << exercise.stateId;
if (exercise.stateId != 6)
onDataChanged(exercise, DataModification::eAdded);
++count;
}
INFO_LOG(m_logger) << "initModel - #exercises: " << m_vecData.size();
return true;
}
QVariant DatabasesModel::data(const QModelIndex &index, int role) const
{
if (role != Qt::DisplayRole || !index.isValid() || index.row() >= m_vecData.size())
return QVariant();
const Exercise &e = m_vecData.at(index.row());
switch (index.column())
{
case Id:
return e.id;
case Name:
return QString(e.name);
case StartTime:
return DTG::toStringMSec(e.startTime);
case EndTime:
return DTG::toStringMSec(e.endTime);
}
return QVariant();
}
int DatabasesModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : m_vecData.size();
}
int DatabasesModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : EndTime + 1;
}
QVariant DatabasesModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal
&& role == Qt::DisplayRole)
{
Columns col = static_cast<Columns>(section);
switch (col)
{
case Id:
return tr("Id");
case Name:
return tr("Name");
case StartTime:
return tr("Start Time");
case EndTime:
return tr("End Time");
}
}
return QAbstractTableModel::headerData(section, orientation, role);
}
Exercise DatabasesModel::getRowData(int row) const
{
if (row < 0 || row >= m_vecData.size())
return Exercise();
return m_vecData.at(row);
}
bool DatabasesModel::insertRow(const Exercise &item)
{
beginInsertRows(QModelIndex(), m_vecData.size(), m_vecData.size());
m_vecData.append(item);
endInsertRows();
return true;
}
bool DatabasesModel::removeRow(const int &row)
{
beginRemoveRows(QModelIndex(), row, row);
m_vecData.remove(row);
endRemoveRows();
return true;
}
void DatabasesModel::onDataChanged(const Exercise &data, DataModification modType)
{
int row = -1;
switch (modType)
{
case DataModification::eAdded:
row = m_vecData.size();
if (insertRow(data))
emit dataChanged(index(row, Columns::Id), index(row, Columns::EndTime));
return;
case DataModification::eModified:
row = m_vecData.indexOf(data);
if (row != -1)
{
m_vecData[row] = data;
emit dataChanged(index(row, Columns::Id), index(row, Columns::EndTime));
}
return;
case DataModification::eRemoved:
row = m_vecData.indexOf(data);
if (row != -1)
if (removeRow(row))
emit dataChanged(index(std::min(row, m_vecData.size()-1), Columns::Id), index(m_vecData.size()-1, Columns::EndTime));
return;
} // switch
}
void DatabasesProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
m_sourceModel = qobject_cast<DatabasesModel*>(sourceModel);
QSortFilterProxyModel::setSourceModel(sourceModel);
}
bool DatabasesProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!m_sourceModel ||
source_left.column() != source_right.column() ||
!source_left.isValid() ||
!source_right.isValid())
return QSortFilterProxyModel::lessThan(source_left, source_right);
const auto &dataLeft = m_sourceModel->m_vecData.at(source_left.row());
const auto dataRight = m_sourceModel->m_vecData.at(source_right.row());
switch (source_left.column())
{
case DatabasesModel::StartTime:
return dataLeft.startTime < dataRight.startTime;
case DatabasesModel::EndTime:
return dataLeft.endTime < dataRight.endTime;
case DatabasesModel::Id:
case DatabasesModel::Name:
break;
}
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
} // namespace AARApplication
+100
View File
@@ -0,0 +1,100 @@
/**
* @RDE_HEADER@
* PresentationManangement - Script Overview Dialog Model
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2017-03-15
*/
#pragma once
#include "logger.h"
#include <LtsUtils/LtsUtilsCore/data_modification_enum.h>
#include <QAbstractTableModel>
#include <QSortFilterProxyModel>
class QSqlDatabase;
namespace AARApplication
{
struct Exercise
{
qint32 id = 0;
QString name;
QString dbName;
qint64 startTime = 0;
qint64 endTime = 0;
qint32 stateId = 0;
bool operator == (const Exercise &other) { return id == other.id; }
bool operator != (const Exercise &other) { return id != other.id; }
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// DatabasesModel
//
class DatabasesModel : public QAbstractTableModel
{
Q_OBJECT
public:
enum Columns
{
Id = 0,
Name,
StartTime,
EndTime
};
explicit DatabasesModel(QObject *parent = nullptr);
~DatabasesModel() = default;
bool initModel(const QSqlDatabase &db);
QVariant data(const QModelIndex &, int) const override final;
int rowCount(const QModelIndex &parent) const override final;
int columnCount(const QModelIndex &parent) const override final;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override final;
Exercise getRowData(int row) const;
bool insertRow(const Exercise &item);
bool removeRow(const int &row);
friend class DatabasesProxyModel;
protected:
public slots:
void onDataChanged(const Exercise &data, DataModification modType);
private:
QVector<Exercise> m_vecData;
LOGGER_T m_logger;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// DatabasesProxyModel
//
class DatabasesProxyModel final : public QSortFilterProxyModel
{
Q_OBJECT
public:
using QSortFilterProxyModel::QSortFilterProxyModel;
void setSourceModel(QAbstractItemModel *sourceModel) override;
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
private:
DatabasesModel *m_sourceModel = nullptr;
};
}
+77
View File
@@ -0,0 +1,77 @@
log4j.reset=true
log4j.rootLogger=WARN, file
# DbAdministration
###########################################################
#log4j.logger.DbAdministration=DEBUG
# File
###########################################################
log4j.appender.file=Lts::RollingFileAppender
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=9
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
# Appnd_Console
###########################################################
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
# Appnd_Syslog
###########################################################
log4j.appender.syslog=org.apache.log4j.SyslogAppender
log4j.appender.syslog.Threshold=ERROR
log4j.appender.syslog.SysLogHost=localhost
log4j.appender.syslog.Facility=LOCAL7
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
###########################################################
###########################################################
###########################################################
# 1) Available Levels in LOG4CXX Version 0.10.0:
# TRACE,
# DEBUG,
# INFO,
# WARN,
# ERROR
# FATAL
#
# d = date/time
# p = priority (Level)
# c = category/channel
# m = message
# F = file
# L = line
# n = platform dependent line separator character or characters.
# ....
#
# Examples for console:
# a)
# %d %p %c #%m# (%.50F:%L)%n
# date/time
# priority
# category/channel
# #message#
# (Maximal 50Character des Filename von rechts:Line)
# line separator
#
# b)
# %d (%.15F:%L) %-5p %c |#| %m%n
# date/time
# (Maximal 15Character des Filename von rechts:Line)
# priority, Right pad with spaces if the priority name is less than 5 characters long.
# category/channel
# message
# line separator
#
# Examples for files:
+37
View File
@@ -0,0 +1,37 @@
/**
* @RDE_HEADER@
* Building Config - logging facility
* $Id$
* $HeadURL$
* $Author$
*/
#include "logger.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
namespace AARApplication
{
LOGGER_T getLogger(const char *name)
{
static const char ns[] = "DBA.";
std::string loggerName;
const size_t len = strlen(name);
loggerName.reserve(sizeof(ns) + len);
loggerName.append(ns, sizeof(ns) - 1);
loggerName.append(name, len);
try
{
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
getNGLLogger(loggerName);
}
catch (const std::exception &ex)
{
fprintf(stderr, "Error retrieving logger: %s", ex.what());
abort();
}
}
} // namespace AARApplication
+23
View File
@@ -0,0 +1,23 @@
/**
* @RDE_HEADER@
* Logging for Evaluations
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <NGLLogger/INGLLogger.h>
namespace AARApplication
{
typedef NGL::INGLLogger &LOGGER_T;
LOGGER_T getLogger(const char *name);
inline LOGGER_T getLogger(const QString &loggerName)
{
return getLogger(loggerName.toUtf8().constData());
}
} // namespace AARApplication
+80
View File
@@ -0,0 +1,80 @@
/*
* @RDE_HEADER@
* <short description>
* $Id$
* $HeadURL$
* $Author$
* Created by Malte Schröder, SLSE, 2016-06-08
*/
#include "aar_application.h"
#include <NGLLogger/INGLLogger.h>
#include <nglapplication/nglapplication.h>
#include <nglapplication/nglcoreapplication.h>
#include <ngltranslator/ngltranslator.h>
#include <LtsCommandLineParser/LtsCommandLineParser.h>
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
{
public:
CmdLineParser()
: LtsCommandLineParser(ProvideCommandLineParameterOptions::None)
{
addOption({{QStringLiteral("l"), QStringLiteral("lang")},
QStringLiteral("Language iso code to use (de_DE, en_GB, en_US)"),
QStringLiteral("<locale iso code>")
});
}
QString langIsoCode() const { return value(QStringLiteral("l")); }
};
int main(int argc, char *argv[])
{
int retval = -1;
bool bHeadless = false;
for (int i = 1; i < argc; ++i)
{
if (strcmp(argv[i], "-e") == 0)
{
bHeadless = true;
break;
}
}
QScopedPointer<QCoreApplication> app;
app.reset(bHeadless ? dynamic_cast<QCoreApplication*>(new NGLCoreApplication(argc, argv))
: dynamic_cast<QCoreApplication*>(new NGLApplication(argc, argv)));
QCoreApplication::setApplicationName(QLatin1String("AarApplication"));
QCoreApplication::setOrganizationName(QLatin1String("RME"));
if (!bHeadless)
app->setAttribute(Qt::AA_UseHighDpiPixmaps);
NGL::LoggerHandler *lh = dynamic_cast<NGL::LoggerHandler*>(app.data());
lh->createLogger("AarApp", "log4cxx_aarApp.props");
NGL::INGLLogger &logger = lh->baseLogger();
// Parse Options
CmdLineParser options;
if (!options.init())
return retval;
// Set Translation
QString langIsoCode = options.langIsoCode();
if (langIsoCode.isEmpty())
langIsoCode = QLocale::system().name();
NGL::setTranslationLocale(langIsoCode.toLatin1());
AARApplication::AarApplication * w = new AARApplication::AarApplication;
if (!w->init())
return -2;
STARTUP_LOG(logger);
w->show();
QGuiApplication::setQuitOnLastWindowClosed(true);
retval = QCoreApplication::exec();
SHUTDOWN_LOG(logger);
return retval;
}