Skip to content

Commit

Permalink
Merge pull request #58864 from rouault/fix_58861
Browse files Browse the repository at this point in the history
QgsJsonUtils: add a way to disable use of field formatters
  • Loading branch information
rouault authored Sep 26, 2024
2 parents 6a488de + dc1583b commit 8335dab
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 6 deletions.
18 changes: 18 additions & 0 deletions python/PyQt6/core/auto_generated/qgsjsonutils.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,24 @@ take precedence over attributes included via :py:func:`~QgsJsonExporter.attribut
.. seealso:: :py:func:`setExcludedAttributes`

.. seealso:: :py:func:`attributes`
%End

void setUseFieldFormatters( bool useFieldFormatters );
%Docstring
Sets whether field formatters (of type KeyValue, List, ValueRelation,
ValueMap) are used to export raw values as displayed
values. The default is true.

.. versionadded:: 3.40
%End

bool useFieldFormatters() const;
%Docstring
Returned whether field formatters (of type KeyValue, List, ValueRelation,
ValueMap) are used to export raw values as displayed
values.

.. versionadded:: 3.40
%End

QString exportFeature( const QgsFeature &feature,
Expand Down
18 changes: 18 additions & 0 deletions python/core/auto_generated/qgsjsonutils.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,24 @@ take precedence over attributes included via :py:func:`~QgsJsonExporter.attribut
.. seealso:: :py:func:`setExcludedAttributes`

.. seealso:: :py:func:`attributes`
%End

void setUseFieldFormatters( bool useFieldFormatters );
%Docstring
Sets whether field formatters (of type KeyValue, List, ValueRelation,
ValueMap) are used to export raw values as displayed
values. The default is true.

.. versionadded:: 3.40
%End

bool useFieldFormatters() const;
%Docstring
Returned whether field formatters (of type KeyValue, List, ValueRelation,
ValueMap) are used to export raw values as displayed
values.

.. versionadded:: 3.40
%End

QString exportFeature( const QgsFeature &feature,
Expand Down
8 changes: 4 additions & 4 deletions src/core/qgsjsonutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ json QgsJsonExporter::exportFeatureToJsonObject( const QgsFeature &feature, cons

QVariant val = feature.attributes().at( i );

if ( mLayer )
if ( mUseFieldFormatters && mLayer )
{
const QgsEditorWidgetSetup setup = fields.at( i ).editorWidgetSetup();
const QgsFieldFormatter *fieldFormatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
Expand Down Expand Up @@ -222,7 +222,7 @@ json QgsJsonExporter::exportFeatureToJsonObject( const QgsFeature &feature, cons
QgsFeature relatedFet;
while ( it.nextFeature( relatedFet ) )
{
relatedFeatureAttributes += QgsJsonUtils::exportAttributesToJsonObject( relatedFet, childLayer, attributeWidgetCaches );
relatedFeatureAttributes += QgsJsonUtils::exportAttributesToJsonObject( relatedFet, childLayer, attributeWidgetCaches, mUseFieldFormatters );
}
}
properties[ relation.name().toStdString() ] = relatedFeatureAttributes;
Expand Down Expand Up @@ -901,15 +901,15 @@ QVariant QgsJsonUtils::parseJson( const QString &jsonString )
return parseJson( jsonString.toStdString() );
}

json QgsJsonUtils::exportAttributesToJsonObject( const QgsFeature &feature, QgsVectorLayer *layer, const QVector<QVariant> &attributeWidgetCaches )
json QgsJsonUtils::exportAttributesToJsonObject( const QgsFeature &feature, QgsVectorLayer *layer, const QVector<QVariant> &attributeWidgetCaches, bool useFieldFormatters )
{
QgsFields fields = feature.fields();
json attrs;
for ( int i = 0; i < fields.count(); ++i )
{
QVariant val = feature.attributes().at( i );

if ( layer )
if ( layer && useFieldFormatters )
{
QgsEditorWidgetSetup setup = layer->fields().at( i ).editorWidgetSetup();
QgsFieldFormatter *fieldFormatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
Expand Down
21 changes: 20 additions & 1 deletion src/core/qgsjsonutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,22 @@ class CORE_EXPORT QgsJsonExporter
*/
QgsAttributeList excludedAttributes() const { return mExcludedAttributeIndexes; }

/**
* Sets whether field formatters (of type KeyValue, List, ValueRelation,
* ValueMap) are used to export raw values as displayed
* values. The default is true.
* \since QGIS 3.40
*/
void setUseFieldFormatters( bool useFieldFormatters ) { mUseFieldFormatters = useFieldFormatters; }

/**
* Returned whether field formatters (of type KeyValue, List, ValueRelation,
* ValueMap) are used to export raw values as displayed
* values.
* \since QGIS 3.40
*/
bool useFieldFormatters() const { return mUseFieldFormatters; }

/**
* Returns a GeoJSON string representation of a feature.
* \param feature feature to convert
Expand Down Expand Up @@ -291,6 +307,8 @@ class CORE_EXPORT QgsJsonExporter
bool mTransformGeometries = true;

QgsCoordinateReferenceSystem mDestinationCrs;

bool mUseFieldFormatters = true;
};

/**
Expand Down Expand Up @@ -350,11 +368,12 @@ class CORE_EXPORT QgsJsonUtils
* richer export utilising settings like the layer's fields widget configuration.
* \param attributeWidgetCaches optional widget configuration cache. Can be used
* to speed up exporting the attributes for multiple features from the same layer.
* \param useFieldFormatters Whether field formatters should be used (since QGIS 3.40)
* \note Not available in Python bindings
* \since QGIS 3.8
*/
static json exportAttributesToJsonObject( const QgsFeature &feature, QgsVectorLayer *layer = nullptr,
const QVector<QVariant> &attributeWidgetCaches = QVector<QVariant>() ) SIP_SKIP;
const QVector<QVariant> &attributeWidgetCaches = QVector<QVariant>(), bool useFieldFormatters = true ) SIP_SKIP;

/**
* Parse a simple array (depth=1)
Expand Down
33 changes: 32 additions & 1 deletion tests/src/python/test_qgsjsonutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -726,11 +726,12 @@ def testExportFeatureRelations(self):
# with field formatter
setup = QgsEditorWidgetSetup('ValueMap', {"map": {"apples": 123, "bananas": 124}})
child.setEditorWidgetSetup(1, setup)
parent.setEditorWidgetSetup(1, QgsEditorWidgetSetup('ValueMap', {"map": {"sixty-seven": 67}}))
expected = """{
"geometry": null,
"id": 432,
"properties": {
"fldint": 67,
"fldint": "sixty-seven",
"fldtxt": "test1",
"foreignkey": 123,
"relation one": [
Expand All @@ -750,6 +751,36 @@ def testExportFeatureRelations(self):
}"""
self.assertEqual(exporter.exportFeature(pf1, indent=2), expected)

# Use raw values
self.assertTrue(exporter.useFieldFormatters())
exporter.setUseFieldFormatters(False)
self.assertFalse(exporter.useFieldFormatters())
expected = """{
"geometry": null,
"id": 432,
"properties": {
"fldint": 67,
"fldtxt": "test1",
"foreignkey": 123,
"relation one": [
{
"x": "foo",
"y": 123,
"z": 321
},
{
"x": "bar",
"y": 123,
"z": 654
}
]
},
"type": "Feature"
}"""
self.assertEqual(exporter.exportFeature(pf1, indent=2), expected)
exporter.setUseFieldFormatters(True)
parent.setEditorWidgetSetup(1, QgsEditorWidgetSetup())

# test excluding related attributes
exporter.setIncludeRelated(False)
self.assertEqual(exporter.includeRelated(), False)
Expand Down

0 comments on commit 8335dab

Please sign in to comment.