QGIS API Documentation 3.99.0-Master (d270888f95f)
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() + QStringLiteral( "[<b>Normal</b>|<b>Lighten</b>|<b>Screen</b>|<b>Dodge</b>|<br>"
110 "<b>Addition</b>|<b>Darken</b>|<b>Multiply</b>|<b>Burn</b>|<b>Overlay</b>|<br>"
111 "<b>SoftLight</b>|<b>HardLight</b>|<b>Difference</b>|<b>Subtract</b>]" );
112 break;
113
114 case Point:
115 mTypes = DataTypeString;
116 mHelpText = QObject::tr( "double coord [<b>X,Y</b>]" );
117 break;
118
119 case Size:
120 mTypes = DataTypeNumeric;
121 mHelpText = QObject::tr( "double [≥ 0.0]" );
122 break;
123
124 case Size2D:
125 mTypes = DataTypeString;
126 mHelpText = QObject::tr( "string of doubles '<b>width,height</b>' or array of doubles <b>[width, height]</b>" );
127 break;
128
129 case LineStyle:
130 mTypes = DataTypeString;
131 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;
132 break;
133
134 case StrokeWidth:
135 mTypes = DataTypeNumeric;
136 mHelpText = QObject::tr( "double [≥ 0.0]" );
137 break;
138
139 case FillStyle:
140 mTypes = DataTypeString;
141 mHelpText = trString() + QStringLiteral( "[<b>solid</b>|<b>horizontal</b>|<b>vertical</b>|<b>cross</b>|<b>b_diagonal</b>|<b>f_diagonal"
142 "</b>|<b>diagonal_x</b>|<b>dense1</b>|<b>dense2</b>|<b>dense3</b>|<b>dense4</b>|<b>dense5"
143 "</b>|<b>dense6</b>|<b>dense7</b>|<b>no]" );
144 break;
145
146 case CapStyle:
147 mTypes = DataTypeString;
148 mHelpText = trString() + u"[<b>square</b>|<b>flat</b>|<b>round</b>]"_s;
149 break;
150
151 case HorizontalAnchor:
152 mTypes = DataTypeString;
153 mHelpText = trString() + u"[<b>left</b>|<b>center</b>|<b>right</b>]"_s;
154 break;
155
156 case VerticalAnchor:
157 mTypes = DataTypeString;
158 mHelpText = trString() + u"[<b>top</b>|<b>center</b>|<b>bottom</b>]"_s;
159 break;
160
161 case SvgPath:
162 mTypes = DataTypeString;
163 mHelpText = trString() + QStringLiteral( "[<b>filepath</b>] as<br>"
164 "<b>''</b>=empty|absolute|search-paths-relative|<br>"
165 "project-relative|URL" );
166 break;
167
168 case Offset:
169 mTypes = DataTypeString;
170 mHelpText = QObject::tr( "string of doubles '<b>x,y</b>' or array of doubles <b>[x, y]</b>" );
171 break;
172
173 case DateTime:
174 mTypes = DataTypeString;
175 mHelpText = QObject::tr( "DateTime or string representation of a DateTime" );
176 break;
177
178 case Custom:
179 mTypes = DataTypeString;
180 }
181}
182
183QgsPropertyDefinition::QgsPropertyDefinition( const QString &name, DataType dataType, const QString &description, const QString &helpText, const QString &origin, const QString &comment )
184 : mName( name )
185 , mDescription( description )
186 , mTypes( dataType )
187 , mHelpText( helpText )
188 , mOrigin( origin )
189 , mComment( comment )
190{}
191
193{
194 return mTypes == DataTypeNumeric || mStandardType == Size || mStandardType == StrokeWidth || mStandardType == ColorNoAlpha || mStandardType == ColorWithAlpha
195 || mStandardType == Rotation;
196}
197
198QString QgsPropertyDefinition::trString()
199{
200 // just something to reduce translation redundancy
201 return QObject::tr( "string " );
202}
203
204//
205// QgsProperty
206//
207
208QVariantMap QgsProperty::propertyMapToVariantMap( const QMap<QString, QgsProperty> &propertyMap )
209{
210 QVariantMap variantMap;
211 QMap<QString, QgsProperty>::const_iterator it = propertyMap.constBegin();
212 for ( ; it != propertyMap.constEnd(); ++it )
213 variantMap.insert( it.key(), it.value().toVariant() );
214 return variantMap;
215}
216
217QMap<QString, QgsProperty> QgsProperty::variantMapToPropertyMap( const QVariantMap &variantMap )
218{
219 QMap<QString, QgsProperty> propertyMap;
220 QVariantMap::const_iterator it = variantMap.constBegin();
221 for ( ; it != variantMap.constEnd(); ++it )
222 {
223 QgsProperty property;
224 if ( property.loadVariant( it.value() ) )
225 propertyMap.insert( it.key(), property );
226 }
227 return propertyMap;
228}
229
231{
232 d = new QgsPropertyPrivate();
233}
234
235QgsProperty::~QgsProperty() = default;
236
237QgsProperty QgsProperty::fromExpression( const QString &expression, bool isActive )
238{
239 QgsProperty p;
240 p.setExpressionString( expression );
241 p.setActive( isActive );
242 return p;
243}
244
245QgsProperty QgsProperty::fromField( const QString &fieldName, bool isActive )
246{
247 QgsProperty p;
248 p.setField( fieldName );
249 p.setActive( isActive );
250 return p;
251}
252
254{
255 QgsProperty p;
257 p.setActive( isActive );
258 return p;
259}
260
261QgsProperty::QgsProperty( const QgsProperty &other ) //NOLINT
262 : d( other.d )
263{}
264
266{
267 if ( &other == this )
268 return *this;
269
270 d = other.d;
271 return *this;
272}
273
274bool QgsProperty::operator==( const QgsProperty &other ) const
275{
276 return d->active == other.d->active
277 && d->type == other.d->type
278 && ( d->type != Qgis::PropertyType::Static || d->staticValue == other.d->staticValue )
279 && ( d->type != Qgis::PropertyType::Field || d->fieldName == other.d->fieldName )
280 && ( d->type != Qgis::PropertyType::Expression || d->expressionString == other.d->expressionString )
281 && ( ( !d->transformer && !other.d->transformer ) || ( d->transformer && other.d->transformer && d->transformer->toExpression( QString() ) == other.d->transformer->toExpression( QString() ) ) );
282}
283
284bool QgsProperty::operator!=( const QgsProperty &other ) const
285{
286 return ( !( ( *this ) == other ) );
287}
288
290{
291 return d->type;
292}
293
295{
296 return d->type != Qgis::PropertyType::Invalid && d->active;
297}
298
300{
301 staticValue = QVariant();
302 switch ( d->type )
303 {
305 return true;
306
308 staticValue = d->staticValue;
309 return true;
310
312 return false;
313
315 {
316 QgsExpression exp = d->expression;
317 if ( exp.prepare( &context ) && exp.rootNode() )
318 {
319 if ( exp.rootNode()->hasCachedStaticValue() )
320 {
322 return true;
323 }
324 }
325 return false;
326 }
327 }
328 return false;
329}
330
331void QgsProperty::setActive( bool active )
332{
333 d.detach();
334 d->active = active;
335}
336
337void QgsProperty::setStaticValue( const QVariant &value )
338{
339 d.detach();
341 d->staticValue = value;
342}
343
345{
346 if ( d->type != Qgis::PropertyType::Static )
347 return QVariant();
348
349 return d->staticValue;
350}
351
352void QgsProperty::setField( const QString &field )
353{
354 d.detach();
356 d->fieldName = field;
357 d->cachedFieldIdx = -1;
358}
359
360QString QgsProperty::field() const
361{
362 if ( d->type != Qgis::PropertyType::Field )
363 return QString();
364
365 return d->fieldName;
366}
367
368QgsProperty::operator bool() const
369{
370 return d->type != Qgis::PropertyType::Invalid;
371}
372
373void QgsProperty::setExpressionString( const QString &expression )
374{
375 d.detach();
376 d->expressionString = expression;
377 d->expression = QgsExpression( expression );
378 d->expressionPrepared = false;
379 d->expressionIsInvalid = false;
380
381 if ( d->expressionString.isEmpty() )
382 {
383 d->active = false;
385 }
386 else
387 {
389 }
390}
391
393{
394 if ( d->type != Qgis::PropertyType::Expression )
395 return QString();
396
397 return d->expressionString;
398}
399
400
402{
403 QString exp;
404 switch ( d->type )
405 {
407 exp = QgsExpression::quotedValue( d->staticValue );
408 break;
409
411 exp = QgsExpression::quotedColumnRef( d->fieldName );
412 break;
413
415 exp = d->expressionString;
416 break;
417
419 exp = QString();
420 break;
421 }
422 return d->transformer ? d->transformer->toExpression( exp ) : exp;
423}
424
425bool QgsProperty::prepare( const QgsExpressionContext &context ) const
426{
427 if ( !d->active )
428 return true;
429
430 switch ( d->type )
431 {
433 return true;
434
436 {
437 d.detach();
438 // cache field index to avoid subsequent lookups
439 const QgsFields f = context.fields();
440 d->cachedFieldIdx = f.lookupField( d->fieldName );
441 return true;
442 }
443
445 {
446 d.detach();
447 if ( !d->expression.prepare( &context ) )
448 {
449 d->expressionReferencedCols.clear();
450 d->expressionPrepared = false;
451 d->expressionIsInvalid = true;
452 return false;
453 }
454
455 d->expressionPrepared = true;
456 d->expressionIsInvalid = false;
457 d->expressionReferencedCols = d->expression.referencedColumns();
458 return true;
459 }
460
462 return true;
463
464 }
465
466 return false;
467}
468
469QSet<QString> QgsProperty::referencedFields( const QgsExpressionContext &context, bool ignoreContext ) const
470{
471 if ( !d->active )
472 return QSet<QString>();
473
474 switch ( d->type )
475 {
478 return QSet<QString>();
479
481 {
482 QSet< QString > fields;
483 if ( !d->fieldName.isEmpty() )
484 fields.insert( d->fieldName );
485 return fields;
486 }
487
489 {
490 if ( ignoreContext )
491 {
492 return d->expression.referencedColumns();
493 }
494
495 if ( d->expressionIsInvalid )
496 return QSet< QString >();
497
498 d.detach();
499 if ( !d->expressionPrepared && !prepare( context ) )
500 {
501 d->expressionIsInvalid = true;
502 return QSet< QString >();
503 }
504
505 return d->expressionReferencedCols;
506 }
507
508 }
509 return QSet<QString>();
510}
511
513{
514 const thread_local QRegularExpression rx( u"^project_color(_object|)\\('.*'\\)$"_s );
515 return d->type == Qgis::PropertyType::Expression && !d->expressionString.isEmpty()
516 && rx.match( d->expressionString ).hasMatch();
517}
518
519QVariant QgsProperty::propertyValue( const QgsExpressionContext &context, const QVariant &defaultValue, bool *ok ) const
520{
521 if ( ok )
522 *ok = false;
523
524 if ( !d->active )
525 return defaultValue;
526
527 switch ( d->type )
528 {
530 {
531 if ( ok )
532 *ok = true;
533 return d->staticValue;
534 }
535
537 {
538 const QgsFeature f = context.feature();
539 if ( !f.isValid() )
540 return defaultValue;
541
542 //shortcut the field lookup
543 if ( d->cachedFieldIdx >= 0 )
544 {
545 if ( ok )
546 *ok = true;
547 return f.attribute( d->cachedFieldIdx );
548 }
549 prepare( context );
550 if ( d->cachedFieldIdx < 0 )
551 return defaultValue;
552
553 if ( ok )
554 *ok = true;
555 return f.attribute( d->cachedFieldIdx );
556 }
557
559 {
560 if ( d->expressionIsInvalid )
561 return defaultValue;
562
563 if ( !d->expressionPrepared && !prepare( context ) )
564 return defaultValue;
565
566 QVariant result = d->expression.evaluate( &context );
567 if ( !QgsVariantUtils::isNull( result ) )
568 {
569 if ( ok )
570 *ok = true;
571 return result;
572 }
573 else
574 {
575 return defaultValue;
576 }
577 }
578
580 return defaultValue;
581
582 }
583
584 return QVariant();
585}
586
587
588QVariant QgsProperty::value( const QgsExpressionContext &context, const QVariant &defaultValue, bool *ok ) const
589{
590 if ( ok )
591 *ok = false;
592
593 bool valOk = false;
594 QVariant val = propertyValue( context, defaultValue, &valOk );
595 if ( !d->transformer && !valOk ) // if transformer present, let it handle null values
596 return defaultValue;
597
598 if ( d->transformer )
599 {
600 if ( !valOk )
601 val = QVariant();
602 val = d->transformer->transform( context, val );
603 }
604
605 if ( ok )
606 *ok = true;
607
608 return val;
609}
610
611QDateTime QgsProperty::valueAsDateTime( const QgsExpressionContext &context, const QDateTime &defaultDateTime, bool *ok ) const
612{
613 bool valOk = false;
614 const QVariant val = value( context, defaultDateTime, &valOk );
615
616 if ( !valOk || QgsVariantUtils::isNull( val ) )
617 {
618 if ( ok )
619 *ok = false;
620 return defaultDateTime;
621 }
622
623 QDateTime dateTime;
624 if ( val.userType() == QMetaType::Type::QDateTime )
625 {
626 dateTime = val.value<QDateTime>();
627 }
628 else
629 {
630 dateTime = val.toDateTime();
631 }
632
633 if ( !dateTime.isValid() )
634 return defaultDateTime;
635 else
636 {
637 if ( ok )
638 *ok = true;
639 return dateTime;
640 }
641}
642
643QString QgsProperty::valueAsString( const QgsExpressionContext &context, const QString &defaultString, bool *ok ) const
644{
645 bool valOk = false;
646 const QVariant val = value( context, defaultString, &valOk );
647
648 if ( !valOk || QgsVariantUtils::isNull( val ) )
649 {
650 if ( ok )
651 *ok = false;
652 return defaultString;
653 }
654 else
655 {
656 if ( ok )
657 *ok = true;
658 return val.toString();
659 }
660}
661
662QColor QgsProperty::valueAsColor( const QgsExpressionContext &context, const QColor &defaultColor, bool *ok ) const
663{
664 if ( ok )
665 *ok = false;
666
667 bool valOk = false;
668 const QVariant val = value( context, defaultColor, &valOk );
669
670 if ( !valOk || QgsVariantUtils::isNull( val ) )
671 return defaultColor;
672
673 QColor color;
674 if ( val.userType() == QMetaType::Type::QColor )
675 {
676 color = val.value<QColor>();
677 }
678 else
679 {
680 color = QgsSymbolLayerUtils::decodeColor( val.toString() );
681 }
682
683 if ( !color.isValid() )
684 return defaultColor;
685 else
686 {
687 if ( ok )
688 *ok = true;
689 return color;
690 }
691}
692
693double QgsProperty::valueAsDouble( const QgsExpressionContext &context, double defaultValue, bool *ok ) const
694{
695 if ( ok )
696 *ok = false;
697
698 bool valOk = false;
699 const QVariant val = value( context, defaultValue, &valOk );
700
701 if ( !valOk || QgsVariantUtils::isNull( val ) )
702 return defaultValue;
703
704 bool convertOk = false;
705 const double dbl = val.toDouble( &convertOk );
706 if ( !convertOk )
707 return defaultValue;
708 else
709 {
710 if ( ok )
711 *ok = true;
712 return dbl;
713 }
714}
715
716int QgsProperty::valueAsInt( const QgsExpressionContext &context, int defaultValue, bool *ok ) const
717{
718 if ( ok )
719 *ok = false;
720
721 bool valOk = false;
722 const QVariant val = value( context, defaultValue, &valOk );
723
724 if ( !valOk || QgsVariantUtils::isNull( val ) )
725 return defaultValue;
726
727 bool convertOk = false;
728 const int integer = val.toInt( &convertOk );
729 if ( !convertOk )
730 {
731 //one more option to try
732 const double dbl = val.toDouble( &convertOk );
733 if ( convertOk )
734 {
735 if ( ok )
736 *ok = true;
737 return std::round( dbl );
738 }
739 else
740 {
741 return defaultValue;
742 }
743 }
744 else
745 {
746 if ( ok )
747 *ok = true;
748 return integer;
749 }
750}
751
752bool QgsProperty::valueAsBool( const QgsExpressionContext &context, bool defaultValue, bool *ok ) const
753{
754 if ( ok )
755 *ok = false;
756
757 bool valOk = false;
758 const QVariant val = value( context, defaultValue, &valOk );
759
760 if ( !valOk || QgsVariantUtils::isNull( val ) )
761 return defaultValue;
762
763 if ( ok )
764 *ok = true;
765 return val.toBool();
766}
767
769{
770 QVariantMap propertyMap;
771
772 propertyMap.insert( u"active"_s, d->active );
773 propertyMap.insert( u"type"_s, static_cast< int >( d->type ) );
774
775 switch ( d->type )
776 {
778 // propertyMap.insert( u"valType"_s, d->staticValue.typeName() );
779 propertyMap.insert( u"val"_s, d->staticValue.toString() );
780 break;
781
783 propertyMap.insert( u"field"_s, d->fieldName );
784 break;
785
787 propertyMap.insert( u"expression"_s, d->expressionString );
788 break;
789
791 break;
792 }
793
794 if ( d->transformer )
795 {
796 QVariantMap transformer;
797 transformer.insert( u"t"_s, d->transformer->transformerType() );
798 transformer.insert( u"d"_s, d->transformer->toVariant() );
799
800 propertyMap.insert( u"transformer"_s, transformer );
801 }
802
803 return propertyMap;
804}
805
806bool QgsProperty::loadVariant( const QVariant &property )
807{
808 const QVariantMap propertyMap = property.toMap();
809
810 d.detach();
811 d->active = propertyMap.value( u"active"_s ).toBool();
812 d->type = static_cast< Qgis::PropertyType >( propertyMap.value( u"type"_s, static_cast< int >( Qgis::PropertyType::Invalid ) ).toInt() );
813
814 switch ( d->type )
815 {
817 d->staticValue = propertyMap.value( u"val"_s );
818 // d->staticValue.convert( QVariant::nameToType( propertyElem.attribute( "valType", "QString" ).toLocal8Bit().constData() ) );
819 break;
820
822 d->fieldName = propertyMap.value( u"field"_s ).toString();
823 if ( d->fieldName.isEmpty() )
824 d->active = false;
825 break;
826
828 d->expressionString = propertyMap.value( u"expression"_s ).toString();
829 if ( d->expressionString.isEmpty() )
830 d->active = false;
831
832 d->expression = QgsExpression( d->expressionString );
833 d->expressionPrepared = false;
834 d->expressionIsInvalid = false;
835 d->expressionReferencedCols.clear();
836 break;
837
839 break;
840
841 }
842
843 //restore transformer if present
844 delete d->transformer;
845 d->transformer = nullptr;
846
847
848 const QVariant transform = propertyMap.value( u"transformer"_s );
849
850 if ( transform.isValid() )
851 {
852 const QVariantMap transformerMap = transform.toMap();
853
854 const QgsPropertyTransformer::Type type = static_cast< QgsPropertyTransformer::Type >( transformerMap.value( u"t"_s, QgsPropertyTransformer::GenericNumericTransformer ).toInt() );
855 std::unique_ptr< QgsPropertyTransformer > transformer( QgsPropertyTransformer::create( type ) );
856
857 if ( transformer )
858 {
859 if ( transformer->loadVariant( transformerMap.value( u"d"_s ) ) )
860 d->transformer = transformer.release();
861 }
862 }
863
864 return true;
865}
866
867
869{
870 d.detach();
871 d->transformer = transformer;
872}
873
875{
876 return d->transformer;
877}
878
880{
881 if ( d->type != Qgis::PropertyType::Expression )
882 return false;
883
884 if ( d->transformer )
885 return false; // already a transformer
886
887 QString baseExpression;
888 QString fieldName;
889 std::unique_ptr< QgsPropertyTransformer > transformer( QgsPropertyTransformer::fromExpression( d->expressionString, baseExpression, fieldName ) );
890 if ( !transformer )
891 return false;
892
893 d.detach();
894 d->transformer = transformer.release();
895 if ( !fieldName.isEmpty() )
896 setField( fieldName );
897 else
898 setExpressionString( baseExpression );
899 return true;
900}
PropertyType
Property types.
Definition qgis.h:701
@ Invalid
Invalid (not set) property.
Definition qgis.h:702
@ Field
Field based property.
Definition qgis.h:704
@ Static
Static property.
Definition qgis.h:703
@ Expression
Expression based property.
Definition qgis.h:705
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:52
@ HorizontalAnchor
Horizontal anchor point.
Definition qgsproperty.h:75
@ Double
Double value (including negative values).
Definition qgsproperty.h:57
@ VerticalAnchor
Vertical anchor point.
Definition qgsproperty.h:76
@ Double0To1
Double value between 0-1 (inclusive).
Definition qgsproperty.h:59
@ FillStyle
Fill style (eg solid, lines).
Definition qgsproperty.h:73
@ StrokeWidth
Line stroke width.
Definition qgsproperty.h:72
@ LineStyle
Line style (eg solid/dashed).
Definition qgsproperty.h:71
@ Integer
Integer value (including negative values).
Definition qgsproperty.h:54
@ String
Any string value.
Definition qgsproperty.h:61
@ DateTime
DateTime value.
Definition qgsproperty.h:79
@ BlendMode
Blend mode.
Definition qgsproperty.h:67
@ Boolean
Boolean value.
Definition qgsproperty.h:53
@ RenderUnits
Render units (eg mm/pixels/map units).
Definition qgsproperty.h:63
@ PenJoinStyle
Pen join style.
Definition qgsproperty.h:66
@ SvgPath
Path to an SVG file.
Definition qgsproperty.h:77
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
Definition qgsproperty.h:56
@ IntegerPositive
Positive integer values (including 0).
Definition qgsproperty.h:55
@ Opacity
Opacity (0-100).
Definition qgsproperty.h:62
@ CapStyle
Line cap style (eg round).
Definition qgsproperty.h:74
@ ColorNoAlpha
Color with no alpha channel.
Definition qgsproperty.h:65
@ Rotation
Rotation (value between 0-360 degrees).
Definition qgsproperty.h:60
@ Custom
Custom property types.
Definition qgsproperty.h:80
@ Size
1D size (eg marker radius, or square marker height/width)
Definition qgsproperty.h:69
@ ColorWithAlpha
Color with alpha channel.
Definition qgsproperty.h:64
@ DoublePositive
Positive double value (including 0).
Definition qgsproperty.h:58
@ Size2D
2D size (width/height different)
Definition qgsproperty.h:70
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:85
@ DataTypeString
Property requires a string value.
Definition qgsproperty.h:92
@ DataTypeBoolean
Property requires a boolean value.
@ DataTypeNumeric
Property requires a numeric value.
Definition qgsproperty.h:99
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.