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