/** * @RDE_HEADER@ * ParticipantManagement - ParticipantInfoDialog * $Id$ * $HeadURL$ * $Author$ * Created by Patric Karwat, SLSE, 2016-06-01 */ #include "participant_info_dialog.h" #include "ui_participant_info_dialog.h" #include "participant_info_helper.h" #include #include #include #include #include #include #include "participant_config_dialog.h" #include "participant_bite_dialog.h" #include "participant_history_dialog.h" #include "participant_set_injury_dialog.h" #include "participant_set_sanitation_dialog.h" #include "participants_mounted_table_dialog.h" #include "participant_gear_restock.h" #include "participant_target_config_dialog.h" #include "participant_info_ltd_gear_component.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ParticipantManagement { ParticipantInfoDialog::ParticipantInfoDialog(int participantId, const QString &menuGroup, QWidget *parent) : LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly) , m_uasId(0) , m_lastPositionMSec(0) , m_typeClass(TypeClass::Unknown) , m_roomId(0) , m_menuGroup(menuGroup) , m_session(nullptr) , m_dtc(nullptr) , m_ftc(nullptr) , m_pdmDtc(nullptr) , m_tgtDtc(nullptr) , m_tgtFtc(nullptr) , m_aesDtc(nullptr) , m_sitMapGuiIfc(nullptr) , m_ppmGuiIfc(nullptr) , m_symbolWatcher(nullptr) , m_requestHelper(new LtsUtils::RequestHelper(this)) , m_ui(new Ui::ParticipantInfoDialog) , m_isTarget(false) , m_logger(getLogger("ParticipantInfoDialog")) { m_ui->setupUi(this); m_oldSpacerSize.first = m_ui->vsBottom->maximumSize().width(); m_oldSpacerSize.second = m_ui->vsBottom->maximumSize().height(); m_participant.id(participantId); m_participant.partyId(-1); m_ui->pbUnlockUas->setIcon(QIcon(QStringLiteral("icon:drone_remote_connection.svg"))); setUnchangeable(); connect(m_ui->pbSetStatus, &QToolButton::clicked, this, &ParticipantInfoDialog::onOpenSetStatusDialog); connect(m_ui->pbSetInjury, &QToolButton::clicked, this, &ParticipantInfoDialog::onOpenSetInjuryDialog); connect(m_ui->pbSetSanitation, &QToolButton::clicked, this, &ParticipantInfoDialog::onOpenSetSanitationDialog); connect(m_ui->pbHistory, &QToolButton::clicked, this, &ParticipantInfoDialog::onOpenHistory); connect(m_ui->pbBite, &QToolButton::clicked, this, &ParticipantInfoDialog::onOpenBite); connect(m_ui->pbMessage, &QToolButton::clicked, this, &ParticipantInfoDialog::onOpenMessage); connect(m_ui->pbFindOnMap, &QToolButton::clicked, this, &ParticipantInfoDialog::onFindOnMap); connect(m_ui->pbGearRanges, &QToolButton::clicked, this, &ParticipantInfoDialog::onGearRanges); m_ui->twGear->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_ui->twGear, &QTableWidget::customContextMenuRequested, this, &ParticipantInfoDialog::onContextMenuRequested); m_ui->pbMovementTrack->setCheckable(true); connect(m_ui->pbMovementTrack, &QToolButton::clicked, this, &ParticipantInfoDialog::onMovementTrack); connect(m_ui->pbUnlockUas, &QToolButton::clicked, this, &ParticipantInfoDialog::onUnlockUAS); //hide first: m_ui->twGear->hide(); m_ui->lblInfo->hide(); m_ui->lblInfoText->hide(); m_ui->lblInBuildingInfo->hide(); m_ui->pbMounted->hide(); m_ui->lbSpecialSensorState->hide(); m_ui->gbSanitation->hide(); LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance(); const bool enableMassages = ps->value(QStringLiteral("msg"), QStringLiteral("enableMessages")).toBool(); if (!enableMassages) m_ui->pbMessage->hide(); m_showPvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"), QStringLiteral("HasPvSan")); m_showVulnerabilityKindProject = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"), QStringLiteral("ShowVulnerabilityKind")); m_symbolWatcher = new AdvancedSymbology::SymbolResultWatcherLabel(m_ui->lblIcon); } ParticipantInfoDialog::~ParticipantInfoDialog() { if (m_ui->pbGearRanges->isChecked()) if (m_sitMapGuiIfc) m_sitMapGuiIfc->enableGearRanges(m_participant.id(), false); if (m_symbolAppearanceSettings) m_symbolAppearanceSettings->removeChangedCallback(this); delete m_ui; } void ParticipantInfoDialog::retranslate() { QString id; dds::core::optional eqId = m_participant.equipmentNumber(); if (eqId.is_set()) id = QString::number(eqId.get()); translate(m_ui, id, false, tr("Participant")); } bool ParticipantInfoDialog::init(LtsSession::LtsSession *session, const std::shared_ptr &dtc, const std::shared_ptr &ftc, const std::shared_ptr &pdmDtc, const std::shared_ptr &sitMapGuiIfc, const std::shared_ptr &asbInterface, const std::shared_ptr &ppmGuiIfc) { DEBUG_LOG(m_logger)<< "ParticipantInfoDialog::init"; m_session = session; m_dtc = dtc; m_ftc = ftc; m_pdmDtc = pdmDtc; m_sitMapGuiIfc = sitMapGuiIfc; m_asbiIfc = asbInterface; m_ppmGuiIfc = ppmGuiIfc; if (m_ltdGearComponent) delete m_ltdGearComponent; m_ltdGearComponent = new ParticipantInfoLtdGearComponent(m_ui->twGear); m_session->getDtc(m_ismDtc); if (!m_session->getDtc(m_aesDtc)) m_ui->pbHistory->setEnabled(false); connect(m_dtc.get(), &Interface::Dtc::partyChanged, this, &ParticipantInfoDialog::updateCurrentIcon, Qt::UniqueConnection); // to handle race condition between DynamicParticipantData and DusMineState: connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::dusMineStateChanged, this, &ParticipantInfoDialog::updateCurrentIcon, Qt::UniqueConnection); connect(m_ui->twGear, &QTableWidget::cellDoubleClicked, this, [this](int row, int column){ Q_UNUSED(column); int gearId = m_ui->twGear->item(row, 0)->data(Qt::UserRole).toInt(); int gTypeId = 0; auto gears = m_dtc->dynamicParticipantData(m_participant.id()).gear(); if (gears.size() < 1) return; for(auto gear : gears) { if (gear.gearId() == gearId) gTypeId = gear.gearTypeId(); } if(m_pdmDtc->canRestock(gTypeId)) { onRestockNow(gearId, gTypeId); } }); DEBUG_LOG(m_logger)<< "Vor setUiValues"; return setUiValues(); } // private bool ParticipantInfoDialog::setUiValues() { /* NOTE: This is a hide-all-you-don't-need concept. Everything is shown, * so everything you don't want to show up must be hidden. * Plus, once hidden, widgets must not be shown again. */ DEBUG_LOG(m_logger) << "------------------setUiValues-----------------"; if (!m_dtc || !m_ftc || m_participant.id() < 0) return false; // m_showPvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"), // QStringLiteral("HasPvSan")); m_ui->pbTarget->setVisible(false); m_ui->lblVitality->setVisible(false); m_ui->pbSetInjury->setVisible(false); m_ui->pbSetSanitation->setVisible(false); //hide findOnMap if no interface available m_ui->pbFindOnMap->setVisible(m_sitMapGuiIfc != nullptr); m_ui->pbMovementTrack->setVisible(m_sitMapGuiIfc != nullptr); m_ui->tbNbc->setVisible(false); //show only if visible // m_participant.id() was given within ctor const Participant participantData = m_dtc->participant(m_participant.id()); const Type type = m_dtc->type(participantData.typeId()); m_typeClass = type.typeClass(); // uas stuff const bool isUas = m_dtc->isTypeUas(participantData.typeId()); DEBUG_LOG(m_logger) << "------------------UAS-----------------" << " isTypeUas" << isUas << " participantId=" <lblOperatingMode->setText(QStringLiteral("-")); onUasChanged(uas); // hide all widgets (and labels) that are not available for uas: m_ui->pbBite->setVisible(false); m_ui->pbMessage->setVisible(false); // these are not supported yet, therefore hidden: m_ui->lblBatteryStatus->setVisible(false); m_ui->lbBatteryStatus->setVisible(false); } else // not a uas { // hide all uas specific widgets (and labels): m_ui->lblBatteryStatus->setVisible(false); m_ui->lbBatteryStatus->setVisible(false); m_ui->lblOperatingMode->setVisible(false); m_ui->lbOperatingMode->setVisible(false); m_ui->pbUnlockUas->setVisible(false); } if (m_typeClass != TypeClass::Human) m_ui->lbKind->setText(tr("Damage Type:")); // translates "Beschaedigungs" for non-Humans. else m_ui->lbKind->setText(tr("Kind:")); // translates "Verwundung" for Humans. bool bUpdateDynamicParticipantData = true; switch (m_typeClass.underlying()) { case TypeClass::Human: { m_ui->lblVitality->setVisible(m_showPvSan); m_ui->pbSetInjury->setVisible(m_showPvSan); m_ui->pbSetSanitation->setVisible(m_showPvSan); Q_FALLTHROUGH(); } case TypeClass::GroundVehicle: case TypeClass::VehicleWithGear: case TypeClass::WeaponSystem: case TypeClass::Aircraft: case TypeClass::SupportEntity: { onParticipantChanged(participantData); connect(m_dtc.get(), &Interface::Dtc::participantChanged, this, &ParticipantInfoDialog::onParticipantChanged, Qt::UniqueConnection); connect(m_dtc.get(), &Interface::Dtc::participantPositionChanged, this, &ParticipantInfoDialog::onPositionChanged, Qt::UniqueConnection); onPositionChanged(m_dtc->participantPosition(m_participant.id())); onPartitionTimeChanged(m_session->partitionTime()); if (m_sitMapGuiIfc) { const int32_t participantId = m_participant.id(); m_ui->pbMovementTrack->setChecked(m_sitMapGuiIfc->isMovementTrackEnabled(participantId)); // set MovementTrackCallback: std::function &activeSimIds)> onMovementTrackChangedFunc = [this, participantId](const QVector &activeSimIds) { bool checkedNew = activeSimIds.contains(participantId); if (m_ui->pbMovementTrack->isChecked() != checkedNew) m_ui->pbMovementTrack->setChecked(checkedNew); }; m_sitMapGuiIfc->setMovementTrackCallback(this, onMovementTrackChangedFunc); } break; } case TypeClass::Unit: case TypeClass::SupportUnit: { if (!m_fltParticipantIfc) m_session->getForeignGuiInterface(m_fltParticipantIfc); if (m_fltParticipantIfc) { const int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId(); m_symbolAppearanceSettings = m_fltParticipantIfc->symbolAppearanceForOperator(operatorId, m_session->workspaceId()); if (m_symbolAppearanceSettings) m_symbolAppearanceSettings->addChangedCallback(this); } //a unit never has a history m_ui->pbHistory->hide(); m_ui->lblEquipNr->hide(); m_ui->lbEquipNr->hide(); m_ui->pbBite->hide(); m_ui->pbMessage->hide(); m_ui->pbMovementTrack->hide(); m_ui->pbSetInjury->hide(); m_ui->pbSetSanitation->hide(); m_ui->lbContamination->hide(); m_ui->lblContamination->hide(); onParticipantChanged(participantData); connect(m_dtc.get(), &Interface::Dtc::participantChanged, this, &ParticipantInfoDialog::onParticipantChanged, Qt::UniqueConnection); connect(m_dtc.get(), &Interface::Dtc::unitPositionChanged, this, &ParticipantInfoDialog::onUnitPositionChanged, Qt::UniqueConnection); onUnitPositionChanged(m_dtc->unitPosition(m_participant.id())); break; } case TypeClass::Vessel: case TypeClass::Unknown: ERROR_LOG(m_logger) << LOGFUNCTION << m_typeClass; return false; } if (bUpdateDynamicParticipantData) { const auto dpd = m_dtc->dynamicParticipantData(m_participant.id()); if (dpd.participantId() || m_participant.id()) onDynamicParticipantDataChanged(dpd); else { const Party party = m_dtc->party(m_participant.partyId()); const QColor color = QColor::fromRgb(QRgb(party.color())); updateIcon(color, QString::fromStdString(m_participant.symbol())); } } setKindVisible(m_typeClass != TypeClass::SupportEntity && m_typeClass != TypeClass::Unit && m_typeClass != TypeClass::SupportUnit); setStatusVisible(m_typeClass != TypeClass::SupportEntity && m_typeClass != TypeClass::Unit && m_typeClass != TypeClass::SupportUnit); setHistoryVisible(m_typeClass != TypeClass::SupportEntity && m_typeClass != TypeClass::Unit && m_typeClass != TypeClass::SupportUnit); //other connects connect(m_dtc.get(), &Interface::Dtc::typeChanged, this, &ParticipantInfoDialog::onTypeChanged, Qt::UniqueConnection); connect(m_dtc.get(), &Interface::Dtc::dynamicParticipantDataChanged, this, &ParticipantInfoDialog::onDynamicParticipantDataChanged, Qt::UniqueConnection); connect(m_session, &LtsSession::LtsSession::partitionTimeChanged, this, &ParticipantInfoDialog::onPartitionTimeChanged, Qt::UniqueConnection); if (m_session->app() == LtsAppDescriptor::App::OC) // is the plugin loaded by the OC-App? { // hide several unused Buttons m_ui->pbBite->hide(); m_ui->pbHistory->hide(); m_ui->pbMessage->hide(); m_ui->pbSetStatus->hide(); m_ui->pbSetInjury->hide(); m_ui->pbSetSanitation->hide(); } if (m_session->isReplayPartition()) // is replay? { m_ui->pbSetStatus->hide(); m_ui->pbMessage->hide(); m_ui->pbBite->hide(); m_ui->pbSetInjury->hide(); m_ui->pbSetSanitation->hide(); } if (!m_participant.equipmentNumber().is_set()) { setEquipNrVisible(false); setBiteVisible(false); setStatusVisible(false); setHistoryVisible(false); setKindVisible(false); setMessageVisible(false); initTargetConfig(false); initTargetConfigL400(false); } else { const EquipmentType eqType = m_dtc->equipmentType(type.equipmentTypeId()); m_isTarget = (eqType.wmsTypeClass() == WmsTypeClass::TargetHuman || eqType.wmsTypeClass() == WmsTypeClass::TargetVehicle); // m_isTarget = 1; // initTargetConfigL400(/*m_isTarget*/ true); initTargetConfig(m_isTarget); m_ui->twGear->setColumnHidden(0, m_isTarget); m_ui->twGear->setColumnHidden(1, m_isTarget); } switch (m_typeClass.underlying()) { case TypeClass::SupportEntity: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Support_Entity")); break; case TypeClass::Unit: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Unit")); break; case TypeClass::Human: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Human")); break; case TypeClass::GroundVehicle: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Ground_Vehicle")); break; case TypeClass::VehicleWithGear: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Ground_Vehicle_With_Gear")); break; case TypeClass::Aircraft: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Aircraft")); break; case TypeClass::Vessel: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Vessel")); break; case TypeClass::WeaponSystem: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Weapon_System")); break; case TypeClass::SupportUnit: setOnlineHelpFilename(QStringLiteral("Info_Dialog-Unit")); break; case TypeClass::Unknown: ERROR_LOG(m_logger) << LOGFUNCTION << m_typeClass; } #if LTS_DEBUG //-- start Test Gui Elment plugin auto cb = [this](const LtsPluginManager::PluginInstance &pi) { return loadGuiElementPLugin(pi);}; LtsPluginManager::LtsPluginLoader::getInstance()->loadPlugins(LtsPluginManager::PluginType::GUI_ELEMENT, cb, QStringList()); //-- end Test Gui Element plugin #endif return true; } bool ParticipantInfoDialog::loadGuiElementPLugin(const LtsPluginManager::PluginInstance &pi) { WARNING_LOG(m_logger)<<">>>> GUI Element pluginName: "<(pi.plugin); if (guiElement->pluginName() == QStringLiteral("KeyValueGuiElement_XY")) { if (!guiElement->init(m_session, m_participant.id())) return false; m_ui->gridLayout_2->addWidget(guiElement->createGuiElement(this)); return true; } return false; } //SLOTS void ParticipantInfoDialog::onDynamicParticipantDataChanged(const DynamicParticipantData &data, DataModification modType) { if (data.participantId() != m_participant.id() && data.participantId() != 0) return; // Do not continue on modType == DataModification::eRemove // otherwise for example the icon would look bad (clover with black on black...) if (modType == DataModification::eRemoved) { if (m_ui->lblIcon != nullptr) m_ui->lblIcon->setEnabled(false); return; } if (m_ui->lblIcon != nullptr) m_ui->lblIcon->setEnabled(true); //Current State qWarning() << "stateHistory count" << data.stateHistory().size(); bool contaminationListIsEmpty = true; if (!data.stateHistory().empty()) { const ProjectDataManagement::VulnerabilityClass vc = m_typeClass == TypeClass::Human ? ProjectDataManagement::VulnerabilityClass_def::SoldierInjuries : ProjectDataManagement::VulnerabilityClass_def::VehicleDamages; //#define FAKE_HISTORY #ifdef FAKE_HISTORY // fake history, where all sis have the same stateTime std::vector history; if (!data.stateHistory().empty()) { auto firstTime = data.stateHistory().front().stateTime(); for (const auto &si : data.stateHistory()) { auto fakeSi = si; fakeSi.stateTime(firstTime); history.push_back(fakeSi); } } #else const auto &history = data.stateHistory(); #endif //LasState is the last "real" state, that has a VBG <=8 (Castastrophic) //It's not the last state received, as there can be other state changes like Sanitation, or NearMiss StateInformation lastState = m_dtc->youngestStateInformation(history/*, true*/ /* debug */);; StateInformation youngestState; youngestState.stateTime(0); for (const StateInformation &si : history) { DEBUG_LOG(m_logger) << "StateInformation " << " time=" << si.stateTime() << " vulnerabilityBits=" << si.vulnerabilityBits() << " vulnerabilityKindId=" << si.vulnerabilityKindId(); if ( youngestState.stateTime() < si.stateTime()) youngestState = si; } // const bool showPvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"), // QStringLiteral("HasPvSan")); m_ui->lblStatus->setText(ProjectDataManagement::toString(lastState.vulnerabilityState(), vc)); //vitality DEBUG_LOG(m_logger)<<" >>> last state: "<lblVitality->setText(QString::number(lastState.vitality()) + QStringLiteral("%")); // Set Contamination const int NCONTAMINATION = 0x4000; const int BCONTAMINATION = 0x8000; const int CCONTAMINATION = 0x10000; QStringList contaminationList; DEBUG_LOG(m_logger) << "Set Contamination" << " time=" << youngestState.stateTime() << " vulnerabilityKindId=" << youngestState.vulnerabilityKindId() << " vulnerabilityBits=" << youngestState.vulnerabilityBits() << " vulnerabilityBits hex=0x" << std::hex << youngestState.vulnerabilityBits(); if ( youngestState.vulnerabilityBits() & NCONTAMINATION) { DEBUG_LOG(m_logger) << "append N"; const ProjectDataManagement::VulnerabilityState vs(static_cast(14)); QString fullName = ProjectDataManagement::toString(vs); QString shortName; shortName.append(fullName[0]); contaminationList.append( shortName); contaminationListIsEmpty = false; } if ( youngestState.vulnerabilityBits() & BCONTAMINATION) { DEBUG_LOG(m_logger) << "append B"; const ProjectDataManagement::VulnerabilityState vs(static_cast(15)); QString fullName = ProjectDataManagement::toString(vs); QString shortName; shortName.append(fullName[0]); contaminationList.append( shortName); contaminationListIsEmpty = false; } if ( youngestState.vulnerabilityBits() & CCONTAMINATION) { DEBUG_LOG(m_logger) << "append C"; const ProjectDataManagement::VulnerabilityState vs(static_cast(16)); QString fullName = ProjectDataManagement::toString(vs); QString shortName; shortName.append(fullName[0]); contaminationList.append( shortName); contaminationListIsEmpty = false; } m_ui->lblContamination->setText(contaminationList.join(QStringLiteral("+"))); // VBA //AG 40 HACK! if (lastState.vulnerabilityKindId() == 459286 && !((lastState.vulnerabilityBits() >> 7) & 1)) // VBG7 NOT set in history bits, but kind id still implying that VBG7 is still active m_ui->lblKind->setText(QLatin1String("-")); else m_ui->lblKind->setText(m_pdmDtc->trVulnerabilityKindName(lastState.vulnerabilityKindId(), vc)); if (m_showPvSan && vc == ProjectDataManagement::VulnerabilityClass_def::SoldierInjuries ) { if (lastState.vulnerabilityState() == ProjectDataManagement::VulnerabilityState::CombatReady ) //Maybe there is some side effect to this like //if (data.stateHistory().size() == 1 && lastState.vulnerabilityState() == ProjectDataManagement::VulnerabilityState::CombatReady) { QPalette pal = QApplication::palette(m_ui->lbKind); m_ui->lblKind->setPalette(pal); // m_ui->lblVitality->setText(QString::number(100) + QStringLiteral("%")); fixed in PPM-Service } else { setSanitationLabelColor(/*m_dtc->proceduresDone(data.stateHistory())*/data.stateHistory().at(data.stateHistory().size()-1).sanitationResult()); } } } else { QPalette pal = QApplication::palette(m_ui->lbKind); m_ui->lblStatus->setText(QStringLiteral("-")); m_ui->lblVitality->setText(QStringLiteral("-")); m_ui->lblKind->setText(QStringLiteral("-")); m_ui->lblKind->setPalette(pal); } m_ui->lbContamination->setHidden(contaminationListIsEmpty); m_ui->lblContamination->setHidden(contaminationListIsEmpty); DEBUG_LOG(m_logger)<< "setBackgroundColor ="<< data.manipulation().size(); setBackgroundColor(m_ui->lblEquipNr, Qt::red, data.manipulation().size()); // Special Sensor State if (!data.specialSensorDataState()) { m_ui->stackSpecialSensor->hide(); m_ui->lbSpecialSensorState->hide(); } else { if (m_typeClass == TypeClass_def::Aircraft) { /* CTC_Apache_Sensor_DiffCorrections = 0x01, // Has GPS Differential Corrections CTC_Apache_Sensor_RadarJammer = 0x02, // APR 39 CTC_Apache_Sensor_IRJammer = 0x04, // ALQ 144 CTC_Apache_Sensor_RadarDetector = 0x08, // ALQ 136 CTC_Apache_Sensor_LaserSensor = 0x10 // AVR2A */ m_ui->stackSpecialSensor->setCurrentWidget(m_ui->stackPageAircraft); m_ui->ledRadarJammer->setStatus(data.specialSensorDataState() & 0x02); m_ui->ledIrJammer->setStatus(data.specialSensorDataState() & 0x04); m_ui->ledRadarDetector->setStatus(data.specialSensorDataState() & 0x08); m_ui->ledLaserSensor->setStatus(data.specialSensorDataState() & 0x10); } else { m_ui->stackSpecialSensor->setCurrentWidget(m_ui->stackPageCommon); showSpecialSensorData(data.specialSensorDataState()); } m_ui->lbSpecialSensorState->show(); m_ui->stackSpecialSensor->show(); } // Gear Tabelle für Steilfeuer allgemein verstecken //[GUEZE-2871] bool showForArtillery = true; /* #ifndef LTS_DEBUG const Participant participantData = m_dtc->participant(m_participant.id()); const Type type = m_dtc->type(participantData.typeId()); const QString jsData = QString::fromStdString(type.properties()).trimmed(); DEBUG_LOG(m_logger)<<">>> >>> properties: "<twGear->clearContents(); m_ui->twGear->clearSpans(); m_ui->twGear->hide(); m_ui->pbGearRanges->hide(); if (m_ltdGearComponent) m_ltdGearComponent->clear(); } else if (data.gear() != m_gearList) { m_gearList = data.gear(); std::vector tmpGearList = m_gearList; std::sort(tmpGearList.begin(), tmpGearList.end(), &compareGear); //sort m_ui->twGear->show(); m_ui->pbGearRanges->show(); m_ui->twGear->clearSpans(); m_ui->twGear->clearContents(); int row = 0; int rowCount = tmpGearList.size(); m_ui->twGear->setRowCount(rowCount); m_ui->twGear->setSortingEnabled(false); constexpr int unknownTasId = 0x80000000; for (const GearInformation &gearInfo : tmpGearList) { QTableWidgetItem *item = nullptr; if (gearInfo.chargeTypeId() == 0) //chargTypeId 0 is near miss code { rowCount--; continue; } const int gearTypeId = gearInfo.gearTypeId(); if ((gearTypeId & unknownTasId) == unknownTasId) item = new QTableWidgetItem(tr("Unknown gear id %1").arg(gearTypeId & ~unknownTasId)); else if (gearTypeId == 0) { // Hack for old systems which neither send gearTasCode/gearType nor gearSerialNumber/gearId // 1 = Wanne, 2 = Turm switch (gearInfo.gearId()) { case 1: item = new QTableWidgetItem(tr("Tank", "Gear Type")); break; case 2: item = new QTableWidgetItem(tr("Turret", "Gear Type")); break; default: item = new QTableWidgetItem(tr("N/A", "Gear Type")); break; } } else item = new QTableWidgetItem(m_pdmDtc->trGearTypeName(gearTypeId)); item->setData(Qt::UserRole, gearInfo.gearId()); if(m_pdmDtc->canRestock(gearInfo.gearTypeId())) { item->setIcon(QIcon(QLatin1String("icon:service.svg"))); } // If it's the same gearId, don't set the item, but make a row span to the one(s) before. int rowStart = row - 1; while (rowStart >= 0) { QTableWidgetItem *oldItem = m_ui->twGear->item(rowStart, 0); //Item above if (oldItem == nullptr)// not set due to rowSpan... break; if (oldItem->data(Qt::UserRole).toInt() != gearInfo.gearId() || // Different gearId oldItem->text() != item->text()) // Different Text (if gearId not set...) break; --rowStart; } if (rowStart + 1 < row) { m_ui->twGear->setItem(row, 0, item); //Need to be set, because of the check above m_ui->twGear->setSpan(rowStart + 1, 0, row - rowStart, 1); } else m_ui->twGear->setItem(row, 0, item); if (gearInfo.chargeTypeId() != 0 && gearInfo.chargeTypeId() != -1) // hat Charge (and ignore only chargecounts) { int chargeTypeId = gearInfo.chargeTypeId(); if ((chargeTypeId & unknownTasId) == unknownTasId) item = new QTableWidgetItem(tr("Unknown charge id %1").arg(chargeTypeId & ~unknownTasId)); else if (chargeTypeId == 0) item = new QTableWidgetItem(tr("N/A", "Charge Type")); else { item = new QTableWidgetItem(m_pdmDtc->trChargeTypeShortName(chargeTypeId, true)); item->setToolTip(m_pdmDtc->trChargeTypeName(chargeTypeId, true)); } m_ui->twGear->setItem(row, 1, item); //ressourceCount //: Blank in this case refers to blank ammunition used for training // Chris didn't wanted the chargeCounting Flag like: If they don't make it right why should we do it? // presevred old mode so just in case.. //UAE wepaons don't send needed telegrams.. so let's hack again.. // in order to avoid the faulty SALTs let's hope they never send remaining ammunition below 100... #ifdef GUEZ_MODE item = new QTableWidgetItem((gearInfo.remain() < 0) ? tr("N/A", "Blank Ammunition") : QString::number(gearInfo.remain())); #else if ( PROJECTBUILD == "ahtc") { if ((gearInfo.chargeTypeId() > 54 && gearInfo.chargeTypeId() < 58) || gearInfo.remain() < 0 || gearInfo.remain() > 1000) item = new QTableWidgetItem(tr("N/A", "Blank Ammunition")); else item = new QTableWidgetItem( QString::number(gearInfo.remain())); }else { item = new QTableWidgetItem((gearInfo.remain() < 0) ? tr("N/A", "Blank Ammunition") : QString::number(gearInfo.remain())); } #endif m_ui->twGear->setItem(row, 2, item); } if (gearInfo.gearTypeId() == ParticipantInfoLtdGearComponent::LTD_ID && m_ltdGearComponent) m_ltdGearComponent->addGear(gearInfo.gearId(), row); row++; } m_ui->twGear->setRowCount(rowCount); m_ui->twGear->resizeColumnsToContents(); // Avoid shrinking last column (2): It'll auto-stretch afterwards m_ui->twGear->horizontalHeader()->resizeSection(2, 42); m_ui->twGear->setColumnHidden(0, m_isTarget); m_ui->twGear->setColumnHidden(1, m_isTarget); } //end Gear if (!showForArtillery) { m_ui->twGear->hide(); } DEBUG_LOG(m_logger) << "### m_sanMatStock: " << m_sanMatStock.size(); DEBUG_LOG(m_logger) << "### data.sanitationMaterialStock(): " << data.sanitationMaterialStock().size(); DEBUG_LOG(m_logger) << "### data.participantId(): " << data.participantId(); DEBUG_LOG(m_logger) << "### data.sampleTime(): " << data.sampleTime(); //sanMat if (data.sanitationMaterialStock().size() == 0) { m_sanMatStock.clear(); m_ui->twSanMat->clearContents(); m_ui->gbSanitation->hide(); } else if (data.sanitationMaterialStock() != m_sanMatStock) { DEBUG_LOG(m_logger) << "### data.qualification(): " << data.qualification(); DEBUG_LOG(m_logger) << "### data.sanitationUniqueId(): " << data.sanitationUniqueId(); m_ui->gbSanitation->show(); m_ui->lblSanAssignState->setText(ParticipantManagement::toString(data.qualification().underlying())); m_ui->lblSanUniqueID->setText(QString::number(data.sanitationUniqueId(),16)); m_ui->lblSanOriginatorEquipNo->setText(QString::number(data.sanitationOriginatorEquipNo())); m_sanMatStock = data.sanitationMaterialStock(); std::vector tmpSanMatStock = m_sanMatStock; std::sort(tmpSanMatStock.begin(), tmpSanMatStock.end(), &compareSanMat); //sort m_ui->twSanMat->clearContents(); int row = 0; m_ui->twSanMat->setRowCount(tmpSanMatStock.size()); m_ui->twSanMat->setColumnCount(2); m_ui->twSanMat->setSortingEnabled(false); for (const SanitationMaterial &sanMat : tmpSanMatStock) { QTableWidgetItem *item = new QTableWidgetItem(QString::number(sanMat.materialCount())); m_ui->twSanMat->setItem(row, 0, item); item = new QTableWidgetItem(ProjectDataManagement::trSanitationMaterialName(m_pdmDtc->sanitationMaterial(sanMat.materialId()).name())); m_ui->twSanMat->setItem(row, 1, item); row++; } m_ui->twSanMat->resizeColumnsToContents(); m_ui->twSanMat->horizontalHeader()->setStretchLastSection(true); m_ui->twSanMat->horizontalHeader()->resizeSection(1, 42); } m_ui->tbNbc->setVisible(data.hasNbcProtectionConfigured() && data.hasNbcProtectionActive()); if(data.sanitationMaterialStock().size() > 0 || (data.gear().size() > 0 && showForArtillery)) setBottomSpacerVisibility(true); else setBottomSpacerVisibility(false); updateIcon(m_participant); if (m_ltdGearComponent) m_ltdGearComponent->updateData(data.designations()); } void ParticipantInfoDialog::showSpecialSensorData(int specialSensorData) { const int specialSensorDataState = specialSensorData & 0xFF; QString strSpecialSensorData; switch (specialSensorDataState) { case SpecialSensorStatus_def::ChemicalDetectionFunction_NotOperational: strSpecialSensorData = toString(SpecialSensorStatus_def::ChemicalDetectionFunction_NotOperational); break; case SpecialSensorStatus_def::ChemicalDetectionFunction_Detecting: strSpecialSensorData = toString(SpecialSensorStatus_def::ChemicalDetectionFunction_Detecting); break; case SpecialSensorStatus_def::NBCDetectionAccessory_NotOperational: strSpecialSensorData = toString(SpecialSensorStatus_def::NBCDetectionAccessory_NotOperational); break; case SpecialSensorStatus_def::NBCDetectionAccessory_Test: strSpecialSensorData = toString(SpecialSensorStatus_def::NBCDetectionAccessory_Test); break; case SpecialSensorStatus_def::NBCDetectionAccessory_DetectingAir: strSpecialSensorData = toString(SpecialSensorStatus_def::NBCDetectionAccessory_DetectingAir); break; case SpecialSensorStatus_def::AVLB_Mounted: strSpecialSensorData = toString(SpecialSensorStatus_def::AVLB_Mounted); break; case SpecialSensorStatus_def::AVLB_Deployed: strSpecialSensorData = toString(SpecialSensorStatus_def::AVLB_Deployed); break; case SpecialSensorStatus_def::AVLB_Mounting: strSpecialSensorData = toString(SpecialSensorStatus_def::AVLB_Mounting); break; case SpecialSensorStatus_def::AVLB_Deploying: strSpecialSensorData = toString(SpecialSensorStatus_def::AVLB_Deploying); break; case SpecialSensorStatus_def::MineLayer_Operational: strSpecialSensorData = toString(SpecialSensorStatus_def::MineLayer_Operational); break; case SpecialSensorStatus_def::MineLayer_Laying: strSpecialSensorData = toString(SpecialSensorStatus_def::MineLayer_Laying); break; case SpecialSensorStatus_def::MineClearingFunction_March: strSpecialSensorData = toString(SpecialSensorStatus_def::MineClearingFunction_March); break; case SpecialSensorStatus_def::MineClearingFunction_ReadyToClear: strSpecialSensorData = toString(SpecialSensorStatus_def::MineClearingFunction_ReadyToClear); break; case SpecialSensorStatus_def::MineClearingFunction_Clearing: strSpecialSensorData = toString(SpecialSensorStatus_def::MineClearingFunction_Clearing); break; case SpecialSensorStatus_def::MineTrowingFunction_NotOperational: strSpecialSensorData = toString(SpecialSensorStatus_def::MineTrowingFunction_NotOperational); break; case SpecialSensorStatus_def::MineTrowingFunction_ParameterInput: strSpecialSensorData = toString(SpecialSensorStatus_def::MineTrowingFunction_ParameterInput); break; case SpecialSensorStatus_def::MineTrowingFunction_ReadyToDeploy: strSpecialSensorData = toString(SpecialSensorStatus_def::MineTrowingFunction_ReadyToDeploy); break; case SpecialSensorStatus_def::MineTrowingFunction_Deploying: strSpecialSensorData = toString(SpecialSensorStatus_def::MineTrowingFunction_Deploying); break; case SpecialSensorStatus_def::MineTrowingFunction_Resupply: strSpecialSensorData = toString(SpecialSensorStatus_def::MineTrowingFunction_Resupply); break; case SpecialSensorStatus_def::MineTrowingFunction_FinishDeploying: strSpecialSensorData = toString(SpecialSensorStatus_def::MineTrowingFunction_FinishDeploying); break; case SpecialSensorStatus_def::ADLER_Operational: strSpecialSensorData = toString(SpecialSensorStatus_def::ADLER_Operational); break; case SpecialSensorStatus_def::ADLER_ConditionallyOperational: strSpecialSensorData = toString(SpecialSensorStatus_def::ADLER_ConditionallyOperational); break; case SpecialSensorStatus_def::ADLER_NotOperational: strSpecialSensorData = toString(SpecialSensorStatus_def::ADLER_NotOperational); break; default: strSpecialSensorData = tr("Unknown (%1)").arg(specialSensorDataState); break; } if ((specialSensorData & (1 << 8)) != 0) strSpecialSensorData += QStringLiteral(" L"); if ((specialSensorData & (1 << 9)) != 0) strSpecialSensorData += QStringLiteral(" R"); if ((specialSensorData & (1 << 10)) != 0) strSpecialSensorData += QStringLiteral(" P"); if ((specialSensorData & (1 << 11)) != 0) strSpecialSensorData += QStringLiteral(" F"); if (specialSensorDataState == 66) // CSF Spürbetrieb { const int type = (specialSensorData >> 12) & 0x0F; strSpecialSensorData += QLatin1Char(' '); switch (type) { case 1: case 2: strSpecialSensorData += tr("FIR"); break; case 3: strSpecialSensorData += tr("ZABC"); break; case 4: strSpecialSensorData += tr("CSF"); break; case 5: strSpecialSensorData += tr("PzBr"); break; case 6: strSpecialSensorData += tr("MV"); break; case 7: strSpecialSensorData += tr("MRF"); break; case 8: strSpecialSensorData += tr("WMV"); break; case 0: default: break; } if (type == 4) // CSF { const int nbcType = (specialSensorData >> 16) & 0x03; strSpecialSensorData += QLatin1Char(' '); switch (nbcType) { case 0: strSpecialSensorData += tr("No C-Agent"); break; case 1: strSpecialSensorData += tr("Sarin"); break; case 2: strSpecialSensorData += tr("VX"); break; case 3: strSpecialSensorData += tr("S-Lost"); break; } } } m_ui->lblSpecialSensorState->setText(strSpecialSensorData); } void ParticipantInfoDialog::onPositionChanged(const ParticipantPosition &position) { bool isOpsBuildingSource = false; if (position.participantId() != m_participant.id() && position.participantId() != 0) return; if ( position.reportingSource() == Core::PositionReportingSource::OpsBuilding ) isOpsBuildingSource = true; DEBUG_LOG(m_logger) << "reportingSource = OpsBuilding true" ; setBackgroundColor(m_ui->lblPositionData, Qt::lightGray, isOpsBuildingSource ); onUpdatePosition(position.participantId(), position.pos(), position.sampleTime()); if (m_ismDtc && m_roomId != position.roomId()) { if (position.roomId() > 0) { const auto mse = m_ismDtc->mainStructureElement(position.buildingId()); QString roomName; for (const auto &room : mse.elements()) { if (room.id() == position.roomId()) { // In the case of external OPS transmitters, the building name was output twice if ( room.structureElementTypeId() != InfrastructureManagement::StructureElementType_def::Room ) continue; roomName = QString::fromStdString(room.displayName()); break; } } QString buildingName = m_ismDtc->getBuildingDisplayName(mse); m_ui->lblInBuildingInfo->setText(buildingName + QLatin1Char(' ') + roomName); } m_ui->lblInBuildingInfo->setVisible(position.roomId() > 0); m_roomId = position.roomId(); } if (position.mountedOn().is_set()) { const auto mountedOnParticipant = m_dtc->participant(position.mountedOn().get()); if (mountedOnParticipant.equipmentNumber().is_set()) m_ui->pbMounted->setText(QString::number(mountedOnParticipant.equipmentNumber().get())); else m_ui->pbMounted->setText(QString(QLatin1Char('0'))); m_ui->pbMounted->show(); disconnect(m_ui->pbMounted, nullptr, nullptr, nullptr); connect(m_ui->pbMounted, &QToolButton::clicked, this, &ParticipantInfoDialog::onParticipantMountedOn); } if (position.mountedParticipants().is_set()) { m_ui->pbMounted->setText(QString::number(position.mountedParticipants().get().size())); m_ui->pbMounted->show(); disconnect(m_ui->pbMounted, nullptr, nullptr, nullptr); connect(m_ui->pbMounted, &QToolButton::clicked, this, &ParticipantInfoDialog::onMountedParticipants); } // hide button when both are not set if (!position.mountedOn().is_set() && !position.mountedParticipants().is_set()) m_ui->pbMounted->hide(); } void ParticipantInfoDialog::onUnitPositionChanged(const UnitPosition &position) { if (position.participantId() != m_participant.id() && position.participantId() != 0) return; const bool bCenter = m_symbolAppearanceSettings && (m_symbolAppearanceSettings->settings().symbolSettings.unitSymbolPosition == FilterManagement::SymbolAppearanceSettings::UnitSymbolPosition::Center); onUpdatePosition(position.participantId(), bCenter ? position.positionCenter() : position.positionLeader(), bCenter ? position.sampleTimeCenter() : position.sampleTimeLeader()); m_ui->lblInBuildingInfo->hide(); m_ui->pbMounted->hide(); } void ParticipantInfoDialog::onUpdatePosition(int participantId, const Core::GeoPosition &position, qint64 sampleTime) { m_lastPositionMSec = sampleTime; if (participantId == 0 || std::isnan(position.lon()) || std::isnan(position.lat())) { m_ui->lblPositionData->setText(tr("Invalid Position")); m_ui->pbMovementTrack->hide(); m_ui->pbFindOnMap->hide(); } else { QString mgrs = LtsCoordTrans::mgrsFromGeographic(position.lon(), position.lat()); if (!qFuzzyIsNull(position.z())) mgrs += QStringLiteral(" | ") + QString::number(position.z(), 'f', 2); m_ui->lblPositionData->setText(mgrs); m_ui->pbMovementTrack->show(); m_ui->pbFindOnMap->show(); } LtsDialog::setMinWidthForWidgetHelper(m_ui->lblPositionData); } void ParticipantInfoDialog::onParticipantChanged(const Participant &participant, DataModification modType) { if (participant.id() != m_participant.id()) return; // Do not continue on modType == DataModification::eRemove // otherwise for example the icon would look bad (clover with black on black...) if (modType == DataModification::eRemoved) return; if (m_participant.typeId() != participant.typeId()) { m_ui->lblType->setText(ParticipantManagement::trTypeName(m_dtc->type(participant.typeId()).name())); TypeClass typeClass = m_dtc->type(participant.typeId()).typeClass(); // If TypeClass changes, close window. Shouldn't ever happen, but for initialization. if (m_typeClass != TypeClass_def::Unknown && m_typeClass != typeClass) { m_buttonBox->getButton(LtsWidgets::DialogButton::Close)->click(); } m_typeClass = typeClass; } if (m_participant.partyId() != participant.partyId()) m_ui->lblParty->setText(ParticipantManagement::trPartyName(m_dtc->party(participant.partyId()).name())); m_participant = participant; m_ui->lblHierarchy->setText(m_dtc->hierarchyFromParticipant(m_participant.id())); m_ui->lblDesignator->setText(QString::fromStdString(m_participant.designator())); m_ui->lblTactitcalIdentifier->setText(QString::fromStdString(m_participant.tacticalIdentifier())); if (participant.equipmentNumber().is_set()) m_ui->lblEquipNr->setText(QString::number(m_participant.equipmentNumber().get())); else m_ui->lblEquipNr->setText(QLatin1String("-")); #ifdef LTS_DEBUG m_ui->lblEquipNr->setToolTip(QString::number(m_participant.id())); #endif //hide Info if not exists m_ui->lblInfoText->setText(QString::fromStdString(m_participant.info())); m_ui->lblInfoText->setVisible(m_participant.info().size() > 0); m_ui->lblInfo->setVisible(m_participant.info().size() > 0); onDynamicParticipantDataChanged(m_dtc->dynamicParticipantData(m_participant.id())); } void ParticipantInfoDialog::onTypeChanged(const Type &type, DataModification) { if (m_participant.typeId() != type.id()) return; m_ui->lblType->setText(ParticipantManagement::trTypeName(type.name())); } void ParticipantInfoDialog::updateCurrentIcon() { if (m_participant.id() == 0) return; updateIcon(m_participant); } void ParticipantInfoDialog::updateIcon(const Participant &participant) { m_symbolWatcher->setSymbolResult(m_asbiIfc->findImage(participant)); } void ParticipantInfoDialog::updateIcon(const QColor &color, const QString &sidc) { AdvancedSymbology::SymbolDataToRender symDataToRender(sidc); symDataToRender.injury = AdvancedSymbology::Injury::NoInjury; symDataToRender.injuryColor = QColor(); symDataToRender.fillColor = color; symDataToRender.fillColorReplace = true; m_symbolWatcher->setSymbolResult(m_asbiIfc->findImage(symDataToRender)); } void ParticipantInfoDialog::setSanitationLabelColor(SanitationResult proceduresDone) { QPalette pal = QApplication::palette(m_ui->lbKind); QString toolTip; switch (proceduresDone.underlying()) { case SanitationResult::NoEffect: return; case SanitationResult::Insufficient: pal.setColor(QPalette::Window, Qt::red); toolTip = tr("Insufficient Care"); break; case SanitationResult::Sufficient: pal.setColor(QPalette::Window, Qt::yellow); toolTip = tr("Sufficient Care"); break; case SanitationResult::Optimal: pal.setColor(QPalette::Window, Qt::green); toolTip = tr("Optimal Care"); break; case SanitationResult::Unhandled: pal.setColor(QPalette::Window, QColor::fromRgb(179, 0, 0)); toolTip = tr("No Care"); break; case SanitationResult::deprecatedNA: break; } DEBUG_LOG(m_logger) << "Set Color to: " << proceduresDone.underlying(); m_ui->lblKind->setPalette(pal); m_ui->lblKind->setAutoFillBackground(true); m_ui->lblKind->setToolTip(toolTip); } void ParticipantInfoDialog::setKindVisible(bool bVisible) { // const bool showVulnerabilityKindProject = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"), // QStringLiteral("ShowVulnerabilityKind")); if (!m_showVulnerabilityKindProject) bVisible = false; m_ui->lblKind->setVisible(bVisible); m_ui->lbKind->setVisible(bVisible); } /*! * \brief ParticipantInfoDialog::setBottomSpacerVisibility * \param isOneListActive * \details If Weapon Table or/and SanMat table is visible -> Hide Bottom Spacer * \author Niklas Schmidt */ void ParticipantInfoDialog::setBottomSpacerVisibility(bool isOneListActive) { if(isOneListActive == true) { m_ui->vsBottom->changeSize(0,0, QSizePolicy::Maximum, QSizePolicy::Maximum); m_ui->vsBottom->invalidate(); }else { m_ui->vsBottom->changeSize(0,0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); m_ui->vsBottom->invalidate(); } } void ParticipantInfoDialog::setStatusVisible(bool bVisible) { m_ui->lblStatus->setVisible(bVisible); m_ui->lbStatus->setVisible(bVisible); m_ui->pbSetStatus->setVisible(bVisible); } void ParticipantInfoDialog::setHistoryVisible(bool bVisible) { m_ui->pbHistory->setVisible(bVisible); } void ParticipantInfoDialog::setEquipNrVisible(bool bVisible) { m_ui->lblEquipNr->setVisible(bVisible); m_ui->lbEquipNr->setVisible(bVisible); } void ParticipantInfoDialog::setBiteVisible(bool bVisible) { m_ui->pbBite->setVisible(bVisible); } void ParticipantInfoDialog::setMessageVisible(bool bVisible) { m_ui->pbMessage->setVisible(bVisible); } void ParticipantInfoDialog::onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part) { if (part != FilterManagement::SymbolAppearanceSettings::Part::Symbol) return; if (m_typeClass != TypeClass::Unit && m_typeClass != TypeClass::SupportUnit) return; onUnitPositionChanged(m_dtc->unitPosition(m_participant.id())); } void ParticipantInfoDialog::setBackgroundColor(QWidget *w, Qt::GlobalColor color, bool bSetColor) { if (!w) return; if (bSetColor) { QPalette pal = QApplication::palette(w); pal.setColor(QPalette::Window, color); w->setPalette(pal); w->setAutoFillBackground(true); } else { // reset to default palette w->setPalette(QApplication::palette(w)); w->setAutoFillBackground(false); } } void ParticipantInfoDialog::onOpenSetStatusDialog() { ParticipantConfigDialog *diag = new ParticipantConfigDialog(m_participant.id(), ParticipantConfigDialog::DialogType::Config, this); if (diag->init(m_session, m_dtc, m_ftc)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantConfig") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onOpenSetInjuryDialog() { ParticipantSetInjuryDialog *diag = new ParticipantSetInjuryDialog(m_participant.id(), this); if (diag->init(m_session, m_dtc, m_ftc, m_pdmDtc)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantSetInjury") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onOpenSetSanitationDialog() { ParticipantSetSanitationDialog *diag = new ParticipantSetSanitationDialog(m_participant.id(), this); if (diag->init(m_session, m_dtc, m_ftc, m_pdmDtc)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantSetSanitationDialog") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onOpenHistory() { if (!m_aesDtc) return; // { // ParticipantTargetConfigurationDialog* diag = new ParticipantTargetConfigurationDialog(this); // if (diag->init(m_participant.id(), m_dtc, m_ftc, /*m_pdmDtc,*/ m_sitMapGuiIfc)) // addDialog(diag, m_menuGroup, QStringLiteral("ParticipantHistory") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eDialogTab); // else // delete diag; // } // return; ParticipantHistoryDialog *diag = new ParticipantHistoryDialog(this); if (diag->init(m_participant.id(), m_dtc, m_pdmDtc, m_aesDtc)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantHistory") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onOpenBite() { const bool bWithSelfTest = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier); ParticipantBiteDialog *diag = new ParticipantBiteDialog(m_participant.id(), this); if (diag->init(m_dtc, m_ftc, m_pdmDtc, bWithSelfTest)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantBit") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eInfoTab); else delete diag; } void ParticipantInfoDialog::onOpenMessage() { ParticipantConfigDialog *diag = new ParticipantConfigDialog(m_participant.id(), ParticipantConfigDialog::DialogType::Message, this); if (diag->init(m_session, m_dtc, m_ftc)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantMessage") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onFindOnMap() { if (m_sitMapGuiIfc) m_sitMapGuiIfc->centerMapToParticipant(m_participant.id()); } void ParticipantInfoDialog::onMovementTrack() { if (m_sitMapGuiIfc) m_sitMapGuiIfc->enableMovementTrack(m_participant.id(), m_ui->pbMovementTrack->isChecked()); } void ParticipantInfoDialog::onParticipantMountedOn() { if (m_ppmGuiIfc) m_ppmGuiIfc->showParticipantInfoWindow(m_dtc->participant(m_dtc->participantPosition(m_participant.id()).mountedOn().get()).id()); } void ParticipantInfoDialog::onMountedParticipants() { ParticipantsMountedTableDialog *diag = new ParticipantsMountedTableDialog(m_participant.id(), this); if (diag->init(m_dtc, m_ppmGuiIfc)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantsMounted") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onPartitionTimeChanged(qint64 newPartitionTime) { if (LtsUtils::isPositionTimeOutdated(newPartitionTime, m_lastPositionMSec) ) { DEBUG_LOG(m_logger)<< "setBackgroundColor ="<< LtsUtils::isPositionTimeOutdated(newPartitionTime, m_lastPositionMSec); setBackgroundColor(m_ui->lblPositionData, Qt::red, true); } qint64 lastPosSec = (newPartitionTime - m_lastPositionMSec) / 1000; QString ts; if (lastPosSec < 60) ts = tr("%1 seconds").arg(QString::number(lastPosSec, 'f', 0)); else if (lastPosSec < 60 * 60) ts = tr("%1 minutes").arg(QString::number(lastPosSec / 60, 'f', 0)); else if (lastPosSec < 24 * 60 * 60) ts = tr("%1 hours").arg(QString::number(lastPosSec / 3600, 'f', 0)); else ts = tr("%1 days").arg(QString::number(lastPosSec / 86400, 'f', 0)); QString updateString = tr("Last Position update: %1 ago").arg(ts); m_ui->lblPositionData->setToolTip(updateString); } void ParticipantInfoDialog::onGearRanges() { if (m_sitMapGuiIfc) m_sitMapGuiIfc->enableGearRanges(m_participant.id(), m_ui->pbGearRanges->isChecked()); } /////////////////////////////////////////////// /// Target /////////////////////////////////////////////// bool ParticipantInfoDialog::initTargetConfig(bool bShow) { if (bShow) { m_ui->pbMessage->hide(); m_ui->pbMovementTrack->hide(); m_ui->pbSetInjury->hide(); m_ui->pbSetSanitation->hide(); // Combobox Weapon: // TODO woher kommen die Waffen? m_ui->cbTargetWeapon->addItem(QStringLiteral("AK47"), 1); m_ui->cbTargetWeapon->addItem(QStringLiteral("Pistol"), 5); m_ui->cbTargetWeapon->addItem(QStringLiteral("Shotgun"), 7); // Combobox Mode: m_ui->cbTargetMode->addItem(TargetManagement::toString(TargetManagement::Mode_def::Deactivated), TargetManagement::Mode_def::Deactivated); m_ui->cbTargetMode->addItem(TargetManagement::toString(TargetManagement::Mode_def::ShootBack), TargetManagement::Mode_def::ShootBack); m_ui->cbTargetMode->addItem(TargetManagement::toString(TargetManagement::Mode_def::ShootFirst), TargetManagement::Mode_def::ShootFirst); m_ui->cbTargetMode->addItem(TargetManagement::toString(TargetManagement::Mode_def::NoWeapon), TargetManagement::Mode_def::NoWeapon); connect(m_ui->btTarget, &QToolButton::clicked, this, &ParticipantInfoDialog::onTargetConfig); connect(m_ui->cbTargetMode, QOverload::of(&QComboBox::currentIndexChanged), this, &ParticipantInfoDialog::onTargetModeChangeed); connect(m_ui->cbTargetWeapon, QOverload::of(&QComboBox::currentIndexChanged), this, &ParticipantInfoDialog::onTargetWeaponChanged); m_session->getDtc(m_tgtDtc); m_tgtDtc->enableTargetConfig(); m_session->getFtc(m_tgtFtc); if (m_tgtDtc) { connect(m_tgtDtc.get(), &TargetManagement::Interface::Dtc::targetConfigChanged, this, &ParticipantInfoDialog::onTargetConfigChanged); } } else { m_ui->lbTarget->setVisible(false); m_ui->btTarget->setVisible(false); } m_ui->pbTarget->setVisible(false); m_ui->lbTargetMode->setVisible(false); m_ui->lbTargetWeapon->setVisible(false); m_ui->cbTargetMode->setVisible(false); m_ui->cbTargetWeapon->setVisible(false); return true; } bool ParticipantInfoDialog::initTargetConfigL400(bool bShow) { m_ui->pbTarget->setVisible(bShow); if (bShow) { connect(m_ui->pbTarget, &QPushButton::clicked, this, &ParticipantInfoDialog::onOpenTargetConfigurationL400, Qt::UniqueConnection); } return true; } void ParticipantInfoDialog::onTargetConfig() { if (!m_tgtFtc) return; INFO_LOG(m_logger) << "onTargetConfig send TargetConfigRequest"; TargetManagement::ConfigureTargetRequest request; request.id(0); request.participantId(m_participant.id()); request.tgtCommand(TargetManagement::TgtCommand_def::RequestTechnicalState); auto cb = [request, this]() { return m_tgtFtc->configureTargetRequest(request, this); }; m_requestHelper->startSingleRequest(cb); } // end of onTargetConfig void ParticipantInfoDialog::onTargetConfigChanged(const TargetManagement::TargetConfig &data, DataModification modType) { if (modType == DataModification::eRemoved) return; INFO_LOG(m_logger) << "onTargetConfigChanged participantId = " << m_participant.id() << " data.participantId = " << data.participantId(); if (data.participantId() != m_participant.id()) return; m_ui->lbTargetMode->setVisible(true); m_ui->lbTargetWeapon->setVisible(true); m_ui->cbTargetMode->setVisible(true); m_ui->cbTargetWeapon->setVisible(true); m_ui->cbTargetMode->setCurrentIndex(m_ui->cbTargetMode->findData(data.mode().underlying())); m_ui->cbTargetWeapon->setCurrentIndex(m_ui->cbTargetWeapon->findData(data.weapon())); } // end of onTargetConfigChanged void ParticipantInfoDialog::onTargetModeChangeed() { if (!m_tgtFtc) return; INFO_LOG(m_logger) << "onTargetModeChangeed"; TargetManagement::ConfigureTargetRequest request; request.id(0); request.participantId(m_participant.id()); request.tgtCommand(TargetManagement::TgtCommand_def::SetMode); int modeInt = m_ui->cbTargetMode->currentData().toInt(); TargetManagement::Mode mode = static_cast (modeInt); INFO_LOG(m_logger) << "onTargetModeChangeed=" << mode; request.mode(mode); auto cb = [request, this]() { return m_tgtFtc->configureTargetRequest(request, this); }; m_requestHelper->startSingleRequest(cb); } void ParticipantInfoDialog::onTargetWeaponChanged() { if (!m_tgtFtc) return; TargetManagement::ConfigureTargetRequest request; request.id(0); request.participantId(m_participant.id()); request.tgtCommand(TargetManagement::TgtCommand_def::SetWeapon); request.weapon(m_ui->cbTargetWeapon->currentData().toInt()); INFO_LOG(m_logger) << "onTargetWeaponChangeed = " << request.weapon(); auto cb = [request, this]() { return m_tgtFtc->configureTargetRequest(request, this); }; m_requestHelper->startSingleRequest(cb); } void ParticipantInfoDialog::onOpenTargetConfigurationL400() { // ParticipantTargetConfigurationDialog -> L400 ParticipantTargetConfigurationDialog* diag = new ParticipantTargetConfigurationDialog(this); if (diag->init(m_participant.id(), m_dtc, m_ftc, m_sitMapGuiIfc)) addDialog(diag, m_menuGroup, QStringLiteral("TargetConfigurationL400") + QString::number(m_participant.id()), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onContextMenuRequested(const QPoint &position) { QTableWidgetItem* pointedItem = m_ui->twGear->itemAt(position); if (!pointedItem || pointedItem->column() != 0) return; GearInformation &gear = m_gearList[pointedItem->row()]; DEBUG_LOG(m_logger) << "gear type selected = " << gear.gearTypeId(); DEBUG_LOG(m_logger) << "gear Id = " << gear.gearId(); QList actions; if (m_pdmDtc->canRestock(gear.gearTypeId())) { QAction *restockNowAction = new QAction(tr("Restock Defaults"), this); connect(restockNowAction, &QAction::triggered, this, [=](){ onRestockNow(gear.gearId(), gear.gearTypeId()); }); actions << restockNowAction; } // if (m_pdmDtc->canSetDefaults(gear.gearTypeId())) // { // QAction *restockDefaultsAction = new QAction(tr("Restock Defaults"), this); // connect(restockDefaultsAction, &QAction::triggered, this, [=](){ onRestockDefaults(gear.gearId(), gear.gearTypeId()); }); // actions << restockDefaultsAction; // } if (actions.isEmpty()) return; QMenu menu(m_ui->twGear); menu.addActions(actions); menu.exec(m_ui->twGear->viewport()->mapToGlobal(position)); } void ParticipantInfoDialog::onRestockNow(int gearId,int gearTypeId) { ParticipantGearRestock *diag = new ParticipantGearRestock(gearId, gearTypeId, m_participant, ParticipantGearRestock::DialogMode::DM_Restock, this); if (diag->init(m_session)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantGearRestockNow") + QString::number(gearId), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onRestockDefaults(int gearId, int gearTypeId) { ParticipantGearRestock *diag = new ParticipantGearRestock(gearId, gearTypeId, m_participant, ParticipantGearRestock::DialogMode::DM_SetRestockDefaults, this); if (diag->init(m_session)) addDialog(diag, m_menuGroup, QStringLiteral("ParticipantGearRestockDefaults") + QString::number(gearId), LtsWidgets::LayoutArea::eDialogTab); else delete diag; } void ParticipantInfoDialog::onUasChanged(const UAS &uas) { // check if changed uas is this uas, on this participant, in this exercise if (uas.id() != m_uasId || uas.exerciseId() != m_session->exerciseId() || uas.participantId() != m_participant.id()) { return; } // set text & text color for uas operating mode const QString operatingMode(ProjectDataManagement::toString(uas.uasState())); static const QString textHtml { QStringLiteral("%2") }; switch (uas.uasState().underlying()) { case ProjectDataManagement::UasState::Auto: { m_ui->lblOperatingMode->setText(textHtml.arg(QStringLiteral("green")).arg(operatingMode)); break; } case ProjectDataManagement::UasState::Manual: { m_ui->lblOperatingMode->setText(textHtml.arg(QStringLiteral("orange")).arg(operatingMode)); break; } default: { m_ui->lblOperatingMode->setText(operatingMode); break; } } } void ParticipantInfoDialog::onUnlockUAS() { UAS uas = m_dtc->getUasByParticipantId(m_participant.id(), m_session->exerciseId()); m_uasId = uas.id(); DEBUG_LOG(m_logger)<<" -- onUnlockUAS uasId: "<< uas.id() <<" /// participantId: "<modifyUasStateRequest(req, this); }; m_requestHelper->startSingleRequest(cb); } } // namespace ParticipantManagement