QGIS API Documentation  3.0.2-Girona (307d082)
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 
202 QgsExpressionFunction *QgsExpressionContextScope::function( const QString &name ) const
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 
441 QgsExpressionFunction *QgsExpressionContext::function( const QString &name ) const
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().toLower();
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 class GetProcessingParameterValue : public QgsScopedExpressionFunction
740 {
741  public:
742  GetProcessingParameterValue( const QVariantMap &params )
743  : QgsScopedExpressionFunction( QStringLiteral( "parameter" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "name" ) ), QStringLiteral( "Processing" ) )
744  , mParams( params )
745  {}
746 
747  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
748  {
749  return mParams.value( values.at( 0 ).toString() );
750  }
751 
752  QgsScopedExpressionFunction *clone() const override
753  {
754  return new GetProcessingParameterValue( mParams );
755  }
756 
757  private:
758 
759  const QVariantMap mParams;
760 
761 };
762 
764 
766 {
767  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Project" ) );
768 
769  if ( !project )
770  return scope;
771 
772  const QVariantMap vars = project->customVariables();
773 
774  QVariantMap::const_iterator it = vars.constBegin();
775 
776  for ( ; it != vars.constEnd(); ++it )
777  {
778  scope->setVariable( it.key(), it.value(), true );
779  }
780 
781  //add other known project variables
782  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_title" ), project->title(), true, true ) );
783  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_path" ), QDir::toNativeSeparators( project->fileInfo().filePath() ), true, true ) );
784  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_folder" ), QDir::toNativeSeparators( project->fileInfo().dir().path() ), true, true ) );
785  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_filename" ), project->fileInfo().fileName(), true, true ) );
786  QgsCoordinateReferenceSystem projectCrs = project->crs();
787  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_crs" ), projectCrs.authid(), true, true ) );
788  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_crs_definition" ), projectCrs.toProj4(), true, true ) );
789 
790  scope->addFunction( QStringLiteral( "project_color" ), new GetNamedProjectColor( project ) );
791  return scope;
792 }
793 
794 void QgsExpressionContextUtils::setProjectVariable( QgsProject *project, const QString &name, const QVariant &value )
795 {
796  if ( !project )
797  return;
798 
799  QVariantMap vars = project->customVariables();
800 
801  vars.insert( name, value );
802 
803  project->setCustomVariables( vars );
804 }
805 
806 void QgsExpressionContextUtils::setProjectVariables( QgsProject *project, const QVariantMap &variables )
807 {
808  if ( !project )
809  return;
810 
811  project->setCustomVariables( variables );
812 }
813 
815 {
816  if ( !project )
817  {
818  return;
819  }
820 
821  QVariantMap vars = project->customVariables();
822  if ( vars.remove( name ) )
823  project->setCustomVariables( vars );
824 }
825 
827 {
828  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) );
829 
830  if ( !layer )
831  return scope;
832 
833  //add variables defined in layer properties
834  QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
835  QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
836 
837  int varIndex = 0;
838  Q_FOREACH ( const QString &variableName, variableNames )
839  {
840  if ( varIndex >= variableValues.length() )
841  {
842  break;
843  }
844 
845  QVariant varValue = variableValues.at( varIndex );
846  varIndex++;
847  scope->setVariable( variableName, varValue, true );
848  }
849 
850  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_name" ), layer->name(), true, true ) );
851  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_id" ), layer->id(), true, true ) );
852  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer >( QgsWeakMapLayerPointer( const_cast<QgsMapLayer *>( layer ) ) ), true, true ) );
853 
854  const QgsVectorLayer *vLayer = qobject_cast< const QgsVectorLayer * >( layer );
855  if ( vLayer )
856  {
857  scope->setFields( vLayer->fields() );
858  }
859 
860  //TODO - add functions. Possibilities include:
861  //is_selected
862  //field summary stats
863 
864  return scope;
865 }
866 
867 QList<QgsExpressionContextScope *> QgsExpressionContextUtils::globalProjectLayerScopes( const QgsMapLayer *layer )
868 {
869  QList<QgsExpressionContextScope *> scopes;
870  scopes << globalScope();
871 
872  QgsProject *project = QgsProject::instance(); // TODO: use project associated with layer
873  if ( project )
874  scopes << projectScope( project );
875 
876  if ( layer )
877  scopes << layerScope( layer );
878  return scopes;
879 }
880 
881 void QgsExpressionContextUtils::setLayerVariable( QgsMapLayer *layer, const QString &name, const QVariant &value )
882 {
883  if ( !layer )
884  return;
885 
886  //write variable to layer
887  QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
888  QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
889 
890  variableNames << name;
891  variableValues << value.toString();
892 
893  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
894  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
895 }
896 
897 void QgsExpressionContextUtils::setLayerVariables( QgsMapLayer *layer, const QVariantMap &variables )
898 {
899  if ( !layer )
900  return;
901 
902  QStringList variableNames;
903  QStringList variableValues;
904 
905  QVariantMap::const_iterator it = variables.constBegin();
906  for ( ; it != variables.constEnd(); ++it )
907  {
908  variableNames << it.key();
909  variableValues << it.value().toString();
910  }
911 
912  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
913  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
914 }
915 
917 {
918  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
919  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
920 
921  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Settings" ) );
922 
923  //add known map settings context variables
924  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_id" ), "canvas", true ) );
925  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_rotation" ), mapSettings.rotation(), true ) );
926  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), mapSettings.scale(), true ) );
927  QgsGeometry extent = QgsGeometry::fromRect( mapSettings.visibleExtent() );
928  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent" ), QVariant::fromValue( extent ), true ) );
929  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_width" ), mapSettings.visibleExtent().width(), true ) );
930  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_height" ), mapSettings.visibleExtent().height(), true ) );
931  QgsGeometry centerPoint = QgsGeometry::fromPointXY( mapSettings.visibleExtent().center() );
932  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_center" ), QVariant::fromValue( centerPoint ), true ) );
933 
934  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs" ), mapSettings.destinationCrs().authid(), true ) );
935  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapSettings.destinationCrs().toProj4(), true ) );
936  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapSettings.mapUnits() ), true ) );
937 
938  scope->addFunction( QStringLiteral( "is_layer_visible" ), new GetLayerVisibility( mapSettings.layers() ) );
939 
940  return scope;
941 }
942 
943 QgsExpressionContextScope *QgsExpressionContextUtils::mapToolCaptureScope( const QList<QgsPointLocator::Match> &matches )
944 {
945  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Tool Capture" ) );
946 
947  QVariantList matchList;
948 
949  for ( const QgsPointLocator::Match &match : matches )
950  {
951  QVariantMap matchMap;
952 
953  matchMap.insert( QStringLiteral( "valid" ), match.isValid() );
954  matchMap.insert( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( match.layer() ) ) );
955  matchMap.insert( QStringLiteral( "feature_id" ), match.featureId() );
956  matchMap.insert( QStringLiteral( "vertex_index" ), match.vertexIndex() );
957  matchMap.insert( QStringLiteral( "distance" ), match.distance() );
958 
959  matchList.append( matchMap );
960  }
961 
962  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "snapping_results" ), matchList ) );
963 
964  return scope;
965 }
966 
968 {
969  if ( !symbolScope )
970  return nullptr;
971 
972  symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbol ? symbol->color() : QColor(), true ) );
973 
974  double angle = 0.0;
975  const QgsMarkerSymbol *markerSymbol = dynamic_cast< const QgsMarkerSymbol * >( symbol );
976  if ( markerSymbol )
977  {
978  angle = markerSymbol->angle();
979  }
981 
982  return symbolScope;
983 }
984 
986 {
987  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Layout" ) ) );
988  if ( !layout )
989  return scope.release();
990 
991  //add variables defined in layout properties
992  QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
993  QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
994 
995  int varIndex = 0;
996  Q_FOREACH ( const QString &variableName, variableNames )
997  {
998  if ( varIndex >= variableValues.length() )
999  {
1000  break;
1001  }
1002 
1003  QVariant varValue = variableValues.at( varIndex );
1004  varIndex++;
1005  scope->setVariable( variableName, varValue );
1006  }
1007 
1008  //add known layout context variables
1009  if ( const QgsMasterLayoutInterface *l = dynamic_cast< const QgsMasterLayoutInterface * >( layout ) )
1010  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_name" ), l->name(), true ) );
1011 
1012  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_numpages" ), layout->pageCollection()->pageCount(), true ) );
1013  if ( layout->pageCollection()->pageCount() > 0 )
1014  {
1015  // just take first page size
1016  QSizeF s = layout->pageCollection()->page( 0 )->sizeWithUnits().toQSizeF();
1017  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
1018  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
1019  }
1020  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_dpi" ), layout->renderContext().dpi(), true ) );
1021 
1022  scope->addFunction( QStringLiteral( "item_variables" ), new GetLayoutItemVariables( layout ) );
1023 
1024  if ( layout->reportContext().layer() )
1025  {
1026  scope->setFields( layout->reportContext().layer()->fields() );
1027  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), layout->reportContext().layer()->id(), true ) );
1028  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), layout->reportContext().layer()->name(), true ) );
1029  }
1030 
1031  if ( layout->reportContext().feature().isValid() )
1032  {
1033  QgsFeature atlasFeature = layout->reportContext().feature();
1034  scope->setFeature( atlasFeature );
1035  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
1036  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), atlasFeature.id(), true ) );
1037  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
1038  }
1039 
1040  return scope.release();
1041 }
1042 
1043 void QgsExpressionContextUtils::setLayoutVariable( QgsLayout *layout, const QString &name, const QVariant &value )
1044 {
1045  if ( !layout )
1046  return;
1047 
1048  //write variable to layout
1049  QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
1050  QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
1051 
1052  variableNames << name;
1053  variableValues << value.toString();
1054 
1055  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
1056  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
1057 }
1058 
1059 void QgsExpressionContextUtils::setLayoutVariables( QgsLayout *layout, const QVariantMap &variables )
1060 {
1061  if ( !layout )
1062  return;
1063 
1064  QStringList variableNames;
1065  QStringList variableValues;
1066 
1067  QVariantMap::const_iterator it = variables.constBegin();
1068  for ( ; it != variables.constEnd(); ++it )
1069  {
1070  variableNames << it.key();
1071  variableValues << it.value().toString();
1072  }
1073 
1074  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
1075  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
1076 }
1077 
1079 {
1080  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
1081  if ( !atlas )
1082  {
1083  //add some dummy atlas variables. This is done so that as in certain contexts we want to show
1084  //users that these variables are available even if they have no current value
1085  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), QString(), true ) );
1086  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( QgsFeature() ), true ) );
1087  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), 0, true ) );
1088  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( QgsGeometry() ), true ) );
1089  return scope;
1090  }
1091 
1092  //add known atlas variables
1093  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_totalfeatures" ), atlas->count(), true ) );
1094  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featurenumber" ), atlas->currentFeatureNumber() + 1, true ) );
1095  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_filename" ), atlas->currentFilename(), true ) );
1096  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), atlas->nameForPage( atlas->currentFeatureNumber() ), true ) );
1097 
1098  if ( atlas->enabled() && atlas->coverageLayer() )
1099  {
1100  scope->setFields( atlas->coverageLayer()->fields() );
1101  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), atlas->coverageLayer()->id(), true ) );
1102  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), atlas->coverageLayer()->name(), true ) );
1103  }
1104 
1105  if ( atlas->enabled() )
1106  {
1107  QgsFeature atlasFeature = atlas->layout()->reportContext().feature();
1108  scope->setFeature( atlasFeature );
1109  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
1110  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), atlasFeature.id(), true ) );
1111  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
1112  }
1113 
1114  return scope;
1115 }
1116 
1118 {
1119  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layout Item" ) );
1120  if ( !item )
1121  return scope;
1122 
1123  //add variables defined in layout item properties
1124  const QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
1125  const QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
1126 
1127  int varIndex = 0;
1128  for ( const QString &variableName : variableNames )
1129  {
1130  if ( varIndex >= variableValues.length() )
1131  {
1132  break;
1133  }
1134 
1135  QVariant varValue = variableValues.at( varIndex );
1136  varIndex++;
1137  scope->setVariable( variableName, varValue );
1138  }
1139 
1140  //add known layout item context variables
1141  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_id" ), item->id(), true ) );
1142  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_uuid" ), item->uuid(), true ) );
1143  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_page" ), item->page() + 1, true ) );
1144 
1145  if ( item->layout() )
1146  {
1147  const QgsLayoutItemPage *page = item->layout()->pageCollection()->page( item->page() );
1148  if ( page )
1149  {
1150  const QSizeF s = page->sizeWithUnits().toQSizeF();
1151  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
1152  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
1153  }
1154  else
1155  {
1156  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), QVariant(), true ) );
1157  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), QVariant(), true ) );
1158  }
1159  }
1160 
1161  return scope;
1162 }
1163 
1164 void QgsExpressionContextUtils::setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value )
1165 {
1166  if ( !item )
1167  return;
1168 
1169  //write variable to layout item
1170  QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
1171  QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
1172 
1173  variableNames << name;
1174  variableValues << value.toString();
1175 
1176  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
1177  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
1178 }
1179 
1180 void QgsExpressionContextUtils::setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables )
1181 {
1182  if ( !item )
1183  return;
1184 
1185  QStringList variableNames;
1186  QStringList variableValues;
1187 
1188  QVariantMap::const_iterator it = variables.constBegin();
1189  for ( ; it != variables.constEnd(); ++it )
1190  {
1191  variableNames << it.key();
1192  variableValues << it.value().toString();
1193  }
1194 
1195  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
1196  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
1197 }
1198 
1200 {
1202  scope->setFeature( feature );
1203  scope->setFields( fields );
1204  return QgsExpressionContext() << scope;
1205 }
1206 
1208 {
1209  // set aside for future use
1210  Q_UNUSED( context );
1211 
1212  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Algorithm" ) ) );
1213  if ( !algorithm )
1214  return scope.release();
1215 
1216  //add standard algorithm variables
1217  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "algorithm_id" ), algorithm->id(), true ) );
1218 
1219  scope->addFunction( QStringLiteral( "parameter" ), new GetProcessingParameterValue( parameters ) );
1220 
1221  return scope.release();
1222 }
1223 
1225 {
1226  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope() );
1227  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "notification_message" ), message, true ) );
1228  return scope.release();
1229 }
1230 
1232 {
1233  QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
1234  QgsExpression::registerFunction( new GetLayoutItemVariables( nullptr ) );
1235  QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>() ) );
1236  QgsExpression::registerFunction( new GetProcessingParameterValue( QVariantMap() ) );
1237 }
1238 
1239 bool QgsScopedExpressionFunction::usesGeometry( const QgsExpressionNodeFunction *node ) const
1240 {
1241  Q_UNUSED( node )
1242  return mUsesGeometry;
1243 }
1244 
1245 QSet<QString> QgsScopedExpressionFunction::referencedColumns( const QgsExpressionNodeFunction *node ) const
1246 {
1247  Q_UNUSED( node )
1248  return mReferencedColumns;
1249 }
1250 
1251 bool QgsScopedExpressionFunction::isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const
1252 {
1253  return allParamsStatic( node, parent, context );
1254 }
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.
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:56
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...
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.
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:111
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 QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
QList< QgsMapLayer * > layers() const
Get list of layers for map rendering The layers are stored in the reverse order of how they are rende...
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()
Return all scopes from this context and remove them, leaving this context without any context...
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
static void setLayoutVariables(QgsLayout *layout, const QVariantMap &variables)
Sets all layout context variables.
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Definition: qgsmaplayer.h:1349
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.
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
Return the actual extent derived from requested extent that takes takes output image size into accoun...
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
Get 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.
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
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.
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:142
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:88
QVariantMap variablesToMap() const
Returns a map of variable name to value representing all the expression variables contained by the co...
Class used to render an Atlas, iterating over geometry features.
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.
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:82
static void setCustomVariable(const QString &name, const QVariant &value)
Set a single custom expression variable.
QColor color() const
Definition: qgssymbol.cpp:454
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.
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
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
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.
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.
QFileInfo fileInfo() const
Returns QFileInfo object for the project&#39;s associated file.
Definition: qgsproject.cpp:441
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...
void clearCachedValues() const
Clears all cached values from the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:383
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:60
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:403
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:170
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.
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.
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.
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:1146
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
QString authid() const
Returns the authority identifier for the CRS.
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
static QColor decodeColor(const QString &str)
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:149
Item representing the paper in a layout.