/** * @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 #include #include #include #include #include #include #include #include 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(m_dtc)) return false; if (!m_session->getFtc(m_ftc)) return false; if (!m_session->getForeignGuiInterface(m_ppmGuiCbxIfc)) return false; if (!m_session->getDtc(m_dtcOpm)) return false; if (!m_session->getFtc(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(m_ui->cbRole->currentData().toInt()); ParticipantManagement::HlaForceIdentifierEnum hlaIdentfier = static_cast(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 ¬if, 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 ¬if) { for(QCheckBox* cb : findChildren()) { 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 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); } }