QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsweakrelation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsweakrelation.cpp - QgsWeakRelation
3 
4  ---------------------
5  begin : 5.12.2019
6  copyright : (C) 2019 by Alessandro Pasotti
7  email : elpaso at itopen dot it
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  ***************************************************************************/
16 
17 #include <QApplication>
18 #include "qgsweakrelation.h"
19 #include "qgslogger.h"
20 
21 
22 QgsWeakRelation::QgsWeakRelation( const QString &relationId, const QString &relationName, const QgsRelation::RelationStrength strength,
23  const QString &referencingLayerId, const QString &referencingLayerName, const QString &referencingLayerSource, const QString &referencingLayerProviderKey,
24  const QString &referencedLayerId, const QString &referencedLayerName, const QString &referencedLayerSource, const QString &referencedLayerProviderKey,
25  const QList<QgsRelation::FieldPair> &fieldPairs )
26  : mReferencingLayer( referencingLayerId, referencingLayerName, referencingLayerSource, referencingLayerProviderKey )
27  , mReferencedLayer( referencedLayerId, referencedLayerName, referencedLayerSource, referencedLayerProviderKey )
28  , mRelationId( relationId )
29  , mRelationName( relationName )
30  , mStrength( strength )
31  , mFieldPairs( fieldPairs )
32 {
33 }
34 
36 {
37  QgsRelation relation;
38  relation.setId( mRelationId );
39  relation.setName( mRelationName );
40  relation.setStrength( mStrength );
41  QgsVectorLayerRef referencedLayerRef { mReferencedLayer };
42  QgsMapLayer *referencedLayer { referencedLayerRef.resolveWeakly( project, matchType ) };
43  if ( referencedLayer )
44  {
45  relation.setReferencedLayer( referencedLayer->id() );
46  }
47  QgsVectorLayerRef referencingLayerRef { mReferencingLayer };
48  QgsMapLayer *referencingLayer { referencingLayerRef.resolveWeakly( project, matchType ) };
49  if ( referencingLayer )
50  {
52  }
53  for ( const auto &fp : qgis::as_const( mFieldPairs ) )
54  {
55  relation.addFieldPair( fp );
56  }
57  return relation;
58 }
59 
61 {
62  return mReferencingLayer;
63 }
64 
66 {
67  return mReferencedLayer;
68 }
69 
71 {
72  return mStrength;
73 }
74 
75 QList<QgsRelation::FieldPair> QgsWeakRelation::fieldPairs() const
76 {
77  return mFieldPairs;
78 }
79 
80 QgsWeakRelation QgsWeakRelation::readXml( const QgsVectorLayer *layer, WeakRelationType type, const QDomNode &node, const QgsPathResolver resolver )
81 {
82  QDomElement relationElement = node.toElement();
83 
84  if ( relationElement.tagName() != QLatin1String( "relation" ) )
85  {
86  QgsLogger::warning( QApplication::translate( "QgsRelation", "Cannot create relation. Unexpected tag '%1'" ).arg( relationElement.tagName() ) );
87  }
88 
89  QList<QgsRelation::FieldPair> fieldPairs;
90  const QDomNodeList fieldPairNodes { relationElement.elementsByTagName( QStringLiteral( "fieldRef" ) ) };
91  for ( int j = 0; j < fieldPairNodes.length(); ++j )
92  {
93  const QDomElement fieldPairElement = fieldPairNodes.at( j ).toElement();
94  fieldPairs.push_back( { fieldPairElement.attribute( QStringLiteral( "referencingField" ) ),
95  fieldPairElement.attribute( QStringLiteral( "referencedField" ) )
96  } );
97  }
98 
99  switch ( type )
100  {
101  case Referencing:
102  return QgsWeakRelation { relationElement.attribute( QStringLiteral( "id" ) ),
103  relationElement.attribute( QStringLiteral( "name" ) ),
104  static_cast<QgsRelation::RelationStrength>( relationElement.attribute( QStringLiteral( "strength" ) ).toInt() ),
105  // Referencing
106  layer->id(),
107  layer->name(),
108  resolver.writePath( layer->publicSource() ),
109  layer->providerType(),
110  // Referenced
111  relationElement.attribute( QStringLiteral( "layerId" ) ),
112  relationElement.attribute( QStringLiteral( "layerName" ) ),
113  relationElement.attribute( QStringLiteral( "dataSource" ) ),
114  relationElement.attribute( QStringLiteral( "providerKey" ) ),
115  fieldPairs
116  };
117  case Referenced:
118  return QgsWeakRelation { relationElement.attribute( QStringLiteral( "id" ) ),
119  relationElement.attribute( QStringLiteral( "name" ) ),
120  static_cast<QgsRelation::RelationStrength>( relationElement.attribute( QStringLiteral( "strength" ) ).toInt() ),
121  // Referencing
122  relationElement.attribute( QStringLiteral( "layerId" ) ),
123  relationElement.attribute( QStringLiteral( "layerName" ) ),
124  relationElement.attribute( QStringLiteral( "dataSource" ) ),
125  relationElement.attribute( QStringLiteral( "providerKey" ) ),
126  // Referenced
127  layer->id(),
128  layer->name(),
129  resolver.writePath( layer->publicSource() ),
130  layer->providerType(),
131  fieldPairs
132  };
133  }
134  // avoid build warnings
135  return QgsWeakRelation( QString(), QString(), QgsRelation::RelationStrength::Association, QString(), QString(), QString(),
136  QString(), QString(), QString(), QString(), QString(), QList< QgsRelation::FieldPair >() );
137 }
138 
139 void QgsWeakRelation::writeXml( const QgsVectorLayer *layer, WeakRelationType type, const QgsRelation &relation, QDomNode &node, QDomDocument &doc )
140 {
141  if ( !layer )
142  return;
143 
144  if ( layer != relation.referencingLayer() && layer != relation.referencedLayer() )
145  return;
146 
147  const QgsPathResolver resolver { QgsProject::instance()->pathResolver() };
148 
149  relation.writeXml( node, doc );
150  QDomNodeList relationsNodeList = node.toElement().elementsByTagName( QStringLiteral( "relation" ) );
151  QDomElement relationElement;
152 
153  for ( int i = 0; i < relationsNodeList.size(); ++i )
154  {
155  relationElement = relationsNodeList.at( i ).toElement();
156  if ( relationElement.hasAttribute( QStringLiteral( "id" ) ) && relationElement.attribute( QStringLiteral( "id" ) ) == relation.id() )
157  {
158  switch ( type )
159  {
160  case Referencing:
161  // if the layer is the referencing one, we save the referenced layer info
162  relationElement.setAttribute( QStringLiteral( "layerId" ), relation.referencedLayer()->id() );
163  relationElement.setAttribute( QStringLiteral( "layerName" ), relation.referencedLayer()->name() );
164  relationElement.setAttribute( QStringLiteral( "dataSource" ), resolver.writePath( relation.referencedLayer()->publicSource() ) );
165  relationElement.setAttribute( QStringLiteral( "providerKey" ), relation.referencedLayer()->providerType() );
166  break;
167 
168  case Referenced:
169  // if the layer is the referenced one, we save the referencing layer info
170  relationElement.setAttribute( QStringLiteral( "layerId" ), relation.referencingLayer()->id() );
171  relationElement.setAttribute( QStringLiteral( "layerName" ), relation.referencingLayer()->name() );
172  relationElement.setAttribute( QStringLiteral( "dataSource" ), resolver.writePath( relation.referencingLayer()->publicSource() ) );
173  relationElement.setAttribute( QStringLiteral( "providerKey" ), relation.referencingLayer()->providerType() );
174  break;
175  }
176  }
177  }
178 }
QgsWeakRelation::writeXml
static void writeXml(const QgsVectorLayer *layer, WeakRelationType type, const QgsRelation &relation, QDomNode &node, QDomDocument &doc)
Writes a weak relation infoto an XML structure.
Definition: qgsweakrelation.cpp:139
QgsWeakRelation::strength
QgsRelation::RelationStrength strength() const
Returns the strength of the relation.
Definition: qgsweakrelation.cpp:70
_LayerRef::resolveWeakly
TYPE * resolveWeakly(const QgsProject *project, MatchType matchType=MatchType::All)
Resolves the map layer by attempting to find a matching layer in a project using a weak match.
Definition: qgsmaplayerref.h:210
qgsweakrelation.h
QgsProject::pathResolver
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
Definition: qgsproject.cpp:2674
QgsRelation::addFieldPair
void addFieldPair(const QString &referencingField, const QString &referencedField)
Add a field pairs which is part of this relation The first element of each pair are the field names o...
Definition: qgsrelation.cpp:172
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:468
QgsRelation::id
Q_GADGET QString id
Definition: qgsrelation.h:45
QgsWeakRelation::resolvedRelation
QgsRelation resolvedRelation(const QgsProject *project, QgsVectorLayerRef::MatchType matchType=QgsVectorLayerRef::MatchType::All) const
Resolves a weak relation in the given project returning a possibly invalid QgsRelation and without pe...
Definition: qgsweakrelation.cpp:35
QgsWeakRelation::QgsWeakRelation
QgsWeakRelation(const QString &relationId, const QString &relationName, const QgsRelation::RelationStrength strength, const QString &referencingLayerId, const QString &referencingLayerName, const QString &referencingLayerSource, const QString &referencingLayerProviderKey, const QString &referencedLayerId, const QString &referencedLayerName, const QString &referencedLayerSource, const QString &referencedLayerProviderKey, const QList< QgsRelation::FieldPair > &fieldPairs)
Creates a QgsWeakRelation.
Definition: qgsweakrelation.cpp:22
QgsRelation::setStrength
void setStrength(RelationStrength strength)
Set a strength for this relation.
Definition: qgsrelation.cpp:150
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:95
QgsMapLayer::providerType
QString providerType() const
Returns the provider type (provider key) for this layer.
Definition: qgsmaplayer.cpp:1617
QgsRelation::setReferencingLayer
void setReferencingLayer(const QString &id)
Set the referencing (child) layer id.
Definition: qgsrelation.cpp:156
QgsRelation::referencingLayer
QgsVectorLayer * referencingLayer
Definition: qgsrelation.h:46
QgsPathResolver::writePath
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
Definition: qgspathresolver.cpp:192
QgsRelation::setName
void setName(const QString &name)
Set a name for this relation.
Definition: qgsrelation.cpp:143
QgsWeakRelation::WeakRelationType
WeakRelationType
Enum to distinguish if the layer is referenced or referencing.
Definition: qgsweakrelation.h:47
QgsRelation::referencedLayer
QgsVectorLayer * referencedLayer
Definition: qgsrelation.h:47
QgsRelation::setId
void setId(const QString &id)
Set an id for this relation.
Definition: qgsrelation.cpp:135
QgsWeakRelation::fieldPairs
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the list of field pairs.
Definition: qgsweakrelation.cpp:75
QgsLogger::warning
static void warning(const QString &msg)
Goes to qWarning.
Definition: qgslogger.cpp:122
QgsMapLayer::id
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Definition: qgsmaplayer.cpp:148
QgsWeakRelation::referencingLayer
QgsVectorLayerRef referencingLayer() const
Returns a weak reference to the referencing layer.
Definition: qgsweakrelation.cpp:60
_LayerRef< QgsVectorLayer >::MatchType
MatchType
Flag for match type in weak resolution.
Definition: qgsmaplayerref.h:41
QgsWeakRelation::referencedLayer
QgsVectorLayerRef referencedLayer() const
Returns a weak reference to the referenced layer.
Definition: qgsweakrelation.cpp:65
QgsMapLayer::publicSource
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
Definition: qgsmaplayer.cpp:184
QgsWeakRelation::Referencing
@ Referencing
The layer is referencing.
Definition: qgsweakrelation.h:48
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
QgsRelation::setReferencedLayer
void setReferencedLayer(const QString &id)
Set the referenced (parent) layer id.
Definition: qgsrelation.cpp:164
QgsWeakRelation::readXml
static QgsWeakRelation readXml(const QgsVectorLayer *layer, WeakRelationType type, const QDomNode &node, const QgsPathResolver resolver)
Returns a weak relation for the given layer.
Definition: qgsweakrelation.cpp:80
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:86
QgsRelation
Definition: qgsrelation.h:42
QgsWeakRelation::Referenced
@ Referenced
The layer is referenced.
Definition: qgsweakrelation.h:49
QgsRelation::RelationStrength
RelationStrength
enum for the relation strength Association, Composition
Definition: qgsrelation.h:58
_LayerRef< QgsVectorLayer >
qgslogger.h
QgsRelation::writeXml
void writeXml(QDomNode &node, QDomDocument &doc) const
Writes a relation to an XML structure.
Definition: qgsrelation.cpp:115
QgsWeakRelation
The QgsWeakRelation class represent a QgsRelation with possibly unresolved layers or unmatched fields...
Definition: qgsweakrelation.h:39
QgsPathResolver
Resolves relative paths into absolute paths and vice versa.
Definition: qgspathresolver.h:32