Files
qt5-legatus-legacy/Lts/Plugins/OcSituationClient/Gui/System/osc_system_gui_plugin.cpp
T
2026-08-13 18:33:10 +02:00

324 lines
9.3 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Gui Plugin for ObserverController
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2017-01-14
*/
#include "osc_system_gui_plugin.h"
#include "osc_selftest.h"
#include "osc_settings.h"
#include "osc_close_aes_list.h"
#include <OcSituationClient/logger.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <LtsNotification/lts_notification.h>
#include <LtsUtilsSettings/settings.h>
#include <QNetworkSession>
#include <QNetworkConfigurationManager>
#include <QNetworkConfiguration>
#include <QTimer>
#include <QPolygonF>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <ProjectDataManagement/pdm_data_plugin_interface.h>
#include <ParticipantManagement/ppm_data_plugin_interface.h>
namespace OcSituationClient
{
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("System.InterfaceImpl"))
, m_closeAreaIdentifier(QStringLiteral("ocrCloseAesList"))
{
m_enterSound.setVolume(90);
m_enterSound.setSource(QUrl(QStringLiteral("qrc:/effectarea-enter.wav")));
m_leaveSound.setVolume(90);
m_leaveSound.setSource(QUrl(QStringLiteral("qrc:/effectarea-leave.wav")));
m_nearInSound.setVolume(90);
m_nearInSound.setSource(QUrl(QStringLiteral("qrc:/entryNew.wav")));
m_nearOutSound.setVolume(90);
m_nearOutSound.setSource(QUrl(QStringLiteral("qrc:/leaveNew.wav")));
}
InterfaceImpl::~InterfaceImpl()
{
}
bool InterfaceImpl::fetchInterfaces()
{
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc;
if (!m_session->getDtc<ParticipantManagement::DataInterface>(ppmDtc))
return false;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> pdmDtc;
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(pdmDtc))
return false;
if (!m_session->getDtc<AreaEffectSimulation::DataInterface>(m_aesDtc))
return false;
if (!m_session->getDtc<TrainingAreaBaseOC::DataInterface>(m_tabocDtc))
return false;
return true;
}
void InterfaceImpl::clearInterfaces()
{
m_aesDtc = nullptr;
m_tabocDtc = nullptr;
}
QString InterfaceImpl::menuGroup() const
{
return tr("System");
}
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
QVector<LtsWidgets::PluginData> ret;
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
// Action 'SelfTest'
plData.menuText = tr("Self Test");
plData.identifier = QStringLiteral("ocrSelftest");
plData.menuIcon = QIcon(QLatin1String("icon:pi_show_bite.svg"));
plData.operatorRight = 0;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowSelfTest(parent);
};
ret.append(plData);
// Action 'Settings'
plData.menuText = tr("Settings");
plData.identifier = QStringLiteral("ocrSettings");
plData.menuIcon = QIcon(QLatin1String("icon:presets.svg"));
plData.operatorRight = 0;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowSettings(parent);
};
ret.append(plData);
// Action 'AES List'
plData.menuText = tr("AES List");
plData.identifier = m_closeAreaIdentifier;
plData.menuIcon = QIcon(QLatin1String("icon:aes_list.svg"));
plData.operatorRight = 0;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowCloseAes(parent);
};
ret.append(plData);
if (m_tabocDtc)
{
m_tabocDtc->enableAll();
connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::enterLeaveAesChanged, this, &InterfaceImpl::onEnterLeaveAesChanged);
if (m_aesDtc)
connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::ownPositionChanged, this, &InterfaceImpl::onCheckAllEffectAreas);
// connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::technicalStateSfmChanged,
// this, &InterfaceImpl::onEnterLeaveAesChanged);
}
return ret;
}
void InterfaceImpl::onEnterLeaveAesChanged(const TrainingAreaBaseOC::EnterLeaveAes &data, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
if (LtsUtils::OperatorSettings::getInstance())
{
bool playSound = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("ObserverController"), QStringLiteral("AcousticWarning"), false).toBool();
if (playSound)
{
DEBUG_LOG(m_logger) << "Got new ENterLeave event and play sound";
if (data.cAreaType()) //entered/leaved directly
{
if(data.aesEntered())
{
m_enterSound.play();
}
else
{
m_leaveSound.play();
}
DEBUG_LOG(m_logger) << "enter leave direvly " << data.aesEntered();
}
else //not entered but warning range
{
if (data.aesEntered())
{
m_nearInSound.play();
}
else
{
m_nearOutSound.play();
}
DEBUG_LOG(m_logger) << "enter leave near " << data.aesEntered();
}
}
if (data.aesEntered() && LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("ObserverController"), QStringLiteral("VisualWarning"), false).toBool() ) //new one
{
bool bWidgetExists = m_session->widgetExists(menuGroup(), m_closeAreaIdentifier, LtsWidgets::LayoutArea::eDialogTab);
if (!bWidgetExists)
m_session->addWidget(onShowCloseAes(), menuGroup(), m_closeAreaIdentifier, LtsWidgets::LayoutArea::eDialogTab);
}
}
}
void InterfaceImpl::onCheckAllEffectAreas()
{
if (!m_tabocDtc || !m_aesDtc)
return;
TrainingAreaBaseOC::OwnPosition pos = m_tabocDtc.get()->ownPosition(1);
TrainingAreaBaseOC::EnterLeaveAes elAes;
//create radios
QPolygonF circle; //5deg steps +1
circle.reserve(73);
int radius = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("ObserverController"), QStringLiteral("WarningRange"), 1).toInt();
DEBUG_LOG(m_logger) << "My warning range is:" << radius;
for (int i=0; i<360; i+=5)
{
double angle = i * M_PI / 180.0;
circle << QPointF(cos(angle) * radius, sin(angle) * radius);
}
LtsCoordTrans::UtmCoordinate posUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(pos.position().lon(), pos.position().lat());
int zone = posUtm.zone;
circle << circle.value(0);
circle.translate(posUtm.x, posUtm.y);
QPolygonF circleLonLat;
circleLonLat.reserve(circle.size());
for (int i=0; i < circle.size(); i++)
{
LtsCoordTrans::UtmCoordinate posUtmC(zone, circle.at(i).x(), circle.at(i).y());
circleLonLat << posUtmC.geographic();
}
//now check all areas
const QMap<qint32, AreaEffectSimulation::AesItemView> views = m_aesDtc.get()->aesItemViews();
DEBUG_LOG(m_logger) << "new position " << posUtm.mgrs();
for(const AreaEffectSimulation::AesItemView &view: qAsConst(views))
{
if (view.aesTypeId() == AreaEffectSimulation::AesType::AtExplosionAreaSingleExplosions
|| view.aesTypeId() == AreaEffectSimulation::AesType::AtMineAreaSingleMines
|| view.aesTypeId() == AreaEffectSimulation::AesType::AtTechnicalArea )
continue;
bool contains = m_closeAes.contains(view.id());
if (m_closeAes.contains(view.id()) && view.effectStateId() != AreaEffectSimulation::AesEffectState::EsActivated)
{
DEBUG_LOG(m_logger) << "outdatet " ;
m_closeAes.remove(view.id());
elAes.aesEntered(false);
}
else if (view.effectStateId() == AreaEffectSimulation::AesEffectState::EsActivated)
{
//not inside and is active
QPolygonF poly(view.form().size());
int i=0;
for(const auto &point : view.form())
{
poly[i++] = QPointF(point.lon(), point.lat());
}
#if QT_VERSION < QT_VERSION_CHECK(5,10,0)
bool inters = poly.intersected(circleLonLat).size() > 0;
#else
bool inters = poly.intersects(circleLonLat);
#endif
DEBUG_LOG(m_logger) << "active " << view.id() << " intersect=" << inters << " inside map=" << contains ;
if (inters && contains)
{
DEBUG_LOG(m_logger) << "already inside" ;
continue; //already inside
}
else if (inters && !contains)
{
// is new
DEBUG_LOG(m_logger) << "is new inside" ;
m_closeAes.insert(view.id());
elAes.aesEntered(true);
}
else if (!inters && contains)
{
//not inside anymore
DEBUG_LOG(m_logger) << "now outside" ;
m_closeAes.remove(view.id());
elAes.aesEntered(false);
}
else
{
continue;
}
}
else
{
DEBUG_LOG(m_logger) << "missed " << view.id() << " ";
continue;
}
elAes.aesId(view.aesItemId());
elAes.chargeTypeId(view.chargeStruct().chargeTypeId());
//now send event
onEnterLeaveAesChanged(elAes,DataModification::eModified);
emit updateAesList(m_closeAes);
}
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowSelfTest(QWidget *parent)
{
SelfTest *dialog = new SelfTest(m_session, parent);
return dialog;
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowSettings(QWidget *parent)
{
Settings *dialog = new Settings(m_session, parent);
return dialog;
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowCloseAes(QWidget *parent)
{
CloseAesList *dialog = new CloseAesList(m_session, parent);
connect (this, &InterfaceImpl::updateAesList, dialog, &CloseAesList::updateAesList);
emit updateAesList(m_closeAes);
return dialog;
}
} // namespace OcSituationClient