Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #4418 from nyalldawson/take_layer
Allow taking layers from QgsProject
  • Loading branch information
nyalldawson committed Apr 26, 2017
2 parents 9bb0762 + a5e33fa commit 946f0fa
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
2 changes: 2 additions & 0 deletions python/core/qgsproject.sip
Expand Up @@ -480,6 +480,8 @@ class QgsProject : QObject, QgsExpressionContextGenerator
*/
void removeMapLayer( QgsMapLayer* layer );

QgsMapLayer *takeMapLayer( QgsMapLayer *layer ) /TransferBack/;

/**
* Removes all registered layers. If the registry has ownership
* of any layers these layers will also be deleted.
Expand Down
21 changes: 21 additions & 0 deletions src/core/qgsproject.cpp
Expand Up @@ -2201,6 +2201,27 @@ void QgsProject::removeMapLayer( QgsMapLayer *layer )
removeMapLayers( QList<QgsMapLayer *>() << layer );
}

QgsMapLayer *QgsProject::takeMapLayer( QgsMapLayer *layer )
{
if ( !layer )
return nullptr;

if ( mMapLayers.contains( layer->id() ) )
{
emit layersWillBeRemoved( QStringList() << layer->id() );
emit layersWillBeRemoved( QList<QgsMapLayer *>() << layer );
emit layerWillBeRemoved( layer->id() );
emit layerWillBeRemoved( layer );

mMapLayers.remove( layer->id() );
layer->setParent( nullptr );
emit layerRemoved( layer->id() );
emit layersRemoved( QStringList() << layer->id() );
return layer;
}
return nullptr; //don't return layer - it wasn't owned and accordingly we aren't transferring ownership
}

void QgsProject::removeAllMapLayers()
{
emit removeAll();
Expand Down
9 changes: 9 additions & 0 deletions src/core/qgsproject.h
Expand Up @@ -699,6 +699,15 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
*/
void removeMapLayer( QgsMapLayer *layer );

/**
* Takes a layer from the registry. If the layer was owned by the project, the
* layer will be returned without deleting it. The caller takes ownership of
* the layer and is responsible for deleting it.
* \see removeMapLayer()
* \since QGIS 3.0
*/
QgsMapLayer *takeMapLayer( QgsMapLayer *layer );

/**
* Removes all registered layers. If the registry has ownership
* of any layers these layers will also be deleted.
Expand Down
29 changes: 29 additions & 0 deletions tests/src/python/test_qgsmaplayerregistry.py
Expand Up @@ -502,6 +502,35 @@ def test_RemoveLayerShouldNotSegFault(self):
for k, layer in list(reg.mapLayers().items()):
assert(layer is not None)

def testTakeLayer(self):
# test taking ownership of a layer from the project
l1 = createLayer('l1')
l2 = createLayer('l2')
p = QgsProject()

# add one layer to project
p.addMapLayer(l1)
self.assertEqual(p.mapLayers(), {l1.id(): l1})
self.assertEqual(l1.parent(), p)

# try taking some layers which don't exist in project
self.assertFalse(p.takeMapLayer(None))
self.assertFalse(p.takeMapLayer(l2))
# but l2 should still exist..
self.assertTrue(l2.isValid())

# take layer from project
self.assertEqual(p.takeMapLayer(l1), l1)
self.assertFalse(p.mapLayers()) # no layers left
# but l1 should still exist
self.assertTrue(l1.isValid())
# layer should have no parent now
self.assertFalse(l1.parent())

# destroy project
p = None
self.assertTrue(l1.isValid())


if __name__ == '__main__':
unittest.main()

0 comments on commit 946f0fa

Please sign in to comment.