- Merged 292 changed files from dlbo snapshot - Fixed IDL enum collisions (PortType, PdmEventType) - Fixed Grantlee template for C++11 scoped enums - Fixed CMake VERSION_GREATER syntax - Added missing directories (THP, LtsRestClient, etc.) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1767 lines
63 KiB
C++
Executable File
1767 lines
63 KiB
C++
Executable File
/**
|
|
* @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 <ProjectDataManagement/pdm_to_string.h>
|
|
#include <ParticipantManagement/ppm_translation.h>
|
|
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
|
#include <AreaEffectSimulation/aes_data_plugin_interface.h>
|
|
#include <TargetManagement/tgt_data_plugin_interface.h>
|
|
#include <TargetManagement/tgt_translation.h>
|
|
|
|
#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 <LtsCoordTrans/lts_coord_trans.h>
|
|
#include <ngltools/ngltools_dtg.h>
|
|
#include <LtsSession/lts_session_data.h>
|
|
#include <LtsUtilsCore/outdated_position.h>
|
|
#include <LtsUtilsSettings/settings.h>
|
|
#include <LtsPluginManager/lts_plugin_loader.h>
|
|
|
|
#include <Services/AreaEffectSimulation/Utils/polygons.h>
|
|
#include <ParticipantManagement/participant_info_gui_element_interface.h>
|
|
|
|
#include <QJsonDocument>
|
|
#include <QTableWidgetItem>
|
|
#include <QToolButton>
|
|
#include <QTransform>
|
|
#include <QMenu>
|
|
#include <QColor>
|
|
#include <QLabel>
|
|
|
|
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<int32_t> 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<Interface::Dtc> &dtc,
|
|
const std::shared_ptr<Interface::Ftc> &ftc,
|
|
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc,
|
|
const std::shared_ptr<SituationMap::ForeignGuiInterface> &sitMapGuiIfc,
|
|
const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asbInterface,
|
|
const std::shared_ptr<ForeignParticipantInfoGuiInterface> &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<InfrastructureManagement::DataInterface>(m_ismDtc);
|
|
if (!m_session->getDtc<AreaEffectSimulation::DataInterface>(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=" <<participantData.id()
|
|
<< " typeId=" << participantData.typeId();
|
|
|
|
if (isUas)
|
|
{
|
|
connect(m_dtc.get(), &Interface::Dtc::uASChanged, this, &ParticipantInfoDialog::onUasChanged, Qt::UniqueConnection);
|
|
m_dtc->waitForHistoricalDataUAS(3000);
|
|
const UAS uas = m_dtc->getUasByParticipantId(participantData.id(), m_session->exerciseId());
|
|
m_uasId = uas.id();
|
|
|
|
if (!m_ftc->isModifyUasStateEnabled())
|
|
{
|
|
m_ftc->enableModifyUasState();
|
|
}
|
|
|
|
// participant might not even be linked to a uas (which isn't even obvious for the operator), so in that case default texts would be shown
|
|
m_ui->lblBatteryStatus->setText(QStringLiteral("-"));
|
|
m_ui->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<void(const QVector<int32_t> &activeSimIds)> onMovementTrackChangedFunc = [this, participantId](const QVector<int32_t> &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<FilterManagement::ForeignFltParticipantGuiInterface>(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.fileName;
|
|
GuiElementInterface *guiElement = qobject_cast<GuiElementInterface *>(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<ParticipantManagement::StateInformation> 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: "<<lastState.vitality() << "last kind: " <<lastState.vulnerabilityKindId();
|
|
m_ui->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<ProjectDataManagement::VulnerabilityState_def::type>(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<ProjectDataManagement::VulnerabilityState_def::type>(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<ProjectDataManagement::VulnerabilityState_def::type>(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: "<<jsData<<" /// typeId: "<<type.id();
|
|
if(!jsData.isEmpty())
|
|
{
|
|
const QJsonObject &typObj = QJsonDocument::fromJson(QByteArray::fromStdString(jsData.toStdString())).object();
|
|
if (!typObj.isEmpty() && typObj[QStringLiteral("isArtillery")].toBool(false))
|
|
{
|
|
showForArtillery = false;
|
|
}
|
|
}
|
|
#endif
|
|
*/
|
|
//Gear
|
|
if (data.gear().size() == 0 )
|
|
{
|
|
m_gearList.clear();
|
|
m_ui->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<GearInformation> 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<SanitationMaterial> 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<int>::of(&QComboBox::currentIndexChanged),
|
|
this, &ParticipantInfoDialog::onTargetModeChangeed);
|
|
connect(m_ui->cbTargetWeapon, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
this, &ParticipantInfoDialog::onTargetWeaponChanged);
|
|
m_session->getDtc<TargetManagement::DataInterface>(m_tgtDtc);
|
|
m_tgtDtc->enableTargetConfig();
|
|
m_session->getFtc<TargetManagement::DataInterface>(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 <TargetManagement::Mode_def::type>(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<QAction*> 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("<font color='%1'>%2</font>") };
|
|
|
|
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: "<<uas.participantId()<<" /// equipmentNumber: "<<m_participant.equipmentNumber();
|
|
|
|
if (uas.id() <= 0 )
|
|
{
|
|
ERROR_LOG(m_logger)<<" -- onUnlockUAS invalid uasId: "<<uas.id()<<" !!!";
|
|
return;
|
|
}
|
|
if (!m_participant.equipmentNumber().is_set())
|
|
{
|
|
ERROR_LOG(m_logger)<<" -- onUnlockUAS invalid EquipmentNumber for UAS: "<<uas.id()<<" !!!";
|
|
return;
|
|
}
|
|
ModifyUasStateRequest req;
|
|
req.uasId(uas.id());
|
|
req.uasState(ProjectDataManagement::UasState_def::Auto);
|
|
req.equipmentNumber(m_participant.equipmentNumber().get());
|
|
auto cb = [req, this]()
|
|
{
|
|
return m_ftc->modifyUasStateRequest(req, this);
|
|
};
|
|
m_requestHelper->startSingleRequest(cb);
|
|
}
|
|
|
|
} // namespace ParticipantManagement
|