342 lines
12 KiB
C++
Executable File
342 lines
12 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Dialog to Simulate drone
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Steve Kemayou, ESZS, 2025-04-08
|
|
*/
|
|
|
|
#include <CentralEffectSimulation/ces_data_plugin_interface.h>
|
|
#include <AreaEffectSimulation/aes_data_plugin_interface.h>
|
|
#include <ParticipantManagement/ppm_data_plugin_interface.h>
|
|
#include <LtsUtilsSettings/settings.h>
|
|
#include <CentralEffectSimulation/ces_operator_rights.h>
|
|
|
|
#include "mission_plan_dialog.h"
|
|
#include "ui_mission_plan_dialog.h"
|
|
|
|
namespace CentralEffectSimulation
|
|
{
|
|
MissionPlanDialog::MissionPlanDialog(const QString &menuGroup, QWidget *parent)
|
|
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
|
, m_ppmDtc(nullptr)
|
|
, m_ppmFtc(nullptr)
|
|
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
|
, m_session(nullptr)
|
|
, m_menuGroup(menuGroup)
|
|
, m_logger(getLogger("MissionPlanDialog"))
|
|
, m_ui(new Ui::MissionPlanDialog)
|
|
{
|
|
m_ui->setupUi(this);
|
|
|
|
m_updateMissionTimer.setSingleShot(true);
|
|
m_updateMissionTimer.setInterval(500);
|
|
connect(&m_updateMissionTimer, &QTimer::timeout, this, &MissionPlanDialog::enaDisa);
|
|
|
|
setOnlineHelpFilename(QStringLiteral("Situation-UAS-Mission"));
|
|
}
|
|
|
|
MissionPlanDialog::~MissionPlanDialog()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
bool MissionPlanDialog::init(LtsSession::LtsSession *session)
|
|
{
|
|
m_session = session;
|
|
|
|
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
|
|
{
|
|
ERROR_LOG(m_logger) << " failed to get ppmDtc";
|
|
return false;
|
|
}
|
|
if (!m_session->getFtc<ParticipantManagement::DataInterface>(m_ppmFtc))
|
|
{
|
|
ERROR_LOG(m_logger) << " failed to get ppmFtc";
|
|
return false;
|
|
}
|
|
|
|
m_ppmDtc->enableUnitPosition();
|
|
m_ppmDtc->waitForHistoricalDataUnitPosition(1000);
|
|
|
|
|
|
delete m_missionPlanModel;
|
|
m_missionPlanModel = new MissionPlanModel(this);
|
|
m_missionPlanModel->initModel(m_ppmDtc, m_session->exerciseId());
|
|
|
|
m_missionPlanProxyModel = new MissionPlanProxyModel(this);
|
|
m_missionPlanProxyModel->setSourceModel(m_missionPlanModel);
|
|
m_ui->participantsDataView->setModel(m_missionPlanProxyModel);
|
|
//Lock Button
|
|
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load, this, &MissionPlanDialog::onLockModifications);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Load, false);
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Lock"));
|
|
m_buttonBox->setIcon(LtsWidgets::DialogButton::Load, QIcon(QStringLiteral("icon:drone_remote_connection.svg")));
|
|
//hide for now
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->hide();
|
|
//unlock Button
|
|
m_buttonBox->connectButton(LtsWidgets::DialogButton::Save, this, &MissionPlanDialog::onUnlockModifications);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, false);
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setText(tr("Unlock"));
|
|
m_buttonBox->setIcon(LtsWidgets::DialogButton::Save, QIcon(QStringLiteral("icon:drone_remote_connection.svg")));
|
|
//hide for now
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->hide();
|
|
|
|
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &MissionPlanDialog::onAddMissionPlan); // wird für das Verblockung missbraucht
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, true);
|
|
|
|
m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &MissionPlanDialog::onEditMissionPlan);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, false);
|
|
|
|
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &MissionPlanDialog::onRemoveMissionPlanClicked);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, false);
|
|
|
|
connect(m_ui->participantsDataView, &LtsDataView::LtsDataView::signalSelectionChanged, this, &MissionPlanDialog::enaDisa);
|
|
|
|
const bool &hasOperatorRightParticipantUAS = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::ParticipantMove);
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Edit)->setVisible(hasOperatorRightParticipantUAS);
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->setVisible(hasOperatorRightParticipantUAS);
|
|
|
|
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::missionPlanChanged,
|
|
this, &MissionPlanDialog::onMissionPlanChanged);
|
|
|
|
connect(m_ui->participantsDataView, &LtsDataView::LtsDataView::doubleClicked, this, &MissionPlanDialog::onEditMissionPlan);
|
|
|
|
return true;
|
|
}
|
|
|
|
void MissionPlanDialog::onModifyMissionPlanReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
m_requestHelper->requestReply(replyObject);
|
|
}
|
|
|
|
void MissionPlanDialog::onRemoveMissionPlanReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
m_requestHelper->requestReply(replyObject);
|
|
}
|
|
|
|
void MissionPlanDialog::retranslate()
|
|
{
|
|
translate(m_ui, tr("UAS Mission Plans"));
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Edit)->setText(tr("Edit"));
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setText(tr("Delete"));
|
|
}
|
|
|
|
bool MissionPlanDialog::removeMissionPlan(int32_t missionplanId)
|
|
{
|
|
if (missionplanId <= 0)
|
|
return false;
|
|
|
|
ParticipantManagement::RemoveMissionPlanRequest req(missionplanId);
|
|
|
|
m_requestHelper->startSingleRequest([req, this]()
|
|
{
|
|
return m_ppmFtc->removeMissionPlanRequest(req, this);
|
|
});
|
|
return m_requestHelper->startRequests();
|
|
|
|
}
|
|
|
|
MissionPlanDialog::WayPointsStatus MissionPlanDialog::wayPointCurrentStatus(const ParticipantManagement::MissionPlan &mp) const
|
|
{
|
|
WayPointsStatus state = WayPointsStatus::Undefined;
|
|
//prepared
|
|
if (mp.missionStart() > m_session->partitionTime())
|
|
return WayPointsStatus::Prepared;
|
|
else if (mp.itemsFulfilled() != static_cast<int32_t>(mp.items().size()))
|
|
return WayPointsStatus::Active;
|
|
else if (mp.itemsFulfilled() == static_cast<int32_t>(mp.items().size()))
|
|
return WayPointsStatus::Expired;
|
|
|
|
//aborted
|
|
WARNING_LOG(m_logger)<<" -- Status Wegpunktkette Abgebrochen muss definiert werden";
|
|
|
|
return state;
|
|
}
|
|
|
|
bool MissionPlanDialog::canBeLocked() const
|
|
{
|
|
auto missionPlan = currentMissionPlan();
|
|
if (missionPlan.id()<= 0)
|
|
return false;
|
|
|
|
const auto wpStatus = wayPointCurrentStatus(missionPlan);
|
|
const auto uas = m_ppmDtc->getUasByParticipantId(missionPlan.participantId(), m_session->exerciseId());
|
|
|
|
if (uas.uasState() == ProjectDataManagement::UasState_def::Manual
|
|
|| wpStatus == WayPointsStatus::Active )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool MissionPlanDialog::canBeUnlocked() const
|
|
{
|
|
auto missionPlan = currentMissionPlan();
|
|
if (missionPlan.id()<= 0)
|
|
return false;
|
|
if (missionPlan.aborted())
|
|
return false;
|
|
|
|
const auto wpStatus = wayPointCurrentStatus(missionPlan);
|
|
const auto uas = m_ppmDtc->getUasByParticipantId(missionPlan.participantId(), m_session->exerciseId());
|
|
|
|
if ( uas.uasState() == ProjectDataManagement::UasState_def::Manual
|
|
|| wpStatus != WayPointsStatus::Active)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
MissionPlanEdit *MissionPlanDialog::currentMissionPlanEditor() const
|
|
{
|
|
QModelIndexList indexList = m_ui->participantsDataView->selectedRows();
|
|
if (indexList.isEmpty())
|
|
return nullptr;
|
|
|
|
const ParticipantManagement::MissionPlan mp = m_missionPlanModel->getRowData(indexList.front().row());
|
|
if (mp.id() < 0)
|
|
return nullptr;
|
|
|
|
return m_participantUasEditMap.value(mp.participantId(), nullptr);
|
|
}
|
|
|
|
ParticipantManagement::MissionPlan MissionPlanDialog::currentMissionPlan() const
|
|
{
|
|
QModelIndexList indexList = m_ui->participantsDataView->selectedRows();
|
|
if (indexList.isEmpty())
|
|
return {};
|
|
|
|
return m_missionPlanModel->getRowData(indexList.front().row());
|
|
}
|
|
|
|
void MissionPlanDialog::tableColumnOrganiserSetting()
|
|
{
|
|
//LtsColumnOrganiser
|
|
m_ui->participantsDataView->setColumnsOrganiserEnabled(identifier(), true);
|
|
}
|
|
|
|
void MissionPlanDialog::enaDisa()
|
|
{
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, false);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, false);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, false);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Load, false); // lock button
|
|
QModelIndexList indexList = m_ui->participantsDataView->selectedRows();
|
|
bool bOk = !indexList.isEmpty();
|
|
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, bOk);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, bOk);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, bOk && canBeLocked());
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Load, bOk && canBeUnlocked()); // lock button
|
|
}
|
|
|
|
void MissionPlanDialog::onUnlockModifications()
|
|
{
|
|
auto dialog = currentMissionPlanEditor();
|
|
if (!dialog)
|
|
return;
|
|
|
|
if (canBeUnlocked())
|
|
dialog->setAllUiElementsEnabled(true);
|
|
else
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Cannot unlock selected Mission Plan:\n mission plan still activ"));
|
|
}
|
|
|
|
void MissionPlanDialog::onLockModifications()
|
|
{
|
|
auto dialog = currentMissionPlanEditor();
|
|
if (!dialog)
|
|
return;
|
|
|
|
if (canBeLocked())
|
|
dialog->setAllUiElementsEnabled(false);
|
|
else {
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Cannot Lock selected Mission Plan."));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void MissionPlanDialog::onAddMissionPlan()
|
|
{
|
|
static QString newMissionPlanIdentifier(QStringLiteral("NewMissionPlan"));
|
|
|
|
// selecting an existing mission plan and clicking 'add' must create a new mission plan dialog as a copy of the existing mission plan
|
|
const QModelIndexList indexList = m_ui->participantsDataView->selectedRows();
|
|
if (indexList.isEmpty())
|
|
{
|
|
addDialog(LtsWidgets::initDialog(new MissionPlanEdit(this), 0, m_session),
|
|
m_menuGroup, newMissionPlanIdentifier, LtsWidgets::LayoutArea::eDialogTab);
|
|
return;
|
|
}
|
|
|
|
const ParticipantManagement::MissionPlan mp = m_missionPlanModel->getRowData(indexList.front().row());
|
|
if (mp.id() <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
addDialog(LtsWidgets::initDialog(new MissionPlanEdit(this), mp.id(), m_session, true /*as copy*/),
|
|
m_menuGroup, newMissionPlanIdentifier, LtsWidgets::LayoutArea::eDialogTab);
|
|
}
|
|
|
|
void MissionPlanDialog::onRemoveMissionPlanClicked()
|
|
{
|
|
const QModelIndexList indexList = m_ui->participantsDataView->selectedRows();
|
|
const bool isOne = (indexList.size() == 1);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, isOne);
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, false);
|
|
|
|
if (!isOne)
|
|
return;
|
|
const ParticipantManagement::MissionPlan mp = m_missionPlanModel->getRowData(indexList.front().row());
|
|
|
|
delete m_participantUasEditMap.value(mp.id());
|
|
m_participantUasEditMap.remove(mp.id());
|
|
removeMissionPlan(mp.id());
|
|
}
|
|
|
|
void MissionPlanDialog::onEditMissionPlan()
|
|
{
|
|
QModelIndexList indexList = m_ui->participantsDataView->selectedRows();
|
|
if (indexList.isEmpty())
|
|
return;
|
|
|
|
const ParticipantManagement::MissionPlan mp = m_missionPlanModel->getRowData(indexList.front().row());
|
|
if (mp.id() <= 0)
|
|
return;
|
|
|
|
const QString dialogIdentifier = QStringLiteral("Edit-MissionPlan_%1").arg(mp.id());
|
|
|
|
if (!m_participantUasEditMap.contains(mp.participantId()))
|
|
{
|
|
MissionPlanEdit *dialog = new MissionPlanEdit(this);
|
|
m_participantUasEditMap.insert(mp.participantId(), dialog);
|
|
connect(dialog, &MissionPlanEdit::editUasDialogClosed, this, &MissionPlanDialog::onEditDialogClosed);
|
|
addDialog(LtsWidgets::initDialog(dialog, mp.id(), m_session)
|
|
, m_menuGroup
|
|
, dialogIdentifier
|
|
, LtsWidgets::LayoutArea::eDialogTab);
|
|
}
|
|
else
|
|
focusDialog(m_menuGroup, dialogIdentifier, LtsWidgets::LayoutArea::eDialogTab);
|
|
|
|
}
|
|
|
|
void MissionPlanDialog::onEditDialogClosed(const int participantId)
|
|
{
|
|
m_participantUasEditMap.remove(participantId);
|
|
}
|
|
|
|
void MissionPlanDialog::onMissionPlanChanged(const ParticipantManagement::MissionPlan &data, const DataModification modType)
|
|
{
|
|
Q_UNUSED(data)
|
|
Q_UNUSED(modType)
|
|
m_updateMissionTimer.start();
|
|
}
|
|
|
|
|
|
} // namespace CentralEffectSimulation
|