2020#include " qgsproject.h"
2121#include " qgsmapsettings.h"
2222#include " qgsvectorlayer.h"
23+ #include " qgslayertreelayer.h"
24+ #include " qgssymbollayerutils.h"
2325
2426QgsPropertyAssistantWidget::QgsPropertyAssistantWidget ( QWidget* parent ,
2527 const QgsPropertyDefinition& definition, const QgsProperty& initialState,
@@ -53,6 +55,16 @@ QgsPropertyAssistantWidget::QgsPropertyAssistantWidget( QWidget* parent ,
5355
5456 connect ( computeValuesButton, &QPushButton::clicked, this , &QgsPropertyAssistantWidget::computeValuesFromLayer );
5557
58+ if ( mLayer )
59+ {
60+ mLayerTreeLayer = new QgsLayerTreeLayer ( const_cast < QgsVectorLayer* >( mLayer ) );
61+ mRoot .addChildNode ( mLayerTreeLayer ); // takes ownership
62+ }
63+ mLegendPreview ->setModel ( &mPreviewList );
64+ mLegendPreview ->setItemDelegate ( new ItemDelegate ( &mPreviewList ) );
65+ mLegendPreview ->setHeaderHidden ( true );
66+ mLegendPreview ->expandAll ();
67+
5668 switch ( definition.standardTemplate () )
5769 {
5870 case QgsPropertyDefinition::Size:
@@ -72,6 +84,8 @@ QgsPropertyAssistantWidget::QgsPropertyAssistantWidget( QWidget* parent ,
7284 connect ( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this , &QgsPropertyAssistantWidget::widgetChanged );
7385 connect ( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this , &QgsPropertyAssistantWidget::widgetChanged );
7486 connect ( mExpressionWidget , static_cast < void ( QgsFieldExpressionWidget::* )( const QString& ) > ( &QgsFieldExpressionWidget::fieldChanged ), this , &QgsPropertyAssistantWidget::widgetChanged );
87+ connect ( this , &QgsPropertyAssistantWidget::widgetChanged, this , &QgsPropertyAssistantWidget::updatePreview );
88+ updatePreview ();
7589}
7690
7791void QgsPropertyAssistantWidget::registerExpressionContextGenerator ( QgsExpressionContextGenerator* generator )
@@ -116,6 +130,55 @@ void QgsPropertyAssistantWidget::computeValuesFromLayer()
116130 emit widgetChanged ();
117131}
118132
133+ void QgsPropertyAssistantWidget::updatePreview ()
134+ {
135+ if ( !mTransformerWidget || !mSymbol )
136+ return ;
137+
138+ if ( dockMode () )
139+ return ;
140+
141+ mLegendPreview ->setIconSize ( QSize ( 512 , 512 ) );
142+ mPreviewList .clear ();
143+
144+ QList<double > breaks = QgsSymbolLayerUtils::prettyBreaks ( minValueSpinBox->value (),
145+ maxValueSpinBox->value (), 4 );
146+
147+ QList< QgsSymbolLegendNode* > nodes = mTransformerWidget ->generatePreviews ( breaks, mLayerTreeLayer , mLayer , mSymbol .get (), minValueSpinBox->value (),
148+ maxValueSpinBox->value () );
149+ if ( nodes.isEmpty () )
150+ {
151+ mLegendPreview ->show ();
152+ return ;
153+ }
154+
155+ int widthMax = 0 ;
156+ int i = 0 ;
157+ Q_FOREACH ( QgsSymbolLegendNode* node, nodes )
158+ {
159+ const QSize minSize ( node->minimumIconSize () );
160+ node->setIconSize ( minSize );
161+ widthMax = qMax ( minSize.width (), widthMax );
162+ mPreviewList .appendRow ( new QStandardItem ( node->data ( Qt::DecorationRole ).value <QPixmap>(), QString::number ( breaks[i] ) ) );
163+ delete node;
164+ i++;
165+ }
166+ // center icon and align text left by giving icons the same width
167+ // @todo maybe add some space so that icons don't touch
168+ for ( int i = 0 ; i < breaks.length (); i++ )
169+ {
170+ QPixmap img ( mPreviewList .item ( i )->icon ().pixmap ( mPreviewList .item ( i )->icon ().actualSize ( QSize ( 512 , 512 ) ) ) );
171+ QPixmap enlarged ( widthMax, img.height () );
172+ // fill transparent and add original image
173+ enlarged.fill ( Qt::transparent );
174+ QPainter p ( &enlarged );
175+ p.drawPixmap ( QPoint (( widthMax - img.width () ) / 2 , 0 ), img );
176+ p.end ();
177+ mPreviewList .item ( i )->setIcon ( enlarged );
178+ }
179+ mLegendPreview ->show ();
180+ }
181+
119182bool QgsPropertyAssistantWidget::computeValuesFromExpression ( const QString& expression, double & minValue, double & maxValue ) const
120183{
121184 QgsExpression e ( expression );
@@ -236,7 +299,7 @@ QgsPropertySizeAssistantWidget::QgsPropertySizeAssistantWidget( QWidget* parent,
236299 );
237300}
238301
239- QgsPropertyTransformer * QgsPropertySizeAssistantWidget::createTransformer ( double minValue, double maxValue ) const
302+ QgsSizeScaleTransformer * QgsPropertySizeAssistantWidget::createTransformer ( double minValue, double maxValue ) const
240303{
241304 QgsSizeScaleTransformer* transformer = new QgsSizeScaleTransformer (
242305 static_cast < QgsSizeScaleTransformer::ScaleType >( scaleMethodComboBox->currentData ().toInt () ),
@@ -248,3 +311,41 @@ QgsPropertyTransformer* QgsPropertySizeAssistantWidget::createTransformer( doubl
248311 exponentSpinBox->value () );
249312 return transformer;
250313}
314+
315+ QList< QgsSymbolLegendNode* > QgsPropertySizeAssistantWidget::generatePreviews ( const QList<double >& breaks, QgsLayerTreeLayer* parent, const QgsVectorLayer* layer, const QgsSymbol* symbol, double minValue, double maxValue ) const
316+ {
317+ QList< QgsSymbolLegendNode* > nodes;
318+
319+ if ( !symbol || !layer )
320+ return nodes;
321+
322+ std::unique_ptr< QgsSizeScaleTransformer > t ( createTransformer ( minValue, maxValue ) );
323+
324+ for ( int i = 0 ; i < breaks.length (); i++ )
325+ {
326+ std::unique_ptr< QgsSymbolLegendNode > node;
327+ if ( dynamic_cast <const QgsMarkerSymbol*>( symbol ) )
328+ {
329+ std::unique_ptr< QgsMarkerSymbol > symbolClone ( static_cast <QgsMarkerSymbol*>( symbol->clone () ) );
330+ symbolClone->setDataDefinedSize ( QgsProperty () );
331+ symbolClone->setDataDefinedAngle ( QgsProperty () ); // to avoid symbol not being drawn
332+ symbolClone->setSize ( t->size ( breaks[i] ) );
333+ node.reset ( new QgsSymbolLegendNode ( parent, QgsLegendSymbolItem ( symbolClone.get (), QString::number ( i ), QString () ) ) );
334+ }
335+ else if ( dynamic_cast <const QgsLineSymbol*>( symbol ) )
336+ {
337+ std::unique_ptr< QgsLineSymbol > symbolClone ( static_cast <QgsLineSymbol*>( symbol->clone () ) );
338+ symbolClone->setDataDefinedWidth ( QgsProperty () );
339+ symbolClone->setWidth ( t->size ( breaks[i] ) );
340+ node.reset ( new QgsSymbolLegendNode ( parent, QgsLegendSymbolItem ( symbolClone.get (), QString::number ( i ), QString () ) ) );
341+ }
342+ if ( node )
343+ nodes << node.release ();
344+ }
345+ return nodes;
346+ }
347+
348+ QList<QgsSymbolLegendNode*> QgsPropertyAbstractTransformerWidget::generatePreviews ( const QList<double >& , QgsLayerTreeLayer* , const QgsVectorLayer*, const QgsSymbol*, double , double ) const
349+ {
350+ return QList< QgsSymbolLegendNode* >();
351+ }
0 commit comments