Skip to content

Commit

Permalink
Legend refactoring: first steps towards legend customization
Browse files Browse the repository at this point in the history
- map layers have associated QgsMapLayerLegend instance
- QgsMapLayerLegend is interface for generation of legend with some default implementations
- QgsLayerTreeModelLegendNode is interface for representation of legend item in layer tree model with some default implementations
  • Loading branch information
wonder-sk committed Jul 17, 2014
1 parent cb1e0fb commit 57dcfca
Show file tree
Hide file tree
Showing 13 changed files with 730 additions and 198 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
%Include qgslabelsearchtree.sip
%Include qgslogger.sip
%Include qgsmaplayer.sip
%Include qgsmaplayerlegend.sip
%Include qgsmaplayerregistry.sip
%Include qgsmaplayerrenderer.sip
%Include qgsmaprenderer.sip
Expand Down
17 changes: 17 additions & 0 deletions python/core/qgsmaplayer.sip
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,17 @@ class QgsMapLayer : QObject
/** @deprecated since 2.4 - does nothing */
virtual void onCacheImageDelete() /Deprecated/;

/**
* Assign a legend controller to the map layer. The object will be responsible for providing legend items.
* @param legend Takes ownership of the object. Can be null pointer
* @note added in 2.6
*/
void setLegend( QgsMapLayerLegend* legend /Transfer/ );
/**
* @note added in 2.6
*/
QgsMapLayerLegend* legend() const;

public slots:

/** Event handler for when a coordinate transform fails due to bad vertex error */
Expand Down Expand Up @@ -430,6 +441,12 @@ class QgsMapLayer : QObject
/** Signal emitted when renderer is changed */
void rendererChanged();

/**
* Signal emitted when legend of the layer has changed
* @note added in 2.6
*/
void legendChanged();

protected:
/** Set the extent */
virtual void setExtent( const QgsRectangle &rect );
Expand Down
163 changes: 163 additions & 0 deletions python/core/qgsmaplayerlegend.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@

/**
* The QgsLegendRendererItem class is abstract interface for legend items
* returned from QgsMapLayerLegend implementation.
*
* The objects are used in QgsLayerTreeModel. Custom implementations may offer additional interactivity
* and customized look.
*
* @note added in 2.6
*/
class QgsLayerTreeModelLegendNode : QObject
{
%TypeHeaderCode
#include <qgsmaplayerlegend.h>
%End

public:

/** Return pointer to the parent layer node */
QgsLayerTreeLayer* parent() const;

/** Return item flags associated with the item. Default implementation returns Qt::ItemIsEnabled. */
virtual Qt::ItemFlags flags() const;

/** Return data associated with the item. Must be implemented in derived class. */
virtual QVariant data( int role ) const = 0;

/** Set some data associated with the item. Default implementation does nothing and returns false. */
virtual bool setData( const QVariant& value, int role );

protected:
/** Construct the node with pointer to its parent layer node */
explicit QgsLayerTreeModelLegendNode( QgsLayerTreeLayer* nodeL );
};


/**
* Implementation of legend node interface for displaying preview of vector symbols and their labels
* and allowing interaction with the symbol / renderer.
*
* @note added in 2.6
*/
class QgsSymbolV2LegendNode : QgsLayerTreeModelLegendNode
{
%TypeHeaderCode
#include <qgsmaplayerlegend.h>
%End
public:
QgsSymbolV2LegendNode( QgsLayerTreeLayer* nodeLayer, QgsSymbolV2* symbol, const QString& label, int rendererRef = -1 );

virtual Qt::ItemFlags flags() const;
virtual QVariant data( int role ) const;
virtual bool setData( const QVariant& value, int role );
};


/**
* Implementation of legend node interface for displaying arbitrary label with icon.
*
* @note added in 2.6
*/
class QgsSimpleLegendNode : QgsLayerTreeModelLegendNode
{
%TypeHeaderCode
#include <qgsmaplayerlegend.h>
%End
public:
QgsSimpleLegendNode( QgsLayerTreeLayer* nodeLayer, const QString& label, const QIcon& icon = QIcon() );

virtual QVariant data( int role ) const;
};


/**
* The QgsMapLayerLegend class is abstract interface for implementations
* of legends for one map layer.
*
* @note added in 2.6
*/
class QgsMapLayerLegend : QObject
{
%TypeHeaderCode
#include <qgsmaplayerlegend.h>
%End

public:
explicit QgsMapLayerLegend( QObject *parent /TransferThis/ = 0 );

// TODO: type, load/save settings

/**
* Return list of legend nodes to be used for a particular layer tree layer node.
* Ownership is transferred to the caller.
*/
virtual QList<QgsLayerTreeModelLegendNode*> createLayerTreeModelLegendNodes( QgsLayerTreeLayer* nodeLayer ) = 0 /Factory/;

// TODO: support for layer tree view delegates

// TODO: support for legend renderer


//! Create new legend implementation for vector layer
static QgsMapLayerLegend* defaultVectorLegend( QgsVectorLayer* vl ) /Factory/;

//! Create new legend implementation for raster layer
static QgsMapLayerLegend* defaultRasterLegend( QgsRasterLayer* rl ) /Factory/;

//! Create new legend implementation for raster layer
static QgsMapLayerLegend* defaultPluginLegend( QgsPluginLayer* pl ) /Factory/;

signals:
//! Emitted when existing items/nodes got invalid and should be replaced by new ones
void itemsChanged();
};


/** Default legend implementation for vector layers
* @note added in 2.6
*/
class QgsDefaultVectorLayerLegend : QgsMapLayerLegend
{
%TypeHeaderCode
#include <qgsmaplayerlegend.h>
%End
public:
explicit QgsDefaultVectorLayerLegend( QgsVectorLayer* vl );

virtual QList<QgsLayerTreeModelLegendNode*> createLayerTreeModelLegendNodes( QgsLayerTreeLayer* nodeLayer ) /Factory/;

};


/** Default legend implementation for raster layers
* @note added in 2.6
*/
class QgsDefaultRasterLayerLegend : QgsMapLayerLegend
{
%TypeHeaderCode
#include <qgsmaplayerlegend.h>
%End
public:
explicit QgsDefaultRasterLayerLegend( QgsRasterLayer* rl );

virtual QList<QgsLayerTreeModelLegendNode*> createLayerTreeModelLegendNodes( QgsLayerTreeLayer* nodeLayer ) /Factory/;

};


/** Default legend implementation for plugin layers
* @note added in 2.6
*/
class QgsDefaultPluginLayerLegend : QgsMapLayerLegend
{
%TypeHeaderCode
#include <qgsmaplayerlegend.h>
%End
public:
explicit QgsDefaultPluginLayerLegend( QgsPluginLayer* pl );

virtual QList<QgsLayerTreeModelLegendNode*> createLayerTreeModelLegendNodes( QgsLayerTreeLayer* nodeLayer ) /Factory/;

};

3 changes: 3 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ SET(QGIS_CORE_SRCS
qgslegendsettings.cpp
qgslogger.cpp
qgsmaplayer.cpp
qgsmaplayerlegend.cpp
qgsmaplayerregistry.cpp
qgsmaprenderer.cpp
qgsmaprenderercache.cpp
Expand Down Expand Up @@ -336,6 +337,7 @@ SET(QGIS_CORE_MOC_HDRS
qgsgmlschema.h
qgshttptransaction.h
qgsmaplayer.h
qgsmaplayerlegend.h
qgsmaplayerregistry.h
qgsmaprenderer.h
qgsmaprenderercache.h
Expand Down Expand Up @@ -469,6 +471,7 @@ SET(QGIS_CORE_HDRS
qgslegendsettings.h
qgslogger.h
qgsmaplayer.h
qgsmaplayerlegend.h
qgsmaplayerregistry.h
qgsmaprenderer.h
qgsmaprenderercache.h
Expand Down
22 changes: 22 additions & 0 deletions src/core/qgsmaplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "qgsmaplayer.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsapplication.h"
#include "qgsmaplayerlegend.h"
#include "qgsproject.h"
#include "qgspluginlayerregistry.h"
#include "qgsprojectfiletransform.h"
Expand All @@ -53,6 +54,7 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
mID( "" ),
mLayerType( type ),
mBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal blending
, mLegend( 0 )
{
mCRS = new QgsCoordinateReferenceSystem();

Expand Down Expand Up @@ -81,6 +83,7 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
QgsMapLayer::~QgsMapLayer()
{
delete mCRS;
delete mLegend;
}

QgsMapLayer::LayerType QgsMapLayer::type() const
Expand Down Expand Up @@ -1376,6 +1379,25 @@ void QgsMapLayer::setCacheImage( QImage * )
emit repaintRequested();
}

void QgsMapLayer::setLegend( QgsMapLayerLegend* legend )
{
if ( legend == mLegend )
return;

delete mLegend;
mLegend = legend;

if ( mLegend )
connect( mLegend, SIGNAL( itemsChanged() ), this, SIGNAL( legendChanged() ) );

emit legendChanged();
}

QgsMapLayerLegend*QgsMapLayer::legend() const
{
return mLegend;
}

void QgsMapLayer::clearCacheImage()
{
emit repaintRequested();
Expand Down
21 changes: 21 additions & 0 deletions src/core/qgsmaplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

class QgsRenderContext;
class QgsCoordinateReferenceSystem;
class QgsMapLayerLegend;
class QgsMapLayerRenderer;

class QDomDocument;
Expand Down Expand Up @@ -382,6 +383,17 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** @deprecated since 2.4 - does nothing */
Q_DECL_DEPRECATED virtual void onCacheImageDelete() {}

/**
* Assign a legend controller to the map layer. The object will be responsible for providing legend items.
* @param legend Takes ownership of the object. Can be null pointer
* @note added in 2.6
*/
void setLegend( QgsMapLayerLegend* legend );
/**
* @note added in 2.6
*/
QgsMapLayerLegend* legend() const;

public slots:

/** Event handler for when a coordinate transform fails due to bad vertex error */
Expand Down Expand Up @@ -446,6 +458,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** Signal emitted when renderer is changed */
void rendererChanged();

/**
* Signal emitted when legend of the layer has changed
* @note added in 2.6
*/
void legendChanged();

protected:
/** Set the extent */
virtual void setExtent( const QgsRectangle &rect );
Expand Down Expand Up @@ -559,6 +577,9 @@ class CORE_EXPORT QgsMapLayer : public QObject

//! Layer's persistent storage of additional properties (may be used by plugins)
QgsObjectCustomProperties mCustomProperties;

//! Controller of legend items of this layer
QgsMapLayerLegend* mLegend;
};

#endif
Loading

0 comments on commit 57dcfca

Please sign in to comment.