Files
qt5-legatus-legacy/Lts/Plugins/AudioVideoManagement/Gui/Eloka/avm_eloka_dialog.cpp
T
2026-08-13 18:33:10 +02:00

336 lines
9.8 KiB
C++
Executable File

/**
* @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 <avm_eloka_edit_dialog.h>
#include <AudioVideoManagement/ava_session.h>
#include <AudioVideoManagement/ava_control.h>
#include <AudioVideoManagement/av_helper.h>
#include <AudioVideoManagement/stream_name_mapping.h>
#include <LtsSession/lts_session_data.h>
#include <LtsPrinting/printing.h>
#include <QTreeView>
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<AvaEloka> &&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<AvaEloka> &&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<qint32, ElokaCircuitType> 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<qint32, ElokaCircuitType>& userProfile)
{
const QMap<qint32, CnrConfig> 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<qint32, ElokaCircuitType>& userProfile)
{
const QMap<qint32, TvcConfig> 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<qint32, Stream> announcements;
QMap<qint32, Stream> 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