QGIS API Documentation 4.1.0-Master (60fea48833c)
Loading...
Searching...
No Matches
qgsproperty.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsproperty.cpp
3 ---------------
4 Date : January 2017
5 Copyright : (C) 2017 by Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsproperty.h"
17
18#include "qgsexpression.h"
19#include "qgsfeature.h"
20#include "qgsproperty_p.h"
21#include "qgssymbollayerutils.h"
22
23#include <QRegularExpression>
24#include <QString>
25
26using namespace Qt::StringLiterals;
27
29 : mName( name )
30 , mDescription( description )
31 , mStandardType( type )
32 , mOrigin( origin )
33 , mComment( comment )
34{
35 switch ( mStandardType )
36 {
37 case Boolean:
38 mTypes = DataTypeBoolean;
39 mHelpText = QObject::tr( "bool [<b>1</b>=True|<b>0</b>=False]" );
40 break;
41
42 case Integer:
43 mTypes = DataTypeNumeric;
44 mHelpText = QObject::tr( "int [≤ 0 ≥]" );
45 break;
46
47 case IntegerPositive:
48 mTypes = DataTypeNumeric;
49 mHelpText = QObject::tr( "int [≥ 0]" );
50 break;
51
53 mTypes = DataTypeNumeric;
54 mHelpText = QObject::tr( "int [≥ 1]" );
55 break;
56
57 case Double:
58 mTypes = DataTypeNumeric;
59 mHelpText = QObject::tr( "double [≤ 0.0 ≥]" );
60 break;
61
62 case DoublePositive:
63 mTypes = DataTypeNumeric;
64 mHelpText = QObject::tr( "double [≥ 0.0]" );
65 break;
66
67 case Double0To1:
68 mTypes = DataTypeNumeric;
69 mHelpText = QObject::tr( "double [0.0-1.0]" );
70 break;
71
72 case Rotation:
73 mTypes = DataTypeNumeric;
74 mHelpText = QObject::tr( "double [0.0-360.0]" );
75 break;
76
77 case String:
78 mTypes = DataTypeString;
79 mHelpText = QObject::tr( "string of variable length" );
80 break;
81
82 case Opacity:
83 mTypes = DataTypeNumeric;
84 mHelpText = QObject::tr( "int [0-100]" );
85 break;
86
87 case RenderUnits:
88 mTypes = DataTypeString;
89 mHelpText = trString() + u"[<b>MM</b>|<b>MapUnit</b>|<b>Pixel</b>|<b>Point</b>]"_s;
90 break;
91
92 case ColorWithAlpha:
93 mTypes = DataTypeString;
94 mHelpText = QObject::tr( "string [<b>r,g,b,a</b>] as int 0-255 or #<b>AARRGGBB</b> as hex or <b>color</b> as color's name" );
95 break;
96
97 case ColorNoAlpha:
98 mTypes = DataTypeString;
99 mHelpText = QObject::tr( "string [<b>r,g,b</b>] as int 0-255 or #<b>RRGGBB</b> as hex or <b>color</b> as color's name" );
100 break;
101
102 case PenJoinStyle:
103 mTypes = DataTypeString;
104 mHelpText = trString() + u"[<b>bevel</b>|<b>miter</b>|<b>round</b>]"_s;
105 break;
106
107 case BlendMode:
108 mTypes = DataTypeString;
109 mHelpText = trString()
110 + QStringLiteral(
111 "[<b>Normal</b>|<b>Lighten</b>|<b>Screen</b>|<b>Dodge</b>|<br>"
112 "<b>Addition</b>|<b>Darken</b>|<b>Multiply</b>|<b>Burn</b>|<b>Overlay</b>|<br>"
113 "<b>SoftLight</b>|<b>HardLight</b>|<b>Difference</b>|<b>Subtract</b>]"
114 );
115 break;
116
117 case Point:
118 mTypes = DataTypeString;
119 mHelpText = QObject::tr( "double coord [<b>X,Y</b>]" );
120 break;
121
122 case Size:
123 mTypes = DataTypeNumeric;
124 mHelpText = QObject::tr( "double [≥ 0.0]" );
125 break;
126
127 case Size2D:
128 mTypes = DataTypeString;
129 mHelpText = QObject::tr( "string of doubles '<b>width,height</b>' or array of doubles <b>[width, height]</b>" );
130 break;
131
132 case LineStyle:
133 mTypes = DataTypeString;
134 mHelpText = trString() + u"[<b>no</b>|<b>solid</b>|<b>dash</b>|<b>dot</b>|<b>dash dot</b>|<b>dash dot dot</b>]"_s;
135 break;
136
137 case StrokeWidth:
138 mTypes = DataTypeNumeric;
139 mHelpText = QObject::tr( "double [≥ 0.0]" );
140 break;
141
142 case FillStyle:
143 mTypes = DataTypeString;
144 mHelpText = trString()
145 + QStringLiteral(
146 "[<b>solid</b>|<b>horizontal</b>|<b>vertical</b>|<b>cross</b>|<b>b_diagonal</b>|<b>f_diagonal"
147 "</b>|<b>diagonal_x</b>|<b>dense1</b>|<b>dense2</b>|<b>dense3</b>|<b>dense4</b>|<b>dense5"
148 "</b>|<b>dense6</b>|<b>dense7</b>|<b>no]"
149 );
150 break;
151
152 case CapStyle:
153 mTypes = DataTypeString;
154 mHelpText = trString() + u"[<b>square</b>|<b>flat</b>|<b>round</b>]"_s;
155 break;
156
157 case HorizontalAnchor:
158 mTypes = DataTypeString;
159 mHelpText = trString() + u"[<b>left</b>|<b>center</b>|<b>right</b>]"_s;
160 break;
161
162 case VerticalAnchor:
163 mTypes = DataTypeString;
164 mHelpText = trString() + u"[<b>top</b>|<b>center</b>|<b>bottom</b>]"_s;
165 break;
166
167 case SvgPath:
168 mTypes = DataTypeString;
169 mHelpText = trString()
170 + QStringLiteral(
171 "[<b>filepath</b>] as<br>"
172 "<b>''</b>=empty|absolute|search-paths-relative|<br>"
173 "project-relative|URL"
174 );
175 break;
176
177 case Offset:
178 mTypes = DataTypeString;
179 mHelpText = QObject::tr( "string of doubles '<b>x,y</b>' or array of doubles <b>[x, y]</b>" );
180 break;
181
182 case DateTime:
183 mTypes = DataTypeString;
184 mHelpText = QObject::tr( "DateTime or string representation of a DateTime" );
185 break;
186
187 case Custom:
188 mTypes = DataTypeString;
189 }
190}
191
192QgsPropertyDefinition::QgsPropertyDefinition( const QString &name, DataType dataType, const QString &description, const QString &helpText, const QString &origin, const QString &comment )
193 : mName( name )
194 , mDescription( description )
195 , mTypes( dataType )
196 , mHelpText( helpText )
197 , mOrigin( origin )
198 , mComment( comment )
199{}
200
202{
203 return mTypes == DataTypeNumeric || mStandardType == Size || mStandardType == StrokeWidth || mStandardType == ColorNoAlpha || mStandardType == ColorWithAlpha || mStandardType == Rotation;
204}
205
206QString QgsPropertyDefinition::trString()
207{
208 // just something to reduce translation redundancy
209 return QObject::tr( "string " );
210}
211
212//
213// QgsProperty
214//
215
216QVariantMap QgsProperty::propertyMapToVariantMap( const QMap<QString, QgsProperty> &propertyMap )
217{
218 QVariantMap variantMap;
219 QMap<QString, QgsProperty>::const_iterator it = propertyMap.constBegin();
220 for ( ; it != propertyMap.constEnd(); ++it )
221 variantMap.insert( it.key(), it.value().toVariant() );
222 return variantMap;
223}
224
225QMap<QString, QgsProperty> QgsProperty::variantMapToPropertyMap( const QVariantMap &variantMap )
226{
227 QMap<QString, QgsProperty> propertyMap;
228 QVariantMap::const_iterator it = variantMap.constBegin();
229 for ( ; it != variantMap.constEnd(); ++it )
230 {
231 QgsProperty property;
232 if ( property.loadVariant( it.value() ) )
233 propertyMap.insert( it.key(), property );
234 }
235 return propertyMap;
236}
237
239{
240 d = new QgsPropertyPrivate();
241}
242
243QgsProperty::~QgsProperty() = default;
244
245QgsProperty QgsProperty::fromExpression( const QString &expression, bool isActive )
246{
247 QgsProperty p;
248 p.setExpressionString( expression );
249 p.setActive( isActive );
250 return p;
251}
252
253QgsProperty QgsProperty::fromField( const QString &fieldName, bool isActive )
254{
255 QgsProperty p;
256 p.setField( fieldName );
257 p.setActive( isActive );
258 return p;
259}
260
262{
263 QgsProperty p;
265 p.setActive( isActive );
266 return p;
267}
268
269QgsProperty::QgsProperty( const QgsProperty &other ) //NOLINT
270 : d( other.d )
271{}
272
274{
275 if ( &other == this )
276 return *this;
277
278 d = other.d;
279 return *this;
280}
281
282bool QgsProperty::operator==( const QgsProperty &other ) const
283{
284 return d->active == other.d->active
285 && d->type == other.d->type
286 && ( d->type != Qgis::PropertyType::Static || d->staticValue == other.d->staticValue )
287 && ( d->type != Qgis::PropertyType::Field || d->fieldName == other.d->fieldName )
288 && ( d->type != Qgis::PropertyType::Expression || d->expressionString == other.d->expressionString )
289 && ( ( !d->transformer && !other.d->transformer ) || ( d->transformer && other.d->transformer && d->transformer->toExpression( QString() ) == other.d->transformer->toExpression( QString() ) ) );
290}
291
292bool QgsProperty::operator!=( const QgsProperty &other ) const
293{
294 return ( !( ( *this ) == other ) );
295}
296
298{
299 return d->type;
300}
301
303{
304 return d->type != Qgis::PropertyType::Invalid && d->active;
305}
306
308{
309 staticValue = QVariant();
310 switch ( d->type )
311 {
313 return true;
314
316 staticValue = d->staticValue;
317 return true;
318
320 return false;
321
323 {
324 QgsExpression exp = d->expression;
325 if ( exp.prepare( &context ) && exp.rootNode() )
326 {
327 if ( exp.rootNode()->hasCachedStaticValue() )
328 {
330 return true;
331 }
332 }
333 return false;
334 }
335 }
336 return false;
337}
338
339void QgsProperty::setActive( bool active )
340{
341 d.detach();
342 d->active = active;
343}
344
345void QgsProperty::setStaticValue( const QVariant &value )
346{
347 d.detach();
349 d->staticValue = value;
350}
351
353{
354 if ( d->type != Qgis::PropertyType::Static )
355 return QVariant();
356
357 return d->staticValue;
358}
359
360void QgsProperty::setField( const QString &field )
361{
362 d.detach();
364 d->fieldName = field;
365 d->cachedFieldIdx = -1;
366}
367
368QString QgsProperty::field() const
369{
370 if ( d->type != Qgis::PropertyType::Field )
371 return QString();
372
373 return d->fieldName;
374}
375
376QgsProperty::operator bool() const
377{
378 return d->type != Qgis::PropertyType::Invalid;
379}
380
381void QgsProperty::setExpressionString( const QString &expression )
382{
383 d.detach();
384 d->expressionString = expression;
385 d->expression = QgsExpression( expression );
386 d->expressionPrepared = false;
387 d->expressionIsInvalid = false;
388
389 if ( d->expressionString.isEmpty() )
390 {
391 d->active = false;
393 }
394 else
395 {
397 }
398}
399
401{
402 if ( d->type != Qgis::PropertyType::Expression )
403 return QString();
404
405 return d->expressionString;
406}
407
408
410{
411 QString exp;
412 switch ( d->type )
413 {
415 exp = QgsExpression::quotedValue( d->staticValue );
416 break;
417
419 exp = QgsExpression::quotedColumnRef( d->fieldName );
420 break;
421
423 exp = d->expressionString;
424 break;
425
427 exp = QString();
428 break;
429 }
430 return d->transformer ? d->transformer->toExpression( exp ) : exp;
431}
432
433bool QgsProperty::prepare( const QgsExpressionContext &context ) const
434{
435 if ( !d->active )
436 return true;
437
438 switch ( d->type )
439 {
441 return true;
442
444 {
445 d.detach();
446 // cache field index to avoid subsequent lookups
447 const QgsFields f = context.fields();
448 d->cachedFieldIdx = f.lookupField( d->fieldName );
449 return true;
450 }
451
453 {
454 d.detach();
455 if ( !d->expression.prepare( &context ) )
456 {
457 d->expressionReferencedCols.clear();
458 d->expressionPrepared = false;
459 d->expressionIsInvalid = true;
460 return false;
461 }
462
463 d->expressionPrepared = true;
464 d->expressionIsInvalid = false;
465 d->expressionReferencedCols = d->expression.referencedColumns();
466 return true;
467 }
468
470 return true;
471 }
472
473 return false;
474}
475
476QSet<QString> QgsProperty::referencedFields( const QgsExpressionContext &context, bool ignoreContext ) const
477{
478 if ( !d->active )
479 return QSet<QString>();
480
481 switch ( d->type )
482 {
485 return QSet<QString>();
486
488 {
489 QSet< QString > fields;
490 if ( !d->fieldName.isEmpty() )
491 fields.insert( d->fieldName );
492 return fields;
493 }
494
496 {
497 if ( ignoreContext )
498 {
499 return d->expression.referencedColumns();
500 }
501
502 if ( d->expressionIsInvalid )
503 return QSet< QString >();
504
505 d.detach();
506 if ( !d->expressionPrepared && !prepare( context ) )
507 {
508 d->expressionIsInvalid = true;
509 return QSet< QString >();
510 }
511
512 return d->expressionReferencedCols;
513 }
514 }
515 return QSet<QString>();
516}
517
519{
520 const thread_local QRegularExpression rx( u"^project_color(_object|)\\('.*'\\)$"_s );
521 return d->type == Qgis::PropertyType::Expression && !d->expressionString.isEmpty() && rx.match( d->expressionString ).hasMatch();
522}
523
524QVariant QgsProperty::propertyValue( const QgsExpressionContext &context, const QVariant &defaultValue, bool *ok ) const
525{
526 if ( ok )
527 *ok = false;
528
529 if ( !d->active )
530 return defaultValue;
531
532 switch ( d->type )
533 {
535 {
536 if ( ok )
537 *ok = true;
538 return d->staticValue;
539 }
540
542 {
543 const QgsFeature f = context.feature();
544 if ( !f.isValid() )
545 return defaultValue;
546
547 //shortcut the field lookup
548 if ( d->cachedFieldIdx >= 0 )
549 {
550 if ( ok )
551 *ok = true;
552 return f.attribute( d->cachedFieldIdx );
553 }
554 prepare( context );
555 if ( d->cachedFieldIdx < 0 )
556 return defaultValue;
557
558 if ( ok )
559 *ok = true;
560 return f.attribute( d->cachedFieldIdx );
561 }
562
564 {
565 if ( d->expressionIsInvalid )
566 return defaultValue;
567
568 if ( !d->expressionPrepared && !prepare( context ) )
569 return defaultValue;
570
571 QVariant result = d->expression.evaluate( &context );
572 if ( !QgsVariantUtils::isNull( result ) )
573 {
574 if ( ok )
575 *ok = true;
576 return result;
577 }
578 else
579 {
580 return defaultValue;
581 }
582 }
583
585 return defaultValue;
586 }
587
588 return QVariant();
589}
590
591
592QVariant QgsProperty::value( const QgsExpressionContext &context, const QVariant &defaultValue, bool *ok ) const
593{
594 if ( ok )
595 *ok = false;
596
597 bool valOk = false;
598 QVariant val = propertyValue( context, defaultValue, &valOk );
599 if ( !d->transformer && !valOk ) // if transformer present, let it handle null values
600 return defaultValue;
601
602 if ( d->transformer )
603 {
604 if ( !valOk )
605 val = QVariant();
606 val = d->transformer->transform( context, val );
607 }
608
609 if ( ok )
610 *ok = true;
611
612 return val;
613}
614
615QDateTime QgsProperty::valueAsDateTime( const QgsExpressionContext &context, const QDateTime &defaultDateTime, bool *ok ) const
616{
617 bool valOk = false;
618 const QVariant val = value( context, defaultDateTime, &valOk );
619
620 if ( !valOk || QgsVariantUtils::isNull( val ) )
621 {
622 if ( ok )
623 *ok = false;
624 return defaultDateTime;
625 }
626
627 QDateTime dateTime;
628 if ( val.userType() == QMetaType::Type::QDateTime )
629 {
630 dateTime = val.value<QDateTime>();
631 }
632 else
633 {
634 dateTime = val.toDateTime();
635 }
636
637 if ( !dateTime.isValid() )
638 return defaultDateTime;
639 else
640 {
641 if ( ok )
642 *ok = true;
643 return dateTime;
644 }
645}
646
647QString QgsProperty::valueAsString( const QgsExpressionContext &context, const QString &defaultString, bool *ok ) const
648{
649 bool valOk = false;
650 const QVariant val = value( context, defaultString, &valOk );
651
652 if ( !valOk || QgsVariantUtils::isNull( val ) )
653 {
654 if ( ok )
655 *ok = false;
656 return defaultString;
657 }
658 else
659 {
660 if ( ok )
661 *ok = true;
662 return val.toString();
663 }
664}
665
666QColor QgsProperty::valueAsColor( const QgsExpressionContext &context, const QColor &defaultColor, bool *ok ) const
667{
668 if ( ok )
669 *ok = false;
670
671 bool valOk = false;
672 const QVariant val = value( context, defaultColor, &valOk );
673
674 if ( !valOk || QgsVariantUtils::isNull( val ) )
675 return defaultColor;
676
677 QColor color;
678 if ( val.userType() == QMetaType::Type::QColor )
679 {
680 color = val.value<QColor>();
681 }
682 else
683 {
684 color = QgsSymbolLayerUtils::decodeColor( val.toString() );
685 }
686
687 if ( !color.isValid() )
688 return defaultColor;
689 else
690 {
691 if ( ok )
692 *ok = true;
693 return color;
694 }
695}
696
697double QgsProperty::valueAsDouble( const QgsExpressionContext &context, double defaultValue, bool *ok ) const
698{
699 if ( ok )
700 *ok = false;
701
702 bool valOk = false;
703 const QVariant val = value( context, defaultValue, &valOk );
704
705 if ( !valOk || QgsVariantUtils::isNull( val ) )
706 return defaultValue;
707
708 bool convertOk = false;
709 const double dbl = val.toDouble( &convertOk );
710 if ( !convertOk )
711 return defaultValue;
712 else
713 {
714 if ( ok )
715 *ok = true;
716 return dbl;
717 }
718}
719
720int QgsProperty::valueAsInt( const QgsExpressionContext &context, int defaultValue, bool *ok ) const
721{
722 if ( ok )
723 *ok = false;
724
725 bool valOk = false;
726 const QVariant val = value( context, defaultValue, &valOk );
727
728 if ( !valOk || QgsVariantUtils::isNull( val ) )
729 return defaultValue;
730
731 bool convertOk = false;
732 const int integer = val.toInt( &convertOk );
733 if ( !convertOk )
734 {
735 //one more option to try
736 const double dbl = val.toDouble( &convertOk );
737 if ( convertOk )
738 {
739 if ( ok )
740 *ok = true;
741 return std::round( dbl );
742 }
743 else
744 {
745 return defaultValue;
746 }
747 }
748 else
749 {
750 if ( ok )
751 *ok = true;
752 return integer;
753 }
754}
755
756bool QgsProperty::valueAsBool( const QgsExpressionContext &context, bool defaultValue, bool *ok ) const
757{
758 if ( ok )
759 *ok = false;
760
761 bool valOk = false;
762 const QVariant val = value( context, defaultValue, &valOk );
763
764 if ( !valOk || QgsVariantUtils::isNull( val ) )
765 return defaultValue;
766
767 if ( ok )
768 *ok = true;
769 return val.toBool();
770}
771
773{
774 QVariantMap propertyMap;
775
776 propertyMap.insert( u"active"_s, d->active );
777 propertyMap.insert( u"type"_s, static_cast< int >( d->type ) );
778
779 switch ( d->type )
780 {
782 // propertyMap.insert( u"valType"_s, d->staticValue.typeName() );
783 propertyMap.insert( u"val"_s, d->staticValue.toString() );
784 break;
785
787 propertyMap.insert( u"field"_s, d->fieldName );
788 break;
789
791 propertyMap.insert( u"expression"_s, d->expressionString );
792 break;
793
795 break;
796 }
797
798 if ( d->transformer )
799 {
800 QVariantMap transformer;
801 transformer.insert( u"t"_s, d->transformer->transformerType() );
802 transformer.insert( u"d"_s, d->transformer->toVariant() );
803
804 propertyMap.insert( u"transformer"_s, transformer );
805 }
806
807 return propertyMap;
808}
809
810bool QgsProperty::loadVariant( const QVariant &property )
811{
812 const QVariantMap propertyMap = property.toMap();
813
814 d.detach();
815 d->active = propertyMap.value( u"active"_s ).toBool();
816 d->type = static_cast< Qgis::PropertyType >( propertyMap.value( u"type"_s, static_cast< int >( Qgis::PropertyType::Invalid ) ).toInt() );
817
818 switch ( d->type )
819 {
821 d->staticValue = propertyMap.value( u"val"_s );
822 // d->staticValue.convert( QVariant::nameToType( propertyElem.attribute( "valType", "QString" ).toLocal8Bit().constData() ) );
823 break;
824
826 d->fieldName = propertyMap.value( u"field"_s ).toString();
827 if ( d->fieldName.isEmpty() )
828 d->active = false;
829 break;
830
832 d->expressionString = propertyMap.value( u"expression"_s ).toString();
833 if ( d->expressionString.isEmpty() )
834 d->active = false;
835
836 d->expression = QgsExpression( d->expressionString );
837 d->expressionPrepared = false;
838 d->expressionIsInvalid = false;
839 d->expressionReferencedCols.clear();
840 break;
841
843 break;
844 }
845
846 //restore transformer if present
847 delete d->transformer;
848 d->transformer = nullptr;
849
850
851 const QVariant transform = propertyMap.value( u"transformer"_s );
852
853 if ( transform.isValid() )
854 {
855 const QVariantMap transformerMap = transform.toMap();
856
857 const QgsPropertyTransformer::Type type = static_cast< QgsPropertyTransformer::Type >( transformerMap.value( u"t"_s, QgsPropertyTransformer::GenericNumericTransformer ).toInt() );
858 std::unique_ptr< QgsPropertyTransformer > transformer( QgsPropertyTransformer::create( type ) );
859
860 if ( transformer )
861 {
862 if ( transformer->loadVariant( transformerMap.value( u"d"_s ) ) )
863 d->transformer = transformer.release();
864 }
865 }
866
867 return true;
868}
869
870
872{
873 d.detach();
874 d->transformer = transformer;
875}
876
878{
879 return d->transformer;
880}
881
883{
884 if ( d->type != Qgis::PropertyType::Expression )
885 return false;
886
887 if ( d->transformer )
888 return false; // already a transformer
889
890 QString baseExpression;
891 QString fieldName;
892 std::unique_ptr< QgsPropertyTransformer > transformer( QgsPropertyTransformer::fromExpression( d->expressionString, baseExpression, fieldName ) );
893 if ( !transformer )
894 return false;
895
896 d.detach();
897 d->transformer = transformer.release();
898 if ( !fieldName.isEmpty() )
899 setField( fieldName );
900 else
901 setExpressionString( baseExpression );
902 return true;
903}
PropertyType
Property types.
Definition qgis.h:708
@ Invalid
Invalid (not set) property.
Definition qgis.h:709
@ Field
Field based property.
Definition qgis.h:711
@ Static
Static property.
Definition qgis.h:710
@ Expression
Expression based property.
Definition qgis.h:712
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
bool hasCachedStaticValue() const
Returns true if the node can be replaced by a static cached value.
QVariant cachedStaticValue() const
Returns the node's static cached value.
Handles parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
QString expression() const
Returns the original, unmodified expression string.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes).
const QgsExpressionNode * rootNode() const
Returns the root node of the expression.
bool isValid() const
Returns the validity of this feature.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Container of fields for a vector layer.
Definition qgsfields.h:46
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
QString helpText() const
Helper text for using the property, including a description of the valid values for the property.
QString comment() const
Returns the comment of the property.
DataType dataType() const
Returns the allowable field/value data type for the property.
QString description() const
Descriptive name of the property.
StandardPropertyTemplate
Predefined standard property templates.
Definition qgsproperty.h:51
@ HorizontalAnchor
Horizontal anchor point.
Definition qgsproperty.h:74
@ Double
Double value (including negative values).
Definition qgsproperty.h:56
@ VerticalAnchor
Vertical anchor point.
Definition qgsproperty.h:75
@ Double0To1
Double value between 0-1 (inclusive).
Definition qgsproperty.h:58
@ FillStyle
Fill style (eg solid, lines).
Definition qgsproperty.h:72
@ StrokeWidth
Line stroke width.
Definition qgsproperty.h:71
@ LineStyle
Line style (eg solid/dashed).
Definition qgsproperty.h:70
@ Integer
Integer value (including negative values).
Definition qgsproperty.h:53
@ String
Any string value.
Definition qgsproperty.h:60
@ DateTime
DateTime value.
Definition qgsproperty.h:78
@ BlendMode
Blend mode.
Definition qgsproperty.h:66
@ Boolean
Boolean value.
Definition qgsproperty.h:52
@ RenderUnits
Render units (eg mm/pixels/map units).
Definition qgsproperty.h:62
@ PenJoinStyle
Pen join style.
Definition qgsproperty.h:65
@ SvgPath
Path to an SVG file.
Definition qgsproperty.h:76
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
Definition qgsproperty.h:55
@ IntegerPositive
Positive integer values (including 0).
Definition qgsproperty.h:54
@ Opacity
Opacity (0-100).
Definition qgsproperty.h:61
@ CapStyle
Line cap style (eg round).
Definition qgsproperty.h:73
@ ColorNoAlpha
Color with no alpha channel.
Definition qgsproperty.h:64
@ Rotation
Rotation (value between 0-360 degrees).
Definition qgsproperty.h:59
@ Custom
Custom property types.
Definition qgsproperty.h:79
@ Size
1D size (eg marker radius, or square marker height/width)
Definition qgsproperty.h:68
@ ColorWithAlpha
Color with alpha channel.
Definition qgsproperty.h:63
@ DoublePositive
Positive double value (including 0).
Definition qgsproperty.h:57
@ Size2D
2D size (width/height different)
Definition qgsproperty.h:69
QString name() const
Returns the name of the property.
bool supportsAssistant() const
Returns true if the property is of a type which is compatible with property override assistants.
QgsPropertyDefinition()=default
Constructs an empty property.
QString origin() const
Returns the origin of the property.
DataType
Valid data types required by property.
Definition qgsproperty.h:84
@ DataTypeString
Property requires a string value.
Definition qgsproperty.h:91
@ DataTypeBoolean
Property requires a boolean value.
@ DataTypeNumeric
Property requires a numeric value.
Definition qgsproperty.h:98
Abstract base class for objects which transform the calculated value of a property.
static QgsPropertyTransformer * fromExpression(const QString &expression, QString &baseExpression, QString &fieldName)
Attempts to parse an expression into a corresponding property transformer.
@ GenericNumericTransformer
Generic transformer for numeric values (QgsGenericNumericTransformer).
static QgsPropertyTransformer * create(Type type)
Factory method for creating a new property transformer of the specified type.
QDateTime valueAsDateTime(const QgsExpressionContext &context, const QDateTime &defaultDateTime=QDateTime(), bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a datetime.
QColor valueAsColor(const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a color.
bool isProjectColor() const
Returns true if the property is set to a linked project color.
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext(), bool ignoreContext=false) const
Returns the set of any fields referenced by the property for a specified expression context.
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
bool operator==(const QgsProperty &other) const
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
QString expressionString() const
Returns the expression used for the property value.
bool convertToTransformer()
Attempts to convert an existing expression based property to a base expression with corresponding tra...
void setTransformer(QgsPropertyTransformer *transformer)
Sets an optional transformer to use for manipulating the calculated values for the property.
void setStaticValue(const QVariant &value)
Sets the static value for the property.
Qgis::PropertyType propertyType() const
Returns the property type.
QString valueAsString(const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a string.
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,...
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
QVariant toVariant() const
Saves this property to a QVariantMap, wrapped in a QVariant.
bool isActive() const
Returns whether the property is currently active.
double valueAsDouble(const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a double.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
void setField(const QString &field)
Sets the field name the property references.
int valueAsInt(const QgsExpressionContext &context, int defaultValue=0, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as an integer.
bool valueAsBool(const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as an boolean.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const
Prepares the property against a specified expression context.
bool loadVariant(const QVariant &property)
Loads this property from a QVariantMap, wrapped in a QVariant.
QVariant staticValue() const
Returns the current static value for the property.
bool operator!=(const QgsProperty &other) const
bool isStaticValueInContext(const QgsExpressionContext &context, QVariant &staticValue) const
Returns true if the property is effectively a static value in the specified context.
void setExpressionString(const QString &expression)
Sets the expression to use for the property value.
QgsProperty & operator=(const QgsProperty &other)
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
QgsProperty()
Constructor for a QgsProperty.
static QgsProperty fromValue(const QVariant &value, bool isActive=true)
Returns a new StaticProperty created from the specified value.
void setActive(bool active)
Sets whether the property is currently active.
static QColor decodeColor(const QString &str)
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.