Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Lts/Plugins/AudioVideoManagement/Gui/AVMenuEdit/AudioSettings/audio_settings_avail_streams_model.cpp
Executable
+297
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManangement - Show all available streams
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-11-06
|
||||
*/
|
||||
|
||||
#include "audio_settings_avail_streams_model.h"
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
#include <QFont>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
QDataStream &operator<<(QDataStream &ds, const StreamData &sd)
|
||||
{
|
||||
ds << sd.topicId << sd.name << sd.bIsCnr;
|
||||
return ds;
|
||||
}
|
||||
QDataStream &operator>>(QDataStream &ds, StreamData &sd)
|
||||
{
|
||||
ds >> sd.topicId >> sd.name >> sd.bIsCnr ;
|
||||
return ds;
|
||||
}
|
||||
|
||||
//
|
||||
// AvailStreamsModel
|
||||
//
|
||||
AvailStreamsModel::AvailStreamsModel(Interface::Dtc *avmDtc,
|
||||
int32_t exerciseId,
|
||||
QObject *parent)
|
||||
: NGLTreeModel(parent, new NGLTreeItem(QVariant()), {tr("Available")})
|
||||
, m_exerciseId(exerciseId)
|
||||
, m_avmDtc(avmDtc)
|
||||
, m_cnrRoot(new NGLTreeItem(QVariant()))
|
||||
, m_tvcRoot(new NGLTreeItem(QVariant()))
|
||||
, m_changes(false)
|
||||
, m_logger(getLogger("AudioSettingsAvailStreamsModel"))
|
||||
{
|
||||
Q_ASSERT(avmDtc);
|
||||
|
||||
qRegisterMetaTypeStreamOperators<StreamData>();
|
||||
|
||||
setMimeType(StreamData::mimeType());
|
||||
|
||||
StreamData data;
|
||||
data.name = tr("CNR");
|
||||
data.bIsCnr = true;
|
||||
m_cnrRoot->setData(QVariant::fromValue(data));
|
||||
m_rootItem->appendChild(m_cnrRoot);
|
||||
|
||||
data.name = tr("TVC");
|
||||
data.bIsCnr = false;
|
||||
m_tvcRoot->setData(QVariant::fromValue(data));
|
||||
m_rootItem->appendChild(m_tvcRoot);
|
||||
}
|
||||
/*
|
||||
AvailStreamsModel::~AvailStreamsModel()
|
||||
{
|
||||
// do not delete, is deleted through root item
|
||||
//delete m_cnrRoot;
|
||||
//delete m_tvcRoot;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void AvailStreamsModel::setStreamChanged(const QVector<StreamData> &streams)
|
||||
{
|
||||
for (const StreamData &d : streams)
|
||||
if (!m_changedStreams.contains(QPair<bool,int>(d.bIsCnr, d.topicId)))
|
||||
m_changedStreams += QPair<bool,int>(d.bIsCnr, d.topicId);
|
||||
emit modelDataChanged();
|
||||
}
|
||||
|
||||
|
||||
bool AvailStreamsModel::initModel()
|
||||
{
|
||||
connect(m_avmDtc, &AudioVideoManagement::Interface::Dtc::cnrConfigChanged,
|
||||
this, &AvailStreamsModel::onCnrConfigChanged, Qt::UniqueConnection);
|
||||
m_avmDtc->cnrConfigs([this](const AudioVideoManagement::CnrConfig & ch) { onCnrConfigChanged(ch, DataModification::eAdded); });
|
||||
|
||||
#if 0
|
||||
AudioVideoManagement::CnrConfig data;
|
||||
data.exerciseId(42);
|
||||
|
||||
data.id(1);
|
||||
data.radioCircuit(QStringLiteral("test1").toStdString());
|
||||
onCnrConfigChanged(data, DataModification::eAdded);
|
||||
|
||||
data.id(2);
|
||||
data.radioCircuit(QStringLiteral("test2").toStdString());
|
||||
onCnrConfigChanged(data, DataModification::eAdded);
|
||||
|
||||
AudioVideoManagement::TvcConfig data2;
|
||||
data2.id(1);
|
||||
data2.radioCircuit(QStringLiteral("test3 (tvc)").toStdString());
|
||||
onTvcConfigChanged(data2, DataModification::eAdded);
|
||||
#endif
|
||||
|
||||
connect(m_avmDtc, &AudioVideoManagement::Interface::Dtc::tvcConfigChanged,
|
||||
this, &AvailStreamsModel::onTvcConfigChanged, Qt::UniqueConnection);
|
||||
m_avmDtc->tvcConfigs([this](const AudioVideoManagement::TvcConfig & ch) { onTvcConfigChanged(ch, DataModification::eAdded); });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::ItemFlags AvailStreamsModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags f = NGLTreeModel::flags(index) | Qt::ItemIsDropEnabled;
|
||||
if (!index.parent().isValid())
|
||||
f &= ~Qt::ItemIsDragEnabled;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
QVariant AvailStreamsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
NGLTreeItem *item = privateData(index);
|
||||
StreamData data = item->data().value<StreamData>();
|
||||
DEBUG_LOG(m_logger) << data.name;
|
||||
return data.name;
|
||||
}
|
||||
|
||||
case Qt::FontRole:
|
||||
{
|
||||
NGLTreeItem *item = privateData(index);
|
||||
StreamData data = item->data().value<StreamData>();
|
||||
if (!m_changedStreams.contains(QPair<bool,int>(data.bIsCnr, data.topicId)))
|
||||
return {};
|
||||
QFont f;
|
||||
f.setBold(true);
|
||||
return f;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NGLTreeModel::data(index, role);
|
||||
}
|
||||
|
||||
bool AvailStreamsModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(column);
|
||||
Q_UNUSED(parent);
|
||||
if (action != supportedDropActions())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AvailStreamsModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
|
||||
int row, int column, const QModelIndex &parent)
|
||||
{
|
||||
Q_UNUSED(action);
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(column);
|
||||
Q_UNUSED(parent);
|
||||
|
||||
const QVector<NGLTreeItem *> droppedItems = getMimeDataItems(data, m_mimeType);
|
||||
QVector<StreamData> streams;
|
||||
streams.reserve(droppedItems.size());
|
||||
for (const NGLTreeItem *item : droppedItems)
|
||||
streams += item->data().value<StreamData>();
|
||||
qDeleteAll(droppedItems);
|
||||
emit droppedStreamNames(streams);
|
||||
m_changes = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AvailStreamsModel::onCnrConfigChanged(const AudioVideoManagement::CnrConfig &data, DataModification modType)
|
||||
{
|
||||
insertUpdateData(data, modType, m_cnrRoot);
|
||||
}
|
||||
|
||||
void AvailStreamsModel::onTvcConfigChanged(const AudioVideoManagement::TvcConfig &data, DataModification modType)
|
||||
{
|
||||
insertUpdateData(data, modType, m_tvcRoot);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AvailStreamsModel::insertUpdateData(const T &config, DataModification modType, NGLTreeItem *parent)
|
||||
{
|
||||
DataModification action = modType;
|
||||
if (modType == DataModification::eModified)
|
||||
{
|
||||
// If a config of a different Exercise was changed the config might have been global before.
|
||||
// Thus we might need to remove this config.
|
||||
if (config.exerciseId().is_set() && config.exerciseId().get() != m_exerciseId)
|
||||
action = DataModification::eRemoved;
|
||||
}
|
||||
|
||||
StreamData newData(config);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
if (config.exerciseId().is_set() && config.exerciseId().get() != m_exerciseId)
|
||||
break;
|
||||
Q_FALLTHROUGH();
|
||||
case DataModification::eModified:
|
||||
{
|
||||
bool bFound = false;
|
||||
for (int i = 0; i < parent->childCount(); ++i)
|
||||
{
|
||||
NGLTreeItem *child = parent->child(i);
|
||||
StreamData data = child->data().value<StreamData>();
|
||||
if (data == newData)
|
||||
{
|
||||
bFound = true;
|
||||
setItemData(indexFromItem(child), QVariant::fromValue(newData), child->icon());
|
||||
emit updateEntry(newData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFound)
|
||||
{
|
||||
NGLTreeItem *child = new NGLTreeItem(QVariant::fromValue(newData));
|
||||
insertRow(parent->childCount(), indexFromItem(parent), child);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
for (int i = 0; i < parent->childCount(); ++i)
|
||||
{
|
||||
NGLTreeItem *child = parent->child(i);
|
||||
StreamData data = child->data().value<StreamData>();
|
||||
if (data == newData)
|
||||
{
|
||||
removeRows(i, 1, indexFromItem(parent));
|
||||
emit removeEntry(newData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// AvailStreamsFilter
|
||||
//
|
||||
AvailStreamsFilter::AvailStreamsFilter(AvailStreamsModel *sourceModel, QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
, m_sourceModel(sourceModel)
|
||||
{
|
||||
Q_ASSERT(sourceModel);
|
||||
setSourceModel(m_sourceModel);
|
||||
}
|
||||
|
||||
void AvailStreamsFilter::addAllocatedStreams(const QVector<StreamData> &streams)
|
||||
{
|
||||
m_allocatedStreams.insert(streams.begin(), streams.end());
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void AvailStreamsFilter::setAllocatedStreams(const QVector<StreamData> &streams)
|
||||
{
|
||||
m_allocatedStreams.clear();
|
||||
m_allocatedStreams.insert(streams.begin(), streams.end());
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void AvailStreamsFilter::removeAllocatedStreams(const QVector<StreamData> &streams)
|
||||
{
|
||||
for (const StreamData &stream : streams)
|
||||
m_allocatedStreams.erase(stream);
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
bool AvailStreamsFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if (!m_sourceModel || !source_parent.isValid())
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
|
||||
NGLTreeItem *parent = m_sourceModel->privateData(source_parent);
|
||||
if (!parent)
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
NGLTreeItem *child = parent->child(source_row);
|
||||
if (!child)
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
|
||||
StreamData data = child->data().value<StreamData>();
|
||||
return m_allocatedStreams.count(data) == 0;
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManangement - Show all available streams
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-11-06
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QVector>
|
||||
#include "audio_stream_type.h"
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class AvailStreamsModel final : public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AvailStreamsModel(AudioVideoManagement::Interface::Dtc *avmDtc, int32_t exerciseId,
|
||||
QObject *parent = nullptr);
|
||||
~AvailStreamsModel() = default;
|
||||
bool getChangeState() {bool result = m_changes; m_changes = false; return result;}
|
||||
void resetChangeState() {m_changes = false;m_changedStreams.clear();}
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
// CopyAction - data is filtered with proxy model
|
||||
Qt::DropActions supportedDropActions() const override { return Qt::MoveAction; }
|
||||
Qt::DropActions supportedDragActions() const override { return Qt::CopyAction; }
|
||||
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
|
||||
bool dropMimeData(const QMimeData *data, Qt::DropAction, int, int, const QModelIndex &) override;
|
||||
void setStreamChanged(const QVector<StreamData> &streams);
|
||||
|
||||
bool initModel();
|
||||
|
||||
signals:
|
||||
void droppedStreamNames(const QVector<AudioVideoManagement::StreamData> &streamNamesDropped);
|
||||
void updateEntry(const AudioVideoManagement::StreamData &stream);
|
||||
void removeEntry(const AudioVideoManagement::StreamData &stream);
|
||||
|
||||
private slots:
|
||||
void onCnrConfigChanged(const AudioVideoManagement::CnrConfig &data, DataModification modType);
|
||||
void onTvcConfigChanged(const AudioVideoManagement::TvcConfig &data, DataModification modType);
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void insertUpdateData(const T &data, DataModification modType, NGLTreeItem *parent);
|
||||
|
||||
int32_t m_exerciseId;
|
||||
AudioVideoManagement::Interface::Dtc *m_avmDtc;
|
||||
NGLTreeItem *m_cnrRoot;
|
||||
NGLTreeItem *m_tvcRoot;
|
||||
bool m_changes;
|
||||
QVector<QPair<bool /* is cnr */, int> > m_changedStreams;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
class AvailStreamsFilter final : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AvailStreamsFilter(AvailStreamsModel *sourceModel, QObject *parent);
|
||||
|
||||
void addAllocatedStreams(const QVector<StreamData> &streams);
|
||||
void setAllocatedStreams(const QVector<StreamData> &streams);
|
||||
void removeAllocatedStreams(const QVector<StreamData> &streams);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
|
||||
private:
|
||||
/** Don't use directly; will we done via constructor. */
|
||||
using QSortFilterProxyModel::setSourceModel;
|
||||
|
||||
AvailStreamsModel *m_sourceModel;
|
||||
std::set<StreamData> m_allocatedStreams;
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+440
@@ -0,0 +1,440 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManagement - Operator Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "audio_settings_dialog.h"
|
||||
#include "ui_audio_settings_dialog.h"
|
||||
#include "audio_settings_avail_streams_model.h"
|
||||
#include "audio_settings_used_streams_model.h"
|
||||
#include "audio_stream_type.h"
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <LtsSession/lts_session_data_dds.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <AudioVideoManagement/avm_ftc_types.h>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
AudioSettingsDialog::AudioSettingsDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_ui(new Ui::AudioSettingsDialog)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_logger(getLogger("AudioSettingsDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Voice_Communication_Access"));
|
||||
}
|
||||
|
||||
AudioSettingsDialog::~AudioSettingsDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool AudioSettingsDialog::init(OperatorManagement::Interface::Dtc *opmDtc,
|
||||
Interface::Dtc *avmDtc,
|
||||
Interface::Ftc *avmFtc,
|
||||
LtsSession::LtsSessionDataDds *session)
|
||||
{
|
||||
Q_ASSERT(opmDtc);
|
||||
Q_ASSERT(avmDtc);
|
||||
Q_ASSERT(avmFtc);
|
||||
Q_ASSERT(session);
|
||||
|
||||
setUnchangeable(true);
|
||||
|
||||
m_session = session;
|
||||
m_avmDtc = avmDtc;
|
||||
m_avmFtc = avmFtc;
|
||||
////////////
|
||||
// Create Model
|
||||
|
||||
m_modelAvailable = new AvailStreamsModel(avmDtc, m_session->exerciseId(), this);
|
||||
if (!m_modelAvailable->initModel())
|
||||
return false;
|
||||
|
||||
m_filterAvailable = new AvailStreamsFilter(m_modelAvailable, this);
|
||||
m_modelAllocated = new AllocatedStreamsModel(this);
|
||||
|
||||
connect(m_modelAvailable, &AvailStreamsModel::droppedStreamNames, this, &AudioSettingsDialog::onDroppedInAvailable); // Drag and Drop from allocated -> available
|
||||
connect(m_modelAllocated, &AllocatedStreamsModel::droppedStreamNames, this, &AudioSettingsDialog::onDroppedInAllocated); // Drag and Drop from available -> allocated
|
||||
|
||||
connect(m_modelAvailable, &AvailStreamsModel::updateEntry, m_modelAllocated, &AllocatedStreamsModel::updateEntry);
|
||||
connect(m_modelAvailable, &AvailStreamsModel::removeEntry, this, &AudioSettingsDialog::onEntryRemoved);
|
||||
|
||||
// Glue model and view together
|
||||
m_ui->treeViewAvailable->setModel(m_filterAvailable);
|
||||
m_ui->treeViewAvailable->expandAll();
|
||||
m_ui->treeViewAllocated->setModel(m_modelAllocated);
|
||||
|
||||
// Operator Management to get Name from operator
|
||||
connect(opmDtc, &OperatorManagement::Interface::Dtc::userChanged,
|
||||
this, &AudioSettingsDialog::onOperatorChanged);
|
||||
auto cbOperator = [this](const OperatorManagement::User & u)
|
||||
{
|
||||
onOperatorChanged(u, DataModification::eAdded);
|
||||
};
|
||||
opmDtc->users(cbOperator);
|
||||
|
||||
fillOperatorBox();
|
||||
|
||||
connect(m_avmDtc, &Interface::Dtc::cnrTvcProfileChanged,
|
||||
this, &AudioSettingsDialog::onCnrTvcProfileChanged);
|
||||
auto cbRadioCircuits = [this](const CnrTvcProfile & rc)
|
||||
{
|
||||
onCnrTvcProfileChanged(rc, DataModification::eAdded);
|
||||
};
|
||||
m_avmDtc->cnrTvcProfiles(cbRadioCircuits);
|
||||
|
||||
connect(m_ui->pushButtonUp, &QPushButton::clicked, this, &AudioSettingsDialog::onUpButtonClicked);
|
||||
connect(m_ui->pushButtonDown, &QPushButton::clicked, this, &AudioSettingsDialog::onDownButtonClicked);
|
||||
connect(m_ui->operatorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioSettingsDialog::onSelectionOperatorChanged);
|
||||
connect(m_ui->treeViewAllocated->selectionModel(), &QItemSelectionModel::selectionChanged, this, &AudioSettingsDialog::onSelectionChangedAllocation);
|
||||
// Populate our Model
|
||||
|
||||
m_ui->treeViewAllocated->setSelectionMode(QAbstractItemView::MultiSelection);
|
||||
m_ui->treeViewAvailable->setSelectionMode(QAbstractItemView::MultiSelection);
|
||||
|
||||
m_ui->treeViewAllocated->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
m_ui->treeViewAvailable->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
//m_ui->treeViewAllocated->setSortingEnabled(true);
|
||||
//m_ui->treeViewAllocated->sortByColumn(0,Qt::AscendingOrder );
|
||||
|
||||
m_ui->pushButtonUp->setEnabled(false);
|
||||
m_ui->pushButtonDown->setEnabled(false);
|
||||
|
||||
m_avmFtc->enableAll();
|
||||
|
||||
int opId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
if (m_ui->operatorComboBox->currentIndex() != m_ui->operatorComboBox->findData(opId))
|
||||
m_ui->operatorComboBox->setCurrentIndex(m_ui->operatorComboBox->findData(opId));
|
||||
else
|
||||
onSelectionOperatorChanged(0); //param is unused
|
||||
setUnchangeable(false);
|
||||
return true;
|
||||
} // end of init
|
||||
|
||||
void AudioSettingsDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Voice Communication Access"));
|
||||
} // end of retranslate
|
||||
|
||||
void AudioSettingsDialog::onOperatorChanged(const OperatorManagement::User &data, DataModification modType)
|
||||
{
|
||||
// Table: opm.opm_operator
|
||||
DEBUG_LOG(m_logger) << "************** onOperatorChanged ";
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
Q_ASSERT(m_operatorMap.contains(data.id()));
|
||||
|
||||
// Check, if Operator is currently open, if yes, reset any changes
|
||||
if (m_ui->operatorComboBox->currentData().toInt() == data.id())
|
||||
{
|
||||
__unchange__();
|
||||
m_modelAllocated->resetChangeState();
|
||||
m_modelAvailable->resetChangeState();
|
||||
m_filterAvailable->invalidate();
|
||||
}
|
||||
|
||||
m_operatorMap.remove(data.id());
|
||||
m_ui->operatorComboBox->removeItem(m_ui->operatorComboBox->findData(data.id()));
|
||||
break;
|
||||
}
|
||||
|
||||
case DataModification::eAdded:
|
||||
{
|
||||
Q_ASSERT(!m_operatorMap.contains(data.id()));
|
||||
const QString operatorName = QString::fromStdString(data.name());
|
||||
m_operatorMap.insert(data.id(), operatorName);
|
||||
m_ui->operatorComboBox->addItem(operatorName, data.id());
|
||||
m_ui->operatorComboBox->model()->sort(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case DataModification::eModified:
|
||||
{
|
||||
Q_ASSERT(m_operatorMap.contains(data.id()));
|
||||
const QString operatorName = QString::fromStdString(data.name());
|
||||
m_operatorMap.insert(data.id(), operatorName);
|
||||
int i = m_ui->operatorComboBox->findData(data.id());
|
||||
Q_ASSERT(i != -1);
|
||||
m_ui->operatorComboBox->setItemText(i, operatorName);
|
||||
m_ui->operatorComboBox->model()->sort(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // end of onOperatorChanged
|
||||
|
||||
void AudioSettingsDialog::onCnrTvcProfileChanged(const CnrTvcProfile &data, DataModification modType)
|
||||
{
|
||||
if (m_session->exerciseId() == data.exerciseId())
|
||||
{
|
||||
if (modType == DataModification::eRemoved)
|
||||
{
|
||||
m_cnrTvcProfileMap.remove(data.id());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cnrTvcProfileMap.insert(data.id(), data);
|
||||
fillOperatorList();
|
||||
}
|
||||
}
|
||||
} // end of onCnrTvcProfileChanged
|
||||
|
||||
void AudioSettingsDialog::fillOperatorList()
|
||||
{
|
||||
QVector<StreamData> newStreamData;
|
||||
|
||||
for (const auto &rc : qAsConst(m_cnrTvcProfileMap))
|
||||
{
|
||||
if ((rc.exerciseId() != m_session->exerciseId())
|
||||
|| (rc.operatorId() != m_ui->operatorComboBox->currentData().toInt()))
|
||||
continue;
|
||||
|
||||
// insert entry in Allocated
|
||||
newStreamData.reserve(rc.data().size());
|
||||
for (const CnrTvcProfileData &profileEntry : rc.data())
|
||||
newStreamData += toStreamData(profileEntry);
|
||||
|
||||
break;
|
||||
}
|
||||
m_modelAllocated->setNewStreamData(newStreamData);
|
||||
m_filterAvailable->setAllocatedStreams(newStreamData);
|
||||
} // end of fillOperatorList
|
||||
|
||||
void AudioSettingsDialog::fillOperatorBox()
|
||||
{
|
||||
m_ui->operatorComboBox->clear();
|
||||
QMap<int, QString>::iterator i = m_operatorMap.begin();
|
||||
while (i != m_operatorMap.end())
|
||||
{
|
||||
m_ui->operatorComboBox->addItem(i.value(), i.key());
|
||||
++i;
|
||||
}
|
||||
m_ui->operatorComboBox->model()->sort(0);
|
||||
}
|
||||
|
||||
void AudioSettingsDialog::onUpButtonClicked()
|
||||
{
|
||||
const QModelIndexList mil = m_ui->treeViewAllocated->selectionModel()->selectedIndexes();
|
||||
if (mil.isEmpty())
|
||||
return;
|
||||
m_modelAllocated->changeOrder(mil.first(), true);
|
||||
|
||||
if (mil.first().row() > 0)
|
||||
{
|
||||
const QModelIndex newRow = m_modelAllocated->index(mil.first().row() - 1, 0);
|
||||
m_ui->treeViewAllocated->setCurrentIndex(newRow);
|
||||
}
|
||||
|
||||
slotChangesMade();
|
||||
} // end of onUpButtonClicked
|
||||
|
||||
void AudioSettingsDialog::onDownButtonClicked()
|
||||
{
|
||||
const QModelIndexList mil = m_ui->treeViewAllocated->selectionModel()->selectedIndexes();
|
||||
if (mil.isEmpty())
|
||||
return;
|
||||
m_modelAllocated->changeOrder(mil.first(), false);
|
||||
const QModelIndex newRow = m_modelAllocated->index(mil.first().row() + 1, 0);
|
||||
m_ui->treeViewAllocated->setCurrentIndex(newRow);
|
||||
slotChangesMade();
|
||||
} // end of onDownButtonClicked
|
||||
|
||||
void AudioSettingsDialog::onSelectionChangedAllocation(const QItemSelection &selected, const QItemSelection &deselected)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSelectionChangedAllocation selected.isEmpty()=" << selected.isEmpty();
|
||||
Q_UNUSED(deselected);
|
||||
QModelIndex first = m_ui->treeViewAllocated->model()->index(0, 0);
|
||||
int rowCnt = m_ui->treeViewAllocated->model()->rowCount();
|
||||
QModelIndex last = m_ui->treeViewAllocated->model()->index(rowCnt - 1, 0);
|
||||
QModelIndexList selectedRows = m_ui->treeViewAllocated->selectionModel()->selectedIndexes();
|
||||
const int cntSelectedRows = selectedRows.size();
|
||||
if (cntSelectedRows > 1)
|
||||
{
|
||||
m_ui->pushButtonUp->setEnabled(false);
|
||||
m_ui->pushButtonDown->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
if (selected.size() > 0)
|
||||
{
|
||||
m_ui->pushButtonUp->setEnabled(selected.first().indexes().first() != first);
|
||||
m_ui->pushButtonDown->setEnabled(selected.first().indexes().first() != last);
|
||||
}
|
||||
} // end of onSelectionAllocationChanged
|
||||
|
||||
|
||||
bool AudioSettingsDialog::apply()
|
||||
{
|
||||
if (m_modelAllocated->getStreamDataVector().isEmpty())
|
||||
applyRemove();
|
||||
else
|
||||
applyModify();
|
||||
m_modelAllocated->resetChangeState();
|
||||
m_modelAvailable->resetChangeState();
|
||||
m_filterAvailable->invalidate();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioSettingsDialog::applyRemove()
|
||||
{
|
||||
RemoveCnrTvcProfileRequest removeRequest;
|
||||
DEBUG_LOG(m_logger) << "AudioSettingsDialog::applyRemove";
|
||||
|
||||
for (const auto &profile : qAsConst(m_cnrTvcProfileMap))
|
||||
{
|
||||
if (profile.operatorId() != m_operatorId)
|
||||
continue;
|
||||
removeRequest.id(profile.id());
|
||||
break;
|
||||
}
|
||||
if (removeRequest.id() <= 0)
|
||||
return true;
|
||||
|
||||
m_requestHelper->startSingleRequest([this, removeRequest]()
|
||||
{
|
||||
return m_avmFtc->removeCnrTvcProfileRequest(removeRequest, this);
|
||||
});
|
||||
|
||||
return true;
|
||||
} // end of applyRemove
|
||||
|
||||
bool AudioSettingsDialog::applyModify()
|
||||
{
|
||||
ModifyCnrTvcProfileRequest modifyRequest;
|
||||
DEBUG_LOG(m_logger) << "AudioSettingsDialog::applyModify";
|
||||
|
||||
for (const auto &profile : qAsConst(m_cnrTvcProfileMap))
|
||||
{
|
||||
if (profile.operatorId() != m_operatorId)
|
||||
continue;
|
||||
modifyRequest.id(profile.id());
|
||||
break;
|
||||
}
|
||||
|
||||
modifyRequest.exerciseId(m_session->exerciseId());
|
||||
modifyRequest.operatorId(m_operatorId);
|
||||
|
||||
const QVector<StreamData> allocatedList = m_modelAllocated->getStreamDataVector();
|
||||
modifyRequest.data().reserve(allocatedList.size());
|
||||
for (const StreamData &stream : allocatedList)
|
||||
{
|
||||
CnrTvcProfileData circuitData;
|
||||
circuitData.radioSystemId(stream.bIsCnr ? RadioSystem::Cnr : RadioSystem::Tvc);
|
||||
circuitData.radioCircuitId(stream.topicId);
|
||||
modifyRequest.data().push_back(std::move(circuitData));
|
||||
}
|
||||
|
||||
m_requestHelper->startSingleRequest([this, modifyRequest]()
|
||||
{
|
||||
return m_avmFtc->modifyCnrTvcProfileRequest(modifyRequest, this);
|
||||
});
|
||||
|
||||
return true;
|
||||
} // end of applyModify
|
||||
|
||||
void AudioSettingsDialog::onModifyCnrTvcProfileReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
__unchange__();
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
} // end of onCreateRadioCircuitsReply
|
||||
//-----------------------------------------------------------------------------
|
||||
void AudioSettingsDialog::onRemoveCnrTvcProfileReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
__unchange__();
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
} // end of onRemoveRadioCircuitsReply
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AudioSettingsDialog::onSelectionOperatorChanged(const int index)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
if (hasUnsavedChanges() ||
|
||||
m_modelAllocated->getChangeState() ||
|
||||
m_modelAvailable->getChangeState())
|
||||
{
|
||||
switch (askApplyDiscardCancel())
|
||||
{
|
||||
case LtsWidgets::Button::Apply:
|
||||
if (!apply())
|
||||
return;
|
||||
break;
|
||||
case LtsWidgets::Button::Cancel:
|
||||
{
|
||||
// cfroebel 2019-06-26:
|
||||
// Setting back the operator would cause this slot to be called again.
|
||||
// Thus we avoid this by blocking signals.
|
||||
{
|
||||
QSignalBlocker blockSignals(m_ui->operatorComboBox);
|
||||
m_ui->operatorComboBox->setCurrentIndex(m_ui->operatorComboBox->findData(m_operatorId)); // reset position
|
||||
}
|
||||
return;
|
||||
}
|
||||
case LtsWidgets::Button::Discard:
|
||||
__unchange__(); // can't call resetChanges() by myself :(
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_ui->pushButtonUp->setEnabled(false);
|
||||
m_ui->pushButtonDown->setEnabled(false);
|
||||
m_operatorId = m_ui->operatorComboBox->currentData().toInt();
|
||||
DEBUG_LOG(m_logger) << "onSelectionOperatorChanged" << " operatorStr=" << m_ui->operatorComboBox->currentText() << " m_operatorId= " << m_operatorId;
|
||||
fillOperatorList();
|
||||
m_modelAllocated->resetChangeState();
|
||||
m_modelAvailable->resetChangeState();
|
||||
m_filterAvailable->invalidate();
|
||||
}
|
||||
|
||||
void AudioSettingsDialog::onDroppedInAllocated(const QVector<StreamData> &streams)
|
||||
{
|
||||
slotChangesMade();
|
||||
m_filterAvailable->addAllocatedStreams(streams);
|
||||
m_modelAllocated->setStreamChanged(streams);
|
||||
m_modelAvailable->setStreamChanged(streams);
|
||||
}
|
||||
|
||||
void AudioSettingsDialog::onDroppedInAvailable(const QVector<StreamData> &streams)
|
||||
{
|
||||
slotChangesMade();
|
||||
m_filterAvailable->removeAllocatedStreams(streams);
|
||||
m_modelAllocated->setStreamChanged(streams);
|
||||
m_modelAvailable->setStreamChanged(streams);
|
||||
}
|
||||
|
||||
void AudioSettingsDialog::onEntryRemoved(const StreamData &stream)
|
||||
{
|
||||
m_modelAllocated->removeEntry(stream);
|
||||
m_filterAvailable->removeAllocatedStreams({stream}); // in case the stream was allocated forget about it
|
||||
}
|
||||
|
||||
StreamData AudioSettingsDialog::toStreamData(const CnrTvcProfileData &profileEntry) const
|
||||
{
|
||||
int configId = profileEntry.radioCircuitId();
|
||||
StreamData streamData;
|
||||
streamData.topicId = configId;
|
||||
|
||||
if (profileEntry.radioSystemId() == RadioSystem::Cnr)
|
||||
{
|
||||
streamData.name = QString::fromStdString(m_avmDtc->cnrConfig(configId).radioCircuit());
|
||||
streamData.bIsCnr = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
streamData.name = QString::fromStdString(m_avmDtc->tvcConfig(configId).radioCircuit());
|
||||
streamData.bIsCnr = false;
|
||||
}
|
||||
|
||||
return streamData;
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManangement - Operator Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <AudioVideoManagement/avm_ftc.h>
|
||||
#include <QVector>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AudioSettingsDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSessionDataDds;
|
||||
}
|
||||
|
||||
class QItemSelection;
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
struct StreamData;
|
||||
class AvailStreamsModel;
|
||||
class AvailStreamsFilter;
|
||||
class AllocatedStreamsModel;
|
||||
|
||||
|
||||
class AudioSettingsDialog : public LtsWidgets::LtsDialog
|
||||
, protected AudioVideoManagement::Interface::Ftc::ModifyCnrTvcProfileReplyHandler
|
||||
, protected AudioVideoManagement::Interface::Ftc::RemoveCnrTvcProfileReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AudioSettingsDialog(QWidget *parent = nullptr);
|
||||
~AudioSettingsDialog();
|
||||
|
||||
bool init(OperatorManagement::Interface::Dtc *opmDtc,
|
||||
AudioVideoManagement::Interface::Dtc *avmDtc,
|
||||
AudioVideoManagement::Interface::Ftc *avmFtc,
|
||||
LtsSession::LtsSessionDataDds *session);
|
||||
|
||||
void onModifyCnrTvcProfileReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onRemoveCnrTvcProfileReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
|
||||
private:
|
||||
enum class CircuitChoice
|
||||
{
|
||||
None,
|
||||
Cnr,
|
||||
Tvc
|
||||
};
|
||||
|
||||
void retranslate() override;
|
||||
bool apply() override final;
|
||||
bool applyModify();
|
||||
bool applyRemove();
|
||||
void fillOperatorBox();
|
||||
void fillOperatorList();
|
||||
|
||||
private slots:
|
||||
void onOperatorChanged(const OperatorManagement::User &data, DataModification modType);
|
||||
void onCnrTvcProfileChanged(const AudioVideoManagement::CnrTvcProfile &data, DataModification modType);
|
||||
void onUpButtonClicked();
|
||||
void onDownButtonClicked();
|
||||
void onSelectionChangedAllocation(const QItemSelection &selected, const QItemSelection &deselected);
|
||||
void onSelectionOperatorChanged(const int index);
|
||||
void onDroppedInAllocated(const QVector<StreamData> &streams);
|
||||
void onDroppedInAvailable(const QVector<StreamData> &streams);
|
||||
void onEntryRemoved(const StreamData &stream);
|
||||
|
||||
private:
|
||||
StreamData toStreamData(const CnrTvcProfileData &profileEntry) const;
|
||||
|
||||
AudioVideoManagement::Interface::Dtc *m_avmDtc{nullptr};
|
||||
AudioVideoManagement::Interface::Ftc *m_avmFtc{nullptr};
|
||||
|
||||
int m_operatorId{-1}; //!< currently displayed operator
|
||||
QMap<int, QString> m_operatorMap;
|
||||
QMap<int, AudioVideoManagement::CnrTvcProfile> m_cnrTvcProfileMap; // all dds-Configs key = DDS-ID
|
||||
|
||||
AvailStreamsModel *m_modelAvailable{nullptr};
|
||||
AvailStreamsFilter *m_filterAvailable{nullptr};
|
||||
AllocatedStreamsModel *m_modelAllocated{nullptr};
|
||||
|
||||
Ui::AudioSettingsDialog *m_ui{nullptr};
|
||||
LtsUtils::RequestHelper *m_requestHelper{nullptr};
|
||||
LtsSession::LtsSessionDataDds *m_session{nullptr};
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AudioSettingsDialog</class>
|
||||
<widget class="QWidget" name="AudioSettingsDialog">
|
||||
<property name="windowTitle">
|
||||
<string>Voice Communication Access</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0" rowspan="5">
|
||||
<widget class="QTreeView" name="treeViewAvailable">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="5">
|
||||
<widget class="QTreeView" name="treeViewAllocated">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::CopyAction</enum>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerCascadingSectionResizes">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerShowSortIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>90</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonUp">
|
||||
<property name="text">
|
||||
<string notr="true">↑ </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QPushButton" name="pushButtonDown">
|
||||
<property name="text">
|
||||
<string notr="true">↓</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>89</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbxOperator">
|
||||
<property name="text">
|
||||
<string>Operator:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsComboBox" name="operatorComboBox">
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>operatorComboBox</tabstop>
|
||||
<tabstop>treeViewAvailable</tabstop>
|
||||
<tabstop>treeViewAllocated</tabstop>
|
||||
<tabstop>pushButtonUp</tabstop>
|
||||
<tabstop>pushButtonDown</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+186
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManangement - Show all available streams
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-11-06
|
||||
*/
|
||||
|
||||
#include "audio_settings_used_streams_model.h"
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
#include <QMimeData>
|
||||
#include <QFont>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
//
|
||||
// UsedStreamsModel
|
||||
//
|
||||
AllocatedStreamsModel::AllocatedStreamsModel(QObject *parent)
|
||||
: NGLTreeModel(parent, new NGLTreeItem(QVariant(QLatin1String("root"))), { tr("Allocated") })
|
||||
, m_logger(getLogger("AudioSettingsUsedStreamsModel"))
|
||||
{
|
||||
setMimeType(StreamData::mimeType());
|
||||
}
|
||||
|
||||
Qt::ItemFlags AllocatedStreamsModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
return NGLTreeModel::flags(index) | Qt::ItemIsDropEnabled;
|
||||
}
|
||||
|
||||
QVariant AllocatedStreamsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
NGLTreeItem *item = privateData(index);
|
||||
StreamData data = item->data().value<StreamData>();
|
||||
DEBUG_LOG(m_logger) << data.name;
|
||||
return data.name;
|
||||
}
|
||||
|
||||
case Qt::FontRole:
|
||||
{
|
||||
NGLTreeItem *item = privateData(index);
|
||||
StreamData data = item->data().value<StreamData>();
|
||||
if (!m_changedStreams.contains(QPair<bool,int>(data.bIsCnr, data.topicId)))
|
||||
return {};
|
||||
QFont f;
|
||||
f.setBold(true);
|
||||
return f;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NGLTreeModel::data(index, role);
|
||||
}
|
||||
|
||||
|
||||
void AllocatedStreamsModel::setStreamChanged(const QVector<StreamData> &streams)
|
||||
{
|
||||
for (const StreamData &d : streams)
|
||||
if (!m_changedStreams.contains(QPair<bool,int>(d.bIsCnr, d.topicId)))
|
||||
m_changedStreams += QPair<bool,int>(d.bIsCnr, d.topicId);
|
||||
emit modelDataChanged();
|
||||
}
|
||||
|
||||
|
||||
bool AllocatedStreamsModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(column);
|
||||
Q_UNUSED(parent);
|
||||
if (action != supportedDropActions())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AllocatedStreamsModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
|
||||
int row, int column, const QModelIndex &parent)
|
||||
{
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(column);
|
||||
Q_UNUSED(parent);
|
||||
|
||||
const QVector<NGLTreeItem *> droppedItems = getMimeDataItems(data, m_mimeType);
|
||||
QVector<StreamData> streams;
|
||||
streams.reserve(droppedItems.size());
|
||||
for (const NGLTreeItem *item : droppedItems)
|
||||
streams += item->data().value<StreamData>();
|
||||
qDeleteAll(droppedItems);
|
||||
emit droppedStreamNames(streams);
|
||||
m_changes = true;
|
||||
DEBUG_LOG(m_logger) << data->data(QStringLiteral("NGLTreeModel/dragDrop"));
|
||||
return NGLTreeModel::dropMimeData(data, action, row, 0, QModelIndex());
|
||||
}
|
||||
|
||||
|
||||
void AllocatedStreamsModel::setNewStreamData(const QVector<StreamData> &newData)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "set new stream data, count: " << newData.size();
|
||||
resetModel();
|
||||
for (const StreamData &sd : newData)
|
||||
m_rootItem->appendChild(new NGLTreeItem(QVariant::fromValue(sd)));
|
||||
|
||||
emit modelDataChanged();
|
||||
}
|
||||
|
||||
QVector<StreamData> AllocatedStreamsModel::getStreamDataVector() const
|
||||
{
|
||||
QVector<StreamData> result;
|
||||
result.reserve(m_rootItem->childCount());
|
||||
for (int i = 0; i < m_rootItem->childCount(); i++)
|
||||
{
|
||||
const NGLTreeItem *item = m_rootItem->child(i);
|
||||
const StreamData sd = item->data().value<StreamData>();
|
||||
result.append(sd);
|
||||
DEBUG_LOG(m_logger) << "result.append(sd.name):" << sd.name;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "getStreamDataVector() size: " << result.size();
|
||||
return result;
|
||||
}
|
||||
|
||||
void AllocatedStreamsModel::changeOrder(const QModelIndex &idx, bool up)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "changeOrder "
|
||||
<< " index = " << idx.row()
|
||||
<< " up = " << up
|
||||
<< " m_rootItem->childCount()= " << m_rootItem->childCount();
|
||||
if (up)
|
||||
{
|
||||
moveRow(idx.parent(), idx.row(),
|
||||
idx.parent(), idx.row() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveRow(idx.parent(), idx.row(),
|
||||
idx.parent(), idx.row() + 1);
|
||||
}
|
||||
emit modelDataChanged();
|
||||
}
|
||||
|
||||
// Wird ueber connect im SettingsDialog vom AvailableModel::updateEntry aufgerufen
|
||||
void AllocatedStreamsModel::updateEntry(const StreamData &stream)
|
||||
{
|
||||
for (int i = 0; i < m_rootItem->childCount(); i++)
|
||||
{
|
||||
NGLTreeItem *child = m_rootItem->child(i);
|
||||
StreamData data = child->data().value<StreamData>();
|
||||
|
||||
if (data == stream)
|
||||
{
|
||||
setItemData(indexFromItem(child), QVariant::fromValue(stream), child->icon());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit modelDataChanged();
|
||||
}
|
||||
|
||||
// Wird ueber connect im SettingsDialog vom AvailableModel::removeEntry aufgerufen
|
||||
void AllocatedStreamsModel::removeEntry(const StreamData &stream)
|
||||
{
|
||||
for (int i = 0; i < m_rootItem->childCount(); i++)
|
||||
{
|
||||
NGLTreeItem *child = m_rootItem->child(i);
|
||||
StreamData data = child->data().value<StreamData>();
|
||||
if (data == stream)
|
||||
{
|
||||
removeRows(i, 1, indexFromItem(m_rootItem));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit modelDataChanged();
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManangement - Show all available streams
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-11-06
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include "audio_stream_type.h"
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class AllocatedStreamsModel final : public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AllocatedStreamsModel(QObject *parent = nullptr);
|
||||
|
||||
bool getChangeState() {bool result = m_changes; m_changes = false; return result;}
|
||||
void resetChangeState() {m_changes = false;m_changedStreams.clear();}
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
Qt::DropActions supportedDropActions() const override { return Qt::CopyAction; }
|
||||
Qt::DropActions supportedDragActions() const override { return Qt::MoveAction; }
|
||||
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
|
||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action,
|
||||
int row, int column, const QModelIndex &parent) override;
|
||||
void setStreamChanged(const QVector<StreamData> &streams);
|
||||
|
||||
void setNewStreamData(const QVector<StreamData> &newData);
|
||||
|
||||
QVector<StreamData> getStreamDataVector() const;
|
||||
|
||||
void changeOrder(const QModelIndex &idx, bool up);
|
||||
void updateEntry(const StreamData &stream);
|
||||
void removeEntry(const StreamData &stream);
|
||||
|
||||
signals:
|
||||
void droppedStreamNames(const QVector<AudioVideoManagement::StreamData> &streamNamesDropped);
|
||||
|
||||
private:
|
||||
bool m_changes{false};
|
||||
QVector<QPair<bool /* is cnr */, int> > m_changedStreams;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManangement - Show all available streams
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-11-06
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AudioVideoManagement/avm.hpp>
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <boost/operators.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
/**
|
||||
* Helper struct used by AvailStreamsModel, AllocatedStreamsModel.
|
||||
*
|
||||
* Comparision operators only consider bIsCnr and topicId, i.e. name is irrelevant.
|
||||
*/
|
||||
struct StreamData : boost::totally_ordered<StreamData>
|
||||
{
|
||||
StreamData() = default;
|
||||
|
||||
explicit StreamData(const TvcConfig &tvcConfig)
|
||||
: name(QString::fromStdString(tvcConfig.radioCircuit()))
|
||||
, topicId(tvcConfig.id())
|
||||
, bIsCnr(false)
|
||||
{}
|
||||
|
||||
explicit StreamData(const CnrConfig &cnrConfig)
|
||||
: name(QString::fromStdString(cnrConfig.radioCircuit()))
|
||||
, topicId(cnrConfig.id())
|
||||
, bIsCnr(true)
|
||||
{}
|
||||
|
||||
QString name;
|
||||
int topicId = 0;
|
||||
bool bIsCnr = false;
|
||||
|
||||
static QString mimeType() { return QStringLiteral("AVM/StreamData"); }
|
||||
|
||||
bool operator<(const StreamData &other) const { return asPair() < other.asPair(); }
|
||||
bool operator==(const StreamData &other) const { return asPair() == other.asPair(); }
|
||||
|
||||
private:
|
||||
std::pair<bool, int> asPair() const { return {bIsCnr, topicId}; }
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
Q_DECLARE_METATYPE(AudioVideoManagement::StreamData);
|
||||
Reference in new issue
Block a user