324 lines
8.7 KiB
C++
Executable File
324 lines
8.7 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Radio TreeModel
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "avm_available_streams_model.h"
|
|
#include <AudioVideoManagement/stream_name_mapping.h>
|
|
#include <InfrastructureManagement/ism.hpp>
|
|
#include <nglwidgets/ngltreeitem.h>
|
|
|
|
#include <QSet>
|
|
#include <QMimeData>
|
|
#include <QCollator>
|
|
|
|
namespace
|
|
{
|
|
|
|
bool isMountingPointOfInterest(const InfrastructureManagement::StructureElement &se, bool isAudio)
|
|
{
|
|
if (se.structureElementTypeId() != InfrastructureManagement::StructureElementType::MountingPoint)
|
|
return false;
|
|
|
|
// Cameras are relevant for both, audio and video
|
|
// The problem for audio here is that we cannot know yet whether later
|
|
// there will be a camera mounted that is capable of audio.
|
|
if (se.mountingPointTypeId() == InfrastructureManagement::MountingPointType::IndoorCamera ||
|
|
se.mountingPointTypeId() == InfrastructureManagement::MountingPointType::OutdoorCamera)
|
|
return true;
|
|
|
|
if (isAudio && se.mountingPointTypeId() == InfrastructureManagement::MountingPointType::AnnouncementUnit)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
namespace AudioVideoManagement
|
|
{
|
|
const QString AvailableStreamsModel::s_MimeType = QStringLiteral("AvailStreamsModel/DragDrop");
|
|
|
|
|
|
|
|
struct sorter
|
|
{
|
|
bool operator()(const StreamModelData &i, const StreamModelData &j)
|
|
{
|
|
QCollator col;
|
|
col.setNumericMode(true);
|
|
return col.compare(j.name, i.name) > 0 ;
|
|
}
|
|
} sortStuff;
|
|
|
|
|
|
AvailableStreamsModel::AvailableStreamsModel(const std::shared_ptr<Interface::Dtc> &avmDtc,
|
|
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
|
LtsSession::LtsSession *session,
|
|
StreamNameMapping *streamNameMapping,
|
|
QObject *parent,
|
|
bool isAudio)
|
|
: NGLTreeModel(parent, new NGLTreeItem(QVariant(), QIcon()), {tr("Available Streams")})
|
|
, m_isAudio(isAudio)
|
|
, m_avmDtc(avmDtc)
|
|
, m_ismDtc(ismDtc)
|
|
, m_session(session)
|
|
, m_streamNameMapping(streamNameMapping)
|
|
, m_logger(getLogger("AvailableStreamsModel"))
|
|
{
|
|
Q_ASSERT(ismDtc);
|
|
Q_ASSERT(streamNameMapping);
|
|
qRegisterMetaTypeStreamOperators<StreamModelData>("StreamModelData");
|
|
qRegisterMetaType<StreamModelData>("StreamModelData");
|
|
|
|
setMimeType(s_MimeType);
|
|
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged,
|
|
this, [ this]()
|
|
{
|
|
initModel();
|
|
});
|
|
|
|
connect(m_streamNameMapping, &StreamNameMapping::changed,
|
|
this, [ this]()
|
|
{
|
|
initModel();
|
|
});
|
|
|
|
if (!m_isAudio)
|
|
{
|
|
connect(m_avmDtc.get(), &AudioVideoManagement::Interface::Dtc::videoTeamChanged,
|
|
this, [ this]()
|
|
{
|
|
initModel();
|
|
});
|
|
}
|
|
initModel();
|
|
}
|
|
|
|
QVariant AvailableStreamsModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid())
|
|
return QVariant();
|
|
|
|
NGLTreeItem *item = privateData(index);
|
|
if (!item->data().canConvert<StreamModelData>())
|
|
return QVariant();
|
|
|
|
const StreamModelData availStream = item->data().value<StreamModelData>();
|
|
|
|
switch (role)
|
|
{
|
|
case Qt::DisplayRole:
|
|
{
|
|
switch (index.column())
|
|
{
|
|
case 0 :
|
|
return availStream.name;
|
|
default:
|
|
return QStringLiteral("??");
|
|
}
|
|
break;
|
|
}
|
|
case Qt::DecorationRole:
|
|
{
|
|
switch (index.column())
|
|
{
|
|
case 0:
|
|
{
|
|
static const QIcon folder(QStringLiteral("icon:evaluation_folder.svg"));
|
|
static const QIcon camera(QStringLiteral("icon:camera_control.svg"));
|
|
return availStream.isGroup ? folder : camera;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
} // switch
|
|
return NGLTreeModel::data(index, role);
|
|
}
|
|
|
|
|
|
Qt::ItemFlags AvailableStreamsModel::flags(const QModelIndex &index) const
|
|
{
|
|
Qt::ItemFlags defaultFlags = NGLTreeModel::flags(index);
|
|
NGLTreeItem *item = privateData(index);
|
|
|
|
if (item == m_rootItem)
|
|
return defaultFlags;
|
|
|
|
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
|
|
}
|
|
|
|
|
|
QMimeData *AvailableStreamsModel::mimeData(const QModelIndexList &indexes) const
|
|
{
|
|
// Use display role (textual name of stream) for identification when dropping mimeData
|
|
QMimeData *pData = NGLTreeModel::mimeData(indexes);
|
|
pData->setText(data(indexes[0]).toString());
|
|
return pData;
|
|
}
|
|
|
|
|
|
bool AvailableStreamsModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
|
|
int row, int column, const QModelIndex &parent)
|
|
{
|
|
INFO_LOG(m_logger) << "dropMimeData: action = " << action
|
|
<< ", row = " << row
|
|
<< ", parent: valid = " << parent.isValid();
|
|
|
|
if (action == Qt::IgnoreAction)
|
|
return true;
|
|
|
|
if (!data->hasFormat(s_MimeType))
|
|
return false;
|
|
|
|
if ((action != Qt::MoveAction) && (action != Qt::CopyAction))
|
|
return false;
|
|
|
|
return NGLTreeModel::dropMimeData(data, action, row, column, parent);
|
|
}
|
|
|
|
|
|
void AvailableStreamsModel::initModel()
|
|
{
|
|
beginResetModel();
|
|
INFO_LOG(m_logger) << "initModel";
|
|
// build tree
|
|
// Ignore NOT installed streams
|
|
m_rootItem->removeAllChildren();
|
|
// group to bundle streams
|
|
StreamModelData availStream;
|
|
availStream.id = 0;
|
|
availStream.name = tr("New group");
|
|
availStream.parentId = -1;
|
|
availStream.isGroup = true;
|
|
|
|
QVariant data;
|
|
data.setValue(availStream);
|
|
m_rootItem->appendChild(new NGLTreeItem(data, QIcon()));
|
|
|
|
std::vector<StreamModelData> toAddIndoor;
|
|
std::vector<StreamModelData> toAddOutdoor;
|
|
|
|
std::vector<StreamModelData> toAddMvs;
|
|
|
|
|
|
const auto &mountedAssets = m_ismDtc->mountingPointAssets();
|
|
const auto &buildings = m_ismDtc->mainStructureElements();
|
|
for (const auto &building : buildings)
|
|
{
|
|
for (const auto &mountingPoint : building.elements())
|
|
{
|
|
if (!isMountingPointOfInterest(mountingPoint, m_isAudio))
|
|
continue;
|
|
|
|
//check for mounted
|
|
bool isMounted = false;
|
|
for (const auto &mountedAsset : mountedAssets)
|
|
{
|
|
if (mountedAsset.structureElementId() == mountingPoint.id())
|
|
{
|
|
isMounted = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isMounted)
|
|
continue;
|
|
StreamModelData item;
|
|
item.name = m_streamNameMapping->displayName(mountingPoint.id());
|
|
item.mountingPointId = mountingPoint.id();
|
|
item.isGroup = false;
|
|
// What about id and parentId?
|
|
|
|
if (mountingPoint.mountingPointTypeId() == InfrastructureManagement::MountingPointType::IndoorCamera)
|
|
toAddIndoor.push_back(item);
|
|
else
|
|
toAddOutdoor.push_back(item);
|
|
// m_rootItem->appendChild(new NGLTreeItem(data, QIcon()));
|
|
}
|
|
}
|
|
|
|
|
|
//add MVS in video list
|
|
if (!m_isAudio)
|
|
{
|
|
const auto &mvsStreams = m_avmDtc->videoTeams();
|
|
for (const auto &videoTeam : mvsStreams)
|
|
{
|
|
if (videoTeam.exerciseId() != m_session->exerciseId())
|
|
continue;
|
|
DEBUG_LOG(m_logger) << "add new videoteam" << videoTeam;
|
|
StreamModelData item;
|
|
item.name = QString::fromStdString(videoTeam.streamName().c_str());
|
|
item.mountingPointId = -1 * videoTeam.id(); // negative id for mvs
|
|
item.isGroup = false;
|
|
|
|
// data.setValue(item);
|
|
toAddMvs.push_back(item);
|
|
//m_rootItem->appendChild(new NGLTreeItem(data, QIcon()));
|
|
}
|
|
|
|
}
|
|
|
|
//sort
|
|
|
|
// using object as comp
|
|
std::sort(toAddOutdoor.begin(), toAddOutdoor.end(), sortStuff);
|
|
for (const auto &item : toAddOutdoor)
|
|
{
|
|
data.setValue(item);
|
|
m_rootItem->appendChild(new NGLTreeItem(data, QIcon()));
|
|
}
|
|
|
|
std::sort(toAddIndoor.begin(), toAddIndoor.end(), sortStuff);
|
|
for (const auto &item : toAddIndoor)
|
|
{
|
|
data.setValue(item);
|
|
m_rootItem->appendChild(new NGLTreeItem(data, QIcon()));
|
|
}
|
|
|
|
std::sort(toAddMvs.begin(), toAddMvs.end(), sortStuff);
|
|
for (const auto &item : toAddMvs)
|
|
{
|
|
data.setValue(item);
|
|
m_rootItem->appendChild(new NGLTreeItem(data, QIcon()));
|
|
}
|
|
endResetModel();
|
|
}
|
|
|
|
StreamModelData StreamModelData::createFromServiceItem(const AvMenuEntry &entry, StreamNameMapping *streamNameMapping, const QMap<int, VideoTeam> &videoTeamList)
|
|
{
|
|
StreamModelData data;
|
|
data.id = entry.id();
|
|
data.parentId = entry.parentId();
|
|
data.isGroup = entry.isGroup();
|
|
if (entry.isGroup())
|
|
data.name = QString::fromStdString(entry.name().get());
|
|
else
|
|
{
|
|
if (entry.mountingPointId().is_set() && (entry.mountingPointId().get() > 0))
|
|
{
|
|
data.mountingPointId = entry.mountingPointId().get();
|
|
data.name = streamNameMapping->displayName(entry.mountingPointId().get());
|
|
}
|
|
else
|
|
{
|
|
data.mountingPointId = entry.mountingPointId().get();
|
|
data.name = QString::fromStdString(videoTeamList.value(entry.mountingPointId().get() * -1).streamName());
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
} // Namespace AudioVideoManagement
|