Skip to content
Permalink
Browse files

Make it possible to load "text on symbol" labels from expression

  • Loading branch information
wonder-sk committed Apr 19, 2018
1 parent 49b02bf commit 00d8dbfb47523700db8b81145ac096e769604721
@@ -19,6 +19,8 @@
#include <QStandardItemModel>
#include <QTreeView>

#include "qgsexpressionbuilderdialog.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerlegend.h"
#include "qgsrenderer.h"
#include "qgssymbollayerutils.h"
@@ -32,14 +34,21 @@ QgsVectorLayerLegendWidget::QgsVectorLayerLegendWidget( QWidget *parent )
mLegendTreeView = new QTreeView;
mLegendTreeView->setRootIsDecorated( false );

mTextOnSymbolFormatButton = new QPushButton( tr( "Set Text Format..." ) );
mTextOnSymbolFormatButton = new QPushButton( tr( "Set Text Format" ) );
connect( mTextOnSymbolFormatButton, &QPushButton::clicked, this, &QgsVectorLayerLegendWidget::openTextFormatWidget );

mTextOnSymbolFromExpressionButton = new QPushButton( tr( "Set Labels from Expression…" ) );
connect( mTextOnSymbolFromExpressionButton, &QPushButton::clicked, this, &QgsVectorLayerLegendWidget::labelsFromExpression );

mTextOnSymbolGroupBox = new QgsCollapsibleGroupBox;

QHBoxLayout *buttonsLayout = new QHBoxLayout;
buttonsLayout->addWidget( mTextOnSymbolFormatButton );
buttonsLayout->addWidget( mTextOnSymbolFromExpressionButton );

QVBoxLayout *groupLayout = new QVBoxLayout;
groupLayout->addWidget( mLegendTreeView );
groupLayout->addWidget( mTextOnSymbolFormatButton );
groupLayout->addLayout( buttonsLayout );

mTextOnSymbolGroupBox->setTitle( tr( "Text on Symbols" ) );
mTextOnSymbolGroupBox->setCheckable( true );
@@ -62,13 +71,17 @@ void QgsVectorLayerLegendWidget::setLayer( QgsVectorLayer *layer )

mTextOnSymbolGroupBox->setChecked( legend->textOnSymbolEnabled() );
mTextOnSymbolTextFormat = legend->textOnSymbolTextFormat();
QHash<QString, QString> content = legend->textOnSymbolContent();
populateLegendTreeView( legend->textOnSymbolContent() );
}


void QgsVectorLayerLegendWidget::populateLegendTreeView( const QHash<QString, QString> &content )
{
QStandardItemModel *model = new QStandardItemModel;
model->setColumnCount( 2 );
model->setHorizontalHeaderLabels( QStringList() << tr( "Symbol" ) << tr( "Text" ) );

const QgsLegendSymbolList lst = layer->renderer()->legendSymbolItems();
const QgsLegendSymbolList lst = mLayer->renderer()->legendSymbolItems();
for ( const QgsLegendSymbolItem &symbolItem : lst )
{
if ( !symbolItem.symbol() )
@@ -138,3 +151,44 @@ void QgsVectorLayerLegendWidget::openTextFormatWidget()

mTextOnSymbolTextFormat = textOnSymbolFormatWidget->format();
}


void QgsVectorLayerLegendWidget::labelsFromExpression()
{
QHash<QString, QString> content;
QgsRenderContext context( QgsRenderContext::fromMapSettings( mCanvas->mapSettings() ) );

QgsExpressionBuilderDialog dlgExpression( mLayer );
dlgExpression.setExpressionContext( context.expressionContext() );
if ( !dlgExpression.exec() )
return;

QgsExpression expr( dlgExpression.expressionText() );
expr.prepare( &context.expressionContext() );

std::unique_ptr< QgsFeatureRenderer > r( mLayer->renderer()->clone() );

QgsFeature f;
QgsFeatureRequest request;
request.setSubsetOfAttributes( r->usedAttributes( context ), mLayer->fields() );
QgsFeatureIterator fi = mLayer->getFeatures();

r->startRender( context, mLayer->fields() );
while ( fi.nextFeature( f ) )
{
context.expressionContext().setFeature( f );
const QSet<QString> keys = r->legendKeysForFeature( f, context );
for ( const QString &key : keys )
{
if ( content.contains( key ) )
continue;

QString label = expr.evaluate( &context.expressionContext() ).toString();
if ( !label.isEmpty() )
content[key] = label;
}
}
r->stopRender( context );

populateLegendTreeView( content );
}
@@ -25,6 +25,7 @@ class QPushButton;
class QTreeView;

class QgsCollapsibleGroupBox;
class QgsMapCanvas;
class QgsVectorLayer;

/**
@@ -36,6 +37,12 @@ class QgsVectorLayerLegendWidget : public QWidget
public:
explicit QgsVectorLayerLegendWidget( QWidget *parent = nullptr );

//! Sets pointer to map canvas
void setMapCanvas( QgsMapCanvas *canvas ) { mCanvas = canvas; }

//! Returns pointer to map canvas
QgsMapCanvas *mapCanvas() const { return mCanvas; }

//! Initialize widget with a map layer
void setLayer( QgsVectorLayer *layer );

@@ -44,13 +51,19 @@ class QgsVectorLayerLegendWidget : public QWidget

private slots:
void openTextFormatWidget();
void labelsFromExpression();

private:
void populateLegendTreeView( const QHash<QString, QString> &content );

private:
QTreeView *mLegendTreeView = nullptr;
QPushButton *mTextOnSymbolFormatButton = nullptr;
QPushButton *mTextOnSymbolFromExpressionButton = nullptr;
QgsCollapsibleGroupBox *mTextOnSymbolGroupBox = nullptr;
QLabel *mTextOnSymbolLabel = nullptr;

QgsMapCanvas *mCanvas = nullptr;
QgsVectorLayer *mLayer = nullptr;
QgsTextFormat mTextOnSymbolTextFormat;
};
@@ -302,6 +302,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
mDiagramFrame->setLayout( diagLayout );

// Legend tab
mLegendWidget->setMapCanvas( QgisApp::instance()->mapCanvas() );
mLegendWidget->setLayer( mLayer );
mLegendConfigEmbeddedWidget->setLayer( mLayer );

0 comments on commit 00d8dbf

Please sign in to comment.
You can’t perform that action at this time.