QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 }
Class for parsing and evaluation of expressions (formerly called "search strings").
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
QgsVectorLayer referencingLayer
Definition: qgsrelation.h:46
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:55
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 FINAL
Returns the list of fields of this layer.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
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)...
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsVectorLayer referencedLayer
Definition: qgsrelation.h:47
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:320
QgsRelationManager relationManager
Definition: qgsproject.h:100
QString displayExpression
QString id() const override
Returns a unique id for this field formatter.
bool isValid
Definition: qgsrelation.h:49
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:411
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 FINAL
Query the layer for features specified in request.
bool nextFeature(QgsFeature &f)
A vector of attributes.
Definition: qgsattributes.h:57
Represents a vector layer which manages a vector based data sets.
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...