diff --git a/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in b/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in index 1dbef61333c5..2fe08e7ad589 100644 --- a/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in +++ b/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in @@ -338,7 +338,7 @@ Draws a symbol layer preview to a QPicture .. versionadded:: 2.9 %End - static QIcon symbolLayerPreviewIcon( const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale = QgsMapUnitScale(), Qgis::SymbolType parentSymbolType = Qgis::SymbolType::Hybrid ); + static QIcon symbolLayerPreviewIcon( const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale = QgsMapUnitScale(), Qgis::SymbolType parentSymbolType = Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer = 0 ); %Docstring Draws a symbol layer preview to an icon. @@ -347,6 +347,7 @@ Draws a symbol layer preview to an icon. :param size: target size of preview icon :param scale: map unit scale for preview :param parentSymbolType: since QGIS 3.22, can be used to specify the parent symbol type so that geometry generator preview icons are correctly calculated +:param mapLayer: since QGIS 3.28, can be used to specify the associated map layer so that layer related expressions are correctly calculated :return: icon containing symbol layer preview diff --git a/src/core/layertree/qgslayertreemodellegendnode.cpp b/src/core/layertree/qgslayertreemodellegendnode.cpp index cb29bb8197ea..90afd4dbe663 100644 --- a/src/core/layertree/qgslayertreemodellegendnode.cpp +++ b/src/core/layertree/qgslayertreemodellegendnode.cpp @@ -467,6 +467,11 @@ QgsRenderContext *QgsLayerTreeModelLegendNode::createTemporaryRenderContext() co context->setMapToPixel( QgsMapToPixel( mupp ) ); context->setFlag( Qgis::RenderContextFlag::Antialiasing, true ); context->setFlag( Qgis::RenderContextFlag::RenderSymbolPreview, true ); + + QgsExpressionContext expContext; + expContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( mLayerNode ? mLayerNode->layer() : nullptr ) ); + context->setExpressionContext( expContext ); + return context.release(); } diff --git a/src/core/symbology/qgssymbollayerutils.cpp b/src/core/symbology/qgssymbollayerutils.cpp index f92c0774a5b1..6af9075f1a75 100644 --- a/src/core/symbology/qgssymbollayerutils.cpp +++ b/src/core/symbology/qgssymbollayerutils.cpp @@ -980,7 +980,7 @@ QPicture QgsSymbolLayerUtils::symbolLayerPreviewPicture( const QgsSymbolLayer *l return picture; } -QIcon QgsSymbolLayerUtils::symbolLayerPreviewIcon( const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &, Qgis::SymbolType parentSymbolType ) +QIcon QgsSymbolLayerUtils::symbolLayerPreviewIcon( const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &, Qgis::SymbolType parentSymbolType, QgsMapLayer *mapLayer ) { QPixmap pixmap( size ); pixmap.fill( Qt::transparent ); @@ -992,7 +992,7 @@ QIcon QgsSymbolLayerUtils::symbolLayerPreviewIcon( const QgsSymbolLayer *layer, renderContext.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms ); // build a minimal expression context QgsExpressionContext expContext; - expContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( nullptr ) ); + expContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( mapLayer ) ); renderContext.setExpressionContext( expContext ); QgsSymbolRenderContext symbolContext( renderContext, u, 1.0, false, Qgis::SymbolRenderHints(), nullptr ); diff --git a/src/core/symbology/qgssymbollayerutils.h b/src/core/symbology/qgssymbollayerutils.h index 31372ebcc60f..36cb36855a81 100644 --- a/src/core/symbology/qgssymbollayerutils.h +++ b/src/core/symbology/qgssymbollayerutils.h @@ -323,10 +323,11 @@ class CORE_EXPORT QgsSymbolLayerUtils * \param size target size of preview icon * \param scale map unit scale for preview * \param parentSymbolType since QGIS 3.22, can be used to specify the parent symbol type so that geometry generator preview icons are correctly calculated + * \param mapLayer since QGIS 3.28, can be used to specify the associated map layer so that layer related expressions are correctly calculated * \returns icon containing symbol layer preview * \see symbolLayerPreviewPicture() */ - static QIcon symbolLayerPreviewIcon( const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale = QgsMapUnitScale(), Qgis::SymbolType parentSymbolType = Qgis::SymbolType::Hybrid ); + static QIcon symbolLayerPreviewIcon( const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale = QgsMapUnitScale(), Qgis::SymbolType parentSymbolType = Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer = nullptr ); /** * Returns an icon preview for a color ramp. diff --git a/src/gui/symbology/qgssymbolselectordialog.cpp b/src/gui/symbology/qgssymbolselectordialog.cpp index 025eac73daf3..bc51d7036f45 100644 --- a/src/gui/symbology/qgssymbolselectordialog.cpp +++ b/src/gui/symbology/qgssymbolselectordialog.cpp @@ -25,14 +25,7 @@ // the widgets #include "qgssymbolslistwidget.h" #include "qgslayerpropertieswidget.h" -#include "qgssymbollayerwidget.h" -#include "qgsellipsesymbollayerwidget.h" -#include "qgsvectorfieldsymbollayerwidget.h" - -#include "qgslogger.h" #include "qgsapplication.h" -#include "qgssettings.h" -#include "qgsfeatureiterator.h" #include "qgsvectorlayer.h" #include "qgssvgcache.h" #include "qgsimagecache.h" @@ -40,7 +33,6 @@ #include "qgsguiutils.h" #include "qgsgui.h" #include "qgsmarkersymbol.h" -#include "qgsfillsymbol.h" #include "qgslinesymbol.h" #include @@ -125,12 +117,14 @@ void DataDefinedRestorer::restore() class SymbolLayerItem : public QStandardItem { public: - explicit SymbolLayerItem( QgsSymbolLayer *layer, Qgis::SymbolType symbolType ) + explicit SymbolLayerItem( QgsSymbolLayer *layer, Qgis::SymbolType symbolType, QgsVectorLayer *vectorLayer ) + : mVectorLayer( vectorLayer ) { setLayer( layer, symbolType ); } - explicit SymbolLayerItem( QgsSymbol *symbol ) + explicit SymbolLayerItem( QgsSymbol *symbol, QgsVectorLayer *vectorLayer ) + : mVectorLayer( vectorLayer ) { setSymbol( symbol ); } @@ -161,9 +155,13 @@ class SymbolLayerItem : public QStandardItem } QIcon icon; if ( mIsLayer ) - icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( mLayer, QgsUnitTypes::RenderMillimeters, mSize, QgsMapUnitScale(), mSymbol ? mSymbol->type() : mSymbolType ); //todo: make unit a parameter + icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( mLayer, QgsUnitTypes::RenderMillimeters, mSize, QgsMapUnitScale(), mSymbol ? mSymbol->type() : mSymbolType, mVectorLayer ); //todo: make unit a parameter else - icon = QgsSymbolLayerUtils::symbolPreviewIcon( mSymbol, mSize ); + { + QgsExpressionContext expContext; + expContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( mVectorLayer ) ); + icon = QIcon( QgsSymbolLayerUtils::symbolPreviewPixmap( mSymbol, mSize, 0, nullptr, false, &expContext, nullptr ) ); + } setIcon( icon ); if ( auto *lParent = parent() ) @@ -236,7 +234,8 @@ class SymbolLayerItem : public QStandardItem protected: QgsSymbolLayer *mLayer = nullptr; QgsSymbol *mSymbol = nullptr; - bool mIsLayer; + QPointer< QgsVectorLayer > mVectorLayer; + bool mIsLayer = false; QSize mSize; Qgis::SymbolType mSymbolType = Qgis::SymbolType::Hybrid; }; @@ -392,7 +391,7 @@ void QgsSymbolSelectorWidget::loadSymbol( QgsSymbol *symbol, SymbolLayerItem *pa parent = static_cast( mSymbolLayersModel->invisibleRootItem() ); } - SymbolLayerItem *symbolItem = new SymbolLayerItem( symbol ); + SymbolLayerItem *symbolItem = new SymbolLayerItem( symbol, mVectorLayer ); QFont boldFont = symbolItem->font(); boldFont.setBold( true ); symbolItem->setFont( boldFont ); @@ -401,7 +400,7 @@ void QgsSymbolSelectorWidget::loadSymbol( QgsSymbol *symbol, SymbolLayerItem *pa const int count = symbol->symbolLayerCount(); for ( int i = count - 1; i >= 0; i-- ) { - SymbolLayerItem *layerItem = new SymbolLayerItem( symbol->symbolLayer( i ), symbol->type() ); + SymbolLayerItem *layerItem = new SymbolLayerItem( symbol->symbolLayer( i ), symbol->type(), mVectorLayer ); layerItem->setEditable( false ); symbolItem->appendRow( layerItem ); if ( symbol->symbolLayer( i )->subSymbol() ) @@ -628,7 +627,7 @@ void QgsSymbolSelectorWidget::addLayer() if ( ddWidth ) static_cast( parentSymbol )->setDataDefinedWidth( ddWidth ); - SymbolLayerItem *newLayerItem = new SymbolLayerItem( newLayer, parentSymbol->type() ); + SymbolLayerItem *newLayerItem = new SymbolLayerItem( newLayer, parentSymbol->type(), mVectorLayer ); item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem ); item->updatePreview(); @@ -727,7 +726,7 @@ void QgsSymbolSelectorWidget::duplicateLayer() else parentSymbol->insertSymbolLayer( item->rowCount() - insertIdx, newLayer ); - SymbolLayerItem *newLayerItem = new SymbolLayerItem( newLayer, parentSymbol->type() ); + SymbolLayerItem *newLayerItem = new SymbolLayerItem( newLayer, parentSymbol->type(), mVectorLayer ); item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem ); if ( newLayer->subSymbol() ) { diff --git a/src/gui/symbology/qgssymbolselectordialog.h b/src/gui/symbology/qgssymbolselectordialog.h index a4152f5d588c..1f0c130905e2 100644 --- a/src/gui/symbology/qgssymbolselectordialog.h +++ b/src/gui/symbology/qgssymbolselectordialog.h @@ -28,6 +28,7 @@ #include #include +#include #include "qgis_gui.h" class QgsStyle; @@ -256,7 +257,7 @@ class GUI_EXPORT QgsSymbolSelectorWidget: public QgsPanelWidget, private Ui::Qgs QgsStyle *mStyle = nullptr; QgsSymbol *mSymbol = nullptr; QMenu *mAdvancedMenu = nullptr; - QgsVectorLayer *mVectorLayer = nullptr; + QPointer< QgsVectorLayer > mVectorLayer; QStandardItemModel *mSymbolLayersModel = nullptr; QWidget *mPresentWidget = nullptr;