28   : d( new QgsRelationPrivate() )
 
   33   : d( new QgsRelationPrivate() )
 
   42   , mContext( other.mContext )
 
   49   mContext = other.mContext;
 
   55   QDomElement elem = node.toElement();
 
   57   if ( elem.tagName() != QLatin1String( 
"relation" ) )
 
   59     QgsLogger::warning( QApplication::translate( 
"QgsRelation", 
"Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) );
 
   65   QString 
referencedLayerId = elem.attribute( QStringLiteral( 
"referencedLayer" ) );
 
   66   QString 
id = elem.attribute( QStringLiteral( 
"id" ) );
 
   68   QString 
strength = elem.attribute( QStringLiteral( 
"strength" ) );
 
   70   QMap<QString, QgsMapLayer *> mapLayers = relationContext.
project()->
mapLayers();
 
   94   relation.d->mReferencingLayer = qobject_cast<QgsVectorLayer *>( 
referencingLayer );
 
   96   relation.d->mReferencedLayer = qobject_cast<QgsVectorLayer *>( 
referencedLayer );
 
   97   relation.d->mRelationId = 
id;
 
   98   relation.d->mRelationName = 
name;
 
   99   relation.d->mRelationStrength = qgsEnumKeyToValue<QgsRelation::RelationStrength>( 
strength, RelationStrength::Association );
 
  101   QDomNodeList references = elem.elementsByTagName( QStringLiteral( 
"fieldRef" ) );
 
  102   for ( 
int i = 0; i < references.size(); ++i )
 
  104     QDomElement refEl = references.at( i ).toElement();
 
  106     QString referencingField = refEl.attribute( QStringLiteral( 
"referencingField" ) );
 
  107     QString referencedField = refEl.attribute( QStringLiteral( 
"referencedField" ) );
 
  109     relation.
addFieldPair( referencingField, referencedField );
 
  119   QDomElement elem = doc.createElement( QStringLiteral( 
"relation" ) );
 
  120   elem.setAttribute( QStringLiteral( 
"id" ), d->mRelationId );
 
  121   elem.setAttribute( QStringLiteral( 
"name" ), d->mRelationName );
 
  122   elem.setAttribute( QStringLiteral( 
"referencingLayer" ), d->mReferencingLayerId );
 
  123   elem.setAttribute( QStringLiteral( 
"referencedLayer" ), d->mReferencedLayerId );
 
  124   elem.setAttribute( QStringLiteral( 
"strength" ), qgsEnumValueToKey<RelationStrength>( d->mRelationStrength ) );
 
  126   for ( 
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
 
  128     QDomElement referenceElem = doc.createElement( QStringLiteral( 
"fieldRef" ) );
 
  129     referenceElem.setAttribute( QStringLiteral( 
"referencingField" ), pair.first );
 
  130     referenceElem.setAttribute( QStringLiteral( 
"referencedField" ), pair.second );
 
  131     elem.appendChild( referenceElem );
 
  134   node.appendChild( elem );
 
  148   d->mRelationName = 
name;
 
  161   d->mReferencingLayerId = 
id;
 
  169   d->mReferencedLayerId = 
id;
 
  177   d->mFieldPairs << 
FieldPair( referencingField, referencedField );
 
  184   d->mFieldPairs << fieldPair;
 
  196   QgsDebugMsgLevel( QStringLiteral( 
"Filter conditions: '%1'" ).arg( filter ), 2 );
 
  205   QStringList conditions;
 
  207   if ( ! d->mPolymorphicRelationId.isEmpty() )
 
  216       QgsDebugMsg( 
"The polymorphic relation is invalid" );
 
  217       conditions << QStringLiteral( 
" FALSE " );
 
  221   for ( 
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
 
  223     QVariant val( feature.
attribute( pair.referencedField() ) );
 
  225     if ( referencingIdx >= 0 )
 
  236   return conditions.join( QLatin1String( 
" AND " ) );
 
  241   QStringList conditions;
 
  243   for ( 
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
 
  247     if ( referencedIdx >= 0 )
 
  260   QgsDebugMsgLevel( QStringLiteral( 
"Filter conditions: '%1'" ).arg( conditions.join( 
" AND " ) ), 2 );
 
  277   d->mReferencedLayer->getFeatures( request ).nextFeature( f );
 
  283   return d->mRelationName;
 
  288   return d->mRelationStrength;
 
  293   return d->mRelationId;
 
  298   if ( !d->mFieldPairs.isEmpty() )
 
  301     d->mRelationId = QStringLiteral( 
"%1_%2_%3_%4" )
 
  312   return d->mReferencingLayerId;
 
  317   return d->mReferencingLayer;
 
  322   return d->mReferencedLayerId;
 
  327   return d->mReferencedLayer;
 
  332   return d->mFieldPairs;
 
  338   attrs.reserve( d->mFieldPairs.size() );
 
  339   for ( 
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
 
  341     attrs << d->mReferencedLayer->fields().lookupField( pair.second );
 
  350   for ( 
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
 
  352     attrs << d->mReferencingLayer->fields().lookupField( pair.first );
 
  360   return d->mValid && !d->mReferencingLayer.isNull() && !d->mReferencedLayer.isNull() && d->mReferencingLayer.data()->isValid() && d->mReferencedLayer.data()->isValid();
 
  365   return d->mReferencedLayerId == other.d->mReferencedLayerId && d->mReferencingLayerId == other.d->mReferencingLayerId && d->mFieldPairs == other.d->mFieldPairs;
 
  370   for ( 
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
 
  372     if ( pair.first == referencingField )
 
  380   for ( 
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
 
  382     if ( pair.second == referencedField )
 
  390   const QMap<QString, QgsMapLayer *> &mapLayers = mContext.
project()->
mapLayers();
 
  392   d->mReferencingLayer = qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencingLayerId] );
 
  393   d->mReferencedLayer = qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencedLayerId] );
 
  397   if ( d->mRelationId.isEmpty() )
 
  399     QgsDebugMsg( QStringLiteral( 
"Invalid relation: no ID" ) );
 
  404     if ( !d->mReferencedLayer )
 
  406       QgsDebugMsgLevel( QStringLiteral( 
"Invalid relation: referenced layer does not exist. ID: %1" ).arg( d->mReferencedLayerId ), 4 );
 
  409     else if ( !d->mReferencingLayer )
 
  411       QgsDebugMsgLevel( QStringLiteral( 
"Invalid relation: referencing layer does not exist. ID: %2" ).arg( d->mReferencingLayerId ), 4 );
 
  416       if ( d->mFieldPairs.count() < 1 )
 
  418         QgsDebugMsgLevel( QStringLiteral( 
"Invalid relation: no pair of field is specified." ), 4 );
 
  422       for ( 
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
 
  424         if ( -1 == d->mReferencingLayer->fields().lookupField( pair.first ) )
 
  426           QgsDebugMsg( QStringLiteral( 
"Invalid relation: field %1 does not exist in referencing layer %2" ).arg( pair.first, d->mReferencingLayer->name() ) );
 
  430         else if ( -1 == d->mReferencedLayer->fields().lookupField( pair.second ) )
 
  432           QgsDebugMsg( QStringLiteral( 
"Invalid relation: field %1 does not exist in referenced layer %2" ).arg( pair.second, d->mReferencedLayer->name() ) );
 
  450   return d->mPolymorphicRelationId;
 
  463   if ( d->mPolymorphicRelationId.isNull() )