/** * @RDE_HEADER@ * Helper class to provide symbol rendering in QAbstractItemModels * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2017-11-01 */ #include "table_model_symbol_renderer_base.h" #include #include #include #include namespace AdvancedSymbology { TableModelSymbolRendererBase::TableModelSymbolRendererBase(int iconColumn) : m_partyRole(AdvancedSymbology::Role::Unknown) , m_iconColumn(iconColumn) , m_super(nullptr) {} void TableModelSymbolRendererBase::init(const std::shared_ptr &asb, QObject *super) { m_asb = asb; m_super = super; } void TableModelSymbolRendererBase::setDefaultRoleAndColor(const Role &role, const QColor &partyColor) { m_partyRole = role; m_partyColor = partyColor; } QVariant TableModelSymbolRendererBase::decorationData(const QModelIndex &idx, int id) const { return decorationIcon(idx, id); } QIcon TableModelSymbolRendererBase::decorationIcon(const QModelIndex &idx, int id) const { if (idx.column() != m_iconColumn) return QIcon(); auto it = m_symbols.find(id); if (it != m_symbols.end()) return it.value(); return QIcon(); } bool TableModelSymbolRendererBase::tryRenderSymbol(const QString &symbol, int id) { return tryRenderSymbol(symbol, id, m_partyColor, m_partyRole); } bool TableModelSymbolRendererBase::tryRenderSymbol(const QString &symbol, int id, const QColor &color, Role role) { if (!m_asb || symbol.isEmpty()) return false; AdvancedSymbology::SymbolDataToRender symDataToRender(symbol); symDataToRender.role = role; if (color.isValid()) { symDataToRender.fillColor = color; symDataToRender.fillColorReplace = true; } else { // User-Defined Symbols (XML) need fillColor: symDataToRender.fillColor = AdvancedSymbology::SymbolDataToRender::unknownColor(); symDataToRender.fillColorReplace = true; } QSharedPointer sr = m_asb->findImage(symDataToRender); AdvancedSymbology::SymbolResult *ptrSr = sr.data(); if (!ptrSr) { WARNING_LOG(logger()) << "Can not render symbol for sidc '" << symbol << "'"; return false; } // already a request available? auto it = m_symbolResultMapping.find(ptrSr); if (it == m_symbolResultMapping.end()) { SymbolResultData srd; srd.result = sr; srd.ids.push_back(id); m_symbolResultMapping.insert(ptrSr, srd); if (ptrSr->isResultReady()) { symbolRendered(ptrSr); } else { // queued because the object is destroyed inside symbolRendered() due to QSharedPointer // works without this as an object because we look for ptrSr (which is a child of this, // see m_symbolResultMapping container) Q_ASSERT(m_super); QPointer qPointer(ptrSr); QObject::connect(ptrSr, &AdvancedSymbology::SymbolResult::resultReadyInternal, m_super ? m_super : ptrSr, [this, qPointer]() { symbolRendered(qPointer); }, Qt::QueuedConnection); } } else { SymbolResultData &srd = it.value(); srd.ids.push_back(id); } return true; } void TableModelSymbolRendererBase::removeRenderedSymbol(int id) { m_symbols.remove(id); } void TableModelSymbolRendererBase::symbolRendered(AdvancedSymbology::SymbolResult *sr) { if (!sr || !sr->isResultReady()) return; auto it = m_symbolResultMapping.constFind(sr); if (it == m_symbolResultMapping.constEnd()) return; const SymbolResultData &srd = it.value(); const QIcon ico(QPixmap::fromImage(srd.result->symbolImage().image())); for (int id : srd.ids) { DEBUG_LOG(logger()) << "Symbol for id " << id << " ready"; m_symbols[id] = ico; const QModelIndex idx = indexForId(id, m_iconColumn); if (idx.isValid()) emit model()->dataChanged(idx, idx, {Qt::DecorationRole}); } m_symbolResultMapping.erase(it); } } // namespace AdvancedSymbology