25#include "moc_qgsrelationmanager.cpp"
27using namespace Qt::StringLiterals;
73 mProject->setDirty(
true );
81 for (
auto relationIt = mRelations.begin(); relationIt != mRelations.end(); ++relationIt )
83 relationIt->updateRelationStatus();
90 mRelations.remove(
id );
102 if ( !mRelations.contains(
id ) )
106 const QList<QString> keys = mPolymorphicRelations.keys();
107 for (
const QString &key : keys )
109 if (
id.startsWith( key ) )
111 return mRelations.value( mPolymorphicRelations[key].upgradeGeneratedRelationId(
id ) );
116 return mRelations.value(
id );
123 for (
const QgsRelation &rel : std::as_const( mRelations ) )
125 if ( QString::compare( rel.name(), name, Qt::CaseInsensitive ) == 0 )
142 return mRelations.values();
147 for (
const QgsRelation &rel : std::as_const( mRelations ) )
149 if ( rel.referencingLayer() == layer )
151 if ( fieldIdx != -2 )
153 bool containsField =
false;
154 const auto constFieldPairs = rel.fieldPairs();
159 containsField =
true;
164 if ( !containsField )
180 return mRelations.values();
185 for (
const QgsRelation &rel : std::as_const( mRelations ) )
187 if ( rel.referencedLayer() == layer )
196void QgsRelationManager::readProject(
const QDomDocument &doc,
QgsReadWriteContext &context )
199 mPolymorphicRelations.clear();
201 QDomNodeList relationNodes = doc.elementsByTagName( u
"relations"_s );
202 if ( relationNodes.count() )
206 QDomNode node = relationNodes.item( 0 );
207 QDomNodeList relationNodes = node.childNodes();
208 int relCount = relationNodes.count();
209 for (
int i = 0; i < relCount; ++i )
219 QDomNodeList polymorphicRelationNodes = doc.elementsByTagName( u
"polymorphicRelations"_s );
220 if ( polymorphicRelationNodes.count() )
222 QgsRelationContext relcontext( mProject );
224 QDomNode node = polymorphicRelationNodes.item( 0 );
225 QDomNodeList relationNodes = node.childNodes();
226 int relCount = relationNodes.count();
227 for (
int i = 0; i < relCount; ++i )
234 QgsDebugMsgLevel( u
"No polymorphic relations data present in this document"_s, 3 );
241void QgsRelationManager::writeProject( QDomDocument &doc )
243 QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
246 QgsDebugError( u
"Unable to find qgis element in project file"_s );
249 QDomNode qgisNode = nl.item( 0 );
251 QDomElement relationsNode = doc.createElement( u
"relations"_s );
252 qgisNode.appendChild( relationsNode );
254 for (
const QgsRelation &
relation : std::as_const( mRelations ) )
266 relation.writeXml( relationsNode, doc );
269 QDomElement polymorphicRelationsNode = doc.createElement( u
"polymorphicRelations"_s );
270 qgisNode.appendChild( polymorphicRelationsNode );
272 for (
const QgsPolymorphicRelation &
relation : std::as_const( mPolymorphicRelations ) )
274 relation.writeXml( polymorphicRelationsNode, doc );
278void QgsRelationManager::layersRemoved(
const QStringList &layers )
280 bool relationsChanged =
false;
281 for (
const QString &layer : std::as_const( layers ) )
283 QMapIterator<QString, QgsRelation> it( mRelations );
285 while ( it.hasNext() )
289 if ( it.value().referencedLayerId() == layer
290 || it.value().referencingLayerId() == layer )
292 mRelations.remove( it.key() );
293 relationsChanged =
true;
297 if ( relationsChanged )
303static bool hasRelationWithEqualDefinition(
const QList<QgsRelation> &existingRelations,
const QgsRelation &relation )
305 for (
const QgsRelation &cur : std::as_const( existingRelations ) )
307 if ( cur.hasEqualDefinition( relation ) )
return true;
314 QList<QgsRelation> result;
319 const auto constDiscoverRelations = provider->discoverRelations( layer, layers );
322 if ( !hasRelationWithEqualDefinition( existingRelations,
relation ) )
334 return mPolymorphicRelations;
339 return mPolymorphicRelations.value( polymorphicRelationId );
350 for (
const QgsRelation &generatedRelation : generatedRelations )
358 const QList<QgsRelation> generatedRelations =
relation.generateRelations();
359 for (
const QgsRelation &generatedRelation : generatedRelations )
@ Generated
A generated relation is a child of a polymorphic relation.
@ Normal
A normal relation.
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A relation where the referenced (parent) layer is calculated based on fields from the referencing (ch...
static QgsPolymorphicRelation createFromXml(const QDomNode &node, QgsReadWriteContext &context, const QgsRelationContext &relationContext=QgsRelationContext())
Creates a relation from an XML structure.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the registry.
void readProjectWithContext(const QDomDocument &document, QgsReadWriteContext &context)
Emitted when a project is being read.
void writeProject(QDomDocument &document)
Emitted when the project is being written.
A container for the context for various read/write operations on objects.
QList< QgsRelation > referencedRelations(const QgsVectorLayer *layer=nullptr) const
Gets all relations where this layer is the referenced part (i.e.
static QList< QgsRelation > discoverRelations(const QList< QgsRelation > &existingRelations, const QList< QgsVectorLayer * > &layers)
Discover all the relations available from the current layers.
QList< QgsRelation > relationsByName(const QString &name) const
Returns a list of relations with matching names.
void addPolymorphicRelation(const QgsPolymorphicRelation &polymorphicRelation)
Adds a new polymorphic relation.
QgsPolymorphicRelation polymorphicRelation(const QString &polymorphicRelationId) const
Returns the list of relations associated with a polymorphic relation.
void setPolymorphicRelations(const QList< QgsPolymorphicRelation > &relations)
Sets the specified polymorphic relations and removes any polymorphic relations currently set.
QMap< QString, QgsPolymorphicRelation > polymorphicRelations() const
Returns all the polymorphic relations.
QgsRelationManager(QgsProject *project=nullptr)
Constructor for QgsRelationManager.
QList< QgsRelation > referencingRelations(const QgsVectorLayer *layer=nullptr, int fieldIdx=-2) const
Gets all relations where the specified layer (and field) is the referencing part (i....
void clear()
Remove any relation managed by this class.
void changed()
Emitted when relations are added or removed to the manager.
QgsRelationContext context() const
Gets the relation context.
void updateRelationsStatus()
Updates relations status.
Q_INVOKABLE void removeRelation(const QString &id)
Remove a relation.
void setRelations(const QList< QgsRelation > &relations)
Will set the specified relations and remove any relation currently set.
void removePolymorphicRelation(const QString &polymorphicRelationId)
Removes an existing polymorphic relation and it's generated relations.
Q_INVOKABLE void addRelation(const QgsRelation &relation)
Add a relation.
QMap< QString, QgsRelation > relations() const
Gets access to the relations managed by this class.
void relationsLoaded()
Emitted when the relations were loaded after reading a project.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Defines a relation between matching fields of the two involved tables of a relation.
Represents a relationship between two vector layers.
static QgsRelation createFromXml(const QDomNode &node, QgsReadWriteContext &context, const QgsRelationContext &relationContext=QgsRelationContext())
Creates a relation from an XML structure.
Base class for vector data providers.
Represents a vector layer which manages a vector based dataset.
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)