mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
[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. git-svn-id: http://svn.osgeo.org/qgis/trunk@12834 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
d8e8ee466d
commit
8f32f25a90
@ -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
|
||||
|
@ -22,6 +22,10 @@ class QgsMapLayer : QObject
|
||||
{
|
||||
sipClass = sipClass_QgsRasterLayer;
|
||||
}
|
||||
else if (layer->type() == QgsMapLayer::PluginLayer)
|
||||
{
|
||||
sipClass = sipClass_QgsPluginLayer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -35,7 +39,8 @@ public:
|
||||
enum LayerType
|
||||
{
|
||||
VectorLayer,
|
||||
RasterLayer
|
||||
RasterLayer,
|
||||
PluginLayer
|
||||
};
|
||||
|
||||
/** Constructor
|
||||
@ -109,7 +114,7 @@ public:
|
||||
|
||||
|
||||
/** 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 @@ signals:
|
||||
|
||||
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.
|
||||
*/
|
||||
|
14
python/core/qgspluginlayer.sip
Normal file
14
python/core/qgspluginlayer.sip
Normal file
@ -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();
|
||||
|
||||
};
|
52
python/core/qgspluginlayerregistry.sip
Normal file
52
python/core/qgspluginlayerregistry.sip
Normal file
@ -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();
|
||||
};
|
@ -165,7 +165,7 @@ void QgsLegendLayer::refreshSymbology( const QString& key, double widthScale )
|
||||
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
|
||||
|
@ -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 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
|
||||
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 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
|
||||
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." ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ SET(QGIS_CORE_SRCS
|
||||
qgsoverlayobject.cpp
|
||||
qgspalgeometry.cpp
|
||||
qgspalobjectpositionmanager.cpp
|
||||
qgspluginlayer.cpp
|
||||
qgspluginlayerregistry.cpp
|
||||
qgspoint.cpp
|
||||
qgsproject.cpp
|
||||
qgsprojectfiletransform.cpp
|
||||
@ -221,6 +223,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
qgsmaplayerregistry.h
|
||||
qgsmaprenderer.h
|
||||
qgsmessageoutput.h
|
||||
qgspluginlayer.h
|
||||
qgsproject.h
|
||||
qgsrunprocess.h
|
||||
qgsvectorlayer.h
|
||||
@ -388,6 +391,8 @@ SET(QGIS_CORE_HDRS
|
||||
qgsmessageoutput.h
|
||||
qgsoverlayobjectpositionmanager.h
|
||||
qgspalobjectpositionmanager.h
|
||||
qgspluginlayer.h
|
||||
qgspluginlayerregistry.h
|
||||
qgspoint.h
|
||||
qgsproject.h
|
||||
qgsprojectfiletransform.h
|
||||
|
@ -850,3 +850,12 @@ void QgsMapLayer::setCacheImage( QImage * thepImage )
|
||||
mpCacheImage = thepImage;
|
||||
}
|
||||
|
||||
bool QgsMapLayer::isEditable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void QgsMapLayer::setValid( bool valid )
|
||||
{
|
||||
mValid = valid;
|
||||
}
|
||||
|
@ -48,7 +48,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
enum LayerType
|
||||
{
|
||||
VectorLayer,
|
||||
RasterLayer
|
||||
RasterLayer,
|
||||
PluginLayer
|
||||
};
|
||||
|
||||
/** Constructor
|
||||
@ -126,7 +127,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
|
||||
|
||||
/** 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 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
|
||||
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.
|
||||
*/
|
||||
|
11
src/core/qgspluginlayer.cpp
Normal file
11
src/core/qgspluginlayer.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "qgspluginlayer.h"
|
||||
|
||||
QgsPluginLayer::QgsPluginLayer( QString layerType, QString layerName )
|
||||
: QgsMapLayer( PluginLayer, layerName ), mPluginLayerType( layerType )
|
||||
{
|
||||
}
|
||||
|
||||
QString QgsPluginLayer::pluginLayerType()
|
||||
{
|
||||
return mPluginLayerType;
|
||||
}
|
28
src/core/qgspluginlayer.h
Normal file
28
src/core/qgspluginlayer.h
Normal file
@ -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
|
128
src/core/qgspluginlayerregistry.cpp
Normal file
128
src/core/qgspluginlayerregistry.cpp
Normal file
@ -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();
|
||||
}
|
89
src/core/qgspluginlayerregistry.h
Normal file
89
src/core/qgspluginlayerregistry.h
Normal file
@ -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
|
@ -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 @@ QPair< bool, QList<QDomNode> > QgsProject::_getMapLayers( QDomDocument const &do
|
||||
{
|
||||
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 @@ bool QgsProject::read( QDomNode & layerNode )
|
||||
{
|
||||
QString type = layerNode.toElement().attribute( "type" );
|
||||
|
||||
QgsMapLayer *mapLayer;
|
||||
QgsMapLayer *mapLayer = NULL;
|
||||
|
||||
if ( type == "vector" )
|
||||
{
|
||||
@ -883,6 +890,11 @@ bool QgsProject::read( QDomNode & layerNode )
|
||||
{
|
||||
mapLayer = new QgsRasterLayer;
|
||||
}
|
||||
else if ( type == "plugin" )
|
||||
{
|
||||
QString typeName = layerNode.toElement().attribute( "name" );
|
||||
mapLayer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "bad layer type" );
|
||||
|
Loading…
x
Reference in New Issue
Block a user