Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Hannes Baeuerle, SLSE, 2017-02-24
|
||||
#
|
||||
|
||||
SET(ces_participant_move_gui_SRCS
|
||||
logger.cpp
|
||||
logger.h
|
||||
ces_participant_move_gui_plugin.h
|
||||
ces_participant_move_gui_plugin.cpp
|
||||
participants_move_model.h
|
||||
participants_move_model.cpp
|
||||
participants_move_dialog.h
|
||||
participants_move_dialog.cpp
|
||||
participant_move_dialog.h
|
||||
participant_move_dialog.cpp
|
||||
)
|
||||
|
||||
NGL_WRAP_UI (ces_participant_move_gui_SRCS
|
||||
participants_move_dialog.ui
|
||||
participant_move_dialog.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS CesParticipantMoveGuiPlugin MODULE ${ces_participant_move_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(CesParticipantMoveGuiPlugin
|
||||
AsbDataPluginInterface
|
||||
LtsCoordTrans
|
||||
LtsPrinting
|
||||
PpmDataPluginInterface
|
||||
PpmGuiParticipantsPluginInterface
|
||||
CesDataPluginInterface
|
||||
GuiPluginInterface
|
||||
AsmGuiPluginInterface
|
||||
ExmDataPluginInterface
|
||||
Qt5::Widgets
|
||||
PpmCommon
|
||||
FlmDataPluginInterface
|
||||
LtsUtilsGuiDds
|
||||
LtsWidgets
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsDataView
|
||||
SituationMapGuiPluginInterface
|
||||
LtsUtilsGuiDds
|
||||
ltsCoordWidget
|
||||
LtsUtilsSettings
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(CesParticipantMoveGuiPlugin)
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for Simulated Movement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSE, 2017-12-19
|
||||
*/
|
||||
|
||||
#include "ces_participant_move_gui_plugin.h"
|
||||
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
||||
#include <Services/CentralEffectSimulation/ces_operator_rights.h>
|
||||
#include <Plugins/CentralEffectSimulation/ces_data_plugin_interface.h>
|
||||
#include "participants_move_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Ces.ParticipantMove"))
|
||||
{
|
||||
}
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<CentralEffectSimulation::DataInterface>(m_cesDtc))
|
||||
return false;
|
||||
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
|
||||
return false;
|
||||
if (!m_session->getFtc<ParticipantManagement::DataInterface>(m_ppmFtc))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
m_ppmDtc = nullptr;
|
||||
m_ppmFtc = nullptr;
|
||||
m_cesDtc = nullptr;
|
||||
}
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
|
||||
LtsWidgets::PluginData plData;
|
||||
if (!m_session->isReplayPartition())
|
||||
{
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Move Participants");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:define_movement_simulation.svg"));
|
||||
plData.identifier = QLatin1String("ParticipantMove");
|
||||
plData.operatorRight = OperatorRights::ParticipantMove;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
|
||||
plData.createWidgetFunc = [this](QWidget * parent)
|
||||
{
|
||||
return LtsWidgets::initDialog(new ParticipantsMoveDialog(menuGroup(), parent),
|
||||
m_session, m_ppmDtc, m_cesDtc, m_ppmFtc);
|
||||
};
|
||||
ret.append(plData);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace CentralEffectSimulation
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for Simulated Movement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSE, 2017-12-19
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "logger.h"
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ParticipantManagement/ppm_ftc.h>
|
||||
#include <CentralEffectSimulation/ces_dtc.h>
|
||||
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
class ForeignGuiComboboxInterface;
|
||||
}
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:ces.participantmove")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QLatin1String("CesParticipantMoveGui"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return (partition == IDL::PartitionType::Exercise);
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public QObject, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
bool fetchInterfaces() override;
|
||||
void clearInterfaces() override;
|
||||
QString menuGroup() const override { return tr("Participants");}
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
|
||||
private: // attributes
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc;
|
||||
std::shared_ptr<CentralEffectSimulation::Interface::Dtc> m_cesDtc;
|
||||
};
|
||||
|
||||
} // namespace CentralEffectSimulation
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Building Config - logging facility
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "CES.";
|
||||
std::string loggerName;
|
||||
const size_t len = strlen(name);
|
||||
loggerName.reserve(sizeof(ns) + len);
|
||||
loggerName.append(ns, sizeof(ns) - 1);
|
||||
loggerName.append(name, len);
|
||||
|
||||
try
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
||||
getNGLLogger(loggerName);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace CentralEffectSimulation
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Logging for CentralEffectSimulation
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
typedef NGL::INGLLogger &LOGGER_T;
|
||||
|
||||
LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
} // namespace CentralEffectSimulation
|
||||
+538
@@ -0,0 +1,538 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Dialog for Simulated Movement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSE, 2018-01-02 */
|
||||
|
||||
#include "participant_move_dialog.h"
|
||||
#include "ui_participant_move_dialog.h"
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <Common/LtsCoordTrans/lts_coord_widget.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_gui_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
||||
#include <Plugins/CentralEffectSimulation/ces_data_plugin_interface.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
static constexpr double s_msConversion = 3.6; // = 3.6 Convert from [km/h] to [m/s]
|
||||
static constexpr int s_timeMilliConversion = 1000; // 1000 Convert from [s] to [ms]
|
||||
|
||||
ParticipantMoveDialog::ParticipantMoveDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_ftc(nullptr)
|
||||
, m_sitMapGuiIfc(nullptr)
|
||||
, m_ui(new Ui::WaypointsEdit)
|
||||
, m_id(0)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_polyline(QPolygonF())
|
||||
, m_logger(getLogger("ParticipantMoveDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->cbJump->hide();
|
||||
m_ui->label_5->hide();
|
||||
m_ui->spSpeed->setValue(30); // 30km/h per default
|
||||
m_ui->lePrefix->setText(tr("Waypoint"));
|
||||
m_uiRequirements->addRequirement({m_ui->lblMoveStart, [this]() { return hasValidEffectStart(m_ui->dteStartTime); }, tr("Begin time is smaller than current time")});
|
||||
connect (this, &ParticipantMoveDialog::signalFocused, this, &ParticipantMoveDialog::onFocus);
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Move_Participant_0"));
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ParticipantMoveDialog::~ParticipantMoveDialog()
|
||||
{
|
||||
m_sitMapGuiIfc = nullptr;
|
||||
delete m_ui;
|
||||
emit closeDialog(m_participantData.id());
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ParticipantMoveDialog::enableUiElements(bool enable)
|
||||
{
|
||||
m_ui->pbPosition->setEnabled(enable);
|
||||
m_ui->pbClear->setEnabled(enable);
|
||||
} // end of enableUiElements()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool ParticipantMoveDialog::init(LtsSession::LtsSessionDataDds *session,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<CentralEffectSimulation::Interface::Dtc> &cesDtc,
|
||||
const ParticipantManagement::ParticipantData &data)
|
||||
{
|
||||
m_session = session;
|
||||
m_participantData = data;
|
||||
m_cesDtc = cesDtc;
|
||||
|
||||
//bool editable = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::BorderlinesEdit);
|
||||
//bool readable = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::BorderlinesShow);
|
||||
//if (!readable && !editable)
|
||||
// return false;
|
||||
|
||||
if (!m_session->getFtc<CentralEffectSimulation::DataInterface>(m_ftc))
|
||||
return false;
|
||||
|
||||
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc);
|
||||
|
||||
if (m_sitMapGuiIfc)
|
||||
{
|
||||
connect(m_ui->pbPosition, &QPushButton::clicked, this, &ParticipantMoveDialog::onGetPolyline);
|
||||
connect(m_ui->pbClear, &QPushButton::clicked, this, &ParticipantMoveDialog::clearCoordinates);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->pbPosition->setEnabled(false);
|
||||
m_ui->pbClear->setEnabled(false);
|
||||
}
|
||||
|
||||
m_ui->dteStartTime->setMinimumTimeMSec(m_session->partitionTime());
|
||||
m_ui->dteStartTime->setRetrieveCurrentTimeCallback([this]() { return m_session->partitionTime(); });
|
||||
m_ui->lbIdentifier->setText(QString::fromStdString(data.tacticalIdentifier()));
|
||||
QString partyStr = ParticipantManagement::trPartyName(ppmDtc->party(m_participantData.partyId()).name());
|
||||
m_ui->lbParty->setText(partyStr);
|
||||
QString typeStr = ParticipantManagement::trTypeName(ppmDtc->type(m_participantData.typeId()).name());
|
||||
m_ui->lbType->setText(typeStr);
|
||||
|
||||
// enableUiElements(editable && readable);
|
||||
enableUiElements(true);
|
||||
|
||||
initTableHeader();
|
||||
|
||||
connect(cesDtc.get(), &CentralEffectSimulation::Interface::Dtc::simulatedMovementChanged,
|
||||
this, &ParticipantMoveDialog::onSimulatedMovementChanged);
|
||||
|
||||
// Get data for all SimulatedMovements
|
||||
{
|
||||
auto sm = [this](const CentralEffectSimulation::SimulatedMovement & sme)
|
||||
{
|
||||
onSimulatedMovementChanged(sme, DataModification::eAdded);
|
||||
};
|
||||
if (!m_cesDtc->simulatedMovements(sm))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save/Load from Library Button
|
||||
m_buttonBox->connectLibraryButton(this,
|
||||
&ParticipantMoveDialog::onImportButtonClicked,
|
||||
&ParticipantMoveDialog::onExportButtonClicked);
|
||||
|
||||
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_flmGui))
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Library, false);
|
||||
|
||||
return true;
|
||||
|
||||
} // end of init()
|
||||
|
||||
void ParticipantMoveDialog::onSimulatedMovementChanged(const CentralEffectSimulation::SimulatedMovement &data, DataModification modType)
|
||||
{
|
||||
if (modType == DataModification::eRemoved || m_participantData.id() != data.participantId())
|
||||
return;
|
||||
INFO_LOG(m_logger) << "onSimulatedMovementChanged";
|
||||
|
||||
// Clear data
|
||||
clearContent();
|
||||
// set new Content
|
||||
m_id = data.id();
|
||||
m_ui->lePrefix->setText(QString::fromStdString(data.name()));
|
||||
m_ui->cbRepeat->setChecked(data.repeat());
|
||||
m_ui->cbJump->setChecked(data.jumpToStart());
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(data.startTime());
|
||||
m_polyline.clear();
|
||||
// Insert data to Vector
|
||||
for (const SimulatedMovementSegment &segment : data.segments())
|
||||
{
|
||||
const Core::GeoPosition2D &pointDds = segment.position();
|
||||
insertPos(pointDds.lon(), pointDds.lat(), QString::fromStdString(segment.name()), segment.delay(), segment.speed());
|
||||
m_polyline.push_back(QPointF(pointDds.lon(), pointDds.lat()));
|
||||
}
|
||||
// Insert data to Map (Preview)
|
||||
if (this->amIFocused())
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, m_polyline, false);
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::showPreview(bool show)
|
||||
{
|
||||
if (m_sitMapGuiIfc)
|
||||
{
|
||||
if (show)
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, m_polyline, false);
|
||||
else
|
||||
m_sitMapGuiIfc->removePreviewObject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ParticipantMoveDialog::onSimulatedMovementRemoveReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
if (!replyObject.error())
|
||||
{
|
||||
m_sitMapGuiIfc->cancelActiveRubberbands();
|
||||
m_sitMapGuiIfc->removePreviewObject();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::onSimulatedMovementModifyReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
if (!replyObject.error())
|
||||
m_sitMapGuiIfc->removePreviewObject();
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, QString::fromStdString(m_participantData.tacticalIdentifier()), false, tr("Waypoints")); // TODO: lock topic?
|
||||
DEBUG_LOG(m_logger) << "retranslate";
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::initTableHeader()
|
||||
{
|
||||
QStringList headers;
|
||||
headers << tr("Identifier") << tr("Idle Time [s]") << tr("Speed [km/h]") << tr("Position");
|
||||
m_ui->tableWidget->setHorizontalHeaderLabels(headers);
|
||||
m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
}
|
||||
|
||||
// idleTime in [s] speed in [m/s]
|
||||
void ParticipantMoveDialog::insertPos(const double lon, const double lat, const QString &identifier, const int idleTime, const double speed)
|
||||
{
|
||||
QLineEdit *le = new QLineEdit;
|
||||
QSpinBox *sbDelay = new QSpinBox;
|
||||
QSpinBox *sbSpeed = new QSpinBox;
|
||||
sbDelay->setMinimum(m_ui->spIdleTime->minimum());
|
||||
sbDelay->setMaximum(m_ui->spIdleTime->maximum());
|
||||
sbSpeed->setMinimum(m_ui->spSpeed->minimum());
|
||||
sbSpeed->setMaximum(m_ui->spSpeed->maximum());
|
||||
int rowCount = m_ui->tableWidget->rowCount();
|
||||
|
||||
LtsCoordWidget::LtsCoordWidget *wdg = new LtsCoordWidget::LtsCoordWidget();
|
||||
//wdg->setCoordinate( 8.794556, 53.080827);
|
||||
wdg->setCoordinate(lon, lat);
|
||||
wdg->setObjectName(QStringLiteral("positionEdit_") + QString::number(rowCount));
|
||||
m_ui->tableWidget->insertRow(rowCount);
|
||||
le->setText(identifier);
|
||||
m_ui->tableWidget->setCellWidget(rowCount, Name, le);
|
||||
sbDelay->setValue(idleTime / s_timeMilliConversion);
|
||||
m_ui->tableWidget->setCellWidget(rowCount, IdleTime, sbDelay);
|
||||
sbSpeed->setValue(speed * s_msConversion);
|
||||
m_ui->tableWidget->setCellWidget(rowCount, Speed, sbSpeed);
|
||||
m_ui->tableWidget->setCellWidget(rowCount, Position, wdg);
|
||||
wdg->setDisplayType(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
void WaypointsEdit::setData(const Borderline &borderline, bool copy)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "borderlineId: " << borderline.id()
|
||||
<< " operatorId: " << borderline.operatorId();
|
||||
|
||||
} // end of setData()
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
void ParticipantMoveDialog::clearContent()
|
||||
{
|
||||
m_ui->lePrefix->clear();
|
||||
m_ui->cbRepeat->setChecked(false);
|
||||
m_ui->cbJump->setChecked(false);
|
||||
|
||||
clearCoordinates();
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::clearCoordinates()
|
||||
{
|
||||
if (m_ui)
|
||||
{
|
||||
m_ui->tableWidget->clearContents();
|
||||
m_ui->tableWidget->setRowCount(0);
|
||||
}
|
||||
// remove PreviewObject:
|
||||
if ( m_sitMapGuiIfc && this->amIFocused())
|
||||
m_sitMapGuiIfc->removePreviewObject();
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::onFocus()
|
||||
{
|
||||
showPreview(true);
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, m_polyline, false);
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::onGetPolyline()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION;
|
||||
|
||||
if (!m_sitMapGuiIfc)
|
||||
return;
|
||||
|
||||
if (m_sitMapGuiIfc->mapMode() != SituationMap::MapMode::MapMode_2D)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Only available in 2D mode"));
|
||||
return;
|
||||
}
|
||||
|
||||
QPolygonF coordinates;
|
||||
int i = 0;
|
||||
while (true)
|
||||
{
|
||||
LtsCoordWidget::LtsCoordWidget *w = findChild<LtsCoordWidget::LtsCoordWidget *>(QStringLiteral("positionEdit_%1").arg(i));
|
||||
if (!w)
|
||||
break;
|
||||
if (!w->coordinate().isNull())
|
||||
coordinates << w->coordinate();
|
||||
++i;
|
||||
}
|
||||
|
||||
m_sitMapGuiIfc->getPolyline(this,
|
||||
SLOT(onPolylineData(QPolygonF)),
|
||||
nullptr,
|
||||
2,
|
||||
11,
|
||||
-1,
|
||||
-1,
|
||||
coordinates);
|
||||
|
||||
} // end of onGetPolyline()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ParticipantMoveDialog::onPolylineData(const QPolygonF &polyline)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " numberOfPoints: " << polyline.size();
|
||||
|
||||
if (polyline.size() < 2)
|
||||
return;
|
||||
|
||||
m_polyline = polyline;
|
||||
|
||||
clearCoordinates();
|
||||
for (int i = 0; i < polyline.size(); i++)
|
||||
insertPos(polyline.at(i).x(), polyline.at(i).y(),
|
||||
m_ui->lePrefix->text() + QLatin1Char('_') + QString::number(i + 1),
|
||||
m_ui->spIdleTime->value() * s_timeMilliConversion,
|
||||
m_ui->spSpeed->value() / s_msConversion);
|
||||
|
||||
// create PreviewObject:
|
||||
m_sitMapGuiIfc->displayPreviewObject(this, polyline, false);
|
||||
|
||||
} // end of onPolylineData()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool ParticipantMoveDialog::hasValidEffectStart(LtsWidgets::LtsDateTimeEdit *dte) const
|
||||
{
|
||||
// if there is visible a enabled/disable checkbox -> also allow 0 as effect start
|
||||
const bool bEmptyAllowed = dte->isCheckable();
|
||||
const auto ms = dte->msecsSinceEpoch();
|
||||
// no effect start -> ok
|
||||
if (bEmptyAllowed && ms == 0)
|
||||
return true;
|
||||
return ms > m_session->partitionTime();
|
||||
}
|
||||
|
||||
SimulatedMovement ParticipantMoveDialog::requestContent() const
|
||||
{
|
||||
std::string name = m_ui->lePrefix->text().toStdString();
|
||||
int32_t repeat = m_ui->cbRepeat->isChecked();
|
||||
//int32_t jumpToStart = m_ui->cbJump->isChecked();
|
||||
int32_t jumpToStart = true;
|
||||
rti::core::int64 startTime = m_ui->dteStartTime->msecsSinceEpoch();
|
||||
int32_t participantId = m_participantData.id();
|
||||
int32_t nextPoint = 0;
|
||||
|
||||
int cntSegments = m_ui->tableWidget->rowCount();
|
||||
std::vector<CentralEffectSimulation::SimulatedMovementSegment> segments;
|
||||
segments.resize(cntSegments);
|
||||
for (int i = 0; i < cntSegments; i++)
|
||||
{
|
||||
QWidget *widget = m_ui->tableWidget->cellWidget(i, Name);
|
||||
const QString nameSeg = static_cast<QLineEdit *>(widget)->text();
|
||||
segments[i].name(nameSeg.toStdString());
|
||||
|
||||
widget = m_ui->tableWidget->cellWidget(i, IdleTime);
|
||||
const int idleTime = static_cast<QSpinBox *>(widget)->value() * s_timeMilliConversion;
|
||||
segments[i].delay(idleTime);
|
||||
|
||||
widget = m_ui->tableWidget->cellWidget(i, Speed);
|
||||
const double speed = static_cast<QSpinBox *>(widget)->value() / s_msConversion;
|
||||
|
||||
segments[i].speed(speed);
|
||||
|
||||
widget = m_ui->tableWidget->cellWidget(i, Position);
|
||||
const QPointF point = static_cast<LtsCoordWidget::LtsCoordWidget *>(widget)->coordinate();
|
||||
const Core::GeoPosition2D pos(Core::GeoPosition2D(point.x(), point.y()));
|
||||
segments[i].position(pos);
|
||||
}
|
||||
|
||||
return SimulatedMovement(m_id,
|
||||
name,
|
||||
startTime,
|
||||
participantId,
|
||||
segments,
|
||||
repeat,
|
||||
jumpToStart,
|
||||
nextPoint
|
||||
);
|
||||
}
|
||||
|
||||
bool ParticipantMoveDialog::apply()
|
||||
{
|
||||
int cntSegments = m_ui->tableWidget->rowCount();
|
||||
if (cntSegments > 0)
|
||||
{
|
||||
const SimulatedMovement req = requestContent();
|
||||
|
||||
INFO_LOG(m_logger) << "--- onApplyMessage() ";
|
||||
|
||||
m_requestHelper->addRequest([this, req]()
|
||||
{
|
||||
return m_ftc->simulatedMovementModifyRequest(req, this);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_id > 0)
|
||||
{
|
||||
Core::RemoveElementRequest req(m_id);
|
||||
m_id = 0; // Next time new Route
|
||||
|
||||
INFO_LOG(m_logger) << "--- onApplyMessage() ";
|
||||
|
||||
m_requestHelper->addRequest([req, this]()
|
||||
{
|
||||
return m_ftc->simulatedMovementRemoveRequest(req, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Save / Load Simulation in DB
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QByteArray ParticipantMoveDialog::simulatedMovementToJson() const
|
||||
{
|
||||
const SimulatedMovement req = requestContent();
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::CESParticipantMove);
|
||||
|
||||
obj[QStringLiteral("id")] = req.id();
|
||||
obj[QStringLiteral("jumpToStart")] = req.jumpToStart();
|
||||
obj[QStringLiteral("name")] = QString::fromStdString(req.name());
|
||||
obj[QStringLiteral("nextPoint")] = req.nextPoint();
|
||||
obj[QStringLiteral("participantId")] = req.participantId();
|
||||
obj[QStringLiteral("repeat")] = req.repeat();
|
||||
obj[QStringLiteral("startTime")] = req.startTime();
|
||||
|
||||
QJsonArray arr;
|
||||
for (auto it = req.segments().begin(); it != req.segments().end(); ++it)
|
||||
{
|
||||
QJsonObject inner;
|
||||
inner[QStringLiteral("delay")] = it->delay();
|
||||
inner[QStringLiteral("name")] = QString::fromStdString(it->name());
|
||||
inner[QStringLiteral("speed")] = it->speed();
|
||||
inner[QStringLiteral("lat")] = it->position().lat();
|
||||
inner[QStringLiteral("lon")] = it->position().lon();
|
||||
arr += inner;
|
||||
}
|
||||
obj[QStringLiteral("segments")] = arr;
|
||||
|
||||
QJsonDocument doc(obj);
|
||||
return doc.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
SimulatedMovement ParticipantMoveDialog::jsonToSimulatedMovement(const QByteArray &content) const
|
||||
{
|
||||
// already checked that content is not empty, parseable and contains proper XmlType (CESParticipantMove)
|
||||
CentralEffectSimulation::SimulatedMovement result;
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(content));
|
||||
const QJsonObject obj(doc.object());
|
||||
|
||||
result.id(obj[QStringLiteral("id")].toInt()); //TODO Library: check id = 0?
|
||||
result.jumpToStart(obj[QStringLiteral("jumpToStart")].toInt());
|
||||
result.name(obj[QStringLiteral("name")].toString().toStdString());
|
||||
result.nextPoint(obj[QStringLiteral("nextPoint")].toInt());
|
||||
result.participantId(m_participantData.id());
|
||||
result.repeat(obj[QStringLiteral("repeat")].toInt());
|
||||
result.startTime(obj[QStringLiteral("startTime")].toDouble());
|
||||
|
||||
const QJsonArray arr(obj.value(QStringLiteral("segments")).toArray());
|
||||
auto &segments = result.segments();
|
||||
segments.resize(arr.size());
|
||||
for (int i = 0; i < arr.size(); ++i)
|
||||
{
|
||||
CentralEffectSimulation::SimulatedMovementSegment &segment = segments[i];
|
||||
const QJsonObject objArr(arr.at(i).toObject());
|
||||
segment.delay(objArr[QStringLiteral("delay")].toDouble());
|
||||
segment.name(objArr[QStringLiteral("name")].toString().toStdString());
|
||||
|
||||
|
||||
segment.position().lat(objArr[QStringLiteral("lat")].toDouble());
|
||||
segment.position().lon(objArr[QStringLiteral("lon")].toDouble());
|
||||
segment.speed(objArr[QStringLiteral("speed")].toDouble());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::onExportButtonClicked()
|
||||
{
|
||||
QJsonObject saveObject;
|
||||
saveObject[QStringLiteral("content")] = QString();
|
||||
|
||||
const QByteArray byteArray = simulatedMovementToJson();
|
||||
|
||||
int fileId = m_flmGui->saveFileContent(this, FileManagement::FileType::Xml, m_session->exerciseId(), byteArray);
|
||||
if (fileId > 0)
|
||||
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Could not save file in library ";
|
||||
}
|
||||
|
||||
void ParticipantMoveDialog::onImportButtonClicked()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " onImportButtonClicked() ";
|
||||
|
||||
QByteArray content;
|
||||
int fileId = m_flmGui->loadFileContent(this, content, {FileManagement::FileType::Xml}, m_session->exerciseId(), FileManagement::toString(FileManagement::XmlType::CESParticipantMove));
|
||||
if (fileId > 0)
|
||||
{
|
||||
if (!m_flmGui->isXmlType(content, FileManagement::toString(FileManagement::XmlType::CESParticipantMove)))
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Invalid xml file content"),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes,
|
||||
texts);
|
||||
}
|
||||
else
|
||||
{
|
||||
SimulatedMovement req = jsonToSimulatedMovement(content);
|
||||
|
||||
INFO_LOG(m_logger) << "--- onImportButtonClicked() ";
|
||||
|
||||
m_requestHelper->addRequest([this, req]()
|
||||
{
|
||||
return m_ftc->simulatedMovementModifyRequest(req, this);
|
||||
});
|
||||
m_requestHelper->startRequests();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace CentralEffectSimulation
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Dialog for Simulated Movement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSE, 2018-01-02 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <CentralEffectSimulation/ces_ftc.h>
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
//DDS
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <CentralEffectSimulation/ces_dtc.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class WaypointsEdit;
|
||||
}
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
class LtsDateTimeEdit;
|
||||
}
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
class TypeModel;
|
||||
|
||||
class ParticipantMoveDialog: public LtsWidgets::LtsDialog
|
||||
, protected CentralEffectSimulation::Interface::Ftc::SimulatedMovementRemoveReplyHandler
|
||||
, protected CentralEffectSimulation::Interface::Ftc::SimulatedMovementModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum SegementColumns
|
||||
{
|
||||
Name,
|
||||
IdleTime,
|
||||
Speed,
|
||||
Position
|
||||
};
|
||||
explicit ParticipantMoveDialog(QWidget *parent = nullptr);
|
||||
~ParticipantMoveDialog();
|
||||
|
||||
bool init(LtsSession::LtsSessionDataDds *session,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<CentralEffectSimulation::Interface::Dtc> &cesDtc,
|
||||
const ParticipantManagement::ParticipantData &data);
|
||||
|
||||
void retranslate() override;
|
||||
|
||||
//virtual functions from CentralEffectSimulation::Interface::Ftc
|
||||
void onSimulatedMovementRemoveReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onSimulatedMovementModifyReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
|
||||
void showPreview(bool show);
|
||||
|
||||
signals:
|
||||
void closeDialog(int32_t participantId);
|
||||
|
||||
private:
|
||||
//std::vector<LtsCoordWidget::LtsCoordWidget *> coordWidgets() const override;
|
||||
|
||||
//void setData(const Borderline &borderline, bool copy);
|
||||
void enableUiElements(bool enable);
|
||||
void initTableHeader();
|
||||
void insertPos(const double lon, const double lat, const QString &identifier, const int idleTime, const double speed);
|
||||
//void onApply();
|
||||
void clearCoordinates();
|
||||
void clearContent();
|
||||
bool hasValidEffectStart(LtsWidgets::LtsDateTimeEdit *dte) const;
|
||||
bool apply() override;
|
||||
SimulatedMovement requestContent() const;
|
||||
QByteArray simulatedMovementToJson() const;
|
||||
SimulatedMovement jsonToSimulatedMovement(const QByteArray &content) const;
|
||||
|
||||
private slots:
|
||||
void onGetPolyline();
|
||||
void onPolylineData(const QPolygonF &polyline); // callback for onGetPolyline()
|
||||
void onSimulatedMovementChanged(const CentralEffectSimulation::SimulatedMovement &data, DataModification modType);
|
||||
void onFocus();
|
||||
void onExportButtonClicked();
|
||||
void onImportButtonClicked();
|
||||
|
||||
private:
|
||||
std::shared_ptr<CentralEffectSimulation::Interface::Dtc> m_cesDtc;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
|
||||
|
||||
Ui::WaypointsEdit *m_ui;
|
||||
LtsSession::LtsSessionDataDds *m_session;
|
||||
ParticipantManagement::ParticipantData m_participantData;
|
||||
int m_id;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
QPolygonF m_polyline;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
};
|
||||
|
||||
} // namespace CentralEffectSimulation
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>WaypointsEdit</class>
|
||||
<widget class="QWidget" name="WaypointsEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>808</width>
|
||||
<height>535</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">MessagingView</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Tact. Identifier:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lbIdentifier">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Party:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lbParty">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lbType">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblMoveStart">
|
||||
<property name="text">
|
||||
<string>Start Time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="LtsWidgets::LtsDateTimeEdit" name="dteStartTime">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Edit Waypoints in Map:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbPosition">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Light/resources/rme_light_style.qrc">
|
||||
<normaloff>:/style/position.svg</normaloff>:/style/position.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbClear">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Light/resources/rme_light_style.qrc">
|
||||
<normaloff>:/style/remove.svg</normaloff>:/style/remove.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Idle Time [s]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spIdleTime">
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Prefix:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lePrefix">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Speed [km/h]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Repeat:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Jump to Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="cbRepeat">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="cbJump">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spSpeed"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidget">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDateTimeEdit</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_date_time_edit.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../Styles/Light/resources/rme_light_style.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
+905
@@ -0,0 +1,905 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for ParticipantsMoveDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSE, 2018-01-02*/
|
||||
|
||||
#include "participants_move_dialog.h"
|
||||
#include "participants_move_model.h"
|
||||
#include "ui_participants_move_dialog.h"
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
#include <AdvancedSymbology/asb_data_plugin_interface.h>
|
||||
#include <CentralEffectSimulation/ces_data_plugin_interface.h>
|
||||
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
|
||||
#include <Plugins/AssetManagement/asm_data_plugin_interface.h>
|
||||
#include <AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
|
||||
#include "participant_move_dialog.h"
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <LtsSession/lts_session_data_dds.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
#include <LtsCoordTrans/lts_coord_widget.h>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDebug>
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
ParticipantsMoveDialog::ParticipantsMoveDialog(const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_participantModel(nullptr)
|
||||
, m_ppmDtc(nullptr)
|
||||
, m_ppmCbxIfc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_ui(new Ui::ParticipantMoveDialog)
|
||||
, m_session(nullptr)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_sitMapGuiIfc(nullptr)
|
||||
, m_logger(getLogger("ParticipantsMoveDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setUnchangeable();
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Save, this, &ParticipantsMoveDialog::onSetSimulatedMGRSPosition);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, false);
|
||||
m_buttonBox->setIcon(LtsWidgets::DialogButton::Save, QIcon(QStringLiteral("icon:position.svg")));
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &ParticipantsMoveDialog::onClicked);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, false);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &ParticipantsMoveDialog::onSetPosition);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, false);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &ParticipantsMoveDialog::onRemove);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, false);
|
||||
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Move_Participant_0"));
|
||||
}
|
||||
|
||||
ParticipantsMoveDialog::~ParticipantsMoveDialog()
|
||||
{
|
||||
m_sitMapGuiIfc = nullptr;
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
static constexpr int s_maxAngleDeg = 360;
|
||||
static constexpr int s_maxAngleMil = 6400;
|
||||
inline constexpr int mil2Deg(const int &mil)
|
||||
{
|
||||
return s_maxAngleDeg * mil / s_maxAngleMil;
|
||||
}
|
||||
inline constexpr int deg2Mil(const int &angleDeg)
|
||||
{
|
||||
return s_maxAngleMil * angleDeg / s_maxAngleDeg;
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Move Participant"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setText(tr("Set Simulated MGRS Position"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->setText(tr("Set Simulated Position"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Edit)->setText(tr("Edit Simulation"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setText(tr("Remove Simulation"));
|
||||
}
|
||||
|
||||
bool ParticipantsMoveDialog::init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<CentralEffectSimulation::Interface::Dtc> &cesDtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc)
|
||||
{
|
||||
m_ppmDtc = ppmDtc;
|
||||
m_cesDtc = cesDtc;
|
||||
m_session = session;
|
||||
m_ppmFtc = ppmFtc;
|
||||
|
||||
if (!m_ppmDtc)
|
||||
return false;
|
||||
|
||||
if (!m_ppmFtc)
|
||||
return false;
|
||||
|
||||
if (!session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmCbxIfc))
|
||||
return false;
|
||||
|
||||
if (!m_session->getFtc<CentralEffectSimulation::DataInterface>(m_ftc))
|
||||
return false;
|
||||
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> exmDtc;
|
||||
if (!m_session->getDtc<ExerciseManagement::DataInterface>(exmDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "failed to get exmDtc ";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<AssetManagement::Interface::Dtc> asmDtc;
|
||||
if (!m_session->getDtc<AssetManagement::DataInterface>(asmDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "failed to get asmDtc ";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (asmDtc == nullptr || exmDtc == nullptr)
|
||||
return false;
|
||||
|
||||
const ExerciseManagement::Exercise exc = exmDtc->exercise(m_session->exerciseId());
|
||||
AssetManagement::TrainingArea ta = asmDtc->trainingArea(exc.trainingAreaId());
|
||||
if (ta.id() != exc.trainingAreaId())
|
||||
{
|
||||
ERROR_LOG(m_logger)<<" couldn't get Training Area with id: "<<exc.trainingAreaId();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_session ->getDtc<AreaEffectSimulation::DataInterface>(m_aesDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger)<<"failed to get aesDtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get training area Rect
|
||||
const LtsCoordTrans::UtmCoordinate &bottomLeft = LtsCoordTrans::UtmCoordinate::fromGeographic(ta.bottomLeft().lon(), ta.bottomLeft().lat());
|
||||
m_trainingAreaRect = QRectF(bottomLeft.geographic(0, ta.height()), bottomLeft.geographic(ta.width(), 0));
|
||||
|
||||
|
||||
// for relativeMove of units via SetSimulatedPositionRelative:
|
||||
m_ppmDtc->enableUnitPosition();
|
||||
m_ppmDtc->waitForHistoricalDataUnitPosition(1000);
|
||||
|
||||
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> asb;
|
||||
session->getForeignDataInterface<AdvancedSymbology::DataInterface>(asb);
|
||||
m_participantModel = new ParticipantMoveModel(this, m_ppmDtc, asb);
|
||||
// only needed to set recursiveFilteringEnabled
|
||||
auto proxyModel = new ParticipantManagement::ParticipantTreeFilterProxyModel(this);
|
||||
proxyModel->setSourceModel(m_participantModel);
|
||||
proxyModel->setRecursiveFilteringEnabled(true);
|
||||
m_ui->dvParticipants->setModel(proxyModel);
|
||||
m_ui->dvParticipants->setSortIndicator(0, Qt::AscendingOrder);
|
||||
|
||||
connect(m_ui->cbParty,
|
||||
static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged),
|
||||
this, &ParticipantsMoveDialog::changeParty);
|
||||
connect(m_ui->cbAll, &QCheckBox::toggled, this, &ParticipantsMoveDialog::changeParty);
|
||||
|
||||
connect(m_ui->dvParticipants, &LtsDataView::LtsDataView::selectionChanged,
|
||||
this, &ParticipantsMoveDialog::onSelectionChanged);
|
||||
|
||||
connect(m_participantModel, &ParticipantMoveModel::newData,
|
||||
this, &ParticipantsMoveDialog::onModelChanged);
|
||||
|
||||
connect(m_ui->dvParticipants, &LtsDataView::LtsDataView::signalDoubleClicked,
|
||||
this, &ParticipantsMoveDialog::onDoubleClicked);
|
||||
|
||||
|
||||
m_ppmCbxIfc->fillPartyComboBox(m_ui->cbParty, ParticipantManagement::ForeignGuiComboboxInterface::CbxPartyFilter::All);
|
||||
changeParty();
|
||||
|
||||
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->setIcon(QIcon(QStringLiteral("icon:position.svg")));
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->dvParticipants->hideColumn(ParticipantMoveModel::ColParticipantId);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//private
|
||||
|
||||
void ParticipantsMoveDialog::closeDialogReceived(int32_t participantId)
|
||||
{
|
||||
m_participantDialogMap.remove(participantId);
|
||||
}
|
||||
|
||||
|
||||
void ParticipantsMoveDialog::onSelectionChanged()
|
||||
{
|
||||
const QModelIndexList indexList = m_ui->dvParticipants->selectedRows();
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, false);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, false);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, false);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, false);
|
||||
bool isOne = (indexList.size() == 1);
|
||||
|
||||
// Set remove Btn
|
||||
if (!isOne)
|
||||
return;
|
||||
|
||||
const ParticipantManagement::ParticipantData data(participantFromIndex(indexList.first()));
|
||||
DEBUG_LOG(m_logger) << "ParticipantId: " << data.id();
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, data.isSimulated());
|
||||
// Show preview of selected Simulation
|
||||
if (data.isSimulated() && m_participantDialogMap.contains(data.id()))
|
||||
m_participantDialogMap.value(data.id())->showPreview(true);
|
||||
else
|
||||
{
|
||||
// Remove Preview
|
||||
QMapIterator<int, ParticipantMoveDialog *> i(m_participantDialogMap);
|
||||
while (i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
//cout << i.key() << ": " << i.value() << endl;
|
||||
i.value()->showPreview(false);
|
||||
}
|
||||
}
|
||||
|
||||
// allow moving units (with all its children)
|
||||
{
|
||||
bool isParticipantInUseOrAdler = participantInUse4ExplosionCluster(indexList.first());
|
||||
// Check for Adler Type too
|
||||
if (!isParticipantInUseOrAdler)
|
||||
isParticipantInUseOrAdler = (m_ppmDtc->isAdlerType(data.typeId()) && !data.name().empty());
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, isOne && !isParticipantInUseOrAdler);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, isOne && !isParticipantInUseOrAdler);
|
||||
}
|
||||
|
||||
if (m_ppmDtc->type(data.typeId()).typeClass() != ParticipantManagement::TypeClass_def::Unit)
|
||||
{
|
||||
|
||||
if (!data.equipmentNumber().is_set() || data.equipmentNumber().get() <= 0)
|
||||
{
|
||||
//No Sim MoveMent for Adler SAA Participants
|
||||
isOne &= !(m_ppmDtc->isAdlerType(data.typeId()) && !data.name().empty());
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, isOne);
|
||||
}
|
||||
else
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onModelChanged()
|
||||
{
|
||||
m_ui->dvParticipants->expandAll();
|
||||
DEBUG_LOG(m_logger) << "onModelChanged";
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onDoubleClicked()
|
||||
{
|
||||
if (!m_sitMapGuiIfc)
|
||||
return;
|
||||
|
||||
if (m_sitMapGuiIfc->mapMode() != SituationMap::MapMode::MapMode_2D)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Only available in 2D mode"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_buttonBox->isButtonEnabled(LtsWidgets::DialogButton::Edit))
|
||||
return;
|
||||
const QModelIndexList indexList = m_ui->dvParticipants->selectedRows();
|
||||
|
||||
bool isOne = (indexList.size() == 1);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, isOne);
|
||||
|
||||
if (!isOne)
|
||||
return;
|
||||
|
||||
const ParticipantManagement::ParticipantData data(participantFromIndex(indexList.first()));
|
||||
DEBUG_LOG(m_logger) << "ParticipantId: " << data.id();
|
||||
|
||||
if (!m_participantDialogMap.contains(data.id()))
|
||||
{
|
||||
ParticipantMoveDialog *dialog = new ParticipantMoveDialog(this);
|
||||
m_participantDialogMap.insert(data.id(), dialog);
|
||||
connect(dialog, &ParticipantMoveDialog::closeDialog,
|
||||
this, &ParticipantsMoveDialog::closeDialogReceived);
|
||||
|
||||
addDialog(LtsWidgets::initDialog(dialog, m_session, m_ppmDtc, m_cesDtc, data),
|
||||
m_menuGroup, QStringLiteral("cesNewSimulation%1").arg(data.id()), LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
else
|
||||
focusDialog(m_menuGroup, QStringLiteral("cesNewSimulation%1").arg(data.id()), LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
|
||||
//Slots
|
||||
void ParticipantsMoveDialog::changeParty()
|
||||
{
|
||||
if (m_ui->cbAll->isChecked())
|
||||
{
|
||||
m_ui->cbParty->setEnabled(false);
|
||||
m_ui->dvParticipants->setEnabled(false);
|
||||
m_participantModel->resetModel();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->cbParty->setEnabled(true);
|
||||
m_ui->dvParticipants->setEnabled(true);
|
||||
int partyId = m_ui->cbParty->currentData().toInt();
|
||||
m_participantModel->onReinitModel(partyId);
|
||||
m_ui->dvParticipants->expandAll();
|
||||
}
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, m_ui->cbAll->isChecked());
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onClicked()
|
||||
{
|
||||
onDoubleClicked();
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onRemove()
|
||||
{
|
||||
const QModelIndexList indexList = m_ui->dvParticipants->selectedRows();
|
||||
|
||||
bool isOne = (indexList.size() == 1);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, isOne);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, false);
|
||||
|
||||
if (!isOne)
|
||||
return;
|
||||
|
||||
const ParticipantManagement::ParticipantData data(participantFromIndex(indexList.first()));
|
||||
INFO_LOG(m_logger) << "onRemove ParticipantId: " << data.id();
|
||||
|
||||
// Remove (possible) open Dialogs
|
||||
delete m_participantDialogMap.value(data.id());
|
||||
m_participantDialogMap.remove(data.id());
|
||||
|
||||
removeFtc(data.id());
|
||||
}
|
||||
|
||||
|
||||
void ParticipantsMoveDialog::onSetSimulatedMGRSPosition()
|
||||
{
|
||||
const QModelIndexList &indexList = m_ui->dvParticipants->selectedRows();
|
||||
if (indexList.size() == 1)
|
||||
{
|
||||
QPointF mgrsCoordinate;
|
||||
m_mgrsPosEditCoordinateActive = true;
|
||||
if(!participantInUse4ExplosionCluster(indexList.first()))
|
||||
{
|
||||
onGetCoordinate(mgrsCoordinate);
|
||||
m_mgrsPosEditCoordinateActive = false;
|
||||
}
|
||||
else
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("This Participant Unit is currently in use.\nThe Parameters can't be changed!"));
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticipantsMoveDialog::participantInUse4ExplosionCluster(const QModelIndex &participantIndex)
|
||||
{
|
||||
const ParticipantManagement::ParticipantData participantData(participantFromIndex(participantIndex));
|
||||
bool bret=false;
|
||||
|
||||
const ParticipantManagement::Type &participantType = m_ppmDtc->type(participantData.typeId());
|
||||
bool isUnitType = (participantType.typeClass() == ParticipantManagement::TypeClass::Unit) ||
|
||||
(participantType.typeClass() == ParticipantManagement::TypeClass::SupportUnit);
|
||||
// get parent
|
||||
//only units tell us if participants are in used with explosion cluster
|
||||
if (!isUnitType)
|
||||
{
|
||||
const QModelIndex parentIndex = m_participantModel->indexFromParticipantId(participantData.superiorModId());
|
||||
const ParticipantManagement::ParticipantData parentParticipantData(participantFromIndex(parentIndex));
|
||||
|
||||
const ParticipantManagement::Type &partentParticipantType = m_ppmDtc->type(parentParticipantData.typeId());
|
||||
isUnitType = (partentParticipantType.typeClass() == ParticipantManagement::TypeClass::Unit) ||
|
||||
(partentParticipantType.typeClass() == ParticipantManagement::TypeClass::SupportUnit);
|
||||
bret = isUnitType && isParticipantInUseForExplosionCluster(parentParticipantData.id());;
|
||||
}
|
||||
else
|
||||
bret = isParticipantInUseForExplosionCluster(participantData.id());
|
||||
|
||||
return bret;
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onSimulatedMovementRemoveByParticipantIdReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onSetSimulatedPositionReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onSetSimulatedPositionRelativeReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onSetSimulatedParticipantFormationReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
bool ParticipantsMoveDialog::removeFtc(int32_t participantId)
|
||||
{
|
||||
if (participantId <= 0)
|
||||
return true;
|
||||
|
||||
CentralEffectSimulation::SimulatedMovementRemoveByParticipantId req(participantId);
|
||||
|
||||
m_requestHelper->addRequest([req, this]()
|
||||
{
|
||||
return m_ftc->simulatedMovementRemoveByParticipantIdRequest(req, this);
|
||||
});
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onGetCoordinate(QPointF coordinate)
|
||||
{
|
||||
const QModelIndexList indexList = m_ui->dvParticipants->selectedRows();
|
||||
if (indexList.size() == 0)
|
||||
return;
|
||||
|
||||
const ParticipantManagement::ParticipantData participantData(participantFromIndex(indexList.first()));
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << "ParticipantId=" << participantData.id()
|
||||
<< " EquipmentNr=" << participantData.equipmentNumber()
|
||||
<< " onGetCoordinate x=" << coordinate.x() << " y=" << coordinate.y();
|
||||
if (participantData.id() <= 0)
|
||||
return;
|
||||
|
||||
const ParticipantManagement::Type &participantType = m_ppmDtc->type(participantData.typeId());
|
||||
const bool &isUnitType =
|
||||
(participantType.typeClass() == ParticipantManagement::TypeClass::Unit) ||
|
||||
(participantType.typeClass() == ParticipantManagement::TypeClass::SupportUnit);
|
||||
|
||||
|
||||
// get participant type properties
|
||||
// special handling when participant has Artillery as property
|
||||
m_formationProps.setFormation(QString::fromStdString(participantType.properties()));
|
||||
const bool &withFormation = (isUnitType && m_formationProps.isArtillery);
|
||||
if (withFormation || m_mgrsPosEditCoordinateActive)
|
||||
setFormationAndPositioningUi(participantData, coordinate, withFormation);
|
||||
else if (isUnitType)
|
||||
m_shiftModifierWhileOnSetPosition ? doSetSimulatedPositionRequest(participantData, coordinate) :
|
||||
doSetSimulatedPositionRelativeRequest(participantData, coordinate);
|
||||
else
|
||||
doSetSimulatedPositionRequest(participantData, coordinate); // single (human|vehicle)
|
||||
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::onSetPosition()
|
||||
{
|
||||
|
||||
if (!m_sitMapGuiIfc) //sanity
|
||||
return;
|
||||
|
||||
if (m_sitMapGuiIfc->mapMode() != SituationMap::MapMode::MapMode_2D)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Only available in 2D mode"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_ui->cbAll->isChecked())
|
||||
{
|
||||
const QModelIndexList indexList = m_ui->dvParticipants->selectedRows();
|
||||
|
||||
bool isOne = (indexList.size() == 1);
|
||||
if (!isOne)
|
||||
return;
|
||||
//const ParticipantManagement::ParticipantData participantData(participantFromIndex(indexList.first()));
|
||||
if (participantInUse4ExplosionCluster(indexList.first()))
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("This Participant Unit is currently in use.\nThe Parameters can't be changed!"));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_shiftModifierWhileOnSetPosition = QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
|
||||
m_sitMapGuiIfc->getCoordinate(this, SLOT(onGetCoordinate(QPointF)), nullptr);
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::setDialogEnable(bool enable)
|
||||
{
|
||||
m_ui->dvParticipants->setEnabled(enable);
|
||||
m_ui->cbParty->setEnabled(enable);
|
||||
m_ui->cbAll->setEnabled(enable);
|
||||
m_buttonBox->setEnabled(enable);
|
||||
}
|
||||
|
||||
bool ParticipantsMoveDialog::isParticipantInUseForExplosionCluster(int id)
|
||||
{
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger)<<" m_aesDTC is not setted";
|
||||
return true;
|
||||
}
|
||||
|
||||
const QMap<qint32, AreaEffectSimulation::ExplosionCluster> &ecMap = m_aesDtc->explosionClusters();
|
||||
for(const AreaEffectSimulation::ExplosionCluster &aes : qAsConst(ecMap))
|
||||
{
|
||||
if (aes.participantId() == id &&
|
||||
(aes.effectStateId() == AreaEffectSimulation::AesEffectState::EsPrepared ||
|
||||
aes.effectStateId() == AreaEffectSimulation::AesEffectState::EsActivated))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->dvParticipants->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief ParticipantsMoveDialog::setFormationAndPositioningUi
|
||||
* \param withMgrsPos:
|
||||
* \param withFormation
|
||||
* \param mgrsCoordinate
|
||||
* \return
|
||||
*/
|
||||
void ParticipantsMoveDialog::setFormationAndPositioningUi(const ParticipantManagement::ParticipantData &participantData,
|
||||
QPointF &mgrsCoordinate,
|
||||
const bool &unitWithFormation)
|
||||
{
|
||||
if (!unitWithFormation && !m_mgrsPosEditCoordinateActive)
|
||||
return;
|
||||
|
||||
const ParticipantManagement::Type &participantType = m_ppmDtc->type(participantData.typeId());
|
||||
const bool isUnitType =
|
||||
(participantType.typeClass() == ParticipantManagement::TypeClass::Unit) ||
|
||||
(participantType.typeClass() == ParticipantManagement::TypeClass::SupportUnit);
|
||||
|
||||
m_formationProps.setFormation(QString::fromStdString(participantType.properties()));
|
||||
|
||||
if (m_formationProps.hasFormationData())
|
||||
return;
|
||||
|
||||
|
||||
LtsWidgets::LtsFramelessDialog *dialog = new LtsWidgets::LtsFramelessDialog(this, LtsWidgets::Behaviour::Popup);
|
||||
dialog->setFixedSize(390, 300);
|
||||
dialog->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *gla = new QGridLayout(dialog);
|
||||
// Message Infobox
|
||||
{
|
||||
QLabel *msgLbl = new QLabel(tr("<b> Following Parameter(s) must be set to proceed. </b>"), dialog);
|
||||
msgLbl->setWordWrap(true);
|
||||
gla->addWidget(msgLbl, row, 0, 1, 2);
|
||||
}
|
||||
|
||||
// set mgrs Postion edit
|
||||
LtsCoordWidget::LtsCoordWidget *posEdit = new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS, dialog);
|
||||
{
|
||||
QLabel *posEditLbl = new QLabel(tr("MGRS Position:"), dialog);
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const QSize offset = QSize(ps->value(QStringLiteral("MgrsSquaresOffsets"), QStringLiteral("xOffset")).toInt(),
|
||||
ps->value(QStringLiteral("MgrsSquaresOffsets"), QStringLiteral("yOffset")).toInt());
|
||||
|
||||
posEdit->setWithSurroundingMgrsSquares(true);
|
||||
posEdit->setMgrsSquareEditable(true);
|
||||
QVector<LtsCoordTrans::UtmCoordinate> geoCoords;
|
||||
|
||||
if (LtsCoordTrans::defaultMgrsSquareWithOffsets().isEmpty())
|
||||
{
|
||||
const QRectF &trainingAreaWithMargin = LtsCoordTrans::addMarginToArea(m_trainingAreaRect, offset);
|
||||
geoCoords = LtsCoordTrans::getMgrsSquares(trainingAreaWithMargin,false,false,true);
|
||||
}
|
||||
else
|
||||
geoCoords = LtsCoordTrans::defaultMgrsSquareWithOffsets();
|
||||
|
||||
posEdit->setMgrsSquares(geoCoords);
|
||||
if (!mgrsCoordinate.isNull())
|
||||
posEdit->setCoordinate(mgrsCoordinate, true);
|
||||
|
||||
++row;
|
||||
gla->addWidget(posEditLbl, row, 0, 1, 1);
|
||||
gla->addWidget(posEdit, row, 1, 1, 1);
|
||||
|
||||
QFrame *line = new QFrame(dialog);
|
||||
line->setObjectName(QString::fromUtf8("line"));
|
||||
line->setGeometry(QRect(110, 110, 118, 3));
|
||||
line->setFrameShape(QFrame::HLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
|
||||
++row;
|
||||
gla->addWidget(line, row, 0, 1, 2);
|
||||
}
|
||||
|
||||
// set Angle
|
||||
QSpinBox *angleSBox = nullptr;
|
||||
//if (m_formationProps.angle == -1 && unitWithFormation)
|
||||
{
|
||||
QLabel *angleLbl = new QLabel( tr("Angle:"), dialog); // Grundrichtung
|
||||
angleSBox = new QSpinBox(dialog);
|
||||
angleSBox->setMinimum(0);
|
||||
angleSBox->setMaximum(s_maxAngleMil);
|
||||
angleSBox->setSuffix(tr(" mil"));
|
||||
++row;
|
||||
gla->addWidget(angleLbl, row, 0, 1, 1);
|
||||
gla->addWidget(angleSBox, row, 1, 1, 1);
|
||||
|
||||
}// end setting angle
|
||||
|
||||
// set Distance
|
||||
QSpinBox *distanceSBox = nullptr;
|
||||
QComboBox *distanceCBox = nullptr;
|
||||
{
|
||||
QLabel *distanceLbl = new QLabel(tr("Distance:"), dialog);
|
||||
distanceCBox = new QComboBox(dialog);
|
||||
for(const auto &dis : m_formationProps.distanceSets.toStdMap())
|
||||
{
|
||||
QString str;
|
||||
if (dis.first == QStringLiteral("Locked")) // Geschlossen
|
||||
str = tr("Locked");
|
||||
else if (dis.first == QStringLiteral("Unlocked")) // Aufgelockert
|
||||
str = tr("Unlocked");
|
||||
distanceCBox->addItem(QStringLiteral("%1 (%2m)").arg(str).arg(dis.second.toInt()), dis.second.toInt());
|
||||
}
|
||||
|
||||
++row;
|
||||
gla->addWidget(distanceLbl, row, 0, 1, 1);
|
||||
gla->addWidget(distanceCBox, row, 1, 1, 1);
|
||||
|
||||
}
|
||||
|
||||
// Vertical spacer
|
||||
{
|
||||
QScopedPointer<QSpacerItem> verticalSpacer(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
row++;
|
||||
gla->addItem(verticalSpacer.take(), row, 0, 1, 1);
|
||||
}
|
||||
|
||||
// dialog button
|
||||
LtsWidgets::LtsDialogButtonBox *btnBox = new LtsWidgets::LtsDialogButtonBox(dialog);
|
||||
btnBox->getButton(LtsWidgets::DialogButton::Ok)->setText(tr("Apply"));
|
||||
btnBox->getButton(LtsWidgets::DialogButton::Close)->setText(tr("Abort"));
|
||||
// horizontal spacer
|
||||
{
|
||||
QScopedPointer <QSpacerItem> horizontalSpacer(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
||||
row++;
|
||||
gla->addItem(horizontalSpacer.take(), row, 0, 1, 1);
|
||||
gla->addWidget(btnBox, row, 0, 1, 2);
|
||||
}
|
||||
|
||||
// handle Data
|
||||
auto applyData = [=]()
|
||||
{
|
||||
// angle can be get in ° or mil, but we work with angle in degree. so we habe to convert mil value if defined
|
||||
// 0° orientation is east ouest
|
||||
{ // get angle value
|
||||
int angleMil = angleSBox->value();
|
||||
// angle in mil: convert in degree, then we work in degree
|
||||
m_formationProps.angle = std::fmod((mil2Deg(angleMil) + 90), 360);// 0° ost-west gerichtet
|
||||
|
||||
DEBUG_LOG(m_logger)<<" angle in deg mil: "<<angleMil
|
||||
<<" -> degree: "<< mil2Deg(angleMil)<<" final position(°): "<<m_formationProps.angle;
|
||||
}
|
||||
|
||||
{// get distance value
|
||||
// spinbox is enable when there is no distance sets available. The user will enter a desired distance
|
||||
if (distanceSBox != nullptr)
|
||||
m_formationProps.distance = distanceSBox->value();
|
||||
else if(distanceCBox != nullptr)
|
||||
m_formationProps.distance = distanceCBox->currentData().toInt();
|
||||
}
|
||||
|
||||
const QPointF mgrsCoordinate = posEdit->coordinate();
|
||||
if (mgrsCoordinate.isNull())
|
||||
{
|
||||
WARNING_LOG(m_logger)<<"MGRS Coordinates invalid!";
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Coordinates invalid!\nPlease check them and try again."));
|
||||
return;
|
||||
}
|
||||
if (unitWithFormation && (m_formationProps.hasFormationData() || !mgrsCoordinate.isNull()))
|
||||
{
|
||||
doSetSimulatedParticipantFormationRequest(participantData, mgrsCoordinate, m_formationProps.getFormationDataObjectString());
|
||||
}
|
||||
else if (isUnitType)
|
||||
{
|
||||
// set while user is pressing
|
||||
m_shiftModifierWhileOnSetPosition ? doSetSimulatedPositionRequest(participantData, mgrsCoordinate) :
|
||||
doSetSimulatedPositionRelativeRequest(participantData, mgrsCoordinate);
|
||||
}
|
||||
else
|
||||
doSetSimulatedPositionRequest(participantData, mgrsCoordinate); // single (human|vehicle)
|
||||
|
||||
setDialogEnable(true);
|
||||
dialog->accept();
|
||||
};
|
||||
|
||||
// abort/close
|
||||
connect(btnBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, dialog, [=](){
|
||||
setDialogEnable(true);
|
||||
dialog->accept();
|
||||
});
|
||||
// apply
|
||||
connect(btnBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, applyData);
|
||||
|
||||
dialog->setLayout(gla);
|
||||
dialog->show();
|
||||
setDialogEnable(false);
|
||||
}
|
||||
|
||||
|
||||
bool ParticipantsMoveDialog::getUnitPosition(int32_t participantId, Core::GeoPosition &unitPositionOut)
|
||||
{
|
||||
// flt
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> fltParticipantIfc;
|
||||
m_session->getForeignGuiInterface<FilterManagement::ForeignFltParticipantGuiInterface>(fltParticipantIfc); // not in global
|
||||
|
||||
if (!fltParticipantIfc)
|
||||
return false;
|
||||
|
||||
int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
QString workspaceId = m_session->workspaceId();
|
||||
|
||||
std::shared_ptr<FilterManagement::SymbolAppearanceSettings> symbolAppearanceSettings =
|
||||
fltParticipantIfc->symbolAppearanceForOperator(operatorId, workspaceId);
|
||||
|
||||
FilterManagement::SymbolAppearanceSettings::Settings settings =
|
||||
symbolAppearanceSettings->settings();
|
||||
|
||||
FilterManagement::SymbolAppearanceSettings::UnitSymbolPosition usp =
|
||||
settings.symbolSettings.unitSymbolPosition;
|
||||
|
||||
ParticipantManagement::UnitPosition up = m_ppmDtc->unitPosition(participantId);
|
||||
if (up.participantId() != participantId)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << ", unitPosition failed for participantId=" << participantId;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (usp)
|
||||
{
|
||||
case FilterManagement::SymbolAppearanceSettings::UnitSymbolPosition::Center:
|
||||
unitPositionOut = up.positionCenter();
|
||||
return true;
|
||||
break;
|
||||
case FilterManagement::SymbolAppearanceSettings::UnitSymbolPosition::Leader:
|
||||
unitPositionOut = up.positionLeader();
|
||||
return true;
|
||||
break;
|
||||
} // switch
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::doSetSimulatedPositionRequest(const ParticipantManagement::ParticipantData &participantData, const QPointF &coordinate)
|
||||
{
|
||||
// single participant or unit should be move to _one_ origin:
|
||||
const int participantId = participantData.id();
|
||||
if (participantId <= 0) // sanity
|
||||
return;
|
||||
|
||||
ParticipantManagement::SetSimulatedPosition req;
|
||||
bool bAll = m_ui->cbAll->isChecked();
|
||||
bool bAskOutdated = true;
|
||||
if (bAll)
|
||||
req.participantId(-1);
|
||||
else
|
||||
{
|
||||
const ParticipantManagement::TypeClass tc = m_ppmDtc->type(participantData.typeId()).typeClass();
|
||||
|
||||
DEBUG_LOG(m_logger) << "ParticipantId=" << participantData.id()
|
||||
<< " EquipmentNr=" << participantData.equipmentNumber()
|
||||
<< " onGetCoordinate x=" << coordinate.x() << " y=" << coordinate.y()
|
||||
<< ", tc=" << tc;
|
||||
if (participantData.id() <= 0)
|
||||
return;
|
||||
req.participantId(participantData.id());
|
||||
|
||||
bAskOutdated = m_ppmDtc->type(participantData.typeId()).typeClass() == ParticipantManagement::TypeClass_def::Unit;
|
||||
}
|
||||
|
||||
bool bOnlyOutdated = false;
|
||||
if (bAskOutdated)
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("All")},
|
||||
{LtsWidgets::Button::No, tr("Only outdated")}
|
||||
});
|
||||
auto b = LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Do you want to move all participants or only outdated ones?"),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes | LtsWidgets::Button::No,
|
||||
texts);
|
||||
if (b == LtsWidgets::Button::Cancel)
|
||||
return;
|
||||
|
||||
bOnlyOutdated = (b == LtsWidgets::Button::No);
|
||||
}
|
||||
|
||||
req.onlyOutdatedParticipants(bOnlyOutdated);
|
||||
req.position(Core::GeoPosition(coordinate.x(), coordinate.y(), 0.0));
|
||||
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ppmFtc->setSimulatedPositionRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void ParticipantsMoveDialog::doSetSimulatedPositionRelativeRequest(const ParticipantManagement::ParticipantData &participantData, const QPointF &coordinate)
|
||||
{
|
||||
// Unit is selected and should be moved relative to it´s current origin:
|
||||
const int participantId = participantData.id();
|
||||
if (participantId <= 0) //sanity
|
||||
return;
|
||||
|
||||
Core::GeoPosition unitPositionOut;
|
||||
if (!getUnitPosition(participantId, unitPositionOut))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << ", getUnitPosition failed for participantId=" << participantId;
|
||||
return;
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << ", getUnitPosition for participantId=" << participantId
|
||||
<< ", unitPositionOut: lon=" << unitPositionOut.lon() << " - lat=" << unitPositionOut.lat();
|
||||
|
||||
LtsCoordTrans::UtmCoordinate curUnitPosUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(unitPositionOut.lon(), unitPositionOut.lat());
|
||||
LtsCoordTrans::UtmCoordinate desiredUnitPosUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(coordinate);
|
||||
QPointF offset = desiredUnitPosUtm.relativeTo(curUnitPosUtm);
|
||||
|
||||
if (offset.isNull())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << ", required offset is zero. not expected... return";
|
||||
return;
|
||||
}
|
||||
|
||||
ParticipantManagement::SetSimulatedPositionRelative req;
|
||||
req.participantId(participantId);
|
||||
req.positionOffsetX(offset.x());
|
||||
req.positionOffsetY(offset.y());
|
||||
|
||||
DEBUG_LOG(m_logger) << "SetSimulatedPositionRelative = " << req;
|
||||
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ppmFtc->setSimulatedPositionRelativeRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
void ParticipantsMoveDialog::doSetSimulatedParticipantFormationRequest(const ParticipantManagement::ParticipantData &participantData, const QPointF &coordinate, const QString &formationData)
|
||||
{
|
||||
// Unit is selected and should be moved relative to it´s current origin:
|
||||
const int participantId = participantData.id();
|
||||
if (participantId <= 0) //sanity
|
||||
return;
|
||||
|
||||
Core::GeoPosition unitPositionOut;
|
||||
if (!getUnitPosition(participantId, unitPositionOut))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << ", getUnitPosition failed for participantId=" << participantId;
|
||||
return;
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << ", getUnitPosition for participantId=" << participantId
|
||||
<< ", unitPositionOut: lon=" << unitPositionOut.lon() << " - lat=" << unitPositionOut.lat();
|
||||
|
||||
LtsCoordTrans::UtmCoordinate curUnitPosUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(unitPositionOut.lon(), unitPositionOut.lat());
|
||||
LtsCoordTrans::UtmCoordinate desiredUnitPosUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(coordinate);
|
||||
const QPointF offset = desiredUnitPosUtm.relativeTo(curUnitPosUtm);
|
||||
|
||||
if (offset.isNull())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << ", required offset is zero. not expected... return";
|
||||
return;
|
||||
}
|
||||
|
||||
ParticipantManagement::SetSimulatedParticipantFormation req;
|
||||
req.participantId(participantId);
|
||||
req.position(Core::GeoPosition(coordinate.x(), coordinate.y(), 0.0));
|
||||
req.positionOffsetX(offset.x());
|
||||
req.positionOffsetY(offset.y());
|
||||
req.formation(formationData.toStdString());
|
||||
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ppmFtc->setSimulatedParticipantFormationRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
ParticipantManagement::ParticipantData ParticipantsMoveDialog::participantFromIndex(const QModelIndex &idx) const
|
||||
{
|
||||
return m_participantModel->getParticipantData(idx);
|
||||
}
|
||||
|
||||
} // namespace CentralEffectSimulation
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for ParticipantsMoveDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSE, 2018-01-02
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//Lts
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include "participant_move_dialog.h"
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
|
||||
#include "participants_move_model.h"
|
||||
|
||||
//DDS
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ParticipantManagement/ppm_ftc.h>
|
||||
#include <CentralEffectSimulation/ces_dtc.h>
|
||||
#include <AreaEffectSimulation/aes_dtc.h>
|
||||
#include <AssetManagement/asm_ftc.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
||||
#include <Plugins/CentralEffectSimulation/ces_gui_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_participants_gui_plugin_interface.h>
|
||||
|
||||
#include "logger.h"
|
||||
//Qt
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ParticipantMoveDialog;
|
||||
}
|
||||
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
// --------------------------------------------------------
|
||||
// ParticipantMoveDialog
|
||||
// --------------------------------------------------------
|
||||
class ParticipantsMoveDialog : public LtsWidgets::LtsDialog
|
||||
, protected CentralEffectSimulation::Interface::Ftc::SimulatedMovementRemoveByParticipantIdReplyHandler
|
||||
, protected ParticipantManagement::Interface::Ftc::SetSimulatedPositionReplyHandler
|
||||
, protected ParticipantManagement::Interface::Ftc::SetSimulatedPositionRelativeReplyHandler
|
||||
, protected ParticipantManagement::Interface::Ftc::SetSimulatedParticipantFormationReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ParticipantsMoveDialog(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~ParticipantsMoveDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<CentralEffectSimulation::Interface::Dtc> &cesDtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc);
|
||||
|
||||
void onSimulatedMovementRemoveByParticipantIdReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onSetSimulatedPositionReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onSetSimulatedPositionRelativeReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onSetSimulatedParticipantFormationReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
|
||||
enum class FormationGeometrieType : int
|
||||
{
|
||||
AimPoint,
|
||||
Radial,
|
||||
Area,
|
||||
Line,
|
||||
Point
|
||||
};
|
||||
|
||||
public slots:
|
||||
void onGetCoordinate(QPointF coordinate);
|
||||
|
||||
private:
|
||||
bool getUnitPosition(int32_t participantId, Core::GeoPosition &unitPositionOut);
|
||||
void doSetSimulatedPositionRequest(const ParticipantManagement::ParticipantData &participantData, const QPointF &coordinate);
|
||||
void doSetSimulatedPositionRelativeRequest(const ParticipantManagement::ParticipantData &participantData, const QPointF &coordinate);
|
||||
void doSetSimulatedParticipantFormationRequest(const ParticipantManagement::ParticipantData &participantData, const QPointF &coordinate, const QString &formationData);
|
||||
private slots:
|
||||
void closeDialogReceived(int32_t participantId);
|
||||
void onModelChanged();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void onClicked();
|
||||
void onRemove();
|
||||
void onSetSimulatedMGRSPosition();
|
||||
bool participantInUse4ExplosionCluster(const QModelIndex &participantIndex);
|
||||
void changeParty();
|
||||
void onSelectionChanged();
|
||||
void onDoubleClicked();
|
||||
void onSetPosition();
|
||||
void setDialogEnable(bool enable);
|
||||
bool isParticipantInUseForExplosionCluster(int id);
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
struct ParticipantTypePropertyStruct
|
||||
{
|
||||
QString m_propertiesStr;
|
||||
bool isArtillery = false;
|
||||
QString geometry = QStringLiteral("line");
|
||||
double distance = -1;
|
||||
double angle = -1;
|
||||
QVariantMap distanceSets;
|
||||
QJsonObject distanceSetsObj;
|
||||
|
||||
ParticipantTypePropertyStruct() {}
|
||||
explicit ParticipantTypePropertyStruct(const QString &properties) : m_propertiesStr(properties)
|
||||
{
|
||||
setFormation(properties);
|
||||
}
|
||||
void setDefaultValue()
|
||||
{
|
||||
isArtillery = false;
|
||||
geometry = QStringLiteral("line");
|
||||
distance = -1;
|
||||
angle = -1;
|
||||
distanceSets.clear();
|
||||
}
|
||||
|
||||
void setFormation(const QString &jsData)
|
||||
{
|
||||
setDefaultValue();
|
||||
const QJsonObject typObj = QJsonDocument::fromJson(QByteArray::fromStdString(jsData.toStdString())).object();
|
||||
if (typObj.isEmpty())
|
||||
return;
|
||||
isArtillery = typObj[isArtilleryStr].toBool(false);
|
||||
// Formation data Object
|
||||
const QJsonObject &formationObj = typObj[formationStr].toObject();
|
||||
if (formationObj.isEmpty())
|
||||
{
|
||||
setDefaultValue();
|
||||
return;
|
||||
}
|
||||
geometry = formationObj[geometryStr].toString(QStringLiteral("line"));
|
||||
angle = formationObj[angleStr].toDouble(-1);
|
||||
distance = formationObj[distanceStr].toDouble(-1);
|
||||
distanceSetsObj = formationObj[distanceSetsStr].toObject();
|
||||
distanceSets = distanceSetsObj.toVariantMap();
|
||||
}
|
||||
|
||||
bool hasFormationData() const
|
||||
{
|
||||
if (isArtillery == false)
|
||||
return true; // no need to continue artillery must be set for formation data to be changed
|
||||
else
|
||||
return (angle != -1) && (distance != -1);
|
||||
}
|
||||
QString getFormationDataObjectString() const
|
||||
{
|
||||
QJsonObject obj {{geometryStr, geometry},
|
||||
{angleStr, angle},
|
||||
{distanceStr, distance},
|
||||
{distanceSetsStr, distanceSetsObj} // doesnt change. use in combobox for selection. selection used by distance
|
||||
};
|
||||
return QString::fromStdString(QJsonDocument(obj).toJson(QJsonDocument::Compact).toStdString());
|
||||
}
|
||||
|
||||
const QString isArtilleryStr = QStringLiteral("isArtillery");
|
||||
const QString formationStr = QStringLiteral("formation");
|
||||
const QString geometryStr = QStringLiteral("geometry");
|
||||
const QString angleStr = QStringLiteral("angle");
|
||||
const QString distanceStr = QStringLiteral("distance");
|
||||
const QString distanceSetsStr = QStringLiteral("distanceSets");
|
||||
};
|
||||
|
||||
void setFormationAndPositioningUi(const ParticipantManagement::ParticipantData &participantData, QPointF &mgrsCoordinate, const bool &unitWithFormation);
|
||||
|
||||
bool removeFtc(int32_t participantId);
|
||||
ParticipantManagement::ParticipantData participantFromIndex(const QModelIndex &idx) const;
|
||||
|
||||
private:
|
||||
|
||||
ParticipantMoveModel *m_participantModel{nullptr};
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc;
|
||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
|
||||
|
||||
std::shared_ptr<CentralEffectSimulation::Interface::Dtc> m_cesDtc;
|
||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmCbxIfc;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
|
||||
Ui::ParticipantMoveDialog *m_ui{nullptr};
|
||||
LtsSession::LtsSession *m_session{nullptr};
|
||||
QString m_menuGroup;
|
||||
QMap<int, ParticipantMoveDialog *> m_participantDialogMap;
|
||||
LtsUtils::RequestHelper *m_requestHelper{nullptr};
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
|
||||
bool m_shiftModifierWhileOnSetPosition{false};
|
||||
bool m_mgrsPosEditCoordinateActive{false};
|
||||
LOGGER_T m_logger;
|
||||
QRectF m_trainingAreaRect;
|
||||
ParticipantTypePropertyStruct m_formationProps;
|
||||
};
|
||||
} // namespace CentralEffectSimulation
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ParticipantMoveDialog</class>
|
||||
<widget class="QWidget" name="ParticipantMoveDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1028</width>
|
||||
<height>451</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>692</width>
|
||||
<height>342</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Participant Configuration</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0">
|
||||
<item row="0" column="3">
|
||||
<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="0" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbParty">
|
||||
<property name="currentText">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<widget class="LtsDataView::LtsDataView" name="dvParticipants" native="true">
|
||||
<property name="rootIsDecorated" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbParty">
|
||||
<property name="text">
|
||||
<string>Party:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="cbAll">
|
||||
<property name="text">
|
||||
<string>All Participants</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>cbParty</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Model for ParticipantsMoveDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSE, 2018-01-02
|
||||
*/
|
||||
|
||||
#include "participants_move_model.h"
|
||||
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
//----------------------------------------------------------------------------
|
||||
ParticipantMoveModel::ParticipantMoveModel(QObject *parent,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asbIfc)
|
||||
: ParticipantManagement::ParticipantEditModel(parent, ppmDtc, asbIfc)
|
||||
, m_logger(getLogger("ParticipantMoveModel"))
|
||||
{
|
||||
m_titles += tr("Simulated");
|
||||
|
||||
connect(m_dtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
|
||||
this, &ParticipantMoveModel::onParticipantChanged);
|
||||
|
||||
DEBUG_LOG(m_logger) << "ParticipantMoveModel::ParticipantMoveModel";
|
||||
}
|
||||
|
||||
|
||||
QVariant ParticipantMoveModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
// ColSimulated is the last column
|
||||
if (role == Qt::DisplayRole && index.column() == columnCount() - 1)
|
||||
{
|
||||
bool bIsSimulated = false;
|
||||
if (!isSelectableBySimulation(index, &bIsSimulated))
|
||||
return QVariant();
|
||||
return bIsSimulated ? tr("Yes") : tr("No");
|
||||
}
|
||||
|
||||
return ParticipantManagement::ParticipantEditModel::data(index, role);
|
||||
}
|
||||
|
||||
void ParticipantMoveModel::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType)
|
||||
if (data.partyId() != m_partyId)
|
||||
return;
|
||||
INFO_LOG(m_logger) << "onParticipantChanged isSimulated=" << data.isSimulated();
|
||||
onReinitModel(partyId());
|
||||
emit newData();
|
||||
}
|
||||
|
||||
bool ParticipantMoveModel::isSelectableBySimulation(const QModelIndex &index, bool *bIsSimulated) const
|
||||
{
|
||||
bool isSimulatable = true;
|
||||
const ParticipantManagement::ParticipantData data(getParticipantData(index));
|
||||
|
||||
if ((data.equipmentNumber().is_set() && data.equipmentNumber().get() > 0) ||
|
||||
m_dtc->type(data.typeId()).typeClass() == ParticipantManagement::TypeClass_def::Unit)
|
||||
isSimulatable = false;
|
||||
|
||||
DEBUG_LOG(m_logger) << "ParticipantId: " << data.id()
|
||||
<< " isSimulated:" << data.isSimulated()
|
||||
<< " equipmentNo:" << data.equipmentNumber()
|
||||
<< " typeId=" << data.typeId()
|
||||
<< " modId=" << data.modId()
|
||||
<< " typeClass=" << m_dtc->type(data.typeId()).typeClass()
|
||||
<< " isSimulatable=" << isSimulatable;
|
||||
|
||||
if (bIsSimulated)
|
||||
*bIsSimulated = data.isSimulated();
|
||||
|
||||
return isSimulatable;
|
||||
}
|
||||
|
||||
} // namespace CentralEffectSimulation
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Model for ParticipantsMoveDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSE, 2018-01-02
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
#include <Services/ParticipantManagement/ppm_dtc.h>
|
||||
#include <QStringList>
|
||||
|
||||
//ParticipantManagement
|
||||
#include <Plugins/ParticipantManagement/Gui/Common/participant_edit_model.h>
|
||||
#include "logger.h"
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
class ParticipantMoveModel final : public ParticipantManagement::ParticipantEditModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ParticipantMoveModel(QObject *parent,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asbIfc);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
signals:
|
||||
void newData();
|
||||
|
||||
private:
|
||||
void onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType);
|
||||
bool isSelectableBySimulation(const QModelIndex &index, bool *bIsSimulated = nullptr) const;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
} // namespace CentralEffectSimulation
|
||||
Reference in new issue
Block a user