Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,116 @@
|
||||
#
|
||||
# $Id: CMakeLists.txt 63121 2024-06-21 07:06:23Z karwat $
|
||||
# $HeadURL: svn://slssvn/TDS/branches/product/features/24_adler/Lts/Plugins/AreaEffectSimulation/Gui/Explosion/CMakeLists.txt $
|
||||
# $Author: karwat $
|
||||
# Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
#
|
||||
|
||||
#
|
||||
# LIBRARY for AesEffectClusterModel (which is used at AirSupportPlugin)
|
||||
#
|
||||
SET(AesEffectCluster_SRCS
|
||||
aes_effect_cluster_model.cpp
|
||||
aes_effect_cluster_model.h
|
||||
aes_effector.h
|
||||
aes_effector.cpp
|
||||
aes_effector.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS AesEffectClusterModel SHARED ${AesEffectCluster_SRCS})
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(AesEffectClusterModel
|
||||
PRIVATE
|
||||
AesBaseGui
|
||||
svcAesClient
|
||||
ngltools
|
||||
PUBLIC
|
||||
NGLLogger
|
||||
Qt5::Core
|
||||
)
|
||||
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(AesEffectClusterModel
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(AesEffectClusterModel)
|
||||
|
||||
|
||||
##
|
||||
##
|
||||
##
|
||||
ADD_INTERFACE_LIBRARY(
|
||||
AesExplosionGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/aes_explosion_gui_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
PdmDataPluginInterface
|
||||
)
|
||||
|
||||
SET(aes_explosion_gui_SRCS
|
||||
aes_explosion_gui_plugin.cpp
|
||||
aes_explosion_gui_plugin.h
|
||||
aes_explosion_edit.cpp
|
||||
aes_explosion_edit.h
|
||||
aes_explosions_edit.cpp
|
||||
aes_explosions_edit.h
|
||||
aes_explosions_edit_adler.cpp
|
||||
aes_explosions_edit_adler.h
|
||||
aes_explosions_edit_adler_standalone.cpp
|
||||
aes_explosions_edit_adler_standalone.h
|
||||
aes_explosion_list.cpp
|
||||
aes_explosion_list.h
|
||||
aes_explosions_area_model.cpp
|
||||
aes_explosions_area_model.h
|
||||
# aes_effect_cluster_model.cpp
|
||||
# aes_effect_cluster_model.h
|
||||
aes_explosions_single_model.cpp
|
||||
aes_explosions_single_model.h
|
||||
aes_effector.cpp
|
||||
aes_effector.h
|
||||
aes_rocket_utility.cpp
|
||||
aes_rocket_utility.h
|
||||
CustomView/aes_explosion.h
|
||||
CustomView/aes_explosion.cpp
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(aes_explosion_gui_SRCS
|
||||
aes_explosion_edit.ui
|
||||
aes_explosions_edit.ui
|
||||
aes_explosions_edit_adler.ui
|
||||
aes_explosions_edit_adler_standalone.ui
|
||||
aes_effector.ui
|
||||
CustomView/aes_explosion.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS AesExplosionGuiPlugin MODULE ${aes_explosion_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(AesExplosionGuiPlugin
|
||||
AesBaseGui
|
||||
ngltools
|
||||
NGLLogger
|
||||
LtsSessionData
|
||||
AesDataPluginInterface
|
||||
AesExplosionGuiPluginInterface
|
||||
AesEffectClusterModel
|
||||
PdmGuiPluginInterface
|
||||
PpmDataPluginInterface
|
||||
PpmParticipantSelectionGui
|
||||
SituationMapGuiPluginInterface
|
||||
|
||||
Qt5::Widgets
|
||||
LtsWidgets
|
||||
LtsDataView
|
||||
LtsUtilsGuiDds
|
||||
LtsUtilsCore
|
||||
LtsUtilsSettings
|
||||
|
||||
LtsElevation
|
||||
Trajectory
|
||||
LtsSessionData
|
||||
AsmDataPluginInterface
|
||||
ExmDataPluginInterface
|
||||
saaTelegrams
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(AesExplosionGuiPlugin)
|
||||
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for AES Explosion
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2016-04-08
|
||||
*/
|
||||
|
||||
#include "aes_explosion.h"
|
||||
#include "ui_aes_explosion.h"
|
||||
#include "aes_explosions_area_model.h"
|
||||
#include "aes_explosions_single_model.h"
|
||||
|
||||
#include <Services/AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
CustomViewExplosion::CustomViewExplosion(LtsSession::LtsSession *session, QWidget *parent)
|
||||
: AbstractDisplayWidget(parent)
|
||||
, m_session(session)
|
||||
, m_ui(new Ui::CustomViewExplosion)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
CustomViewExplosion::~CustomViewExplosion()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool CustomViewExplosion::init(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid())
|
||||
return false;
|
||||
|
||||
m_ui->lbName->setText(rowData(idx, AreaEffectSimulation::ExplosionsAreaModel::BcName).toString());
|
||||
m_ui->lbEffectState->setText(rowData(idx, AreaEffectSimulation::ExplosionsAreaModel::BcEffectState).toString());
|
||||
m_ui->lbEffectStart->setText(rowData(idx, AreaEffectSimulation::ExplosionsAreaModel::BcEffectStart).toString());
|
||||
m_ui->lbChargeType->setText(rowData(idx, AreaEffectSimulation::ExplosionsAreaModel::BcChargeType).toString());
|
||||
|
||||
QString durationString = rowData(idx, AreaEffectSimulation::ExplosionsAreaModel::BcEffectDuration).toString();
|
||||
if (!durationString.isEmpty() && durationString != QLatin1String("0"))
|
||||
{
|
||||
m_ui->lbEffectDuration->setText(durationString);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->label_4->hide();
|
||||
m_ui->lbEffectDuration->hide();
|
||||
}
|
||||
m_ui->lblIcon->clear();
|
||||
m_ui->lblIcon->setAutoFillBackground(true);
|
||||
|
||||
const AesItemSortFilterProxyModel *sfpm = qobject_cast<const AesItemSortFilterProxyModel*>(idx.model());
|
||||
if (!sfpm)
|
||||
return false;
|
||||
const auto srcIdx = sfpm->mapToSource(idx);
|
||||
const ExplosionsAreaModel *aesModelArea = qobject_cast<const ExplosionsAreaModel*>(sfpm->sourceModel());
|
||||
if (aesModelArea)
|
||||
{
|
||||
ExplosionArea ea = aesModelArea->getRowData(srcIdx.row());
|
||||
calculateIcon(ea, sfpm->partyColor(idx.row()));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const ExplosionsSingleModel *aesModelSingle = qobject_cast<const ExplosionsSingleModel*>(sfpm->sourceModel());
|
||||
if (aesModelSingle)
|
||||
{
|
||||
ExplosionSingle es = aesModelSingle->getRowData(srcIdx.row());
|
||||
calculateIcon(es, sfpm->partyColor(idx.row()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CustomViewExplosion::calculateIcon(const ExplosionArea &area, const QColor &color)
|
||||
{
|
||||
Database::AesExplosionArea ea;
|
||||
ea.impactPosition = QPointF(area.area().cornerBottomLeft().lon(),
|
||||
area.area().cornerBottomLeft().lat());
|
||||
ea.rotationAngle = area.area().rotation();
|
||||
ea.impactWidth = area.area().width();
|
||||
ea.impactLength = area.area().height(); // Todo: Correct?
|
||||
|
||||
QPolygonF poly = AreaEffectSimulation::Polygons::explosionArea(ea);
|
||||
Qt::BrushStyle bStyle = PixmapLabel::checkForBrushStyle(area.effectStateId());
|
||||
const auto pix = Polygons::pixmapFromPolygon(PixmapLabel::geographic2Utm(poly), color, ICON_RESOLUTION, bStyle);
|
||||
m_ui->lblIcon->setPixmap(pix);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CustomViewExplosion::calculateIcon(const ExplosionSingle &single, const QColor &color)
|
||||
{
|
||||
Database::AesExplosionSingle es;
|
||||
es.impactPosition = QPointF(single.impactPosition().lon(), single.impactPosition().lat());
|
||||
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> pdmDtc;
|
||||
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(pdmDtc))
|
||||
return false;
|
||||
|
||||
double radius = pdmDtc->impactRadius(single.chargeStruct().chargeTypeId(),
|
||||
single.chargeStruct().igniterTypeId(),
|
||||
single.chargeStruct().igniterFunctionId());
|
||||
QPolygonF poly = AreaEffectSimulation::Polygons::explosionSingle(es, radius);
|
||||
Qt::BrushStyle bStyle = PixmapLabel::checkForBrushStyle(single.effectStateId());
|
||||
const auto pix = Polygons::pixmapFromPolygon(PixmapLabel::geographic2Utm(poly), color, ICON_RESOLUTION, bStyle);
|
||||
m_ui->lblIcon->setPixmap(pix);
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for AES Explosion
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2016-04-08
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewer/LtsDataView/abstract_display_widget.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CustomViewExplosion;
|
||||
}
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
class ExplosionArea;
|
||||
class ExplosionSingle;
|
||||
class CustomViewExplosion final : public LtsDataView::AbstractDisplayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomViewExplosion(LtsSession::LtsSession *session, QWidget *parent = nullptr);
|
||||
~CustomViewExplosion();
|
||||
bool init(const QModelIndex &idx) override final;
|
||||
|
||||
private:
|
||||
bool calculateIcon(const AreaEffectSimulation::ExplosionArea &area, const QColor &color);
|
||||
bool calculateIcon(const AreaEffectSimulation::ExplosionSingle &single, const QColor &color);
|
||||
|
||||
LtsSession::LtsSession *m_session;
|
||||
Ui::CustomViewExplosion *m_ui;
|
||||
|
||||
};
|
||||
} // namespace AreaEffectSimulation
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CustomViewExplosion</class>
|
||||
<widget class="QWidget" name="CustomViewExplosion">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>350</width>
|
||||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbName">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbChargeType">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>State:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbEffectState">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">State</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AreaEffectSimulation::PixmapLabel" name="lblIcon">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">icon</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbEffectStart">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">for</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbEffectDuration">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Duration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AreaEffectSimulation::PixmapLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>AreaEffectSimulation/Gui/Base/aes_pixmap_label.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectManangement - Explosion Single Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "aes_explosions_single_central_model.h"
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
bool ExplosionsSingleCentralModel::initModel(LtsSession::LtsSession *session)
|
||||
{
|
||||
if (!AesGuiBaseModel::initModel(session))
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &Interface::Dtc::explosionSingleCentralChanged,
|
||||
this, &ExplosionsSingleCentralModel::onDataChanged);
|
||||
|
||||
fillAvailableChargeIds(m_gearClass);
|
||||
|
||||
m_aesDtc->explosionSingleCentrals([this](const ExplosionSingleCentral &item) { insertRow(item); });
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* ExplosionManangement - Explosion Single Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_model.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
/************ Class for Artillery and Mortar Explosion Single ***************/
|
||||
class ExplosionsSingleCentralModel : public AesGuiBaseModel<ExplosionSingleCentral>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExplosionsSingleCentralModel(ProjectDataManagement::GearClass gc, QObject *parent)
|
||||
: AesGuiBaseModel<ExplosionSingleCentral>(parent)
|
||||
, m_gearClass(gc)
|
||||
{}
|
||||
|
||||
bool initModel(LtsSession::LtsSession *session);
|
||||
ProjectDataManagement::GearClass gearClass() const { return m_gearClass; }
|
||||
|
||||
protected:
|
||||
ProjectDataManagement::GearClass m_gearClass;
|
||||
};
|
||||
|
||||
} //namespace AreaEffectSimulation
|
||||
|
||||
|
||||
+310
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectManangement - Explosion Cluster Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Norbert Thoden, SLSE, 2023-12-15
|
||||
*/
|
||||
|
||||
#include "aes_effect_cluster_model.h"
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <ProjectDataManagement/pdm_dtc.h>
|
||||
#include <ProjectDataManagement/pdm_translation.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
EffectClusterModel::EffectClusterModel(const QVector<ProjectDataManagement::GearClass> &gcs, QObject *parent)
|
||||
: AesGuiBaseModel<EffectCluster>(parent,
|
||||
{tr("GearType"),
|
||||
tr("Fuse Type"),
|
||||
tr("FiringPosition"),
|
||||
tr("ExplosionGeometry"),
|
||||
tr("ZOG"), // TLA ZOG
|
||||
tr("MeanHitPoints"),
|
||||
tr("MhpRotation"),
|
||||
tr("Impact Count"),
|
||||
tr("AnnotationString"),
|
||||
tr("Element"),
|
||||
tr("Original Flight Duration"),
|
||||
tr("Original Peak Height"),
|
||||
tr("Calculated Flight Duration"),
|
||||
tr("Calculated Peak Height"),
|
||||
tr("Calculated Firing Speed [m/s]"),
|
||||
tr("Launch Velocity [m/s]"),
|
||||
tr("Launch Angle [degree]"),
|
||||
tr("Drop Angle [degree]"),
|
||||
tr("TapTimepoint"),
|
||||
tr("Laser Code Prf"),
|
||||
tr("Laser Code Termination"),
|
||||
tr("Cloud Base")})
|
||||
, m_gearClasses(gcs)
|
||||
{
|
||||
}
|
||||
|
||||
bool EffectClusterModel::initModel(LtsSession::LtsSession *session)
|
||||
{
|
||||
updateEffectStateComboboxFilterData(true);
|
||||
|
||||
if (!AesGuiBaseModel::initModel(session))
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &Interface::Dtc::effectClusterChanged, this, &EffectClusterModel::onDataChanged);
|
||||
connect(m_aesDtc.get(), &Interface::Dtc::explosionClusterChanged, this, &EffectClusterModel::onExplosionClusterDataChanged);
|
||||
|
||||
fillAvailableChargeIds(m_gearClasses);
|
||||
// fillAvailableChargeIds({ProjectDataManagement::GearClass_def::Artillery, ProjectDataManagement::GearClass_def::Mortar});
|
||||
|
||||
m_aesDtc->effectClusters([this](const EffectCluster &item) { insertRow(item); });
|
||||
m_aesDtc->explosionClusters([this](const ExplosionCluster &item) { insertRow(toEffectCluster(item)); });
|
||||
|
||||
m_pdmDtc->enableGearTypeChargeType();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EffectCluster EffectClusterModel::toEffectCluster(const ExplosionCluster &data)
|
||||
{
|
||||
EffectCluster ec;
|
||||
ec.id(data.id());
|
||||
ec.name(data.name());
|
||||
ec.effectSourceId(data.effectSourceId());
|
||||
ec.effectStateId(data.effectStateId());
|
||||
ec.chargeStruct(data.chargeStruct());
|
||||
ec.effectDuration(data.effectDuration());
|
||||
ec.effectStart(data.effectStart());
|
||||
ec.area(data.area());
|
||||
ec.esmParticipantIds(data.esmParticipantIds());
|
||||
ec.explosionGeometry(data.explosionGeometry());
|
||||
ec.element(data.element());
|
||||
ec.firePurposeId(data.firePurposeId());
|
||||
ec.firingPosition(data.firingPosition());
|
||||
ec.fireRequestTime(data.fireRequestTime());
|
||||
ec.tla(data.tla());
|
||||
ec.sampleTime(data.sampleTime());
|
||||
ec.effectMarkingInTa(data.effectMarkingInTa());
|
||||
ec.externalId(data.externalId());
|
||||
ec.remainExplosionNumber(data.remainExplosionNumber());
|
||||
ec.participantId(data.participantId());
|
||||
ec.partyId(data.partyId());
|
||||
ec.properties(data.properties());
|
||||
|
||||
ec.isCentral(data.isCentral());
|
||||
ec.isDeleted(data.isDeleted());
|
||||
ec.isUsed(data.isUsed());
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
void EffectClusterModel::onExplosionClusterDataChanged(const ExplosionCluster &data, const DataModification &mod) { onDataChanged(toEffectCluster(data), mod); }
|
||||
|
||||
void EffectClusterModel::toolTipHelper(const EffectClusterModel *model, const QModelIndex &idx, int col, QString &toolTipStringInOut) const
|
||||
{
|
||||
const QString &hdr = model->headerData(col, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
const QModelIndex &idxTemp = idx.siblingAtColumn(col);
|
||||
toolTipStringInOut.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, model->data(idxTemp, Qt::DisplayRole).toString()));
|
||||
}
|
||||
|
||||
QVariant EffectClusterModel::data(const QModelIndex &idx, int role) const
|
||||
{
|
||||
if (!indexIsValid(idx))
|
||||
return QVariant();
|
||||
|
||||
const EffectCluster &ec = m_vecData.at(idx.row());
|
||||
// const dds::core::optional<AreaEffectSimulation::FlightCurve>& flightCurveRef = ec.flightCurve();
|
||||
// const dds::core::optional<AreaEffectSimulation::LaserGuiding>& laserGuidingRef = ec.laserGuiding();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (idx.column())
|
||||
{
|
||||
case ColGearType:
|
||||
{
|
||||
const int chargeTypeId = ec.chargeStruct().chargeTypeId();
|
||||
// There might be several gears for the same charge and we take the first one knowingly.
|
||||
const int gearTypeId = m_pdmDtc->gearTypeIdFromChargeTypeId(chargeTypeId).value(0, 0);
|
||||
return m_pdmDtc->trGearTypeName(gearTypeId);
|
||||
}
|
||||
break;
|
||||
case ColIgniterType:
|
||||
return m_pdmDtc->trIgniterTypeShortName(ec.chargeStruct().igniterTypeId());
|
||||
break;
|
||||
case ColFiringPosition:
|
||||
{
|
||||
const Core::GeoPosition &firingPositionRef = ec.firingPosition();
|
||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(firingPositionRef.lon(), firingPositionRef.lat());
|
||||
if (!qFuzzyIsNull(firingPositionRef.z()))
|
||||
mgrs.append(QStringLiteral(" ") + QString::number(firingPositionRef.z(), 'f', 2));
|
||||
return mgrs;
|
||||
}
|
||||
break;
|
||||
case ColExplosionGeometry:
|
||||
return AreaEffectSimulation::toString(ec.explosionGeometry());
|
||||
break;
|
||||
case ColTlaZog:
|
||||
return ec.tla();
|
||||
break;
|
||||
// case ColMhPointCount:
|
||||
// return static_cast<int>(ec.mhPoints().size());
|
||||
// break;
|
||||
// case ColMhpRotationCount:
|
||||
// return std::ceil(ec.mhpRotation() * 100) / 100;
|
||||
// break;
|
||||
// case ColImpactCount:
|
||||
// return ec.impactCount();
|
||||
// break;
|
||||
case ColAnnotationString:
|
||||
return QString::fromStdString(ec.annotationString());
|
||||
break;
|
||||
|
||||
case ColZpElement:
|
||||
return QString::fromStdString(ec.element());
|
||||
break;
|
||||
/* Might be used again if needed
|
||||
// FlightCurve
|
||||
case ColOriginalFlightDuration:
|
||||
if (flightCurveRef.is_set())
|
||||
return std::ceil(flightCurveRef.get().requestedFlightDuration() * 100) / 100;
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColOriginalPeakHeight:
|
||||
if (flightCurveRef.is_set())
|
||||
return flightCurveRef.get().requestedRelativePeakHeight();
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColCalculatedFlightDuration:
|
||||
if (flightCurveRef.is_set())
|
||||
return flightCurveRef.get().calculatedFlightDuration();
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColCalculatedPeakHeight:
|
||||
if (flightCurveRef.is_set())
|
||||
return std::ceil(flightCurveRef.get().calculatedPeakHeightAbs() * 100) / 100;
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColCalculatedFiringSpeed:
|
||||
if (flightCurveRef.is_set())
|
||||
return std::ceil(flightCurveRef.get().calculatedFiringSpeed() * 100) / 100;
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColLaunchVelocity:
|
||||
if (flightCurveRef.is_set())
|
||||
return std::ceil(flightCurveRef.get().launchVelocity() * 100) / 100;
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColLaunchAngleDeg:
|
||||
if (flightCurveRef.is_set())
|
||||
return std::ceil(flightCurveRef.get().launchAngle() * 100) / 100;
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColDropAngle:
|
||||
if (flightCurveRef.is_set())
|
||||
return std::ceil(flightCurveRef.get().dropAngle() * 100) / 100;
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
|
||||
// LaserGuiding
|
||||
case ColTapTimepoint:
|
||||
if (laserGuidingRef.is_set())
|
||||
return DTG::toStringMSec(laserGuidingRef.get().tapTime());
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColLcAttack_Prf:
|
||||
if (laserGuidingRef.is_set())
|
||||
return laserGuidingRef.get().lcAttack();
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColLcTermination:
|
||||
if (laserGuidingRef.is_set())
|
||||
return laserGuidingRef.get().lcTermination();
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
case ColCloudBase:
|
||||
if (laserGuidingRef.is_set())
|
||||
return laserGuidingRef.get().cloudBase();
|
||||
else
|
||||
return QStringLiteral("-");
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
return AesGuiBaseModel::data(idx, role);
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
else if (role == Qt::ToolTipRole)
|
||||
{
|
||||
switch (idx.column())
|
||||
{
|
||||
case ColAnnotationString:
|
||||
// return QString::fromStdString(ec.annotationString());
|
||||
break;
|
||||
default:
|
||||
{
|
||||
QString tooltip(QStringLiteral("<html>"));
|
||||
|
||||
const QString &hdr = this->headerData(BcName, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, QString::fromStdString(ec.name())));
|
||||
|
||||
bool bIsArtilleryOrMortar = m_gearClasses.contains(ProjectDataManagement::GearClass_def::Artillery)
|
||||
|| m_gearClasses.contains(ProjectDataManagement::GearClass_def::Mortar)
|
||||
|| m_gearClasses.contains(ProjectDataManagement::GearClass_def::Rocket);
|
||||
|
||||
toolTipHelper(this, idx, ColGearType, tooltip);
|
||||
if (bIsArtilleryOrMortar)
|
||||
{
|
||||
toolTipHelper(this, idx, BcChargeType, tooltip);
|
||||
toolTipHelper(this, idx, ColIgniterType, tooltip);
|
||||
}
|
||||
|
||||
// Origin
|
||||
toolTipHelper(this, idx, ColFiringPosition, tooltip);
|
||||
|
||||
// target
|
||||
if (bIsArtilleryOrMortar)
|
||||
{
|
||||
toolTipHelper(this, idx, ColExplosionGeometry, tooltip);
|
||||
|
||||
toolTipHelper(this, idx, ColTlaZog, tooltip);
|
||||
|
||||
toolTipHelper(this, idx, ColMhPointCount, tooltip);
|
||||
toolTipHelper(this, idx, ColImpactCount, tooltip);
|
||||
|
||||
toolTipHelper(this, idx, ColCalculatedFlightDuration, tooltip);
|
||||
toolTipHelper(this, idx, ColCalculatedPeakHeight, tooltip);
|
||||
toolTipHelper(this, idx, ColCalculatedFiringSpeed, tooltip);
|
||||
|
||||
toolTipHelper(this, idx, ColLaunchAngleDeg, tooltip);
|
||||
toolTipHelper(this, idx, ColDropAngle, tooltip);
|
||||
toolTipHelper(this, idx, ColTapTimepoint, tooltip);
|
||||
|
||||
toolTipHelper(this, idx, ColLcAttack_Prf, tooltip);
|
||||
toolTipHelper(this, idx, ColLcTermination, tooltip);
|
||||
|
||||
toolTipHelper(this, idx, ColCloudBase, tooltip);
|
||||
}
|
||||
|
||||
tooltip.append(QStringLiteral("</html>"));
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
|
||||
return AesGuiBaseModel::data(idx, role);
|
||||
}
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectManangement - Explosion Cluster Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Norbert Thoden, SLSE, 2023-12-15
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_model.h>
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Explosion/aeseffectclustermodel_export.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
//
|
||||
// Model for ExplosionsCluster (Artillery and/or Mortar and/or AirSupport
|
||||
//
|
||||
|
||||
class AESEFFECTCLUSTERMODEL_EXPORT EffectClusterModel : public AesGuiBaseModel<EffectCluster>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum AdditionalColumns
|
||||
{
|
||||
ColGearType = BcCount,
|
||||
ColIgniterType = BcCount + 1,
|
||||
ColFiringPosition = BcCount + 2,
|
||||
ColExplosionGeometry = BcCount + 3,
|
||||
ColTlaZog = BcCount + 4,
|
||||
ColMhPointCount = BcCount + 5,
|
||||
ColMhpRotationCount = BcCount + 6,
|
||||
ColImpactCount = BcCount + 7,
|
||||
ColAnnotationString = BcCount + 8,
|
||||
ColZpElement = BcCount + 9,
|
||||
ColOriginalFlightDuration = BcCount + 10, // origional...
|
||||
ColOriginalPeakHeight = BcCount + 11, // origional...
|
||||
ColCalculatedFlightDuration = BcCount + 12, // calculated...
|
||||
ColCalculatedPeakHeight = BcCount + 13,
|
||||
ColCalculatedFiringSpeed = BcCount + 14,
|
||||
ColLaunchVelocity = BcCount + 15, // more or less requested velocity, value is transfered to calculatedFiringSpeed
|
||||
ColLaunchAngleDeg = BcCount + 16,
|
||||
ColDropAngle = BcCount + 17,
|
||||
ColTapTimepoint = BcCount + 18,
|
||||
ColLcAttack_Prf = BcCount + 19,
|
||||
ColLcTermination = BcCount + 20,
|
||||
ColCloudBase = BcCount + 21,
|
||||
}; // origional...
|
||||
|
||||
EffectClusterModel(const QVector<ProjectDataManagement::GearClass> &gcs, QObject *parent);
|
||||
bool initModel(LtsSession::LtsSession *session) override;
|
||||
|
||||
QVariant data(const QModelIndex &idx, int role) const override;
|
||||
|
||||
public slots:
|
||||
void onExplosionClusterDataChanged(const ExplosionCluster &data, const DataModification &mod);
|
||||
|
||||
protected:
|
||||
void toolTipHelper(const EffectClusterModel *model, const QModelIndex &idx, int col, QString &toolTipStringInOut) const;
|
||||
EffectCluster toEffectCluster(const ExplosionCluster &data);
|
||||
|
||||
QVector<ProjectDataManagement::GearClass> m_gearClasses;
|
||||
};
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Effector
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2026-02-18
|
||||
*/
|
||||
|
||||
#include "aes_effector.h"
|
||||
#include "ui_aes_effector.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
AesEffector::AesEffector(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::AesEffector)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
connect(m_ui->pbTriggerNextState, &QPushButton::clicked, this, &AesEffector::onPbNextStateClicked);
|
||||
}
|
||||
|
||||
AesEffector::~AesEffector()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool AesEffector::init(int effectorId, const QString &verEin, const QString &name, AreaEffectSimulation::AesEffectorState state)
|
||||
{
|
||||
m_effectorId = effectorId;
|
||||
m_ui->lblVerEin->setText(verEin);
|
||||
m_ui->gbEffector->setTitle(verEin);
|
||||
m_ui->lblName->setText(name);
|
||||
setState(state);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AesEffector::setStateButtonVisible( bool visible)
|
||||
{
|
||||
m_ui->pbTriggerNextState->setVisible(visible);
|
||||
}
|
||||
|
||||
AreaEffectSimulation::AesEffectorState AesEffector::getState() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void AesEffector::setState(const AreaEffectSimulation::AesEffectorState &newState)
|
||||
{
|
||||
m_state = newState;
|
||||
|
||||
switch(newState.underlying())
|
||||
{
|
||||
case AreaEffectSimulation::AesEffectorState::EsNotReadyToFire:
|
||||
m_ui->lblState->setText(tr("Not ready to fire"));
|
||||
m_ui->pbTriggerNextState->setText(tr("Ready to Fire"));
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectorState::EsReadyToFire:
|
||||
m_ui->lblState->setText(tr("Ready to fire"));
|
||||
m_ui->pbTriggerNextState->setText(tr("Fire"));
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectorState::EsReceivedOrder:
|
||||
m_ui->lblState->setText(tr("Fire command received"));
|
||||
m_ui->pbTriggerNextState->setText(tr("Fire"));
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectorState::EsReportedFired:
|
||||
m_ui->lblState->setText(tr("Fired reported"));
|
||||
m_ui->pbTriggerNextState->setText(tr("Report Ready to Fire"));
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectorState::EsFired:
|
||||
m_ui->lblState->setText(tr("Fired"));
|
||||
m_ui->pbTriggerNextState->setText(tr("Report Fired"));
|
||||
break;
|
||||
default:
|
||||
// this shouldn't happen...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AesEffector::onPbNextStateClicked()
|
||||
{
|
||||
switch (m_state.underlying()) {
|
||||
case AreaEffectSimulation::AesEffectorState::EsFired:
|
||||
emit reportFired();
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectorState::EsReportedFired:
|
||||
emit reportReadyToFire();
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectorState::EsNotReadyToFire:
|
||||
emit reportReadyToFire();
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectorState::EsReadyToFire:
|
||||
emit fire();
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectorState::EsReceivedOrder:
|
||||
break;
|
||||
emit fire();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_ui->pbTriggerNextState->setDisabled(true);
|
||||
|
||||
// Re-Enable PB, so we can call it another time, if it does not react...
|
||||
QTimer::singleShot(2000, [this](){m_ui->pbTriggerNextState->setEnabled(true);});
|
||||
}
|
||||
|
||||
int AesEffector::effectorId() const
|
||||
{
|
||||
return m_effectorId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Effector
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2026-02-18
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <AreaEffectSimulation/aes_enums.hpp>
|
||||
|
||||
namespace Ui {
|
||||
class AesEffector;
|
||||
}
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
class AesEffector : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AesEffector(QWidget *parent = nullptr);
|
||||
~AesEffector();
|
||||
|
||||
bool init(int effectorId, const QString &verEin, const QString &name, AreaEffectSimulation::AesEffectorState state);
|
||||
|
||||
AreaEffectSimulation::AesEffectorState getState() const;
|
||||
void setState(const AreaEffectSimulation::AesEffectorState &newState);
|
||||
void setStateButtonVisible(bool visible);
|
||||
|
||||
int effectorId() const;
|
||||
|
||||
private slots:
|
||||
void onPbNextStateClicked();
|
||||
|
||||
signals:
|
||||
void reportFired();
|
||||
void reportReadyToFire();
|
||||
void fire();
|
||||
|
||||
private:
|
||||
Ui::AesEffector *m_ui;
|
||||
int m_effectorId;
|
||||
AreaEffectSimulation::AesEffectorState m_state;
|
||||
};
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AesEffector</class>
|
||||
<widget class="QWidget" name="AesEffector">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>282</width>
|
||||
<height>458</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="gbEffector">
|
||||
<property name="title">
|
||||
<string>Effector</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblName">
|
||||
<property name="text">
|
||||
<string>XXX Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblVerEin">
|
||||
<property name="text">
|
||||
<string>XXX 12345</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>240</width>
|
||||
<height>2</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxVerEin">
|
||||
<property name="text">
|
||||
<string>VerEin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxName">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="pbTriggerNextState">
|
||||
<property name="text">
|
||||
<string>TriggerNextState</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxState">
|
||||
<property name="text">
|
||||
<string>State:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblState">
|
||||
<property name="text">
|
||||
<string>XXX Fired</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,880 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Explosion Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Patric Karwat, SLSE, 2016-07-05
|
||||
*/
|
||||
|
||||
|
||||
#include "aes_explosion_edit.h"
|
||||
#include "ui_aes_explosion_edit.h"
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Services/AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <QJsonDocument>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
|
||||
#include <Plugins/AdvancedSymbology/asb_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/Gui/ParticipantSelection/participant_selection.h>
|
||||
|
||||
#include <QSpinBox>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
double ExplosionEdit::s_minWidth;
|
||||
double ExplosionEdit::s_maxWidth;
|
||||
double ExplosionEdit::s_stepWidth;
|
||||
double ExplosionEdit::s_minHeight;
|
||||
double ExplosionEdit::s_maxHeight;
|
||||
double ExplosionEdit::s_stepHeight;
|
||||
double ExplosionEdit::s_minRadius;
|
||||
double ExplosionEdit::s_maxRadius;
|
||||
double ExplosionEdit::s_stepRadius;
|
||||
int ExplosionEdit::s_maxChargeUsage;
|
||||
double ExplosionEdit::s_minAltitude;
|
||||
double ExplosionEdit::s_maxAltitude;
|
||||
qint64 ExplosionEdit::s_maxDurationSeconds;
|
||||
static int s_lastChargeTypeA = 0;
|
||||
static int s_lastChargeTypeM = 0;
|
||||
|
||||
ExplosionEdit::ExplosionEdit(const QString &menuGroup, ExplosionType type, ProjectDataManagement::GearClass gc, QWidget *parent)
|
||||
: BaseEdit(menuGroup, QLatin1String("ExplosionEdit"), parent)
|
||||
, m_type(type)
|
||||
, m_editable(false)
|
||||
, m_gearClass(gc)
|
||||
, m_previewCircleRadius(0.0)
|
||||
, m_ui(new Ui::ExplosionEdit)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
// Todo: Get these values
|
||||
|
||||
s_minWidth = 5;
|
||||
s_maxWidth = 1275;
|
||||
s_stepWidth = 5;
|
||||
s_minHeight = 5;
|
||||
s_maxHeight = 1275;
|
||||
s_minRadius = 5;
|
||||
s_maxRadius = 255;
|
||||
s_stepRadius = 1;
|
||||
s_stepHeight = 5;
|
||||
s_minAltitude = 0;
|
||||
s_maxAltitude = 1000;
|
||||
s_maxChargeUsage = 1000;
|
||||
s_maxDurationSeconds = 1800; // 30 Minutes
|
||||
|
||||
m_ui->sbDimensionX->setMinimum(s_minWidth);
|
||||
m_ui->sbDimensionX->setMaximum(s_maxWidth);
|
||||
m_ui->sbDimensionX->setSingleStep(s_stepWidth);
|
||||
m_ui->sbDimensionY->setMinimum(s_minHeight);
|
||||
m_ui->sbDimensionY->setMaximum(s_maxHeight);
|
||||
m_ui->sbDimensionY->setSingleStep(s_stepHeight);
|
||||
m_ui->sbAltitude->setMinimum(s_minAltitude);
|
||||
m_ui->sbAltitude->setMaximum(s_maxAltitude);
|
||||
m_ui->sbCannons->setMinimum(1);
|
||||
m_ui->sbCannons->setMaximum(s_maxChargeUsage);
|
||||
m_ui->sbRounds->setMinimum(1);
|
||||
m_ui->sbRounds->setMaximum(s_maxChargeUsage);
|
||||
m_ui->sbDurationSeconds->setMinimum(1);
|
||||
m_ui->sbDurationSeconds->setMaximum(s_maxDurationSeconds);
|
||||
m_ui->sbAimingAxis->setMaximum(6400);
|
||||
|
||||
m_ui->lblDesignator->clear();
|
||||
m_ui->lblIcon->clear();
|
||||
m_ui->lblTactIdentifier->clear();
|
||||
|
||||
|
||||
m_uiRequirements->addRequirement({m_ui->lblPosition, [this]() { return (!m_ui->positionEdit->coordinate().isNull()); }});
|
||||
m_uiRequirements->addRequirement({m_ui->lblName, [this]() { return (!m_ui->leIdentifier->text().isEmpty()); }});
|
||||
m_uiRequirements->addRequirement({m_ui->lblChargeType, [this]() { return (!m_ui->cbChargeType->currentData().isNull()); }});
|
||||
// either no effect start is set or effect start is greater than request time
|
||||
m_uiRequirements->addRequirement({m_ui->lblEffectStart, [this]()
|
||||
{
|
||||
return (hasValidEffectStart(m_ui->dteEffectStart) ||
|
||||
m_ui->dteEffectStart->msecsSinceEpoch() >= m_ui->dteRequestTime->msecsSinceEpoch());
|
||||
}});
|
||||
|
||||
if (m_type != etArea)
|
||||
{
|
||||
m_ui->lblAimingAxis->hide();
|
||||
m_ui->sbAimingAxis->hide();
|
||||
|
||||
m_ui->lblDuration->hide();
|
||||
m_ui->sbDurationSeconds->hide();
|
||||
|
||||
m_ui->sbDimensionX->setEnabled(false);
|
||||
m_ui->lblOperatorA->hide();
|
||||
m_ui->sbDimensionY->hide();
|
||||
|
||||
m_ui->sbDimensionX->setMinimum(s_minRadius);
|
||||
m_ui->sbDimensionX->setMaximum(s_maxRadius);
|
||||
m_ui->sbDimensionX->setSingleStep(s_stepRadius);
|
||||
|
||||
m_ui->sbCannons->setEnabled(false);
|
||||
m_ui->sbCannons->hide();
|
||||
m_ui->lblOperatorB->hide();
|
||||
m_ui->sbRounds->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->sbDurationSeconds->setValue(60);
|
||||
m_ui->sbCannons->setValue(4);
|
||||
m_ui->sbRounds->setValue(9);
|
||||
}
|
||||
|
||||
if (m_type != etSingleCentral)
|
||||
{
|
||||
m_ui->lbxFiringAngle->hide();
|
||||
m_ui->sbFiringAngle->hide();
|
||||
m_ui->lbxIgniterType->hide();
|
||||
m_ui->cbIgniterType->hide();
|
||||
m_ui->lbxParticipant->hide();
|
||||
m_ui->lblDesignator->hide();
|
||||
m_ui->lblIcon->hide();
|
||||
m_ui->lblTactIdentifier->hide();
|
||||
m_ui->pbParticipant->hide();
|
||||
m_ui->cbParty->setEnabled(false);
|
||||
}
|
||||
else
|
||||
m_uiRequirements->addRequirement({m_ui->lbxParticipant, [this]() { return (m_participant.id() != 0); }});
|
||||
|
||||
enaDisa();
|
||||
|
||||
connect(m_ui->cbParty, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &ExplosionEdit::onPartyChanged);
|
||||
connect(m_ui->cbChargeType, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &ExplosionEdit::onChargeTypeChanged);
|
||||
|
||||
connect(m_ui->sbDimensionX, &QSpinBox::editingFinished, this, &ExplosionEdit::correctSpinBoxValue);
|
||||
connect(m_ui->sbDimensionY, &QSpinBox::editingFinished, this, &ExplosionEdit::correctSpinBoxValue);
|
||||
connect(m_ui->sbAltitude, &QSpinBox::editingFinished, this, &ExplosionEdit::correctSpinBoxValue);
|
||||
|
||||
// Not yet needed (no singleStep defined)
|
||||
// connect(m_ui->sbAimingAxis, &QSpinBox::editingFinished, this, &ExplosionEdit::correctSpinBoxValue);
|
||||
// connect(m_ui->sbCannons, &QSpinBox::editingFinished, this, &ExplosionEdit::correctSpinBoxValue);
|
||||
// connect(m_ui->sbRounds, &QSpinBox::editingFinished, this, &ExplosionEdit::correctSpinBoxValue);
|
||||
// connect(m_ui->sbDurationSeconds, &QSpinBox::editingFinished, this, &ExplosionEdit::correctSpinBoxValue);
|
||||
|
||||
connect(m_ui->sbCannons, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, [this](int val) { onCannonsChanged(val); });
|
||||
connect(m_ui->sbRounds, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, [this](int val) { onRoundsChanged(val); });
|
||||
connect(m_ui->pbFire, &QPushButton::clicked,
|
||||
this, &ExplosionEdit::onFireClicked);
|
||||
|
||||
connect(m_ui->pbClear, &QPushButton::clicked,
|
||||
m_ui->positionEdit, &LtsCoordWidget::LtsCoordWidget::clear);
|
||||
|
||||
connect(m_ui->pbParticipant, &QPushButton::clicked,
|
||||
this, &ExplosionEdit::onParticipantClicked);
|
||||
|
||||
m_symbolWatcher = new AdvancedSymbology::SymbolResultWatcherLabel(m_ui->lblIcon);
|
||||
}
|
||||
|
||||
ExplosionEdit::~ExplosionEdit()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void ExplosionEdit::retranslate()
|
||||
{
|
||||
QString title;
|
||||
|
||||
switch (m_gearClass.underlying())
|
||||
{
|
||||
case ProjectDataManagement::GearClass::Artillery:
|
||||
if (m_type == etSingle)
|
||||
title = tr("Single Artillery");
|
||||
else if (m_type == etArea)
|
||||
title = tr("Area Artillery");
|
||||
else
|
||||
title = tr ("Single Artillery Central");
|
||||
break;
|
||||
case ProjectDataManagement::GearClass::Mortar:
|
||||
if (m_type == etSingle)
|
||||
title = tr("Single Mortar");
|
||||
else if (m_type == etArea)
|
||||
title = tr("Area Mortar");
|
||||
else
|
||||
title = tr ("Single Mortar Central");
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
translate(m_ui, m_aesItem, title);
|
||||
|
||||
if (m_type != etArea)
|
||||
{
|
||||
m_ui->sbCannons->setValue(1);
|
||||
m_ui->sbRounds->setValue(1);
|
||||
m_ui->lblRounds->setText(tr("Rounds:"));
|
||||
m_ui->lblDimension->setText(tr("Diameter [m]:"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->lblRounds->setText(tr("Cannons x Rounds:"));
|
||||
m_ui->lblDimension->setText(tr("Dimension [m]:"));
|
||||
}
|
||||
|
||||
setFireButton(m_aesItem.effectStateId());
|
||||
|
||||
updateMaxLabel(false);
|
||||
}
|
||||
|
||||
void ExplosionEdit::onCannonsChanged(int cannons, bool modifiedFromExternal)
|
||||
{
|
||||
updateMaxLabel(modifiedFromExternal);
|
||||
if (cannons == 0 || maxAvailableRounds() == 0)
|
||||
return;
|
||||
|
||||
m_ui->sbRounds->setMaximum(maxAvailableRounds() / cannons);
|
||||
updateMaxLabel(modifiedFromExternal);
|
||||
}
|
||||
|
||||
void ExplosionEdit::onRoundsChanged(int rounds, bool modifiedFromExternal)
|
||||
{
|
||||
updateMaxLabel(modifiedFromExternal);
|
||||
if (rounds == 0 || maxAvailableRounds() == 0)
|
||||
return;
|
||||
|
||||
m_ui->sbCannons->setMaximum(maxAvailableRounds() / rounds);
|
||||
updateMaxLabel(modifiedFromExternal);
|
||||
}
|
||||
|
||||
void ExplosionEdit::enableUiElements(bool enable)
|
||||
{
|
||||
ERROR_LOG(m_logger) << " enableUiElements enable=" << enable;
|
||||
|
||||
m_ui->leIdentifier->setMaxLength(30);
|
||||
|
||||
m_ui->cbChargeType->setEnabled(enable);
|
||||
m_ui->sbDurationSeconds->setEnabled(enable);
|
||||
m_ui->cbParty->setEnabled(enable && m_type != etSingleCentral); // Set via Participant
|
||||
setEffectStartEnabled(m_ui->dteEffectStart, enable);
|
||||
|
||||
m_ui->dteRequestTime->setEnabled(enable);
|
||||
m_ui->pbPosition->setEnabled(m_sitMapGuiIfc && enable);
|
||||
m_ui->positionEdit->setEnabled(enable);
|
||||
m_ui->sbAltitude->setEnabled(enable);
|
||||
m_ui->sbDimensionX->setEnabled(enable && m_type == etArea);
|
||||
m_ui->sbDimensionY->setEnabled(enable);
|
||||
m_ui->sbAimingAxis->setEnabled(enable);
|
||||
m_ui->cbPurpose->setEnabled(enable);
|
||||
m_ui->sbCannons->setEnabled(enable && m_type == etArea);
|
||||
m_ui->sbRounds->setEnabled(enable && m_type == etArea);
|
||||
m_ui->cbEffectMarkingInTa->setEnabled(enable);
|
||||
m_ui->leIdentifier->setEnabled(enable || isOnlyNameModifiable());
|
||||
m_ui->pbClear->setEnabled(enable);
|
||||
|
||||
m_ui->sbFiringAngle->setEnabled(enable);
|
||||
m_ui->pbParticipant->setEnabled(enable);
|
||||
m_ui->cbIgniterType->setEnabled(enable);
|
||||
|
||||
if (!enable)
|
||||
{
|
||||
bool hasChanges = hasUnsavedChanges();
|
||||
m_ui->sbDurationSeconds->setValue(m_aesItem.effectDuration() / 1000); // ms -> s
|
||||
if (!hasChanges)
|
||||
__unchange__();
|
||||
}
|
||||
|
||||
setFireButton(m_aesItem.effectStateId());
|
||||
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();
|
||||
AesItem baseData;
|
||||
if (m_type == etSingle)
|
||||
{
|
||||
ExplosionSingle singleData = m_dtc->explosionSingle(m_aesItem.id());
|
||||
setSingleData(singleData);
|
||||
baseData = singleData;
|
||||
}
|
||||
else if (m_type == etArea)
|
||||
{
|
||||
ExplosionArea areaData = m_dtc->explosionArea(m_aesItem.id());
|
||||
setAreaData(areaData);
|
||||
baseData = areaData;
|
||||
}
|
||||
setBaseData(baseData, false);
|
||||
setFireButton(baseData.effectStateId());
|
||||
__unchange__();
|
||||
if (name != m_ui->leIdentifier->text())
|
||||
m_ui->leIdentifier->setText(name);
|
||||
}
|
||||
if (m_aesItem.effectStateId() == AesEffectState_def::EsPaused)
|
||||
__unchange__();
|
||||
}
|
||||
|
||||
int ExplosionEdit::maxAvailableRounds() const
|
||||
{
|
||||
int mapMax = m_chargeTypeMap[m_ui->cbChargeType->currentData().toInt()].available[m_ui->cbParty->currentData().toInt()];
|
||||
return mapMax > s_maxChargeUsage ? s_maxChargeUsage : mapMax;
|
||||
}
|
||||
|
||||
void ExplosionEdit::setBaseData(const AesItem &baseData, bool copy)
|
||||
{
|
||||
m_aesItem = baseData;
|
||||
if (copy)
|
||||
{
|
||||
m_aesItem.id(0);
|
||||
m_aesItem.effectStateId(AreaEffectSimulation::AesEffectState_def::get_default());
|
||||
}
|
||||
m_ui->leIdentifier->setText(QString::fromUtf8(baseData.name().c_str()));
|
||||
int idx = m_ui->cbChargeType->findData(baseData.chargeStruct().chargeTypeId());
|
||||
if (idx < 0)
|
||||
{
|
||||
auto ct = m_chargeTypeMap[baseData.chargeStruct().chargeTypeId()].chargeType;
|
||||
m_ui->cbChargeType->addItem(m_pdmDtc->trChargeTypeShortName(ct.id(), true), ct.id());
|
||||
idx = m_ui->cbChargeType->findData(ct.id());
|
||||
}
|
||||
m_ui->cbChargeType->setCurrentIndex(idx);
|
||||
m_ui->dteEffectStart->setMsecsSinceEpoch(baseData.effectStart().is_set() ? baseData.effectStart().get() : 0);
|
||||
m_ui->sbDurationSeconds->setValue(baseData.effectDuration() / 1000); // ms -> s
|
||||
|
||||
m_ui->cbParty->setCurrentIndex(m_ui->cbParty->findData(partyForItem(baseData)));
|
||||
m_ui->cbEffectMarkingInTa->setChecked(baseData.effectMarkingInTa());
|
||||
m_editable = m_editable && isModifiable() && !isOnlyNameModifiable() && m_session->app() != LtsAppDescriptor::App::OC;
|
||||
|
||||
}
|
||||
|
||||
bool ExplosionEdit::init(int aesItemId, bool copy,
|
||||
LtsSession::LtsSession *session)
|
||||
{
|
||||
if (!BaseEdit::init(aesItemId, session))
|
||||
return false;
|
||||
|
||||
if (!m_session->getForeignDataInterface<AdvancedSymbology::DataInterface>(m_asbIfc))
|
||||
return false;
|
||||
|
||||
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << " failed to get ppmDtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_session->getForeignGuiInterface<ProjectDataManagement::ForeignGuiInterface>(m_pdmCbx))
|
||||
return false;
|
||||
|
||||
bool readable = false;
|
||||
switch (m_gearClass.underlying())
|
||||
{
|
||||
case ProjectDataManagement::GearClass::Artillery:
|
||||
m_editable = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsEditArtillery) && m_type == etSingle) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::AreaExplosionsEditArtillery) && m_type == etArea) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsCentralEditArtillery) && m_type == etSingleCentral) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::ExplosionEditCluster) && m_type == etArea) ;
|
||||
readable = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsShowArtillery) && m_type == etSingle) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::AreaExplosionsShowArtillery) && m_type == etArea) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsCentralEditArtillery) && m_type == etSingleCentral) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::ExplosionShowCluster) && m_type == etArea);
|
||||
if (m_type == etSingle) // Single Artillery
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Add_Single_Artillery"));
|
||||
else if (m_type == etArea) // Area Artillery
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Add_Area_Artillery"));
|
||||
else if (m_type == etSingleCentral) // Single Central Artillery
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Add_Single_Central_Artillery"));
|
||||
break;
|
||||
case ProjectDataManagement::GearClass::Mortar:
|
||||
m_editable = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsEditMortar) && m_type == etSingle) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::AreaExplosionsEditMortar) && m_type == etArea) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsCentralEditMortar) && m_type == etSingleCentral) ;
|
||||
readable = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsShowMortar) && m_type == etSingle) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::AreaExplosionsShowMortar) && m_type == etArea) ||
|
||||
(LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsCentralShowMortar) && m_type == etSingleCentral) ;
|
||||
if (m_type == etSingle) // Single Artillery
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Add_Single_Mortar"));
|
||||
else if (m_type == etArea) // Area Artillery
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Add_Area_Mortar"));
|
||||
else if (m_type == etSingleCentral) // Single Central Artillery
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Add_Single_Central_Mortar"));
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!readable && !m_editable)
|
||||
return false;
|
||||
|
||||
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(m_pdmDtc))
|
||||
return false;
|
||||
|
||||
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
|
||||
return false;
|
||||
|
||||
m_ui->dteEffectStart->setMinimumTimeMSec(m_session->partitionTime());
|
||||
m_ui->dteEffectStart->setRetrieveCurrentTimeCallback([this]() { return m_session->partitionTime(); });
|
||||
m_ui->dteRequestTime->setRetrieveCurrentTimeCallback([this]() { return m_session->partitionTime(); });
|
||||
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const bool enableEffectShowManagement = ps->value(QStringLiteral("esm"),
|
||||
QStringLiteral("enableEffectShowManagement")).toBool();
|
||||
m_ui->cbEffectMarkingInTa->setVisible(enableEffectShowManagement &&
|
||||
((m_session->app() == LtsAppDescriptor::App::Situation ||
|
||||
m_session->app() == LtsAppDescriptor::App::SituationTablet) &&
|
||||
(!m_session->isReplayPartition())));
|
||||
|
||||
if (m_sitMapGuiIfc)
|
||||
connect(m_ui->pbPosition, &QPushButton::clicked, this, &ExplosionEdit::getPosition);
|
||||
else
|
||||
m_ui->pbPosition->setEnabled(false);
|
||||
|
||||
const auto firePurposes = m_pdmDtc->firePurposes();
|
||||
for (const auto &firePurpose : firePurposes)
|
||||
m_ui->cbPurpose->addItem(m_pdmDtc->trFirePurposeName(firePurpose.id()), firePurpose.id());
|
||||
|
||||
const auto chargesForGearClass =
|
||||
m_pdmDtc->chargesForGearClass(m_gearClass);
|
||||
for (const ProjectDataManagement::ChargeType &chargeType : chargesForGearClass)
|
||||
m_chargeTypeMap[chargeType.id()].chargeType = chargeType;
|
||||
const auto chargeAdmins = m_dtc->chargeAdministrations();
|
||||
for (const ChargeAdministration &val : chargeAdmins)
|
||||
{
|
||||
if (!m_chargeTypeMap.contains(val.chargeTypeId()))
|
||||
continue;
|
||||
m_chargeTypeMap[val.chargeTypeId()].available.insert(val.partyId(), val.amount() - val.planned());
|
||||
}
|
||||
|
||||
m_ppmGuiCbxIfc->fillPartyComboBox(m_ui->cbParty);
|
||||
onPartyChanged();
|
||||
|
||||
if (aesItemId > 0)
|
||||
{
|
||||
AesItem baseData;
|
||||
if (m_type == etSingle)
|
||||
{
|
||||
ExplosionSingle singleData = m_dtc->explosionSingle(aesItemId);
|
||||
setSingleData(singleData);
|
||||
baseData = singleData;
|
||||
}
|
||||
else if (m_type == etArea)
|
||||
{
|
||||
ExplosionArea areaData = m_dtc->explosionArea(aesItemId);
|
||||
setAreaData(areaData, copy);
|
||||
baseData = areaData;
|
||||
}
|
||||
setBaseData(baseData, copy);
|
||||
setFireButton(baseData.effectStateId());
|
||||
}
|
||||
else
|
||||
setFireButton(AreaEffectSimulation::AesEffectState::EsUnknown);
|
||||
enableUiElements(m_editable);
|
||||
|
||||
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::chargeAdministrationChanged,
|
||||
this, &ExplosionEdit::onChargeCountChanged);
|
||||
|
||||
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionAreaChanged,
|
||||
this, &BaseEdit::onAreaChanged);
|
||||
|
||||
onChargeTypeChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString ExplosionEdit::dialogIdentifier() const
|
||||
{
|
||||
switch (m_gearClass.underlying())
|
||||
{
|
||||
case ProjectDataManagement::GearClass::Artillery:
|
||||
if (m_type == etSingle)
|
||||
return m_aesItem.id() <= 0 ? QStringLiteral("AddExplosionSingleArtillery") : QStringLiteral("EditExplosionSingleArtillery%1").arg(m_aesItem.id());
|
||||
else if (m_type == etArea)
|
||||
return m_aesItem.id() <= 0 ? QStringLiteral("AddExplosionAreaArtillery") : QStringLiteral("EditExplosionAreaArtillery%1").arg(m_aesItem.id());
|
||||
else
|
||||
return m_aesItem.id() <= 0 ? QStringLiteral("AddExplosionSingleCentralArtillery") : QStringLiteral("EditExplosionSingleCentralArtillery%1").arg(m_aesItem.id());
|
||||
case ProjectDataManagement::GearClass::Mortar:
|
||||
if (m_type == etSingle)
|
||||
return m_aesItem.id() <= 0 ? QStringLiteral("AddExplosionSingleMortar") : QStringLiteral("EditExplosionSingleMortar%1").arg(m_aesItem.id());
|
||||
else if (m_type == etArea)
|
||||
return m_aesItem.id() <= 0 ? QStringLiteral("AddExplosionAreaMortar") : QStringLiteral("EditExplosionAreaMortar%1").arg(m_aesItem.id());
|
||||
else
|
||||
return m_aesItem.id() <= 0 ? QStringLiteral("AddExplosionSingleCentralMortar") : QStringLiteral("EditExplosionSingleCentralMortar%1").arg(m_aesItem.id());
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
void ExplosionEdit::onChargeCountChanged(const AreaEffectSimulation::ChargeAdministration &data, DataModification modType)
|
||||
{
|
||||
// All relevant Charge Types are in Map. So we can just skip the others.
|
||||
if (!m_chargeTypeMap.contains(data.chargeTypeId()))
|
||||
return;
|
||||
|
||||
if (modType == DataModification::eRemoved || data.amount() - data.planned() <= 0)
|
||||
m_chargeTypeMap[data.chargeTypeId()].available.remove(data.partyId());
|
||||
else
|
||||
m_chargeTypeMap[data.chargeTypeId()].available.insert(data.partyId(), data.amount() - data.planned());
|
||||
onPartyChanged();
|
||||
updateCannonsRounds(true);
|
||||
updateMaxLabel(true);
|
||||
}
|
||||
|
||||
void ExplosionEdit::showPreviewObject()
|
||||
{
|
||||
if (!m_sitMapGuiIfc)
|
||||
return;
|
||||
|
||||
if (m_previewCircleCenter.isNull() && m_previewPolygon.isEmpty())
|
||||
return;
|
||||
|
||||
if (m_previewCircleCenter.isNull())
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, m_previewPolygon, true);
|
||||
else
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, m_previewCircleCenter, m_previewCircleRadius);
|
||||
}
|
||||
|
||||
void ExplosionEdit::setFireButton(AreaEffectSimulation::AesEffectState effectState)
|
||||
{
|
||||
if (effectState == AesEffectState::EsActivated)
|
||||
{
|
||||
m_ui->pbFire->setText(tr("Pause"));
|
||||
m_ui->pbFire->setIcon(QIcon(QStringLiteral("icon:avm_pause.svg")));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->pbFire->setText(tr("Start"));
|
||||
m_ui->pbFire->setIcon(QIcon(QStringLiteral("icon:avm_start.svg")));
|
||||
}
|
||||
|
||||
if ((effectState == AesEffectState::EsActivated ||
|
||||
effectState == AesEffectState::EsPrepared ||
|
||||
effectState == AesEffectState::EsCreated ||
|
||||
effectState == AesEffectState::EsPaused)
|
||||
&& m_aesItem.id() > 0)
|
||||
m_ui->pbFire->setEnabled(true);
|
||||
else
|
||||
m_ui->pbFire->setEnabled(false);
|
||||
}
|
||||
|
||||
void ExplosionEdit::updateCannonsRounds(bool modifiedFromExternal)
|
||||
{
|
||||
// If Cannons are already more than availRounds, Reset both to One
|
||||
if (m_ui->sbCannons->value() > maxAvailableRounds() && m_editable && m_aesItem.id() <= 0)
|
||||
{
|
||||
m_ui->sbCannons->setValue(1);
|
||||
m_ui->sbRounds->setValue(1);
|
||||
}
|
||||
// setMaximum on one or both.
|
||||
onCannonsChanged(m_ui->sbCannons->value(), modifiedFromExternal);
|
||||
onRoundsChanged(m_ui->sbRounds->value(), modifiedFromExternal);
|
||||
}
|
||||
|
||||
void ExplosionEdit::updateMaxLabel(bool modifiedFromExternal)
|
||||
{
|
||||
QString text = tr("= %1 (avail: %2%3)").arg(m_ui->sbCannons->value() * m_ui->sbRounds->value())
|
||||
.arg(maxAvailableRounds() == s_maxChargeUsage ? QLatin1String(">=") : QString())
|
||||
.arg(maxAvailableRounds());
|
||||
|
||||
if (modifiedFromExternal) // Todo: Use palette
|
||||
text = QStringLiteral("<span style=\"color:#aa0000;\">%1</span>").arg(text);
|
||||
|
||||
if (text == m_ui->lblMaxCount->text())
|
||||
return;
|
||||
|
||||
m_ui->lblMaxCount->setText(text);
|
||||
m_ui->lblMaxCount->setToolTip(modifiedFromExternal ? tr("Cannons / Rounds potentially modified by external source!") : QString());
|
||||
}
|
||||
|
||||
quint32 ExplosionEdit::partyForItem(const AesItem &aesItem) const
|
||||
{
|
||||
if (aesItem.participantId().is_set())
|
||||
{
|
||||
if (m_participant.id() == aesItem.participantId().get())
|
||||
return m_participant.partyId();
|
||||
else
|
||||
return m_ppmDtc->participant(aesItem.participantId().get()).partyId();
|
||||
}
|
||||
else if (aesItem.partyId().is_set())
|
||||
return aesItem.partyId().get();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ExplosionEdit::setSingleData(const ExplosionSingle &singleData)
|
||||
{
|
||||
QPointF impactPosition(singleData.impactPosition().lon(), singleData.impactPosition().lat());
|
||||
if (!impactPosition.isNull())
|
||||
m_ui->positionEdit->setCoordinate(impactPosition);
|
||||
|
||||
m_ui->dteRequestTime->setMsecsSinceEpoch(singleData.fireRequestTime());
|
||||
m_ui->cbPurpose->setCurrentText(QString::fromUtf8(singleData.purpose().c_str()));
|
||||
m_ui->sbAltitude->setValue(singleData.altitude());
|
||||
|
||||
if (m_aesItem.id() > 0)
|
||||
m_chargeTypeMap[singleData.chargeStruct().chargeTypeId()].available[partyForItem(singleData)] += 1;
|
||||
|
||||
const double radius = m_pdmDtc->impactRadius(singleData.chargeStruct().chargeTypeId(),singleData.chargeStruct().igniterTypeId(), singleData.chargeStruct().igniterFunctionId());
|
||||
m_ui->sbDimensionX->setValue(2 * radius);
|
||||
}
|
||||
|
||||
void ExplosionEdit::setAreaData(const ExplosionArea &areaData, bool copy)
|
||||
{
|
||||
const Area &area = areaData.area();
|
||||
if (!qFuzzyCompare(area.cornerBottomLeft().lon(), 0) ||
|
||||
!qFuzzyCompare(area.cornerBottomLeft().lat(), 0))
|
||||
{
|
||||
QPointF bottomLeft(area.cornerBottomLeft().lon(), area.cornerBottomLeft().lat());
|
||||
m_ui->positionEdit->setCoordinate(Polygons::bottomLeft2CenterPoint(bottomLeft, area.width(), area.height(), area.rotation()));
|
||||
}
|
||||
|
||||
m_ui->sbDimensionX->setValue(area.width());
|
||||
m_ui->sbDimensionY->setValue(area.height());
|
||||
m_ui->sbAimingAxis->setValue(fmod((90.0 + area.rotation()) * 6400 / 360, 6400));
|
||||
m_ui->sbCannons->setValue(areaData.cannonCount() == 0 ? 4 : areaData.cannonCount());
|
||||
m_ui->sbRounds->setValue(areaData.cannonRounds() == 0 ? 9 : areaData.cannonRounds());
|
||||
if (m_aesItem.id() > 0 && !copy)
|
||||
{
|
||||
if (!m_chargeTypeMap.contains(areaData.chargeStruct().chargeTypeId()))
|
||||
ERROR_LOG(m_logger) << "SetAreaData called with a charge Type, that has doesn't match. Id " << areaData.chargeStruct().chargeTypeId() << "is not in m_chargeTypeMap";
|
||||
if (!areaData.partyId().is_set())
|
||||
ERROR_LOG(m_logger) << "SetAreaData called without a party set. m_chargeTypeMap might be corrupted.";
|
||||
m_chargeTypeMap[areaData.chargeStruct().chargeTypeId()].available[areaData.partyId().get()] += areaData.cannonCount() * areaData.cannonRounds();
|
||||
}
|
||||
|
||||
|
||||
m_ui->dteRequestTime->setMsecsSinceEpoch(areaData.fireRequestTime());
|
||||
m_ui->cbPurpose->setCurrentText(QString::fromUtf8(areaData.purpose().c_str()));
|
||||
m_ui->sbAltitude->setValue(areaData.altitude());
|
||||
}
|
||||
|
||||
//slots
|
||||
|
||||
void ExplosionEdit::getPosition()
|
||||
{
|
||||
if (!has2DMap())
|
||||
return;
|
||||
|
||||
bool isNull = qFuzzyCompare(m_ui->positionEdit->coordinate().x(), 0) && qFuzzyCompare(m_ui->positionEdit->coordinate().y(), 0);
|
||||
|
||||
QPointF p(Polygons::centerPoint2BottomLeft(m_ui->positionEdit->coordinate(), m_ui->sbDimensionX->value(), m_ui->sbDimensionY->value(), (m_ui->sbAimingAxis->value() - 1600) / 6400. * 360));
|
||||
|
||||
if (m_type != etArea)
|
||||
m_sitMapGuiIfc->getCoordinate(this, SLOT(onCoordinate(QPointF)), nullptr);
|
||||
else
|
||||
m_sitMapGuiIfc->getRectangle(this,
|
||||
SLOT(onMapRecData(QPointF,double,double,double,QPolygonF)),
|
||||
nullptr,
|
||||
s_minWidth,
|
||||
s_maxWidth,
|
||||
s_minHeight,
|
||||
s_maxHeight,
|
||||
isNull ? m_ui->positionEdit->coordinate() : p,
|
||||
m_ui->sbDimensionX->value(),
|
||||
m_ui->sbDimensionY->value(),
|
||||
(m_ui->sbAimingAxis->value() - 1600) / 6400. * 360);
|
||||
}
|
||||
|
||||
void ExplosionEdit::onCoordinate(const QPointF ¢erPoint)
|
||||
{
|
||||
m_previewPolygon.clear();
|
||||
m_previewCircleCenter = centerPoint;
|
||||
m_previewCircleRadius = 0.5 * m_ui->sbDimensionX->value();
|
||||
m_ui->positionEdit->setCoordinate(centerPoint);
|
||||
|
||||
showPreviewObject();
|
||||
}
|
||||
|
||||
void ExplosionEdit::onMapRecData(const QPointF &bottomLeft, double width, double height, double angleDegNorth, const QPolygonF &bufferOutlinePolygon)
|
||||
{
|
||||
m_previewCircleCenter = QPointF();
|
||||
m_previewPolygon = bufferOutlinePolygon;
|
||||
|
||||
m_ui->positionEdit->setCoordinate(Polygons::bottomLeft2CenterPoint(bottomLeft, width, height, angleDegNorth));
|
||||
m_ui->sbDimensionX->setValue(round(width));
|
||||
m_ui->sbDimensionY->setValue(round(height));
|
||||
m_ui->sbAimingAxis->setValue(fmod((90.0 + angleDegNorth) * 6400 / 360, 6400));
|
||||
|
||||
showPreviewObject();
|
||||
}
|
||||
|
||||
void ExplosionEdit::onChargeTypeChanged()
|
||||
{
|
||||
int chargeTypeId =m_ui->cbChargeType->currentData().toInt();
|
||||
// update comboBox IgniterType:
|
||||
m_pdmCbx->fillIgniterComboBox(m_ui->cbIgniterType, chargeTypeId);
|
||||
|
||||
updateCannonsRounds();
|
||||
if (m_type == etArea)
|
||||
return;
|
||||
|
||||
// NOTE: igniterType/IgniterFunciton = 0 as long as ExplosionEdit does not contain values
|
||||
double impactRadius = m_pdmDtc->impactRadius(m_ui->cbChargeType->currentData().toInt(), 0, 0);
|
||||
m_ui->sbDimensionX->setValue(2 * impactRadius);
|
||||
}
|
||||
|
||||
void ExplosionEdit::onPartyChanged()
|
||||
{
|
||||
int partyId = m_ui->cbParty->currentData().toInt();
|
||||
int chargeTypeId = m_ui->cbChargeType->currentData().toInt();
|
||||
if (chargeTypeId <= 0)
|
||||
chargeTypeId = m_gearClass == ProjectDataManagement::GearClass::Artillery ? s_lastChargeTypeA : s_lastChargeTypeM;
|
||||
|
||||
QSignalBlocker sb(m_ui->cbChargeType);
|
||||
m_ui->cbChargeType->clear();
|
||||
for (const Charges &charge : qAsConst(m_chargeTypeMap))
|
||||
{
|
||||
if (charge.available.contains(partyId) && charge.available[partyId] > 0)
|
||||
m_ui->cbChargeType->addItem(m_pdmDtc->trChargeTypeShortName(charge.chargeType.id(), true), charge.chargeType.id());
|
||||
}
|
||||
|
||||
m_ui->cbChargeType->setCurrentIndex(m_ui->cbChargeType->findData(chargeTypeId) < 0 ? 0 : m_ui->cbChargeType->findData(chargeTypeId));
|
||||
sb.unblock();
|
||||
updateCannonsRounds();
|
||||
}
|
||||
|
||||
bool ExplosionEdit::apply()
|
||||
{
|
||||
std::string name = m_ui->leIdentifier->text().toStdString();
|
||||
qint64 effectStart = m_ui->dteEffectStart->msecsSinceEpoch();
|
||||
int chargeType = m_ui->cbChargeType->currentData().toInt();
|
||||
if (m_gearClass == ProjectDataManagement::GearClass::Artillery)
|
||||
s_lastChargeTypeA = chargeType;
|
||||
else
|
||||
s_lastChargeTypeM = chargeType;
|
||||
int partyId = m_ui->cbParty->currentData().toInt();
|
||||
// int playerId = m_participant.id();
|
||||
int cannons = m_ui->sbCannons->value();
|
||||
int rounds = m_ui->sbRounds->value();
|
||||
int duration = m_ui->sbDurationSeconds->value() * 1000; // secs --> msecs
|
||||
|
||||
// Area:
|
||||
QPointF bottomLeft(Polygons::centerPoint2BottomLeft(m_ui->positionEdit->coordinate(), m_ui->sbDimensionX->value(), m_ui->sbDimensionY->value(), (m_ui->sbAimingAxis->value() - 1600) * 360.0 / 6400));
|
||||
const Core::GeoPosition2D bottomLeftGeo(bottomLeft.x(), bottomLeft.y());
|
||||
const Area area(bottomLeftGeo, m_ui->sbDimensionX->value(), m_ui->sbDimensionY->value(), (m_ui->sbAimingAxis->value() - 1600) * 360.0 / 6400);
|
||||
|
||||
// Single:
|
||||
const Core::GeoPosition2D pos(m_ui->positionEdit->coordinate().x(), m_ui->positionEdit->coordinate().y());
|
||||
const Core::GeoPosition pos3D(m_ui->positionEdit->coordinate().x(), m_ui->positionEdit->coordinate().y(), 0.0);
|
||||
|
||||
qint64 fireRequestTime = m_ui->dteRequestTime->msecsSinceEpoch();
|
||||
int altitude = m_ui->sbAltitude->value();
|
||||
std::string purpose = m_ui->cbPurpose->currentText().toStdString();
|
||||
|
||||
if (m_type == etSingle)
|
||||
{
|
||||
const ExplosionSingleModifyRequest req(m_aesItem.id(),
|
||||
name,
|
||||
LtsUtils::toOptional(effectStart),
|
||||
m_aesItem.effectSourceId(),
|
||||
chargeType,
|
||||
pos,
|
||||
LtsUtils::toOptional(partyId),
|
||||
LtsUtils::toOptional(0), // PlayerId
|
||||
fireRequestTime,
|
||||
altitude,
|
||||
purpose,
|
||||
m_ui->cbEffectMarkingInTa->isChecked(),
|
||||
dds::core::optional<rti::core::int64>());
|
||||
|
||||
m_requestHelper->addRequest([this, req]()
|
||||
{
|
||||
return m_ftc->explosionSingleModifyRequest(req, this);
|
||||
});
|
||||
}
|
||||
else if (m_type == etArea) // area
|
||||
{
|
||||
const ExplosionAreaModifyRequest req(m_aesItem.id(),
|
||||
name,
|
||||
LtsUtils::toOptional(effectStart),
|
||||
duration,
|
||||
m_aesItem.effectSourceId(),
|
||||
chargeType,
|
||||
area,
|
||||
LtsUtils::toOptional(partyId),
|
||||
LtsUtils::toOptional(0), // PlayerId
|
||||
cannons,
|
||||
rounds,
|
||||
fireRequestTime,
|
||||
altitude,
|
||||
purpose,
|
||||
m_ui->cbEffectMarkingInTa->isChecked(),
|
||||
dds::core::optional<rti::core::int64>());
|
||||
m_requestHelper->addRequest([this, req]()
|
||||
{
|
||||
return m_ftc->explosionAreaModifyRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void ExplosionEdit::onFireClicked()
|
||||
{
|
||||
m_ui->pbFire->setEnabled(false);
|
||||
if ((m_aesItem.effectStateId() != AesEffectState_def::EsActivated &&
|
||||
m_aesItem.effectStateId() != AesEffectState_def::EsPaused &&
|
||||
m_aesItem.effectStateId() != AesEffectState_def::EsCreated &&
|
||||
m_aesItem.effectStateId() != AesEffectState_def::EsPrepared)
|
||||
|| m_aesItem.id() <= 0)
|
||||
return;
|
||||
|
||||
// Catches all single fires...
|
||||
if (m_aesItem.effectStateId() == AesEffectState_def::EsCreated ||
|
||||
m_aesItem.effectStateId() == AesEffectState_def::EsPrepared)
|
||||
{
|
||||
m_ui->dteEffectStart->setMsecsSinceEpoch(m_session->partitionTime() + 3000);
|
||||
m_ui->dteEffectStart->setChecked(true);
|
||||
// Todo: Triggering by simulated button press is a little awkward...
|
||||
if (m_uiRequirements->checkRequirements(this))
|
||||
this->m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->click();
|
||||
else
|
||||
m_ui->pbFire->setEnabled(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// No more single fires handled here...
|
||||
m_requestHelper->addRequest([ = ]()
|
||||
{
|
||||
return m_ftc->explosionAreaPauseResumeRequest(ExplosionAreaPauseResumeRequest(m_aesItem.id(),
|
||||
m_aesItem.effectStateId() != AesEffectState_def::EsActivated,
|
||||
dds::core::optional<rti::core::int64>(),
|
||||
dds::core::optional<int32_t>(),
|
||||
dds::core::optional<int32_t>())
|
||||
, this);
|
||||
});
|
||||
m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void ExplosionEdit::onParticipantClicked()
|
||||
{
|
||||
ParticipantManagement::ParticipantSelection *ps = new ParticipantManagement::ParticipantSelection(m_session, this);
|
||||
ps->init();
|
||||
ps->setParticipantSelected(m_participant.partyId(), m_participant.id());
|
||||
|
||||
connect(ps, &ParticipantManagement::ParticipantSelection::selectedParticipants, this, &ExplosionEdit::onParticipant);
|
||||
ps->exec();
|
||||
}
|
||||
|
||||
void ExplosionEdit::onParticipant(const QVector<int> &participants)
|
||||
{
|
||||
if (participants.isEmpty())
|
||||
return;
|
||||
|
||||
if (participants[0] == m_participant.id())
|
||||
return;
|
||||
m_participant = m_ppmDtc->participant(participants[0]);
|
||||
|
||||
m_symbolWatcher->setSymbolResult(m_asbIfc->findImage(m_participant));
|
||||
m_ui->lblDesignator->setText(QString::fromStdString(m_participant.designator()));
|
||||
m_ui->lblTactIdentifier->setText(QString::fromStdString(m_participant.tacticalIdentifier()));
|
||||
|
||||
// m_ui->lblParticipant->setText(participant.equipmentNumber().is_set() ? QString::number(participant.equipmentNumber().get()) : tr("Id: %1").arg(participant.id()));
|
||||
m_ui->cbParty->setCurrentIndex(m_ui->cbParty->findData(m_participant.partyId()));
|
||||
slotChangesMade();
|
||||
}
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Explosion Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Patric Karwat, SLSE, 2016-07-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_edit.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_gui_plugin_interface.h>
|
||||
|
||||
#include <AreaEffectSimulation/aes_ftc.h>
|
||||
#include <ProjectDataManagement/pdm.hpp>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ExplosionEdit;
|
||||
}
|
||||
|
||||
class QSpinBox;
|
||||
|
||||
namespace AdvancedSymbology {
|
||||
class SymbolResultWatcherLabel;
|
||||
class ForeignDataInterface;
|
||||
}
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
class ExplosionEdit final
|
||||
: public BaseEdit
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaModifyReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionSingleModifyReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaPauseResumeReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum ExplosionType
|
||||
{
|
||||
etSingle,
|
||||
etArea,
|
||||
etSingleCentral
|
||||
};
|
||||
|
||||
explicit ExplosionEdit(const QString &menuGroup, ExplosionType type, ProjectDataManagement::GearClass gc, QWidget *parent = nullptr);
|
||||
~ExplosionEdit();
|
||||
|
||||
bool init(int aesItemId, bool copy, LtsSession::LtsSession *session);
|
||||
QString dialogIdentifier() const override;
|
||||
|
||||
void onExplosionAreaModifyReply(const Core::FunctionReplyObject &replyObject) override final { onAesItemModifyReply(replyObject); }
|
||||
void onExplosionSingleModifyReply(const Core::FunctionReplyObject &replyObject) override final { onAesItemModifyReply(replyObject); }
|
||||
|
||||
void onExplosionAreaPauseResumeReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
void setFireButton(AesEffectState effectState);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
|
||||
static double s_minWidth;
|
||||
static double s_maxWidth;
|
||||
static double s_stepWidth;
|
||||
static double s_minHeight;
|
||||
static double s_maxHeight;
|
||||
static double s_stepHeight;
|
||||
static double s_minRadius;
|
||||
static double s_maxRadius;
|
||||
static double s_stepRadius;
|
||||
static int s_maxChargeUsage;
|
||||
static double s_minAltitude;
|
||||
static double s_maxAltitude;
|
||||
static qint64 s_maxDurationSeconds;
|
||||
|
||||
void setBaseData(const AesItem &baseData, bool copy);
|
||||
void setSingleData(const ExplosionSingle &singleData);
|
||||
void setAreaData(const ExplosionArea &areaData, bool copy = false);
|
||||
void enableUiElements(bool enable) override;
|
||||
int maxAvailableRounds() const;
|
||||
void updateCannonsRounds(bool modifiedFromExternal = false);
|
||||
void updateMaxLabel(bool modifiedFromExternal = false);
|
||||
quint32 partyForItem(const AesItem &aesItem) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void getPosition();
|
||||
void onMapRecData(const QPointF &bottomLeft, double width, double height, double angleDegNorth, const QPolygonF &bufferOutlinePolygon);
|
||||
void onCoordinate(const QPointF ¢erPoint);
|
||||
void onChargeTypeChanged();
|
||||
void onPartyChanged();
|
||||
bool apply() override final;
|
||||
void onFireClicked();
|
||||
void onParticipantClicked();
|
||||
void onCannonsChanged(int cannons, bool modifiedFromExternal = false);
|
||||
void onRoundsChanged(int rounds, bool modifiedFromExternal = false);
|
||||
void onChargeCountChanged(const AreaEffectSimulation::ChargeAdministration &data, DataModification modType);
|
||||
void showPreviewObject() override;
|
||||
|
||||
void onParticipant(const QVector<int> &participants);
|
||||
private:
|
||||
|
||||
struct Charges
|
||||
{
|
||||
ProjectDataManagement::ChargeType chargeType;
|
||||
QMap<int, int> available; // PartyId
|
||||
Charges() {}
|
||||
explicit Charges(const ProjectDataManagement::ChargeType &type) : chargeType(type) {}
|
||||
};
|
||||
|
||||
ExplosionType m_type;
|
||||
bool m_editable;
|
||||
ProjectDataManagement::GearClass m_gearClass;
|
||||
QPointF m_previewCircleCenter;
|
||||
double m_previewCircleRadius;
|
||||
QPolygonF m_previewPolygon;
|
||||
QMap<qint32, Charges> m_chargeTypeMap; // ChargeTypeId
|
||||
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> m_asbIfc;
|
||||
std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> m_pdmCbx;
|
||||
|
||||
AdvancedSymbology::SymbolResultWatcherLabel *m_symbolWatcher;
|
||||
ParticipantManagement::Participant m_participant;
|
||||
Ui::ExplosionEdit *m_ui;
|
||||
};
|
||||
|
||||
} //namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,506 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExplosionEdit</class>
|
||||
<widget class="QWidget" name="ExplosionEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>962</width>
|
||||
<height>322</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Aes Explosion Edit</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="7" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="sbCannons">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblOperatorB">
|
||||
<property name="text">
|
||||
<string notr="true">x</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="sbRounds">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblMaxCount">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>=0 (avail: 0)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4">
|
||||
<widget class="LtsWidgets::LtsDateTimeEdit" name="dteRequestTime" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="withButtons" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="withSlider" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="withReset" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblAltitude">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Altitude [m]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QLabel" name="lblChargeType">
|
||||
<property name="toolTip">
|
||||
<string>Only charges with available stock are visible</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Charge Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="sbAimingAxis"/>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QCheckBox" name="cbEffectMarkingInTa">
|
||||
<property name="text">
|
||||
<string>Fire marker</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="4">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbChargeType">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="currentText">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblFireRequest">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fire Request:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="6">
|
||||
<widget class="QLabel" name="lblEffectStart">
|
||||
<property name="text">
|
||||
<string>Impact Time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4">
|
||||
<widget class="QComboBox" name="cbPurpose"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="sbAltitude"/>
|
||||
</item>
|
||||
<item row="4" column="7">
|
||||
<widget class="QSpinBox" name="sbDurationSeconds">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1800</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblParty">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Firing Party:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLabel" name="lblRounds">
|
||||
<property name="text">
|
||||
<string>Cannons x Rounds:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="8">
|
||||
<widget class="QPushButton" name="pbFire">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fire</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/avm_start.svg</normaloff>:/style/avm_start.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QLabel" name="lblName">
|
||||
<property name="text">
|
||||
<string>Identifier:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLabel" name="lblDimension">
|
||||
<property name="text">
|
||||
<string>Dimension [m]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="7" colspan="2">
|
||||
<widget class="LtsWidgets::LtsDateTimeEdit" name="dteEffectStart" native="true">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checkable" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="withReset" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="9">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lblAimingAxis">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Aiming Axis [mil]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbDimensionX"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblOperatorA">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">x</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbDimensionY"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbParty">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="currentText">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblPosition">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="6">
|
||||
<widget class="QLabel" name="lblDuration">
|
||||
<property name="text">
|
||||
<string>Duration [s]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLabel" name="lblPurpose">
|
||||
<property name="text">
|
||||
<string>Purpose:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="LtsCoordWidget::LtsCoordWidget" name="positionEdit" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbPosition">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/position.svg</normaloff>:/style/position.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbClear">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/remove.svg</normaloff>:/style/remove.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="7" colspan="2">
|
||||
<widget class="QLineEdit" name="leIdentifier">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lbxFiringAngle">
|
||||
<property name="text">
|
||||
<string>Firing Angle:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QDoubleSpinBox" name="sbFiringAngle">
|
||||
<property name="maximum">
|
||||
<double>98.989999999999995</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QLabel" name="lbxIgniterType">
|
||||
<property name="text">
|
||||
<string>IgniterType</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="4">
|
||||
<widget class="QComboBox" name="cbIgniterType"/>
|
||||
</item>
|
||||
<item row="5" column="6">
|
||||
<widget class="QLabel" name="lbxParticipant">
|
||||
<property name="text">
|
||||
<string>Firing Participant:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="7">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblDesignator">
|
||||
<property name="text">
|
||||
<string notr="true">DESIG</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblIcon">
|
||||
<property name="text">
|
||||
<string notr="true">XXX</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblTactIdentifier">
|
||||
<property name="text">
|
||||
<string notr="true">TACT_ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="8">
|
||||
<widget class="QPushButton" name="pbParticipant">
|
||||
<property name="text">
|
||||
<string>Choose</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsCoordWidget::LtsCoordWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsCoordTrans/lts_coord_widget.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>LtsWidgets/lts_spinbox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDateTimeEdit</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_date_time_edit.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>cbParty</tabstop>
|
||||
<tabstop>dteRequestTime</tabstop>
|
||||
<tabstop>positionEdit</tabstop>
|
||||
<tabstop>pbPosition</tabstop>
|
||||
<tabstop>pbClear</tabstop>
|
||||
<tabstop>sbAltitude</tabstop>
|
||||
<tabstop>sbDimensionX</tabstop>
|
||||
<tabstop>sbDimensionY</tabstop>
|
||||
<tabstop>sbAimingAxis</tabstop>
|
||||
<tabstop>cbPurpose</tabstop>
|
||||
<tabstop>sbCannons</tabstop>
|
||||
<tabstop>sbRounds</tabstop>
|
||||
<tabstop>cbChargeType</tabstop>
|
||||
<tabstop>cbEffectMarkingInTa</tabstop>
|
||||
<tabstop>leIdentifier</tabstop>
|
||||
<tabstop>dteEffectStart</tabstop>
|
||||
<tabstop>sbDurationSeconds</tabstop>
|
||||
<tabstop>pbFire</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+385
@@ -0,0 +1,385 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for AreaEffectSimulation - Explosions
|
||||
* $Id: aes_explosion_gui_plugin.cpp 64799 2025-04-02 12:19:43Z kemayou_s $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/24_adler/Lts/Plugins/AreaEffectSimulation/Gui/Explosion/aes_explosion_gui_plugin.cpp $
|
||||
* $Author: kemayou_s $
|
||||
* Created by Patric Karwat, SLSE, 2016-07-05
|
||||
*/
|
||||
|
||||
#include "aes_explosion_gui_plugin.h"
|
||||
#include "aes_explosion_edit.h"
|
||||
#include "aes_explosion_list.h"
|
||||
#include "aes_explosions_edit.h"
|
||||
#include "aes_explosions_edit_adler.h"
|
||||
#include "aes_explosions_edit_adler_standalone.h"
|
||||
#include <QApplication>
|
||||
#include <AreaEffectSimulation/aes_operator_rights.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
#include <LtsWidgets/lts_events.h>
|
||||
#include <ProjectDataManagement/pdm_enums.hpp>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
const QString InterfaceImpl::s_ExplosionGuiScheme = QStringLiteral("ExplosionGui");
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session) { return std::make_shared<InterfaceImpl>(session); }
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: AesBaseInterface(session, getLogger("Plugins.Gui.Explosion"))
|
||||
, ForeignGuiInterface()
|
||||
{
|
||||
qApp->installEventFilter(this); // for link events
|
||||
}
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const bool enableSingleExplosionArtillery = ps->value(QStringLiteral("aes"), QStringLiteral("enableSingleExplosionArtillery")).toBool();
|
||||
|
||||
const bool enableCentralExplosionArtillery = ps->value(QStringLiteral("aes"), QStringLiteral("enableCentralExplosionArtillery")).toBool();
|
||||
|
||||
if (enableSingleExplosionArtillery)
|
||||
{
|
||||
// Single Explosion Artillery
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Single Artillery"),
|
||||
QLatin1String("ShowExplosionSingleArtillery"),
|
||||
QIcon(QLatin1String("icon:arti_ammunition_firings_single.svg")),
|
||||
[this](QWidget *parent) { return onShowExplosionListDialog(true, false, ProjectDataManagement::GearClass::Artillery, parent); },
|
||||
OperatorRights::SingleExplosionsShowArtillery,
|
||||
LtsWidgets::ExercisePart::eExecution));
|
||||
|
||||
if (m_session->isExercisePartition() && appId() != LtsAppDescriptor::App::OC)
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Add Single Artillery"),
|
||||
QLatin1String("AddExplosionSingleArtillery"),
|
||||
QIcon(QLatin1String("icon:arti_ammunition_firings_single_add.svg")),
|
||||
[this](QWidget *parent) { return onShowAddExplosionDialog(true, false, ProjectDataManagement::GearClass::Artillery, parent); },
|
||||
OperatorRights::SingleExplosionsShowArtillery,
|
||||
LtsWidgets::ExercisePart::eExecution,
|
||||
LtsWidgets::ExerciseState::eCreated | LtsWidgets::ExerciseState::eStarted | LtsWidgets::ExerciseState::ePaused));
|
||||
|
||||
// Single Explosion Central Artillery
|
||||
if (enableCentralExplosionArtillery)
|
||||
{
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Single Artillery Central"),
|
||||
QLatin1String("ShowExplosionSingleCentralArtillery"),
|
||||
QIcon(QLatin1String("icon:arti_ammunition_firings_single.svg")),
|
||||
[this](QWidget *parent) { return onShowExplosionListDialog(true, true, ProjectDataManagement::GearClass::Artillery, parent); },
|
||||
// OperatorRights::SingleExplosionsCentralShowArtillery,
|
||||
OperatorRights::SingleExplosionsShowArtillery,
|
||||
LtsWidgets::ExercisePart::eExecution));
|
||||
|
||||
if (m_session->isExercisePartition() && appId() != LtsAppDescriptor::App::OC)
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Add Single Artillery Central"),
|
||||
QLatin1String("AddExplosionSingleCentralArtillery"),
|
||||
QIcon(QLatin1String("icon:arti_ammunition_firings_single_add.svg")),
|
||||
[this](QWidget *parent) { return onShowAddExplosionDialog(true, true, ProjectDataManagement::GearClass::Artillery, parent); },
|
||||
// OperatorRights::SingleExplosionsCentralShowArtillery,
|
||||
OperatorRights::SingleExplosionsShowArtillery,
|
||||
LtsWidgets::ExercisePart::eExecution,
|
||||
LtsWidgets::ExerciseState::eCreated | LtsWidgets::ExerciseState::eStarted | LtsWidgets::ExerciseState::ePaused));
|
||||
}
|
||||
}
|
||||
|
||||
const bool enableSingleExplosionMortar = ps->value(QStringLiteral("aes"), QStringLiteral("enableSingleExplosionMortar")).toBool();
|
||||
|
||||
if (enableSingleExplosionMortar)
|
||||
{
|
||||
// Single Explosion Mortar
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Single Mortar"),
|
||||
QLatin1String("ShowExplosionSingleMortar"),
|
||||
QIcon(QLatin1String("icon:mortar_ammunition_firings.svg")),
|
||||
[this](QWidget *parent) { return onShowExplosionListDialog(true, false, ProjectDataManagement::GearClass::Mortar, parent); },
|
||||
OperatorRights::SingleExplosionsShowMortar,
|
||||
LtsWidgets::ExercisePart::eExecution));
|
||||
|
||||
if (m_session->isExercisePartition() && appId() != LtsAppDescriptor::App::OC)
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Add Single Mortar"),
|
||||
QLatin1String("AddExplosionSingleMortar"),
|
||||
QIcon(QLatin1String("icon:add_mortar_ammunition_firings_single.svg")),
|
||||
[this](QWidget *parent) { return onShowAddExplosionDialog(true, false, ProjectDataManagement::GearClass::Mortar, parent); },
|
||||
OperatorRights::SingleExplosionsEditMortar,
|
||||
LtsWidgets::ExercisePart::eExecution,
|
||||
LtsWidgets::ExerciseState::eCreated | LtsWidgets::ExerciseState::eStarted | LtsWidgets::ExerciseState::ePaused));
|
||||
}
|
||||
|
||||
// Air Support single fire (for GUEZ Nasat)
|
||||
if (m_logger.isDebugEnabled())
|
||||
{
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Single NASAT Impacts"),
|
||||
QLatin1String("ShowExplosionSingleAerial"),
|
||||
QIcon(QLatin1String("icon:mortar_ammunition_firings.svg")),
|
||||
[this](QWidget *parent) { return onShowExplosionListDialog(true, false, ProjectDataManagement::GearClass::AirSupport, parent); },
|
||||
OperatorRights::AirSupportShow,
|
||||
LtsWidgets::ExercisePart::eExecution));
|
||||
}
|
||||
|
||||
const bool enableAreaExplosionArtillery = ps->value(QStringLiteral("aes"), QStringLiteral("enableAreaExplosionArtillery")).toBool();
|
||||
|
||||
if (enableAreaExplosionArtillery)
|
||||
{
|
||||
// Area Explosion Artillery
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Area Artillery"),
|
||||
QLatin1String("ShowExplosionAreaArtillery"),
|
||||
QIcon(QLatin1String("icon:arti_ammunition_firings.svg")),
|
||||
[this](QWidget *parent) { return onShowExplosionListDialog(false, false, ProjectDataManagement::GearClass::Artillery, parent); },
|
||||
OperatorRights::AreaExplosionsShowArtillery,
|
||||
LtsWidgets::ExercisePart::eExecution));
|
||||
|
||||
if (m_session->isExercisePartition() && appId() != LtsAppDescriptor::App::OC)
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Add Area Artillery"),
|
||||
QLatin1String("AddExplosionAreaArtillery"),
|
||||
QIcon(QLatin1String("icon:arti_ammunition_firings_add.svg")),
|
||||
[this](QWidget *parent) { return onShowAddExplosionDialog(false, false, ProjectDataManagement::GearClass::Artillery, parent); },
|
||||
OperatorRights::AreaExplosionsEditArtillery,
|
||||
LtsWidgets::ExercisePart::eExecution,
|
||||
LtsWidgets::ExerciseState::eCreated | LtsWidgets::ExerciseState::eStarted | LtsWidgets::ExerciseState::ePaused));
|
||||
}
|
||||
|
||||
const bool enableAreaExplosionMortar = ps->value(QStringLiteral("aes"), QStringLiteral("enableAreaExplosionMortar")).toBool();
|
||||
|
||||
if (enableAreaExplosionMortar)
|
||||
{
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Area Mortar"),
|
||||
QLatin1String("ShowExplosionAreaMortar"),
|
||||
QIcon(QLatin1String("icon:mortar_ammunition_firings.svg")),
|
||||
[this](QWidget *parent) { return onShowExplosionListDialog(false, false, ProjectDataManagement::GearClass::Mortar, parent); },
|
||||
OperatorRights::AreaExplosionsShowMortar,
|
||||
LtsWidgets::ExercisePart::eExecution));
|
||||
|
||||
if (m_session->isExercisePartition() && appId() != LtsAppDescriptor::App::OC)
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Add Area Mortar"),
|
||||
QLatin1String("AddExplosionAreaMortar"),
|
||||
QIcon(QLatin1String("icon:add_mortar_ammunition_firings.svg")),
|
||||
[this](QWidget *parent) { return onShowAddExplosionDialog(false, false, ProjectDataManagement::GearClass::Mortar, parent); },
|
||||
OperatorRights::AreaExplosionsEditMortar,
|
||||
LtsWidgets::ExercisePart::eExecution,
|
||||
LtsWidgets::ExerciseState::eCreated | LtsWidgets::ExerciseState::eStarted | LtsWidgets::ExerciseState::ePaused));
|
||||
}
|
||||
|
||||
const bool enableExplosionCluster = ps->value(QStringLiteral("aes"), QStringLiteral("enableExplosionCluster")).toBool();
|
||||
if (enableExplosionCluster)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ShowExplosionClusterArtillery";
|
||||
// Explosions / ExplosionCluster
|
||||
// ListView:
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Artillery"),
|
||||
QStringLiteral("ShowExplosionClusterArtillery"),
|
||||
QIcon(QStringLiteral("icon:mortar_ammunition_firings.svg")),
|
||||
[this](QWidget *parent) { return onShowExplosionClusterListDialog(parent); },
|
||||
OperatorRights::ExplosionShowCluster,
|
||||
LtsWidgets::ExercisePart::eExecution));
|
||||
|
||||
if (m_session->isExercisePartition() && appId() != LtsAppDescriptor::App::OC)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onShowAddExplosionClusterDialog";
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Add Artillery"),
|
||||
QStringLiteral("AddExplosionClusterArtillery"),
|
||||
QIcon(QStringLiteral("icon:arti_ammunition_firings_add.svg")),
|
||||
[this](QWidget *parent) { return onShowAddExplosionClusterDialog(parent); },
|
||||
OperatorRights::ExplosionEditCluster,
|
||||
LtsWidgets::ExercisePart::eExecution,
|
||||
LtsWidgets::ExerciseState::eCreated | LtsWidgets::ExerciseState::eStarted | LtsWidgets::ExerciseState::ePaused));
|
||||
DEBUG_LOG(m_logger) << "onShowAddExplosionAdlerDialog";
|
||||
ret.append(LtsWidgets::PluginData(
|
||||
menuGroup(),
|
||||
tr("Add ADLER Artillery"),
|
||||
QStringLiteral("AddAdlerArtillery"),
|
||||
QIcon(QStringLiteral("icon:arti_ammunition_firings_add.svg")),
|
||||
[this](QWidget *parent) { return onShowAddExplosionAdlerStandAloneDialog(parent); },
|
||||
OperatorRights::AdlerExplosionClusterEdit,
|
||||
LtsWidgets::ExercisePart::eExecution,
|
||||
LtsWidgets::ExerciseState::eCreated | LtsWidgets::ExerciseState::eStarted | LtsWidgets::ExerciseState::ePaused));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
AreaEffectSimulation::BaseEdit *InterfaceImpl::showEditWindow(int aesEntityId, bool isSingle, bool isCentral, ProjectDataManagement::GearClass gc, QWidget *parent)
|
||||
{
|
||||
ExplosionEdit *editWidget
|
||||
= new ExplosionEdit(menuGroup(), isSingle ? (isCentral ? ExplosionEdit::etSingleCentral : ExplosionEdit::etSingle) : ExplosionEdit::etArea, gc, parent);
|
||||
if (editWidget->init(aesEntityId, false, m_session))
|
||||
return editWidget;
|
||||
|
||||
delete editWidget;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BaseEdit *InterfaceImpl::showEditWindow(int aesEntityId, ProjectDataManagement::EffectSource effectSource, QWidget *parent)
|
||||
{
|
||||
switch (effectSource.underlying())
|
||||
{
|
||||
case ProjectDataManagement::EffectSource::ES_ADLER_STANDALONE:
|
||||
{
|
||||
ExplosionsEditAdlerStandAlone *editWidget = new ExplosionsEditAdlerStandAlone(menuGroup(), parent);
|
||||
if (editWidget->init(aesEntityId, false, m_session))
|
||||
return editWidget;
|
||||
|
||||
delete editWidget;
|
||||
return nullptr;
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::EffectSource::ES_ADLER:
|
||||
{
|
||||
ExplosionsEditAdler *editWidget = new ExplosionsEditAdler(menuGroup(), parent);
|
||||
if (editWidget->init(aesEntityId, false, m_session))
|
||||
return editWidget;
|
||||
|
||||
delete editWidget;
|
||||
return nullptr;
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::EffectSource::ES_Internal:
|
||||
case ProjectDataManagement::EffectSource::ES_HLA:
|
||||
{
|
||||
ExplosionsEdit *editWidget = new ExplosionsEdit(menuGroup(), parent);
|
||||
if (editWidget->init(aesEntityId, false, m_session))
|
||||
return editWidget;
|
||||
|
||||
delete editWidget;
|
||||
return nullptr;
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::EffectSource::ES_Unknown:
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Unknow EffectSource";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowAddExplosionDialog(bool isSingle, bool isCentral, ProjectDataManagement::GearClass gc, QWidget *parent)
|
||||
{
|
||||
ExplosionEdit *editWidget
|
||||
= new ExplosionEdit(menuGroup(), isSingle ? (isCentral ? ExplosionEdit::etSingleCentral : ExplosionEdit::etSingle) : ExplosionEdit::etArea, gc, parent);
|
||||
if (editWidget->init(0, false, m_session))
|
||||
return editWidget;
|
||||
|
||||
delete editWidget;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowExplosionListDialog(bool isSingle, bool /*isCentral*/, ProjectDataManagement::GearClass gc, QWidget *parent)
|
||||
{
|
||||
ExplosionList *listWidget;
|
||||
if (isSingle)
|
||||
listWidget = new ExplosionSingleList(menuGroup(), gc, parent);
|
||||
else
|
||||
listWidget = new ExplosionAreaList(menuGroup(), gc, parent);
|
||||
|
||||
if (listWidget->init(m_session))
|
||||
return listWidget;
|
||||
|
||||
delete listWidget;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowAddExplosionClusterDialog(QWidget *parent)
|
||||
{
|
||||
ExplosionsEdit *editWidget = new ExplosionsEdit(menuGroup(), parent);
|
||||
if (editWidget->init(0, false, m_session))
|
||||
return editWidget;
|
||||
|
||||
delete editWidget;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowAddExplosionAdlerStandAloneDialog(QWidget *parent)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onShowAddExplosionAdlerStandAloneDialog";
|
||||
ExplosionsEditAdlerStandAlone *editWidget = new ExplosionsEditAdlerStandAlone(menuGroup(), parent);
|
||||
if (editWidget->init(0, false, m_session))
|
||||
return editWidget;
|
||||
|
||||
delete editWidget;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowExplosionClusterListDialog(QWidget *parent)
|
||||
{
|
||||
ExplosionList *listWidget;
|
||||
|
||||
listWidget = new ExplosionClusterList(menuGroup(),
|
||||
{ProjectDataManagement::GearClass_def::Artillery,
|
||||
ProjectDataManagement::GearClass_def::Mortar,
|
||||
ProjectDataManagement::GearClass_def::Rocket},
|
||||
parent);
|
||||
|
||||
if (listWidget->init(m_session))
|
||||
return listWidget;
|
||||
|
||||
delete listWidget;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool InterfaceImpl::eventFilter(QObject *obj, QEvent *event) // show dialogs dialog on clicked link
|
||||
{
|
||||
if (obj == qApp && !event->isAccepted() && event->type() == LtsWidgets::LtsLinkEvent::eventTypeId())
|
||||
{
|
||||
auto ev = static_cast<LtsWidgets::LtsLinkEvent *>(event);
|
||||
|
||||
const auto isChildOfSession = [this](QWidget *w)
|
||||
{
|
||||
if (!w)
|
||||
return true;
|
||||
auto baseLayout = m_session->baseLayout();
|
||||
return baseLayout->isAncestorOf(w);
|
||||
};
|
||||
if (isChildOfSession(ev->sourceBaseLayoutWidget()) && ev->url().host() == s_ExplosionGuiScheme.toLower())
|
||||
{
|
||||
bool ok = false;
|
||||
ERROR_LOG(m_logger) << ev->url().path();
|
||||
const QStringList params = ev->url().path().split(QStringLiteral("/"));
|
||||
if (params.size() < 2)
|
||||
return QObject::eventFilter(obj, event);
|
||||
ERROR_LOG(m_logger) << "DIalog Name " << params.at(1) << " aesId " << params.at(2);
|
||||
QString dialogName = params.at(1);
|
||||
int aesId = params.at(2).toInt(&ok);
|
||||
if (ok)
|
||||
{
|
||||
ExplosionsEditAdler *dlg = new ExplosionsEditAdler(menuGroup(), m_session->baseLayout());
|
||||
if (dlg->init(aesId, false, m_session))
|
||||
m_session->addWidget(dlg, menuGroup(), dlg->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
|
||||
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for AreaEffectSimuation - Explosions
|
||||
* $Id: aes_explosion_gui_plugin.h 62538 2024-04-23 06:13:45Z karwat $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/24_adler/Lts/Plugins/AreaEffectSimulation/Gui/Explosion/aes_explosion_gui_plugin.h $
|
||||
* $Author: karwat $
|
||||
* Created by Patric Karwat, SLSE, 2016-07-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_gui_plugin.h>
|
||||
#include "aes_explosion_gui_plugin_interface.h"
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
class GuiPlugin final : public AesBaseGuiPlugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:aes.explosions")
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QStringLiteral("AreaEffectSimuationExplosionGui"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return partition == IDL::PartitionType::Exercise ||
|
||||
partition == IDL::PartitionType::Replay;
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public AesBaseInterface, public AesExplosion::ForeignGuiInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
|
||||
AreaEffectSimulation::BaseEdit *showEditWindow(int aesEntityId, bool isSingle, bool isCentral, ProjectDataManagement::GearClass gc, QWidget *parent) override;
|
||||
AreaEffectSimulation::BaseEdit *showEditWindow(int aesEntityId, ProjectDataManagement::EffectSource effectSource, QWidget *parent) override; // ExplosionCluster
|
||||
|
||||
private:
|
||||
LtsWidgets::LtsDialog *onShowAddExplosionDialog(bool isSingle, bool isCentral, ProjectDataManagement::GearClass gc, QWidget *parent);
|
||||
LtsWidgets::LtsDialog *onShowExplosionListDialog(bool isSingle, bool, ProjectDataManagement::GearClass gc, QWidget *parent);
|
||||
|
||||
LtsWidgets::LtsDialog *onShowAddExplosionClusterDialog(QWidget *parent);
|
||||
|
||||
LtsWidgets::LtsDialog *onShowExplosionClusterListDialog(QWidget *parent);
|
||||
LtsWidgets::LtsDialog *onShowAddExplosionAdlerStandAloneDialog(QWidget *parent);
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *event) override; // show dialogs dialog on clicked link
|
||||
|
||||
static const QString s_ExplosionGuiScheme;
|
||||
|
||||
};
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for AreaEffectSimulation (Interface for access from other Plugins)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Patric Karwat, SLSE, 2016-07-01
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ProjectDataManagement/pdm_enums.hpp>
|
||||
|
||||
class QWidget;
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
class BaseEdit;
|
||||
}
|
||||
|
||||
namespace AesExplosion
|
||||
{
|
||||
class ForeignGuiInterface
|
||||
{
|
||||
public:
|
||||
ForeignGuiInterface() = default;
|
||||
virtual ~ForeignGuiInterface() = default;
|
||||
|
||||
virtual AreaEffectSimulation::BaseEdit *showEditWindow(int aesEntityId, bool isSingle, bool isCentral, ProjectDataManagement::GearClass gc, QWidget *parent) = 0;
|
||||
virtual AreaEffectSimulation::BaseEdit *showEditWindow(int aesEntityId, ProjectDataManagement::EffectSource effectSource, QWidget *parent) = 0; // ExplosionCluster
|
||||
|
||||
};
|
||||
} // namespace AesExplosion
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Explosion Overview Dialog
|
||||
* $Id: aes_explosion_list.cpp 64525 2025-02-14 12:35:41Z fritsche_h $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/features/24_adler/Lts/Plugins/AreaEffectSimulation/Gui/Explosion/aes_explosion_list.cpp $
|
||||
* $Author: fritsche_h $
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "aes_explosion_list.h"
|
||||
#include "CustomView/aes_explosion.h"
|
||||
#include "aes_effect_cluster_model.h"
|
||||
#include "aes_explosion_edit.h"
|
||||
#include "aes_explosions_area_model.h"
|
||||
#include "aes_explosions_edit.h"
|
||||
#include "aes_explosions_edit_adler.h"
|
||||
#include "aes_explosions_edit_adler_standalone.h"
|
||||
#include "aes_explosions_single_model.h"
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
ExplosionList::ExplosionList(const QString &menuGroup, ExplosionType type, ProjectDataManagement::GearClass gc, QWidget *parent)
|
||||
: AesItemList(menuGroup, parent), m_type(type), m_gearClass(gc)
|
||||
{
|
||||
}
|
||||
|
||||
bool ExplosionList::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
if (!AesItemList::init(session))
|
||||
return false;
|
||||
|
||||
m_bHasAddEditOperatorRights = false;
|
||||
switch (m_gearClass.underlying())
|
||||
{
|
||||
case ProjectDataManagement::GearClass::Artillery:
|
||||
|
||||
// switch per m_type :
|
||||
switch (m_type)
|
||||
{
|
||||
case etSingle:
|
||||
m_bHasAddEditOperatorRights = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsEditArtillery);
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Single_Artillery"));
|
||||
m_windowTitle = tr("Single Artillery");
|
||||
break;
|
||||
case etArea:
|
||||
m_bHasAddEditOperatorRights = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::AreaExplosionsEditArtillery);
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Area_Artillery"));
|
||||
m_windowTitle = tr("Area Artillery");
|
||||
break;
|
||||
case etExplosionCluster:
|
||||
{
|
||||
m_bHasAddAdlerOperatorRights = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::AdlerExplosionClusterEdit);
|
||||
m_bHasAddEditOperatorRights = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::ExplosionEditCluster);
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Cluster_Artillery"));
|
||||
m_windowTitle = tr("Artillery");
|
||||
|
||||
if (m_bHasAddAdlerOperatorRights)
|
||||
{
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load, this, &ExplosionList::onAddAdlerAes);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setVisible(m_bHasAddAdlerOperatorRights);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
} // switch
|
||||
// : switch per m_type
|
||||
|
||||
break;
|
||||
case ProjectDataManagement::GearClass::Mortar:
|
||||
m_bHasAddEditOperatorRights = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SingleExplosionsEditMortar) && m_type == etSingle)
|
||||
|| (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::AreaExplosionsEditMortar) && m_type == etArea);
|
||||
if (m_type == etSingle) // Single Mortar
|
||||
{
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Single_Mortar"));
|
||||
m_windowTitle = tr("Single Mortar");
|
||||
}
|
||||
else if (m_type == etArea) // Area Mortar
|
||||
{
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Area_Mortar"));
|
||||
m_windowTitle = tr("Area Mortar");
|
||||
}
|
||||
break;
|
||||
case ProjectDataManagement::GearClass::AirSupport:
|
||||
Q_ASSERT(m_type == etSingle);
|
||||
// NLDEVCTRL-1727
|
||||
// aes_explosion_gui_plugin.cpp:118 -> just debug -> no setOnlineHelpFilename required:
|
||||
// just debug: setOnlineHelpFilename(QStringLiteral("Situation-Single_Fire_Air_Support")); // former Situation-Single Aerial Ordnance
|
||||
m_windowTitle = tr("Single Fire Air Support");
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
setDataViewModel(model(), [this]() { return new CustomViewExplosion(m_session, this); });
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
hideColumn(ExplosionsSingleModel::BcId);
|
||||
#endif
|
||||
hideColumn(ExplosionsSingleModel::BcParticipant);
|
||||
|
||||
setSortIndicator(ExplosionsSingleModel::BcName);
|
||||
|
||||
enaDisa();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExplosionList::onAddAesItem()
|
||||
{
|
||||
if (m_type == etExplosionCluster)
|
||||
{
|
||||
ExplosionsEdit *dialog = new ExplosionsEdit(menuGroup(), this);
|
||||
const int aesItemId = model()->aesId(currentRow());
|
||||
if (dialog->init(aesItemId, aesItemId > 0, m_session))
|
||||
addDialog(dialog, m_menuGroup, dialog->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
|
||||
else
|
||||
delete dialog;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExplosionEdit *dialog = new ExplosionEdit(m_menuGroup, static_cast<ExplosionEdit::ExplosionType>(m_type), m_gearClass, this);
|
||||
|
||||
const int aesItemId = model()->aesId(currentRow());
|
||||
if (dialog->init(aesItemId, aesItemId > 0, m_session))
|
||||
addDialog(dialog, m_menuGroup, dialog->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
|
||||
else
|
||||
delete dialog;
|
||||
}
|
||||
}
|
||||
|
||||
void ExplosionList::onAddAdlerAes()
|
||||
{
|
||||
ExplosionsEditAdlerStandAlone *dialog = new ExplosionsEditAdlerStandAlone(m_menuGroup, this);
|
||||
|
||||
const int aesItemId = model()->aesId(currentRow());
|
||||
if (dialog->init(aesItemId, aesItemId > 0, m_session))
|
||||
addDialog(dialog, m_menuGroup, dialog->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
|
||||
else
|
||||
delete dialog;
|
||||
}
|
||||
|
||||
void ExplosionList::onEditAesItem()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "\n\nonEditAesItem ExplosionsEdit und ExplosionsEditAdler************************";
|
||||
const int aesItemId = model()->aesId(currentRow());
|
||||
|
||||
if (aesItemId <= 0)
|
||||
return;
|
||||
|
||||
ProjectDataManagement::EffectSource effectSource = model()->aesEffectSourceId(currentRow());
|
||||
|
||||
DEBUG_LOG(m_logger) << "current Aes Item Id: " << aesItemId;
|
||||
DEBUG_LOG(m_logger) << "current EffectSource " << effectSource;
|
||||
|
||||
if (m_type == etExplosionCluster)
|
||||
{
|
||||
if (effectSource == ProjectDataManagement::EffectSource::ES_ADLER)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Dialog ExplosionsEditAdler";
|
||||
ExplosionsEditAdler *dialog = new ExplosionsEditAdler(m_menuGroup, this);
|
||||
if (dialog->init(aesItemId, false, m_session))
|
||||
addDialog(dialog, m_menuGroup, dialog->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
|
||||
else
|
||||
delete dialog;
|
||||
}
|
||||
else if (effectSource == ProjectDataManagement::EffectSource::ES_ADLER_STANDALONE)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "new ExplosionsEditAdlerStandAlone *************************************";
|
||||
ExplosionsEditAdlerStandAlone *dialogAdler = new ExplosionsEditAdlerStandAlone(m_menuGroup, this);
|
||||
if (dialogAdler->init(aesItemId, false, m_session))
|
||||
{
|
||||
QString identifier = dialogAdler->dialogIdentifier();
|
||||
identifier.append(QStringLiteral("Adler StandAlone"));
|
||||
DEBUG_LOG(m_logger) << "addDialog identifier=" << identifier;
|
||||
addDialog(dialogAdler, m_menuGroup, identifier, LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
else
|
||||
delete dialogAdler;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExplosionsEdit *dialog = new ExplosionsEdit(m_menuGroup, this);
|
||||
if (dialog->init(aesItemId, false, m_session))
|
||||
addDialog(dialog, m_menuGroup, dialog->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
|
||||
else
|
||||
delete dialog;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExplosionEdit *dialog = new ExplosionEdit(m_menuGroup, static_cast<ExplosionEdit::ExplosionType>(m_type), m_gearClass, this);
|
||||
if (dialog->init(aesItemId, false, m_session))
|
||||
addDialog(dialog, m_menuGroup, dialog->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
|
||||
else
|
||||
delete dialog;
|
||||
}
|
||||
}
|
||||
|
||||
void ExplosionList::onRemoveAesItem()
|
||||
{
|
||||
Core::RemoveElementRequest req(model()->aesId(currentRow()));
|
||||
m_requestHelper->startSingleRequest(
|
||||
[req, this]()
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case etSingle:
|
||||
return m_ftc->explosionSingleRemoveRequest(req, this);
|
||||
break;
|
||||
case etArea:
|
||||
return m_ftc->explosionAreaRemoveRequest(req, this);
|
||||
break;
|
||||
case etExplosionCluster:
|
||||
{
|
||||
ProjectDataManagement::EffectSource effectSource = model()->aesEffectSourceId(currentRow());
|
||||
if (effectSource == ProjectDataManagement::EffectSource::ES_ADLER_STANDALONE)
|
||||
{
|
||||
return m_ftc->effectClusterRemoveRequest(req, this);
|
||||
}
|
||||
return m_ftc->explosionClusterRemoveRequest(req, this);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
} // switch
|
||||
return int64_t(0);
|
||||
});
|
||||
}
|
||||
|
||||
void ExplosionList::retranslate() { translateBase(m_windowTitle); }
|
||||
|
||||
void ExplosionList::onExplosionAreaRemoveReply(const Core::FunctionReplyObject &replyObject) { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
void ExplosionList::onExplosionSingleRemoveReply(const Core::FunctionReplyObject &replyObject) { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
void ExplosionList::onExplosionClusterRemoveReply(const Core::FunctionReplyObject &replyObject) { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
void ExplosionList::onEffectClusterRemoveReply(const Core::FunctionReplyObject &replyObject) { m_requestHelper->requestReply(replyObject); }
|
||||
//
|
||||
// ExplosionSingleList
|
||||
//
|
||||
ExplosionSingleList::ExplosionSingleList(const QString &menuGroup, ProjectDataManagement::GearClass gc, QWidget *parent)
|
||||
: ExplosionList(menuGroup, etSingle, gc, parent), m_model(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
bool ExplosionSingleList::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
if (!ExplosionList::init(session))
|
||||
return false;
|
||||
|
||||
// Single - keine Effect Duration
|
||||
hideColumn(ExplosionsSingleModel::BcEffectDuration);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExplosionSingleList::createModel()
|
||||
{
|
||||
m_model = new AesItemSortFilterProxyModelTmpl<ExplosionSingle>(m_session, this);
|
||||
|
||||
ExplosionsSingleModel *sourceModel = new ExplosionsSingleModel(m_gearClass, this);
|
||||
|
||||
sourceModel->initModel(m_session);
|
||||
m_model->setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
//
|
||||
// ExplosionAreaList
|
||||
//
|
||||
ExplosionAreaList::ExplosionAreaList(const QString &menuGroup, ProjectDataManagement::GearClass gc, QWidget *parent)
|
||||
: ExplosionList(menuGroup, etArea, gc, parent), m_model(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void ExplosionAreaList::createModel()
|
||||
{
|
||||
m_model = new AesItemSortFilterProxyModelTmpl<ExplosionArea>(m_session, this);
|
||||
|
||||
ExplosionsAreaModel *sourceModel = new ExplosionsAreaModel(m_gearClass, this);
|
||||
|
||||
sourceModel->initModel(m_session);
|
||||
m_model->setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
//
|
||||
// ExplosionClusterList
|
||||
//
|
||||
|
||||
ExplosionClusterList::ExplosionClusterList(const QString &menuGroup, const QVector<ProjectDataManagement::GearClass> &gcs, QWidget *parent)
|
||||
: ExplosionList(menuGroup, etExplosionCluster, ProjectDataManagement::GearClass_def::Artillery, parent), m_model(nullptr), m_gearClasses(gcs)
|
||||
{
|
||||
}
|
||||
|
||||
bool ExplosionClusterList::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
if (!ExplosionList::init(session))
|
||||
return false;
|
||||
|
||||
// ColLaunchVelocity is more or less requested velocity, value is transfered to calculatedFiringSpeed
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColLaunchVelocity);
|
||||
|
||||
if (m_session->app() == LtsAppDescriptor::App::OC)
|
||||
{
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColAnnotationString);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColCloudBase);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColLcAttack_Prf);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColLcTermination);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColTapTimepoint);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColDropAngle);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColLaunchAngleDeg);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColCalculatedFiringSpeed);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColCalculatedPeakHeight);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColCalculatedFlightDuration);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColOriginalPeakHeight);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColOriginalFlightDuration);
|
||||
hideColumn(EffectClusterModel::AdditionalColumns::ColZpElement);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExplosionClusterList::createModel()
|
||||
{
|
||||
m_model = new AesItemSortFilterProxyModelTmpl<EffectCluster>(m_session, this);
|
||||
|
||||
EffectClusterModel *sourceModel = new EffectClusterModel(m_gearClasses, this);
|
||||
|
||||
sourceModel->initModel(m_session);
|
||||
m_model->setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Explosion Overview Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_itemlist.h>
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_model.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
class ExplosionList : public AesItemList
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaRemoveReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionSingleRemoveReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionClusterRemoveReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::EffectClusterRemoveReplyHandler
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
bool init(LtsSession::LtsSession *session) override;
|
||||
|
||||
enum ExplosionType
|
||||
{
|
||||
etSingle,
|
||||
etArea,
|
||||
// etSingleCentral, // outdated
|
||||
etExplosionCluster
|
||||
};
|
||||
|
||||
protected:
|
||||
ExplosionList(const QString &menuGroup, ExplosionList::ExplosionType type, ProjectDataManagement::GearClass gc, QWidget *parent);
|
||||
|
||||
private slots:
|
||||
void onAddAesItem() override;
|
||||
void onEditAesItem() override;
|
||||
void onRemoveAesItem() override;
|
||||
void onAddAdlerAes();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void onExplosionAreaRemoveReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onExplosionSingleRemoveReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onExplosionClusterRemoveReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onEffectClusterRemoveReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
|
||||
ExplosionType m_type;
|
||||
|
||||
protected:
|
||||
ProjectDataManagement::GearClass m_gearClass;
|
||||
QString m_windowTitle;
|
||||
};
|
||||
|
||||
|
||||
class ExplosionSingleList final : public ExplosionList
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
public:
|
||||
ExplosionSingleList(const QString &menuGroup, ProjectDataManagement::GearClass gc, QWidget *parent = nullptr);
|
||||
bool init(LtsSession::LtsSession *session) override;
|
||||
protected:
|
||||
void createModel() override;
|
||||
AesItemSortFilterProxyModel *model() override { return m_model; }
|
||||
const AesItemSortFilterProxyModel *model() const override { return m_model; }
|
||||
|
||||
AesItemSortFilterProxyModelTmpl<ExplosionSingle> *m_model{nullptr};
|
||||
};
|
||||
|
||||
class ExplosionAreaList final : public ExplosionList
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExplosionAreaList(const QString &menuGroup, ProjectDataManagement::GearClass gc, QWidget *parent = nullptr);
|
||||
protected:
|
||||
void createModel() override;
|
||||
AesItemSortFilterProxyModel *model() override { return m_model; }
|
||||
const AesItemSortFilterProxyModel *model() const override { return m_model; }
|
||||
|
||||
AesItemSortFilterProxyModelTmpl<ExplosionArea> *m_model{nullptr};
|
||||
};
|
||||
|
||||
//
|
||||
// ExplosionClusterList
|
||||
//
|
||||
class ExplosionClusterList final : public ExplosionList
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExplosionClusterList(const QString &menuGroup, const QVector<ProjectDataManagement::GearClass> &gcs, QWidget *parent = nullptr);
|
||||
bool init(LtsSession::LtsSession *session) override;
|
||||
protected:
|
||||
void createModel() override;
|
||||
AesItemSortFilterProxyModel *model() override { return m_model; }
|
||||
const AesItemSortFilterProxyModel *model() const override { return m_model; }
|
||||
|
||||
AesItemSortFilterProxyModelTmpl<EffectCluster> *m_model{nullptr};
|
||||
QVector<ProjectDataManagement::GearClass> m_gearClasses;
|
||||
};
|
||||
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectManangement - Explosion Area Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "aes_explosions_area_model.h"
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
bool ExplosionsAreaModel::initModel(LtsSession::LtsSession *session)
|
||||
{
|
||||
updateEffectStateComboboxFilterData(true);
|
||||
|
||||
if (!AesGuiBaseModel::initModel(session))
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &Interface::Dtc::explosionAreaChanged,
|
||||
this, &ExplosionsAreaModel::onDataChanged);
|
||||
|
||||
fillAvailableChargeIds(m_gearClass);
|
||||
|
||||
m_aesDtc->explosionAreas([this](const ExplosionArea &item) { insertRow(item); });
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* ExplosionManangement - Explosion Area Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_model.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
/************ Abstract Class for Artillery and Mortar Explosion Area ***************/
|
||||
class ExplosionsAreaModel : public AesGuiBaseModel<ExplosionArea>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExplosionsAreaModel(ProjectDataManagement::GearClass gc, QObject *parent)
|
||||
: AesGuiBaseModel<ExplosionArea>(parent)
|
||||
, m_gearClass(gc)
|
||||
{}
|
||||
|
||||
bool initModel(LtsSession::LtsSession *session);
|
||||
ProjectDataManagement::GearClass gearClass() const { return m_gearClass; }
|
||||
|
||||
protected:
|
||||
ProjectDataManagement::GearClass m_gearClass;
|
||||
};
|
||||
|
||||
} //namespace AreaEffectSimulation
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Explosions Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Steve Tougnia, SLTE, 2023-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_edit.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_gui_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <Plugins/EffectShowManagement/esm_gui_combobox_plugin_interface.h>
|
||||
|
||||
#include <AreaEffectSimulation/aes_ftc.h>
|
||||
#include <ProjectDataManagement/pdm.hpp>
|
||||
|
||||
#include "LtsElevation/lts_elevation_manager.h"
|
||||
#include <ElevationMap/elevation_map_manager.h>
|
||||
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ExplosionsEdit;
|
||||
}
|
||||
|
||||
class QSpinBox;
|
||||
|
||||
namespace AdvancedSymbology {
|
||||
class SymbolResultWatcherLabel;
|
||||
class ForeignDataInterface;
|
||||
}
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
class ExplosionsEdit final
|
||||
: public BaseEdit
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaModifyReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionSingleModifyReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaPauseResumeReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionClusterModifyReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::ExplosionClusterPauseResumeReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = BaseEdit;
|
||||
|
||||
enum class FlighDurationOrPeakHeight
|
||||
{
|
||||
FDPH_flightDuration,
|
||||
FDPH_peakHeight
|
||||
};
|
||||
QString toString(FlighDurationOrPeakHeight val);
|
||||
|
||||
|
||||
explicit ExplosionsEdit(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~ExplosionsEdit();
|
||||
|
||||
bool init(int aesItemId, bool copy, LtsSession::LtsSession *session);
|
||||
|
||||
void setExplosionClusterData(const ExplosionCluster &ecData);
|
||||
|
||||
|
||||
QString dialogIdentifier() const override;
|
||||
|
||||
void onExplosionAreaModifyReply(const Core::FunctionReplyObject &replyObject) override final { onAesItemModifyReply(replyObject); }
|
||||
void onExplosionSingleModifyReply(const Core::FunctionReplyObject &replyObject) override final { onAesItemModifyReply(replyObject); }
|
||||
void onExplosionClusterModifyReply(const Core::FunctionReplyObject &replyObject) override final { onAesItemModifyReply(replyObject); }
|
||||
void onExplosionAreaPauseResumeReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onExplosionClusterPauseResumeReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
void onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &ecData, DataModification modType);
|
||||
void handleLaserPrecisionChargeType(const int chargeTypeId);
|
||||
QPointF centerOfFiringUnitGeo(int particpantUnitId);
|
||||
void showCenterOfFiringUnit(int particpantUnitId);
|
||||
|
||||
private Q_SLOTS:
|
||||
void showPreviewObject() override;
|
||||
bool isDataSufficiant();
|
||||
bool apply() override final;
|
||||
void onGeometrySelected(int explosionGeometryInt);
|
||||
void onFireClicked();
|
||||
void onGearClassChanged();
|
||||
void onPositionChanged(const QPointF &newGeoCoord);
|
||||
void onPartyChanged();
|
||||
void onChargeTypeChanged();
|
||||
void onIgniterTypeChanged();
|
||||
void onParticipantUnitChanged(int idx);
|
||||
void onParticipantUnitEntered();
|
||||
void onParticipantUnitLeaved();
|
||||
void onParticipantPositionChanged();
|
||||
void getPosition();
|
||||
void onCoordinate(const QPointF ¢erPoint);
|
||||
void onMapRecData(const QPointF &bottomLeft, double width, double height, double angleDegNorth, const QPolygonF &bufferOutlinePolygon);
|
||||
void onCircleData(const QPointF &position, double radius);
|
||||
void onPolylineData(const QPolygonF &polyline);
|
||||
void setCoord(const QPointF &coord);
|
||||
void onFirePurposeChanged();
|
||||
void onDropAngleChanged();
|
||||
void onWidthChanged(int width);
|
||||
void onAimingAxisChanged(int aimingAxis);
|
||||
void onLineP1Changed(const QPointF &point);
|
||||
void onLineP2Changed(const QPointF &point);
|
||||
|
||||
void onPeakHeigthChanged(int data);
|
||||
void onFlightDurationChanged(int data);
|
||||
|
||||
void onEffectDurationChanged(int value);
|
||||
|
||||
void switchTo(FlighDurationOrPeakHeight phfd);
|
||||
void setMinMaxConstraints(ExplosionsEdit::FlighDurationOrPeakHeight phfd, ProjectDataManagement::GearClass_def::type gearClass, int chargeTypeId);
|
||||
bool setValueAccordingContraints(int newValue, ExplosionsEdit::FlighDurationOrPeakHeight phfd);
|
||||
|
||||
bool isGuiVulcano();
|
||||
|
||||
void doCalculations(bool executeEnableUiElements = true);
|
||||
void onPartitionTimeChanged(qint64 newPartitionTimeMsec = 0);
|
||||
|
||||
private:
|
||||
friend class DoCalculationsExitGuard;
|
||||
static double s_minWidth;
|
||||
static double s_maxWidth;
|
||||
static double s_stepWidth;
|
||||
static double s_minHeight;
|
||||
static double s_maxHeight;
|
||||
static double s_stepHeight;
|
||||
static double s_minRadius;
|
||||
static double s_maxRadius;
|
||||
static double s_stepRadius;
|
||||
static int s_maxChargeUsage;
|
||||
static double s_minAltitude;
|
||||
static double s_maxAltitude;
|
||||
static qint64 s_maxDurationSeconds;
|
||||
static int s_dropAngleDown;
|
||||
static int s_dropAngleUp;
|
||||
|
||||
|
||||
void retranslate() override;
|
||||
void enableUiElements();
|
||||
void enableUiElements(bool enable) override;
|
||||
void enableUiFireButton();
|
||||
void fillParticipantUnit();
|
||||
void gatherParticipantUnits(const int &partyId, QHash<int/*superiorId*/, QSet<int> > &units) const;
|
||||
void fillParties();
|
||||
bool isValidParty(qint32 partyId);
|
||||
|
||||
void fillCharges();
|
||||
void fillGearClasses();
|
||||
int currentDropAngleDegree();
|
||||
void setDropAngleTo(double dropAngleDegree);
|
||||
double currentDropAngleRadiant();
|
||||
|
||||
private:
|
||||
bool isOnlyNameModifiable() const override;
|
||||
bool isSmoke();
|
||||
void updateActorComboBox(const Core::GeoPosition &coordGeo);
|
||||
|
||||
struct Charges
|
||||
{
|
||||
Charges() {}
|
||||
explicit Charges(const ProjectDataManagement::ChargeType &type) : chargeType(type) {}
|
||||
ProjectDataManagement::ChargeType chargeType;
|
||||
QMap<int, int> available; // PartyId
|
||||
};
|
||||
|
||||
QVector<ProjectDataManagement::GearClass> m_gearClassFilter;
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
|
||||
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> m_asbIfc;
|
||||
std::shared_ptr<EffectShowManagement::ForeignGuiComboboxInterface> m_esmActorCbx;
|
||||
std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> m_pdmCbx;
|
||||
|
||||
ExplosionCluster m_explosionClusterData;
|
||||
|
||||
QPointF m_coord;
|
||||
|
||||
// doCalculations will update following:
|
||||
struct temporaryData
|
||||
{
|
||||
qint64 m_estimatedFlightDurationMsec{-1};
|
||||
qint64 m_distanceFiringToTarget{-1};
|
||||
Core::GeoPosition m_idealTapAbsoluteGeoOut;
|
||||
QString m_remainingTimeStr;
|
||||
QString m_annotationStringFiring4Dlg;
|
||||
QStringList m_annotationString4Dlg;
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_estimatedFlightDurationMsec = -1;
|
||||
m_distanceFiringToTarget = -1;
|
||||
m_remainingTimeStr.clear();
|
||||
m_annotationStringFiring4Dlg.clear();
|
||||
m_annotationString4Dlg.clear();
|
||||
}
|
||||
} m_temporaryData;
|
||||
|
||||
void resetTempAndAnnotationStr();
|
||||
void addAnnotationStr(const QString &newAnno);
|
||||
void updateAnnotationStr();
|
||||
double getElevation(const double lon, const double lat) const;
|
||||
|
||||
|
||||
QMap<qint32, Charges> m_chargeTypeMap; // ChargeTypeId
|
||||
QPointF m_previewCircleCenter;
|
||||
double m_previewCircleRadius;
|
||||
QPolygonF m_previewPolygon;
|
||||
QButtonGroup *m_geometrieButtonGroup;
|
||||
AreaEffectSimulation::AesExplosionGeometry m_currentGeometry; // safe_enum is initialized by itself
|
||||
Ui::ExplosionsEdit *m_ui;
|
||||
bool m_initDone{false};
|
||||
QTimer *m_enableFireBtnTimer{nullptr};
|
||||
Core::GeoPosition m_coordGeo;
|
||||
LtsElevation::LTS_ELEVATION_MANAGER_TYPE m_elevationManager{nullptr};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
+1678
File diff suppressed because it is too large.
Load diff
+763
@@ -0,0 +1,763 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Explosions Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Steve Tougnia, SLTE, 2023-09-05
|
||||
*/
|
||||
|
||||
#include "aes_explosions_edit_adler.h"
|
||||
// #include "aes_explosions_edit_helper.h"
|
||||
#include "aes_effector.h"
|
||||
#include "ui_aes_explosions_edit_adler.h"
|
||||
|
||||
#include <Proxies/TrainingAreaBase/Plugins/AdlerJson/telegrams.h>
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_model.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <Services/AreaEffectSimulation/Utils/aes_helper.h>
|
||||
#include <Services/AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <Services/ParticipantManagement/ppm_translation.h>
|
||||
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <Services/AreaEffectSimulation/settings.h>
|
||||
|
||||
#include <Plugins/AdvancedSymbology/asb_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/Gui/ParticipantSelection/participant_selection.h>
|
||||
|
||||
#include <AreaEffectSimulation/aes_translation.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <ProjectDataManagement/pdm_translation.h>
|
||||
#include <Trajectory/trajectory_generator.h>
|
||||
#include <Trajectory/trajectory_helper.h>
|
||||
|
||||
#include <AssetManagement/asm_data_plugin_interface.h>
|
||||
#include <ExerciseManagement/exm_data_plugin_interface.h>
|
||||
#include <LtsElevation/lts_elevation_manager.h>
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QDateTime>
|
||||
#include <QHash>
|
||||
#include <QJsonDocument>
|
||||
#include <QSpinBox>
|
||||
#include <QTimer>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
static const char *const VALUE_VALID_PROPERTY_NAME = "VALUE_VALID";
|
||||
|
||||
/*!
|
||||
* \brief ExplosionsEditAdler::ExplosionsEditAdler
|
||||
* \param menuGroup
|
||||
* \param parent
|
||||
*/
|
||||
QString ExplosionsEditAdler::toString(ExplosionsEditAdler::FlighDurationOrPeakHeight val)
|
||||
{
|
||||
switch (val)
|
||||
{
|
||||
case ExplosionsEditAdler::FlighDurationOrPeakHeight::FDPH_flightDuration:
|
||||
return QStringLiteral("FDPH_flightDuration");
|
||||
break;
|
||||
case ExplosionsEditAdler::FlighDurationOrPeakHeight::FDPH_peakHeight:
|
||||
return QStringLiteral("FDPH_peakHeight");
|
||||
break;
|
||||
default:
|
||||
return QStringLiteral("PHFD_Unknow");
|
||||
break;
|
||||
}
|
||||
return QStringLiteral("PHFD_Unknow");
|
||||
}
|
||||
|
||||
// Maximaler Winkel fuer untere Winkelgruppe
|
||||
static double maxAngleUW = 45.0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class ExplosionsEditAdler
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExplosionsEditAdler::ExplosionsEditAdler(const QString &menuGroup, QWidget *parent)
|
||||
: BaseEdit(menuGroup, QStringLiteral("ExplosionsEditAdler"), parent)
|
||||
, m_ui(new Ui::ExplosionsEditAdler)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_geometrieButtonGroup = new QButtonGroup(this);
|
||||
m_geometrieButtonGroup->addButton(m_ui->geometrieAimPointBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgAimPoint));
|
||||
m_geometrieButtonGroup->addButton(m_ui->geometrieAreaBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgArea));
|
||||
m_geometrieButtonGroup->addButton(m_ui->geometrieLineBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgLine));
|
||||
m_geometrieButtonGroup->addButton(m_ui->geometriePointBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgPoint));
|
||||
m_geometrieButtonGroup->addButton(m_ui->geometrieRadialBtn, static_cast<int>(AreaEffectSimulation::AesExplosionGeometry_def::EgRadial));
|
||||
m_geometrieButtonGroup->setExclusive(true);
|
||||
|
||||
m_gearClassFilter = {ProjectDataManagement::GearClass::Artillery, ProjectDataManagement::GearClass::Mortar};
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const bool enableRocket = ps->value(QStringLiteral("aes"), QStringLiteral("enableRocket"), false).toBool();
|
||||
if (enableRocket)
|
||||
m_gearClassFilter += ProjectDataManagement::GearClass::Rocket;
|
||||
|
||||
m_uiRequirements->addRequirement(
|
||||
{m_ui->lbxActors,
|
||||
[this]() { return ((m_ui->gbEffectMarkingInTa->isChecked() && m_ui->cbActors->currentData().toInt() > 0) || !m_ui->gbEffectMarkingInTa->isChecked()); }});
|
||||
|
||||
connect(m_ui->pbClear, &QPushButton::clicked, m_ui->positionEdit, &LtsCoordWidget::LtsCoordWidget::clear);
|
||||
|
||||
// "Einschießen" is hidden for now
|
||||
m_ui->lblFire->hide();
|
||||
m_ui->einschlJaBtn->hide();
|
||||
m_ui->einschlNoBtn->hide();
|
||||
|
||||
// "Wirkungsfeuer" is hidden for now
|
||||
m_ui->lblFire_2->hide();
|
||||
m_ui->wirkungJaBtn->hide();
|
||||
m_ui->wirkungNoBtn->hide();
|
||||
|
||||
// DMF EffectMarkingInTa hide currently always true
|
||||
// m_ui->cbEffectMarkingInTa->hide();
|
||||
|
||||
m_ui->rbAngleGroupLower->setChecked(true);
|
||||
// disable Tab Additional/Charge for now
|
||||
m_ui->tabWidget->setTabEnabled(1, false);
|
||||
m_ui->tabWidget->setTabEnabled(2, false);
|
||||
|
||||
m_ui->pbStateChange->hide();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief ExplosionsEditAdler::~ExplosionsEditAdler
|
||||
*/
|
||||
ExplosionsEditAdler::~ExplosionsEditAdler()
|
||||
{
|
||||
if (m_sitMapGuiIfc)
|
||||
m_sitMapGuiIfc->removeObjectIndicator();
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief AreaEffectSimulation::ExplosionsEditAdler::init
|
||||
* \param aesItemId
|
||||
* \param session
|
||||
* \return
|
||||
*/
|
||||
bool ExplosionsEditAdler::init(int aesItemId, bool copy, LtsSession::LtsSession *session)
|
||||
{
|
||||
|
||||
Q_UNUSED(copy)
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!BaseEdit::init(aesItemId, session))
|
||||
return false;
|
||||
|
||||
if (!m_session->getForeignDataInterface<AdvancedSymbology::DataInterface>(m_asbIfc))
|
||||
return false;
|
||||
|
||||
if (!session->getForeignGuiInterface(m_esmActorCbx))
|
||||
return false;
|
||||
|
||||
// P _D_ M
|
||||
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(m_pdmDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << " failed to get pdmDtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_session->getForeignGuiInterface<ProjectDataManagement::ForeignGuiInterface>(m_pdmCbx))
|
||||
return false;
|
||||
|
||||
m_pdmDtc->waitForHistoricalDataChargeType(1000);
|
||||
m_pdmDtc->waitForHistoricalDataGearType(1000);
|
||||
m_pdmDtc->waitForHistoricalDataGearTypeChargeType(1000);
|
||||
m_dtc->waitForHistoricalDataExplosionCluster(1000);
|
||||
m_ftc->enableAcknowledgeExternalAesItem();
|
||||
|
||||
// P _P_ M
|
||||
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << " failed to get ppmDtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aesItemId > 0)
|
||||
{
|
||||
const EffectCluster &ecData = m_dtc->effectCluster(aesItemId);
|
||||
DEBUG_LOG(m_logger) << "chargeTypeId: " << ecData.chargeStruct().chargeTypeId();
|
||||
m_effectClusterData = ecData;
|
||||
setEffectClusterData(ecData);
|
||||
|
||||
setPbStateChangeName();
|
||||
m_ui->gbEffectMarkingInTa->setChecked(m_aesItem.effectMarkingInTa()); // always true for explosion cluster
|
||||
}
|
||||
|
||||
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::effectClusterChanged, this, &ExplosionsEditAdler::onEffectClusterChanged, Qt::UniqueConnection);
|
||||
|
||||
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::effectorChanged, this, &ExplosionsEditAdler::onEffectorChanged);
|
||||
|
||||
connect(m_ui->pbStateChange, &QPushButton::clicked, this, &ExplosionsEditAdler::onPbStateChangeClicked);
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Add_Cluster_Artillery_AdlerVerbund.md"));
|
||||
|
||||
m_initDone = true;
|
||||
|
||||
enableUiElements();
|
||||
m_ui->dteEffectStart->setEnabled(false);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief ExplosionsEditAdlerStandAlone::showPreviewObject
|
||||
*/
|
||||
void ExplosionsEditAdler::showPreviewObject()
|
||||
{
|
||||
if (!has2DMap(false)) // showMsgBoxIfNot2D
|
||||
return;
|
||||
|
||||
switch (m_currentGeometry.underlying())
|
||||
{
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgArea:
|
||||
if (m_previewPolygon.isEmpty())
|
||||
return;
|
||||
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, m_previewPolygon, true);
|
||||
return;
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgAimPoint:
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgPoint:
|
||||
if (m_previewCircleCenter.isNull())
|
||||
return;
|
||||
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, m_previewPolygon, false);
|
||||
return;
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgRadial:
|
||||
if (m_previewCircleCenter.isNull())
|
||||
return;
|
||||
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, m_previewCircleCenter, m_previewCircleRadius);
|
||||
return;
|
||||
default:
|
||||
WARNING_LOG(m_logger) << " Unknown Geometry!";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool ExplosionsEditAdler::isDataSufficiant()
|
||||
{
|
||||
// identifier:
|
||||
if (m_ui->lblZpNumber->text().isEmpty())
|
||||
return false;
|
||||
|
||||
// originator:
|
||||
bool hasParticipant = !m_ui->lblParticipantUnits->text().isEmpty();
|
||||
if (!hasParticipant)
|
||||
return false;
|
||||
|
||||
// target:
|
||||
bool bHasTargetArea = !m_coord.isNull();
|
||||
switch (m_currentGeometry.underlying())
|
||||
{
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgArea:
|
||||
bHasTargetArea &= m_ui->lblDimensionYDepth->text().toInt() > 0;
|
||||
bHasTargetArea &= m_ui->lblWidthRadius->text().toInt() > 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!bHasTargetArea)
|
||||
return false;
|
||||
|
||||
// ammo
|
||||
const bool bHasAmmo = !m_ui->lblChargeType->text().isEmpty();
|
||||
if (!bHasAmmo)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::setEffectClusterData(const EffectCluster &ecData)
|
||||
{
|
||||
m_aesItem = ecData;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, ecData=" << ecData;
|
||||
|
||||
m_ui->lblZpNumber->setText(QString::fromStdString(ecData.name()));
|
||||
|
||||
qint64 effectStart = 0;
|
||||
|
||||
if (ecData.effectStart().is_set())
|
||||
{
|
||||
const QJsonObject propsObj(QJsonDocument::fromJson(QByteArray::fromStdString(ecData.properties())).object());
|
||||
const FiringType firingType = static_cast<FiringType::inner_enum>(propsObj[AdlerJson::JsonKeys::ABFEUERUNGSART()].toInt());
|
||||
|
||||
effectStart = ecData.effectStart().get();
|
||||
|
||||
if (firingType == FiringType::FireWithIndicationTTF)
|
||||
effectStart -= ecData.effectors().size() ? ecData.effectors().at(0).flightTime() : 0;
|
||||
}
|
||||
|
||||
m_ui->dteEffectStart->setMsecsSinceEpoch(effectStart);
|
||||
|
||||
// Geometry/Area
|
||||
const AreaEffectSimulation::AesExplosionGeometry_def::type geometryType = ecData.explosionGeometry().underlying();
|
||||
switch (geometryType)
|
||||
{
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgAimPoint:
|
||||
m_ui->geometrieAimPointBtn->setChecked(true);
|
||||
break;
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgPoint:
|
||||
m_ui->geometriePointBtn->setChecked(true);
|
||||
break;
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgArea:
|
||||
m_ui->geometrieAreaBtn->setChecked(true);
|
||||
break;
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgLine:
|
||||
m_ui->geometrieLineBtn->setChecked(true);
|
||||
break;
|
||||
case AreaEffectSimulation::AesExplosionGeometry_def::EgRadial:
|
||||
m_ui->geometrieRadialBtn->setChecked(true);
|
||||
break;
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
} // switch
|
||||
|
||||
if (ecData.effectDuration() == DEFAULT_EFFECT_DURATION)
|
||||
m_ui->lblDuration->setText(QStringLiteral("---"));
|
||||
else
|
||||
m_ui->lblDuration->setText(QString::number(ecData.effectDuration() / 1000)); // msecs -> secs
|
||||
|
||||
// 1st GearClass
|
||||
ProjectDataManagement::GearClass gc = m_pdmDtc->gearClassFromChargeTypeId(ecData.chargeStruct().chargeTypeId());
|
||||
m_ui->lblGearClass->setText(ProjectDataManagement::toString(gc));
|
||||
|
||||
// 2nd Party
|
||||
if (ecData.partyId().is_set())
|
||||
m_ui->lblParty->setText(ParticipantManagement::trPartyName(m_ppmDtc->party(ecData.partyId().get()).name()));
|
||||
|
||||
// 3rd Originator
|
||||
if (ecData.participantId().is_set())
|
||||
m_ui->lblParticipantUnits->setText(QString::fromStdString(m_ppmDtc->participant(ecData.participantId().get()).name()));
|
||||
|
||||
m_ui->lblChargeType->setText(m_pdmDtc->adlerChargeTypeName(ecData.chargeStruct().chargeTypeId()));
|
||||
m_ui->lblIgniterType->setText(m_pdmDtc->adlerIgniterTypeName(ecData.chargeStruct().igniterTypeId()));
|
||||
m_ui->lblIgniterFunction->setText(m_pdmDtc->adlerIgniterFunctionName(ecData.chargeStruct().igniterFunctionId()));
|
||||
|
||||
int impactCount = 0;
|
||||
|
||||
// delete existing widgets
|
||||
QLayoutItem *item = nullptr;
|
||||
while((item = m_ui->layoutEffectors->takeAt(0)) != nullptr)
|
||||
{
|
||||
if (item->widget())
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
for (const auto &effectorData : ecData.effectors())
|
||||
{
|
||||
setEffector(effectorData.participantId(), m_dtc->effector(effectorData.participantId()).effectorState());
|
||||
impactCount += effectorData.chargeAmount();
|
||||
}
|
||||
|
||||
m_ui->layoutEffectors->setColumnStretch(m_effectorNumber + 1 % m_maxColumns, 1);
|
||||
m_ui->lblCannons->setText(QString::number(impactCount));
|
||||
m_ui->lblFirePurpose->setText(m_pdmDtc->trFirePurposeName(ecData.firePurposeId()));
|
||||
|
||||
m_ui->lblZog->setText(QString::number(ecData.tla())); // tla == zog
|
||||
|
||||
const AreaEffectSimulation::Area &areaRef = ecData.area();
|
||||
const QPointF bottomLeft(areaRef.cornerBottomLeft().lon(), areaRef.cornerBottomLeft().lat());
|
||||
const QPointF centerpoint = Polygons::bottomLeft2CenterPoint(bottomLeft, areaRef.width(), areaRef.height(), areaRef.rotation());
|
||||
if (!bottomLeft.isNull())
|
||||
{
|
||||
m_ui->positionEdit->setCoordinate(centerpoint);
|
||||
m_coord = centerpoint;
|
||||
const Core::GeoPosition coordGeo(centerpoint.x(), centerpoint.y(), 0);
|
||||
bool isSmoke = m_pdmDtc->isSmoke(ecData.chargeStruct().chargeTypeId(), ecData.chargeStruct().igniterTypeId(), ecData.chargeStruct().igniterFunctionId());
|
||||
m_esmActorCbx->fillActorComboBox(m_ui->cbActors, coordGeo, isSmoke, 0);
|
||||
m_esmActorCbx->fillActorComboBox(m_ui->cbActors_2, coordGeo, isSmoke, 0);
|
||||
}
|
||||
|
||||
if (ecData.explosionGeometry().underlying() == AreaEffectSimulation::AesExplosionGeometry_def::EgRadial)
|
||||
{
|
||||
m_ui->lblDimensionYDepth->setText(QString::number(static_cast<int>(std::round(areaRef.height() / 2))));
|
||||
m_ui->lblWidthRadius->setText(QString::number(static_cast<int>(std::round(areaRef.width() / 2))));
|
||||
m_ui->lblAimingAxis->setText(QString::number(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->lblDimensionYDepth->setText(QString::number(static_cast<int>(std::round(areaRef.height()))));
|
||||
m_ui->lblWidthRadius->setText(QString::number(static_cast<int>(std::round(areaRef.width()))));
|
||||
m_ui->lblAimingAxis->setText(QString::number(static_cast<int>(std::round(fmod((areaRef.rotation()) * 6400 / 360, 6400)))));
|
||||
}
|
||||
setEffectClusterDataFromJson(ecData.properties());
|
||||
if (!ecData.esmParticipantIds().empty())
|
||||
{
|
||||
m_ui->cbActors->setCurrentIndex(m_ui->cbActors->findData(ecData.esmParticipantIds().at(0)));
|
||||
if (ecData.esmParticipantIds().size() > 1)
|
||||
m_ui->cbActors_2->setCurrentIndex(m_ui->cbActors_2->findData(ecData.esmParticipantIds().at(1)));
|
||||
}
|
||||
if (ecData.effectors().size())
|
||||
setOWUWFromTrajectory(ecData.effectors().at(0).trajectoryRelative());
|
||||
|
||||
// enable second Actor if possible
|
||||
const int amountFireMarker = m_pdmDtc->getAmountFireMarkers(ecData.firePurposeId());
|
||||
m_ui->cbActors_2->setEnabled(amountFireMarker > 1);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::setEffector(int participantId, const AreaEffectSimulation::AesEffectorState &effectorState)
|
||||
{
|
||||
const ParticipantManagement::Participant &part = m_ppmDtc->participant(participantId);
|
||||
|
||||
auto *effectorWidget = new AesEffector(this);
|
||||
effectorWidget->init(participantId, QString::fromStdString(part.tacticalIdentifier()), QString::fromStdString(part.name()), effectorState);
|
||||
effectorWidget->setStateButtonVisible(false);
|
||||
|
||||
const int row = m_effectorNumber / m_maxColumns;
|
||||
const int col = m_effectorNumber % m_maxColumns;
|
||||
m_ui->layoutEffectors->addWidget(effectorWidget, row, col);
|
||||
m_effectorNumber++;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief ExplosionsEditAdler::dialogIdentifier
|
||||
* \return
|
||||
*/
|
||||
QString ExplosionsEditAdler::dialogIdentifier() const
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "dialogIdentifier";
|
||||
return m_aesItem.id() <= 0 ? QStringLiteral("AddExplosionsArtillery") : QStringLiteral("EditExplosionsArtillery%1").arg(m_aesItem.id());
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::onAcknowledgeExternalAesItemReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " GOIT REPLY for onAcknowledgeExternalAesItemReply";
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::onEffectClusterChanged(const EffectCluster &ecData, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onExplosionClusterChanged";
|
||||
if (ecData.id() != m_aesItem.id())
|
||||
return;
|
||||
|
||||
BaseEdit::onAreaChanged(ecData, modType);
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
{
|
||||
m_effectClusterData = EffectCluster();
|
||||
return;
|
||||
}
|
||||
|
||||
m_effectClusterData = ecData;
|
||||
m_currentGeometry = m_effectClusterData.explosionGeometry();
|
||||
|
||||
setEffectClusterData(ecData);
|
||||
setPbStateChangeName();
|
||||
|
||||
if (m_effectClusterData.effectDuration() == DEFAULT_EFFECT_DURATION)
|
||||
m_ui->lblDuration->setText(QStringLiteral("---"));
|
||||
else
|
||||
m_ui->lblDuration->setText(QString::number(m_effectClusterData.effectDuration() / 1000)); // msec -> sec
|
||||
|
||||
enableUiElements();
|
||||
if (unchangeable())
|
||||
{
|
||||
m_ui->pbStateChange->setEnabled(false);
|
||||
m_ui->gbEffectMarkingInTa->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
QPointF ExplosionsEditAdler::centerOfFiringUnitGeo(int particpantUnitId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "centerOfFiringUnitGeo";
|
||||
if (!m_sitMapGuiIfc || !m_ppmDtc)
|
||||
return {};
|
||||
if (particpantUnitId <= 0)
|
||||
return {};
|
||||
|
||||
std::vector<Core::GeoPosition> singlePositionsOut_unused;
|
||||
const LtsUtils::QPoint3D ¢erCoordGeo = Polygons::calculateFiringUnitCenterNonRecursive(m_ppmDtc, particpantUnitId, singlePositionsOut_unused, m_logger);
|
||||
if (centerCoordGeo.isNull() || std::isnan(centerCoordGeo.x()))
|
||||
{
|
||||
// may happen in real life: so WARNING_LOG to DEBUG_LOG
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " calculateFiringUnitCenterNonRecursive failed, particpantUnitId = " << particpantUnitId;
|
||||
return {};
|
||||
}
|
||||
return centerCoordGeo.toPointF();
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::showCenterOfFiringUnit(int particpantUnitId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "showCenterOfFiringUnit";
|
||||
|
||||
if (!m_sitMapGuiIfc || !m_ppmDtc)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START particpantUnitId: " << particpantUnitId;
|
||||
if (particpantUnitId <= 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " showCenterOfFiringUnit: " << particpantUnitId << ", removeObjectIndicator";
|
||||
m_sitMapGuiIfc->removeObjectIndicator();
|
||||
return;
|
||||
}
|
||||
|
||||
const QPointF ¢erFiringUnitGeo = centerOfFiringUnitGeo(particpantUnitId);
|
||||
|
||||
if (centerFiringUnitGeo.isNull())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " showCenterOfFiringUnit: " << particpantUnitId << ", removeObjectIndicator due to invalid position";
|
||||
m_sitMapGuiIfc->removeObjectIndicator();
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END particpantUnitId: " << particpantUnitId;
|
||||
m_sitMapGuiIfc->objectIndicatorToPoint(centerFiringUnitGeo); // you can provide a duration: lifetimeMsec = -1
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief ExplosionsEditAdler::retranslate
|
||||
*/
|
||||
void ExplosionsEditAdler::retranslate()
|
||||
{
|
||||
QString title = tr("ADLER Artillery");
|
||||
|
||||
translate(m_ui, m_aesItem, title);
|
||||
|
||||
if (unchangeable())
|
||||
{
|
||||
m_ui->pbStateChange->setEnabled(false);
|
||||
m_ui->gbEffectMarkingInTa->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::enableUiElements() { enableUiElements(false); }
|
||||
|
||||
void ExplosionsEditAdler::enableUiElements(bool enable)
|
||||
{
|
||||
m_ui->pbPosition->setEnabled(m_sitMapGuiIfc && enable);
|
||||
m_ui->pbPosition_2->setEnabled(m_sitMapGuiIfc && enable);
|
||||
m_ui->positionEdit->setEnabled(enable);
|
||||
m_ui->positionEdit_2->setEnabled(enable);
|
||||
m_ui->pbClear->setEnabled(enable);
|
||||
m_ui->pbClear_2->setEnabled(enable);
|
||||
|
||||
m_ui->geometrieAimPointBtn->setEnabled(enable);
|
||||
m_ui->geometrieAreaBtn->setEnabled(enable);
|
||||
m_ui->geometriePointBtn->setEnabled(enable);
|
||||
m_ui->geometrieLineBtn->setEnabled(enable);
|
||||
m_ui->geometrieRadialBtn->setEnabled(enable);
|
||||
m_ui->rbAngleGroupLower->setEnabled(enable);
|
||||
m_ui->rbAngleGroupUpper->setEnabled(enable);
|
||||
|
||||
if (m_aesItem.effectStateId() == AesEffectState_def::EsReceived)
|
||||
m_ui->pbStateChange->setEnabled(true);
|
||||
else
|
||||
m_ui->pbStateChange->setEnabled(m_effectClusterData.effectorState() != AreaEffectSimulation::AesEffectorState::EsReadyToFire);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief ExplosionsEditAdler::apply
|
||||
* \return
|
||||
*/
|
||||
bool ExplosionsEditAdler::apply()
|
||||
{
|
||||
// DMF (Actors)
|
||||
int esmParticipantId1 = m_ui->cbActors->currentData().toInt(); // participant ID
|
||||
int esmParticipantId2 = m_ui->cbActors_2->currentData().toInt(); // participant ID
|
||||
|
||||
EffectClusterModifyActorRequest request;
|
||||
request.aesId(m_aesItem.id());
|
||||
DEBUG_LOG(m_logger) << "currentIndex: " << m_ui->cbActors->currentIndex() << ", currentText: " << m_ui->cbActors->currentText()
|
||||
<< ", participantId1: " << esmParticipantId1;
|
||||
|
||||
if (esmParticipantId1 > 0 || esmParticipantId2 > 0)
|
||||
{
|
||||
request.esmParticipantIds().reserve(2);
|
||||
if (esmParticipantId1 > 0)
|
||||
request.esmParticipantIds().push_back(esmParticipantId1);
|
||||
if (esmParticipantId2 > 0 && esmParticipantId1 != esmParticipantId2 && m_ui->cbActors_2->isEnabled())
|
||||
request.esmParticipantIds().push_back(esmParticipantId2);
|
||||
}
|
||||
|
||||
m_requestHelper->addRequest([this, request]() { return m_ftc->effectClusterModifyActorRequest(request, this); });
|
||||
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
//
|
||||
void ExplosionsEditAdler::setPbStateChangeName()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onPbStateChangeName: AesEffectState: " << m_aesItem.effectStateId();
|
||||
|
||||
if ((m_aesItem.effectStateId() != AesEffectState::EsReceived && m_aesItem.effectStateId() != AesEffectState::EsCreated) || m_aesItem.id() <= 0)
|
||||
return;
|
||||
|
||||
m_ui->pbStateChange->show();
|
||||
|
||||
if (m_aesItem.effectStateId() == AesEffectState_def::EsReceived)
|
||||
m_ui->pbStateChange->setText(tr("Acknowledge"));
|
||||
else
|
||||
{
|
||||
m_ui->pbStateChange->setText(tr("Ready to fire"));
|
||||
m_ui->pbStateChange->setEnabled(m_effectClusterData.effectorState() != AreaEffectSimulation::AesEffectorState::EsReadyToFire);
|
||||
}
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::onPbStateChangeClicked()
|
||||
{
|
||||
if ((m_aesItem.effectStateId() != AesEffectState::EsReceived && m_aesItem.effectStateId() != AesEffectState::EsCreated) || m_aesItem.id() <= 0)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << " onPbStateChangeClicked: AesEffectState = " << m_aesItem.effectStateId();
|
||||
|
||||
m_ui->pbStateChange->setDisabled(true);
|
||||
|
||||
if (m_ui->gbEffectMarkingInTa->isChecked())
|
||||
apply();
|
||||
|
||||
// Re-Enable PB, so we can call it another time, if it does not react...
|
||||
QTimer::singleShot(2000, [this]() { m_ui->pbStateChange->setEnabled(m_effectClusterData.effectorState() != AreaEffectSimulation::AesEffectorState::EsReadyToFire); });
|
||||
|
||||
if (m_aesItem.effectStateId() == AesEffectState_def::EsReceived)
|
||||
{
|
||||
AreaEffectSimulation::AcknowledgeExternalAesItemRequest request;
|
||||
request.aesId(m_aesItem.id());
|
||||
DEBUG_LOG(m_logger) << "Send acknowledgeExternalAesItemRequest with aesId: " << request.aesId();
|
||||
m_requestHelper->addRequest([this, request]() { return m_ftc->acknowledgeExternalAesItemRequest(request, this); });
|
||||
}
|
||||
else
|
||||
{
|
||||
AreaEffectSimulation::SetAesItemEffectorStateRequest request;
|
||||
request.aesId(m_aesItem.id());
|
||||
request.newEffectorState(AesEffectorState::EsReadyToFire);
|
||||
DEBUG_LOG(m_logger) << "Send setAesItemEffectorStateRequest with aesId: " << request.aesId() << ", AesEffectorState: " << request.newEffectorState();
|
||||
m_requestHelper->addRequest([this, request]() { return m_ftc->setAesItemEffectorStateRequest(request, this); });
|
||||
}
|
||||
|
||||
m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::onEffectorChanged(const AreaEffectSimulation::Effector &data, DataModification modType)
|
||||
{
|
||||
if (data.aesItemId() != m_aesItem.id())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < m_ui->layoutEffectors->count(); ++i)
|
||||
{
|
||||
QLayoutItem *item = m_ui->layoutEffectors->itemAt(i);
|
||||
if (QWidget *widget = item->widget())
|
||||
{
|
||||
if (AesEffector *effectorWidget = qobject_cast<AesEffector *>(widget))
|
||||
{
|
||||
if (effectorWidget->effectorId() != data.id())
|
||||
continue;
|
||||
|
||||
effectorWidget->setState(data.effectorState());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modType == DataModification::eAdded)
|
||||
setEffector(data.participantId(), data.effectorState());
|
||||
}
|
||||
|
||||
bool ExplosionsEditAdler::isOnlyNameModifiable() const
|
||||
{
|
||||
// BaseClass::isOnlyNameModifiable() -> EsPaused || EsActivated
|
||||
// m_effectClusterData.isObjectModifiable -> since PreStart and s_calculationOffsetMSec
|
||||
const bool ret = BaseClass::isOnlyNameModifiable() || !m_effectClusterData.isObjectModifiable();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::resetTempAndAnnotationStr()
|
||||
{
|
||||
INFO_LOG(m_logger) << " RESET resetTempAndAnnotationStr";
|
||||
m_temporaryData.reset();
|
||||
// updateAnnotationStr();
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::addAnnotationStr(const QString &newAnno)
|
||||
{
|
||||
m_temporaryData.m_annotationString4Dlg += newAnno;
|
||||
updateAnnotationStr();
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::setOWUWFromTrajectory(const std::vector<Core::RelativePositionRelativeTime> &vecGeometry)
|
||||
{
|
||||
if (vecGeometry.size() < 2)
|
||||
return;
|
||||
|
||||
const double dz = vecGeometry.at(1).offsetZ() - vecGeometry.at(0).offsetZ();
|
||||
const QLineF line(vecGeometry.at(0).offsetX(), vecGeometry.at(0).offsetY(),
|
||||
vecGeometry.at(1).offsetX(), vecGeometry.at(1).offsetY());
|
||||
|
||||
double angleArc = std::atan2(dz, line.length());
|
||||
double angleDegree = angleArc * (180.0 / M_PI);
|
||||
angleDegree = std::fmod(angleDegree + 360.0, 360.0);
|
||||
DEBUG_LOG(m_logger) << "distance: " << line.length() << ", height: " << dz << ", angleDegree: " << angleDegree;
|
||||
|
||||
if (angleDegree > maxAngleUW)
|
||||
m_ui->rbAngleGroupUpper->setChecked(true);
|
||||
else
|
||||
m_ui->rbAngleGroupLower->setChecked(true);
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::updateAnnotationStr()
|
||||
{
|
||||
QStringList sl;
|
||||
if (!m_temporaryData.m_annotationStringFiring4Dlg.isEmpty())
|
||||
sl.append(m_temporaryData.m_annotationStringFiring4Dlg);
|
||||
if (!m_temporaryData.m_annotationString4Dlg.isEmpty())
|
||||
sl.append(m_temporaryData.m_annotationString4Dlg);
|
||||
if (!m_temporaryData.m_remainingTimeStr.isEmpty())
|
||||
sl.append(m_temporaryData.m_remainingTimeStr);
|
||||
|
||||
if (sl.isEmpty())
|
||||
m_ui->lblAnnotationStringContent->setText(QStringLiteral("-"));
|
||||
else if (sl.size() == 1)
|
||||
m_ui->lblAnnotationStringContent->setText(sl.first());
|
||||
else
|
||||
m_ui->lblAnnotationStringContent->setText(sl.join(QStringLiteral(" ; ")));
|
||||
}
|
||||
|
||||
void ExplosionsEditAdler::setEffectClusterDataFromJson(const std::string &properties)
|
||||
{
|
||||
const QJsonObject propsObj(QJsonDocument::fromJson(QByteArray::fromStdString(properties)).object());
|
||||
DEBUG_LOG(m_logger) << "ecData json: " << properties;
|
||||
|
||||
const int elemente = propsObj[AdlerJson::JsonKeys::ELEMENTE()].toInt();
|
||||
if (elemente > 0)
|
||||
m_ui->lblElement->setText(QString::number(elemente));
|
||||
|
||||
const int loadTypeId = propsObj[AdlerJson::JsonKeys::LADUNG()].toInt();
|
||||
if (loadTypeId > 0)
|
||||
m_ui->lblLoadType->setText(m_pdmDtc->trLoadTypeShortName(loadTypeId));
|
||||
|
||||
const int loadNumber = propsObj[AdlerJson::JsonKeys::LADUNGSNUMMER()].toInt(-1);
|
||||
if (loadNumber >= 0)
|
||||
m_ui->lblLoadNumber->setText(QString::number(loadNumber));
|
||||
|
||||
const int targetTypeId = propsObj[AdlerJson::JsonKeys::TYP()].toInt();
|
||||
if (targetTypeId > 0)
|
||||
m_ui->lblTargetType->setText(m_pdmDtc->trTargetTypeName(targetTypeId));
|
||||
|
||||
const int targetSubTypeId = propsObj[AdlerJson::JsonKeys::SUB_TYP()].toInt();
|
||||
if (targetSubTypeId > 0)
|
||||
m_ui->lblTargetSubType->setText(m_pdmDtc->trTargetSubTypeName(targetSubTypeId));
|
||||
|
||||
const int angleGroup = propsObj[AdlerJson::JsonKeys::WINKELGRUPPE()].toInt();
|
||||
if (angleGroup == ProjectDataManagement::L43_AngleGroup::Lower)
|
||||
m_ui->rbAngleGroupLower->setChecked(true);
|
||||
else
|
||||
m_ui->rbAngleGroupUpper->setChecked(true);
|
||||
|
||||
const FiringType &firingType = static_cast<FiringType::inner_enum>(propsObj[AdlerJson::JsonKeys::ABFEUERUNGSART()].toInt());
|
||||
m_ui->lblFiringType->setText(AreaEffectSimulation::toString(firingType));
|
||||
}
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Explosions Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Steve Tougnia, SLTE, 2023-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AreaEffectSimulation/aes_ftc.h>
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_edit.h>
|
||||
#include <Plugins/EffectShowManagement/esm_gui_combobox_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_gui_plugin_interface.h>
|
||||
#include <ProjectDataManagement/pdm.hpp>
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ExplosionsEditAdler;
|
||||
}
|
||||
|
||||
class QSpinBox;
|
||||
|
||||
namespace AdvancedSymbology
|
||||
{
|
||||
class SymbolResultWatcherLabel;
|
||||
class ForeignDataInterface;
|
||||
} // namespace AdvancedSymbology
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
class ExplosionsEditAdler final
|
||||
: public BaseEdit
|
||||
, protected AreaEffectSimulation::Interface::Ftc::EffectClusterModifyReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::EffectClusterModifyActorReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::SetAesItemEffectorStateReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::AcknowledgeExternalAesItemReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = BaseEdit;
|
||||
|
||||
enum class FlighDurationOrPeakHeight
|
||||
{
|
||||
FDPH_flightDuration,
|
||||
FDPH_peakHeight
|
||||
};
|
||||
QString toString(FlighDurationOrPeakHeight val);
|
||||
|
||||
explicit ExplosionsEditAdler(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~ExplosionsEditAdler();
|
||||
|
||||
bool init(int aesItemId, bool copy, LtsSession::LtsSession *session);
|
||||
void setEffectClusterData(const EffectCluster &ecData);
|
||||
void setEffector(int participantId, const AreaEffectSimulation::AesEffectorState &effectorState);
|
||||
void setEffectClusterDataFromJson(const std::string &properties);
|
||||
|
||||
void setOWUWFromTrajectory(const std::vector<Core::RelativePositionRelativeTime> &vecGeometry);
|
||||
|
||||
QString dialogIdentifier() const override;
|
||||
|
||||
void onEffectClusterModifyReply(const Core::FunctionReplyObject &replyObject) override final { onAesItemModifyReply(replyObject); }
|
||||
void onEffectClusterModifyActorReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onAcknowledgeExternalAesItemReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onSetAesItemEffectorStateReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
void onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &ecData, DataModification modType);
|
||||
|
||||
QPointF centerOfFiringUnitGeo(int particpantUnitId);
|
||||
void showCenterOfFiringUnit(int particpantUnitId);
|
||||
void showPreviewObject() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
bool isDataSufficiant();
|
||||
bool apply() override final;
|
||||
void onPbStateChangeClicked();
|
||||
void onEffectorChanged(const AreaEffectSimulation::Effector &data, DataModification modType);
|
||||
|
||||
private:
|
||||
friend class doCalculationsAdlerStandAloneExitGuard;
|
||||
|
||||
void retranslate() override;
|
||||
void enableUiElements();
|
||||
void enableUiElements(bool enable) override;
|
||||
void setPbStateChangeName();
|
||||
|
||||
private:
|
||||
bool isOnlyNameModifiable() const override;
|
||||
|
||||
struct Charges
|
||||
{
|
||||
Charges() {}
|
||||
explicit Charges(const ProjectDataManagement::ChargeType &type) : chargeType(type) {}
|
||||
ProjectDataManagement::ChargeType chargeType;
|
||||
QMap<int, int> available; // PartyId
|
||||
};
|
||||
|
||||
QVector<ProjectDataManagement::GearClass> m_gearClassFilter;
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> m_asbIfc;
|
||||
std::shared_ptr<EffectShowManagement::ForeignGuiComboboxInterface> m_esmActorCbx;
|
||||
std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> m_pdmCbx;
|
||||
|
||||
EffectCluster m_effectClusterData;
|
||||
|
||||
QPointF m_coord;
|
||||
|
||||
// doCalculationsAdler will update following:
|
||||
struct temporaryData
|
||||
{
|
||||
qint64 m_estimatedFlightDurationMsec{-1};
|
||||
qint64 m_distanceFiringToTarget{-1};
|
||||
Core::GeoPosition m_idealTapAbsoluteGeoOut;
|
||||
QString m_remainingTimeStr;
|
||||
QString m_annotationStringFiring4Dlg;
|
||||
QStringList m_annotationString4Dlg;
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_estimatedFlightDurationMsec = -1;
|
||||
m_distanceFiringToTarget = -1;
|
||||
m_remainingTimeStr.clear();
|
||||
m_annotationStringFiring4Dlg.clear();
|
||||
m_annotationString4Dlg.clear();
|
||||
}
|
||||
} m_temporaryData;
|
||||
|
||||
void resetTempAndAnnotationStr();
|
||||
void addAnnotationStr(const QString &newAnno);
|
||||
void updateAnnotationStr();
|
||||
|
||||
QMap<qint32, Charges> m_chargeTypeMap; // ChargeTypeId
|
||||
QPointF m_previewCircleCenter;
|
||||
double m_previewCircleRadius;
|
||||
QPolygonF m_previewPolygon;
|
||||
QButtonGroup *m_geometrieButtonGroup;
|
||||
AreaEffectSimulation::AesExplosionGeometry m_currentGeometry; // safe_enum is initialized by itself
|
||||
Ui::ExplosionsEditAdler *m_ui;
|
||||
bool m_initDone{false};
|
||||
Core::GeoPosition m_coordGeo;
|
||||
int m_maxColumns{4};
|
||||
int m_effectorNumber{0};
|
||||
};
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
+1565
File diff suppressed because it is too large.
Load diff
+3092
File diff suppressed because it is too large.
Load diff
+232
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectSimulation - Explosions Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Steve Tougnia, SLTE, 2023-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LtsElevation/lts_elevation_manager.h"
|
||||
#include <AreaEffectSimulation/aes_ftc.h>
|
||||
#include <ElevationMap/elevation_map_manager.h>
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_edit.h>
|
||||
#include <Plugins/EffectShowManagement/esm_gui_combobox_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_gui_plugin_interface.h>
|
||||
#include <ProjectDataManagement/pdm.hpp>
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ExplosionsEditAdlerStandAlone;
|
||||
}
|
||||
|
||||
class QSpinBox;
|
||||
|
||||
namespace AdvancedSymbology
|
||||
{
|
||||
class SymbolResultWatcherLabel;
|
||||
class ForeignDataInterface;
|
||||
} // namespace AdvancedSymbology
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
class ExplosionsEditAdlerStandAlone final
|
||||
: public BaseEdit
|
||||
, protected AreaEffectSimulation::Interface::Ftc::EffectClusterModifyReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::EffectClusterPauseResumeReplyHandler
|
||||
, protected AreaEffectSimulation::Interface::Ftc::SetAesItemEffectorStateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = BaseEdit;
|
||||
|
||||
enum class FlighDurationOrPeakHeight
|
||||
{
|
||||
FDPH_flightDuration,
|
||||
FDPH_peakHeight
|
||||
};
|
||||
QString toString(FlighDurationOrPeakHeight val);
|
||||
|
||||
explicit ExplosionsEditAdlerStandAlone(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~ExplosionsEditAdlerStandAlone();
|
||||
|
||||
bool init(int aesItemId, bool copy, LtsSession::LtsSession *session);
|
||||
void setEffectClusterData(const EffectCluster &ecData);
|
||||
void setEffector(const ParticipantManagement::Participant &part, const AreaEffectSimulation::AesEffectorState &effectorState);
|
||||
|
||||
QString dialogIdentifier() const override;
|
||||
|
||||
void onEffectClusterModifyReply(const Core::FunctionReplyObject &replyObject) override final { onAesItemModifyReply(replyObject); }
|
||||
void onEffectClusterPauseResumeReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onSetAesItemEffectorStateReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &ecData, DataModification modType);
|
||||
|
||||
QPointF centerOfFiringUnitGeo(int particpantUnitId);
|
||||
void showCenterOfFiringUnit(int particpantUnitId);
|
||||
|
||||
private Q_SLOTS:
|
||||
void showPreviewObject() override;
|
||||
bool isDataSufficiant();
|
||||
bool apply() override final;
|
||||
void onGeometrySelected(int explosionGeometryInt);
|
||||
void onStartBtnClicked();
|
||||
void onGearClassChanged();
|
||||
void onPositionChanged(const QPointF &newGeoCoord);
|
||||
void onPartyChanged();
|
||||
void onChargeTypeChanged();
|
||||
void onIgniterTypeChanged();
|
||||
void onLoadTypeChanged();
|
||||
void onTargetTypeChanged();
|
||||
void onParticipantUnitChanged(int idx);
|
||||
void onParticipantUnitEntered();
|
||||
void onParticipantUnitLeaved();
|
||||
void onParticipantPositionChanged();
|
||||
void getPosition();
|
||||
void onCoordinate(const QPointF ¢erPoint);
|
||||
void onMapRecData(const QPointF &bottomLeft, double width, double height, double angleDegNorth, const QPolygonF &bufferOutlinePolygon);
|
||||
void onCircleData(const QPointF &position, double radius);
|
||||
void onPolylineData(const QPolygonF &polyline);
|
||||
void setCoord(const QPointF &coord);
|
||||
void onFirePurposeChanged();
|
||||
void onCbFiringTypeChanged();
|
||||
void setFireBtnState();
|
||||
void onFireBtnClicked();
|
||||
void onWidthChanged(int width);
|
||||
void onAimingAxisChanged(int aimingAxis);
|
||||
void onLineP1Changed(const QPointF &point);
|
||||
void onLineP2Changed(const QPointF &point);
|
||||
|
||||
void onPeakHeigthChanged(int data);
|
||||
void onEffectDurationChanged(int value);
|
||||
|
||||
void switchTo(FlighDurationOrPeakHeight phfd);
|
||||
void setMinMaxConstraints(ExplosionsEditAdlerStandAlone::FlighDurationOrPeakHeight phfd, ProjectDataManagement::GearClass_def::type gearClass, int chargeTypeId);
|
||||
bool setValueAccordingContraints(int newValue, ExplosionsEditAdlerStandAlone::FlighDurationOrPeakHeight phfd);
|
||||
|
||||
bool isGuiVulcano();
|
||||
|
||||
void doCalculationsAdlerStandAlone(bool executeEnableUiElements = true);
|
||||
void onPartitionTimeChanged(qint64 newPartitionTimeMsec = 0);
|
||||
void onEffectorChanged(const AreaEffectSimulation::Effector &data, DataModification modType);
|
||||
|
||||
private:
|
||||
friend class doCalculationsAdlerStandAloneExitGuard;
|
||||
static double s_minWidth;
|
||||
static double s_maxWidth;
|
||||
static double s_stepWidth;
|
||||
static double s_minHeight;
|
||||
static double s_maxHeight;
|
||||
static double s_stepHeight;
|
||||
static double s_minRadius;
|
||||
static double s_maxRadius;
|
||||
static double s_stepRadius;
|
||||
static int s_maxChargeUsage;
|
||||
static double s_minAltitude;
|
||||
static double s_maxAltitude;
|
||||
static qint64 s_maxDurationSeconds;
|
||||
|
||||
void retranslate() override;
|
||||
void enableUiElements();
|
||||
void enableUiElements(bool enable) override;
|
||||
void enableUiFireButton();
|
||||
void fillParticipantUnit();
|
||||
void gatherParticipantUnits(const int &partyId, QHash<int /*superiorId*/, QSet<int>> &units) const;
|
||||
void fillParties();
|
||||
bool isValidParty(qint32 partyId);
|
||||
bool allEffectorReadyToFire() const;
|
||||
|
||||
void fillCharges();
|
||||
void fillFiringTypCbox();
|
||||
void fillGearClasses();
|
||||
void mmiToJsonproperties(QJsonObject &data);
|
||||
void setEffectClusterDataFromJson(const std::string &properties);
|
||||
|
||||
private:
|
||||
bool isOnlyNameModifiable() const override;
|
||||
bool isSmoke();
|
||||
void updateActorComboBox(const Core::GeoPosition &coordGeo);
|
||||
|
||||
QPair<int, int> getMinMaxDistance(ProjectDataManagement::GearClass_def::type gearClass, int chargeTypeId);
|
||||
int getMinDistance(ProjectDataManagement::GearClass::inner_enum gearClass, int chargeTypeId);
|
||||
int getMaxDistance(ProjectDataManagement::GearClass::inner_enum gearClass, int chargeTypeId);
|
||||
QPair<int, int> getMinMaxFlightDurationSec(ProjectDataManagement::GearClass::inner_enum gearClass, int chargeTypeId);
|
||||
int getMinFlightDurationSec(ProjectDataManagement::GearClass::inner_enum gearClass, int chargeTypeId);
|
||||
int getMaxFlightDurationSec(ProjectDataManagement::GearClass::inner_enum gearClass, int chargeTypeId);
|
||||
QPair<int, int> getMinMaxPeakHeight(ProjectDataManagement::GearClass::inner_enum gearClass, int chargeTypeId);
|
||||
int getMinPeakHeight(ProjectDataManagement::GearClass::inner_enum gearClass, int chargeTypeId);
|
||||
int getMaxPeakHeight(ProjectDataManagement::GearClass::inner_enum gearClass, int chargeTypeId);
|
||||
bool isPointSimilar(AreaEffectSimulation::AesExplosionGeometry geometry);
|
||||
|
||||
struct Charges
|
||||
{
|
||||
Charges() {}
|
||||
explicit Charges(const ProjectDataManagement::ChargeType &type)
|
||||
: chargeType(type)
|
||||
{
|
||||
}
|
||||
ProjectDataManagement::ChargeType chargeType;
|
||||
QMap<int, int> available; // PartyId
|
||||
};
|
||||
|
||||
QVector<ProjectDataManagement::GearClass> m_gearClassFilter;
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> m_asbIfc;
|
||||
std::shared_ptr<EffectShowManagement::ForeignGuiComboboxInterface> m_esmActorCbx;
|
||||
std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> m_pdmCbx;
|
||||
|
||||
EffectCluster m_effectClusterData;
|
||||
|
||||
QPointF m_coord;
|
||||
double m_firstFlightTime;
|
||||
|
||||
// doCalculationsAdlerStandAlone will update following:
|
||||
struct temporaryData
|
||||
{
|
||||
qint64 m_estimatedFlightDurationMsec{-1};
|
||||
qint64 m_distanceFiringToTarget{-1};
|
||||
Core::GeoPosition m_idealTapAbsoluteGeoOut;
|
||||
QString m_remainingTimeStr;
|
||||
QString m_annotationStringFiring4Dlg;
|
||||
QStringList m_annotationString4Dlg;
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_estimatedFlightDurationMsec = -1;
|
||||
m_distanceFiringToTarget = -1;
|
||||
m_remainingTimeStr.clear();
|
||||
m_annotationStringFiring4Dlg.clear();
|
||||
m_annotationString4Dlg.clear();
|
||||
}
|
||||
} m_temporaryData;
|
||||
|
||||
void resetTempAndAnnotationStr();
|
||||
void addAnnotationStr(const QString &newAnno);
|
||||
void updateAnnotationStr();
|
||||
double getElevation(const double lon, const double lat) const;
|
||||
|
||||
EffectCluster m_data;
|
||||
QMap<qint32, Charges> m_chargeTypeMap; // ChargeTypeId
|
||||
QPointF m_previewCircleCenter;
|
||||
double m_previewCircleRadius;
|
||||
QPolygonF m_previewPolygon;
|
||||
QButtonGroup *m_geometrieButtonGroup;
|
||||
AreaEffectSimulation::AesExplosionGeometry m_currentGeometry; // safe_enum is initialized by itself
|
||||
Ui::ExplosionsEditAdlerStandAlone *m_ui;
|
||||
bool m_initDone{false};
|
||||
QTimer *m_enableStartBtnTimer{nullptr};
|
||||
Core::GeoPosition m_coordGeo;
|
||||
const int m_maxColumns{4};
|
||||
int m_effectorNumber{0};
|
||||
LtsElevation::LTS_ELEVATION_MANAGER_TYPE m_elevationManager{nullptr};
|
||||
};
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
+1634
File diff suppressed because it is too large.
Load diff
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AreaEffectManangement - Explosion Single Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "aes_explosions_single_model.h"
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
bool ExplosionsSingleModel::initModel(LtsSession::LtsSession *session)
|
||||
{
|
||||
if (!AesGuiBaseModel::initModel(session))
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &Interface::Dtc::explosionSingleChanged,
|
||||
this, &ExplosionsSingleModel::onDataChanged);
|
||||
|
||||
fillAvailableChargeIds(m_gearClass);
|
||||
|
||||
m_aesDtc->explosionSingles([this](const ExplosionSingle &item) { insertRow(item); });
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace AreaEffectSimulation
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* ExplosionManangement - Explosion Single Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/Gui/Base/aes_base_model.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
/************ Class for Artillery and Mortar Explosion Single ***************/
|
||||
class ExplosionsSingleModel : public AesGuiBaseModel<ExplosionSingle>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExplosionsSingleModel(ProjectDataManagement::GearClass gc, QObject *parent)
|
||||
: AesGuiBaseModel<ExplosionSingle>(parent)
|
||||
, m_gearClass(gc)
|
||||
{}
|
||||
|
||||
bool initModel(LtsSession::LtsSession *session);
|
||||
ProjectDataManagement::GearClass gearClass() const { return m_gearClass; }
|
||||
|
||||
protected:
|
||||
ProjectDataManagement::GearClass m_gearClass;
|
||||
};
|
||||
|
||||
} //namespace AreaEffectSimulation
|
||||
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Namespace for rocket related functions
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Fritsche, ESZS, 2026-06-03
|
||||
*/
|
||||
|
||||
#include "aes_rocket_utility.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include <AreaEffectSimulation/aes.hpp>
|
||||
#include <AreaEffectSimulation/Trajectory/trajectory_generator.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <LtsUtils/LtsUtilsCore/qpoint3d.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ProjectDataManagement/pdm_enums.hpp>
|
||||
#include <Proxies/TrainingAreaBase/Plugins/AdlerJson/telegrams.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
namespace RocketUtility
|
||||
{
|
||||
|
||||
void enaDisaWirkmittel(QComboBox *wirkmittelCombobox, AesExplosionGeometry::type geometry)
|
||||
{
|
||||
if (wirkmittelCombobox == nullptr)
|
||||
return;
|
||||
|
||||
const QStandardItemModel *cboModel = qobject_cast<QStandardItemModel *>(wirkmittelCombobox->model());
|
||||
|
||||
if (cboModel == nullptr)
|
||||
return;
|
||||
|
||||
switch (geometry)
|
||||
{
|
||||
case AesExplosionGeometry::type::EgAimPoint:
|
||||
case AesExplosionGeometry::type::EgPoint:
|
||||
case AesExplosionGeometry::type::EgLine:
|
||||
for (int indexCounter = 0; indexCounter < wirkmittelCombobox->count(); ++indexCounter)
|
||||
{
|
||||
const QVariant currentData = wirkmittelCombobox->itemData(indexCounter);
|
||||
const ProjectDataManagement::GearClass::type currentGearClass = static_cast<ProjectDataManagement::GearClass::type>(currentData.toInt());
|
||||
|
||||
if (currentGearClass == ProjectDataManagement::GearClass::Rocket)
|
||||
{
|
||||
QStandardItem *item = cboModel->item(indexCounter);
|
||||
|
||||
if (item == nullptr)
|
||||
continue;
|
||||
|
||||
item->setFlags(item->flags() | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||
|
||||
// we do not break the loop here because there may be more rocket wirkmittel in the future
|
||||
}
|
||||
}
|
||||
return;
|
||||
case AesExplosionGeometry::type::EgRadial:
|
||||
case AesExplosionGeometry::type::EgArea:
|
||||
{
|
||||
const int currentIndex = wirkmittelCombobox->currentIndex();
|
||||
|
||||
for (int indexCounter = 0; indexCounter < wirkmittelCombobox->count(); ++indexCounter)
|
||||
{
|
||||
const QVariant currentData = wirkmittelCombobox->itemData(indexCounter);
|
||||
const ProjectDataManagement::GearClass::type currentGearClass = static_cast<ProjectDataManagement::GearClass::type>(currentData.toInt());
|
||||
|
||||
if (currentGearClass == ProjectDataManagement::GearClass::Rocket)
|
||||
{
|
||||
QStandardItem *item = cboModel->item(indexCounter);
|
||||
|
||||
if (item == nullptr)
|
||||
continue;
|
||||
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsEnabled & ~Qt::ItemIsSelectable);
|
||||
|
||||
// if rocket ist currently selected, we have to set another index
|
||||
if (indexCounter == currentIndex && wirkmittelCombobox->count() > 1)
|
||||
{
|
||||
const int newIndex = currentIndex == 0 ? 1 : 0;
|
||||
|
||||
wirkmittelCombobox->setCurrentIndex(newIndex);
|
||||
}
|
||||
// we do not break the loop here because there may be more rocket wirkmittel in the future
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void addRocketPropertiesToRequest(EffectClusterModifyRequest &request, const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc)
|
||||
{
|
||||
switch (request.explosionGeometry().underlying())
|
||||
{
|
||||
case AesExplosionGeometry::type::EgAimPoint:
|
||||
case AesExplosionGeometry::type::EgPoint:
|
||||
addRocketPropertiesForPointGeometry(request, ppmDtc);
|
||||
return;
|
||||
case AesExplosionGeometry::type::EgLine:
|
||||
addRocketPropertiesForLinearGeometry(request, ppmDtc);
|
||||
return;
|
||||
case AesExplosionGeometry::type::EgRadial:
|
||||
case AesExplosionGeometry::type::EgArea:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void addRocketPropertiesForLinearGeometry(EffectClusterModifyRequest &request, const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc)
|
||||
{
|
||||
using namespace LtsCoordTrans;
|
||||
|
||||
AdlerJson::WirkmittelFeuerkommandoRakete wirkmittel;
|
||||
AdlerJson::Treffpunkt treffpunkt;
|
||||
|
||||
wirkmittel.wirkzeit = 6;
|
||||
|
||||
const UtmCoordinate areaBottomLeftUtm = UtmCoordinate::fromGeographic(request.area().cornerBottomLeft().lon(), request.area().cornerBottomLeft().lat());
|
||||
|
||||
QTransform transform;
|
||||
transform.translate(areaBottomLeftUtm.x, areaBottomLeftUtm.y);
|
||||
transform.rotate(-request.area().rotation());
|
||||
|
||||
const double yLocal = request.area().height() / 2;
|
||||
|
||||
int mhpSliceCounter = 1;
|
||||
|
||||
for (EffectorData ¤tEffector : request.effectors())
|
||||
{
|
||||
wirkmittel.geschoss.anzahl = currentEffector.chargeAmount();
|
||||
treffpunkt.anzahl = wirkmittel.geschoss.anzahl;
|
||||
|
||||
// calculate local x
|
||||
double xLocal = request.area().width() * (static_cast<double>(mhpSliceCounter++) / (request.effectors().size() + 1));
|
||||
|
||||
// transform local point to UTM
|
||||
const QPointF localPoint(xLocal, yLocal);
|
||||
const QPointF utmPoint = transform.map(localPoint);
|
||||
|
||||
// tranform utm point to geographic WGS84 coordinate
|
||||
const UtmCoordinate currentUtm(areaBottomLeftUtm.zone, utmPoint.x(), utmPoint.y());
|
||||
const QPointF mhpGeo = currentUtm.geographic();
|
||||
|
||||
// treffpunkt
|
||||
currentEffector.mhpPosition().lon(mhpGeo.x());
|
||||
currentEffector.mhpPosition().lat(mhpGeo.y());
|
||||
treffpunkt.koordinate.koordinate.longitude = currentEffector.mhpPosition().lon() * LtsCoordTrans::rad2deg();
|
||||
treffpunkt.koordinate.koordinate.latitude = currentEffector.mhpPosition().lat() * LtsCoordTrans::rad2deg();
|
||||
|
||||
wirkmittel.treffpunkte.clear();
|
||||
wirkmittel.treffpunkte.append(treffpunkt);
|
||||
|
||||
QJsonObject wirkmittelObj;
|
||||
AdlerJson::wirkmittelFeuerkommandoRaketeToJson(wirkmittelObj, wirkmittel);
|
||||
|
||||
currentEffector.properties(QJsonDocument(wirkmittelObj).toJson().toStdString());
|
||||
|
||||
// trajectory
|
||||
const ParticipantManagement::ParticipantPosition &participantPosition = ppmDtc->participantPosition(currentEffector.participantId());
|
||||
const LtsUtils::QPoint3D trajectoryStart(participantPosition.pos().lon(),
|
||||
participantPosition.pos().lat(),
|
||||
participantPosition.pos().z());
|
||||
const LtsUtils::QPoint3D trajectoryEnd(currentEffector.mhpPosition().lon(),
|
||||
currentEffector.mhpPosition().lat(),
|
||||
currentEffector.mhpPosition().z()); // TODO
|
||||
TrajectoryGeoPosition trajectoryWithoutTime;
|
||||
|
||||
TrajectoryGenerator::getInstance()->generateTrajectoryBiedziak(trajectoryStart, trajectoryEnd, 45.0, trajectoryWithoutTime);
|
||||
|
||||
currentEffector.flightTime(60000.0);
|
||||
const double flightTimeStep = currentEffector.flightTime() / static_cast<double>(trajectoryWithoutTime.size());
|
||||
double currentFlightTime = 0.0;
|
||||
|
||||
const LtsCoordTrans::UtmCoordinate utmStartPos = LtsCoordTrans::UtmCoordinate::fromGeographic(participantPosition.pos().lon(), participantPosition.pos().lat());
|
||||
for (const Core::GeoPosition &pos : trajectoryWithoutTime)
|
||||
{
|
||||
const LtsCoordTrans::UtmCoordinate utmCurrentPos = LtsCoordTrans::UtmCoordinate::fromGeographic(pos.lon(), pos.lat());
|
||||
|
||||
currentEffector.trajectoryRelative().emplace_back(utmCurrentPos.x - utmStartPos.x,
|
||||
utmCurrentPos.y - utmStartPos.y, pos.z(), currentFlightTime);
|
||||
|
||||
currentFlightTime += flightTimeStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addRocketPropertiesForPointGeometry(EffectClusterModifyRequest &request, const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc)
|
||||
{
|
||||
using namespace LtsCoordTrans;
|
||||
|
||||
AdlerJson::WirkmittelFeuerkommandoRakete wirkmittel;
|
||||
AdlerJson::Treffpunkt treffpunkt;
|
||||
|
||||
wirkmittel.wirkzeit = 6;
|
||||
treffpunkt.anzahl = 1;
|
||||
|
||||
const UtmCoordinate areaBottomLeftUtm = UtmCoordinate::fromGeographic(request.area().cornerBottomLeft().lon(), request.area().cornerBottomLeft().lat());
|
||||
const QPointF areaCenterGeo = areaBottomLeftUtm.geographic(request.area().width() / 2, request.area().height() / 2);
|
||||
|
||||
for (EffectorData ¤tEffector : request.effectors())
|
||||
{
|
||||
wirkmittel.geschoss.anzahl = currentEffector.chargeAmount();
|
||||
treffpunkt.anzahl = wirkmittel.geschoss.anzahl;
|
||||
|
||||
// treffpunkt
|
||||
currentEffector.mhpPosition().lon(areaCenterGeo.x());
|
||||
currentEffector.mhpPosition().lat(areaCenterGeo.y());
|
||||
treffpunkt.koordinate.koordinate.longitude = currentEffector.mhpPosition().lon() * LtsCoordTrans::rad2deg();
|
||||
treffpunkt.koordinate.koordinate.latitude = currentEffector.mhpPosition().lat() * LtsCoordTrans::rad2deg();
|
||||
|
||||
wirkmittel.treffpunkte.clear();
|
||||
wirkmittel.treffpunkte.append(treffpunkt);
|
||||
|
||||
QJsonObject wirkmittelObj;
|
||||
AdlerJson::wirkmittelFeuerkommandoRaketeToJson(wirkmittelObj, wirkmittel);
|
||||
|
||||
currentEffector.properties(QJsonDocument(wirkmittelObj).toJson().toStdString());
|
||||
|
||||
// trajectory
|
||||
const ParticipantManagement::ParticipantPosition &participantPosition = ppmDtc->participantPosition(currentEffector.participantId());
|
||||
const LtsUtils::QPoint3D trajectoryStart(participantPosition.pos().lon(),
|
||||
participantPosition.pos().lat(),
|
||||
participantPosition.pos().z());
|
||||
const LtsUtils::QPoint3D trajectoryEnd(currentEffector.mhpPosition().lon(),
|
||||
currentEffector.mhpPosition().lat(),
|
||||
currentEffector.mhpPosition().z());
|
||||
TrajectoryGeoPosition trajectoryWithoutTime;
|
||||
|
||||
TrajectoryGenerator::getInstance()->generateTrajectoryBiedziak(trajectoryStart, trajectoryEnd, 45.0, trajectoryWithoutTime);
|
||||
|
||||
currentEffector.flightTime(60000.0);
|
||||
const double flightTimeStep = currentEffector.flightTime() / static_cast<double>(trajectoryWithoutTime.size());
|
||||
double currentFlightTime = 0.0;
|
||||
|
||||
const LtsCoordTrans::UtmCoordinate utmStartPos = LtsCoordTrans::UtmCoordinate::fromGeographic(participantPosition.pos().lon(), participantPosition.pos().lat());
|
||||
for (const Core::GeoPosition &pos : trajectoryWithoutTime)
|
||||
{
|
||||
const LtsCoordTrans::UtmCoordinate utmCurrentPos = LtsCoordTrans::UtmCoordinate::fromGeographic(pos.lon(), pos.lat());
|
||||
|
||||
currentEffector.trajectoryRelative().emplace_back(utmCurrentPos.x - utmStartPos.x,
|
||||
utmCurrentPos.y - utmStartPos.y, pos.z(), currentFlightTime);
|
||||
|
||||
currentFlightTime += flightTimeStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RocketUtility
|
||||
} // namespace AreaEffectSimulation
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Namespace for rocket related functions
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Fritsche, ESZS, 2026-06-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AreaEffectSimulation/aes_enums.hpp>
|
||||
|
||||
class QComboBox;
|
||||
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
class EffectClusterModifyRequest;
|
||||
|
||||
namespace RocketUtility
|
||||
{
|
||||
|
||||
void enaDisaWirkmittel(QComboBox *wirkmittelCombobox, AesExplosionGeometry::type geometry);
|
||||
void addRocketPropertiesToRequest(EffectClusterModifyRequest &request, const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc);
|
||||
void addRocketPropertiesForPointGeometry(EffectClusterModifyRequest &request, const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc);
|
||||
void addRocketPropertiesForLinearGeometry(EffectClusterModifyRequest &request, const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc);
|
||||
|
||||
} // namespace RocketUtility
|
||||
} // namespace AreaEffectSimulation
|
||||
+1558
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user