[QGIS Commit] r12769 - in trunk/qgis: python/core python/gui
src/core/symbology-ng src/gui/symbology-ng
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Fri Jan 15 12:54:18 EST 2010
Author: wonder
Date: 2010-01-15 12:54:18 -0500 (Fri, 15 Jan 2010)
New Revision: 12769
Modified:
trunk/qgis/python/core/symbology-ng-core.sip
trunk/qgis/python/gui/symbology-ng-gui.sip
trunk/qgis/src/core/symbology-ng/qgsrendererv2.cpp
trunk/qgis/src/core/symbology-ng/qgsrendererv2registry.cpp
trunk/qgis/src/core/symbology-ng/qgsrendererv2registry.h
trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.cpp
trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.h
trunk/qgis/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp
trunk/qgis/src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp
Log:
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.
Modified: trunk/qgis/python/core/symbology-ng-core.sip
===================================================================
--- trunk/qgis/python/core/symbology-ng-core.sip 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/python/core/symbology-ng-core.sip 2010-01-15 17:54:18 UTC (rev 12769)
@@ -3,6 +3,15 @@
typedef QList< QPair<QString, QPixmap> > QgsLegendSymbologyList;
+
+// this is a workaround for an error in generated code by SIP
+// to ensure it will recognize the class name
+%ModuleHeaderCode
+class QgsRendererV2Widget;
+class QgsSymbolLayerV2Widget;
+%End
+
+
///////////////
/*
@@ -608,31 +617,25 @@
//////////
-//typedef QgsSymbolLayerV2 * ( * QgsSymbolLayerV2CreateFunc )( const QgsStringMap& );
-//typedef QgsSymbolLayerV2Widget*( *QgsSymbolLayerV2WidgetFunc )();
+class QgsSymbolLayerV2Widget /External/;
-
-class QgsSymbolLayerV2Metadata
+class QgsSymbolLayerV2AbstractMetadata
{
%TypeHeaderCode
#include <qgssymbollayerv2registry.h>
%End
-public:
- /** construct invalid metadata */
- QgsSymbolLayerV2Metadata();
+ public:
+ /** construct metadata */
+ QgsSymbolLayerV2AbstractMetadata( QString name, QgsSymbolV2::SymbolType type );
- /** construct metadata */
- // TODO
- //QgsSymbolLayerV2Metadata(QString name, QgsSymbolV2::SymbolType type,
- // QgsSymbolLayerV2CreateFunc pfCreate,
- // QgsSymbolLayerV2WidgetFunc pfWidget);
+ QString name() const;
+ QgsSymbolV2::SymbolType type() const;
- QString name() const;
- QgsSymbolV2::SymbolType type();
- // TODO QgsSymbolLayerV2CreateFunc createFunction() const;
- // TODO QgsSymbolLayerV2WidgetFunc widgetFunction() const;
-
+ /** create a symbol layer of this type given the map of properties. */
+ virtual QgsSymbolLayerV2* createSymbolLayer( const QgsStringMap& map ) = 0 /Factory/;
+ /** create widget for symbol layer of this type. Can return NULL if there's no GUI */
+ virtual QgsSymbolLayerV2Widget* createSymbolLayerWidget() /Factory/;
};
//////////
@@ -649,13 +652,16 @@
static QgsSymbolLayerV2Registry* instance();
//! return metadata for specified symbol layer
- QgsSymbolLayerV2Metadata symbolLayerMetadata(QString name) const;
+ QgsSymbolLayerV2AbstractMetadata* symbolLayerMetadata(QString name) const;
//! register a new symbol layer type
- void addSymbolLayerType(const QgsSymbolLayerV2Metadata& metadata);
+ void addSymbolLayerType(QgsSymbolLayerV2AbstractMetadata* metadata /Transfer/);
//! create a new instance of symbol layer given symbol layer name and properties
- QgsSymbolLayerV2* createSymbolLayer(QString name, const QgsStringMap& properties) const /Factory/;
+ // TODO: disabled in PyQGIS because if used with symbol layer from Python
+ // the combination of /Factory/ annotation QgsSymbolLayerV2AbstractMetadata::createSymbolLayer()
+ // and here is deadly: results in premature deallocation of the symbol layer -> segfaults
+ //QgsSymbolLayerV2* createSymbolLayer(QString name, const QgsStringMap& properties) const /Factory/;
//! return a list of available symbol layers for a specified symbol type
QStringList symbolLayersForType(QgsSymbolV2::SymbolType type);
@@ -665,6 +671,7 @@
protected:
QgsSymbolLayerV2Registry();
+ ~QgsSymbolLayerV2Registry();
};
@@ -787,3 +794,57 @@
static void rendererV2toV1(QgsVectorLayer* layer);
};
+
+////////////
+
+class QgsRendererV2Widget /External/;
+
+class QgsRendererV2AbstractMetadata
+{
+%TypeHeaderCode
+#include <qgsrendererv2registry.h>
+%End
+
+ public:
+ QgsRendererV2AbstractMetadata( QString name, QString visibleName, QString iconName = QString() );
+
+ QString name() const;
+ QString visibleName() const;
+ QString iconName() 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/;
+ /** Return new instance of settings widget for the renderer. Returns NULL on error. */
+ virtual QgsRendererV2Widget* createRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) /Factory/;
+
+};
+
+
+class QgsRendererV2Registry
+{
+%TypeHeaderCode
+#include <qgsrendererv2registry.h>
+%End
+
+ public:
+
+ static QgsRendererV2Registry* instance();
+
+ //! add a renderer to registry. Takes ownership of the metadata object.
+ bool addRenderer( QgsRendererV2AbstractMetadata* metadata /Transfer/ );
+
+ //! remove renderer from registry
+ bool removeRenderer( QString rendererName );
+
+ //! get metadata for particular renderer. Returns NULL if not found in registry.
+ QgsRendererV2AbstractMetadata* rendererMetadata( QString rendererName );
+
+ //! return a list of available renderers
+ QStringList renderersList();
+
+ protected:
+ //! protected constructor
+ QgsRendererV2Registry();
+ ~QgsRendererV2Registry();
+};
Modified: trunk/qgis/python/gui/symbology-ng-gui.sip
===================================================================
--- trunk/qgis/python/gui/symbology-ng-gui.sip 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/python/gui/symbology-ng-gui.sip 2010-01-15 17:54:18 UTC (rev 12769)
@@ -96,3 +96,38 @@
void symbolModified();
};
+
+
+
+class QgsSymbolLayerV2Widget : QWidget
+{
+%TypeHeaderCode
+#include <qgssymbollayerv2widget.h>
+%End
+
+ public:
+ QgsSymbolLayerV2Widget( QWidget* parent );
+ virtual ~QgsSymbolLayerV2Widget();
+
+ virtual void setSymbolLayer( QgsSymbolLayerV2* layer ) = 0;
+ virtual QgsSymbolLayerV2* symbolLayer() = 0;
+
+ signals:
+ void changed();
+};
+
+class QgsRendererV2Widget : QWidget
+{
+%TypeHeaderCode
+#include <qgsrendererv2widget.h>
+%End
+
+ public:
+ QgsRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style );
+
+ virtual ~QgsRendererV2Widget();
+
+ //! return pointer to the renderer (no transfer of ownership)
+ virtual QgsFeatureRendererV2* renderer() = 0;
+
+};
Modified: trunk/qgis/src/core/symbology-ng/qgsrendererv2.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgsrendererv2.cpp 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/src/core/symbology-ng/qgsrendererv2.cpp 2010-01-15 17:54:18 UTC (rev 12769)
@@ -311,13 +311,11 @@
// load renderer
QString rendererType = element.attribute( "type" );
- QgsRendererV2CreateFunc pfCreate = QgsRendererV2Registry::instance()->rendererMetadata( rendererType ).createFunction();
-
- // unknown renderer type?
- if ( pfCreate == NULL )
+ QgsRendererV2AbstractMetadata* m = QgsRendererV2Registry::instance()->rendererMetadata( rendererType );
+ if (m == NULL)
return NULL;
- QgsFeatureRendererV2* r = pfCreate( element );
+ QgsFeatureRendererV2* r = m->createRenderer( element );
if ( r )
r->setUsingSymbolLevels( element.attribute( "symbollevels", "0" ).toInt() );
Modified: trunk/qgis/src/core/symbology-ng/qgsrendererv2registry.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgsrendererv2registry.cpp 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/src/core/symbology-ng/qgsrendererv2registry.cpp 2010-01-15 17:54:18 UTC (rev 12769)
@@ -11,20 +11,29 @@
QgsRendererV2Registry::QgsRendererV2Registry()
{
// add default renderers
- addRenderer( QgsRendererV2Metadata( "singleSymbol",
+ addRenderer( new QgsRendererV2Metadata( "singleSymbol",
QObject::tr( "Single Symbol" ),
QgsSingleSymbolRendererV2::create,
"rendererSingleSymbol.png" ) );
- addRenderer( QgsRendererV2Metadata( "categorizedSymbol",
+ addRenderer( new QgsRendererV2Metadata( "categorizedSymbol",
QObject::tr( "Categorized" ),
QgsCategorizedSymbolRendererV2::create,
"rendererCategorizedSymbol.png" ) );
- addRenderer( QgsRendererV2Metadata( "graduatedSymbol",
+ addRenderer( new QgsRendererV2Metadata( "graduatedSymbol",
QObject::tr( "Graduated" ),
QgsGraduatedSymbolRendererV2::create,
"rendererGraduatedSymbol.png" ) );
}
+QgsRendererV2Registry::~QgsRendererV2Registry()
+{
+ foreach (QString name, mRenderers.keys())
+ {
+ delete mRenderers[name];
+ }
+ mRenderers.clear();
+}
+
QgsRendererV2Registry* QgsRendererV2Registry::instance()
{
if ( !mInstance )
@@ -34,34 +43,32 @@
}
-void QgsRendererV2Registry::addRenderer( const QgsRendererV2Metadata& metadata )
+bool QgsRendererV2Registry::addRenderer( QgsRendererV2AbstractMetadata* metadata )
{
- mRenderers[metadata.name()] = metadata;
- mRenderersOrder << metadata.name();
+ if (metadata == NULL || mRenderers.contains(metadata->name()) )
+ return false;
+
+ mRenderers[metadata->name()] = metadata;
+ mRenderersOrder << metadata->name();
+ return true;
}
bool QgsRendererV2Registry::removeRenderer( QString rendererName )
{
if ( !mRenderers.contains( rendererName ) )
return false;
+
+ delete mRenderers[rendererName];
mRenderers.remove( rendererName );
mRenderersOrder.removeAll( rendererName );
return true;
}
-QgsRendererV2Metadata QgsRendererV2Registry::rendererMetadata( QString rendererName )
+QgsRendererV2AbstractMetadata* QgsRendererV2Registry::rendererMetadata( QString rendererName )
{
return mRenderers.value( rendererName );
}
-bool QgsRendererV2Registry::setRendererWidgetFunction( QString name, QgsRendererV2WidgetFunc f )
-{
- if ( !mRenderers.contains( name ) )
- return false;
- mRenderers[name].setWidgetFunction( f );
- return true;
-}
-
QStringList QgsRendererV2Registry::renderersList()
{
return mRenderersOrder;
Modified: trunk/qgis/src/core/symbology-ng/qgsrendererv2registry.h
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgsrendererv2registry.h 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/src/core/symbology-ng/qgsrendererv2registry.h 2010-01-15 17:54:18 UTC (rev 12769)
@@ -10,15 +10,48 @@
class QgsStyleV2;
class QgsRendererV2Widget;
+/**
+ Stores metadata about one renderer class.
+
+ @note It's necessary to implement createRenderer() function.
+ In C++ you can use QgsRendererV2Metadata convenience class.
+ */
+class CORE_EXPORT QgsRendererV2AbstractMetadata
+{
+ public:
+ QgsRendererV2AbstractMetadata( QString name, QString visibleName, QString iconName = QString() )
+ : mName( name ), mVisibleName( visibleName ), mIconName( iconName ) {}
+
+ QString name() const { return mName; }
+ QString visibleName() const { return mVisibleName; }
+ QString iconName() const { return mIconName; }
+
+ /** 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;
+ /** Return new instance of settings widget for the renderer. Returns NULL on error. */
+ virtual QgsRendererV2Widget* createRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
+ { return NULL; }
+
+ protected:
+ //! name used within QGIS for identification (the same what renderer's type() returns)
+ QString mName;
+ //! name visible for users (translatable)
+ QString mVisibleName;
+ //! icon to be shown in the renderer properties dialog
+ QString mIconName;
+};
+
+
typedef QgsFeatureRendererV2*( *QgsRendererV2CreateFunc )( QDomElement& );
typedef QgsRendererV2Widget*( *QgsRendererV2WidgetFunc )( QgsVectorLayer*, QgsStyleV2*, QgsFeatureRendererV2* );
-class CORE_EXPORT QgsRendererV2Metadata
+/**
+ Convenience metadata class that uses static functions to create renderer and its widget.
+ */
+class CORE_EXPORT QgsRendererV2Metadata : public QgsRendererV2AbstractMetadata
{
public:
- /** construct invalid metadata */
- QgsRendererV2Metadata()
- : mName(), mVisibleName(), mCreateFunc( NULL ), mIconName(), mWidgetFunc( NULL ) {}
/** construct metadata */
QgsRendererV2Metadata( QString name,
@@ -26,25 +59,20 @@
QgsRendererV2CreateFunc pfCreate,
QString iconName = QString(),
QgsRendererV2WidgetFunc pfWidget = NULL )
- : mName( name ), mVisibleName( visibleName ), mCreateFunc( pfCreate ), mIconName( iconName ), mWidgetFunc( pfWidget ) {}
+ : QgsRendererV2AbstractMetadata( name, visibleName, iconName ), mCreateFunc( pfCreate ), mWidgetFunc( pfWidget ) {}
- QString name() const { return mName; }
- QString visibleName() const { return mVisibleName; }
- QString iconName() const { return mIconName; }
+ virtual QgsFeatureRendererV2* createRenderer( QDomElement& elem ) { return mCreateFunc ? mCreateFunc(elem):NULL; }
+ virtual QgsRendererV2Widget* createRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
+ { return mWidgetFunc ? mWidgetFunc(layer, style, renderer) : NULL; }
+
QgsRendererV2CreateFunc createFunction() const { return mCreateFunc; }
QgsRendererV2WidgetFunc widgetFunction() const { return mWidgetFunc; }
void setWidgetFunction( QgsRendererV2WidgetFunc f ) { mWidgetFunc = f; }
protected:
- //! name used within QGIS for identification (the same what renderer's type() returns)
- QString mName;
- //! name visible for users (translatable)
- QString mVisibleName;
//! pointer to function that creates an instance of the renderer when loading project / style
QgsRendererV2CreateFunc mCreateFunc;
- //! icon to be shown in the renderer properties dialog
- QString mIconName;
//! pointer to function that creates a widget for configuration of renderer's params
QgsRendererV2WidgetFunc mWidgetFunc;
};
@@ -60,28 +88,26 @@
static QgsRendererV2Registry* instance();
- //! add a renderer to registry
- void addRenderer( const QgsRendererV2Metadata& metadata );
+ //! add a renderer to registry. Takes ownership of the metadata object.
+ bool addRenderer( QgsRendererV2AbstractMetadata* metadata );
//! remove renderer from registry
bool removeRenderer( QString rendererName );
- //! get factory method for particular renderer
- QgsRendererV2Metadata rendererMetadata( QString rendererName );
+ //! get metadata for particular renderer. Returns NULL if not found in registry.
+ QgsRendererV2AbstractMetadata* rendererMetadata( QString rendererName );
- //! assign a widget factory to particular renderer
- bool setRendererWidgetFunction( QString name, QgsRendererV2WidgetFunc f );
-
//! return a list of available renderers
QStringList renderersList();
protected:
//! protected constructor
QgsRendererV2Registry();
+ ~QgsRendererV2Registry();
static QgsRendererV2Registry* mInstance;
- QMap<QString, QgsRendererV2Metadata> mRenderers;
+ QMap<QString, QgsRendererV2AbstractMetadata*> mRenderers;
//! list to keep order in which renderers have been added
QStringList mRenderersOrder;
Modified: trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.cpp 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.cpp 2010-01-15 17:54:18 UTC (rev 12769)
@@ -10,41 +10,47 @@
QgsSymbolLayerV2Registry::QgsSymbolLayerV2Registry()
{
// init registry with known symbol layers
- addSymbolLayerType( QgsSymbolLayerV2Metadata( "SimpleLine", QgsSymbolV2::Line,
+ addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SimpleLine", QgsSymbolV2::Line,
QgsSimpleLineSymbolLayerV2::create ) );
- addSymbolLayerType( QgsSymbolLayerV2Metadata( "MarkerLine", QgsSymbolV2::Line,
+ addSymbolLayerType( new QgsSymbolLayerV2Metadata( "MarkerLine", QgsSymbolV2::Line,
QgsMarkerLineSymbolLayerV2::create ) );
- addSymbolLayerType( QgsSymbolLayerV2Metadata( "LineDecoration", QgsSymbolV2::Line,
+ addSymbolLayerType( new QgsSymbolLayerV2Metadata( "LineDecoration", QgsSymbolV2::Line,
QgsLineDecorationSymbolLayerV2::create ) );
- addSymbolLayerType( QgsSymbolLayerV2Metadata( "SimpleMarker", QgsSymbolV2::Marker,
+ addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SimpleMarker", QgsSymbolV2::Marker,
QgsSimpleMarkerSymbolLayerV2::create ) );
- addSymbolLayerType( QgsSymbolLayerV2Metadata( "SvgMarker", QgsSymbolV2::Marker,
+ addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SvgMarker", QgsSymbolV2::Marker,
QgsSvgMarkerSymbolLayerV2::create ) );
- addSymbolLayerType( QgsSymbolLayerV2Metadata( "SimpleFill", QgsSymbolV2::Fill,
+ addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SimpleFill", QgsSymbolV2::Fill,
QgsSimpleFillSymbolLayerV2::create ) );
}
-void QgsSymbolLayerV2Registry::addSymbolLayerType( const QgsSymbolLayerV2Metadata& metadata )
+QgsSymbolLayerV2Registry::~QgsSymbolLayerV2Registry()
{
- mMetadata[metadata.name()] = metadata;
+ foreach (QString name, mMetadata.keys())
+ {
+ delete mMetadata[name];
+ }
+ mMetadata.clear();
}
-bool QgsSymbolLayerV2Registry::setLayerTypeWidgetFunction( QString name, QgsSymbolLayerV2WidgetFunc f )
+bool QgsSymbolLayerV2Registry::addSymbolLayerType( QgsSymbolLayerV2AbstractMetadata* metadata )
{
- if ( !mMetadata.contains( name ) )
+ if ( metadata == NULL || mMetadata.contains( metadata->name() ) )
return false;
- mMetadata[name].setWidgetFunction( f );
+
+ mMetadata[metadata->name()] = metadata;
return true;
}
-QgsSymbolLayerV2Metadata QgsSymbolLayerV2Registry::symbolLayerMetadata( QString name ) const
+
+QgsSymbolLayerV2AbstractMetadata* QgsSymbolLayerV2Registry::symbolLayerMetadata( QString name ) const
{
if ( mMetadata.contains( name ) )
return mMetadata.value( name );
else
- return QgsSymbolLayerV2Metadata();
+ return NULL;
}
QgsSymbolLayerV2Registry* QgsSymbolLayerV2Registry::instance()
@@ -76,16 +82,16 @@
if ( !mMetadata.contains( name ) )
return NULL;
- return mMetadata[name].createFunction()( properties );
+ return mMetadata[name]->createSymbolLayer( properties );
}
QStringList QgsSymbolLayerV2Registry::symbolLayersForType( QgsSymbolV2::SymbolType type )
{
QStringList lst;
- QMap<QString, QgsSymbolLayerV2Metadata>::ConstIterator it = mMetadata.begin();
+ QMap<QString, QgsSymbolLayerV2AbstractMetadata*>::ConstIterator it = mMetadata.begin();
for ( ; it != mMetadata.end(); ++it )
{
- if ( it->type() == type )
+ if ( (*it)->type() == type )
lst.append( it.key() );
}
return lst;
Modified: trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.h
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.h 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.h 2010-01-15 17:54:18 UTC (rev 12769)
@@ -5,40 +5,60 @@
#include "qgssymbolv2.h"
#include "qgssymbollayerv2.h"
-typedef QgsSymbolLayerV2*( *QgsSymbolLayerV2CreateFunc )( const QgsStringMap& );
-typedef QgsSymbolLayerV2Widget*( *QgsSymbolLayerV2WidgetFunc )();
-
/**
Stores metadata about one symbol layer class.
+
+ @note It's necessary to implement createSymbolLayer() function.
+ In C++ you can use QgsSymbolLayerV2Metadata convenience class.
*/
-class CORE_EXPORT QgsSymbolLayerV2Metadata
+class CORE_EXPORT QgsSymbolLayerV2AbstractMetadata
{
public:
- /** construct invalid metadata */
- QgsSymbolLayerV2Metadata()
- : mName(), mCreateFunc( NULL ), mWidgetFunc( NULL ) {}
+ QgsSymbolLayerV2AbstractMetadata( QString name, QgsSymbolV2::SymbolType type )
+ : mName( name ), mType( type ) {}
- /** construct metadata */
- QgsSymbolLayerV2Metadata( QString name, QgsSymbolV2::SymbolType type,
- QgsSymbolLayerV2CreateFunc pfCreate,
- QgsSymbolLayerV2WidgetFunc pfWidget = NULL )
- : mName( name ), mType( type ), mCreateFunc( pfCreate ), mWidgetFunc( pfWidget ) {}
-
QString name() const { return mName; }
QgsSymbolV2::SymbolType type() const { return mType; }
- QgsSymbolLayerV2CreateFunc createFunction() const { return mCreateFunc; }
- QgsSymbolLayerV2WidgetFunc widgetFunction() const { return mWidgetFunc; }
- void setWidgetFunction( QgsSymbolLayerV2WidgetFunc f ) { mWidgetFunc = f; }
+ /** create a symbol layer of this type given the map of properties. */
+ virtual QgsSymbolLayerV2* createSymbolLayer( const QgsStringMap& map ) = 0;
+ /** create widget for symbol layer of this type. Can return NULL if there's no GUI */
+ virtual QgsSymbolLayerV2Widget* createSymbolLayerWidget() { return NULL; }
protected:
QString mName;
QgsSymbolV2::SymbolType mType;
- QgsSymbolLayerV2CreateFunc mCreateFunc;
- QgsSymbolLayerV2WidgetFunc mWidgetFunc;
};
+typedef QgsSymbolLayerV2*( *QgsSymbolLayerV2CreateFunc )( const QgsStringMap& );
+typedef QgsSymbolLayerV2Widget*( *QgsSymbolLayerV2WidgetFunc )();
+
/**
+ Convenience metadata class that uses static functions to create symbol layer and its widget.
+ */
+class CORE_EXPORT QgsSymbolLayerV2Metadata : public QgsSymbolLayerV2AbstractMetadata
+{
+public:
+ QgsSymbolLayerV2Metadata( QString name, QgsSymbolV2::SymbolType type,
+ QgsSymbolLayerV2CreateFunc pfCreate,
+ QgsSymbolLayerV2WidgetFunc pfWidget = NULL )
+ : QgsSymbolLayerV2AbstractMetadata( name, type ), mCreateFunc( pfCreate ), mWidgetFunc( pfWidget ) {}
+
+ QgsSymbolLayerV2CreateFunc createFunction() const { return mCreateFunc; }
+ QgsSymbolLayerV2WidgetFunc widgetFunction() const { return mWidgetFunc; }
+
+ void setWidgetFunction( QgsSymbolLayerV2WidgetFunc f ) { mWidgetFunc = f; }
+
+ virtual QgsSymbolLayerV2* createSymbolLayer( const QgsStringMap& map ) { return mCreateFunc ? mCreateFunc(map) : NULL; }
+ virtual QgsSymbolLayerV2Widget* createSymbolLayerWidget() { return mWidgetFunc ? mWidgetFunc() : NULL; }
+
+protected:
+ QgsSymbolLayerV2CreateFunc mCreateFunc;
+ QgsSymbolLayerV2WidgetFunc mWidgetFunc;
+};
+
+
+/**
Registry of available symbol layer classes.
Implemented as a singleton.
*/
@@ -49,15 +69,12 @@
//! return the single instance of this class (instantiate it if not exists)
static QgsSymbolLayerV2Registry* instance();
- //! return metadata for specified symbol layer
- QgsSymbolLayerV2Metadata symbolLayerMetadata( QString name ) const;
+ //! return metadata for specified symbol layer. Returns NULL if not found
+ QgsSymbolLayerV2AbstractMetadata* symbolLayerMetadata( QString name ) const;
- //! register a new symbol layer type
- void addSymbolLayerType( const QgsSymbolLayerV2Metadata& metadata );
+ //! register a new symbol layer type. Takes ownership of the metadata instance.
+ bool addSymbolLayerType( QgsSymbolLayerV2AbstractMetadata* metadata );
- //! set layer type's widget function
- bool setLayerTypeWidgetFunction( QString name, QgsSymbolLayerV2WidgetFunc f );
-
//! create a new instance of symbol layer given symbol layer name and properties
QgsSymbolLayerV2* createSymbolLayer( QString name, const QgsStringMap& properties = QgsStringMap() ) const;
@@ -69,9 +86,10 @@
protected:
QgsSymbolLayerV2Registry();
+ ~QgsSymbolLayerV2Registry();
static QgsSymbolLayerV2Registry* mInstance;
- QMap<QString, QgsSymbolLayerV2Metadata> mMetadata;
+ QMap<QString, QgsSymbolLayerV2AbstractMetadata*> mMetadata;
};
Modified: trunk/qgis/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp
===================================================================
--- trunk/qgis/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp 2010-01-15 17:54:18 UTC (rev 12769)
@@ -18,6 +18,33 @@
#include <QKeyEvent>
#include <QMessageBox>
+static bool _initRendererWidgetFunction(QString name, QgsRendererV2WidgetFunc f )
+{
+ QgsRendererV2Registry* reg = QgsRendererV2Registry::instance();
+ QgsRendererV2AbstractMetadata* am = reg->rendererMetadata( name );
+ if (am == NULL)
+ return false;
+ QgsRendererV2Metadata* m = dynamic_cast<QgsRendererV2Metadata*>(am);
+ if (m == NULL)
+ return false;
+
+ m->setWidgetFunction(f);
+ QgsDebugMsg("Set for "+name);
+ return true;
+}
+
+static void _initRendererWidgetFunctions()
+{
+ static bool initialized = false;
+ if (initialized)
+ return;
+
+ _initRendererWidgetFunction( "singleSymbol", QgsSingleSymbolRendererV2Widget::create );
+ _initRendererWidgetFunction( "categorizedSymbol", QgsCategorizedSymbolRendererV2Widget::create );
+ _initRendererWidgetFunction( "graduatedSymbol", QgsGraduatedSymbolRendererV2Widget::create );
+ initialized = true;
+}
+
QgsRendererV2PropertiesDialog::QgsRendererV2PropertiesDialog( QgsVectorLayer* layer, QgsStyleV2* style, bool embedded )
: mLayer( layer ), mStyle( style ), mActiveWidget( NULL )
{
@@ -35,25 +62,20 @@
connect( btnOldSymbology, SIGNAL( clicked() ), this, SLOT( useOldSymbology() ) );
// initialize registry's widget functions
- QgsRendererV2Registry* reg = QgsRendererV2Registry::instance();
- if ( reg->rendererMetadata( "singleSymbol" ).widgetFunction() == NULL )
- {
- reg->setRendererWidgetFunction( "singleSymbol", QgsSingleSymbolRendererV2Widget::create );
- reg->setRendererWidgetFunction( "categorizedSymbol", QgsCategorizedSymbolRendererV2Widget::create );
- reg->setRendererWidgetFunction( "graduatedSymbol", QgsGraduatedSymbolRendererV2Widget::create );
- }
+ _initRendererWidgetFunctions();
QPixmap pix;
+ QgsRendererV2Registry* reg = QgsRendererV2Registry::instance();
QStringList renderers = reg->renderersList();
foreach( QString name, renderers )
{
- QgsRendererV2Metadata m = reg->rendererMetadata( name );
+ QgsRendererV2AbstractMetadata* m = reg->rendererMetadata( name );
- QString iconPath = QgsApplication::defaultThemePath() + m.iconName();
+ QString iconPath = QgsApplication::defaultThemePath() + m->iconName();
if ( !pix.load( iconPath, "png" ) )
pix = QPixmap();
- cboRenderers->addItem( QIcon( pix ), m.visibleName(), name );
+ cboRenderers->addItem( QIcon( pix ), m->visibleName(), name );
}
cboRenderers->setCurrentIndex( -1 ); // set no current renderer
@@ -105,12 +127,15 @@
mActiveWidget = NULL;
}
- QgsRendererV2Metadata m = QgsRendererV2Registry::instance()->rendererMetadata( rendererName );
- QgsRendererV2WidgetFunc fWidget = m.widgetFunction();
- if ( fWidget != NULL )
+ QgsRendererV2Widget* w = NULL;
+ QgsRendererV2AbstractMetadata* m = QgsRendererV2Registry::instance()->rendererMetadata( rendererName );
+ if ( m != NULL )
+ w = m->createRendererWidget( mLayer, mStyle, mLayer->rendererV2()->clone() );
+
+ if ( w != NULL )
{
// instantiate the widget and set as active
- mActiveWidget = fWidget( mLayer, mStyle, mLayer->rendererV2()->clone() );
+ mActiveWidget = w;
stackedWidget->addWidget( mActiveWidget );
stackedWidget->setCurrentWidget( mActiveWidget );
Modified: trunk/qgis/src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp
===================================================================
--- trunk/qgis/src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp 2010-01-15 16:27:13 UTC (rev 12768)
+++ trunk/qgis/src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp 2010-01-15 17:54:18 UTC (rev 12769)
@@ -10,10 +10,12 @@
#include "qgssymbollayerv2registry.h"
#include "qgsapplication.h"
+#include "qgslogger.h"
#include "qgssymbollayerv2widget.h"
#include "qgssymbolv2.h" //for the unit
+
static const int SymbolLayerItemType = QStandardItem::UserType + 1;
class SymbolLayerItem : public QStandardItem
@@ -68,6 +70,47 @@
//////////
+static bool _initWidgetFunction( QString name, QgsSymbolLayerV2WidgetFunc f )
+{
+ QgsSymbolLayerV2Registry* reg = QgsSymbolLayerV2Registry::instance();
+
+ QgsSymbolLayerV2AbstractMetadata* abstractMetadata = reg->symbolLayerMetadata(name);
+ if (abstractMetadata == NULL)
+ {
+ QgsDebugMsg("Failed to find symbol layer's entry in registry: "+name);
+ return false;
+ }
+ QgsSymbolLayerV2Metadata* metadata = dynamic_cast<QgsSymbolLayerV2Metadata*>(abstractMetadata);
+ if (metadata == NULL)
+ {
+ QgsDebugMsg("Failed to cast symbol layer's metadata: "+name);
+ return false;
+ }
+ metadata->setWidgetFunction(f);
+ return true;
+}
+
+static void _initWidgetFunctions()
+{
+ static bool initialized = false;
+ if (initialized)
+ return;
+
+ _initWidgetFunction( "SimpleLine", QgsSimpleLineSymbolLayerV2Widget::create );
+ _initWidgetFunction( "MarkerLine", QgsMarkerLineSymbolLayerV2Widget::create );
+ _initWidgetFunction( "LineDecoration", QgsLineDecorationSymbolLayerV2Widget::create );
+
+ _initWidgetFunction( "SimpleMarker", QgsSimpleMarkerSymbolLayerV2Widget::create );
+ _initWidgetFunction( "SvgMarker", QgsSvgMarkerSymbolLayerV2Widget::create );
+
+ _initWidgetFunction( "SimpleFill", QgsSimpleFillSymbolLayerV2Widget::create );
+
+ initialized = true;
+}
+
+
+//////////
+
QgsSymbolV2PropertiesDialog::QgsSymbolV2PropertiesDialog( QgsSymbolV2* symbol, QWidget* parent )
: QDialog( parent ), mSymbol( symbol )
{
@@ -82,15 +125,8 @@
// set widget functions
// (should be probably moved somewhere else)
- QgsSymbolLayerV2Registry::instance()->setLayerTypeWidgetFunction( "SimpleLine", QgsSimpleLineSymbolLayerV2Widget::create );
- QgsSymbolLayerV2Registry::instance()->setLayerTypeWidgetFunction( "MarkerLine", QgsMarkerLineSymbolLayerV2Widget::create );
- QgsSymbolLayerV2Registry::instance()->setLayerTypeWidgetFunction( "LineDecoration", QgsLineDecorationSymbolLayerV2Widget::create );
+ _initWidgetFunctions();
- QgsSymbolLayerV2Registry::instance()->setLayerTypeWidgetFunction( "SimpleMarker", QgsSimpleMarkerSymbolLayerV2Widget::create );
- QgsSymbolLayerV2Registry::instance()->setLayerTypeWidgetFunction( "SvgMarker", QgsSvgMarkerSymbolLayerV2Widget::create );
-
- QgsSymbolLayerV2Registry::instance()->setLayerTypeWidgetFunction( "SimpleFill", QgsSimpleFillSymbolLayerV2Widget::create );
-
loadSymbol();
connect( btnUp, SIGNAL( clicked() ), this, SLOT( moveLayerUp() ) );
@@ -198,11 +234,11 @@
for ( int i = 0; i < layerTypes.count(); i++ )
{
QString layerType = layerTypes[i];
- QgsSymbolLayerV2WidgetFunc f = pReg->symbolLayerMetadata( layerType ).widgetFunction();
- if ( f == NULL ) // check whether the function is assigned
+ QgsSymbolLayerV2AbstractMetadata* am = pReg->symbolLayerMetadata( layerType );
+ if ( am == NULL ) // check whether the metadata is assigned
continue;
- QgsSymbolLayerV2Widget* w = f();
+ QgsSymbolLayerV2Widget* w = am->createSymbolLayerWidget();
if ( w == NULL ) // check whether the function returns correct widget
continue;
@@ -288,12 +324,12 @@
// get creation function for new layer from registry
QgsSymbolLayerV2Registry* pReg = QgsSymbolLayerV2Registry::instance();
- QgsSymbolLayerV2CreateFunc f = pReg->symbolLayerMetadata( newLayerType ).createFunction();
- if ( f == NULL ) // check whether the function is assigned
+ QgsSymbolLayerV2AbstractMetadata* am = pReg->symbolLayerMetadata( newLayerType );
+ if ( am == NULL ) // check whether the metadata is assigned
return;
// change layer to a new (with different type)
- QgsSymbolLayerV2* newLayer = f( QgsStringMap() );
+ QgsSymbolLayerV2* newLayer = am->createSymbolLayer( QgsStringMap() );
mSymbol->changeSymbolLayer( currentLayerIndex(), newLayer );
updateSymbolLayerWidget( newLayer );
More information about the QGIS-commit
mailing list