28 #include <nlohmann/json.hpp> 50 return QStringLiteral(
"ValueRelation" );
57 if ( cache.isValid() )
66 if ( config.value( QStringLiteral(
"AllowMulti" ) ).toBool() )
70 if ( layer->
fields().
at( fieldIndex ).
type() == QVariant::Map )
73 keyList = value.toStringList();
77 keyList = valueToStringList( value );
80 QStringList valueList;
84 if ( keyList.contains( item.key.toString() ) )
86 valueList << item.value;
90 return valueList.join( QStringLiteral(
", " ) ).prepend(
'{' ).append(
'}' );
101 if ( item.key == value )
108 return QStringLiteral(
"(%1)" ).arg( value.toString() );
113 return representValue( layer, fieldIndex, config, cache, value );
119 Q_UNUSED( fieldIndex )
120 return QVariant::fromValue<ValueRelationCache>( createCache( config ) );
134 int ki = fields.
indexOf( config.value( QStringLiteral(
"Key" ) ).toString() );
135 int vi = fields.
indexOf( config.value( QStringLiteral(
"Value" ) ).toString() );
142 const QString expression = config.value( QStringLiteral(
"FilterExpression" ) ).toString();
146 if ( ! expression.isEmpty() && ( ! expressionRequiresFormScope( expression )
147 || expressionIsUsable( expression, formFeature ) ) )
164 if ( config.value( QStringLiteral(
"OrderByValue" ) ).toBool() )
179 QList<QgsVectorLayerRef> result;
180 const QString layerId { config.value( QStringLiteral(
"Layer" ) ).toString() };
181 const QString layerName { config.value( QStringLiteral(
"LayerName" ) ).toString() };
182 const QString providerName { config.value( QStringLiteral(
"LayerProviderName" ) ).toString() };
183 const QString layerSource { config.value( QStringLiteral(
"LayerSource" ) ).toString() };
184 if ( ! layerId.isEmpty() && ! layerName.isEmpty() && ! providerName.isEmpty() && ! layerSource.isEmpty() )
186 result.append(
QgsVectorLayerRef( layerId, layerName, layerSource, providerName ) );
198 if ( referencedLayer )
200 int fieldIndex = referencedLayer->
fields().
indexOf( config.value( QStringLiteral(
"Key" ) ).toString() );
201 values = referencedLayer->
uniqueValues( fieldIndex, countLimit ).toList();
209 QStringList checkList;
210 if ( value.type() == QVariant::StringList )
212 checkList = value.toStringList();
216 QVariantList valuesList;
217 if ( value.type() == QVariant::String )
220 auto newVal { value };
221 if ( newVal.toString().trimmed().startsWith(
'{' ) )
226 else if ( newVal.toString().trimmed().startsWith(
'[' ) )
231 for (
auto &element :
json::parse( newVal.toString().toStdString() ) )
233 if ( element.is_number_integer() )
235 valuesList.push_back( element.get<
int>() );
237 else if ( element.is_number_unsigned() )
239 valuesList.push_back( element.get<
unsigned>() );
241 else if ( element.is_string() )
243 valuesList.push_back( QString::fromStdString( element.get<std::string>() ) );
247 catch ( json::parse_error &ex )
249 QgsMessageLog::logMessage( QObject::tr(
"Cannot parse JSON like string '%1' Error: %2" ).arg( newVal.toString(), ex.what() ) );
253 else if ( value.type() == QVariant::List )
255 valuesList = value.toList( );
258 checkList.reserve( valuesList.size() );
259 for (
const QVariant &listItem : qgis::as_const( valuesList ) )
261 QString v( listItem.toString( ) );
263 checkList.append( v );
273 QSet< QString > formVariables = scope->variableNames().toSet();
275 formVariables.intersect( usedVariables );
276 return formVariables;
281 return !( expressionFormAttributes( expression ).isEmpty() && expressionFormVariables( expression ).isEmpty() );
286 QSet<QString> attributes;
290 const QSet<QString> formFunctions( scope->functionNames()
295 for (
const auto &f : expFunctions )
298 if ( formFunctions.contains( fd->
name( ) ) )
300 for (
const auto ¶m : f->args( )->list() )
302 attributes.insert( param->eval( &exp, &context ).toString() );
311 const QSet<QString> attrs = expressionFormAttributes( expression );
312 for (
auto it = attrs.constBegin() ; it != attrs.constEnd(); it++ )
314 if ( ! feature.
attribute( *it ).isValid() )
317 if ( ! expressionFormVariables( expression ).isEmpty() && feature.
geometry().
isEmpty( ) )
325 config.value( QStringLiteral(
"LayerName" ) ).toString(),
326 config.value( QStringLiteral(
"LayerSource" ) ).toString(),
327 config.value( QStringLiteral(
"LayerProviderName" ) ).toString() };
bool isValid() const
Returns the validity of this feature.
Class for parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
TYPE * resolveByIdOrNameOnly(const QgsProject *project)
Resolves the map layer by attempting to find a matching layer in a project using a weak match...
A context for field formatter containing information like the project.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Container of fields for a vector layer.
static QVariantList parseArray(const QString &string)
Returns a QVariantList created out of a string containing an array in postgres array format {1...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static QgsExpressionContextScope * formScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current attribute form/table feat...
QSet< QString > referencedVariables() const
Returns a list of all variables which are used in this expression.
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
This class wraps a request for features to a vector layer (or directly its vector data provider)...
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
An expression node for expression functions.
QString name() const
The name of the function.
A abstract base class for defining QgsExpression functions.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const FINAL
Calculates a list of unique values contained within an attribute in the layer.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
static QgsProject * instance()
Returns the QgsProject singleton instance.
_LayerRef< QgsVectorLayer > QgsVectorLayerRef
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QList< int > QgsAttributeList
bool nextFeature(QgsFeature &f)
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QgsSQLStatement::Node * parse(const QString &str, QString &parserErrorMsg)
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
QgsProject * project() const
Returns the project used in field formatter.
QList< const T * > findNodes() const
Returns a list of all nodes of the given class which are used in this expression. ...
QSet< QString > referencedFunctions() const
Returns a list of the names of all functions which are used in this expression.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.