178 lines
5.7 KiB
C++
Executable File
178 lines
5.7 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* A small helper class to provide icon rendering capabilities for NGLTreeModels
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Ehrlicher, SLSE, 2017-10-26
|
|
*/
|
|
|
|
#include "participant_icon_model_base.h"
|
|
#include <ParticipantManagement/ppm_translation.h>
|
|
#include <Plugins/AdvancedSymbology/asb_data_plugin_interface.h>
|
|
#include <nglwidgets/ngltreeitem.h>
|
|
#include <QHash>
|
|
#include <QIcon>
|
|
#include <QPointer>
|
|
#include <QTimer>
|
|
|
|
|
|
namespace ParticipantManagement
|
|
{
|
|
ParticipantIconModelBase::ParticipantIconModelBase(const std::shared_ptr<Interface::Dtc> &ppmDtc,
|
|
const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asbIfc,
|
|
const QStringList &hdr,
|
|
NGLTreeItem *rootItem,
|
|
QObject *parent,
|
|
NGL::INGLLogger &logger)
|
|
: NGLTreeModel(parent, rootItem, hdr)
|
|
, m_dtc(ppmDtc)
|
|
, m_asb(asbIfc)
|
|
, m_partyRole(AdvancedSymbology::Role::Unknown)
|
|
, m_logger(logger)
|
|
{
|
|
this->setMimeDataWithIcon(false); // do not serialize icons, they are repaint on drop again (with the new party color)
|
|
|
|
connect(ppmDtc.get(), &ParticipantManagement::Interface::Dtc::typeChanged,
|
|
this, &ParticipantIconModelBase::onTypeChanged);
|
|
auto cbTypes = [this](const ParticipantManagement::Type &type)
|
|
{
|
|
onTypeChanged(type, DataModification::eAdded);
|
|
};
|
|
ppmDtc->types(cbTypes);
|
|
}
|
|
|
|
|
|
void ParticipantIconModelBase::onTypeChanged(const ParticipantManagement::Type &data, DataModification modType)
|
|
{
|
|
if (modType == DataModification::eRemoved)
|
|
{
|
|
m_types.remove(data.id());
|
|
return;
|
|
}
|
|
|
|
m_types[data.id()] = data;
|
|
}
|
|
|
|
// type handling
|
|
ParticipantManagement::TypeClass ParticipantIconModelBase::typeClassIdFromTypeId(int typeId) const
|
|
{
|
|
return m_types.value(typeId).typeClass();
|
|
}
|
|
|
|
QString ParticipantIconModelBase::typeClassStringFromTypeId(int typeId) const
|
|
{
|
|
auto it = m_types.find(typeId);
|
|
if (it == m_types.end())
|
|
return QString();
|
|
return ParticipantManagement::toString(it.value().typeClass());
|
|
}
|
|
|
|
bool ParticipantIconModelBase::isUnitType(int typeId) const
|
|
{
|
|
const ParticipantManagement::TypeClass typeClassId = typeClassIdFromTypeId(typeId);
|
|
return typeClassId == ParticipantManagement::TypeClass::Unit ||
|
|
typeClassId == ParticipantManagement::TypeClass::SupportUnit;
|
|
}
|
|
|
|
// symbol handling
|
|
void ParticipantIconModelBase::tryRenderSymbol(const QString &symbol, NGLTreeItem *item)
|
|
{
|
|
if ( (item) && (m_asb) && (!symbol.isEmpty()) )
|
|
{
|
|
AdvancedSymbology::SymbolDataToRender symDataToRender(symbol);
|
|
symDataToRender.role = m_partyRole;
|
|
DEBUG_LOG(m_logger) << "Rendering symbol '" << symbol << "' for item " << item;
|
|
if (m_partyColor.isValid())
|
|
{
|
|
symDataToRender.fillColor = m_partyColor;
|
|
symDataToRender.fillColorReplace = true;
|
|
}
|
|
else
|
|
{
|
|
// User-Defined Symbols (XML) need fillColor:
|
|
symDataToRender.fillColor = AdvancedSymbology::SymbolDataToRender::unknownColor();
|
|
symDataToRender.fillColorReplace = true;
|
|
}
|
|
|
|
QSharedPointer<AdvancedSymbology::SymbolResult> symRes = m_asb->findImage(symDataToRender);
|
|
AdvancedSymbology::SymbolResult *symResPtr = symRes.data();
|
|
if (!symResPtr)
|
|
{
|
|
WARNING_LOG(m_logger) << "Can not render symbol for sidc '" << symbol << "'";
|
|
return;
|
|
}
|
|
|
|
auto it = m_symbolResultMapping.find(symResPtr);
|
|
if (it == m_symbolResultMapping.end())
|
|
{
|
|
if (symResPtr->isResultReady())
|
|
{
|
|
item->setIcon(QIcon(QPixmap::fromImage(symRes->symbolImage().image())));
|
|
}
|
|
else
|
|
{
|
|
SymbolResultData symResData;
|
|
symResData.result = symRes;
|
|
symResData.treeItems.push_back(item);
|
|
m_symbolResultMapping.insertMulti(symResPtr, symResData);
|
|
QPointer<AdvancedSymbology::SymbolResult> qPointer(symResPtr);
|
|
|
|
// queued because the object is destroyed inside symbolRendered() due to QSharedPointer
|
|
connect(symResPtr, &AdvancedSymbology::SymbolResult::resultReadyInternal,
|
|
this, [this, qPointer]() { symbolRendered(qPointer); }, Qt::QueuedConnection);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SymbolResultData &srd = it.value();
|
|
srd.treeItems.push_back(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ParticipantIconModelBase::symbolRendered(AdvancedSymbology::SymbolResult *symbolResult)
|
|
{
|
|
if ( (!symbolResult) || (!symbolResult->isResultReady()) )
|
|
return;
|
|
|
|
auto it = m_symbolResultMapping.constFind(symbolResult);
|
|
if (it == m_symbolResultMapping.constEnd())
|
|
return;
|
|
|
|
const SymbolResultData &symResData = it.value();
|
|
|
|
const QIcon icon(QPixmap::fromImage(symResData.result->symbolImage().image()));
|
|
for (NGLTreeItem *item : symResData.treeItems)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Symbol for " << item << " ready";
|
|
|
|
// we need to search for srd.treeItem because it may be already destroyed
|
|
if (!updateIcon(QModelIndex(), item, icon))
|
|
WARNING_LOG(m_logger) << "updateIcon failed for item " << item;
|
|
}
|
|
|
|
m_symbolResultMapping.erase(it);
|
|
}
|
|
|
|
bool ParticipantIconModelBase::updateIcon(const QModelIndex ¤tIndex, NGLTreeItem *itemToUpdate, const QIcon &icon)
|
|
{
|
|
const NGLTreeItem *currentItem = privateData(currentIndex);
|
|
if (currentItem == itemToUpdate)
|
|
{
|
|
itemToUpdate->setIcon(icon);
|
|
emit dataChanged(currentIndex, currentIndex, { Qt::DecorationRole });
|
|
return true;
|
|
}
|
|
const int childCount = currentItem->childCount();
|
|
for (int row = 0; row < childCount; ++row)
|
|
{
|
|
const QModelIndex childIndex = index(row, 0, currentIndex);
|
|
if (updateIcon(childIndex, itemToUpdate, icon))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // namespace ParticipantManagement
|