diff --git a/python/core/symbology-ng/qgsrendererv2registry.sip b/python/core/symbology-ng/qgsrendererv2registry.sip index 738921e3e2d..ae189e8e499 100644 --- a/python/core/symbology-ng/qgsrendererv2registry.sip +++ b/python/core/symbology-ng/qgsrendererv2registry.sip @@ -13,6 +13,19 @@ class QgsRendererV2AbstractMetadata %End public: + + + //! Layer types the renderer is compatible with + //! @note added in QGIS 2.16 + enum LayerType + { + PointLayer, //!< Compatible with point layers + LineLayer, //!< Compatible with line layers + PolygonLayer, //!< Compatible with polygon layers + All, //!< Compatible with all vector layers + }; + typedef QFlags LayerTypes; + QgsRendererV2AbstractMetadata( const QString& name, const QString& visibleName, const QIcon& icon = QIcon() ); virtual ~QgsRendererV2AbstractMetadata(); @@ -22,6 +35,11 @@ class QgsRendererV2AbstractMetadata QIcon icon() const; void setIcon( const QIcon& icon ); + /** Returns flags indicating the types of layer the renderer is compatible with. + * @note added in QGIS 2.16 + */ + virtual QgsRendererV2AbstractMetadata::LayerTypes compatibleLayerTypes() const; + /** Return new instance of the renderer given the DOM element. Returns NULL on error. * Pure virtual function: must be implemented in derived classes. */ virtual QgsFeatureRendererV2* createRenderer( QDomElement& elem ) = 0 /Factory/; @@ -37,6 +55,8 @@ class QgsRendererV2AbstractMetadata virtual QgsFeatureRendererV2* createRendererFromSld( QDomElement& elem, QGis::GeometryType geomType ) /Factory/; }; +QFlags operator|(QgsRendererV2AbstractMetadata::LayerType f1, QFlags f2); + /** Convenience metadata class that uses static functions to create renderer and its widget. */ @@ -55,15 +75,19 @@ class QgsRendererV2Metadata : QgsRendererV2AbstractMetadata // QgsFeatureRendererV2* (*)( QDomElement&, QGis::GeometryType geomType ) createFromSldFunction() const; // void setWidgetFunction( QgsRendererV2WidgetFunc f ); + virtual QgsRendererV2AbstractMetadata::LayerTypes compatibleLayerTypes() const; + private: QgsRendererV2Metadata(); // pretend this is private }; -/** - Registry of renderers. - - This is a singleton, renderers can be added / removed at any time +/** \ingroup core + * \class QgsRendererV2Registry + * \brief Registry of renderers. + * + * This is a singleton, renderers can be added / removed at any time */ + class QgsRendererV2Registry { %TypeHeaderCode @@ -72,19 +96,33 @@ class QgsRendererV2Registry public: + //! Returns a pointer to the QgsRendererV2Registry singleton static QgsRendererV2Registry* instance(); - //! add a renderer to registry. Takes ownership of the metadata object. + //! Adds a renderer to the registry. Takes ownership of the metadata object. + //! @param metadata renderer metadata + //! @returns true if renderer was added successfully, or false if renderer could not + //! be added (eg a renderer with a duplicate name already exists) bool addRenderer( QgsRendererV2AbstractMetadata* metadata /Transfer/ ); - //! remove renderer from registry + //! Removes a renderer from registry. + //! @param rendererName name of renderer to remove from registry + //! @returns true if renderer was sucessfully removed, or false if matching + //! renderer could not be found bool removeRenderer( const QString& rendererName ); - //! get metadata for particular renderer. Returns NULL if not found in registry. + //! Returns the metadata for a specified renderer. Returns NULL if a matching + //! renderer was not found in the registry. QgsRendererV2AbstractMetadata* rendererMetadata( const QString& rendererName ); - //! return a list of available renderers - QStringList renderersList(); + //! Returns a list of available renderers. + //! @param layerTypes flags to filter the renderers by compatible layer types + QStringList renderersList( QgsRendererV2AbstractMetadata::LayerTypes layerTypes = QgsRendererV2AbstractMetadata::All ) const; + + //! Returns a list of available renderers which are compatible with a specified layer. + //! @param layer vector layer + //! @note added in QGIS 2.16 + QStringList renderersList( const QgsVectorLayer* layer ) const; protected: //! protected constructor @@ -93,5 +131,6 @@ class QgsRendererV2Registry private: QgsRendererV2Registry( const QgsRendererV2Registry& rh ); + //QgsRendererV2Registry& operator=( const QgsRendererV2Registry& rh ); }; diff --git a/src/core/symbology-ng/qgsrendererv2registry.cpp b/src/core/symbology-ng/qgsrendererv2registry.cpp index c32e763a1a6..82ccaa653e5 100644 --- a/src/core/symbology-ng/qgsrendererv2registry.cpp +++ b/src/core/symbology-ng/qgsrendererv2registry.cpp @@ -24,6 +24,7 @@ #include "qgsheatmaprenderer.h" #include "qgs25drenderer.h" #include "qgsnullsymbolrenderer.h" +#include "qgsvectorlayer.h" QgsRendererV2Registry::QgsRendererV2Registry() { @@ -52,20 +53,32 @@ QgsRendererV2Registry::QgsRendererV2Registry() addRenderer( new QgsRendererV2Metadata( "pointDisplacement", QObject::tr( "Point displacement" ), - QgsPointDisplacementRenderer::create ) ); + QgsPointDisplacementRenderer::create, + QIcon(), + nullptr, + QgsRendererV2AbstractMetadata::PointLayer ) ); addRenderer( new QgsRendererV2Metadata( "invertedPolygonRenderer", QObject::tr( "Inverted polygons" ), - QgsInvertedPolygonRenderer::create ) ); + QgsInvertedPolygonRenderer::create, + QIcon(), + nullptr, + QgsRendererV2AbstractMetadata::PolygonLayer ) ); addRenderer( new QgsRendererV2Metadata( "heatmapRenderer", QObject::tr( "Heatmap" ), - QgsHeatmapRenderer::create ) ); + QgsHeatmapRenderer::create, + QIcon(), + nullptr, + QgsRendererV2AbstractMetadata::PointLayer ) ); addRenderer( new QgsRendererV2Metadata( "25dRenderer", QObject::tr( "2.5 D" ), - Qgs25DRenderer::create ) ); + Qgs25DRenderer::create, + QIcon(), + nullptr, + QgsRendererV2AbstractMetadata::PolygonLayer ) ); } QgsRendererV2Registry::~QgsRendererV2Registry() @@ -108,7 +121,39 @@ QgsRendererV2AbstractMetadata* QgsRendererV2Registry::rendererMetadata( const QS QgsRendererV2Metadata::~QgsRendererV2Metadata() {} -QStringList QgsRendererV2Registry::renderersList() +QStringList QgsRendererV2Registry::renderersList( QgsRendererV2AbstractMetadata::LayerTypes layerTypes ) const { - return mRenderersOrder; + QStringList renderers; + Q_FOREACH ( const QString& renderer, mRenderersOrder ) + { + if ( mRenderers.value( renderer )->compatibleLayerTypes() & layerTypes ) + renderers << renderer; + } + return renderers; +} + +QStringList QgsRendererV2Registry::renderersList( const QgsVectorLayer* layer ) const +{ + QgsRendererV2AbstractMetadata::LayerType layerType = QgsRendererV2AbstractMetadata::All; + + switch ( layer->geometryType() ) + { + case QGis::Point: + layerType = QgsRendererV2AbstractMetadata::PointLayer; + break; + + case QGis::Line: + layerType = QgsRendererV2AbstractMetadata::LineLayer; + break; + + case QGis::Polygon: + layerType = QgsRendererV2AbstractMetadata::PolygonLayer; + break; + + case QGis::UnknownGeometry: + case QGis::NoGeometry: + break; + } + + return renderersList( layerType ); } diff --git a/src/core/symbology-ng/qgsrendererv2registry.h b/src/core/symbology-ng/qgsrendererv2registry.h index 5f03e58d9f6..4e0acbb1568 100644 --- a/src/core/symbology-ng/qgsrendererv2registry.h +++ b/src/core/symbology-ng/qgsrendererv2registry.h @@ -36,6 +36,18 @@ class QgsRendererV2Widget; class CORE_EXPORT QgsRendererV2AbstractMetadata { public: + + //! Layer types the renderer is compatible with + //! @note added in QGIS 2.16 + enum LayerType + { + PointLayer = 1, //!< Compatible with point layers + LineLayer = 2, //!< Compatible with line layers + PolygonLayer = 4, //!< Compatible with polygon layers + All = PointLayer | LineLayer | PolygonLayer, //!< Compatible with all vector layers + }; + Q_DECLARE_FLAGS( LayerTypes, LayerType ) + QgsRendererV2AbstractMetadata( const QString& name, const QString& visibleName, const QIcon& icon = QIcon() ) : mName( name ) , mVisibleName( visibleName ) @@ -49,6 +61,11 @@ class CORE_EXPORT QgsRendererV2AbstractMetadata QIcon icon() const { return mIcon; } void setIcon( const QIcon& icon ) { mIcon = icon; } + /** Returns flags indicating the types of layer the renderer is compatible with. + * @note added in QGIS 2.16 + */ + virtual LayerTypes compatibleLayerTypes() const { return All; } + /** Return new instance of the renderer given the DOM element. Returns NULL on error. * Pure virtual function: must be implemented in derived classes. */ virtual QgsFeatureRendererV2* createRenderer( QDomElement& elem ) = 0; @@ -75,6 +92,9 @@ class CORE_EXPORT QgsRendererV2AbstractMetadata }; +Q_DECLARE_OPERATORS_FOR_FLAGS( QgsRendererV2AbstractMetadata::LayerTypes ) + + typedef QgsFeatureRendererV2*( *QgsRendererV2CreateFunc )( QDomElement& ); typedef QgsRendererV2Widget*( *QgsRendererV2WidgetFunc )( QgsVectorLayer*, QgsStyleV2*, QgsFeatureRendererV2* ); typedef QgsFeatureRendererV2*( *QgsRendererV2CreateFromSldFunc )( QDomElement&, QGis::GeometryType geomType ); @@ -92,11 +112,13 @@ class CORE_EXPORT QgsRendererV2Metadata : public QgsRendererV2AbstractMetadata const QString& visibleName, QgsRendererV2CreateFunc pfCreate, const QIcon& icon = QIcon(), - QgsRendererV2WidgetFunc pfWidget = nullptr ) + QgsRendererV2WidgetFunc pfWidget = nullptr, + QgsRendererV2AbstractMetadata::LayerTypes layerTypes = QgsRendererV2AbstractMetadata::All ) : QgsRendererV2AbstractMetadata( name, visibleName, icon ) , mCreateFunc( pfCreate ) , mWidgetFunc( pfWidget ) , mCreateFromSldFunc( nullptr ) + , mLayerTypes( layerTypes ) {} //! @note not available in python bindings @@ -105,11 +127,13 @@ class CORE_EXPORT QgsRendererV2Metadata : public QgsRendererV2AbstractMetadata QgsRendererV2CreateFunc pfCreate, QgsRendererV2CreateFromSldFunc pfCreateFromSld, const QIcon& icon = QIcon(), - QgsRendererV2WidgetFunc pfWidget = nullptr ) + QgsRendererV2WidgetFunc pfWidget = nullptr, + QgsRendererV2AbstractMetadata::LayerTypes layerTypes = QgsRendererV2AbstractMetadata::All ) : QgsRendererV2AbstractMetadata( name, visibleName, icon ) , mCreateFunc( pfCreate ) , mWidgetFunc( pfWidget ) , mCreateFromSldFunc( pfCreateFromSld ) + , mLayerTypes( layerTypes ) {} virtual ~QgsRendererV2Metadata(); @@ -130,6 +154,8 @@ class CORE_EXPORT QgsRendererV2Metadata : public QgsRendererV2AbstractMetadata //! @note not available in python bindings void setWidgetFunction( QgsRendererV2WidgetFunc f ) { mWidgetFunc = f; } + virtual QgsRendererV2AbstractMetadata::LayerTypes compatibleLayerTypes() const override { return mLayerTypes; } + protected: //! pointer to function that creates an instance of the renderer when loading project / style QgsRendererV2CreateFunc mCreateFunc; @@ -137,39 +163,61 @@ class CORE_EXPORT QgsRendererV2Metadata : public QgsRendererV2AbstractMetadata QgsRendererV2WidgetFunc mWidgetFunc; //! pointer to function that creates an instance of the renderer from SLD QgsRendererV2CreateFromSldFunc mCreateFromSldFunc; + + private: + + QgsRendererV2AbstractMetadata::LayerTypes mLayerTypes; }; -/** - Registry of renderers. - This is a singleton, renderers can be added / removed at any time +/** \ingroup core + * \class QgsRendererV2Registry + * \brief Registry of renderers. + * + * This is a singleton, renderers can be added / removed at any time */ + class CORE_EXPORT QgsRendererV2Registry { public: + //! Returns a pointer to the QgsRendererV2Registry singleton static QgsRendererV2Registry* instance(); - //! add a renderer to registry. Takes ownership of the metadata object. + //! Adds a renderer to the registry. Takes ownership of the metadata object. + //! @param metadata renderer metadata + //! @returns true if renderer was added successfully, or false if renderer could not + //! be added (eg a renderer with a duplicate name already exists) bool addRenderer( QgsRendererV2AbstractMetadata* metadata ); - //! remove renderer from registry + //! Removes a renderer from registry. + //! @param rendererName name of renderer to remove from registry + //! @returns true if renderer was sucessfully removed, or false if matching + //! renderer could not be found bool removeRenderer( const QString& rendererName ); - //! get metadata for particular renderer. Returns NULL if not found in registry. + //! Returns the metadata for a specified renderer. Returns NULL if a matching + //! renderer was not found in the registry. QgsRendererV2AbstractMetadata* rendererMetadata( const QString& rendererName ); - //! return a list of available renderers - QStringList renderersList(); + //! Returns a list of available renderers. + //! @param layerTypes flags to filter the renderers by compatible layer types + QStringList renderersList( QgsRendererV2AbstractMetadata::LayerTypes layerTypes = QgsRendererV2AbstractMetadata::All ) const; + + //! Returns a list of available renderers which are compatible with a specified layer. + //! @param layer vector layer + //! @note added in QGIS 2.16 + QStringList renderersList( const QgsVectorLayer* layer ) const; protected: //! protected constructor QgsRendererV2Registry(); ~QgsRendererV2Registry(); + //! Map of name to renderer QMap mRenderers; - //! list to keep order in which renderers have been added + //! List of renderers, maintained in the order that they have been added QStringList mRenderersOrder; private: diff --git a/src/gui/symbology-ng/qgsinvertedpolygonrendererwidget.cpp b/src/gui/symbology-ng/qgsinvertedpolygonrendererwidget.cpp index 93b470263d7..6d9d184e6c3 100644 --- a/src/gui/symbology-ng/qgsinvertedpolygonrendererwidget.cpp +++ b/src/gui/symbology-ng/qgsinvertedpolygonrendererwidget.cpp @@ -69,14 +69,13 @@ QgsInvertedPolygonRendererWidget::QgsInvertedPolygonRendererWidget( QgsVectorLay int currentEmbeddedIdx = 0; //insert possible renderer types - QStringList rendererList = QgsRendererV2Registry::instance()->renderersList(); + QStringList rendererList = QgsRendererV2Registry::instance()->renderersList( QgsRendererV2AbstractMetadata::PolygonLayer ); QStringList::const_iterator it = rendererList.constBegin(); int idx = 0; mRendererComboBox->blockSignals( true ); for ( ; it != rendererList.constEnd(); ++it, ++idx ) { - if (( *it != "invertedPolygonRenderer" ) && //< an inverted renderer cannot contain another inverted renderer - ( *it != "pointDisplacement" ) ) //< an inverted renderer can only contain a polygon renderer + if ( *it != "invertedPolygonRenderer" ) //< an inverted renderer cannot contain another inverted renderer { QgsRendererV2AbstractMetadata* m = QgsRendererV2Registry::instance()->rendererMetadata( *it ); mRendererComboBox->addItem( m->icon(), m->visibleName(), /* data */ *it ); diff --git a/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp b/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp index 02d4628a583..3e2c705dbf0 100644 --- a/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp +++ b/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp @@ -87,11 +87,11 @@ QgsPointDisplacementRendererWidget::QgsPointDisplacementRendererWidget( QgsVecto } //insert possible renderer types - QStringList rendererList = QgsRendererV2Registry::instance()->renderersList(); + QStringList rendererList = QgsRendererV2Registry::instance()->renderersList( QgsRendererV2AbstractMetadata::PointLayer ); QStringList::const_iterator it = rendererList.constBegin(); for ( ; it != rendererList.constEnd(); ++it ) { - if ( *it != "pointDisplacement" && *it != "heatmapRenderer" && *it != "invertedPolygonRenderer" ) + if ( *it != "pointDisplacement" ) { QgsRendererV2AbstractMetadata* m = QgsRendererV2Registry::instance()->rendererMetadata( *it ); mRendererComboBox->addItem( m->icon(), m->visibleName(), *it ); diff --git a/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp b/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp index cdd3a9124ea..331f6239d60 100644 --- a/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp +++ b/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp @@ -100,7 +100,7 @@ QgsRendererV2PropertiesDialog::QgsRendererV2PropertiesDialog( QgsVectorLayer* la _initRendererWidgetFunctions(); QgsRendererV2Registry* reg = QgsRendererV2Registry::instance(); - QStringList renderers = reg->renderersList(); + QStringList renderers = reg->renderersList( mLayer ); Q_FOREACH ( const QString& name, renderers ) { QgsRendererV2AbstractMetadata* m = reg->rendererMetadata( name ); diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index 010c00f5412..84622ece0ce 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -68,6 +68,7 @@ ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py) ADD_PYTHON_TEST(PyQgsRectangle test_qgsrectangle.py) ADD_PYTHON_TEST(PyQgsRelation test_qgsrelation.py) ADD_PYTHON_TEST(PyQgsRelationManager test_qgsrelationmanager.py) +ADD_PYTHON_TEST(PyQgsRendererV2 test_qgsrendererv2.py) ADD_PYTHON_TEST(PyQgsRulebasedRenderer test_qgsrulebasedrenderer.py) ADD_PYTHON_TEST(PyQgsSingleSymbolRenderer test_qgssinglesymbolrenderer.py) ADD_PYTHON_TEST(PyQgsShapefileProvider test_provider_shapefile.py) diff --git a/tests/src/python/test_qgsrendererv2.py b/tests/src/python/test_qgsrendererv2.py new file mode 100644 index 00000000000..f86791cfff8 --- /dev/null +++ b/tests/src/python/test_qgsrendererv2.py @@ -0,0 +1,176 @@ +# -*- coding: utf-8 -*- +"""QGIS Unit tests for QgsFeatureRendererV2. + +.. 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__ = '07/06/2016' +__copyright__ = 'Copyright 2016, The QGIS Project' +# This will get replaced with a git SHA1 when you do a git archive +__revision__ = '$Format:%H$' + +import qgis # NOQA + +from qgis.core import (QgsFeatureRendererV2, + QgsRendererV2AbstractMetadata, + QgsRendererV2Registry, + QgsVectorLayer + ) +from qgis.testing import start_app, unittest + +start_app() + + +def createReferencingLayer(): + layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer", + "referencinglayer", "memory") + pr = layer.dataProvider() + f1 = QgsFeature() + f1.setFields(layer.pendingFields()) + f1.setAttributes(["test1", 123]) + f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200))) + f2 = QgsFeature() + f2.setFields(layer.pendingFields()) + f2.setAttributes(["test2", 123]) + f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(101, 201))) + assert pr.addFeatures([f1, f2]) + return layer + + +class TestRenderer(QgsRendererV2AbstractMetadata): + + def __init__(self, name, layerTypes=QgsRendererV2AbstractMetadata.All): + QgsRendererV2AbstractMetadata.__init__(self, name, "Test Renderer") + self.types = layerTypes + + def compatibleLayerTypes(self): + return self.types + + def createRenderer(self, elem): + return None + + +def clearRegistry(): + # clear registry to start with + for r in QgsRendererV2Registry.instance().renderersList(): + if r == 'singleSymbol': + continue + QgsRendererV2Registry.instance().removeRenderer(r) + + +class TestQgsRendererV2Registry(unittest.TestCase): + + def testInstance(self): + """ test retrieving global instance """ + self.assertTrue(QgsRendererV2Registry.instance()) + + # instance should be initially populated with some default renderers + self.assertTrue('singleSymbol' in QgsRendererV2Registry.instance().renderersList()) + + # register a renderer to the singleton, to test that the same instance is always returned + self.assertFalse('test' in QgsRendererV2Registry.instance().renderersList()) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(TestRenderer('test'))) + self.assertTrue('test' in QgsRendererV2Registry.instance().renderersList()) + + def testAddRenderer(self): + """ test adding renderers to registry """ + clearRegistry() + + # add a renderer + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(TestRenderer('test2'))) + self.assertTrue('test2' in QgsRendererV2Registry.instance().renderersList()) + + # try adding it again - should be rejected due to duplicate name + self.assertFalse(QgsRendererV2Registry.instance().addRenderer(TestRenderer('test2'))) + self.assertTrue('test2' in QgsRendererV2Registry.instance().renderersList()) + + def testRemoveRenderer(self): + """ test removing renderers from registry """ + clearRegistry() + + # try removing non-existant renderer + self.assertFalse(QgsRendererV2Registry.instance().removeRenderer('test3')) + + # now add it + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(TestRenderer('test3'))) + self.assertTrue('test3' in QgsRendererV2Registry.instance().renderersList()) + + # try removing it again - should be ok this time + self.assertTrue(QgsRendererV2Registry.instance().removeRenderer('test3')) + self.assertFalse('test3' in QgsRendererV2Registry.instance().renderersList()) + + # try removing it again - should be false since already removed + self.assertFalse(QgsRendererV2Registry.instance().removeRenderer('test3')) + + def testRetrieveRenderer(self): + """ test retrieving renderer by name """ + clearRegistry() + + # try non-existant renderer + self.assertFalse(QgsRendererV2Registry.instance().rendererMetadata('test4')) + + # now add it + r = TestRenderer('test4') + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r)) + + # try retrieving it + result = QgsRendererV2Registry.instance().rendererMetadata('test4') + self.assertTrue(result) + self.assertEqual(result.name(), 'test4') + + def testRenderersList(self): + """ test getting list of renderers from registry """ + clearRegistry() + + self.assertEqual(QgsRendererV2Registry.instance().renderersList(), ['singleSymbol']) + + # add some renderers + r1 = TestRenderer('test1', QgsRendererV2AbstractMetadata.PointLayer) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r1)) + r2 = TestRenderer('test2', QgsRendererV2AbstractMetadata.LineLayer) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r2)) + r3 = TestRenderer('test3', QgsRendererV2AbstractMetadata.PolygonLayer) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r3)) + r4 = TestRenderer('test4', QgsRendererV2AbstractMetadata.PointLayer | QgsRendererV2AbstractMetadata.LineLayer) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r4)) + + self.assertEqual(QgsRendererV2Registry.instance().renderersList(), ['singleSymbol', 'test1', 'test2', 'test3', 'test4']) + + # test subsets + self.assertEqual(QgsRendererV2Registry.instance().renderersList(QgsRendererV2AbstractMetadata.PointLayer), ['singleSymbol', 'test1', 'test4']) + self.assertEqual(QgsRendererV2Registry.instance().renderersList(QgsRendererV2AbstractMetadata.LineLayer), ['singleSymbol', 'test2', 'test4']) + self.assertEqual(QgsRendererV2Registry.instance().renderersList(QgsRendererV2AbstractMetadata.PolygonLayer), ['singleSymbol', 'test3']) + self.assertEqual(QgsRendererV2Registry.instance().renderersList(QgsRendererV2AbstractMetadata.LineLayer | QgsRendererV2AbstractMetadata.PolygonLayer), ['singleSymbol', 'test2', 'test3', 'test4']) + + def testRenderersByLayerType(self): + """ test retrieving compatible renderers by layer type """ + clearRegistry() + + # add some renderers + r1 = TestRenderer('test1', QgsRendererV2AbstractMetadata.PointLayer) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r1)) + r2 = TestRenderer('test2', QgsRendererV2AbstractMetadata.LineLayer) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r2)) + r3 = TestRenderer('test3', QgsRendererV2AbstractMetadata.PolygonLayer) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r3)) + r4 = TestRenderer('test4', QgsRendererV2AbstractMetadata.PointLayer | QgsRendererV2AbstractMetadata.LineLayer) + self.assertTrue(QgsRendererV2Registry.instance().addRenderer(r4)) + + # make some layers + point_layer = QgsVectorLayer("Point?field=fldtxt:string", + "pointlayer", "memory") + line_layer = QgsVectorLayer("LineString?field=fldtxt:string", + "linelayer", "memory") + polygon_layer = QgsVectorLayer("Polygon?field=fldtxt:string", + "polylayer", "memory") + + # test subsets + self.assertEqual(QgsRendererV2Registry.instance().renderersList(point_layer), ['singleSymbol', 'test1', 'test4']) + self.assertEqual(QgsRendererV2Registry.instance().renderersList(line_layer), ['singleSymbol', 'test2', 'test4']) + self.assertEqual(QgsRendererV2Registry.instance().renderersList(polygon_layer), ['singleSymbol', 'test3']) + +if __name__ == '__main__': + unittest.main()