[QGIS Commit] r12834 - in trunk/qgis: python/core src/app
src/app/legend src/core
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Tue Jan 26 10:43:54 EST 2010
Author: wonder
Date: 2010-01-26 10:43:54 -0500 (Tue, 26 Jan 2010)
New Revision: 12834
Added:
trunk/qgis/python/core/qgspluginlayer.sip
trunk/qgis/python/core/qgspluginlayerregistry.sip
trunk/qgis/src/core/qgspluginlayer.cpp
trunk/qgis/src/core/qgspluginlayer.h
trunk/qgis/src/core/qgspluginlayerregistry.cpp
trunk/qgis/src/core/qgspluginlayerregistry.h
Modified:
trunk/qgis/python/core/core.sip
trunk/qgis/python/core/qgsmaplayer.sip
trunk/qgis/src/app/legend/qgslegendlayer.cpp
trunk/qgis/src/app/qgisapp.cpp
trunk/qgis/src/core/CMakeLists.txt
trunk/qgis/src/core/qgsmaplayer.cpp
trunk/qgis/src/core/qgsmaplayer.h
trunk/qgis/src/core/qgsproject.cpp
Log:
[FEATURE] Support for custom plugin layers. Applied patch from #2392 contributed by Mathias Walker. Thanks!
Some parts modified to make plugin layers easier to use and more robust.
Modified: trunk/qgis/python/core/core.sip
===================================================================
--- trunk/qgis/python/core/core.sip 2010-01-25 22:00:08 UTC (rev 12833)
+++ trunk/qgis/python/core/core.sip 2010-01-26 15:43:54 UTC (rev 12834)
@@ -43,6 +43,8 @@
%Include qgsmarkercatalogue.sip
%Include qgsmessageoutput.sip
%Include qgsoverlayobject.sip
+%Include qgspluginlayer.sip
+%Include qgspluginlayerregistry.sip
%Include qgspoint.sip
%Include qgsproject.sip
%Include qgsprovidermetadata.sip
Modified: trunk/qgis/python/core/qgsmaplayer.sip
===================================================================
--- trunk/qgis/python/core/qgsmaplayer.sip 2010-01-25 22:00:08 UTC (rev 12833)
+++ trunk/qgis/python/core/qgsmaplayer.sip 2010-01-26 15:43:54 UTC (rev 12834)
@@ -22,6 +22,10 @@
{
sipClass = sipClass_QgsRasterLayer;
}
+ else if (layer->type() == QgsMapLayer::PluginLayer)
+ {
+ sipClass = sipClass_QgsPluginLayer;
+ }
}
else
{
@@ -35,7 +39,8 @@
enum LayerType
{
VectorLayer,
- RasterLayer
+ RasterLayer,
+ PluginLayer
};
/** Constructor
@@ -109,7 +114,7 @@
/** True if the layer can be edited */
- virtual bool isEditable() const = 0;
+ virtual bool isEditable() const;
/** sets state from Dom document
@param layer_node is Dom node corresponding to ``maplayer'' tag
@@ -323,6 +328,9 @@
protected:
+ /** set whether layer is valid or not - should be used in constructor */
+ void setValid( bool valid );
+
/** called by readXML(), used by children to read state specific to them from
project files.
*/
Added: trunk/qgis/python/core/qgspluginlayer.sip
===================================================================
--- trunk/qgis/python/core/qgspluginlayer.sip (rev 0)
+++ trunk/qgis/python/core/qgspluginlayer.sip 2010-01-26 15:43:54 UTC (rev 12834)
@@ -0,0 +1,14 @@
+
+class QgsPluginLayer : QgsMapLayer
+{
+%TypeHeaderCode
+#include "qgspluginlayer.h"
+%End
+
+ public:
+ QgsPluginLayer(QString layerType, QString layerName = QString());
+
+ /** return plugin layer type (the same as used in QgsPluginLayerRegistry) */
+ QString pluginLayerType();
+
+};
Added: trunk/qgis/python/core/qgspluginlayerregistry.sip
===================================================================
--- trunk/qgis/python/core/qgspluginlayerregistry.sip (rev 0)
+++ trunk/qgis/python/core/qgspluginlayerregistry.sip 2010-01-26 15:43:54 UTC (rev 12834)
@@ -0,0 +1,52 @@
+
+class QgsPluginLayerType
+{
+%TypeHeaderCode
+#include "qgspluginlayerregistry.h"
+%End
+ public:
+
+ QgsPluginLayerType(QString name);
+ virtual ~QgsPluginLayerType();
+
+ QString name();
+
+ /** return new layer of this type. Return NULL on error */
+ virtual QgsPluginLayer* createLayer() /Factory/;
+
+ /** show plugin layer properties dialog. Return FALSE if the dialog cannot be shown. */
+ virtual bool showLayerProperties(QgsPluginLayer* layer);
+
+};
+
+
+class QgsPluginLayerRegistry
+{
+%TypeHeaderCode
+#include "qgspluginlayerregistry.h"
+%End
+ public:
+
+ /** means of accessing canonical single instance */
+ static QgsPluginLayerRegistry* instance();
+
+ ~QgsPluginLayerRegistry();
+
+ /** add plugin layer type (take ownership) and return TRUE on success */
+ bool addPluginLayerType(QgsPluginLayerType* pluginLayerType /Transfer/);
+
+ /** remove plugin layer type and return TRUE on success */
+ bool removePluginLayerType(QString typeName);
+
+ /** return plugin layer type metadata or NULL if doesn't exist */
+ QgsPluginLayerType* pluginLayerType(QString typeName);
+
+ /** return new layer if corresponding plugin has been found, else return NULL */
+ // to be resolved
+ //QgsPluginLayer* createLayer(QString typeName);
+
+ private:
+
+ /** private since instance() creates it */
+ QgsPluginLayerRegistry();
+};
Modified: trunk/qgis/src/app/legend/qgslegendlayer.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgslegendlayer.cpp 2010-01-25 22:00:08 UTC (rev 12833)
+++ trunk/qgis/src/app/legend/qgslegendlayer.cpp 2010-01-26 15:43:54 UTC (rev 12834)
@@ -165,7 +165,7 @@
else
vectorLayerSymbology( vlayer, widthScale ); // get and change symbology
}
- else // RASTER
+ else if ( theMapLayer->type() == QgsMapLayer::RasterLayer ) // RASTER
{
QgsRasterLayer* rlayer = qobject_cast<QgsRasterLayer *>( theMapLayer );
rasterLayerSymbology( rlayer ); // get and change symbology
Modified: trunk/qgis/src/app/qgisapp.cpp
===================================================================
--- trunk/qgis/src/app/qgisapp.cpp 2010-01-25 22:00:08 UTC (rev 12833)
+++ trunk/qgis/src/app/qgisapp.cpp 2010-01-26 15:43:54 UTC (rev 12834)
@@ -118,6 +118,8 @@
#include "qgsoptions.h"
#include "qgspastetransformations.h"
#include "qgspluginitem.h"
+#include "qgspluginlayer.h"
+#include "qgspluginlayerregistry.h"
#include "qgspluginmanager.h"
#include "qgspluginmetadata.h"
#include "qgspluginregistry.h"
@@ -6108,7 +6110,7 @@
rlp->exec();
delete rlp; // delete since dialog cannot be reused without updating code
}
- else // VECTOR
+ else if ( ml->type() == QgsMapLayer::VectorLayer ) // VECTOR
{
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( ml );
@@ -6125,4 +6127,20 @@
vlp->exec();
delete vlp; // delete since dialog cannot be reused without updating code
}
+ else if ( ml->type() == QgsMapLayer::PluginLayer )
+ {
+ QgsPluginLayer* pl = qobject_cast<QgsPluginLayer *>( ml );
+ if ( !pl )
+ return;
+
+ QgsPluginLayerType* plt = QgsPluginLayerRegistry::instance()->pluginLayerType( pl->pluginLayerType() );
+ if ( !plt )
+ return;
+
+ if ( !plt->showLayerProperties( pl ) )
+ {
+ QMessageBox::information( this, tr( "Warning" ), tr( "This layer doesn't have a properties dialog." ) );
+ }
+
+ }
}
Modified: trunk/qgis/src/core/CMakeLists.txt
===================================================================
--- trunk/qgis/src/core/CMakeLists.txt 2010-01-25 22:00:08 UTC (rev 12833)
+++ trunk/qgis/src/core/CMakeLists.txt 2010-01-26 15:43:54 UTC (rev 12834)
@@ -60,6 +60,8 @@
qgsoverlayobject.cpp
qgspalgeometry.cpp
qgspalobjectpositionmanager.cpp
+ qgspluginlayer.cpp
+ qgspluginlayerregistry.cpp
qgspoint.cpp
qgsproject.cpp
qgsprojectfiletransform.cpp
@@ -221,6 +223,7 @@
qgsmaplayerregistry.h
qgsmaprenderer.h
qgsmessageoutput.h
+ qgspluginlayer.h
qgsproject.h
qgsrunprocess.h
qgsvectorlayer.h
@@ -388,6 +391,8 @@
qgsmessageoutput.h
qgsoverlayobjectpositionmanager.h
qgspalobjectpositionmanager.h
+ qgspluginlayer.h
+ qgspluginlayerregistry.h
qgspoint.h
qgsproject.h
qgsprojectfiletransform.h
Modified: trunk/qgis/src/core/qgsmaplayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsmaplayer.cpp 2010-01-25 22:00:08 UTC (rev 12833)
+++ trunk/qgis/src/core/qgsmaplayer.cpp 2010-01-26 15:43:54 UTC (rev 12834)
@@ -850,3 +850,12 @@
mpCacheImage = thepImage;
}
+bool QgsMapLayer::isEditable() const
+{
+ return false;
+}
+
+void QgsMapLayer::setValid( bool valid )
+{
+ mValid = valid;
+}
Modified: trunk/qgis/src/core/qgsmaplayer.h
===================================================================
--- trunk/qgis/src/core/qgsmaplayer.h 2010-01-25 22:00:08 UTC (rev 12833)
+++ trunk/qgis/src/core/qgsmaplayer.h 2010-01-26 15:43:54 UTC (rev 12834)
@@ -48,7 +48,8 @@
enum LayerType
{
VectorLayer,
- RasterLayer
+ RasterLayer,
+ PluginLayer
};
/** Constructor
@@ -126,7 +127,7 @@
/** True if the layer can be edited */
- virtual bool isEditable() const = 0;
+ virtual bool isEditable() const;
/** sets state from Dom document
@param layer_node is Dom node corresponding to ``maplayer'' tag
@@ -343,6 +344,9 @@
protected:
+ /** set whether layer is valid or not - should be used in constructor */
+ void setValid( bool valid );
+
/** called by readXML(), used by children to read state specific to them from
project files.
*/
Added: trunk/qgis/src/core/qgspluginlayer.cpp
===================================================================
--- trunk/qgis/src/core/qgspluginlayer.cpp (rev 0)
+++ trunk/qgis/src/core/qgspluginlayer.cpp 2010-01-26 15:43:54 UTC (rev 12834)
@@ -0,0 +1,11 @@
+#include "qgspluginlayer.h"
+
+QgsPluginLayer::QgsPluginLayer( QString layerType, QString layerName )
+ : QgsMapLayer( PluginLayer, layerName ), mPluginLayerType( layerType )
+{
+}
+
+QString QgsPluginLayer::pluginLayerType()
+{
+ return mPluginLayerType;
+}
Added: trunk/qgis/src/core/qgspluginlayer.h
===================================================================
--- trunk/qgis/src/core/qgspluginlayer.h (rev 0)
+++ trunk/qgis/src/core/qgspluginlayer.h 2010-01-26 15:43:54 UTC (rev 12834)
@@ -0,0 +1,28 @@
+#ifndef QGSPLUGINLAYER_H
+#define QGSPLUGINLAYER_H
+
+#include "qgsmaplayer.h"
+
+/** \ingroup core
+ Base class for plugin layers. These can be implemented by plugins
+ and registered in QgsPluginLayerRegistry.
+
+ In order to be readable from project files, they should set these attributes in layer DOM node:
+ "type" = "plugin"
+ "name" = "your_layer_type"
+ */
+class CORE_EXPORT QgsPluginLayer : public QgsMapLayer
+{
+ Q_OBJECT
+
+ public:
+ QgsPluginLayer( QString layerType, QString layerName = QString() );
+
+ /** return plugin layer type (the same as used in QgsPluginLayerRegistry) */
+ QString pluginLayerType();
+
+ protected:
+ QString mPluginLayerType;
+};
+
+#endif // QGSPLUGINLAYER_H
Added: trunk/qgis/src/core/qgspluginlayerregistry.cpp
===================================================================
--- trunk/qgis/src/core/qgspluginlayerregistry.cpp (rev 0)
+++ trunk/qgis/src/core/qgspluginlayerregistry.cpp 2010-01-26 15:43:54 UTC (rev 12834)
@@ -0,0 +1,128 @@
+/***************************************************************************
+ qgspluginlayerregistry.cpp - class for
+ registering plugin layer creators
+ -------------------
+ begin : Mon Nov 30 2009
+ copyright : (C) 2009 by Mathias Walker, Sourcepole
+ email : mwa at sourcepole.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+/* $Id$ */
+
+#include "qgspluginlayerregistry.h"
+#include "qgslogger.h"
+#include "qgspluginlayer.h"
+#include "qgsmaplayerregistry.h"
+
+QgsPluginLayerType::QgsPluginLayerType(QString name)
+ : mName(name)
+{
+}
+
+QgsPluginLayerType::~QgsPluginLayerType()
+{
+}
+
+QString QgsPluginLayerType::name()
+{
+ return mName;
+}
+
+QgsPluginLayer* QgsPluginLayerType::createLayer()
+{
+ return NULL;
+}
+
+bool QgsPluginLayerType::showLayerProperties(QgsPluginLayer* layer)
+{
+ return false;
+}
+
+//=============================================================================
+
+/** Static calls to enforce singleton behaviour */
+QgsPluginLayerRegistry* QgsPluginLayerRegistry::_instance = NULL;
+QgsPluginLayerRegistry* QgsPluginLayerRegistry::instance()
+{
+ if ( _instance == NULL )
+ {
+ _instance = new QgsPluginLayerRegistry();
+ }
+ return _instance;
+}
+
+
+QgsPluginLayerRegistry::QgsPluginLayerRegistry()
+{
+}
+
+QgsPluginLayerRegistry::~QgsPluginLayerRegistry()
+{
+ if ( !mPluginLayerTypes.isEmpty() )
+ {
+ QgsDebugMsg("QgsPluginLayerRegistry::~QgsPluginLayerRegistry(): creator list not empty");
+ foreach (QString typeName, mPluginLayerTypes.keys())
+ removePluginLayerType(typeName);
+ }
+}
+
+bool QgsPluginLayerRegistry::addPluginLayerType(QgsPluginLayerType* type)
+{
+ if (type == NULL)
+ return false;
+ if (mPluginLayerTypes.contains(type->name()))
+ return false;
+
+ mPluginLayerTypes[type->name()] = type;
+ return true;
+}
+
+
+bool QgsPluginLayerRegistry::removePluginLayerType(QString typeName)
+{
+ if (!mPluginLayerTypes.contains(typeName))
+ return false;
+
+ // remove all remaining layers of this type - to avoid invalid behaviour
+ QList<QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers().values();
+ foreach (QgsMapLayer* layer, layers)
+ {
+ if (layer->type() == QgsMapLayer::PluginLayer)
+ {
+ QgsPluginLayer* pl = qobject_cast<QgsPluginLayer*>(layer);
+ if (pl->pluginLayerType() == typeName)
+ {
+ QgsMapLayerRegistry::instance()->removeMapLayer(layer->getLayerID());
+ }
+ }
+ }
+
+ delete mPluginLayerTypes.take(typeName);
+ return true;
+}
+
+QgsPluginLayerType* QgsPluginLayerRegistry::pluginLayerType(QString typeName)
+{
+ return mPluginLayerTypes.value(typeName, NULL);
+}
+
+
+QgsPluginLayer* QgsPluginLayerRegistry::createLayer(QString typeName)
+{
+ QgsPluginLayerType* type = pluginLayerType(typeName);
+ if (!type)
+ {
+ QgsDebugMsg("Unknown plugin layer type: "+typeName);
+ return NULL;
+ }
+
+ return type->createLayer();
+}
Added: trunk/qgis/src/core/qgspluginlayerregistry.h
===================================================================
--- trunk/qgis/src/core/qgspluginlayerregistry.h (rev 0)
+++ trunk/qgis/src/core/qgspluginlayerregistry.h 2010-01-26 15:43:54 UTC (rev 12834)
@@ -0,0 +1,89 @@
+/***************************************************************************
+ qgspluginlayerregistry.cpp - class for
+ registering plugin layer creators
+ -------------------
+ begin : Mon Nov 30 2009
+ copyright : (C) 2009 by Mathias Walker, Sourcepole
+ email : mwa at sourcepole.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+/* $Id$ */
+
+#ifndef QGSPLUGINLAYERREGSITRY_H
+#define QGSPLUGINLAYERREGSITRY_H
+
+#include <QMap>
+#include <QDomNode>
+
+class QgsPluginLayer;
+
+/** \ingroup core
+ class for creating plugin specific layers
+*/
+class CORE_EXPORT QgsPluginLayerType
+{
+ public:
+
+ QgsPluginLayerType(QString name);
+ virtual ~QgsPluginLayerType();
+
+ QString name();
+
+ /** return new layer of this type. Return NULL on error */
+ virtual QgsPluginLayer* createLayer();
+
+ /** show plugin layer properties dialog. Return FALSE if the dialog cannot be shown. */
+ virtual bool showLayerProperties(QgsPluginLayer* layer);
+
+protected:
+ QString mName;
+};
+
+//=============================================================================
+
+/** \ingroup core
+ a registry of plugin layers types
+*/
+class CORE_EXPORT QgsPluginLayerRegistry
+{
+ public:
+
+ /** means of accessing canonical single instance */
+ static QgsPluginLayerRegistry* instance();
+
+ ~QgsPluginLayerRegistry();
+
+ /** add plugin layer type (take ownership) and return TRUE on success */
+ bool addPluginLayerType(QgsPluginLayerType* pluginLayerType);
+
+ /** remove plugin layer type and return TRUE on success */
+ bool removePluginLayerType(QString typeName);
+
+ /** return plugin layer type metadata or NULL if doesn't exist */
+ QgsPluginLayerType* pluginLayerType(QString typeName);
+
+ /** return new layer if corresponding plugin has been found, else return NULL */
+ QgsPluginLayer* createLayer(QString typeName);
+
+ private:
+
+ typedef QMap<QString, QgsPluginLayerType*> PluginLayerTypes;
+
+ /** private since instance() creates it */
+ QgsPluginLayerRegistry();
+
+ /** pointer to canonical Singleton object */
+ static QgsPluginLayerRegistry* _instance;
+
+ PluginLayerTypes mPluginLayerTypes;
+};
+
+#endif // QGSPLUGINLAYERREGSITRY_H
Modified: trunk/qgis/src/core/qgsproject.cpp
===================================================================
--- trunk/qgis/src/core/qgsproject.cpp 2010-01-25 22:00:08 UTC (rev 12833)
+++ trunk/qgis/src/core/qgsproject.cpp 2010-01-26 15:43:54 UTC (rev 12834)
@@ -30,6 +30,8 @@
#include "qgslogger.h"
#include "qgsprojectfiletransform.h"
#include "qgsprojectversion.h"
+#include "qgspluginlayer.h"
+#include "qgspluginlayerregistry.h"
#include <QApplication>
#include <QFileInfo>
@@ -695,6 +697,11 @@
{
mapLayer = new QgsRasterLayer;
}
+ else if ( type == "plugin" )
+ {
+ QString typeName = element.attribute( "name" );
+ mapLayer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
+ }
Q_CHECK_PTR( mapLayer );
@@ -873,7 +880,7 @@
{
QString type = layerNode.toElement().attribute( "type" );
- QgsMapLayer *mapLayer;
+ QgsMapLayer *mapLayer = NULL;
if ( type == "vector" )
{
@@ -883,6 +890,11 @@
{
mapLayer = new QgsRasterLayer;
}
+ else if ( type == "plugin" )
+ {
+ QString typeName = layerNode.toElement().attribute( "name" );
+ mapLayer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
+ }
else
{
QgsDebugMsg( "bad layer type" );
More information about the QGIS-commit
mailing list