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

+106
View File
@@ -0,0 +1,106 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Christian Ehrlicher, SLSE, 2016-02-29
#
SET(smo_monitors_gui_SRCS
smo_monitors_gui_plugin.cpp
smo_monitors_gui_plugin.h
smo_base_equipment_check.cpp
smo_base_equipment_check.h
smo_base_player_model.cpp
smo_base_player_model.h
smo_bite_model.h
smo_bite_model.cpp
smo_ctas_error_model.cpp
smo_ctas_error_model.h
smo_dialog.cpp
smo_dialog.h
smo_egcu_model.cpp
smo_egcu_model.h
smo_egcu_edit.cpp
smo_egcu_edit.h
smo_fault_message_dialog.cpp
smo_fault_message_dialog.h
smo_manipulation_model.h
smo_manipulation_model.cpp
smo_party_equipment_check_dialog.cpp
smo_party_equipment_check_dialog.h
smo_party_player_model.cpp
smo_party_player_model.h
smo_single_service_equipment_check_dialog.cpp
smo_single_service_equipment_check_dialog.h
smo_single_player_model.cpp
smo_single_player_model.h
smo_structure_element_edit.cpp
smo_structure_element_edit.h
)
NGL_WRAP_UI(smo_monitors_gui_SRCS
smo_dialog.ui
smo_egcu_edit.ui
smo_fault_message_dialog.ui
smo_party_equipment_check_dialog.ui
smo_single_service_equipment_check_dialog.ui
smo_structure_element_edit.ui
)
NGL_ADD_LIBRARY(WS SmoMonitorsGuiPlugin MODULE ${smo_monitors_gui_SRCS})
NGL_TARGET_LINK_LIBRARIES(SmoMonitorsGuiPlugin
Qt5::Widgets
AsbDataPluginInterface
AsbHelper
FlmDataPluginInterface
FlmExplorerGuiPluginInterface
GuiPluginInterface
IsmDataPluginInterface
IsmShared
LtsCoordTrans
LtsDataView
LtsPrinting
LtsSession
LtsSessionData
LtsUtilsGuiDds
LtsUtilsSettings
ngltools
nglwidgets
PpmCommon
PpmDataPluginInterface
SmoCheckButtonHandler
SmoCommon
SmoMonitorsGuiPluginInterface
SituationMapGuiPluginInterface
svcAsmClient
svcBldCommon
# svcOssCommon
svcOssClient
svcSmoDummy
TabocDataPluginInterface
tabTelegrams
svcAesClient
)
NGL_INSTALL_TARGET(SmoMonitorsGuiPlugin)
## check_button_handler
SET(smo_check_button_handler_SRCS
smo_check_button_handler.cpp
smo_check_button_handler.h
)
NGL_ADD_LIBRARY2(WS SmoCheckButtonHandler SHARED ${smo_check_button_handler_SRCS})
NGL_TARGET_INCLUDE_DIRECTORIES(SmoCheckButtonHandler
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(SmoCheckButtonHandler
Qt5::Widgets
LtsPrinting
LtsSessionData
LtsUtilsGuiDds
LtsUtilsSettings
PpmDataPluginInterface
)
@@ -0,0 +1,201 @@
/**
* @RDE_HEADER@
* Base Equipment Check
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-06-07
*/
#include "smo_base_equipment_check.h"
#include <ProjectDataManagement/pdm_to_string.h>
#include <QAction>
#include <QMenu>
#include <QTimer>
#include <QTreeView>
#include <LtsSession/lts_session_data.h>
#include <LtsDataView/lts_data_view.h>
#include <LtsPrinting/printing.h>
namespace ServiceMonitor
{
BaseEquipmentCheck::BaseEquipmentCheck(const char *loggerName,
LtsSession::LtsSession *session,
QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
, m_session(session)
, m_playerModel(nullptr)
, m_ppmFtc(nullptr)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_timeoutVal(65000)
, m_actionMenu(new QMenu(this))
, m_requestBite(new QAction(tr("Request BITE"), this))
, m_requestBiteSelfTest(new QAction(tr("Request BITE (with self test)"), this))
, m_checkButtonHandler(nullptr)
, m_logger(getLogger(loggerName))
{
// Edit-Button is used as Check-Button
// Added QStringLiteral is workaround for REGG-3773. Author of this dialog should fix this properly.
m_buttonBox->setButtonVisible(LtsWidgets::DialogButton::Edit, true);
m_buttonBox->setText(LtsWidgets::DialogButton::Edit, tr("Check") + QStringLiteral(" "));
m_buttonBox->setIcon(LtsWidgets::DialogButton::Edit, QIcon(QStringLiteral(":/style/dialog-ok.svg")));
m_actionMenu->addAction(m_requestBite);
connect(m_requestBite, &QAction::triggered,
this, [this]() { sendBiteRequest(m_selectedParticipants, false);});
m_actionMenu->addAction(m_requestBiteSelfTest);
connect(m_requestBiteSelfTest, &QAction::triggered,
this, [this]() { sendBiteRequest(m_selectedParticipants, true);});
m_buttonBox->setMenu(LtsWidgets::DialogButton::Edit, m_actionMenu);
m_checkButtonHandler = new CheckButtonHandler(m_buttonBox->getButton(LtsWidgets::DialogButton::Edit));
m_checkButtonHandler->addReset();
m_checkButtonHandler->addTacticalState();
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print,
this,
&BaseEquipmentCheck::onPrint);
}
bool BaseEquipmentCheck::init(const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc)
{
// Ftc
if (!ppmFtc || m_ppmFtc)
return false;
m_ppmFtc = ppmFtc;
// Dtc
m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc);
if (m_checkButtonHandler && m_ppmDtc)
m_checkButtonHandler->setPpm(m_ppmDtc, m_ppmFtc);
view()->treeView()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(view()->treeView(), &QTreeView::customContextMenuRequested,
this, &BaseEquipmentCheck::onCustomContextMenuRequested);
connect(view(), &LtsDataView::LtsDataView::selectionChanged,
this, &BaseEquipmentCheck::onSelectionChanged);
onSelectionChanged();
return true;
}
void BaseEquipmentCheck::sendBiteRequest(const std::vector<int> &selectedIds,
bool bWithSelfTest)
{
if (selectedIds.size() == 0)
return;
ParticipantManagement::CallBiteRequest req;
req.participantIds(selectedIds);
req.withSelfTest(bWithSelfTest);
m_requestHelper->startSingleRequest([req, this]() { return m_ppmFtc->callBiteRequest(req, this); });
for (int id : selectedIds)
{
m_playerModel->updateBitResult(id, tr("Test running"));
// set timer for timeout for the participant
QTimer *t = new QTimer(this);
connect(t, &QTimer::timeout, this, [this, id, t]() { onMappedEquipTimeout(id, t); });
t->start(m_timeoutVal);
}
}
void BaseEquipmentCheck::sendInitRequest(const std::vector<int> &selectedIds,
bool resetManipulation,
bool restockCharges,
bool resetVulnerabilityState,
bool restockSanMat)
{
if (!resetManipulation && !restockCharges && !resetVulnerabilityState)
return;
ParticipantManagement::InitParticipantRequest req;
req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId());
req.participantIds(selectedIds);
req.resetManipulation(resetManipulation);
req.restockCharges(restockCharges);
req.resetVulnerabilityState(resetVulnerabilityState);
req.restockSanitationMaterial(restockSanMat);
m_requestHelper->startSingleRequest([req, this]() { return m_ppmFtc->initParticipantRequest(req, this); });
}
void BaseEquipmentCheck::sendModifyState(const std::vector<int> &selectedIds,
ProjectDataManagement::VulnerabilityState vs)
{
ParticipantManagement::ModifyStateRequest req;
req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId());
req.participantIds(selectedIds);
req.vulnerabilityState(vs);
m_requestHelper->startSingleRequest([req, this]() { return m_ppmFtc->modifyStateRequest(req, this); });
}
void BaseEquipmentCheck::onMappedEquipTimeout(int participantId, QTimer *timer)
{
timer->deleteLater();
const QString bitResult = m_playerModel->getBitResult(participantId);
if (bitResult == tr("Test running"))
{
// update tableView
m_playerModel->updateBitResult(participantId,
tr("Timeout ..."));
}
}
void BaseEquipmentCheck::onSelectionChanged()
{
DEBUG_LOG(m_logger) << "onSelectionChanged";
bool enable = false;
const auto selectedIndexes = view()->selectedRows();
if (m_checkButtonHandler)
{
std::vector<int> selectedParticipantCandidates;
for (const auto &idx : selectedIndexes)
{
const auto &part = m_playerModel->getRowData(idx.row());
if (part.participantId <= 0)
continue;
selectedParticipantCandidates.push_back(part.participantId);
}
//
// check candidates:
//
// setSelectedParticipantIds will check for TypeClass etc and set visi of actions accordingly.
// additional, unknown/invalid entries will be removed:
m_selectedParticipants = m_checkButtonHandler->setSelectedParticipantIds(selectedParticipantCandidates);
enable = m_selectedParticipants.size() > 0;
}
// set visi according number of valid participants:
m_requestBite->setVisible(enable);
m_requestBiteSelfTest->setVisible(enable);
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, !selectedIndexes.isEmpty());
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Show, enable);
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, enable);
}
void BaseEquipmentCheck::onCustomContextMenuRequested(const QPoint &pos)
{
if (m_selectedParticipants.size() == 0)
return;
m_actionMenu->exec(view()->treeView()->mapToGlobal(pos));
}
void BaseEquipmentCheck::onPrint()
{
LtsPrinting::printView(m_session, this, view()->treeView());
}
} // namespace ServiceMonitor
@@ -0,0 +1,94 @@
/**
* @RDE_HEADER@
* Base Equipment Check
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-06-07
*/
#pragma once
#include <ParticipantManagement/ppm_ftc.h>
#include <ParticipantManagement/ppm_dtc.h>
#include <LtsSession/lts_session.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <LtsWidgets/lts_dialog.h>
#include <Common/logger.h>
#include "smo_base_player_model.h"
#include "smo_check_button_handler.h"
class QTimer;
namespace LtsDataView
{
class LtsDataView;
}
namespace ServiceMonitor
{
class BaseEquipmentCheck : public LtsWidgets::LtsDialog
, protected ParticipantManagement::Interface::Ftc::CallBiteReplyHandler
, protected ParticipantManagement::Interface::Ftc::InitParticipantReplyHandler
, protected ParticipantManagement::Interface::Ftc::ModifyStateReplyHandler
{
Q_OBJECT
public:
explicit BaseEquipmentCheck(const char *loggerName,
LtsSession::LtsSession *session,
QWidget *parent = nullptr);
bool init(const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc);
void onCallBiteReply(const Core::FunctionReplyObject &replyObject) override final
{
m_requestHelper->requestReply(replyObject);
}
void onInitParticipantReply(const Core::FunctionReplyObject &replyObject) override final
{
m_requestHelper->requestReply(replyObject);
}
void onModifyStateReply(const Core::FunctionReplyObject &replyObject) override final
{
m_requestHelper->requestReply(replyObject);
}
void sendBiteRequest(const std::vector<int> &selectedIds, bool bWithSelfTest);
void sendInitRequest(const std::vector<int> &selectedIds,
bool resetManipulation,
bool restockCharges,
bool resetVulnerabilityState,
bool restockSanMat);
void sendModifyState(const std::vector<int> &selectedIds,
ProjectDataManagement::VulnerabilityState vs);
protected slots:
void onMappedEquipTimeout(int participantId, QTimer *timer);
void onSelectionChanged();
void onCustomContextMenuRequested(const QPoint &pos);
void onPrint();
protected:
virtual LtsDataView::LtsDataView *view() = 0;
virtual const LtsDataView::LtsDataView *view() const = 0;
protected:
LtsSession::LtsSession *m_session;
BasePlayerModel *m_playerModel;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc;
LtsUtils::RequestHelper *m_requestHelper;
int m_timeoutVal;
QMenu *m_actionMenu;
QAction *m_requestBite;
QAction *m_requestBiteSelfTest;
std::vector<int> m_selectedParticipants;
CheckButtonHandler *m_checkButtonHandler;
NGL::INGLLogger &m_logger;
};
} // namespace ServiceMonitor
@@ -0,0 +1,918 @@
/**
* @RDE_HEADER@
* Base Model for Equipment Check
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-06-07
*/
#include "smo_base_player_model.h"
#include "smo_bite_model.h"
#include <LtsSession/lts_session.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <LtsUtilsCore/outdated_position.h>
#include <ProjectDataManagement/pdm_to_string.h>
#include <ProjectDataManagement/pdm_translation.h>
#include <ParticipantManagement/ppm_translation.h>
#include <Plugins/AdvancedSymbology/asb_data_plugin_interface.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <ngltools/ngltools_dtg.h>
#include <QApplication>
#include <QDateTime>
#include <QTimer>
#include <Common/logger.h>
#include <Symbology/symbol_data_to_render_role.h>
namespace ServiceMonitor
{
BasePlayerModel::BasePlayerModel(QObject *parent)
: LtsWidgets::LtsAbstractTableModel<PlayerData>(
{
tr("Id"),
tr("Equip. No."),
tr("Party"),
tr("Hierarchy"),
tr("Designator"),
tr("Tact. Identifier"),
tr("Sign"),
tr("Type"),
tr("Tact. Status"),
tr("Pos."),
tr("Age"),
tr("BITE"),
tr("Warnings")
},
parent)
, AdvancedSymbology::TableModelSymbolRenderer<BasePlayerModel>(ColEquipmentNummer)
, m_ppmDtc(nullptr)
, m_ppmGuiCbxIfc(nullptr)
, m_biteModel(new BiteModel(this))
, m_tactStatusGreen(QLatin1String("icon:green_light.svg"))
, m_tactStatusYellow(QLatin1String("icon:yellow_light.svg"))
, m_tactStatusOrange(QLatin1String("icon:orange_light.svg"))
, m_tactStatusRed(QLatin1String("icon:red_light.svg"))
, m_partitionTime(0)
, m_timeoutCheckTimer(new QTimer(this))
, m_positionAgeTimer(new QTimer(this))
, m_session(nullptr)
, m_logger(getLogger("BasePlayerModel"))
{
m_timeoutCheckTimer->setSingleShot(false);
connect(m_timeoutCheckTimer, &QTimer::timeout,
this, &BasePlayerModel::onTimeoutCheck);
m_positionAgeTimer->setSingleShot(false);
connect(m_positionAgeTimer, &QTimer::timeout,
this, &BasePlayerModel::onUpdatePositionAge);
}
bool BasePlayerModel::initModel(LtsSession::LtsSessionDataDds *session)
{
if (!session)
return false;
DEBUG_LOG(m_logger) << "**** initModel";
m_session = session;
m_partitionTime = m_session->partitionTime();
if (!session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
return false;
session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmGuiCbxIfc);
// optional
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> asb;
session->getForeignDataInterface<AdvancedSymbology::DataInterface>(asb);
AdvancedSymbology::TableModelSymbolRenderer<BasePlayerModel>::init(asb, this);
std::shared_ptr<ProjectDataManagement::Interface::Dtc> pdmDtc;
session->getDtc<ProjectDataManagement::DataInterface>(pdmDtc);
m_biteModel->initModel(m_ppmDtc, pdmDtc);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged,
this, &BasePlayerModel::onDynamicParticipantChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
this, &BasePlayerModel::onParticipantChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::biteChanged,
this, &BasePlayerModel::onBiteChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::partyChanged,
this, &BasePlayerModel::onPartyChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged,
this, &BasePlayerModel::onPositionChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::typeChanged,
this, &BasePlayerModel::onTypeChanged);
auto cbParticipant = [this](const ParticipantManagement::Participant &participant)
{
onParticipantChanged(participant, DataModification::eAdded);
};
m_ppmDtc->participants(cbParticipant);
auto cbBite = [this](const ParticipantManagement::Bite &bite)
{
onBiteChanged(bite, DataModification::eAdded);
};
m_ppmDtc->bites(cbBite);
auto cbParty = [this](const ParticipantManagement::Party &party)
{
onPartyChanged(party, DataModification::eAdded);
};
m_ppmDtc->partys(cbParty);
auto cbPosition = [this](const ParticipantManagement::ParticipantPosition &position)
{
onPositionChanged(position, DataModification::eAdded);
};
m_ppmDtc->participantPositions(cbPosition);
auto cbTypes = [this](const ParticipantManagement::Type &type)
{
onTypeChanged(type, DataModification::eAdded);
};
m_ppmDtc->types(cbTypes);
connect(session, &LtsSession::LtsSession::partitionTimeChanged,
this, &BasePlayerModel::onPartitionTimeChanged);
m_timeoutCheckTimer->start(2000);
m_positionAgeTimer->start(10000);
connect(this, &BasePlayerModel::rowsInserted, this, &BasePlayerModel::updateUsedPartyIds);
connect(this, &BasePlayerModel::rowsRemoved, this, &BasePlayerModel::updateUsedPartyIds);
connect(this, &BasePlayerModel::modelReset, this, &BasePlayerModel::updateUsedPartyIds);
return true;
}
QVariant BasePlayerModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole &&
orientation == Qt::Horizontal)
{
if (section == ColParty)
{
LtsWidgets::ComboboxFilterContent cfc;
cfc.data.reserve(m_usedPartyIds.size());
LtsWidgets::ComboboxFilterData cfd;
for (const int partyId : m_usedPartyIds)
{
const auto party = m_parties.value(partyId);
cfd.data = partyId;
cfd.text = party.name;
cfd.icon = party.icon;
cfc.data.push_back(cfd);
}
return cfc.toVariant();
}
if (section == ColTacticalStatus)
{
LtsWidgets::ComboboxFilterContent cfc;
cfc.data.reserve(4);
auto fill = [&cfc, this](ProjectDataManagement::VulnerabilityState state, const QIcon &icon)
{
LtsWidgets::ComboboxFilterData cfd;
cfd.data = state.underlying();
cfd.text = vulnerabilityStateString(ParticipantManagement::TypeClass::Human, state);
cfd.icon = icon;
cfc.data.push_back(std::move(cfd));
};
fill(ProjectDataManagement::VulnerabilityState_def::CombatReady, m_tactStatusGreen);
{
LtsWidgets::ComboboxFilterData cfd;
cfd.data = ProjectDataManagement::VulnerabilityState_def::LightDamage;
cfd.text = tr("Wounded / Damaged");
cfd.icon = m_tactStatusYellow;
cfc.data.push_back(std::move(cfd));
}
fill(ProjectDataManagement::VulnerabilityState_def::CatastrophicKill, m_tactStatusRed);
fill(ProjectDataManagement::VulnerabilityState_def::NotReady, m_tactStatusOrange);
return cfc.toVariant();
}
if (section == ColPosition)
{
LtsWidgets::ComboboxFilterContent cfc;
cfc.data.reserve(2);
LtsWidgets::ComboboxFilterData cfd;
cfd.data = QVariant(false);
cfd.text = tr("Valid positions");
cfc.data.push_back(cfd);
cfd.data = QVariant(true);
cfd.text = tr("Outdated positions");
cfc.data.push_back(cfd);
return cfc.toVariant();
}
if (section == ColType)
{
LtsWidgets::ComboboxFilterContent cfc;
cfc.data.reserve(m_usedTypeIds.size());
LtsWidgets::ComboboxFilterData cfd;
for (const int typeId : m_usedTypeIds)
{
cfd.data = typeId;
cfd.text = ParticipantManagement::trTypeName(m_types.value(typeId).name());
cfc.data.push_back(cfd);
}
cfc.sortItems = true;
return cfc.toVariant();
}
}
return LtsWidgets::LtsAbstractTableModel<PlayerData>::headerData(section, orientation, role);
}
QVariant BasePlayerModel::data(const QModelIndex &index, int role) const
{
if (!indexIsValid(index))
return QVariant();
if (role != Qt::DisplayRole &&
role != Qt::DecorationRole &&
role != Qt::BackgroundRole &&
role != Qt::ToolTipRole &&
role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
return QVariant();
const PlayerData &data = m_vecData.at(index.row());
if (role == Qt::DecorationRole)
{
switch (index.column())
{
case ColParty:
return m_parties.value(data.partyId).icon;
case ColEquipmentNummer:
return decorationData(index, data.participantId);
case ColTacticalStatus:
{
switch (data.vulnerabilityState.underlying())
{
case ProjectDataManagement::VulnerabilityState::NotReady:
return m_tactStatusOrange;
case ProjectDataManagement::VulnerabilityState::CombatReady:
return m_tactStatusGreen;
case ProjectDataManagement::VulnerabilityState::CatastrophicKill:
return m_tactStatusRed;
default:
return m_tactStatusYellow;
}
}
default:
break;
}
}
if (role == Qt::ToolTipRole)
{
switch (index.column())
{
case ColTacticalStatus:
return data.vulnerabilityStateStr;
default:
break;
}
}
if (role == Qt::BackgroundRole)
{
if (data.typeId <= 0)
return QVariant();
switch (index.column())
{
case ColEquipmentNummer:
if (data.isManipulated)
return QColor(Qt::red);
break;
case ColPosition:
if (data.isOutdated)
return QColor(Qt::red);
break;
case ColBitResult:
if (data.biteSampleTime > 0 &&
data.biteSampleTime < (m_session->partitionTime() - (2 * 60 *1000)) ) //<- so 2 minutes
return (QColor(Qt::gray));
break;
default:
break;
}
return QVariant();
}
if (role == Qt::DisplayRole)
{
switch (index.column())
{
case ColEquipmentNummer:
if (data.equipmentNumber)
return data.equipmentNumber;
return QVariant();
case ColParticipantId:
return data.participantId;
case ColParty:
return data.partyStr;
case ColHierachy:
return data.hierarchy;
case ColDesignator:
return data.designator;
case ColTacticalIdentifier:
return data.tacticalIdentifier;
case ColSign:
return data.identification;
case ColType:
return data.typeName;
case ColTacticalStatus:
return QVariant(); // only per tooltip and decoration role
case ColPosition:
return data.positionStr;
case ColPositionAge:
if (data.participantId < 0 || data.positionSampleTime < 0)
return QStringLiteral("-");
return QStringLiteral("%1s").arg(calculatePositionAge(data.positionSampleTime));
case ColBitResult:
return data.biteResultStr;
case ColWarnings:
return data.biteWarningsStr;
}
}
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
{
switch (index.column())
{
case ColParty:
return data.partyId;
case ColTacticalStatus:
{
switch (data.vulnerabilityState.underlying())
{
case ProjectDataManagement::VulnerabilityState::NotReady:
case ProjectDataManagement::VulnerabilityState::CombatReady:
case ProjectDataManagement::VulnerabilityState::CatastrophicKill:
return data.vulnerabilityState.underlying();
default:
break;
}
return ProjectDataManagement::VulnerabilityState_def::LightDamage;
}
case ColPosition:
return data.isOutdated;
case ColType:
return data.typeId;
default:
break;
}
}
return QVariant();
}
QString BasePlayerModel::getBitResult(const ParticipantManagement::Bite &bite, int equipmnetNumber) const
{
if (bite.equipmentNumber() != equipmnetNumber)
return QString();
const QString bitErrors = m_biteModel->getBitErrors(bite);
return (bitErrors.isEmpty() ? tr("Ok") : bitErrors);
}
QString BasePlayerModel::getBiteWarnings(const ParticipantManagement::Bite &bite, int equipmnetNumber) const
{
if (bite.equipmentNumber() != equipmnetNumber)
return QString();
const QString s1(m_biteModel->getLowBattery(bite.batteryState()));
const QString s2(m_biteModel->getComponents(bite));
QStringList ret;
if (!s1.isEmpty())
ret << s1;
if (!s2.isEmpty())
ret << s2;
if (bite.configError())
ret << tr("Config Error");
return ret.isEmpty() ? QStringLiteral("-") : ret.join(QStringLiteral(", "));
}
QString BasePlayerModel::getPositionString(const ParticipantManagement::ParticipantPosition &position,
int participantId) const
{
if (position.participantId() != participantId)
return QStringLiteral("-");
QString mgrs = LtsCoordTrans::mgrsFromGeographic(position.pos().lon(),
position.pos().lat());
if (!qFuzzyIsNull(position.pos().z()))
mgrs.append(QStringLiteral(" ") + QString::number(position.pos().z(), 'f', 2));
return mgrs;
}
void BasePlayerModel::updateBitResult(int participantId, const QString &result)
{
setBiteResult(findRowForId(participantId),
QDateTime::currentMSecsSinceEpoch(),
result,
QString());
}
QString BasePlayerModel::getBitResult(int participantId) const
{
const int row = findRowForId(participantId);
if (row < 0)
return QString();
return m_vecData.at(row).biteResultStr;
}
void BasePlayerModel::removeItems(const QModelIndexList &indexes)
{
if (indexes.count() == rowCount())
{
clear();
return;
}
QVector<int> idsToRemove;
idsToRemove.reserve(indexes.size());
// not in one loop since removeRow invalidates the indexes
for (const QModelIndex &idx : indexes)
{
const int id = m_vecData.at(idx.row()).participantId;
idsToRemove.append(id);
}
for (int id : idsToRemove)
removeRow(findRowForId(id));
}
void BasePlayerModel::updateUsedPartyIds()
{
m_usedPartyIds.clear();
m_usedTypeIds.clear();
for (const PlayerData &p : qAsConst(m_vecData))
{
m_usedPartyIds[p.partyId] = p.partyId;
m_usedTypeIds += p.typeId;
}
}
void BasePlayerModel::setBiteResult(int row, qint64 sampleTime, const QString &biteResult, const QString &warnings)
{
if (row < 0 || row >= m_vecData.size())
return;
auto &playerData = m_vecData[row];
playerData.biteSampleTime = sampleTime;
playerData.biteResultStr = biteResult;
playerData.biteWarningsStr = warnings;
const auto idxBiteResult(index(row, ColBitResult));
const auto idxBiteWarnings(index(row, ColWarnings));
emit dataChanged(idxBiteResult, idxBiteResult, {Qt::DisplayRole, Qt::BackgroundRole});
emit dataChanged(idxBiteWarnings, idxBiteWarnings, {Qt::DisplayRole});
}
int BasePlayerModel::getParticipantId(const QModelIndex &idx) const
{
if (!indexIsValid(idx))
return 0;
return m_vecData.at(idx.row()).participantId;
}
int BasePlayerModel::findRowForEquipmentNumber(int equipNo) const
{
for (int i = 0; i < m_vecData.size(); ++i)
{
const auto &data = m_vecData.at(i);
if (!data.equipmentNumber)
continue;
if (data.equipmentNumber == equipNo)
{
DEBUG_LOG(m_logger) << "** findRowForEquipmentNumber: "
<< equipNo << "--> " << i;
return i;
}
}
return -1;
}
void BasePlayerModel::onDynamicParticipantChanged(const ParticipantManagement::DynamicParticipantData &data,
DataModification modType)
{
DEBUG_LOG(m_logger) << "**** onDynamicParticipantChanged: " << data;
int row = findRowForId(data.participantId());
if (row < 0)
{
row = findRowForId(-data.participantId());
if (row < 0)
return;
if (modType == DataModification::eAdded)
modType = DataModification::eModified;
}
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
PlayerData playerData = getRowData(row);
const auto oldSymbol = playerData.symbolStr;
playerData.isManipulated = data.manipulation().size();
const auto tactStatus = getTacticalStatus(data);
playerData.vulnerabilityState = tactStatus.vulnerabilityState();
playerData.vulnerabilityStateStr = vulnerabilityStateString(playerData.typeClass,
playerData.vulnerabilityState);
setRowData(row, playerData);
if (oldSymbol != playerData.symbolStr)
{
tryRenderSymbol(playerData.symbolStr,
playerData.participantId,
playerData.partyColor,
playerData.partyRole);
}
break;
}
case DataModification::eRemoved:
removeRow(row);
break;
}
}
void BasePlayerModel::onParticipantChanged(const ParticipantManagement::Participant &participant,
DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
int row = -1;
auto it = m_participants.find(participant.id());
if (it == m_participants.end())
{
if (participant.equipmentNumber().is_set())
row = findRowForId(-participant.equipmentNumber().get());
if (row < 0)
{
// unknown player, add for maybe later usage
m_participants.insert(participant.id(), participant);
return;
}
it = m_participants.insert(participant.id(), ParticipantManagement::Participant());
}
const auto old = it.value();
it.value() = participant;
if (row < 0)
row = findRowForId(participant.id());
if (row < 0 && participant.equipmentNumber().is_set())
row = findRowForId(-participant.equipmentNumber().get());
if (row < 0)
return;
if (old.equipmentNumber() != participant.equipmentNumber() ||
old.partyId() != participant.partyId() ||
old.superiorId() != participant.superiorId() ||
old.designator() != participant.designator() ||
old.tacticalIdentifier() != participant.tacticalIdentifier() ||
old.info() != participant.info() ||
old.symbol() != participant.symbol() ||
old.identification() != participant.identification())
{
const auto party = m_parties.value(participant.partyId());
const auto type = m_types.value(participant.typeId());
PlayerData &data = m_vecData[row];
// color
data.partyColor = party.color;
// int
data.equipmentNumber = participant.equipmentNumber().is_set() ? participant.equipmentNumber().get() : 0;
data.participantId = participant.id();
data.partyId = participant.partyId();
data.typeId = participant.typeId();
// str
data.designator = QString::fromStdString(participant.designator());
data.hierarchy = m_ppmDtc->hierarchyFromParticipant(data.participantId, m_participants);
data.info = QString::fromStdString(participant.info());
data.partyStr = party.name;
data.symbolStr = QString::fromStdString(participant.symbol());
data.tacticalIdentifier = QString::fromStdString(participant.tacticalIdentifier());
data.typeName = type.id() > 0 ? ParticipantManagement::trTypeName(type.name()) : tr("Unknown (%1)").arg(participant.typeId());
data.identification = QString::fromStdString(participant.identification());
tryRenderSymbol(data.symbolStr,
data.participantId,
data.partyColor,
data.partyRole);
emit dataChanged(createIndex(row, 0), createIndex(row, ColWarnings));
}
}
PlayerData BasePlayerModel::setPlayerData(int participantId,
const ParticipantManagement::DynamicParticipantData &dp)
{
return setPlayerData(m_participants.value(participantId), dp);
}
PlayerData BasePlayerModel::setPlayerData(const ParticipantManagement::Participant &participant,
const ParticipantManagement::DynamicParticipantData &dp)
{
const auto bite = participant.equipmentNumber().is_set()
? m_bites.value(participant.equipmentNumber().get())
: ParticipantManagement::Bite();
const auto party = m_parties.value(participant.partyId());
const auto pos = m_positions.value(participant.id());
const auto type = m_types.value(participant.typeId());
const auto tactStatus = getTacticalStatus(dp);
PlayerData data;
// int64
data.biteSampleTime = bite.sampleTime();
data.positionSampleTime = pos.sampleTime();
// color
data.partyColor = party.color;
// enum
data.vulnerabilityState = tactStatus.vulnerabilityState();
data.typeClass = type.typeClass();
data.partyRole = party.role;
// int
data.equipmentNumber = participant.equipmentNumber().is_set() ? participant.equipmentNumber().get() : 0;
data.participantId = participant.id();
data.partyId = participant.partyId();
data.typeId = participant.typeId();
// bool
data.isManipulated = dp.manipulation().size();
data.isOutdated = LtsUtils::isPositionTimeOutdated(m_partitionTime, data.positionSampleTime);
// str
data.biteResultStr = getBitResult(bite, data.equipmentNumber);
data.biteWarningsStr = getBiteWarnings(bite, data.equipmentNumber);
data.designator = QString::fromStdString(participant.designator());
data.hierarchy = m_ppmDtc->hierarchyFromParticipant(data.participantId, m_participants);
data.info = QString::fromStdString(participant.info());
data.partyStr = party.name;
data.positionStr = getPositionString(pos, data.participantId);
data.symbolStr = QString::fromStdString(participant.symbol());
data.tacticalIdentifier = QString::fromStdString(participant.tacticalIdentifier());
data.typeName = type.id() > 0 ? ParticipantManagement::trTypeName(type.name()) : tr("Unknown (%1)").arg(participant.typeId());
data.vulnerabilityStateStr = vulnerabilityStateString(type.typeClass(),
tactStatus.vulnerabilityState());
data.identification = QString::fromStdString(participant.identification());
tryRenderSymbol(data.symbolStr,
data.participantId,
data.partyColor,
data.partyRole);
return data;
}
/**
* @brief BasePlayerModel::getPositionAge
* get the position age of a player in given row
* @param row of a specific player
* @return position age of specific player
* @see calculatePositionAge(const long long sampleTime)
*/
qint64 BasePlayerModel::getPositionAge(const int row) const
{
const PlayerData &data = m_vecData.at(row);
return calculatePositionAge(data.positionSampleTime);
}
/**
* @brief BasePlayerModel::calculatePositionAge
* calculates the position age
* @param sampleTime of a specific player
* @return position age
* @see getPositionAge(const int row)
*/
qint64 BasePlayerModel::calculatePositionAge(qint64 sampleTime) const
{
return (m_partitionTime - sampleTime) / 1000;
}
ParticipantManagement::StateInformation BasePlayerModel::getTacticalStatus(const ParticipantManagement::DynamicParticipantData &data) const
{
return m_ppmDtc->youngestStateInformation(data.stateHistory());
}
void BasePlayerModel::onPositionChanged(const ParticipantManagement::ParticipantPosition &position,
DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
DEBUG_LOG(m_logger) << "**** onPositionChanged: " << position;
m_positions[position.participantId()] = position;
int row = findRowForId(position.participantId());
if (row < 0)
{
row = findRowForId(-position.participantId());
if (row < 0)
return;
}
if ((modType == DataModification::eAdded) ||
(modType == DataModification::eModified))
{
auto &playerData = m_vecData[row];
playerData.positionSampleTime = position.sampleTime();
playerData.positionStr = getPositionString(position, position.participantId());
playerData.isOutdated = false;
const auto idxPosition(index(row, ColPosition));
const auto idxPositionAge(index(row, ColPositionAge));
emit dataChanged(idxPosition, idxPosition, {Qt::DisplayRole, Qt::BackgroundRole});
emit dataChanged(idxPositionAge, idxPositionAge, {Qt::DisplayRole});
}
}
void BasePlayerModel::onBiteChanged(const ParticipantManagement::Bite &bite,
DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
DEBUG_LOG(m_logger) << "**** onBiteChanged: " << bite;
m_bites[bite.equipmentNumber()] = bite;
int row = findRowForEquipmentNumber(bite.equipmentNumber());
if (row < 0)
return;
if ((modType == DataModification::eAdded) ||
(modType == DataModification::eModified))
{
setBiteResult(row,
bite.sampleTime(),
getBitResult(bite, bite.equipmentNumber()),
getBiteWarnings(bite, bite.equipmentNumber()));
}
}
void BasePlayerModel::onPartyChanged(const ParticipantManagement::Party &party,
DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
SmoParty smoParty;
smoParty.id = party.id();
smoParty.name = ParticipantManagement::trPartyName(party.name());
smoParty.color = QColor::fromRgb(QRgb(party.color()));
smoParty.role = AdvancedSymbology::roleToRole(party.role());
if (m_ppmGuiCbxIfc)
smoParty.icon = m_ppmGuiCbxIfc->pixmapFromParty(smoParty.color);
m_parties[smoParty.id] = smoParty;
}
void BasePlayerModel::onPartitionTimeChanged(qint64 newPartitionTime)
{
m_partitionTime = newPartitionTime;
}
void BasePlayerModel::onTimeoutCheck()
{
for (int i = 0; i < m_vecData.size(); ++i)
{
const auto &data = m_vecData.at(i);
if (data.isOutdated)
continue;
if (LtsUtils::isPositionTimeOutdated(m_partitionTime, data.positionSampleTime))
{
m_vecData[i].isOutdated = true;
const QModelIndex idx(index(i, ColPosition, QModelIndex()));
emit dataChanged(idx, idx, {Qt::BackgroundRole});
}
}
}
void BasePlayerModel::onUpdatePositionAge()
{
for (int i = 0; i < m_vecData.size(); ++i)
{
const QModelIndex idx(index(i, ColPositionAge, QModelIndex()));
emit dataChanged(idx, idx, {Qt::DisplayRole});
}
}
QString BasePlayerModel::vulnerabilityStateString(ParticipantManagement::TypeClass typeClass,
ProjectDataManagement::VulnerabilityState vulState) const
{
const ProjectDataManagement::VulnerabilityClass vc = typeClass == ParticipantManagement::TypeClass::Human ?
ProjectDataManagement::VulnerabilityClass_def::SoldierInjuries :
ProjectDataManagement::VulnerabilityClass_def::VehicleDamages;
return ProjectDataManagement::toString(vulState, vc);
}
void BasePlayerModel::onTypeChanged(const ParticipantManagement::Type &type,
DataModification modType)
{
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
m_types[type.id()] = type;
bool bNeedUpdate = false;
for (auto &data : m_vecData)
{
if (data.typeId != type.id())
continue;
data.typeClass = type.typeClass();
data.typeName = ParticipantManagement::trTypeName(type.name());
bNeedUpdate = true;
}
if (bNeedUpdate)
emit dataChanged(index(0, ColType), index(rowCount() - 1, ColType), {Qt::DisplayRole});
break;
}
case DataModification::eRemoved:
m_types.remove(type.id());
break;
}
}
bool BasePlayerModel::isPartyId(int row, int partyId) const
{
if (row < 0 || row >= m_vecData.size())
return false;
const auto &data = m_vecData.at(row);
return data.partyId == partyId;
}
bool BasePlayerModel::isTypeClass(int row, const ParticipantManagement::TypeClass &tc) const
{
if (row < 0 || row >= m_vecData.size())
return false;
const auto &data = m_vecData.at(row);
return data.typeClass == tc;
}
//
// BasePlayerProxyModel
//
void BasePlayerProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
m_sourceModel = qobject_cast<BasePlayerModel*>(sourceModel);
LtsColumnFilterProxyModel::setSourceModel(sourceModel);
}
bool BasePlayerProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!m_sourceModel ||
source_left.column() != source_right.column() ||
source_left.row() < 0 || source_left.row() >= m_sourceModel->m_vecData.size() ||
source_right.row() < 0 || source_right.row() >= m_sourceModel->m_vecData.size()
)
return LtsColumnFilterProxyModel::lessThan(source_left, source_right);
const PlayerData &left = m_sourceModel->m_vecData.at(source_left.row());
const PlayerData &right = m_sourceModel->m_vecData.at(source_right.row());
switch (source_left.column())
{
case BasePlayerModel::ColParticipantId:
return left.participantId < right.participantId;
case BasePlayerModel::ColEquipmentNummer:
if (!left.equipmentNumber && !right.equipmentNumber)
return left.participantId < right.participantId;
if (!left.equipmentNumber)
return true;
if (!right.equipmentNumber)
return false;
return left.equipmentNumber < right.equipmentNumber;
case BasePlayerModel::ColParty:
return left.partyId < right.partyId;
case BasePlayerModel::ColDesignator:
{
const int iRet = left.designator.compare(right.designator);
if (left.designator == right.designator)
return left.participantId < right.participantId;
return iRet < 0;
}
case BasePlayerModel::ColSign:
{
const int iRet = left.info.compare(right.info);
if (iRet == 0)
return left.participantId < right.participantId;
return iRet < 0;
}
case BasePlayerModel::ColType:
return left.typeId < right.typeId;
case BasePlayerModel::ColTacticalStatus:
return left.vulnerabilityState < right.vulnerabilityState;
case BasePlayerModel::ColPositionAge:
return m_sourceModel->getPositionAge(source_left.row()) < m_sourceModel->getPositionAge(source_right.row());
case BasePlayerModel::ColHierachy:
case BasePlayerModel::ColPosition:
case BasePlayerModel::ColBitResult:
case BasePlayerModel::ColWarnings:
// QString compare
return source_left.data() < source_right.data();
};
return LtsColumnFilterProxyModel::lessThan(source_left, source_right);
}
} // namespace ServiceMonitor
@@ -0,0 +1,194 @@
/**
* @RDE_HEADER@
* Base Model for Equipment Check
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-06-07
*/
#pragma once
#include <LtsWidgets/lts_abstract_table_model.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
#include <LtsSession/lts_session_data_dds.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
#include <Plugins/AdvancedSymbology/Helper/table_model_symbol_renderer.h>
#include <QSet>
class QTimer;
namespace ServiceMonitor
{
struct PlayerData
{
QString biteResultStr;
QString biteWarningsStr;
QString designator;
QString hierarchy;
QString info;
QString partyStr;
QString positionStr;
QString symbolStr;
QString tacticalIdentifier;
QString typeName;
QString vulnerabilityStateStr;
QString identification;
qint64 biteSampleTime = 0;
qint64 positionSampleTime = 0;
QColor partyColor;
ProjectDataManagement::VulnerabilityState vulnerabilityState;
ParticipantManagement::TypeClass typeClass;
AdvancedSymbology::Role partyRole;
int equipmentNumber = 0;
int participantId = 0;
int partyId = 0;
int typeId = 0;
bool isManipulated = false;
bool isOutdated = false;
int id() const { return participantId; }
};
class BiteModel;
// --------------------------------------------------------
// BasePlayerModel
// --------------------------------------------------------
class BasePlayerModel : public LtsWidgets::LtsAbstractTableModel<PlayerData>
, public AdvancedSymbology::TableModelSymbolRenderer<BasePlayerModel>
{
Q_OBJECT
friend class AdvancedSymbology::TableModelSymbolRenderer<BasePlayerModel>;
struct SmoParty
{
QString name;
QColor color;
QIcon icon;
AdvancedSymbology::Role role = AdvancedSymbology::Role(0);
int id = 0;
};
public:
enum Columns
{
ColParticipantId,
ColEquipmentNummer,
ColParty,
ColHierachy,
ColDesignator,
ColTacticalIdentifier,
ColSign,
ColType,
ColTacticalStatus,
ColPosition,
ColPositionAge,
ColBitResult,
ColWarnings
};
explicit BasePlayerModel(QObject *parent = nullptr);
virtual bool initModel(LtsSession::LtsSessionDataDds *session);
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void updateBitResult(int participantId, const QString &result);
QString getBitResult(int participantId) const;
void removeItems(const QModelIndexList &indexes);
virtual QStringList getAllParticipantIds() const { return QStringList(); }
int getParticipantId(const QModelIndex &idx) const;
bool isPartyId(int row, int partyId) const;
bool isTypeClass(int row, const ParticipantManagement::TypeClass &tc) const;
qint64 getPositionAge(const int row) const;
public Q_SLOTS:
// return added participantIds
virtual QVector<int> updateDataView(const QVector<int> &equipNoList) = 0;
virtual void loadData(const QVector<int> &idList) = 0;
protected slots:
void onDynamicParticipantChanged(const ParticipantManagement::DynamicParticipantData &data,
DataModification modType);
void onParticipantChanged(const ParticipantManagement::Participant &data,
DataModification modType);
void onPositionChanged(const ParticipantManagement::ParticipantPosition &position,
DataModification modType);
void onBiteChanged(const ParticipantManagement::Bite &bite,
DataModification modType);
void onPartyChanged(const ParticipantManagement::Party &party,
DataModification modType);
void onTypeChanged(const ParticipantManagement::Type &type,
DataModification modType);
void onPartitionTimeChanged(qint64 newPartitionTime);
void onTimeoutCheck();
void onUpdatePositionAge();
protected:
void updateUsedPartyIds();
void setBiteResult(int row, qint64 sampleTime, const QString &biteResult, const QString &warnings);
QString getBitResult(const ParticipantManagement::Bite &bite, int equipmnetNumber) const;
QString getBiteWarnings(const ParticipantManagement::Bite &bite, int equipmnetNumber) const;
QString getPositionString(const ParticipantManagement::ParticipantPosition &position,
int participantId) const;
PlayerData setPlayerData(const int participantId,
const ParticipantManagement::DynamicParticipantData &dp);
PlayerData setPlayerData(const ParticipantManagement::Participant &participant,
const ParticipantManagement::DynamicParticipantData &dp);
qint64 calculatePositionAge(qint64 sampleTime) const;
ParticipantManagement::StateInformation getTacticalStatus(
const ParticipantManagement::DynamicParticipantData &data) const;
int findRowForEquipmentNumber(int equipNo) const;
QString vulnerabilityStateString(ParticipantManagement::TypeClass typeClass,
ProjectDataManagement::VulnerabilityState vulState) const;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmGuiCbxIfc;
BiteModel *m_biteModel;
QHash<int, ParticipantManagement::Type> m_types;
QHash<int, SmoParty> m_parties;
QHash<int, ParticipantManagement::Bite> m_bites;
QMap<int, ParticipantManagement::Participant> m_participants;
QHash<int, ParticipantManagement::ParticipantPosition> m_positions;
QMap<int, int> m_usedPartyIds; // keep sorted
QSet<int> m_usedTypeIds;
QIcon m_tactStatusGreen;
QIcon m_tactStatusYellow;
QIcon m_tactStatusOrange;
QIcon m_tactStatusRed;
qint64 m_partitionTime;
QTimer *m_timeoutCheckTimer;
QTimer *m_positionAgeTimer;
LtsSession::LtsSessionDataDds *m_session;
NGL::INGLLogger &m_logger;
friend class BasePlayerProxyModel;
};
class BasePlayerProxyModel : public LtsWidgets::LtsColumnFilterProxyModel
{
Q_OBJECT
public:
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
void setSourceModel(QAbstractItemModel *sourceModel) override;
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
protected:
BasePlayerModel *m_sourceModel = nullptr;
};
} //namespace ServiceMonitor
+314
View File
@@ -0,0 +1,314 @@
/**
* @RDE_HEADER@
* Model for Bite Message
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-04
*/
#include "smo_bite_model.h"
#include <LtsSession/lts_session_data.h>
#include <Common/logger.h>
#include <ngltools/ngltools_dtg.h>
#include <ProjectDataManagement/pdm_dtc.h>
namespace ServiceMonitor
{
BiteModel::BiteModel(QObject *parent)
: LtsWidgets::LtsAbstractTableModel<ParticipantManagement::Bite>({tr("Time of Receipt"),
tr("Equip. No."),
tr("BIT Error"),
tr("Low Battery"),
tr("Component")},
parent)
, m_logger(getLogger("BiteModel"))
{}
bool BiteModel::initModel(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc)
{
DEBUG_LOG(m_logger) << "initModel";
m_ppmDtc = ppmDtc;
if (!m_ppmDtc)
return false;
m_pdmDtc = pdmDtc;
if (!m_pdmDtc)
return false;
m_ccsMap = pdmDtc->canComponentStrings();
m_bctMap = pdmDtc->biteComponentTexts();
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::biteChanged,
this, &BiteModel::biteDataChanged);
m_ppmDtc->bites([this](const ParticipantManagement::Bite &bite) { insertRow(bite); } );
return true;
}
QVariant BiteModel::data(const QModelIndex &index, int role) const
{
if (role != Qt::DisplayRole || !indexIsValid(index))
return QVariant();
const ParticipantManagement::Bite &biteMsg = m_vecData.at(index.row());
switch (index.column())
{
case ReceiveTime:
return QDateTime::fromMSecsSinceEpoch(biteMsg.sampleTime());
case EquipmentNummer:
return biteMsg.equipmentNumber();
case BitError:
return getBitErrors(biteMsg);
case LowBattery:
return getLowBattery(biteMsg.batteryState());
case Component:
return getComponents(biteMsg);
}
return QVariant();
}
bool BiteModel::isFiltered(const ParticipantManagement::Bite &data, DataModification modType) const
{
Q_UNUSED(modType);
return data.biteState() == data.configState() &&
!data.configError() &&
data.batteryState() == 0 &&
data.biteErrors().size() == 0;
}
QString BiteModel::getBitErrors(const ParticipantManagement::Bite &bite) const
{
QStringList errorString;
errorString.reserve(8);
for (int i = 0; i < 32; i++)
{
quint32 bitValue = 1U << i;
QString val = checkBit(bite, bitValue);
if (!val.isEmpty())
errorString += val;
}
return errorString.join(QLatin1Char(','));
}
QString BiteModel::checkBit(const ParticipantManagement::Bite &bite, quint32 bitValue) const
{
bool available = (bite.biteState() & bitValue) == bitValue;
bool statusOk = (bite.configState() & bitValue) == bitValue;
QString name;
for (const ProjectDataManagement::CanComponentString &ccs : m_ccsMap)
{
if (ccs.bitMask() == bitValue)
{
name = m_pdmDtc->trCanComponentStringName(ccs.id());
break;
}
}
DEBUG_LOG(m_logger) << "** name: " << name;
QString ret;
if (available)
{
if (!statusOk)
ret = name;
}
else if (statusOk)
ret = name + tr("(COM)");
return ret;
}
QString BiteModel::getLowBattery(int batteryState) const
{
// Check the battery state to battery warnings (bit 0 to 7)
QStringList errorString;
errorString.reserve(2);
for (int i = 0; i < 8; i++)
{
quint32 bitValue = 1U << i;
const QString val = checkBatteryBit(batteryState, bitValue);
if (!val.isEmpty())
errorString += val;
}
return errorString.join(QLatin1Char(';'));
}
QString BiteModel::checkBatteryBit(int state, qint64 bitValue) const
{
QString name;
for (const ProjectDataManagement::CanComponentString &ccs : m_ccsMap)
{
// The devices to locate the battery warning are coded in the table as
// bit 32 to 39
qint64 compareValue = (bitValue << 32);
if (ccs.bitMask() == compareValue)
{
name = m_pdmDtc->trCanComponentStringName(ccs.id());
break;
}
}
DEBUG_LOG(m_logger) << "** name: " << name;
if ((state & bitValue) == bitValue)
return name;
return QString();
}
QString BiteModel::getComponents(const ParticipantManagement::Bite &bite) const
{
QStringList errorString;
for (const auto &bitError : bite.biteErrors())
{
if (bitError.errorNumber() == 0)
continue;
errorString += getErrorString(bitError);
}
return errorString.join(QLatin1Char(';'));
}
QString BiteModel::getCanDeviceName(int id) const
{
for (const ProjectDataManagement::CanComponentString &ccs : m_ccsMap)
{
if (ccs.canDeviceId() == id)
return m_pdmDtc->trCanComponentStringName(ccs.id());
}
return tr("Unknown Can device (%1)").arg(id);
}
QString BiteModel::getSubDeviceName(int id) const
{
for (const ProjectDataManagement::CanComponentString &ccs : m_ccsMap)
{
if (ccs.subDeviceId() == id)
return m_pdmDtc->trCanComponentStringName(ccs.id());
}
return tr("Unknown subdevice (%1)").arg(id);
}
QString BiteModel::getErrorString(const ParticipantManagement::BiteError &error) const
{
QString errString;
const bool subDevice = (error.subdeviceNumber() != 0);
for (const ProjectDataManagement::BiteComponentText &bct : m_bctMap)
{
if (((subDevice && bct.subDeviceId() == error.subdeviceNumber()) ||
(bct.canDeviceId() == error.canDeviceNumber())) &&
(bct.errorNumber() == error.errorNumber()))
{
errString = m_pdmDtc->trBiteComponentTextName(bct.id());
break;
}
}
if (errString.isEmpty())
errString = tr("Unknown error (%1)").arg(error.errorNumber());
QString subErrString;
if (subDevice)
subErrString = QLatin1Char('-') +
getSubDeviceName(error.subdeviceNumber()) +
QLatin1Char('-') +
QString::number( error.uniqueId(), 16 ).toUpper();
//QString::number(error.uniqueId());
return tr("Error: %1 - Device: %2 %3").arg(errString, getCanDeviceName(error.canDeviceNumber()), subErrString);
}
int BiteModel::findRowForEquipmentNumber(int equipNo) const
{
for (int i = 0; i < m_vecData.size(); ++i)
{
if (m_vecData.at(i).equipmentNumber() == equipNo)
{
DEBUG_LOG(m_logger) << "findRowForEquipmentNumber: "
<< equipNo << "-->" << i;
return i;
}
}
return -1;
}
void BiteModel::biteDataChanged(const ParticipantManagement::Bite &data,
DataModification modType)
{
DEBUG_LOG(m_logger) << "biteDataChanged";
const int equipNo = data.equipmentNumber();
const int row = findRowForEquipmentNumber(equipNo);
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
DEBUG_LOG(m_logger) << " Modified bite msg";
if (row < 0)
{
insertRow(data);
return;
}
if (isFiltered(data, modType))
{
if (row >= m_vecData.size())
return;
removeRow(row);
return;
}
setRowData(row, data);
break;
}
case DataModification::eRemoved:
{
DEBUG_LOG(m_logger) << " Remove bite msg";
removeRow(row);
break;
}
}
}
//
// BiteProxyModel
//
void BiteProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
m_sourceModel = qobject_cast<BiteModel*>(sourceModel);
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(sourceModel);
}
bool BiteProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!m_sourceModel ||
source_left.column() != source_right.column() ||
!source_left.isValid() ||
!source_right.isValid())
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
const auto &dataLeft = m_sourceModel->m_vecData.at(source_left.row());
const auto dataRight = m_sourceModel->m_vecData.at(source_right.row());
switch (source_left.column())
{
case BiteModel::ReceiveTime:
return dataLeft.sampleTime() < dataRight.sampleTime();
case BiteModel::EquipmentNummer:
return dataLeft.equipmentNumber() < dataRight.equipmentNumber();
case BiteModel::BitError:
case BiteModel::LowBattery:
case BiteModel::Component:
break;
}
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
}
} // namespace ServiceMonitor
+95
View File
@@ -0,0 +1,95 @@
/**
* @RDE_HEADER@
* Model for Bite Message
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-04
*/
#pragma once
#include <LtsWidgets/lts_abstract_table_model.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
#include <ParticipantManagement/ppm_dtc.h>
namespace ProjectDataManagement {
namespace Interface {
class Dtc;
}
}
#include <Common/logger.h>
namespace ServiceMonitor
{
// --------------------------------------------------------
// BiteModel
// --------------------------------------------------------
class BiteModel final : public LtsWidgets::LtsAbstractTableModel<ParticipantManagement::Bite>
{
Q_OBJECT
public:
enum Columns
{
ReceiveTime,
EquipmentNummer,
BitError,
LowBattery,
Component,
};
explicit BiteModel(QObject *parent = nullptr);
bool initModel(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc);
QString getBitErrors(const ParticipantManagement::Bite &bite) const;
QString getLowBattery(int batteryState) const;
QString getComponents(const ParticipantManagement::Bite &bite) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool isFiltered(const ParticipantManagement::Bite &data, DataModification modType) const override final;
private slots:
void biteDataChanged(const ParticipantManagement::Bite &data,
DataModification modType);
private:
QString checkBit(const ParticipantManagement::Bite &bite,
quint32 bitValue) const;
QString checkBatteryBit(int state, qint64 bitValue) const;
int findRowForEquipmentNumber(int equipNo) const;
QString getCanDeviceName(int id) const;
QString getSubDeviceName(int id) const;
QString getErrorString(const ParticipantManagement::BiteError &error) const;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
QMap<qint32, ProjectDataManagement::CanComponentString> m_ccsMap;
QMap<qint32, ProjectDataManagement::BiteComponentText> m_bctMap;
NGL::INGLLogger &m_logger;
friend class BiteProxyModel;
};
class BiteProxyModel final : public LtsWidgets::LtsColumnFilterProxyModel
{
Q_OBJECT
public:
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
void setSourceModel(QAbstractItemModel *sourceModel) override;
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
private:
BiteModel *m_sourceModel = nullptr;
};
} //namespace ServiceMonitor
@@ -0,0 +1,322 @@
/**
* @RDE_HEADER@
* Check Button Handler (for Equipment Check)
* $Id$
* $HeadURL$
* $Author$
* Created by Norbert Thoden, NLE, 2019-02-06
*/
#include "smo_check_button_handler.h"
#include <LtsUtilsSettings/settings.h>
#include <ProjectDataManagement/pdm_to_string.h>
#include <LtsSession/lts_session_data.h>
#include <QMenu>
#include <QAction>
namespace LtsDataView
{
class LtsDataView;
}
namespace ServiceMonitor
{
CheckButtonHandler::CheckButtonHandler(QPushButton *checkBtn)
: QObject(checkBtn)
, m_checkBtn(checkBtn)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_resetManipulation(new QAction(tr("Manipulation"), this))
, m_rearmWeapons(new QAction(tr("Gear Charge"), this))
, m_resetSanMat(new QAction(tr("Reset Medical Supplies"), this))
, m_resetAndRearm(new QAction(tr("Both"), this))
, m_resetAndRearmAndSanMat(new QAction(tr("All"), this))
, m_actionMenu(nullptr)
, m_menuReset(nullptr)
, m_menuTacticalState(nullptr)
, m_menuVitality(nullptr)
{
if (m_checkBtn)
{
m_actionMenu = m_checkBtn->menu();
if (!m_actionMenu)
{
m_actionMenu = new QMenu(m_checkBtn);
m_checkBtn->setMenu(m_actionMenu);
}
}
m_pvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"),
QStringLiteral("HasPvSan"));
}
void CheckButtonHandler::setPpm(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc)
{
m_ppmDtc = ppmDtc;
m_ppmFtc = ppmFtc;
}
void CheckButtonHandler::addReset()
{
if (!m_actionMenu || m_menuReset)
return;
m_menuReset = m_actionMenu->addMenu(tr("Reset"));
m_menuReset->addAction(m_resetManipulation);
m_menuReset->addAction(m_rearmWeapons);
m_menuReset->addAction(m_resetAndRearm);
if (m_pvSan)
{
m_menuReset->addAction(m_resetSanMat);
m_menuReset->addAction(m_resetAndRearmAndSanMat);
}
connect(m_resetManipulation, &QAction::triggered,
this, [this]() { sendInitRequest(m_selectedParticipants, true, false, false, false);});
connect(m_rearmWeapons, &QAction::triggered,
this, [this]() { sendInitRequest(m_selectedParticipants, false, true, false, false);});
connect(m_resetSanMat, &QAction::triggered,
this, [this]() { sendInitRequest(m_selectedParticipants, false, false, false, true);});
connect(m_resetAndRearm, &QAction::triggered,
this, [this]() { sendInitRequest(m_selectedParticipants, true, true, false, false);});
connect(m_resetAndRearmAndSanMat, &QAction::triggered,
this, [this]() { sendInitRequest(m_selectedParticipants, true, true, false, true);});
}
void CheckButtonHandler::addTacticalState()
{
if (!m_actionMenu || m_menuTacticalState || m_menuVitality)
return;
m_menuTacticalState = m_actionMenu->addMenu(tr("Tactical State"));
m_vbgs.reserve(13);
// CombatReady without contamination
ProjectDataManagement::VulnerabilityState vs = ProjectDataManagement::VulnerabilityState_def::CombatReady;
QAction *a1 = new QAction(ProjectDataManagement::toString(vs) + tr(" (Bldg: without cont. reset)"), m_menuTacticalState);
m_vbgs += a1;
m_menuTacticalState->addAction(a1);
connect(m_vbgs.last(), &QAction::triggered,
this, [this]() { sendInitRequest(m_selectedParticipants, false, false, true, false);});
// signal signal connection for MapObjectSelectionWidget to reset building also:
connect(m_vbgs.last(), &QAction::triggered, this, &CheckButtonHandler::combatReadyRequested);
// CombatReady with contamination reset
vs = ProjectDataManagement::VulnerabilityState_def::CombatReady;
QAction *a2 = new QAction(ProjectDataManagement::toString(vs) + tr(" (Bldg: with cont. reset)"), m_menuTacticalState);
m_vbgs += a2;
m_menuTacticalState->addAction(a2);
connect(m_vbgs.last(), &QAction::triggered,
this, [this]() { sendInitRequest(m_selectedParticipants, false, false, true, false);});
// signal signal connection for MapObjectSelectionWidget to reset building also:
connect(m_vbgs.last(), &QAction::triggered, this, &CheckButtonHandler::combatReadyResetContamintationRequested);
// No VulnerabilityChange, only contamination reset
vs = ProjectDataManagement::VulnerabilityState_def::NoChange;
QAction *a3 = new QAction( tr("Contamination reset only"), m_menuTacticalState);
m_vbgs += a3;
m_menuTacticalState->addAction(a3);
// signal signal connection for MapObjectSelectionWidget to reset building also:
connect(m_vbgs.last(), &QAction::triggered, this, &CheckButtonHandler::resetContaminationRequested);
for (int i = 1; i <= 9; ++i) // 9 == VulnerabilityState_def::TemporarySeverance
{
ProjectDataManagement::VulnerabilityState vs(static_cast<ProjectDataManagement::VulnerabilityState_def::type>(i));
QAction *ac = new QAction(ProjectDataManagement::toString(vs), m_menuTacticalState);
m_vbgs += ac;
m_menuTacticalState->addAction(ac);
if (i == static_cast<int>(ProjectDataManagement::VulnerabilityState_def::CombatReady)) // CombatReady = 0
{
connect(m_vbgs.last(), &QAction::triggered,
this, [this]() { sendInitRequest(m_selectedParticipants, false, false, true, false);});
// signal signal connection for MapObjectSelectionWidget to reset building also:
connect(m_vbgs.last(), &QAction::triggered, this, &CheckButtonHandler::combatReadyRequested);
} else {
connect(m_vbgs.last(), &QAction::triggered,
this, [this, vs]() { sendModifyState(m_selectedParticipants, vs);});
}
}
if (m_pvSan)
{
m_menuVitality = m_menuTacticalState->addMenu(tr("Vitality"));
for (int i = 9; i > 1; i--)
{
QAction *a = new QAction(QString::number(i * 10));
a->setData(i * 10);
connect(a, &QAction::triggered,
this, [this, i]() { sendModifyVitality(m_selectedParticipants, i * 10);});
m_menuVitality->addAction(a);
}
}
}
void CheckButtonHandler::onCallBiteReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
}
void CheckButtonHandler::onInitParticipantReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
}
void CheckButtonHandler::onModifyStateReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
}
void CheckButtonHandler::sendInitRequest(const std::vector<int> &selectedIds,
bool resetManipulation,
bool restockCharges,
bool resetVulnerabilityState,
bool restockSanMat)
{
// keep enableForBuildingReset in mind!
if (selectedIds.size() == 0)
return;
// qCritical() << " sendInitRequest " << selectedIds.size();
if (!resetManipulation && !restockCharges && !resetVulnerabilityState && !restockSanMat)
return;
ParticipantManagement::InitParticipantRequest req;
req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId());
req.participantIds(selectedIds);
req.resetManipulation(resetManipulation);
req.restockCharges(restockCharges);
req.resetVulnerabilityState(resetVulnerabilityState);
req.restockSanitationMaterial(restockSanMat);
m_requestHelper->startSingleRequest([req, this]() { return m_ppmFtc->initParticipantRequest(req, this); });
}
void CheckButtonHandler::sendModifyState(const std::vector<int> &selectedIds,
ProjectDataManagement::VulnerabilityState vs)
{
// keep enableForBuildingReset in mind!
if (selectedIds.size() == 0)
return;
ParticipantManagement::ModifyStateRequest req;
req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId());
req.participantIds(selectedIds);
req.vulnerabilityState(vs);
m_requestHelper->startSingleRequest([req, this]() { return m_ppmFtc->modifyStateRequest(req, this); });
}
void CheckButtonHandler::sendModifyVitality(const std::vector<int> &selectedIds, int vitality)
{
// keep enableForBuildingReset in mind!
if (selectedIds.size() == 0)
return;
ParticipantManagement::ModifyStateRequest req;
req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId());
req.participantIds(selectedIds);
req.vitality(vitality);
m_requestHelper->startSingleRequest([req, this]() { return m_ppmFtc->modifyStateRequest(req, this); });
}
std::vector<int> CheckButtonHandler::setSelectedParticipantIds(const std::vector<int> &selectedParticipantsIds)
{
m_selectedParticipants.clear();
if (!m_ppmDtc)
return {};
const QMap<qint32, ParticipantManagement::Participant> &participants = m_ppmDtc->participants();
const QMap<qint32, ParticipantManagement::Type> &types = m_ppmDtc->types();
bool hasOC = false;
bool hasSoldier = false;
bool hasVehicles = false;
for (const auto &participantId : selectedParticipantsIds)
{
auto partIter = participants.constFind(participantId);
if (partIter == participants.constEnd())
continue;
const ParticipantManagement::Participant &part = partIter.value();
// check equipmentNumber:
if (!part.equipmentNumber().is_set() || part.equipmentNumber().get() < 0)
continue;
// check type:
int typeId = part.typeId();
auto typeIter = types.constFind(typeId);
if (typeIter == types.constEnd())
continue;
const ParticipantManagement::TypeClass &tc = typeIter.value().typeClass();
m_selectedParticipants.push_back(partIter.key());
if (!hasSoldier)
hasSoldier = (tc == ParticipantManagement::TypeClass_def::Human);
if (!hasVehicles)
hasVehicles = (tc != ParticipantManagement::TypeClass_def::Human &&
tc != ParticipantManagement::TypeClass_def::SupportEntity);
if (!hasOC)
hasOC = (tc == ParticipantManagement::TypeClass_def::SupportEntity);
}
const bool enable = m_selectedParticipants.size() != 0;
setMenueResetVisible(enable && !hasOC);
setMenueTactStateVisible(enable && !hasOC, hasSoldier, hasVehicles);
m_checkBtn->setToolTip(tr("%1 relevant objects").arg(m_selectedParticipants.size()));
return m_selectedParticipants;
}
void CheckButtonHandler::enableForBuildingReset_OfMapObjectSelectionWidget()
{
// [NLDEVCTRL-1357] MASIE-60: Zurücksetzen Gebäude über VorauswahlDialog - auch wenn nur Bldgs selektiert sind.
// following setEnabled/setVisible should be overwritten next time (setSelectedParticipantIds)
if (m_menuTacticalState)
m_menuTacticalState->setEnabled(true);
if (!m_vbgs.isEmpty())
{
m_vbgs.at(0)->setVisible(true);
m_vbgs.at(1)->setVisible(true);
m_vbgs.at(2)->setVisible(true);
}
}
void CheckButtonHandler::setMenueResetVisible(bool visi)
{
if (m_menuReset)
m_menuReset->setEnabled(visi);
m_resetManipulation->setVisible(visi);
m_rearmWeapons->setVisible(visi);
m_resetSanMat->setVisible(visi && m_pvSan);
m_resetAndRearmAndSanMat->setVisible(visi && m_pvSan);
m_resetAndRearm->setVisible(visi);
}
void CheckButtonHandler::setMenueTactStateVisible(bool visi, bool hasSoldier, bool hasVehicles)
{
if (m_menuTacticalState)
m_menuTacticalState->setEnabled(visi);
m_resetManipulation->setVisible(visi);
m_rearmWeapons->setVisible(visi);
m_resetAndRearm->setVisible(visi);
for (auto *a : qAsConst(m_vbgs))
a->setVisible(visi);
if (visi && hasSoldier)
{
m_vbgs.at(1)->setVisible(false);
m_vbgs.at(2)->setVisible(false);
m_vbgs.at(6)->setVisible(false);
m_vbgs.at(7)->setVisible(false);
}
if (m_menuTacticalState && m_pvSan)
m_menuVitality->setEnabled(hasSoldier && !hasVehicles);
}
} // namespace ServiceMonitor
@@ -0,0 +1,98 @@
/**
* @RDE_HEADER@
* Check Button Handler (for Equipment Check)
* $Id$
* $HeadURL$
* $Author$
* Created by Norbert Thoden, NLE, 2019-02-06
*/
#pragma once
#include <Plugins/ServiceMonitor/Gui/Monitors/smocheckbuttonhandler_export.h>
#include <ParticipantManagement/ppm_dtc.h>
#include <ParticipantManagement/ppm_ftc.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <LtsWidgets/lts_dialog.h>
#include <QMenu>
#include <QAction>
namespace LtsDataView
{
class LtsDataView;
}
namespace ServiceMonitor
{
class SMOCHECKBUTTONHANDLER_EXPORT CheckButtonHandler : public QObject
, protected ParticipantManagement::Interface::Ftc::CallBiteReplyHandler
, protected ParticipantManagement::Interface::Ftc::InitParticipantReplyHandler
, protected ParticipantManagement::Interface::Ftc::ModifyStateReplyHandler
{
Q_OBJECT
public:
explicit CheckButtonHandler(QPushButton *checkBtn);
void setPpm(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc);
void addReset();
void addTacticalState();
void onCallBiteReply(const Core::FunctionReplyObject &replyObject) override final;
void onInitParticipantReply(const Core::FunctionReplyObject &replyObject) override final;
void onModifyStateReply(const Core::FunctionReplyObject &replyObject) override final;
void sendInitRequest(const std::vector<int> &selectedIds,
bool resetManipulation,
bool restockCharges,
bool resetVulnerabilityState,
bool restockSanMat);
void sendModifyState(const std::vector<int> &selectedIds,
ProjectDataManagement::VulnerabilityState vs);
void sendModifyVitality(const std::vector<int> &selectedIds,
int vitality);
std::vector<int> setSelectedParticipantIds(const std::vector<int> &selectedParticipantsIds);
void enableForBuildingReset_OfMapObjectSelectionWidget();
Q_SIGNALS:
void combatReadyRequested();
void combatReadyResetContamintationRequested();
void resetContaminationRequested();
private:
void setMenueResetVisible(bool visi);
void setMenueTactStateVisible(bool visi, bool hasSoldier, bool hasVehicles);
private:
QPushButton *m_checkBtn;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc;
LtsUtils::RequestHelper *m_requestHelper;
std::vector<int> m_selectedParticipants;
bool m_pvSan;
QAction *m_resetManipulation;
QAction *m_rearmWeapons;
QAction *m_resetSanMat;
QAction *m_resetAndRearm;
QAction *m_resetAndRearmAndSanMat;
QVector<QAction *> m_vbgs;
QMenu *m_actionMenu;
QMenu *m_menuReset;
QMenu *m_menuTacticalState;
QMenu *m_menuVitality;
};
// class CheckButtonHandler
} // namespace ServiceMonitor
@@ -0,0 +1,305 @@
/**
* @RDE_HEADER@
* Model for Fehlermeldung GFD Message
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-06-29
*/
#include "smo_ctas_error_model.h"
#include <LtsSession/lts_session_data.h>
#include <ngltools/ngltools_dtg.h>
#include <Common/logger.h>
#include <ProjectDataManagement/pdm_translation.h>
#include <TrainingAreaBase/training_area_telegrams.h>
namespace ServiceMonitor
{
CtasErrorModel:: CtasErrorModel(QObject *parent)
: LtsWidgets::LtsAbstractTableModel<ParticipantManagement::CtaError>(
{
tr("Time of Receipt"),
tr("Equip. No."),
tr("Time (PU)"),
tr("Origin"),
tr("Telegram Identification")
},
parent)
, m_ppmDtc(nullptr)
, m_logger(getLogger("CtasErrorModel"))
{}
bool CtasErrorModel::initModel(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc)
{
DEBUG_LOG(m_logger) << "initModel";
if (!ppmDtc)
return false;
m_ppmDtc = ppmDtc;
m_ppmDtc->ctaErrors([this](const ParticipantManagement::CtaError &error) {insertRow(error);});
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::ctaErrorChanged,
this, &CtasErrorModel::ctasErrorChanged);
return true;
}
QVariant CtasErrorModel::data(const QModelIndex &index, int role) const
{
if (role != Qt::DisplayRole || !indexIsValid(index))
return QVariant();
const ParticipantManagement::CtaError &error = m_vecData.at(index.row());
switch (index.column())
{
case ReceiveTime:
return QDateTime::fromMSecsSinceEpoch(error.timeReceipt());
case EquipmentNummer:
return error.equipmentNumber();
case TimePlayerUnit:
return QDateTime::fromMSecsSinceEpoch(error.timePlayerUnit());
case ErrorReason:
return ProjectDataManagement::toString(error.errorReason());
case TelegramId:
return telegramId2Text(error.telegramId());
}
return QVariant();
}
// Telegram list see zsksxdgt.x telegramm_id_et
QString CtasErrorModel::telegramId2Text(int id) const
{
using namespace TrainingAreaBase::TetraIcd;
enum TelegramId telId = static_cast<enum TelegramId>(id);
switch (telId)
{
case UNKNOWN:
return tr("UNKNOWN");
case BESTAETIGUNG:
return tr("BESTAETIGUNG");
case INIT:
return tr("INIT");
case MANIPULATIONSMELDUNG:
return tr("MANIPULATIONSMELDUNG");
case UMGEBUNGS_MELDUNG2:
return tr("UMGEBUNGS_MELDUNG2");
case AUFFORDERUNG_BITE_MELDUNG:
return tr("AUFFORDERUNG_BITE_MELDUNG");
case BITE_MELDUNG2:
return tr("BITE_MELDUNG2");
case BETRIEBSZUSTAND_AUSSTATTUNG:
return tr("BETRIEBSZUSTAND_AUSSTATTUNG");
case KONFIGURATION_WIRKMODELL:
return tr("KONFIGURATION_WIRKMODELL");
case ANFORDERUNG_KONFIGURATIONSDATEN:
return tr("ANFORDERUNG_KONFIGURATIONSDATEN");
case KONFIGURATIONSMELDUNG:
return tr("KONFIGURATIONSMELDUNG");
case FEHLERMELDUNG_GFD:
return tr("FEHLERMELDUNG_GFD");
case WIEDERHERSTELLUNG_FUNKBEREITSCHAFT:
return tr("WIEDERHERSTELLUNG_FUNKBEREITSCHAFT");
case POSITIONS_MELDUNG:
return tr("POSITIONS_MELDUNG");
case POSITIONS_MELDUNG_MIT_TEILNEHMER:
return tr("POSITIONS_MELDUNG_MIT_TEILNEHMER");
case POSITIONS_MELDUNG_LFZ:
return tr("POSITIONS_MELDUNG_LFZ");
case IPS_POSITIONSDATEN:
return tr("IPS_POSITIONSDATEN");
case WIRKFELD_EINZELGESCHOSS:
return tr("WIRKFELD_EINZELGESCHOSS");
case WIRKFELD_FLAECHENDECKENDES_FEUER:
return tr("WIRKFELD_FLAECHENDECKENDES_FEUER");
case WIRKFELD_FLAECHENDECKENDES_FEUER_STOP:
return tr("WIRKFELD_FLAECHENDECKENDES_FEUER_STOP");
case WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN:
return tr("WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN");
case WIRKFELD_MINENSPERRE:
return tr("WIRKFELD_MINENSPERRE");
case WIRKFELD_STATUS_MINENSPERRE:
return tr("WIRKFELD_STATUS_MINENSPERRE");
case WIRKFELD_A_KAMPFMITTEL:
return tr("WIRKFELD_A_KAMPFMITTEL");
case WIRKFELD_C_KAMPFMITTEL:
return tr("WIRKFELD_C_KAMPFMITTEL");
case DEAKTIVIERUNG_WIRKFELD:
return tr("DEAKTIVIERUNG_WIRKFELD");
case WIRKFELD_AENDERUNG_BEZEICHNER:
return tr("WIRKFELD_AENDERUNG_BEZEICHNER");
case DEAKTIVIERUNG_EINZELMINE:
return tr("DEAKTIVIERUNG_EINZELMINE");
case REAKTIVIERUNG_DUS_MINE:
return tr("REAKTIVIERUNG_DUS_MINE");
case DEFINITION_IED:
return tr("DEFINITION_IED");
case ZUSTAND_IED:
return tr("ZUSTAND_IED");
case STATUS_EINZELMINENSIMULATOR:
return tr("STATUS_EINZELMINENSIMULATOR");
case WIRKFELD_EINZELMINENSIMULATOR:
return tr("WIRKFELD_EINZELMINENSIMULATOR");
case TREFFER_EREIGNIS_DUS:
return tr("TREFFER_EREIGNIS_DUS");
case TREFFER_EREIGNIS_WIRKSIMULATION:
return tr("TREFFER_EREIGNIS_WIRKSIMULATION");
case TREFFER_AUSLOESUNG:
return tr("TREFFER_AUSLOESUNG");
case SCHIEDSRICHTEREINGRIFF:
return tr("SCHIEDSRICHTEREINGRIFF");
case SELEKTIVE_AUFMUNITIONIERUNG:
return tr("SELEKTIVE_AUFMUNITIONIERUNG");
case TREFFER_EREIGNIS_SEKUNDAERWIRKUNG:
return tr("TREFFER_EREIGNIS_SEKUNDAERWIRKUNG");
case TREFFER_EREIGNIS_DUS_IPS:
return tr("TREFFER_EREIGNIS_DUS_IPS");
case TREFFER_EREIGNIS_WIRKSIMULATION_IPS:
return tr("TREFFER_EREIGNIS_WIRKSIMULATION_IPS");
case TAKTISCHER_STATUS:
return tr("TAKTISCHER_STATUS");
case FUNKTIONSRAUM:
return tr("FUNKTIONSRAUM");
case EINTRETEN_FUNKTIONSRAUM:
return tr("EINTRETEN_FUNKTIONSRAUM");
case DEAKTIVIEREN_FUNKTIONSRAUM:
return tr("DEAKTIVIEREN_FUNKTIONSRAUM");
case DATENVERKEHR_SRT_TDS:
return tr("DATENVERKEHR_SRT_TDS");
case DATENVERKEHR_TDS_SRT:
return tr("DATENVERKEHR_TDS_SRT");
case DATENVERKEHR_DMF_TDS:
return tr("DATENVERKEHR_DMF_TDS");
case DATENVERKEHR_TDS_DMF:
return tr("DATENVERKEHR_TDS_DMF");
case NACHFORDERUNG_BROADCAST_TELEGRAMME:
return tr("NACHFORDERUNG_BROADCAST_TELEGRAMME");
case SONDERSENSORIK_FAHRSPUR:
return tr("SONDERSENSORIK_FAHRSPUR");
case SONDERSENSORIK_MIVANH_VERLEGEDATEN:
return tr("SONDERSENSORIK_MIVANH_VERLEGEDATEN");
case SONDERSENSORIK_WMIV_VERLEGEDATEN:
return tr("SONDERSENSORIK_WMIV_VERLEGEDATEN");
case SONDERSENSORIK_MIVANH_VERLEGEPOSITION:
return tr("SONDERSENSORIK_MIVANH_VERLEGEPOSITION");
case SPRACHAUSWAHL:
return tr("SPRACHAUSWAHL");
case ALLGEMEINE_NACHRICHT:
return tr("ALLGEMEINE_NACHRICHT");
case GERAETEEREIGNIS:
return tr("GERAETEEREIGNIS");
case WAFFENZUORDNUNG:
return tr("WAFFENZUORDNUNG");
case MUNITIONSVORRAT_EINER_ZUGEORDNETEN_WAFFE:
return tr("MUNITIONSVORRAT_EINER_ZUGEORDNETEN_WAFFE");
case FEUEREREIGNIS_MIT_WAFFENZUORDNUNG:
return tr("FEUEREREIGNIS_MIT_WAFFENZUORDNUNG");
case AUSLOESUNG_DUS_TREFFER:
return tr("AUSLOESUNG_DUS_TREFFER");
case ANFORDERUNG_SW_VERSION:
return tr("ANFORDERUNG_SW_VERSION");
case SW_VERSIONSMELDUNG:
return tr("SW_VERSIONSMELDUNG");
case TECHNIK_FUNKTIONSRAUM:
return tr("TECHNIK_FUNKTIONSRAUM");
case TEILNEHMERMODE_SETZEN:
return tr("TEILNEHMERMODE_SETZEN");
case TEILNEHMERMODE_MELDUNG:
return tr("TEILNEHMERMODE_MELDUNG");
case TEILNEHMERMODE_ANFORDERN:
return tr("TEILNEHMERMODE_ANFORDERN");
case TEILNEHMER_KONFIG_ANTWORT:
return tr("TEILNEHMER_KONFIG_ANTWORT");
case TEILNEHMER_KONFIG_SETZEN:
return tr("TEILNEHMER_KONFIG_SETZEN");
case TEILNEHMER_KONFIG_ANFORDERN:
return tr("TEILNEHMER_KONFIG_ANFORDERN");
case NOTRUF:
return tr("NOTRUF");
case BETRIEBSZUSTANDSMELDUNG:
return tr("BETRIEBSZUSTANDSMELDUNG");
case ANFORDERUNG_STATISTIK_BROADCAST_NACHFORDERUNGEN:
return tr("ANFORDERUNG_STATISTIK_BROADCAST_NACHFORDERUNGEN");
case STATISTIK_BROADCAST_NACHFORDERUNGEN:
return tr("STATISTIK_BROADCAST_NACHFORDERUNGEN");
case EXERCISE_EQUIPMENT_ASSIGNMENT_COMPLETE:
return tr("EXERCISE_EQUIPMENT_ASSIGNMENT_COMPLETE");
case SANITAETSDIENST_INSTANDSETZUNG:
return tr("SANITATION");
case SANITAETSDIENST_INSTANDSETZUNG_PVSAN:
return tr("SANITATION_PVSAN");
case BESTANDSMELDUNG_SANITAETSMATERIAL:
return tr("SANITATION_MATERIAL_STOCK");
case PROXY_CONNECTION_STATE:
return tr("PROXY_CONNECTION_STATE");
case PARTICIPANT_LICENSE_CHANGE:
return tr("PARTICIPANT_LICENSE_CHANGE");
case WLS_PARTICIPANTS_STATE_REQUEST:
return tr("WLS_PARTICIPANTS_STATE_REQUEST");
case WLS_PARTICIPANTS_STATE_REPORT:
return tr("WLS_PARTICIPANTS_STATE_REPORT");
case WLS_BINARY_SFM_DATA:
return tr("WLS_BINARY_SFM_DATA");
case WLS_PARTICIPANT_CONNECTION_STATE:
return tr("WLS_PARTICIPANT_CONNECTION_STATE");
case SR_DMF_NACHRICHT:
return tr("SR_DMF_NACHRICHT");
}
return tr("Unknown telegram id: %1").arg(id);
}
void CtasErrorModel::ctasErrorChanged(const ParticipantManagement::CtaError &data,
DataModification modType)
{
DEBUG_LOG(m_logger) << "ctasErrorChanged";
if (modType == DataModification::eAdded || modType == DataModification::eModified)
{
DEBUG_LOG(m_logger) << " Added Fehlermeldung GFD";
insertRow(data);
return;
}
}
//
// CtasErrorProxyModel
//
void CtasErrorProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
m_sourceModel = qobject_cast<CtasErrorModel*>(sourceModel);
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(sourceModel);
}
bool CtasErrorProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!m_sourceModel ||
source_left.column() != source_right.column() ||
!source_left.isValid() ||
!source_right.isValid())
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
const auto &dataLeft = m_sourceModel->m_vecData.at(source_left.row());
const auto dataRight = m_sourceModel->m_vecData.at(source_right.row());
switch (source_left.column())
{
case CtasErrorModel::ReceiveTime:
return dataLeft.timeReceipt() < dataRight.timeReceipt();
case CtasErrorModel::EquipmentNummer:
return dataLeft.equipmentNumber() < dataRight.equipmentNumber();
case CtasErrorModel::TimePlayerUnit:
return dataLeft.timePlayerUnit() < dataRight.timePlayerUnit();
case CtasErrorModel::ErrorReason:
case CtasErrorModel::TelegramId:
break;
}
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
}
} // namespace ServiceMonitor
@@ -0,0 +1,68 @@
/**
* @RDE_HEADER@
* Model for Fehlermeldung GFD Message
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-06-29
*/
#pragma once
#include <LtsWidgets/lts_abstract_table_model.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
#include <ParticipantManagement/ppm_dtc.h>
#include <Common/logger.h>
namespace ServiceMonitor
{
// --------------------------------------------------------
// ServiceMonitorCtasErrorModel
// --------------------------------------------------------
class CtasErrorModel final : public LtsWidgets::LtsAbstractTableModel<ParticipantManagement::CtaError>
{
Q_OBJECT
public:
enum Columns
{
ReceiveTime,
EquipmentNummer,
TimePlayerUnit,
ErrorReason,
TelegramId,
};
explicit CtasErrorModel(QObject *parent = nullptr);
bool initModel(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
private slots:
void ctasErrorChanged(const ParticipantManagement::CtaError &data,
DataModification modType);
private:
QString telegramId2Text(int id) const;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
NGL::INGLLogger &m_logger;
friend class CtasErrorProxyModel;
};
class CtasErrorProxyModel final : public LtsWidgets::LtsColumnFilterProxyModel
{
Q_OBJECT
public:
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
void setSourceModel(QAbstractItemModel *sourceModel) override;
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
private:
CtasErrorModel *m_sourceModel = nullptr;
};
} //namespace ServiceMonitor
+419
View File
@@ -0,0 +1,419 @@
/**
* @RDE_HEADER@
* ServiceMonitor Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-04
*/
#include "smo_dialog.h"
#include "ui_smo_dialog.h"
#include <Common/logger.h>
#include "smo_egcu_model.h"
#include "smo_egcu_edit.h"
#include "smo_structure_element_edit.h"
#include <LtsSession/lts_session.h>
#include <LtsPrinting/printing.h>
#include <QTreeView>
#include <QMenu>
#include <QWidgetAction>
#include <QLabel>
#include <Common/PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/Buildings/bld_data_plugin_interface.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
namespace ServiceMonitor
{
ServiceMonitorDialog::ServiceMonitorDialog(Monitor monitor,
LtsSession::LtsSession *session,
QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
, m_session(session)
, m_ui(new Ui::ServiceMonitorDialog)
, m_monitor(monitor)
, m_proxyModel(nullptr)
, m_ppmDtc(nullptr)
, m_pdmDtc(nullptr)
, m_logger(getLogger("ServiceMonitorDialog"))
{
m_ui->setupUi(this);
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &ServiceMonitorDialog::onPrint);
if (m_monitor == Monitor::Bite)
setOnlineHelpFilename(QStringLiteral("Situation-BITE_Monitor"));
else if (m_monitor == Monitor::Manipulation)
setOnlineHelpFilename(QStringLiteral("Situation-Manipulation_Monitor"));
else if (m_monitor == Monitor::CtasError)
setOnlineHelpFilename(QStringLiteral("Situation-GFS_Telegram_Monitor"));
else if (m_monitor == Monitor::Egcu)
setOnlineHelpFilename(QStringLiteral("Situation-Effect_representation"));
}
ServiceMonitorDialog::~ServiceMonitorDialog()
{
onParticipantClicked(-1);
delete m_ui;
}
void ServiceMonitorDialog::retranslate()
{
QString text;
switch (m_monitor)
{
case Bite:
{
text = tr("BITE Monitor");
break;
}
case Manipulation:
{
text = tr("Manipulation Monitor");
break;
}
case CtasError:
{
text = tr("CTAS Error Monitor");
break;
}
case Egcu:
{
text = tr("Egcu Monitor");
break;
}
case Unset:
default:
{
break;
}
}
translate(m_ui, text);
}
bool ServiceMonitorDialog::init()
{
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
return false;
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(m_pdmDtc))
return false;
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(m_ismDtc))
return false;
delete m_proxyModel;
m_proxyModel = nullptr;
switch (m_monitor)
{
case Bite:
{
BiteModel *biteModel = new BiteModel(this);
biteModel->initModel(m_ppmDtc, m_pdmDtc);
m_proxyModel = new BiteProxyModel(this);
m_proxyModel->setSourceModel(biteModel);
break;
}
case Manipulation:
{
ManipulationModel *maniModel = new ManipulationModel(this);
maniModel->initModel(m_ppmDtc, m_pdmDtc);
m_proxyModel = new ManipulationProxyModel(this);
m_proxyModel->setSourceModel(maniModel);
break;
}
case CtasError:
{
CtasErrorModel *ctasErrorModel = new CtasErrorModel(this);
ctasErrorModel->initModel(m_ppmDtc);
m_proxyModel = new CtasErrorProxyModel(this);
m_proxyModel->setSourceModel(ctasErrorModel);
break;
}
case Egcu:
{
EgcuModel *egcuModel = new EgcuModel(this);
egcuModel->initModel(m_session);
m_proxyModel = new EgcuProxyModel(this);
m_proxyModel->setSourceModel(egcuModel);
m_ui->ltsDataView->setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(egcuModel, &EgcuModel::invalidateFilter, this, [this](const QModelIndex &mi)
{
Q_UNUSED(mi)
m_proxyModel->invalidate();
// This somehow does not work:
// m_ui->ltsDataView->treeView()->expand(mi);
m_ui->ltsDataView->treeView()->expandAll();
});
EgcuDelegate *treeDelegate = new EgcuDelegate(m_proxyModel);
m_ui->ltsDataView->treeView()->setItemDelegateForColumn(EgcuModel::Columns::Status, treeDelegate);
break;
}
case Unset:
default:
{
break;
}
}
if (!m_proxyModel)
return false;
m_ui->ltsDataView->setModel(m_proxyModel);
if (m_monitor == Egcu)
{
m_ui->ltsDataView->treeView()->expandAll();
m_ui->ltsDataView->hideColumn(EgcuModel::Barcode);
#ifndef LTS_DEBUG
m_ui->ltsDataView->hideColumn(EgcuModel::Id);
m_ui->ltsDataView->hideColumn(EgcuModel::Properties);
m_ui->ltsDataView->hideColumn(EgcuModel::Hostname);
#endif
m_ui->ltsDataView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::customContextMenuRequested, this, &ServiceMonitorDialog::onShowContextMenu);
m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &ServiceMonitorDialog::onEditItem);
m_buttonBox->connectButton(LtsWidgets::DialogButton::No, this, &ServiceMonitorDialog::onAllOff);
m_buttonBox->getButton(LtsWidgets::DialogButton::No)->setText(tr("All Off"));
m_buttonBox->connectButton(LtsWidgets::DialogButton::Yes, this, &ServiceMonitorDialog::onAllAuto);
m_buttonBox->getButton(LtsWidgets::DialogButton::Yes)->setText(tr("All Auto"));
onTableViewSelectionChanged({});
}
// connect signals of TableView:
connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::doubleClicked, this, &ServiceMonitorDialog::onTableViewClicked);
connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::selectionChanged, this, &ServiceMonitorDialog::onTableViewSelectionChanged);
return true;
}
// Not yet implemented:
void ServiceMonitorDialog::setSelectedStructureElements(const QVector<int> &structureElementIds, bool replace)
{
if (m_monitor != Monitor::Egcu)
return;
EgcuModel *em = qobject_cast<EgcuModel*>(m_ui->ltsDataView->sourceModel());
if (!em)
return;
QMap<int,QModelIndex> map = em->setSelectedStructureElements(structureElementIds);
if (map.isEmpty())
return;
m_ui->ltsDataView->setUpdatesEnabled(false);
if (replace)
m_ui->ltsDataView->clearSelection();
for (const auto index : map)
{
auto mappedIdx = m_proxyModel->mapFromSource(index);
m_ui->ltsDataView->selectRow(mappedIdx);
}
m_ui->ltsDataView->scrollTo(m_proxyModel->mapFromSource(map.first()));
m_ui->ltsDataView->setUpdatesEnabled(true);
}
void ServiceMonitorDialog::onShowContextMenu(const QPoint &position)
{
LtsDataView::LtsDataView *tv = qobject_cast<LtsDataView::LtsDataView *>(sender());
if (!tv)
return;
const QModelIndexList indexes = tv->selectedRows();
if (indexes.isEmpty())
return;
EgcuModel *em = qobject_cast<EgcuModel*>(m_ui->ltsDataView->sourceModel());
if (!em)
return;
QMenu menu;
em->getContextMenu(indexes, menu);
menu.exec(tv->mapToGlobal(position));
}
void ServiceMonitorDialog::onTableViewClicked(const QModelIndex &index)
{
if (m_monitor == Egcu)
{
EgcuModel *em = qobject_cast<EgcuModel*>(m_ui->ltsDataView->sourceModel());
if (!em)
return;
NGLTreeItem *item = em->privateData(index);
if (!item)
return;
if (item->data().canConvert<EgcuData>())
{
EgcuData ed = item->data().value<EgcuData>();
EgcuEdit *dlg = new EgcuEdit(menuGroup(), this);
if (dlg->init(ed, m_session))
addDialog(dlg, menuGroup(), dlg->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
else
delete dlg;
}
else if (item->data().canConvert<InfrastructureManagement::StructureElement>())
{
InfrastructureManagement::StructureElement se = item->data().value<InfrastructureManagement::StructureElement>();
StructureElementEdit *dlg = new StructureElementEdit(menuGroup(), this);
if (dlg->init(se, m_session))
addDialog(dlg, menuGroup(), dlg->dialogIdentifier(), LtsWidgets::LayoutArea::eDialogTab);
else
delete dlg;
}
}
TRACE_LOG(m_logger) << LOGFUNCTION << " START, index=" << index.row() << " - " << index.column();
if (!m_ui->ltsDataView->sourceModel())
return;
onParticipantClicked(participantId(index));
TRACE_LOG(m_logger) << LOGFUNCTION << " END, index=" << index.row() << " - " << index.column();
}
void ServiceMonitorDialog::onEditItem()
{
if (m_ui->ltsDataView->selectedRows().count() != 1)
return;
auto index = m_ui->ltsDataView->selectedRows().first();
onTableViewClicked(index);
}
void ServiceMonitorDialog::setAllOverrides(InfrastructureManagement::EffectOverride eo)
{
const QModelIndexList indexes = m_ui->ltsDataView->selectedRows();
if (indexes.isEmpty())
return;
EgcuModel *em = qobject_cast<EgcuModel*>(m_ui->ltsDataView->sourceModel());
if (!em)
return;
em->setAllOverrides(eo, indexes);
}
void ServiceMonitorDialog::onAllOff()
{
setAllOverrides(InfrastructureManagement::EffectOverride_def::PermanentOff);
}
void ServiceMonitorDialog::onAllAuto()
{
setAllOverrides(InfrastructureManagement::EffectOverride_def::Automatic);
}
void ServiceMonitorDialog::onTableViewSelectionChanged(const QItemSelection &selected)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (m_monitor == Monitor::Egcu)
{
// Only ONE selected row enables the EDIT Button. This row MUST be a Building or a MountingPoint (==EGCU)
bool ena = (m_ui->ltsDataView->selectedRows().count() == 1);
if (ena)
{
// Model Pointer will be valid. Where else does the SelectionChange come from?
EgcuModel *em = qobject_cast<EgcuModel*>(m_ui->ltsDataView->sourceModel());
auto type = em->getStructureElementType(m_ui->ltsDataView->selectedRows().first());
if (type != InfrastructureManagement::StructureElementType_def::Building &&
type != InfrastructureManagement::StructureElementType_def::MountingPoint)
ena = false;
}
m_buttonBox->getButton(LtsWidgets::DialogButton::Edit)->setEnabled(ena);
m_buttonBox->getButton(LtsWidgets::DialogButton::Yes)->setEnabled(m_ui->ltsDataView->selectedRows().count());
m_buttonBox->getButton(LtsWidgets::DialogButton::No)->setEnabled(m_ui->ltsDataView->selectedRows().count());
}
QModelIndexList mil = selected.indexes();
if (mil.isEmpty())
onParticipantClicked(-1); // -1 -> removeObjectIndicator
else
{
onParticipantClicked(participantId(mil.first()));
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void ServiceMonitorDialog::onParticipantClicked(int participantId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, participantId=" << participantId;
if (!m_session)
return;
std::shared_ptr<SituationMap::ForeignGuiInterface> sitMapGuiIfc;
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(sitMapGuiIfc);
if (!sitMapGuiIfc)
return;
if (participantId < 0)
sitMapGuiIfc->removeObjectIndicator();
else
if (!sitMapGuiIfc->objectIndicatorToParticipant(participantId))
ERROR_LOG(m_logger) << LOGFUNCTION << " objectIndicatorToParticipant failed for participantId = " << participantId;
TRACE_LOG(m_logger) << LOGFUNCTION << " END, participantId=" << participantId;
}
void ServiceMonitorDialog::leaveEvent(QEvent *e)
{
BaseClass::leaveEvent(e);
std::shared_ptr<SituationMap::ForeignGuiInterface> sitMapGuiIfc;
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(sitMapGuiIfc);
if (!sitMapGuiIfc)
return;
sitMapGuiIfc->removeObjectIndicator();
}
void ServiceMonitorDialog::onPrint()
{
LtsPrinting::printView(m_session, this, m_ui->ltsDataView->treeView() );
}
int ServiceMonitorDialog::participantId(const QModelIndex &index) const
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, index=" << index.row() << " - " << index.column();
if (!m_ui->ltsDataView->sourceModel())
return -1;
switch (m_monitor)
{
case Bite:
{
BiteModel *bm = qobject_cast<BiteModel*>(m_ui->ltsDataView->sourceModel());
if (bm)
{
const ParticipantManagement::Bite &bite = bm->getRowData(index.row());
return bite.participantId();
}
break;
}
case Manipulation:
{
ManipulationModel *mm = qobject_cast<ManipulationModel*>(m_ui->ltsDataView->sourceModel());
if (mm)
{
const ManipulationData &md = mm->getRowData(index.row());
return md.participantId;
}
break;
}
case Egcu:
case CtasError:
case Unset:
// currently not supported
break;
}
return -1;
}
void ServiceMonitorDialog::tableColumnOrganiserSetting()
{
//LtsColumnOrganiser
m_ui->ltsDataView->setColumnsOrganiserEnabled(identifier(), true);
}
} // namespace ServiceMonitor
+95
View File
@@ -0,0 +1,95 @@
/**
* @RDE_HEADER@
* ServiceMonitor Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-04
*/
#pragma once
#include "smo_bite_model.h"
#include "smo_manipulation_model.h"
#include "smo_ctas_error_model.h"
#include <InfrastructureManagement/ism_data_plugin_interface.h>
#include <ProjectDataManagement/pdm_data_plugin_interface.h>
#include <ParticipantManagement/ppm_data_plugin_interface.h>
#include <LtsWidgets/lts_dialog.h>
#include <Buildings/bld.hpp>
namespace Ui
{
class ServiceMonitorDialog;
}
namespace LtsSession
{
class LtsSession;
}
namespace ServiceMonitor
{
class EgcuModel;
class ServiceMonitorDialog : public LtsWidgets::LtsDialog
{
Q_OBJECT
using BaseClass = LtsWidgets::LtsDialog;
public:
enum Monitor
{
Bite,
Manipulation,
CtasError, // Fehlermeldung GFD
Egcu,
Unset,
};
explicit ServiceMonitorDialog(Monitor monitor,
LtsSession::LtsSession *session,
QWidget *parent = nullptr);
~ServiceMonitorDialog();
bool init();
// Not yet implemented:
void setSelectedStructureElements(const QVector<int> &structureElementIds, bool replace);
protected Q_SLOTS:
// TableView
void onTableViewClicked(const QModelIndex &index);
void onEditItem();
void onTableViewSelectionChanged(const QItemSelection &selected);
void onParticipantClicked(int participantId);
void leaveEvent(QEvent *e) override;
private slots:
void onAllOff();
void onAllAuto();
void onShowContextMenu(const QPoint &position);
private:
void setAllOverrides(InfrastructureManagement::EffectOverride eo);
void retranslate() override;
void onPrint();
int participantId(const QModelIndex &index) const;
void tableColumnOrganiserSetting() override;
LtsSession::LtsSession *m_session = nullptr;
Ui::ServiceMonitorDialog *m_ui = nullptr;
Monitor m_monitor = Monitor::Unset;
QSortFilterProxyModel *m_proxyModel;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
NGL::INGLLogger &m_logger;
};
}
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ServiceMonitorDialog</class>
<widget class="QWidget" name="ServiceMonitorDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>570</width>
<height>664</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">Bite Monitor</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="LtsDataView::LtsDataView" name="ltsDataView"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsDataView::LtsDataView</class>
<extends>QWidget</extends>
<header>LtsDataView/lts_data_view.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+351
View File
@@ -0,0 +1,351 @@
/**
* @RDE_HEADER@
* Edit the defaults for an EGCU
* $Id$
* $HeadURL$
* $Author$
* Created by Malte Diers, SLTE, 2021-05-10
*/
#include "smo_egcu_edit.h"
#include "ui_smo_egcu_edit.h"
#include <Common/logger.h>
#include <ServiceMonitor/smo_operator_rights.h>
// Lts
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <LtsUtilsGuiDds/request_helper.h>
// DDS
#include <AssetManagement/asm_data_plugin_interface.h>
#include <InfrastructureManagement/ism_data_plugin_interface.h>
// Qt
#include <QComboBox>
#include <QJsonDocument>
#include <QJsonArray>
#include <QSpacerItem>
namespace ServiceMonitor
{
EgcuEdit::EgcuEdit(const QString &menuGroup, QWidget *parent, LtsWidgets::ButtonCombination buttonCombination)
: LtsWidgets::LtsDialog(parent, buttonCombination)
, m_menuGroup(menuGroup)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_logger(getLogger(QLatin1String("EgcuEdit")))
, m_ui(new Ui::EgcuEdit)
{
m_ui->setupUi(this);
setOnlineHelpFilename(QStringLiteral("Situation-Effect_representation"));
}
bool EgcuEdit::init(const EgcuData &data, LtsSession::LtsSession *session)
{
m_egcuData = data;
std::shared_ptr<AssetManagement::Interface::Dtc> asmDtc;
if (!session->getDtc<AssetManagement::DataInterface>(asmDtc))
return false;
asmDtc->enableRelayInfo();
if (!session->getDtc<InfrastructureManagement::DataInterface>(m_ismDtc))
return false;
if (!session->getFtc<InfrastructureManagement::DataInterface>(m_ismFtc))
return false;
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mountingPointAssetChanged,
this, &EgcuEdit::onMountinPointAssetChanged);
QGridLayout *l = new QGridLayout(m_ui->relays);
m_ui->relays->setLayout(l);
auto cbRelayInfos = [this, l](const AssetManagement::RelayInfo &relayInfo)
{
QLabel *name = new QLabel(QString::fromStdString(relayInfo.name()), this);
QComboBox *cb = new QComboBox(this);
if (EgcuModel::readAllowance(InfrastructureManagement::EffectOverride_def::PermanentOn, relayInfo.property()))
cb->addItem(tr("On"), InfrastructureManagement::EffectOverride_def::PermanentOn);
if (EgcuModel::readAllowance(InfrastructureManagement::EffectOverride_def::PermanentOff, relayInfo.property()))
cb->addItem(tr("Off"), InfrastructureManagement::EffectOverride_def::PermanentOff);
cb->addItem(tr("Auto"), InfrastructureManagement::EffectOverride_def::Automatic);
l->addWidget(name, l->rowCount(), 0);
l->addWidget(cb, l->rowCount()-1, 1);
cb->setCurrentIndex(cb->findData(InfrastructureManagement::EffectOverride_def::Automatic));
m_relayCbs.insert(relayInfo.id(), cb);
};
asmDtc->waitForHistoricalDataRelayInfo();
asmDtc->relayInfos(cbRelayInfos);
l->addItem(new QSpacerItem(20, 210, QSizePolicy::Minimum, QSizePolicy::Expanding), l->rowCount(), 0);
m_ui->lblHostname->setText(QString::fromStdString(data.instrumentationAsset.hostname()));
m_ui->leSegmentName->setText(QString::fromStdString(data.mountingPointAsset.name().empty() ? data.instrumentationAsset.hostname() : data.mountingPointAsset.name()));
// Get Building MSE
// List all Floors/Rooms in TreeWidget
// Check Rooms in data.rooms
QMap<qint32, QTreeWidgetItem*> treemap;
const std::vector<InfrastructureManagement::StructureElement> &vecElements = data.mainStructureElement.elements();
for (const auto &se : vecElements)
{
if (se.structureElementTypeId() != InfrastructureManagement::StructureElementType_def::Floor)
continue;
QTreeWidgetItem *twi = new QTreeWidgetItem(m_ui->twRooms, {QString::fromStdString(se.displayName())});
twi->setFlags(twi->flags() | Qt::ItemIsAutoTristate | Qt::ItemIsUserCheckable);
twi->setCheckState(0, Qt::Unchecked);
treemap[se.id()] = twi;
}
// Identify building rooms and assign them to the correct floors by using map
for (const auto &se : vecElements)
{
if (se.structureElementTypeId() != InfrastructureManagement::StructureElementType_def::Room)
continue;
if (se.path().size() < 2) // Just for safety...
continue;
// ...as for rooms: path(): 0 = self, 1 = floor, 2 = building
const int floorId = se.path()[1];
if (!treemap.contains(floorId))
continue;
QTreeWidgetItem *floorItem = treemap[floorId];
QTreeWidgetItem *mountingPoint = new QTreeWidgetItem(floorItem, {QString::fromStdString(se.displayName())});
treemap.insert(se.id(), mountingPoint);
bool selected = data.rooms.contains(se.mountingPointId());
mountingPoint->setCheckState(0, selected ? Qt::Checked : Qt::Unchecked);
mountingPoint->setData(0, Qt::UserRole, se.mountingPointId());
if (selected)
floorItem->setExpanded(true);
}
connect(m_ui->twRooms, &QTreeWidget::itemChanged, this, &EgcuEdit::slotChangesMade);
m_ui->twRooms->header()->hide();
updateRelays();
bool editable = true; //LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::EgcuRoomsEdit);
if (!editable)
m_ui->twRooms->hide();
return true;
}
EgcuEdit::~EgcuEdit()
{
delete m_ui;
}
void EgcuEdit::updateRelays()
{
//QGridLayout *l = dynamic_cast<QGridLayout*>(m_ui->relays->layout());
InfrastructureManagement::StructureElement structureElement;
for (const auto &se : m_egcuData.mainStructureElement.elements())
{
if (se.id() == m_egcuData.mountingPoint.id())
{
structureElement = se;
break;
}
}
QJsonParseError parserError;
QByteArray content = QByteArray::fromStdString(structureElement.properties());
const QJsonDocument doc(QJsonDocument::fromJson(content, &parserError));
if (parserError.error != QJsonParseError::NoError)
return;
QJsonObject docObj = QJsonObject(doc.object());
if ( !docObj.contains(QStringLiteral("Overrides")))
return;
QJsonObject overridesObj = docObj.value(QStringLiteral("Overrides")).toObject();
QJsonArray arrRelays = overridesObj.value(QStringLiteral("relays")).toArray();
for (int i=0; i<arrRelays.size(); ++i)
{
QJsonObject objState = arrRelays[i].toObject();
QStringList relayIds = objState.keys();
QString relayIdString = relayIds.at(0);
int value = objState.value(relayIdString).toInt();
if (m_relayCbs.contains(relayIdString.toInt()))
m_relayCbs[relayIdString.toInt()]->setCurrentIndex(m_relayCbs[relayIdString.toInt()]->findData(value));
}
}
void EgcuEdit::onMountinPointAssetChanged(const InfrastructureManagement::MountingPointAsset &mpa, DataModification mod)
{
if (m_egcuData.mountingPointAsset.id() != mpa.id())
return;
if (mod == DataModification::eRemoved)
deleteLater();
}
QString EgcuEdit::dialogIdentifier() const
{
return QLatin1String("EgcuEdit") + QString::number(m_egcuData.instrumentationAsset.id());
}
void EgcuEdit::retranslate()
{
translate(m_ui, tr("Edit Segment: %1").arg(m_egcuData.segmentName()));
}
void EgcuEdit::getRoomIds(QTreeWidgetItem *twi, QVariantList &vl)
{
if (twi->checkState(0) == Qt::Checked)
vl << twi->data(0, Qt::UserRole);
for (int i=0; i<twi->childCount(); ++i)
getRoomIds(twi->child(i), vl);
}
void EgcuEdit::onMainStructureElementModifyReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
}
void EgcuEdit::onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
}
void EgcuEdit::onMountingPointAssetModifyReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
}
bool EgcuEdit::apply()
{
InfrastructureManagement::StructureElement structureElement;
std::string properties;
if (true) // LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::EgcuRoomsEdit))
{
if (!saveEgcuToRooms())
return false;
}
for (const auto &se : m_egcuData.mainStructureElement.elements())
{
if (se.id() == m_egcuData.mountingPoint.id())
{
structureElement = se;
break;
}
}
if (m_ui->leSegmentName->text() != QString::fromStdString(m_egcuData.mountingPointAsset.name()))
{
InfrastructureManagement::MountingPointAssetModifyRequest req;
InfrastructureManagement::MountingPointAsset &mpa = req;
mpa = m_egcuData.mountingPointAsset;
mpa.name(m_ui->leSegmentName->text().toStdString());
m_requestHelper->addRequest([this, req]() {return m_ismFtc->mountingPointAssetModifyRequest(req, this);});
}
properties= structureElement.properties();
DEBUG_LOG(m_logger) << "structureElementId=" << m_egcuData.mountingPoint.id()
<< " properties=" << properties;
QJsonArray arrRelays;
for (auto it = m_relayCbs.cbegin(); it != m_relayCbs.cend(); ++it)
{
QJsonObject objRelay;
if (it.value()->currentData().toInt() == InfrastructureManagement::EffectOverride_def::Automatic)
continue;
objRelay[QString::number(it.key())] = it.value()->currentData().toInt();
arrRelays.append(objRelay);
}
QJsonObject resultObj;
QJsonObject overrideObj;
if (arrRelays.size())
overrideObj.insert(QStringLiteral("relays"),arrRelays);
resultObj.insert (QStringLiteral("Overrides"), overrideObj);
QByteArray content_neu = QJsonDocument(resultObj).toJson(QJsonDocument::Compact);
structureElement.properties(content_neu.toStdString());
InfrastructureManagement::StructureElementModifyRequest request;
request.mainStructureElementId(m_egcuData.mainStructureElement.id());
request.elements().resize(1);
request.elements().at(0) = structureElement;
m_requestHelper->addRequest([this, request]() {return m_ismFtc->structureElementModifyRequest(request, this);});
m_requestHelper->startRequests();
return true;
}
bool EgcuEdit::saveEgcuToRooms()
{
QJsonParseError parserError;
QByteArray content = QByteArray::fromStdString(m_egcuData.mainStructureElement.properties());
const QJsonDocument doc(QJsonDocument::fromJson(content, &parserError));
if (parserError.error != QJsonParseError::NoError)
return false;
QJsonObject docObj = QJsonObject(doc.object());
QJsonArray arrEgcus = docObj.value(QStringLiteral("egcusToRooms")).toArray();
bool found = false;
for (int i=0; i<arrEgcus.size(); ++i)
{
QJsonObject objRooms = arrEgcus[i].toObject();
if (m_egcuData.mountingPoint.data().mountingPointId() != objRooms.value(QStringLiteral("mountpointEgcu")).toInt())
continue;
// This is only done once, if it is found, so don't worry about for-loop
found = true;
QVariantList roomIds;
getRoomIds(m_ui->twRooms->invisibleRootItem(), roomIds);
QJsonArray roomIdsArray = QJsonArray::fromVariantList(roomIds);
for ( int j = roomIdsArray.size() - 1 ; j >= 0 ; j-- )
{
QJsonValue val = roomIdsArray.at(j);
if ( val.toInt() == 0)
roomIdsArray.removeAt(j);
}
objRooms.insert(QLatin1String("rooms"), roomIdsArray);
arrEgcus.removeAt(i);
arrEgcus.insert(i, objRooms);
break;
}
if (!found)
{
QJsonObject objRooms;
QVariantList roomIds;
getRoomIds(m_ui->twRooms->invisibleRootItem(), roomIds);
objRooms.insert(QLatin1String("rooms"), QJsonArray::fromVariantList(roomIds));
objRooms.insert(QLatin1String("mountpointEgcu"), m_egcuData.mountingPoint.data().mountingPointId());
arrEgcus.append(objRooms);
}
docObj.insert(QStringLiteral("egcusToRooms"), arrEgcus);
content = QJsonDocument(docObj).toJson(QJsonDocument::Compact);
m_egcuData.mainStructureElement.properties(content.toStdString());
InfrastructureManagement::MainStructureElementModifyRequest request;
InfrastructureManagement::MainStructureElement &mse = request;
mse = m_egcuData.mainStructureElement;
m_requestHelper->addRequest([this, request]() {return m_ismFtc->mainStructureElementModifyRequest(request, this);});
return true;
}
} // namespace
+77
View File
@@ -0,0 +1,77 @@
/**
* @RDE_HEADER@
* Edit the defaults for an EGCU
* $Id$
* $HeadURL$
* $Author$
* Created by Malte Diers, SLTE, 2021-05-10
*/
#pragma once
#include "smo_egcu_model.h"
#include <InfrastructureManagement/ism_ftc.h>
#include <LtsWidgets/lts_dialog.h>
namespace Ui {
class EgcuEdit;
}
namespace LtsSession {
class LtsSession;
}
namespace LtsUtils {
class RequestHelper;
}
class QTreeWidgetItem;
namespace ServiceMonitor
{
class EgcuEdit
: public LtsWidgets::LtsDialog
, protected InfrastructureManagement::Interface::Ftc::MainStructureElementModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::StructureElementModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MountingPointAssetModifyReplyHandler
{
Q_OBJECT
public:
explicit EgcuEdit(const QString &menuGroup,
QWidget *parent = nullptr,
LtsWidgets::ButtonCombination buttonCombination = LtsWidgets::ButtonCombination::OkApplyCancel);
~EgcuEdit();
QString menuGroup() const { return m_menuGroup; }
QString dialogIdentifier() const;
bool init(const EgcuData &data, LtsSession::LtsSession *session);
void onMainStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final;
void onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final;
void onMountingPointAssetModifyReply(const Core::FunctionReplyObject &replyObject) override final;
bool apply() override;
private:
void retranslate() override;
static void getRoomIds(QTreeWidgetItem *twi, QVariantList &vl);
void updateRelays();
private slots:
void onMountinPointAssetChanged(const InfrastructureManagement::MountingPointAsset &mpa, DataModification mod);
private:
EgcuData m_egcuData;
QString m_menuGroup;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
std::shared_ptr<InfrastructureManagement::Interface::Ftc> m_ismFtc;
LtsUtils::RequestHelper *m_requestHelper;
QMap<int, QComboBox*> m_relayCbs;
NGL::INGLLogger &m_logger;
Ui::EgcuEdit *m_ui;
bool saveEgcuToRooms();
};
} // namespace ServiceMonitor
+77
View File
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EgcuEdit</class>
<widget class="QWidget" name="EgcuEdit">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>781</width>
<height>473</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lbxSegmentName">
<property name="text">
<string>Segment:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbxHostname">
<property name="text">
<string>Hostname:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="leSegmentName"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lblHostname">
<property name="text">
<string notr="true">&lt;EGCUNAME&gt;</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="lbxRooms">
<property name="text">
<string>Rooms:</string>
</property>
</widget>
</item>
<item row="1" column="3" rowspan="4">
<widget class="QTreeWidget" name="twRooms">
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="relays">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Overrides</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
File diff suppressed because it is too large. Load diff
+265
View File
@@ -0,0 +1,265 @@
/**
* @RDE_HEADER@
* The EgcuModel provices data for MountingPointListDialog
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-11-03
*/
#pragma once
#include <AssetManagement/asm_dtc.h>
#include <InfrastructureManagement/ism_dtc.h>
#include <InfrastructureManagement/Shared/ism_mounting_point.h>
#include <Plugins/Buildings/bld_data_plugin_interface.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
#include <QSet>
#include <QMenu>
#include <QStyledItemDelegate>
#include <nglwidgets/ngltreemodel.h>
#include <nglwidgets/ngltreeitem.h>
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
#include <Plugins/AssetManagement/asm_data_plugin_interface.h>
//Lts
#include <LtsUtilsGuiDds/request_helper.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
class QAction;
namespace LtsSession
{
class LtsSession;
}
namespace ServiceMonitor
{
// EGCU Data combines data from:
// - Instrumentation Asset (The EGCU itself)
// - MountingPoint (Where is it mounted?)
// - MainStructureElement (In which Building? Which rooms belong to this EGCU?)
// - MountingPointAsset (The Asset is mounted on which point?)
class EgcuData
{
public:
InfrastructureManagement::InstrumentationAsset instrumentationAsset;
InfrastructureManagement::MountingPoint mountingPoint;
InfrastructureManagement::MainStructureElement mainStructureElement;
Buildings::RelayState relayState;
InfrastructureManagement::MountingPointAsset mountingPointAsset;
QMap<int, InfrastructureManagement::EffectOverride> effectOverrides; // key = relayId
QVector<int> rooms;
QString segmentName() const { return (mountingPointAsset.name().empty() ? QString::fromStdString(instrumentationAsset.name()) : QString::fromStdString(mountingPointAsset.name())); }
explicit EgcuData() = default;
EgcuData(const InfrastructureManagement::InstrumentationAsset &ia,
const InfrastructureManagement::MountingPoint &mp,
const InfrastructureManagement::MainStructureElement &mse,
const Buildings::RelayState &rs,
const InfrastructureManagement::MountingPointAsset &mpa,
const QSet<int> &relayIds);
bool isNull() const { return (instrumentationAsset.id() == 0 || mountingPoint.id() == 0 || mainStructureElement.id() == 0); }
// Todo: Check what updates are feasible
void update(const InfrastructureManagement::MainStructureElement &mse);
void update(const InfrastructureManagement::MountingPoint &mp, bool overrideId); // fails if instrumentationAssetId Changed!
void update(const InfrastructureManagement::InstrumentationAsset &instrumentationAsset, bool overrideId);
void update(const InfrastructureManagement::StructureElement &mse, bool overrideId);
void update(const Buildings::RelayState &data);
int update(const InfrastructureManagement::MountingPointAsset &mpa); // 1= asset needs change, 2= mountingPoint needs change
};
class EgcuDelegate
: public QStyledItemDelegate
{
Q_OBJECT
public:
EgcuDelegate(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QSize sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
}; // EgcuDelegate
class EgcuModel final : public NGLTreeModel
, protected InfrastructureManagement::Interface::Ftc::StructureElementModifyReplyHandler
, protected Buildings::Interface::Ftc::SwitchRelayReplyHandler
{
Q_OBJECT
public:
enum Columns
{
Name,
Id,
MountingPointType,
Barcode,
Hostname,
Properties,
Rooms,
Overrides,
Status,
};
explicit EgcuModel(QObject *parent = nullptr);
/**
* Handles the representation of data.
* In case of CheckStateRole only leafs will be handled.
* Nodes are handled in the upstream CheckStateProxyModel class.
* @param[in] index item index to be handled
* @param[in] role role to which the data relates
*
*/
QVariant data(const QModelIndex &index, int role) const override final;
bool initModel(LtsSession::LtsSession *session);
QModelIndex getIndexOfVisableRootItem() const;
/**
* Sets only the leafs of the tree view to Qt::ItemIsUserCheckable.
* Nodes are handled in the upstream CheckStateProxyModel class.
* @param[in] index item index to be handled
*
*/
Qt::ItemFlags flags(const QModelIndex &index) const override final;
/**
* Sets the check state data according to their check box in the internal model.
* CheckState data can be set for leafs only.
* Nodes are handled in the upstream CheckStateProxyModel class.
* @param[in] index item index to be handled
* @param[in] value value to be set
* @param[in] role role to which the data relates (here especially Qt::CheckStateRole)
*
*/
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
InfrastructureManagement::StructureElementType getStructureElementType(const QModelIndex &mi) const;
QAction *addContextMenuHeaderItem(const QString &name);
void getContextMenu(const QModelIndexList &indexes, QMenu &menu);
void onSwitchRelayReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
void onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
static QVector<int> getRoomsForEgcu(const std::string &mseProperties, int mountingPointId);
static bool readAllowance(InfrastructureManagement::EffectOverride eo, const std::string &properties);
// Not yet implemented:
QMap<int,QModelIndex> setSelectedStructureElements(const QVector<int> &structureElementIds);
QPair<QMap<int, InfrastructureManagement::StructureElement>, QMap<int, InfrastructureManagement::StructureElement> > findEgcusAndBuildings(const QModelIndexList &indexes);
public Q_SLOTS:
void onMountingPointChanged(const InfrastructureManagement::MountingPoint &mountingPoint, DataModification modType);
void onInstrumentationAssetChanged(const InfrastructureManagement::InstrumentationAsset &instrumentationAsset, DataModification modType);
void onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &mainStructureElement, DataModification modType);
void onRelayStateChanged(const Buildings::RelayState &data, DataModification modType);
void onRelayInfoChanged(const AssetManagement::RelayInfo &data, DataModification modType);
void onMountingPointAssetChanged(const InfrastructureManagement::MountingPointAsset &mpa, DataModification modType);
void setAllOverrides(InfrastructureManagement::EffectOverride eo, const QModelIndexList &indexes);
signals:
void invalidateFilter(const QModelIndex &mi = QModelIndex());
private:
void initData();
void removeUnused(NGLTreeItem *item);
bool isMountpointEgcu(const QByteArray &properties);
void udpatePropertiesForRelayOverride(const int relay,
const InfrastructureManagement::EffectOverride state,
InfrastructureManagement::StructureElement &se);
void udpatePropertiesForOverride(const QString &tagName,
const InfrastructureManagement::EffectOverride state,
InfrastructureManagement::StructureElement &se);
friend class EgcuProxyModel;
NGLTreeItem *m_visRoot;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_dtc;
std::shared_ptr<InfrastructureManagement::Interface::Ftc> m_ftc;
std::shared_ptr<Buildings::Interface::Dtc> m_bldDtc;
std::shared_ptr<Buildings::Interface::Ftc> m_bldFtc;
std::shared_ptr<AssetManagement::Interface::Dtc> m_asmDtc;
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> m_dataInterface;
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
QMap<int, AssetManagement::RelayInfo> m_relayInfos;
LtsSession::LtsSession *m_session = nullptr;
LtsUtils::RequestHelper *m_requestHelper = nullptr;
NGL::INGLLogger &m_logger;
NGLTreeItem* findItemByMountingPointId(int mpId, NGLTreeItem *parent) const;
NGLTreeItem* findItemByAssetId(int assetId, NGLTreeItem *parent) const;
NGLTreeItem* findItemByMseId(int mseId, NGLTreeItem *parent) const;
NGLTreeItem* findItemByStructureElementId(int seId, NGLTreeItem *parent) const;
NGLTreeItem* createItemFromMountingPoint(const InfrastructureManagement::StructureElement &currentElement);
NGLTreeItem* createItemFromStructureElement(const InfrastructureManagement::StructureElement &currentElement);
Buildings::SwitchRelayRequest createSwitchRelayRequest(int buildingId, int assetId, int relayId, Buildings::StateSetRelay state, int pulse = 0, int count = 0, int pause = 0);
static bool jsonBoolSearch(const std::string &propoerties, const QString &tagName, bool defaultVal);
QAction* getGenericAction(const InfrastructureManagement::EffectOverride eo, const QString &actionName, const QString &tagName, const QMap<int, InfrastructureManagement::StructureElement> &buildings);
QAction* getRelayAction(const InfrastructureManagement::EffectOverride eo, const QMap<int, InfrastructureManagement::StructureElement> &egcus, const AssetManagement::RelayInfo &relayInfo);
QAction* getCenterAction(const int mseId);
void findEgcuChildren(NGLTreeItem *parent, QMap<int, InfrastructureManagement::StructureElement> &resVec);
void findEgcuChildren(NGLTreeItem *parent, QSet<NGLTreeItem *> &set);
void findBuildings(NGLTreeItem *parent, QMap<int, InfrastructureManagement::StructureElement> &buildings);
void findStructureElementChildren(NGLTreeItem *parent, QSet<NGLTreeItem *> &set);
void findStructureElementChildrenByIds(NGLTreeItem *parent, const QVector<int> &structureElementIds, QMap<int, QModelIndex> &map);
QString getOverridesString(const EgcuData &data) const;
QString getRelaisStates(const EgcuData &data) const;
static QString getOverridesFlash(const QByteArray &properties);
static QString getRoomsString(const EgcuData &data);
static QString getIconFromState(const std::string &properties, bool state);
QMap<qint32, InfrastructureManagement::MountingPointAsset> m_mountingPointAssets;
bool mseHasMountedAsset(const InfrastructureManagement::MainStructureElement &mse, InfrastructureManagement::MountingPointType mpType);
bool isMounted(int mountingPointId);
}; // class EgcuModel
//=== EgcuProxyModel ===================================================================
class EgcuProxyModel final : public LtsWidgets::LtsColumnFilterProxyModel
{
using BaseClass = LtsWidgets::LtsColumnFilterProxyModel;
Q_OBJECT
public:
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
void setSourceModel(QAbstractItemModel *sourceModel) override;
void showIncluded(const bool bShow);
void showNotIncluded(const bool bShow);
void setTypeFilter(const QSet<InfrastructureManagement::MountingPointType> &visibleTypes);
void addToTypeFilter(const InfrastructureManagement::MountingPointType mpt, const bool bAdd);
bool filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const override;
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
using LtsWidgets::LtsColumnFilterProxyModel::invalidateFilter;
private:
EgcuModel *m_sourceModel = nullptr;
QSet<InfrastructureManagement::MountingPointType> m_visibleTypes;
bool m_bShowIncluded = true;
bool m_bShowNotIncluded = true;
};
} // namespace InfrastructureManagement
Q_DECLARE_METATYPE(ServiceMonitor::EgcuData)
Q_DECLARE_METATYPE(InfrastructureManagement::StructureElement)
@@ -0,0 +1,223 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Fault Message Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Filip Biedziak, SLTE, 2021-10-12
*/
#include "smo_fault_message_dialog.h"
#include "ui_smo_fault_message_dialog.h"
#include <AdvancedSymbology/asb_data_plugin_interface.h>
#include <Common/logger.h>
#include <PluginInterfaces/gui_plugin_interface.h>
namespace ServiceMonitor
{
FaultMessageDialog::FaultMessageDialog(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
, m_session(session)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_ui(new Ui::FaultMessageDialog)
, m_logger(getLogger(QStringLiteral("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, &FaultMessageDialog::onTextChanged);
connect(m_ui->leDevice, &QLineEdit::textChanged, this, &FaultMessageDialog::onDevTextChanged);
setOnlineHelpFilename(QStringLiteral("OC-Fault_Message"));
}
FaultMessageDialog::~FaultMessageDialog()
{
delete m_ui;
}
///////////////////////////////////////////////////////////////////////////////
// PUBLIC
bool FaultMessageDialog::init(/*const std::shared_ptr<OcSituationServer::Interface::Ftc> &ossFtc*/)
{
// if (!ossFtc)
// return false;
// m_ossFtc = ossFtc;
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->createTopicClient(m_ossFtc))
return false;
m_ossFtc->enableEquipmentError();
// if (!m_session->getFtc<OcSituationServer::Interface::Ftc>(m_ossFtc))
// return false;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmGuiCbxIfc))
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_ppmGuiCbxIfc->fillPartyComboBox(m_ui->cbParty);
connect(m_ui->dvParticipants, &LtsDataView::LtsDataView::signalSelectionChanged,
this, &FaultMessageDialog::onSlotSelectionChanged);
connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::specificsEquipmentChanged,
this, &FaultMessageDialog::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;
}
///////////////////////////////////////////////////////////////////////////////
// PRIVATE
void FaultMessageDialog::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 FaultMessageDialog::apply()
{
if (m_ui->leParticipant->text().toInt() <= 0)
return false;
OcSituationServer::EquipmentErrorRequest req;
req.equipmentNumber(m_ui->leParticipant->text().toInt());
req.device(m_ui->leDevice->text().toStdString());
req.text(m_ui->teComment->toPlainText().toStdString());
return m_requestHelper->startSingleRequest([req, this]()
{
return m_ossFtc->equipmentErrorRequest(req, this);
});
}
void FaultMessageDialog::tableColumnOrganiserSetting()
{
//LtsColumnOrganiser
m_ui->dvParticipants->setColumnsOrganiserEnabled(identifier(), true);
}
void FaultMessageDialog::trimText(QLineEdit *lineEdit, QLabel *label)
{
QString plainText(lineEdit->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)
lineEdit->setText(plainText);
label->setText(QString::number(currentUsedChars));
}
///////////////////////////////////////////////////////////////////////////////
// PRIVATE SLOTS
void FaultMessageDialog::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 FaultMessageDialog::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 FaultMessageDialog::onDevTextChanged()
{
trimText(m_ui->leDevice, m_ui->lblDevCount);
}
void FaultMessageDialog::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 ServiceMonitor
@@ -0,0 +1,77 @@
/**
* @RDE_HEADER@
* HMI Plugin for Observer Controller - Fault Message Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Filip Biedziak, SLTE, 2021-10-12
*/
#pragma once
#include <LtsSession/lts_session.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <LtsWidgets/lts_dialog.h>
#include <OcSituationServer/oss_ftc.h>
#include <OcSituationServer/oss.hpp>
#include <ParticipantManagement/Gui/Common/participant_edit_model.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
#include <Plugins/TrainingAreaBaseOC/taboc_data_plugin_interface.h>
namespace Ui { class FaultMessageDialog; }
namespace ServiceMonitor
{
class FaultMessageDialog : public LtsWidgets::LtsDialog
, private OcSituationServer::Interface::Ftc::EquipmentErrorReplyHandler
{
Q_OBJECT
public:
explicit FaultMessageDialog(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~FaultMessageDialog();
bool init();
void onEquipmentErrorReply(const Core::FunctionReplyObject &replyObject) override
{
m_requestHelper->requestReply(replyObject);
}
private:
void retranslate() override;
bool apply() override;
void tableColumnOrganiserSetting() override;
void trimText(QLineEdit *lineEdit, QLabel *label);
private slots:
void onSlotSelectionChanged();
void onTextChanged();
void onDevTextChanged();
void onSpecificsEquipmentChanged(const TrainingAreaBaseOC::SpecificsEquipment &data, const DataModification &modType);
private:
LtsSession::LtsSession *m_session{nullptr};
LtsUtils::RequestHelper *m_requestHelper{nullptr};
int m_selectedEqNr{-1};
int m_maxChars{255};
int m_maxPartChars{35};
int m_ownEquipmentId{0};
ParticipantManagement::ParticipantEditModel *m_model{nullptr};
LtsWidgets::LtsColumnFilterProxyModel *m_proxyModel{nullptr};
std::shared_ptr<OcSituationServer::Interface::Ftc> m_ossFtc{nullptr};
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc{nullptr};
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmGuiCbxIfc{nullptr};
Ui::FaultMessageDialog *m_ui{nullptr};
NGL::INGLLogger &m_logger;
};
} // namespace ServiceMonitor
@@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FaultMessageDialog</class>
<widget class="QWidget" name="FaultMessageDialog">
<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,218 @@
/**
* @RDE_HEADER@
* Model for Manipulation Message
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-10
*/
#include "smo_manipulation_model.h"
#include <LtsSession/lts_session_data.h>
#include <Common/logger.h>
#include <ngltools/ngltools_dtg.h>
#include <QDateTime>
namespace ServiceMonitor
{
ManipulationModel::ManipulationModel(QObject *parent)
: LtsWidgets::LtsAbstractTableModel<ManipulationData>({tr("Time of Receipt"),
tr("Equip. No."),
tr("Time (PU)"),
tr("Equipment Identification")},
parent)
, m_logger(getLogger("ManipulationModel"))
{}
bool ManipulationModel::initModel(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc)
{
DEBUG_LOG(m_logger) << "----- initModel";
if (!pdmDtc || !ppmDtc)
return false;
m_ppmDtc = ppmDtc;
m_pdmDtc = pdmDtc;
auto cbCs = [this](const ProjectDataManagement::CanComponentString &ccs)
{
m_ccsMap[ccs.canDeviceId()] = ccs;
};
pdmDtc->canComponentStrings(cbCs);
connect(m_ppmDtc.get(),
&ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged,
this, &ManipulationModel::manipulationDataChanged);
connect(m_ppmDtc.get(),
&ParticipantManagement::Interface::Dtc::participantChanged,
this, &ManipulationModel::participantChanged);
auto cb = [this](const ParticipantManagement::DynamicParticipantData &partData)
{
manipulationDataChanged(partData, DataModification::eAdded);
};
m_ppmDtc->dynamicParticipantDatas(cb);
return true;
}
QVariant ManipulationModel::data(const QModelIndex &index,
int role) const
{
if (role != Qt::DisplayRole || !indexIsValid(index))
return QVariant();
const ManipulationData &data = m_vecData.at(index.row());
switch (index.column())
{
case ReceiveTime:
return QDateTime::fromMSecsSinceEpoch(data.sampleTime);
case EquipmentNummer:
return data.equipNo;
case TimePlayerUnit:
return QDateTime::fromMSecsSinceEpoch(data.manipulationTime);
case EquipmentIdentification:
return data.canDevices;
}
return QVariant();
}
void ManipulationModel::manipulationDataChanged(const ParticipantManagement::DynamicParticipantData &data,
DataModification modType)
{
DEBUG_LOG(m_logger) << "manipulationDataChanged: " << data.manipulation().size() << ", " << modType;
const bool isManipulated = data.manipulation().size() > 0;
switch (modType)
{
case DataModification::eAdded:
{
if (!isManipulated)
return;
const ManipulationData &mData = buildManipulationData(data);
if (mData.participantId == 0)
return;
insertRow(mData);
m_participantsWithManipulation += data.participantId();
break;
}
case DataModification::eModified:
{
const int row = findRowForId(data.participantId());
if (isManipulated)
{
if (row >= 0 && data.manipulation().size() > 0 &&
m_vecData.at(row).manipulationTime == data.manipulation().at(data.manipulation().size() - 1).manipulationTime())
{
// manipulation did not change - ignore
break;
}
const ManipulationData mData = buildManipulationData(data);
if (mData.participantId == 0)
removeRow(row);
else if (row == -1)
insertRow(mData);
else
setRowData(row, mData);
m_participantsWithManipulation += data.participantId();
}
else
{
removeRow(row);
m_participantsWithManipulation -= data.participantId();
}
break;
}
case DataModification::eRemoved:
break;
}
}
void ManipulationModel::participantChanged(const ParticipantManagement::Participant &data, DataModification modType)
{
if (!m_participantsWithManipulation.contains(data.id()))
return;
const int row = findRowForId(data.id());
if (row < 0)
return;
if (!data.equipmentNumber().is_set() || modType == DataModification::eRemoved)
{
removeRow(row);
m_participantsWithManipulation -= data.id();
return;
}
m_vecData[row].equipNo = data.equipmentNumber().get();
const QModelIndex idx(index(row, EquipmentNummer));
emit dataChanged(idx, idx, {Qt::DisplayRole});
}
ManipulationData ManipulationModel::buildManipulationData(const ParticipantManagement::DynamicParticipantData &data) const
{
ManipulationData mData;
if (data.manipulation().size() == 0)
return mData;
const auto equipNo = m_ppmDtc->participant(data.participantId()).equipmentNumber();
if (!equipNo.is_set())
return mData;
mData.participantId = data.participantId();
mData.equipNo = equipNo.get();
mData.sampleTime = data.sampleTime();
mData.manipulationTime = data.manipulation().at(data.manipulation().size() - 1).manipulationTime();
mData.canDevices = buildCanDeviceString(data.manipulation());
return mData;
}
QString ManipulationModel::buildCanDeviceString(const std::vector<ParticipantManagement::ManipulationInformation>& manipulations) const
{
QStringList canDeviceList;
for (const ParticipantManagement::ManipulationInformation &mi : manipulations)
{
auto it = m_ccsMap.find(mi.equipmentFunctionId());
if (it == m_ccsMap.end())
canDeviceList.prepend(tr("Unknown can device (%1)").arg(mi.equipmentFunctionId()));
else
canDeviceList.prepend(m_pdmDtc->trCanComponentStringName(it.value().id()));
}
return canDeviceList.join(QLatin1Char(','));
}
//
// ManipulationProxyModel
//
void ManipulationProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
m_sourceModel = qobject_cast<ManipulationModel*>(sourceModel);
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(sourceModel);
}
bool ManipulationProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!m_sourceModel ||
source_left.column() != source_right.column() ||
!source_left.isValid() ||
!source_right.isValid())
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
const auto &dataLeft = m_sourceModel->m_vecData.at(source_left.row());
const auto dataRight = m_sourceModel->m_vecData.at(source_right.row());
switch (source_left.column())
{
case ManipulationModel::ReceiveTime:
return dataLeft.sampleTime < dataRight.sampleTime;
case ManipulationModel::EquipmentNummer:
return dataLeft.equipNo < dataRight.equipNo;
case ManipulationModel::TimePlayerUnit:
return dataLeft.manipulationTime < dataRight.manipulationTime;
case ManipulationModel::EquipmentIdentification:
return dataLeft.canDevices < dataRight.canDevices;
}
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
}
} // namespace ServiceMonitor
@@ -0,0 +1,86 @@
/**
* @RDE_HEADER@
* Model for Manipulation Message
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-10
*/
#pragma once
#include <LtsWidgets/lts_abstract_table_model.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
#include <ParticipantManagement/ppm_dtc.h>
#include <ProjectDataManagement/pdm_dtc.h>
#include <QSet>
#include <Common/logger.h>
namespace ServiceMonitor
{
struct ManipulationData
{
int participantId = 0;
int equipNo = 0;
qint64 sampleTime = 0;
qint64 manipulationTime = 0;
QString canDevices;
int id() const { return participantId; }
};
// --------------------------------------------------------
// ManipulationModel
// --------------------------------------------------------
class ManipulationModel final : public LtsWidgets::LtsAbstractTableModel<ManipulationData>
{
Q_OBJECT
public:
enum Columns
{
ReceiveTime,
EquipmentNummer,
TimePlayerUnit,
EquipmentIdentification
};
explicit ManipulationModel(QObject *parent = nullptr);
bool initModel(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
private slots:
void manipulationDataChanged(const ParticipantManagement::DynamicParticipantData &data,
DataModification modType);
void participantChanged(const ParticipantManagement::Participant &data, DataModification modType);
private:
ManipulationData buildManipulationData(const ParticipantManagement::DynamicParticipantData &data) const;
QString buildCanDeviceString(const std::vector<ParticipantManagement::ManipulationInformation>& manipulations) const;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
QHash<int, ProjectDataManagement::CanComponentString> m_ccsMap;
QSet<int> m_participantsWithManipulation;
NGL::INGLLogger &m_logger;
friend class ManipulationProxyModel;
};
class ManipulationProxyModel final : public LtsWidgets::LtsColumnFilterProxyModel
{
Q_OBJECT
public:
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
void setSourceModel(QAbstractItemModel *sourceModel) override;
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
private:
ManipulationModel *m_sourceModel = nullptr;
};
} //namespace ServiceMonitor
@@ -0,0 +1,269 @@
/**
* @RDE_HEADER@
* GUI Plugin for serviceMonitor
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-04
*/
#include "smo_monitors_gui_plugin.h"
#include "smo_dialog.h"
#include "smo_fault_message_dialog.h"
#include "smo_party_equipment_check_dialog.h"
#include "smo_single_service_equipment_check_dialog.h"
#include <Common/logger.h>
#include <Common/settings.h>
#include <LtsSession/lts_session.h>
#include <LtsUtilsSettings/settings.h>
#include <LtsWidgets/lts_base_layout_widget.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
#include <ServiceMonitor/smo_operator_rights.h>
namespace ServiceMonitor
{
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("MonitorGuiPlugin"))
{}
bool InterfaceImpl::fetchInterfaces()
{
//foreign
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
return false;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmCbxDtc))
return false;
if (!m_session->getFtc<ParticipantManagement::DataInterface>(m_ppmFtc))
return false;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignParticipantInfoGuiInterface>(m_ppmGuiIfcDtc))
return false;
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(m_pdmDtc))
return false;
// if (!m_session->getFtc<OcSituationServer::Interface::Ftc>(m_ossFtc))
// return false;
return true;
}
void InterfaceImpl::clearInterfaces()
{
m_ppmDtc.reset();
m_ppmCbxDtc.reset();
m_ppmFtc.reset();
m_ppmGuiIfcDtc.reset();
m_pdmDtc.reset();
// m_ossFtc.reset();
}
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
QVector<LtsWidgets::PluginData> ret;
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("BITE Monitor");
plData.identifier = QLatin1String("smoBiteMonitors");
plData.menuIcon = QIcon(QLatin1String("icon:pi_show_bite.svg"));
plData.operatorRight = OperatorRights::BiteMonitorShow;
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowServiceMonitorBite(parent);
};
ret.append(plData);
plData.menuText = tr("Manipulation Monitor");
plData.identifier = QStringLiteral("smoManipulationMonitor");
plData.menuIcon = QIcon(QLatin1String("icon:status.svg"));
plData.operatorRight = OperatorRights::ManipulationMonitorShow;
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowServiceMonitorMani(parent);
};
ret.append(plData);
plData.menuText = tr("Party Equipment Check");
plData.identifier = QLatin1String("smoPartyEquipmentCheck");
plData.menuIcon = QIcon(QLatin1String("icon:player_equipment_check.svg"));
plData.operatorRight = OperatorRights::EquipmentCheckMonitorShow;
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowServiceMonitorPartyEquipmentCheck(parent);
};
ret.append(plData);
plData.menuText = tr("Single Service Equipment Check");
plData.identifier = QLatin1String("smoSingleServiceEquipmentCheck");
plData.menuIcon = QIcon(QLatin1String("icon:player_equipment_check.svg"));
plData.operatorRight = OperatorRights::EquipmentCheckMonitorShow;
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowServiceMonitorSingleServiceEquipmentCheck(parent);
};
ret.append(plData);
plData.menuText = tr("CTAS Error Monitor");
plData.identifier = QLatin1String("smoCtasMonitor");
plData.menuIcon = QIcon(QLatin1String("icon:system_status.svg"));
plData.operatorRight = OperatorRights::FaultMonitorShow;
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowServiceMonitorCtasError(parent);
};
ret.append(plData);
plData.menuText = tr("EGCU Monitor");
plData.identifier = QLatin1String("smoEgcuMonitor");
plData.menuIcon = QIcon(QLatin1String("icon:system_status.svg"));
plData.operatorRight = OperatorRights::EquipmentCheckMonitorShow; // OperatorRights::EgcuMonitorShow;
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowServiceMonitorEgcu(parent);
};
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
if (m_session->app() != LtsAppDescriptor::App::OC
&& ps->value(QStringLiteral("smo"),
QStringLiteral("enableEGCUMonitor")).toBool())
ret.append(plData);
// Action 'Equipment Fault'
if (m_session->app() != LtsAppDescriptor::App::OC
&& ps->value(QStringLiteral("smo"),
QStringLiteral("enableFaultMessage")).toBool())
{
plData.menuText = tr("Fault Message");
plData.identifier = QStringLiteral("smoFaultMessage");
plData.menuIcon = QIcon(QStringLiteral("icon:player_equipment_fault.svg"));
plData.operatorRight = 0;
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowServiceMonitorFaultMessage(parent);
};
ret.append(plData);
}
return ret;
}
void InterfaceImpl::showSingleServiceEquipmentCheck(const QVector<int> &equipmentNumbers, bool replace)
{
LtsWidgets::LtsBaseLayoutWidget *baseLayout = m_session->baseLayout();
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.identifier = QLatin1String("smoSingleServiceEquipmentCheck");
SingleServiceEquipmentCheckDialog *dialog = nullptr;
LtsWidgets::LtsDialog *ltsDialog = baseLayout->getWidget(plData.menuGroup, plData.identifier, plData.layoutArea);
if (ltsDialog)
{
dialog = dynamic_cast<SingleServiceEquipmentCheckDialog *>(ltsDialog);
baseLayout->focusTab(plData.menuGroup, plData.identifier, plData.layoutArea);
}
else
{
QWidget *parent = baseLayout;
dialog = LtsWidgets::initDialog(new SingleServiceEquipmentCheckDialog(m_session, parent),
m_ppmFtc, m_ppmGuiIfcDtc);
baseLayout->addWidget(dialog, plData.menuGroup, plData.identifier, plData.layoutArea, plData.closable);
}
if (dialog)
dialog->setEquipmentNumbers(equipmentNumbers, replace);
}
void InterfaceImpl::showEgcuMonitor(const QVector<int> &structureElementIds, bool replace)
{
// Not yet implemented:
Q_UNUSED(structureElementIds);
Q_UNUSED(replace);
LtsWidgets::LtsBaseLayoutWidget *baseLayout = m_session->baseLayout();
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.identifier = QLatin1String("smoEgcuMonitor");
ServiceMonitorDialog *dialog = nullptr;
LtsWidgets::LtsDialog *ltsDialog = baseLayout->getWidget(plData.menuGroup, plData.identifier, plData.layoutArea);
if (ltsDialog)
{
dialog = dynamic_cast<ServiceMonitorDialog *>(ltsDialog);
baseLayout->focusTab(plData.menuGroup, plData.identifier, plData.layoutArea);
}
else
{
QWidget *parent = baseLayout;
dialog = LtsWidgets::initDialog(new ServiceMonitorDialog(ServiceMonitorDialog::Egcu, m_session, parent));
baseLayout->addWidget(dialog, plData.menuGroup, plData.identifier, plData.layoutArea, plData.closable);
}
if (dialog)
dialog->setSelectedStructureElements(structureElementIds, replace);
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowServiceMonitorBite(QWidget *parent)
{
return LtsWidgets::initDialog(new ServiceMonitorDialog(ServiceMonitorDialog::Monitor::Bite,
m_session,
parent));
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowServiceMonitorMani(QWidget *parent)
{
return LtsWidgets::initDialog(new ServiceMonitorDialog(ServiceMonitorDialog::Monitor::Manipulation,
m_session,
parent));
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowServiceMonitorPartyEquipmentCheck(QWidget *parent)
{
return LtsWidgets::initDialog(new PartyEquipmentCheckDialog(m_session, parent),
m_ppmFtc, m_ppmCbxDtc);
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowServiceMonitorSingleServiceEquipmentCheck(QWidget *parent)
{
return LtsWidgets::initDialog(new SingleServiceEquipmentCheckDialog(m_session, parent),
m_ppmFtc, m_ppmGuiIfcDtc);
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowServiceMonitorCtasError(QWidget *parent)
{
return LtsWidgets::initDialog(new ServiceMonitorDialog(ServiceMonitorDialog::Monitor::CtasError,
m_session,
parent));
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowServiceMonitorEgcu(QWidget *parent)
{
return LtsWidgets::initDialog(new ServiceMonitorDialog(ServiceMonitorDialog::Monitor::Egcu,
m_session,
parent));
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowServiceMonitorFaultMessage(QWidget *parent)
{
return LtsWidgets::initDialog(new FaultMessageDialog(m_session, parent)/*, m_ossFtc*/);
}
}
// namespace ServiceMonitor
@@ -0,0 +1,77 @@
/**
* @RDE_HEADER@
* Gui Plugin for ServiceMonitor
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-04
*/
#pragma once
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Common/ProjectConfig/project_defines.h>
//#include <OcSituationServer/oss_ftc.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_participant_info_gui_plugin_interface.h>
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
#include <Plugins/ServiceMonitor/smo_monitors_gui_plugin_interface.h>
namespace ServiceMonitor
{
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "gui:3:smo")
Q_INTERFACES(GuiPluginBase::Plugin)
Q_OBJECT
public:
explicit GuiPlugin() = default;
~GuiPlugin() = default;
QString pluginName() override { return QStringLiteral("ServiceMonitorMonitorsGui"); }
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return (partition == IDL::PartitionType::Exercise);
}
};
class InterfaceImpl final : public QObject, public ForeignGuiInterface, public GuiPluginBase::Interface
{
Q_OBJECT
public:
explicit InterfaceImpl(LtsSession::LtsSession *session);
bool fetchInterfaces() override;
void clearInterfaces() override;
QVector<LtsWidgets::PluginData> getActions() override;
QString menuGroup() const override { return tr("Service Monitors"); }
void showSingleServiceEquipmentCheck(const QVector<int> &equipmentNumbers, bool replace = true) override;
void showEgcuMonitor(const QVector<int> &structureElementIds, bool replace) override;
private:
LtsWidgets::LtsDialog *onShowServiceMonitorBite(QWidget *parent);
LtsWidgets::LtsDialog *onShowServiceMonitorMani(QWidget *parent);
LtsWidgets::LtsDialog *onShowServiceMonitorPartyEquipmentCheck(QWidget *parent);
LtsWidgets::LtsDialog *onShowServiceMonitorSingleServiceEquipmentCheck(QWidget *parent);
LtsWidgets::LtsDialog *onShowServiceMonitorCtasError(QWidget *parent);
LtsWidgets::LtsDialog *onShowServiceMonitorEgcu(QWidget *parent);
LtsWidgets::LtsDialog *onShowServiceMonitorSystem(QWidget *parent);
LtsWidgets::LtsDialog *onShowServiceMonitorFaultMessage(QWidget *parent);
// Data
// std::shared_ptr<OcSituationServer::Interface::Ftc> m_ossFtc{nullptr};
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc{nullptr};
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc{nullptr};
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmCbxDtc{nullptr};
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc{nullptr};
std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> m_ppmGuiIfcDtc{nullptr};
};
} // namespace ServiceMonitor
@@ -0,0 +1,111 @@
/**
* @RDE_HEADER@
* Party Equipment Check Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-16
*/
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
#include "smo_party_equipment_check_dialog.h"
#include "ui_smo_party_equipment_check_dialog.h"
namespace ServiceMonitor
{
PartyEquipmentCheckDialog::PartyEquipmentCheckDialog(LtsSession::LtsSession *session, QWidget *parent)
: BaseEquipmentCheck("PartyEquipmentCheckDialog", session, parent)
, m_ui(new Ui::PartyEquipmentCheckDialog)
, m_partyPlayerProxyModel(nullptr)
, m_ppmCbxDtc(nullptr)
, m_filter(ParticipantManagement::ForeignGuiComboboxInterface::eParticipantsWithCtaEquipment)
{
m_ui->setupUi(this);
connect(m_ui->cbParty, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &PartyEquipmentCheckDialog::onPartyCbChanged);
connect(m_ui->cbTypeClass, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &PartyEquipmentCheckDialog::onTypeClassCbChanged);
setOnlineHelpFilename(QStringLiteral("Situation-Party_Equipment_Check"));
}
PartyEquipmentCheckDialog::~PartyEquipmentCheckDialog()
{
delete m_ui;
}
LtsDataView::LtsDataView *PartyEquipmentCheckDialog::view()
{
return m_ui->tvPartyPlayer;
}
const LtsDataView::LtsDataView *PartyEquipmentCheckDialog::view() const
{
return m_ui->tvPartyPlayer;
}
void PartyEquipmentCheckDialog::retranslate()
{
translate(m_ui, tr("Party Equipment Check"));
m_ppmCbxDtc->fillTypeClassComboBox(m_ui->cbTypeClass, m_filter);
}
void PartyEquipmentCheckDialog::tableColumnOrganiserSetting()
{
//LtsColumnOrganiser
m_ui->tvPartyPlayer->setColumnsOrganiserEnabled(identifier(), true);
}
bool PartyEquipmentCheckDialog::init(const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc,
const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ppmCbxDtc)
{
DEBUG_LOG(m_logger) << "**** init() ";
if (!BaseEquipmentCheck::init(ppmFtc))
return false;
if (!ppmCbxDtc)
{
ERROR_LOG(m_logger) << "init: ppmCbxDtc shared_ptr invalid";
return false;
}
m_playerModel = new PartyPlayerModel(this);
m_playerModel->initModel(m_session);
m_partyPlayerProxyModel = new PartyPlayerProxyModel(this);
m_partyPlayerProxyModel->setSourceModel(m_playerModel);
m_ui->tvPartyPlayer->setModel(m_partyPlayerProxyModel);
m_ui->tvPartyPlayer->setSelectionMode(QAbstractItemView::ExtendedSelection);
#ifndef LTS_DEBUG
m_ui->tvPartyPlayer->hideColumn(BasePlayerModel::Columns::ColParticipantId);
#endif
m_ui->tvPartyPlayer->hideColumn(BasePlayerModel::ColParty); // until the filter is in the view via combobox
m_ui->tvPartyPlayer->hideColumn(BasePlayerModel::ColTacticalStatus);
m_ui->tvPartyPlayer->setSortIndicator(BasePlayerModel::ColEquipmentNummer, Qt::AscendingOrder);
m_ppmCbxDtc = ppmCbxDtc;
m_ppmCbxDtc->fillPartyComboBox(m_ui->cbParty);
m_ppmCbxDtc->fillTypeClassComboBox(m_ui->cbTypeClass, m_filter);
onPartyCbChanged();
onTypeClassCbChanged();
return true;
}
void PartyEquipmentCheckDialog::onPartyCbChanged()
{
const int partyId = m_ui->cbParty->currentData().toInt();
m_partyPlayerProxyModel->setPartyId(partyId);
}
void PartyEquipmentCheckDialog::onTypeClassCbChanged()
{
const auto tc = ParticipantManagement::TypeClass_def::type(m_ui->cbTypeClass->currentData().toInt());
m_partyPlayerProxyModel->setTypeClass(tc);
}
} // namespace ServiceMonitor
@@ -0,0 +1,59 @@
/**
* @RDE_HEADER@
* Party Equipment Check Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-16
*/
#pragma once
#include "smo_party_player_model.h"
#include "smo_base_equipment_check.h"
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
#include <ParticipantManagement/ppm_ftc.h>
namespace Ui
{
class PartyEquipmentCheckDialog;
}
namespace LtsSession
{
class LtsSession;
}
namespace ServiceMonitor
{
class PartyEquipmentCheckDialog final : public BaseEquipmentCheck
{
Q_OBJECT
public:
explicit PartyEquipmentCheckDialog(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~PartyEquipmentCheckDialog();
bool init(const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc,
const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ppmCbxDtc);
private slots:
void onPartyCbChanged();
void onTypeClassCbChanged();
protected:
LtsDataView::LtsDataView *view() override;
const LtsDataView::LtsDataView *view() const override;
private:
void retranslate() override;
void tableColumnOrganiserSetting() override;
Ui::PartyEquipmentCheckDialog *m_ui;
PartyPlayerProxyModel *m_partyPlayerProxyModel;
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmCbxDtc;
const int m_filter;
};
}
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartyEquipmentCheckDialog</class>
<widget class="QWidget" name="PartyEquipmentCheckDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>570</width>
<height>664</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">Equipment Check</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="QComboBox" name="cbParty"/>
</item>
<item>
<widget class="QLabel" name="leTypeClass">
<property name="text">
<string>Class:</string>
</property>
</widget>
</item>
<item>
<widget class="LtsWidgets::LtsComboBox" name="cbTypeClass"/>
</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>
</layout>
</item>
<item>
<widget class="LtsDataView::LtsDataView" name="tvPartyPlayer"/>
</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>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,75 @@
/**
* @RDE_HEADER@
* Model for Equipment Check Force
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-16
*/
#include "smo_party_player_model.h"
namespace ServiceMonitor
{
PartyPlayerModel::PartyPlayerModel(QObject *parent)
: BasePlayerModel(parent)
{}
bool PartyPlayerModel::initModel(LtsSession::LtsSessionDataDds *session)
{
DEBUG_LOG(m_logger) << "**** initModel";
if (!BasePlayerModel::initModel(session))
return false;
QVector<PlayerData> playerData;
playerData.reserve(m_participants.size());
const auto dynPartData = m_ppmDtc->dynamicParticipantDatas();
for (const ParticipantManagement::Participant &part : qAsConst(m_participants))
{
if (!part.equipmentNumber().is_set())
continue;
playerData.push_back(setPlayerData(part, dynPartData.value(part.id())));
};
setData(playerData);
return true;
}
// --------------------------------------------------------
// PartyPlayerProxyModel
// --------------------------------------------------------
bool PartyPlayerProxyModel::filterAcceptsRow(int source_row,
const QModelIndex &source_parent) const
{
if (m_sourceModel)
{
if (m_partyId > 0 &&
!m_sourceModel->isPartyId(source_row, m_partyId))
return false;
if (m_typeClass != ParticipantManagement::TypeClass::Unknown &&
!m_sourceModel->isTypeClass(source_row, m_typeClass))
return false;
}
return LtsWidgets::LtsColumnFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
void PartyPlayerProxyModel::setPartyId(int partyId)
{
if (m_partyId == partyId)
return;
m_partyId = partyId;
invalidateFilter();
}
void PartyPlayerProxyModel::setTypeClass(ParticipantManagement::TypeClass typeClass)
{
if (m_typeClass == typeClass)
return;
m_typeClass = typeClass;
invalidateFilter();
}
} // namespace ServiceMonitor
@@ -0,0 +1,54 @@
/**
* @RDE_HEADER@
* Model for Equipment Check Force
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-16
*/
#pragma once
#include "smo_base_player_model.h"
namespace ServiceMonitor
{
// --------------------------------------------------------
// PartyPlayerModel
// --------------------------------------------------------
class PartyPlayerModel final : public BasePlayerModel
{
Q_OBJECT
public:
explicit PartyPlayerModel(QObject *parent = nullptr);
bool initModel(LtsSession::LtsSessionDataDds *session) override;
QVector<int> updateDataView(const QVector<int> &equipNumberList) override { Q_UNUSED(equipNumberList); return {}; }
void loadData(const QVector<int> &idList) override { Q_UNUSED(idList); }
};
// --------------------------------------------------------
// PartyPlayerProxyModel
// --------------------------------------------------------
class PartyPlayerProxyModel final : public BasePlayerProxyModel
{
Q_OBJECT
public:
using BasePlayerProxyModel::BasePlayerProxyModel;
public slots:
void setPartyId(int partyId);
void setTypeClass(ParticipantManagement::TypeClass typeClass);
protected:
bool filterAcceptsRow(int source_row,
const QModelIndex &source_parent) const override;
int m_partyId = -1;
ParticipantManagement::TypeClass m_typeClass = ParticipantManagement::TypeClass::Unknown;
};
} //namespace ServiceMonitor
@@ -0,0 +1,161 @@
/**
* @RDE_HEADER@
* Model for Equipment Check Single Service
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-16
*/
#include "smo_single_player_model.h"
namespace ServiceMonitor
{
void SinglePlayerModel::loadData(const QVector<int> &idList)
{
DEBUG_LOG(m_logger) << "**** loadData: ";
const QMap<qint32,ParticipantManagement::Participant> participants =
m_ppmDtc->participants();
const QMap<qint32, ParticipantManagement::DynamicParticipantData> dynPartData =
m_ppmDtc->dynamicParticipantDatas();
QVector<int> equipNos;
QVector<PlayerData> newRows;
newRows.reserve(idList.size());
for (int id : idList)
{
if (id < 0)
{
equipNos += id;
continue;
}
auto itParticipants = participants.find(id);
if (itParticipants == participants.end())
continue; // participant with id not available
const auto &participant = itParticipants.value();
if (!participant.equipmentNumber().is_set())
continue; // participant has (currently) no equipment number
const int row = findRowForId(participant.id());
if (row == -1)
{
auto itDynData = dynPartData.find(participant.id());
newRows.push_back(setPlayerData(itParticipants.value(), itDynData == dynPartData.end() ?
ParticipantManagement::DynamicParticipantData() :
itDynData.value()));
}
else
{
// nothing to do, participant already in list
}
}
if (!equipNos.isEmpty())
{
for (const auto &participant : participants)
{
if (equipNos.isEmpty())
break;
if (participant.equipmentNumber().is_set() && equipNos.contains(-participant.equipmentNumber().get()))
{
equipNos.removeAll(-participant.equipmentNumber().get());
int row = findRowForId(participant.id());
if (row < 0)
row = findRowForId(-participant.equipmentNumber().get());
if (row == -1)
{
auto itDynData = dynPartData.find(participant.id());
newRows.push_back(setPlayerData(participant, itDynData == dynPartData.end() ?
ParticipantManagement::DynamicParticipantData() :
itDynData.value()));
}
}
}
}
for (int equipNo : qAsConst(equipNos))
{
ParticipantManagement::Participant p;
p.id(equipNo); // already negative
p.equipmentNumber(-equipNo);
if (!findParticipantId(p.id()))
newRows.push_back(setPlayerData(p, ParticipantManagement::DynamicParticipantData()));
}
insertRows(newRows);
}
QVector<int> SinglePlayerModel::updateDataView(const QVector<int> &equipNumberList)
{
QVector<int> ret;
DEBUG_LOG(m_logger) << "**** updateDataView: ";
QVector<PlayerData> newRows;
newRows.reserve(equipNumberList.size());
const QHash<int, ParticipantManagement::Participant> equipNo2PartMap(participantsByEquipNo());
const QMap<qint32, ParticipantManagement::DynamicParticipantData> dynPartData =
m_ppmDtc->dynamicParticipantDatas();
for (int number : equipNumberList)
{
auto itEquipNo = equipNo2PartMap.find(number);
if (itEquipNo == equipNo2PartMap.end())
{
ParticipantManagement::Participant p;
p.id(-number);
p.equipmentNumber(number);
if (!findParticipantId(p.id()))
newRows.push_back(setPlayerData(p, ParticipantManagement::DynamicParticipantData()));
continue; // equipNo currently not available
}
const auto &participant = itEquipNo.value();
ret += participant.id();
const int row = findRowForId(participant.id());
if (row == -1)
{
auto itDynData = dynPartData.find(participant.id());
newRows.push_back(setPlayerData(itEquipNo.value(),
itDynData == dynPartData.end() ?
ParticipantManagement::DynamicParticipantData() :
itDynData.value()));
}
else
{
// nothing to do, equipment number already in list
}
}
insertRows(newRows);
return ret;
}
QHash<int,ParticipantManagement::Participant> SinglePlayerModel::participantsByEquipNo() const
{
QHash<int,ParticipantManagement::Participant> ret;
ret.reserve(m_participants.size());
for (const ParticipantManagement::Participant &part : m_participants)
{
if (part.equipmentNumber().is_set())
ret.insert(part.equipmentNumber().get(), part);
}
return ret;
}
QStringList SinglePlayerModel::getAllParticipantIds() const
{
QStringList ids;
ids.reserve(m_vecData.size());
for (const auto &playerData : m_vecData)
ids.append(QString::number(playerData.participantId));
return ids;
}
bool SinglePlayerModel::findParticipantId(int id) const
{
for (const auto &playerData : m_vecData)
{
if (playerData.participantId == id)
return true;
}
return false;
}
} // namespace ServiceMonitor
@@ -0,0 +1,36 @@
/**
* @RDE_HEADER@
* Model for Equipment Check
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-16
*/
#pragma once
#include "smo_base_player_model.h"
namespace ServiceMonitor
{
// --------------------------------------------------------
// SinglePlayerModel
// --------------------------------------------------------
class SinglePlayerModel final : public BasePlayerModel
{
Q_OBJECT
public:
using BasePlayerModel::BasePlayerModel;
QVector<int> updateDataView(const QVector<int> &equipNumberList) override;
void loadData(const QVector<int> &idList) override;
QStringList getAllParticipantIds() const override;
private:
// EquipNo, ParticipantId
QHash<int, ParticipantManagement::Participant> participantsByEquipNo() const;
bool findParticipantId(int id) const;
};
} //namespace ServiceMonitor
@@ -0,0 +1,266 @@
/**
* @RDE_HEADER@
* Single Service Equipment Check Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-16
*/
#include "smo_single_service_equipment_check_dialog.h"
#include "ui_smo_single_service_equipment_check_dialog.h"
#include <PluginInterfaces/gui_plugin_interface.h>
#include <FileManagement/flm_translation.h>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <LtsUtilsSettings/settings.h>
namespace ServiceMonitor
{
SingleServiceEquipmentCheckDialog::SingleServiceEquipmentCheckDialog(LtsSession::LtsSession *session, QWidget *parent)
: BaseEquipmentCheck("SingleServiceEquipmentCheckDialog", session, parent)
, m_ppmGuiIfcDtc(nullptr)
, m_flmGui(nullptr)
, m_ui(new Ui::SingleServiceEquipmentCheckDialog)
{
m_ui->setupUi(this);
m_buttonBox->connectButton(LtsWidgets::DialogButton::Show,
this,
&SingleServiceEquipmentCheckDialog::onShowClicked);
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove,
this,
&SingleServiceEquipmentCheckDialog::onRemoveClicked);
// Save/Load from Library Button
m_buttonBox->connectLibraryButton(this,
&SingleServiceEquipmentCheckDialog::onLoadClicked,
&SingleServiceEquipmentCheckDialog::onSaveClicked);
if (!session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_flmGui))
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Library, false);
connect(m_ui->leEquipNumber, &QLineEdit::returnPressed,
this, &SingleServiceEquipmentCheckDialog::onAddEquipmentNr);
connect(m_ui->pbAddEquip, &QPushButton::clicked,
this, &SingleServiceEquipmentCheckDialog::onAddEquipmentNr);
connect(m_ui->tvSinglePlayer, &LtsDataView::LtsDataView::doubleClicked,
this, &SingleServiceEquipmentCheckDialog::onShowClicked);
m_ui->cbRequestBITOnAdd->setChecked(true);
setOnlineHelpFilename(QStringLiteral("Situation-Single_Service_Equipment_Check"));
}
SingleServiceEquipmentCheckDialog::~SingleServiceEquipmentCheckDialog()
{
delete m_ui;
}
void SingleServiceEquipmentCheckDialog::retranslate()
{
translate(m_ui, tr("Single Service Equipment Check"));
}
void SingleServiceEquipmentCheckDialog::tableColumnOrganiserSetting()
{
//LtsColumnOrganiser
m_ui->tvSinglePlayer->setColumnsOrganiserEnabled(identifier(), true);
}
bool SingleServiceEquipmentCheckDialog::init(const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc,
const std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> &ppmGuiIfcDtc)
{
DEBUG_LOG(m_logger) << "**** init() ";
if (!BaseEquipmentCheck::init(ppmFtc))
{
ERROR_LOG(m_logger) << "init: ppmDtc or ppmFtc shared_ptr invalid";
return false;
}
if (!ppmGuiIfcDtc)
{
ERROR_LOG(m_logger) << "init: ppmGuiIfcDtc shared_ptr invalid";
return false;
}
m_ppmGuiIfcDtc = ppmGuiIfcDtc;
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_flmGui))
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Load, false);
m_playerModel = new SinglePlayerModel(this);
m_playerModel->initModel(m_session);
auto proxyModel = new BasePlayerProxyModel(this);
proxyModel->setSourceModel(static_cast<SinglePlayerModel *>(m_playerModel));
proxyModel->setDynamicSortFilter(false);
m_ui->tvSinglePlayer->setSortingEnabled(true);
m_ui->tvSinglePlayer->setModel(proxyModel);
m_ui->tvSinglePlayer->setSelectionMode(QAbstractItemView::ExtendedSelection);
#ifndef LTS_DEBUG
m_ui->tvSinglePlayer->hideColumn(BasePlayerModel::ColParticipantId);
#endif
m_ui->tvSinglePlayer->setSortIndicator(BasePlayerModel::ColPositionAge, Qt::AscendingOrder);
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, false);
connect(m_playerModel, &SinglePlayerModel::rowsInserted, this, [this]()
{
if (m_flmGui)
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, m_playerModel->rowCount() > 0);
});
connect(m_playerModel, &SinglePlayerModel::rowsRemoved, this, [this]()
{
if (m_flmGui)
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, m_playerModel->rowCount() > 0);
});
const bool showPvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"),
QStringLiteral("HasPvSan"));
m_ui->cbResetSanMat->setVisible(showPvSan);
return true;
}
void SingleServiceEquipmentCheckDialog::setEquipmentNumbers(const QVector<int> &equipmentNumbers, bool replace)
{
// do not trigger BITE:
m_ui->cbRequestBITOnAdd->setChecked(false);
if (replace)
m_playerModel->clear();
SinglePlayerModel *spm = static_cast<SinglePlayerModel *>(m_playerModel);
spm->updateDataView(equipmentNumbers);
}
void SingleServiceEquipmentCheckDialog::keyPressEvent(QKeyEvent *event)
{
BaseEquipmentCheck::keyPressEvent(event);
if (event->key() == Qt::Key_Delete)
onRemoveClicked();
}
LtsDataView::LtsDataView *SingleServiceEquipmentCheckDialog::view()
{
return m_ui->tvSinglePlayer;
}
const LtsDataView::LtsDataView *SingleServiceEquipmentCheckDialog::view() const
{
return m_ui->tvSinglePlayer;
}
void SingleServiceEquipmentCheckDialog::onShowClicked()
{
DEBUG_LOG(m_logger) << "**** onShowClicked() ";
const QModelIndexList selectedRows = m_ui->tvSinglePlayer->selectedRows();
for (const QModelIndex &idx : selectedRows)
{
const int id = m_playerModel->getRowData(idx.row()).participantId;
if (id <= 0)
continue;
m_ppmGuiIfcDtc->showParticipantInfoWindow(id);
}
}
void SingleServiceEquipmentCheckDialog::onRemoveClicked()
{
DEBUG_LOG(m_logger) << "**** onRemoveClicked() ";
m_playerModel->removeItems(m_ui->tvSinglePlayer->selectedRows());
}
void SingleServiceEquipmentCheckDialog::onSaveClicked()
{
if (!m_flmGui)
return;
DEBUG_LOG(m_logger) << "**** onSaveClicked() ";
QJsonArray ids = QJsonArray::fromStringList(m_playerModel->getAllParticipantIds());
if (ids.isEmpty())
return;
QJsonObject saveObject;
saveObject[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::SMOSingleServiceEquipmentCheck);
saveObject[QStringLiteral("Ids")] = ids;
const QJsonDocument saveDoc(saveObject);
int fileId = m_flmGui->saveFileContent(this, FileManagement::FileType::Xml, m_session->exerciseId(), saveDoc.toJson(QJsonDocument::Compact));
if (fileId > 0)
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
else
ERROR_LOG(m_logger) << "Could not save file in library ";
}
void SingleServiceEquipmentCheckDialog::onLoadClicked()
{
if (!m_flmGui)
return;
DEBUG_LOG(m_logger) << "**** onLoadClicked() ";
QByteArray content;
int fileId = m_flmGui->loadFileContent(this, content, {FileManagement::FileType::Xml}, m_session->exerciseId(), FileManagement::toString(FileManagement::XmlType::SMOSingleServiceEquipmentCheck));
if (fileId > 0)
{
if (!m_flmGui->isXmlType(content, FileManagement::toString(FileManagement::XmlType::SMOSingleServiceEquipmentCheck)))
{
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
LtsWidgets::LtsMessageDialog::showMessage(this,
tr("Invalid xml file content"),
windowTitle(),
LtsWidgets::Behaviour::Modal,
LtsWidgets::Button::Yes,
texts);
}
else
{
const QJsonDocument loadDoc(QJsonDocument::fromJson(content));
const QJsonArray arr = loadDoc.object().value(QStringLiteral("Ids")).toArray();
QVector<int> playerList;
playerList.reserve(arr.size());
for (const auto &val : arr)
playerList.append(val.toString().toInt());
m_playerModel->loadData(playerList);
}
}
}
void SingleServiceEquipmentCheckDialog::addEquipmentNr(int equipmentNumber)
{
auto ret = m_playerModel->updateDataView({equipmentNumber});
if (ret.isEmpty())
return;
std::vector<int> vec;
vec.push_back(ret.first());
if (m_ui->cbRequestBITOnAdd->isChecked())
sendBiteRequest(vec, false);
sendInitRequest(vec,
m_ui->cbResetManipulation->isChecked(),
m_ui->cbResetGearCharge->isChecked(),
m_ui->cbInit->isChecked(),
m_ui->cbResetSanMat->isChecked());
}
void SingleServiceEquipmentCheckDialog::onAddEquipmentNr()
{
if (m_ui->leEquipNumber->text().isEmpty())
return;
const int eqNo = m_ui->leEquipNumber->text().toInt();
m_ui->leEquipNumber->clear();
addEquipmentNr(eqNo);
}
} // namespace ServiceMonitor
@@ -0,0 +1,64 @@
/**
* @RDE_HEADER@
* Single Service Equipment Check Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Mueller, SGAS, 2017-05-16
*/
#pragma once
#include "smo_base_equipment_check.h"
#include "smo_single_player_model.h"
#include <LtsSession/lts_session.h>
#include <Plugins/ParticipantManagement/ppm_participant_info_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
class QItemSelection;
namespace Ui
{
class SingleServiceEquipmentCheckDialog;
}
namespace ServiceMonitor
{
class SingleServiceEquipmentCheckDialog final : public BaseEquipmentCheck
{
Q_OBJECT
public:
explicit SingleServiceEquipmentCheckDialog(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~SingleServiceEquipmentCheckDialog();
bool init(const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc,
const std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> &ppmGuiIfcDtc);
void setEquipmentNumbers(const QVector<int> &equipmentNumbers, bool replace = true);
protected:
void keyPressEvent(QKeyEvent *event) override;
LtsDataView::LtsDataView *view() override;
const LtsDataView::LtsDataView *view() const override;
private slots:
void onShowClicked();
void onRemoveClicked();
void onSaveClicked();
void onLoadClicked();
void onAddEquipmentNr();
private:
void addEquipmentNr(int equipmentNumber);
void retranslate() override;
void tableColumnOrganiserSetting() override;
std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> m_ppmGuiIfcDtc;
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
Ui::SingleServiceEquipmentCheckDialog *m_ui;
};
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SingleServiceEquipmentCheckDialog</class>
<widget class="QWidget" name="SingleServiceEquipmentCheckDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>999</width>
<height>473</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">Equipment Check</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lEquipNumber">
<property name="text">
<string>Add Equipment Number:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leEquipNumber"/>
</item>
<item>
<widget class="QPushButton" name="pbAddEquip">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbRequestBITOnAdd">
<property name="text">
<string>Request BITE</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbInit">
<property name="text">
<string>Init</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbResetManipulation">
<property name="text">
<string>Reset Manipulation</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbResetGearCharge">
<property name="text">
<string>Reset Gear Charge</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbResetSanMat">
<property name="text">
<string>Reset Medical Supplies</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="LtsDataView::LtsDataView" name="tvSinglePlayer" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<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,173 @@
/**
* @RDE_HEADER@
* Edit the defaults for an EGCU
* $Id$
* $HeadURL$
* $Author$
* Created by Malte Diers, SLTE, 2021-05-10
*/
#include "smo_structure_element_edit.h"
#include "ui_smo_structure_element_edit.h"
#include <Common/logger.h>
// Lts
#include <LtsSession/lts_session.h>
#include <LtsUtilsGuiDds/request_helper.h>
// DDS
#include <AssetManagement/asm_data_plugin_interface.h>
#include <InfrastructureManagement/ism_data_plugin_interface.h>
// Qt
#include <QComboBox>
#include <QJsonDocument>
#include <QJsonArray>
namespace ServiceMonitor
{
StructureElementEdit::StructureElementEdit(const QString &menuGroup, QWidget *parent, LtsWidgets::ButtonCombination buttonCombination)
: LtsWidgets::LtsDialog(parent, buttonCombination)
, m_menuGroup(menuGroup)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_logger(getLogger(QLatin1String("StructureElementEdit")))
, m_ui(new Ui::StructureElementEdit)
{
m_ui->setupUi(this);
}
bool StructureElementEdit::init(const InfrastructureManagement::StructureElement &data, LtsSession::LtsSession *session)
{
m_structureElement = data;
if (!session->getDtc<InfrastructureManagement::DataInterface>(m_ismDtc))
return false;
if (!session->getFtc<InfrastructureManagement::DataInterface>(m_ismFtc))
return false;
if (m_structureElement.structureElementTypeId() != InfrastructureManagement::StructureElementType_def::Building)
{
m_ui->groupBox->hide(); // Flashing
}
m_ui->cbFlashing->addItem(tr("Off"), InfrastructureManagement::EffectOverride_def::PermanentOff);
m_ui->cbFlashing->addItem(tr("Auto"), InfrastructureManagement::EffectOverride_def::Automatic);
m_ui->cbFlashing->setCurrentIndex(m_ui->cbFlashing->findData(InfrastructureManagement::EffectOverride_def::Automatic));
updateComboBoxes();
m_ui->lblRoom->hide();
m_ui->lbxRoom->hide();
m_ui->lblFloor->hide();
m_ui->lbxFloor->hide();
switch (m_structureElement.path().size()) {
case 3:
m_ui->lblRoom->setText(structureElementName(m_structureElement.path()[2]));
m_ui->lblRoom->show();
m_ui->lbxRoom->show();
Q_FALLTHROUGH();
case 2:
m_ui->lblFloor->setText(structureElementName(m_structureElement.path()[1]));
m_ui->lblFloor->show();
m_ui->lbxFloor->show();
Q_FALLTHROUGH();
case 1:
m_ui->lblBuilding->setText(structureElementName(m_structureElement.path()[0]));
break;
default:
break;
}
return true;
}
QString StructureElementEdit::structureElementName(int seId)
{
InfrastructureManagement::StructureElement se;
m_ismDtc->getStructureElementById(seId, se);
return QString::fromStdString(se.displayName());
}
StructureElementEdit::~StructureElementEdit()
{
delete m_ui;
}
void StructureElementEdit::updateComboBoxes()
{
QJsonParseError parserError;
QByteArray content = QByteArray::fromStdString(m_structureElement.properties());
const QJsonDocument doc(QJsonDocument::fromJson(content, &parserError));
if (parserError.error != QJsonParseError::NoError)
return;
QJsonObject docObj = QJsonObject(doc.object());
if ( !docObj.contains(QStringLiteral("Overrides")))
return;
QJsonObject overridesObj = docObj.value(QStringLiteral("Overrides")).toObject();
int flashValue = overridesObj.value(QStringLiteral("flash")).toInt();
m_ui->cbFlashing->setCurrentIndex(m_ui->cbFlashing->findData(flashValue));
}
QString StructureElementEdit::dialogIdentifier() const
{
return QLatin1String("StructureElementEdit") + QString::number(m_structureElement.id());
}
void StructureElementEdit::retranslate()
{
translate(m_ui, tr("Edit Building/Floor/Room: %1").arg(QString::fromStdString(m_structureElement.displayName())));
}
void StructureElementEdit::onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
}
bool StructureElementEdit::apply()
{
std::string properties;
QByteArray content_neu;
properties= m_structureElement.properties();
DEBUG_LOG(m_logger) << "structureElementId=" << m_structureElement.id()
<< " properties=" << properties
<< " MountingPointType=" << m_structureElement.mountingPointTypeId()
<< " structureElementTypeId=" << m_structureElement.structureElementTypeId();
QJsonObject resultObj;
QJsonObject overrideObj;
if (m_ui->cbFlashing->currentData().toInt() != InfrastructureManagement::EffectOverride_def::Automatic)
overrideObj.insert(QStringLiteral("flash"), m_ui->cbFlashing->currentData().toInt());
if (overrideObj.size())
resultObj.insert (QStringLiteral("Overrides"), overrideObj);
content_neu = QJsonDocument(resultObj).toJson(QJsonDocument::Compact);
if (content_neu.toStdString() == properties)
return true;
m_structureElement.properties(content_neu.toStdString());
ERROR_LOG(m_logger) << "properties=" << m_structureElement.properties()
<< " name=" << m_structureElement.name()
<< " seId=" << m_structureElement.id()
<< " mountingPointId=" << m_structureElement.mountingPointId();
InfrastructureManagement::StructureElementModifyRequest request;
request.mainStructureElementId(m_structureElement.mainStructureElementId());
request.elements().resize(1);
request.elements().at(0) = m_structureElement;
m_requestHelper->addRequest([this, request]() {return m_ismFtc->structureElementModifyRequest(request, this);});
m_requestHelper->startRequests();
return true;
}
} // namespace
@@ -0,0 +1,68 @@
/**
* @RDE_HEADER@
* Edit the defaults for an EGCU
* $Id$
* $HeadURL$
* $Author$
* Created by Malte Diers, SLTE, 2021-05-10
*/
#pragma once
#include "smo_egcu_model.h"
#include <InfrastructureManagement/ism_ftc.h>
#include <LtsWidgets/lts_dialog.h>
namespace Ui {
class StructureElementEdit;
}
namespace LtsSession {
class LtsSession;
}
namespace LtsUtils {
class RequestHelper;
}
class QTreeWidgetItem;
namespace ServiceMonitor
{
class StructureElementEdit
: public LtsWidgets::LtsDialog
, protected InfrastructureManagement::Interface::Ftc::StructureElementModifyReplyHandler
{
Q_OBJECT
public:
explicit StructureElementEdit(const QString &menuGroup,
QWidget *parent = nullptr,
LtsWidgets::ButtonCombination buttonCombination = LtsWidgets::ButtonCombination::OkApplyCancel);
~StructureElementEdit();
QString menuGroup() const { return m_menuGroup; }
QString dialogIdentifier() const;
bool init(const InfrastructureManagement::StructureElement &data, LtsSession::LtsSession *session);
void onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final;
bool apply() override;
private:
void retranslate() override;
void updateComboBoxes();
private:
InfrastructureManagement::StructureElement m_structureElement;
QString m_menuGroup;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
std::shared_ptr<InfrastructureManagement::Interface::Ftc> m_ismFtc;
LtsUtils::RequestHelper *m_requestHelper;
NGL::INGLLogger &m_logger;
Ui::StructureElementEdit *m_ui;
QString structureElementName(int seId);
};
} // namespace ServiceMonitor
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>StructureElementEdit</class>
<widget class="QWidget" name="StructureElementEdit">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>781</width>
<height>473</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="lbxFloor">
<property name="text">
<string>Floor:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbxRoom">
<property name="text">
<string>Room:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Flashing</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QComboBox" name="cbFlashing"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="lblRoom">
<property name="text">
<string notr="true">&lt;ROOM&gt;</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lbxBuilding">
<property name="text">
<string>Building:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lblBuilding">
<property name="text">
<string notr="true">&lt;BUILDING&gt;</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>210</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lblFloor">
<property name="text">
<string notr="true">&lt;FLOOR&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>