Skip to content

Commit

Permalink
Safer approach to saving common QgsFeatureRenderer properties
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 28, 2021
1 parent 54610b2 commit c8da0c4
Show file tree
Hide file tree
Showing 15 changed files with 58 additions and 122 deletions.
15 changes: 14 additions & 1 deletion python/core/auto_generated/symbology/qgsrenderer.sip.in
Expand Up @@ -259,7 +259,10 @@ create a renderer from XML element

virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context );
%Docstring
store renderer info to XML element
Stores renderer properties to an XML element.

Subclasses which override this method should call :py:func:`~QgsFeatureRenderer.saveRendererData` as part of their
implementation in order to store all common base class properties in the returned DOM element.
%End

virtual QDomElement writeSld( QDomDocument &doc, const QString &styleName, const QVariantMap &props = QVariantMap() ) const;
Expand Down Expand Up @@ -544,6 +547,16 @@ Currently clones
:param destRenderer: destination renderer for copied effect
%End

void saveRendererData( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context );
%Docstring
Saves generic renderer data into the specified ``element``.

This method should be called in a subclass' :py:func:`~QgsFeatureRenderer.save` implementation in order
to store all common base class properties in the DOM ``element``.

.. versionadded:: 3.22
%End




Expand Down
2 changes: 2 additions & 0 deletions src/core/symbology/qgs25drenderer.cpp
Expand Up @@ -122,6 +122,8 @@ QDomElement Qgs25DRenderer::save( QDomDocument &doc, const QgsReadWriteContext &

QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "symbol" ), mSymbol.get(), doc, context );

saveRendererData( doc, rendererElem, context );

rendererElem.appendChild( symbolElem );

return rendererElem;
Expand Down
16 changes: 2 additions & 14 deletions src/core/symbology/qgscategorizedsymbolrenderer.cpp
Expand Up @@ -776,8 +776,6 @@ QDomElement QgsCategorizedSymbolRenderer::save( QDomDocument &doc, const QgsRead
// clazy:skip
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "categorizedSymbol" ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "attr" ), mAttrName );

// categories
Expand Down Expand Up @@ -819,7 +817,6 @@ QDomElement QgsCategorizedSymbolRenderer::save( QDomDocument &doc, const QgsRead
// save symbols
QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
rendererElem.appendChild( symbolsElem );

}

// save source symbol
Expand All @@ -844,24 +841,15 @@ QDomElement QgsCategorizedSymbolRenderer::save( QDomDocument &doc, const QgsRead
QDomElement sizeScaleElem = doc.createElement( QStringLiteral( "sizescale" ) );
rendererElem.appendChild( sizeScaleElem );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mDataDefinedSizeLegend )
{
QDomElement ddsLegendElem = doc.createElement( QStringLiteral( "data-defined-size-legend" ) );
mDataDefinedSizeLegend->writeXml( ddsLegendElem, context );
rendererElem.appendChild( ddsLegendElem );
}

saveRendererData( doc, rendererElem, context );

return rendererElem;
}

Expand Down
13 changes: 1 addition & 12 deletions src/core/symbology/qgsembeddedsymbolrenderer.cpp
Expand Up @@ -137,24 +137,13 @@ QDomElement QgsEmbeddedSymbolRenderer::save( QDomDocument &doc, const QgsReadWri
{
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "embeddedSymbol" ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

QgsSymbolMap symbols;
symbols[QStringLiteral( "0" )] = mDefaultSymbol.get();
QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
rendererElem.appendChild( symbolsElem );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
Expand Down
15 changes: 2 additions & 13 deletions src/core/symbology/qgsgraduatedsymbolrenderer.cpp
Expand Up @@ -627,8 +627,6 @@ QDomElement QgsGraduatedSymbolRenderer::save( QDomDocument &doc, const QgsReadWr
{
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "graduatedSymbol" ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "attr" ), mAttrName );
rendererElem.setAttribute( QStringLiteral( "graduatedMethod" ), graduatedMethodStr( mGraduatedMethod ) );

Expand Down Expand Up @@ -685,24 +683,15 @@ QDomElement QgsGraduatedSymbolRenderer::save( QDomDocument &doc, const QgsReadWr
QDomElement sizeScaleElem = doc.createElement( QStringLiteral( "sizescale" ) );
rendererElem.appendChild( sizeScaleElem );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mDataDefinedSizeLegend )
{
QDomElement ddsLegendElem = doc.createElement( QStringLiteral( "data-defined-size-legend" ) );
mDataDefinedSizeLegend->writeXml( ddsLegendElem, context );
rendererElem.appendChild( ddsLegendElem );
}

saveRendererData( doc, rendererElem, context );

return rendererElem;
}

Expand Down
13 changes: 2 additions & 11 deletions src/core/symbology/qgsheatmaprenderer.cpp
Expand Up @@ -335,23 +335,14 @@ QDomElement QgsHeatmapRenderer::save( QDomDocument &doc, const QgsReadWriteConte
rendererElem.setAttribute( QStringLiteral( "max_value" ), QString::number( mExplicitMax ) );
rendererElem.setAttribute( QStringLiteral( "quality" ), QString::number( mRenderQuality ) );
rendererElem.setAttribute( QStringLiteral( "weight_expression" ), mWeightExpressionString );

if ( mGradientRamp )
{
QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( QStringLiteral( "[source]" ), mGradientRamp, doc );
rendererElem.appendChild( colorRampElem );
}
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
Expand Down
12 changes: 1 addition & 11 deletions src/core/symbology/qgsinvertedpolygonrenderer.cpp
Expand Up @@ -86,24 +86,14 @@ QDomElement QgsInvertedPolygonRenderer::save( QDomDocument &doc, const QgsReadWr
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "invertedPolygonRenderer" ) );
rendererElem.setAttribute( QStringLiteral( "preprocessing" ), preprocessingEnabled() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mSubRenderer )
{
QDomElement embeddedRendererElem = mSubRenderer->save( doc, context );
rendererElem.appendChild( embeddedRendererElem );
}

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
Expand Down
12 changes: 1 addition & 11 deletions src/core/symbology/qgsmergedfeaturerenderer.cpp
Expand Up @@ -442,24 +442,14 @@ QDomElement QgsMergedFeatureRenderer::save( QDomDocument &doc, const QgsReadWrit

QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "mergedFeatureRenderer" ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mSubRenderer )
{
QDomElement embeddedRendererElem = mSubRenderer->save( doc, context );
rendererElem.appendChild( embeddedRendererElem );
}

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
Expand Down
3 changes: 3 additions & 0 deletions src/core/symbology/qgsnullsymbolrenderer.cpp
Expand Up @@ -112,6 +112,9 @@ QDomElement QgsNullSymbolRenderer::save( QDomDocument &doc, const QgsReadWriteCo
Q_UNUSED( context )
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "nullSymbol" ) );

saveRendererData( doc, rendererElem, context );

return rendererElem;
}

Expand Down
12 changes: 1 addition & 11 deletions src/core/symbology/qgspointclusterrenderer.cpp
Expand Up @@ -127,7 +127,6 @@ QgsMarkerSymbol *QgsPointClusterRenderer::clusterSymbol()
QDomElement QgsPointClusterRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
{
QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
rendererElement.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "pointCluster" ) );
rendererElement.setAttribute( QStringLiteral( "tolerance" ), QString::number( mTolerance ) );
rendererElement.setAttribute( QStringLiteral( "toleranceUnit" ), QgsUnitTypes::encodeUnit( mToleranceUnit ) );
Expand All @@ -144,16 +143,7 @@ QDomElement QgsPointClusterRenderer::save( QDomDocument &doc, const QgsReadWrite
rendererElement.appendChild( centerSymbolElem );
}

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElement );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElement.appendChild( orderBy );
}
rendererElement.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElement, context );

return rendererElement;
}
Expand Down
12 changes: 1 addition & 11 deletions src/core/symbology/qgspointdisplacementrenderer.cpp
Expand Up @@ -194,7 +194,6 @@ QgsMarkerSymbol *QgsPointDisplacementRenderer::centerSymbol()
QDomElement QgsPointDisplacementRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
{
QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
rendererElement.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "pointDisplacement" ) );
rendererElement.setAttribute( QStringLiteral( "labelAttributeName" ), mLabelAttributeName );
rendererElement.appendChild( QgsFontUtils::toXmlElement( mLabelFont, doc, QStringLiteral( "labelFontProperties" ) ) );
Expand All @@ -220,16 +219,7 @@ QDomElement QgsPointDisplacementRenderer::save( QDomDocument &doc, const QgsRead
rendererElement.appendChild( centerSymbolElem );
}

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElement );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElement.appendChild( orderBy );
}
rendererElement.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElement, context );

return rendererElement;
}
Expand Down
10 changes: 9 additions & 1 deletion src/core/symbology/qgsrenderer.cpp
Expand Up @@ -192,7 +192,16 @@ QDomElement QgsFeatureRenderer::save( QDomDocument &doc, const QgsReadWriteConte
Q_UNUSED( context )
// create empty renderer element
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );

saveRendererData( doc, rendererElem, context );

return rendererElem;
}

void QgsFeatureRenderer::saveRendererData( QDomDocument &doc, QDomElement &rendererElem, const QgsReadWriteContext & )
{
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );
Expand All @@ -204,7 +213,6 @@ QDomElement QgsFeatureRenderer::save( QDomDocument &doc, const QgsReadWriteConte
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
return rendererElem;
}

QgsFeatureRenderer *QgsFeatureRenderer::loadSld( const QDomNode &node, QgsWkbTypes::GeometryType geomType, QString &errorMessage )
Expand Down
17 changes: 16 additions & 1 deletion src/core/symbology/qgsrenderer.h
Expand Up @@ -294,7 +294,12 @@ class CORE_EXPORT QgsFeatureRenderer
//! create a renderer from XML element
static QgsFeatureRenderer *load( QDomElement &symbologyElem, const QgsReadWriteContext &context ) SIP_FACTORY;

//! store renderer info to XML element
/**
* Stores renderer properties to an XML element.
*
* Subclasses which override this method should call saveRendererData() as part of their
* implementation in order to store all common base class properties in the returned DOM element.
*/
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context );

/**
Expand Down Expand Up @@ -525,6 +530,16 @@ class CORE_EXPORT QgsFeatureRenderer
*/
void copyRendererData( QgsFeatureRenderer *destRenderer ) const;

/**
* Saves generic renderer data into the specified \a element.
*
* This method should be called in a subclass' save() implementation in order
* to store all common base class properties in the DOM \a element.
*
* \since QGIS 3.22
*/
void saveRendererData( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context );

QString mType;

bool mUsingSymbolLevels = false;
Expand Down
13 changes: 1 addition & 12 deletions src/core/symbology/qgsrulebasedrenderer.cpp
Expand Up @@ -1080,8 +1080,6 @@ QDomElement QgsRuleBasedRenderer::save( QDomDocument &doc, const QgsReadWriteCon
{
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "RuleRenderer" ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

QgsSymbolMap symbols;

Expand All @@ -1092,16 +1090,7 @@ QDomElement QgsRuleBasedRenderer::save( QDomDocument &doc, const QgsReadWriteCon
QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
rendererElem.appendChild( symbolsElem );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
Expand Down

0 comments on commit c8da0c4

Please sign in to comment.