Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Astrid Mueller, SGAS, 2017-10-17
|
||||
#
|
||||
|
||||
SET(avm_eloka_gui_SRCS
|
||||
avm_eloka_gui_plugin.cpp
|
||||
avm_eloka_gui_plugin.h
|
||||
avm_eloka_dialog.cpp
|
||||
avm_eloka_dialog.h
|
||||
avm_eloka_edit_dialog.cpp
|
||||
avm_eloka_edit_dialog.h
|
||||
avm_eloka_model.cpp
|
||||
avm_eloka_model.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(avm_eloka_gui_SRCS
|
||||
avm_eloka_dialog.ui
|
||||
avm_eloka_edit_dialog.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS AvmElokaGuiPlugin MODULE ${avm_eloka_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(AvmElokaGuiPlugin
|
||||
LtsPrinting
|
||||
NGLLogger
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsUtilsSettings
|
||||
AvmDataPluginInterface
|
||||
PpmDataPluginInterface
|
||||
svcAvmCommon
|
||||
Qt5::Widgets
|
||||
LtsWidgets
|
||||
LtsDataView
|
||||
LtsUtilsGuiDds
|
||||
ngltools
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(AvmElokaGuiPlugin)
|
||||
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
* @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
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <AudioVideoManagement/ava_types.h>
|
||||
#include <AudioVideoManagement/list_response_collector.h>
|
||||
|
||||
#include <avm_eloka_model.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ElokaDialog;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class AvaSession;
|
||||
class StreamNameMapping;
|
||||
|
||||
class ElokaDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ElokaDialog(LtsSession::LtsSession *session, AvaSession *avaSession, Interface::Dtc *avmDtc, StreamNameMapping *streamNameMapping,
|
||||
const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~ElokaDialog();
|
||||
|
||||
private slots:
|
||||
void onAvaSessionEstablished();
|
||||
void onAvaSessionDisconnected();
|
||||
|
||||
void onAddClicked();
|
||||
void onEditClicked();
|
||||
void onRemoveClicked();
|
||||
void onSelectionChanged();
|
||||
void onPrint();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void setAvaSessionStatus(bool established);
|
||||
void getUsedRadioCircuits();
|
||||
bool isCnr(ElokaData& data, const QMultiMap<qint32, ElokaCircuitType>& userProfile);
|
||||
bool isTvc(ElokaData& data, const QMultiMap<qint32, ElokaCircuitType>& userProfile);
|
||||
bool isAnnouncement(ElokaData& data);
|
||||
void onQueryElokaResponse(const QVector<AvaEloka> &&eloka);
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
|
||||
private:
|
||||
Ui::ElokaDialog *m_ui;
|
||||
QString m_menuGroup;
|
||||
|
||||
ElokaModel *m_elokaModel;
|
||||
LtsSession::LtsSession *m_session;
|
||||
AvaSession *m_avaSession;
|
||||
QueryElokaListCollector m_elokaListCollector;
|
||||
StreamNameMapping *m_streamNameMapping;
|
||||
Interface::Dtc *m_avmDtc;
|
||||
bool m_avaSessionEstablished;
|
||||
std::vector<qint32> m_usedCnr;
|
||||
std::vector<qint32> m_usedTvc;
|
||||
std::vector<qint32> m_usedAnnouncement;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ElokaDialog</class>
|
||||
<widget class="QWidget" name="ElokaDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>566</width>
|
||||
<height>457</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblAvaSessionStatus">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" color:#cc0000;">No connection to Ava Session !</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="tvEloka"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,568 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ElokaEditDialog adds and updates electronic warfare
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Astrid Mueller, SGAS, 2017-10-17
|
||||
*/
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
#include "avm_eloka_edit_dialog.h"
|
||||
#include "ui_avm_eloka_edit_dialog.h"
|
||||
#include <AudioVideoManagement/ava_session.h>
|
||||
#include <AudioVideoManagement/ava_control.h>
|
||||
#include <AudioVideoManagement/stream_name_mapping.h>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* Used as UserData for the entries in cmbCircuit.
|
||||
*/
|
||||
struct ComboBoxUserData
|
||||
{
|
||||
QString internalName; // the text itself in the ComboBox is the displayName
|
||||
AudioVideoManagement::ElokaCircuitType circuitType;
|
||||
int id;
|
||||
};
|
||||
|
||||
|
||||
ComboBoxUserData userDataAt(QComboBox *cb, int index)
|
||||
{
|
||||
Q_ASSERT(cb);
|
||||
Q_ASSERT(index >= 0 && index < cb->count());
|
||||
QVariant userData = cb->itemData(index);
|
||||
Q_ASSERT(userData.canConvert<ComboBoxUserData>());
|
||||
return userData.value<ComboBoxUserData>();
|
||||
}
|
||||
|
||||
ComboBoxUserData currentUserData(QComboBox* cb)
|
||||
{
|
||||
Q_ASSERT(cb);
|
||||
return userDataAt(cb, cb->currentIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the currently selected item in the ComboBox.
|
||||
* @return boost::none if there is no item selected or its type does not match circuitType
|
||||
*/
|
||||
boost::optional<int> currentId(QComboBox *comboBox, AudioVideoManagement::ElokaCircuitType circuitType)
|
||||
{
|
||||
Q_ASSERT(comboBox);
|
||||
|
||||
int selectedIndex = comboBox->currentIndex();
|
||||
if (selectedIndex == -1)
|
||||
return boost::none;
|
||||
|
||||
QVariant userData_ = comboBox->itemData(selectedIndex);
|
||||
Q_ASSERT(userData_.canConvert<ComboBoxUserData>());
|
||||
ComboBoxUserData userData = userData_.value<ComboBoxUserData>();
|
||||
if (userData.circuitType != circuitType)
|
||||
return boost::none;
|
||||
|
||||
return userData.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to select the item with the given id.
|
||||
* If no id is given or the item is not available for selection the first item is selected.
|
||||
*/
|
||||
void selectItemWithId(QComboBox *comboBox, boost::optional<int> id)
|
||||
{
|
||||
Q_ASSERT(comboBox);
|
||||
|
||||
if (comboBox->count() == 0)
|
||||
return;
|
||||
|
||||
if (!id.is_initialized())
|
||||
{
|
||||
comboBox->setCurrentIndex(0);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < comboBox->count(); ++i)
|
||||
{
|
||||
QVariant userData_ = comboBox->itemData(i);
|
||||
Q_ASSERT(userData_.canConvert<ComboBoxUserData>());
|
||||
ComboBoxUserData userData = userData_.value<ComboBoxUserData>();
|
||||
if (userData.id == *id)
|
||||
{
|
||||
comboBox->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
comboBox->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// in order to use it with QVariant
|
||||
Q_DECLARE_METATYPE(ComboBoxUserData)
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
ElokaEditDialog::ElokaEditDialog(LtsSession::LtsSession *session, AvaSession *avaSession, Interface::Dtc *avmDtc, StreamNameMapping *streamNameMapping,
|
||||
const ElokaData &data, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_ui(new Ui::ElokaEditDialog)
|
||||
, m_session(session)
|
||||
, m_streamNameMapping(streamNameMapping)
|
||||
, m_avaCtrl(avaSession->control())
|
||||
, m_avmDtc(avmDtc)
|
||||
, m_elokaData(data)
|
||||
, m_cnrConfigMap()
|
||||
, m_tvcConfigMap()
|
||||
, m_announcementMap()
|
||||
, m_userProfile()
|
||||
, m_logger(getLogger("ElokaEditDialog"))
|
||||
{
|
||||
Q_ASSERT(session);
|
||||
Q_ASSERT(avaSession);
|
||||
Q_ASSERT(streamNameMapping);
|
||||
Q_ASSERT(avmDtc);
|
||||
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_uiRequirements->addRequirement( { m_ui->lbAction, [this]() { return !m_ui->cmbAction->currentText().isEmpty(); } });
|
||||
m_uiRequirements->addRequirement( { m_ui->lbCircuit, [this]() { return !m_ui->cmbCircuit->currentText().isEmpty(); } });
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Electronic_Warfare_Measures"));
|
||||
}
|
||||
|
||||
ElokaEditDialog::~ElokaEditDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void ElokaEditDialog::retranslate()
|
||||
{
|
||||
bool isNew = true;
|
||||
if (!m_elokaData.internalName.isEmpty())
|
||||
isNew = false;
|
||||
|
||||
translate(m_ui, QString(), isNew, tr("Eloka"));
|
||||
}
|
||||
|
||||
bool ElokaEditDialog::init(const std::vector<qint32> &usedCnr,
|
||||
const std::vector<qint32> &usedTvc,
|
||||
const std::vector<qint32> &usedAnnouncement)
|
||||
{
|
||||
setUnchangeable(true);
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->rbTvc->hide();
|
||||
#endif
|
||||
// get the user profile of the accessible radio circuits
|
||||
getUserProfile();
|
||||
|
||||
// get all CNR's
|
||||
getActiveCnrs();
|
||||
// new CNR
|
||||
if (m_elokaData.internalName.isEmpty())
|
||||
{
|
||||
for (int used : usedCnr)
|
||||
m_cnrConfigMap.remove(used);
|
||||
}
|
||||
else // edit CNR
|
||||
{
|
||||
m_cnrConfigMap.remove(m_elokaData.id);
|
||||
}
|
||||
|
||||
// get all TVC's
|
||||
m_tvcConfigMap = m_avmDtc->tvcConfigs();
|
||||
// new TVC
|
||||
if (m_elokaData.internalName.isEmpty())
|
||||
{
|
||||
for (int used : usedTvc)
|
||||
m_tvcConfigMap.remove(used);
|
||||
}
|
||||
else // edit TVC
|
||||
{
|
||||
m_tvcConfigMap.remove(m_elokaData.id);
|
||||
}
|
||||
|
||||
// get all Announcements
|
||||
const QMap<qint32, Stream> streams = m_avmDtc->streams();
|
||||
for (const Stream &stream : streams)
|
||||
{
|
||||
if ((stream.type() == StreamType_def::AudioOut) ||
|
||||
(stream.type() == StreamType_def::AudioInOut))
|
||||
m_announcementMap.insert(stream.id(), stream);
|
||||
}
|
||||
// new announcement
|
||||
if (m_elokaData.internalName.isEmpty())
|
||||
{
|
||||
for (int used : usedAnnouncement)
|
||||
m_announcementMap.remove(used);
|
||||
}
|
||||
else // edit announcement
|
||||
{
|
||||
m_announcementMap.remove(m_elokaData.id);
|
||||
}
|
||||
|
||||
connect(m_avmDtc,
|
||||
&AudioVideoManagement::Interface::Dtc::cnrConfigChanged,
|
||||
this, &ElokaEditDialog::onCnrConfigChanged);
|
||||
connect(m_avmDtc,
|
||||
&AudioVideoManagement::Interface::Dtc::tvcConfigChanged,
|
||||
this, &ElokaEditDialog::onTvcConfigChanged);
|
||||
connect(m_avmDtc,
|
||||
&AudioVideoManagement::Interface::Dtc::cnrTvcProfileChanged,
|
||||
this, &ElokaEditDialog::onCnrTvcProfileChanged);
|
||||
connect(m_avmDtc,
|
||||
&AudioVideoManagement::Interface::Dtc::streamChanged,
|
||||
this, &ElokaEditDialog::onStreamChanged);
|
||||
|
||||
connect(m_ui->cmbCircuit,
|
||||
QOverload<int>::of(&LtsWidgets::LtsComboBox::currentIndexChanged),
|
||||
this, &ElokaEditDialog::onCmbCircuitChanged);
|
||||
connect(m_ui->rbCnr, &QRadioButton::toggled,
|
||||
this, &ElokaEditDialog::onCbCnrToggled);
|
||||
connect(m_ui->rbAnnouncement, &QRadioButton::toggled,
|
||||
this, &ElokaEditDialog::onCbAnnouncementToggled);
|
||||
connect(m_ui->rbTvc, &QRadioButton::toggled,
|
||||
this, &ElokaEditDialog::onCbTvcToggled);
|
||||
connect(m_avaCtrl, &AvaControl::getElokaListResponse,
|
||||
this, &ElokaEditDialog::onGetElokaListResponse);
|
||||
|
||||
if (m_elokaData.internalName.isEmpty())
|
||||
{
|
||||
// get as default CNR
|
||||
checkedRadioButtons(true, false, false);
|
||||
enabledRadioButtons(true, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_elokaData.circuitType == ElokaCircuitType::Cnr)
|
||||
{
|
||||
checkedRadioButtons(true, false, false);
|
||||
enabledRadioButtons(true, false, false);
|
||||
}
|
||||
if (m_elokaData.circuitType == ElokaCircuitType::Tvc)
|
||||
{
|
||||
checkedRadioButtons(false, true, false);
|
||||
enabledRadioButtons(false, true, false);
|
||||
}
|
||||
if (m_elokaData.circuitType == ElokaCircuitType::Announcement)
|
||||
{
|
||||
checkedRadioButtons(false, false, true);
|
||||
enabledRadioButtons(false, false, true);
|
||||
}
|
||||
if (m_elokaData.mode == AvaElokaMode::EndlessLoop)
|
||||
m_ui->chbEndlessPlayback->setChecked(true);
|
||||
|
||||
setCurrentCircuit(m_elokaData);
|
||||
m_ui->cmbAction->setCurrentText(m_elokaData.action);
|
||||
}
|
||||
|
||||
setUnchangeable(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ElokaEditDialog::checkedRadioButtons(bool cnr, bool tvc, bool announcement)
|
||||
{
|
||||
m_ui->rbCnr->setChecked(cnr);
|
||||
m_ui->rbTvc->setChecked(tvc);
|
||||
m_ui->rbAnnouncement->setChecked(announcement);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::enabledRadioButtons(bool cnr, bool tvc, bool announcement)
|
||||
{
|
||||
m_ui->rbCnr->setEnabled(cnr);
|
||||
m_ui->rbTvc->setEnabled(tvc);
|
||||
m_ui->rbAnnouncement->setEnabled(announcement);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onCmbCircuitChanged(int index)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
|
||||
m_ui->cmbAction->clear();
|
||||
|
||||
if (m_ui->cmbCircuit->currentText().isEmpty())
|
||||
return;
|
||||
|
||||
// get Actions from AVS Workstation
|
||||
ComboBoxUserData userData = currentUserData(m_ui->cmbCircuit);
|
||||
m_avaCtrl->getElokaList(userData.internalName);
|
||||
}
|
||||
|
||||
bool ElokaEditDialog::apply()
|
||||
{
|
||||
ComboBoxUserData userData = currentUserData(m_ui->cmbCircuit);
|
||||
|
||||
ElokaData data;
|
||||
data.id = userData.id;
|
||||
data.internalName = userData.internalName;
|
||||
data.displayName = m_ui->cmbCircuit->currentText();
|
||||
data.party = -1;
|
||||
data.exerciseId = m_session->exerciseId();
|
||||
data.circuitType = userData.circuitType;
|
||||
data.action = m_ui->cmbAction->currentText();
|
||||
data.mode = m_ui->chbEndlessPlayback->isChecked() ? AvaElokaMode::EndlessLoop : AvaElokaMode::Once;
|
||||
data.startTime = m_session->partitionTime();
|
||||
|
||||
if (userData.circuitType == ElokaCircuitType::Cnr)
|
||||
data.party = m_cnrConfigMap.value(userData.id).partyId();
|
||||
|
||||
|
||||
if (m_elokaData.internalName.isEmpty())
|
||||
m_avaCtrl->chooseEloka(data.internalName, data.action, data.mode);
|
||||
else if (m_elokaData.action != data.action)
|
||||
{
|
||||
m_avaCtrl->releaseEloka(m_elokaData.internalName);
|
||||
m_avaCtrl->chooseEloka(data.internalName, data.action, data.mode);
|
||||
}
|
||||
|
||||
m_elokaData = data;
|
||||
emit signalNewEloka(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onCbCnrToggled(bool checked)
|
||||
{
|
||||
if (!checked)
|
||||
return;
|
||||
|
||||
fillComboBoxCircuit(ElokaCircuitType::Cnr);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onCbAnnouncementToggled(bool checked)
|
||||
{
|
||||
if (!checked)
|
||||
return;
|
||||
|
||||
fillComboBoxCircuit(ElokaCircuitType::Announcement);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onCbTvcToggled(bool checked)
|
||||
{
|
||||
if (!checked)
|
||||
return;
|
||||
|
||||
fillComboBoxCircuit(ElokaCircuitType::Tvc);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::getActiveCnrs()
|
||||
{
|
||||
const QMap<qint32, CnrConfig> cnrs = m_avmDtc->cnrConfigs();
|
||||
for (const CnrConfig &cnr : cnrs)
|
||||
{
|
||||
if (cnr.isActive() == true)
|
||||
m_cnrConfigMap.insert(cnr.id(), cnr);
|
||||
}
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onCnrConfigChanged(const CnrConfig &data,
|
||||
DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onCnrConfigChanged";
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
{
|
||||
m_cnrConfigMap.insert(data.id(), data);
|
||||
break;
|
||||
}
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
m_cnrConfigMap.remove(data.id());
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
if (m_ui->rbCnr->isChecked())
|
||||
fillComboBoxCircuit(ElokaCircuitType::Cnr);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onTvcConfigChanged(const TvcConfig &data,
|
||||
DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onTvcConfigChanged";
|
||||
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
{
|
||||
m_tvcConfigMap.insert(data.id(), data);
|
||||
break;
|
||||
}
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
m_tvcConfigMap.remove(data.id());
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
if (m_ui->rbTvc->isChecked())
|
||||
fillComboBoxCircuit(ElokaCircuitType::Tvc);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onStreamChanged(const Stream &data,
|
||||
DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onStreamChanged";
|
||||
|
||||
if ((data.type() != StreamType_def::AudioOut) &&
|
||||
(data.type() != StreamType_def::AudioInOut))
|
||||
return;
|
||||
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
{
|
||||
m_announcementMap.insert(data.id(), data);
|
||||
break;
|
||||
}
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
m_announcementMap.remove(data.id());
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
if (m_ui->rbAnnouncement->isChecked())
|
||||
fillComboBoxCircuit(ElokaCircuitType::Announcement);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onCnrTvcProfileChanged(const CnrTvcProfile &data,
|
||||
DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
DEBUG_LOG(m_logger) << "onCnrTvcProfileChanged";
|
||||
|
||||
if (data.exerciseId() != m_session->exerciseId() ||
|
||||
data.operatorId() != LtsSessionData::LtsSessionData::getInstance()->getOperatorId())
|
||||
return;
|
||||
|
||||
getUserProfile();
|
||||
|
||||
if (m_ui->rbCnr->isChecked())
|
||||
fillComboBoxCircuit(ElokaCircuitType::Cnr);
|
||||
else if (m_ui->rbTvc->isChecked())
|
||||
fillComboBoxCircuit(ElokaCircuitType::Tvc);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::getUserProfile()
|
||||
{
|
||||
m_userProfile.clear();
|
||||
|
||||
const QMap<qint32, AudioVideoManagement::CnrTvcProfile> cnrTvcProfiles = m_avmDtc->cnrTvcProfiles();
|
||||
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)
|
||||
m_userProfile.insert(cnrTvcProfileData.radioCircuitId(), ElokaCircuitType::Cnr);
|
||||
else
|
||||
m_userProfile.insert(cnrTvcProfileData.radioCircuitId(), ElokaCircuitType::Tvc);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ElokaEditDialog::fillComboBoxCircuit(ElokaCircuitType type)
|
||||
{
|
||||
boost::optional<int> selectedId = currentId(m_ui->cmbCircuit, type);
|
||||
m_ui->cmbCircuit->clear();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ElokaCircuitType::Cnr:
|
||||
{
|
||||
for (const CnrConfig &cnr : qAsConst(m_cnrConfigMap))
|
||||
{
|
||||
if (!m_userProfile.contains(cnr.id(), ElokaCircuitType::Cnr))
|
||||
continue;
|
||||
|
||||
QString internalName = QString::fromStdString(cnr.radioCircuit());
|
||||
QVariant userData = QVariant::fromValue(ComboBoxUserData{internalName, ElokaCircuitType::Cnr, cnr.id()});
|
||||
m_ui->cmbCircuit->addItem(internalName, userData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ElokaCircuitType::Tvc:
|
||||
{
|
||||
for (const TvcConfig &tvc : qAsConst(m_tvcConfigMap))
|
||||
{
|
||||
if (!m_userProfile.contains(tvc.id(), ElokaCircuitType::Tvc))
|
||||
continue;
|
||||
|
||||
QString internalName = QString::fromStdString(tvc.radioCircuit());
|
||||
QVariant userData = QVariant::fromValue(ComboBoxUserData{internalName, ElokaCircuitType::Tvc, tvc.id()});
|
||||
m_ui->cmbCircuit->addItem(internalName, userData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ElokaCircuitType::Announcement:
|
||||
{
|
||||
for (const Stream &stream : qAsConst(m_announcementMap))
|
||||
{
|
||||
QString internalName = QString::fromStdString(stream.name());
|
||||
QString displayName = m_streamNameMapping->displayName(internalName);
|
||||
QVariant userData = QVariant::fromValue(ComboBoxUserData{internalName, ElokaCircuitType::Announcement, stream.id()});
|
||||
m_ui->cmbCircuit->addItem(displayName, userData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
m_ui->cmbCircuit->model()->sort(0);
|
||||
selectItemWithId(m_ui->cmbCircuit, selectedId);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::setCurrentCircuit(const ElokaData &data)
|
||||
{
|
||||
for (int i = 0; i < m_ui->cmbCircuit->count(); ++i)
|
||||
{
|
||||
ComboBoxUserData userData = userDataAt(m_ui->cmbCircuit, i);
|
||||
if (userData.circuitType != data.circuitType)
|
||||
continue;
|
||||
|
||||
if (userData.id != data.id)
|
||||
continue;
|
||||
|
||||
m_ui->cmbCircuit->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
void ElokaEditDialog::onGetElokaListResponse(const QVector<QString> &actions)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onGetElokaListResponse";
|
||||
if (!m_elokaData.internalName.isEmpty())
|
||||
setUnchangeable(true);
|
||||
|
||||
m_ui->cmbAction->clear();
|
||||
|
||||
if (actions.isEmpty())
|
||||
return;
|
||||
|
||||
for (const QString &action : actions)
|
||||
m_ui->cmbAction->addItem(action);
|
||||
|
||||
if(m_elokaData.action.isEmpty() == false)
|
||||
m_ui->cmbAction->setCurrentText(m_elokaData.action);
|
||||
|
||||
if (!m_elokaData.internalName.isEmpty())
|
||||
setUnchangeable(false);
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ElokaEditDialog adds or updates electronic warfare
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Astrid Mueller, SGAS, 2017-10-17
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
#include "avm_eloka_model.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ElokaEditDialog;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class AvaSession;
|
||||
class AvaControl;
|
||||
class StreamNameMapping;
|
||||
|
||||
|
||||
class ElokaEditDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ElokaEditDialog(LtsSession::LtsSession *session, AvaSession *avaSession, Interface::Dtc *avmDtc, StreamNameMapping *streamNameMapping,
|
||||
const ElokaData &data, QWidget *parent = nullptr);
|
||||
~ElokaEditDialog();
|
||||
|
||||
bool init(const std::vector<qint32> &usedCnr,
|
||||
const std::vector<qint32> &usedTvc,
|
||||
const std::vector<qint32> &usedAnnouncement);
|
||||
signals:
|
||||
void signalNewEloka(const ElokaData &data);
|
||||
|
||||
protected:
|
||||
bool apply() override;
|
||||
|
||||
private slots:
|
||||
void onCmbCircuitChanged(int index);
|
||||
void onCbCnrToggled(bool checked);
|
||||
void onCbAnnouncementToggled(bool checked);
|
||||
void onCbTvcToggled(bool checked);
|
||||
|
||||
void onCnrConfigChanged(const CnrConfig &data, DataModification modType);
|
||||
void onTvcConfigChanged(const TvcConfig &data, DataModification modType);
|
||||
void onStreamChanged(const Stream &data, DataModification modType);
|
||||
void onCnrTvcProfileChanged(const CnrTvcProfile &data, DataModification modType);
|
||||
void onGetElokaListResponse(const QVector<QString> &actions);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
|
||||
void checkedRadioButtons(bool cnr, bool tvc, bool announcement);
|
||||
void enabledRadioButtons(bool cnr, bool tvc, bool announcement);
|
||||
void getUserProfile();
|
||||
void getActiveCnrs();
|
||||
void fillComboBoxCircuit(ElokaCircuitType type);
|
||||
void setCurrentCircuit(const ElokaData &data);
|
||||
|
||||
private:
|
||||
Ui::ElokaEditDialog *m_ui;
|
||||
LtsSession::LtsSession *m_session;
|
||||
StreamNameMapping *m_streamNameMapping;
|
||||
AvaControl *m_avaCtrl;
|
||||
Interface::Dtc *m_avmDtc;
|
||||
ElokaData m_elokaData; //!< default-constructed in case we are creating a new Eloka
|
||||
QMap<qint32, CnrConfig> m_cnrConfigMap;
|
||||
QMap<qint32, TvcConfig> m_tvcConfigMap;
|
||||
QMap<qint32, Stream> m_announcementMap;
|
||||
QMultiMap<qint32, ElokaCircuitType> m_userProfile;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ElokaEditDialog</class>
|
||||
<widget class="QWidget" name="ElokaEditDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>661</width>
|
||||
<height>144</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbCircuit">
|
||||
<property name="text">
|
||||
<string>Circuit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbCnr">
|
||||
<property name="text">
|
||||
<string>&CNR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbAnnouncement">
|
||||
<property name="text">
|
||||
<string>Announce&ment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbTvc">
|
||||
<property name="text">
|
||||
<string>&TVC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cmbCircuit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbAction">
|
||||
<property name="text">
|
||||
<string>Action:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cmbAction">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="chbEndlessPlayback">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Endless Playback</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>118</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>rbCnr</tabstop>
|
||||
<tabstop>rbAnnouncement</tabstop>
|
||||
<tabstop>rbTvc</tabstop>
|
||||
<tabstop>cmbCircuit</tabstop>
|
||||
<tabstop>cmbAction</tabstop>
|
||||
<tabstop>chbEndlessPlayback</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for AudioVideoManagement - Eloka
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Astrid Mueller, SGAS, 2017-10-17
|
||||
*/
|
||||
|
||||
#include "avm_eloka_gui_plugin.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <Services/AudioVideoManagement/avm_operator_rights.h>
|
||||
#include <avm_eloka_dialog.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.avm.Eloka"))
|
||||
, m_dtc(nullptr)
|
||||
, m_avmDataIfc(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<AudioVideoManagement::DataInterface>(m_dtc))
|
||||
return false;
|
||||
if (!m_session->getForeignDataInterface_NEW<AudioVideoManagement::DataInterface>(m_avmDataIfc))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
m_dtc = nullptr;
|
||||
m_avmDataIfc = nullptr;
|
||||
}
|
||||
|
||||
QString InterfaceImpl::menuGroup() const
|
||||
{
|
||||
return tr("Audio / Video");
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
if (!m_avmDataIfc->hasAvsSession())
|
||||
return {}; // Someone else has access to the AvaSession in a different exercise context.
|
||||
|
||||
QVector<LtsWidgets::PluginData> actions;
|
||||
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const bool enableElectronicWarfareMeasures = ps->value(QStringLiteral("avm"),
|
||||
QStringLiteral("enableElectronicWarfareMeasures")).toBool();
|
||||
|
||||
if (enableElectronicWarfareMeasures)
|
||||
{
|
||||
LtsWidgets::PluginData plData;
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Electronic Warfare Measures");
|
||||
plData.identifier = QLatin1String("avmEwm");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:electronical_warfare_measures.svg"));
|
||||
plData.operatorRight = OperatorRights::ElectronicWarfareMeasures::AvmEwmEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
|
||||
plData.createWidgetFunc = [this](QWidget *parent)
|
||||
{
|
||||
return onShowEloka(parent);
|
||||
};
|
||||
actions.append(plData);
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowEloka(QWidget *parent)
|
||||
{
|
||||
return new ElokaDialog(m_session, m_avmDataIfc->avaSession(), m_dtc.get(), m_avmDataIfc->streamNameMapping(),
|
||||
menuGroup(), parent);
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for AudioVideoManagement - Eloka
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Astrid Mueller, SGAS, 2017-10-17
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/AudioVideoManagement/avm_data_plugin_interface.h>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:avm.eloka")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QStringLiteral("AudioVideoManagement.GuiPlugin.Eloka"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return (partition == IDL::PartitionType::Exercise);
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public QObject, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
bool fetchInterfaces() override;
|
||||
void clearInterfaces() override;
|
||||
QString menuGroup() const override;
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override { return partition == IDL::PartitionType::Global || partition == IDL::PartitionType::Exercise; }
|
||||
|
||||
private:
|
||||
LtsWidgets::LtsDialog *onShowEloka(QWidget *parent);
|
||||
|
||||
std::shared_ptr<AudioVideoManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<AudioVideoManagement::DataInterface> m_avmDataIfc;
|
||||
};
|
||||
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Model for electronic warfare (Eloka)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Astrid Mueller, SGAS, 2017-10-18
|
||||
*/
|
||||
|
||||
#include "avm_eloka_model.h"
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
ElokaModel::ElokaModel(LtsSession::LtsSession *session, QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<ElokaData>(
|
||||
{
|
||||
tr("Party"),
|
||||
tr("Radio Circuit"),
|
||||
tr("Action"),
|
||||
tr("Endless Playback"),
|
||||
tr("Start Time")
|
||||
},
|
||||
parent)
|
||||
, m_logger(getLogger("ElokaModel"))
|
||||
{
|
||||
Q_ASSERT(session);
|
||||
// optional
|
||||
session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc);
|
||||
}
|
||||
|
||||
QVariant ElokaModel::data(const QModelIndex &index,
|
||||
int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole || !indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const ElokaData &data = m_vecData.at(index.row());
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case Party:
|
||||
{
|
||||
if (!m_ppmDtc)
|
||||
return QString::number(data.party);
|
||||
|
||||
if (data.party >= 0)
|
||||
return ParticipantManagement::trPartyName(m_ppmDtc->party(data.party).name());
|
||||
return QVariant(QLatin1Char('-'));
|
||||
}
|
||||
case RadioCircuit:
|
||||
return data.displayName;
|
||||
case Action:
|
||||
return data.action;
|
||||
case EndlessPlayback:
|
||||
return QVariant(data.mode == AvaElokaMode::EndlessLoop ? QLatin1Char('+') : QLatin1Char('-'));
|
||||
case StartTime:
|
||||
return QDateTime::fromMSecsSinceEpoch(data.startTime);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Model for electronic warfare (Eloka)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Astrid Mueller, SGAS, 2017-10-18
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <Plugins/AudioVideoManagement/avm_data_plugin_interface.h>
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/ava_types.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
enum class ElokaCircuitType
|
||||
{
|
||||
Cnr = 1,
|
||||
Tvc = 2,
|
||||
Announcement = 3
|
||||
};
|
||||
|
||||
struct ElokaData
|
||||
{
|
||||
QString internalName;
|
||||
QString displayName;
|
||||
QString action;
|
||||
qint64 startTime = 0;
|
||||
qint32 id = 0;
|
||||
qint32 exerciseId = 0;
|
||||
qint32 party = 0;
|
||||
ElokaCircuitType circuitType = ElokaCircuitType::Cnr;
|
||||
AvaElokaMode mode = AvaElokaMode::EndlessLoop;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------
|
||||
// ElokaModel
|
||||
// --------------------------------------------------------
|
||||
class ElokaModel : public LtsWidgets::LtsAbstractTableModel<ElokaData>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
Party,
|
||||
RadioCircuit,
|
||||
Action,
|
||||
EndlessPlayback,
|
||||
StartTime
|
||||
};
|
||||
|
||||
ElokaModel(LtsSession::LtsSession *session, QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
private:
|
||||
LOGGER_T &m_logger;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
Reference in new issue
Block a user