QGIS API Documentation 3.41.0-Master (cea29feecf2)
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
34QgsPropertyAssistantWidget::QgsPropertyAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState, const QgsVectorLayer *layer )
35 : QgsPanelWidget( parent )
36 , mDefinition( definition )
37 , mLayer( layer )
38{
39 setupUi( this );
40
41 layout()->setContentsMargins( 0, 0, 0, 0 );
42
44
45 mLegendPreview->hide();
46
47 minValueSpinBox->setShowClearButton( false );
48 maxValueSpinBox->setShowClearButton( false );
49
50 // TODO expression widget shouldn't require a non-const layer
51 mExpressionWidget->setLayer( const_cast<QgsVectorLayer *>( mLayer ) );
52 mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric );
53 mExpressionWidget->setField( initialState.propertyType() == Qgis::PropertyType::Expression ? initialState.expressionString() : initialState.field() );
54
55 if ( auto *lTransformer = initialState.transformer() )
56 {
57 minValueSpinBox->setValue( lTransformer->minValue() );
58 maxValueSpinBox->setValue( lTransformer->maxValue() );
59
60 if ( lTransformer->curveTransform() )
61 {
62 mTransformCurveCheckBox->setChecked( true );
63 mTransformCurveCheckBox->setCollapsed( false );
64 mCurveEditor->setCurve( *lTransformer->curveTransform() );
65 }
66 }
67
68 connect( computeValuesButton, &QPushButton::clicked, this, &QgsPropertyAssistantWidget::computeValuesFromLayer );
69
70 if ( mLayer )
71 {
72 mLayerTreeLayer = new QgsLayerTreeLayer( const_cast<QgsVectorLayer *>( mLayer ) );
73 mRoot.addChildNode( mLayerTreeLayer ); // takes ownership
74 }
75 mLegendPreview->setModel( &mPreviewList );
76 mLegendPreview->setItemDelegate( new QgsAssistantPreviewItemDelegate( &mPreviewList ) );
77 mLegendPreview->setHeaderHidden( true );
78 mLegendPreview->expandAll();
79 mLegendVerticalFrame->setLayout( new QVBoxLayout() );
80 mLegendVerticalFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
81 mLegendVerticalFrame->hide();
82
83 switch ( definition.standardTemplate() )
84 {
87 {
88 mTransformerWidget = new QgsPropertySizeAssistantWidget( this, mDefinition, initialState );
89 mLegendPreview->show();
90 break;
91 }
92
95 {
96 mTransformerWidget = new QgsPropertyColorAssistantWidget( this, mDefinition, initialState );
97 mLegendPreview->show();
98 break;
99 }
100
102 {
103 mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
104 break;
105 }
106
107 default:
108 {
110 {
111 mTransformerWidget = new QgsPropertyGenericNumericAssistantWidget( this, mDefinition, initialState );
112 }
113 break;
114 }
115 }
116
117 if ( mTransformerWidget )
118 {
119 mOutputWidget->layout()->addWidget( mTransformerWidget );
120 connect( mTransformerWidget, &QgsPropertyAbstractTransformerWidget::widgetChanged, this, &QgsPropertyAssistantWidget::widgetChanged );
121
122 mCurveEditor->setMinHistogramValueRange( minValueSpinBox->value() );
123 mCurveEditor->setMaxHistogramValueRange( maxValueSpinBox->value() );
124
125 mCurveEditor->setHistogramSource( mLayer, mExpressionWidget->currentField() );
126 connect( mExpressionWidget, static_cast<void ( QgsFieldExpressionWidget::* )( const QString & )>( &QgsFieldExpressionWidget::fieldChanged ), this, [=]( const QString &expression ) {
127 mCurveEditor->setHistogramSource( mLayer, expression );
128 } );
129 connect( minValueSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMinHistogramValueRange );
130 connect( maxValueSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), mCurveEditor, &QgsCurveEditorWidget::setMaxHistogramValueRange );
131 }
132 mTransformCurveCheckBox->setVisible( mTransformerWidget );
133
134 connect( minValueSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
135 connect( maxValueSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
136 connect( mExpressionWidget, static_cast<void ( QgsFieldExpressionWidget::* )( const QString & )>( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
137 connect( mTransformCurveCheckBox, &QgsCollapsibleGroupBox::toggled, 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(), maxValueSpinBox->value(), 8 );
220
221 QgsCurveTransform curve = mCurveEditor->curve();
222 const QList<QgsSymbolLegendNode *> nodes = mTransformerWidget->generatePreviews( breaks, mLayerTreeLayer, mSymbol.get(), minValueSpinBox->value(), maxValueSpinBox->value(), mTransformCurveCheckBox->isChecked() ? &curve : nullptr );
223
224 int widthMax = 0;
225 int i = 0;
226 const auto constNodes = nodes;
227 for ( QgsSymbolLegendNode *node : constNodes )
228 {
229 const QSize minSize( node->minimumIconSize() );
230 node->setIconSize( minSize );
231 widthMax = std::max( minSize.width(), widthMax );
232 QStandardItem *item = new QStandardItem( node->data( Qt::DecorationRole ).value<QPixmap>(), QLocale().toString( breaks[i] ) );
233 item->setEditable( false );
234 mPreviewList.appendRow( item );
235 delete node;
236 i++;
237 }
238 // center icon and align text left by giving icons the same width
239 // TODO maybe add some space so that icons don't touch
240 for ( int i = 0; i < breaks.length(); i++ )
241 {
242 const QPixmap img( mPreviewList.item( i )->icon().pixmap( mPreviewList.item( i )->icon().actualSize( QSize( 512, 512 ) ) ) );
243 QPixmap enlarged( widthMax, img.height() );
244 // fill transparent and add original image
245 enlarged.fill( Qt::transparent );
246 QPainter p( &enlarged );
247 p.drawPixmap( QPoint( ( widthMax - img.width() ) / 2, 0 ), img );
248 p.end();
249 mPreviewList.item( i )->setIcon( enlarged );
250 }
251}
252
253bool QgsPropertyAssistantWidget::computeValuesFromExpression( const QString &expression, double &minValue, double &maxValue ) const
254{
255 QgsExpression e( expression );
256
257 QgsExpressionContext context;
258 if ( mExpressionContextGenerator )
259 {
260 context = mExpressionContextGenerator->createExpressionContext();
261 }
262 else
263 {
267 }
268
269 if ( !e.prepare( &context ) )
270 return false;
271
272 const QSet<QString> referencedCols( e.referencedColumns() );
273
274 QgsFeatureIterator fit = mLayer->getFeatures(
275 QgsFeatureRequest().setFlags( e.needsGeometry() ? Qgis::FeatureRequestFlag::NoFlags : Qgis::FeatureRequestFlag::NoGeometry ).setSubsetOfAttributes( referencedCols, mLayer->fields() )
276 );
277
278 // create list of non-null attribute values
279 double min = std::numeric_limits<double>::max();
280 double max = std::numeric_limits<double>::lowest();
281 QgsFeature f;
282 bool found = false;
283 while ( fit.nextFeature( f ) )
284 {
285 bool ok;
286 context.setFeature( f );
287 const double value = e.evaluate( &context ).toDouble( &ok );
288 if ( ok )
289 {
290 max = std::max( max, value );
291 min = std::min( min, value );
292 found = true;
293 }
294 }
295 if ( found )
296 {
297 minValue = min;
298 maxValue = max;
299 }
300 return found;
301}
302
303bool QgsPropertyAssistantWidget::computeValuesFromField( const QString &fieldName, double &minValue, double &maxValue ) const
304{
305 const int fieldIndex = mLayer->fields().lookupField( fieldName );
306 if ( fieldIndex < 0 )
307 {
308 return false;
309 }
310
311 QVariant min;
312 QVariant max;
313 mLayer->minimumAndMaximumValue( fieldIndex, min, max );
314
315 bool ok = false;
316 const double minDouble = min.toDouble( &ok );
317 if ( !ok )
318 return false;
319
320 const double maxDouble = max.toDouble( &ok );
321 if ( !ok )
322 return false;
323
324 minValue = minDouble;
325 maxValue = maxDouble;
326 return true;
327}
328
330
331//
332// QgsPropertySizeAssistantWidget
333//
334
335QgsPropertySizeAssistantWidget::QgsPropertySizeAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
336 : QgsPropertyAbstractTransformerWidget( parent, definition )
337{
338 setupUi( this );
339
340 layout()->setContentsMargins( 0, 0, 0, 0 );
341
342 if ( definition.standardTemplate() == QgsPropertyDefinition::Size )
343 {
344 scaleMethodComboBox->addItem( tr( "Flannery" ), QgsSizeScaleTransformer::Flannery );
345 scaleMethodComboBox->addItem( tr( "Surface" ), QgsSizeScaleTransformer::Area );
346 scaleMethodComboBox->addItem( tr( "Radius" ), QgsSizeScaleTransformer::Linear );
347 scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
348 }
349 else if ( definition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
350 {
351 scaleMethodComboBox->addItem( tr( "Exponential" ), QgsSizeScaleTransformer::Exponential );
352 scaleMethodComboBox->addItem( tr( "Linear" ), QgsSizeScaleTransformer::Linear );
353 }
354
355 minSizeSpinBox->setShowClearButton( false );
356 maxSizeSpinBox->setShowClearButton( false );
357 nullSizeSpinBox->setShowClearButton( false );
358
359 if ( const QgsSizeScaleTransformer *sizeTransform = dynamic_cast<const QgsSizeScaleTransformer *>( initialState.transformer() ) )
360 {
361 minSizeSpinBox->setValue( sizeTransform->minSize() );
362 maxSizeSpinBox->setValue( sizeTransform->maxSize() );
363 nullSizeSpinBox->setValue( sizeTransform->nullSize() );
364 exponentSpinBox->setValue( sizeTransform->exponent() );
365 scaleMethodComboBox->setCurrentIndex( scaleMethodComboBox->findData( sizeTransform->type() ) );
366 }
367
368 exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
369
370 connect( minSizeSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
371 connect( maxSizeSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
372 connect( nullSizeSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
373 connect( exponentSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
374 connect( scaleMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
375 connect( scaleMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [=] {
376 exponentSpinBox->setEnabled( scaleMethodComboBox->currentData().toInt() == QgsSizeScaleTransformer::Exponential );
377 } );
378}
379
380QgsSizeScaleTransformer *QgsPropertySizeAssistantWidget::createTransformer( double minValue, double maxValue ) const
381{
383 static_cast<QgsSizeScaleTransformer::ScaleType>( scaleMethodComboBox->currentData().toInt() ),
384 minValue,
385 maxValue,
386 minSizeSpinBox->value(),
387 maxSizeSpinBox->value(),
388 nullSizeSpinBox->value(),
389 exponentSpinBox->value()
390 );
391 return transformer;
392}
393
394QList<QgsSymbolLegendNode *> QgsPropertySizeAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
395{
396 QList<QgsSymbolLegendNode *> nodes;
397
398 const QgsSymbol *legendSymbol = symbol;
399 std::unique_ptr<QgsSymbol> tempSymbol;
400
401 if ( !legendSymbol )
402 {
403 if ( mDefinition.standardTemplate() == QgsPropertyDefinition::Size )
404 {
405 tempSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
406 }
407 else if ( mDefinition.standardTemplate() == QgsPropertyDefinition::StrokeWidth )
408 {
409 tempSymbol.reset( QgsLineSymbol::createSimple( QVariantMap() ) );
410 }
411 legendSymbol = tempSymbol.get();
412 }
413 if ( !legendSymbol )
414 return nodes;
415
416 std::unique_ptr<QgsSizeScaleTransformer> t( createTransformer( minValue, maxValue ) );
417 if ( curve )
418 t->setCurveTransform( new QgsCurveTransform( *curve ) );
419
420 for ( int i = 0; i < breaks.length(); i++ )
421 {
422 std::unique_ptr<QgsSymbolLegendNode> node;
423 if ( dynamic_cast<const QgsMarkerSymbol *>( legendSymbol ) )
424 {
425 std::unique_ptr<QgsMarkerSymbol> symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
426 symbolClone->setDataDefinedSize( QgsProperty() );
427 symbolClone->setDataDefinedAngle( QgsProperty() ); // to avoid symbol not being drawn
428 symbolClone->setSize( t->size( breaks[i] ) );
429 node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
430 }
431 else if ( dynamic_cast<const QgsLineSymbol *>( legendSymbol ) )
432 {
433 std::unique_ptr<QgsLineSymbol> symbolClone( static_cast<QgsLineSymbol *>( legendSymbol->clone() ) );
434 symbolClone->setDataDefinedWidth( QgsProperty() );
435 symbolClone->setWidth( t->size( breaks[i] ) );
436 node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
437 }
438 if ( node )
439 nodes << node.release();
440 }
441 return nodes;
442}
443
444QList<QgsSymbolLegendNode *> QgsPropertyAbstractTransformerWidget::generatePreviews( const QList<double> &, QgsLayerTreeLayer *, const QgsSymbol *, double, double, QgsCurveTransform * ) const
445{
446 return QList<QgsSymbolLegendNode *>();
447}
448
449QgsPropertyColorAssistantWidget::QgsPropertyColorAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
450 : QgsPropertyAbstractTransformerWidget( parent, definition )
451{
452 setupUi( this );
453
454 layout()->setContentsMargins( 0, 0, 0, 0 );
455
456 const bool supportsAlpha = definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha;
457 mNullColorButton->setAllowOpacity( supportsAlpha );
458 mNullColorButton->setShowNoColor( true );
459 mNullColorButton->setColorDialogTitle( tr( "Color For Null Values" ) );
460 mNullColorButton->setContext( QStringLiteral( "symbology" ) );
461 mNullColorButton->setNoColorString( tr( "Transparent" ) );
462
463 if ( const QgsColorRampTransformer *colorTransform = dynamic_cast<const QgsColorRampTransformer *>( initialState.transformer() ) )
464 {
465 mNullColorButton->setColor( colorTransform->nullColor() );
466 if ( colorTransform->colorRamp() )
467 mColorRampButton->setColorRamp( colorTransform->colorRamp() );
468 }
469
470 connect( mNullColorButton, &QgsColorButton::colorChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
471 connect( mColorRampButton, &QgsColorRampButton::colorRampChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
472
473 if ( !mColorRampButton->colorRamp() )
474 {
475 // set a default ramp
476 std::unique_ptr<QgsColorRamp> colorRamp( QgsProject::instance()->styleSettings()->defaultColorRamp() );
477 if ( !colorRamp )
478 {
479 colorRamp.reset( QgsStyle::defaultStyle()->colorRamp( QStringLiteral( "Blues" ) ) );
480 }
481 if ( colorRamp )
482 mColorRampButton->setColorRamp( colorRamp.get() );
483 }
484}
485
486QgsColorRampTransformer *QgsPropertyColorAssistantWidget::createTransformer( double minValue, double maxValue ) const
487{
489 minValue,
490 maxValue,
491 mColorRampButton->colorRamp(),
492 mNullColorButton->color(),
493 mColorRampButton->colorRampName()
494 );
495 return transformer;
496}
497
498QList<QgsSymbolLegendNode *> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const
499{
500 QList<QgsSymbolLegendNode *> nodes;
501
502 const QgsMarkerSymbol *legendSymbol = dynamic_cast<const QgsMarkerSymbol *>( symbol );
503 std::unique_ptr<QgsMarkerSymbol> tempSymbol;
504
505 if ( !legendSymbol )
506 {
507 tempSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
508 legendSymbol = tempSymbol.get();
509 }
510 if ( !legendSymbol )
511 return nodes;
512
513 std::unique_ptr<QgsColorRampTransformer> t( createTransformer( minValue, maxValue ) );
514 if ( curve )
515 t->setCurveTransform( new QgsCurveTransform( *curve ) );
516
517 for ( int i = 0; i < breaks.length(); i++ )
518 {
519 std::unique_ptr<QgsSymbolLegendNode> node;
520 std::unique_ptr<QgsMarkerSymbol> symbolClone( static_cast<QgsMarkerSymbol *>( legendSymbol->clone() ) );
521 symbolClone->setColor( t->color( breaks[i] ) );
522 node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
523 if ( node )
524 nodes << node.release();
525 }
526 return nodes;
527}
528
529QgsPropertyGenericNumericAssistantWidget::QgsPropertyGenericNumericAssistantWidget( QWidget *parent, const QgsPropertyDefinition &definition, const QgsProperty &initialState )
530 : QgsPropertyAbstractTransformerWidget( parent, definition )
531{
532 setupUi( this );
533
534 layout()->setContentsMargins( 0, 0, 0, 0 );
535
536 nullOutputSpinBox->setShowClearButton( false );
537
538 switch ( definition.standardTemplate() )
539 {
541 {
542 // tweak dialog for rotation
543 minOutputSpinBox->setMaximum( 360.0 );
544 minOutputSpinBox->setValue( 0.0 );
545 minOutputSpinBox->setShowClearButton( true );
546 minOutputSpinBox->setClearValue( 0.0 );
547 minOutputSpinBox->setSuffix( tr( " °" ) );
548 maxOutputSpinBox->setMaximum( 360.0 );
549 maxOutputSpinBox->setValue( 360.0 );
550 maxOutputSpinBox->setShowClearButton( true );
551 maxOutputSpinBox->setClearValue( 360.0 );
552 maxOutputSpinBox->setSuffix( tr( " °" ) );
553 exponentSpinBox->hide();
554 mExponentLabel->hide();
555 mLabelMinOutput->setText( tr( "Angle from" ) );
556 mLabelNullOutput->setText( tr( "Angle when NULL" ) );
557 break;
558 }
559
561 {
562 // tweak dialog for opacity
563 minOutputSpinBox->setMaximum( 100.0 );
564 minOutputSpinBox->setValue( 0.0 );
565 minOutputSpinBox->setShowClearButton( true );
566 minOutputSpinBox->setClearValue( 0.0 );
567 minOutputSpinBox->setSuffix( tr( " %" ) );
568 maxOutputSpinBox->setMaximum( 100.0 );
569 maxOutputSpinBox->setValue( 100.0 );
570 maxOutputSpinBox->setShowClearButton( true );
571 maxOutputSpinBox->setClearValue( 100.0 );
572 maxOutputSpinBox->setSuffix( tr( " %" ) );
573 mLabelMinOutput->setText( tr( "Opacity from" ) );
574 mLabelNullOutput->setText( tr( "Opacity when NULL" ) );
575 break;
576 }
577
580 minOutputSpinBox->setMinimum( 0 );
581 maxOutputSpinBox->setMinimum( 0 );
582 minOutputSpinBox->setShowClearButton( false );
583 maxOutputSpinBox->setShowClearButton( false );
584 break;
585
587 minOutputSpinBox->setMinimum( 1 );
588 maxOutputSpinBox->setMinimum( 1 );
589 minOutputSpinBox->setShowClearButton( false );
590 maxOutputSpinBox->setShowClearButton( false );
591 break;
592
594 minOutputSpinBox->setMinimum( 0 );
595 maxOutputSpinBox->setMinimum( 0 );
596 minOutputSpinBox->setMaximum( 1 );
597 maxOutputSpinBox->setMaximum( 1 );
598 minOutputSpinBox->setShowClearButton( false );
599 maxOutputSpinBox->setShowClearButton( false );
600 break;
601
603 minOutputSpinBox->setMinimum( -99999999.000000 );
604 maxOutputSpinBox->setMinimum( -99999999.000000 );
605 minOutputSpinBox->setMaximum( 99999999.000000 );
606 maxOutputSpinBox->setMaximum( 99999999.000000 );
607 minOutputSpinBox->setShowClearButton( false );
608 maxOutputSpinBox->setShowClearButton( false );
609 break;
610
611 default:
612 {
613 minOutputSpinBox->setShowClearButton( false );
614 maxOutputSpinBox->setShowClearButton( false );
615 break;
616 }
617 }
618
619 if ( const QgsGenericNumericTransformer *transform = dynamic_cast<const QgsGenericNumericTransformer *>( initialState.transformer() ) )
620 {
621 minOutputSpinBox->setValue( transform->minOutputValue() );
622 maxOutputSpinBox->setValue( transform->maxOutputValue() );
623 nullOutputSpinBox->setValue( transform->nullOutputValue() );
624 exponentSpinBox->setValue( transform->exponent() );
625 }
626
627 connect( minOutputSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
628 connect( maxOutputSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
629 connect( nullOutputSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
630 connect( exponentSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertySizeAssistantWidget::widgetChanged );
631}
632
633QgsGenericNumericTransformer *QgsPropertyGenericNumericAssistantWidget::createTransformer( double minValue, double maxValue ) const
634{
636 minValue,
637 maxValue,
638 minOutputSpinBox->value(),
639 maxOutputSpinBox->value(),
640 nullOutputSpinBox->value(),
641 exponentSpinBox->value()
642 );
643 return transformer;
644}
645
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:270
static QgsGui::HigFlags higFlags()
Returns the platform's HIG flags.
Definition qgsgui.cpp:234
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:5928