QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 "qgsfield.h"
21 #include "qgsvectorlayer.h"
22 #include "qgsproject.h"
23 #include "qgssymbollayerv2utils.h"
24 #include "qgsgeometry.h"
25 #include "qgscomposition.h"
26 #include "qgscomposeritem.h"
27 #include "qgsatlascomposition.h"
28 #include "qgsapplication.h"
29 #include <QSettings>
30 #include <QDir>
31 
32 
33 const QString QgsExpressionContext::EXPR_FIELDS( "_fields_" );
34 const QString QgsExpressionContext::EXPR_FEATURE( "_feature_" );
36 const QString QgsExpressionContext::EXPR_SYMBOL_COLOR( "symbol_color" );
37 const QString QgsExpressionContext::EXPR_SYMBOL_ANGLE( "symbol_angle" );
38 const QString QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT( "geometry_part_count" );
39 const QString QgsExpressionContext::EXPR_GEOMETRY_PART_NUM( "geometry_part_num" );
40 const QString QgsExpressionContext::EXPR_GEOMETRY_POINT_COUNT( "geometry_point_count" );
41 const QString QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM( "geometry_point_num" );
42 
43 //
44 // QgsExpressionContextScope
45 //
46 
48  : mName( name )
49 {
50 
51 }
52 
54  : mName( other.mName )
55  , mVariables( other.mVariables )
56 {
58  for ( ; it != other.mFunctions.constEnd(); ++it )
59  {
60  mFunctions.insert( it.key(), it.value()->clone() );
61  }
62 }
63 
65 {
66  mName = other.mName;
67  mVariables = other.mVariables;
68 
69  qDeleteAll( mFunctions );
70  mFunctions.clear();
72  for ( ; it != other.mFunctions.constEnd(); ++it )
73  {
74  mFunctions.insert( it.key(), it.value()->clone() );
75  }
76 
77  return *this;
78 }
79 
81 {
82  qDeleteAll( mFunctions );
83 }
84 
86 {
87  if ( mVariables.contains( name ) )
88  {
89  StaticVariable existing = mVariables.value( name );
90  existing.value = value;
91  addVariable( existing );
92  }
93  else
94  {
96  }
97 }
98 
100 {
101  mVariables.insert( variable.name, variable );
102 }
103 
105 {
106  return mVariables.remove( name ) > 0;
107 }
108 
110 {
111  return mVariables.contains( name );
112 }
113 
115 {
116  return hasVariable( name ) ? mVariables.value( name ).value : QVariant();
117 }
118 
120 {
121  QStringList names = mVariables.keys();
122  return names;
123 }
124 
125 bool QgsExpressionContextScope::variableNameSort( const QString& a, const QString& b )
126 {
127  return QString::localeAwareCompare( a, b ) < 0;
128 }
129 
131 class QgsExpressionContextVariableCompare
132 {
133  public:
134  explicit QgsExpressionContextVariableCompare( const QgsExpressionContextScope& scope )
135  : mScope( scope )
136  { }
137 
138  bool operator()( const QString& a, const QString& b ) const
139  {
140  bool aReadOnly = mScope.isReadOnly( a );
141  bool bReadOnly = mScope.isReadOnly( b );
142  if ( aReadOnly != bReadOnly )
143  return aReadOnly;
144  return QString::localeAwareCompare( a, b ) < 0;
145  }
146 
147  private:
148  const QgsExpressionContextScope& mScope;
149 };
151 
153 {
154  QStringList allVariables = mVariables.keys();
155  QStringList filtered;
156  Q_FOREACH ( const QString& variable, allVariables )
157  {
158  if ( variable.startsWith( '_' ) )
159  continue;
160 
161  filtered << variable;
162  }
163  QgsExpressionContextVariableCompare cmp( *this );
164  qSort( filtered.begin(), filtered.end(), cmp );
165 
166  return filtered;
167 }
168 
170 {
171  return hasVariable( name ) ? mVariables.value( name ).readOnly : false;
172 }
173 
175 {
176  return mFunctions.contains( name );
177 }
178 
180 {
181  return mFunctions.contains( name ) ? mFunctions.value( name ) : nullptr;
182 }
183 
185 {
186  return mFunctions.keys();
187 }
188 
190 {
191  mFunctions.insert( name, function );
192 }
193 
195 {
197 }
198 
200 {
202 }
203 
204 
205 //
206 // QgsExpressionContext
207 //
208 
210 {
211  Q_FOREACH ( const QgsExpressionContextScope* scope, other.mStack )
212  {
213  mStack << new QgsExpressionContextScope( *scope );
214  }
215  mHighlightedVariables = other.mHighlightedVariables;
216  mCachedValues = other.mCachedValues;
217 }
218 
220 {
221  qDeleteAll( mStack );
222  mStack.clear();
223  Q_FOREACH ( const QgsExpressionContextScope* scope, other.mStack )
224  {
225  mStack << new QgsExpressionContextScope( *scope );
226  }
227  mHighlightedVariables = other.mHighlightedVariables;
228  mCachedValues = other.mCachedValues;
229  return *this;
230 }
231 
233 {
234  qDeleteAll( mStack );
235  mStack.clear();
236 }
237 
239 {
240  Q_FOREACH ( const QgsExpressionContextScope* scope, mStack )
241  {
242  if ( scope->hasVariable( name ) )
243  return true;
244  }
245  return false;
246 }
247 
249 {
250  const QgsExpressionContextScope* scope = activeScopeForVariable( name );
251  return scope ? scope->variable( name ) : QVariant();
252 }
253 
255 {
256  return mHighlightedVariables.contains( name );
257 }
258 
260 {
261  mHighlightedVariables = variableNames;
262 }
263 
265 {
266  //iterate through stack backwards, so that higher priority variables take precedence
268  while ( it != mStack.constBegin() )
269  {
270  --it;
271  if (( *it )->hasVariable( name ) )
272  return ( *it );
273  }
274  return nullptr;
275 }
276 
278 {
279  //iterate through stack backwards, so that higher priority variables take precedence
281  while ( it != mStack.constBegin() )
282  {
283  --it;
284  if (( *it )->hasVariable( name ) )
285  return ( *it );
286  }
287  return nullptr;
288 }
289 
291 {
292  if ( index < 0 || index >= mStack.count() )
293  return nullptr;
294 
295  return mStack.at( index );
296 }
297 
299 {
300  if ( mStack.count() < 1 )
301  return nullptr;
302 
303  return mStack.last();
304 }
305 
307 {
308  if ( !scope )
309  return -1;
310 
311  return mStack.indexOf( scope );
312 }
313 
314 int QgsExpressionContext::indexOfScope( const QString& scopeName ) const
315 {
316  int index = 0;
317  Q_FOREACH ( const QgsExpressionContextScope* scope, mStack )
318  {
319  if ( scope->name() == scopeName )
320  return index;
321 
322  index++;
323  }
324  return -1;
325 }
326 
328 {
329  QStringList names;
330  Q_FOREACH ( const QgsExpressionContextScope* scope, mStack )
331  {
332  names << scope->variableNames();
333  }
334  return names.toSet().toList();
335 }
336 
338 {
339  QStringList allVariables = variableNames();
340  QStringList filtered;
341  Q_FOREACH ( const QString& variable, allVariables )
342  {
343  if ( variable.startsWith( '_' ) )
344  continue;
345 
346  filtered << variable;
347  }
348 
349  filtered.sort();
350  return filtered;
351 }
352 
354 {
355  Q_FOREACH ( const QgsExpressionContextScope* scope, mStack )
356  {
357  if ( scope->isReadOnly( name ) )
358  return true;
359  }
360  return false;
361 }
362 
364 {
365  Q_FOREACH ( const QgsExpressionContextScope* scope, mStack )
366  {
367  if ( scope->hasFunction( name ) )
368  return true;
369  }
370  return false;
371 }
372 
374 {
375  QStringList result;
376  Q_FOREACH ( const QgsExpressionContextScope* scope, mStack )
377  {
378  result << scope->functionNames();
379  }
380  result = result.toSet().toList();
381  result.sort();
382  return result;
383 }
384 
386 {
387  //iterate through stack backwards, so that higher priority variables take precedence
389  while ( it != mStack.constBegin() )
390  {
391  --it;
392  if (( *it )->hasFunction( name ) )
393  return ( *it )->function( name );
394  }
395  return nullptr;
396 }
397 
399 {
400  return mStack.count();
401 }
402 
404 {
405  mStack.append( scope );
406 }
407 
409 {
410  if ( !mStack.isEmpty() )
411  return mStack.takeLast();
412 
413  return nullptr;
414 }
415 
417 {
418  mStack.append( scope );
419  return *this;
420 }
421 
423 {
424  if ( mStack.isEmpty() )
425  mStack.append( new QgsExpressionContextScope() );
426 
427  mStack.last()->setFeature( feature );
428 }
429 
431 {
432  return qvariant_cast<QgsFeature>( variable( QgsExpressionContext::EXPR_FEATURE ) );
433 }
434 
436 {
437  if ( mStack.isEmpty() )
438  mStack.append( new QgsExpressionContextScope() );
439 
440  mStack.last()->setFields( fields );
441 }
442 
444 {
445  return qvariant_cast<QgsFields>( variable( QgsExpressionContext::EXPR_FIELDS ) );
446 }
447 
449 {
450  if ( mStack.isEmpty() )
451  mStack.append( new QgsExpressionContextScope() );
452 
454  value, true ) );
455 }
456 
457 void QgsExpressionContext::setCachedValue( const QString& key, const QVariant& value ) const
458 {
459  mCachedValues.insert( key, value );
460 }
461 
463 {
464  return mCachedValues.contains( key );
465 }
466 
468 {
469  return mCachedValues.value( key, QVariant() );
470 }
471 
473 {
474  mCachedValues.clear();
475 }
476 
477 
478 //
479 // QgsExpressionContextUtils
480 //
481 
483 {
485 
486  //read values from QSettings
487  QSettings settings;
488 
489  //check if settings contains any variables
490  if ( settings.contains( QString( "/variables/values" ) ) )
491  {
492  QList< QVariant > customVariableVariants = settings.value( QString( "/variables/values" ) ).toList();
493  QList< QVariant > customVariableNames = settings.value( QString( "/variables/names" ) ).toList();
494  int variableIndex = 0;
495  for ( QList< QVariant >::const_iterator it = customVariableVariants.constBegin();
496  it != customVariableVariants.constEnd(); ++it )
497  {
498  if ( variableIndex >= customVariableNames.length() )
499  {
500  break;
501  }
502 
503  QVariant value = ( *it );
504  QString name = customVariableNames.at( variableIndex ).toString();
505 
506  scope->setVariable( name, value );
507  variableIndex++;
508  }
509  }
510 
511  //add some extra global variables
514  scope->addVariable( QgsExpressionContextScope::StaticVariable( "qgis_release_name", QGis::QGIS_RELEASE_NAME, true ) );
519 
520  return scope;
521 }
522 
524 {
525  // save variable to settings
526  QSettings settings;
527 
528  QList< QVariant > customVariableVariants = settings.value( QString( "/variables/values" ) ).toList();
529  QList< QVariant > customVariableNames = settings.value( QString( "/variables/names" ) ).toList();
530 
531  customVariableVariants << value;
532  customVariableNames << name;
533 
534  settings.setValue( QString( "/variables/names" ), customVariableNames );
535  settings.setValue( QString( "/variables/values" ), customVariableVariants );
536 }
537 
539 {
540  QSettings settings;
541 
542  QList< QVariant > customVariableVariants;
543  QList< QVariant > customVariableNames;
544 
546  for ( ; it != variables.constEnd(); ++it )
547  {
548  customVariableNames << it.key();
549  customVariableVariants << it.value();
550  }
551 
552  settings.setValue( QString( "/variables/names" ), customVariableNames );
553  settings.setValue( QString( "/variables/values" ), customVariableVariants );
554 }
555 
557 
558 class GetNamedProjectColor : public QgsScopedExpressionFunction
559 {
560  public:
561  GetNamedProjectColor()
562  : QgsScopedExpressionFunction( "project_color", 1, "Color" )
563  {
564  //build up color list from project. Do this in advance for speed
565  QStringList colorStrings = QgsProject::instance()->readListEntry( "Palette", "/Colors" );
566  QStringList colorLabels = QgsProject::instance()->readListEntry( "Palette", "/Labels" );
567 
568  //generate list from custom colors
569  int colorIndex = 0;
570  for ( QStringList::iterator it = colorStrings.begin();
571  it != colorStrings.end(); ++it )
572  {
574  QString label;
575  if ( colorLabels.length() > colorIndex )
576  {
577  label = colorLabels.at( colorIndex );
578  }
579 
580  mColors.insert( label.toLower(), color );
581  colorIndex++;
582  }
583  }
584 
585  virtual QVariant func( const QVariantList& values, const QgsExpressionContext*, QgsExpression* ) override
586  {
587  QString colorName = values.at( 0 ).toString().toLower();
588  if ( mColors.contains( colorName ) )
589  {
590  return QString( "%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
591  }
592  else
593  return QVariant();
594  }
595 
596  QgsScopedExpressionFunction* clone() const override
597  {
598  return new GetNamedProjectColor();
599  }
600 
601  private:
602 
603  QHash< QString, QColor > mColors;
604 
605 };
606 
608 
610 {
611  QgsProject* project = QgsProject::instance();
612 
614 
615  //add variables defined in project file
616  QStringList variableNames = project->readListEntry( "Variables", "/variableNames" );
617  QStringList variableValues = project->readListEntry( "Variables", "/variableValues" );
618 
619  int varIndex = 0;
620  Q_FOREACH ( const QString& variableName, variableNames )
621  {
622  if ( varIndex >= variableValues.length() )
623  {
624  break;
625  }
626 
627  QString varValueString = variableValues.at( varIndex );
628  varIndex++;
629  scope->setVariable( variableName, varValueString );
630  }
631 
632  //add other known project variables
633  scope->addVariable( QgsExpressionContextScope::StaticVariable( "project_title", project->title(), true ) );
634  scope->addVariable( QgsExpressionContextScope::StaticVariable( "project_path", QDir::toNativeSeparators( project->fileInfo().filePath() ), true ) );
635  scope->addVariable( QgsExpressionContextScope::StaticVariable( "project_folder", QDir::toNativeSeparators( project->fileInfo().dir().path() ), true ) );
636  scope->addVariable( QgsExpressionContextScope::StaticVariable( "project_filename", project->fileInfo().fileName(), true ) );
637 
638  scope->addFunction( "project_color", new GetNamedProjectColor() );
639  return scope;
640 }
641 
643 {
644  QgsProject* project = QgsProject::instance();
645 
646  //write variable to project
647  QStringList variableNames = project->readListEntry( "Variables", "/variableNames" );
648  QStringList variableValues = project->readListEntry( "Variables", "/variableValues" );
649 
650  variableNames << name;
651  variableValues << value.toString();
652 
653  project->writeEntry( "Variables", "/variableNames", variableNames );
654  project->writeEntry( "Variables", "/variableValues", variableValues );
655 }
656 
658 {
659  QgsProject* project = QgsProject::instance();
660 
661  //write variable to project
663  QStringList variableValues;
664 
666  for ( ; it != variables.constEnd(); ++it )
667  {
668  variableNames << it.key();
669  variableValues << it.value();
670  }
671 
672  project->writeEntry( "Variables", "/variableNames", variableNames );
673  project->writeEntry( "Variables", "/variableValues", variableValues );
674 }
675 
677 {
679 
680  if ( !layer )
681  return scope;
682 
683  //add variables defined in layer properties
684  QStringList variableNames = layer->customProperty( "variableNames" ).toStringList();
685  QStringList variableValues = layer->customProperty( "variableValues" ).toStringList();
686 
687  int varIndex = 0;
688  Q_FOREACH ( const QString& variableName, variableNames )
689  {
690  if ( varIndex >= variableValues.length() )
691  {
692  break;
693  }
694 
695  QVariant varValue = variableValues.at( varIndex );
696  varIndex++;
697  scope->setVariable( variableName, varValue );
698  }
699 
700  scope->addVariable( QgsExpressionContextScope::StaticVariable( "layer_name", layer->name(), true ) );
701  scope->addVariable( QgsExpressionContextScope::StaticVariable( "layer_id", layer->id(), true ) );
702 
703  const QgsVectorLayer* vLayer = dynamic_cast< const QgsVectorLayer* >( layer );
704  if ( vLayer )
705  {
706  scope->setFields( vLayer->fields() );
707  }
708 
709  //TODO - add functions. Possibilities include:
710  //is_selected
711  //field summary stats
712 
713  return scope;
714 }
715 
717 {
718  if ( !layer )
719  return;
720 
721  //write variable to layer
722  QStringList variableNames = layer->customProperty( "variableNames" ).toStringList();
723  QStringList variableValues = layer->customProperty( "variableValues" ).toStringList();
724 
725  variableNames << name;
726  variableValues << value.toString();
727 
728  layer->setCustomProperty( "variableNames", variableNames );
729  layer->setCustomProperty( "variableValues", variableValues );
730 }
731 
733 {
734  if ( !layer )
735  return;
736 
738  QStringList variableValues;
739 
741  for ( ; it != variables.constEnd(); ++it )
742  {
743  variableNames << it.key();
744  variableValues << it.value();
745  }
746 
747  layer->setCustomProperty( "variableNames", variableNames );
748  layer->setCustomProperty( "variableValues", variableValues );
749 }
750 
752 {
753  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsComposerMap::createExpressionContext()
754  // (rationale is described in QgsComposerMap::createExpressionContext() )
755 
756  QgsExpressionContextScope* scope = new QgsExpressionContextScope( QObject::tr( "Map Settings" ) );
757 
758  //add known map settings context variables
759  scope->addVariable( QgsExpressionContextScope::StaticVariable( "map_id", "canvas", true ) );
760  scope->addVariable( QgsExpressionContextScope::StaticVariable( "map_rotation", mapSettings.rotation(), true ) );
761  scope->addVariable( QgsExpressionContextScope::StaticVariable( "map_scale", mapSettings.scale(), true ) );
762  scope->addVariable( QgsExpressionContextScope::StaticVariable( "map_extent_width", mapSettings.visibleExtent().width(), true ) );
763  scope->addVariable( QgsExpressionContextScope::StaticVariable( "map_extent_height", mapSettings.visibleExtent().height(), true ) );
764  QgsGeometry* centerPoint = QgsGeometry::fromPoint( mapSettings.visibleExtent().center() );
765  scope->addVariable( QgsExpressionContextScope::StaticVariable( "map_extent_center", QVariant::fromValue( *centerPoint ), true ) );
766  delete centerPoint;
767 
768  return scope;
769 }
770 
772 {
773  if ( !symbolScope )
774  return nullptr;
775 
777 
778  double angle = 0.0;
779  const QgsMarkerSymbolV2* markerSymbol = dynamic_cast< const QgsMarkerSymbolV2* >( symbol );
780  if ( markerSymbol )
781  {
782  angle = markerSymbol->angle();
783  }
785 
786  return symbolScope;
787 }
788 
790 {
791  QgsExpressionContextScope* scope = new QgsExpressionContextScope( QObject::tr( "Composition" ) );
792  if ( !composition )
793  return scope;
794 
795  //add variables defined in composition properties
796  QStringList variableNames = composition->customProperty( "variableNames" ).toStringList();
797  QStringList variableValues = composition->customProperty( "variableValues" ).toStringList();
798 
799  int varIndex = 0;
800  Q_FOREACH ( const QString& variableName, variableNames )
801  {
802  if ( varIndex >= variableValues.length() )
803  {
804  break;
805  }
806 
807  QVariant varValue = variableValues.at( varIndex );
808  varIndex++;
809  scope->setVariable( variableName, varValue );
810  }
811 
812  //add known composition context variables
813  scope->addVariable( QgsExpressionContextScope::StaticVariable( "layout_numpages", composition->numPages(), true ) );
814  scope->addVariable( QgsExpressionContextScope::StaticVariable( "layout_pageheight", composition->paperHeight(), true ) );
815  scope->addVariable( QgsExpressionContextScope::StaticVariable( "layout_pagewidth", composition->paperWidth(), true ) );
816  scope->addVariable( QgsExpressionContextScope::StaticVariable( "layout_dpi", composition->printResolution(), true ) );
817 
818  return scope;
819 }
820 
822 {
823  if ( !composition )
824  return;
825 
826  //write variable to composition
827  QStringList variableNames = composition->customProperty( "variableNames" ).toStringList();
828  QStringList variableValues = composition->customProperty( "variableValues" ).toStringList();
829 
830  variableNames << name;
831  variableValues << value.toString();
832 
833  composition->setCustomProperty( "variableNames", variableNames );
834  composition->setCustomProperty( "variableValues", variableValues );
835 }
836 
838 {
839  if ( !composition )
840  return;
841 
843  QStringList variableValues;
844 
846  for ( ; it != variables.constEnd(); ++it )
847  {
848  variableNames << it.key();
849  variableValues << it.value();
850  }
851 
852  composition->setCustomProperty( "variableNames", variableNames );
853  composition->setCustomProperty( "variableValues", variableValues );
854 }
855 
857 {
859  if ( !atlas )
860  {
861  //add some dummy atlas variables. This is done so that as in certain contexts we want to show
862  //users that these variables are available even if they have no current value
863  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_pagename", QString(), true ) );
865  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_featureid", 0, true ) );
867  return scope;
868  }
869 
870  //add known atlas variables
871  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_totalfeatures", atlas->numFeatures(), true ) );
872  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_featurenumber", atlas->currentFeatureNumber() + 1, true ) );
873  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_filename", atlas->currentFilename(), true ) );
874  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_pagename", atlas->currentPageName(), true ) );
875 
876  if ( atlas->enabled() && atlas->coverageLayer() )
877  {
878  scope->setFields( atlas->coverageLayer()->fields() );
879  }
880 
881  if ( atlas->enabled() )
882  {
883  QgsFeature atlasFeature = atlas->feature();
884  scope->setFeature( atlasFeature );
885  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_feature", QVariant::fromValue( atlasFeature ), true ) );
886  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_featureid", atlasFeature.id(), true ) );
887  scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_geometry", QVariant::fromValue( *atlasFeature.constGeometry() ), true ) );
888  }
889 
890  return scope;
891 }
892 
894 {
895  QgsExpressionContextScope* scope = new QgsExpressionContextScope( QObject::tr( "Composer Item" ) );
896  if ( !composerItem )
897  return scope;
898 
899  //add variables defined in composer item properties
900  QStringList variableNames = composerItem->customProperty( "variableNames" ).toStringList();
901  QStringList variableValues = composerItem->customProperty( "variableValues" ).toStringList();
902 
903  int varIndex = 0;
904  Q_FOREACH ( const QString& variableName, variableNames )
905  {
906  if ( varIndex >= variableValues.length() )
907  {
908  break;
909  }
910 
911  QVariant varValue = variableValues.at( varIndex );
912  varIndex++;
913  scope->setVariable( variableName, varValue );
914  }
915 
916  //add known composer item context variables
917  scope->addVariable( QgsExpressionContextScope::StaticVariable( "item_id", composerItem->id(), true ) );
918  scope->addVariable( QgsExpressionContextScope::StaticVariable( "item_uuid", composerItem->uuid(), true ) );
919  scope->addVariable( QgsExpressionContextScope::StaticVariable( "layout_page", composerItem->page(), true ) );
920 
921  return scope;
922 }
923 
925 {
926  if ( !composerItem )
927  return;
928 
929  //write variable to composer item
930  QStringList variableNames = composerItem->customProperty( "variableNames" ).toStringList();
931  QStringList variableValues = composerItem->customProperty( "variableValues" ).toStringList();
932 
933  variableNames << name;
934  variableValues << value.toString();
935 
936  composerItem->setCustomProperty( "variableNames", variableNames );
937  composerItem->setCustomProperty( "variableValues", variableValues );
938 }
939 
941 {
942  if ( !composerItem )
943  return;
944 
946  QStringList variableValues;
947 
949  for ( ; it != variables.constEnd(); ++it )
950  {
951  variableNames << it.key();
952  variableValues << it.value();
953  }
954 
955  composerItem->setCustomProperty( "variableNames", variableNames );
956  composerItem->setCustomProperty( "variableValues", variableValues );
957 }
958 
960 {
962  scope->setFeature( feature );
963  scope->setFields( fields );
964  return QgsExpressionContext() << scope;
965 }
966 
968 {
969  QgsExpression::registerFunction( new GetNamedProjectColor() );
970 }
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").
QVariant cachedValue(const QString &key) const
Returns the matching cached value, if set.
Single variable definition for use within a QgsExpressionContextScope.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the object.
static void setGlobalVariable(const QString &name, const QVariant &value)
Sets a global context variable.
static unsigned index
Base class for all map layer types.
Definition: qgsmaplayer.h:49
QString toNativeSeparators(const QString &pathName)
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:217
QgsExpression::Function * function(const QString &name) const
Retrieves a function from the scope.
double angle() const
Returns the marker angle for the whole symbol.
iterator insert(const Key &key, const T &value)
QgsExpressionContextScope * scope(int index)
Returns the scope at the specified index within the context.
bool isReadOnly(const QString &name) const
Returns whether a variable is read only, and should not be modifiable by users.
static void setGlobalVariables(const QgsStringMap &variables)
Sets all global context variables.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
QStringList filteredVariableNames() const
Returns a filtered list of variables names set by all scopes in the context.
int localeAwareCompare(const QString &other) const
QgsExpressionContext & operator=(const QgsExpressionContext &other)
double rotation() const
Return the rotation of the resulting map image Units are clockwise degrees.
bool hasFunction(const QString &name) const
Checks whether a specified function is contained in the context.
static QgsExpressionContextScope * atlasScope(const QgsAtlasComposition *atlas)
Creates a new scope which contains variables and functions relating to a QgsAtlasComposition.
void addFunction(const QString &name, QgsScopedExpressionFunction *function)
Adds a function to the scope.
int length() const
A abstract base class for defining QgsExpression functions.
QgsExpressionContextScope(const QString &name=QString())
Constructor for QgsExpressionContextScope.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
static void setLayerVariables(QgsMapLayer *layer, const QgsStringMap &variables)
Sets all layer context variables.
QgsExpressionContextScope * activeScopeForVariable(const QString &name)
Returns the currently active scope from the context for a specified variable name.
QList< QVariant > toList() const
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.
int printResolution() const
const_iterator constBegin() const
const T & at(int i) const
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
QString currentPageName() const
Returns the name of the page for the current atlas feature.
A item that forms part of a map composition.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the composition.
bool isReadOnly(const QString &name) const
Tests whether the specified variable is read only and should not be editable by users.
QString currentFilename() const
Returns the current filename.
int numPages() const
Returns the number of pages in the composition.
T value() const
Container of fields for a vector layer.
Definition: qgsfield.h:252
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:76
int numFeatures() const
Returns the number of features in the coverage layer.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:82
QSet< T > toSet() const
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
const Key & key() const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
QgsExpressionContextScope & operator=(const QgsExpressionContextScope &other)
QString tr(const char *sourceText, const char *disambiguation, int n)
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
void setVariable(const QString &name, const QVariant &value)
Convenience method for setting a variable in the context scope by name and value. ...
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
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.
static void setCompositionVariables(QgsComposition *composition, const QgsStringMap &variables)
Sets all composition context variables.
QgsFields fields() const
Returns the list of fields of this layer.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the composition.
The QgsMapSettings class contains configuration for rendering of the map.
QString filePath() const
void setValue(const QString &key, const QVariant &value)
int page() const
Gets the page the item is currently on.
bool writeEntry(const QString &scope, const QString &key, bool value)
bool removeVariable(const QString &name)
Removes a variable from the context scope, if found.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the 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
Get this layer&#39;s unique ID, this ID is used to access this layer from map layer registry.
const_iterator constEnd() const
QString path() const
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.
QString fileName() const
Q_DECL_DEPRECATED void title(const QString &title)
Every project has an associated title string.
Definition: qgsproject.h:91
double scale() const
Return the calculated scale of the map.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:207
bool contains(const QString &key) const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static bool registerFunction(Function *function, bool transferOwnership=false)
Registers a function to the expression engine.
const T & value() const
const_iterator constEnd() const
QVariant variable(const QString &name) const
Retrieves a variable&#39;s value from the scope.
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
static void setComposerItemVariable(QgsComposerItem *composerItem, const QString &name, const QVariant &value)
Sets a composer item context variable.
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:71
QString uuid() const
Get item identification name.
static void setCompositionVariable(QgsComposition *composition, const QString &name, const QVariant &value)
Sets a composition context variable.
QDir dir() const
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.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
static QgsExpressionContextScope * composerItemScope(const QgsComposerItem *composerItem)
Creates a new scope which contains variables and functions relating to a QgsComposerItem.
QStringList functionNames() const
Retrieves a list of names of functions contained in the scope.
static QString QGIS_VERSION
Definition: qgis.h:46
Graphics scene for map printing.
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 QgsGeometry * fromPoint(const QgsPoint &point)
Creates a new geometry from a QgsPoint object.
static QString userLoginName()
Returns the user&#39;s operating system login account name.
void clear()
int currentFeatureNumber() const
Returns the current feature number, where a value of 0 corresponds to the first feature.
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
iterator end()
QString toLower() const
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
static QString osName()
Returns a string name of the operating system QGIS is running on.
QVariant fromValue(const T &value)
QChar toLower() const
const Key key(const T &value) const
static void setComposerItemVariables(QgsComposerItem *composerItem, const QgsStringMap &variables)
Sets all composition context variables.
QgsExpression::Function * function(const QString &name) const
Fetches a matching function from the context.
static void registerContextFunctions()
Registers all known core functions provided by QgsExpressionContextScope objects. ...
QVariant value(const QString &key, const QVariant &defaultValue) const
const_iterator constBegin() const
QFileInfo fileInfo() const
Returns QFileInfo object for the project&#39;s associated file.
Definition: qgsproject.cpp:442
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.
QStringList toStringList() const
static const QString EXPR_FEATURE
Inbuilt variable name for feature storage.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the object.
void clearCachedValues() const
Clears all cached values from the context.
QColor color() const
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
const QChar at(int position) const
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:382
static QString platform()
Returns the QGIS platform name, eg "desktop" or "server".
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.
Class used to render an Atlas, iterating over geometry features.
double paperHeight() const
Height of paper item.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user...
static QColor decodeColor(const QString &str)
QString name
Read property of QString layerName.
Definition: qgsmaplayer.h:53
double paperWidth() const
Width of paper item.
QgsFeature feature() const
Returns the current atlas feature.
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
static void setProjectVariable(const QString &name, const QVariant &value)
Sets a project context variable.
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
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.
const_iterator constEnd() const
const_iterator constBegin() const
static const QString EXPR_GEOMETRY_PART_NUM
Inbuilt variable name for geometry part number variable.
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.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbolV2 *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbolV2 to an expression context.
QString toString() const
static QString QGIS_RELEASE_NAME
Definition: qgis.h:50
QStringList filteredVariableNames() const
Returns a fitlered and sorted list of variable names contained within the scope.
static const int QGIS_VERSION_INT
Definition: qgis.h:48
QString id() const
Get item&#39;s id (which is not necessarly unique)
iterator begin()
Expression function for use within a QgsExpressionContextScope.
bool enabled() const
Returns whether the atlas generation is enabled.
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:212
const T value(const Key &key) const
static void setProjectVariables(const QgsStringMap &variables)
Sets all project context variables.
static QgsExpressionContextScope * compositionScope(const QgsComposition *composition)
Creates a new scope which contains variables and functions relating to a QgsComposition.