QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 dot kuhn at gmx 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 
33 void QgsRelationManager::setRelations( const QList<QgsRelation>& relations )
34 {
35  mRelations.clear();
36  foreach ( const QgsRelation& rel, relations )
37  {
38  addRelation( rel );
39  }
40  emit changed();
41 }
42 
43 const QMap<QString, QgsRelation>& QgsRelationManager::relations() const
44 {
45  return mRelations;
46 }
47 
49 {
50  if ( !relation.isValid() )
51  return;
52 
53  mRelations.insert( relation.id(), relation );
54 
55  mProject->dirty( true );
56  emit changed();
57 }
58 
59 void QgsRelationManager::removeRelation( const QString& id )
60 {
61  mRelations.remove( id );
62  emit changed();
63 }
64 
66 {
67  mRelations.remove( relation.id() );
68  emit changed();
69 }
70 
71 QgsRelation QgsRelationManager::relation( const QString& id ) const
72 {
73  return mRelations.value( id );
74 }
75 
77 {
78  mRelations.clear();
79  emit changed();
80 }
81 
82 QList<QgsRelation> QgsRelationManager::referencingRelations( QgsVectorLayer* layer, int fieldIdx ) const
83 {
84  if ( !layer )
85  {
86  return mRelations.values();
87  }
88 
89  QList<QgsRelation> relations;
90 
91  foreach ( const QgsRelation& rel, mRelations )
92  {
93  if ( rel.referencingLayer() == layer )
94  {
95  if ( fieldIdx != -2 )
96  {
97  bool containsField = false;
98  foreach ( const QgsRelation::FieldPair& fp, rel.fieldPairs() )
99  {
100  if ( fieldIdx == layer->fieldNameIndex( fp.referencingField() ) )
101  {
102  containsField = true;
103  break;
104  }
105  }
106 
107  if ( !containsField )
108  {
109  continue;
110  }
111  }
112  relations.append( rel );
113  }
114  }
115 
116  return relations;
117 }
118 
119 QList<QgsRelation> QgsRelationManager::referencedRelations( QgsVectorLayer* layer ) const
120 {
121  if ( !layer )
122  {
123  return mRelations.values();
124  }
125 
126  QList<QgsRelation> relations;
127 
128  foreach ( const QgsRelation& rel, mRelations )
129  {
130  if ( rel.referencedLayer() == layer )
131  {
132  relations.append( rel );
133  }
134  }
135 
136  return relations;
137 }
138 
139 void QgsRelationManager::readProject( const QDomDocument & doc )
140 {
141  mRelations.clear();
142 
143  QDomNodeList nodes = doc.elementsByTagName( "relations" );
144  if ( nodes.count() )
145  {
146  QDomNode node = nodes.item( 0 );
147  QDomNodeList relationNodes = node.childNodes();
148  int relCount = relationNodes.count();
149  for ( int i = 0; i < relCount; ++i )
150  {
151  addRelation( QgsRelation::createFromXML( relationNodes.at( i ) ) );
152  }
153  }
154  else
155  {
156  QgsDebugMsg( "No relations data present in this document" );
157  }
158 
159  emit( relationsLoaded() );
160  emit changed();
161 }
162 
163 void QgsRelationManager::writeProject( QDomDocument & doc )
164 {
165  QDomNodeList nl = doc.elementsByTagName( "qgis" );
166  if ( !nl.count() )
167  {
168  QgsDebugMsg( "Unable to find qgis element in project file" );
169  return;
170  }
171  QDomNode qgisNode = nl.item( 0 ); // there should only be one
172 
173  QDomElement relationsNode = doc.createElement( "relations" );
174  qgisNode.appendChild( relationsNode );
175 
176  foreach ( const QgsRelation& relation, mRelations )
177  {
178  relation.writeXML( relationsNode, doc );
179  }
180 }
181 
182 void QgsRelationManager::layersRemoved( const QStringList& layers )
183 {
184  bool relationsChanged = false;
185  Q_FOREACH ( const QString& layer, layers )
186  {
187  QMapIterator<QString, QgsRelation> it( mRelations );
188 
189  while ( it.hasNext() )
190  {
191  it.next();
192 
193  if ( it.value().referencedLayerId() == layer
194  || it.value().referencingLayerId() == layer )
195  {
196  mRelations.remove( it.key() );
197  relationsChanged = true;
198  }
199  }
200  }
201  if ( relationsChanged )
202  {
203  emit changed();
204  }
205 }
bool isValid() const
Returns the validity of this relation.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
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
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.
QList< QgsRelation > referencedRelations(QgsVectorLayer *layer=0) const
Get all relations where this layer is the referenced part (i.e.
const QMap< QString, QgsRelation > & relations() const
Get access to the relations managed by this class.
Defines a relation between matchin fields of the two involved tables of a relation.
Definition: qgsrelation.h:38
QgsRelation relation(const QString &id) const
Get access to a relation by its id.
const QString & id() const
The id.
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
Reads and writes project states.
Definition: qgsproject.h:67
QList< QgsRelation > referencingRelations(QgsVectorLayer *layer=0, int fieldIdx=-2) const
Get all relations where the specified layer (and field) is the referencing part (i.e.
QgsRelationManager(QgsProject *project)
void relationsLoaded()
this signal is emitted when the relations were loaded after reading a project
const QString & referencingField() const
Get the name of the referencing field.
Definition: qgsrelation.h:50
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 f...
void removeRelation(const QString &id)
Remove a relation.
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.
void addRelation(const QgsRelation &relation)
Add a relation.
void dirty(bool b)
Definition: qgsproject.cpp:396