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