Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+11
View File
@@ -0,0 +1,11 @@
#
# $Id$
# $HeadURL$
# $Author$
#
#ADD_SUBDIRECTORY(BaseDownloader)
ADD_SUBDIRECTORY(OcTerminal)
ADD_SUBDIRECTORY(System)
ADD_SUBDIRECTORY(ParticipantInfoOc)
@@ -0,0 +1,58 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Patric Karwat, SLSE, 2018-01-17
#
SET(osc_terminal_gui_SRCS
osc_terminal_gui_plugin.cpp
osc_terminal_gui_plugin.h
osc_demand_situation.cpp
osc_demand_situation.h
osc_fault_message.h
osc_fault_message.cpp
osc_equip_player.h
osc_equip_player.cpp
osc_edit_folder_content.cpp
osc_edit_folder_content.h
osc_demand_situation_filter.cpp
osc_demand_situation_filter.h
)
NGL_WRAP_UI(osc_terminal_gui_SRCS
osc_demand_situation.ui
osc_fault_message.ui
osc_equip_player.ui
osc_edit_folder_content.ui
osc_demand_situation_filter.ui
)
NGL_ADD_LIBRARY(WS OscTerminalGuiPlugin MODULE ${osc_terminal_gui_SRCS})
NGL_TARGET_LINK_LIBRARIES(OscTerminalGuiPlugin
AsbDataPluginInterface
LtsPrinting
NGLLogger
LtsNotification
LtsSession
LtsSessionData
LtsDataView
LtsUtilsSettings
PpmCommon
PpmDataPluginInterface
TabocDataPluginInterface
ObdDataPluginInterface
SituationMapGuiPluginInterface
OscTerminalGuiPluginInterface
svcOscClient
LtsWidgets
ngltools
nglsettings
ltsCoordWidget
LtsUtilsSettings
LtsUtilsGuiDds
Qt5::Widgets
)
NGL_INSTALL_TARGET(OscTerminalGuiPlugin)
@@ -0,0 +1,315 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - DemandSituation Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-27
*/
#include "osc_demand_situation.h"
#include "ui_osc_demand_situation.h"
#include <AdvancedSymbology/asb_data_plugin_interface.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <LtsUtilsSettings/settings.h>
#include <Map/map.h> // Interface
#include <QTreeView>
namespace OcSituationClient
{
DemandSituation::DemandSituation(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
, m_session(session)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_selectedEqNr(0)
, m_ocDemandGroupString(QStringLiteral("ObserverControllerDemand"))
, m_ocDemandFilterGroupString(QStringLiteral("ObserverControllerDemandFilter"))
, m_opSettings(LtsUtils::OperatorSettings::getInstance())
, m_model(nullptr)
, m_proxyModel(nullptr)
, m_ui(new Ui::DemandSituation)
, m_logger(getLogger("DemandSituationDialog"))
{
m_ui->setupUi(this);
setOnlineHelpFilename(QStringLiteral("OC-Demand_Situation"));
}
DemandSituation::~DemandSituation()
{
delete m_ui;
}
bool DemandSituation::init(const std::shared_ptr<Interface::Ftc> &ftc)
{
if (!ftc)
return false;
m_ftc = ftc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> dtcPpm;
if (!m_session->getDtc<ParticipantManagement::DataInterface>(dtcPpm))
return false;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmCbxGui))
return false;
if (!m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc))
return false;
//optional
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc);
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> asb;
m_session->getForeignDataInterface<AdvancedSymbology::DataInterface>(asb);
m_model = new ParticipantManagement::ParticipantEditModel(this, dtcPpm, asb);
// only needed to set recursiveFilteringEnabled
m_proxyModel = new ParticipantManagement::ParticipantTreeFilterProxyModel(this);
m_proxyModel->setSourceModel(m_model);
m_proxyModel->setRecursiveFilteringEnabled(true);
m_ui->dvParticipants->setModel(m_proxyModel);
m_ppmCbxGui->fillPartyComboBox(m_ui->cbParty, ParticipantManagement::ForeignGuiComboboxInterface::CbxPartyFilter::NormalOc);
connect(m_ui->dvParticipants, &LtsDataView::LtsDataView::signalSelectionChanged,
this, &DemandSituation::onSlotSelectionChanged);
if (m_sitMapGuiIfc)
{
connect(m_ui->pbClear, &QPushButton::clicked, this, &DemandSituation::onClearCoordinate);
connect(m_ui->pbPos, &QPushButton::clicked, this, &DemandSituation::onGetPosition);
}
else
{
m_ui->pbPos->setEnabled(false);
}
connect(m_ui->cbParty, &LtsWidgets::LtsComboBox::currentTextChanged, this, [this]
{
m_model->onReinitModel(m_ui->cbParty->currentData().toInt());
m_ui->dvParticipants->expandAll();
});
connect(m_ui->slRange, &QSlider::valueChanged, this, [this](int range)
{
m_ui->lblRange->setText(QString::number(range));
repaintSitmapCircle();
});
m_model->onReinitModel(m_ui->cbParty->currentData().toInt());
m_ui->slRange->setValue(10);
m_ui->dvParticipants->expandAll();
m_ui->dvParticipants->setSortIndicator(0, Qt::AscendingOrder);
//load old settings
m_ui->slRange->setValue(m_opSettings->value(m_ocDemandGroupString, QStringLiteral("Range"), 100).toInt());
m_ui->cbParty->setCurrentIndex(m_ui->cbParty->findData(m_opSettings->value(m_ocDemandGroupString, QStringLiteral("Party"), 1).toInt()));
if (m_opSettings->value(m_ocDemandGroupString, QStringLiteral("ParticipantId"), 0).toInt() > 0)
{
const auto idx = m_model->indexFromParticipantId(m_opSettings->value(m_ocDemandGroupString, QStringLiteral("ParticipantId"), -1).toInt());
m_ui->dvParticipants->treeView()->setCurrentIndex(m_proxyModel->mapFromSource(idx));
m_ui->dtePos->clear();
}
else if (m_opSettings->value(m_ocDemandGroupString, QStringLiteral("PosLon"), -1).toDouble() > 0)
{
m_ui->dtePos->setCoordinate(m_opSettings->value(m_ocDemandGroupString, QStringLiteral("PosLon"), -1).toDouble(),
m_opSettings->value(m_ocDemandGroupString, QStringLiteral("PosLat"), -1).toDouble());
}
m_ui->cbFilter->setChecked(m_opSettings->value(m_ocDemandGroupString, QStringLiteral("FilterActive"), false).toBool());
connect(m_ui->pbClear, &QPushButton::clicked,
m_ui->dvParticipants->selectionModel(), &QItemSelectionModel::clearSelection);
__unchange__();
return true;
}
void DemandSituation::onSendDemandSituationReply(const Core::FunctionReplyObject &replyObject)
{
if (replyObject.str().empty())
{
// save new settings
m_opSettings->setValue(m_ocDemandGroupString, QStringLiteral("Range"), m_ui->slRange->value());
m_opSettings->setValue(m_ocDemandGroupString, QStringLiteral("Party"), m_ui->cbParty->currentData().toInt());
const auto selIndexes = m_ui->dvParticipants->selectedRows();
if (!selIndexes.isEmpty())
m_opSettings->setValue(m_ocDemandGroupString, QStringLiteral("ParticipantId"), m_model->getParticipantData(selIndexes.first()).id());
else
m_opSettings->setValue(m_ocDemandGroupString, QStringLiteral("ParticipantId"), 0);
m_opSettings->setValue(m_ocDemandGroupString, QStringLiteral("PosLon"), m_ui->dtePos->coordinate().x());
m_opSettings->setValue(m_ocDemandGroupString, QStringLiteral("PosLat"), m_ui->dtePos->coordinate().y());
m_opSettings->setValue(m_ocDemandGroupString, QStringLiteral("FilterActive"),m_ui->cbFilter->isChecked());
}
else
{
// reset to old settings
discardSitmapCircle();
}
m_requestHelper->requestReply(replyObject);
}
void DemandSituation::onSlotSelectionChanged()
{
m_selectedEqNr = 0;
const auto selIndexes = m_ui->dvParticipants->selectedRows();
if (!selIndexes.isEmpty())
{
ParticipantManagement::ParticipantData part = m_model->getParticipantData(selIndexes.first());
if (part.equipmentNumber().is_set())
{
//clear pos
onClearCoordinate();
m_selectedEqNr = part.equipmentNumber().get();
}
else
m_selectedEqNr = 0;
}
repaintSitmapCircle();
slotChangesMade();
}
void DemandSituation::onGetPosition()
{
//clear selection
m_ui->dvParticipants->selectionModel()->clearSelection();
m_sitMapGuiIfc->getCircle(this,
SLOT(onCoordinate(QPointF, double)),
nullptr,
m_ui->slRange->minimum(),
m_ui->slRange->maximum());
}
void DemandSituation::onCoordinate(const QPointF &coord, double radius)
{
m_ui->dtePos->setCoordinate(coord);
m_ui->slRange->setValue(static_cast<int>(radius));
repaintSitmapCircle();
slotChangesMade();
}
void DemandSituation::onClearCoordinate()
{
m_ui->dtePos->clear();
slotChangesMade();
}
void DemandSituation::retranslate()
{
translate(m_ui, tr("Demand Situation") );
m_uiRequirements->clear();
m_uiRequirements->addRequirement({m_ui->lbRange, [this]() { return !!(m_selectedEqNr >= 0 || m_ui->dtePos->coordinate().x() > 0 ); },
tr("Select none or one participant with equipment number or a position.")});
}
bool DemandSituation::apply()
{
// set filter
m_partys.clear();
m_typesClass.clear();
if(m_ui->cbFilter->isChecked())
{
m_filterActive = true;
QStringList partyList = m_opSettings->value(m_ocDemandFilterGroupString, QStringLiteral("Partys"),-1).toStringList();
for(const auto &s : partyList)
m_partys.push_back(s.toInt());
QStringList typeClassList = m_opSettings->value(m_ocDemandFilterGroupString, QStringLiteral("TypeClass"),-1).toStringList();
for(const auto &s : typeClassList)
m_typesClass.push_back(s.toInt());
}
else
{
m_filterActive = false;
}
SendDemandSituationRequest req(m_selectedEqNr,
m_ui->slRange->value(),
dds::core::optional<Core::GeoPosition2D>(),
m_filterActive,
m_partys,
m_typesClass);
bool bret;
bool stopDemand = false;
if (m_ui->dtePos->coordinate().isNull() && m_selectedEqNr == 0)
{
req.radius() = 0;
const Core::GeoPosition2D pos(std::nan(""),std::nan(""));
req.position() = pos;
stopDemand = true;
}
else if (m_ui->dtePos->coordinate().x() > 0)
{
const Core::GeoPosition2D pos(m_ui->dtePos->coordinate().x(), m_ui->dtePos->coordinate().y() );
req.position().set(pos);
}
bret = m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->sendDemandSituationRequest(req, this);
});
if (bret && stopDemand)
emit demandSituationStopped();
return bret;
}
void DemandSituation::dialogCanceled()
{
discardSitmapCircle();
}
void DemandSituation::repaintSitmapCircle()
{
double range = static_cast<double>(m_ui->slRange->value());
const auto selIndexes = m_ui->dvParticipants->selectedRows();
if (!selIndexes.isEmpty())
{
m_sitMapGuiIfc->ocSituationRange_create(m_model->getParticipantData(selIndexes.first()).id(), range);
}
else if (!m_ui->dtePos->coordinate().isNull())
{
QPointF pos(m_ui->dtePos->coordinate().x(),
m_ui->dtePos->coordinate().y());
m_sitMapGuiIfc->ocSituationRange_create(pos, range);
}
else
{
m_sitMapGuiIfc->ocSituationRange_remove();
}
}
void DemandSituation::discardSitmapCircle()
{
//load old settings
double range = static_cast<double>(m_opSettings->value(m_ocDemandGroupString, QStringLiteral("Range"), 100).toInt());
int participantId = m_opSettings->value(m_ocDemandGroupString, QStringLiteral("ParticipantId"), 0).toInt();
if (participantId > 0)
{
m_sitMapGuiIfc->ocSituationRange_create(participantId, range);
}
else if (m_opSettings->value(m_ocDemandGroupString, QStringLiteral("PosLon"), -1).toDouble() > 0)
{
QPointF pos(m_opSettings->value(m_ocDemandGroupString, QStringLiteral("PosLon"), -1).toDouble(),
m_opSettings->value(m_ocDemandGroupString, QStringLiteral("PosLat"), -1).toDouble());
m_sitMapGuiIfc->ocSituationRange_create(pos, range);
}
else // no oc sitmap selected
{
m_sitMapGuiIfc->ocSituationRange_remove();
}
}
} // namespace OcSituationClient
@@ -0,0 +1,95 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Demand Situation Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-27
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <LtsSession/lts_session.h>
#include <OcSituationClient/logger.h>
#include <Plugins/OcSituationClient/osc_data_plugin_interface.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <ParticipantManagement/Gui/Common/participant_edit_model.h>
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
namespace Ui
{
class DemandSituation;
}
namespace SituationMap
{
class ForeignGuiInterface;
}
namespace LtsUtils
{
class OperatorSettings;
}
namespace LtsWidgets
{
class LtsColumnFilterProxyModel;
}
namespace OcSituationClient
{
class DemandSituation : public LtsWidgets::LtsDialog,
private OcSituationClient::Interface::Ftc::SendDemandSituationReplyHandler
{
Q_OBJECT
public:
explicit DemandSituation(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~DemandSituation();
bool init(const std::shared_ptr<Interface::Ftc> &ftc);
void onSendDemandSituationReply(const Core::FunctionReplyObject &replyObject) override;
Q_SIGNALS:
void demandSituationStopped();
private Q_SLOTS:
void onSlotSelectionChanged();
void onGetPosition();
void onCoordinate(const QPointF &coord, double radius);
void onClearCoordinate();
private:
void retranslate() override;
bool apply() override;
void dialogCanceled () override;
void repaintSitmapCircle();
void discardSitmapCircle();
private:
LtsSession::LtsSession *m_session;
LtsUtils::RequestHelper *m_requestHelper;
int m_selectedEqNr;
bool m_filterActive{false};
std::vector<int> m_partys;
std::vector<int> m_typesClass;
QString m_ocDemandGroupString;
QString m_ocDemandFilterGroupString;
LtsUtils::OperatorSettings *m_opSettings;
ParticipantManagement::ParticipantEditModel *m_model;
LtsWidgets::LtsColumnFilterProxyModel *m_proxyModel;
std::shared_ptr<OcSituationClient::Interface::Ftc> m_ftc;
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmCbxGui;
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
Ui::DemandSituation *m_ui;
LOGGER_T m_logger;
};
} // namespace OcSituationClient
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DemandSituation</class>
<widget class="QWidget" name="DemandSituation">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>438</width>
<height>82</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">MessagingView</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Party:</string>
</property>
</widget>
</item>
<item>
<widget class="LtsWidgets::LtsComboBox" name="cbParty"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label2">
<property name="text">
<string>Position</string>
</property>
</widget>
</item>
<item>
<widget class="LtsCoordWidget::LtsCoordWidget" name="dtePos" native="true"/>
</item>
<item>
<widget class="QPushButton" name="pbPos">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/style/position.svg</normaloff>:/style/position.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbClear">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/style/remove.svg</normaloff>:/style/remove.svg</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Use Filter:</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbFilter">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lbRange">
<property name="text">
<string>Range: [m]</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="slRange">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblRange">
<property name="text">
<string notr="true">&lt;RANGE&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="LtsDataView::LtsDataView" name="dvParticipants" native="true">
<property name="rootIsDecorated" stdset="0">
<bool>true</bool>
</property>
<property name="showColumnCount" stdset="0">
<bool>false</bool>
</property>
<property name="toolButtonsVisible" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsCoordWidget::LtsCoordWidget</class>
<extends>QWidget</extends>
<header>LtsCoordTrans/lts_coord_widget.h</header>
</customwidget>
<customwidget>
<class>LtsWidgets::LtsComboBox</class>
<extends>QComboBox</extends>
<header>LtsWidgets/lts_combo_box.h</header>
</customwidget>
<customwidget>
<class>LtsDataView::LtsDataView</class>
<extends>QWidget</extends>
<header>LtsDataView/lts_data_view.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,245 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - OC Situation Filter
* $Id$
* $HeadURL$
* $Author$
* Created by Steve Kemayou, SLSE, 2022-07-07
*/
#include "osc_demand_situation_filter.h"
#include "ui_osc_demand_situation_filter.h"
#include <PluginInterfaces/gui_plugin_interface.h>
#include <LtsUtilsSettings/settings.h>
#include <QVBoxLayout>
#include <QLayout>
#include <QCheckBox>
#include <QLabel>
namespace OcSituationClient
{
DemandSituationFilter::DemandSituationFilter(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
, m_ui(new Ui::DemandSituationFilter)
, m_session(session)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_ftc(nullptr)
, m_ppmDtc(nullptr)
, m_opSettings(LtsUtils::OperatorSettings::getInstance())
, m_ocDemandFilterGroupString(QStringLiteral("ObserverControllerDemandFilter"))
{
m_ui->setupUi(this);
setOnlineHelpFilename(QStringLiteral("OC-Demand_Situation_Filter"));
}
DemandSituationFilter::~DemandSituationFilter()
{
delete m_ui;
}
void DemandSituationFilter::retranslate()
{
translate(m_ui, tr("Demand Situation Filter") );
m_uiRequirements->retranslate();
}
bool DemandSituationFilter::init(const std::shared_ptr<Interface::Ftc> &ftc)
{
if (!ftc)
return false;
m_ftc = ftc;
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
return false;
m_ppmDtc->enableParticipant(true);
m_ppmDtc->enableEquipmentType(true);
m_partyList.clear();
m_typeClassList.clear();
/// build partys filter
// get settings
QStringList partys;
partys = m_opSettings->value(m_ocDemandFilterGroupString, QStringLiteral("Partys"),-1).toStringList();
for(const auto &s : partys)
{
if(s.compare(QStringLiteral("-1")) != 0)
m_partyList << s;
}
buildPartyTable(m_ppmDtc->partys());
/// build typeClass filter
// fill typClass
std::set<ParticipantManagement::TypeClass> ppmTypeClass;
ppmTypeClass.insert(ParticipantManagement::TypeClass_def::SupportEntity);
//ppmTypeClass.insert(ParticipantManagement::TypeClass_def::Unit);
ppmTypeClass.insert(ParticipantManagement::TypeClass_def::Human);
ppmTypeClass.insert(ParticipantManagement::TypeClass_def::GroundVehicle);
//ppmTypeClass.insert(ParticipantManagement::TypeClass_def::Vessel);
ppmTypeClass.insert(ParticipantManagement::TypeClass_def::VehicleWithGear);
ppmTypeClass.insert(ParticipantManagement::TypeClass_def::WeaponSystem);
//ppmTypeClass.insert(ParticipantManagement::TypeClass_def::SupportUnit);
ppmTypeClass.insert(ParticipantManagement::TypeClass_def::Aircraft);
// get current settings
QStringList typeClassList;
typeClassList = m_opSettings->value(m_ocDemandFilterGroupString, QStringLiteral("TypeClass"),-1).toStringList();
for(const auto &s : typeClassList)
{
if(s.compare(QStringLiteral("-1")) != 0)
m_typeClassList << s;
}
buildTypeClassTable(ppmTypeClass);
m_ui->lblInfo->setText(tr("After saving Filter settings, the Demand Situation Request will be updated, if the filter in 'Demand Situation Dialog' is activated."));
return true;
}
bool DemandSituationFilter::apply()
{
// save typeClassList and partyList
m_opSettings->setValue(m_ocDemandFilterGroupString, QStringLiteral("Partys"),m_partyList);
m_opSettings->setValue(m_ocDemandFilterGroupString, QStringLiteral("TypeClass"),m_typeClassList);
bool ret;
const QString ocDemandGroup = QStringLiteral("ObserverControllerDemand");
const bool useFilter = m_opSettings->value(ocDemandGroup, QStringLiteral("FilterActive"), false).toBool();
const int ppId = m_opSettings->value(ocDemandGroup, QStringLiteral("ParticipantId"), 0).toInt();
if(useFilter == true && ppId > 0)
{
const int range = m_opSettings->value(ocDemandGroup, QStringLiteral("Range"), 100).toInt();
const double posLon = m_opSettings->value(ocDemandGroup, QStringLiteral("PosLon"), -1).toDouble();
const double posLat = m_opSettings->value(ocDemandGroup, QStringLiteral("PosLat"), -1).toDouble();
const ParticipantManagement::Participant participant = m_ppmDtc->participant(ppId);
int equipNumber = 0;
if(participant.equipmentNumber().is_set())
{
equipNumber= participant.equipmentNumber().get();
}
std::vector<int> partyList;
for(const auto & pl : m_partyList )
{
partyList.push_back(pl.toInt());
}
std::vector<int> typeClassList;
for(const auto &tl : m_typeClassList)
{
typeClassList.push_back(tl.toInt());
}
SendDemandSituationRequest req(equipNumber,
range,
dds::core::optional<Core::GeoPosition2D>(),
useFilter,
partyList,
typeClassList);
if (posLon > 0)
{
const Core::GeoPosition2D pos(posLon, posLat );
req.position().set(pos);
}
ret = m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->sendDemandSituationRequest(req, this);
});
if(ret == false)
{
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Filter successfully Saved, but Couldn't send demand situation request."));
}
}
return true;
}
static void addSpacerItem(QVBoxLayout *gridLayout)
{
gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
}
void DemandSituationFilter::buildPartyTable(const QMap<int, ParticipantManagement::Party> &parties)
{
for (const ParticipantManagement::Party &party : parties)
{
if(party.id() == 0)
continue;
QCheckBox *cbParty = new QCheckBox(ParticipantManagement::trPartyName(party.name()), this);
cbParty->setObjectName(QStringLiteral("party_%1").arg(party.id()));
cbParty->setChecked(m_partyList.contains(QString::number(party.id())));
connect(cbParty, &QCheckBox::stateChanged, this, &DemandSituationFilter::onPartyBoxChecked);
m_ui->glParty->addWidget(cbParty);
// <spc>
}
addSpacerItem(m_ui->glParty);
}
void DemandSituationFilter::buildTypeClassTable(const std::set<ParticipantManagement::TypeClass> &typeClassList)
{
for (const ParticipantManagement::TypeClass &typeClass : typeClassList)
{
QCheckBox *cb = new QCheckBox(ParticipantManagement::toString(typeClass.underlying()), this);
cb->setObjectName(QStringLiteral("typeClass_%1").arg(typeClass.underlying()));
cb->setChecked(m_typeClassList.contains(QString::number(typeClass.underlying())));
connect(cb, &QCheckBox::stateChanged, this, &DemandSituationFilter::onTypeClassCBoxChecked);
m_ui->glTypeClass->addWidget(cb);
}
addSpacerItem(m_ui->glTypeClass);
}
void DemandSituationFilter::onSendDemandSituationReply(const Core::FunctionReplyObject &replyObject)
{
DEBUG_LOG(m_logger)<< " update filter demand situationReply: "<<replyObject.str();
m_requestHelper->requestReply(replyObject);
}
void DemandSituationFilter::onPartyBoxChecked()
{
QCheckBox *cb = (QCheckBox*) sender();
if(cb!=nullptr)
{
QString partyId = cb->objectName().section(QStringLiteral("party_"),1,1);
DEBUG_LOG(m_logger)<<" onPartyBoxChecked(): partyId: "<<partyId;
if(cb->isChecked())
{
m_partyList << partyId;
}
else
{
m_partyList.removeOne(partyId);
}
}
}
void DemandSituationFilter::onTypeClassCBoxChecked()
{
QCheckBox *cb = (QCheckBox*) sender();
if(cb!=nullptr)
{
QString partyId = cb->objectName().section(QStringLiteral("typeClass_"),1,1);
DEBUG_LOG(m_logger)<<" onTypeClassCBoxChecked(): typClass: "<<partyId;
if(cb->isChecked())
{
if(m_typeClassList.contains(partyId) == false)
{
m_typeClassList << partyId;
}
}
else
{
m_typeClassList.removeOne(partyId);
}
}
}
} // namespace OcSituationClient
@@ -0,0 +1,72 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - OC Situation Filter
* $Id$
* $HeadURL$
* $Author$
* Created by Steve Kemayou, SLSE, 2022-07-07
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <LtsSession/lts_session.h>
#include <OcSituationClient/logger.h>
#include <Plugins/OcSituationClient/osc_data_plugin_interface.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <ProjectDataManagement/pdm_enums.hpp>
#include <ParticipantManagement/ppm_translation.h>
#include <ParticipantManagement/ppm.hpp>
#include <set>
#include <QWidget>
namespace Ui {
class DemandSituationFilter;
}
namespace LtsUtils
{
class OperatorSettings;
}
namespace OcSituationClient
{
class DemandSituationFilter : public LtsWidgets::LtsDialog,
private OcSituationClient::Interface::Ftc::SendDemandSituationReplyHandler
{
Q_OBJECT
public:
explicit DemandSituationFilter(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~DemandSituationFilter();
bool init(const std::shared_ptr<Interface::Ftc> &ftc);
void buildPartyTable(const QMap<int, ParticipantManagement::Party> &parties);
void buildTypeClassTable(const std::set<ParticipantManagement::TypeClass> &typeClassList);
void onSendDemandSituationReply(const Core::FunctionReplyObject &replyObject) override;
protected slots:
void onPartyBoxChecked();
void onTypeClassCBoxChecked();
private:
bool apply() override;
void retranslate() override;
private:
Ui::DemandSituationFilter *m_ui;
LtsSession::LtsSession *m_session;
LtsUtils::RequestHelper *m_requestHelper;
std::shared_ptr<OcSituationClient::Interface::Ftc> m_ftc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
QStringList m_typeClassList;
QStringList m_partyList;
LtsUtils::OperatorSettings *m_opSettings;
QString m_ocDemandFilterGroupString;
};
} // namespace OcSituationClient
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DemandSituationFilter</class>
<widget class="QWidget" name="DemandSituationFilter">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>787</width>
<height>326</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>247</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1" rowspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="glParty"/>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>247</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2">
<layout class="QVBoxLayout" name="glTypeClass"/>
</item>
<item row="3" column="0" colspan="3">
<widget class="QLabel" name="lblInfo">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">&lt;INFO&gt;</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Type Class</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Partys</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,362 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - PDF Folder Content
* $Id$
* $HeadURL$
* $Author$
* Created by Steve Kemayou, SLSE, 2022-07-07
*/
#include "osc_edit_folder_content.h"
#include "ui_osc_edit_folder_content.h"
#include <QDir>
#include <QTableView>
#include <LtsUtilsSettings/settings.h>
#include <LtsDataView/lts_data_view.h>
#include <LtsSession/lts_session_data.h>
namespace OcSituationClient
{
static Poppler::Page::Rotation getRotationFromValue(int rotation);
/*!
* \brief FolderContentEditDialog::FolderContentEditDialog
* \param parent
*/
FolderContentEditDialog::FolderContentEditDialog(QWidget *parent)
:LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
, m_ui(new Ui::FolderContentEditDialog)
, m_session(nullptr)
, m_obdFtc(nullptr)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_logger(getLogger("OscFolderContentEditDialog"))
{
m_ui->setupUi(this);
setOnlineHelpFilename(QStringLiteral("OSC-Edit_Folder_Content"));
m_ui->filesView->horizontalHeader()->setStretchLastSection(true);
m_ui->filesView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); // resize view table to have the same column width
m_ui->filesView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_ui->filesView->setEditTriggers(QAbstractItemView::NoEditTriggers); // can't be edited from user.
m_ui->filesView->verticalHeader()->hide();
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &FolderContentEditDialog::onDeleteFile);
m_buttonBox->connectButton(LtsWidgets::DialogButton::Show, this, &FolderContentEditDialog::onPreviewFile);
enaDisa();
const QString opName = LtsSessionData::LtsSessionData::getInstance()->getOperatorName();
const QString dir = QStringLiteral("%1/OcPdf/%2/").arg(QDir::tempPath()).arg(opName);
QDir directory(dir);
if(!directory.exists())
directory.mkdir(dir);
setDefaultFileSystemPath(dir);
}
FolderContentEditDialog::~FolderContentEditDialog()
{
if(m_pdfWidget != nullptr)
delete m_pdfWidget;
m_pdfWidget = nullptr;
delete m_ui;
}
/*!
* \brief FolderContentEditDialog::init
* \param session
* \return
*/
bool FolderContentEditDialog::init(LtsSession::LtsSessionDataDds *session)
{
m_session = session;
if (!m_session->getFtc<OcBaseDownload::DataInterface>(m_obdFtc))
{
ERROR_LOG(m_logger) << "Cant get Obd FTC can't download";
return false;
}
delete m_fileSystemModel;
m_fileSystemModel = new QFileSystemModel();
m_fileSystemModel->setFilter(QDir::Files|QDir::NoDotAndDotDot);
m_fileSystemModel->setReadOnly(true);
QStringList filters;
filters << QStringLiteral("*.pdf");
m_fileSystemModel->setNameFilters(filters);
m_fileSystemModel->setNameFilterDisables(false);
m_fileSystemModel->setReadOnly(true);
m_ui->filesView->setModel(m_fileSystemModel);
m_ui->filesView->setRootIndex(m_fileSystemModel->setRootPath(getFileSysPath()));
m_ui->filesView->hideColumn(1);
m_fileSystemModel->sort(3, Qt::DescendingOrder);
m_ui->filesView->horizontalHeader()->setStyleSheet(QStringLiteral("font-weight: bold;"));
connect(m_ui->filesView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &FolderContentEditDialog::onSelectionChanged);
QPushButton *btn = m_buttonBox->getButton(LtsWidgets::DialogButton::Save);
btn->setText(tr("Pdf Download"));
m_buttonBox->connectButton(LtsWidgets::DialogButton::Save, this, &FolderContentEditDialog::onOcPdfDownloadClicked);
initPdfWidow();
return true;
}
/*!
* \brief FolderContentEditDialog::retranslate
*/
void FolderContentEditDialog::retranslate()
{
translate(m_ui, tr("Folder Content"));
}
/*!
* \brief FolderContentEditDialog::enaDisa
*/
void FolderContentEditDialog::enaDisa()
{
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, false);
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Show, false);
QItemSelectionModel *select = m_ui->filesView->selectionModel();
if(select == nullptr)
return;
QModelIndexList indexList =select->selectedRows();
if(indexList.size() == 0)
return;
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, indexList.size() > 0);
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Show, indexList.size()==1);
}
/*!
* \brief FolderContentEditDialog::onSelectionChanged
*/
void FolderContentEditDialog::onSelectionChanged()
{
enaDisa();
}
void FolderContentEditDialog::onOcPdfDownloadClicked()
{
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
const int folderId = ps->value(QStringLiteral("obd"), QStringLiteral("ocPdfDownloadFolderId")).toInt();
if(folderId <= 0)
{
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Couldn't download pdf files: Folder id invalid!"));
return;
}
const QString matrixOperator = LtsSessionData::LtsSessionData::getInstance()->getOperatorName();
DEBUG_LOG(m_logger)<<LOGFUNCTION<<" folderId:" <<folderId<<" operatorName: "<<matrixOperator;
OcBaseDownload::OcPdfDownloadRequest req(folderId,matrixOperator.toStdString());
m_requestHelper->startSingleRequest([req, this]()
{
return m_obdFtc->ocPdfDownloadRequest(req, this);
});
}
/*!
* \brief FolderContentEditDialog::onPreviewFile
*/
void FolderContentEditDialog::onPreviewFile()
{
QItemSelectionModel *select = m_ui->filesView->selectionModel();
if(select == nullptr)
return;
QModelIndexList indexList =select->selectedRows();
if(indexList.size() == 0)
return;
QModelIndex index = indexList.at(0);
m_currViewPath = m_fileSystemModel->filePath(index);
//const QUrl url = QUrl(QStringLiteral("file://") + m_currViewPath);
if(m_pdfWidget == nullptr)
{
WARNING_LOG(m_logger)<<" pdf widget not initialized. trying to init...";
initPdfWidow();
}
QFile f(m_currViewPath);
if(f.open(QIODevice::ReadOnly))
{
DEBUG_LOG(m_logger) << "Current File: " << m_currViewPath;
setPage(1);
setZoomFactor(ZOOM_DEFAULT);
setRotation(Poppler::Page::Rotate0);
m_pdfWidget->setWindowTitle(m_fileSystemModel->fileName(index));
m_pdfWidget->showPDF(f.readAll());
m_pdfWidget->setVisible(true);
m_pdfWidget->showMaximized();
}
}
/*!
* \brief FolderContentEditDialog::onDeleteFile
*/
void FolderContentEditDialog::onDeleteFile()
{
TRACE_LOG(m_logger)<<" delete file START ";
QItemSelectionModel *select = m_ui->filesView->selectionModel();
if(select == nullptr)
return;
QModelIndexList indexList =select->selectedRows();
m_pdfWidget->hide();
if(indexList.size() > 0)
{
QFileInfoList fileInfoList;
for(const auto index : qAsConst(indexList))
{
fileInfoList << m_fileSystemModel->fileInfo(index);
TRACE_LOG(m_logger)<< "file path:"<<fileInfoList.last().absoluteFilePath();
}
QDir dir;
dir.setPath(getFileSysPath());
for (auto fileInfo : fileInfoList)
{
bool success = dir.remove(fileInfo.fileName());
TRACE_LOG(m_logger)<< "remove file:"<<fileInfo.absoluteFilePath() << " | succeed? "<< success;
}
}
TRACE_LOG(m_logger) <<" delete file End ";
}
/*!
* \brief FolderContentEditDialog::setDefaultFileSystemPath
* \param path
*/
void FolderContentEditDialog::setDefaultFileSystemPath(QString path)
{
m_filesysPath = path.isEmpty() ? QDir::homePath() : path;
TRACE_LOG(m_logger)<<" set default filesystem path: "<< path;
}
/*!
* \brief FolderContentEditDialog::setPage
* \param pageNo
*/
void FolderContentEditDialog::setPage(int pageNo)
{
if (m_pageNo == pageNo)
return;
DEBUG_LOG(m_logger) << "setPage = " << pageNo;
m_pageNo = pageNo;
m_pdfWidget->setPage(pageNo);
emit currentPageChanged(m_pageNo);
}
/*!
* \brief FolderContentEditDialog::getCurPage
* \return
*/
int FolderContentEditDialog::getCurPage() const
{
return m_pdfWidget->curPage();
}
/*!
* \brief FolderContentEditDialog::getNumPages
* \return
*/
int FolderContentEditDialog::getNumPages() const
{
return m_pdfWidget->numPages();
}
/*!
* \brief FolderContentEditDialog::setZoomFactor
* \param zoomFactor
*/
void FolderContentEditDialog::setZoomFactor(double zoomFactor)
{
if (qFuzzyCompare(m_zoomFactor, zoomFactor))
return;
DEBUG_LOG(m_logger) << "setZoomFactor = " << zoomFactor;
m_zoomFactor = zoomFactor;
m_pdfWidget->setZoomFactor(zoomFactor);
}
/*!
* \brief FolderContentEditDialog::setRotation
* \param rotation
*/
void FolderContentEditDialog::setRotation(int rotation)
{
if (m_rotation == rotation)
return;
DEBUG_LOG(m_logger) << "setRotation = " << rotation;
m_rotation = rotation;
m_pdfWidget->setRotation(getRotationFromValue(m_rotation));
emit rotationChanged(rotation);
}
/*!
* \brief FolderContentEditDialog::initPdfWidow
*/
void FolderContentEditDialog::initPdfWidow()
{
if(m_pdfWidget!= nullptr)
delete m_pdfWidget;
m_pdfWidget = new NGL::PDFWidget();
m_pdfWidget->setObjectName(QStringLiteral("osc_pdfWidget"));
m_pdfWidget->setSizePolicy(QSizePolicy::Policy::MinimumExpanding, QSizePolicy::Policy::MinimumExpanding);
m_pdfWidget->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
connect(m_pdfWidget, &NGL::PDFWidget::currentPageChanged, this, &FolderContentEditDialog::setPage);
connect(m_pdfWidget, &NGL::PDFWidget::rotationChanged, this, [this](Poppler::Page::Rotation rot)
{
switch (rot)
{
case Poppler::Page::Rotate90:
setRotation(90);
break;
case Poppler::Page::Rotate180:
setRotation(180);
break;
case Poppler::Page::Rotate270:
setRotation(270);
break;
case Poppler::Page::Rotate0:
setRotation(0);
break;
}
});
}
void FolderContentEditDialog::onOcPdfDownloadReply(const Core::FunctionReplyObject & replyObject)
{
m_requestHelper->requestReply(replyObject);
m_fileSystemModel->setRootPath(getFileSysPath());
}
/*!
* \brief getRotationFromValue
* \param rotation
* \return
*/
Poppler::Page::Rotation getRotationFromValue(int rotation)
{
Poppler::Page::Rotation rot;
switch (rotation)
{
case 90:
rot = Poppler::Page::Rotate90;
break;
case 180:
rot = Poppler::Page::Rotate180;
break;
case 270:
rot = Poppler::Page::Rotate270;
break;
case 0:
default:
rot = Poppler::Page::Rotate0;
break;
}
return rot;
}
} // end namespace
@@ -0,0 +1,84 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - PDF Folder Content
* $Id$
* $HeadURL$
* $Author$
* Created by Steve Kemayou, SLSE, 2022-07-07
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <OcSituationClient/logger.h>
#include <Plugins/OcSituationClient/osc_data_plugin_interface.h>
#include <LtsSession/lts_session.h>
#include <QFileSystemModel>
#include <nglwidgets/nglpdfwidget.h>
#include <QSortFilterProxyModel>
#include <LtsUtilsGuiDds/request_helper.h>
#include <Plugins/OcBaseDownload/obd_data_plugin_interface.h>
#define ZOOM_DEFAULT 1.0
namespace Ui {
class FolderContentEditDialog;
}
namespace OcSituationClient
{
class FolderContentEditDialog : public LtsWidgets::LtsDialog
, protected OcBaseDownload::Interface::Ftc::OcPdfDownloadReplyHandler
{
Q_OBJECT
public:
explicit FolderContentEditDialog(QWidget *parent = nullptr);
~FolderContentEditDialog();
bool init(LtsSession::LtsSessionDataDds *session);
void setDefaultFileSystemPath(QString path = QStringLiteral(""));
QString getFileSysPath(){return m_filesysPath;}
void initPdfWidow();
void onOcPdfDownloadReply(const Core::FunctionReplyObject &replyObject) override final;
private slots:
void onDeleteFile();
void onPreviewFile();
void setPage(int pageNo);
int getNumPages() const;
int getCurPage() const;
void setZoomFactor(double zoomFactor);
void setRotation(int rotation);
void onSelectionChanged();
void onOcPdfDownloadClicked();
signals:
void currentPageChanged(int curPage);
void rotationChanged(int rotation);
private:
void retranslate();
void enaDisa();
Ui::FolderContentEditDialog *m_ui;
LtsSession::LtsSessionDataDds *m_session;
std::shared_ptr<OcBaseDownload::Interface::Ftc> m_obdFtc;
QFileSystemModel *m_fileSystemModel{nullptr};
QString m_filesysPath{};
NGL::PDFWidget *m_pdfWidget{nullptr};
int m_pageNo{-1};
double m_zoomFactor{ZOOM_DEFAULT};
int m_rotation; // degree
QSortFilterProxyModel *m_proxymodel;
QString m_currViewPath;
QSortFilterProxyModel *m_sortProxyModel{nullptr};
LtsUtils::RequestHelper *m_requestHelper{nullptr};
LOGGER_T m_logger;
};
}// namespace FileManagement
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FolderContentEditDialog</class>
<widget class="QWidget" name="FolderContentEditDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>490</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTableView" name="filesView"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,240 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Fault Message Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-27
*/
#include "osc_equip_player.h"
#include "ui_osc_equip_player.h"
#include <AdvancedSymbology/asb_data_plugin_interface.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <ParticipantManagement/ppm_ftc.h>
namespace OcSituationClient
{
EquipPlayer::EquipPlayer(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
, m_session(session)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_selectedParticipantId(-1)
, m_maxChars(255)
, m_maxPartChars(35)
, m_isValid(false)
, m_model(nullptr)
, m_ftc(nullptr)
, m_ppmFtc(nullptr)
, m_tabocDtc(nullptr)
, m_ppmDtc(nullptr)
, m_ppmCbxGui(nullptr)
, m_ui(new Ui::EquipPlayer)
, m_logger(getLogger("EquipPlayerDialog"))
{
m_ui->setupUi(this);
setOnlineHelpFilename(QStringLiteral("OC-Equip_Player"));
}
EquipPlayer::~EquipPlayer()
{
delete m_ui;
}
bool EquipPlayer::init(const std::shared_ptr<Interface::Ftc> &ftc)
{
if (!ftc)
return false;
m_ftc = ftc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> dtcPpm;
if (!m_session->getDtc<ParticipantManagement::DataInterface>(dtcPpm))
return false;
if (!m_session->getFtc<ParticipantManagement::DataInterface>(m_ppmFtc))
return false;
if (!m_session->getDtc<TrainingAreaBaseOC::DataInterface>(m_tabocDtc))
return false;
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
return false;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmCbxGui))
return false;
#ifdef TABLET_MODE
//css didn"t worked
m_ui->dvParticipants->setIconSize(QSize(50,50));
#endif
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> asb;
m_session->getForeignDataInterface<AdvancedSymbology::DataInterface>(asb);
m_model = new ParticipantManagement::ParticipantEditModel(this, dtcPpm, asb);
// only needed to set recursiveFilteringEnabled
m_proxyModel = new ParticipantManagement::ParticipantTreeFilterProxyModel(this);
m_proxyModel->setSourceModel(m_model);
m_proxyModel->setRecursiveFilteringEnabled(true);
m_ui->dvParticipants->setModel(m_proxyModel);
m_ppmCbxGui->fillPartyComboBox(m_ui->cbParty);
connect(m_ui->dvParticipants, &LtsDataView::LtsDataView::signalSelectionChanged,
this, &EquipPlayer::onSlotSelectionChanged);
connect(m_ui->cbParty, &LtsWidgets::LtsComboBox::currentTextChanged, this, [this]
{
m_model->onReinitModel(m_ui->cbParty->currentData().toInt());
m_ui->dvParticipants->expandAll();
});
m_model->onReinitModel(m_ui->cbParty->currentData().toInt());
m_ui->dvParticipants->expandAll();
m_ui->dvParticipants->setSortIndicator(0, Qt::AscendingOrder);
m_ui->leParticipant->setValidator( new QIntValidator(0, 10000, this) );
m_ui->lblMaxEq->setText(QStringLiteral("-"));
m_ui->lblMinEq->setText(QStringLiteral("-"));
return true;
}
void EquipPlayer::onSlotSelectionChanged()
{
m_selectedParticipantId = 0;
const auto selIndexes = m_ui->dvParticipants->selectedRows();
ParticipantManagement::ParticipantData part;
ParticipantManagement::TypeClass tc;
if (!selIndexes.isEmpty())
{
part = m_model->getParticipantData(selIndexes.first());
ParticipantManagement::Type tp = m_ppmDtc->type(part.typeId());
ParticipantManagement::EquipmentType eq= m_ppmDtc->equipmentType(tp.equipmentTypeId());
m_ui->lblMinEq->setText(QString::number(eq.minEquipNo()));
m_ui->lblMaxEq->setText(QString::number(eq.maxEquipNo()));
tc = tp.typeClass();
if ( (tc == ParticipantManagement::TypeClass::Human)
|| (tc == ParticipantManagement::TypeClass::GroundVehicle)
|| (tc == ParticipantManagement::TypeClass::Aircraft)
|| (tc == ParticipantManagement::TypeClass::Vessel)
|| (tc == ParticipantManagement::TypeClass::WeaponSystem)
|| (tc == ParticipantManagement::TypeClass::VehicleWithGear) )
m_isValid = true;
else
m_isValid = false;
if (part.id())
m_selectedParticipantId = part.id();
else
m_selectedParticipantId = -1;
}
else
{
m_isValid = false;
m_selectedParticipantId = -1;
}
slotChangesMade();
if (m_selectedParticipantId > 0 && part.equipmentNumber().is_set())
m_ui->leParticipant->setText(QString::number(part.equipmentNumber().get()));
else
m_ui->leParticipant->setText(QString::number(0));
m_ui->leParticipant->setEnabled(m_isValid);
}
void EquipPlayer::retranslate()
{
translate(m_ui, tr("Equip Player") );
m_uiRequirements->clear();
m_uiRequirements->addRequirement({m_ui->lblParticpant, [this]() { return checkEqNr(); },
tr("Set to a valid Number or Equipment Number already exists!")});
m_uiRequirements->addRequirement({m_ui->label, [this]() { return m_isValid; },
tr("Only Participants are Allowed!")});
}
bool EquipPlayer::apply()
{
if (m_ui->leParticipant->text().toInt() < 0)
return false;
SendEquipmentRegistrationRequest req;
req.equipmentNumber(m_ui->leParticipant->text().toInt());
req.participantId(m_selectedParticipantId);
bool ret = m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->sendEquipmentRegistrationRequest(req, this);
});
//if( ret)
{
if (m_ppmDtc->participant(m_selectedParticipantId).equipmentNumber().is_set())
{
ParticipantManagement::RegisterParticipantRequest req3;
req3.participantId(m_selectedParticipantId);
req3.equipmentNumber(0);
req3.assignState(ParticipantManagement::ParticipantAssignState::NotAssigned);
m_requestHelper->startSingleRequest([req3, this]()
{
return m_ppmFtc->registerParticipantRequest(req3, this);
});
}
ParticipantManagement::RegisterParticipantRequest req2;
req2.participantId(m_selectedParticipantId);
req2.equipmentNumber(req.equipmentNumber());
req2.assignState(ParticipantManagement::ParticipantAssignState::HandoutExcon);
m_requestHelper->startSingleRequest([req2, this]()
{
return m_ppmFtc->registerParticipantRequest(req2, this);
});
}
return ret;
}
bool EquipPlayer::checkEqNr()
{
m_ui->lblError->setText(QString());
if (!m_isValid)
{
m_ui->lblError->setText(tr("No valid Participant selected!"));
return false;;
}
if(m_ui->leParticipant->text().isEmpty())
{
m_ui->lblError->setText(tr("Equipment Number is not valid!"));
return false;;
}
int equipNr = m_ui->leParticipant->text().toInt();
if (equipNr <= 0)
return true;
std::vector<ParticipantManagement::ParticipantData> data = m_model->participantData(false);
for (const auto &part : data)
{
if (!part.equipmentNumber().is_set())
continue;
if (part.equipmentNumber().is_set() && part.equipmentNumber().get() == equipNr)
{
m_ui->lblError->setText(tr("Equipment Number already exists!"));
return false;;
}
}
return true;
}
} // namespace OcSituationClient
@@ -0,0 +1,73 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Fault Message Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-27
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <LtsSession/lts_session.h>
#include <OcSituationClient/logger.h>
#include <Plugins/OcSituationClient/osc_data_plugin_interface.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/TrainingAreaBaseOC/taboc_data_plugin_interface.h>
#include <ParticipantManagement/Gui/Common/participant_edit_model.h>
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
namespace Ui
{
class EquipPlayer;
}
namespace OcSituationClient
{
class EquipPlayer : public LtsWidgets::LtsDialog
, private OcSituationClient::Interface::Ftc::SendEquipmentRegistrationReplyHandler
, private ParticipantManagement::Interface::Ftc::RegisterParticipantReplyHandler
{
Q_OBJECT
public:
explicit EquipPlayer(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~EquipPlayer();
bool init(const std::shared_ptr<Interface::Ftc> &ftc);
void onSendEquipmentRegistrationReply(const Core::FunctionReplyObject &replyObject) override { m_requestHelper->requestReply(replyObject); }
void onRegisterParticipantReply(const ParticipantManagement::RegisterReply &replyObject) override { m_requestHelper->requestReply(replyObject); }
private Q_SLOTS:
void onSlotSelectionChanged();
private:
void retranslate() override;
bool apply() override;
bool checkEqNr();
private:
LtsSession::LtsSession *m_session;
LtsUtils::RequestHelper *m_requestHelper;
int m_selectedParticipantId;
int m_maxChars;
int m_maxPartChars;
bool m_isValid;
ParticipantManagement::ParticipantEditModel *m_model;
LtsWidgets::LtsColumnFilterProxyModel *m_proxyModel;
std::shared_ptr<OcSituationClient::Interface::Ftc> m_ftc;
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmCbxGui;
Ui::EquipPlayer *m_ui;
LOGGER_T m_logger;
};
} // namespace OcSituationClient
@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EquipPlayer</class>
<widget class="QWidget" name="EquipPlayer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>726</width>
<height>442</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">MessagingView</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Party:</string>
</property>
</widget>
</item>
<item>
<widget class="LtsWidgets::LtsComboBox" name="cbParty"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="LtsDataView::LtsDataView" name="dvParticipants" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="showColumnCount" stdset="0">
<bool>false</bool>
</property>
<property name="toolButtonsVisible" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="lblMinEq">
<property name="text">
<string notr="true">&lt;COUNT&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string notr="true">/</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblMaxEq">
<property name="text">
<string notr="true">&lt;MAX&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblParticpant">
<property name="text">
<string>Equipment Number:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="leParticipant">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Participant</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lblError">
<property name="text">
<string notr="true"/>
</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>
<tabstop>leParticipant</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,216 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Fault Message Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-27
*/
#include "osc_fault_message.h"
#include "ui_osc_fault_message.h"
#include <AdvancedSymbology/asb_data_plugin_interface.h>
#include <PluginInterfaces/gui_plugin_interface.h>
namespace OcSituationClient
{
FaultMessage::FaultMessage(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
, m_session(session)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_selectedEqNr(-1)
, m_maxChars(255)
, m_maxPartChars(35)
, m_ownEquipmentId(0)
, m_model(nullptr)
, m_ftc(nullptr)
, m_tabocDtc(nullptr)
, m_ppmCbxGui(nullptr)
, m_ui(new Ui::FaultMessage)
, m_logger(getLogger("FaultMessageDialog"))
{
m_ui->setupUi(this);
m_ui->lblCountMax->setText(QString::number(m_maxChars));
m_ui->lblCount->setText(QString::number(0));
m_ui->lblDevCountMax->setText(QString::number(m_maxPartChars));
m_ui->lblDevCount->setText(QString::number(0));
connect(m_ui->teComment, &QPlainTextEdit::textChanged, this, &FaultMessage::onTextChanged);
connect(m_ui->leDevice, &QLineEdit::textChanged, this, &FaultMessage::onDevTextChanged);
setOnlineHelpFilename(QStringLiteral("OC-Fault_Message"));
}
FaultMessage::~FaultMessage()
{
delete m_ui;
}
bool FaultMessage::init(const std::shared_ptr<Interface::Ftc> &ftc)
{
if (!ftc)
return false;
m_ftc = ftc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> dtcPpm;
if (!m_session->getDtc<ParticipantManagement::DataInterface>(dtcPpm))
return false;
if (!m_session->getDtc<TrainingAreaBaseOC::DataInterface>(m_tabocDtc))
return false;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmCbxGui))
return false;
#ifdef TABLET_MODE
//css didn"t worked
m_ui->dvParticipants->setIconSize(QSize(50,50));
#endif
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> asb;
m_session->getForeignDataInterface<AdvancedSymbology::DataInterface>(asb);
m_model = new ParticipantManagement::ParticipantEditModel(this, dtcPpm, asb);
// only needed to set recursiveFilteringEnabled
m_proxyModel = new ParticipantManagement::ParticipantTreeFilterProxyModel(this);
m_proxyModel->setSourceModel(m_model);
m_proxyModel->setRecursiveFilteringEnabled(true);
m_ui->dvParticipants->setModel(m_proxyModel);
m_ppmCbxGui->fillPartyComboBox(m_ui->cbParty);
connect(m_ui->dvParticipants, &LtsDataView::LtsDataView::signalSelectionChanged,
this, &FaultMessage::onSlotSelectionChanged);
connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::specificsEquipmentChanged,
this, &FaultMessage::onSpecificsEquipmentChanged);
m_tabocDtc->specificsEquipments([this](const TrainingAreaBaseOC::SpecificsEquipment & data) { onSpecificsEquipmentChanged(data, DataModification::eAdded); });
connect(m_ui->cbParty, &LtsWidgets::LtsComboBox::currentTextChanged, this, [this]
{
m_model->onReinitModel(m_ui->cbParty->currentData().toInt());
m_ui->dvParticipants->expandAll();
});
m_model->onReinitModel(m_ui->cbParty->currentData().toInt());
m_ui->dvParticipants->expandAll();
m_ui->dvParticipants->setSortIndicator(0, Qt::AscendingOrder);
m_ui->leParticipant->setValidator( new QIntValidator(1, 10000, this) );
return true;
}
void FaultMessage::onSlotSelectionChanged()
{
m_selectedEqNr = 0;
const auto selIndexes = m_ui->dvParticipants->selectedRows();
if (!selIndexes.isEmpty())
{
ParticipantManagement::ParticipantData part = m_model->getParticipantData(selIndexes.first());
if (part.equipmentNumber().is_set())
m_selectedEqNr = part.equipmentNumber().get();
else
m_selectedEqNr = -1;
}
slotChangesMade();
if (m_selectedEqNr > 0)
m_ui->leParticipant->setText(QString::number(m_selectedEqNr));
}
void FaultMessage::onTextChanged()
{
QString plainText(m_ui->teComment->toPlainText());
int currentUsedChars = plainText.toUtf8().size();
bool bNeedSetNew = false;
while (currentUsedChars > m_maxChars)
{
plainText.chop(1);
currentUsedChars = plainText.toUtf8().size();
bNeedSetNew = true; // do not set text directly, results in recursion
}
// if text longer than allowed
if (bNeedSetNew)
{
m_ui->teComment->setPlainText(plainText);
m_ui->teComment->moveCursor(QTextCursor::End);
}
m_ui->lblCount->setText(QString::number(currentUsedChars));
}
void FaultMessage::onDevTextChanged()
{
timText(m_ui->leDevice, m_ui->lblDevCount);
}
void FaultMessage::timText(QLineEdit *le, QLabel *lbl)
{
QString plainText(le->text());
int currentUsedChars = plainText.toUtf8().size();
bool bNeedSetNew = false;
while (currentUsedChars > m_maxPartChars)
{
plainText.chop(1);
currentUsedChars = plainText.toUtf8().size();
bNeedSetNew = true; // do not set text directly, results in recursion
}
// if text longer than allowed
if (bNeedSetNew)
{
le->setText(plainText);
}
lbl->setText(QString::number(currentUsedChars));
}
void FaultMessage::retranslate()
{
translate(m_ui, tr("Fault Message") );
m_uiRequirements->clear();
m_uiRequirements->addRequirement({m_ui->lblDevice, [this]() { return !m_ui->leDevice->text().isEmpty(); },
tr("Name the faulty devices.")});
m_uiRequirements->addRequirement({m_ui->lblComment, [this]()
{
return (!m_ui->teComment->toPlainText().isEmpty() &&
m_ui->teComment->toPlainText().count() <= m_maxChars);
},
tr("Add a text comment.")});
}
bool FaultMessage::apply()
{
if (m_ui->leParticipant->text().toInt() <= 0)
return false;
SendEquipmentErrorRegistrationRequest req;
req.device(m_ui->leDevice->text().toStdString());
req.faultEquipmentNumber(m_ui->leParticipant->text().toStdString());
req.text(m_ui->teComment->toPlainText().toStdString());
req.ocEquipmentNumber(m_ownEquipmentId);
return m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->sendEquipmentErrorRegistrationRequest(req, this);
});
}
void FaultMessage::onSpecificsEquipmentChanged(const TrainingAreaBaseOC::SpecificsEquipment &data, const DataModification &modType)
{
if (DataModification::eRemoved == modType)
return;
m_ownEquipmentId = data.equipmentNumber();
if (m_ownEquipmentId <= 0)
WARNING_LOG(m_logger) << "EquipmentNumber " << data.equipmentNumber() << " is not present ";
}
} // namespace OcSituationClient
@@ -0,0 +1,71 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Fault Message Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-27
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <LtsSession/lts_session.h>
#include <OcSituationClient/logger.h>
#include <Plugins/OcSituationClient/osc_data_plugin_interface.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/TrainingAreaBaseOC/taboc_data_plugin_interface.h>
#include <ParticipantManagement/Gui/Common/participant_edit_model.h>
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
namespace Ui
{
class FaultMessage;
}
namespace OcSituationClient
{
class FaultMessage : public LtsWidgets::LtsDialog
, private OcSituationClient::Interface::Ftc::SendEquipmentErrorRegistrationReplyHandler
{
Q_OBJECT
public:
explicit FaultMessage(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~FaultMessage();
bool init(const std::shared_ptr<Interface::Ftc> &ftc);
void onSendEquipmentErrorRegistrationReply(const Core::FunctionReplyObject &replyObject) override { m_requestHelper->requestReply(replyObject); }
private Q_SLOTS:
void onSlotSelectionChanged();
void onTextChanged();
void onDevTextChanged();
void onSpecificsEquipmentChanged(const TrainingAreaBaseOC::SpecificsEquipment &data, const DataModification &modType);
private:
void retranslate() override;
bool apply() override;
void timText(QLineEdit *le, QLabel *lbl);
private:
LtsSession::LtsSession *m_session;
LtsUtils::RequestHelper *m_requestHelper;
int m_selectedEqNr;
int m_maxChars;
int m_maxPartChars;
int m_ownEquipmentId;
ParticipantManagement::ParticipantEditModel *m_model;
LtsWidgets::LtsColumnFilterProxyModel *m_proxyModel;
std::shared_ptr<OcSituationClient::Interface::Ftc> m_ftc;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc;
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmCbxGui;
Ui::FaultMessage *m_ui;
LOGGER_T m_logger;
};
} // namespace OcSituationClient
@@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FaultMessage</class>
<widget class="QWidget" name="FaultMessage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>388</width>
<height>757</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">MessagingView</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Party:</string>
</property>
</widget>
</item>
<item>
<widget class="LtsWidgets::LtsComboBox" name="cbParty"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="LtsDataView::LtsDataView" name="dvParticipants">
<property name="showColumnCount" stdset="0">
<bool>false</bool>
</property>
<property name="toolButtonsVisible">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="lblDevice">
<property name="text">
<string>Device:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblParticpant">
<property name="text">
<string>Participant:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="leDevice">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Device</string>
</property>
</widget>
</item>
<item row="1" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="lblDevCount">
<property name="text">
<string notr="true">&lt;COUNT&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string notr="true">/</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblDevCountMax">
<property name="text">
<string notr="true">&lt;MAX&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="leParticipant">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Participant</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lblComment">
<property name="text">
<string>Comment:</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="teComment">
<property name="toolTip">
<string>Comment</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Characters:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblCount">
<property name="text">
<string notr="true">&lt;COUNT&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string notr="true">/</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblCountMax">
<property name="text">
<string notr="true">&lt;MAX&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>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>
<tabstop>leParticipant</tabstop>
<tabstop>leDevice</tabstop>
<tabstop>teComment</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,462 @@
/**
* @RDE_HEADER@
* Gui Plugin for Demand Situation
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-27
*/
#include "osc_terminal_gui_plugin.h"
#include "osc_fault_message.h"
#include "osc_equip_player.h"
#include "osc_demand_situation_filter.h"
#include "osc_edit_folder_content.h"
#include <OcSituationClient/logger.h>
#include <ngltools/ngltools_dtg.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <LtsUtilsSettings/settings.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
#include <Map/map.h> // Interface
#include <QTimer>
#include <LtsWidgets/lts_base_layout_widget.h>
#include <QPainter>
#include <QImage>
#include <QRect>
#include <QRadialGradient>
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("OcTerminal.InterfaceImpl"))
, m_timer(new QTimer(this))
, m_requestHelper( new LtsUtils::RequestHelper(this))
, m_shortcutDemandSituation(nullptr)
, m_mapTimeLabelHideTimer(new QTimer(this))
, m_demandSituation(nullptr)
{
m_timer->setInterval(3*60*1000); //3 minutes
connect(m_timer, &QTimer::timeout, this, &InterfaceImpl::onNoDataTimerTick);
m_mapTimeLabelHideTimer->setInterval(1000);
m_mapTimeLabelHideTimer->setSingleShot(true);
connect(m_mapTimeLabelHideTimer, &QTimer::timeout, this, &InterfaceImpl::onShortcutDemandSituationIconChanged);
}
InterfaceImpl::~InterfaceImpl()
{}
void InterfaceImpl::onSendDemandSituationReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
}
void InterfaceImpl::stopSituationDemand()
{
const int range = 0;
const int participant = 0;
const Core::GeoPosition2D pos(0,0);
std::vector<int> partyIds{};
std::vector<int> typesClass{};
SendDemandSituationRequest req(participant,
range,
dds::core::optional<Core::GeoPosition2D>(),
false,
partyIds,
typesClass);
m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->sendDemandSituationRequest(req, this);
});
setShortcutDemandSituationIconData(true);
}
bool InterfaceImpl::fetchInterfaces()
{
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> ppmCbxGui;
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_dtcPpm))
return false;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(ppmCbxGui))
return false;
if (!m_session->getDtc<TrainingAreaBaseOC::DataInterface>(m_dtcTab))
return false;
if (!m_session->getFtc<OcSituationClient::DataInterface>(m_ftc))
return false;
if (!m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc))
return false;
return true;
}
void InterfaceImpl::clearInterfaces()
{
m_ftc = nullptr;
}
QString InterfaceImpl::menuGroup() const
{
return tr("Terminal");
}
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
QVector<LtsWidgets::PluginData> ret;
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
if(m_shortcutDemandSituation == nullptr)
{
m_shortcutDemandSituation = m_session->createNotification(QStringLiteral("oscShortcutDemandSituation"));
m_shortcutDemandSituation->setIcon(QIcon(QStringLiteral("icon:demand_situation.svg")));
m_shortcutDemandSituation->setToolTip(tr("Demand Situation not started"));
m_shortcutDemandSituation->setAction([this]()
{
m_session->addWidget(onShowDemandSituation(nullptr), menuGroup(), QStringLiteral("oscDemandSituation"), LtsWidgets::LayoutArea::eDialogTab);
});
connect(m_dtcTab.get(), &TrainingAreaBaseOC::Interface::Dtc::participantsOverloadChanged, this, &InterfaceImpl::onParticipantsOverloadChanged);
connect(m_dtcTab.get(), &TrainingAreaBaseOC::Interface::Dtc::centralAesOverloadChanged, this, &InterfaceImpl::onCentralAesOverloadChanged);
connect(m_session->baseLayout(), &LtsWidgets::LtsBaseLayoutWidget::signalLogout,
this, [this]{
stopSituationDemand();
});
}
// Action 'Demand Situation'
plData.menuText = tr("Demand Situation");
plData.identifier = QStringLiteral("oscDemandSituation");
plData.menuIcon = QIcon(QLatin1String("icon:demand_situation.svg"));
plData.operatorRight = 0;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowDemandSituation(parent);
};
ret.append(plData);
{
// Action 'Demand Situation Filter'
LtsWidgets::PluginData plData2;
plData2.menuGroup = menuGroup();
plData2.menuText = tr("Demand Situation Filter");
plData2.identifier = QStringLiteral("oscDemandSituationFilter");
plData2.menuIcon = QIcon(QLatin1String("icon:demand_situation_filter.svg"));
plData2.operatorRight = 0;
plData2.createWidgetFunc = [this](QWidget * parent)
{
return onShowDemandSituationFilter(parent);
};
ret.append(plData2);
}
if (strcmp(PROJECTBUILD, "guez") != 0) //not guez add fault message
{
// Action 'Equipment Fault'
plData.menuText = tr("Fault Message");
plData.identifier = QStringLiteral("oscFaultMessage");
plData.menuIcon = QIcon(QLatin1String("icon:player_equipment_fault.svg"));
plData.operatorRight = 0;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowFaultMessage(parent);
};
ret.append(plData);
}else //is guez add folder content
{
// Action 'Edit folder content'
plData.menuText = tr(" Folder Content");
plData.identifier = QStringLiteral("oscEditFolderContent");
plData.menuIcon = QIcon(QLatin1String("icon:organize_library.svg"));
plData.operatorRight = 0;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowEditFolderContentDialog(parent);
};
ret.append(plData);
}
if (strcmp(PROJECTBUILD, "guez") != 0)
{
// Action 'Equipment Fault'
plData.menuText = tr("Equip Player");
plData.identifier = QStringLiteral("oscEquipPlayer");
plData.menuIcon = QIcon(QLatin1String("icon:force_player_configuration.svg"));
plData.operatorRight = 0;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowEquipPlayer(parent);
};
ret.append(plData);
}
//now send request for old
QTimer::singleShot(2000, this, &InterfaceImpl::onTimerTick);
m_dtcTab->enableParticipantsOverload();
return ret;
}
void InterfaceImpl::onTimerTick()
{
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged,
this, &InterfaceImpl::onParticipantPosition, Qt::UniqueConnection);
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged,
this, &InterfaceImpl::onParticipantDynamic, Qt::UniqueConnection);
LtsUtils::OperatorSettings *settings = LtsUtils::OperatorSettings::getInstance();
QString ocString = QStringLiteral("ObserverControllerDemand");
const int range = settings->value(ocString, QStringLiteral("Range"), 0).toInt();
// if (range <= 0)
// return;
/// stop sending demand situation on initialization
const int participant = 0;
const Core::GeoPosition2D pos(0,0);
std::vector<int> partyIds{};
std::vector<int> typesClass{};
const QStringList partyList = settings->value(ocString, QStringLiteral("Partys"),-1).toStringList();
const QStringList typeClassList = settings->value(ocString, QStringLiteral("TypeClass"),-1).toStringList();
partyIds.reserve(partyList.size());
for (const auto &party: partyList)
{
partyIds.push_back(party.toInt());
}
typesClass.reserve(typeClassList.size());
for (const auto &typeCl: typeClassList)
{
typesClass.push_back(typeCl.toInt());
}
SendDemandSituationRequest req(participant,
range,
dds::core::optional<Core::GeoPosition2D>(),
settings->value(ocString, QStringLiteral("FilterActive"),false).toBool(),
partyIds,
typesClass);
if (pos.lat() > 0)
{
req.position().set(pos);
}
m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->sendDemandSituationRequest(req, this);
});
setShortcutDemandSituationIconData(true);
}
void InterfaceImpl::onNoDataTimerTick()
{
//We stop the timer until the first overload message arrives again
m_timer->stop();
setShortcutDemandSituationIconData(true);
}
void InterfaceImpl::onParticipantDynamic(const ParticipantManagement::DynamicParticipantData &data)
{
if (m_dtcPpm->participant(data.participantId()).equipmentNumber() == m_dtcTab->specificsEquipment(1).equipmentNumber())
return;
onParticipantData();
}
void InterfaceImpl::onParticipantPosition(const ParticipantManagement::ParticipantPosition &data)
{
if (m_dtcPpm->participant(data.participantId()).equipmentNumber() == m_dtcTab->specificsEquipment(1).equipmentNumber())
return;
onParticipantData();
}
void InterfaceImpl::onCentralAesOverloadChanged(const TrainingAreaBaseOC::CentralAesOverload &data, DataModification modType)
{
Q_UNUSED(modType)
m_hasCentralAesOverload = data.hasOverload();
setShortcutDemandSituationIconData();
m_timer->start();
}
void InterfaceImpl::onParticipantsOverloadChanged(const TrainingAreaBaseOC::ParticipantsOverload &data, DataModification modType)
{
Q_UNUSED(modType)
m_hasParticipantOverload = data.hasOverload();
setShortcutDemandSituationIconData();
m_timer->start();
}
void InterfaceImpl::onShortcutDemandSituationIconChanged()
{
if (!m_sitMapGuiIfc)
{
m_mapTimeLabelHideTimer->start();
return;
}
m_sitMapGuiIfc->map()->showTimeString(m_demandSituationActive);
m_sitMapGuiIfc->map()->setTimeString(DTG::toStringMSec(m_session->partitionTime()));
}
void InterfaceImpl::setShortcutDemandSituationIconData(bool hasToBeDisabled)
{
if (m_shortcutDemandSituation == nullptr)
return;
m_demandSituationActive = true;
if (hasToBeDisabled)
{
m_shortcutDemandSituation->setIcon(QIcon(QStringLiteral("icon:demand_situation_disabled.svg")));
m_shortcutDemandSituation->setToolTip(tr("Demand Situation not started"));
m_demandSituationActive = false;
}
else
{
m_shortcutDemandSituation->setIcon(getOverloadIcon());
m_shortcutDemandSituation->setToolTip(getOverLoadTooltip());
}
if (m_mapTimeLabelHideTimer != nullptr)
m_mapTimeLabelHideTimer->start();
}
QString InterfaceImpl::getOverLoadTooltip() const
{
if (m_hasParticipantOverload && m_hasCentralAesOverload)
{
return tr("Demand Situation: Participant and Central AES count out of range");
}
else if (m_hasParticipantOverload)
{
return tr("Demand Situation: Participant count out of range");
}
else if (m_hasCentralAesOverload)
{
return tr("Demand Situation: Central AES count out of range");
}
else
{
return tr("Demand Situation");
}
}
QIcon InterfaceImpl::getOverloadIcon() const
{
qint32 size = 100;
QImage image(size, size, QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
painter.setPen(Qt::transparent);
QColor centralAesOverloadColor = m_hasCentralAesOverload ? Qt::red : Qt::green;
QColor participantOverloadColor = m_hasParticipantOverload ? Qt::red : Qt::green;
QRect arcRect(0, 0, size , size);
QRadialGradient arcGradient(arcRect.center(), size * 0.6);
arcGradient.setColorAt(1.0, Qt::transparent);
// participant overload
arcGradient.setColorAt(0.0, participantOverloadColor);
painter.setBrush(QBrush(arcGradient));
painter.drawPie(arcRect, 90 * 16, 180 * 16);
// central aes overload
arcGradient.setColorAt(0.0, centralAesOverloadColor);
painter.setBrush(QBrush(arcGradient));
painter.drawPie(arcRect, 270 * 16, 180 * 16);
QFont font = painter.font() ;
font.setPointSize(30);
font.setBold(true);
painter.setFont(font);
painter.setBrush(QBrush(Qt::black, Qt::NoBrush));
painter.setPen(Qt::black);
painter.drawText(55, 65, tr("W"));
painter.setBrush(QBrush(Qt::black, Qt::NoBrush));
painter.setPen(Qt::black);
painter.drawText(17, 65, tr("T"));
painter.end();
return QIcon(QPixmap::fromImage(image));
}
void InterfaceImpl::onParticipantData()
{
if (!m_sitMapGuiIfc)
return;
m_sitMapGuiIfc->map()->showTimeString(m_demandSituationActive);
m_sitMapGuiIfc->map()->setTimeString(DTG::toStringMSec(m_session->partitionTime()));
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowDemandSituation(QWidget *parent)
{
m_demandSituation = new DemandSituation(m_session, parent);
connect(m_demandSituation, &DemandSituation::destroyed, this,[this]()
{
m_demandSituation = nullptr;
});
connect(m_demandSituation, &DemandSituation::demandSituationStopped, this, [this]()
{
stopSituationDemand();
}, Qt::UniqueConnection);
return LtsWidgets::initDialog(m_demandSituation,
m_ftc);
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowDemandSituationFilter(QWidget *parent)
{
return LtsWidgets::initDialog(new DemandSituationFilter(m_session, parent),
m_ftc);
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowFaultMessage(QWidget *parent)
{
return LtsWidgets::initDialog(new FaultMessage(m_session, parent),
m_ftc);
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowEquipPlayer(QWidget *parent)
{
return LtsWidgets::initDialog(new EquipPlayer(m_session, parent),
m_ftc);
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowEditFolderContentDialog(QWidget *parent)
{
return LtsWidgets::initDialog(new FolderContentEditDialog(parent),m_session);
}
} // namespace OcSituationClient
@@ -0,0 +1,108 @@
/**
* @RDE_HEADER@
* Gui Plugin for Demand Situation
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-27
*/
#pragma once
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/TrainingAreaBaseOC/taboc_data_plugin_interface.h>
#include <Plugins/OcSituationClient/osc_terminal_gui_plugin_interface.h>
#include <Plugins/OcSituationClient/osc_data_plugin_interface.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <LtsNotification/lts_notification.h>
#include "osc_demand_situation.h"
class QTimer;
namespace OcSituationClient
{
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "gui:3:osc.terminal")
Q_INTERFACES(GuiPluginBase::Plugin)
Q_OBJECT
public:
GuiPlugin() = default;
~GuiPlugin() = default;
QString pluginName() override { return QStringLiteral("ObserverController.Terminal"); }
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return (partition == IDL::PartitionType::Exercise ||
partition == IDL::PartitionType::Replay);
}
};
class InterfaceImpl final : public QObject, public ForeignTerminalGuiInterface, public GuiPluginBase::Interface,
private OcSituationClient::Interface::Ftc::SendDemandSituationReplyHandler
{
Q_OBJECT
public:
explicit InterfaceImpl(LtsSession::LtsSession *session);
~InterfaceImpl();
void onSendDemandSituationReply(const Core::FunctionReplyObject &replyObject) override;
void stopSituationDemand();
bool fetchInterfaces() override;
void clearInterfaces() override;
QString menuGroup() const override;
QVector<LtsWidgets::PluginData> getActions() override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return partition == IDL::PartitionType::Global || partition == IDL::PartitionType::Exercise;
}
private slots:
void onTimerTick();
void onNoDataTimerTick();
void onParticipantData();
void onParticipantDynamic(const ParticipantManagement::DynamicParticipantData &data);
void onParticipantPosition(const ParticipantManagement::ParticipantPosition &data);
void onCentralAesOverloadChanged(const TrainingAreaBaseOC::CentralAesOverload &data, DataModification modType);
void onParticipantsOverloadChanged(const TrainingAreaBaseOC::ParticipantsOverload &data, DataModification modType);
void onShortcutDemandSituationIconChanged();
private:
void setShortcutDemandSituationIconData(bool hasToBeDisabled = false);
QString getOverLoadTooltip() const;
QIcon getOverloadIcon() const;
private:
QTimer *m_timer;
LtsUtils::RequestHelper *m_requestHelper;
LtsWidgets::LtsDialog *onShowDemandSituation(QWidget *parent);
LtsWidgets::LtsDialog *onShowDemandSituationFilter(QWidget *parent);
LtsWidgets::LtsDialog *onShowFaultMessage(QWidget *parent);
LtsWidgets::LtsDialog *onShowEquipPlayer(QWidget *parent);
LtsWidgets::LtsDialog *onShowEditFolderContentDialog(QWidget *parent);
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_dtcPpm;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_dtcTab;
std::shared_ptr<OcSituationClient::Interface::Ftc> m_ftc;
LtsNotification::LtsNotification *m_shortcutDemandSituation;
QTimer *m_mapTimeLabelHideTimer;
bool m_demandSituationActive{false};
bool m_hasParticipantOverload{false};
bool m_hasCentralAesOverload{false};
DemandSituation *m_demandSituation;
};
} // namespace OcSituationClient
@@ -0,0 +1,39 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Patric Karwat, SLSE, 2018-01-17
#
SET(osc_participant_info_gui_SRCS
osc_participant_info_gui_plugin.cpp
osc_participant_info_gui_plugin.h
osc_participant_info.cpp
osc_participant_info.h
)
NGL_WRAP_UI(osc_participant_info_gui_SRCS
osc_participant_info.ui
)
NGL_ADD_LIBRARY(WS OscParticipantInfoGuiPlugin MODULE ${osc_participant_info_gui_SRCS})
NGL_TARGET_LINK_LIBRARIES(OscParticipantInfoGuiPlugin
NGLLogger
svcOscClient
LtsPrinting
LtsSession
LtsSessionData
LtsCoordTrans
LtsWidgets
LtsUtilsGuiDds
OscParticipantInfoGuiPluginInterface
PpmDataPluginInterface
PdmDataPluginInterface
AsbDataPluginInterface
IsmDataPluginInterface
SituationMapGuiPluginInterface
Qt5::Widgets
Qt5::Multimedia
)
NGL_INSTALL_TARGET(OscParticipantInfoGuiPlugin)
@@ -0,0 +1,635 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - OcParticipantInfo Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-03-17
*/
#include "osc_participant_info.h"
#include "ui_osc_participant_info.h"
#include <ProjectDataManagement/pdm_to_string.h>
#include <ParticipantManagement/ppm_translation.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <LtsSession/lts_session_data.h>
#include <LtsUtilsCore/outdated_position.h>
#include <PluginInterfaces/gui_plugin_interface.h>
namespace OcSituationClient
{
OcParticipantInfo::OcParticipantInfo(int participantId, LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
, m_roomId(0)
, m_session(session)
, m_ui(new Ui::OcParticipantInfo)
, m_logger(getLogger("OcOcParticipantInfo"))
{
m_ui->setupUi(this);
m_participant.id(participantId);
m_participant.partyId(-1);
m_symbolWatcher = new AdvancedSymbology::SymbolResultWatcherLabel(m_ui->lblIcon);
//hide first
setBuildingPosVisible(false);
setSpecialSensorVisible(false);
setChargeVisible(false);
setKindVisible(false);
m_ui->pbHistory->setVisible(false);
//config movement track button
m_ui->pbMovementTrack->setCheckable(true);
//connects
connect(m_ui->pbFindOnMap, &QToolButton::clicked, this, &OcParticipantInfo::onFindOnMap);
connect(m_ui->pbMovementTrack, &QToolButton::clicked, this, &OcParticipantInfo::onMovementTrack);
}
OcParticipantInfo::~OcParticipantInfo()
{
delete m_ui;
}
bool OcParticipantInfo::init()
{
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
return false;
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(m_pdmDtc))
return false;
if (!m_session->getForeignDataInterface<AdvancedSymbology::DataInterface>(m_asbiIfc))
return false;
//optional
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc);
m_session->getDtc<InfrastructureManagement::DataInterface>(m_ismDtc);
return setUiValues();
}
void OcParticipantInfo::retranslate()
{
translate(m_ui, tr("Participant Info") );
}
void OcParticipantInfo::setRed(QWidget *w, bool bRed)
{
if (!w)
return;
if (bRed)
{
QPalette pal = QApplication::palette(w);
pal.setColor(QPalette::Window, Qt::red);
w->setPalette(pal);
w->setAutoFillBackground(true);
}
else
{
// reset to default palette
w->setPalette(QApplication::palette(w));
w->setAutoFillBackground(false);
}
}
void OcParticipantInfo::updateIcon(const ParticipantManagement::Participant &participant)
{
m_symbolWatcher->setSymbolResult(m_asbiIfc->findImage(participant));
}
void OcParticipantInfo::updateIcon(const QColor &color, const QString &sidc)
{
AdvancedSymbology::SymbolDataToRender symDataToRender(sidc);
symDataToRender.injury = AdvancedSymbology::Injury::NoInjury;
symDataToRender.injuryColor = QColor();
symDataToRender.fillColor = color;
symDataToRender.fillColorReplace = true;
m_symbolWatcher->setSymbolResult(m_asbiIfc->findImage(symDataToRender));
}
bool OcParticipantInfo::setUiValues()
{
if (!m_ppmDtc || m_participant.id() < 0)
return false;
//hide findOnMap if no interface available
m_ui->pbFindOnMap->setVisible(m_sitMapGuiIfc != nullptr);
m_ui->tbNbc->setVisible(false); //show only if visible
// m_participant.id() was given within ctor
const ParticipantManagement::Participant participantData = m_ppmDtc->participant(m_participant.id());
m_typeClass = m_ppmDtc->type(participantData.typeId()).typeClass();
bool bUpdateDynamicParticipantData = true;
switch (m_typeClass.underlying())
{
case ParticipantManagement::TypeClass::Human:
case ParticipantManagement::TypeClass::GroundVehicle:
case ParticipantManagement::TypeClass::VehicleWithGear:
case ParticipantManagement::TypeClass::WeaponSystem:
case ParticipantManagement::TypeClass::Aircraft:
case ParticipantManagement::TypeClass::SupportEntity:
{
onParticipantChanged(participantData);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
this, &OcParticipantInfo::onParticipantChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged,
this, &OcParticipantInfo::onPositionChanged);
onPositionChanged(m_ppmDtc->participantPosition(participantData.id()));
if (m_sitMapGuiIfc)
{
const int32_t participantId = participantData.id();
m_ui->pbFindOnMap->setVisible(true);
m_ui->pbMovementTrack->setVisible(true);
m_ui->pbMovementTrack->setChecked(m_sitMapGuiIfc->isMovementTrackEnabled(participantId));
// set MovementTrackCallback:
std::function<void(const QVector<int32_t> &activeSimIds)> onMovementTrackChangedFunc = [this, participantId](const QVector<int32_t> &activeSimIds)
{
bool checkedNew = activeSimIds.contains(participantId);
if (m_ui->pbMovementTrack->isChecked() != checkedNew)
{
m_ui->pbMovementTrack->setChecked(checkedNew);
}
};
if (!m_sitMapGuiIfc->setMovementTrackCallback(this, onMovementTrackChangedFunc))
ERROR_LOG(m_logger) << LOGFUNCTION << " setMovementTrackCallback failed";
}
break;
}
case ParticipantManagement::TypeClass::Unit:
case ParticipantManagement::TypeClass::SupportUnit:
case ParticipantManagement::TypeClass::Vessel:
case ParticipantManagement::TypeClass::Unknown:
return false;
}
if (bUpdateDynamicParticipantData)
{
const auto dpd = m_ppmDtc->dynamicParticipantData(participantData.id());
if (dpd.participantId() || participantData.id())
{
onDynamicParticipantDataChanged(dpd);
}
else
{
const ParticipantManagement::Party party = m_ppmDtc->party(m_participant.partyId());
const QColor color = QColor::fromRgb(QRgb(party.color()));
updateIcon(color, QString::fromStdString(m_participant.symbol()));
}
}
//other connects
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::typeChanged,
this, &OcParticipantInfo::onTypeChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged,
this, &OcParticipantInfo::onDynamicParticipantDataChanged);
connect(m_session, &LtsSession::LtsSession::partitionTimeChanged,
this, &OcParticipantInfo::onPartitionTimeChanged);
return true;
}
void OcParticipantInfo::setChargeVisible(bool vis)
{
m_ui->twGear->setVisible(vis);
}
void OcParticipantInfo::setSpecialSensorVisible(bool vis)
{
m_ui->lblSpecialSensorState->setVisible(vis);
m_ui->lbSpecialSensorState->setVisible(vis);
}
void OcParticipantInfo::setBuildingPosVisible(bool vis)
{
m_ui->lblBuilding->setVisible(vis);
m_ui->lblRoom->setVisible(vis);
}
void OcParticipantInfo::setKindVisible(bool vis)
{
m_ui->lblKind->setVisible(vis);
m_ui->lbKind->setVisible(vis);
}
void OcParticipantInfo::onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &data)
{
if (data.participantId() != m_participant.id() && data.participantId() != 0)
return;
//Current State
if (data.stateHistory().size() > 0)
{
const ProjectDataManagement::VulnerabilityClass vc = m_typeClass == ParticipantManagement::TypeClass::Human ?
ProjectDataManagement::VulnerabilityClass_def::SoldierInjuries :
ProjectDataManagement::VulnerabilityClass_def::VehicleDamages;
const ParticipantManagement::StateInformation &lastState = m_ppmDtc->youngestStateInformation(data.stateHistory());
m_ui->lblStatus->setText(ProjectDataManagement::toString(lastState.vulnerabilityState(), vc));
// VBA
setKindVisible(lastState.vulnerabilityKindId() > 0);
m_ui->lblKind->setText(m_pdmDtc->trVulnerabilityKindName(lastState.vulnerabilityKindId(), vc));
}
else
{
m_ui->lblStatus->setText(QStringLiteral("-"));
m_ui->lblKind->setText(QStringLiteral("-"));
}
setRed(m_ui->lblEquipNr, data.manipulation().size());
// Note: This is not transmitted to O/C. If so, we need to add LEDs for Apache.
// So long: Hide, if it's an aircraft.
// Special Sensor State
if (!data.specialSensorDataState() || m_typeClass == ParticipantManagement::TypeClass_def::Aircraft)
{
m_ui->lblSpecialSensorState->hide();
m_ui->lbSpecialSensorState->hide();
}
else
{
showSpecialSensorData(data.specialSensorDataState());
m_ui->lbSpecialSensorState->show();
m_ui->lblSpecialSensorState->show();
}
//Gear
if (data.gear().size() == 0)
{
m_gearList.clear();
m_ui->twGear->clearContents();
m_ui->twGear->hide();
m_ui->pbGearRanges->hide();
}
else if (data.gear() != m_gearList)
{
m_gearList = data.gear();
std::vector<ParticipantManagement::GearInformation> tmpGearList = m_gearList;
m_ui->twGear->show();
m_ui->pbGearRanges->show();
m_ui->twGear->clearContents();
int row = 0;
int rowCount = tmpGearList.size();
m_ui->twGear->setRowCount(rowCount);
m_ui->twGear->setSortingEnabled(false);
constexpr int unknownTasId = 0x80000000;
for (const ParticipantManagement::GearInformation &gearInfo : m_gearList)
{
QTableWidgetItem *item = nullptr;
if (gearInfo.chargeTypeId() <= 0) //chargTypeId 0 is near miss code
{
rowCount--;
continue;
}
const int gearTypeId = gearInfo.gearTypeId();
if ((gearTypeId & unknownTasId) == unknownTasId)
item = new QTableWidgetItem(tr("Unknown gear id %1").arg(gearTypeId & ~unknownTasId));
else if (gearTypeId == 0)
{
// Hack for old systems which neither send gearTasCode/gearType nor gearSerialNumber/gearId
// 1 = Wanne, 2 = Turm
switch (gearInfo.gearId())
{
case 1:
item = new QTableWidgetItem(tr("Tank", "Gear Type"));
break;
case 2:
item = new QTableWidgetItem(tr("Turret", "Gear Type"));
break;
default:
item = new QTableWidgetItem(tr("N/A", "Gear Type"));
break;
}
}
else
item = new QTableWidgetItem(m_pdmDtc->trGearTypeName(gearTypeId));
m_ui->twGear->setItem(row, 0, item);
if (gearInfo.chargeTypeId() != 0 && gearInfo.chargeTypeId() != -1) // hat Charge (and ignore only chargecounts)
{
int chargeTypeId = gearInfo.chargeTypeId();
if ((chargeTypeId & unknownTasId) == unknownTasId)
item = new QTableWidgetItem(tr("Unknown charge id %1").arg(chargeTypeId & ~unknownTasId));
else if (chargeTypeId == 0)
item = new QTableWidgetItem(tr("N/A", "Charge Type"));
else
{
item = new QTableWidgetItem(m_pdmDtc->trChargeTypeShortName(chargeTypeId, true));
item->setToolTip(m_pdmDtc->trChargeTypeName(chargeTypeId, true));
}
m_ui->twGear->setItem(row, 1, item);
//ressourceCount
//: Blank in this case refers to blank ammunition used for training
item = new QTableWidgetItem((gearInfo.remain() < 0) ? tr("N/A", "Blank Ammunition") : QString::number(gearInfo.remain()));
m_ui->twGear->setItem(row, 2, item);
}
row++;
}
m_ui->twGear->setRowCount(rowCount);
m_ui->twGear->setSortingEnabled(true);
} //end Gear
m_ui->tbNbc->setVisible(data.hasNbcProtectionConfigured() && data.hasNbcProtectionActive());
updateIcon(m_participant);
}
void OcParticipantInfo::showSpecialSensorData(int specialSensorData)
{
const int specialSensorDataState = specialSensorData & 0xFF;
QString strSpecialSensorData;
switch (specialSensorDataState)
{
case ParticipantManagement::SpecialSensorStatus_def::ChemicalDetectionFunction_NotOperational:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::ChemicalDetectionFunction_NotOperational);
break;
case ParticipantManagement::SpecialSensorStatus_def::ChemicalDetectionFunction_Detecting:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::ChemicalDetectionFunction_Detecting);
break;
case ParticipantManagement::SpecialSensorStatus_def::NBCDetectionAccessory_NotOperational:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::NBCDetectionAccessory_NotOperational);
break;
case ParticipantManagement::SpecialSensorStatus_def::NBCDetectionAccessory_Test:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::NBCDetectionAccessory_Test);
break;
case ParticipantManagement::SpecialSensorStatus_def::NBCDetectionAccessory_DetectingAir:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::NBCDetectionAccessory_DetectingAir);
break;
case ParticipantManagement::SpecialSensorStatus_def::AVLB_Mounted:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::AVLB_Mounted);
break;
case ParticipantManagement::SpecialSensorStatus_def::AVLB_Deployed:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::AVLB_Deployed);
break;
case ParticipantManagement::SpecialSensorStatus_def::AVLB_Mounting:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::AVLB_Mounting);
break;
case ParticipantManagement::SpecialSensorStatus_def::AVLB_Deploying:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::AVLB_Deploying);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineLayer_Operational:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineLayer_Operational);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineLayer_Laying:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineLayer_Laying);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineClearingFunction_March:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineClearingFunction_March);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineClearingFunction_ReadyToClear:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineClearingFunction_ReadyToClear);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineClearingFunction_Clearing:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineClearingFunction_Clearing);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_NotOperational:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_NotOperational);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_ParameterInput:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_ParameterInput);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_ReadyToDeploy:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_ReadyToDeploy);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_Deploying:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_Deploying);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_Resupply:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_Resupply);
break;
case ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_FinishDeploying:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::MineTrowingFunction_FinishDeploying);
break;
case ParticipantManagement::SpecialSensorStatus_def::ADLER_Operational:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::ADLER_Operational);
break;
case ParticipantManagement::SpecialSensorStatus_def::ADLER_ConditionallyOperational:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::ADLER_ConditionallyOperational);
break;
case ParticipantManagement::SpecialSensorStatus_def::ADLER_NotOperational:
strSpecialSensorData = toString(ParticipantManagement::SpecialSensorStatus_def::ADLER_NotOperational);
break;
default:
strSpecialSensorData = tr("Unknown (%1)").arg(specialSensorDataState);
break;
}
if ((specialSensorData & (1 << 8)) != 0)
strSpecialSensorData += QStringLiteral(" L");
if ((specialSensorData & (1 << 9)) != 0)
strSpecialSensorData += QStringLiteral(" R");
if ((specialSensorData & (1 << 10)) != 0)
strSpecialSensorData += QStringLiteral(" P");
if ((specialSensorData & (1 << 11)) != 0)
strSpecialSensorData += QStringLiteral(" F");
if (specialSensorDataState == 66) // CSF Spürbetrieb
{
const int type = (specialSensorData >> 12) & 0x0F;
strSpecialSensorData += QLatin1Char(' ');
switch (type)
{
case 1:
case 2:
strSpecialSensorData += tr("FIR");
break;
case 3:
strSpecialSensorData += tr("ZABC");
break;
case 4:
strSpecialSensorData += tr("CSF");
break;
case 5:
strSpecialSensorData += tr("PzBr");
break;
case 6:
strSpecialSensorData += tr("MV");
break;
case 7:
strSpecialSensorData += tr("MRF");
break;
case 8:
strSpecialSensorData += tr("WMV");
break;
case 0:
default:
break;
}
if (type == 4) // CSF
{
const int nbcType = (specialSensorData >> 16) & 0x03;
strSpecialSensorData += QLatin1Char(' ');
switch (nbcType)
{
case 0:
strSpecialSensorData += tr("No C-Agent");
break;
case 1:
strSpecialSensorData += tr("Sarin");
break;
case 2:
strSpecialSensorData += tr("VX");
break;
case 3:
strSpecialSensorData += tr("S-Lost");
break;
}
}
}
m_ui->lblSpecialSensorState->setText(strSpecialSensorData);
}
void OcParticipantInfo::onPositionChanged(const ParticipantManagement::ParticipantPosition &position)
{
if (position.participantId() != m_participant.id() && position.participantId() != 0)
return;
onUpdatePosition(position.participantId(), position.pos(), position.sampleTime());
if (m_ismDtc && m_roomId != position.roomId())
{
if (position.roomId() > 0)
{
const auto mse = m_ismDtc->mainStructureElement(position.buildingId());
QString roomName;
for (const auto &room : mse.elements())
{
if (room.id() == position.roomId())
{
roomName = QString::fromStdString(room.displayName());
break;
}
}
QString buildingName = m_ismDtc->getBuildingDisplayName(mse);
m_roomId = position.roomId();
m_ui->lblBuilding->setText(buildingName);
m_ui->lblRoom->setText(roomName);
}
setBuildingPosVisible(m_roomId > 0);
}
if (position.mountedOn().is_set())
{
const auto mountedOnParticipant = m_ppmDtc->participant(position.mountedOn().get());
if (mountedOnParticipant.equipmentNumber().is_set())
m_ui->pbMountedOn->setText(QString::number(mountedOnParticipant.equipmentNumber().get()));
else
m_ui->pbMountedOn->setText(QString::number(0));
m_ui->pbMountedOn->show();
}
else
m_ui->pbMountedOn->hide();
if (position.mountedParticipants().is_set())
{
m_ui->pbMountedParticipants->setText(QString::number(position.mountedParticipants().get().size()));
m_ui->pbMountedParticipants->show();
}
else
m_ui->pbMountedParticipants->hide();
}
void OcParticipantInfo::onUpdatePosition(int participantId, const Core::GeoPosition &position, qint64 sampleTime)
{
m_lastPositionMSec = sampleTime;
if ((position.lat() == 0 && position.lon() == 0) || participantId == 0 || std::isnan(position.lon()) || std::isnan(position.lat()))
{
m_ui->lblPosition->setText(tr("Invalid Position"));
}
else
{
QString mgrs = LtsCoordTrans::mgrsFromGeographic(position.lon(), position.lat());
if (!qFuzzyIsNull(position.z()))
mgrs += QStringLiteral(" | ") + QString::number(position.z(), 'f', 2);
m_ui->lblPosition->setText(mgrs);
}
}
void OcParticipantInfo::onParticipantChanged(const ParticipantManagement::Participant &participant)
{
if (participant.id() != m_participant.id())
return;
if (m_participant.typeId() != participant.typeId())
m_ui->lblType->setText(ParticipantManagement::trTypeName(m_ppmDtc->type(participant.typeId()).name()));
if (m_participant.partyId() != participant.partyId())
m_ui->lblParty->setText(ParticipantManagement::trPartyName(m_ppmDtc->party(participant.partyId()).name()));
m_ui->lblDesignator->setText(QString::fromStdString(participant.designator()));
m_ui->lblTactitcalIdentifier->setText(QString::fromStdString(participant.tacticalIdentifier()));
if (participant.equipmentNumber().is_set())
m_ui->lblEquipNr->setText(QString::number(participant.equipmentNumber().get()));
else if (participant.isSimulated())
m_ui->lblEquipNr->setText(tr("simulated"));
else
m_ui->lblEquipNr->setText(QLatin1String("-"));
#ifdef LTS_DEBUG
m_ui->lblEquipNr->setToolTip(QString::number(participant.id()));
#endif
m_participant = participant;
//hide Info if not exists
m_ui->lblInfoText->setText(QString::fromStdString(participant.info()));
m_ui->lblInfoText->setVisible(participant.info().size() > 0);
m_ui->lblInfo->setVisible(participant.info().size() > 0);
m_ui->lblInfo->setText(QString::number(participant.info().size()));
onDynamicParticipantDataChanged(m_ppmDtc->dynamicParticipantData(participant.id()));
}
void OcParticipantInfo::onTypeChanged(const ParticipantManagement::Type &type, DataModification modType)
{
Q_UNUSED(modType)
if (m_participant.typeId() != type.id())
return;
m_ui->lblType->setText(ParticipantManagement::trTypeName(type.name()));
}
void OcParticipantInfo::onPartitionTimeChanged(qint64 newPartitionTime)
{
setRed(m_ui->lblPosition, LtsUtils::isPositionTimeOutdated(newPartitionTime, m_lastPositionMSec)); //10minuten
}
void OcParticipantInfo::onFindOnMap()
{
if (m_sitMapGuiIfc)
m_sitMapGuiIfc->centerMapToParticipant(m_participant.id());
}
void OcParticipantInfo::onMovementTrack()
{
if (m_sitMapGuiIfc)
m_sitMapGuiIfc->enableMovementTrack(m_participant.id(), m_ui->pbMovementTrack->isChecked());
}
} // namespace OcSituationClient
@@ -0,0 +1,94 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Selfcheck Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <LtsSession/lts_session.h>
#include <OcSituationClient/logger.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
#include <Plugins/AdvancedSymbology/asb_data_plugin_interface.h>
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
#include <FilterManagement/flt_aes_plugin_interface.h>
#include <FilterManagement/flt_symbol_appearance_settings.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
namespace Ui
{
class OcParticipantInfo;
}
namespace OcSituationClient
{
class OcParticipantInfo : public LtsWidgets::LtsDialog
{
Q_OBJECT
public:
explicit OcParticipantInfo(int participantId, LtsSession::LtsSession *session, QWidget *parent = nullptr);
~OcParticipantInfo();
bool init();
private:
void retranslate() override;
static void setRed(QWidget *w, bool bRed);
void updateIcon(const ParticipantManagement::Participant& participant);
void updateIcon(const QColor &color, const QString &sidc);
bool setUiValues();
void setChargeVisible(bool vis);
void setSpecialSensorVisible(bool vis);
void setBuildingPosVisible(bool vis);
void setKindVisible(bool vis);
private Q_SLOTS:
void onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &data);
void onPositionChanged(const ParticipantManagement::ParticipantPosition &position);
void onUpdatePosition(int participantId, const Core::GeoPosition &position, qint64 sampleTime);
void onParticipantChanged(const ParticipantManagement::Participant &participant);
void onTypeChanged(const ParticipantManagement::Type &type, DataModification modType);
void onPartitionTimeChanged(qint64 newPartitionTime);
void onFindOnMap();
void onMovementTrack();
void showSpecialSensorData(int specialSensorData);
private:
ParticipantManagement::Participant m_participant;
qint64 m_lastPositionMSec;
ParticipantManagement::TypeClass m_typeClass;
std::vector<ParticipantManagement::GearInformation> m_gearList;
int m_roomId;
LtsSession::LtsSession *m_session;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> m_asbiIfc;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
std::shared_ptr<FilterManagement::SymbolAppearanceSettings> m_symbolAppearanceSettings;
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> m_fltAesGuiIfc;
AdvancedSymbology::SymbolResultWatcherLabel *m_symbolWatcher;
Ui::OcParticipantInfo *m_ui;
LOGGER_T m_logger;
};
} // namespace OcSituationClient
@@ -0,0 +1,501 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OcParticipantInfo</class>
<widget class="QWidget" name="OcParticipantInfo">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>399</width>
<height>750</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">MessagingView</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblIcon">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout"/>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="11" column="1">
<widget class="QLabel" name="lbSpecialSensorState">
<property name="text">
<string>Special Sensor State:</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="lblParty">
<property name="text">
<string notr="true">&lt;PARTY&gt;</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="lbKind">
<property name="text">
<string>Kind:</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QLabel" name="lblEquipNr">
<property name="text">
<string notr="true">&lt;EUIPNR&gt;</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="pbMountedParticipants">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Opens list with currently mounted participants.</string>
</property>
<property name="text">
<string notr="true">&lt;COUNT_PART&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbMountedOn">
<property name="toolTip">
<string>Opens participant currently mounted on.</string>
</property>
<property name="text">
<string notr="true">&lt;EQUIPNR&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="QLabel" name="lbType">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="8" column="3" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="lblStatus">
<property name="text">
<string notr="true">&lt;STATUS&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="tbNbc">
<property name="toolTip">
<string>N/B/C</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
<normaloff>:/style/pi_nbc.svg</normaloff>:/style/pi_nbc.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QLabel" name="lblDesignator">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">&lt;DESIGNATOR&gt;</string>
</property>
</widget>
</item>
<item row="10" column="1" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QToolButton" name="pbHistory">
<property name="maximumSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="toolTip">
<string>History</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
<normaloff>:/style/pi_tact_status_history.svg</normaloff>:/style/pi_tact_status_history.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="pbGearRanges">
<property name="maximumSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="toolTip">
<string>Shows the gear ranges on the situation map</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
<normaloff>:/style/pi_type_weaponrange.svg</normaloff>:/style/pi_type_weaponrange.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="pbMovementTrack">
<property name="maximumSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="toolTip">
<string>Show movement track</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
<normaloff>:/style/pi_movementtrack.svg</normaloff>:/style/pi_movementtrack.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="pbFindOnMap">
<property name="maximumSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="toolTip">
<string>Find on map</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
<normaloff>:/style/center_to_object.svg</normaloff>:/style/center_to_object.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="5" column="1">
<widget class="QLabel" name="lbEquipNr">
<property name="text">
<string>Equip. No.:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="lbParty">
<property name="text">
<string>Party:</string>
</property>
</widget>
</item>
<item row="9" column="3">
<widget class="QLabel" name="lblKind">
<property name="text">
<string notr="true">&lt;KIND&gt;</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="lblBuilding">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">&lt;BUILDING&gt;</string>
</property>
</widget>
</item>
<item row="7" column="3">
<widget class="QLabel" name="lblRoom">
<property name="text">
<string notr="true">&lt;ROOM&gt;</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="lblTactitcalIdentifier">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">&lt;TACTIDENTIFIER&gt;</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblErrorCodes">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QLabel" name="lblType">
<property name="text">
<string notr="true">&lt;TYPE&gt;</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="lbStatus">
<property name="text">
<string>Status:</string>
</property>
</widget>
</item>
<item row="11" column="3">
<widget class="QLabel" name="lblSpecialSensorState">
<property name="text">
<string notr="true">&lt;SPECIAL SENSOR STATE&gt;</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QLabel" name="lblInfo">
<property name="text">
<string>Info:</string>
</property>
</widget>
</item>
<item row="13" column="3">
<widget class="QLabel" name="lblInfoText">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
<item row="14" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="12" column="1" colspan="3">
<widget class="QTableWidget" name="twGear">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>15</number>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>60</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Gear type</string>
</property>
</column>
<column>
<property name="text">
<string>Charge type</string>
</property>
</column>
<column>
<property name="text">
<string>Remain</string>
</property>
</column>
</widget>
</item>
<item row="2" column="4">
<spacer name="horizontalSpacer_5">
<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="6" column="3">
<widget class="QLabel" name="lblPosition">
<property name="text">
<string notr="true">&lt;POSITION&gt;</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="lbPosition">
<property name="text">
<string>Position:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../../Styles/Dark/resources/rme_dark_style.qrc"/>
</resources>
<connections/>
</ui>
@@ -0,0 +1,100 @@
/**
* @RDE_HEADER@
* Gui Plugin for ObserverController
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2017-01-14
*/
#include "osc_participant_info_gui_plugin.h"
#include "osc_participant_info.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <OcSituationClient/logger.h>
#include <LtsSession/lts_session.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("OcParticipantInfo.InterfaceImpl"))
{
}
InterfaceImpl::~InterfaceImpl()
{}
bool InterfaceImpl::fetchInterfaces()
{
return false;
if (appId() != LtsAppDescriptor::App::OC) // do the hack now
return false;
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> pdmDtc;
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> asbiIfc;
//return m_session->getDtc<TrainingAreaBaseOC::DataInterface>(tabocDtc);
if (!m_session->getDtc<ParticipantManagement::DataInterface>(ppmDtc))
{
ERROR_LOG(m_logger) << "No Ppm";
return false;
}
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(pdmDtc))
{
ERROR_LOG(m_logger) << "No Pdm";
return false;
}
if (!m_session->getForeignDataInterface<AdvancedSymbology::DataInterface>(asbiIfc))
{
ERROR_LOG(m_logger) << "No Asb";
return false;
}
return true;
}
void InterfaceImpl::clearInterfaces()
{}
QString InterfaceImpl::menuGroup() const
{
return tr("Info");
}
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
return QVector<LtsWidgets::PluginData>();
}
void InterfaceImpl::showOcParticipantInfoWindow(const QVector<int> &entityIds)
{
for (auto id : entityIds)
showOcParticipantInfoWindow(id);
}
void InterfaceImpl::showOcParticipantInfoWindow(int entityId)
{
OcParticipantInfo *ti = new OcParticipantInfo(entityId, m_session);
if (!ti->init())
{
delete ti;
return;
}
m_session->addWidget(ti, menuGroup(), QStringLiteral("TlnInfo%1").arg(entityId), LtsWidgets::LayoutArea::eInfoTab);
}
} // namespace OcSituationClient
@@ -0,0 +1,63 @@
/**
* @RDE_HEADER@
* Gui Plugin for ObserverController
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#pragma once
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/OcSituationClient/osc_participant_info_gui_plugin_interface.h>
namespace OcSituationClient
{
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "gui:3:osc.participantinfo")
Q_INTERFACES(GuiPluginBase::Plugin)
Q_OBJECT
public:
GuiPlugin() = default;
~GuiPlugin() = default;
QString pluginName() override { return QStringLiteral("ObserverController.ParticipantInfo"); }
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return (partition == IDL::PartitionType::Global ||
partition == IDL::PartitionType::Exercise);
}
};
class InterfaceImpl final : public QObject, public ForeignParticipantInfoGuiInterface, public GuiPluginBase::Interface
{
Q_OBJECT
public:
explicit InterfaceImpl(LtsSession::LtsSession *session);
~InterfaceImpl();
bool fetchInterfaces() override;
void clearInterfaces() override;
QString menuGroup() const override;
QVector<LtsWidgets::PluginData> getActions() override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return partition == IDL::PartitionType::Global || partition == IDL::PartitionType::Exercise;
}
// ForeignDataInterface
void showOcParticipantInfoWindow(const QVector<int> &entityIds) override;
void showOcParticipantInfoWindow(int entityId) override;
private:
LtsWidgets::LtsDialog *onShowInfo(QWidget *parent);
};
} // namespace OcSituationClient
+50
View File
@@ -0,0 +1,50 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Patric Karwat, SLSE, 2018-01-17
#
SET(osc_system_gui_SRCS
osc_system_gui_plugin.cpp
osc_system_gui_plugin.h
osc_selftest.cpp
osc_selftest.h
osc_settings.cpp
osc_settings.h
osc_close_aes_list.cpp
osc_close_aes_list.h
osc_close_aes_list_model.cpp
osc_close_aes_list_model.h
)
NGL_WRAP_UI(osc_system_gui_SRCS
osc_selftest.ui
osc_settings.ui
osc_close_aes_list.ui
)
NGL_ADD_LIBRARY(WS OscSystemGuiPlugin MODULE ${osc_system_gui_SRCS})
NGL_TARGET_LINK_LIBRARIES(OscSystemGuiPlugin
LtsPrinting
NGLLogger
LtsSession
LtsSessionData
LtsCoordTrans
LtsDataView
LtsNotification
OscGuiPluginInterface
svcOscClient
TabocDataPluginInterface
EscDataPluginInterface
AesDataPluginInterface
PdmDataPluginInterface
PpmDataPluginInterface
LtsWidgets
LtsUtilsSettings
LtsUtilsGuiDds
Qt5::Widgets
Qt5::Multimedia
)
NGL_INSTALL_TARGET(OscSystemGuiPlugin)
@@ -0,0 +1,50 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - CloseAesList Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#include "osc_close_aes_list.h"
#include "ui_osc_close_aes_list.h"
#include <PluginInterfaces/gui_plugin_interface.h>
namespace OcSituationClient
{
CloseAesList::CloseAesList(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
, m_model(new AesListModel(session, this))
, m_ui(new Ui::CloseAesList)
, m_logger(getLogger("CloseAesList"))
{
m_ui->setupUi(this);
m_ui->aesList->setModel(m_model);
#ifndef LTS_DEBUG
m_ui->aesList->hideColumn(AesListModel::Columns::Id);
#endif
connect(this, &CloseAesList::updateAesList, m_model, &AesListModel::initModel);
setOnlineHelpFilename(QStringLiteral("OC-AesList"));
}
CloseAesList::~CloseAesList()
{
delete m_ui;
}
void CloseAesList::setCloseAes(const QSet<int> &aesList)
{
m_model->initModel(aesList);
}
void CloseAesList::retranslate()
{
translate(m_ui, tr("AES List") );
}
} // namespace OcSituationClient
@@ -0,0 +1,48 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - CloseAesList Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <OcSituationClient/logger.h>
#include <osc_close_aes_list_model.h>
namespace Ui
{
class CloseAesList;
}
namespace OcSituationClient
{
class CloseAesList : public LtsWidgets::LtsDialog
{
Q_OBJECT
public:
explicit CloseAesList(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~CloseAesList();
void setCloseAes(const QSet<int> &aesList);
Q_SIGNALS:
void updateAesList(const QSet<int> &newList);
private:
void retranslate() override;
private:
AesListModel *m_model;
Ui::CloseAesList *m_ui;
LOGGER_T m_logger;
};
} // namespace OcSituationClient
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CloseAesList</class>
<widget class="QWidget" name="CloseAesList">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>517</width>
<height>302</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">MessagingView</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="LtsDataView::LtsDataView" name="aesList"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsDataView::LtsDataView</class>
<extends>QWidget</extends>
<header>LtsDataView/lts_data_view.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../Styles/Dark/resources/rme_dark_style.qrc"/>
</resources>
<connections/>
</ui>
@@ -0,0 +1,86 @@
/**
* @RDE_HEADER@
* HMI Plugin for Messaging - Messaging Model
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2016-10.05
*/
#include "osc_close_aes_list_model.h"
#include <LtsSession/lts_session_data.h>
#include <ngltools/ngltools_dtg.h>
#include <ParticipantManagement/ppm_translation.h>
namespace OcSituationClient
{
AesListModel::AesListModel(LtsSession::LtsSession *session, QObject *parent)
: LtsWidgets::LtsAbstractTableModel<int>(
{ tr("Id"),
tr("Name"),
tr("Type"),
tr("Party")
}
, parent)
, m_session(session)
, m_logger(getLogger("AesListModel"))
{
m_session->getDtc<AreaEffectSimulation::DataInterface>(m_aesDtc);
m_session->getDtc<ProjectDataManagement::DataInterface>(m_pdmDtc);
m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc);
}
bool AesListModel::initModel(const QSet<int> &viewList)
{
beginResetModel();
m_vecData.clear();
endResetModel();
if (viewList.isEmpty())
return true;
beginInsertRows(QModelIndex(), 0, viewList.size() - 1);
for (int i : viewList)
m_vecData.push_back(i);
endInsertRows();
return true;
}
QVariant AesListModel::data(const QModelIndex &index, int role) const
{
if (!indexIsValid(index) || role != Qt::DisplayRole)
return QVariant();
// Display Role only!
const AreaEffectSimulation::AesItemView &view = m_aesDtc.get()->aesItemView(m_vecData.at(index.row()));
if (view.id() == 0)
return QVariant();
AreaEffectSimulation::AesItem aesItem;
m_aesDtc->aesItemFromId(view.aesItemId(), aesItem);
if (aesItem.id() < 0)
return QVariant();
switch (index.column())
{
case Columns::Id:
return aesItem.id();
case Columns::Name:
return QString::fromStdString(aesItem.name());
case Columns::AesType:
return m_pdmDtc->trChargeTypeShortName(aesItem.chargeStruct().chargeTypeId(), true);
case Columns::Party:
return aesItem.partyId().is_set() ? ParticipantManagement::trPartyName(m_ppmDtc->party(aesItem.partyId().get()).name()) : QObject::tr("---");
default:
return QVariant();
break;
}
}
} // namespace OcSituationClient
@@ -0,0 +1,54 @@
/**
* @RDE_HEADER@
* HMI Plugin for Messaging - Messaging Model
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2016-10.05
*/
#pragma once
#include <AreaEffectSimulation/aes_data_plugin_interface.h>
#include <ProjectDataManagement/pdm_data_plugin_interface.h>
#include <ParticipantManagement/ppm_data_plugin_interface.h>
#include <OcSituationClient/logger.h>
#include <QSet>
#include <LtsSession/lts_session.h>
#include <LtsWidgets/lts_abstract_table_model.h>
namespace OcSituationClient
{
// --------------------------------------------------------
// AesListModel
// --------------------------------------------------------
class AesListModel final : public LtsWidgets::LtsAbstractTableModel<int>
{
Q_OBJECT
public:
enum Columns
{
Id,
Name,
AesType,
Party
};
explicit AesListModel(LtsSession::LtsSession *session, QObject *parent = nullptr);
bool initModel(const QSet<int> &viewList);
QVariant data(const QModelIndex &, int) const override;
private:
LtsSession::LtsSession *m_session;
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
LOGGER_T m_logger;
};
} //namespace OcSituationClient
+205
View File
@@ -0,0 +1,205 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - SelfTest Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#include "osc_selftest.h"
#include "ui_osc_selftest.h"
#include <QTimer>
#include <QStorageInfo>
#include <LtsUtilsSettings/settings.h>
namespace OcSituationClient
{
SelfTest::SelfTest(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
, m_timer(nullptr)
, m_lastStatesTime(0)
, m_session(session)
, m_tabocDtc(nullptr)
, m_escDtc(nullptr)
, m_ui(new Ui::SelfTest)
, m_logger(getLogger("SelfTestDialog"))
{
m_ui->setupUi(this);
if ( m_session->getDtc<TrainingAreaBaseOC::DataInterface>(m_tabocDtc))
{
WARNING_LOG(m_logger) << "load tab settings";
connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::technicalStateSfmChanged,
this, &SelfTest::onSfmStatusChanged);
onSfmStatusChanged(m_tabocDtc->technicalStateSfm(1), DataModification());
}
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
const bool enableEffectShowManagement = ps->value(QStringLiteral("esm"), QStringLiteral("enableEffectShowManagement")).toBool();
if (!enableEffectShowManagement)
{
m_ui->lblEsc->hide();
m_ui->leEsc->hide();
}
else
{
m_timer = new QTimer(this);
if ( m_escDtc.get() != nullptr) {
connect(m_escDtc.get(), &EffectShowClient::Interface::Dtc::operatingConditionEntityChanged, this, &SelfTest::onEscOperationConditionChanged);
onEscOperationConditionChanged(m_escDtc->operatingConditionEntity(), DataModification());
connect(m_timer, &QTimer::timeout, this, &SelfTest::onCheckLastCondition);
m_timer->start(3000);
}
}
setOnlineHelpFilename(QStringLiteral("OC-Self_Test"));
} // end of ctor()
void SelfTest::onCheckLastCondition()
{
if ((m_session->partitionTime() - 10*1000) > m_lastStatesTime )
{
m_ui->leEsc->setText(tr("No Effect Show Connected"));
}
}
SelfTest::~SelfTest()
{
delete m_ui;
}
void SelfTest::retranslate()
{
translate(m_ui, tr("Self Test") );
}
QString SelfTest::getTechStatError(u_char errorID) const
{
switch (errorID)
{
case 1:
return tr("Error ROM");
case 2:
return tr("Error RAM");
case 3:
return tr("Error SCC1");
case 4:
return tr("Error SCC2");
case 5:
return tr("Error SCP");
case 10:
return tr("Error EEPROM");
case 11:
return tr("Error A/D-Converter");
case 12:
return tr("Error CAN");
case 13:
return tr("Error DUART A");
case 14:
return tr("Error DUART B");
case 20:
return tr("Error GPS");
case 21:
return tr("Error PUMA/T");
case 30:
return tr("Error Equipment Configuration");
case 31:
return tr("Error Exercise Configuration");
case 40:
return tr("Error Login");
case 41:
return tr("Error TETRA Registration");
case 42:
return tr("Error Transparent Channel O/C");
case 43:
return tr("Error Transparent Channel DMF");
default:
break;
}
return tr("Unknown Error (%1)").arg(errorID);
}
void SelfTest::onStatusHDD()
{
QStorageInfo storage(QCoreApplication::applicationFilePath());
if (storage.isValid() && storage.isReady())
{
quint64 freeBytesAvailable = storage.bytesAvailable();
quint64 bytesAvailable = storage.bytesTotal();
double percent = bytesAvailable ? 100.0 * freeBytesAvailable / bytesAvailable : 0;
m_ui->leDisk->setText(tr("%1% available (%2)").arg(QString::number(percent, 'f', 2), readableSize(freeBytesAvailable)));
}
else
{
m_ui->leDisk->setText(tr("Error reading available disk space"));
}
}
void SelfTest::onSfmStatusChanged(const TrainingAreaBaseOC::TechnicalStateSfm &data, DataModification modType)
{
Q_UNUSED(modType)
m_ui->leRadio->setText(data.radioAvailable() ? tr("Available") : tr("Not Available"));
m_ui->leLicense->setText(data.licensed() ? tr("Yes") : tr("No"));
m_ui->leSfm->setText(data.sfmConnected() ? tr("Connected") : tr("Not Connected"));
m_ui->leSfmMani->setText(data.manipulationSfm() ? tr("Yes") : tr("No"));
m_ui->leEquipmentMani->setText(data.manipulationEquipment() ? tr("Yes") : tr("No"));
m_ui->lblErrorCodes->setText(data.errorCode() > 0 ? getTechStatError(data.errorCode()) : QLatin1String(""));
onStatusHDD();
}
void SelfTest::onEscOperationConditionChanged(const EffectShowClient::OperatingConditionEntity &data, DataModification modType)
{
Q_UNUSED(modType)
QString feature = tr("Effect Show Connected: ");
switch (data.vehicleFeature().underlying())
{
case EffectShowManagement::Feature_e::Smoke:
feature += tr("Smoke");
break;
case EffectShowManagement::Feature_e::Explosion24:
feature += tr("Explosion (24)");
break;
case EffectShowManagement::Feature_e::Explosion48:
feature += tr("Explosion (48)");
break;
case EffectShowManagement::Feature_e::NotSpecified:
feature.clear();
break;
}
if (feature.isEmpty())
m_ui->leEsc->setText(tr("No Effect Show Connected"));
else
m_ui->leEsc->setText(feature);
m_lastStatesTime = m_session->partitionTime();
}
QString SelfTest::readableSize(quint64 bytes) const
{
if (bytes > TB)
return tr("%1 TB").arg((double) bytes / TB, 0, 'f', 2);
else if (bytes > GB)
return tr("%1 GB").arg((double) bytes / GB, 0, 'f', 2);
else if (bytes > MB)
return tr("%1 MB").arg((double) bytes / MB, 0, 'f', 2);
else if (bytes > KB)
return tr("%1 KB").arg((double) bytes / KB, 0, 'f', 2);
else
return tr("%1 Bytes").arg(bytes);
}
} // namespace OcSituationClient
+70
View File
@@ -0,0 +1,70 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Selfcheck Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <LtsSession/lts_session.h>
#include <OcSituationClient/logger.h>
#include <TrainingAreaBaseOC/taboc_data_plugin_interface.h>
#include <EffectShowClient/esc_data_plugin_interface.h>
class QTimer;
namespace Ui
{
class SelfTest;
}
namespace OcSituationClient
{
class SelfTest : public LtsWidgets::LtsDialog
{
Q_OBJECT
public:
explicit SelfTest(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~SelfTest();
private Q_SLOTS:
void onStatusHDD();
void onSfmStatusChanged(const TrainingAreaBaseOC::TechnicalStateSfm &data, DataModification modType);
void onEscOperationConditionChanged(const EffectShowClient::OperatingConditionEntity &data, DataModification modType);
void onCheckLastCondition();
private:
void retranslate() override;
QString getTechStatError(u_char errorID) const;
QString readableSize(const quint64 bytes) const;
private:
static const quint64 BYTE = 1;
static const quint64 KB = 1024 * BYTE;
static const quint64 MB = 1024 * KB;
static const quint64 GB = 1024 * MB;
static const quint64 TB = 1024 * GB;
QTimer *m_timer;
qint64 m_lastStatesTime;
LtsSession::LtsSession *m_session;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc;
std::shared_ptr<EffectShowClient::Interface::Dtc> m_escDtc;
Ui::SelfTest *m_ui;
LOGGER_T m_logger;
};
} // namespace OcSituationClient
+178
View File
@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelfTest</class>
<widget class="QWidget" name="SelfTest">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>302</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">MessagingView</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="1">
<widget class="QLineEdit" name="leSfmMani">
<property name="toolTip">
<string>Manipulation Sfm</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="leLicense">
<property name="toolTip">
<string>Radio License</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Manipulation Equipment:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Sfm Connection:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Disk Space:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="leSfm">
<property name="toolTip">
<string>Sfm Connection</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Radio Connection:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="leRadio">
<property name="toolTip">
<string>Radio Connection</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="leEquipmentMani">
<property name="toolTip">
<string>Manipulation Equipment</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<widget class="QLabel" name="lblErrorCodes">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Manipulation Sfm:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Radio License:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="leDisk">
<property name="toolTip">
<string>Disk Space</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblEsc">
<property name="text">
<string>Effect Show Connection:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="leEsc">
<property name="toolTip">
<string>Effect Show Connection</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+208
View File
@@ -0,0 +1,208 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Settings Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#include "osc_settings.h"
#include "ui_osc_settings.h"
#include <LtsUtilsSettings/settings.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <QDebug>
namespace OcSituationClient
{
Settings::Settings(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
, m_mediaplayer(new QMediaPlayer(this))
, m_ocGroupString(QStringLiteral("ObserverController"))
, m_opSettings(LtsUtils::OperatorSettings::getInstance())
, m_ui(new Ui::Settings)
// , m_logger(getLogger("SettingsDialog"))
{
m_ui->setupUi(this);
//optional
session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc);
//connects
connect(m_ui->pbSoundCheck, &LtsWidgets::LtsDragIcon::clicked, this, &Settings::onSoundCheck);
connect(m_ui->pbResetRange, &LtsWidgets::LtsDragIcon::clicked, this, &Settings::onResetRange);
connect(m_ui->slWarningRange, &QSlider::valueChanged, this, [this](int range)
{
m_ui->lblRange->setText(QString::number(range));
});
#ifdef WIN32
m_handler = CreateFile(L"\\\\.\\LCD",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0, NULL);
m_monitorLightBrightness = getMonitorCurrentLightBrightness();
connect(m_ui->slMonitorBrightness, &QSlider::valueChanged, this, [this](int range)
{
m_ui->lblMonitorBrightness->setText(QString::number(range));
setMonitorLightBrightness(range);
});
if(m_monitorLightBrightness >= 0)
{
m_ui->slMonitorBrightness->setValue(m_monitorLightBrightness);
}
m_ui->lblMonitorBrightness->setText(QString::number(m_ui->slMonitorBrightness->value()));
connect(m_buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked,
this, [this]()
{
//reset to old Value
setMonitorLightBrightness(m_monitorLightBrightness);
});
#else
m_ui->slMonitorBrightness->hide();
m_ui->lblMonitorBrightness->hide();
m_ui->LblMonitorBrightness->hide();
#endif
connect(m_ui->cbxAcusticWarning, &LtsWidgets::LtsDragIcon::clicked, this, &Settings::slotChangesMade);
connect(m_ui->cbxVisualWarning, &LtsWidgets::LtsDragIcon::clicked, this, &Settings::slotChangesMade);
connect(m_ui->cbxOcSituationBorder, &LtsWidgets::LtsDragIcon::clicked, this, &Settings::slotChangesMade);
connect(m_ui->cbxMovingMapToSelf, &LtsWidgets::LtsDragIcon::clicked, this, &Settings::slotChangesMade);
//load OperatorSettings and set Ui Values
loadOperatorSettings();
//set audio file
m_mediaplayer->setMedia(QUrl(QLatin1String("qrc:/beep.wav")));
m_mediaplayer->setVolume(100);
setOnlineHelpFilename(QStringLiteral("OC-Settings"));
}
Settings::~Settings()
{
delete m_ui;
}
/*!
* \brief Settings::setMonitorLightBrightness
* this method set the light brightness of an windows os monitor
* \warning this funcion work only for windows os
* \param value
*/
void Settings::setMonitorLightBrightness(const int value)
{
#ifdef WIN32
m_displayBrightness.ucDisplayPolicy = 0;
m_displayBrightness.ucACBrightness = 0;
m_displayBrightness.ucDCBrightness = value;
DWORD ret = 0;
DWORD nOutBufferSize = sizeof(m_displayBrightness);
if(m_handler == INVALID_HANDLE_VALUE)
{
m_handler = CreateFile(L"\\\\.\\LCD",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if(m_handler == INVALID_HANDLE_VALUE)
{
qCritical()<<" couldn't CreateFile for setting monitor light brightness. Error: "<<GetLastError();
return;
}
}
if (!DeviceIoControl(m_handler,
IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS,
(DISPLAY_BRIGHTNESS*)&m_displayBrightness,
nOutBufferSize,
NULL,
0,
&ret,
NULL))
{
qCritical()<<" couldn't set monitor light brightness. Error: "<<GetLastError();
}
#else
Q_UNUSED(value)
#endif
}
/*!
* \brief Settings::getMonitorCurrentLightBrightness
* get on win os monitor light brightness
* \warning this funcion work only for windows os
* \return
*/
int Settings::getMonitorCurrentLightBrightness()
{
#ifdef WIN32
DWORD ret;
int nRes = DeviceIoControl(
m_handler, // handle to device
IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS , // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
(DISPLAY_BRIGHTNESS*)&m_displayBrightness, // output buffer
sizeof(m_displayBrightness), // size of output buffer
(LPDWORD) &ret, // bytes returned
NULL // OVERLAPPED
);
if(nRes !=0)
{
const int l = m_displayBrightness.ucDCBrightness;
return l;
}
else {
return -1;
}
#endif
return -1;
}
void Settings::onResetRange()
{
m_ui->slWarningRange->setValue(WARNINGRANGEDEFAULT);
}
void Settings::onSoundCheck()
{
m_mediaplayer->play();
}
void Settings::loadOperatorSettings()
{
// now set values
m_ui->slWarningRange->setValue(m_opSettings->value(m_ocGroupString, QStringLiteral("WarningRange"), WARNINGRANGEDEFAULT).toInt());
m_ui->cbxAcusticWarning->setChecked(m_opSettings->value(m_ocGroupString, QStringLiteral("AcousticWarning"), false).toBool());
m_ui->cbxVisualWarning->setChecked(m_opSettings->value(m_ocGroupString, QStringLiteral("VisualWarning"), false).toBool());
m_ui->cbxOcSituationBorder->setChecked(m_opSettings->value(m_ocGroupString, QStringLiteral("OcSituationBorder"), false).toBool());
m_ui->cbxMovingMapToSelf->setChecked(m_opSettings->value(m_ocGroupString, QStringLiteral("MovingMapToSelf"), false).toBool());
}
void Settings::retranslate()
{
translate(m_ui, tr("Settings") );
}
bool Settings::apply()
{
//write qsettings
m_opSettings->setValue(m_ocGroupString, QStringLiteral("WarningRange"), m_ui->slWarningRange->value());
m_opSettings->setValue(m_ocGroupString, QStringLiteral("AcousticWarning"), m_ui->cbxAcusticWarning->isChecked());
m_opSettings->setValue(m_ocGroupString, QStringLiteral("VisualWarning"), m_ui->cbxVisualWarning->isChecked());
m_opSettings->setValue(m_ocGroupString, QStringLiteral("OcSituationBorder"), m_ui->cbxOcSituationBorder->isChecked());
m_opSettings->setValue(m_ocGroupString, QStringLiteral("MovingMapToSelf"), m_ui->cbxMovingMapToSelf->isChecked());
m_sitMapGuiIfc->ocSituationRange_show(m_ui->cbxOcSituationBorder->isChecked());
#ifdef WIN32
m_monitorLightBrightness = getMonitorCurrentLightBrightness();
#endif
return true;
}
} // namespace OcSituationClient
+84
View File
@@ -0,0 +1,84 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Settings Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#pragma once
#include <QMediaPlayer>
#include <LtsWidgets/lts_dialog.h>
#include <LtsSession/lts_session.h>
#ifdef WIN32
#include <windows.h>
#include <ntddvdeo.h>
#endif
namespace SituationMap
{
class ForeignGuiInterface;
}
namespace LtsUtils
{
class OperatorSettings;
}
namespace Ui
{
class Settings;
}
namespace OcSituationClient
{
class Settings : public LtsWidgets::LtsDialog
{
Q_OBJECT
public:
explicit Settings(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~Settings();
void setMonitorLightBrightness(const int value);
int getMonitorCurrentLightBrightness();
#ifdef WIN32
typedef struct _DISPLAY_BRIGHTNESS {
UCHAR ucDisplayPolicy;
UCHAR ucACBrightness;
UCHAR ucDCBrightness;
} DISPLAY_BRIGHTNESS, *PDISPLAY_BRIGHTNESS;
#endif
private Q_SLOTS:
void onResetRange();
void onSoundCheck();
private:
void loadOperatorSettings();
void retranslate() override;
bool apply() override;
private:
static const int WARNINGRANGEDEFAULT = 100;
QMediaPlayer *m_mediaplayer;
QString m_ocGroupString;
LtsUtils::OperatorSettings *m_opSettings;
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
Ui::Settings *m_ui;
int m_monitorLightBrightness;
#ifdef WIN32
DISPLAY_BRIGHTNESS m_displayBrightness;
HANDLE m_handler;
#endif
//LOGGER_T m_logger;
};
} // namespace OcSituationClient
+226
View File
@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Settings</class>
<widget class="QWidget" name="Settings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>584</width>
<height>302</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">MessagingView</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="LtsWidgets::LtsDragIcon" name="cbxAcusticWarning" native="true">
<property name="minimumSize">
<size>
<width>150</width>
<height>40</height>
</size>
</property>
<property name="text" stdset="0">
<string>Acoustical Warning</string>
</property>
<property name="isCheckable" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LtsWidgets::LtsDragIcon" name="cbxOcSituationBorder" native="true">
<property name="minimumSize">
<size>
<width>150</width>
<height>40</height>
</size>
</property>
<property name="text" stdset="0">
<string>OC-Situation Borderline</string>
</property>
<property name="isCheckable" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>57</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="LtsWidgets::LtsDragIcon" name="pbSoundCheck" native="true">
<property name="minimumSize">
<size>
<width>100</width>
<height>40</height>
</size>
</property>
<property name="text" stdset="0">
<string>Sound Check</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="LtsWidgets::LtsDragIcon" name="cbxVisualWarning" native="true">
<property name="text" stdset="0">
<string>Visual Warning</string>
</property>
<property name="isCheckable" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="LtsWidgets::LtsDragIcon" name="cbxMovingMapToSelf" native="true">
<property name="minimumSize">
<size>
<width>150</width>
<height>40</height>
</size>
</property>
<property name="text" stdset="0">
<string>Moving Map To Self</string>
</property>
<property name="isCheckable" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Warning Range [m]:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblRange">
<property name="text">
<string notr="true">&lt;RANGE&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>121</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="LtsWidgets::LtsDragIcon" name="pbResetRange" native="true">
<property name="toolTip">
<string>Reset</string>
</property>
<property name="icon" stdset="0">
<iconset>
<normaloff>:/style/restart.svg</normaloff>:/style/restart.svg</iconset>
</property>
<property name="eForceFixedSize" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<widget class="QSlider" name="slWarningRange">
<property name="minimum">
<number>25</number>
</property>
<property name="maximum">
<number>500</number>
</property>
<property name="pageStep">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="LblMonitorBrightness">
<property name="text">
<string>Monitor Brightness:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lblMonitorBrightness">
<property name="text">
<string notr="true">&lt;RANGE&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QSlider" name="slMonitorBrightness">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="value">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDragIcon</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_drag_icon.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,323 @@
/**
* @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
@@ -0,0 +1,89 @@
/**
* @RDE_HEADER@
* Gui Plugin for ObserverController
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2018-01-17
*/
#pragma once
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/OcSituationClient/osc_gui_plugin_interface.h>
#include <TrainingAreaBaseOC/taboc_data_plugin_interface.h>
#include <AreaEffectSimulation/aes_data_plugin_interface.h>
#include <QSoundEffect>
class QNetworkSession;
namespace LtsNotification
{
class LtsNotification;
}
namespace OcSituationClient
{
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "gui:3:osc.system")
Q_INTERFACES(GuiPluginBase::Plugin)
Q_OBJECT
public:
GuiPlugin() = default;
~GuiPlugin() = default;
QString pluginName() override { return QStringLiteral("ObserverController.System"); }
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return (partition == IDL::PartitionType::Global ||
partition == IDL::PartitionType::Exercise ||
partition == IDL::PartitionType::Replay);
}
};
class InterfaceImpl final : public QObject, public ForeignGuiInterface, public GuiPluginBase::Interface
{
Q_OBJECT
public:
explicit InterfaceImpl(LtsSession::LtsSession *session);
~InterfaceImpl();
bool fetchInterfaces() override;
void clearInterfaces() override;
QString menuGroup() const override;
QVector<LtsWidgets::PluginData> getActions() override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return partition == IDL::PartitionType::Global || partition == IDL::PartitionType::Exercise;
}
private slots:
//void slotConnectionChanged(const OcSituationClient:: &data, DataModification modType);
void onEnterLeaveAesChanged(const TrainingAreaBaseOC::EnterLeaveAes &data, DataModification modType);
void onCheckAllEffectAreas();
Q_SIGNALS:
void updateAesList(const QSet<int> &newList);
private:
LtsWidgets::LtsDialog *onShowSelfTest(QWidget *parent);
LtsWidgets::LtsDialog *onShowSettings(QWidget *parent);
LtsWidgets::LtsDialog *onShowCloseAes(QWidget *parent = nullptr);
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc;
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
QString m_closeAreaIdentifier;
QSet<int> m_closeAes;
QSoundEffect m_enterSound;
QSoundEffect m_leaveSound;
QSoundEffect m_nearInSound;
QSoundEffect m_nearOutSound;
};
} // namespace OcSituationClient