/** * @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 #include #include #include #include #include #include namespace ParticipantManagement { ParticipantIconModelBase::ParticipantIconModelBase(const std::shared_ptr &ppmDtc, const std::shared_ptr &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 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 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