QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgspropertyassistantwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspropertyassistantwidget.cpp
3  ------------------------------
4  begin : February, 2017
5  copyright : (C) 2017 Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
20 #include "qgsproject.h"
21 #include "qgsmapsettings.h"
22 #include "qgsvectorlayer.h"
23 #include "qgslayertreelayer.h"
24 #include "qgssymbollayerutils.h"
26 #include "qgsstyle.h"
27 
29  const QgsPropertyDefinition &definition, const QgsProperty &initialState,
30  const QgsVectorLayer *layer )
31  : QgsPanelWidget( parent )
32  , mDefinition( definition )
33  , mLayer( layer )
34 {
35  setupUi( this );
36 
37  layout()->setContentsMargins( 0, 0, 0, 0 );
38 
39  setPanelTitle( mDefinition.description() );
40 
41  mLegendPreview->hide();
42 
43  minValueSpinBox->setShowClearButton( false );
44  maxValueSpinBox->setShowClearButton( false );
45 
46  // TODO expression widget shouldn't require a non-const layer
47  mExpressionWidget->setLayer( const_cast< QgsVectorLayer * >( mLayer ) );
48  mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric );
49  mExpressionWidget->setField( initialState.propertyType() == QgsProperty::ExpressionBasedProperty ? initialState.expressionString() : initialState.field() );
50 
51  if ( auto *lTransformer = initialState.transformer() )
52  {
53  minValueSpinBox->setValue( lTransformer->minValue() );
54  maxValueSpinBox->setValue( lTransformer->maxValue() );
55 
56  if ( lTransformer->curveTransform() )
57  {
58  mTransformCurveCheckBox->setChecked( true );
59  mTransformCurveCheckBox->setCollapsed( false );
60  mCurveEditor->setCurve( *lTransformer->curveTransform() );
61  }
62  }
63 
64  connect( computeValuesButton, &QPushButton::clicked, this, &QgsPropertyAssistantWidget::computeValuesFromLayer );
65 
66  if ( mLayer )
67  {
68  mLayerTreeLayer = new QgsLayerTreeLayer( const_cast< QgsVectorLayer * >( mLayer ) );
69  mRoot.addChildNode( mLayerTreeLayer ); // takes ownership
70  }
71  mLegendPreview->setModel( &mPreviewList );
72  mLegendPreview->setItemDelegate( new QgsAssistantPreviewItemDelegate( &mPreviewList ) );
73  mLegendPreview->setHeaderHidden( true );
74  mLegendPreview->expandAll();
75  mLegendVerticalFrame->setLayout( new QVBoxLayout() );
76  mLegendVerticalFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
77  mLegendVerticalFrame->hide();
78 
79  switch ( definition.standardTemplate() )
80  {
83  {
84  mTransformerWidget = new QgsPropertySizeAssistantWidget( this, mDefinition, initialState );
85  mLegendPreview->show();
86  break;
87  }
88 
91  {
92  mTransformerWidget = new QgsPropertyColorAssistantWidget( this, mDefinition, initialState );
93  mLegendPreview->show();
94  break;
95  }
96 
98  {
99  mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
100  break;
101  }
102 
103  default:
104  {
105  if ( mDefinition.dataType() == QgsPropertyDefinition::DataTypeNumeric )
106  {
107  mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
108  }
109  break;
110  }
111  }
112 
113  if ( mTransformerWidget )
114  {
115  mOutputWidget->layout()->addWidget( mTransformerWidget );
116  connect( mTransformerWidget, &QgsPropertyAbstractTransformerWidget::widgetChanged, this, &QgsPropertyAssistantWidget::widgetChanged );
117 
118  mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
119  mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
120 
121  mCurveEditor->setHistogramSource( mLayer, mExpressionWidget->currentField() );
122  connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & expression )
123  {
124  mCurveEditor->setHistogramSource( mLayer, expression );
125  }
126  );
127  connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMinHistogramValueRange );
128  connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMaxHistogramValueRange );
129  }
130  mTransformCurveCheckBox->setVisible( mTransformerWidget );
131 
132  connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
133  connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
134  connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
136  connect( this, &QgsPropertyAssistantWidget::widgetChanged, this, &QgsPropertyAssistantWidget::updatePreview );
137  updatePreview();
138 }
139 
141 {
142  mExpressionContextGenerator = generator;
143  mExpressionWidget->registerExpressionContextGenerator( generator );
144 }
145 
147 {
148  property.setActive( !mExpressionWidget->currentText().isEmpty() );
149  if ( mExpressionWidget->isExpression() )
150  property.setExpressionString( mExpressionWidget->currentField() );
151  else
152  property.setField( mExpressionWidget->currentField() );
153 
154  if ( mTransformerWidget )
155  {
156  std::unique_ptr< QgsPropertyTransformer> t( mTransformerWidget->createTransformer( minValueSpinBox->value(), maxValueSpinBox->value() ) );
157  if ( mTransformCurveCheckBox->isChecked() )
158  {
159  t->setCurveTransform( new QgsCurveTransform( mCurveEditor->curve() ) );
160  }
161  else
162  {
163  t->setCurveTransform( nullptr );
164  }
165  property.setTransformer( t.release() );
166  }
167 }
168 
170 {
172 
173  if ( dockMode && mLegendVerticalFrame->isHidden() )
174  {
175  mLegendVerticalFrame->layout()->addWidget( mLegendPreview );
176  mLegendVerticalFrame->show();
177  }
178 }
179 
180 void QgsPropertyAssistantWidget::computeValuesFromLayer()
181 {
182  if ( !mLayer )
183  return;
184 
185  double minValue = 0.0;
186  double maxValue = 0.0;
187 
188  if ( mExpressionWidget->isExpression() )
189  {
190  if ( !computeValuesFromExpression( mExpressionWidget->currentField(), minValue, maxValue ) )
191  return;
192  }
193  else
194  {
195  if ( !computeValuesFromField( mExpressionWidget->currentField(), minValue, maxValue ) )
196  return;
197  }
198 
199  whileBlocking( minValueSpinBox )->setValue( minValue );
200  whileBlocking( maxValueSpinBox )->setValue( maxValue );
201 
202  mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
203  mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
204 
205  emit widgetChanged();
206 }
207 
208 void QgsPropertyAssistantWidget::updatePreview()
209 {
210  if ( mLegendPreview->isHidden() || !mTransformerWidget || !mLayer ) // TODO - make this work OK without a layer
211  return;
212 
213  mLegendPreview->setIconSize( QSize( 512, 512 ) );
214  mPreviewList.clear();
215 
216  QList<double> breaks = QgsSymbolLayerUtils::prettyBreaks( minValueSpinBox->value(),
217  maxValueSpinBox->value(), 8 );
218 
219  QgsCurveTransform curve = mCurveEditor->curve();
220  QList< QgsSymbolLegendNode * > nodes = mTransformerWidget->generatePreviews( breaks, mLayerTreeLayer, mSymbol.get(), minValueSpinBox->value(),
221  maxValueSpinBox->value(), mTransformCurveCheckBox->isChecked() ? &curve : nullptr );
222 
223  int widthMax = 0;
224  int i = 0;
225  const auto constNodes = nodes;
226  for ( QgsSymbolLegendNode *node : constNodes )
227  {
228  const QSize minSize( node->minimumIconSize() );
229  node->setIconSize( minSize );
230  widthMax = std::max( minSize.width(), widthMax );
231  QStandardItem *item = new QStandardItem( node->data( Qt::DecorationRole ).value<QPixmap>(), QString::number( breaks[i] ) );
232  item->setEditable( false );
233  mPreviewList.appendRow( item );
234  delete node;
235  i++;
236  }
237  // center icon and align text left by giving icons the same width
238  // TODO maybe add some space so that icons don't touch
239  for ( int i = 0; i < breaks.length(); i++ )
240  {
241  QPixmap img( mPreviewList.item( i )->icon().pixmap( mPreviewList.item( i )->icon().actualSize( QSize( 512, 512 ) ) ) );
242  QPixmap enlarged( widthMax, img.height() );
243  // fill transparent and add original image
244  enlarged.fill( Qt::transparent );
245  QPainter p( &enlarged );
246  p.drawPixmap( QPoint( ( widthMax - img.width() ) / 2, 0 ), img );
247  p.end();
248  mPreviewList.item( i )->setIcon( enlarged );
249  }
250 }
251 
252 bool QgsPropertyAssistantWidget::computeValuesFromExpression( const QString &expression, double &minValue, double &maxValue ) const
253 {
254  QgsExpression e( expression );
255 
256  QgsExpressionContext context;
257  if ( mExpressionContextGenerator )
258  {
259  context = mExpressionContextGenerator->createExpressionContext();
260  }
261  else
262  {
266  }
267 
268  if ( !e.prepare( &context ) )
269  return false;
270 
271  QSet<QString> referencedCols( e.referencedColumns() );
272 
273  QgsFeatureIterator fit = mLayer->getFeatures(
274  QgsFeatureRequest().setFlags( e.needsGeometry()
277  .setSubsetOfAttributes( referencedCols, mLayer->fields() ) );
278 
279  // create list of non-null attribute values
280  double min = std::numeric_limits<double>::max();
281  double max = std::numeric_limits<double>::lowest();
282  QgsFeature f;
283  bool found = false;
284  while ( fit.nextFeature( f ) )
285  {
286  bool ok;
287  context.setFeature( f );
288  const double value = e.evaluate( &context ).toDouble( &ok );
289  if ( ok )
290  {
291  max = std::max( max, value );
292  min = std::min( min, value );
293  found = true;
294  }
295  }
296  if ( found )
297  {
298  minValue = min;
299  maxValue = max;
300  }
301  return found;
302 }
303 
304 bool QgsPropertyAssistantWidget::computeValuesFromField( const QString &fieldName, double &minValue, double &maxValue ) const
305 {
306  int fieldIndex = mLayer->fields().lookupField( fieldName );
307  if ( fieldIndex < 0 )
308  {
309  return false;
310  }
311 
312  bool ok = false;
313  double minDouble = mLayer->minimumValue( fieldIndex ).toDouble( &ok );
314  if ( !ok )
315  return false;
316 
317  double maxDouble = mLayer->maximumValue( fieldIndex ).toDouble( &ok );
318  if ( !ok )
319  return false;
320 
321  minValue = minDouble;
322  maxValue = maxDouble;
323  return true;
324 }
325 
327 
328 //
329 // QgsPropertySizeAssistantWidget
330 //
331 
332 QgsPropertySizeAssistantWidget::QgsPropertySizeAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
333  : QgsPropertyAbstractTransformerWidget( parent, definition )
334 {
335  setupUi( this );
336 
337  layout()->setContentsMargins( 0, 0, 0, 0 );
338 
339  if ( definition.standardTemplate() == QgsPropertyDefinition::Size )
340  {
341  scaleMethodComboBox->addItem( tr( "Flannery" ), QgsSizeScaleTransformer::Flannery );
342  scaleMethodComboBox->addItem( tr( "Surface" ), QgsSizeScaleTransformer::Area );
343  scaleMethodComboBox->addItem( tr( "Radius" ), QgsSizeScaleTransformer::Linear );
344  scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
345  }
346  else if ( definition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
347  {
348  scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
349  scaleMethodComboBox->addItem( tr( "Linear" ), QgsSizeScaleTransformer::Linear );
350  }
351 
352  minSizeSpinBox->setShowClearButton( false );
353  maxSizeSpinBox->setShowClearButton( false );
354  nullSizeSpinBox->setShowClearButton( false );
355 
356  if ( const QgsSizeScaleTransformer *sizeTransform = dynamic_cast< const QgsSizeScaleTransformer * >( initialState.transformer() ) )
357  {
358  minSizeSpinBox->setValue( sizeTransform->minSize() );
359  maxSizeSpinBox->setValue( sizeTransform->maxSize() );
360  nullSizeSpinBox->setValue( sizeTransform->nullSize() );
361  exponentSpinBox->setValue( sizeTransform->exponent() );
362  scaleMethodComboBox->setCurrentIndex( scaleMethodComboBox->findData( sizeTransform->type() ) );
363  }
364 
365  exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
366 
367  connect( minSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
368  connect( maxSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
369  connect( nullSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
370  connect( exponentSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
371  connect( scaleMethodComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
372  connect( scaleMethodComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this,
373  [ = ]
374  {
375  exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
376  }
377  );
378 }
379 
380 QgsSizeScaleTransformer *QgsPropertySizeAssistantWidget::createTransformer( double minValue, double maxValue ) const
381 {
383  static_cast< QgsSizeScaleTransformer::ScaleType >( scaleMethodComboBox->currentData().toInt() ),
384  minValue,
385  maxValue,
386  minSizeSpinBox->value(),
387  maxSizeSpinBox->value(),
388  nullSizeSpinBox->value(),
389  exponentSpinBox->value() );
390  return transformer;
391 }
392 
393 QList< QgsSymbolLegendNode * > QgsPropertySizeAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
394 {
395  QList< QgsSymbolLegendNode * > nodes;
396 
397  const QgsSymbol *legendSymbol = symbol;
398  std::unique_ptr< QgsSymbol > tempSymbol;
399 
400  if ( !legendSymbol )
401  {
402  if ( mDefinition.standardTemplate() == QgsPropertyDefinition::Size )
403  {
404  tempSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
405  }
406  else if ( mDefinition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
407  {
408  tempSymbol.reset( QgsLineSymbol::createSimple( QgsStringMap() ) );
409  }
410  legendSymbol = tempSymbol.get();
411  }
412  if ( !legendSymbol )
413  return nodes;
414 
415  std::unique_ptr< QgsSizeScaleTransformer > t( createTransformer( minValue, maxValue ) );
416  if ( curve )
417  t->setCurveTransform( new QgsCurveTransform( *curve ) );
418 
419  for ( int i = 0; i < breaks.length(); i++ )
420  {
421  std::unique_ptr< QgsSymbolLegendNode > node;
422  if ( dynamic_cast<const QgsMarkerSymbol *>( legendSymbol ) )
423  {
424  std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
425  symbolClone->setDataDefinedSize( QgsProperty() );
426  symbolClone->setDataDefinedAngle( QgsProperty() ); // to avoid symbol not being drawn
427  symbolClone->setSize( t->size( breaks[i] ) );
428  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
429  }
430  else if ( dynamic_cast<const QgsLineSymbol *>( legendSymbol ) )
431  {
432  std::unique_ptr< QgsLineSymbol > symbolClone( static_cast<QgsLineSymbol *>( legendSymbol->clone() ) );
433  symbolClone->setDataDefinedWidth( QgsProperty() );
434  symbolClone->setWidth( t->size( breaks[i] ) );
435  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
436  }
437  if ( node )
438  nodes << node.release();
439  }
440  return nodes;
441 }
442 
443 QList<QgsSymbolLegendNode *> QgsPropertyAbstractTransformerWidget::generatePreviews( const QList<double> &, QgsLayerTreeLayer *, const QgsSymbol *, double, double, QgsCurveTransform * ) const
444 {
445  return QList< QgsSymbolLegendNode * >();
446 }
447 
448 QgsPropertyColorAssistantWidget::QgsPropertyColorAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
449  : QgsPropertyAbstractTransformerWidget( parent, definition )
450 {
451  setupUi( this );
452 
453  layout()->setContentsMargins( 0, 0, 0, 0 );
454 
455  bool supportsAlpha = definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha;
456  mNullColorButton->setAllowOpacity( supportsAlpha );
457  mNullColorButton->setShowNoColor( true );
458  mNullColorButton->setColorDialogTitle( tr( "Color For Null Values" ) );
459  mNullColorButton->setContext( QStringLiteral( "symbology" ) );
460  mNullColorButton->setNoColorString( tr( "Transparent" ) );
461 
462  if ( const QgsColorRampTransformer *colorTransform = dynamic_cast< const QgsColorRampTransformer * >( initialState.transformer() ) )
463  {
464  mNullColorButton->setColor( colorTransform->nullColor() );
465  if ( colorTransform->colorRamp() )
466  mColorRampButton->setColorRamp( colorTransform->colorRamp() );
467  }
468 
469  connect( mNullColorButton, &QgsColorButton::colorChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
470  connect( mColorRampButton, &QgsColorRampButton::colorRampChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
471 
472  if ( !mColorRampButton->colorRamp() )
473  {
474  // set a default ramp
475  QString defaultRampName = QgsProject::instance()->readEntry( QStringLiteral( "DefaultStyles" ), QStringLiteral( "/ColorRamp" ), QString() );
476  std::unique_ptr< QgsColorRamp > defaultRamp( QgsStyle::defaultStyle()->colorRamp( !defaultRampName.isEmpty() ? defaultRampName : QStringLiteral( "Blues" ) ) );
477  if ( defaultRamp )
478  mColorRampButton->setColorRamp( defaultRamp.get() );
479  }
480 }
481 
482 QgsColorRampTransformer *QgsPropertyColorAssistantWidget::createTransformer( double minValue, double maxValue ) const
483 {
485  minValue,
486  maxValue,
487  mColorRampButton->colorRamp(),
488  mNullColorButton->color() );
489  return transformer;
490 }
491 
492 QList<QgsSymbolLegendNode *> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
493 {
494  QList< QgsSymbolLegendNode * > nodes;
495 
496  const QgsMarkerSymbol *legendSymbol = dynamic_cast<const QgsMarkerSymbol *>( symbol );
497  std::unique_ptr< QgsMarkerSymbol > tempSymbol;
498 
499  if ( !legendSymbol )
500  {
501  tempSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
502  legendSymbol = tempSymbol.get();
503  }
504  if ( !legendSymbol )
505  return nodes;
506 
507  std::unique_ptr< QgsColorRampTransformer > t( createTransformer( minValue, maxValue ) );
508  if ( curve )
509  t->setCurveTransform( new QgsCurveTransform( *curve ) );
510 
511  for ( int i = 0; i < breaks.length(); i++ )
512  {
513  std::unique_ptr< QgsSymbolLegendNode > node;
514  std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
515  symbolClone->setColor( t->color( breaks[i] ) );
516  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
517  if ( node )
518  nodes << node.release();
519  }
520  return nodes;
521 }
522 
523 QgsPropertyGenericNumericAssistantWidget::QgsPropertyGenericNumericAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
524  : QgsPropertyAbstractTransformerWidget( parent, definition )
525 {
526  setupUi( this );
527 
528  layout()->setContentsMargins( 0, 0, 0, 0 );
529 
530  nullOutputSpinBox->setShowClearButton( false );
531 
533  {
534  // tweak dialog for rotation
535  minOutputSpinBox->setMaximum( 360.0 );
536  minOutputSpinBox->setValue( 0.0 );
537  minOutputSpinBox->setShowClearButton( true );
538  minOutputSpinBox->setClearValue( 0.0 );
539  minOutputSpinBox->setSuffix( tr( " °" ) );
540  maxOutputSpinBox->setMaximum( 360.0 );
541  maxOutputSpinBox->setValue( 360.0 );
542  maxOutputSpinBox->setShowClearButton( true );
543  maxOutputSpinBox->setClearValue( 360.0 );
544  maxOutputSpinBox->setSuffix( tr( " °" ) );
545  exponentSpinBox->hide();
546  mExponentLabel->hide();
547  mLabelMinOutput->setText( tr( "Angle from" ) );
548  mLabelNullOutput->setText( tr( "Angle when NULL" ) );
549  }
550  else
551  {
552  minOutputSpinBox->setShowClearButton( false );
553  maxOutputSpinBox->setShowClearButton( false );
554  }
555 
556  if ( const QgsGenericNumericTransformer *transform = dynamic_cast< const QgsGenericNumericTransformer * >( initialState.transformer() ) )
557  {
558  minOutputSpinBox->setValue( transform->minOutputValue() );
559  maxOutputSpinBox->setValue( transform->maxOutputValue() );
560  nullOutputSpinBox->setValue( transform->nullOutputValue() );
561  exponentSpinBox->setValue( transform->exponent() );
562  }
563 
564  connect( minOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
565  connect( maxOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
566  connect( nullOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
567  connect( exponentSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
568 }
569 
570 QgsGenericNumericTransformer *QgsPropertyGenericNumericAssistantWidget::createTransformer( double minValue, double maxValue ) const
571 {
573  minValue,
574  maxValue,
575  minOutputSpinBox->value(),
576  maxOutputSpinBox->value(),
577  nullOutputSpinBox->value(),
578  exponentSpinBox->value() );
579  return transformer;
580 }
581 
QgsPropertyAssistantWidget::registerExpressionContextGenerator
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
Definition: qgspropertyassistantwidget.cpp:140
QgsFieldProxyModel::Numeric
@ Numeric
All numeric fields.
Definition: qgsfieldproxymodel.h:45
QgsFeatureRequest::NoGeometry
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition: qgsfeaturerequest.h:81
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:993
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:370
qgsexpressioncontextutils.h
QgsProperty
A store for object properties.
Definition: qgsproperty.h:232
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:34
QgsSizeScaleTransformer::Exponential
@ Exponential
Scale using set exponent.
Definition: qgspropertytransformer.h:471
QgsPanelWidget::setDockMode
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
Definition: qgspanelwidget.cpp:44
QgsMarkerSymbol::createSimple
static QgsMarkerSymbol * createSimple(const QgsStringMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Definition: qgssymbol.cpp:1459
qgssymbollayerutils.h
QgsExpressionContextUtils::layerScope
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Definition: qgsexpressioncontextutils.cpp:265
qgslayertreelayer.h
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:468
QgsPropertyDefinition::DataTypeNumeric
@ DataTypeNumeric
Property requires a numeric value.
Definition: qgsproperty.h:100
QgsPropertyAssistantWidget::setDockMode
void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
Definition: qgspropertyassistantwidget.cpp:169
QgsColorRampTransformer
QgsPropertyTransformer subclass for transforming a numeric value into a color from a color ramp.
Definition: qgspropertytransformer.h:609
QgsProject::readEntry
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
Definition: qgsproject.cpp:2526
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:185
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:64
QgsProperty::propertyType
Type propertyType() const
Returns the property type.
Definition: qgsproperty.cpp:261
QgsCurveEditorWidget::setMaxHistogramValueRange
void setMaxHistogramValueRange(double maxValueRange)
Sets the maximum expected value for the range of values shown in the histogram.
Definition: qgscurveeditorwidget.cpp:146
qgsmapsettings.h
QgsProperty::transformer
const QgsPropertyTransformer * transformer() const
Returns the existing transformer used for manipulating the calculated values for the property,...
Definition: qgsproperty.cpp:801
QgsPanelWidget::dockMode
bool dockMode()
Returns the dock mode state.
Definition: qgspanelwidget.h:83
QgsProperty::expressionString
QString expressionString() const
Returns the expression used for the property value.
Definition: qgsproperty.cpp:323
QgsMarkerSymbol::clone
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:1937
QgsColorButton::colorChanged
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
QgsStyle::defaultStyle
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:127
QgsPropertyDefinition::Rotation
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:61
QgsPropertyDefinition::dataType
DataType dataType() const
Returns the allowable field/value data type for the property.
Definition: qgsproperty.h:189
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3283
QgsLegendSymbolItem
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
Definition: qgslegendsymbolitem.h:37
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
QgsProperty::ExpressionBasedProperty
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
Definition: qgsproperty.h:241
QgsExpressionContextUtils::projectScope
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
Definition: qgsexpressioncontextutils.cpp:222
QgsFeatureRequest::NoFlags
@ NoFlags
Definition: qgsfeaturerequest.h:80
QgsCurveEditorWidget::changed
void changed()
Emitted when the widget curve changes.
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:30
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:262
QgsMarkerSymbol
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:931
QgsPropertyDefinition::ColorWithAlpha
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:65
QgsLayerTreeLayer
Layer tree node points to a map layer.
Definition: qgslayertreelayer.h:44
QgsFieldExpressionWidget::fieldChanged
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
QgsSizeScaleTransformer
QgsPropertyTransformer subclass for scaling a value into a size according to various scaling methods.
Definition: qgspropertytransformer.h:462
QgsSizeScaleTransformer::Flannery
@ Flannery
Flannery scaling method.
Definition: qgspropertytransformer.h:470
QgsPanelWidget::widgetChanged
void widgetChanged()
Emitted when the widget state changes.
QgsLineSymbol
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:1131
QgsSymbolLayerUtils::prettyBreaks
static QList< double > prettyBreaks(double minimum, double maximum, int classes)
Computes a sequence of about 'classes' equally spaced round values which cover the range of values fr...
Definition: qgssymbollayerutils.cpp:4266
QgsPropertyDefinition
Definition for a property.
Definition: qgsproperty.h:48
QgsExpressionContextGenerator::createExpressionContext
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QgsVectorLayer::maximumValue
QVariant maximumValue(int index) const FINAL
Returns the maximum value for an attribute column or an invalid variant in case of error.
Definition: qgsvectorlayer.cpp:4181
QgsPropertyDefinition::standardTemplate
StandardPropertyTemplate standardTemplate() const
Returns the property's standard template, if applicable.
Definition: qgsproperty.h:195
QgsPanelWidget::setPanelTitle
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
Definition: qgspanelwidget.h:44
QgsVectorLayer::minimumValue
QVariant minimumValue(int index) const FINAL
Returns the minimum value for an attribute column or an invalid variant in case of error.
Definition: qgsvectorlayer.cpp:4176
qgsstyle.h
QgsPropertyAssistantWidget::updateProperty
void updateProperty(QgsProperty &property)
Updates a property in place to corresponding to the current settings shown in the widget.
Definition: qgspropertyassistantwidget.cpp:146
QgsCurveTransform
Handles scaling of input values to output values by using a curve created from smoothly joining a num...
Definition: qgspropertytransformer.h:57
qgsvectorlayer.h
QgsPropertyDefinition::description
QString description() const
Descriptive name of the property.
Definition: qgsproperty.h:164
QgsSymbol::clone
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
QgsPropertyDefinition::Size
@ Size
1D size (eg marker radius, or square marker height/width)
Definition: qgsproperty.h:70
QgsStringMap
QMap< QString, QString > QgsStringMap
Definition: qgis.h:758
QgsPropertyAssistantWidget::QgsPropertyAssistantWidget
QgsPropertyAssistantWidget(QWidget *parent=nullptr, const QgsPropertyDefinition &definition=QgsPropertyDefinition(), const QgsProperty &initialState=QgsProperty(), const QgsVectorLayer *layer=nullptr)
Constructor for QgsPropertyAssistantWidget.
Definition: qgspropertyassistantwidget.cpp:28
QgsCurveEditorWidget::setMinHistogramValueRange
void setMinHistogramValueRange(double minValueRange)
Sets the minimum expected value for the range of values shown in the histogram.
Definition: qgscurveeditorwidget.cpp:140
QgsSizeScaleTransformer::Area
@ Area
Area based scaling.
Definition: qgspropertytransformer.h:469
QgsSizeScaleTransformer::Linear
@ Linear
Linear scaling.
Definition: qgspropertytransformer.h:468
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsLayerTreeGroup::addChildNode
void addChildNode(QgsLayerTreeNode *node)
Append an existing node.
Definition: qgslayertreegroup.cpp:127
QgsLineSymbol::createSimple
static QgsLineSymbol * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
Definition: qgssymbol.cpp:1470
QgsProperty::field
QString field() const
Returns the current field name the property references.
Definition: qgsproperty.cpp:300
QgsDoubleSpinBox
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
Definition: qgsdoublespinbox.h:43
qgspropertyassistantwidget.h
QgsGenericNumericTransformer
QgsPropertyTransformer subclass for scaling an input numeric value into an output numeric value.
Definition: qgspropertytransformer.h:344
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsSizeScaleTransformer::ScaleType
ScaleType
Size scaling methods.
Definition: qgspropertytransformer.h:467
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:344
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:105
QgsSymbolLegendNode
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Definition: qgslayertreemodellegendnode.h:292
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsFieldExpressionWidget
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
Definition: qgsfieldexpressionwidget.h:47
QgsExpressionContextGenerator
Abstract interface for generating an expression context.
Definition: qgsexpressioncontextgenerator.h:37
QgsPropertyDefinition::StrokeWidth
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:73
qgsproject.h
QgsPropertyDefinition::ColorNoAlpha
@ ColorNoAlpha
Color with no alpha channel.
Definition: qgsproperty.h:66
QgsColorRampButton::colorRampChanged
void colorRampChanged()
Emitted whenever a new color ramp is set for the button.
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:521