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