Files
qt5-legatus-legacy/Lts/Plugins/ParticipantManagement/Gui/PartyEdit/ppm_party_edit.cpp
T
torstenandCopilot 3028302f7b Qt6 Migration: Merge latest Qt5 devel content and apply migration fixes
- Merged 292 changed files from dlbo snapshot
- Fixed IDL enum collisions (PortType, PdmEventType)
- Fixed Grantlee template for C++11 scoped enums
- Fixed CMake VERSION_GREATER syntax
- Added missing directories (THP, LtsRestClient, etc.)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-15 18:20:51 +00:00

449 lines
15 KiB
C++
Executable File

/**
* @RDE_HEADER@
* ParticipantManagement - Party Edit Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2016-11-11
*/
#include "ppm_party_edit.h"
#include "NGLLogger/INGLLogger.h"
#include "ui_ppm_party_edit.h"
#include <QColorDialog>
#include <QJsonDocument>
#include <QJsonArray>
#include <QMessageBox>
#include <ParticipantManagement/ppm_translation.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <LtsUtilsSettings/settings.h>
#include <LtsSession/lts_session_data.h>
#include <Services/AreaEffectSimulation/aes_operator_rights.h>
namespace ParticipantManagement
{
PartyEdit::PartyEdit(QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
, m_partyId(-1)
, m_color(Qt::white)
, m_fadedColor(Qt::white)
, m_isUsed(false)
, m_partiallyUnchangeable(false)
, m_dtc(nullptr)
, m_ftc(nullptr)
, m_ppmGuiCbxIfc(nullptr)
, m_dtcOpm(nullptr)
, m_ftcOpm(nullptr)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_session(nullptr)
, m_ui(new Ui::PartyEdit)
, m_logger(getLogger("PartyEdit"))
{
m_ui->setupUi(this);
} // end of ctor()
//-----------------------------------------------------------------------------
PartyEdit::~PartyEdit()
{
delete m_ui;
} // end of dtor()
//-----------------------------------------------------------------------------
void PartyEdit::retranslate()
{
translate(m_ui, m_dtc->party(m_partyId), trPartyName(m_dtc->party(m_partyId).name()), tr("Party"));
m_ppmGuiCbxIfc->fillRoleComboBox(m_ui->cbRole);
m_ppmGuiCbxIfc->fillHlaForceIdentifierComboBox(m_ui->cbHlaForceIdentifier);
}
void PartyEdit::lock()
{
LtsWidgets::LtsDialog::lock();
if (unchangeable())
{
m_partiallyUnchangeable = true;
setUnchangeable(false);
m_ui->tbColor->setEnabled(false);
m_ui->tbFadedColor->setEnabled(false);
}
m_ui->cbAdlerNotification->setEnabled(true);
m_ui->cbCombatOrder->setEnabled(true);
}
bool PartyEdit::init(int partyId, LtsSession::LtsSession *session)
{
DEBUG_LOG(m_logger) << "PartyEdit::init()";
m_session = session;
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_dtc))
return false;
if (!m_session->getFtc<ParticipantManagement::DataInterface>(m_ftc))
return false;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmGuiCbxIfc))
return false;
if (!m_session->getDtc<OperatorManagement::DataInterface>(m_dtcOpm))
return false;
if (!m_session->getFtc<OperatorManagement::DataInterface>(m_ftcOpm))
return false;
m_partyId = partyId;
m_ppmGuiCbxIfc->fillRoleComboBox(m_ui->cbRole);
m_ppmGuiCbxIfc->fillHlaForceIdentifierComboBox(m_ui->cbHlaForceIdentifier);
if (m_partyId >= 0) // pool has id 0 so is a valid party
{
const Party &party = m_dtc->party(m_partyId);
if(party.id() >= 0)
{
setData(party);
}
}
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
const bool enableHlaForceIdentifier = ps->value(QStringLiteral("ppm"),
QStringLiteral("enableHlaForceIdentifier")).toBool();
if (!enableHlaForceIdentifier)
{
m_ui->lblHlaIdentifier->hide();
m_ui->cbHlaForceIdentifier->hide();
}
// Could be filled programmatically later
m_ui->cbAdlerNotification->setProperty("Notification", NotificationManagement::NotificationType::AdlerNotification);
m_ui->cbCombatOrder->setProperty("Notification", NotificationManagement::NotificationType::CombatOrder);
bool enableNotification = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::NotificationShow) );
if (!enableNotification)
{
m_ui->cbAdlerNotification->hide();
m_ui->cbCombatOrder->hide();
}
const ParticipantManagement::ConnectState status = m_dtc->saaConnectedState(m_partyId);
const bool enableReset = (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::ChargeAdministrationShow)) &&
(status.underlying() == ParticipantManagement::ConnectState::NoHeartbeat);
if (!enableReset)
{
m_ui->lblReset->hide();
m_ui->tbResetAdlerConnection->hide();
}
connect(m_ui->tbColor, &QToolButton::clicked, this, &PartyEdit::onColorClicked);
connect(m_ui->tbFadedColor, &QToolButton::clicked, this, &PartyEdit::onFadedColorClicked);
connect(m_ui->tbResetAdlerConnection, &QToolButton::clicked, this, &PartyEdit::onResetAdlerConnectionClicked);
connect(m_dtc.get(), &ParticipantManagement::Interface::Dtc::partyChanged, this, &PartyEdit::onPartyChanged);
// check Notifications
notificationCheck();
setOnlineHelpFilename(QStringLiteral("Situation-Parties"));
return true;
}
//slots
bool PartyEdit::apply()
{
if (!m_partiallyUnchangeable)
{
ParticipantManagement::Role role = static_cast<ParticipantManagement::Role_def::type>(m_ui->cbRole->currentData().toInt());
ParticipantManagement::HlaForceIdentifierEnum hlaIdentfier = static_cast<ParticipantManagement::HlaForceIdentifierEnum_def::type>(m_ui->cbHlaForceIdentifier->currentData().toInt());
Party req;
req.id(m_partyId);
req.name(m_ui->leName->text().toStdString());
req.color(m_color.rgb());
req.fadingColor(m_fadedColor.rgb());
req.role(role);
req.hlaForceIdentifier(hlaIdentfier);
req.isUsedBy(m_isUsed);
m_requestHelper->addRequest([req, this]()
{
return m_ftc->modifyPartyDataRequest(req, this);
});
}
OperatorManagement::User user = m_dtcOpm->user(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
QJsonObject opmProperties(QJsonDocument::fromJson(QByteArray::fromStdString(user.properties())).object());
fillOpmProperties(opmProperties);
OperatorManagement::OperatorCreateModifyRequest reqOpm;
reqOpm.id(user.id());
reqOpm.name(user.name());
reqOpm.description(user.description());
reqOpm.audioChannelPriority(user.audioChannelPriority());
reqOpm.projectionPriority(user.projectionPriority());
reqOpm.image(user.image());
reqOpm.visiblePartiesByExercise(user.visiblePartiesByExercise());
reqOpm.rolePresetId(user.rolePresetId());
QString properties = QString::fromUtf8(QJsonDocument(opmProperties).toJson());
DEBUG_LOG(m_logger) << "properties: " << properties;
reqOpm.properties(properties.toStdString());
m_requestHelper->addRequest([reqOpm, this]()
{
return m_ftcOpm->operatorCreateModifyRequest(reqOpm, this);
});
return m_requestHelper->startRequests();
}
void ParticipantManagement::PartyEdit::onColorClicked()
{
QColorDialog diag;
diag.setOption(QColorDialog::DontUseNativeDialog);
diag.setCurrentColor(m_color);
if( diag.exec() == QColorDialog::Accepted)
{
m_color = diag.currentColor();
setColorToButton(m_ui->tbColor, m_color);
slotChangesMade();
}
}
void ParticipantManagement::PartyEdit::onFadedColorClicked()
{
QColorDialog diag;
diag.setOption(QColorDialog::DontUseNativeDialog);
diag.setCurrentColor(m_fadedColor);
if(diag.exec() == QColorDialog::Accepted)
{
m_fadedColor = diag.currentColor();
setColorToButton(m_ui->tbFadedColor, m_fadedColor);
slotChangesMade();
}
}
void PartyEdit::onResetAdlerConnectionClicked()
{
const int ret = QMessageBox::question(this, tr("Reset ADLER system"),
tr("Are you sure you want to do that?\n"
"If any ADLER objects exist, they will all be deleted and force the disconnection.\n\n"
"Please note:\nAll open ADLER Effect Cluster Dialog boxes must be closed first.\n"
),
QMessageBox::Yes | QMessageBox::Cancel);
if(ret == QMessageBox::Yes)
modifyPartyProperties();
}
void PartyEdit::onPartyChanged(const Party &data, DataModification modType)
{
if (modType == DataModification::eRemoved || data.id() != m_partyId)
return;
const ConnectState connectState = m_dtc->saaConnectedState(m_partyId);
switch (connectState.underlying())
{
case ParticipantManagement::ConnectState::NoHeartbeat:
{
m_ui->lblReset->show();
m_ui->tbResetAdlerConnection->show();
break;
}
default:
{
m_ui->lblReset->hide();
m_ui->tbResetAdlerConnection->hide();
break;
}
}
}
//private
void PartyEdit::setData(const Party &party)
{
m_ui->leName->setText(ParticipantManagement::trPartyName(party.name()));
m_color = QColor::fromRgb(QRgb(party.color()));
m_fadedColor = QColor::fromRgb(QRgb(party.fadingColor()));
m_isUsed = party.isUsedBy();
setColorToButton(m_ui->tbColor, m_color);
setColorToButton(m_ui->tbFadedColor, m_fadedColor);
m_ui->cbRole->setCurrentIndex(m_ui->cbRole->findData(party.role().underlying()));
m_ui->cbHlaForceIdentifier->setCurrentIndex(m_ui->cbHlaForceIdentifier->findData(party.hlaForceIdentifier().underlying()));
}
void PartyEdit::setColorToButton(QToolButton *button, const QColor &color)
{
button->setStyleSheet(QStringLiteral("QToolButton{ background: %1; }").arg(color.name())); // TODO: muss das sein?
}
void PartyEdit::fillJsonSuppressNotifications( QJsonArray &notif, NotificationManagement::NotificationType notifType)
{
QJsonObject suppNotif;
suppNotif[QStringLiteral("partyId")] = m_partyId;
suppNotif[QStringLiteral("AddressType")] = NotificationManagement::AddressType_def::Service;
suppNotif[QStringLiteral("Address")] = AreaEffectSimulation::Offset;
QCheckBox *cbNotif = findCheckBoxByNotificationType(notifType);
if (!cbNotif)
return;
int index = findSuppressNotification(m_partyId, notifType, notif);
if (!cbNotif->isChecked())
{
suppNotif[QStringLiteral("NotificationType")] = notifType.underlying();
if (index >= 0)
notif.replace(index, suppNotif);
else
notif.append(suppNotif);
}
else
{
if (index >= 0)
notif.removeAt(index);
}
}
QCheckBox* PartyEdit::findCheckBoxByNotificationType(const NotificationManagement::NotificationType &notif)
{
for(QCheckBox* cb : findChildren<QCheckBox*>())
{
if (cb->property("Notification").toInt() == notif.underlying())
return cb;
}
return nullptr;
}
int PartyEdit::findSuppressNotification( int partyId, NotificationManagement::NotificationType notifType, QJsonArray suppNotif)
{
for (int i=0; i < suppNotif.size(); ++i)
{
QJsonObject obj = suppNotif.at(i).toObject();
if (obj[QStringLiteral("partyId")] == partyId &&
obj[QStringLiteral("NotificationType")] == notifType.underlying())
return i;
}
return -1;
}
void PartyEdit::fillOpmProperties( QJsonObject &opmProperties)
{
QJsonArray arrExercises = opmProperties[QStringLiteral("Exercises")].toArray();
QJsonObject objExe;
QJsonArray notif;
int indexToReplace = -1;
if (arrExercises.isEmpty())
{
fillJsonSuppressNotifications(notif, NotificationManagement::NotificationType_def::AdlerNotification);
fillJsonSuppressNotifications(notif, NotificationManagement::NotificationType_def::CombatOrder);
}
else
{
for (int i=0; i < arrExercises.size(); ++i)
{
objExe = arrExercises.at(i).toObject();
if (objExe[QStringLiteral("exerciseId")] == m_session->exerciseId())
{
notif = objExe[QStringLiteral("suppressNotifications")].toArray();
fillJsonSuppressNotifications(notif, NotificationManagement::NotificationType_def::AdlerNotification);
fillJsonSuppressNotifications(notif, NotificationManagement::NotificationType_def::CombatOrder);
indexToReplace = i;
break;
}
}
}
objExe[QStringLiteral("suppressNotifications")] = notif;
objExe[QStringLiteral("exerciseId")] = m_session->exerciseId();
if (indexToReplace >= 0)
arrExercises.replace(indexToReplace, objExe);
else
arrExercises.append(objExe);
opmProperties[QStringLiteral("Exercises")] = arrExercises;
}
void PartyEdit::notificationCheck()
{
if (!m_dtcOpm->isAdlerAllowedParty(m_session->exerciseId(), m_partyId, LtsSessionData::LtsSessionData::getInstance()->getOperatorId()))
{
WARNING_LOG(m_logger) << "Party " << m_partyId << " not allowed for this user";
m_ui->lblNotifications->hide();
m_ui->cbAdlerNotification->hide();
m_ui->cbCombatOrder->hide();
return;
}
DEBUG_LOG(m_logger) << "Party allowed for ADLER notifications";
const std::string properties = m_dtcOpm->user(LtsSessionData::LtsSessionData::getInstance()->getOperatorId()).properties();
QJsonObject opmProperties(QJsonDocument::fromJson(QByteArray::fromStdString(properties)).object());
QJsonArray arrExercises = opmProperties[QStringLiteral("Exercises")].toArray();
m_ui->cbAdlerNotification->setCheckState(Qt::Checked);
m_ui->cbCombatOrder->setCheckState(Qt::Checked);
// Here add another NotificationType, everything else will happen automatically
// CheckBox insert in Ui
const QList<NotificationManagement::NotificationType> notifTypes { NotificationManagement::NotificationType_def::AdlerNotification,
NotificationManagement::NotificationType_def::CombatOrder};
for (int i=0; i < arrExercises.size(); ++i)
{
const QJsonObject objExe = arrExercises.at(i).toObject();
if (objExe[QStringLiteral("exerciseId")] != m_session->exerciseId())
continue;
const QJsonArray notif = objExe[QStringLiteral("suppressNotifications")].toArray();
for (const auto elem : notifTypes)
{
auto cb = findCheckBoxByNotificationType(elem);
if (!cb)
continue;
int index = findSuppressNotification(m_partyId, elem, notif);
cb->setCheckState( index>= 0 ? Qt::Unchecked : Qt::Checked);
}
}
}
void PartyEdit::modifyPartyProperties()
{
DEBUG_LOG(m_logger) << LOGFUNCTION;
ParticipantManagement::Party requestParty;
requestParty = m_dtc->party(m_partyId);
// Get properties and then update them
const QJsonObject &origObj = QJsonDocument::fromJson(requestParty.properties().c_str()).object();
QJsonObject adlerPropertiesObj = origObj[QStringLiteral("Adler")].toObject();
adlerPropertiesObj[QStringLiteral("saaConnectedState")] = ParticipantManagement::ConnectState::Disconnecting;
const QByteArray &propertiesBa = requestParty.properties().c_str();
QJsonParseError parserError;
QJsonDocument doc(QJsonDocument::fromJson(propertiesBa, &parserError));
if (parserError.error != QJsonParseError::NoError)
{
ERROR_LOG(m_logger) << "Error parsing json document: " << parserError.errorString() << " '" << propertiesBa << "'";
doc = QJsonDocument();
}
DEBUG_LOG(m_logger) << "json to parse: " << doc.toJson();
QJsonObject obj(doc.object());
obj[QStringLiteral("Adler")] = adlerPropertiesObj;
const QByteArray propertiesStr = QJsonDocument(obj).toJson(QJsonDocument::Compact);
requestParty.properties() = propertiesStr.data();
m_ftc->modifyPartyDataRequest(requestParty);
}
}