398 lines
15 KiB
C++
Executable File
398 lines
15 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* AreaEffectSimulation - Contamination Edit Dialog
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Patric Karwat, SLSE, 2016-07-07
|
|
*/
|
|
|
|
|
|
#include "aes_bccontamination_edit.h"
|
|
#include "ui_aes_bccontamination_edit.h"
|
|
#include "../AesInfo/aes_danger_area_aes_item_info.h"
|
|
|
|
#include <LtsWidgets/lts_message_dialog.h>
|
|
#include <LtsSession/lts_session_data.h>
|
|
#include <PluginInterfaces/gui_plugin_interface.h>
|
|
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
|
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
|
#include <Plugins/AreaEffectSimulation/aes_info_gui_plugin_interface.h>
|
|
|
|
#include <AreaEffectSimulation/aes_translation.h>
|
|
#include <LtsUtilsSettings/settings.h>
|
|
#include <Services/AreaEffectSimulation/Utils/polygons.h>
|
|
|
|
|
|
namespace AreaEffectSimulation
|
|
{
|
|
double BCContaminationEdit::s_minRadius;
|
|
double BCContaminationEdit::s_maxRadius;
|
|
double BCContaminationEdit::s_stepRadius;
|
|
int BCContaminationEdit::s_minDurationHours;
|
|
int BCContaminationEdit::s_maxDurationHours;
|
|
double BCContaminationEdit::s_minAltitude;
|
|
double BCContaminationEdit::s_maxAltitude;
|
|
|
|
static int s_lastChargeTypeB = 0;
|
|
static int s_lastChargeTypeC = 0;
|
|
|
|
// Todo: Höhe und Radius in Abhängigkeit der Munitionsart berechnen
|
|
|
|
BCContaminationEdit::BCContaminationEdit(const QString &menuGroup, bool isChemical, QWidget *parent)
|
|
: BaseEdit(menuGroup, QLatin1String("BCContaminationEdit"), parent)
|
|
, m_isChemical(isChemical)
|
|
, m_ui(new Ui::BCContaminationEdit)
|
|
{
|
|
m_ui->setupUi(this);
|
|
|
|
s_minRadius = 50;
|
|
s_maxRadius = 2500;
|
|
s_stepRadius = 5;
|
|
s_minDurationHours = 1;
|
|
s_maxDurationHours = 4;
|
|
s_minAltitude = 2;
|
|
s_maxAltitude = 50;
|
|
|
|
m_ui->sbRadius->setMinimum(s_minRadius);
|
|
m_ui->sbRadius->setMaximum(s_maxRadius);
|
|
m_ui->sbRadius->setSingleStep(s_stepRadius);
|
|
m_ui->sbDurationHours->setMinimum(s_minDurationHours);
|
|
m_ui->sbDurationHours->setMaximum(s_maxDurationHours);
|
|
m_ui->sbAltitude->setMinimum(s_minAltitude);
|
|
m_ui->sbAltitude->setMaximum(s_maxAltitude);
|
|
|
|
m_uiRequirements->addRequirement({m_ui->lblPosition, [this]() { return (!m_ui->positionEdit->coordinate().isNull()); }});
|
|
m_uiRequirements->addRequirement({m_ui->lblIdentifier, [this]() { return (!m_ui->leIdentifier->text().isEmpty()); }});
|
|
m_uiRequirements->addRequirement({m_ui->lblEffectStart, [this]() { return hasValidEffectStart(m_ui->dteEffectStart); }});
|
|
m_uiRequirements->addRequirement({m_ui->lblChargeType, [this]() { return (m_ui->cbChargeType->currentData().toInt() > 0); }});
|
|
|
|
connect(m_ui->pbDangerArea, &QPushButton::clicked, this, &BCContaminationEdit::onPbDangerAreaClicked);
|
|
connect(m_ui->pbClear, &QPushButton::clicked, m_ui->positionEdit, &LtsCoordWidget::LtsCoordWidget::clear);
|
|
|
|
connect(m_ui->sbRadius, &QSpinBox::editingFinished, this, &BCContaminationEdit::correctSpinBoxValue);
|
|
|
|
// [GUEZE-2833] Inkonsistenz - Wetter Einstellungen bei A und C Feldern
|
|
// Order changed AwsDynamic = 0, AwsStatic = 1,
|
|
m_ui->cbWeather->addItem(toString(AesWeatherSource::AwsDynamic), AesWeatherSource::AwsDynamic);
|
|
m_ui->cbWeather->addItem(toString(AesWeatherSource::AwsStatic), AesWeatherSource::AwsStatic);
|
|
|
|
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
|
const bool enableShowMeteoDataStations = ps->value(QStringLiteral("mdm"),
|
|
QStringLiteral("enableShowMeteoDataStations")).toBool();
|
|
if (!enableShowMeteoDataStations)
|
|
{
|
|
m_ui->cbWeather->hide();
|
|
m_ui->lblWeather->hide();
|
|
// cbWeather per default auf AesWeatherSource::AwsStatic
|
|
}
|
|
m_ui->lblAltitude->show();
|
|
m_ui->sbAltitude->show();
|
|
// Not yet needed, as no step is defined:
|
|
// connect(m_ui->sbAltitude, &QSpinBox::editingFinished, this, &BCContaminationEdit::correctSpinBoxValue);
|
|
// connect(m_ui->sbDurationMinutes, &QSpinBox::editingFinished, this, &BCContaminationEdit::correctSpinBoxValue);
|
|
|
|
// party is (currently) not user-visible
|
|
// m_ui->lblParty->setVisible(false);
|
|
// m_ui->cbParty->setVisible(false);
|
|
|
|
enaDisa();
|
|
|
|
if (m_isChemical)
|
|
setOnlineHelpFilename(QStringLiteral("Situation-Add_C-Contamination"));
|
|
else
|
|
setOnlineHelpFilename(QStringLiteral("Situation-Add_B-Contamination"));
|
|
}
|
|
|
|
BCContaminationEdit::~BCContaminationEdit()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
void BCContaminationEdit::retranslate()
|
|
{
|
|
translate(m_ui, m_aesItem, m_isChemical ? tr("C-Contamination") : tr("B-Contamination"));
|
|
|
|
if (m_isChemical)
|
|
m_pdmGuiIfc->fillCComboBox(m_ui->cbChargeType);
|
|
else
|
|
m_pdmGuiIfc->fillBComboBox(m_ui->cbChargeType);
|
|
setCombobxToValueIfPossible(m_ui->cbChargeType, m_isChemical ? s_lastChargeTypeC : s_lastChargeTypeB);
|
|
}
|
|
|
|
void BCContaminationEdit::enableUiElements(bool enable)
|
|
{
|
|
m_ui->leIdentifier->setMaxLength(30);
|
|
m_ui->cbChargeType->setEnabled(enable);
|
|
m_ui->sbDurationHours->setEnabled(enable);
|
|
m_ui->cbParty->setEnabled(enable);
|
|
setEffectStartEnabled(m_ui->dteEffectStart, enable);
|
|
|
|
m_ui->pbPosition->setEnabled(m_sitMapGuiIfc && enable);
|
|
m_ui->positionEdit->setEnabled(enable);
|
|
m_ui->sbAltitude->setEnabled(enable);
|
|
m_ui->cbLowerLimit->setEnabled(enable);
|
|
m_ui->sbRadius->setEnabled(enable);
|
|
m_ui->leIdentifier->setEnabled(enable || isOnlyNameModifiable());
|
|
|
|
m_ui->cbWeather->setEnabled(enable);
|
|
m_ui->pbClear->setEnabled(enable);
|
|
if (m_aesItem.effectStateId() == AesEffectState_def::EsExpired)
|
|
{
|
|
m_ui->leIdentifier->setText(QString::fromStdString(m_aesItem.name()));
|
|
__unchange__();
|
|
}
|
|
if (m_aesItem.effectStateId() == AesEffectState_def::EsActivated)
|
|
{
|
|
QString name = m_ui->leIdentifier->text();
|
|
auto baseData = m_dtc->bCContamination(m_aesItem.id());
|
|
setData(baseData, false);
|
|
__unchange__();
|
|
if (name != m_ui->leIdentifier->text())
|
|
m_ui->leIdentifier->setText(name);
|
|
}
|
|
|
|
}
|
|
|
|
bool BCContaminationEdit::init(int aesItemId, bool copy,
|
|
LtsSession::LtsSession *session)
|
|
{
|
|
if (!BaseEdit::init(aesItemId, session))
|
|
return false;
|
|
|
|
bool editable = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::CContaminationsEdit) && m_isChemical) ||
|
|
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::BContaminationsEdit) && !m_isChemical) ||
|
|
m_session->app() == LtsAppDescriptor::App::OC;
|
|
|
|
bool readable = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::CContaminationsShow) && m_isChemical) ||
|
|
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::BContaminationsShow) && !m_isChemical) ;
|
|
|
|
setPbDangerAreaText();
|
|
if (!readable && !editable)
|
|
return false;
|
|
|
|
// FIXME: in GUI plugin, nicht ausserhalb!
|
|
if (!m_session->getForeignGuiInterface<ProjectDataManagement::ForeignGuiInterface>(m_pdmGuiIfc))
|
|
return false;
|
|
|
|
m_ui->dteEffectStart->setMinimumTimeMSec(m_session->partitionTime());
|
|
m_ui->dteEffectStart->setRetrieveCurrentTimeCallback([this]() { return m_session->partitionTime(); });
|
|
|
|
if (m_sitMapGuiIfc)
|
|
connect(m_ui->pbPosition, &QPushButton::clicked, this, &BCContaminationEdit::getPosition);
|
|
else
|
|
m_ui->pbPosition->setEnabled(false);
|
|
|
|
if (m_isChemical)
|
|
m_pdmGuiIfc->fillCComboBox(m_ui->cbChargeType);
|
|
else
|
|
m_pdmGuiIfc->fillBComboBox(m_ui->cbChargeType);
|
|
|
|
m_ppmGuiCbxIfc->fillPartyComboBox(m_ui->cbParty);
|
|
|
|
if (aesItemId > 0)
|
|
{
|
|
auto baseData = m_dtc->bCContamination(aesItemId);
|
|
setData(baseData, copy);
|
|
}
|
|
|
|
auto cb = [this](const DangerAreaCorrelatedAesItem &item)
|
|
{
|
|
if (item.aesItemId() == m_aesItem.id())
|
|
m_dangerAreaIds << item.dangerAreaId();
|
|
};
|
|
m_dtc->dangerAreaCorrelatedAesItems(cb);
|
|
setPbDangerAreaText();
|
|
|
|
enableUiElements(editable && isModifiable() && !isOnlyNameModifiable());
|
|
|
|
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::dangerAreaCorrelatedAesItemChanged,
|
|
this, &BCContaminationEdit::onDangerAreaChanged);
|
|
|
|
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::bCContaminationChanged,
|
|
this, &BaseEdit::onAreaChanged);
|
|
|
|
|
|
|
|
auto cbDangerArea = [this](const DangerArea &data)
|
|
{
|
|
if (data.effectStateId() != AesEffectState::EsRemoved && data.associatedAesId() == m_aesItem.id())
|
|
m_associatedDangerId = data.id();
|
|
};
|
|
m_dtc->dangerAreas(cbDangerArea);
|
|
if (m_associatedDangerId)
|
|
{
|
|
m_ui->chbDangerArea->setChecked(true);
|
|
m_ui->chbDangerArea->setEnabled(false);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void BCContaminationEdit::setPbDangerAreaText()
|
|
{
|
|
QStringList sl;
|
|
sl.reserve(m_dangerAreaIds.size());
|
|
for (int idx : qAsConst(m_dangerAreaIds))
|
|
{
|
|
sl << QString::fromStdString(m_dtc->dangerArea(idx).name());
|
|
}
|
|
m_ui->pbDangerArea->setEnabled(sl.size());
|
|
m_ui->pbDangerArea->setText(sl.join(QStringLiteral(", ")));
|
|
}
|
|
|
|
void BCContaminationEdit::onDangerAreaChanged(const DangerAreaCorrelatedAesItem &data, DataModification modType)
|
|
{
|
|
if (data.aesItemId() != m_aesItem.id())
|
|
return;
|
|
|
|
if (modType == DataModification::eAdded)
|
|
m_dangerAreaIds += data.dangerAreaId();
|
|
|
|
if (modType == DataModification::eRemoved)
|
|
m_dangerAreaIds -= data.dangerAreaId();
|
|
// Note: Modification cannot happen as the key is unique for the combination.
|
|
|
|
setPbDangerAreaText();
|
|
}
|
|
|
|
void BCContaminationEdit::onPbDangerAreaClicked()
|
|
{
|
|
if (m_dangerAreaIds.isEmpty())
|
|
return;
|
|
|
|
std::shared_ptr<ForeignInfoGuiInterface> infoGuiInterface;
|
|
if (!m_session->getForeignGuiInterface<ForeignInfoGuiInterface>(infoGuiInterface))
|
|
return;
|
|
|
|
LtsWidgets::LtsDialog *dialog = infoGuiInterface->showDangerAreaAesItemInfo(m_dangerAreaIds, {m_aesItem.id()});
|
|
|
|
addDialog(dialog, m_menuGroup, tr("Danger Areas for %1 %2").arg(m_isChemical ? tr("C-Contamination") : tr("B-Contamination"), m_ui->leIdentifier->text()), LtsWidgets::LayoutArea::eInfoTab);
|
|
}
|
|
|
|
void BCContaminationEdit::setData(const BCContamination &contamination, bool copy)
|
|
{
|
|
m_aesItem = contamination;
|
|
if (copy)
|
|
{
|
|
m_aesItem.id(0);
|
|
m_aesItem.effectStateId(AreaEffectSimulation::AesEffectState_def::get_default());
|
|
}
|
|
m_ui->leIdentifier->setText(QString::fromStdString(contamination.name()));
|
|
m_ui->dteEffectStart->setMsecsSinceEpoch(contamination.effectStart().is_set() ? contamination.effectStart().get() : 0);
|
|
m_ui->cbChargeType->setCurrentIndex(m_ui->cbChargeType->findData(contamination.chargeStruct().chargeTypeId())); // not user-visible
|
|
m_ui->sbDurationHours->setValue(contamination.effectDuration() / 1000 / 60/ 60); // msecs -> mins -> hours
|
|
m_ui->sbRadius->setValue(contamination.impactRadius());
|
|
m_ui->cbParty->setCurrentIndex(m_ui->cbParty->findData(contamination.partyId().is_set() ? contamination.partyId().get() : 0));
|
|
m_ui->cbWeather->setCurrentIndex(contamination.weatherSource().underlying());
|
|
|
|
QPointF impactPosition(contamination.impactPosition().lon(), contamination.impactPosition().lat());
|
|
if (!impactPosition.isNull())
|
|
m_ui->positionEdit->setCoordinate(impactPosition);
|
|
|
|
m_ui->sbAltitude->setValue(contamination.upperOffset());
|
|
m_ui->cbLowerLimit->setChecked(qFuzzyIsNull(contamination.lowerOffset()));
|
|
|
|
}
|
|
|
|
void BCContaminationEdit::getPosition()
|
|
{
|
|
if (!has2DMap())
|
|
return;
|
|
|
|
m_sitMapGuiIfc->getCircle(this,
|
|
SLOT(onCircleData(QPointF, double)),
|
|
nullptr,
|
|
s_minRadius,
|
|
s_maxRadius,
|
|
m_ui->positionEdit->coordinate(),
|
|
m_ui->sbRadius->value()); //max
|
|
}
|
|
|
|
void BCContaminationEdit::onCircleData(const QPointF &position, double radius)
|
|
{
|
|
m_previewCircleCenter = position;
|
|
|
|
// SB corrects value acc. singleStep
|
|
m_ui->sbRadius->setValue(radius);
|
|
m_previewCircleRadius = m_ui->sbRadius->value();
|
|
|
|
m_ui->positionEdit->setCoordinate(position);
|
|
DEBUG_LOG(m_logger) << "Pos X: " << position.x() << " Y: " << position.y() << " R: " << radius;
|
|
|
|
showPreviewObject();
|
|
}
|
|
|
|
bool BCContaminationEdit::apply()
|
|
{
|
|
std::string name = m_ui->leIdentifier->text().toStdString();
|
|
qint64 effectStart = m_ui->dteEffectStart->msecsSinceEpoch();
|
|
int duration = m_ui->sbDurationHours->value() * 60 * 1000 * 60; //hours -> mins -> msecs
|
|
int chargeType = m_ui->cbChargeType->currentData().toInt();
|
|
if (m_isChemical)
|
|
s_lastChargeTypeC = chargeType;
|
|
else
|
|
s_lastChargeTypeB = chargeType;
|
|
int partyId = m_ui->cbParty->currentData().toInt();
|
|
int participantId = 0;
|
|
int radius = m_ui->sbRadius->value();
|
|
int weathersource = m_ui->cbWeather->currentData().toInt();
|
|
double extrusionHeight = m_ui->sbAltitude->value();
|
|
|
|
double lowerOffset = 0.0;
|
|
if (!m_ui->cbLowerLimit->isChecked())
|
|
lowerOffset = -1000.0;
|
|
|
|
QPointF p(m_ui->positionEdit->coordinate());
|
|
const Core::GeoPosition2D pos(p.x(), p.y());
|
|
|
|
|
|
const BCContaminationModifyRequest req(m_aesItem.id(),
|
|
name,
|
|
LtsUtils::toOptional(effectStart),
|
|
duration,
|
|
chargeType,
|
|
pos,
|
|
radius,
|
|
static_cast<AesWeatherSource::inner_enum>(weathersource),
|
|
LtsUtils::toOptional(partyId),
|
|
LtsUtils::toOptional(participantId),
|
|
dds::core::optional<double>(),
|
|
dds::core::optional<double>(),
|
|
dds::core::optional<Core::GeoPosition2D>(),
|
|
dds::core::optional<rti::core::int64>(),
|
|
dds::core::optional<rti::core::int64>(),
|
|
extrusionHeight,
|
|
lowerOffset,
|
|
m_ui->chbDangerArea->isChecked());
|
|
|
|
INFO_LOG(m_logger) << "apply "
|
|
<< " extrusionHeight=" << extrusionHeight
|
|
<< " req.upperOffset=" << req.upperOffset()
|
|
<< " lowerOf"
|
|
"fset=" << lowerOffset
|
|
<< " req.lowerOffset=" << req.lowerOffset();
|
|
|
|
m_requestHelper->addRequest([this,req]()
|
|
{
|
|
return m_ftc->bCContaminationModifyRequest(req, this);
|
|
});
|
|
bool ret= m_requestHelper->startRequests();
|
|
if (m_ui->chbDangerArea->isChecked() && ret)
|
|
m_ui->chbDangerArea->setEnabled(false);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void BCContaminationEdit::showPreviewObject()
|
|
{
|
|
if (!m_sitMapGuiIfc)
|
|
return;
|
|
|
|
if (m_previewCircleCenter.isNull())
|
|
return;
|
|
|
|
m_sitMapGuiIfc->displayPreviewObject(this, m_previewCircleCenter, m_previewCircleRadius);
|
|
}
|
|
|
|
} // namespace AreaEffectSimulation
|