QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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"
22 #include "qgsmapsettings.h"
23 #include "qgsvectorlayer.h"
24 #include "qgslayertreelayer.h"
25 #include "qgssymbollayerutils.h"
27 #include "qgsstyle.h"
28 #include "qgsmarkersymbol.h"
29 #include "qgslinesymbol.h"
30 
32  const QgsPropertyDefinition &definition, const QgsProperty &initialState,
33  const QgsVectorLayer *layer )
34  : QgsPanelWidget( parent )
35  , mDefinition( definition )
36  , mLayer( layer )
37 {
38  setupUi( this );
39 
40  layout()->setContentsMargins( 0, 0, 0, 0 );
41 
42  setPanelTitle( mDefinition.description() );
43 
44  mLegendPreview->hide();
45 
46  minValueSpinBox->setShowClearButton( false );
47  maxValueSpinBox->setShowClearButton( false );
48 
49  // TODO expression widget shouldn't require a non-const layer
50  mExpressionWidget->setLayer( const_cast< QgsVectorLayer * >( mLayer ) );
51  mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric );
52  mExpressionWidget->setField( initialState.propertyType() == QgsProperty::ExpressionBasedProperty ? initialState.expressionString() : initialState.field() );
53 
54  if ( auto *lTransformer = initialState.transformer() )
55  {
56  minValueSpinBox->setValue( lTransformer->minValue() );
57  maxValueSpinBox->setValue( lTransformer->maxValue() );
58 
59  if ( lTransformer->curveTransform() )
60  {
61  mTransformCurveCheckBox->setChecked( true );
62  mTransformCurveCheckBox->setCollapsed( false );
63  mCurveEditor->setCurve( *lTransformer->curveTransform() );
64  }
65  }
66 
67  connect( computeValuesButton, &QPushButton::clicked, this, &QgsPropertyAssistantWidget::computeValuesFromLayer );
68 
69  if ( mLayer )
70  {
71  mLayerTreeLayer = new QgsLayerTreeLayer( const_cast< QgsVectorLayer * >( mLayer ) );
72  mRoot.addChildNode( mLayerTreeLayer ); // takes ownership
73  }
74  mLegendPreview->setModel( &mPreviewList );
75  mLegendPreview->setItemDelegate( new QgsAssistantPreviewItemDelegate( &mPreviewList ) );
76  mLegendPreview->setHeaderHidden( true );
77  mLegendPreview->expandAll();
78  mLegendVerticalFrame->setLayout( new QVBoxLayout() );
79  mLegendVerticalFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
80  mLegendVerticalFrame->hide();
81 
82  switch ( definition.standardTemplate() )
83  {
86  {
87  mTransformerWidget = new QgsPropertySizeAssistantWidget( this, mDefinition, initialState );
88  mLegendPreview->show();
89  break;
90  }
91 
94  {
95  mTransformerWidget = new QgsPropertyColorAssistantWidget( this, mDefinition, initialState );
96  mLegendPreview->show();
97  break;
98  }
99 
101  {
102  mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
103  break;
104  }
105 
106  default:
107  {
108  if ( mDefinition.dataType() == QgsPropertyDefinition::DataTypeNumeric )
109  {
110  mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
111  }
112  break;
113  }
114  }
115 
116  if ( mTransformerWidget )
117  {
118  mOutputWidget->layout()->addWidget( mTransformerWidget );
119  connect( mTransformerWidget, &QgsPropertyAbstractTransformerWidget::widgetChanged, this, &QgsPropertyAssistantWidget::widgetChanged );
120 
121  mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
122  mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
123 
124  mCurveEditor->setHistogramSource( mLayer, mExpressionWidget->currentField() );
125  connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & expression )
126  {
127  mCurveEditor->setHistogramSource( mLayer, expression );
128  }
129  );
130  connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMinHistogramValueRange );
131  connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMaxHistogramValueRange );
132  }
133  mTransformCurveCheckBox->setVisible( mTransformerWidget );
134 
135  connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
136  connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
137  connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
139  connect( this, &QgsPropertyAssistantWidget::widgetChanged, this, &QgsPropertyAssistantWidget::updatePreview );
140  updatePreview();
141 }
142 
144 {
145  mExpressionContextGenerator = generator;
146  mExpressionWidget->registerExpressionContextGenerator( generator );
147 }
148 
150 {
151  property.setActive( !mExpressionWidget->currentText().isEmpty() );
152  if ( mExpressionWidget->isExpression() )
153  property.setExpressionString( mExpressionWidget->currentField() );
154  else
155  property.setField( mExpressionWidget->currentField() );
156 
157  if ( mTransformerWidget )
158  {
159  std::unique_ptr< QgsPropertyTransformer> t( mTransformerWidget->createTransformer( minValueSpinBox->value(), maxValueSpinBox->value() ) );
160  if ( mTransformCurveCheckBox->isChecked() )
161  {
162  t->setCurveTransform( new QgsCurveTransform( mCurveEditor->curve() ) );
163  }
164  else
165  {
166  t->setCurveTransform( nullptr );
167  }
168  property.setTransformer( t.release() );
169  }
170 }
171 
173 {
175 
176  if ( dockMode && mLegendVerticalFrame->isHidden() )
177  {
178  mLegendVerticalFrame->layout()->addWidget( mLegendPreview );
179  mLegendVerticalFrame->show();
180  }
181 }
182 
183 void QgsPropertyAssistantWidget::computeValuesFromLayer()
184 {
185  if ( !mLayer )
186  return;
187 
188  double minValue = 0.0;
189  double maxValue = 0.0;
190 
191  if ( mExpressionWidget->isExpression() )
192  {
193  if ( !computeValuesFromExpression( mExpressionWidget->currentField(), minValue, maxValue ) )
194  return;
195  }
196  else
197  {
198  if ( !computeValuesFromField( mExpressionWidget->currentField(), minValue, maxValue ) )
199  return;
200  }
201 
202  whileBlocking( minValueSpinBox )->setValue( minValue );
203  whileBlocking( maxValueSpinBox )->setValue( maxValue );
204 
205  mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
206  mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
207 
208  emit widgetChanged();
209 }
210 
211 void QgsPropertyAssistantWidget::updatePreview()
212 {
213  if ( mLegendPreview->isHidden() || !mTransformerWidget || !mLayer ) // TODO - make this work OK without a layer
214  return;
215 
216  mLegendPreview->setIconSize( QSize( 512, 512 ) );
217  mPreviewList.clear();
218 
219  QList<double> breaks = QgsSymbolLayerUtils::prettyBreaks( minValueSpinBox->value(),
220  maxValueSpinBox->value(), 8 );
221 
222  QgsCurveTransform curve = mCurveEditor->curve();
223  const QList< QgsSymbolLegendNode * > nodes = mTransformerWidget->generatePreviews( breaks, mLayerTreeLayer, mSymbol.get(), minValueSpinBox->value(),
224  maxValueSpinBox->value(), mTransformCurveCheckBox->isChecked() ? &curve : nullptr );
225 
226  int widthMax = 0;
227  int i = 0;
228  const auto constNodes = nodes;
229  for ( QgsSymbolLegendNode *node : constNodes )
230  {
231  const QSize minSize( node->minimumIconSize() );
232  node->setIconSize( minSize );
233  widthMax = std::max( minSize.width(), widthMax );
234  QStandardItem *item = new QStandardItem( node->data( Qt::DecorationRole ).value<QPixmap>(), QLocale().toString( breaks[i] ) );
235  item->setEditable( false );
236  mPreviewList.appendRow( item );
237  delete node;
238  i++;
239  }
240  // center icon and align text left by giving icons the same width
241  // TODO maybe add some space so that icons don't touch
242  for ( int i = 0; i < breaks.length(); i++ )
243  {
244  const QPixmap img( mPreviewList.item( i )->icon().pixmap( mPreviewList.item( i )->icon().actualSize( QSize( 512, 512 ) ) ) );
245  QPixmap enlarged( widthMax, img.height() );
246  // fill transparent and add original image
247  enlarged.fill( Qt::transparent );
248  QPainter p( &enlarged );
249  p.drawPixmap( QPoint( ( widthMax - img.width() ) / 2, 0 ), img );
250  p.end();
251  mPreviewList.item( i )->setIcon( enlarged );
252  }
253 }
254 
255 bool QgsPropertyAssistantWidget::computeValuesFromExpression( const QString &expression, double &minValue, double &maxValue ) const
256 {
257  QgsExpression e( expression );
258 
259  QgsExpressionContext context;
260  if ( mExpressionContextGenerator )
261  {
262  context = mExpressionContextGenerator->createExpressionContext();
263  }
264  else
265  {
269  }
270 
271  if ( !e.prepare( &context ) )
272  return false;
273 
274  const QSet<QString> referencedCols( e.referencedColumns() );
275 
276  QgsFeatureIterator fit = mLayer->getFeatures(
277  QgsFeatureRequest().setFlags( e.needsGeometry()
280  .setSubsetOfAttributes( referencedCols, mLayer->fields() ) );
281 
282  // create list of non-null attribute values
283  double min = std::numeric_limits<double>::max();
284  double max = std::numeric_limits<double>::lowest();
285  QgsFeature f;
286  bool found = false;
287  while ( fit.nextFeature( f ) )
288  {
289  bool ok;
290  context.setFeature( f );
291  const double value = e.evaluate( &context ).toDouble( &ok );
292  if ( ok )
293  {
294  max = std::max( max, value );
295  min = std::min( min, value );
296  found = true;
297  }
298  }
299  if ( found )
300  {
301  minValue = min;
302  maxValue = max;
303  }
304  return found;
305 }
306 
307 bool QgsPropertyAssistantWidget::computeValuesFromField( const QString &fieldName, double &minValue, double &maxValue ) const
308 {
309  const int fieldIndex = mLayer->fields().lookupField( fieldName );
310  if ( fieldIndex < 0 )
311  {
312  return false;
313  }
314 
315  QVariant min;
316  QVariant max;
317  mLayer->minimumAndMaximumValue( fieldIndex, min, max );
318 
319  bool ok = false;
320  const double minDouble = min.toDouble( &ok );
321  if ( !ok )
322  return false;
323 
324  const double maxDouble = max.toDouble( &ok );
325  if ( !ok )
326  return false;
327 
328  minValue = minDouble;
329  maxValue = maxDouble;
330  return true;
331 }
332 
334 
335 //
336 // QgsPropertySizeAssistantWidget
337 //
338 
339 QgsPropertySizeAssistantWidget::QgsPropertySizeAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
340  : QgsPropertyAbstractTransformerWidget( parent, definition )
341 {
342  setupUi( this );
343 
344  layout()->setContentsMargins( 0, 0, 0, 0 );
345 
346  if ( definition.standardTemplate() == QgsPropertyDefinition::Size )
347  {
348  scaleMethodComboBox->addItem( tr( "Flannery" ), QgsSizeScaleTransformer::Flannery );
349  scaleMethodComboBox->addItem( tr( "Surface" ), QgsSizeScaleTransformer::Area );
350  scaleMethodComboBox->addItem( tr( "Radius" ), QgsSizeScaleTransformer::Linear );
351  scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
352  }
353  else if ( definition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
354  {
355  scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
356  scaleMethodComboBox->addItem( tr( "Linear" ), QgsSizeScaleTransformer::Linear );
357  }
358 
359  minSizeSpinBox->setShowClearButton( false );
360  maxSizeSpinBox->setShowClearButton( false );
361  nullSizeSpinBox->setShowClearButton( false );
362 
363  if ( const QgsSizeScaleTransformer *sizeTransform = dynamic_cast< const QgsSizeScaleTransformer * >( initialState.transformer() ) )
364  {
365  minSizeSpinBox->setValue( sizeTransform->minSize() );
366  maxSizeSpinBox->setValue( sizeTransform->maxSize() );
367  nullSizeSpinBox->setValue( sizeTransform->nullSize() );
368  exponentSpinBox->setValue( sizeTransform->exponent() );
369  scaleMethodComboBox->setCurrentIndex( scaleMethodComboBox->findData( sizeTransform->type() ) );
370  }
371 
372  exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
373 
374  connect( minSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
375  connect( maxSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
376  connect( nullSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
377  connect( exponentSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
378  connect( scaleMethodComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
379  connect( scaleMethodComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this,
380  [ = ]
381  {
382  exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
383  }
384  );
385 }
386 
387 QgsSizeScaleTransformer *QgsPropertySizeAssistantWidget::createTransformer( double minValue, double maxValue ) const
388 {
390  static_cast< QgsSizeScaleTransformer::ScaleType >( scaleMethodComboBox->currentData().toInt() ),
391  minValue,
392  maxValue,
393  minSizeSpinBox->value(),
394  maxSizeSpinBox->value(),
395  nullSizeSpinBox->value(),
396  exponentSpinBox->value() );
397  return transformer;
398 }
399 
400 QList< QgsSymbolLegendNode * > QgsPropertySizeAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
401 {
402  QList< QgsSymbolLegendNode * > nodes;
403 
404  const QgsSymbol *legendSymbol = symbol;
405  std::unique_ptr< QgsSymbol > tempSymbol;
406 
407  if ( !legendSymbol )
408  {
409  if ( mDefinition.standardTemplate() == QgsPropertyDefinition::Size )
410  {
411  tempSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
412  }
413  else if ( mDefinition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
414  {
415  tempSymbol.reset( QgsLineSymbol::createSimple( QVariantMap() ) );
416  }
417  legendSymbol = tempSymbol.get();
418  }
419  if ( !legendSymbol )
420  return nodes;
421 
422  std::unique_ptr< QgsSizeScaleTransformer > t( createTransformer( minValue, maxValue ) );
423  if ( curve )
424  t->setCurveTransform( new QgsCurveTransform( *curve ) );
425 
426  for ( int i = 0; i < breaks.length(); i++ )
427  {
428  std::unique_ptr< QgsSymbolLegendNode > node;
429  if ( dynamic_cast<const QgsMarkerSymbol *>( legendSymbol ) )
430  {
431  std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
432  symbolClone->setDataDefinedSize( QgsProperty() );
433  symbolClone->setDataDefinedAngle( QgsProperty() ); // to avoid symbol not being drawn
434  symbolClone->setSize( t->size( breaks[i] ) );
435  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
436  }
437  else if ( dynamic_cast<const QgsLineSymbol *>( legendSymbol ) )
438  {
439  std::unique_ptr< QgsLineSymbol > symbolClone( static_cast<QgsLineSymbol *>( legendSymbol->clone() ) );
440  symbolClone->setDataDefinedWidth( QgsProperty() );
441  symbolClone->setWidth( t->size( breaks[i] ) );
442  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
443  }
444  if ( node )
445  nodes << node.release();
446  }
447  return nodes;
448 }
449 
450 QList<QgsSymbolLegendNode *> QgsPropertyAbstractTransformerWidget::generatePreviews( const QList<double> &, QgsLayerTreeLayer *, const QgsSymbol *, double, double, QgsCurveTransform * ) const
451 {
452  return QList< QgsSymbolLegendNode * >();
453 }
454 
455 QgsPropertyColorAssistantWidget::QgsPropertyColorAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
456  : QgsPropertyAbstractTransformerWidget( parent, definition )
457 {
458  setupUi( this );
459 
460  layout()->setContentsMargins( 0, 0, 0, 0 );
461 
462  const bool supportsAlpha = definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha;
463  mNullColorButton->setAllowOpacity( supportsAlpha );
464  mNullColorButton->setShowNoColor( true );
465  mNullColorButton->setColorDialogTitle( tr( "Color For Null Values" ) );
466  mNullColorButton->setContext( QStringLiteral( "symbology" ) );
467  mNullColorButton->setNoColorString( tr( "Transparent" ) );
468 
469  if ( const QgsColorRampTransformer *colorTransform = dynamic_cast< const QgsColorRampTransformer * >( initialState.transformer() ) )
470  {
471  mNullColorButton->setColor( colorTransform->nullColor() );
472  if ( colorTransform->colorRamp() )
473  mColorRampButton->setColorRamp( colorTransform->colorRamp() );
474  }
475 
476  connect( mNullColorButton, &QgsColorButton::colorChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
477  connect( mColorRampButton, &QgsColorRampButton::colorRampChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
478 
479  if ( !mColorRampButton->colorRamp() )
480  {
481  // set a default ramp
482  std::unique_ptr< QgsColorRamp > colorRamp( QgsProject::instance()->styleSettings()->defaultColorRamp() );
483  if ( !colorRamp )
484  {
485  colorRamp.reset( QgsStyle::defaultStyle()->colorRamp( QStringLiteral( "Blues" ) ) );
486  }
487  if ( colorRamp )
488  mColorRampButton->setColorRamp( colorRamp.get() );
489  }
490 }
491 
492 QgsColorRampTransformer *QgsPropertyColorAssistantWidget::createTransformer( double minValue, double maxValue ) const
493 {
495  minValue,
496  maxValue,
497  mColorRampButton->colorRamp(),
498  mNullColorButton->color() );
499  return transformer;
500 }
501 
502 QList<QgsSymbolLegendNode *> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
503 {
504  QList< QgsSymbolLegendNode * > nodes;
505 
506  const QgsMarkerSymbol *legendSymbol = dynamic_cast<const QgsMarkerSymbol *>( symbol );
507  std::unique_ptr< QgsMarkerSymbol > tempSymbol;
508 
509  if ( !legendSymbol )
510  {
511  tempSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
512  legendSymbol = tempSymbol.get();
513  }
514  if ( !legendSymbol )
515  return nodes;
516 
517  std::unique_ptr< QgsColorRampTransformer > t( createTransformer( minValue, maxValue ) );
518  if ( curve )
519  t->setCurveTransform( new QgsCurveTransform( *curve ) );
520 
521  for ( int i = 0; i < breaks.length(); i++ )
522  {
523  std::unique_ptr< QgsSymbolLegendNode > node;
524  std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
525  symbolClone->setColor( t->color( breaks[i] ) );
526  node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
527  if ( node )
528  nodes << node.release();
529  }
530  return nodes;
531 }
532 
533 QgsPropertyGenericNumericAssistantWidget::QgsPropertyGenericNumericAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
534  : QgsPropertyAbstractTransformerWidget( parent, definition )
535 {
536  setupUi( this );
537 
538  layout()->setContentsMargins( 0, 0, 0, 0 );
539 
540  nullOutputSpinBox->setShowClearButton( false );
541 
542  switch ( definition.standardTemplate() )
543  {
545  {
546  // tweak dialog for rotation
547  minOutputSpinBox->setMaximum( 360.0 );
548  minOutputSpinBox->setValue( 0.0 );
549  minOutputSpinBox->setShowClearButton( true );
550  minOutputSpinBox->setClearValue( 0.0 );
551  minOutputSpinBox->setSuffix( tr( " °" ) );
552  maxOutputSpinBox->setMaximum( 360.0 );
553  maxOutputSpinBox->setValue( 360.0 );
554  maxOutputSpinBox->setShowClearButton( true );
555  maxOutputSpinBox->setClearValue( 360.0 );
556  maxOutputSpinBox->setSuffix( tr( " °" ) );
557  exponentSpinBox->hide();
558  mExponentLabel->hide();
559  mLabelMinOutput->setText( tr( "Angle from" ) );
560  mLabelNullOutput->setText( tr( "Angle when NULL" ) );
561  break;
562  }
563 
565  {
566  // tweak dialog for opacity
567  minOutputSpinBox->setMaximum( 100.0 );
568  minOutputSpinBox->setValue( 0.0 );
569  minOutputSpinBox->setShowClearButton( true );
570  minOutputSpinBox->setClearValue( 0.0 );
571  minOutputSpinBox->setSuffix( tr( " %" ) );
572  maxOutputSpinBox->setMaximum( 100.0 );
573  maxOutputSpinBox->setValue( 100.0 );
574  maxOutputSpinBox->setShowClearButton( true );
575  maxOutputSpinBox->setClearValue( 100.0 );
576  maxOutputSpinBox->setSuffix( tr( " %" ) );
577  mLabelMinOutput->setText( tr( "Opacity from" ) );
578  mLabelNullOutput->setText( tr( "Opacity when NULL" ) );
579  break;
580  }
581 
584  minOutputSpinBox->setMinimum( 0 );
585  maxOutputSpinBox->setMinimum( 0 );
586  minOutputSpinBox->setShowClearButton( false );
587  maxOutputSpinBox->setShowClearButton( false );
588  break;
589 
591  minOutputSpinBox->setMinimum( 1 );
592  maxOutputSpinBox->setMinimum( 1 );
593  minOutputSpinBox->setShowClearButton( false );
594  maxOutputSpinBox->setShowClearButton( false );
595  break;
596 
598  minOutputSpinBox->setMinimum( 0 );
599  maxOutputSpinBox->setMinimum( 0 );
600  minOutputSpinBox->setMaximum( 1 );
601  maxOutputSpinBox->setMaximum( 1 );
602  minOutputSpinBox->setShowClearButton( false );
603  maxOutputSpinBox->setShowClearButton( false );
604  break;
605 
607  minOutputSpinBox->setMinimum( -99999999.000000 );
608  maxOutputSpinBox->setMinimum( -99999999.000000 );
609  minOutputSpinBox->setMaximum( 99999999.000000 );
610  maxOutputSpinBox->setMaximum( 99999999.000000 );
611  minOutputSpinBox->setShowClearButton( false );
612  maxOutputSpinBox->setShowClearButton( false );
613  break;
614 
615  default:
616  {
617  minOutputSpinBox->setShowClearButton( false );
618  maxOutputSpinBox->setShowClearButton( false );
619  break;
620  }
621  }
622 
623  if ( const QgsGenericNumericTransformer *transform = dynamic_cast< const QgsGenericNumericTransformer * >( initialState.transformer() ) )
624  {
625  minOutputSpinBox->setValue( transform->minOutputValue() );
626  maxOutputSpinBox->setValue( transform->maxOutputValue() );
627  nullOutputSpinBox->setValue( transform->nullOutputValue() );
628  exponentSpinBox->setValue( transform->exponent() );
629  }
630 
631  connect( minOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
632  connect( maxOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
633  connect( nullOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
634  connect( exponentSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
635 }
636 
637 QgsGenericNumericTransformer *QgsPropertyGenericNumericAssistantWidget::createTransformer( double minValue, double maxValue ) const
638 {
640  minValue,
641  maxValue,
642  minOutputSpinBox->value(),
643  maxOutputSpinBox->value(),
644  nullOutputSpinBox->value(),
645  exponentSpinBox->value() );
646  return transformer;
647 }
648 
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:143
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:115
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:1052
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:406
qgsexpressioncontextutils.h
QgsProperty
A store for object properties.
Definition: qgsproperty.h:230
qgsprojectstylesettings.h
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:40
QgsVectorLayer::minimumAndMaximumValue
void minimumAndMaximumValue(int index, QVariant &minimum, QVariant &maximum) const
Calculates both the minimum and maximum value for an attribute column.
Definition: qgsvectorlayer.cpp:4384
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
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:334
qgslayertreelayer.h
QgsPropertyDefinition::IntegerPositiveGreaterZero
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
Definition: qgsproperty.h:56
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsPropertyDefinition::DataTypeNumeric
@ DataTypeNumeric
Property requires a numeric value.
Definition: qgsproperty.h:99
QgsPropertyDefinition::Double
@ Double
Double value (including negative values)
Definition: qgsproperty.h:57
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:172
QgsColorRampTransformer
QgsPropertyTransformer subclass for transforming a numeric value into a color from a color ramp.
Definition: qgspropertytransformer.h:608
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:228
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:92
QgsProperty::propertyType
Type propertyType() const
Returns the property type.
Definition: qgsproperty.cpp:286
QgsCurveEditorWidget::setMaxHistogramValueRange
void setMaxHistogramValueRange(double maxValueRange)
Sets the maximum expected value for the range of values shown in the histogram.
Definition: qgscurveeditorwidget.cpp:148
qgsmapsettings.h
QgsProperty::transformer
const QgsPropertyTransformer * transformer() const
Returns the existing transformer used for manipulating the calculated values for the property,...
Definition: qgsproperty.cpp:871
QgsPanelWidget::dockMode
bool dockMode()
Returns the dock mode state.
Definition: qgspanelwidget.h:93
QgsLineSymbol::createSimple
static QgsLineSymbol * createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
Definition: qgslinesymbol.cpp:22
QgsProperty::expressionString
QString expressionString() const
Returns the expression used for the property value.
Definition: qgsproperty.cpp:389
QgsMarkerSymbol::clone
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgsmarkersymbol.cpp:523
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:145
QgsPropertyDefinition::Rotation
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:60
QgsPropertyDefinition::dataType
DataType dataType() const
Returns the allowable field/value data type for the property.
Definition: qgsproperty.h:188
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3436
QgsLegendSymbolItem
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
Definition: qgslegendsymbolitem.h:36
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
QgsProperty::ExpressionBasedProperty
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
Definition: qgsproperty.h:240
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:291
QgsFeatureRequest::NoFlags
@ NoFlags
Definition: qgsfeaturerequest.h:114
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:2191
QgsMarkerSymbol
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgsmarkersymbol.h:30
QgsPropertyDefinition::ColorWithAlpha
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:64
QgsLayerTreeLayer
Layer tree node points to a map layer.
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
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:29
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:4580
QgsPropertyDefinition
Definition for a property.
Definition: qgsproperty.h:46
QgsExpressionContextGenerator::createExpressionContext
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QgsPropertyDefinition::standardTemplate
StandardPropertyTemplate standardTemplate() const
Returns the property's standard template, if applicable.
Definition: qgsproperty.h:194
QgsPanelWidget::setPanelTitle
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
Definition: qgspanelwidget.h:44
QgsPropertyDefinition::Double0To1
@ Double0To1
Double value between 0-1 (inclusive)
Definition: qgsproperty.h:59
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:149
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::IntegerPositive
@ IntegerPositive
Positive integer values (including 0)
Definition: qgsproperty.h:55
QgsPropertyDefinition::description
QString description() const
Descriptive name of the property.
Definition: qgsproperty.h:163
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:69
QgsPropertyAssistantWidget::QgsPropertyAssistantWidget
QgsPropertyAssistantWidget(QWidget *parent=nullptr, const QgsPropertyDefinition &definition=QgsPropertyDefinition(), const QgsProperty &initialState=QgsProperty(), const QgsVectorLayer *layer=nullptr)
Constructor for QgsPropertyAssistantWidget.
Definition: qgspropertyassistantwidget.cpp:31
QgsCurveEditorWidget::setMinHistogramValueRange
void setMinHistogramValueRange(double minValueRange)
Sets the minimum expected value for the range of values shown in the histogram.
Definition: qgscurveeditorwidget.cpp:142
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:399
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsLayerTreeGroup::addChildNode
void addChildNode(QgsLayerTreeNode *node)
Append an existing node.
Definition: qgslayertreegroup.cpp:143
qgsmarkersymbol.h
QgsProperty::field
QString field() const
Returns the current field name the property references.
Definition: qgsproperty.cpp:357
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
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsPropertyDefinition::Opacity
@ Opacity
Opacity (0-100)
Definition: qgsproperty.h:62
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:349
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings")....
Definition: qgsexpression.h:102
QgsSymbolLegendNode
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Definition: qgslayertreemodellegendnode.h:358
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
QgsFieldExpressionWidget
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
Definition: qgsfieldexpressionwidget.h:46
QgsExpressionContextGenerator
Abstract interface for generating an expression context.
Definition: qgsexpressioncontextgenerator.h:36
QgsMarkerSymbol::createSimple
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Definition: qgsmarkersymbol.cpp:22
QgsPropertyDefinition::StrokeWidth
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:72
qgsproject.h
QgsPropertyDefinition::ColorNoAlpha
@ ColorNoAlpha
Color with no alpha channel.
Definition: qgsproperty.h:65
qgslinesymbol.h
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:525
QgsPropertyDefinition::DoublePositive
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:58