Skip to content
Permalink
Browse files

Merge pull request #9221 from m-kuhn/relation-reference-field-formatt…

…er-cache

Add cache for relation reference field formatter
  • Loading branch information
m-kuhn committed Feb 21, 2019
2 parents 3d99fd5 + 9f77b2d commit 5292efd082218a0c3e0961c8fb610e5bdf6149f6
@@ -35,6 +35,9 @@ Default constructor of field formatter for a relation reference field.

virtual QVariant sortValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const;


virtual QVariant createCache( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config ) const;

};

/************************************************************************
@@ -30,7 +30,10 @@ QString QgsRelationReferenceFieldFormatter::id() const

QString QgsRelationReferenceFieldFormatter::representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const
{
Q_UNUSED( cache );
if ( cache.isValid() )
{
return cache.value<QMap<QVariant, QString>>().value( value );
}

// Some sanity checks
if ( !config.contains( QStringLiteral( "Relation" ) ) )
@@ -90,3 +93,70 @@ QVariant QgsRelationReferenceFieldFormatter::sortValue( QgsVectorLayer *layer, i
{
return representValue( layer, fieldIndex, config, cache, value );
}

QVariant QgsRelationReferenceFieldFormatter::createCache( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config ) const
{
Q_UNUSED( fieldIndex );
QMap<QVariant, QString> cache;

// Some sanity checks
if ( !config.contains( QStringLiteral( "Relation" ) ) )
{
QgsMessageLog::logMessage( QObject::tr( "Missing Relation in configuration" ) );
return QVariant();
}
QgsRelation relation = QgsProject::instance()->relationManager()->relation( config[QStringLiteral( "Relation" )].toString() );
if ( !relation.isValid() )
{
QgsMessageLog::logMessage( QObject::tr( "Invalid relation" ) );
return QVariant();
}
QgsVectorLayer *referencingLayer = relation.referencingLayer();
if ( layer != referencingLayer )
{
QgsMessageLog::logMessage( QObject::tr( "representValue() with inconsistent layer parameter w.r.t relation referencingLayer" ) );
return QVariant();
}
QgsVectorLayer *referencedLayer = relation.referencedLayer();
if ( !referencedLayer )
{
QgsMessageLog::logMessage( QObject::tr( "Cannot find referenced layer" ) );
return QVariant();
}
int referencedFieldIdx = referencedLayer->fields().lookupField( relation.fieldPairs().at( 0 ).second );
if ( referencedFieldIdx == -1 )
{
QgsMessageLog::logMessage( QObject::tr( "Invalid referenced field (%1) configured in relation %2" ).arg( relation.fieldPairs().at( 0 ).second, relation.name() ) );
return QVariant();
}

QgsExpression expr( referencedLayer->displayExpression() );

QgsFeatureRequest request;
request.setFlags( QgsFeatureRequest::NoGeometry );
QgsAttributeList requiredAttributes = expr.referencedAttributeIndexes( referencedLayer->fields() ).toList();
requiredAttributes << referencedFieldIdx;
request.setSubsetOfAttributes( requiredAttributes );
QgsFeature feature;
auto iterator = referencedLayer->getFeatures( request );

QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( referencedLayer ) );

expr.prepare( &context );

while ( iterator.nextFeature( feature ) )
{
context.setFeature( feature );
QString title = expr.evaluate( &context ).toString();

if ( expr.hasEvalError() )
{
int referencedFieldIdx = referencedLayer->fields().lookupField( relation.fieldPairs().at( 0 ).second );
title = feature.attribute( referencedFieldIdx ).toString();
}

cache.insert( feature.attribute( referencedFieldIdx ), title );
}

return QVariant::fromValue<QMap<QVariant, QString>>( cache );
}
@@ -41,6 +41,8 @@ class CORE_EXPORT QgsRelationReferenceFieldFormatter : public QgsFieldFormatter
QString representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const override;

QVariant sortValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const override;

QVariant createCache( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config ) const override;
};

#endif // QGSRELATIONREFERENCEFIELDKIT_H

0 comments on commit 5292efd

Please sign in to comment.
You can’t perform that action at this time.