QGIS API Documentation  3.2.0-Bonn (bc43194)
qgsexpressioncontext.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpressioncontext.cpp
3  ------------------------
4  Date : April 2015
5  Copyright : (C) 2015 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 "qgsexpressioncontext.h"
17 
18 #include "qgslogger.h"
19 #include "qgsexpression.h"
20 #include "qgsexpressionfunction.h"
21 #include "qgsfields.h"
22 #include "qgsvectorlayer.h"
23 #include "qgsproject.h"
24 #include "qgssymbollayerutils.h"
25 #include "qgsgeometry.h"
26 #include "qgsapplication.h"
27 #include "qgsmapsettings.h"
28 #include "qgsmaplayerlistutils.h"
29 #include "qgsprocessingcontext.h"
30 #include "qgsprocessingalgorithm.h"
31 #include "qgslayoutatlas.h"
32 #include "qgslayout.h"
34 #include "qgslayoutreportcontext.h"
35 
36 #include <QSettings>
37 #include <QDir>
38 
39 
40 const QString QgsExpressionContext::EXPR_FIELDS( QStringLiteral( "_fields_" ) );
41 const QString QgsExpressionContext::EXPR_ORIGINAL_VALUE( QStringLiteral( "value" ) );
42 const QString QgsExpressionContext::EXPR_SYMBOL_COLOR( QStringLiteral( "symbol_color" ) );
43 const QString QgsExpressionContext::EXPR_SYMBOL_ANGLE( QStringLiteral( "symbol_angle" ) );
44 const QString QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT( QStringLiteral( "geometry_part_count" ) );
45 const QString QgsExpressionContext::EXPR_GEOMETRY_PART_NUM( QStringLiteral( "geometry_part_num" ) );
46 const QString QgsExpressionContext::EXPR_GEOMETRY_POINT_COUNT( QStringLiteral( "geometry_point_count" ) );
47 const QString QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM( QStringLiteral( "geometry_point_num" ) );
48 const QString QgsExpressionContext::EXPR_CLUSTER_SIZE( QStringLiteral( "cluster_size" ) );
49 const QString QgsExpressionContext::EXPR_CLUSTER_COLOR( QStringLiteral( "cluster_color" ) );
50 
51 //
52 // QgsExpressionContextScope
53 //
54 
56  : mName( name )
57 {
58 
59 }
60 
62  : mName( other.mName )
63  , mVariables( other.mVariables )
64  , mHasFeature( other.mHasFeature )
65  , mFeature( other.mFeature )
66 {
67  QHash<QString, QgsScopedExpressionFunction * >::const_iterator it = other.mFunctions.constBegin();
68  for ( ; it != other.mFunctions.constEnd(); ++it )
69  {
70  mFunctions.insert( it.key(), it.value()->clone() );
71  }
72 }
73 
75 {
76  mName = other.mName;
77  mVariables = other.mVariables;
78  mHasFeature = other.mHasFeature;
79  mFeature = other.mFeature;
80 
81  qDeleteAll( mFunctions );
82  mFunctions.clear();
83  QHash<QString, QgsScopedExpressionFunction * >::const_iterator it = other.mFunctions.constBegin();
84  for ( ; it != other.mFunctions.constEnd(); ++it )
85  {
86  mFunctions.insert( it.key(), it.value()->clone() );
87  }
88 
89  return *this;
90 }
91 
93 {
94  qDeleteAll( mFunctions );
95 }
96 
97 void QgsExpressionContextScope::setVariable( const QString &name, const QVariant &value, bool isStatic )
98 {
99  if ( mVariables.contains( name ) )
100  {
101  StaticVariable existing = mVariables.value( name );
102  existing.value = value;
103  existing.isStatic = isStatic;
104  addVariable( existing );
105  }
106  else
107  {
108  addVariable( QgsExpressionContextScope::StaticVariable( name, value, false, isStatic ) );
109  }
110 }
111 
113 {
114  mVariables.insert( variable.name, variable );
115 }
116 
118 {
119  return mVariables.remove( name ) > 0;
120 }
121 
122 bool QgsExpressionContextScope::hasVariable( const QString &name ) const
123 {
124  return mVariables.contains( name );
125 }
126 
127 QVariant QgsExpressionContextScope::variable( const QString &name ) const
128 {
129  return hasVariable( name ) ? mVariables.value( name ).value : QVariant();
130 }
131 
133 {
134  QStringList names = mVariables.keys();
135  return names;
136 }
137 
138 bool QgsExpressionContextScope::variableNameSort( const QString &a, const QString &b )
139 {
140  return QString::localeAwareCompare( a, b ) < 0;
141 }
142 
144 class QgsExpressionContextVariableCompare
145 {
146  public:
147  explicit QgsExpressionContextVariableCompare( const QgsExpressionContextScope &scope )
148  : mScope( scope )
149  { }
150 
151  bool operator()( const QString &a, const QString &b ) const
152  {
153  bool aReadOnly = mScope.isReadOnly( a );
154  bool bReadOnly = mScope.isReadOnly( b );
155  if ( aReadOnly != bReadOnly )
156  return aReadOnly;
157  return QString::localeAwareCompare( a, b ) < 0;
158  }
159 
160  private:
161  const QgsExpressionContextScope &mScope;
162 };
164 
166 {
167  QStringList allVariables = mVariables.keys();
168  QStringList filtered;
169  Q_FOREACH ( const QString &variable, allVariables )
170  {
171  if ( variable.startsWith( '_' ) )
172  continue;
173 
174  filtered << variable;
175  }
176  QgsExpressionContextVariableCompare cmp( *this );
177  std::sort( filtered.begin(), filtered.end(), cmp );
178 
179  return filtered;
180 }
181 
182 bool QgsExpressionContextScope::isReadOnly( const QString &name ) const
183 {
184  return hasVariable( name ) ? mVariables.value( name ).readOnly : false;
185 }
186 
187 bool QgsExpressionContextScope::isStatic( const QString &name ) const
188 {
189  return hasVariable( name ) ? mVariables.value( name ).isStatic : false;
190 }
191 
192 QString QgsExpressionContextScope::description( const QString &name ) const
193 {
194  return hasVariable( name ) ? mVariables.value( name ).description : QString();
195 }
196 
197 bool QgsExpressionContextScope::hasFunction( const QString &name ) const
198 {
199  return mFunctions.contains( name );
200 }
201 
203 {
204  return mFunctions.contains( name ) ? mFunctions.value( name ) : nullptr;
205 }
206 
208 {
209  return mFunctions.keys();
210 }
211 
213 {
214  mFunctions.insert( name, function );
215 }
216 
217 
219 {
220  addVariable( StaticVariable( QgsExpressionContext::EXPR_FIELDS, QVariant::fromValue( fields ), true ) );
221 }
222 
223 
224 //
225 // QgsExpressionContext
226 //
227 
228 QgsExpressionContext::QgsExpressionContext( const QList<QgsExpressionContextScope *> &scopes )
229  : mStack( scopes )
230 {
231 }
232 
234 {
235  Q_FOREACH ( const QgsExpressionContextScope *scope, other.mStack )
236  {
237  mStack << new QgsExpressionContextScope( *scope );
238  }
239  mHighlightedVariables = other.mHighlightedVariables;
240  mCachedValues = other.mCachedValues;
241 }
242 
244 {
245  if ( this != &other )
246  {
247  qDeleteAll( mStack );
248  // move the stack over
249  mStack = other.mStack;
250  other.mStack.clear();
251 
252  mHighlightedVariables = other.mHighlightedVariables;
253  mCachedValues = other.mCachedValues;
254  }
255  return *this;
256 }
257 
259 {
260  qDeleteAll( mStack );
261  mStack.clear();
262  Q_FOREACH ( const QgsExpressionContextScope *scope, other.mStack )
263  {
264  mStack << new QgsExpressionContextScope( *scope );
265  }
266  mHighlightedVariables = other.mHighlightedVariables;
267  mCachedValues = other.mCachedValues;
268  return *this;
269 }
270 
272 {
273  qDeleteAll( mStack );
274  mStack.clear();
275 }
276 
277 bool QgsExpressionContext::hasVariable( const QString &name ) const
278 {
279  Q_FOREACH ( const QgsExpressionContextScope *scope, mStack )
280  {
281  if ( scope->hasVariable( name ) )
282  return true;
283  }
284  return false;
285 }
286 
287 QVariant QgsExpressionContext::variable( const QString &name ) const
288 {
290  return scope ? scope->variable( name ) : QVariant();
291 }
292 
294 {
295  QStringList names = variableNames();
296  QVariantMap m;
297  Q_FOREACH ( const QString &name, names )
298  {
299  m.insert( name, variable( name ) );
300  }
301  return m;
302 }
303 
304 bool QgsExpressionContext::isHighlightedVariable( const QString &name ) const
305 {
306  return mHighlightedVariables.contains( name );
307 }
308 
310 {
311  mHighlightedVariables = variableNames;
312 }
313 
315 {
316  //iterate through stack backwards, so that higher priority variables take precedence
317  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
318  while ( it != mStack.constBegin() )
319  {
320  --it;
321  if ( ( *it )->hasVariable( name ) )
322  return ( *it );
323  }
324  return nullptr;
325 }
326 
328 {
329  //iterate through stack backwards, so that higher priority variables take precedence
330  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
331  while ( it != mStack.constBegin() )
332  {
333  --it;
334  if ( ( *it )->hasVariable( name ) )
335  return ( *it );
336  }
337  return nullptr;
338 }
339 
341 {
342  if ( index < 0 || index >= mStack.count() )
343  return nullptr;
344 
345  return mStack.at( index );
346 }
347 
349 {
350  if ( mStack.count() < 1 )
351  return nullptr;
352 
353  return mStack.last();
354 }
355 
357 {
358  if ( !scope )
359  return -1;
360 
361  return mStack.indexOf( scope );
362 }
363 
364 int QgsExpressionContext::indexOfScope( const QString &scopeName ) const
365 {
366  int index = 0;
367  Q_FOREACH ( const QgsExpressionContextScope *scope, mStack )
368  {
369  if ( scope->name() == scopeName )
370  return index;
371 
372  index++;
373  }
374  return -1;
375 }
376 
378 {
379  QStringList names;
380  Q_FOREACH ( const QgsExpressionContextScope *scope, mStack )
381  {
382  names << scope->variableNames();
383  }
384  return names.toSet().toList();
385 }
386 
388 {
389  QStringList allVariables = variableNames();
390  QStringList filtered;
391  Q_FOREACH ( const QString &variable, allVariables )
392  {
393  if ( variable.startsWith( '_' ) )
394  continue;
395 
396  filtered << variable;
397  }
398 
399  filtered.sort();
400  return filtered;
401 }
402 
403 bool QgsExpressionContext::isReadOnly( const QString &name ) const
404 {
405  Q_FOREACH ( const QgsExpressionContextScope *scope, mStack )
406  {
407  if ( scope->isReadOnly( name ) )
408  return true;
409  }
410  return false;
411 }
412 
413 QString QgsExpressionContext::description( const QString &name ) const
414 {
416  return ( scope && !scope->description( name ).isEmpty() ) ? scope->description( name ) : QgsExpression::variableHelpText( name );
417 }
418 
419 bool QgsExpressionContext::hasFunction( const QString &name ) const
420 {
421  Q_FOREACH ( const QgsExpressionContextScope *scope, mStack )
422  {
423  if ( scope->hasFunction( name ) )
424  return true;
425  }
426  return false;
427 }
428 
430 {
431  QStringList result;
432  Q_FOREACH ( const QgsExpressionContextScope *scope, mStack )
433  {
434  result << scope->functionNames();
435  }
436  result = result.toSet().toList();
437  result.sort();
438  return result;
439 }
440 
442 {
443  //iterate through stack backwards, so that higher priority variables take precedence
444  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
445  while ( it != mStack.constBegin() )
446  {
447  --it;
448  if ( ( *it )->hasFunction( name ) )
449  return ( *it )->function( name );
450  }
451  return nullptr;
452 }
453 
455 {
456  return mStack.count();
457 }
458 
460 {
461  mStack.append( scope );
462 }
463 
464 void QgsExpressionContext::appendScopes( const QList<QgsExpressionContextScope *> &scopes )
465 {
466  mStack.append( scopes );
467 }
468 
470 {
471  if ( !mStack.isEmpty() )
472  return mStack.takeLast();
473 
474  return nullptr;
475 }
476 
477 QList<QgsExpressionContextScope *> QgsExpressionContext::takeScopes()
478 {
479  QList<QgsExpressionContextScope *> stack = mStack;
480  mStack.clear();
481  return stack;
482 }
483 
485 {
486  mStack.append( scope );
487  return *this;
488 }
489 
491 {
492  if ( mStack.isEmpty() )
493  mStack.append( new QgsExpressionContextScope() );
494 
495  mStack.last()->setFeature( feature );
496 }
497 
499 {
500  Q_FOREACH ( const QgsExpressionContextScope *scope, mStack )
501  {
502  if ( scope->hasFeature() )
503  return true;
504  }
505  return false;
506 }
507 
509 {
510  //iterate through stack backwards, so that higher priority variables take precedence
511  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
512  while ( it != mStack.constBegin() )
513  {
514  --it;
515  if ( ( *it )->hasFeature() )
516  return ( *it )->feature();
517  }
518  return QgsFeature();
519 }
520 
522 {
523  if ( mStack.isEmpty() )
524  mStack.append( new QgsExpressionContextScope() );
525 
526  mStack.last()->setFields( fields );
527 }
528 
530 {
531  return qvariant_cast<QgsFields>( variable( QgsExpressionContext::EXPR_FIELDS ) );
532 }
533 
535 {
536  if ( mStack.isEmpty() )
537  mStack.append( new QgsExpressionContextScope() );
538 
540  value, true ) );
541 }
542 
543 void QgsExpressionContext::setCachedValue( const QString &key, const QVariant &value ) const
544 {
545  mCachedValues.insert( key, value );
546 }
547 
548 bool QgsExpressionContext::hasCachedValue( const QString &key ) const
549 {
550  return mCachedValues.contains( key );
551 }
552 
553 QVariant QgsExpressionContext::cachedValue( const QString &key ) const
554 {
555  return mCachedValues.value( key, QVariant() );
556 }
557 
559 {
560  mCachedValues.clear();
561 }
562 
563 
564 //
565 // QgsExpressionContextUtils
566 //
567 
569 {
570  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Global" ) );
571 
572  QVariantMap customVariables = QgsApplication::customVariables();
573 
574  for ( QVariantMap::const_iterator it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
575  {
576  scope->setVariable( it.key(), it.value(), true );
577  }
578 
579  //add some extra global variables
580  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_version" ), Qgis::QGIS_VERSION, true, true ) );
581  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_version_no" ), Qgis::QGIS_VERSION_INT, true, true ) );
582  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_short_version" ), QStringLiteral( "%1.%2" ).arg( Qgis::QGIS_VERSION_INT / 10000 ).arg( Qgis::QGIS_VERSION_INT / 100 % 100 ), true, true ) );
583  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_release_name" ), Qgis::QGIS_RELEASE_NAME, true, true ) );
584  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_platform" ), QgsApplication::platform(), true, true ) );
585  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_os_name" ), QgsApplication::osName(), true, true ) );
586  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_locale" ), QgsApplication::locale(), true, true ) );
587  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "user_account_name" ), QgsApplication::userLoginName(), true, true ) );
588  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "user_full_name" ), QgsApplication::userFullName(), true, true ) );
589 
590  return scope;
591 }
592 
593 void QgsExpressionContextUtils::setGlobalVariable( const QString &name, const QVariant &value )
594 {
595  QgsApplication::setCustomVariable( name, value );
596 }
597 
598 void QgsExpressionContextUtils::setGlobalVariables( const QVariantMap &variables )
599 {
601 }
602 
604 {
605  QVariantMap vars = QgsApplication::customVariables();
606  if ( vars.remove( name ) )
608 }
609 
610 
612 
613 class GetNamedProjectColor : public QgsScopedExpressionFunction
614 {
615  public:
616  GetNamedProjectColor( const QgsProject *project )
617  : QgsScopedExpressionFunction( QStringLiteral( "project_color" ), 1, QStringLiteral( "Color" ) )
618  , mProject( project )
619  {
620  if ( !project )
621  return;
622 
623  //build up color list from project. Do this in advance for speed
624  QStringList colorStrings = project->readListEntry( QStringLiteral( "Palette" ), QStringLiteral( "/Colors" ) );
625  QStringList colorLabels = project->readListEntry( QStringLiteral( "Palette" ), QStringLiteral( "/Labels" ) );
626 
627  //generate list from custom colors
628  int colorIndex = 0;
629  for ( QStringList::iterator it = colorStrings.begin();
630  it != colorStrings.end(); ++it )
631  {
632  QColor color = QgsSymbolLayerUtils::decodeColor( *it );
633  QString label;
634  if ( colorLabels.length() > colorIndex )
635  {
636  label = colorLabels.at( colorIndex );
637  }
638 
639  mColors.insert( label.toLower(), color );
640  colorIndex++;
641  }
642  }
643 
644  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
645  {
646  QString colorName = values.at( 0 ).toString().toLower();
647  if ( mColors.contains( colorName ) )
648  {
649  return QStringLiteral( "%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
650  }
651  else
652  return QVariant();
653  }
654 
655  QgsScopedExpressionFunction *clone() const override
656  {
657  return new GetNamedProjectColor( mProject );
658  }
659 
660  private:
661 
662  const QgsProject *mProject = nullptr;
663  QHash< QString, QColor > mColors;
664 
665 };
666 
667 class GetLayoutItemVariables : public QgsScopedExpressionFunction
668 {
669  public:
670  GetLayoutItemVariables( const QgsLayout *c )
671  : QgsScopedExpressionFunction( QStringLiteral( "item_variables" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "Layout" ) )
672  , mLayout( c )
673  {}
674 
675  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
676  {
677  if ( !mLayout )
678  return QVariant();
679 
680  QString id = values.at( 0 ).toString();
681 
682  const QgsLayoutItem *item = mLayout->itemById( id );
683  if ( !item )
684  return QVariant();
685 
687 
688  return c.variablesToMap();
689  }
690 
691  QgsScopedExpressionFunction *clone() const override
692  {
693  return new GetLayoutItemVariables( mLayout );
694  }
695 
696  private:
697 
698  const QgsLayout *mLayout = nullptr;
699 
700 };
701 
702 class GetLayerVisibility : public QgsScopedExpressionFunction
703 {
704  public:
705  GetLayerVisibility( const QList<QgsMapLayer *> &layers )
706  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
707  , mLayers( layers )
708  {}
709 
710  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
711  {
712  if ( mLayers.isEmpty() )
713  {
714  return QVariant( false );
715  }
716 
717  QgsMapLayer *layer = _qgis_findLayer( mLayers, values.at( 0 ).toString() );
718  if ( layer )
719  {
720  return QVariant( true );
721  }
722  else
723  {
724  return QVariant( false );
725  }
726  }
727 
728  QgsScopedExpressionFunction *clone() const override
729  {
730  return new GetLayerVisibility( mLayers );
731  }
732 
733  private:
734 
735  const QList<QgsMapLayer *> mLayers;
736 
737 };
738 
739 
740 class GetCurrentFormFieldValue : public QgsScopedExpressionFunction
741 {
742  public:
743  GetCurrentFormFieldValue( )
744  : QgsScopedExpressionFunction( QStringLiteral( "current_value" ), QgsExpressionFunction::ParameterList() << QStringLiteral( "field_name" ), QStringLiteral( "Form" ) )
745  {}
746 
747  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
748  {
749  QString fieldName( values.at( 0 ).toString() );
750  const QgsFeature feat( context->variable( QStringLiteral( "current_feature" ) ).value<QgsFeature>() );
751  if ( fieldName.isEmpty() || ! feat.isValid( ) )
752  {
753  return QVariant();
754  }
755  return feat.attribute( fieldName ) ;
756  }
757 
758  QgsScopedExpressionFunction *clone() const override
759  {
760  return new GetCurrentFormFieldValue( );
761  }
762 
763 };
764 
765 
766 class GetProcessingParameterValue : public QgsScopedExpressionFunction
767 {
768  public:
769  GetProcessingParameterValue( const QVariantMap &params )
770  : QgsScopedExpressionFunction( QStringLiteral( "parameter" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "name" ) ), QStringLiteral( "Processing" ) )
771  , mParams( params )
772  {}
773 
774  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
775  {
776  return mParams.value( values.at( 0 ).toString() );
777  }
778 
779  QgsScopedExpressionFunction *clone() const override
780  {
781  return new GetProcessingParameterValue( mParams );
782  }
783 
784  private:
785 
786  const QVariantMap mParams;
787 
788 };
789 
791 
792 
794 {
795  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Form" ) );
796  scope->addFunction( QStringLiteral( "current_value" ), new GetCurrentFormFieldValue( ) );
797  scope->setVariable( QStringLiteral( "current_geometry" ), formFeature.geometry( ), true );
798  scope->setVariable( QStringLiteral( "current_feature" ), formFeature, true );
799  return scope;
800 }
801 
803 {
804  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Project" ) );
805 
806  if ( !project )
807  return scope;
808 
809  const QVariantMap vars = project->customVariables();
810 
811  QVariantMap::const_iterator it = vars.constBegin();
812 
813  for ( ; it != vars.constEnd(); ++it )
814  {
815  scope->setVariable( it.key(), it.value(), true );
816  }
817 
818  QString projectPath = project->projectStorage() ? project->fileName() : project->absoluteFilePath();
819  QString projectFolder = QFileInfo( projectPath ).path();
820  QString projectFilename = QFileInfo( projectPath ).fileName();
821  QString projectBasename = project->baseName();
822 
823  //add other known project variables
824  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_title" ), project->title(), true, true ) );
825  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_path" ), QDir::toNativeSeparators( projectPath ), true, true ) );
826  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_folder" ), QDir::toNativeSeparators( projectFolder ), true, true ) );
827  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_filename" ), projectFilename, true, true ) );
828  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_basename" ), projectBasename, true, true ) );
829  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_home" ), QDir::toNativeSeparators( project->homePath() ), true, true ) );
830  QgsCoordinateReferenceSystem projectCrs = project->crs();
831  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_crs" ), projectCrs.authid(), true, true ) );
832  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_crs_definition" ), projectCrs.toProj4(), true, true ) );
833 
834  // metadata
835  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_author" ), project->metadata().author(), true, true ) );
836  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_abstract" ), project->metadata().abstract(), true, true ) );
837  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_creation_date" ), project->metadata().creationDateTime(), true, true ) );
838  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_identifier" ), project->metadata().identifier(), true, true ) );
839 
840  // keywords
841  QVariantMap keywords;
842  QgsAbstractMetadataBase::KeywordMap metadataKeywords = project->metadata().keywords();
843  for ( auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
844  {
845  keywords.insert( it.key(), it.value() );
846  }
847  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_keywords" ), keywords, true, true ) );
848 
849  scope->addFunction( QStringLiteral( "project_color" ), new GetNamedProjectColor( project ) );
850  return scope;
851 }
852 
853 void QgsExpressionContextUtils::setProjectVariable( QgsProject *project, const QString &name, const QVariant &value )
854 {
855  if ( !project )
856  return;
857 
858  QVariantMap vars = project->customVariables();
859 
860  vars.insert( name, value );
861 
862  project->setCustomVariables( vars );
863 }
864 
865 void QgsExpressionContextUtils::setProjectVariables( QgsProject *project, const QVariantMap &variables )
866 {
867  if ( !project )
868  return;
869 
870  project->setCustomVariables( variables );
871 }
872 
874 {
875  if ( !project )
876  {
877  return;
878  }
879 
880  QVariantMap vars = project->customVariables();
881  if ( vars.remove( name ) )
882  project->setCustomVariables( vars );
883 }
884 
886 {
887  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) );
888 
889  if ( !layer )
890  return scope;
891 
892  //add variables defined in layer properties
893  QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
894  QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
895 
896  int varIndex = 0;
897  Q_FOREACH ( const QString &variableName, variableNames )
898  {
899  if ( varIndex >= variableValues.length() )
900  {
901  break;
902  }
903 
904  QVariant varValue = variableValues.at( varIndex );
905  varIndex++;
906  scope->setVariable( variableName, varValue, true );
907  }
908 
909  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_name" ), layer->name(), true, true ) );
910  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_id" ), layer->id(), true, true ) );
911  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer >( QgsWeakMapLayerPointer( const_cast<QgsMapLayer *>( layer ) ) ), true, true ) );
912 
913  const QgsVectorLayer *vLayer = qobject_cast< const QgsVectorLayer * >( layer );
914  if ( vLayer )
915  {
916  scope->setFields( vLayer->fields() );
917  }
918 
919  //TODO - add functions. Possibilities include:
920  //is_selected
921  //field summary stats
922 
923  return scope;
924 }
925 
926 QList<QgsExpressionContextScope *> QgsExpressionContextUtils::globalProjectLayerScopes( const QgsMapLayer *layer )
927 {
928  QList<QgsExpressionContextScope *> scopes;
929  scopes << globalScope();
930 
931  QgsProject *project = QgsProject::instance(); // TODO: use project associated with layer
932  if ( project )
933  scopes << projectScope( project );
934 
935  if ( layer )
936  scopes << layerScope( layer );
937  return scopes;
938 }
939 
940 
941 void QgsExpressionContextUtils::setLayerVariable( QgsMapLayer *layer, const QString &name, const QVariant &value )
942 {
943  if ( !layer )
944  return;
945 
946  //write variable to layer
947  QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
948  QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
949 
950  variableNames << name;
951  variableValues << value.toString();
952 
953  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
954  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
955 }
956 
957 void QgsExpressionContextUtils::setLayerVariables( QgsMapLayer *layer, const QVariantMap &variables )
958 {
959  if ( !layer )
960  return;
961 
962  QStringList variableNames;
963  QStringList variableValues;
964 
965  QVariantMap::const_iterator it = variables.constBegin();
966  for ( ; it != variables.constEnd(); ++it )
967  {
968  variableNames << it.key();
969  variableValues << it.value().toString();
970  }
971 
972  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
973  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
974 }
975 
977 {
978  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
979  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
980 
981  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Settings" ) );
982 
983  //add known map settings context variables
984  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_id" ), "canvas", true ) );
985  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_rotation" ), mapSettings.rotation(), true ) );
986  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), mapSettings.scale(), true ) );
987  QgsGeometry extent = QgsGeometry::fromRect( mapSettings.visibleExtent() );
988  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent" ), QVariant::fromValue( extent ), true ) );
989  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_width" ), mapSettings.visibleExtent().width(), true ) );
990  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_height" ), mapSettings.visibleExtent().height(), true ) );
991  QgsGeometry centerPoint = QgsGeometry::fromPointXY( mapSettings.visibleExtent().center() );
992  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_center" ), QVariant::fromValue( centerPoint ), true ) );
993 
994  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs" ), mapSettings.destinationCrs().authid(), true ) );
995  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapSettings.destinationCrs().toProj4(), true ) );
996  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapSettings.mapUnits() ), true ) );
997 
998  scope->addFunction( QStringLiteral( "is_layer_visible" ), new GetLayerVisibility( mapSettings.layers() ) );
999 
1000  return scope;
1001 }
1002 
1003 QgsExpressionContextScope *QgsExpressionContextUtils::mapToolCaptureScope( const QList<QgsPointLocator::Match> &matches )
1004 {
1005  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Tool Capture" ) );
1006 
1007  QVariantList matchList;
1008 
1009  for ( const QgsPointLocator::Match &match : matches )
1010  {
1011  QVariantMap matchMap;
1012 
1013  matchMap.insert( QStringLiteral( "valid" ), match.isValid() );
1014  matchMap.insert( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( match.layer() ) ) );
1015  matchMap.insert( QStringLiteral( "feature_id" ), match.featureId() );
1016  matchMap.insert( QStringLiteral( "vertex_index" ), match.vertexIndex() );
1017  matchMap.insert( QStringLiteral( "distance" ), match.distance() );
1018 
1019  matchList.append( matchMap );
1020  }
1021 
1022  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "snapping_results" ), matchList ) );
1023 
1024  return scope;
1025 }
1026 
1028 {
1029  if ( !symbolScope )
1030  return nullptr;
1031 
1032  symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbol ? symbol->color() : QColor(), true ) );
1033 
1034  double angle = 0.0;
1035  const QgsMarkerSymbol *markerSymbol = dynamic_cast< const QgsMarkerSymbol * >( symbol );
1036  if ( markerSymbol )
1037  {
1038  angle = markerSymbol->angle();
1039  }
1041 
1042  return symbolScope;
1043 }
1044 
1046 {
1047  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Layout" ) ) );
1048  if ( !layout )
1049  return scope.release();
1050 
1051  //add variables defined in layout properties
1052  QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
1053  QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
1054 
1055  int varIndex = 0;
1056  Q_FOREACH ( const QString &variableName, variableNames )
1057  {
1058  if ( varIndex >= variableValues.length() )
1059  {
1060  break;
1061  }
1062 
1063  QVariant varValue = variableValues.at( varIndex );
1064  varIndex++;
1065  scope->setVariable( variableName, varValue );
1066  }
1067 
1068  //add known layout context variables
1069  if ( const QgsMasterLayoutInterface *l = dynamic_cast< const QgsMasterLayoutInterface * >( layout ) )
1070  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_name" ), l->name(), true ) );
1071 
1072  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_numpages" ), layout->pageCollection()->pageCount(), true ) );
1073  if ( layout->pageCollection()->pageCount() > 0 )
1074  {
1075  // just take first page size
1076  QSizeF s = layout->pageCollection()->page( 0 )->sizeWithUnits().toQSizeF();
1077  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
1078  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
1079  }
1080  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_dpi" ), layout->renderContext().dpi(), true ) );
1081 
1082  scope->addFunction( QStringLiteral( "item_variables" ), new GetLayoutItemVariables( layout ) );
1083 
1084  if ( layout->reportContext().layer() )
1085  {
1086  scope->setFields( layout->reportContext().layer()->fields() );
1087  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), layout->reportContext().layer()->id(), true ) );
1088  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), layout->reportContext().layer()->name(), true ) );
1089  }
1090 
1091  if ( layout->reportContext().feature().isValid() )
1092  {
1093  QgsFeature atlasFeature = layout->reportContext().feature();
1094  scope->setFeature( atlasFeature );
1095  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
1096  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), atlasFeature.id(), true ) );
1097  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
1098  }
1099 
1100  return scope.release();
1101 }
1102 
1103 void QgsExpressionContextUtils::setLayoutVariable( QgsLayout *layout, const QString &name, const QVariant &value )
1104 {
1105  if ( !layout )
1106  return;
1107 
1108  //write variable to layout
1109  QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
1110  QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
1111 
1112  variableNames << name;
1113  variableValues << value.toString();
1114 
1115  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
1116  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
1117 }
1118 
1119 void QgsExpressionContextUtils::setLayoutVariables( QgsLayout *layout, const QVariantMap &variables )
1120 {
1121  if ( !layout )
1122  return;
1123 
1124  QStringList variableNames;
1125  QStringList variableValues;
1126 
1127  QVariantMap::const_iterator it = variables.constBegin();
1128  for ( ; it != variables.constEnd(); ++it )
1129  {
1130  variableNames << it.key();
1131  variableValues << it.value().toString();
1132  }
1133 
1134  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
1135  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
1136 }
1137 
1139 {
1140  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
1141  if ( !atlas )
1142  {
1143  //add some dummy atlas variables. This is done so that as in certain contexts we want to show
1144  //users that these variables are available even if they have no current value
1145  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), QString(), true ) );
1146  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( QgsFeature() ), true ) );
1147  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), 0, true ) );
1148  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( QgsGeometry() ), true ) );
1149  return scope;
1150  }
1151 
1152  //add known atlas variables
1153  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_totalfeatures" ), atlas->count(), true ) );
1154  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featurenumber" ), atlas->currentFeatureNumber() + 1, true ) );
1155  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_filename" ), atlas->currentFilename(), true ) );
1156  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), atlas->nameForPage( atlas->currentFeatureNumber() ), true ) );
1157 
1158  if ( atlas->enabled() && atlas->coverageLayer() )
1159  {
1160  scope->setFields( atlas->coverageLayer()->fields() );
1161  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), atlas->coverageLayer()->id(), true ) );
1162  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), atlas->coverageLayer()->name(), true ) );
1163  }
1164 
1165  if ( atlas->enabled() )
1166  {
1167  QgsFeature atlasFeature = atlas->layout()->reportContext().feature();
1168  scope->setFeature( atlasFeature );
1169  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
1170  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), atlasFeature.id(), true ) );
1171  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
1172  }
1173 
1174  return scope;
1175 }
1176 
1178 {
1179  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layout Item" ) );
1180  if ( !item )
1181  return scope;
1182 
1183  //add variables defined in layout item properties
1184  const QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
1185  const QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
1186 
1187  int varIndex = 0;
1188  for ( const QString &variableName : variableNames )
1189  {
1190  if ( varIndex >= variableValues.length() )
1191  {
1192  break;
1193  }
1194 
1195  QVariant varValue = variableValues.at( varIndex );
1196  varIndex++;
1197  scope->setVariable( variableName, varValue );
1198  }
1199 
1200  //add known layout item context variables
1201  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_id" ), item->id(), true ) );
1202  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_uuid" ), item->uuid(), true ) );
1203  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_page" ), item->page() + 1, true ) );
1204 
1205  if ( item->layout() )
1206  {
1207  const QgsLayoutItemPage *page = item->layout()->pageCollection()->page( item->page() );
1208  if ( page )
1209  {
1210  const QSizeF s = page->sizeWithUnits().toQSizeF();
1211  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
1212  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
1213  }
1214  else
1215  {
1216  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), QVariant(), true ) );
1217  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), QVariant(), true ) );
1218  }
1219  }
1220 
1221  return scope;
1222 }
1223 
1224 void QgsExpressionContextUtils::setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value )
1225 {
1226  if ( !item )
1227  return;
1228 
1229  //write variable to layout item
1230  QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
1231  QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
1232 
1233  variableNames << name;
1234  variableValues << value.toString();
1235 
1236  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
1237  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
1238 }
1239 
1240 void QgsExpressionContextUtils::setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables )
1241 {
1242  if ( !item )
1243  return;
1244 
1245  QStringList variableNames;
1246  QStringList variableValues;
1247 
1248  QVariantMap::const_iterator it = variables.constBegin();
1249  for ( ; it != variables.constEnd(); ++it )
1250  {
1251  variableNames << it.key();
1252  variableValues << it.value().toString();
1253  }
1254 
1255  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
1256  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
1257 }
1258 
1260 {
1262  scope->setFeature( feature );
1263  scope->setFields( fields );
1264  return QgsExpressionContext() << scope;
1265 }
1266 
1268 {
1269  // set aside for future use
1270  Q_UNUSED( context );
1271 
1272  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Algorithm" ) ) );
1273  if ( !algorithm )
1274  return scope.release();
1275 
1276  //add standard algorithm variables
1277  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "algorithm_id" ), algorithm->id(), true ) );
1278 
1279  scope->addFunction( QStringLiteral( "parameter" ), new GetProcessingParameterValue( parameters ) );
1280 
1281  return scope.release();
1282 }
1283 
1285 {
1286  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope() );
1287  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "notification_message" ), message, true ) );
1288  return scope.release();
1289 }
1290 
1292 {
1293  QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
1294  QgsExpression::registerFunction( new GetLayoutItemVariables( nullptr ) );
1295  QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>() ) );
1296  QgsExpression::registerFunction( new GetProcessingParameterValue( QVariantMap() ) );
1297  QgsExpression::registerFunction( new GetCurrentFormFieldValue( ) );
1298 }
1299 
1301 {
1302  Q_UNUSED( node )
1303  return mUsesGeometry;
1304 }
1305 
1307 {
1308  Q_UNUSED( node )
1309  return mReferencedColumns;
1310 }
1311 
1313 {
1314  return allParamsStatic( node, parent, context );
1315 }
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:176
bool hasVariable(const QString &name) const
Tests whether a variable with the specified name exists in the scope.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
Class for parsing and evaluation of expressions (formerly called "search strings").
static QString locale()
Returns the QGIS locale.
QgsFeatureId id
Definition: qgsfeature.h:71
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
QVariant cachedValue(const QString &key) const
Returns the matching cached value, if set.
QString description(const QString &name) const
Returns the translated description for the variable with the specified name (if set).
static QgsExpressionContextScope * processingAlgorithmScope(const QgsProcessingAlgorithm *algorithm, const QVariantMap &parameters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing algorithm...
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
static void setLayoutItemVariable(QgsLayoutItem *item, const QString &name, const QVariant &value)
Sets a layout item context variable, with the given name and value.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Single variable definition for use within a QgsExpressionContextScope.
static void setGlobalVariable(const QString &name, const QVariant &value)
Sets a global context variable.
Base class for all map layer types.
Definition: qgsmaplayer.h:61
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
static void setLayoutItemVariables(QgsLayoutItem *item, const QVariantMap &variables)
Sets all layout item context variables for an item.
static const QString QGIS_VERSION
Version string.
Definition: qgis.h:63
QgsExpressionContextScope * scope(int index)
Returns the scope at the specified index within the context.
static void setLayerVariables(QgsMapLayer *layer, const QVariantMap &variables)
Sets all layer context variables.
QString id() const
Returns the unique ID for the algorithm, which is a combination of the algorithm provider&#39;s ID and th...
QgsAbstractMetadataBase::KeywordMap keywords() const
Returns the keywords map, which is a set of descriptive keywords associated with the resource...
bool isReadOnly(const QString &name) const
Returns whether a variable is read only, and should not be modifiable by users.
Base class for graphical items within a QgsLayout.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
static void setLayoutVariable(QgsLayout *layout, const QString &name, const QVariant &value)
Sets a layout context variable.
QStringList filteredVariableNames() const
Returns a filtered list of variables names set by all scopes in the context.
static void setCustomVariables(const QVariantMap &customVariables)
Custom expression variables for this application.
QgsExpressionContext & operator=(const QgsExpressionContext &other)
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
bool hasFunction(const QString &name) const
Checks whether a specified function is contained in the context.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the layout.
Definition: qgslayout.cpp:411
void addFunction(const QString &name, QgsScopedExpressionFunction *function)
Adds a function to the scope.
QgsExpressionContextScope(const QString &name=QString())
Constructor for QgsExpressionContextScope.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
static void removeProjectVariable(QgsProject *project, const QString &name)
Remove project context variable.
QgsExpressionContextScope * activeScopeForVariable(const QString &name)
Returns the currently active scope from the context for a specified variable name.
static QgsExpressionContext createFeatureBasedContext(const QgsFeature &feature, const QgsFields &fields)
Helper function for creating an expression context which contains just a feature and fields collectio...
QStringList variableNames() const
Returns a list of variable names contained within the scope.
bool hasCachedValue(const QString &key) const
Returns true if the expression context contains a cached value with a matching key.
QgsLayoutSize sizeWithUnits() const
Returns the item&#39;s current size, including units.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the object.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the object.
QString toProj4() const
Returns a Proj4 string representation of this CRS.
bool isReadOnly(const QString &name) const
Tests whether the specified variable is read only and should not be editable by users.
QString author() const
Returns the project author string.
Container of fields for a vector layer.
Definition: qgsfields.h:42
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:104
static QVariantMap customVariables()
Custom expression variables for this application.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
static QgsExpressionContextScope * mapToolCaptureScope(const QList< QgsPointLocator::Match > &matches)
Sets the expression context variables which are available for expressions triggered by a map tool cap...
static QString variableHelpText(const QString &variableName)
Returns the help text for a specified variable.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
QList< QgsMapLayer * > layers() const
Gets list of layers for map rendering The layers are stored in the reverse order of how they are rend...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
QgsExpressionContextScope & operator=(const QgsExpressionContextScope &other)
QList< QgsExpressionContextScope * > takeScopes()
Returns all scopes from this context and remove them, leaving this context without any context...
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
static void setLayoutVariables(QgsLayout *layout, const QVariantMap &variables)
Sets all layout context variables.
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Definition: qgsmaplayer.h:1385
static const int QGIS_VERSION_INT
Version number used for comparing versions using the "Check QGIS Version" function.
Definition: qgis.h:65
Abstract base class for processing algorithms.
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout&#39;s render context, which stores information relating to the current ...
Definition: qgslayout.cpp:355
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
QgsExpressionContext & operator<<(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
static QString userFullName()
Returns the user&#39;s operating system login account full display name.
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
QString description(const QString &name) const
Returns a translated description string for the variable with specified name.
bool hasFeature() const
Returns true if the context has a feature associated with it.
QgsUnitTypes::DistanceUnit mapUnits() const
Gets units of map&#39;s geographical coordinates - used for scale calculation.
QgsLayout * layout() override
Returns the layout associated with the iterator.
The QgsMapSettings class contains configuration for rendering of the map.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
QString homePath
Definition: qgsproject.h:90
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QSizeF toQSizeF() const
Converts the layout size to a QSizeF.
static QgsExpressionContextScope * layoutItemScope(const QgsLayoutItem *item)
Creates a new scope which contains variables and functions relating to a QgsLayoutItem.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
bool removeVariable(const QString &name)
Removes a variable from the context scope, if found.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
QgsVectorLayer * layer() const
Returns the vector layer associated with the layout&#39;s context.
bool hasFunction(const QString &name) const
Tests whether a function with the specified name exists in the scope.
static const QString EXPR_SYMBOL_ANGLE
Inbuilt variable name for symbol angle variable.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
const QgsLayout * layout() const
Returns the layout the object is attached to.
QgsLayoutItemPage * page(int pageNumber)
Returns a specific page (by pageNumber) from the collection.
QgsFields fields() const override
Returns the list of fields of this layer.
int scopeCount() const
Returns the number of scopes contained in the context.
bool isHighlightedVariable(const QString &name) const
Returns true if the specified variable name is intended to be highlighted to the user.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout&#39;s page collection, which stores and manages page items in the layout...
Definition: qgslayout.cpp:455
static void setProjectVariables(QgsProject *project, const QVariantMap &variables)
Sets all project context variables.
QgsProjectMetadata metadata
Definition: qgsproject.h:97
double scale() const
Returns the calculated map scale.
double dpi() const
Returns the dpi for outputting the layout.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:201
static QgsExpressionContextScope * notificationScope(const QString &message=QString())
Creates a new scope which contains variables and functions relating to provider notifications.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static void removeGlobalVariable(const QString &name)
Remove a global context variable.
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:91
QVariantMap variablesToMap() const
Returns a map of variable name to value representing all the expression variables contained by the co...
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
QVariant variable(const QString &name) const
Retrieves a variable&#39;s value from the scope.
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
QDateTime creationDateTime() const
Returns the project&#39;s creation date/timestamp.
static bool registerFunction(QgsExpressionFunction *function, bool transferOwnership=false)
Registers a function to the expression engine.
QStringList readListEntry(const QString &scope, const QString &key, const QStringList &def=QStringList(), bool *ok=nullptr) const
Key value accessors.
Reads and writes project states.
Definition: qgsproject.h:85
static void setCustomVariable(const QString &name, const QVariant &value)
Set a single custom expression variable.
QColor color() const
Definition: qgssymbol.cpp:449
QString currentFilename() const
Returns the current feature filename.
int page() const
Returns the page the item is currently on, with the first page returning 0.
QString id() const
Returns the item&#39;s ID name.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
QgsExpressionFunction * function(const QString &name) const
Retrieves a function from the scope.
static const QString EXPR_FIELDS
Inbuilt variable name for fields storage.
QStringList variableNames() const
Returns a list of variables names set by all scopes in the context.
int count() override
Returns the number of features to iterate over.
Single scope for storing variables and functions for use within a QgsExpressionContext.
An expression node for expression functions.
QgsGeometry geometry() const
Returns the geometry associated with this feature.
Definition: qgsfeature.cpp:101
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
QStringList functionNames() const
Retrieves a list of names of functions contained in the scope.
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:49
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file...
Definition: qgsproject.cpp:471
QString abstract() const
Returns a free-form description of the resource.
static void setLayerVariable(QgsMapLayer *layer, const QString &name, const QVariant &value)
Sets a layer context variable.
static QString userLoginName()
Returns the user&#39;s operating system login account name.
static QString osName()
Returns a string name of the operating system QGIS is running on.
int pageCount() const
Returns the number of pages in the collection.
int currentFeatureNumber() const
Returns the current feature number, where a value of 0 corresponds to the first feature.
QgsLayoutReportContext & reportContext()
Returns a reference to the layout&#39;s report context, which stores information relating to the current ...
Definition: qgslayout.cpp:365
static void setProjectVariable(QgsProject *project, const QString &name, const QVariant &value)
Sets a project context variable.
A abstract base class for defining QgsExpression functions.
static void registerContextFunctions()
Registers all known core functions provided by QgsExpressionContextScope objects. ...
static QgsExpressionContextScope * atlasScope(QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object...
QStringList functionNames() const
Retrieves a list of function names contained in the context.
static const QString QGIS_RELEASE_NAME
Release name.
Definition: qgis.h:67
QgsExpressionContext()=default
Constructor for QgsExpressionContext.
static QgsExpressionContextScope * layoutScope(const QgsLayout *layout)
Creates a new scope which contains variables and functions relating to a QgsLayout layout...
static QgsExpressionContextScope * formScope(const QgsFeature &formFeature=QgsFeature())
Creates a new scope which contains functions and variables from the current attribute form/table feat...
void clearCachedValues() const
Clears all cached values from the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
QMap< QString, QStringList > KeywordMap
Map of vocabulary string to keyword list.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:391
virtual QString uuid() const
Returns the item identification string.
This class represents a coordinate reference system (CRS).
bool isStatic(const QString &name) const
Tests whether the variable with the specified name is static and can be cached.
QString nameForPage(int page) const
Returns the calculated name for a specified atlas page number.
static QString platform()
Returns the QGIS platform name, e.g., "desktop" or "server".
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the layout.
Definition: qgslayout.cpp:403
bool enabled() const
Returns whether the atlas generation is enabled.
bool hasFeature() const
Returns true if the scope has a feature associated with it.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
QgsFeature feature() const
Returns the current feature for evaluating the layout.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user...
QString name
Definition: qgsmaplayer.h:65
Represents a single parameter passed to a function.
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QString title() const
Returns the project&#39;s title.
Definition: qgsproject.cpp:411
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:229
QVariantMap customVariables() const
A map of custom project variables.
QString name() const
Returns the friendly display name of the context scope.
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
QString baseName() const
Returns the base name of the project file without the path and without extension - derived from fileN...
Definition: qgsproject.cpp:501
Interface for master layout type objects, such as print layouts and reports.
static const QString EXPR_GEOMETRY_PART_NUM
Inbuilt variable name for geometry part number variable.
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
Definition: qgsproject.cpp:490
bool isStatic
A static variable can be cached for the lifetime of a context.
Represents a vector layer which manages a vector based data sets.
int indexOfScope(QgsExpressionContextScope *scope) const
Returns the index of the specified scope if it exists within the context.
static const QString EXPR_GEOMETRY_PART_COUNT
Inbuilt variable name for geometry part count variable.
Contains information about the context in which a processing algorithm is executed.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
QStringList filteredVariableNames() const
Returns a filtered and sorted list of variable names contained within the scope.
QList< QgsExpressionContextScope *> scopes()
Returns a list of scopes contained within the stack.
QString fileName
Definition: qgsproject.h:89
static void setGlobalVariables(const QVariantMap &variables)
Sets all global context variables.
QgsExpressionFunction * function(const QString &name) const
Fetches a matching function from the context.
Expression function for use within a QgsExpressionContextScope.
double angle() const
Returns the marker angle for the whole symbol.
Definition: qgssymbol.cpp:1141
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
QString authid() const
Returns the authority identifier for the CRS.
QString identifier() const
A reference, URI, URL or some other mechanism to identify the resource.
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
static QColor decodeColor(const QString &str)
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:208
Item representing the paper in a layout.