From 8ee976fd48a7fa40ff5fb232895cbfe7ea89f7a9 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 17 Feb 2025 14:46:12 +1000 Subject: [PATCH] Fix data-defined overrides ignored in legend text format Fixes #60628 --- python/PyQt6/core/auto_generated/qgslegendsettings.sip.in | 8 ++++++++ python/PyQt6/core/auto_generated/qgslegendstyle.sip.in | 8 ++++++++ python/core/auto_generated/qgslegendsettings.sip.in | 8 ++++++++ python/core/auto_generated/qgslegendstyle.sip.in | 8 ++++++++ src/core/qgslegendrenderer.cpp | 2 ++ src/core/qgslegendsettings.cpp | 8 ++++++++ src/core/qgslegendsettings.h | 8 ++++++++ src/core/qgslegendstyle.cpp | 8 ++++++++ src/core/qgslegendstyle.h | 8 ++++++++ 9 files changed, 66 insertions(+) diff --git a/python/PyQt6/core/auto_generated/qgslegendsettings.sip.in b/python/PyQt6/core/auto_generated/qgslegendsettings.sip.in index bb6fce56c29c..a0cbd59f6c53 100644 --- a/python/PyQt6/core/auto_generated/qgslegendsettings.sip.in +++ b/python/PyQt6/core/auto_generated/qgslegendsettings.sip.in @@ -26,6 +26,14 @@ The content of the legend is driven by the :py:class:`QgsLegendModel` class. public: QgsLegendSettings(); + void updateDataDefinedProperties( QgsRenderContext &context ); +%Docstring +Updates any data-defined properties in the settings, using the specified +render ``context``. + +.. versionadded:: 3.42 +%End + void setTitle( const QString &t ); %Docstring Sets the title for the legend, which will be rendered above all legend items. diff --git a/python/PyQt6/core/auto_generated/qgslegendstyle.sip.in b/python/PyQt6/core/auto_generated/qgslegendstyle.sip.in index 3ae5cc4667b8..9dec540ae5f9 100644 --- a/python/PyQt6/core/auto_generated/qgslegendstyle.sip.in +++ b/python/PyQt6/core/auto_generated/qgslegendstyle.sip.in @@ -161,6 +161,14 @@ Writes the component's style definition to an XML element. Reads the component's style definition from an XML element. .. seealso:: :py:func:`writeXml` +%End + + void updateDataDefinedProperties( QgsRenderContext &context ); +%Docstring +Updates any data-defined properties in the style, using the specified +render ``context``. + +.. versionadded:: 3.42 %End static QString styleName( Style s ); diff --git a/python/core/auto_generated/qgslegendsettings.sip.in b/python/core/auto_generated/qgslegendsettings.sip.in index bb6fce56c29c..a0cbd59f6c53 100644 --- a/python/core/auto_generated/qgslegendsettings.sip.in +++ b/python/core/auto_generated/qgslegendsettings.sip.in @@ -26,6 +26,14 @@ The content of the legend is driven by the :py:class:`QgsLegendModel` class. public: QgsLegendSettings(); + void updateDataDefinedProperties( QgsRenderContext &context ); +%Docstring +Updates any data-defined properties in the settings, using the specified +render ``context``. + +.. versionadded:: 3.42 +%End + void setTitle( const QString &t ); %Docstring Sets the title for the legend, which will be rendered above all legend items. diff --git a/python/core/auto_generated/qgslegendstyle.sip.in b/python/core/auto_generated/qgslegendstyle.sip.in index 66fe22adb73e..6a92699aa9ea 100644 --- a/python/core/auto_generated/qgslegendstyle.sip.in +++ b/python/core/auto_generated/qgslegendstyle.sip.in @@ -161,6 +161,14 @@ Writes the component's style definition to an XML element. Reads the component's style definition from an XML element. .. seealso:: :py:func:`writeXml` +%End + + void updateDataDefinedProperties( QgsRenderContext &context ); +%Docstring +Updates any data-defined properties in the style, using the specified +render ``context``. + +.. versionadded:: 3.42 %End static QString styleName( Style s ); diff --git a/src/core/qgslegendrenderer.cpp b/src/core/qgslegendrenderer.cpp index f0701ea2910d..4f5d74ac7b1c 100644 --- a/src/core/qgslegendrenderer.cpp +++ b/src/core/qgslegendrenderer.cpp @@ -206,6 +206,8 @@ QSizeF QgsLegendRenderer::paintAndDetermineSize( QgsRenderContext &context ) if ( !rootGroup ) return size; + mSettings.updateDataDefinedProperties( context ); + // temporarily remove painter from context -- we don't need to actually draw anything yet. But we DO need // to send the full render context so that an expression context is available during the size calculation QgsScopedRenderContextPainterSwap noPainter( context, nullptr ); diff --git a/src/core/qgslegendsettings.cpp b/src/core/qgslegendsettings.cpp index 258ed06d91ca..85aca0a578c4 100644 --- a/src/core/qgslegendsettings.cpp +++ b/src/core/qgslegendsettings.cpp @@ -64,6 +64,14 @@ QgsLegendSettings::QgsLegendSettings() rstyle( QgsLegendStyle::SymbolLabel ).setTextFormat( f ); } +void QgsLegendSettings::updateDataDefinedProperties( QgsRenderContext &context ) +{ + rstyle( QgsLegendStyle::Title ).updateDataDefinedProperties( context ); + rstyle( QgsLegendStyle::Group ).updateDataDefinedProperties( context ); + rstyle( QgsLegendStyle::Subgroup ).updateDataDefinedProperties( context ); + rstyle( QgsLegendStyle::SymbolLabel ).updateDataDefinedProperties( context ); +} + QColor QgsLegendSettings::fontColor() const { return style( QgsLegendStyle::SymbolLabel ).textFormat().color(); diff --git a/src/core/qgslegendsettings.h b/src/core/qgslegendsettings.h index dec88dfe08eb..a516f73accd2 100644 --- a/src/core/qgslegendsettings.h +++ b/src/core/qgslegendsettings.h @@ -39,6 +39,14 @@ class CORE_EXPORT QgsLegendSettings public: QgsLegendSettings(); + /** + * Updates any data-defined properties in the settings, using the specified + * render \a context. + * + * \since QGIS 3.42 + */ + void updateDataDefinedProperties( QgsRenderContext &context ); + /** * Sets the title for the legend, which will be rendered above all legend items. * diff --git a/src/core/qgslegendstyle.cpp b/src/core/qgslegendstyle.cpp index 7c0391e23ae1..267a076c0a87 100644 --- a/src/core/qgslegendstyle.cpp +++ b/src/core/qgslegendstyle.cpp @@ -19,6 +19,7 @@ #include "qgsfontutils.h" #include "qgis.h" #include "qgsreadwritecontext.h" +#include "qgspropertycollection.h" #include #include @@ -110,6 +111,13 @@ void QgsLegendStyle::readXml( const QDomElement &elem, const QDomDocument &doc, mIndent = elem.attribute( QStringLiteral( "indent" ), QStringLiteral( "0" ) ).toDouble(); } +void QgsLegendStyle::updateDataDefinedProperties( QgsRenderContext &context ) +{ + if ( mTextFormat.dataDefinedProperties().hasActiveProperties() ) // note, we use format instead of tmpFormat here, it's const and potentially avoids a detach + mTextFormat.updateDataDefinedProperties( context ); + +} + QString QgsLegendStyle::styleName( Style s ) { switch ( s ) diff --git a/src/core/qgslegendstyle.h b/src/core/qgslegendstyle.h index 565fbd291e7c..8c3fe9cb5d78 100644 --- a/src/core/qgslegendstyle.h +++ b/src/core/qgslegendstyle.h @@ -165,6 +165,14 @@ class CORE_EXPORT QgsLegendStyle */ void readXml( const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context = QgsReadWriteContext() ); + /** + * Updates any data-defined properties in the style, using the specified + * render \a context. + * + * \since QGIS 3.42 + */ + void updateDataDefinedProperties( QgsRenderContext &context ); + /** * Returns the name for a style component as a string. *