QGIS API Documentation  3.0.2-Girona (307d082)
qgsvaluerelationfieldformatter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvaluerelationfieldformatter.cpp - QgsValueRelationFieldFormatter
3 
4  ---------------------
5  begin : 3.12.2016
6  copyright : (C) 2016 by Matthias Kuhn
7  email : [email protected]
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
17 
18 #include "qgis.h"
19 #include "qgsproject.h"
20 #include "qgsvectorlayer.h"
21 
22 #include <QSettings>
23 
25 {
26  return qgsVariantLessThan( p1.key, p2.key );
27 }
28 
30 {
31  return qgsVariantLessThan( p1.value, p2.value );
32 }
33 
35 {
36  return QStringLiteral( "ValueRelation" );
37 }
38 
39 QString QgsValueRelationFieldFormatter::representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const
40 {
41  Q_UNUSED( layer )
42  Q_UNUSED( fieldIndex )
43 
44  ValueRelationCache vrCache;
45 
46  if ( cache.isValid() )
47  {
49  }
50  else
51  {
53  }
54 
55  if ( config.value( QStringLiteral( "AllowMulti" ) ).toBool() )
56  {
57  QStringList keyList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( ',' );
58  QStringList valueList;
59 
60  for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : qgis::as_const( vrCache ) )
61  {
62  if ( keyList.contains( item.key.toString() ) )
63  {
64  valueList << item.value;
65  }
66  }
67 
68  return valueList.join( QStringLiteral( ", " ) ).prepend( '{' ).append( '}' );
69  }
70  else
71  {
72  if ( value.isNull() )
73  {
75  }
76 
77  for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : qgis::as_const( vrCache ) )
78  {
79  if ( item.key == value )
80  {
81  return item.value;
82  }
83  }
84  }
85 
86  return QStringLiteral( "(%1)" ).arg( value.toString() );
87 }
88 
89 QVariant QgsValueRelationFieldFormatter::sortValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const
90 {
91  return representValue( layer, fieldIndex, config, cache, value );
92 }
93 
94 QVariant QgsValueRelationFieldFormatter::createCache( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config ) const
95 {
96  Q_UNUSED( layer )
97  Q_UNUSED( fieldIndex )
98  return QVariant::fromValue<ValueRelationCache>( createCache( config ) );
99 
100 }
101 
103 {
104  ValueRelationCache cache;
105 
106  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( config.value( QStringLiteral( "Layer" ) ).toString() ) );
107 
108  if ( !layer )
109  return cache;
110 
111  QgsFields fields = layer->fields();
112  int ki = fields.indexOf( config.value( QStringLiteral( "Key" ) ).toString() );
113  int vi = fields.indexOf( config.value( QStringLiteral( "Value" ) ).toString() );
114 
115  QgsFeatureRequest request;
116 
118  request.setSubsetOfAttributes( QgsAttributeList() << ki << vi );
119  if ( !config.value( QStringLiteral( "FilterExpression" ) ).toString().isEmpty() )
120  {
122  request.setExpressionContext( context );
123  request.setFilterExpression( config.value( QStringLiteral( "FilterExpression" ) ).toString() );
124  }
125 
126  QgsFeatureIterator fit = layer->getFeatures( request );
127 
128  QgsFeature f;
129  while ( fit.nextFeature( f ) )
130  {
131  cache.append( ValueRelationItem( f.attribute( ki ), f.attribute( vi ).toString() ) );
132  }
133 
134  if ( config.value( QStringLiteral( "OrderByValue" ) ).toBool() )
135  {
136  std::sort( cache.begin(), cache.end(), orderByValueLessThan );
137  }
138  else
139  {
140  std::sort( cache.begin(), cache.end(), orderByKeyLessThan );
141  }
142 
143  return cache;
144 }
Wrapper for iterator of features from vector data provider or vector layer.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Container of fields for a vector layer.
Definition: qgsfields.h:42
QVariant sortValue(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value) const override
If the default sort order should be overwritten for this widget, you can transform the value in here...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
QVector< QgsValueRelationFieldFormatter::ValueRelationItem > ValueRelationCache
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
Definition: qgis.cpp:146
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 override
Returns the list of fields of this layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
This class wraps a request for features to a vector layer (or directly its vector data provider)...
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
QVariant createCache(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config) const override
Create a cache for a given field.
bool orderByKeyLessThan(const QgsValueRelationFieldFormatter::ValueRelationItem &p1, const QgsValueRelationFieldFormatter::ValueRelationItem &p2)
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Query the layer for features specified in request.
bool orderByValueLessThan(const QgsValueRelationFieldFormatter::ValueRelationItem &p1, const QgsValueRelationFieldFormatter::ValueRelationItem &p2)
QString representValue(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value) const override
Create a pretty String representation of the value.
int indexOf(const QString &fieldName) const
Get the field index from the field name.
Definition: qgsfields.cpp:189
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:383
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QString id() const override
Return a unique id for this field formatter.
QList< int > QgsAttributeList
Definition: qgsfield.h:27
bool nextFeature(QgsFeature &f)
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:255
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Set flags that affect how features will be fetched.