QGIS API Documentation  3.0.2-Girona (307d082)
qgsrelationreferencefieldformatter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrelationreferencefieldformatter.cpp - QgsRelationReferenceFieldFormatter
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 "qgsmessagelog.h"
19 #include "qgsrelation.h"
20 #include "qgsexpressioncontext.h"
21 #include "qgsproject.h"
22 #include "qgsrelationmanager.h"
23 #include "qgsvectorlayer.h"
24 
26 {
27  return QStringLiteral( "RelationReference" );
28 }
29 
30 QString QgsRelationReferenceFieldFormatter::representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const
31 {
32  Q_UNUSED( cache );
33 
34  // Some sanity checks
35  if ( !config.contains( QStringLiteral( "Relation" ) ) )
36  {
37  QgsMessageLog::logMessage( QObject::tr( "Missing Relation in configuration" ) );
38  return value.toString();
39  }
40  QgsRelation relation = QgsProject::instance()->relationManager()->relation( config[QStringLiteral( "Relation" )].toString() );
41  if ( !relation.isValid() )
42  {
43  QgsMessageLog::logMessage( QObject::tr( "Invalid relation" ) );
44  return value.toString();
45  }
46  QgsVectorLayer *referencingLayer = relation.referencingLayer();
47  if ( layer != referencingLayer )
48  {
49  QgsMessageLog::logMessage( QObject::tr( "representValue() with inconsistent layer parameter w.r.t relation referencingLayer" ) );
50  return value.toString();
51  }
52  int referencingFieldIdx = referencingLayer->fields().lookupField( relation.fieldPairs().at( 0 ).first );
53  if ( referencingFieldIdx != fieldIndex )
54  {
55  QgsMessageLog::logMessage( QObject::tr( "representValue() with inconsistent fieldIndex parameter w.r.t relation referencingFieldIdx" ) );
56  return value.toString();
57  }
58  QgsVectorLayer *referencedLayer = relation.referencedLayer();
59  if ( !referencedLayer )
60  {
61  QgsMessageLog::logMessage( QObject::tr( "Cannot find referenced layer" ) );
62  return value.toString();
63  }
64 
65  // Attributes from the referencing layer
66  QgsAttributes attrs = QgsAttributes( layer->fields().count() );
67  // Set the value on the foreign key field of the referencing record
68  attrs[ referencingFieldIdx ] = value;
69 
70  QgsFeatureRequest request = relation.getReferencedFeatureRequest( attrs );
71  QgsFeature feature;
72  referencedLayer->getFeatures( request ).nextFeature( feature );
73  if ( !feature.isValid() )
74  return value.toString();
75 
76  QgsExpression expr( referencedLayer->displayExpression() );
78  context.setFeature( feature );
79  QString title = expr.evaluate( &context ).toString();
80  if ( expr.hasEvalError() )
81  {
82  int referencedFieldIdx = referencedLayer->fields().lookupField( relation.fieldPairs().at( 0 ).second );
83  title = feature.attribute( referencedFieldIdx ).toString();
84  }
85  return title;
86 }
87 
88 QVariant QgsRelationReferenceFieldFormatter::sortValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const
89 {
90  return representValue( layer, fieldIndex, config, cache, value );
91 }
int lookupField(const QString &fieldName) const
Look up field's index from the field name.
Definition: qgsfields.cpp:299
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:176
QgsVectorLayer referencingLayer
Definition: qgsrelation.h:43
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.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
int count() const
Return number of items.
Definition: qgsfields.cpp:115
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning)
add a message to the instance (and create it if necessary)
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
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)...
QgsVectorLayer referencedLayer
Definition: qgsrelation.h:44
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
QgsRelationManager relationManager
Definition: qgsproject.h:92
QString displayExpression
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Query the layer for features specified in request.
QString id() const override
Return a unique id for this field formatter.
bool isValid
Definition: qgsrelation.h:46
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:383
bool nextFeature(QgsFeature &f)
Q_INVOKABLE QgsRelation relation(const QString &id) const
Get access to a relation by its id.
A vector of attributes.
Definition: qgsattributes.h:58
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
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...