Files
qt5-legatus-legacy/Lts/Plugins/AdvancedSymbology/Helper/table_model_symbol_renderer_base.cpp
T
2026-08-13 18:33:10 +02:00

149 lines
4.1 KiB
C++
Executable File

/**
* @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 <AdvancedSymbology/asb_data_plugin_interface.h>
#include <NGLLogger/INGLLogger.h>
#include <QAbstractItemModel>
#include <QPointer>
namespace AdvancedSymbology
{
TableModelSymbolRendererBase::TableModelSymbolRendererBase(int iconColumn)
: m_partyRole(AdvancedSymbology::Role::Unknown)
, m_iconColumn(iconColumn)
, m_super(nullptr)
{}
void TableModelSymbolRendererBase::init(const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &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<AdvancedSymbology::SymbolResult> 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<AdvancedSymbology::SymbolResult> 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