463 lines
14 KiB
C++
Executable File
463 lines
14 KiB
C++
Executable File
/**
|
|
* @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
|