QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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  layout()->setMargin( 0 );
39 
40  setPanelTitle( mDefinition.description() );
41 
42  mLegendPreview->hide();
43 
44  minValueSpinBox->setShowClearButton( false );
45  maxValueSpinBox->setShowClearButton( false );
46 
47  // TODO expression widget shouldn't require a non-const layer
48  mExpressionWidget->setLayer( const_cast< QgsVectorLayer * >( mLayer ) );
49  mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric );
50  mExpressionWidget->setField( initialState.propertyType() == QgsProperty::ExpressionBasedProperty ? initialState.expressionString() : initialState.field() );
51 
52  if ( initialState.transformer() )
53  {
54  minValueSpinBox->setValue( initialState.transformer()->minValue() );
55  maxValueSpinBox->setValue( initialState.transformer()->maxValue() );
56 
57  if ( initialState.transformer()->curveTransform() )
58  {
59  mTransformCurveCheckBox->setChecked( true );
60  mTransformCurveCheckBox->setCollapsed( false );
61  mCurveEditor->setCurve( *initialState.transformer()->curveTransform() );
62  }
63  }
64 
65  connect( computeValuesButton, &QPushButton::clicked, this, &QgsPropertyAssistantWidget::computeValuesFromLayer );
66 
67  if ( mLayer )
68  {
69  mLayerTreeLayer = new QgsLayerTreeLayer( const_cast< QgsVectorLayer * >( mLayer ) );
70  mRoot.addChildNode( mLayerTreeLayer ); // takes ownership
71  }
72  mLegendPreview->setModel( &mPreviewList );
73  mLegendPreview->setItemDelegate( new QgsAssistantPreviewItemDelegate( &mPreviewList ) );
74  mLegendPreview->setHeaderHidden( true );
75  mLegendPreview->expandAll();
76  mLegendVerticalFrame->setLayout( new QVBoxLayout() );
77  mLegendVerticalFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
78  mLegendVerticalFrame->layout()->setMargin( 0 );
79  mLegendVerticalFrame->hide();
80 
81  switch ( definition.standardTemplate() )
82  {
85  {
86  mTransformerWidget = new QgsPropertySizeAssistantWidget( this, mDefinition, initialState );
87  mLegendPreview->show();
88  break;
89  }
90 
93  {
94  mTransformerWidget = new QgsPropertyColorAssistantWidget( this, mDefinition, initialState );
95  mLegendPreview->show();
96  break;
97  }
98 
100  {
101  mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
102  break;
103  }
104 
105  default:
106  {
107  if ( mDefinition.dataType() == QgsPropertyDefinition::DataTypeNumeric )
108  {
109  mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
110  }
111  break;
112  }
113  }
114 
115  if ( mTransformerWidget )
116  {
117  mOutputWidget->layout()->addWidget( mTransformerWidget );
118  connect( mTransformerWidget, &QgsPropertyAbstractTransformerWidget::widgetChanged, this, &QgsPropertyAssistantWidget::widgetChanged );
119 
120  mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
121  mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
122 
123  mCurveEditor->setHistogramSource( mLayer, mExpressionWidget->currentField() );
124  connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & expression )
125  {
126  mCurveEditor->setHistogramSource( mLayer, expression );
127  }
128  );
129  connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMinHistogramValueRange );
130  connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMaxHistogramValueRange );
131  }
132  mTransformCurveCheckBox->setVisible( mTransformerWidget );
133 
134  connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
135  connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
136  connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
138  connect( this, &QgsPropertyAssistantWidget::widgetChanged, this, &QgsPropertyAssistantWidget::updatePreview );
139  updatePreview();
140 }
141 
143 {
144  mExpressionContextGenerator = generator;
145  mExpressionWidget->registerExpressionContextGenerator( generator );
146 }
147 
149 {
150  property.setActive( !mExpressionWidget->currentText().isEmpty() );
151  if ( mExpressionWidget->isExpression() )
152  property.setExpressionString( mExpressionWidget->currentField() );
153  else
154  property.setField( mExpressionWidget->currentField() );
155 
156  if ( mTransformerWidget )
157  {
158  std::unique_ptr< QgsPropertyTransformer> t( mTransformerWidget->createTransformer( minValueSpinBox->value(), maxValueSpinBox->value() ) );
159  if ( mTransformCurveCheckBox->isChecked() )
160  {
161  t->setCurveTransform( new QgsCurveTransform( mCurveEditor->curve() ) );
162  }
163  else
164  {
165  t->setCurveTransform( nullptr );
166  }
167  property.setTransformer( t.release() );
168  }
169 }
170 
172 {
174 
175  if ( dockMode && mLegendVerticalFrame->isHidden() )
176  {
177  mLegendVerticalFrame->layout()->addWidget( mLegendPreview );
178  mLegendVerticalFrame->show();
179  }
180 }
181 
182 void QgsPropertyAssistantWidget::computeValuesFromLayer()
183 {
184  if ( !mLayer )
185  return;
186 
187  double minValue = 0.0;
188  double maxValue = 0.0;
189 
190  if ( mExpressionWidget->isExpression() )
191  {
192  if ( !computeValuesFromExpression( mExpressionWidget->currentField(), minValue, maxValue ) )
193  return;
194  }
195  else
196  {
197  if ( !computeValuesFromField( mExpressionWidget->currentField(), minValue, maxValue ) )
198  return;
199  }
200 
201  whileBlocking( minValueSpinBox )->setValue( minValue );
202  whileBlocking( maxValueSpinBox )->setValue( maxValue );
203 
204  mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
205  mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
206 
207  emit widgetChanged();
208 }
209 
210 void QgsPropertyAssistantWidget::updatePreview()
211 {
212  if ( mLegendPreview->isHidden() || !mTransformerWidget || !mLayer ) // TODO - make this work OK without a layer
213  return;
214 
215  mLegendPreview->setIconSize( QSize( 512, 512 ) );
216  mPreviewList.clear();
217 
218  QList<double> breaks = QgsSymbolLayerUtils::prettyBreaks( minValueSpinBox->value(),
219  maxValueSpinBox->value(), 8 );
220 
221  QgsCurveTransform curve = mCurveEditor->curve();
222  QList< QgsSymbolLegendNode * > nodes = mTransformerWidget->generatePreviews( breaks, mLayerTreeLayer, mSymbol.get(), minValueSpinBox->value(),
223  maxValueSpinBox->value(), mTransformCurveCheckBox->isChecked() ? &curve : nullptr );
224 
225  int widthMax = 0;
226  int i = 0;
227  const auto constNodes = nodes;
228  for ( QgsSymbolLegendNode *node : constNodes )
229  {
230  const QSize minSize( node->minimumIconSize() );
231  node->setIconSize( minSize );
232  widthMax = std::max( minSize.width(), widthMax );
233  QStandardItem *item = new QStandardItem( node->data( Qt::DecorationRole ).value<QPixmap>(), QString::number( breaks[i] ) );
234  item->setEditable( false );
235  mPreviewList.appendRow( item );
236  delete node;
237  i++;
238  }
239  // center icon and align text left by giving icons the same width
240  // TODO maybe add some space so that icons don't touch
241  for ( int i = 0; i < breaks.length(); i++ )
242  {
243  QPixmap img( mPreviewList.item( i )->icon().pixmap( mPreviewList.item( i )->icon().actualSize( QSize( 512, 512 ) ) ) );
244  QPixmap enlarged( widthMax, img.height() );
245  // fill transparent and add original image
246  enlarged.fill( Qt::transparent );
247  QPainter p( &enlarged );
248  p.drawPixmap( QPoint( ( widthMax - img.width() ) / 2, 0 ), img );
249  p.end();
250  mPreviewList.item( i )->setIcon( enlarged );
251  }
252 }
253 
254 bool QgsPropertyAssistantWidget::computeValuesFromExpression( const QString &expression, double &minValue, double &maxValue ) const
255 {
256  QgsExpression e( expression );
257 
258  QgsExpressionContext context;
259  if ( mExpressionContextGenerator )
260  {
261  context = mExpressionContextGenerator->createExpressionContext();
262  }
263  else
264  {
268  }
269 
270  if ( !e.prepare( &context ) )
271  return false;
272 
273  QSet<QString> referencedCols( e.referencedColumns() );
274 
275  QgsFeatureIterator fit = mLayer->getFeatures(
276  QgsFeatureRequest().setFlags( e.needsGeometry()
279  .setSubsetOfAttributes( referencedCols, mLayer->fields() ) );
280 
281  // create list of non-null attribute values
282  double min = std::numeric_limits<double>::max();
283  double max = std::numeric_limits<double>::lowest();
284  QgsFeature f;
285  bool found = false;
286  while ( fit.nextFeature( f ) )
287  {
288  bool ok;
289  context.setFeature( f );
290  const double value = e.evaluate( &context ).toDouble( &ok );
291  if ( ok )
292  {
293  max = std::max( max, value );
294  min = std::min( min, value );
295  found = true;
296  }
297  }
298  if ( found )
299  {
300  minValue = min;
301  maxValue = max;
302  }
303  return found;
304 }
305 
306 bool QgsPropertyAssistantWidget::computeValuesFromField( const QString &fieldName, double &minValue, double &maxValue ) const
307 {
308  int fieldIndex = mLayer->fields().lookupField( fieldName );
309  if ( fieldIndex < 0 )
310  {
311  return false;
312  }
313 
314  bool ok = false;
315  double minDouble = mLayer->minimumValue( fieldIndex ).toDouble( &ok );
316  if ( !ok )
317  return false;
318 
319  double maxDouble = mLayer->maximumValue( fieldIndex ).toDouble( &ok );
320  if ( !ok )
321  return false;
322 
323  minValue = minDouble;
324  maxValue = maxDouble;
325  return true;
326 }
327 
329 
330 //
331 // QgsPropertySizeAssistantWidget
332 //
333 
334 QgsPropertySizeAssistantWidget::QgsPropertySizeAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
335  : QgsPropertyAbstractTransformerWidget( parent, definition )
336 {
337  setupUi( this );
338 
339  layout()->setContentsMargins( 0, 0, 0, 0 );
340  layout()->setMargin( 0 );
341 
342  if ( definition.standardTemplate() == QgsPropertyDefinition::Size )
343  {
344  scaleMethodComboBox->addItem( tr( "Flannery" ), QgsSizeScaleTransformer::Flannery );
345  scaleMethodComboBox->addItem( tr( "Surface" ), QgsSizeScaleTransformer::Area );
346  scaleMethodComboBox->addItem( tr( "Radius" ), QgsSizeScaleTransformer::Linear );
347  scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
348  }
349  else if ( definition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
350  {
351  scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
352  scaleMethodComboBox->addItem( tr( "Linear" ), QgsSizeScaleTransformer::Linear );
353  }
354 
355  minSizeSpinBox->setShowClearButton( false );
356  maxSizeSpinBox->setShowClearButton( false );
357  nullSizeSpinBox->setShowClearButton( false );
358 
359  if ( const QgsSizeScaleTransformer *sizeTransform = dynamic_cast< const QgsSizeScaleTransformer * >( initialState.transformer() ) )
360  {
361  minSizeSpinBox->setValue( sizeTransform->minSize() );
362  maxSizeSpinBox->setValue( sizeTransform->maxSize() );
363  nullSizeSpinBox->setValue( sizeTransform->nullSize() );
364  exponentSpinBox->setValue( sizeTransform->exponent() );
365  scaleMethodComboBox->setCurrentIndex( scaleMethodComboBox->findData( sizeTransform->type() ) );
366  }
367 
368  exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
369 
370  connect( minSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
371  connect( maxSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
372  connect( nullSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
373  connect( exponentSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
374  connect( scaleMethodComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
375  connect( scaleMethodComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this,
376  [ = ]
377  {
378  exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
379  }
380  );
381 }
382 
383 QgsSizeScaleTransformer *QgsPropertySizeAssistantWidget::createTransformer( double minValue, double maxValue ) const
384 {
386  static_cast< QgsSizeScaleTransformer::ScaleType >( scaleMethodComboBox->currentData().toInt() ),
387  minValue,
388  maxValue,
389  minSizeSpinBox->value(),
390  maxSizeSpinBox->value(),
391  nullSizeSpinBox->value(),
392  exponentSpinBox->value() );
393  return transformer;
394 }
395 
396 QList< QgsSymbolLegendNode * > QgsPropertySizeAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
397 {
398  QList< QgsSymbolLegendNode * > nodes;
399 
400  const QgsSymbol *legendSymbol = symbol;
401  std::unique_ptr< QgsSymbol > tempSymbol;
402 
403  if ( !legendSymbol )
404  {
405  if ( mDefinition.standardTemplate() == QgsPropertyDefinition::Size )
406  {
407  tempSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
408  }
409  else if ( mDefinition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
410  {
411  tempSymbol.reset( QgsLineSymbol::createSimple( QgsStringMap() ) );
412  }
413  legendSymbol = tempSymbol.get();
414  }
415  if ( !legendSymbol )
416  return nodes;
417 
418  std::unique_ptr< QgsSizeScaleTransformer > t( createTransformer( minValue, maxValue ) );
419  if ( curve )
420  t->setCurveTransform( new QgsCurveTransform( *curve ) );
421 
422  for ( int i = 0; i < breaks.length(); i++ )
423  {
424  std::unique_ptr< QgsSymbolLegendNode > node;
425  if ( dynamic_cast<const QgsMarkerSymbol *>( legendSymbol ) )
426  {
427  std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
428  symbolClone->setDataDefinedSize( QgsProperty() );
429  symbolClone->setDataDefinedAngle( QgsProperty() ); // to avoid symbol not being drawn
430  symbolClone->setSize( t->size( breaks[i] ) );
431  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
432  }
433  else if ( dynamic_cast<const QgsLineSymbol *>( legendSymbol ) )
434  {
435  std::unique_ptr< QgsLineSymbol > symbolClone( static_cast<QgsLineSymbol *>( legendSymbol->clone() ) );
436  symbolClone->setDataDefinedWidth( QgsProperty() );
437  symbolClone->setWidth( t->size( breaks[i] ) );
438  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
439  }
440  if ( node )
441  nodes << node.release();
442  }
443  return nodes;
444 }
445 
446 QList<QgsSymbolLegendNode *> QgsPropertyAbstractTransformerWidget::generatePreviews( const QList<double> &, QgsLayerTreeLayer *, const QgsSymbol *, double, double, QgsCurveTransform * ) const
447 {
448  return QList< QgsSymbolLegendNode * >();
449 }
450 
451 QgsPropertyColorAssistantWidget::QgsPropertyColorAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
452  : QgsPropertyAbstractTransformerWidget( parent, definition )
453 {
454  setupUi( this );
455 
456  layout()->setContentsMargins( 0, 0, 0, 0 );
457  layout()->setMargin( 0 );
458 
459  bool supportsAlpha = definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha;
460  mNullColorButton->setAllowOpacity( supportsAlpha );
461  mNullColorButton->setShowNoColor( true );
462  mNullColorButton->setColorDialogTitle( tr( "Color For Null Values" ) );
463  mNullColorButton->setContext( QStringLiteral( "symbology" ) );
464  mNullColorButton->setNoColorString( tr( "Transparent" ) );
465 
466  if ( const QgsColorRampTransformer *colorTransform = dynamic_cast< const QgsColorRampTransformer * >( initialState.transformer() ) )
467  {
468  mNullColorButton->setColor( colorTransform->nullColor() );
469  if ( colorTransform->colorRamp() )
470  mColorRampButton->setColorRamp( colorTransform->colorRamp() );
471  }
472 
473  connect( mNullColorButton, &QgsColorButton::colorChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
474  connect( mColorRampButton, &QgsColorRampButton::colorRampChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
475 
476  if ( !mColorRampButton->colorRamp() )
477  {
478  // set a default ramp
479  QString defaultRampName = QgsProject::instance()->readEntry( QStringLiteral( "DefaultStyles" ), QStringLiteral( "/ColorRamp" ), QString() );
480  std::unique_ptr< QgsColorRamp > defaultRamp( QgsStyle::defaultStyle()->colorRamp( !defaultRampName.isEmpty() ? defaultRampName : QStringLiteral( "Blues" ) ) );
481  if ( defaultRamp )
482  mColorRampButton->setColorRamp( defaultRamp.get() );
483  }
484 }
485 
486 QgsColorRampTransformer *QgsPropertyColorAssistantWidget::createTransformer( double minValue, double maxValue ) const
487 {
489  minValue,
490  maxValue,
491  mColorRampButton->colorRamp(),
492  mNullColorButton->color() );
493  return transformer;
494 }
495 
496 QList<QgsSymbolLegendNode *> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
497 {
498  QList< QgsSymbolLegendNode * > nodes;
499 
500  const QgsMarkerSymbol *legendSymbol = dynamic_cast<const QgsMarkerSymbol *>( symbol );
501  std::unique_ptr< QgsMarkerSymbol > tempSymbol;
502 
503  if ( !legendSymbol )
504  {
505  tempSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
506  legendSymbol = tempSymbol.get();
507  }
508  if ( !legendSymbol )
509  return nodes;
510 
511  std::unique_ptr< QgsColorRampTransformer > t( createTransformer( minValue, maxValue ) );
512  if ( curve )
513  t->setCurveTransform( new QgsCurveTransform( *curve ) );
514 
515  for ( int i = 0; i < breaks.length(); i++ )
516  {
517  std::unique_ptr< QgsSymbolLegendNode > node;
518  std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
519  symbolClone->setColor( t->color( breaks[i] ) );
520  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
521  if ( node )
522  nodes << node.release();
523  }
524  return nodes;
525 }
526 
527 QgsPropertyGenericNumericAssistantWidget::QgsPropertyGenericNumericAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
528  : QgsPropertyAbstractTransformerWidget( parent, definition )
529 {
530  setupUi( this );
531 
532  layout()->setContentsMargins( 0, 0, 0, 0 );
533  layout()->setMargin( 0 );
534 
535  nullOutputSpinBox->setShowClearButton( false );
536 
538  {
539  // tweak dialog for rotation
540  minOutputSpinBox->setMaximum( 360.0 );
541  minOutputSpinBox->setValue( 0.0 );
542  minOutputSpinBox->setShowClearButton( true );
543  minOutputSpinBox->setClearValue( 0.0 );
544  minOutputSpinBox->setSuffix( tr( " °" ) );
545  maxOutputSpinBox->setMaximum( 360.0 );
546  maxOutputSpinBox->setValue( 360.0 );
547  maxOutputSpinBox->setShowClearButton( true );
548  maxOutputSpinBox->setClearValue( 360.0 );
549  maxOutputSpinBox->setSuffix( tr( " °" ) );
550  exponentSpinBox->hide();
551  mExponentLabel->hide();
552  mLabelMinOutput->setText( tr( "Angle from" ) );
553  mLabelNullOutput->setText( tr( "Angle when NULL" ) );
554  }
555  else
556  {
557  minOutputSpinBox->setShowClearButton( false );
558  maxOutputSpinBox->setShowClearButton( false );
559  }
560 
561  if ( const QgsGenericNumericTransformer *transform = dynamic_cast< const QgsGenericNumericTransformer * >( initialState.transformer() ) )
562  {
563  minOutputSpinBox->setValue( transform->minOutputValue() );
564  maxOutputSpinBox->setValue( transform->maxOutputValue() );
565  nullOutputSpinBox->setValue( transform->nullOutputValue() );
566  exponentSpinBox->setValue( transform->exponent() );
567  }
568 
569  connect( minOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
570  connect( maxOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
571  connect( nullOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
572  connect( exponentSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
573 }
574 
575 QgsGenericNumericTransformer *QgsPropertyGenericNumericAssistantWidget::createTransformer( double minValue, double maxValue ) const
576 {
578  minValue,
579  maxValue,
580  minOutputSpinBox->value(),
581  maxOutputSpinBox->value(),
582  nullOutputSpinBox->value(),
583  exponentSpinBox->value() );
584  return transformer;
585 }
586 
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:142
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:107
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:369
qgsexpressioncontextutils.h
QgsProperty
A store for object properties.
Definition: qgsproperty.h:231
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:33
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:1418
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:264
qgslayertreelayer.h
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
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:171
QgsColorRampTransformer
QgsPropertyTransformer subclass for transforming a numeric value into a color from a color ramp.
Definition: qgspropertytransformer.h:608
QgsProject::readEntry
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Definition: qgsproject.cpp:2448
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:190
QgsSymbol
Definition: qgssymbol.h:63
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:1896
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:111
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:3280
QgsLegendSymbolItem
Definition: qgslegendsymbolitem.h:36
QgsFeatureRequest
Definition: qgsfeaturerequest.h:75
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:221
QgsFeatureRequest::NoFlags
@ NoFlags
Definition: qgsfeaturerequest.h:106
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:29
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
Definition: qgssymbol.h:917
QgsPropertyDefinition::ColorWithAlpha
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:65
QgsLayerTreeLayer
Definition: qgslayertreelayer.h:43
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:461
QgsSizeScaleTransformer::Flannery
@ Flannery
Flannery scaling method.
Definition: qgspropertytransformer.h:470
QgsPanelWidget::widgetChanged
void widgetChanged()
Emitted when the widget state changes.
QgsLineSymbol
Definition: qgssymbol.h:1117
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:4100
QgsPropertyDefinition
Definition for a property.
Definition: qgsproperty.h:47
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:4162
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:4157
QgsPropertyTransformer::maxValue
double maxValue() const
Returns the maximum value expected by the transformer.
Definition: qgspropertytransformer.h:263
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:148
QgsCurveTransform
Handles scaling of input values to output values by using a curve created from smoothly joining a num...
Definition: qgspropertytransformer.h:56
qgsvectorlayer.h
QgsPropertyDefinition::description
QString description() const
Descriptive name of the property.
Definition: qgsproperty.h:164
QgsPropertyTransformer::minValue
double minValue() const
Returns the minimum value expected by the transformer.
Definition: qgspropertytransformer.h:248
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:714
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:373
QgsVectorLayer
Definition: qgsvectorlayer.h:385
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:1429
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:42
qgspropertyassistantwidget.h
QgsGenericNumericTransformer
QgsPropertyTransformer subclass for scaling an input numeric value into an output numeric value.
Definition: qgspropertytransformer.h:343
QgsFeature
Definition: qgsfeature.h:55
QgsSizeScaleTransformer::ScaleType
ScaleType
Size scaling methods.
Definition: qgspropertytransformer.h:466
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:324
QgsExpression
Definition: qgsexpression.h:113
QgsPropertyTransformer::curveTransform
QgsCurveTransform * curveTransform() const
Returns the curve transform applied to input values before they are transformed by the individual tra...
Definition: qgspropertytransformer.h:278
QgsSymbolLegendNode
Definition: qgslayertreemodellegendnode.h:283
QgsFeatureIterator
Definition: qgsfeatureiterator.h:263
QgsFieldExpressionWidget
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
Definition: qgsfieldexpressionwidget.h:46
QgsExpressionContextGenerator
Definition: qgsexpressioncontextgenerator.h:36
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