27 : d( new QgsPolymorphicRelationPrivate() )
32 : d( new QgsPolymorphicRelationPrivate() )
41 , mContext( other.mContext )
48 mContext = other.mContext;
55 QDomElement elem = node.toElement();
57 if ( elem.tagName() != QLatin1String(
"relation" ) )
59 QgsLogger::warning( QApplication::translate(
"QgsPolymorphicRelation",
"Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) );
67 QString
id = elem.attribute( QStringLiteral(
"id" ) );
68 QString
name = elem.attribute( QStringLiteral(
"name" ) );
69 QString relationStrength = elem.attribute( QStringLiteral(
"relationStrength" ) );
70 QStringList
referencedLayerIds = elem.attribute( QStringLiteral(
"referencedLayerIds" ) ).split(
"," );
72 QMap<QString, QgsMapLayer *> mapLayers = relationContext.
project()->
mapLayers();
75 relation.d->mReferencingLayer = qobject_cast<QgsVectorLayer *>( mapLayers[
referencingLayerId] );
79 relation.d->mRelationId =
id;
80 relation.d->mRelationName =
name;
81 relation.d->mRelationStrength = qgsEnumKeyToValue<QgsRelation::RelationStrength>( relationStrength, QgsRelation::RelationStrength::Association );
83 QDomNodeList references = elem.elementsByTagName( QStringLiteral(
"fieldRef" ) );
84 for (
int i = 0; i < references.size(); ++i )
86 QDomElement refEl = references.at( i ).toElement();
88 QString referencingField = refEl.attribute( QStringLiteral(
"referencingField" ) );
89 QString referencedField = refEl.attribute( QStringLiteral(
"referencedField" ) );
91 relation.
addFieldPair( referencingField, referencedField );
101 QDomElement elem = doc.createElement( QStringLiteral(
"relation" ) );
102 elem.setAttribute( QStringLiteral(
"id" ), d->mRelationId );
103 elem.setAttribute( QStringLiteral(
"name" ), d->mRelationName );
104 elem.setAttribute( QStringLiteral(
"referencingLayer" ), d->mReferencingLayerId );
105 elem.setAttribute( QStringLiteral(
"referencedLayerField" ), d->mReferencedLayerField );
106 elem.setAttribute( QStringLiteral(
"referencedLayerExpression" ), d->mReferencedLayerExpression );
107 elem.setAttribute( QStringLiteral(
"referencedLayerIds" ), d->mReferencedLayerIds.join(
"," ) );
108 elem.setAttribute( QStringLiteral(
"relationStrength" ), qgsEnumValueToKey<QgsRelation::RelationStrength>( d->mRelationStrength ) );
111 for (
const QString &layerId : std::as_const( d->mReferencedLayerIds ) )
112 Q_ASSERT( ! layerId.contains(
"," ) );
116 QDomElement referenceElem = doc.createElement( QStringLiteral(
"fieldRef" ) );
117 referenceElem.setAttribute( QStringLiteral(
"referencingField" ), pair.first );
118 referenceElem.setAttribute( QStringLiteral(
"referencedField" ), pair.second );
119 elem.appendChild( referenceElem );
122 node.appendChild( elem );
127 if ( d->mRelationId ==
id )
139 d->mReferencingLayerId =
id;
154 d->mFieldPairs << fieldPair;
160 return d->mRelationId;
165 d->mRelationId = QStringLiteral(
"%1_%2_%3_%4" )
167 d->mFieldPairs.at( 0 ).referencingField(),
169 d->mFieldPairs.at( 0 ).referencedField() );
175 return d->mReferencingLayerId;
180 return d->mReferencingLayer;
185 return d->mFieldPairs;
192 if ( d->mReferencedLayerIds.contains( layerId ) )
214 attrs << d->mReferencingLayer->fields().lookupField( pair.first );
222 return d->mValid && !d->mReferencingLayer.isNull() && !d->mReferencedLayerField.isNull() && d->mReferencingLayer.data()->isValid() && !d->mReferencedLayerExpression.isNull();
227 return d->mReferencedLayerField == other.d->mReferencedLayerField
228 && d->mReferencedLayerExpression == other.d->mReferencedLayerExpression
229 && d->mReferencingLayerId == other.d->mReferencingLayerId
230 && d->mFieldPairs == other.d->mFieldPairs;
235 const QMap<QString, QgsMapLayer *> &mapLayers = mContext.
project()->
mapLayers();
238 d->mReferencingLayer = mapLayers.contains( d->mReferencingLayerId )
239 ? qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencingLayerId] )
241 d->mReferencedLayersMap.clear();
243 if ( d->mRelationId.isEmpty() )
245 QgsDebugMsg( QStringLiteral(
"Invalid relation: no ID" ) );
250 if ( !d->mReferencingLayer )
252 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referencing layer does not exist. ID: %1" ).arg( d->mReferencingLayerId ), 4 );
257 if ( d->mReferencingLayer->fields().lookupField( d->mReferencedLayerField ) == -1 )
259 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referenced layer field \"%1\" does not exist in layer with ID: %2" ).arg( d->mReferencedLayerField, d->mReferencingLayerId ), 4 );
264 if ( d->mReferencedLayerExpression.trimmed().isNull() )
266 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referenced layer expression \"%1\" is missing" ).arg( d->mReferencedLayerExpression ), 4 );
274 d->mReferencedLayersMap.insert( referencedLayerId, qobject_cast<QgsVectorLayer *>( mapLayers[referencedLayerId] ) );
276 if ( !d->mReferencedLayersMap[referencedLayerId] || !d->mReferencedLayersMap[referencedLayerId]->isValid() )
278 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referenced layer does not exist. ID: %1" ).arg( d->mReferencedLayersMap[referencedLayerId]->id() ), 4 );
284 if ( d->mFieldPairs.count() == 0 )
286 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: no pair of field is specified." ), 4 );
293 if ( d->mReferencingLayer->fields().lookupField( pair.first ) == -1 )
295 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referencing layer %2" ).arg( pair.first, d->mReferencingLayer->name() ) );
302 if ( d->mReferencedLayersMap[referencedLayerId]->fields().lookupField( pair.second ) == -1 )
304 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referenced layer %2" ).arg( pair.second, d->mReferencedLayersMap[referencedLayerId]->name() ) );
314 if ( d->mRelationName ==
name && !
name.isEmpty() )
318 d->mRelationName =
name;
324 if ( d->mRelationName.isEmpty() )
325 return QObject::tr(
"Polymorphic relations for \"%1\"" ).arg( d->mReferencingLayer ? d->mReferencingLayer->name() : QStringLiteral(
"<NO LAYER>" ) );
327 return d->mRelationName;
339 return d->mReferencedLayerField;
351 return d->mReferencedLayerExpression;
363 return d->mReferencedLayerIds;
368 return d->mRelationStrength;
374 d->mRelationStrength = relationStrength;
380 QList<QgsRelation> relations;
390 QString referencedLayerName = d->mReferencedLayersMap[referencedLayerId]->name();
392 relation.
setId( QStringLiteral(
"%1_%2" ).arg( d->mRelationId, referencedLayerName ) );
395 relation.
setName( QStringLiteral(
"Generated for \"%1\"" ).arg( referencedLayerName ) );
399 const QList<QgsRelation::FieldPair> constFieldPairs =
fieldPairs();
406 relations << relation;
414 if ( !layer || !layer->
isValid() )
420 return expr.
evaluate( &context ).toString();