Skip to content

Commit f951d16

Browse files
author
wonder
committedJan 26, 2010
[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/qgis@12834 c8812cc2-4d05-0410-92ff-de0c093fc19c

14 files changed

+387
-7
lines changed
 

‎python/core/core.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
%Include qgsmarkercatalogue.sip
4444
%Include qgsmessageoutput.sip
4545
%Include qgsoverlayobject.sip
46+
%Include qgspluginlayer.sip
47+
%Include qgspluginlayerregistry.sip
4648
%Include qgspoint.sip
4749
%Include qgsproject.sip
4850
%Include qgsprovidermetadata.sip

‎python/core/qgsmaplayer.sip

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ class QgsMapLayer : QObject
2222
{
2323
sipClass = sipClass_QgsRasterLayer;
2424
}
25+
else if (layer->type() == QgsMapLayer::PluginLayer)
26+
{
27+
sipClass = sipClass_QgsPluginLayer;
28+
}
2529
}
2630
else
2731
{
@@ -35,7 +39,8 @@ public:
3539
enum LayerType
3640
{
3741
VectorLayer,
38-
RasterLayer
42+
RasterLayer,
43+
PluginLayer
3944
};
4045

4146
/** Constructor
@@ -109,7 +114,7 @@ public:
109114

110115

111116
/** True if the layer can be edited */
112-
virtual bool isEditable() const = 0;
117+
virtual bool isEditable() const;
113118

114119
/** sets state from Dom document
115120
@param layer_node is Dom node corresponding to ``maplayer'' tag
@@ -323,6 +328,9 @@ signals:
323328

324329
protected:
325330

331+
/** set whether layer is valid or not - should be used in constructor */
332+
void setValid( bool valid );
333+
326334
/** called by readXML(), used by children to read state specific to them from
327335
project files.
328336
*/

‎python/core/qgspluginlayer.sip

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
class QgsPluginLayer : QgsMapLayer
3+
{
4+
%TypeHeaderCode
5+
#include "qgspluginlayer.h"
6+
%End
7+
8+
public:
9+
QgsPluginLayer(QString layerType, QString layerName = QString());
10+
11+
/** return plugin layer type (the same as used in QgsPluginLayerRegistry) */
12+
QString pluginLayerType();
13+
14+
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
class QgsPluginLayerType
3+
{
4+
%TypeHeaderCode
5+
#include "qgspluginlayerregistry.h"
6+
%End
7+
public:
8+
9+
QgsPluginLayerType(QString name);
10+
virtual ~QgsPluginLayerType();
11+
12+
QString name();
13+
14+
/** return new layer of this type. Return NULL on error */
15+
virtual QgsPluginLayer* createLayer() /Factory/;
16+
17+
/** show plugin layer properties dialog. Return FALSE if the dialog cannot be shown. */
18+
virtual bool showLayerProperties(QgsPluginLayer* layer);
19+
20+
};
21+
22+
23+
class QgsPluginLayerRegistry
24+
{
25+
%TypeHeaderCode
26+
#include "qgspluginlayerregistry.h"
27+
%End
28+
public:
29+
30+
/** means of accessing canonical single instance */
31+
static QgsPluginLayerRegistry* instance();
32+
33+
~QgsPluginLayerRegistry();
34+
35+
/** add plugin layer type (take ownership) and return TRUE on success */
36+
bool addPluginLayerType(QgsPluginLayerType* pluginLayerType /Transfer/);
37+
38+
/** remove plugin layer type and return TRUE on success */
39+
bool removePluginLayerType(QString typeName);
40+
41+
/** return plugin layer type metadata or NULL if doesn't exist */
42+
QgsPluginLayerType* pluginLayerType(QString typeName);
43+
44+
/** return new layer if corresponding plugin has been found, else return NULL */
45+
// to be resolved
46+
//QgsPluginLayer* createLayer(QString typeName);
47+
48+
private:
49+
50+
/** private since instance() creates it */
51+
QgsPluginLayerRegistry();
52+
};

‎src/app/legend/qgslegendlayer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ void QgsLegendLayer::refreshSymbology( const QString& key, double widthScale )
165165
else
166166
vectorLayerSymbology( vlayer, widthScale ); // get and change symbology
167167
}
168-
else // RASTER
168+
else if ( theMapLayer->type() == QgsMapLayer::RasterLayer ) // RASTER
169169
{
170170
QgsRasterLayer* rlayer = qobject_cast<QgsRasterLayer *>( theMapLayer );
171171
rasterLayerSymbology( rlayer ); // get and change symbology

‎src/app/qgisapp.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@
118118
#include "qgsoptions.h"
119119
#include "qgspastetransformations.h"
120120
#include "qgspluginitem.h"
121+
#include "qgspluginlayer.h"
122+
#include "qgspluginlayerregistry.h"
121123
#include "qgspluginmanager.h"
122124
#include "qgspluginmetadata.h"
123125
#include "qgspluginregistry.h"
@@ -6108,7 +6110,7 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
61086110
rlp->exec();
61096111
delete rlp; // delete since dialog cannot be reused without updating code
61106112
}
6111-
else // VECTOR
6113+
else if ( ml->type() == QgsMapLayer::VectorLayer ) // VECTOR
61126114
{
61136115
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( ml );
61146116

@@ -6125,4 +6127,20 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
61256127
vlp->exec();
61266128
delete vlp; // delete since dialog cannot be reused without updating code
61276129
}
6130+
else if ( ml->type() == QgsMapLayer::PluginLayer )
6131+
{
6132+
QgsPluginLayer* pl = qobject_cast<QgsPluginLayer *>( ml );
6133+
if ( !pl )
6134+
return;
6135+
6136+
QgsPluginLayerType* plt = QgsPluginLayerRegistry::instance()->pluginLayerType( pl->pluginLayerType() );
6137+
if ( !plt )
6138+
return;
6139+
6140+
if ( !plt->showLayerProperties( pl ) )
6141+
{
6142+
QMessageBox::information( this, tr( "Warning" ), tr( "This layer doesn't have a properties dialog." ) );
6143+
}
6144+
6145+
}
61286146
}

‎src/core/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ SET(QGIS_CORE_SRCS
6060
qgsoverlayobject.cpp
6161
qgspalgeometry.cpp
6262
qgspalobjectpositionmanager.cpp
63+
qgspluginlayer.cpp
64+
qgspluginlayerregistry.cpp
6365
qgspoint.cpp
6466
qgsproject.cpp
6567
qgsprojectfiletransform.cpp
@@ -221,6 +223,7 @@ SET(QGIS_CORE_MOC_HDRS
221223
qgsmaplayerregistry.h
222224
qgsmaprenderer.h
223225
qgsmessageoutput.h
226+
qgspluginlayer.h
224227
qgsproject.h
225228
qgsrunprocess.h
226229
qgsvectorlayer.h
@@ -388,6 +391,8 @@ SET(QGIS_CORE_HDRS
388391
qgsmessageoutput.h
389392
qgsoverlayobjectpositionmanager.h
390393
qgspalobjectpositionmanager.h
394+
qgspluginlayer.h
395+
qgspluginlayerregistry.h
391396
qgspoint.h
392397
qgsproject.h
393398
qgsprojectfiletransform.h

‎src/core/qgsmaplayer.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,3 +850,12 @@ void QgsMapLayer::setCacheImage( QImage * thepImage )
850850
mpCacheImage = thepImage;
851851
}
852852

853+
bool QgsMapLayer::isEditable() const
854+
{
855+
return false;
856+
}
857+
858+
void QgsMapLayer::setValid( bool valid )
859+
{
860+
mValid = valid;
861+
}

‎src/core/qgsmaplayer.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
4848
enum LayerType
4949
{
5050
VectorLayer,
51-
RasterLayer
51+
RasterLayer,
52+
PluginLayer
5253
};
5354

5455
/** Constructor
@@ -126,7 +127,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
126127

127128

128129
/** True if the layer can be edited */
129-
virtual bool isEditable() const = 0;
130+
virtual bool isEditable() const;
130131

131132
/** sets state from Dom document
132133
@param layer_node is Dom node corresponding to ``maplayer'' tag
@@ -343,6 +344,9 @@ class CORE_EXPORT QgsMapLayer : public QObject
343344

344345
protected:
345346

347+
/** set whether layer is valid or not - should be used in constructor */
348+
void setValid( bool valid );
349+
346350
/** called by readXML(), used by children to read state specific to them from
347351
project files.
348352
*/

‎src/core/qgspluginlayer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "qgspluginlayer.h"
2+
3+
QgsPluginLayer::QgsPluginLayer( QString layerType, QString layerName )
4+
: QgsMapLayer( PluginLayer, layerName ), mPluginLayerType( layerType )
5+
{
6+
}
7+
8+
QString QgsPluginLayer::pluginLayerType()
9+
{
10+
return mPluginLayerType;
11+
}

‎src/core/qgspluginlayer.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef QGSPLUGINLAYER_H
2+
#define QGSPLUGINLAYER_H
3+
4+
#include "qgsmaplayer.h"
5+
6+
/** \ingroup core
7+
Base class for plugin layers. These can be implemented by plugins
8+
and registered in QgsPluginLayerRegistry.
9+
10+
In order to be readable from project files, they should set these attributes in layer DOM node:
11+
"type" = "plugin"
12+
"name" = "your_layer_type"
13+
*/
14+
class CORE_EXPORT QgsPluginLayer : public QgsMapLayer
15+
{
16+
Q_OBJECT
17+
18+
public:
19+
QgsPluginLayer( QString layerType, QString layerName = QString() );
20+
21+
/** return plugin layer type (the same as used in QgsPluginLayerRegistry) */
22+
QString pluginLayerType();
23+
24+
protected:
25+
QString mPluginLayerType;
26+
};
27+
28+
#endif // QGSPLUGINLAYER_H

‎src/core/qgspluginlayerregistry.cpp

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/***************************************************************************
2+
qgspluginlayerregistry.cpp - class for
3+
registering plugin layer creators
4+
-------------------
5+
begin : Mon Nov 30 2009
6+
copyright : (C) 2009 by Mathias Walker, Sourcepole
7+
email : mwa at sourcepole.ch
8+
***************************************************************************/
9+
10+
/***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
/* $Id$ */
19+
20+
#include "qgspluginlayerregistry.h"
21+
#include "qgslogger.h"
22+
#include "qgspluginlayer.h"
23+
#include "qgsmaplayerregistry.h"
24+
25+
QgsPluginLayerType::QgsPluginLayerType(QString name)
26+
: mName(name)
27+
{
28+
}
29+
30+
QgsPluginLayerType::~QgsPluginLayerType()
31+
{
32+
}
33+
34+
QString QgsPluginLayerType::name()
35+
{
36+
return mName;
37+
}
38+
39+
QgsPluginLayer* QgsPluginLayerType::createLayer()
40+
{
41+
return NULL;
42+
}
43+
44+
bool QgsPluginLayerType::showLayerProperties(QgsPluginLayer* layer)
45+
{
46+
return false;
47+
}
48+
49+
//=============================================================================
50+
51+
/** Static calls to enforce singleton behaviour */
52+
QgsPluginLayerRegistry* QgsPluginLayerRegistry::_instance = NULL;
53+
QgsPluginLayerRegistry* QgsPluginLayerRegistry::instance()
54+
{
55+
if ( _instance == NULL )
56+
{
57+
_instance = new QgsPluginLayerRegistry();
58+
}
59+
return _instance;
60+
}
61+
62+
63+
QgsPluginLayerRegistry::QgsPluginLayerRegistry()
64+
{
65+
}
66+
67+
QgsPluginLayerRegistry::~QgsPluginLayerRegistry()
68+
{
69+
if ( !mPluginLayerTypes.isEmpty() )
70+
{
71+
QgsDebugMsg("QgsPluginLayerRegistry::~QgsPluginLayerRegistry(): creator list not empty");
72+
foreach (QString typeName, mPluginLayerTypes.keys())
73+
removePluginLayerType(typeName);
74+
}
75+
}
76+
77+
bool QgsPluginLayerRegistry::addPluginLayerType(QgsPluginLayerType* type)
78+
{
79+
if (type == NULL)
80+
return false;
81+
if (mPluginLayerTypes.contains(type->name()))
82+
return false;
83+
84+
mPluginLayerTypes[type->name()] = type;
85+
return true;
86+
}
87+
88+
89+
bool QgsPluginLayerRegistry::removePluginLayerType(QString typeName)
90+
{
91+
if (!mPluginLayerTypes.contains(typeName))
92+
return false;
93+
94+
// remove all remaining layers of this type - to avoid invalid behaviour
95+
QList<QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers().values();
96+
foreach (QgsMapLayer* layer, layers)
97+
{
98+
if (layer->type() == QgsMapLayer::PluginLayer)
99+
{
100+
QgsPluginLayer* pl = qobject_cast<QgsPluginLayer*>(layer);
101+
if (pl->pluginLayerType() == typeName)
102+
{
103+
QgsMapLayerRegistry::instance()->removeMapLayer(layer->getLayerID());
104+
}
105+
}
106+
}
107+
108+
delete mPluginLayerTypes.take(typeName);
109+
return true;
110+
}
111+
112+
QgsPluginLayerType* QgsPluginLayerRegistry::pluginLayerType(QString typeName)
113+
{
114+
return mPluginLayerTypes.value(typeName, NULL);
115+
}
116+
117+
118+
QgsPluginLayer* QgsPluginLayerRegistry::createLayer(QString typeName)
119+
{
120+
QgsPluginLayerType* type = pluginLayerType(typeName);
121+
if (!type)
122+
{
123+
QgsDebugMsg("Unknown plugin layer type: "+typeName);
124+
return NULL;
125+
}
126+
127+
return type->createLayer();
128+
}

‎src/core/qgspluginlayerregistry.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/***************************************************************************
2+
qgspluginlayerregistry.cpp - class for
3+
registering plugin layer creators
4+
-------------------
5+
begin : Mon Nov 30 2009
6+
copyright : (C) 2009 by Mathias Walker, Sourcepole
7+
email : mwa at sourcepole.ch
8+
***************************************************************************/
9+
10+
/***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************/
18+
/* $Id$ */
19+
20+
#ifndef QGSPLUGINLAYERREGSITRY_H
21+
#define QGSPLUGINLAYERREGSITRY_H
22+
23+
#include <QMap>
24+
#include <QDomNode>
25+
26+
class QgsPluginLayer;
27+
28+
/** \ingroup core
29+
class for creating plugin specific layers
30+
*/
31+
class CORE_EXPORT QgsPluginLayerType
32+
{
33+
public:
34+
35+
QgsPluginLayerType(QString name);
36+
virtual ~QgsPluginLayerType();
37+
38+
QString name();
39+
40+
/** return new layer of this type. Return NULL on error */
41+
virtual QgsPluginLayer* createLayer();
42+
43+
/** show plugin layer properties dialog. Return FALSE if the dialog cannot be shown. */
44+
virtual bool showLayerProperties(QgsPluginLayer* layer);
45+
46+
protected:
47+
QString mName;
48+
};
49+
50+
//=============================================================================
51+
52+
/** \ingroup core
53+
a registry of plugin layers types
54+
*/
55+
class CORE_EXPORT QgsPluginLayerRegistry
56+
{
57+
public:
58+
59+
/** means of accessing canonical single instance */
60+
static QgsPluginLayerRegistry* instance();
61+
62+
~QgsPluginLayerRegistry();
63+
64+
/** add plugin layer type (take ownership) and return TRUE on success */
65+
bool addPluginLayerType(QgsPluginLayerType* pluginLayerType);
66+
67+
/** remove plugin layer type and return TRUE on success */
68+
bool removePluginLayerType(QString typeName);
69+
70+
/** return plugin layer type metadata or NULL if doesn't exist */
71+
QgsPluginLayerType* pluginLayerType(QString typeName);
72+
73+
/** return new layer if corresponding plugin has been found, else return NULL */
74+
QgsPluginLayer* createLayer(QString typeName);
75+
76+
private:
77+
78+
typedef QMap<QString, QgsPluginLayerType*> PluginLayerTypes;
79+
80+
/** private since instance() creates it */
81+
QgsPluginLayerRegistry();
82+
83+
/** pointer to canonical Singleton object */
84+
static QgsPluginLayerRegistry* _instance;
85+
86+
PluginLayerTypes mPluginLayerTypes;
87+
};
88+
89+
#endif // QGSPLUGINLAYERREGSITRY_H

‎src/core/qgsproject.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "qgslogger.h"
3131
#include "qgsprojectfiletransform.h"
3232
#include "qgsprojectversion.h"
33+
#include "qgspluginlayer.h"
34+
#include "qgspluginlayerregistry.h"
3335

3436
#include <QApplication>
3537
#include <QFileInfo>
@@ -695,6 +697,11 @@ QPair< bool, QList<QDomNode> > QgsProject::_getMapLayers( QDomDocument const &do
695697
{
696698
mapLayer = new QgsRasterLayer;
697699
}
700+
else if ( type == "plugin" )
701+
{
702+
QString typeName = element.attribute( "name" );
703+
mapLayer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
704+
}
698705

699706
Q_CHECK_PTR( mapLayer );
700707

@@ -873,7 +880,7 @@ bool QgsProject::read( QDomNode & layerNode )
873880
{
874881
QString type = layerNode.toElement().attribute( "type" );
875882

876-
QgsMapLayer *mapLayer;
883+
QgsMapLayer *mapLayer = NULL;
877884

878885
if ( type == "vector" )
879886
{
@@ -883,6 +890,11 @@ bool QgsProject::read( QDomNode & layerNode )
883890
{
884891
mapLayer = new QgsRasterLayer;
885892
}
893+
else if ( type == "plugin" )
894+
{
895+
QString typeName = layerNode.toElement().attribute( "name" );
896+
mapLayer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
897+
}
886898
else
887899
{
888900
QgsDebugMsg( "bad layer type" );

0 commit comments

Comments
 (0)
Please sign in to comment.