25using namespace Qt::StringLiterals;
49 : mName( other.mName )
50 , mVariables( other.mVariables )
51 , mHasFeature( other.mHasFeature )
52 , mFeature( other.mFeature )
53 , mHasGeometry( other.mHasGeometry )
54 , mGeometry( other.mGeometry )
55 , mHiddenVariables( other.mHiddenVariables )
56 , mLayerStores( other.mLayerStores )
59 QHash<QString, QgsScopedExpressionFunction * >::const_iterator it = other.mFunctions.constBegin();
60 for ( ; it != other.mFunctions.constEnd(); ++it )
62 mFunctions.insert( it.key(), it.value()->clone() );
67 : mName( std::move( other.mName ) )
68 , mVariables( std::move( other.mVariables ) )
69 , mFunctions( std::move( other.mFunctions ) )
70 , mHasFeature( other.mHasFeature )
71 , mFeature( std::move( other.mFeature ) )
72 , mHasGeometry( other.mHasGeometry )
73 , mGeometry( std::move( other.mGeometry ) )
74 , mHiddenVariables( std::move( other.mHiddenVariables ) )
75 , mLayerStores( std::move( other.mLayerStores ) )
85 mVariables = other.mVariables;
86 mHasFeature = other.mHasFeature;
87 mFeature = other.mFeature;
88 mHasGeometry = other.mHasGeometry;
89 mGeometry = other.mGeometry;
90 mHiddenVariables = other.mHiddenVariables;
91 mLayerStores = other.mLayerStores;
93 qDeleteAll( mFunctions );
95 QHash<QString, QgsScopedExpressionFunction * >::const_iterator it = other.mFunctions.constBegin();
96 for ( ; it != other.mFunctions.constEnd(); ++it )
98 mFunctions.insert( it.key(), it.value()->clone() );
106 if ( &other ==
this )
109 mName = std::move( other.mName );
110 mVariables = std::move( other.mVariables );
111 mHasFeature = other.mHasFeature;
112 mFeature = std::move( other.mFeature );
113 mHasGeometry = other.mHasGeometry;
114 mGeometry = std::move( other.mGeometry );
115 mHiddenVariables = std::move( other.mHiddenVariables );
116 mLayerStores = std::move( other.mLayerStores );
117 mFunctions = std::move( other.mFunctions );
123 qDeleteAll( mFunctions );
128 auto it = mVariables.find(
name );
129 if ( it != mVariables.end() )
147 return mVariables.remove(
name );
152 return mVariables.contains(
name );
162 QStringList names = mVariables.keys();
166 names.append( u
"feature"_s );
167 names.append( u
"id"_s );
168 names.append( u
"geometry"_s );
176 return mHiddenVariables;
186 if ( !mHiddenVariables.contains( hiddenVariable ) )
187 mHiddenVariables << hiddenVariable;
192 if ( mHiddenVariables.contains( hiddenVariable ) )
193 mHiddenVariables.removeAt( mHiddenVariables.indexOf( hiddenVariable ) );
198 mLayerStores.append( store );
203 QList<QgsMapLayerStore *> res;
204 res.reserve( mLayerStores.size() );
214class QgsExpressionContextVariableCompare
221 bool operator()(
const QString &a,
const QString &b )
const
223 bool aReadOnly = mScope.isReadOnly( a );
224 bool bReadOnly = mScope.isReadOnly( b );
225 if ( aReadOnly != bReadOnly )
227 return QString::localeAwareCompare( a, b ) < 0;
231 const QgsExpressionContextScope &mScope;
237 QStringList allVariables = mVariables.keys();
238 QStringList filtered;
239 const auto constAllVariables = allVariables;
240 for (
const QString &
variable : constAllVariables )
247 QgsExpressionContextVariableCompare cmp( *
this );
248 std::sort( filtered.begin(), filtered.end(), cmp );
270 return mFunctions.contains(
name );
275 return mFunctions.contains(
name ) ? mFunctions.value(
name ) :
nullptr;
280 return mFunctions.keys();
296 const QDomNodeList variablesNodeList = element.childNodes();
297 for (
int i = 0; i < variablesNodeList.size(); ++i )
299 const QDomElement variableElement = variablesNodeList.at( i ).toElement();
300 const QString key = variableElement.attribute( u
"name"_s );
301 if ( variableElement.tagName() ==
"Variable"_L1 )
313 for (
auto it = mVariables.constBegin(); it != mVariables.constEnd(); ++it )
315 QDomElement varElem = document.createElement( u
"Variable"_s );
316 varElem.setAttribute( u
"name"_s, it.key() );
318 varElem.appendChild( valueElem );
319 element.appendChild( varElem );
322 for ( QString hiddenVariable : mHiddenVariables )
324 QDomElement varElem = document.createElement( u
"HiddenVariable"_s );
325 varElem.setAttribute( u
"name"_s, hiddenVariable );
326 element.appendChild( varElem );
338 mLoadLayerFunction = std::make_unique< LoadLayerFunction >();
344 mLoadLayerFunction = std::make_unique< LoadLayerFunction >();
355 mHighlightedVariables = other.mHighlightedVariables;
356 mHighlightedFunctions = other.mHighlightedFunctions;
357 mCachedValues = other.mCachedValues;
358 mFeedback = other.mFeedback;
359 mDestinationStore = other.mDestinationStore;
360 mLoadLayerFunction = std::make_unique< LoadLayerFunction >();
365 : mStack( std::move( other.mStack ) )
366 , mHighlightedVariables( std::move( other.mHighlightedVariables ) )
367 , mHighlightedFunctions( std::move( other.mHighlightedFunctions ) )
368 , mFeedback( other.mFeedback )
369 , mLoadLayerFunction( std::move( other.mLoadLayerFunction ) )
370 , mDestinationStore( std::move( other.mDestinationStore ) )
371 , mCachedValues( std::move( other.mCachedValues ) )
376 if (
this != &other )
378 qDeleteAll( mStack );
380 mStack = std::move( other.mStack );
382 mHighlightedVariables = std::move( other.mHighlightedVariables );
383 mHighlightedFunctions = std::move( other.mHighlightedFunctions );
384 mLoadLayerFunction = std::move( other.mLoadLayerFunction );
385 mCachedValues = std::move( other.mCachedValues );
386 mFeedback = other.mFeedback;
387 mDestinationStore = std::move( other.mDestinationStore );
395 if ( &other ==
this )
399 qDeleteAll( mStack );
405 mHighlightedVariables = other.mHighlightedVariables;
406 mHighlightedFunctions = other.mHighlightedFunctions;
407 mCachedValues = other.mCachedValues;
408 mFeedback = other.mFeedback;
409 mDestinationStore = other.mDestinationStore;
416 qDeleteAll( mStack );
422 const auto constMStack = mStack;
425 if (
scope->hasVariable( name ) )
434 return scope ?
scope->variable( name ) : QVariant();
441 const auto constNames = names;
442 for (
const QString &name : constNames )
451 return mHighlightedVariables.contains( name );
456 return mHighlightedVariables;
466 return mHighlightedFunctions.contains( name );
471 mHighlightedFunctions = names;
477 QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
478 while ( it != mStack.constBegin() )
481 if ( ( *it )->hasVariable( name ) )
490 QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
491 while ( it != mStack.constBegin() )
494 if ( ( *it )->hasVariable( name ) )
502 if ( index < 0 || index >= mStack.count() )
505 return mStack.at( index );
510 if ( mStack.count() < 1 )
513 return mStack.last();
521 return mStack.indexOf(
scope );
527 const auto constMStack = mStack;
530 if (
scope->name() == scopeName )
540 QSet< QString> names;
545 names.insert( name );
547 return QStringList( names.constBegin(), names.constEnd() );
553 QStringList filtered;
554 const auto constAllVariables = allVariables;
556 QStringList hiddenVariables;
560 const QStringList scopeHiddenVariables =
scope->hiddenVariables();
561 for (
const QString &name : scopeHiddenVariables )
562 hiddenVariables << name;
565 for (
const QString &
variable : constAllVariables )
579 const auto constMStack = mStack;
582 if (
scope->isReadOnly( name ) )
596 if ( name.compare(
"load_layer"_L1 ) == 0 && mDestinationStore )
601 if (
scope->hasFunction( name ) )
609 QSet< QString > result;
614 result.insert( name );
617 if ( mDestinationStore )
618 result.insert( u
"load_layer"_s );
620 QStringList listResult( result.constBegin(), result.constEnd() );
627 if ( name.compare(
"load_layer"_L1 ) == 0 && mDestinationStore )
629 return mLoadLayerFunction.get();
633 QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
634 while ( it != mStack.constBegin() )
637 if ( ( *it )->hasFunction( name ) )
638 return ( *it )->function( name );
645 return mStack.count();
650 mStack.append(
scope );
660 if ( !mStack.isEmpty() )
661 return mStack.takeLast();
668 QList<QgsExpressionContextScope *> stack = mStack;
675 mStack.append(
scope );
681 if ( mStack.isEmpty() )
691 if (
scope->hasFeature() )
700 QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
701 while ( it != mStack.constBegin() )
704 if ( ( *it )->hasFeature() )
705 return ( *it )->feature();
712 if ( mStack.isEmpty() )
715 mStack.last()->setGeometry(
geometry );
722 if (
scope->hasGeometry() )
731 QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
732 while ( it != mStack.constBegin() )
735 if ( ( *it )->hasGeometry() )
736 return ( *it )->geometry();
743 if ( mStack.isEmpty() )
746 mStack.last()->setFields(
fields );
756 if ( mStack.isEmpty() )
764 mCachedValues.insert( key, value );
769 return mCachedValues.contains( key );
774 return mCachedValues.value( key, QVariant() );
779 mCachedValues.clear();
785 QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
786 QList<QgsMapLayerStore *> res;
787 while ( it != mStack.constBegin() )
790 res.append( ( *it )->layerStores() );
793 if ( mDestinationStore && !res.contains( mDestinationStore ) )
794 res.append( mDestinationStore );
800 mDestinationStore = store;
805 return mDestinationStore;
822 const QString delimiter( u
"||~~||"_s );
826 hash.append( QString::number(
feature().
id() ) + delimiter + QString::number(
qHash(
feature() ) ) + delimiter );
829 QStringList sortedVars = qgis::setToList( variables );
830 if ( sortedVars.empty() )
832 std::sort( sortedVars.begin(), sortedVars.end() );
834 for (
const QString &variableName : std::as_const( sortedVars ) )
836 const QVariant value =
variable( variableName );
837 hash.append( variableName +
"=" );
840 hash.append( delimiter );
842 else if ( value.type() == QVariant::String )
844 hash.append( value.toString() + delimiter );
848 const QString variantString = value.toString();
849 if ( variantString.isEmpty() )
854 hash.append( variantString + delimiter );
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addLayerStore(QgsMapLayerStore *store)
Adds a layer store to the scope.
bool hasVariable(const QString &name) const
Tests whether a variable with the specified name exists in the scope.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
QString description(const QString &name) const
Returns the translated description for the variable with the specified name (if set).
void setHiddenVariables(const QStringList &hiddenVariables)
Sets the list of variables intended to be hidden in the expression builder dialog and widget.
void addHiddenVariable(const QString &hiddenVariable)
Adds the passed variable to a list of hidden variables that won't be visible in the expression builde...
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads scope variables from an XML element.
QStringList hiddenVariables() const
Returns the list of variables hidden within the scope.
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Writes scope variables to an XML element.
QgsExpressionFunction * function(const QString &name) const
Retrieves a function from the scope.
QVariant variable(const QString &name) const
Retrieves a variable's value from the scope.
QList< QgsMapLayerStore * > layerStores() const
Returns the list of layer stores associated with the scope.
void removeHiddenVariable(const QString &hiddenVariable)
Removes the passed variable from a list of hidden variables.
bool removeVariable(const QString &name)
Removes a variable from the context scope, if found.
bool isReadOnly(const QString &name) const
Tests whether the specified variable is read only and should not be editable by users.
void addFunction(const QString &name, QgsScopedExpressionFunction *function)
Adds a function to the scope.
bool hasFeature() const
Returns true if the scope has a feature associated with it.
bool hasFunction(const QString &name) const
Tests whether a function with the specified name exists in the scope.
QString name() const
Returns the friendly display name of the context scope.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
bool isStatic(const QString &name) const
Tests whether the variable with the specified name is static and can be cached.
QStringList filteredVariableNames() const
Returns a filtered and sorted list of variable names contained within the scope.
QStringList functionNames() const
Retrieves a list of names of functions contained in the scope.
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.
QgsExpressionContextScope & operator=(const QgsExpressionContextScope &other)
QgsExpressionContextScope(const QString &name=QString())
Constructor for QgsExpressionContextScope.
~QgsExpressionContextScope()
QStringList variableNames() const
Returns a list of variable names contained within the scope.
static const QString EXPR_GEOMETRY_PART_COUNT
Inbuilt variable name for geometry part count variable.
bool hasFunction(const QString &name) const
Checks whether a specified function is contained in the context.
QString description(const QString &name) const
Returns a translated description string for the variable with specified name.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
QStringList highlightedVariables() const
Returns the current list of variables highlighted within the context.
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
QStringList functionNames() const
Retrieves a list of function names contained in the context.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
int indexOfScope(QgsExpressionContextScope *scope) const
Returns the index of the specified scope if it exists within the context.
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
void clearCachedValues() const
Clears all cached values from the context.
void setHighlightedFunctions(const QStringList &names)
Sets the list of function names intended to be highlighted to the user.
QString uniqueHash(bool &ok, const QSet< QString > &variables=QSet< QString >()) const
Returns a unique hash representing the current state of the context.
QgsGeometry geometry() const
Convenience function for retrieving the geometry for the context, if set.
bool isHighlightedFunction(const QString &name) const
Returns true if the specified function name is intended to be highlighted to the user.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
QgsExpressionContext & operator=(const QgsExpressionContext &other)
static const QString EXPR_FIELDS
Inbuilt variable name for fields storage.
QStringList filteredVariableNames() const
Returns a filtered list of variables names set by all scopes in the context.
QList< QgsMapLayerStore * > layerStores() const
Returns the list of layer stores associated with the context.
void setGeometry(const QgsGeometry &geometry)
Convenience function for setting a geometry for the context.
static const QString EXPR_GEOMETRY_RING_NUM
Inbuilt variable name for geometry ring number variable.
bool isHighlightedVariable(const QString &name) const
Returns true if the specified variable name is intended to be highlighted to the user.
QgsExpressionContextScope * activeScopeForVariable(const QString &name)
Returns the currently active scope from the context for a specified variable name.
static const QString EXPR_GEOMETRY_PART_NUM
Inbuilt variable name for geometry part number variable.
QgsMapLayerStore * loadedLayerStore() const
Returns the destination layer store for any layers loaded during expression evaluation.
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
QList< QgsExpressionContextScope * > scopes()
Returns a list of scopes contained within the stack.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
QList< QgsExpressionContextScope * > takeScopes()
Returns all scopes from this context and remove them, leaving this context without any context.
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly by the expression to check if evaluation sh...
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly by the expression engine to check if expressio...
int scopeCount() const
Returns the number of scopes contained in the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static const QString EXPR_SYMBOL_ANGLE
Inbuilt variable name for symbol angle variable.
bool isReadOnly(const QString &name) const
Returns whether a variable is read only, and should not be modifiable by users.
bool hasGeometry() const
Returns true if the context has a geometry associated with it.
QgsExpressionFunction * function(const QString &name) const
Fetches a matching function from the context.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
QVariantMap variablesToMap() const
Returns a map of variable name to value representing all the expression variables contained by the co...
bool hasCachedValue(const QString &key) const
Returns true if the expression context contains a cached value with a matching key.
void setLoadedLayerStore(QgsMapLayerStore *store)
Sets the destination layer store for any layers loaded during expression evaluation.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
QgsExpressionContext & operator<<(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
QStringList variableNames() const
Returns a list of variables names set by all scopes in the context.
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
QgsExpressionContextScope * scope(int index)
Returns the scope at the specified index within the context.
QVariant cachedValue(const QString &key) const
Returns the matching cached value, if set.
bool hasFeature() const
Returns true if the context has a feature associated with it.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
An abstract base class for defining QgsExpression functions.
static QString variableHelpText(const QString &variableName)
Returns the help text for a specified variable.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
A container for the context for various read/write operations on objects.
Expression function for use within a QgsExpressionContextScope.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
uint qHash(const QVariant &variant)
Hash for QVariant.
Single variable definition for use within a QgsExpressionContextScope.