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

311 lines
12 KiB
C++
Executable File

/**
* @RDE_HEADER@
* AreaEffectManangement - Explosion Cluster Overview Dialog Model
* $Id$
* $HeadURL$
* $Author$
*
* Created by Norbert Thoden, SLSE, 2023-12-15
*/
#include "aes_effect_cluster_model.h"
#include <LtsCoordTrans/lts_coord_trans.h>
#include <ProjectDataManagement/pdm_dtc.h>
#include <ProjectDataManagement/pdm_translation.h>
namespace AreaEffectSimulation
{
EffectClusterModel::EffectClusterModel(const QVector<ProjectDataManagement::GearClass> &gcs, QObject *parent)
: AesGuiBaseModel<EffectCluster>(parent,
{tr("GearType"),
tr("Fuse Type"),
tr("FiringPosition"),
tr("ExplosionGeometry"),
tr("ZOG"), // TLA ZOG
tr("MeanHitPoints"),
tr("MhpRotation"),
tr("Impact Count"),
tr("AnnotationString"),
tr("Element"),
tr("Original Flight Duration"),
tr("Original Peak Height"),
tr("Calculated Flight Duration"),
tr("Calculated Peak Height"),
tr("Calculated Firing Speed [m/s]"),
tr("Launch Velocity [m/s]"),
tr("Launch Angle [degree]"),
tr("Drop Angle [degree]"),
tr("TapTimepoint"),
tr("Laser Code Prf"),
tr("Laser Code Termination"),
tr("Cloud Base")})
, m_gearClasses(gcs)
{
}
bool EffectClusterModel::initModel(LtsSession::LtsSession *session)
{
updateEffectStateComboboxFilterData(true);
if (!AesGuiBaseModel::initModel(session))
return false;
connect(m_aesDtc.get(), &Interface::Dtc::effectClusterChanged, this, &EffectClusterModel::onDataChanged);
connect(m_aesDtc.get(), &Interface::Dtc::explosionClusterChanged, this, &EffectClusterModel::onExplosionClusterDataChanged);
fillAvailableChargeIds(m_gearClasses);
// fillAvailableChargeIds({ProjectDataManagement::GearClass_def::Artillery, ProjectDataManagement::GearClass_def::Mortar});
m_aesDtc->effectClusters([this](const EffectCluster &item) { insertRow(item); });
m_aesDtc->explosionClusters([this](const ExplosionCluster &item) { insertRow(toEffectCluster(item)); });
m_pdmDtc->enableGearTypeChargeType();
return true;
}
EffectCluster EffectClusterModel::toEffectCluster(const ExplosionCluster &data)
{
EffectCluster ec;
ec.id(data.id());
ec.name(data.name());
ec.effectSourceId(data.effectSourceId());
ec.effectStateId(data.effectStateId());
ec.chargeStruct(data.chargeStruct());
ec.effectDuration(data.effectDuration());
ec.effectStart(data.effectStart());
ec.area(data.area());
ec.esmParticipantIds(data.esmParticipantIds());
ec.explosionGeometry(data.explosionGeometry());
ec.element(data.element());
ec.firePurposeId(data.firePurposeId());
ec.firingPosition(data.firingPosition());
ec.fireRequestTime(data.fireRequestTime());
ec.tla(data.tla());
ec.sampleTime(data.sampleTime());
ec.effectMarkingInTa(data.effectMarkingInTa());
ec.externalId(data.externalId());
ec.remainExplosionNumber(data.remainExplosionNumber());
ec.participantId(data.participantId());
ec.partyId(data.partyId());
ec.properties(data.properties());
ec.isCentral(data.isCentral());
ec.isDeleted(data.isDeleted());
ec.isUsed(data.isUsed());
return ec;
}
void EffectClusterModel::onExplosionClusterDataChanged(const ExplosionCluster &data, const DataModification &mod) { onDataChanged(toEffectCluster(data), mod); }
void EffectClusterModel::toolTipHelper(const EffectClusterModel *model, const QModelIndex &idx, int col, QString &toolTipStringInOut) const
{
const QString &hdr = model->headerData(col, Qt::Horizontal, Qt::DisplayRole).toString();
const QModelIndex &idxTemp = idx.siblingAtColumn(col);
toolTipStringInOut.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, model->data(idxTemp, Qt::DisplayRole).toString()));
}
QVariant EffectClusterModel::data(const QModelIndex &idx, int role) const
{
if (!indexIsValid(idx))
return QVariant();
const EffectCluster &ec = m_vecData.at(idx.row());
// const dds::core::optional<AreaEffectSimulation::FlightCurve>& flightCurveRef = ec.flightCurve();
// const dds::core::optional<AreaEffectSimulation::LaserGuiding>& laserGuidingRef = ec.laserGuiding();
if (role == Qt::DisplayRole)
{
switch (idx.column())
{
case ColGearType:
{
const int chargeTypeId = ec.chargeStruct().chargeTypeId();
// There might be several gears for the same charge and we take the first one knowingly.
const int gearTypeId = m_pdmDtc->gearTypeIdFromChargeTypeId(chargeTypeId).value(0, 0);
return m_pdmDtc->trGearTypeName(gearTypeId);
}
break;
case ColIgniterType:
return m_pdmDtc->trIgniterTypeShortName(ec.chargeStruct().igniterTypeId());
break;
case ColFiringPosition:
{
const Core::GeoPosition &firingPositionRef = ec.firingPosition();
QString mgrs = LtsCoordTrans::mgrsFromGeographic(firingPositionRef.lon(), firingPositionRef.lat());
if (!qFuzzyIsNull(firingPositionRef.z()))
mgrs.append(QStringLiteral(" ") + QString::number(firingPositionRef.z(), 'f', 2));
return mgrs;
}
break;
case ColExplosionGeometry:
return AreaEffectSimulation::toString(ec.explosionGeometry());
break;
case ColTlaZog:
return ec.tla();
break;
// case ColMhPointCount:
// return static_cast<int>(ec.mhPoints().size());
// break;
// case ColMhpRotationCount:
// return std::ceil(ec.mhpRotation() * 100) / 100;
// break;
// case ColImpactCount:
// return ec.impactCount();
// break;
case ColAnnotationString:
return QString::fromStdString(ec.annotationString());
break;
case ColZpElement:
return QString::fromStdString(ec.element());
break;
/* Might be used again if needed
// FlightCurve
case ColOriginalFlightDuration:
if (flightCurveRef.is_set())
return std::ceil(flightCurveRef.get().requestedFlightDuration() * 100) / 100;
else
return QStringLiteral("-");
break;
case ColOriginalPeakHeight:
if (flightCurveRef.is_set())
return flightCurveRef.get().requestedRelativePeakHeight();
else
return QStringLiteral("-");
break;
case ColCalculatedFlightDuration:
if (flightCurveRef.is_set())
return flightCurveRef.get().calculatedFlightDuration();
else
return QStringLiteral("-");
break;
case ColCalculatedPeakHeight:
if (flightCurveRef.is_set())
return std::ceil(flightCurveRef.get().calculatedPeakHeightAbs() * 100) / 100;
else
return QStringLiteral("-");
break;
case ColCalculatedFiringSpeed:
if (flightCurveRef.is_set())
return std::ceil(flightCurveRef.get().calculatedFiringSpeed() * 100) / 100;
else
return QStringLiteral("-");
break;
case ColLaunchVelocity:
if (flightCurveRef.is_set())
return std::ceil(flightCurveRef.get().launchVelocity() * 100) / 100;
else
return QStringLiteral("-");
break;
case ColLaunchAngleDeg:
if (flightCurveRef.is_set())
return std::ceil(flightCurveRef.get().launchAngle() * 100) / 100;
else
return QStringLiteral("-");
break;
case ColDropAngle:
if (flightCurveRef.is_set())
return std::ceil(flightCurveRef.get().dropAngle() * 100) / 100;
else
return QStringLiteral("-");
break;
// LaserGuiding
case ColTapTimepoint:
if (laserGuidingRef.is_set())
return DTG::toStringMSec(laserGuidingRef.get().tapTime());
else
return QStringLiteral("-");
break;
case ColLcAttack_Prf:
if (laserGuidingRef.is_set())
return laserGuidingRef.get().lcAttack();
else
return QStringLiteral("-");
break;
case ColLcTermination:
if (laserGuidingRef.is_set())
return laserGuidingRef.get().lcTermination();
else
return QStringLiteral("-");
break;
case ColCloudBase:
if (laserGuidingRef.is_set())
return laserGuidingRef.get().cloudBase();
else
return QStringLiteral("-");
break;
*/
default:
return AesGuiBaseModel::data(idx, role);
break;
} // switch
}
else if (role == Qt::ToolTipRole)
{
switch (idx.column())
{
case ColAnnotationString:
// return QString::fromStdString(ec.annotationString());
break;
default:
{
QString tooltip(QStringLiteral("<html>"));
const QString &hdr = this->headerData(BcName, Qt::Horizontal, Qt::DisplayRole).toString();
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, QString::fromStdString(ec.name())));
bool bIsArtilleryOrMortar = m_gearClasses.contains(ProjectDataManagement::GearClass_def::Artillery)
|| m_gearClasses.contains(ProjectDataManagement::GearClass_def::Mortar)
|| m_gearClasses.contains(ProjectDataManagement::GearClass_def::Rocket);
toolTipHelper(this, idx, ColGearType, tooltip);
if (bIsArtilleryOrMortar)
{
toolTipHelper(this, idx, BcChargeType, tooltip);
toolTipHelper(this, idx, ColIgniterType, tooltip);
}
// Origin
toolTipHelper(this, idx, ColFiringPosition, tooltip);
// target
if (bIsArtilleryOrMortar)
{
toolTipHelper(this, idx, ColExplosionGeometry, tooltip);
toolTipHelper(this, idx, ColTlaZog, tooltip);
toolTipHelper(this, idx, ColMhPointCount, tooltip);
toolTipHelper(this, idx, ColImpactCount, tooltip);
toolTipHelper(this, idx, ColCalculatedFlightDuration, tooltip);
toolTipHelper(this, idx, ColCalculatedPeakHeight, tooltip);
toolTipHelper(this, idx, ColCalculatedFiringSpeed, tooltip);
toolTipHelper(this, idx, ColLaunchAngleDeg, tooltip);
toolTipHelper(this, idx, ColDropAngle, tooltip);
toolTipHelper(this, idx, ColTapTimepoint, tooltip);
toolTipHelper(this, idx, ColLcAttack_Prf, tooltip);
toolTipHelper(this, idx, ColLcTermination, tooltip);
toolTipHelper(this, idx, ColCloudBase, tooltip);
}
tooltip.append(QStringLiteral("</html>"));
return tooltip;
}
break;
} // switch
}
return AesGuiBaseModel::data(idx, role);
}
} // namespace AreaEffectSimulation