QGIS API Documentation 3.27.0-Master (9c08adf5ef)
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 {
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
183void 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
211void 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
255bool 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
307bool 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
339QgsPropertySizeAssistantWidget::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
387QgsSizeScaleTransformer *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
400QList< 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
450QList<QgsSymbolLegendNode *> QgsPropertyAbstractTransformerWidget::generatePreviews( const QList<double> &, QgsLayerTreeLayer *, const QgsSymbol *, double, double, QgsCurveTransform * ) const
451{
452 return QList< QgsSymbolLegendNode * >();
453}
454
455QgsPropertyColorAssistantWidget::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
492QgsColorRampTransformer *QgsPropertyColorAssistantWidget::createTransformer( double minValue, double maxValue ) const
493{
495 minValue,
496 maxValue,
497 mColorRampButton->colorRamp(),
498 mNullColorButton->color() );
499 return transformer;
500}
501
502QList<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
533QgsPropertyGenericNumericAssistantWidget::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
637QgsGenericNumericTransformer *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
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
void colorRampChanged()
Emitted whenever a new color ramp is set for the button.
QgsPropertyTransformer subclass for transforming a numeric value into a color from a color ramp.
void setMaxHistogramValueRange(double maxValueRange)
Sets the maximum expected value for the range of values shown in the histogram.
void changed()
Emitted when the widget curve changes.
void setMinHistogramValueRange(double minValueRange)
Sets the minimum expected value for the range of values shown in the histogram.
Handles scaling of input values to output values by using a curve created from smoothly joining a num...
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
Abstract interface for generating an expression context.
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Class for parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
@ Numeric
All numeric fields.
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:349
QgsPropertyTransformer subclass for scaling an input numeric value into an output numeric value.
void addChildNode(QgsLayerTreeNode *node)
Append an existing node.
Layer tree node points to a map layer.
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
static QgsLineSymbol * createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
A marker symbol type, for rendering Point and MultiPoint geometries.
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Base class for any widget that can be shown as a inline panel.
void widgetChanged()
Emitted when the widget state changes.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
bool dockMode()
Returns the dock mode state.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
QgsPropertyAssistantWidget(QWidget *parent=nullptr, const QgsPropertyDefinition &definition=QgsPropertyDefinition(), const QgsProperty &initialState=QgsProperty(), const QgsVectorLayer *layer=nullptr)
Constructor for QgsPropertyAssistantWidget.
void updateProperty(QgsProperty &property)
Updates a property in place to corresponding to the current settings shown in the widget.
Definition for a property.
Definition: qgsproperty.h:47
StandardPropertyTemplate standardTemplate() const
Returns the property's standard template, if applicable.
Definition: qgsproperty.h:194
DataType dataType() const
Returns the allowable field/value data type for the property.
Definition: qgsproperty.h:188
QString description() const
Descriptive name of the property.
Definition: qgsproperty.h:163
@ Double
Double value (including negative values)
Definition: qgsproperty.h:57
@ Double0To1
Double value between 0-1 (inclusive)
Definition: qgsproperty.h:59
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:72
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
Definition: qgsproperty.h:56
@ IntegerPositive
Positive integer values (including 0)
Definition: qgsproperty.h:55
@ Opacity
Opacity (0-100)
Definition: qgsproperty.h:62
@ ColorNoAlpha
Color with no alpha channel.
Definition: qgsproperty.h:65
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:60
@ Size
1D size (eg marker radius, or square marker height/width)
Definition: qgsproperty.h:69
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:64
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:58
@ DataTypeNumeric
Property requires a numeric value.
Definition: qgsproperty.h:99
A store for object properties.
Definition: qgsproperty.h:231
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
Definition: qgsproperty.h:240
QString expressionString() const
Returns the expression used for the property value.
QString field() const
Returns the current field name the property references.
const QgsPropertyTransformer * transformer() const
Returns the existing transformer used for manipulating the calculated values for the property,...
Type propertyType() const
Returns the property type.
QgsPropertyTransformer subclass for scaling a value into a size according to various scaling methods.
ScaleType
Size scaling methods.
@ Exponential
Scale using set exponent.
@ Flannery
Flannery scaling method.
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:145
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...
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:93
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
void minimumAndMaximumValue(int index, QVariant &minimum, QVariant &maximum) const
Calculates both the minimum and maximum value for an attribute column.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2330