/** * @RDE_HEADER@ * The ElokaDialog shows all electronic warfare and offers options to creating, updating and deleting * $Id$ * $HeadURL$ * $Author$ * Created by Astrid Mueller, SGAS, 2017-10-17 */ #include "avm_eloka_dialog.h" #include "ui_avm_eloka_dialog.h" #include #include #include #include #include #include #include #include namespace AudioVideoManagement { ElokaDialog::ElokaDialog(LtsSession::LtsSession *session, AvaSession *avaSession, Interface::Dtc *avmDtc, StreamNameMapping *streamNameMapping, const QString &menuGroup, QWidget *parent) : LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly) , m_ui(new Ui::ElokaDialog) , m_menuGroup(menuGroup) , m_elokaModel(new ElokaModel(session, this)) , m_session(session) , m_avaSession(avaSession) , m_elokaListCollector(m_avaSession->control()->comm(), [this] (QVector &&eloka) { onQueryElokaResponse(std::move(eloka)); }) , m_streamNameMapping(streamNameMapping) , m_avmDtc(avmDtc) , m_avaSessionEstablished(false) , m_usedCnr() , m_usedTvc() , m_usedAnnouncement() , m_logger(getLogger("ElokaDialog")) { Q_ASSERT(session); Q_ASSERT(avaSession); Q_ASSERT(streamNameMapping); Q_ASSERT(avmDtc); m_ui->setupUi(this); connect(m_avaSession, &AvaSession::sessionEstablished, this, &ElokaDialog::onAvaSessionEstablished); connect(m_avaSession, &AvaSession::disconnected, this, &ElokaDialog::onAvaSessionDisconnected); m_elokaListCollector.start(); m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &ElokaDialog::onAddClicked); m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &ElokaDialog::onEditClicked); m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &ElokaDialog::onRemoveClicked); m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &ElokaDialog::onPrint); m_ui->tvEloka->setModel(m_elokaModel); connect(m_ui->tvEloka, &LtsDataView::LtsDataView::signalSelectionChanged, this, &ElokaDialog::onSelectionChanged); onSelectionChanged(); connect(m_ui->tvEloka, &LtsDataView::LtsDataView::signalDoubleClicked, this, &ElokaDialog::onEditClicked); setAvaSessionStatus(m_avaSession->isEstablished()); setOnlineHelpFilename(QStringLiteral("Situation-Electronic_Warfare_Measures")); } ElokaDialog::~ElokaDialog() { delete m_elokaModel; delete m_ui; m_avaSession->control()->queryEloka(AvaQueryElokaMode::Stop); } void ElokaDialog::retranslate() { translate(m_ui, tr("Eloka")); } void ElokaDialog::onAvaSessionEstablished() { setAvaSessionStatus(true); } void ElokaDialog::onAvaSessionDisconnected() { m_elokaListCollector.reset(); m_elokaListCollector.start(); setAvaSessionStatus(false); } void ElokaDialog::setAvaSessionStatus(bool established) { m_avaSessionEstablished = established; // get all active eloka if (established) m_avaSession->control()->queryEloka(AvaQueryElokaMode::Push); m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, established); m_ui->lblAvaSessionStatus->setVisible(!established); onSelectionChanged(); } void ElokaDialog::onAddClicked() { DEBUG_LOG(m_logger) << "**** onAddClicked() "; ElokaEditDialog *dialog = new ElokaEditDialog(m_session, m_avaSession, m_avmDtc, m_streamNameMapping, ElokaData(), this); connect(dialog, &ElokaEditDialog::signalNewEloka, this, [this](const ElokaData & data) { m_elokaModel->insertRow(data); }); getUsedRadioCircuits(); dialog->init(m_usedCnr, m_usedTvc, m_usedAnnouncement); addDialog(dialog, m_menuGroup, QStringLiteral("AddEloka")); } void ElokaDialog::onEditClicked() { DEBUG_LOG(m_logger) << "**** onEditClicked() "; const QModelIndex idx = m_ui->tvEloka->currentIndex(); if (!idx.isValid()) return; const ElokaData data = m_elokaModel->getRowData(idx.row()); ElokaEditDialog *dialog = new ElokaEditDialog(m_session, m_avaSession, m_avmDtc, m_streamNameMapping, data, this); connect(dialog, &ElokaEditDialog::signalNewEloka, this, [ = ](const ElokaData & data) { m_elokaModel->setRowData(idx.row(), data); }); getUsedRadioCircuits(); dialog->init(m_usedCnr, m_usedTvc, m_usedAnnouncement); addDialog(dialog, m_menuGroup, QStringLiteral("EditEloka")); } void ElokaDialog::onRemoveClicked() { DEBUG_LOG(m_logger) << "**** onRemoveClicked() "; const QModelIndex idx = m_ui->tvEloka->currentIndex(); if (!idx.isValid()) return; m_avaSession->control()->releaseEloka(m_elokaModel->getRowData(idx.row()).internalName); m_elokaModel->removeRow(idx.row()); } void ElokaDialog::onSelectionChanged() { QModelIndexList selectedRows = m_ui->tvEloka->selectedRows(); const int cntSelectedRows = selectedRows.size(); m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, cntSelectedRows == 1 && m_avaSessionEstablished); m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, cntSelectedRows > 0 && m_avaSessionEstablished); m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, !(m_elokaModel->rowCount() >= 20)); } void ElokaDialog::onPrint() { LtsPrinting::printView(m_session, this, m_ui->tvEloka->treeView() ); } void ElokaDialog::onQueryElokaResponse(const QVector &&eloka) { DEBUG_LOG(m_logger) << "onQueryElokaResponse"; m_elokaListCollector.start(); // re-start the collector m_elokaModel->clear(); if (eloka.isEmpty()) return; const auto cnrTvcProfiles = m_avmDtc->cnrTvcProfiles(); QMultiMap userProfile; int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId(); int exerciseId = m_session->exerciseId(); for (const auto &cnrTvcProfile : cnrTvcProfiles) { if (cnrTvcProfile.exerciseId() == exerciseId && cnrTvcProfile.operatorId() == operatorId) { for (const auto &cnrTvcProfileData : cnrTvcProfile.data()) { if (cnrTvcProfileData.radioSystemId() == RadioSystem::inner_enum::Cnr) userProfile.insert(cnrTvcProfileData.radioCircuitId(), ElokaCircuitType::Cnr); else userProfile.insert(cnrTvcProfileData.radioCircuitId(), ElokaCircuitType::Tvc); } break; } } ElokaData data; for (const auto &elokaData : eloka) { data.internalName = elokaData.stream; data.displayName = elokaData.stream; // Can differ from internalName only for AnnouncementUnits; in this case displayName will be set in isAnnouncement(). data.action = elokaData.signal; data.mode = AvaElokaMode::EndlessLoop; data.startTime = toMSecSinceEpoch(elokaData.time); if (isCnr(data, userProfile) || isTvc(data, userProfile) || isAnnouncement(data)) m_elokaModel->insertRow(data); } } void ElokaDialog::tableColumnOrganiserSetting() { //LtsColumnOrganiser m_ui->tvEloka->setColumnsOrganiserEnabled(identifier(), true); } bool ElokaDialog::isCnr(ElokaData& data, const QMultiMap& userProfile) { const QMap cnrs = m_avmDtc->cnrConfigs(); for (const auto &cnr : cnrs) { if ((QString::fromStdString(cnr.radioCircuit()) == data.internalName) && (userProfile.contains(cnr.id(), ElokaCircuitType::Cnr))) { data.circuitType = ElokaCircuitType::Cnr; data.party = cnr.partyId(); data.id = cnr.id(); return true; } } return false; } bool ElokaDialog::isTvc(ElokaData& data, const QMultiMap& userProfile) { const QMap tvcs = m_avmDtc->tvcConfigs(); for (const auto &tvc : tvcs) { if (tvc.exerciseId() != m_session->exerciseId()) continue; if ((QString::fromStdString(tvc.radioCircuit()) == data.internalName) && (userProfile.contains(tvc.id(), ElokaCircuitType::Tvc))) { data.circuitType = ElokaCircuitType::Tvc; data.party = 0; data.id = tvc.id(); return true; } } return false; } bool ElokaDialog::isAnnouncement(ElokaData& data) { QMap announcements; QMap streams = m_avmDtc->streams(); for (const Stream &stream : qAsConst(streams)) { if ((stream.type() == StreamType_def::AudioOut) || (stream.type() == StreamType_def::AudioInOut)) announcements.insert(stream.id(), stream); } for (const auto &announcement : announcements) { if (QString::fromStdString(announcement.name()) == data.internalName) { data.circuitType = ElokaCircuitType::Announcement; data.party = -1; // data.id = announcement.id(); data.exerciseId = m_session->exerciseId(); data.displayName = m_streamNameMapping->displayName(data.internalName); return true; } } return false; } void ElokaDialog::getUsedRadioCircuits() { m_usedAnnouncement.clear(); m_usedCnr.clear(); m_usedTvc.clear(); for (int i=0; i < m_elokaModel->rowCount(); ++i) { ElokaData elokaData = m_elokaModel->getRowData(i); switch (elokaData.circuitType) { case ElokaCircuitType::Cnr: m_usedCnr.push_back(elokaData.id); break; case ElokaCircuitType::Tvc: m_usedTvc.push_back(elokaData.id); break; case ElokaCircuitType::Announcement: m_usedAnnouncement.push_back(elokaData.id); break; default: break; } } } } // namespace AudioVideoManagement