[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