/** * @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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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(AreaEffectSimulation::AesExplosionGeometry_def::EgAimPoint)); m_geometrieButtonGroup->addButton(m_ui->geometrieAreaBtn, static_cast(AreaEffectSimulation::AesExplosionGeometry_def::EgArea)); m_geometrieButtonGroup->addButton(m_ui->geometrieLineBtn, static_cast(AreaEffectSimulation::AesExplosionGeometry_def::EgLine)); m_geometrieButtonGroup->addButton(m_ui->geometriePointBtn, static_cast(AreaEffectSimulation::AesExplosionGeometry_def::EgPoint)); m_geometrieButtonGroup->addButton(m_ui->geometrieRadialBtn, static_cast(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(m_asbIfc)) return false; if (!session->getForeignGuiInterface(m_esmActorCbx)) return false; // P _D_ M if (!m_session->getDtc(m_pdmDtc)) { ERROR_LOG(m_logger) << " failed to get pdmDtc"; return false; } if (!m_session->getForeignGuiInterface(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(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(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(std::round(areaRef.height() / 2)))); m_ui->lblWidthRadius->setText(QString::number(static_cast(std::round(areaRef.width() / 2)))); m_ui->lblAimingAxis->setText(QString::number(0)); } else { m_ui->lblDimensionYDepth->setText(QString::number(static_cast(std::round(areaRef.height())))); m_ui->lblWidthRadius->setText(QString::number(static_cast(std::round(areaRef.width())))); m_ui->lblAimingAxis->setText(QString::number(static_cast(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); } __unchange__(); } QPointF ExplosionsEditAdler::centerOfFiringUnitGeo(int particpantUnitId) { DEBUG_LOG(m_logger) << "centerOfFiringUnitGeo"; if (!m_sitMapGuiIfc || !m_ppmDtc) return {}; if (particpantUnitId <= 0) return {}; std::vector singlePositionsOut_unused; const LtsUtils::QPoint3D ¢erCoordGeo = 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 ¢erFiringUnitGeo = 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(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 &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(propsObj[AdlerJson::JsonKeys::ABFEUERUNGSART()].toInt()); m_ui->lblFiringType->setText(AreaEffectSimulation::toString(firingType)); } } // namespace AreaEffectSimulation