336 lines
9.8 KiB
C++
Executable File
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
|