Skip to content

Commit

Permalink
Renamed to represent_attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Dec 13, 2021
1 parent c9c5896 commit f0a337c
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 18 deletions.
14 changes: 14 additions & 0 deletions resources/function_help/json/represent_attributes
@@ -0,0 +1,14 @@
{
"name": "represent_attributes",
"type": "function",
"groups": ["Record and Attributes"],
"description": "Returns a map with the attribute names as keys and the configured representation values as values. The representation value for the attributes depends on the configured widget type for each attribute. Often, this is useful for 'Value Map' widgets.",
"arguments": [
{"arg":"feature", "description": "The feature containing the attributes to be represented. (Optional)" },
{"arg":"layer", "description": "The vector layer the feature belongs to. (Optional)"}
],
"examples": [
{ "expression":"represent_attributes()", "returns":"The representation values for the current feature"},
{ "expression":"represent_attributes(feature, layer)", "returns":"The representation values for the specified feature and layer"}
]
}
67 changes: 49 additions & 18 deletions src/core/expression/qgsexpressionfunction.cpp
Expand Up @@ -1727,47 +1727,78 @@ static QVariant fcnAttributes( const QVariantList &values, const QgsExpressionCo
return result;
}

static QVariant fcnFormattedAttributes( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * )
static QVariant fcnRepresentAttributes( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QgsVectorLayer *vl = nullptr;
QgsVectorLayer *layer = nullptr;
QgsFeature feature;
if ( values.size() == 0 || values.at( 0 ).isNull() )
if ( ( values.size() == 0 || values.at( 0 ).isNull() ) && context )
{
feature = context->feature();
// first step - find current layer
vl = QgsExpressionUtils::getVectorLayer( context->variable( QStringLiteral( "layer" ) ), parent );
layer = QgsExpressionUtils::getVectorLayer( context->variable( QStringLiteral( "layer" ) ), parent );
}
else if ( values.size() == 2 && ! values.at( 1 ).isNull() )
{
feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
vl = QgsExpressionUtils::getVectorLayer( values.at( 1 ), parent );
layer = QgsExpressionUtils::getVectorLayer( values.at( 1 ), parent );
}
else
{
parent->setEvalErrorString( QObject::tr( "Layer is not set" ) );
return QVariant();
}

if ( !vl )
if ( !layer )
{
parent->setEvalErrorString( QObject::tr( "Cannot use formatted attributes function in this context" ) );
parent->setEvalErrorString( QObject::tr( "Cannot use represent attributes function in this context: layer coould not be resolved." ) );
return QVariant();
}

const QgsFields fields = feature.fields();
QVariantMap result;
for ( int idx = 0; idx < fields.count(); ++idx )
for ( int fieldIndex = 0; fieldIndex < fields.count(); ++fieldIndex )
{
QVariant attributeVal { feature.attribute( idx ) };
const QgsEditorWidgetSetup setup = vl->editorWidgetSetup( idx );
QgsFieldFormatter *fieldFormatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
QString value( fieldFormatter->representValue( vl, idx, setup.config(), QVariant(), attributeVal ) );

if ( setup.config().value( QStringLiteral( "AllowMulti" ) ).toBool() && value.startsWith( QLatin1Char( '{' ) ) && value.endsWith( QLatin1Char( '}' ) ) )
const QString fieldName { fields.at( fieldIndex ).name() };
QVariant attributeVal { feature.attribute( fieldIndex ) };
const QString cacheValueKey = QStringLiteral( "repvalfcnval:%1:%2:%3" ).arg( layer ? layer->id() : QStringLiteral( "[None]" ), fieldName, attributeVal.toString() );
if ( context && context->hasCachedValue( cacheValueKey ) )
{
value = value.mid( 1, value.size() - 2 );
result.insert( fieldName, context->cachedValue( cacheValueKey ) );
}
else
{
const QgsEditorWidgetSetup setup = layer->editorWidgetSetup( fieldIndex );
QgsFieldFormatter *fieldFormatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
QVariant cache;
if ( context )
{
const QString cacheKey = QStringLiteral( "repvalfcn:%1:%2" ).arg( layer ? layer->id() : QStringLiteral( "[None]" ), fieldName );

if ( !context->hasCachedValue( cacheKey ) )
{
cache = fieldFormatter->createCache( layer, fieldIndex, setup.config() );
context->setCachedValue( cacheKey, cache );
}
else
{
cache = context->cachedValue( cacheKey );
}
}
QString value( fieldFormatter->representValue( layer, fieldIndex, setup.config(), cache, attributeVal ) );

if ( setup.config().value( QStringLiteral( "AllowMulti" ), false ).toBool() && value.startsWith( QLatin1Char( '{' ) ) && value.endsWith( QLatin1Char( '}' ) ) )
{
value = value.mid( 1, value.size() - 2 );
}

result.insert( fields.at( fieldIndex ).name(), value );

if ( context )
{
context->setCachedValue( cacheValueKey, value );
}

}
result.insert( fields.at( idx ).name(), value );
}
return result;
}
Expand Down Expand Up @@ -7708,8 +7739,8 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
fcnAttributes, QStringLiteral( "Record and Attributes" ), QString(), false, QSet<QString>() << QgsFeatureRequest::ALL_ATTRIBUTES );
attributesFunc->setIsStatic( false );
functions << attributesFunc;
QgsStaticExpressionFunction *formattedAttributesFunc = new QgsStaticExpressionFunction( QStringLiteral( "formatted_attributes" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "feature" ), true ) << QgsExpressionFunction::Parameter( QStringLiteral( "layer" ), true ),
fcnFormattedAttributes, QStringLiteral( "Record and Attributes" ), QString(), false, QSet<QString>() << QgsFeatureRequest::ALL_ATTRIBUTES );
QgsStaticExpressionFunction *formattedAttributesFunc = new QgsStaticExpressionFunction( QStringLiteral( "represent_attributes" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "feature" ), true ) << QgsExpressionFunction::Parameter( QStringLiteral( "layer" ), true ),
fcnRepresentAttributes, QStringLiteral( "Record and Attributes" ), QString(), false, QSet<QString>() << QgsFeatureRequest::ALL_ATTRIBUTES );
formattedAttributesFunc->setIsStatic( false );
functions << formattedAttributesFunc;

Expand Down
5 changes: 5 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -516,6 +516,11 @@ class TestQgsExpression: public QObject
QCOMPARE( exp.dump(), dump );
}

void represent_attributes()
{

};

void represent_value()
{
QVariantMap config;
Expand Down

0 comments on commit f0a337c

Please sign in to comment.