Skip to content

Commit

Permalink
Add a flag which can be set on QgsSymbols to indicate that a renderer
Browse files Browse the repository at this point in the history
should use symbol levels whenever that symbol is used by the renderer

Not exposed to users -- only settable via API, but IS saved in the
symbol's XML definition and restored when loading a symbol from XML.
  • Loading branch information
nyalldawson committed May 26, 2021
1 parent 92639ae commit 86b3459
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 0 deletions.
4 changes: 4 additions & 0 deletions python/core/auto_additions/qgis.py
Expand Up @@ -53,6 +53,10 @@
QgsSymbol.DynamicRotation.__doc__ = "Rotation of symbol may be changed during rendering and symbol should not be cached"
Qgis.SymbolRenderHint.__doc__ = 'Flags controlling behavior of symbols during rendering\n\n.. versionadded:: 3.20\n\n' + '* ``DynamicRotation``: ' + Qgis.SymbolRenderHint.DynamicRotation.__doc__
# --
# monkey patching scoped based enum
Qgis.SymbolFlag.RendererShouldUseSymbolLevels.__doc__ = "If present, indicates that a QgsFeatureRenderer using the symbol should use symbol levels for best results"
Qgis.SymbolFlag.__doc__ = 'Flags controlling behavior of symbols\n\n.. versionadded:: 3.20\n\n' + '* ``RendererShouldUseSymbolLevels``: ' + Qgis.SymbolFlag.RendererShouldUseSymbolLevels.__doc__
# --
QgsSymbol.PreviewFlag = Qgis.SymbolPreviewFlag
# monkey patching scoped based enum
QgsSymbol.FlagIncludeCrosshairsForMarkerSymbols = Qgis.SymbolPreviewFlag.FlagIncludeCrosshairsForMarkerSymbols
Expand Down
9 changes: 9 additions & 0 deletions python/core/auto_generated/qgis.sip.in
Expand Up @@ -138,6 +138,13 @@ The development version
typedef QFlags<Qgis::SymbolRenderHint> SymbolRenderHints;


enum class SymbolFlag
{
RendererShouldUseSymbolLevels,
};
typedef QFlags<Qgis::SymbolFlag> SymbolFlags;


enum class SymbolPreviewFlag
{
FlagIncludeCrosshairsForMarkerSymbols,
Expand Down Expand Up @@ -245,6 +252,8 @@ GEOS string version linked

QFlags<Qgis::SymbolRenderHint> operator|(Qgis::SymbolRenderHint f1, QFlags<Qgis::SymbolRenderHint> f2);

QFlags<Qgis::SymbolFlag> operator|(Qgis::SymbolFlag f1, QFlags<Qgis::SymbolFlag> f2);

QFlags<Qgis::SymbolPreviewFlag> operator|(Qgis::SymbolPreviewFlag f1, QFlags<Qgis::SymbolPreviewFlag> f2);


Expand Down
20 changes: 20 additions & 0 deletions python/core/auto_generated/symbology/qgssymbol.sip.in
Expand Up @@ -437,6 +437,24 @@ Sets rendering hint flags for the symbol.
Returns the rendering hint flags for the symbol.

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

void setFlags( Qgis::SymbolFlags flags );
%Docstring
Sets ``flags`` for the symbol.

.. seealso:: :py:func:`flags`

.. versionadded:: 3.320
%End

Qgis::SymbolFlags flags() const;
%Docstring
Returns flags for the symbol.

.. seealso:: :py:func:`setFlags`

.. versionadded:: 3.20
%End

void setClipFeaturesToExtent( bool clipFeaturesToExtent );
Expand Down Expand Up @@ -668,6 +686,8 @@ Render editing vertex marker at specified point





private:
QgsSymbol( const QgsSymbol & );
};
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgis.h
Expand Up @@ -192,6 +192,17 @@ class CORE_EXPORT Qgis
};
Q_DECLARE_FLAGS( SymbolRenderHints, SymbolRenderHint )

/**
* \brief Flags controlling behavior of symbols
*
* \since QGIS 3.20
*/
enum class SymbolFlag : int
{
RendererShouldUseSymbolLevels = 1 << 0, //!< If present, indicates that a QgsFeatureRenderer using the symbol should use symbol levels for best results
};
Q_DECLARE_FLAGS( SymbolFlags, SymbolFlag )

/**
* Flags for controlling how symbol preview images are generated.
*
Expand Down Expand Up @@ -366,6 +377,7 @@ class CORE_EXPORT Qgis
};

Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::SymbolRenderHints )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::SymbolFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::SymbolPreviewFlags )


Expand Down
1 change: 1 addition & 0 deletions src/core/symbology/qgsfillsymbol.cpp
Expand Up @@ -150,6 +150,7 @@ QgsFillSymbol *QgsFillSymbol::clone() const
cloneSymbol->setClipFeaturesToExtent( mClipFeaturesToExtent );
cloneSymbol->setForceRHR( mForceRHR );
cloneSymbol->setDataDefinedProperties( dataDefinedProperties() );
cloneSymbol->setFlags( mSymbolFlags );
return cloneSymbol;
}

Expand Down
1 change: 1 addition & 0 deletions src/core/symbology/qgslinesymbol.cpp
Expand Up @@ -281,5 +281,6 @@ QgsLineSymbol *QgsLineSymbol::clone() const
cloneSymbol->setClipFeaturesToExtent( mClipFeaturesToExtent );
cloneSymbol->setForceRHR( mForceRHR );
cloneSymbol->setDataDefinedProperties( dataDefinedProperties() );
cloneSymbol->setFlags( mSymbolFlags );
return cloneSymbol;
}
1 change: 1 addition & 0 deletions src/core/symbology/qgsmarkersymbol.cpp
Expand Up @@ -484,6 +484,7 @@ QgsMarkerSymbol *QgsMarkerSymbol::clone() const
cloneSymbol->setClipFeaturesToExtent( mClipFeaturesToExtent );
cloneSymbol->setForceRHR( mForceRHR );
cloneSymbol->setDataDefinedProperties( dataDefinedProperties() );
cloneSymbol->setFlags( mSymbolFlags );
return cloneSymbol;
}

24 changes: 24 additions & 0 deletions src/core/symbology/qgssymbol.h
Expand Up @@ -447,6 +447,22 @@ class CORE_EXPORT QgsSymbol
*/
Qgis::SymbolRenderHints renderHints() const { return mRenderHints; }

/**
* Sets \a flags for the symbol.
*
* \see flags()
* \since QGIS 3.320
*/
void setFlags( Qgis::SymbolFlags flags ) { mSymbolFlags = flags; }

/**
* Returns flags for the symbol.
*
* \see setFlags()
* \since QGIS 3.20
*/
Qgis::SymbolFlags flags() const { return mSymbolFlags; }

/**
* Sets whether features drawn by the symbol should be clipped to the render context's
* extent. If this option is enabled then features which are partially outside the extent
Expand Down Expand Up @@ -680,6 +696,14 @@ class CORE_EXPORT QgsSymbol
qreal mOpacity = 1.0;

Qgis::SymbolRenderHints mRenderHints;

/**
* Symbol flags.
*
* \since QGIS 3.20
*/
Qgis::SymbolFlags mSymbolFlags = Qgis::SymbolFlags();

bool mClipFeaturesToExtent = true;
bool mForceRHR = false;

Expand Down
7 changes: 7 additions & 0 deletions src/core/symbology/qgssymbollayerutils.cpp
Expand Up @@ -1148,6 +1148,10 @@ QgsSymbol *QgsSymbolLayerUtils::loadSymbol( const QDomElement &element, const Qg
symbol->setOpacity( element.attribute( QStringLiteral( "alpha" ), QStringLiteral( "1.0" ) ).toDouble() );
symbol->setClipFeaturesToExtent( element.attribute( QStringLiteral( "clip_to_extent" ), QStringLiteral( "1" ) ).toInt() );
symbol->setForceRHR( element.attribute( QStringLiteral( "force_rhr" ), QStringLiteral( "0" ) ).toInt() );
Qgis::SymbolFlags flags;
if ( element.attribute( QStringLiteral( "renderer_should_use_levels" ), QStringLiteral( "0" ) ).toInt() )
flags |= Qgis::SymbolFlag::RendererShouldUseSymbolLevels;
symbol->setFlags( flags );

QDomElement ddProps = element.firstChildElement( QStringLiteral( "data_defined_properties" ) );
if ( !ddProps.isNull() )
Expand Down Expand Up @@ -1230,6 +1234,9 @@ QDomElement QgsSymbolLayerUtils::saveSymbol( const QString &name, const QgsSymbo
symEl.setAttribute( QStringLiteral( "alpha" ), QString::number( symbol->opacity() ) );
symEl.setAttribute( QStringLiteral( "clip_to_extent" ), symbol->clipFeaturesToExtent() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
symEl.setAttribute( QStringLiteral( "force_rhr" ), symbol->forceRHR() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
if ( symbol->flags() & Qgis::SymbolFlag::RendererShouldUseSymbolLevels )
symEl.setAttribute( QStringLiteral( "renderer_should_use_levels" ), QStringLiteral( "1" ) );

//QgsDebugMsg( "num layers " + QString::number( symbol->symbolLayerCount() ) );

QDomElement ddProps = doc.createElement( QStringLiteral( "data_defined_properties" ) );
Expand Down
10 changes: 10 additions & 0 deletions src/gui/symbology/qgssinglesymbolrendererwidget.cpp
Expand Up @@ -112,6 +112,12 @@ void QgsSingleSymbolRendererWidget::disableSymbolLevels()
void QgsSingleSymbolRendererWidget::setSymbolLevels( const QList<QgsLegendSymbolItem> &levels, bool enabled )
{
mSingleSymbol.reset( levels.at( 0 ).symbol()->clone() );
if ( !enabled )
{
// remove the renderer symbol levels flag (if present), as we don't symbol levels automatically re-enabling when other changes
// are made to the symbol
mSingleSymbol->setFlags( mSingleSymbol->flags() & ~Qgis::SymbolFlags( Qgis::SymbolFlag::RendererShouldUseSymbolLevels ) );
}
mRenderer->setSymbol( mSingleSymbol->clone() );
mRenderer->setUsingSymbolLevels( enabled );
mSelector->loadSymbol( mSingleSymbol.get() );
Expand All @@ -122,6 +128,10 @@ void QgsSingleSymbolRendererWidget::changeSingleSymbol()
{
// update symbol from the GUI
mRenderer->setSymbol( mSingleSymbol->clone() );

if ( mSingleSymbol->flags() & Qgis::SymbolFlag::RendererShouldUseSymbolLevels )
mRenderer->setUsingSymbolLevels( true );

emit widgetChanged();
}

Expand Down
1 change: 1 addition & 0 deletions src/gui/symbology/qgssymbolslistwidget.cpp
Expand Up @@ -581,6 +581,7 @@ void QgsSymbolsListWidget::setSymbolFromStyle( const QString &name, QgsStyle::St
mSymbol->appendSymbolLayer( sl );
}
mSymbol->setOpacity( s->opacity() );
mSymbol->setFlags( s->flags() );

updateSymbolInfo();
emit changed();
Expand Down

0 comments on commit 86b3459

Please sign in to comment.