Skip to content

Commit f3bfef4

Browse files
committed
Safety checks for unregistering map layers from registry
If a map layer which is registered is deleted outside of the layer registry but not unregistered, the layer registry would still happily return a pointer to this layer if queried with its id. Up to now, this caused crashes. Now, the layer will be unregistered and a warning is printed. This patch also contains slight improvements to other parts of the map layer registry.
1 parent 6103669 commit f3bfef4

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

src/core/qgsmaplayerregistry.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,11 @@ QList<QgsMapLayer *> QgsMapLayerRegistry::addMapLayers(
7373
bool takeOwnership )
7474
{
7575
QList<QgsMapLayer *> myResultList;
76-
for ( int i = 0; i < theMapLayers.size(); ++i )
76+
Q_FOREACH ( QgsMapLayer* myLayer, theMapLayers )
7777
{
78-
QgsMapLayer * myLayer = theMapLayers.at( i );
7978
if ( !myLayer || !myLayer->isValid() )
8079
{
81-
QgsDebugMsg( "cannot add invalid layers" );
80+
QgsDebugMsg( "Cannot add invalid layers" );
8281
continue;
8382
}
8483
//check the layer is not already registered!
@@ -87,7 +86,10 @@ QList<QgsMapLayer *> QgsMapLayerRegistry::addMapLayers(
8786
mMapLayers[myLayer->id()] = myLayer;
8887
myResultList << mMapLayers[myLayer->id()];
8988
if ( takeOwnership )
90-
mOwnedLayers << myLayer;
89+
{
90+
myLayer->setParent( this );
91+
}
92+
connect( myLayer, SIGNAL( destroyed( QObject* ) ), this, SLOT( onMapLayerDeleted( QObject* ) ) );
9193
emit layerWasAdded( myLayer );
9294
}
9395
}
@@ -149,10 +151,9 @@ void QgsMapLayerRegistry::removeMapLayers( const QList<QgsMapLayer*>& layers )
149151
QString myId( lyr->id() );
150152
emit layerWillBeRemoved( myId );
151153
emit layerWillBeRemoved( lyr );
152-
if ( mOwnedLayers.contains( lyr ) )
154+
if ( lyr->parent() == this )
153155
{
154156
delete lyr;
155-
mOwnedLayers.remove( lyr );
156157
}
157158
mMapLayers.remove( myId );
158159
emit layerRemoved( myId );
@@ -183,14 +184,23 @@ void QgsMapLayerRegistry::removeAllMapLayers()
183184

184185
void QgsMapLayerRegistry::reloadAllLayers()
185186
{
186-
QMap<QString, QgsMapLayer *>::iterator it;
187-
for ( it = mMapLayers.begin(); it != mMapLayers.end() ; ++it )
187+
Q_FOREACH ( QgsMapLayer* layer, mMapLayers )
188188
{
189-
QgsMapLayer* layer = it.value();
190-
if ( layer )
191-
{
192-
layer->reload();
193-
}
189+
layer->reload();
190+
}
191+
}
192+
193+
void QgsMapLayerRegistry::onMapLayerDeleted( QObject* obj )
194+
{
195+
QgsMapLayer* ml = qobject_cast<QgsMapLayer*>( obj );
196+
Q_ASSERT( ml );
197+
198+
QString id = mMapLayers.key( ml );
199+
200+
if ( !id.isNull() )
201+
{
202+
QgsDebugMsg( QString( "Map layer deleted without unregistering! %1" ).arg( id ) );
203+
mMapLayers.remove( id );
194204
}
195205
}
196206

src/core/qgsmaplayerregistry.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,14 @@ class CORE_EXPORT QgsMapLayerRegistry : public QObject
309309
void connectNotify( const char * signal ) override;
310310
#endif
311311

312+
private slots:
313+
void onMapLayerDeleted( QObject* obj );
314+
312315
private:
313316
//! private singleton constructor
314317
QgsMapLayerRegistry( QObject * parent = nullptr );
315318

316319
QMap<QString, QgsMapLayer*> mMapLayers;
317-
QSet<QgsMapLayer*> mOwnedLayers;
318320
}; // class QgsMapLayerRegistry
319321

320322
#endif //QgsMapLayerRegistry_H

0 commit comments

Comments
 (0)