Skip to content

Commit e711851

Browse files
author
wonder
committed
symbology-ng: updates to symbol layer registry and renderer registry so that they can be used from python.
Added wrappers for these two registries and their metadata classes. git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12769 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 3a72b35 commit e711851

9 files changed

+344
-132
lines changed

python/core/symbology-ng-core.sip

+81-20
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ typedef QList<QgsSymbolV2*> QgsSymbolV2List;
33

44
typedef QList< QPair<QString, QPixmap> > QgsLegendSymbologyList;
55

6+
7+
// this is a workaround for an error in generated code by SIP
8+
// to ensure it will recognize the class name
9+
%ModuleHeaderCode
10+
class QgsRendererV2Widget;
11+
class QgsSymbolLayerV2Widget;
12+
%End
13+
14+
615
///////////////
716

817
/*
@@ -608,31 +617,25 @@ typedef QMap<QString, QString> QgsStringMap;
608617

609618
//////////
610619

611-
//typedef QgsSymbolLayerV2 * ( * QgsSymbolLayerV2CreateFunc )( const QgsStringMap& );
612-
//typedef QgsSymbolLayerV2Widget*( *QgsSymbolLayerV2WidgetFunc )();
620+
class QgsSymbolLayerV2Widget /External/;
613621

614-
615-
class QgsSymbolLayerV2Metadata
622+
class QgsSymbolLayerV2AbstractMetadata
616623
{
617624
%TypeHeaderCode
618625
#include <qgssymbollayerv2registry.h>
619626
%End
620627

621-
public:
622-
/** construct invalid metadata */
623-
QgsSymbolLayerV2Metadata();
624-
625-
/** construct metadata */
626-
// TODO
627-
//QgsSymbolLayerV2Metadata(QString name, QgsSymbolV2::SymbolType type,
628-
// QgsSymbolLayerV2CreateFunc pfCreate,
629-
// QgsSymbolLayerV2WidgetFunc pfWidget);
628+
public:
629+
/** construct metadata */
630+
QgsSymbolLayerV2AbstractMetadata( QString name, QgsSymbolV2::SymbolType type );
630631

631-
QString name() const;
632-
QgsSymbolV2::SymbolType type();
633-
// TODO QgsSymbolLayerV2CreateFunc createFunction() const;
634-
// TODO QgsSymbolLayerV2WidgetFunc widgetFunction() const;
632+
QString name() const;
633+
QgsSymbolV2::SymbolType type() const;
635634

635+
/** create a symbol layer of this type given the map of properties. */
636+
virtual QgsSymbolLayerV2* createSymbolLayer( const QgsStringMap& map ) = 0 /Factory/;
637+
/** create widget for symbol layer of this type. Can return NULL if there's no GUI */
638+
virtual QgsSymbolLayerV2Widget* createSymbolLayerWidget() /Factory/;
636639
};
637640

638641
//////////
@@ -649,13 +652,16 @@ public:
649652
static QgsSymbolLayerV2Registry* instance();
650653

651654
//! return metadata for specified symbol layer
652-
QgsSymbolLayerV2Metadata symbolLayerMetadata(QString name) const;
655+
QgsSymbolLayerV2AbstractMetadata* symbolLayerMetadata(QString name) const;
653656

654657
//! register a new symbol layer type
655-
void addSymbolLayerType(const QgsSymbolLayerV2Metadata& metadata);
658+
void addSymbolLayerType(QgsSymbolLayerV2AbstractMetadata* metadata /Transfer/);
656659

657660
//! create a new instance of symbol layer given symbol layer name and properties
658-
QgsSymbolLayerV2* createSymbolLayer(QString name, const QgsStringMap& properties) const /Factory/;
661+
// TODO: disabled in PyQGIS because if used with symbol layer from Python
662+
// the combination of /Factory/ annotation QgsSymbolLayerV2AbstractMetadata::createSymbolLayer()
663+
// and here is deadly: results in premature deallocation of the symbol layer -> segfaults
664+
//QgsSymbolLayerV2* createSymbolLayer(QString name, const QgsStringMap& properties) const /Factory/;
659665

660666
//! return a list of available symbol layers for a specified symbol type
661667
QStringList symbolLayersForType(QgsSymbolV2::SymbolType type);
@@ -665,6 +671,7 @@ public:
665671

666672
protected:
667673
QgsSymbolLayerV2Registry();
674+
~QgsSymbolLayerV2Registry();
668675

669676
};
670677

@@ -787,3 +794,57 @@ public:
787794
static void rendererV2toV1(QgsVectorLayer* layer);
788795

789796
};
797+
798+
////////////
799+
800+
class QgsRendererV2Widget /External/;
801+
802+
class QgsRendererV2AbstractMetadata
803+
{
804+
%TypeHeaderCode
805+
#include <qgsrendererv2registry.h>
806+
%End
807+
808+
public:
809+
QgsRendererV2AbstractMetadata( QString name, QString visibleName, QString iconName = QString() );
810+
811+
QString name() const;
812+
QString visibleName() const;
813+
QString iconName() const;
814+
815+
/** Return new instance of the renderer given the DOM element. Returns NULL on error.
816+
* Pure virtual function: must be implemented in derived classes. */
817+
virtual QgsFeatureRendererV2* createRenderer( QDomElement& elem ) = 0 /Factory/;
818+
/** Return new instance of settings widget for the renderer. Returns NULL on error. */
819+
virtual QgsRendererV2Widget* createRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) /Factory/;
820+
821+
};
822+
823+
824+
class QgsRendererV2Registry
825+
{
826+
%TypeHeaderCode
827+
#include <qgsrendererv2registry.h>
828+
%End
829+
830+
public:
831+
832+
static QgsRendererV2Registry* instance();
833+
834+
//! add a renderer to registry. Takes ownership of the metadata object.
835+
bool addRenderer( QgsRendererV2AbstractMetadata* metadata /Transfer/ );
836+
837+
//! remove renderer from registry
838+
bool removeRenderer( QString rendererName );
839+
840+
//! get metadata for particular renderer. Returns NULL if not found in registry.
841+
QgsRendererV2AbstractMetadata* rendererMetadata( QString rendererName );
842+
843+
//! return a list of available renderers
844+
QStringList renderersList();
845+
846+
protected:
847+
//! protected constructor
848+
QgsRendererV2Registry();
849+
~QgsRendererV2Registry();
850+
};

python/gui/symbology-ng-gui.sip

+35
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,38 @@ signals:
9696
void symbolModified();
9797

9898
};
99+
100+
101+
102+
class QgsSymbolLayerV2Widget : QWidget
103+
{
104+
%TypeHeaderCode
105+
#include <qgssymbollayerv2widget.h>
106+
%End
107+
108+
public:
109+
QgsSymbolLayerV2Widget( QWidget* parent );
110+
virtual ~QgsSymbolLayerV2Widget();
111+
112+
virtual void setSymbolLayer( QgsSymbolLayerV2* layer ) = 0;
113+
virtual QgsSymbolLayerV2* symbolLayer() = 0;
114+
115+
signals:
116+
void changed();
117+
};
118+
119+
class QgsRendererV2Widget : QWidget
120+
{
121+
%TypeHeaderCode
122+
#include <qgsrendererv2widget.h>
123+
%End
124+
125+
public:
126+
QgsRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style );
127+
128+
virtual ~QgsRendererV2Widget();
129+
130+
//! return pointer to the renderer (no transfer of ownership)
131+
virtual QgsFeatureRendererV2* renderer() = 0;
132+
133+
};

src/core/symbology-ng/qgsrendererv2.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -311,13 +311,11 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::load( QDomElement& element )
311311
// load renderer
312312
QString rendererType = element.attribute( "type" );
313313

314-
QgsRendererV2CreateFunc pfCreate = QgsRendererV2Registry::instance()->rendererMetadata( rendererType ).createFunction();
315-
316-
// unknown renderer type?
317-
if ( pfCreate == NULL )
314+
QgsRendererV2AbstractMetadata* m = QgsRendererV2Registry::instance()->rendererMetadata( rendererType );
315+
if (m == NULL)
318316
return NULL;
319317

320-
QgsFeatureRendererV2* r = pfCreate( element );
318+
QgsFeatureRendererV2* r = m->createRenderer( element );
321319
if ( r )
322320
r->setUsingSymbolLevels( element.attribute( "symbollevels", "0" ).toInt() );
323321

src/core/symbology-ng/qgsrendererv2registry.cpp

+22-15
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,29 @@ QgsRendererV2Registry* QgsRendererV2Registry::mInstance = NULL;
1111
QgsRendererV2Registry::QgsRendererV2Registry()
1212
{
1313
// add default renderers
14-
addRenderer( QgsRendererV2Metadata( "singleSymbol",
14+
addRenderer( new QgsRendererV2Metadata( "singleSymbol",
1515
QObject::tr( "Single Symbol" ),
1616
QgsSingleSymbolRendererV2::create,
1717
"rendererSingleSymbol.png" ) );
18-
addRenderer( QgsRendererV2Metadata( "categorizedSymbol",
18+
addRenderer( new QgsRendererV2Metadata( "categorizedSymbol",
1919
QObject::tr( "Categorized" ),
2020
QgsCategorizedSymbolRendererV2::create,
2121
"rendererCategorizedSymbol.png" ) );
22-
addRenderer( QgsRendererV2Metadata( "graduatedSymbol",
22+
addRenderer( new QgsRendererV2Metadata( "graduatedSymbol",
2323
QObject::tr( "Graduated" ),
2424
QgsGraduatedSymbolRendererV2::create,
2525
"rendererGraduatedSymbol.png" ) );
2626
}
2727

28+
QgsRendererV2Registry::~QgsRendererV2Registry()
29+
{
30+
foreach (QString name, mRenderers.keys())
31+
{
32+
delete mRenderers[name];
33+
}
34+
mRenderers.clear();
35+
}
36+
2837
QgsRendererV2Registry* QgsRendererV2Registry::instance()
2938
{
3039
if ( !mInstance )
@@ -34,34 +43,32 @@ QgsRendererV2Registry* QgsRendererV2Registry::instance()
3443
}
3544

3645

37-
void QgsRendererV2Registry::addRenderer( const QgsRendererV2Metadata& metadata )
46+
bool QgsRendererV2Registry::addRenderer( QgsRendererV2AbstractMetadata* metadata )
3847
{
39-
mRenderers[metadata.name()] = metadata;
40-
mRenderersOrder << metadata.name();
48+
if (metadata == NULL || mRenderers.contains(metadata->name()) )
49+
return false;
50+
51+
mRenderers[metadata->name()] = metadata;
52+
mRenderersOrder << metadata->name();
53+
return true;
4154
}
4255

4356
bool QgsRendererV2Registry::removeRenderer( QString rendererName )
4457
{
4558
if ( !mRenderers.contains( rendererName ) )
4659
return false;
60+
61+
delete mRenderers[rendererName];
4762
mRenderers.remove( rendererName );
4863
mRenderersOrder.removeAll( rendererName );
4964
return true;
5065
}
5166

52-
QgsRendererV2Metadata QgsRendererV2Registry::rendererMetadata( QString rendererName )
67+
QgsRendererV2AbstractMetadata* QgsRendererV2Registry::rendererMetadata( QString rendererName )
5368
{
5469
return mRenderers.value( rendererName );
5570
}
5671

57-
bool QgsRendererV2Registry::setRendererWidgetFunction( QString name, QgsRendererV2WidgetFunc f )
58-
{
59-
if ( !mRenderers.contains( name ) )
60-
return false;
61-
mRenderers[name].setWidgetFunction( f );
62-
return true;
63-
}
64-
6572
QStringList QgsRendererV2Registry::renderersList()
6673
{
6774
return mRenderersOrder;

src/core/symbology-ng/qgsrendererv2registry.h

+48-22
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,69 @@ class QgsVectorLayer;
1010
class QgsStyleV2;
1111
class QgsRendererV2Widget;
1212

13+
/**
14+
Stores metadata about one renderer class.
15+
16+
@note It's necessary to implement createRenderer() function.
17+
In C++ you can use QgsRendererV2Metadata convenience class.
18+
*/
19+
class CORE_EXPORT QgsRendererV2AbstractMetadata
20+
{
21+
public:
22+
QgsRendererV2AbstractMetadata( QString name, QString visibleName, QString iconName = QString() )
23+
: mName( name ), mVisibleName( visibleName ), mIconName( iconName ) {}
24+
25+
QString name() const { return mName; }
26+
QString visibleName() const { return mVisibleName; }
27+
QString iconName() const { return mIconName; }
28+
29+
/** Return new instance of the renderer given the DOM element. Returns NULL on error.
30+
* Pure virtual function: must be implemented in derived classes. */
31+
virtual QgsFeatureRendererV2* createRenderer( QDomElement& elem ) = 0;
32+
/** Return new instance of settings widget for the renderer. Returns NULL on error. */
33+
virtual QgsRendererV2Widget* createRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
34+
{ return NULL; }
35+
36+
protected:
37+
//! name used within QGIS for identification (the same what renderer's type() returns)
38+
QString mName;
39+
//! name visible for users (translatable)
40+
QString mVisibleName;
41+
//! icon to be shown in the renderer properties dialog
42+
QString mIconName;
43+
};
44+
45+
1346
typedef QgsFeatureRendererV2*( *QgsRendererV2CreateFunc )( QDomElement& );
1447
typedef QgsRendererV2Widget*( *QgsRendererV2WidgetFunc )( QgsVectorLayer*, QgsStyleV2*, QgsFeatureRendererV2* );
1548

16-
class CORE_EXPORT QgsRendererV2Metadata
49+
/**
50+
Convenience metadata class that uses static functions to create renderer and its widget.
51+
*/
52+
class CORE_EXPORT QgsRendererV2Metadata : public QgsRendererV2AbstractMetadata
1753
{
1854
public:
19-
/** construct invalid metadata */
20-
QgsRendererV2Metadata()
21-
: mName(), mVisibleName(), mCreateFunc( NULL ), mIconName(), mWidgetFunc( NULL ) {}
2255

2356
/** construct metadata */
2457
QgsRendererV2Metadata( QString name,
2558
QString visibleName,
2659
QgsRendererV2CreateFunc pfCreate,
2760
QString iconName = QString(),
2861
QgsRendererV2WidgetFunc pfWidget = NULL )
29-
: mName( name ), mVisibleName( visibleName ), mCreateFunc( pfCreate ), mIconName( iconName ), mWidgetFunc( pfWidget ) {}
62+
: QgsRendererV2AbstractMetadata( name, visibleName, iconName ), mCreateFunc( pfCreate ), mWidgetFunc( pfWidget ) {}
63+
64+
virtual QgsFeatureRendererV2* createRenderer( QDomElement& elem ) { return mCreateFunc ? mCreateFunc(elem):NULL; }
65+
virtual QgsRendererV2Widget* createRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
66+
{ return mWidgetFunc ? mWidgetFunc(layer, style, renderer) : NULL; }
3067

31-
QString name() const { return mName; }
32-
QString visibleName() const { return mVisibleName; }
33-
QString iconName() const { return mIconName; }
3468
QgsRendererV2CreateFunc createFunction() const { return mCreateFunc; }
3569
QgsRendererV2WidgetFunc widgetFunction() const { return mWidgetFunc; }
3670

3771
void setWidgetFunction( QgsRendererV2WidgetFunc f ) { mWidgetFunc = f; }
3872

3973
protected:
40-
//! name used within QGIS for identification (the same what renderer's type() returns)
41-
QString mName;
42-
//! name visible for users (translatable)
43-
QString mVisibleName;
4474
//! pointer to function that creates an instance of the renderer when loading project / style
4575
QgsRendererV2CreateFunc mCreateFunc;
46-
//! icon to be shown in the renderer properties dialog
47-
QString mIconName;
4876
//! pointer to function that creates a widget for configuration of renderer's params
4977
QgsRendererV2WidgetFunc mWidgetFunc;
5078
};
@@ -60,28 +88,26 @@ class CORE_EXPORT QgsRendererV2Registry
6088

6189
static QgsRendererV2Registry* instance();
6290

63-
//! add a renderer to registry
64-
void addRenderer( const QgsRendererV2Metadata& metadata );
91+
//! add a renderer to registry. Takes ownership of the metadata object.
92+
bool addRenderer( QgsRendererV2AbstractMetadata* metadata );
6593

6694
//! remove renderer from registry
6795
bool removeRenderer( QString rendererName );
6896

69-
//! get factory method for particular renderer
70-
QgsRendererV2Metadata rendererMetadata( QString rendererName );
71-
72-
//! assign a widget factory to particular renderer
73-
bool setRendererWidgetFunction( QString name, QgsRendererV2WidgetFunc f );
97+
//! get metadata for particular renderer. Returns NULL if not found in registry.
98+
QgsRendererV2AbstractMetadata* rendererMetadata( QString rendererName );
7499

75100
//! return a list of available renderers
76101
QStringList renderersList();
77102

78103
protected:
79104
//! protected constructor
80105
QgsRendererV2Registry();
106+
~QgsRendererV2Registry();
81107

82108
static QgsRendererV2Registry* mInstance;
83109

84-
QMap<QString, QgsRendererV2Metadata> mRenderers;
110+
QMap<QString, QgsRendererV2AbstractMetadata*> mRenderers;
85111

86112
//! list to keep order in which renderers have been added
87113
QStringList mRenderersOrder;

0 commit comments

Comments
 (0)