QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
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 "moc_qgspropertyassistantwidget.cpp"
21#include "qgsproject.h"
23#include "qgsmapsettings.h"
24#include "qgsvectorlayer.h"
25#include "qgslayertreelayer.h"
26#include "qgssymbollayerutils.h"
28#include "qgsstyle.h"
29#include "qgsmarkersymbol.h"
30#include "qgslinesymbol.h"
31#include "qgsstringutils.h"
32#include "qgsgui.h"
33
35 const QgsPropertyDefinition &definition, const QgsProperty &initialState,
36 const QgsVectorLayer *layer )
37 : QgsPanelWidget( parent )
38 , mDefinition( definition )
39 , mLayer( layer )
40{
41 setupUi( this );
42
43 layout()->setContentsMargins( 0, 0, 0, 0 );
44
46
47 mLegendPreview->hide();
48
49 minValueSpinBox->setShowClearButton( false );
50 maxValueSpinBox->setShowClearButton( false );
51
52 // TODO expression widget shouldn't require a non-const layer
53 mExpressionWidget->setLayer( const_cast< QgsVectorLayer * >( mLayer ) );
54 mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric );
55 mExpressionWidget->setField( initialState.propertyType() == Qgis::PropertyType::Expression ? initialState.expressionString() : initialState.field() );
56
57 if ( auto *lTransformer = initialState.transformer() )
58 {
59 minValueSpinBox->setValue( lTransformer->minValue() );
60 maxValueSpinBox->setValue( lTransformer->maxValue() );
61
62 if ( lTransformer->curveTransform() )
63 {
64 mTransformCurveCheckBox->setChecked( true );
65 mTransformCurveCheckBox->setCollapsed( false );
66 mCurveEditor->setCurve( *lTransformer->curveTransform() );
67 }
68 }
69
70 connect( computeValuesButton, &QPushButton::clicked, this, &QgsPropertyAssistantWidget::computeValuesFromLayer );
71
72 if ( mLayer )
73 {
74 mLayerTreeLayer = new QgsLayerTreeLayer( const_cast< QgsVectorLayer * >( mLayer ) );
75 mRoot.addChildNode( mLayerTreeLayer ); // takes ownership
76 }
77 mLegendPreview->setModel( &mPreviewList );
78 mLegendPreview->setItemDelegate( new QgsAssistantPreviewItemDelegate( &mPreviewList ) );
79 mLegendPreview->setHeaderHidden( true );
80 mLegendPreview->expandAll();
81 mLegendVerticalFrame->setLayout( new QVBoxLayout() );
82 mLegendVerticalFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
83 mLegendVerticalFrame->hide();
84
85 switch ( definition.standardTemplate() )
86 {
89 {
90 mTransformerWidget = new QgsPropertySizeAssistantWidget( this, mDefinition, initialState );
91 mLegendPreview->show();
92 break;
93 }
94
97 {
98 mTransformerWidget = new QgsPropertyColorAssistantWidget( this, mDefinition, initialState );
99 mLegendPreview->show();
100 break;
101 }
102
104 {
105 mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
106 break;
107 }
108
109 default:
110 {
112 {
113 mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
114 }
115 break;
116 }
117 }
118
119 if ( mTransformerWidget )
120 {
121 mOutputWidget->layout()->addWidget( mTransformerWidget );
122 connect( mTransformerWidget, &QgsPropertyAbstractTransformerWidget::widgetChanged, this, &QgsPropertyAssistantWidget::widgetChanged );
123
124 mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
125 mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
126
127 mCurveEditor->setHistogramSource( mLayer, mExpressionWidget->currentField() );
128 connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & expression )
129 {
130 mCurveEditor->setHistogramSource( mLayer, expression );
131 }
132 );
133 connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMinHistogramValueRange );
134 connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMaxHistogramValueRange );
135 }
136 mTransformCurveCheckBox->setVisible( mTransformerWidget );
137
138 connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
139 connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
140 connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
141 connect( mTransformCurveCheckBox, &QgsCollapsibleGroupBox::toggled, this, &QgsPropertyAssistantWidget::widgetChanged );
143 connect( this, &QgsPropertyAssistantWidget::widgetChanged, this, &QgsPropertyAssistantWidget::updatePreview );
144 updatePreview();
145}
146
148{
149 mExpressionContextGenerator = generator;
150 mExpressionWidget->registerExpressionContextGenerator( generator );
151}
152
154{
155 property.setActive( !mExpressionWidget->currentText().isEmpty() );
156 if ( mExpressionWidget->isExpression() )
157 property.setExpressionString( mExpressionWidget->currentField() );
158 else
159 property.setField( mExpressionWidget->currentField() );
160
161 if ( mTransformerWidget )
162 {
163 std::unique_ptr< QgsPropertyTransformer> t( mTransformerWidget->createTransformer( minValueSpinBox->value(), maxValueSpinBox->value() ) );
164 if ( mTransformCurveCheckBox->isChecked() )
165 {
166 t->setCurveTransform( new QgsCurveTransform( mCurveEditor->curve() ) );
167 }
168 else
169 {
170 t->setCurveTransform( nullptr );
171 }
172 property.setTransformer( t.release() );
173 }
174}
175
177{
179
180 if ( dockMode && mLegendVerticalFrame->isHidden() )
181 {
182 mLegendVerticalFrame->layout()->addWidget( mLegendPreview );
183 mLegendVerticalFrame->show();
184 }
185}
186
187void QgsPropertyAssistantWidget::computeValuesFromLayer()
188{
189 if ( !mLayer )
190 return;
191
192 double minValue = 0.0;
193 double maxValue = 0.0;
194
195 if ( mExpressionWidget->isExpression() )
196 {
197 if ( !computeValuesFromExpression( mExpressionWidget->currentField(), minValue, maxValue ) )
198 return;
199 }
200 else
201 {
202 if ( !computeValuesFromField( mExpressionWidget->currentField(), minValue, maxValue ) )
203 return;
204 }
205
206 whileBlocking( minValueSpinBox )->setValue( minValue );
207 whileBlocking( maxValueSpinBox )->setValue( maxValue );
208
209 mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
210 mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
211
212 emit widgetChanged();
213}
214
215void QgsPropertyAssistantWidget::updatePreview()
216{
217 if ( mLegendPreview->isHidden() || !mTransformerWidget || !mLayer ) // TODO - make this work OK without a layer
218 return;
219
220 mLegendPreview->setIconSize( QSize( 512, 512 ) );
221 mPreviewList.clear();
222
223 QList<double> breaks = QgsSymbolLayerUtils::prettyBreaks( minValueSpinBox->value(),
224 maxValueSpinBox->value(), 8 );
225
226 QgsCurveTransform curve = mCurveEditor->curve();
227 const QList< QgsSymbolLegendNode * > nodes = mTransformerWidget->generatePreviews( breaks, mLayerTreeLayer, mSymbol.get(), minValueSpinBox->value(),
228 maxValueSpinBox->value(), mTransformCurveCheckBox->isChecked() ? &curve : nullptr );
229
230 int widthMax = 0;
231 int i = 0;
232 const auto constNodes = nodes;
233 for ( QgsSymbolLegendNode *node : constNodes )
234 {
235 const QSize minSize( node->minimumIconSize() );
236 node->setIconSize( minSize );
237 widthMax = std::max( minSize.width(), widthMax );
238 QStandardItem *item = new QStandardItem( node->data( Qt::DecorationRole ).value<QPixmap>(), QLocale().toString( breaks[i] ) );
239 item->setEditable( false );
240 mPreviewList.appendRow( item );
241 delete node;
242 i++;
243 }
244 // center icon and align text left by giving icons the same width
245 // TODO maybe add some space so that icons don't touch
246 for ( int i = 0; i < breaks.length(); i++ )
247 {
248 const QPixmap img( mPreviewList.item( i )->icon().pixmap( mPreviewList.item( i )->icon().actualSize( QSize( 512, 512 ) ) ) );
249 QPixmap enlarged( widthMax, img.height() );
250 // fill transparent and add original image
251 enlarged.fill( Qt::transparent );
252 QPainter p( &enlarged );
253 p.drawPixmap( QPoint( ( widthMax - img.width() ) / 2, 0 ), img );
254 p.end();
255 mPreviewList.item( i )->setIcon( enlarged );
256 }
257}
258
259bool QgsPropertyAssistantWidget::computeValuesFromExpression( const QString &expression, double &minValue, double &maxValue ) const
260{
261 QgsExpression e( expression );
262
263 QgsExpressionContext context;
264 if ( mExpressionContextGenerator )
265 {
266 context = mExpressionContextGenerator->createExpressionContext();
267 }
268 else
269 {
273 }
274
275 if ( !e.prepare( &context ) )
276 return false;
277
278 const QSet<QString> referencedCols( e.referencedColumns() );
279
280 QgsFeatureIterator fit = mLayer->getFeatures(
281 QgsFeatureRequest().setFlags( e.needsGeometry()
283 : Qgis::FeatureRequestFlag::NoGeometry )
284 .setSubsetOfAttributes( referencedCols, mLayer->fields() ) );
285
286 // create list of non-null attribute values
287 double min = std::numeric_limits<double>::max();
288 double max = std::numeric_limits<double>::lowest();
289 QgsFeature f;
290 bool found = false;
291 while ( fit.nextFeature( f ) )
292 {
293 bool ok;
294 context.setFeature( f );
295 const double value = e.evaluate( &context ).toDouble( &ok );
296 if ( ok )
297 {
298 max = std::max( max, value );
299 min = std::min( min, value );
300 found = true;
301 }
302 }
303 if ( found )
304 {
305 minValue = min;
306 maxValue = max;
307 }
308 return found;
309}
310
311bool QgsPropertyAssistantWidget::computeValuesFromField( const QString &fieldName, double &minValue, double &maxValue ) const
312{
313 const int fieldIndex = mLayer->fields().lookupField( fieldName );
314 if ( fieldIndex < 0 )
315 {
316 return false;
317 }
318
319 QVariant min;
320 QVariant max;
321 mLayer->minimumAndMaximumValue( fieldIndex, min, max );
322
323 bool ok = false;
324 const double minDouble = min.toDouble( &ok );
325 if ( !ok )
326 return false;
327
328 const double maxDouble = max.toDouble( &ok );
329 if ( !ok )
330 return false;
331
332 minValue = minDouble;
333 maxValue = maxDouble;
334 return true;
335}
336
338
339//
340// QgsPropertySizeAssistantWidget
341//
342
343QgsPropertySizeAssistantWidget::QgsPropertySizeAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
344 : QgsPropertyAbstractTransformerWidget( parent, definition )
345{
346 setupUi( this );
347
348 layout()->setContentsMargins( 0, 0, 0, 0 );
349
350 if ( definition.standardTemplate() == QgsPropertyDefinition::Size )
351 {
352 scaleMethodComboBox->addItem( tr( "Flannery" ), QgsSizeScaleTransformer::Flannery );
353 scaleMethodComboBox->addItem( tr( "Surface" ), QgsSizeScaleTransformer::Area );
354 scaleMethodComboBox->addItem( tr( "Radius" ), QgsSizeScaleTransformer::Linear );
355 scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
356 }
357 else if ( definition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
358 {
359 scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
360 scaleMethodComboBox->addItem( tr( "Linear" ), QgsSizeScaleTransformer::Linear );
361 }
362
363 minSizeSpinBox->setShowClearButton( false );
364 maxSizeSpinBox->setShowClearButton( false );
365 nullSizeSpinBox->setShowClearButton( false );
366
367 if ( const QgsSizeScaleTransformer *sizeTransform = dynamic_cast< const QgsSizeScaleTransformer * >( initialState.transformer() ) )
368 {
369 minSizeSpinBox->setValue( sizeTransform->minSize() );
370 maxSizeSpinBox->setValue( sizeTransform->maxSize() );
371 nullSizeSpinBox->setValue( sizeTransform->nullSize() );
372 exponentSpinBox->setValue( sizeTransform->exponent() );
373 scaleMethodComboBox->setCurrentIndex( scaleMethodComboBox->findData( sizeTransform->type() ) );
374 }
375
376 exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
377
378 connect( minSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
379 connect( maxSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
380 connect( nullSizeSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
381 connect( exponentSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
382 connect( scaleMethodComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
383 connect( scaleMethodComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this,
384 [ = ]
385 {
386 exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
387 }
388 );
389}
390
391QgsSizeScaleTransformer *QgsPropertySizeAssistantWidget::createTransformer( double minValue, double maxValue ) const
392{
394 static_cast< QgsSizeScaleTransformer::ScaleType >( scaleMethodComboBox->currentData().toInt() ),
395 minValue,
396 maxValue,
397 minSizeSpinBox->value(),
398 maxSizeSpinBox->value(),
399 nullSizeSpinBox->value(),
400 exponentSpinBox->value() );
401 return transformer;
402}
403
404QList< QgsSymbolLegendNode * > QgsPropertySizeAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
405{
406 QList< QgsSymbolLegendNode * > nodes;
407
408 const QgsSymbol *legendSymbol = symbol;
409 std::unique_ptr< QgsSymbol > tempSymbol;
410
411 if ( !legendSymbol )
412 {
413 if ( mDefinition.standardTemplate() == QgsPropertyDefinition::Size )
414 {
415 tempSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
416 }
417 else if ( mDefinition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
418 {
419 tempSymbol.reset( QgsLineSymbol::createSimple( QVariantMap() ) );
420 }
421 legendSymbol = tempSymbol.get();
422 }
423 if ( !legendSymbol )
424 return nodes;
425
426 std::unique_ptr< QgsSizeScaleTransformer > t( createTransformer( minValue, maxValue ) );
427 if ( curve )
428 t->setCurveTransform( new QgsCurveTransform( *curve ) );
429
430 for ( int i = 0; i < breaks.length(); i++ )
431 {
432 std::unique_ptr< QgsSymbolLegendNode > node;
433 if ( dynamic_cast<const QgsMarkerSymbol *>( legendSymbol ) )
434 {
435 std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
436 symbolClone->setDataDefinedSize( QgsProperty() );
437 symbolClone->setDataDefinedAngle( QgsProperty() ); // to avoid symbol not being drawn
438 symbolClone->setSize( t->size( breaks[i] ) );
439 node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
440 }
441 else if ( dynamic_cast<const QgsLineSymbol *>( legendSymbol ) )
442 {
443 std::unique_ptr< QgsLineSymbol > symbolClone( static_cast<QgsLineSymbol *>( legendSymbol->clone() ) );
444 symbolClone->setDataDefinedWidth( QgsProperty() );
445 symbolClone->setWidth( t->size( breaks[i] ) );
446 node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
447 }
448 if ( node )
449 nodes << node.release();
450 }
451 return nodes;
452}
453
454QList<QgsSymbolLegendNode *> QgsPropertyAbstractTransformerWidget::generatePreviews( const QList<double> &, QgsLayerTreeLayer *, const QgsSymbol *, double, double, QgsCurveTransform * ) const
455{
456 return QList< QgsSymbolLegendNode * >();
457}
458
459QgsPropertyColorAssistantWidget::QgsPropertyColorAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
460 : QgsPropertyAbstractTransformerWidget( parent, definition )
461{
462 setupUi( this );
463
464 layout()->setContentsMargins( 0, 0, 0, 0 );
465
466 const bool supportsAlpha = definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha;
467 mNullColorButton->setAllowOpacity( supportsAlpha );
468 mNullColorButton->setShowNoColor( true );
469 mNullColorButton->setColorDialogTitle( tr( "Color For Null Values" ) );
470 mNullColorButton->setContext( QStringLiteral( "symbology" ) );
471 mNullColorButton->setNoColorString( tr( "Transparent" ) );
472
473 if ( const QgsColorRampTransformer *colorTransform = dynamic_cast< const QgsColorRampTransformer * >( initialState.transformer() ) )
474 {
475 mNullColorButton->setColor( colorTransform->nullColor() );
476 if ( colorTransform->colorRamp() )
477 mColorRampButton->setColorRamp( colorTransform->colorRamp() );
478 }
479
480 connect( mNullColorButton, &QgsColorButton::colorChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
481 connect( mColorRampButton, &QgsColorRampButton::colorRampChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
482
483 if ( !mColorRampButton->colorRamp() )
484 {
485 // set a default ramp
486 std::unique_ptr< QgsColorRamp > colorRamp( QgsProject::instance()->styleSettings()->defaultColorRamp() );
487 if ( !colorRamp )
488 {
489 colorRamp.reset( QgsStyle::defaultStyle()->colorRamp( QStringLiteral( "Blues" ) ) );
490 }
491 if ( colorRamp )
492 mColorRampButton->setColorRamp( colorRamp.get() );
493 }
494}
495
496QgsColorRampTransformer *QgsPropertyColorAssistantWidget::createTransformer( double minValue, double maxValue ) const
497{
499 minValue,
500 maxValue,
501 mColorRampButton->colorRamp(),
502 mNullColorButton->color(),
503 mColorRampButton->colorRampName() );
504 return transformer;
505}
506
507QList<QgsSymbolLegendNode *> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
508{
509 QList< QgsSymbolLegendNode * > nodes;
510
511 const QgsMarkerSymbol *legendSymbol = dynamic_cast<const QgsMarkerSymbol *>( symbol );
512 std::unique_ptr< QgsMarkerSymbol > tempSymbol;
513
514 if ( !legendSymbol )
515 {
516 tempSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
517 legendSymbol = tempSymbol.get();
518 }
519 if ( !legendSymbol )
520 return nodes;
521
522 std::unique_ptr< QgsColorRampTransformer > t( createTransformer( minValue, maxValue ) );
523 if ( curve )
524 t->setCurveTransform( new QgsCurveTransform( *curve ) );
525
526 for ( int i = 0; i < breaks.length(); i++ )
527 {
528 std::unique_ptr< QgsSymbolLegendNode > node;
529 std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
530 symbolClone->setColor( t->color( breaks[i] ) );
531 node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
532 if ( node )
533 nodes << node.release();
534 }
535 return nodes;
536}
537
538QgsPropertyGenericNumericAssistantWidget::QgsPropertyGenericNumericAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
539 : QgsPropertyAbstractTransformerWidget( parent, definition )
540{
541 setupUi( this );
542
543 layout()->setContentsMargins( 0, 0, 0, 0 );
544
545 nullOutputSpinBox->setShowClearButton( false );
546
547 switch ( definition.standardTemplate() )
548 {
550 {
551 // tweak dialog for rotation
552 minOutputSpinBox->setMaximum( 360.0 );
553 minOutputSpinBox->setValue( 0.0 );
554 minOutputSpinBox->setShowClearButton( true );
555 minOutputSpinBox->setClearValue( 0.0 );
556 minOutputSpinBox->setSuffix( tr( " °" ) );
557 maxOutputSpinBox->setMaximum( 360.0 );
558 maxOutputSpinBox->setValue( 360.0 );
559 maxOutputSpinBox->setShowClearButton( true );
560 maxOutputSpinBox->setClearValue( 360.0 );
561 maxOutputSpinBox->setSuffix( tr( " °" ) );
562 exponentSpinBox->hide();
563 mExponentLabel->hide();
564 mLabelMinOutput->setText( tr( "Angle from" ) );
565 mLabelNullOutput->setText( tr( "Angle when NULL" ) );
566 break;
567 }
568
570 {
571 // tweak dialog for opacity
572 minOutputSpinBox->setMaximum( 100.0 );
573 minOutputSpinBox->setValue( 0.0 );
574 minOutputSpinBox->setShowClearButton( true );
575 minOutputSpinBox->setClearValue( 0.0 );
576 minOutputSpinBox->setSuffix( tr( " %" ) );
577 maxOutputSpinBox->setMaximum( 100.0 );
578 maxOutputSpinBox->setValue( 100.0 );
579 maxOutputSpinBox->setShowClearButton( true );
580 maxOutputSpinBox->setClearValue( 100.0 );
581 maxOutputSpinBox->setSuffix( tr( " %" ) );
582 mLabelMinOutput->setText( tr( "Opacity from" ) );
583 mLabelNullOutput->setText( tr( "Opacity when NULL" ) );
584 break;
585 }
586
589 minOutputSpinBox->setMinimum( 0 );
590 maxOutputSpinBox->setMinimum( 0 );
591 minOutputSpinBox->setShowClearButton( false );
592 maxOutputSpinBox->setShowClearButton( false );
593 break;
594
596 minOutputSpinBox->setMinimum( 1 );
597 maxOutputSpinBox->setMinimum( 1 );
598 minOutputSpinBox->setShowClearButton( false );
599 maxOutputSpinBox->setShowClearButton( false );
600 break;
601
603 minOutputSpinBox->setMinimum( 0 );
604 maxOutputSpinBox->setMinimum( 0 );
605 minOutputSpinBox->setMaximum( 1 );
606 maxOutputSpinBox->setMaximum( 1 );
607 minOutputSpinBox->setShowClearButton( false );
608 maxOutputSpinBox->setShowClearButton( false );
609 break;
610
612 minOutputSpinBox->setMinimum( -99999999.000000 );
613 maxOutputSpinBox->setMinimum( -99999999.000000 );
614 minOutputSpinBox->setMaximum( 99999999.000000 );
615 maxOutputSpinBox->setMaximum( 99999999.000000 );
616 minOutputSpinBox->setShowClearButton( false );
617 maxOutputSpinBox->setShowClearButton( false );
618 break;
619
620 default:
621 {
622 minOutputSpinBox->setShowClearButton( false );
623 maxOutputSpinBox->setShowClearButton( false );
624 break;
625 }
626 }
627
628 if ( const QgsGenericNumericTransformer *transform = dynamic_cast< const QgsGenericNumericTransformer * >( initialState.transformer() ) )
629 {
630 minOutputSpinBox->setValue( transform->minOutputValue() );
631 maxOutputSpinBox->setValue( transform->maxOutputValue() );
632 nullOutputSpinBox->setValue( transform->nullOutputValue() );
633 exponentSpinBox->setValue( transform->exponent() );
634 }
635
636 connect( minOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
637 connect( maxOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
638 connect( nullOutputSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
639 connect( exponentSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
640}
641
642QgsGenericNumericTransformer *QgsPropertyGenericNumericAssistantWidget::createTransformer( double minValue, double maxValue ) const
643{
645 minValue,
646 maxValue,
647 minOutputSpinBox->value(),
648 maxOutputSpinBox->value(),
649 nullOutputSpinBox->value(),
650 exponentSpinBox->value() );
651 return transformer;
652}
653
The Qgis class provides global constants for use throughout the application.
Definition qgis.h:54
@ NoFlags
No flags are set.
@ Expression
Expression based property.
@ TitleCase
Simple title case conversion - does not fully grammatically parse the text and uses simple rules only...
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)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
The QgsFieldExpressionWidget class creates 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.
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
QgsPropertyTransformer subclass for scaling an input numeric value into an output numeric value.
@ HigDialogTitleIsTitleCase
Dialog titles should be title case.
Definition qgsgui.h:271
static QgsGui::HigFlags higFlags()
Returns the platform's HIG flags.
Definition qgsgui.cpp:233
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.
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.
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:45
StandardPropertyTemplate standardTemplate() const
Returns the property's standard template, if applicable.
DataType dataType() const
Returns the allowable field/value data type for the property.
QString description() const
Descriptive name of the property.
@ Double
Double value (including negative values)
Definition qgsproperty.h:55
@ Double0To1
Double value between 0-1 (inclusive)
Definition qgsproperty.h:57
@ StrokeWidth
Line stroke width.
Definition qgsproperty.h:70
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
Definition qgsproperty.h:54
@ IntegerPositive
Positive integer values (including 0)
Definition qgsproperty.h:53
@ Opacity
Opacity (0-100)
Definition qgsproperty.h:60
@ ColorNoAlpha
Color with no alpha channel.
Definition qgsproperty.h:63
@ Rotation
Rotation (value between 0-360 degrees)
Definition qgsproperty.h:58
@ Size
1D size (eg marker radius, or square marker height/width)
Definition qgsproperty.h:67
@ ColorWithAlpha
Color with alpha channel.
Definition qgsproperty.h:62
@ DoublePositive
Positive double value (including 0)
Definition qgsproperty.h:56
@ DataTypeNumeric
Property requires a numeric value.
Definition qgsproperty.h:97
A store for object properties.
QString expressionString() const
Returns the expression used for the property value.
Qgis::PropertyType propertyType() const
Returns the property type.
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,...
QgsPropertyTransformer subclass for scaling a value into a size according to various scaling methods.
@ Exponential
Scale using set exponent.
@ Flannery
Flannery scaling method.
static QString capitalize(const QString &string, Qgis::Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Definition qgsstyle.cpp:146
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:231
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.
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:5862