QGIS API Documentation  2.17.0-Master (3a3b9ab7)
qgsrelationmanager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrelationmanager.cpp
3  --------------------------------------
4  Date : 1.3.2013
5  Copyright : (C) 2013 Matthias Kuhn
6  Email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsrelationmanager.h"
17 
18 #include "qgsapplication.h"
19 #include "qgslogger.h"
20 #include "qgsmaplayerregistry.h"
21 #include "qgsproject.h"
22 #include "qgsvectorlayer.h"
23 
25  : QObject( project )
26  , mProject( project )
27 {
28  connect( project, SIGNAL( readProject( const QDomDocument& ) ), SLOT( readProject( const QDomDocument& ) ) );
29  connect( project, SIGNAL( writeProject( QDomDocument& ) ), SLOT( writeProject( QDomDocument& ) ) );
30  connect( QgsMapLayerRegistry::instance(), SIGNAL( layersRemoved( QStringList ) ), this, SLOT( layersRemoved( QStringList ) ) );
31 }
32 
34 {
35  mRelations.clear();
36  Q_FOREACH ( const QgsRelation& rel, relations )
37  {
38  addRelation( rel );
39  }
40  emit changed();
41 }
42 
44 {
45  return mRelations;
46 }
47 
49 {
50  if ( !relation.isValid() )
51  return;
52 
53  mRelations.insert( relation.id(), relation );
54 
55  if ( mProject )
56  mProject->setDirty( true );
57  emit changed();
58 }
59 
61 {
62  mRelations.remove( id );
63  emit changed();
64 }
65 
67 {
68  mRelations.remove( relation.id() );
69  emit changed();
70 }
71 
73 {
74  return mRelations.value( id );
75 }
76 
78 {
80 
81  Q_FOREACH ( const QgsRelation& rel, mRelations )
82  {
83  if ( QString::compare( rel.name(), name, Qt::CaseInsensitive ) == 0 )
84  relations << rel;
85  }
86 
87  return relations;
88 }
89 
91 {
92  mRelations.clear();
93  emit changed();
94 }
95 
97 {
98  if ( !layer )
99  {
100  return mRelations.values();
101  }
102 
104 
105  Q_FOREACH ( const QgsRelation& rel, mRelations )
106  {
107  if ( rel.referencingLayer() == layer )
108  {
109  if ( fieldIdx != -2 )
110  {
111  bool containsField = false;
112  Q_FOREACH ( const QgsRelation::FieldPair& fp, rel.fieldPairs() )
113  {
114  if ( fieldIdx == layer->fieldNameIndex( fp.referencingField() ) )
115  {
116  containsField = true;
117  break;
118  }
119  }
120 
121  if ( !containsField )
122  {
123  continue;
124  }
125  }
126  relations.append( rel );
127  }
128  }
129 
130  return relations;
131 }
132 
134 {
135  if ( !layer )
136  {
137  return mRelations.values();
138  }
139 
141 
142  Q_FOREACH ( const QgsRelation& rel, mRelations )
143  {
144  if ( rel.referencedLayer() == layer )
145  {
146  relations.append( rel );
147  }
148  }
149 
150  return relations;
151 }
152 
153 void QgsRelationManager::readProject( const QDomDocument & doc )
154 {
155  mRelations.clear();
156 
157  QDomNodeList nodes = doc.elementsByTagName( "relations" );
158  if ( nodes.count() )
159  {
160  QDomNode node = nodes.item( 0 );
161  QDomNodeList relationNodes = node.childNodes();
162  int relCount = relationNodes.count();
163  for ( int i = 0; i < relCount; ++i )
164  {
165  addRelation( QgsRelation::createFromXML( relationNodes.at( i ) ) );
166  }
167  }
168  else
169  {
170  QgsDebugMsg( "No relations data present in this document" );
171  }
172 
173  emit relationsLoaded();
174  emit changed();
175 }
176 
177 void QgsRelationManager::writeProject( QDomDocument & doc )
178 {
179  QDomNodeList nl = doc.elementsByTagName( "qgis" );
180  if ( !nl.count() )
181  {
182  QgsDebugMsg( "Unable to find qgis element in project file" );
183  return;
184  }
185  QDomNode qgisNode = nl.item( 0 ); // there should only be one
186 
187  QDomElement relationsNode = doc.createElement( "relations" );
188  qgisNode.appendChild( relationsNode );
189 
190  Q_FOREACH ( const QgsRelation& relation, mRelations )
191  {
192  relation.writeXML( relationsNode, doc );
193  }
194 }
195 
196 void QgsRelationManager::layersRemoved( const QStringList& layers )
197 {
198  bool relationsChanged = false;
199  Q_FOREACH ( const QString& layer, layers )
200  {
201  QMapIterator<QString, QgsRelation> it( mRelations );
202 
203  while ( it.hasNext() )
204  {
205  it.next();
206 
207  if ( it.value().referencedLayerId() == layer
208  || it.value().referencingLayerId() == layer )
209  {
210  mRelations.remove( it.key() );
211  relationsChanged = true;
212  }
213  }
214  }
215  if ( relationsChanged )
216  {
217  emit changed();
218  }
219 }
void setDirty(bool b=true)
Flag the project as dirty (modified).
Definition: qgsproject.cpp:410
bool isValid() const
Returns the validity of this relation.
QDomNode item(int index) const
QList< T > values() const
QDomNode appendChild(const QDomNode &newChild)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QList< QgsRelation > relationsByName(const QString &name) const
Returns a list of relations with matching names.
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
static QgsRelation createFromXML(const QDomNode &node)
Creates a relation from an XML structure.
Definition: qgsrelation.cpp:30
QString name() const
Returns a human readable name for this relation.
void clear()
QString id() const
A (project-wide) unique id for this relation.
QDomNodeList childNodes() const
void writeXML(QDomNode &node, QDomDocument &doc) const
Writes a relation to an XML structure.
Definition: qgsrelation.cpp:92
void clear()
Remove any relation managed by this class.
void setRelations(const QList< QgsRelation > &relations)
Will set the specified relations and remove any relation currently set.
const char * name() const
int count() const
void append(const T &value)
const QMap< QString, QgsRelation > & relations() const
Get access to the relations managed by this class.
Defines a relation between matching fields of the two involved tables of a relation.
Definition: qgsrelation.h:42
QgsRelation relation(const QString &id) const
Get access to a relation by its id.
QString referencingField() const
Get the name of the referencing (child) field.
Definition: qgsrelation.h:54
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
QDomNodeList elementsByTagName(const QString &tagname) const
Reads and writes project states.
Definition: qgsproject.h:71
const Key & key() const
const T & value() const
void relationsLoaded()
This signal is emitted when the relations were loaded after reading a project.
QList< QgsRelation > referencedRelations(QgsVectorLayer *layer=nullptr) const
Get all relations where this layer is the referenced part (i.e.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
void changed()
Emitted when relations are added or removed to the manager.
QList< FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
iterator insert(const Key &key, const T &value)
void removeRelation(const QString &id)
Remove a relation.
QDomElement createElement(const QString &tagName)
QgsRelationManager(QgsProject *project=nullptr)
Constructor for QgsRelationManager.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
int compare(const QString &other) const
bool hasNext() const
QList< QgsRelation > referencingRelations(QgsVectorLayer *layer=nullptr, int fieldIdx=-2) const
Get all relations where the specified layer (and field) is the referencing part (i.e.
QDomNode at(int index) const
const T value(const Key &key) const
int remove(const Key &key)
void addRelation(const QgsRelation &relation)
Add a relation.