Skip to content

Commit

Permalink
Use first feature in layer to generate symbol preview icon in widget
Browse files Browse the repository at this point in the history
Uses the first feature found in a layer in order to create a better
preview for the symbol in the symbol selector dialog. This allows
data defined settings to be evaluated correctly (at least, for the
first feature) and avoids missing previews due to missing
attribute values when data defined settings are present.

Fixes #17061
  • Loading branch information
nyalldawson committed Feb 19, 2018
1 parent 7701ea6 commit 23dc1c8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
26 changes: 25 additions & 1 deletion src/gui/symbology/qgssymbolselectordialog.cpp
Expand Up @@ -31,6 +31,8 @@
#include "qgslogger.h"
#include "qgsapplication.h"
#include "qgssettings.h"
#include "qgsfeatureiterator.h"
#include "qgsvectorlayer.h"

#include <QColorDialog>
#include <QPainter>
Expand Down Expand Up @@ -247,6 +249,19 @@ QgsSymbolSelectorWidget::QgsSymbolSelectorWidget( QgsSymbol *symbol, QgsStyle *s
layersTree->setModel( model );
layersTree->setHeaderHidden( true );

//get first feature from layer for previews
if ( mVectorLayer )
{
QgsFeatureIterator it = mVectorLayer->getFeatures( QgsFeatureRequest().setLimit( 1 ) );
it.nextFeature( mPreviewFeature );
mPreviewExpressionContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( mVectorLayer ) );
mPreviewExpressionContext.setFeature( mPreviewFeature );
}
else
{
mPreviewExpressionContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( nullptr ) );
}

QItemSelectionModel *selModel = layersTree->selectionModel();
connect( selModel, &QItemSelectionModel::currentChanged, this, &QgsSymbolSelectorWidget::layerChanged );

Expand Down Expand Up @@ -285,6 +300,15 @@ void QgsSymbolSelectorWidget::setContext( const QgsSymbolWidgetContext &context
{
mContext = context;

if ( mContext.expressionContext() )
{
mPreviewExpressionContext = *mContext.expressionContext();
if ( mVectorLayer )
mPreviewExpressionContext.appendScope( QgsExpressionContextUtils::layerScope( mVectorLayer ) );

mPreviewExpressionContext.setFeature( mPreviewFeature );
}

QWidget *widget = stackedWidget->currentWidget();
QgsLayerPropertiesWidget *layerProp = dynamic_cast< QgsLayerPropertiesWidget * >( widget );
QgsSymbolsListWidget *listWidget = dynamic_cast< QgsSymbolsListWidget * >( widget );
Expand Down Expand Up @@ -362,7 +386,7 @@ void QgsSymbolSelectorWidget::updateUi()

void QgsSymbolSelectorWidget::updatePreview()
{
QImage preview = mSymbol->bigSymbolPreviewImage( mContext.expressionContext() );
QImage preview = mSymbol->bigSymbolPreviewImage( &mPreviewExpressionContext );
lblPreview->setPixmap( QPixmap::fromImage( preview ) );
// Hope this is a appropriate place
emit symbolModified();
Expand Down
3 changes: 3 additions & 0 deletions src/gui/symbology/qgssymbolselectordialog.h
Expand Up @@ -250,6 +250,9 @@ class GUI_EXPORT QgsSymbolSelectorWidget: public QgsPanelWidget, private Ui::Qgs
private:
std::unique_ptr<DataDefinedRestorer> mDataDefineRestorer;
QgsSymbolWidgetContext mContext;
QgsFeature mPreviewFeature;
QgsExpressionContext mPreviewExpressionContext;

};

/**
Expand Down

0 comments on commit 23dc1c8

Please sign in to comment.