Files
qt5-legatus-legacy/Lts/Plugins/ParticipantManagement/Gui/Common/participant_icon_model_base.cpp
T
2026-08-13 18:33:10 +02:00

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 &currentIndex, 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