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() )