mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-07 00:03:52 -05:00
Split off map layer storage handling from QgsProject to QgsMapLayerStore
Turns out that there's valid use cases for having layer stores outside of the cost of using a whole QgsProject. Partially reverts the merger of QgsMapLayerRegistry into QgsProject, except that there's no singletons here.
This commit is contained in:
parent
8e70aa84fa
commit
f9bd83c035
@ -92,6 +92,7 @@
|
||||
%Include qgsmaplayermodel.sip
|
||||
%Include qgsmaplayerproxymodel.sip
|
||||
%Include qgsmaplayerrenderer.sip
|
||||
%Include qgsmaplayerstore.sip
|
||||
%Include qgsmaplayerstylemanager.sip
|
||||
%Include qgsmaprenderercache.sip
|
||||
%Include qgsmaprenderercustompainterjob.sip
|
||||
|
||||
292
python/core/qgsmaplayerstore.sip
Normal file
292
python/core/qgsmaplayerstore.sip
Normal file
@ -0,0 +1,292 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/qgsmaplayerstore.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsMapLayerStore : QObject
|
||||
{
|
||||
%Docstring
|
||||
A storage object for map layers, in which the layers are owned by the
|
||||
store and have their lifetime bound to the store.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsmaplayerstore.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
explicit QgsMapLayerStore( QObject *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsMapLayerStore.
|
||||
%End
|
||||
|
||||
~QgsMapLayerStore();
|
||||
|
||||
int count() const;
|
||||
%Docstring
|
||||
Returns the number of layers contained in the store.
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
|
||||
int __len__() const;
|
||||
%Docstring
|
||||
Returns the number of layers contained in the store.
|
||||
:rtype: int
|
||||
%End
|
||||
%MethodCode
|
||||
sipRes = sipCpp->count();
|
||||
%End
|
||||
|
||||
QgsMapLayer *mapLayer( const QString &id ) const;
|
||||
%Docstring
|
||||
Retrieve a pointer to a layer by layer ``id``.
|
||||
\param id ID of layer to retrieve
|
||||
:return: matching layer, or None if no matching layer found
|
||||
.. seealso:: mapLayersByName()
|
||||
.. seealso:: mapLayers()
|
||||
:rtype: QgsMapLayer
|
||||
%End
|
||||
|
||||
QList<QgsMapLayer *> mapLayersByName( const QString &name ) const;
|
||||
%Docstring
|
||||
Retrieve a list of matching layers by layer ``name``.
|
||||
\param name name of layers to match
|
||||
:return: list of matching layers
|
||||
.. seealso:: mapLayer()
|
||||
.. seealso:: mapLayers()
|
||||
:rtype: list of QgsMapLayer
|
||||
%End
|
||||
|
||||
QMap<QString, QgsMapLayer *> mapLayers() const;
|
||||
%Docstring
|
||||
Returns a map of all layers by layer ID.
|
||||
.. seealso:: mapLayer()
|
||||
.. seealso:: mapLayersByName()
|
||||
.. seealso:: layers()
|
||||
:rtype: QMap<str, QgsMapLayer *>
|
||||
%End
|
||||
|
||||
|
||||
QList<QgsMapLayer *> addMapLayers( const QList<QgsMapLayer *> &layers /Transfer/ );
|
||||
%Docstring
|
||||
\brief
|
||||
Add a list of ``layers`` to the store. Ownership of the layers is transferred
|
||||
to the store.
|
||||
|
||||
The layersAdded() and layerWasAdded() signals will always be emitted.
|
||||
|
||||
\param layers A list of layer which should be added to the store.
|
||||
|
||||
:return: a list of the map layers that were added
|
||||
successfully. If a layer is invalid, or already exists in the store,
|
||||
it will not be part of the returned list.
|
||||
|
||||
.. seealso:: addMapLayer()
|
||||
:rtype: list of QgsMapLayer
|
||||
%End
|
||||
|
||||
QgsMapLayer *addMapLayer( QgsMapLayer *layer /Transfer/ );
|
||||
%Docstring
|
||||
\brief
|
||||
Add a ``layer`` to the store. Ownership of the layer is transferred to the
|
||||
store.
|
||||
|
||||
The layersAdded() and layerWasAdded() signals will always be emitted.
|
||||
If you are adding multiple layers at once, you should use
|
||||
addMapLayers() instead.
|
||||
|
||||
\param layer A layer to add to the store
|
||||
|
||||
:return: None if unable to add layer, otherwise pointer to newly added layer
|
||||
|
||||
.. seealso:: addMapLayers
|
||||
|
||||
.. note::
|
||||
|
||||
Use addMapLayers() if adding more than one layer at a time.
|
||||
.. seealso:: addMapLayers()
|
||||
:rtype: QgsMapLayer
|
||||
%End
|
||||
|
||||
void removeMapLayers( const QStringList &layerIds ) /PyName=removeMapLayersById/;
|
||||
%Docstring
|
||||
\brief
|
||||
Remove a set of layers from the store by layer ID.
|
||||
|
||||
The specified layers will be removed from the store.
|
||||
These layers will also be deleted.
|
||||
|
||||
\param layerIds list of IDs of the layers to remove
|
||||
|
||||
.. seealso:: takeMapLayer()
|
||||
.. seealso:: removeMapLayer()
|
||||
.. seealso:: removeAllMapLayers()
|
||||
.. note::
|
||||
|
||||
available in Python bindings as removeMapLayersById.
|
||||
%End
|
||||
|
||||
void removeMapLayers( const QList<QgsMapLayer *> &layers );
|
||||
|
||||
void removeMapLayer( const QString &id );
|
||||
%Docstring
|
||||
\brief
|
||||
Remove a layer from the store by layer ``id``.
|
||||
|
||||
The specified layer will be removed from the store. The layer will also be deleted.
|
||||
|
||||
\param id ID of the layer to remove
|
||||
|
||||
.. seealso:: takeMapLayer()
|
||||
.. seealso:: removeMapLayers()
|
||||
.. seealso:: removeAllMapLayers()
|
||||
%End
|
||||
|
||||
void removeMapLayer( QgsMapLayer *layer );
|
||||
%Docstring
|
||||
\brief
|
||||
Remove a ``layer`` from the store.
|
||||
|
||||
The specified layer will be removed from the store. The layer will also be deleted.
|
||||
|
||||
\param layer The layer to remove. Null pointers are ignored.
|
||||
|
||||
.. seealso:: takeMapLayer()
|
||||
.. seealso:: removeMapLayers()
|
||||
.. seealso:: removeAllMapLayers()
|
||||
%End
|
||||
|
||||
QgsMapLayer *takeMapLayer( QgsMapLayer *layer ) /TransferBack/;
|
||||
%Docstring
|
||||
Takes a ``layer`` from the store. If the layer was owned by the store, the
|
||||
layer will be returned without deleting it. The caller takes ownership of
|
||||
the layer and is responsible for deleting it.
|
||||
.. seealso:: removeMapLayer()
|
||||
:rtype: QgsMapLayer
|
||||
%End
|
||||
|
||||
void removeAllMapLayers();
|
||||
%Docstring
|
||||
Removes all registered layers. These layers will also be deleted.
|
||||
|
||||
.. note::
|
||||
|
||||
Calling this method will cause the removeAll() signal to
|
||||
be emitted.
|
||||
.. seealso:: removeMapLayer()
|
||||
.. seealso:: removeMapLayers()
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void layersWillBeRemoved( const QStringList &layerIds );
|
||||
%Docstring
|
||||
Emitted when one or more layers are about to be removed from the store.
|
||||
|
||||
\param layerIds A list of IDs for the layers which are to be removed.
|
||||
.. seealso:: layerWillBeRemoved()
|
||||
.. seealso:: layersRemoved()
|
||||
%End
|
||||
|
||||
void layersWillBeRemoved( const QList<QgsMapLayer *> &layers );
|
||||
%Docstring
|
||||
Emitted when one or more layers are about to be removed from the store.
|
||||
|
||||
\param layers A list of layers which are to be removed.
|
||||
.. seealso:: layerWillBeRemoved()
|
||||
.. seealso:: layersRemoved()
|
||||
%End
|
||||
|
||||
void layerWillBeRemoved( const QString &layerId );
|
||||
%Docstring
|
||||
Emitted when a layer is about to be removed from the store.
|
||||
|
||||
\param layerId The ID of the layer to be removed.
|
||||
|
||||
.. note::
|
||||
|
||||
Consider using layersWillBeRemoved() instead.
|
||||
.. seealso:: layersWillBeRemoved()
|
||||
.. seealso:: layerRemoved()
|
||||
%End
|
||||
|
||||
void layerWillBeRemoved( QgsMapLayer *layer );
|
||||
%Docstring
|
||||
Emitted when a layer is about to be removed from the store.
|
||||
|
||||
\param layer The layer to be removed.
|
||||
|
||||
.. note::
|
||||
|
||||
Consider using layersWillBeRemoved() instead.
|
||||
.. seealso:: layersWillBeRemoved()
|
||||
.. seealso:: layerRemoved()
|
||||
%End
|
||||
|
||||
void layersRemoved( const QStringList &layerIds );
|
||||
%Docstring
|
||||
Emitted after one or more layers were removed from the store.
|
||||
|
||||
\param layerIds A list of IDs of the layers which were removed.
|
||||
.. seealso:: layersWillBeRemoved()
|
||||
%End
|
||||
|
||||
void layerRemoved( const QString &layerId );
|
||||
%Docstring
|
||||
Emitted after a layer was removed from the store.
|
||||
|
||||
\param layerId The ID of the layer removed.
|
||||
|
||||
.. note::
|
||||
|
||||
Consider using layersRemoved() instead
|
||||
.. seealso:: layerWillBeRemoved()
|
||||
%End
|
||||
|
||||
void allLayersRemoved();
|
||||
%Docstring
|
||||
Emitted when all layers are removed, before layersWillBeRemoved() and
|
||||
layerWillBeRemoved() signals are emitted. The layersWillBeRemoved() and
|
||||
layerWillBeRemoved() signals will still be emitted following this signal.
|
||||
You can use this signal to do easy (and fast) cleanup.
|
||||
%End
|
||||
|
||||
void layersAdded( const QList<QgsMapLayer *> &layers );
|
||||
%Docstring
|
||||
Emitted when one or more layers were added to the store.
|
||||
|
||||
\param layers List of layers which have been added.
|
||||
|
||||
.. seealso:: legendLayersAdded()
|
||||
.. seealso:: layerWasAdded()
|
||||
%End
|
||||
|
||||
void layerWasAdded( QgsMapLayer *layer );
|
||||
%Docstring
|
||||
Emitted when a ``layer`` was added to the store.
|
||||
|
||||
.. note::
|
||||
|
||||
Consider using layersAdded() instead
|
||||
.. seealso:: layersAdded()
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/qgsmaplayerstore.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
@ -176,6 +176,7 @@ SET(QGIS_CORE_SRCS
|
||||
qgsmaplayerlegend.cpp
|
||||
qgsmaplayermodel.cpp
|
||||
qgsmaplayerproxymodel.cpp
|
||||
qgsmaplayerstore.cpp
|
||||
qgsmaplayerstylemanager.cpp
|
||||
qgsmaprenderercache.cpp
|
||||
qgsmaprenderercustompainterjob.cpp
|
||||
@ -525,6 +526,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
qgsmaplayerlegend.h
|
||||
qgsmaplayermodel.h
|
||||
qgsmaplayerproxymodel.h
|
||||
qgsmaplayerstore.h
|
||||
qgsmaplayerstylemanager.h
|
||||
qgsmaprenderercache.h
|
||||
qgsmaprenderercustompainterjob.h
|
||||
|
||||
195
src/core/qgsmaplayerstore.cpp
Normal file
195
src/core/qgsmaplayerstore.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
/***************************************************************************
|
||||
qgsmaplayerstore.cpp
|
||||
--------------------
|
||||
begin : May 2017
|
||||
copyright : (C) 2017 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsmaplayerstore.h"
|
||||
#include "qgslogger.h"
|
||||
|
||||
QgsMapLayerStore::QgsMapLayerStore( QObject *parent )
|
||||
: QObject( parent )
|
||||
{}
|
||||
|
||||
QgsMapLayerStore::~QgsMapLayerStore()
|
||||
{
|
||||
removeAllMapLayers();
|
||||
}
|
||||
|
||||
int QgsMapLayerStore::count() const
|
||||
{
|
||||
return mMapLayers.size();
|
||||
}
|
||||
|
||||
QgsMapLayer *QgsMapLayerStore::mapLayer( const QString &layerId ) const
|
||||
{
|
||||
return mMapLayers.value( layerId );
|
||||
}
|
||||
|
||||
QList<QgsMapLayer *> QgsMapLayerStore::mapLayersByName( const QString &layerName ) const
|
||||
{
|
||||
QList<QgsMapLayer *> myResultList;
|
||||
Q_FOREACH ( QgsMapLayer *layer, mMapLayers )
|
||||
{
|
||||
if ( layer->name() == layerName )
|
||||
{
|
||||
myResultList << layer;
|
||||
}
|
||||
}
|
||||
return myResultList;
|
||||
}
|
||||
|
||||
QList<QgsMapLayer *> QgsMapLayerStore::addMapLayers(
|
||||
const QList<QgsMapLayer *> &layers )
|
||||
{
|
||||
QList<QgsMapLayer *> myResultList;
|
||||
Q_FOREACH ( QgsMapLayer *myLayer, layers )
|
||||
{
|
||||
if ( !myLayer || !myLayer->isValid() )
|
||||
{
|
||||
QgsDebugMsg( "Cannot add invalid layers" );
|
||||
continue;
|
||||
}
|
||||
//check the layer is not already registered!
|
||||
if ( !mMapLayers.contains( myLayer->id() ) )
|
||||
{
|
||||
mMapLayers[myLayer->id()] = myLayer;
|
||||
myResultList << mMapLayers[myLayer->id()];
|
||||
myLayer->setParent( this );
|
||||
connect( myLayer, &QObject::destroyed, this, &QgsMapLayerStore::onMapLayerDeleted );
|
||||
emit layerWasAdded( myLayer );
|
||||
}
|
||||
}
|
||||
if ( !myResultList.isEmpty() )
|
||||
{
|
||||
emit layersAdded( myResultList );
|
||||
}
|
||||
return myResultList;
|
||||
}
|
||||
|
||||
QgsMapLayer *
|
||||
QgsMapLayerStore::addMapLayer( QgsMapLayer *layer )
|
||||
{
|
||||
QList<QgsMapLayer *> addedLayers;
|
||||
addedLayers = addMapLayers( QList<QgsMapLayer *>() << layer );
|
||||
return addedLayers.isEmpty() ? nullptr : addedLayers[0];
|
||||
}
|
||||
|
||||
void QgsMapLayerStore::removeMapLayers( const QStringList &layerIds )
|
||||
{
|
||||
QList<QgsMapLayer *> layers;
|
||||
Q_FOREACH ( const QString &myId, layerIds )
|
||||
{
|
||||
layers << mMapLayers.value( myId );
|
||||
}
|
||||
|
||||
removeMapLayers( layers );
|
||||
}
|
||||
|
||||
void QgsMapLayerStore::removeMapLayers( const QList<QgsMapLayer *> &layers )
|
||||
{
|
||||
if ( layers.isEmpty() )
|
||||
return;
|
||||
|
||||
QStringList layerIds;
|
||||
QList<QgsMapLayer *> layerList;
|
||||
|
||||
Q_FOREACH ( QgsMapLayer *layer, layers )
|
||||
{
|
||||
// check layer and the store contains it
|
||||
if ( layer && mMapLayers.contains( layer->id() ) )
|
||||
{
|
||||
layerIds << layer->id();
|
||||
layerList << layer;
|
||||
}
|
||||
}
|
||||
|
||||
if ( layerIds.isEmpty() )
|
||||
return;
|
||||
|
||||
emit layersWillBeRemoved( layerIds );
|
||||
emit layersWillBeRemoved( layerList );
|
||||
|
||||
Q_FOREACH ( QgsMapLayer *lyr, layerList )
|
||||
{
|
||||
QString myId( lyr->id() );
|
||||
emit layerWillBeRemoved( myId );
|
||||
emit layerWillBeRemoved( lyr );
|
||||
mMapLayers.remove( myId );
|
||||
if ( lyr->parent() == this )
|
||||
{
|
||||
delete lyr;
|
||||
}
|
||||
emit layerRemoved( myId );
|
||||
}
|
||||
|
||||
emit layersRemoved( layerIds );
|
||||
}
|
||||
|
||||
void QgsMapLayerStore::removeMapLayer( const QString &layerId )
|
||||
{
|
||||
removeMapLayers( QList<QgsMapLayer *>() << mMapLayers.value( layerId ) );
|
||||
}
|
||||
|
||||
void QgsMapLayerStore::removeMapLayer( QgsMapLayer *layer )
|
||||
{
|
||||
if ( layer )
|
||||
removeMapLayers( QList<QgsMapLayer *>() << layer );
|
||||
}
|
||||
|
||||
QgsMapLayer *QgsMapLayerStore::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 QgsMapLayerStore::removeAllMapLayers()
|
||||
{
|
||||
emit allLayersRemoved();
|
||||
// now let all observers know to clear themselves,
|
||||
// and then consequently any of their map legends
|
||||
removeMapLayers( mMapLayers.keys() );
|
||||
mMapLayers.clear();
|
||||
}
|
||||
|
||||
void QgsMapLayerStore::onMapLayerDeleted( QObject *obj )
|
||||
{
|
||||
QString id = mMapLayers.key( static_cast<QgsMapLayer *>( obj ) );
|
||||
|
||||
if ( !id.isNull() )
|
||||
{
|
||||
QgsDebugMsg( QString( "Map layer deleted without unregistering! %1" ).arg( id ) );
|
||||
mMapLayers.remove( id );
|
||||
}
|
||||
}
|
||||
|
||||
QMap<QString, QgsMapLayer *> QgsMapLayerStore::mapLayers() const
|
||||
{
|
||||
return mMapLayers;
|
||||
}
|
||||
330
src/core/qgsmaplayerstore.h
Normal file
330
src/core/qgsmaplayerstore.h
Normal file
@ -0,0 +1,330 @@
|
||||
/***************************************************************************
|
||||
qgsmaplayerstore.h
|
||||
------------------
|
||||
begin : May 2017
|
||||
copyright : (C) 2017 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef QGSMAPLAYERSTORE_H
|
||||
#define QGSMAPLAYERSTORE_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis.h"
|
||||
#include "qgsmaplayer.h"
|
||||
#include <QObject>
|
||||
|
||||
/**
|
||||
* \class QgsMapLayerStore
|
||||
* \ingroup core
|
||||
* A storage object for map layers, in which the layers are owned by the
|
||||
* store and have their lifetime bound to the store.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
|
||||
class CORE_EXPORT QgsMapLayerStore : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsMapLayerStore.
|
||||
*/
|
||||
explicit QgsMapLayerStore( QObject *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
~QgsMapLayerStore();
|
||||
|
||||
/**
|
||||
* Returns the number of layers contained in the store.
|
||||
*/
|
||||
int count() const;
|
||||
|
||||
#ifdef SIP_RUN
|
||||
|
||||
/**
|
||||
* Returns the number of layers contained in the store.
|
||||
*/
|
||||
int __len__() const;
|
||||
% MethodCode
|
||||
sipRes = sipCpp->count();
|
||||
% End
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Retrieve a pointer to a layer by layer \a id.
|
||||
* \param id ID of layer to retrieve
|
||||
* \returns matching layer, or nullptr if no matching layer found
|
||||
* \see mapLayersByName()
|
||||
* \see mapLayers()
|
||||
*/
|
||||
QgsMapLayer *mapLayer( const QString &id ) const;
|
||||
|
||||
/**
|
||||
* Retrieve a list of matching layers by layer \a name.
|
||||
* \param name name of layers to match
|
||||
* \returns list of matching layers
|
||||
* \see mapLayer()
|
||||
* \see mapLayers()
|
||||
*/
|
||||
QList<QgsMapLayer *> mapLayersByName( const QString &name ) const;
|
||||
|
||||
/**
|
||||
* Returns a map of all layers by layer ID.
|
||||
* \see mapLayer()
|
||||
* \see mapLayersByName()
|
||||
* \see layers()
|
||||
*/
|
||||
QMap<QString, QgsMapLayer *> mapLayers() const;
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
||||
/**
|
||||
* Returns a list of registered map layers with a specified layer type.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* QVector<QgsVectorLayer*> vectorLayers = store->layers<QgsVectorLayer*>();
|
||||
*
|
||||
* \note not available in Python bindings
|
||||
* \see mapLayers()
|
||||
*/
|
||||
template <typename T>
|
||||
QVector<T> layers() const
|
||||
{
|
||||
QVector<T> layers;
|
||||
QMap<QString, QgsMapLayer *>::const_iterator layerIt = mMapLayers.constBegin();
|
||||
for ( ; layerIt != mMapLayers.constEnd(); ++layerIt )
|
||||
{
|
||||
T tLayer = qobject_cast<T>( layerIt.value() );
|
||||
if ( tLayer )
|
||||
{
|
||||
layers << tLayer;
|
||||
}
|
||||
}
|
||||
return layers;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* Add a list of \a layers to the store. Ownership of the layers is transferred
|
||||
* to the store.
|
||||
*
|
||||
* The layersAdded() and layerWasAdded() signals will always be emitted.
|
||||
*
|
||||
* \param layers A list of layer which should be added to the store.
|
||||
*
|
||||
* \returns a list of the map layers that were added
|
||||
* successfully. If a layer is invalid, or already exists in the store,
|
||||
* it will not be part of the returned list.
|
||||
*
|
||||
* \see addMapLayer()
|
||||
*/
|
||||
QList<QgsMapLayer *> addMapLayers( const QList<QgsMapLayer *> &layers SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* Add a \a layer to the store. Ownership of the layer is transferred to the
|
||||
* store.
|
||||
*
|
||||
* The layersAdded() and layerWasAdded() signals will always be emitted.
|
||||
* If you are adding multiple layers at once, you should use
|
||||
* addMapLayers() instead.
|
||||
*
|
||||
* \param layer A layer to add to the store
|
||||
*
|
||||
* \returns nullptr if unable to add layer, otherwise pointer to newly added layer
|
||||
*
|
||||
* \see addMapLayers
|
||||
*
|
||||
* \note Use addMapLayers() if adding more than one layer at a time.
|
||||
* \see addMapLayers()
|
||||
*/
|
||||
QgsMapLayer *addMapLayer( QgsMapLayer *layer SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* Remove a set of layers from the store by layer ID.
|
||||
*
|
||||
* The specified layers will be removed from the store.
|
||||
* These layers will also be deleted.
|
||||
*
|
||||
* \param layerIds list of IDs of the layers to remove
|
||||
*
|
||||
* \see takeMapLayer()
|
||||
* \see removeMapLayer()
|
||||
* \see removeAllMapLayers()
|
||||
* \note available in Python bindings as removeMapLayersById.
|
||||
*/
|
||||
void removeMapLayers( const QStringList &layerIds ) SIP_PYNAME( removeMapLayersById );
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* Remove a set of \a layers from the store.
|
||||
*
|
||||
* The specified layers will be removed from the store.
|
||||
* These layers will also be deleted.
|
||||
*
|
||||
* \param layers A list of layers to remove. Null pointers are ignored.
|
||||
*
|
||||
* \see takeMapLayer()
|
||||
* \see removeMapLayer()
|
||||
* \see removeAllMapLayers()
|
||||
*/
|
||||
//TODO QGIS 3.0 - add PyName alias to avoid list type conversion error
|
||||
void removeMapLayers( const QList<QgsMapLayer *> &layers );
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* Remove a layer from the store by layer \a id.
|
||||
*
|
||||
* The specified layer will be removed from the store. The layer will also be deleted.
|
||||
*
|
||||
* \param id ID of the layer to remove
|
||||
*
|
||||
* \see takeMapLayer()
|
||||
* \see removeMapLayers()
|
||||
* \see removeAllMapLayers()
|
||||
*/
|
||||
void removeMapLayer( const QString &id );
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* Remove a \a layer from the store.
|
||||
*
|
||||
* The specified layer will be removed from the store. The layer will also be deleted.
|
||||
*
|
||||
* \param layer The layer to remove. Null pointers are ignored.
|
||||
*
|
||||
* \see takeMapLayer()
|
||||
* \see removeMapLayers()
|
||||
* \see removeAllMapLayers()
|
||||
*/
|
||||
void removeMapLayer( QgsMapLayer *layer );
|
||||
|
||||
/**
|
||||
* Takes a \a layer from the store. If the layer was owned by the store, the
|
||||
* layer will be returned without deleting it. The caller takes ownership of
|
||||
* the layer and is responsible for deleting it.
|
||||
* \see removeMapLayer()
|
||||
*/
|
||||
QgsMapLayer *takeMapLayer( QgsMapLayer *layer ) SIP_TRANSFERBACK;
|
||||
|
||||
/**
|
||||
* Removes all registered layers. These layers will also be deleted.
|
||||
*
|
||||
* \note Calling this method will cause the removeAll() signal to
|
||||
* be emitted.
|
||||
* \see removeMapLayer()
|
||||
* \see removeMapLayers()
|
||||
*/
|
||||
void removeAllMapLayers();
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
* Emitted when one or more layers are about to be removed from the store.
|
||||
*
|
||||
* \param layerIds A list of IDs for the layers which are to be removed.
|
||||
* \see layerWillBeRemoved()
|
||||
* \see layersRemoved()
|
||||
*/
|
||||
void layersWillBeRemoved( const QStringList &layerIds );
|
||||
|
||||
/**
|
||||
* Emitted when one or more layers are about to be removed from the store.
|
||||
*
|
||||
* \param layers A list of layers which are to be removed.
|
||||
* \see layerWillBeRemoved()
|
||||
* \see layersRemoved()
|
||||
*/
|
||||
void layersWillBeRemoved( const QList<QgsMapLayer *> &layers );
|
||||
|
||||
/**
|
||||
* Emitted when a layer is about to be removed from the store.
|
||||
*
|
||||
* \param layerId The ID of the layer to be removed.
|
||||
*
|
||||
* \note Consider using layersWillBeRemoved() instead.
|
||||
* \see layersWillBeRemoved()
|
||||
* \see layerRemoved()
|
||||
*/
|
||||
void layerWillBeRemoved( const QString &layerId );
|
||||
|
||||
/**
|
||||
* Emitted when a layer is about to be removed from the store.
|
||||
*
|
||||
* \param layer The layer to be removed.
|
||||
*
|
||||
* \note Consider using layersWillBeRemoved() instead.
|
||||
* \see layersWillBeRemoved()
|
||||
* \see layerRemoved()
|
||||
*/
|
||||
void layerWillBeRemoved( QgsMapLayer *layer );
|
||||
|
||||
/**
|
||||
* Emitted after one or more layers were removed from the store.
|
||||
*
|
||||
* \param layerIds A list of IDs of the layers which were removed.
|
||||
* \see layersWillBeRemoved()
|
||||
*/
|
||||
void layersRemoved( const QStringList &layerIds );
|
||||
|
||||
/**
|
||||
* Emitted after a layer was removed from the store.
|
||||
*
|
||||
* \param layerId The ID of the layer removed.
|
||||
*
|
||||
* \note Consider using layersRemoved() instead
|
||||
* \see layerWillBeRemoved()
|
||||
*/
|
||||
void layerRemoved( const QString &layerId );
|
||||
|
||||
/**
|
||||
* Emitted when all layers are removed, before layersWillBeRemoved() and
|
||||
* layerWillBeRemoved() signals are emitted. The layersWillBeRemoved() and
|
||||
* layerWillBeRemoved() signals will still be emitted following this signal.
|
||||
* You can use this signal to do easy (and fast) cleanup.
|
||||
*/
|
||||
void allLayersRemoved();
|
||||
|
||||
/**
|
||||
* Emitted when one or more layers were added to the store.
|
||||
*
|
||||
* \param layers List of layers which have been added.
|
||||
*
|
||||
* \see legendLayersAdded()
|
||||
* \see layerWasAdded()
|
||||
*/
|
||||
void layersAdded( const QList<QgsMapLayer *> &layers );
|
||||
|
||||
/**
|
||||
* Emitted when a \a layer was added to the store.
|
||||
*
|
||||
* \note Consider using layersAdded() instead
|
||||
* \see layersAdded()
|
||||
*/
|
||||
void layerWasAdded( QgsMapLayer *layer );
|
||||
|
||||
private slots:
|
||||
|
||||
void onMapLayerDeleted( QObject *obj );
|
||||
|
||||
private:
|
||||
|
||||
QMap<QString, QgsMapLayer *> mMapLayers;
|
||||
|
||||
};
|
||||
|
||||
#endif //QGSMAPLAYERSTORE_H
|
||||
@ -75,6 +75,7 @@ ADD_PYTHON_TEST(PyQgsMapCanvas test_qgsmapcanvas.py)
|
||||
ADD_PYTHON_TEST(PyQgsMapCanvasAnnotationItem test_qgsmapcanvasannotationitem.py)
|
||||
ADD_PYTHON_TEST(PyQgsMapLayer test_qgsmaplayer.py)
|
||||
ADD_PYTHON_TEST(PyQgsMapLayerModel test_qgsmaplayermodel.py)
|
||||
ADD_PYTHON_TEST(PyQgsMapLayerStore test_qgsmaplayerstore.py)
|
||||
ADD_PYTHON_TEST(PyQgsMapRenderer test_qgsmaprenderer.py)
|
||||
ADD_PYTHON_TEST(PyQgsMapRendererCache test_qgsmaprenderercache.py)
|
||||
ADD_PYTHON_TEST(PyQgsMapThemeCollection test_qgsmapthemecollection.py)
|
||||
|
||||
495
tests/src/python/test_qgsmaplayerstore.py
Normal file
495
tests/src/python/test_qgsmaplayerstore.py
Normal file
@ -0,0 +1,495 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for QgsMapLayerStore.
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
__author__ = 'Nyall Dawson'
|
||||
__date__ = '2017-05'
|
||||
__copyright__ = 'Copyright 2017, The QGIS Project'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.core import QgsMapLayerStore, QgsVectorLayer, QgsMapLayer
|
||||
from qgis.testing import start_app, unittest
|
||||
from qgis.PyQt.QtCore import QT_VERSION_STR
|
||||
import sip
|
||||
from qgis.PyQt.QtTest import QSignalSpy
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
def createLayer(name):
|
||||
return QgsVectorLayer("Point?field=x:string", name, "memory")
|
||||
|
||||
|
||||
class TestQgsMapLayerStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def test_addMapLayer(self):
|
||||
""" test adding individual map layers to store"""
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
l1 = createLayer('test')
|
||||
self.assertEqual(store.addMapLayer(l1), l1)
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 1)
|
||||
self.assertEqual(store.count(), 1)
|
||||
self.assertEqual(len(store), 1)
|
||||
|
||||
# adding a second layer should leave existing layers intact
|
||||
l2 = createLayer('test2')
|
||||
self.assertEqual(store.addMapLayer(l2), l2)
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 1)
|
||||
self.assertEqual(len(store.mapLayersByName('test2')), 1)
|
||||
self.assertEqual(store.count(), 2)
|
||||
self.assertEqual(len(store), 2)
|
||||
|
||||
def test_addMapLayerAlreadyAdded(self):
|
||||
""" test that already added layers can't be readded to store """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
l1 = createLayer('test')
|
||||
store.addMapLayer(l1)
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 1)
|
||||
self.assertEqual(store.count(), 1)
|
||||
self.assertEqual(store.addMapLayer(l1), None)
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 1)
|
||||
self.assertEqual(store.count(), 1)
|
||||
self.assertEqual(len(store), 1)
|
||||
|
||||
def test_addMapLayerInvalid(self):
|
||||
""" test that invalid map layers can't be added to store """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
self.assertEqual(store.addMapLayer(QgsVectorLayer("Point?field=x:string", 'test', "xxx")), None)
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 0)
|
||||
self.assertEqual(store.count(), 0)
|
||||
|
||||
def test_addMapLayerSignals(self):
|
||||
""" test that signals are correctly emitted when adding map layer"""
|
||||
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
layer_was_added_spy = QSignalSpy(store.layerWasAdded)
|
||||
layers_added_spy = QSignalSpy(store.layersAdded)
|
||||
|
||||
l1 = createLayer('test')
|
||||
store.addMapLayer(l1)
|
||||
|
||||
# can't seem to actually test the data which was emitted, so best we can do is test
|
||||
# the signal count
|
||||
self.assertEqual(len(layer_was_added_spy), 1)
|
||||
self.assertEqual(len(layers_added_spy), 1)
|
||||
|
||||
store.addMapLayer(createLayer('test2'))
|
||||
self.assertEqual(len(layer_was_added_spy), 2)
|
||||
self.assertEqual(len(layers_added_spy), 2)
|
||||
|
||||
# try readding a layer already in the store
|
||||
store.addMapLayer(l1)
|
||||
# should be no extra signals emitted
|
||||
self.assertEqual(len(layer_was_added_spy), 2)
|
||||
self.assertEqual(len(layers_added_spy), 2)
|
||||
|
||||
def test_addMapLayers(self):
|
||||
""" test adding multiple map layers to store """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
self.assertEqual(set(store.addMapLayers([l1, l2])), {l1, l2})
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 1)
|
||||
self.assertEqual(len(store.mapLayersByName('test2')), 1)
|
||||
self.assertEqual(store.count(), 2)
|
||||
|
||||
# adding more layers should leave existing layers intact
|
||||
l3 = createLayer('test3')
|
||||
l4 = createLayer('test4')
|
||||
self.assertEqual(set(store.addMapLayers([l3, l4])), {l3, l4})
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 1)
|
||||
self.assertEqual(len(store.mapLayersByName('test2')), 1)
|
||||
self.assertEqual(len(store.mapLayersByName('test3')), 1)
|
||||
self.assertEqual(len(store.mapLayersByName('test4')), 1)
|
||||
self.assertEqual(store.count(), 4)
|
||||
|
||||
store.removeAllMapLayers()
|
||||
|
||||
def test_addMapLayersInvalid(self):
|
||||
""" test that invalid map layersd can't be added to store """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
self.assertEqual(store.addMapLayers([QgsVectorLayer("Point?field=x:string", 'test', "xxx")]), [])
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 0)
|
||||
self.assertEqual(store.count(), 0)
|
||||
|
||||
def test_addMapLayersAlreadyAdded(self):
|
||||
""" test that already added layers can't be readded to store """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
l1 = createLayer('test')
|
||||
self.assertEqual(store.addMapLayers([l1]), [l1])
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 1)
|
||||
self.assertEqual(store.count(), 1)
|
||||
self.assertEqual(store.addMapLayers([l1]), [])
|
||||
self.assertEqual(len(store.mapLayersByName('test')), 1)
|
||||
self.assertEqual(store.count(), 1)
|
||||
|
||||
def test_addMapLayersSignals(self):
|
||||
""" test that signals are correctly emitted when adding map layers"""
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
layer_was_added_spy = QSignalSpy(store.layerWasAdded)
|
||||
layers_added_spy = QSignalSpy(store.layersAdded)
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
store.addMapLayers([l1, l2])
|
||||
|
||||
# can't seem to actually test the data which was emitted, so best we can do is test
|
||||
# the signal count
|
||||
self.assertEqual(len(layer_was_added_spy), 2)
|
||||
self.assertEqual(len(layers_added_spy), 1)
|
||||
|
||||
store.addMapLayers([createLayer('test3'), createLayer('test4')])
|
||||
self.assertEqual(len(layer_was_added_spy), 4)
|
||||
self.assertEqual(len(layers_added_spy), 2)
|
||||
|
||||
# try readding a layer already in the store
|
||||
store.addMapLayers([l1, l2])
|
||||
# should be no extra signals emitted
|
||||
self.assertEqual(len(layer_was_added_spy), 4)
|
||||
self.assertEqual(len(layers_added_spy), 2)
|
||||
|
||||
def test_mapLayerById(self):
|
||||
""" test retrieving map layer by ID """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# test no crash with empty store
|
||||
self.assertEqual(store.mapLayer('bad'), None)
|
||||
self.assertEqual(store.mapLayer(None), None)
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
|
||||
store.addMapLayers([l1, l2])
|
||||
|
||||
self.assertEqual(store.mapLayer('bad'), None)
|
||||
self.assertEqual(store.mapLayer(None), None)
|
||||
self.assertEqual(store.mapLayer(l1.id()), l1)
|
||||
self.assertEqual(store.mapLayer(l2.id()), l2)
|
||||
|
||||
def test_mapLayersByName(self):
|
||||
""" test retrieving map layer by name """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# test no crash with empty store
|
||||
self.assertEqual(store.mapLayersByName('bad'), [])
|
||||
self.assertEqual(store.mapLayersByName(None), [])
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
|
||||
store.addMapLayers([l1, l2])
|
||||
|
||||
self.assertEqual(store.mapLayersByName('bad'), [])
|
||||
self.assertEqual(store.mapLayersByName(None), [])
|
||||
self.assertEqual(store.mapLayersByName('test'), [l1])
|
||||
self.assertEqual(store.mapLayersByName('test2'), [l2])
|
||||
|
||||
#duplicate name
|
||||
l3 = createLayer('test')
|
||||
store.addMapLayer(l3)
|
||||
self.assertEqual(set(store.mapLayersByName('test')), {l1, l3})
|
||||
|
||||
def test_mapLayers(self):
|
||||
""" test retrieving map layers list """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# test no crash with empty store
|
||||
self.assertEqual(store.mapLayers(), {})
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
|
||||
store.addMapLayers([l1, l2])
|
||||
|
||||
self.assertEqual(store.mapLayers(), {l1.id(): l1, l2.id(): l2})
|
||||
|
||||
def test_removeMapLayersById(self):
|
||||
""" test removing map layers by ID """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# test no crash with empty store
|
||||
store.removeMapLayersById(['bad'])
|
||||
store.removeMapLayersById([None])
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
l3 = createLayer('test3')
|
||||
|
||||
store.addMapLayers([l1, l2, l3])
|
||||
self.assertEqual(store.count(), 3)
|
||||
|
||||
#remove bad layers
|
||||
store.removeMapLayersById(['bad'])
|
||||
self.assertEqual(store.count(), 3)
|
||||
store.removeMapLayersById([None])
|
||||
self.assertEqual(store.count(), 3)
|
||||
|
||||
# remove valid layers
|
||||
l1_id = l1.id()
|
||||
store.removeMapLayersById([l1_id])
|
||||
self.assertEqual(store.count(), 2)
|
||||
# double remove
|
||||
store.removeMapLayersById([l1_id])
|
||||
self.assertEqual(store.count(), 2)
|
||||
|
||||
# test that layer has been deleted
|
||||
self.assertTrue(sip.isdeleted(l1))
|
||||
|
||||
# remove multiple
|
||||
store.removeMapLayersById([l2.id(), l3.id()])
|
||||
self.assertEqual(store.count(), 0)
|
||||
self.assertTrue(sip.isdeleted(l2))
|
||||
|
||||
# try removing a layer not in the store
|
||||
l4 = createLayer('test4')
|
||||
store.removeMapLayersById([l4.id()])
|
||||
self.assertFalse(sip.isdeleted(l4))
|
||||
|
||||
def test_removeMapLayersByLayer(self):
|
||||
""" test removing map layers by layer"""
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# test no crash with empty store
|
||||
store.removeMapLayers([None])
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
l3 = createLayer('test3')
|
||||
|
||||
store.addMapLayers([l1, l2, l3])
|
||||
self.assertEqual(store.count(), 3)
|
||||
|
||||
#remove bad layers
|
||||
store.removeMapLayers([None])
|
||||
self.assertEqual(store.count(), 3)
|
||||
|
||||
# remove valid layers
|
||||
store.removeMapLayers([l1])
|
||||
self.assertEqual(store.count(), 2)
|
||||
|
||||
# test that layer has been deleted
|
||||
self.assertTrue(sip.isdeleted(l1))
|
||||
|
||||
# remove multiple
|
||||
store.removeMapLayers([l2, l3])
|
||||
self.assertEqual(store.count(), 0)
|
||||
self.assertTrue(sip.isdeleted(l2))
|
||||
self.assertTrue(sip.isdeleted(l3))
|
||||
|
||||
def test_removeMapLayerById(self):
|
||||
""" test removing a map layer by ID """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# test no crash with empty store
|
||||
store.removeMapLayer('bad')
|
||||
store.removeMapLayer(None)
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
|
||||
store.addMapLayers([l1, l2])
|
||||
self.assertEqual(store.count(), 2)
|
||||
|
||||
#remove bad layers
|
||||
store.removeMapLayer('bad')
|
||||
self.assertEqual(store.count(), 2)
|
||||
store.removeMapLayer(None)
|
||||
self.assertEqual(store.count(), 2)
|
||||
|
||||
# remove valid layers
|
||||
l1_id = l1.id()
|
||||
store.removeMapLayer(l1_id)
|
||||
self.assertEqual(store.count(), 1)
|
||||
# double remove
|
||||
store.removeMapLayer(l1_id)
|
||||
self.assertEqual(store.count(), 1)
|
||||
|
||||
# test that layer has been deleted
|
||||
self.assertTrue(sip.isdeleted(l1))
|
||||
|
||||
# remove second layer
|
||||
store.removeMapLayer(l2.id())
|
||||
self.assertEqual(store.count(), 0)
|
||||
self.assertTrue(sip.isdeleted(l2))
|
||||
|
||||
# try removing a layer not in the store
|
||||
l3 = createLayer('test3')
|
||||
store.removeMapLayer(l3.id())
|
||||
self.assertFalse(sip.isdeleted(l3))
|
||||
|
||||
def test_removeMapLayerByLayer(self):
|
||||
""" test removing a map layer by layer """
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# test no crash with empty store
|
||||
store.removeMapLayer('bad')
|
||||
store.removeMapLayer(None)
|
||||
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
|
||||
store.addMapLayers([l1, l2])
|
||||
self.assertEqual(store.count(), 2)
|
||||
|
||||
#remove bad layers
|
||||
store.removeMapLayer(None)
|
||||
self.assertEqual(store.count(), 2)
|
||||
l3 = createLayer('test3')
|
||||
store.removeMapLayer(l3)
|
||||
self.assertEqual(store.count(), 2)
|
||||
|
||||
# remove valid layers
|
||||
store.removeMapLayer(l1)
|
||||
self.assertEqual(store.count(), 1)
|
||||
|
||||
# test that layer has been deleted
|
||||
self.assertTrue(sip.isdeleted(l1))
|
||||
|
||||
# remove second layer
|
||||
store.removeMapLayer(l2)
|
||||
self.assertEqual(store.count(), 0)
|
||||
self.assertTrue(sip.isdeleted(l2))
|
||||
|
||||
# try removing a layer not in the store
|
||||
l3 = createLayer('test3')
|
||||
store.removeMapLayer(l3)
|
||||
self.assertFalse(sip.isdeleted(l3))
|
||||
|
||||
def test_removeAllMapLayers(self):
|
||||
""" test removing all map layers from store """
|
||||
store = QgsMapLayerStore()
|
||||
l1 = createLayer('test')
|
||||
l2 = createLayer('test2')
|
||||
|
||||
store.addMapLayers([l1, l2])
|
||||
self.assertEqual(store.count(), 2)
|
||||
store.removeAllMapLayers()
|
||||
self.assertEqual(store.count(), 0)
|
||||
self.assertEqual(store.mapLayersByName('test'), [])
|
||||
self.assertEqual(store.mapLayersByName('test2'), [])
|
||||
|
||||
def test_addRemoveLayersSignals(self):
|
||||
""" test that signals are correctly emitted when removing map layers"""
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
layers_will_be_removed_spy = QSignalSpy(store.layersWillBeRemoved)
|
||||
layer_will_be_removed_spy_str = QSignalSpy(store.layerWillBeRemoved[str])
|
||||
layer_will_be_removed_spy_layer = QSignalSpy(store.layerWillBeRemoved[QgsMapLayer])
|
||||
layers_removed_spy = QSignalSpy(store.layersRemoved)
|
||||
layer_removed_spy = QSignalSpy(store.layerRemoved)
|
||||
remove_all_spy = QSignalSpy(store.allLayersRemoved)
|
||||
|
||||
l1 = createLayer('l1')
|
||||
l2 = createLayer('l2')
|
||||
l3 = createLayer('l3')
|
||||
l4 = createLayer('l4')
|
||||
store.addMapLayers([l1, l2, l3, l4])
|
||||
|
||||
# remove 1 layer
|
||||
store.removeMapLayer(l1)
|
||||
# can't seem to actually test the data which was emitted, so best we can do is test
|
||||
# the signal count
|
||||
self.assertEqual(len(layers_will_be_removed_spy), 1)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_str), 1)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_layer), 1)
|
||||
self.assertEqual(len(layers_removed_spy), 1)
|
||||
self.assertEqual(len(layer_removed_spy), 1)
|
||||
self.assertEqual(len(remove_all_spy), 0)
|
||||
self.assertEqual(store.count(), 3)
|
||||
|
||||
# remove 2 layers at once
|
||||
store.removeMapLayersById([l2.id(), l3.id()])
|
||||
self.assertEqual(len(layers_will_be_removed_spy), 2)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_str), 3)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_layer), 3)
|
||||
self.assertEqual(len(layers_removed_spy), 2)
|
||||
self.assertEqual(len(layer_removed_spy), 3)
|
||||
self.assertEqual(len(remove_all_spy), 0)
|
||||
self.assertEqual(store.count(), 1)
|
||||
|
||||
# remove all
|
||||
store.removeAllMapLayers()
|
||||
self.assertEqual(len(layers_will_be_removed_spy), 3)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_str), 4)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_layer), 4)
|
||||
self.assertEqual(len(layers_removed_spy), 3)
|
||||
self.assertEqual(len(layer_removed_spy), 4)
|
||||
self.assertEqual(len(remove_all_spy), 1)
|
||||
|
||||
#remove some layers which aren't in the store
|
||||
store.removeMapLayersById(['asdasd'])
|
||||
self.assertEqual(len(layers_will_be_removed_spy), 3)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_str), 4)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_layer), 4)
|
||||
self.assertEqual(len(layers_removed_spy), 3)
|
||||
self.assertEqual(len(layer_removed_spy), 4)
|
||||
self.assertEqual(len(remove_all_spy), 1)
|
||||
|
||||
l5 = createLayer('test5')
|
||||
store.removeMapLayer(l5)
|
||||
self.assertEqual(len(layers_will_be_removed_spy), 3)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_str), 4)
|
||||
self.assertEqual(len(layer_will_be_removed_spy_layer), 4)
|
||||
self.assertEqual(len(layers_removed_spy), 3)
|
||||
self.assertEqual(len(layer_removed_spy), 4)
|
||||
self.assertEqual(len(remove_all_spy), 1)
|
||||
|
||||
def test_RemoveLayerShouldNotSegFault(self):
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# Should not segfault
|
||||
store.removeMapLayersById(['not_exists'])
|
||||
store.removeMapLayer('not_exists2')
|
||||
|
||||
# check also that the removal of an unexistent layer does not insert a null layer
|
||||
for k, layer in list(store.mapLayers().items()):
|
||||
assert(layer is not None)
|
||||
|
||||
def testTakeLayer(self):
|
||||
# test taking ownership of a layer from the store
|
||||
l1 = createLayer('l1')
|
||||
l2 = createLayer('l2')
|
||||
store = QgsMapLayerStore()
|
||||
|
||||
# add one layer to store
|
||||
store.addMapLayer(l1)
|
||||
self.assertEqual(store.mapLayers(), {l1.id(): l1})
|
||||
self.assertEqual(l1.parent(), store)
|
||||
|
||||
# try taking some layers which don't exist in store
|
||||
self.assertFalse(store.takeMapLayer(None))
|
||||
self.assertFalse(store.takeMapLayer(l2))
|
||||
# but l2 should still exist..
|
||||
self.assertTrue(l2.isValid())
|
||||
|
||||
# take layer from store
|
||||
self.assertEqual(store.takeMapLayer(l1), l1)
|
||||
self.assertFalse(store.mapLayers()) # no layers left
|
||||
# but l1 should still exist
|
||||
self.assertTrue(l1.isValid())
|
||||
# layer should have no parent now
|
||||
self.assertFalse(l1.parent())
|
||||
|
||||
# destroy store
|
||||
store = None
|
||||
self.assertTrue(l1.isValid())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
x
Reference in New Issue
Block a user