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

@@ -0,0 +1,223 @@
/**
* @RDE_HEADER@
* Plugin to watch the currently active Exercise and keep track of the Exc Name, Exc Phase, etc.
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2017-09-29
*/
#include "exm_watch_gui_plugin.h"
#include <LtsSession/lts_session.h>
#include <LtsWidgets/lts_message_dialog.h>
#include <LtsWidgets/lts_base_layout_widget.h>
#include <ExerciseManagement/exm_translation.h>
#include <ngltools/ngltools_dtg.h>
namespace ExerciseManagement
{
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
{
return std::make_shared<InterfaceImpl>(session);
}
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Exm.Watch"))
, m_dtc(nullptr)
, m_isDeleted(false)
{}
bool InterfaceImpl::fetchInterfaces()
{
if (!m_session->getDtc<ExerciseManagement::DataInterface>(m_dtc))
return false;
return true;
}
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
QVector<LtsWidgets::PluginData> ret;
{
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.createInstant = LtsWidgets::CreateInstantType::CreateInstantAndDiscardAction;
plData.directFunc = [this](const LtsWidgets::PluginData &)
{
connect(m_dtc.get(), &ExerciseManagement::Interface::Dtc::exerciseChanged,
this, &InterfaceImpl::slotExerciseChanged);
connect(m_dtc.get(), &ExerciseManagement::Interface::Dtc::exercisePhaseChanged,
this, &InterfaceImpl::slotExercisePhaseChanged);
if (m_session->isInitializationDone())
slotSetExerciseData();
else
connect(m_session, &LtsSession::LtsSession::signalDoneInitializingSession,
this, &InterfaceImpl::slotSetExerciseData); // wait until session is initialized
};
ret.append(plData);
}
return ret;
}
LtsWidgets::ExcState InterfaceImpl::convertState(ExerciseState state)
{
int underlying = state.underlying() - 1;
if (underlying >= 0)
{
int i_state = (1 << static_cast<int>(underlying));
return static_cast<LtsWidgets::ExcState>(i_state);
}
return LtsWidgets::ExcState::eUnknown;
}
void InterfaceImpl::clearInterfaces()
{
m_dtc = nullptr;
}
QColor InterfaceImpl::exerciseStateColor(ExerciseManagement::ExerciseState state)
{
switch(state.underlying())
{
case ExerciseState::Unknown: return Qt::black;
case ExerciseState::Created: return Qt::cyan;
case ExerciseState::Started: return Qt::darkGreen;
case ExerciseState::Paused: return Qt::darkYellow;
case ExerciseState::Stopped: return Qt::magenta;
case ExerciseState::Terminated: return Qt::red;
}
return QColor();
}
void InterfaceImpl::slotExerciseChanged(const ExerciseManagement::Exercise &data, DataModification modType)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this << ", exId=" << data.id();
if (m_isDeleted)
return;
if (data.id() != m_session->exerciseId())
return;
switch (modType)
{
case DataModification::eRemoved:
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " eRemoved" << ", this=" << this << ", exId=" << data.id();
m_previouslyRemoved = true;
WARNING_LOG(m_logger) << "Partition has been removed from the DDS bus! Session: " << m_session->toString();
if (m_session->baseLayout())
m_session->baseLayout()->showMessage(tr("Connection to server lost"), tr("Trying to reconnect. You will be notified."), LtsWidgets::LtsNotificationBox::MessageType::Error);
break;
}
case DataModification::eAdded:
{
WARNING_LOG(m_logger) << LOGFUNCTION << ", Partition added to DDS bus! Session: " << m_session->toString();
DEBUG_LOG(m_logger) << LOGFUNCTION << " eAdded, m_previouslyRemoved=" << m_previouslyRemoved << ", this=" << this << ", exId=" << data.id();
if (m_previouslyRemoved)
{
m_previouslyRemoved = false;
if (m_session->baseLayout())
m_session->baseLayout()->showMessage(tr("Successfully reconnected"), tr("Connection to server was successfully reestablished."), LtsWidgets::LtsNotificationBox::MessageType::Success);
}
Q_FALLTHROUGH();
}
case DataModification::eModified:
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " eModified, m_previouslyRemoved=" << m_previouslyRemoved << ", this=" << this << ", exId=" << data.id();
slotSetExerciseData();
break;
}
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this << ", exId=" << data.id();
}
void InterfaceImpl::slotExercisePhaseChanged(const ExerciseManagement::ExercisePhase &data, DataModification modType)
{
Q_UNUSED(modType);
if (m_isDeleted)
return;
if (data.exerciseId() != m_session->exerciseId() ||
data.id() != m_session->exerciseData()->phId)
return;
slotExerciseChanged(m_dtc->exercise(m_session->exerciseId()), DataModification::eModified);
}
QString InterfaceImpl::partitionTypeString() const
{
switch (m_session->partitionType())
{
case IDL::PartitionType::Global: return QStringLiteral("<font color='grey'>%1</font>").arg(tr("Admin"));
case IDL::PartitionType::Exercise: return QStringLiteral("<font color='green'>%1</font>").arg(tr("Live"));
case IDL::PartitionType::Replay: return QStringLiteral("<font color='red'>%1</font>").arg(tr("Replay"));
default: return tr("unknown");
}
}
void InterfaceImpl::slotSetExerciseData()
{
disconnect(m_session, &LtsSession::LtsSession::signalDoneInitializingSession,
this, nullptr);
LtsWidgets::ExerciseData exData;
// 26.06.2023, Norbert Thoden
// Sometimes the ScriptEditorEssentialsView doesn´t have any buttons at the right menue.
// Reason:
// "Partition has been removed from the DDS bus"
// So afterwards slotSetExerciseData has called.
// With a virgin dtc leads to invalid data Exercise.
// So add waitForHistoricalData :-)
// Addtionally:
// Within slotExerciseChanged it´s handled as not m_previouslyRemoved
// and 'break' had skipped the rest of the slot - especially eModified.
// Now: If DDS partiton is newly created, the slot is called,
// eAdded and via Q_FALLTHROUGH eModified is executed also!
// To avoid signalExerciseDataChanged to be emiited multiple times,
// data is checked (operator==())
m_dtc->waitForHistoricalDataExercise(2000);
m_dtc->waitForHistoricalDataExercisePhase(2000);
const ExerciseManagement::Exercise &ex = m_dtc->exercise(m_session->exerciseId());
if (ex.id() != m_session->exerciseId())
FATAL_LOG(m_logger) << LOGFUNCTION << ", requested exId and return exId do not match!!!";
// no assert here to not desturb debugging
const ExerciseManagement::ExercisePhase &ph = m_dtc->exercisePhase(ex.activePhaseId());
exData.exName = QString::fromStdString(ex.name());
exData.exDescription = QString::fromStdString(ex.description());
exData.exStateString = ExerciseManagement::toString(ex.state());
exData.exState = convertState(ex.state());
exData.exStateCol = exerciseStateColor(ex.state());
exData.partitionType = partitionTypeString();
exData.phId = ph.id();
exData.phName = QString::fromStdString(ph.name());
exData.phDescription = QString::fromStdString(ph.description());
m_session->setExerciseData(exData);
DTG::setTimezone(ex.defaultTimeZone(), false);
}
} // namespace ExerciseManagement