QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgsmaplayerstore.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaplayerstore.cpp
3  --------------------
4  begin : May 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsmaplayerstore.h"
19 #include "qgsmaplayer.h"
20 #include "qgslogger.h"
21 #include <QList>
22 
24  : QObject( parent )
25 {}
26 
28 {
30 }
31 
33 {
34  return mMapLayers.size();
35 }
36 
38 {
39  int i = 0;
40  const QList<QgsMapLayer *> cLayers = mMapLayers.values();
41  for ( const auto l : cLayers )
42  {
43  if ( l->isValid() )
44  i++;
45  }
46  return i;
47 }
48 
49 QgsMapLayer *QgsMapLayerStore::mapLayer( const QString &layerId ) const
50 {
51  return mMapLayers.value( layerId );
52 }
53 
54 QList<QgsMapLayer *> QgsMapLayerStore::mapLayersByName( const QString &layerName ) const
55 {
56  QList<QgsMapLayer *> myResultList;
57  const auto constMMapLayers = mMapLayers;
58  for ( QgsMapLayer *layer : constMMapLayers )
59  {
60  if ( layer->name() == layerName )
61  {
62  myResultList << layer;
63  }
64  }
65  return myResultList;
66 }
67 
68 QList<QgsMapLayer *> QgsMapLayerStore::addMapLayers( const QList<QgsMapLayer *> &layers, bool takeOwnership )
69 {
70  QList<QgsMapLayer *> myResultList;
71  const auto constLayers = layers;
72  for ( QgsMapLayer *myLayer : constLayers )
73  {
74  if ( !myLayer )
75  {
76  QgsDebugMsg( QStringLiteral( "Cannot add null layers" ) );
77  continue;
78  }
79  // If the layer is already in the store but its validity has flipped to TRUE reset data source
80  if ( mMapLayers.contains( myLayer->id() ) && ! mMapLayers[myLayer->id()]->isValid() && myLayer->isValid() && myLayer->dataProvider() )
81  {
82  mMapLayers[myLayer->id()]->setDataSource( myLayer->dataProvider()->dataSourceUri(), myLayer->name(), myLayer->providerType(), QgsDataProvider::ProviderOptions() );
83  }
84  //check the layer is not already registered!
85  if ( !mMapLayers.contains( myLayer->id() ) )
86  {
87  mMapLayers[myLayer->id()] = myLayer;
88  myResultList << mMapLayers[myLayer->id()];
89  if ( takeOwnership )
90  {
91  myLayer->setParent( this );
92  }
93  connect( myLayer, &QObject::destroyed, this, &QgsMapLayerStore::onMapLayerDeleted );
94  emit layerWasAdded( myLayer );
95  }
96  }
97  if ( !myResultList.isEmpty() )
98  {
99  emit layersAdded( myResultList );
100  }
101  return myResultList;
102 }
103 
104 QgsMapLayer *
105 QgsMapLayerStore::addMapLayer( QgsMapLayer *layer, bool takeOwnership )
106 {
107  QList<QgsMapLayer *> addedLayers;
108  addedLayers = addMapLayers( QList<QgsMapLayer *>() << layer, takeOwnership );
109  return addedLayers.isEmpty() ? nullptr : addedLayers[0];
110 }
111 
112 void QgsMapLayerStore::removeMapLayers( const QStringList &layerIds )
113 {
114  QList<QgsMapLayer *> layers;
115  const auto constLayerIds = layerIds;
116  for ( const QString &myId : constLayerIds )
117  {
118  layers << mMapLayers.value( myId );
119  }
120 
121  removeMapLayers( layers );
122 }
123 
124 void QgsMapLayerStore::removeMapLayers( const QList<QgsMapLayer *> &layers )
125 {
126  if ( layers.isEmpty() )
127  return;
128 
129  QStringList layerIds;
130  QList<QgsMapLayer *> layerList;
131 
132  const auto constLayers = layers;
133  for ( QgsMapLayer *layer : constLayers )
134  {
135  // check layer and the store contains it
136  if ( layer && mMapLayers.contains( layer->id() ) )
137  {
138  layerIds << layer->id();
139  layerList << layer;
140  }
141  }
142 
143  if ( layerIds.isEmpty() )
144  return;
145 
146  emit layersWillBeRemoved( layerIds );
147  emit layersWillBeRemoved( layerList );
148 
149  const auto constLayerList = layerList;
150  for ( QgsMapLayer *lyr : constLayerList )
151  {
152  QString myId( lyr->id() );
153  emit layerWillBeRemoved( myId );
154  emit layerWillBeRemoved( lyr );
155  mMapLayers.remove( myId );
156  if ( lyr->parent() == this )
157  {
158  delete lyr;
159  }
160  emit layerRemoved( myId );
161  }
162 
163  emit layersRemoved( layerIds );
164 }
165 
166 void QgsMapLayerStore::removeMapLayer( const QString &layerId )
167 {
168  removeMapLayers( QList<QgsMapLayer *>() << mMapLayers.value( layerId ) );
169 }
170 
172 {
173  if ( layer )
174  removeMapLayers( QList<QgsMapLayer *>() << layer );
175 }
176 
178 {
179  if ( !layer )
180  return nullptr;
181 
182  if ( mMapLayers.contains( layer->id() ) )
183  {
184  emit layersWillBeRemoved( QStringList() << layer->id() );
185  emit layersWillBeRemoved( QList<QgsMapLayer *>() << layer );
186  emit layerWillBeRemoved( layer->id() );
187  emit layerWillBeRemoved( layer );
188 
189  mMapLayers.remove( layer->id() );
190  layer->setParent( nullptr );
191  emit layerRemoved( layer->id() );
192  emit layersRemoved( QStringList() << layer->id() );
193  return layer;
194  }
195  return nullptr; //don't return layer - it wasn't owned and accordingly we aren't transferring ownership
196 }
197 
199 {
200  emit allLayersRemoved();
201  // now let all observers know to clear themselves,
202  // and then consequently any of their map legends
203  removeMapLayers( mMapLayers.keys() );
204  mMapLayers.clear();
205 }
206 
208 {
209  if ( !other || other == this )
210  return;
211 
212  Q_ASSERT_X( other->thread() == thread(), "QgsMapLayerStore::transferLayersFromStore", "Cannot transfer layers from store with different thread affinity" );
213 
214  QMap<QString, QgsMapLayer *> otherLayers = other->mapLayers();
215  QMap<QString, QgsMapLayer *>::const_iterator it = otherLayers.constBegin();
216  for ( ; it != otherLayers.constEnd(); ++it )
217  {
218  QgsMapLayer *layer = other->takeMapLayer( it.value() );
219  if ( layer )
220  addMapLayer( layer );
221  }
222 }
223 
224 void QgsMapLayerStore::onMapLayerDeleted( QObject *obj )
225 {
226  QString id = mMapLayers.key( static_cast<QgsMapLayer *>( obj ) );
227 
228  if ( !id.isNull() )
229  {
230  QgsDebugMsg( QStringLiteral( "Map layer deleted without unregistering! %1" ).arg( id ) );
231  mMapLayers.remove( id );
232  }
233 }
234 
235 QMap<QString, QgsMapLayer *> QgsMapLayerStore::mapLayers() const
236 {
237  return mMapLayers;
238 }
239 
240 QMap<QString, QgsMapLayer *> QgsMapLayerStore::validMapLayers() const
241 {
242  QMap<QString, QgsMapLayer *> validLayers;
243  for ( const auto &id : mMapLayers.keys() )
244  {
245  if ( mMapLayers[id]->isValid() )
246  validLayers[id] = mMapLayers[id];
247  }
248  return validLayers;
249 }
QMap< QString, QgsMapLayer * > validMapLayers() const
Returns a map of all valid layers by layer ID.
Base class for all map layer types.
Definition: qgsmaplayer.h:79
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the store.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
void removeMapLayer(const QString &id)
Remove a layer from the store by layer id.
void layersAdded(const QList< QgsMapLayer *> &layers)
Emitted when one or more layers were added to the store.
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the store.
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the store.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the store.
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
void removeAllMapLayers()
Removes all registered layers.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
~QgsMapLayerStore() override
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the store.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the store.
int count() const
Returns the number of layers contained in the store.
int validCount() const
Returns the number of valid layers contained in the store.
Setting options for creating vector data providers.
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all layers by layer ID.
QgsMapLayer * addMapLayer(QgsMapLayer *layer, bool takeOwnership=true)
Add a layer to the store.
void transferLayersFromStore(QgsMapLayerStore *other)
Transfers all the map layers contained within another map layer store and adds them to this store...
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the store by layer ID.
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer *> &layers, bool takeOwnership=true)
Add a list of layers to the store.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
QList< QgsMapLayer * > mapLayersByName(const QString &name) const
Retrieve a list of matching layers by layer name.
QgsMapLayerStore(QObject *parent=nullptr)
Constructor for QgsMapLayerStore.