Skip to content

Commit

Permalink
symbology-ng: updates to symbol layer registry and renderer registry …
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
wonder committed Jan 15, 2010
1 parent 3a72b35 commit e711851
Show file tree
Hide file tree
Showing 9 changed files with 344 additions and 132 deletions.
101 changes: 81 additions & 20 deletions python/core/symbology-ng-core.sip
Expand Up @@ -3,6 +3,15 @@ typedef QList<QgsSymbolV2*> QgsSymbolV2List;

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


///////////////

/*
Expand Down Expand Up @@ -608,31 +617,25 @@ typedef QMap<QString, QString> QgsStringMap;

//////////

//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();

/** construct metadata */
// TODO
//QgsSymbolLayerV2Metadata(QString name, QgsSymbolV2::SymbolType type,
// QgsSymbolLayerV2CreateFunc pfCreate,
// QgsSymbolLayerV2WidgetFunc pfWidget);
public:
/** construct metadata */
QgsSymbolLayerV2AbstractMetadata( QString name, QgsSymbolV2::SymbolType type );

QString name() const;
QgsSymbolV2::SymbolType type();
// TODO QgsSymbolLayerV2CreateFunc createFunction() const;
// TODO QgsSymbolLayerV2WidgetFunc widgetFunction() const;
QString name() const;
QgsSymbolV2::SymbolType type() 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/;
};

//////////
Expand All @@ -649,13 +652,16 @@ public:
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);
Expand All @@ -665,6 +671,7 @@ public:

protected:
QgsSymbolLayerV2Registry();
~QgsSymbolLayerV2Registry();

};

Expand Down Expand Up @@ -787,3 +794,57 @@ public:
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();
};
35 changes: 35 additions & 0 deletions python/gui/symbology-ng-gui.sip
Expand Up @@ -96,3 +96,38 @@ signals:
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;

};
8 changes: 3 additions & 5 deletions src/core/symbology-ng/qgsrendererv2.cpp
Expand Up @@ -311,13 +311,11 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::load( QDomElement& element )
// 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() );

Expand Down
37 changes: 22 additions & 15 deletions src/core/symbology-ng/qgsrendererv2registry.cpp
Expand Up @@ -11,20 +11,29 @@ QgsRendererV2Registry* QgsRendererV2Registry::mInstance = NULL;
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 )
Expand All @@ -34,34 +43,32 @@ QgsRendererV2Registry* QgsRendererV2Registry::instance()
}


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;
Expand Down
70 changes: 48 additions & 22 deletions src/core/symbology-ng/qgsrendererv2registry.h
Expand Up @@ -10,41 +10,69 @@ class QgsVectorLayer;
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,
QString visibleName,
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 ) {}

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; }

QString name() const { return mName; }
QString visibleName() const { return mVisibleName; }
QString iconName() const { return mIconName; }
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;
};
Expand All @@ -60,28 +88,26 @@ class CORE_EXPORT QgsRendererV2Registry

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 );

//! assign a widget factory to particular renderer
bool setRendererWidgetFunction( QString name, QgsRendererV2WidgetFunc f );
//! 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();

static QgsRendererV2Registry* mInstance;

QMap<QString, QgsRendererV2Metadata> mRenderers;
QMap<QString, QgsRendererV2AbstractMetadata*> mRenderers;

//! list to keep order in which renderers have been added
QStringList mRenderersOrder;
Expand Down

0 comments on commit e711851

Please sign in to comment.