Files
qt5-legatus-legacy/Lts/Plugins/AreaEffectSimulation/Gui/Explosion/aes_explosions_edit_adler.cpp
T
2026-08-13 18:33:10 +02:00

764 lines
27 KiB
C++
Executable File

/**
* @RDE_HEADER@
* AreaEffectSimulation - Explosions Edit Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Steve Tougnia, SLTE, 2023-09-05
*/
#include "aes_explosions_edit_adler.h"
// #include "aes_explosions_edit_helper.h"
#include "aes_effector.h"
#include "ui_aes_explosions_edit_adler.h"
#include <Proxies/TrainingAreaBase/Plugins/AdlerJson/telegrams.h>
#include <LtsSession/lts_session_data.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_model.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
#include <Services/AreaEffectSimulation/Utils/aes_helper.h>
#include <Services/AreaEffectSimulation/Utils/polygons.h>
#include <Services/ParticipantManagement/ppm_translation.h>
#include <LtsUtilsSettings/settings.h>
#include <Services/AreaEffectSimulation/settings.h>
#include <Plugins/AdvancedSymbology/asb_data_plugin_interface.h>
#include <Plugins/ParticipantManagement/Gui/ParticipantSelection/participant_selection.h>
#include <AreaEffectSimulation/aes_translation.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <ProjectDataManagement/pdm_translation.h>
#include <Trajectory/trajectory_generator.h>
#include <Trajectory/trajectory_helper.h>
#include <AssetManagement/asm_data_plugin_interface.h>
#include <ExerciseManagement/exm_data_plugin_interface.h>
#include <LtsElevation/lts_elevation_manager.h>
#include <QButtonGroup>
#include <QDateTime>
#include <QHash>
#include <QJsonDocument>
#include <QSpinBox>
#include <QTimer>
namespace AreaEffectSimulation
{
static const char *const VALUE_VALID_PROPERTY_NAME = "VALUE_VALID";
/*!
* \brief ExplosionsEditAdler::ExplosionsEditAdler
* \param menuGroup
* \param parent
*/
QString ExplosionsEditAdler::toString(ExplosionsEditAdler::FlighDurationOrPeakHeight val)
{
switch (val)
{
case ExplosionsEditAdler::FlighDurationOrPeakHeight::FDPH_flightDuration:
return QStringLiteral("FDPH_flightDuration");
break;
case ExplosionsEditAdler::FlighDurationOrPeakHeight::FDPH_peakHeight:
return QStringLiteral("FDPH_peakHeight");
break;
default:
return QStringLiteral("PHFD_Unknow");
break;
}
return QStringLiteral("PHFD_Unknow");
}
// Maximaler Winkel fuer untere Winkelgruppe
static double maxAngleUW = 45.0;
////////////////////////////////////////////////////////////////////////////////
// class ExplosionsEditAdler
////////////////////////////////////////////////////////////////////////////////
ExplosionsEditAdler::ExplosionsEditAdler(const QString &menuGroup, QWidget *parent)
: BaseEdit(menuGroup, QStringLiteral("ExplosionsEditAdler"), parent)
, m_ui(new Ui::ExplosionsEditAdler)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
m_ui->setupUi(this);
m_geometrieButtonGroup = new QButtonGroup(this);
m_geometrieButtonGroup->addButton(m_ui->geometrieAimPointBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgAimPoint));
m_geometrieButtonGroup->addButton(m_ui->geometrieAreaBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgArea));
m_geometrieButtonGroup->addButton(m_ui->geometrieLineBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgLine));
m_geometrieButtonGroup->addButton(m_ui->geometriePointBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgPoint));
m_geometrieButtonGroup->addButton(m_ui->geometrieRadialBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgRadial));
m_geometrieButtonGroup->setExclusive(true);
m_gearClassFilter = {ProjectDataManagement::GearClass::Artillery, ProjectDataManagement::GearClass::Mortar};
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
const bool enableRocket = ps->value(QStringLiteral("aes"), QStringLiteral("enableRocket"), false).toBool();
if (enableRocket)
m_gearClassFilter += ProjectDataManagement::GearClass::Rocket;
m_uiRequirements->addRequirement(
{m_ui->lbxActors,
[this]() { return ((m_ui->gbEffectMarkingInTa->isChecked() && m_ui->cbActors->currentData().toInt() > 0) || !m_ui->gbEffectMarkingInTa->isChecked()); }});
connect(m_ui->pbClear, &QPushButton::clicked, m_ui->positionEdit, &LtsCoordWidget::LtsCoordWidget::clear);
// "Einschießen" is hidden for now
m_ui->lblFire->hide();
m_ui->einschlJaBtn->hide();
m_ui->einschlNoBtn->hide();
// "Wirkungsfeuer" is hidden for now
m_ui->lblFire_2->hide();
m_ui->wirkungJaBtn->hide();
m_ui->wirkungNoBtn->hide();
// DMF EffectMarkingInTa hide currently always true
// m_ui->cbEffectMarkingInTa->hide();
m_ui->rbAngleGroupLower->setChecked(true);
// disable Tab Additional/Charge for now
m_ui->tabWidget->setTabEnabled(1, false);
m_ui->tabWidget->setTabEnabled(2, false);
m_ui->pbStateChange->hide();
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
}
/*!
* \brief ExplosionsEditAdler::~ExplosionsEditAdler
*/
ExplosionsEditAdler::~ExplosionsEditAdler()
{
if (m_sitMapGuiIfc)
m_sitMapGuiIfc->removeObjectIndicator();
delete m_ui;
}
/*!
* \brief AreaEffectSimulation::ExplosionsEditAdler::init
* \param aesItemId
* \param session
* \return
*/
bool ExplosionsEditAdler::init(int aesItemId, bool copy, LtsSession::LtsSession *session)
{
Q_UNUSED(copy)
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
if (!BaseEdit::init(aesItemId, session))
return false;
if (!m_session->getForeignDataInterface<AdvancedSymbology::DataInterface>(m_asbIfc))
return false;
if (!session->getForeignGuiInterface(m_esmActorCbx))
return false;
// P _D_ M
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(m_pdmDtc))
{
ERROR_LOG(m_logger) << " failed to get pdmDtc";
return false;
}
if (!m_session->getForeignGuiInterface<ProjectDataManagement::ForeignGuiInterface>(m_pdmCbx))
return false;
m_pdmDtc->waitForHistoricalDataChargeType(1000);
m_pdmDtc->waitForHistoricalDataGearType(1000);
m_pdmDtc->waitForHistoricalDataGearTypeChargeType(1000);
m_dtc->waitForHistoricalDataExplosionCluster(1000);
m_ftc->enableAcknowledgeExternalAesItem();
// P _P_ M
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
{
ERROR_LOG(m_logger) << " failed to get ppmDtc";
return false;
}
if (aesItemId > 0)
{
const EffectCluster &ecData = m_dtc->effectCluster(aesItemId);
DEBUG_LOG(m_logger) << "chargeTypeId: " << ecData.chargeStruct().chargeTypeId();
m_effectClusterData = ecData;
setEffectClusterData(ecData);
setPbStateChangeName();
m_ui->gbEffectMarkingInTa->setChecked(m_aesItem.effectMarkingInTa()); // always true for explosion cluster
}
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::effectClusterChanged, this, &ExplosionsEditAdler::onEffectClusterChanged, Qt::UniqueConnection);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::effectorChanged, this, &ExplosionsEditAdler::onEffectorChanged);
connect(m_ui->pbStateChange, &QPushButton::clicked, this, &ExplosionsEditAdler::onPbStateChangeClicked);
setOnlineHelpFilename(QStringLiteral("Situation-Add_Cluster_Artillery_AdlerVerbund.md"));
m_initDone = true;
enableUiElements();
m_ui->dteEffectStart->setEnabled(false);
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
/*!
* \brief ExplosionsEditAdlerStandAlone::showPreviewObject
*/
void ExplosionsEditAdler::showPreviewObject()
{
if (!has2DMap(false)) // showMsgBoxIfNot2D
return;
switch (m_currentGeometry.underlying())
{
case AreaEffectSimulation::AesExplosionGeometry_def::EgArea:
if (m_previewPolygon.isEmpty())
return;
m_sitMapGuiIfc->displayPreviewObject(this, m_previewPolygon, true);
return;
case AreaEffectSimulation::AesExplosionGeometry_def::EgAimPoint:
case AreaEffectSimulation::AesExplosionGeometry_def::EgPoint:
if (m_previewCircleCenter.isNull())
return;
m_sitMapGuiIfc->displayPreviewObject(this, m_previewPolygon, false);
return;
case AreaEffectSimulation::AesExplosionGeometry_def::EgRadial:
if (m_previewCircleCenter.isNull())
return;
m_sitMapGuiIfc->displayPreviewObject(this, m_previewCircleCenter, m_previewCircleRadius);
return;
default:
WARNING_LOG(m_logger) << " Unknown Geometry!";
return;
}
}
bool ExplosionsEditAdler::isDataSufficiant()
{
// identifier:
if (m_ui->lblZpNumber->text().isEmpty())
return false;
// originator:
bool hasParticipant = !m_ui->lblParticipantUnits->text().isEmpty();
if (!hasParticipant)
return false;
// target:
bool bHasTargetArea = !m_coord.isNull();
switch (m_currentGeometry.underlying())
{
case AreaEffectSimulation::AesExplosionGeometry_def::EgArea:
bHasTargetArea &= m_ui->lblDimensionYDepth->text().toInt() > 0;
bHasTargetArea &= m_ui->lblWidthRadius->text().toInt() > 0;
break;
default:
break;
}
if (!bHasTargetArea)
return false;
// ammo
const bool bHasAmmo = !m_ui->lblChargeType->text().isEmpty();
if (!bHasAmmo)
return false;
return true;
}
void ExplosionsEditAdler::setEffectClusterData(const EffectCluster &ecData)
{
m_aesItem = ecData;
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, ecData=" << ecData;
m_ui->lblZpNumber->setText(QString::fromStdString(ecData.name()));
qint64 effectStart = 0;
if (ecData.effectStart().is_set())
{
const QJsonObject propsObj(QJsonDocument::fromJson(QByteArray::fromStdString(ecData.properties())).object());
const FiringType firingType = static_cast<FiringType::inner_enum>(propsObj[AdlerJson::JsonKeys::ABFEUERUNGSART()].toInt());
effectStart = ecData.effectStart().get();
if (firingType == FiringType::FireWithIndicationTTF)
effectStart -= ecData.effectors().size() ? ecData.effectors().at(0).flightTime() : 0;
}
m_ui->dteEffectStart->setMsecsSinceEpoch(effectStart);
// Geometry/Area
const AreaEffectSimulation::AesExplosionGeometry_def::type geometryType = ecData.explosionGeometry().underlying();
switch (geometryType)
{
case AreaEffectSimulation::AesExplosionGeometry_def::EgAimPoint:
m_ui->geometrieAimPointBtn->setChecked(true);
break;
case AreaEffectSimulation::AesExplosionGeometry_def::EgPoint:
m_ui->geometriePointBtn->setChecked(true);
break;
case AreaEffectSimulation::AesExplosionGeometry_def::EgArea:
m_ui->geometrieAreaBtn->setChecked(true);
break;
case AreaEffectSimulation::AesExplosionGeometry_def::EgLine:
m_ui->geometrieLineBtn->setChecked(true);
break;
case AreaEffectSimulation::AesExplosionGeometry_def::EgRadial:
m_ui->geometrieRadialBtn->setChecked(true);
break;
default:
// empty
break;
} // switch
if (ecData.effectDuration() == DEFAULT_EFFECT_DURATION)
m_ui->lblDuration->setText(QStringLiteral("---"));
else
m_ui->lblDuration->setText(QString::number(ecData.effectDuration() / 1000)); // msecs -> secs
// 1st GearClass
ProjectDataManagement::GearClass gc = m_pdmDtc->gearClassFromChargeTypeId(ecData.chargeStruct().chargeTypeId());
m_ui->lblGearClass->setText(ProjectDataManagement::toString(gc));
// 2nd Party
if (ecData.partyId().is_set())
m_ui->lblParty->setText(ParticipantManagement::trPartyName(m_ppmDtc->party(ecData.partyId().get()).name()));
// 3rd Originator
if (ecData.participantId().is_set())
m_ui->lblParticipantUnits->setText(QString::fromStdString(m_ppmDtc->participant(ecData.participantId().get()).name()));
m_ui->lblChargeType->setText(m_pdmDtc->adlerChargeTypeName(ecData.chargeStruct().chargeTypeId()));
m_ui->lblIgniterType->setText(m_pdmDtc->adlerIgniterTypeName(ecData.chargeStruct().igniterTypeId()));
m_ui->lblIgniterFunction->setText(m_pdmDtc->adlerIgniterFunctionName(ecData.chargeStruct().igniterFunctionId()));
int impactCount = 0;
// delete existing widgets
QLayoutItem *item = nullptr;
while((item = m_ui->layoutEffectors->takeAt(0)) != nullptr)
{
if (item->widget())
delete item->widget();
delete item;
}
for (const auto &effectorData : ecData.effectors())
{
setEffector(effectorData.participantId(), m_dtc->effector(effectorData.participantId()).effectorState());
impactCount += effectorData.chargeAmount();
}
m_ui->layoutEffectors->setColumnStretch(m_effectorNumber + 1 % m_maxColumns, 1);
m_ui->lblCannons->setText(QString::number(impactCount));
m_ui->lblFirePurpose->setText(m_pdmDtc->trFirePurposeName(ecData.firePurposeId()));
m_ui->lblZog->setText(QString::number(ecData.tla())); // tla == zog
const AreaEffectSimulation::Area &areaRef = ecData.area();
const QPointF bottomLeft(areaRef.cornerBottomLeft().lon(), areaRef.cornerBottomLeft().lat());
const QPointF centerpoint = Polygons::bottomLeft2CenterPoint(bottomLeft, areaRef.width(), areaRef.height(), areaRef.rotation());
if (!bottomLeft.isNull())
{
m_ui->positionEdit->setCoordinate(centerpoint);
m_coord = centerpoint;
const Core::GeoPosition coordGeo(centerpoint.x(), centerpoint.y(), 0);
bool isSmoke = m_pdmDtc->isSmoke(ecData.chargeStruct().chargeTypeId(), ecData.chargeStruct().igniterTypeId(), ecData.chargeStruct().igniterFunctionId());
m_esmActorCbx->fillActorComboBox(m_ui->cbActors, coordGeo, isSmoke, 0);
m_esmActorCbx->fillActorComboBox(m_ui->cbActors_2, coordGeo, isSmoke, 0);
}
if (ecData.explosionGeometry().underlying() == AreaEffectSimulation::AesExplosionGeometry_def::EgRadial)
{
m_ui->lblDimensionYDepth->setText(QString::number(static_cast<int>(std::round(areaRef.height() / 2))));
m_ui->lblWidthRadius->setText(QString::number(static_cast<int>(std::round(areaRef.width() / 2))));
m_ui->lblAimingAxis->setText(QString::number(0));
}
else
{
m_ui->lblDimensionYDepth->setText(QString::number(static_cast<int>(std::round(areaRef.height()))));
m_ui->lblWidthRadius->setText(QString::number(static_cast<int>(std::round(areaRef.width()))));
m_ui->lblAimingAxis->setText(QString::number(static_cast<int>(std::round(fmod((areaRef.rotation()) * 6400 / 360, 6400)))));
}
setEffectClusterDataFromJson(ecData.properties());
if (!ecData.esmParticipantIds().empty())
{
m_ui->cbActors->setCurrentIndex(m_ui->cbActors->findData(ecData.esmParticipantIds().at(0)));
if (ecData.esmParticipantIds().size() > 1)
m_ui->cbActors_2->setCurrentIndex(m_ui->cbActors_2->findData(ecData.esmParticipantIds().at(1)));
}
if (ecData.effectors().size())
setOWUWFromTrajectory(ecData.effectors().at(0).trajectoryRelative());
// enable second Actor if possible
const int amountFireMarker = m_pdmDtc->getAmountFireMarkers(ecData.firePurposeId());
m_ui->cbActors_2->setEnabled(amountFireMarker > 1);
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
}
void ExplosionsEditAdler::setEffector(int participantId, const AreaEffectSimulation::AesEffectorState &effectorState)
{
const ParticipantManagement::Participant &part = m_ppmDtc->participant(participantId);
auto *effectorWidget = new AesEffector(this);
effectorWidget->init(participantId, QString::fromStdString(part.tacticalIdentifier()), QString::fromStdString(part.name()), effectorState);
effectorWidget->setStateButtonVisible(false);
const int row = m_effectorNumber / m_maxColumns;
const int col = m_effectorNumber % m_maxColumns;
m_ui->layoutEffectors->addWidget(effectorWidget, row, col);
m_effectorNumber++;
}
/*!
* \brief ExplosionsEditAdler::dialogIdentifier
* \return
*/
QString ExplosionsEditAdler::dialogIdentifier() const
{
DEBUG_LOG(m_logger) << "dialogIdentifier";
return m_aesItem.id() <= 0 ? QStringLiteral("AddExplosionsArtillery") : QStringLiteral("EditExplosionsArtillery%1").arg(m_aesItem.id());
}
void ExplosionsEditAdler::onAcknowledgeExternalAesItemReply(const Core::FunctionReplyObject &replyObject)
{
DEBUG_LOG(m_logger) << " GOIT REPLY for onAcknowledgeExternalAesItemReply";
m_requestHelper->requestReply(replyObject);
}
void ExplosionsEditAdler::onEffectClusterChanged(const EffectCluster &ecData, DataModification modType)
{
DEBUG_LOG(m_logger) << "onExplosionClusterChanged";
if (ecData.id() != m_aesItem.id())
return;
BaseEdit::onAreaChanged(ecData, modType);
if (modType == DataModification::eRemoved)
{
m_effectClusterData = EffectCluster();
return;
}
m_effectClusterData = ecData;
m_currentGeometry = m_effectClusterData.explosionGeometry();
setEffectClusterData(ecData);
setPbStateChangeName();
if (m_effectClusterData.effectDuration() == DEFAULT_EFFECT_DURATION)
m_ui->lblDuration->setText(QStringLiteral("---"));
else
m_ui->lblDuration->setText(QString::number(m_effectClusterData.effectDuration() / 1000)); // msec -> sec
enableUiElements();
if (unchangeable())
{
m_ui->pbStateChange->setEnabled(false);
m_ui->gbEffectMarkingInTa->setEnabled(false);
}
}
QPointF ExplosionsEditAdler::centerOfFiringUnitGeo(int particpantUnitId)
{
DEBUG_LOG(m_logger) << "centerOfFiringUnitGeo";
if (!m_sitMapGuiIfc || !m_ppmDtc)
return {};
if (particpantUnitId <= 0)
return {};
std::vector<Core::GeoPosition> singlePositionsOut_unused;
const LtsUtils::QPoint3D &centerCoordGeo = Polygons::calculateFiringUnitCenterNonRecursive(m_ppmDtc, particpantUnitId, singlePositionsOut_unused, m_logger);
if (centerCoordGeo.isNull() || std::isnan(centerCoordGeo.x()))
{
// may happen in real life: so WARNING_LOG to DEBUG_LOG
DEBUG_LOG(m_logger) << LOGFUNCTION << " calculateFiringUnitCenterNonRecursive failed, particpantUnitId = " << particpantUnitId;
return {};
}
return centerCoordGeo.toPointF();
}
void ExplosionsEditAdler::showCenterOfFiringUnit(int particpantUnitId)
{
DEBUG_LOG(m_logger) << "showCenterOfFiringUnit";
if (!m_sitMapGuiIfc || !m_ppmDtc)
return;
DEBUG_LOG(m_logger) << LOGFUNCTION << " START particpantUnitId: " << particpantUnitId;
if (particpantUnitId <= 0)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " showCenterOfFiringUnit: " << particpantUnitId << ", removeObjectIndicator";
m_sitMapGuiIfc->removeObjectIndicator();
return;
}
const QPointF &centerFiringUnitGeo = centerOfFiringUnitGeo(particpantUnitId);
if (centerFiringUnitGeo.isNull())
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " showCenterOfFiringUnit: " << particpantUnitId << ", removeObjectIndicator due to invalid position";
m_sitMapGuiIfc->removeObjectIndicator();
return;
}
DEBUG_LOG(m_logger) << LOGFUNCTION << " END particpantUnitId: " << particpantUnitId;
m_sitMapGuiIfc->objectIndicatorToPoint(centerFiringUnitGeo); // you can provide a duration: lifetimeMsec = -1
}
/*!
* \brief ExplosionsEditAdler::retranslate
*/
void ExplosionsEditAdler::retranslate()
{
QString title = tr("ADLER Artillery");
translate(m_ui, m_aesItem, title);
if (unchangeable())
{
m_ui->pbStateChange->setEnabled(false);
m_ui->gbEffectMarkingInTa->setEnabled(false);
}
}
void ExplosionsEditAdler::enableUiElements() { enableUiElements(false); }
void ExplosionsEditAdler::enableUiElements(bool enable)
{
m_ui->pbPosition->setEnabled(m_sitMapGuiIfc && enable);
m_ui->pbPosition_2->setEnabled(m_sitMapGuiIfc && enable);
m_ui->positionEdit->setEnabled(enable);
m_ui->positionEdit_2->setEnabled(enable);
m_ui->pbClear->setEnabled(enable);
m_ui->pbClear_2->setEnabled(enable);
m_ui->geometrieAimPointBtn->setEnabled(enable);
m_ui->geometrieAreaBtn->setEnabled(enable);
m_ui->geometriePointBtn->setEnabled(enable);
m_ui->geometrieLineBtn->setEnabled(enable);
m_ui->geometrieRadialBtn->setEnabled(enable);
m_ui->rbAngleGroupLower->setEnabled(enable);
m_ui->rbAngleGroupUpper->setEnabled(enable);
if (m_aesItem.effectStateId() == AesEffectState_def::EsReceived)
m_ui->pbStateChange->setEnabled(true);
else
m_ui->pbStateChange->setEnabled(m_effectClusterData.effectorState() != AreaEffectSimulation::AesEffectorState::EsReadyToFire);
}
/*!
* \brief ExplosionsEditAdler::apply
* \return
*/
bool ExplosionsEditAdler::apply()
{
// DMF (Actors)
int esmParticipantId1 = m_ui->cbActors->currentData().toInt(); // participant ID
int esmParticipantId2 = m_ui->cbActors_2->currentData().toInt(); // participant ID
EffectClusterModifyActorRequest request;
request.aesId(m_aesItem.id());
DEBUG_LOG(m_logger) << "currentIndex: " << m_ui->cbActors->currentIndex() << ", currentText: " << m_ui->cbActors->currentText()
<< ", participantId1: " << esmParticipantId1;
if (esmParticipantId1 > 0 || esmParticipantId2 > 0)
{
request.esmParticipantIds().reserve(2);
if (esmParticipantId1 > 0)
request.esmParticipantIds().push_back(esmParticipantId1);
if (esmParticipantId2 > 0 && esmParticipantId1 != esmParticipantId2 && m_ui->cbActors_2->isEnabled())
request.esmParticipantIds().push_back(esmParticipantId2);
}
m_requestHelper->addRequest([this, request]() { return m_ftc->effectClusterModifyActorRequest(request, this); });
return m_requestHelper->startRequests();
}
//
void ExplosionsEditAdler::setPbStateChangeName()
{
DEBUG_LOG(m_logger) << "onPbStateChangeName: AesEffectState: " << m_aesItem.effectStateId();
if ((m_aesItem.effectStateId() != AesEffectState::EsReceived && m_aesItem.effectStateId() != AesEffectState::EsCreated) || m_aesItem.id() <= 0)
return;
m_ui->pbStateChange->show();
if (m_aesItem.effectStateId() == AesEffectState_def::EsReceived)
m_ui->pbStateChange->setText(tr("Acknowledge"));
else
{
m_ui->pbStateChange->setText(tr("Ready to fire"));
m_ui->pbStateChange->setEnabled(m_effectClusterData.effectorState() != AreaEffectSimulation::AesEffectorState::EsReadyToFire);
}
}
void ExplosionsEditAdler::onPbStateChangeClicked()
{
if ((m_aesItem.effectStateId() != AesEffectState::EsReceived && m_aesItem.effectStateId() != AesEffectState::EsCreated) || m_aesItem.id() <= 0)
return;
DEBUG_LOG(m_logger) << " onPbStateChangeClicked: AesEffectState = " << m_aesItem.effectStateId();
m_ui->pbStateChange->setDisabled(true);
if (m_ui->gbEffectMarkingInTa->isChecked())
apply();
// Re-Enable PB, so we can call it another time, if it does not react...
QTimer::singleShot(2000, [this]() { m_ui->pbStateChange->setEnabled(m_effectClusterData.effectorState() != AreaEffectSimulation::AesEffectorState::EsReadyToFire); });
if (m_aesItem.effectStateId() == AesEffectState_def::EsReceived)
{
AreaEffectSimulation::AcknowledgeExternalAesItemRequest request;
request.aesId(m_aesItem.id());
DEBUG_LOG(m_logger) << "Send acknowledgeExternalAesItemRequest with aesId: " << request.aesId();
m_requestHelper->addRequest([this, request]() { return m_ftc->acknowledgeExternalAesItemRequest(request, this); });
}
else
{
AreaEffectSimulation::SetAesItemEffectorStateRequest request;
request.aesId(m_aesItem.id());
request.newEffectorState(AesEffectorState::EsReadyToFire);
DEBUG_LOG(m_logger) << "Send setAesItemEffectorStateRequest with aesId: " << request.aesId() << ", AesEffectorState: " << request.newEffectorState();
m_requestHelper->addRequest([this, request]() { return m_ftc->setAesItemEffectorStateRequest(request, this); });
}
m_requestHelper->startRequests();
}
void ExplosionsEditAdler::onEffectorChanged(const AreaEffectSimulation::Effector &data, DataModification modType)
{
if (data.aesItemId() != m_aesItem.id())
return;
for (int i = 0; i < m_ui->layoutEffectors->count(); ++i)
{
QLayoutItem *item = m_ui->layoutEffectors->itemAt(i);
if (QWidget *widget = item->widget())
{
if (AesEffector *effectorWidget = qobject_cast<AesEffector *>(widget))
{
if (effectorWidget->effectorId() != data.id())
continue;
effectorWidget->setState(data.effectorState());
return;
}
}
}
if (modType == DataModification::eAdded)
setEffector(data.participantId(), data.effectorState());
}
bool ExplosionsEditAdler::isOnlyNameModifiable() const
{
// BaseClass::isOnlyNameModifiable() -> EsPaused || EsActivated
// m_effectClusterData.isObjectModifiable -> since PreStart and s_calculationOffsetMSec
const bool ret = BaseClass::isOnlyNameModifiable() || !m_effectClusterData.isObjectModifiable();
return ret;
}
void ExplosionsEditAdler::resetTempAndAnnotationStr()
{
INFO_LOG(m_logger) << " RESET resetTempAndAnnotationStr";
m_temporaryData.reset();
// updateAnnotationStr();
}
void ExplosionsEditAdler::addAnnotationStr(const QString &newAnno)
{
m_temporaryData.m_annotationString4Dlg += newAnno;
updateAnnotationStr();
}
void ExplosionsEditAdler::setOWUWFromTrajectory(const std::vector<Core::RelativePositionRelativeTime> &vecGeometry)
{
if (vecGeometry.size() < 2)
return;
const double dz = vecGeometry.at(1).offsetZ() - vecGeometry.at(0).offsetZ();
const QLineF line(vecGeometry.at(0).offsetX(), vecGeometry.at(0).offsetY(),
vecGeometry.at(1).offsetX(), vecGeometry.at(1).offsetY());
double angleArc = std::atan2(dz, line.length());
double angleDegree = angleArc * (180.0 / M_PI);
angleDegree = std::fmod(angleDegree + 360.0, 360.0);
DEBUG_LOG(m_logger) << "distance: " << line.length() << ", height: " << dz << ", angleDegree: " << angleDegree;
if (angleDegree > maxAngleUW)
m_ui->rbAngleGroupUpper->setChecked(true);
else
m_ui->rbAngleGroupLower->setChecked(true);
}
void ExplosionsEditAdler::updateAnnotationStr()
{
QStringList sl;
if (!m_temporaryData.m_annotationStringFiring4Dlg.isEmpty())
sl.append(m_temporaryData.m_annotationStringFiring4Dlg);
if (!m_temporaryData.m_annotationString4Dlg.isEmpty())
sl.append(m_temporaryData.m_annotationString4Dlg);
if (!m_temporaryData.m_remainingTimeStr.isEmpty())
sl.append(m_temporaryData.m_remainingTimeStr);
if (sl.isEmpty())
m_ui->lblAnnotationStringContent->setText(QStringLiteral("-"));
else if (sl.size() == 1)
m_ui->lblAnnotationStringContent->setText(sl.first());
else
m_ui->lblAnnotationStringContent->setText(sl.join(QStringLiteral(" ; ")));
}
void ExplosionsEditAdler::setEffectClusterDataFromJson(const std::string &properties)
{
const QJsonObject propsObj(QJsonDocument::fromJson(QByteArray::fromStdString(properties)).object());
DEBUG_LOG(m_logger) << "ecData json: " << properties;
const int elemente = propsObj[AdlerJson::JsonKeys::ELEMENTE()].toInt();
if (elemente > 0)
m_ui->lblElement->setText(QString::number(elemente));
const int loadTypeId = propsObj[AdlerJson::JsonKeys::LADUNG()].toInt();
if (loadTypeId > 0)
m_ui->lblLoadType->setText(m_pdmDtc->trLoadTypeShortName(loadTypeId));
const int loadNumber = propsObj[AdlerJson::JsonKeys::LADUNGSNUMMER()].toInt(-1);
if (loadNumber >= 0)
m_ui->lblLoadNumber->setText(QString::number(loadNumber));
const int targetTypeId = propsObj[AdlerJson::JsonKeys::TYP()].toInt();
if (targetTypeId > 0)
m_ui->lblTargetType->setText(m_pdmDtc->trTargetTypeName(targetTypeId));
const int targetSubTypeId = propsObj[AdlerJson::JsonKeys::SUB_TYP()].toInt();
if (targetSubTypeId > 0)
m_ui->lblTargetSubType->setText(m_pdmDtc->trTargetSubTypeName(targetSubTypeId));
const int angleGroup = propsObj[AdlerJson::JsonKeys::WINKELGRUPPE()].toInt();
if (angleGroup == ProjectDataManagement::L43_AngleGroup::Lower)
m_ui->rbAngleGroupLower->setChecked(true);
else
m_ui->rbAngleGroupUpper->setChecked(true);
const FiringType &firingType = static_cast<FiringType::inner_enum>(propsObj[AdlerJson::JsonKeys::ABFEUERUNGSART()].toInt());
m_ui->lblFiringType->setText(AreaEffectSimulation::toString(firingType));
}
} // namespace AreaEffectSimulation