QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 
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 }
QgsMapLayerStore::transferLayersFromStore
void transferLayersFromStore(QgsMapLayerStore *other)
Transfers all the map layers contained within another map layer store and adds them to this store.
Definition: qgsmaplayerstore.cpp:207
QgsMapLayerStore::allLayersRemoved
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
QgsMapLayerStore::addMapLayer
QgsMapLayer * addMapLayer(QgsMapLayer *layer, bool takeOwnership=true)
Add a layer to the store.
Definition: qgsmaplayerstore.cpp:105
QgsDataProvider::ProviderOptions
Setting options for creating vector data providers.
Definition: qgsdataprovider.h:105
QgsMapLayerStore::addMapLayers
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer * > &layers, bool takeOwnership=true)
Add a list of layers to the store.
Definition: qgsmaplayerstore.cpp:68
QgsMapLayerStore::~QgsMapLayerStore
~QgsMapLayerStore() override
Definition: qgsmaplayerstore.cpp:27
QgsMapLayerStore::mapLayersByName
QList< QgsMapLayer * > mapLayersByName(const QString &name) const
Retrieve a list of matching layers by layer name.
Definition: qgsmaplayerstore.cpp:54
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsMapLayerStore::mapLayer
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
Definition: qgsmaplayerstore.cpp:49
qgsmaplayerstore.h
QgsMapLayerStore::count
int count() const
Returns the number of layers contained in the store.
Definition: qgsmaplayerstore.cpp:32
QgsMapLayerStore::validCount
int validCount() const
Returns the number of valid layers contained in the store.
Definition: qgsmaplayerstore.cpp:37
QgsMapLayerStore::validMapLayers
QMap< QString, QgsMapLayer * > validMapLayers() const
Returns a map of all valid layers by layer ID.
Definition: qgsmaplayerstore.cpp:240
QgsMapLayerStore::layersAdded
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the store.
QgsMapLayerStore::layersRemoved
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the store.
QgsMapLayerStore::mapLayers
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all layers by layer ID.
Definition: qgsmaplayerstore.cpp:235
QgsMapLayerStore::layerWasAdded
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the store.
QgsMapLayerStore
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
Definition: qgsmaplayerstore.h:36
QgsMapLayerStore::removeMapLayers
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the store by layer ID.
Definition: qgsmaplayerstore.cpp:112
QgsMapLayerStore::layers
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
Definition: qgsmaplayerstore.h:124
QgsMapLayerStore::layersWillBeRemoved
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the store.
qgsmaplayer.h
QgsMapLayer::id
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Definition: qgsmaplayer.cpp:148
QgsMapLayerStore::QgsMapLayerStore
QgsMapLayerStore(QObject *parent=nullptr)
Constructor for QgsMapLayerStore.
Definition: qgsmaplayerstore.cpp:23
QgsMapLayerStore::takeMapLayer
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the store.
Definition: qgsmaplayerstore.cpp:177
QgsMapLayerStore::layerRemoved
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the store.
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
QgsMapLayerStore::removeAllMapLayers
void removeAllMapLayers()
Removes all registered layers.
Definition: qgsmaplayerstore.cpp:198
qgslogger.h
QgsMapLayerStore::removeMapLayer
void removeMapLayer(const QString &id)
Remove a layer from the store by layer id.
Definition: qgsmaplayerstore.cpp:166
QgsMapLayerStore::layerWillBeRemoved
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the store.