Ensure correct expression context is used when generating symbol preview

icons

Fixes #49106
This commit is contained in:
Nyall Dawson 2022-09-29 10:23:26 +10:00
parent 52e44c1e3e
commit 73e50bfc06
6 changed files with 29 additions and 22 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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 );

View File

@ -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.

View File

@ -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 <QColorDialog>
@ -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<SymbolLayerItem *>( 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<QgsLineSymbol *>( 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() )
{

View File

@ -28,6 +28,7 @@
#include <QStandardItemModel>
#include <QDialogButtonBox>
#include <QPointer>
#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;