Skip to content

Commit 57dcfca

Browse files
committed
Legend refactoring: first steps towards legend customization
- 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
1 parent cb1e0fb commit 57dcfca

File tree

13 files changed

+730
-198
lines changed

13 files changed

+730
-198
lines changed

python/core/core.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
%Include qgslabelsearchtree.sip
4848
%Include qgslogger.sip
4949
%Include qgsmaplayer.sip
50+
%Include qgsmaplayerlegend.sip
5051
%Include qgsmaplayerregistry.sip
5152
%Include qgsmaplayerrenderer.sip
5253
%Include qgsmaprenderer.sip

python/core/qgsmaplayer.sip

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,17 @@ class QgsMapLayer : QObject
366366
/** @deprecated since 2.4 - does nothing */
367367
virtual void onCacheImageDelete() /Deprecated/;
368368

369+
/**
370+
* Assign a legend controller to the map layer. The object will be responsible for providing legend items.
371+
* @param legend Takes ownership of the object. Can be null pointer
372+
* @note added in 2.6
373+
*/
374+
void setLegend( QgsMapLayerLegend* legend /Transfer/ );
375+
/**
376+
* @note added in 2.6
377+
*/
378+
QgsMapLayerLegend* legend() const;
379+
369380
public slots:
370381

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

444+
/**
445+
* Signal emitted when legend of the layer has changed
446+
* @note added in 2.6
447+
*/
448+
void legendChanged();
449+
433450
protected:
434451
/** Set the extent */
435452
virtual void setExtent( const QgsRectangle &rect );

python/core/qgsmaplayerlegend.sip

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
2+
/**
3+
* The QgsLegendRendererItem class is abstract interface for legend items
4+
* returned from QgsMapLayerLegend implementation.
5+
*
6+
* The objects are used in QgsLayerTreeModel. Custom implementations may offer additional interactivity
7+
* and customized look.
8+
*
9+
* @note added in 2.6
10+
*/
11+
class QgsLayerTreeModelLegendNode : QObject
12+
{
13+
%TypeHeaderCode
14+
#include <qgsmaplayerlegend.h>
15+
%End
16+
17+
public:
18+
19+
/** Return pointer to the parent layer node */
20+
QgsLayerTreeLayer* parent() const;
21+
22+
/** Return item flags associated with the item. Default implementation returns Qt::ItemIsEnabled. */
23+
virtual Qt::ItemFlags flags() const;
24+
25+
/** Return data associated with the item. Must be implemented in derived class. */
26+
virtual QVariant data( int role ) const = 0;
27+
28+
/** Set some data associated with the item. Default implementation does nothing and returns false. */
29+
virtual bool setData( const QVariant& value, int role );
30+
31+
protected:
32+
/** Construct the node with pointer to its parent layer node */
33+
explicit QgsLayerTreeModelLegendNode( QgsLayerTreeLayer* nodeL );
34+
};
35+
36+
37+
/**
38+
* Implementation of legend node interface for displaying preview of vector symbols and their labels
39+
* and allowing interaction with the symbol / renderer.
40+
*
41+
* @note added in 2.6
42+
*/
43+
class QgsSymbolV2LegendNode : QgsLayerTreeModelLegendNode
44+
{
45+
%TypeHeaderCode
46+
#include <qgsmaplayerlegend.h>
47+
%End
48+
public:
49+
QgsSymbolV2LegendNode( QgsLayerTreeLayer* nodeLayer, QgsSymbolV2* symbol, const QString& label, int rendererRef = -1 );
50+
51+
virtual Qt::ItemFlags flags() const;
52+
virtual QVariant data( int role ) const;
53+
virtual bool setData( const QVariant& value, int role );
54+
};
55+
56+
57+
/**
58+
* Implementation of legend node interface for displaying arbitrary label with icon.
59+
*
60+
* @note added in 2.6
61+
*/
62+
class QgsSimpleLegendNode : QgsLayerTreeModelLegendNode
63+
{
64+
%TypeHeaderCode
65+
#include <qgsmaplayerlegend.h>
66+
%End
67+
public:
68+
QgsSimpleLegendNode( QgsLayerTreeLayer* nodeLayer, const QString& label, const QIcon& icon = QIcon() );
69+
70+
virtual QVariant data( int role ) const;
71+
};
72+
73+
74+
/**
75+
* The QgsMapLayerLegend class is abstract interface for implementations
76+
* of legends for one map layer.
77+
*
78+
* @note added in 2.6
79+
*/
80+
class QgsMapLayerLegend : QObject
81+
{
82+
%TypeHeaderCode
83+
#include <qgsmaplayerlegend.h>
84+
%End
85+
86+
public:
87+
explicit QgsMapLayerLegend( QObject *parent /TransferThis/ = 0 );
88+
89+
// TODO: type, load/save settings
90+
91+
/**
92+
* Return list of legend nodes to be used for a particular layer tree layer node.
93+
* Ownership is transferred to the caller.
94+
*/
95+
virtual QList<QgsLayerTreeModelLegendNode*> createLayerTreeModelLegendNodes( QgsLayerTreeLayer* nodeLayer ) = 0 /Factory/;
96+
97+
// TODO: support for layer tree view delegates
98+
99+
// TODO: support for legend renderer
100+
101+
102+
//! Create new legend implementation for vector layer
103+
static QgsMapLayerLegend* defaultVectorLegend( QgsVectorLayer* vl ) /Factory/;
104+
105+
//! Create new legend implementation for raster layer
106+
static QgsMapLayerLegend* defaultRasterLegend( QgsRasterLayer* rl ) /Factory/;
107+
108+
//! Create new legend implementation for raster layer
109+
static QgsMapLayerLegend* defaultPluginLegend( QgsPluginLayer* pl ) /Factory/;
110+
111+
signals:
112+
//! Emitted when existing items/nodes got invalid and should be replaced by new ones
113+
void itemsChanged();
114+
};
115+
116+
117+
/** Default legend implementation for vector layers
118+
* @note added in 2.6
119+
*/
120+
class QgsDefaultVectorLayerLegend : QgsMapLayerLegend
121+
{
122+
%TypeHeaderCode
123+
#include <qgsmaplayerlegend.h>
124+
%End
125+
public:
126+
explicit QgsDefaultVectorLayerLegend( QgsVectorLayer* vl );
127+
128+
virtual QList<QgsLayerTreeModelLegendNode*> createLayerTreeModelLegendNodes( QgsLayerTreeLayer* nodeLayer ) /Factory/;
129+
130+
};
131+
132+
133+
/** Default legend implementation for raster layers
134+
* @note added in 2.6
135+
*/
136+
class QgsDefaultRasterLayerLegend : QgsMapLayerLegend
137+
{
138+
%TypeHeaderCode
139+
#include <qgsmaplayerlegend.h>
140+
%End
141+
public:
142+
explicit QgsDefaultRasterLayerLegend( QgsRasterLayer* rl );
143+
144+
virtual QList<QgsLayerTreeModelLegendNode*> createLayerTreeModelLegendNodes( QgsLayerTreeLayer* nodeLayer ) /Factory/;
145+
146+
};
147+
148+
149+
/** Default legend implementation for plugin layers
150+
* @note added in 2.6
151+
*/
152+
class QgsDefaultPluginLayerLegend : QgsMapLayerLegend
153+
{
154+
%TypeHeaderCode
155+
#include <qgsmaplayerlegend.h>
156+
%End
157+
public:
158+
explicit QgsDefaultPluginLayerLegend( QgsPluginLayer* pl );
159+
160+
virtual QList<QgsLayerTreeModelLegendNode*> createLayerTreeModelLegendNodes( QgsLayerTreeLayer* nodeLayer ) /Factory/;
161+
162+
};
163+

src/core/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ SET(QGIS_CORE_SRCS
9696
qgslegendsettings.cpp
9797
qgslogger.cpp
9898
qgsmaplayer.cpp
99+
qgsmaplayerlegend.cpp
99100
qgsmaplayerregistry.cpp
100101
qgsmaprenderer.cpp
101102
qgsmaprenderercache.cpp
@@ -336,6 +337,7 @@ SET(QGIS_CORE_MOC_HDRS
336337
qgsgmlschema.h
337338
qgshttptransaction.h
338339
qgsmaplayer.h
340+
qgsmaplayerlegend.h
339341
qgsmaplayerregistry.h
340342
qgsmaprenderer.h
341343
qgsmaprenderercache.h
@@ -469,6 +471,7 @@ SET(QGIS_CORE_HDRS
469471
qgslegendsettings.h
470472
qgslogger.h
471473
qgsmaplayer.h
474+
qgsmaplayerlegend.h
472475
qgsmaplayerregistry.h
473476
qgsmaprenderer.h
474477
qgsmaprenderercache.h

src/core/qgsmaplayer.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "qgsmaplayer.h"
3636
#include "qgscoordinatereferencesystem.h"
3737
#include "qgsapplication.h"
38+
#include "qgsmaplayerlegend.h"
3839
#include "qgsproject.h"
3940
#include "qgspluginlayerregistry.h"
4041
#include "qgsprojectfiletransform.h"
@@ -53,6 +54,7 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
5354
mID( "" ),
5455
mLayerType( type ),
5556
mBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal blending
57+
, mLegend( 0 )
5658
{
5759
mCRS = new QgsCoordinateReferenceSystem();
5860

@@ -81,6 +83,7 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
8183
QgsMapLayer::~QgsMapLayer()
8284
{
8385
delete mCRS;
86+
delete mLegend;
8487
}
8588

8689
QgsMapLayer::LayerType QgsMapLayer::type() const
@@ -1376,6 +1379,25 @@ void QgsMapLayer::setCacheImage( QImage * )
13761379
emit repaintRequested();
13771380
}
13781381

1382+
void QgsMapLayer::setLegend( QgsMapLayerLegend* legend )
1383+
{
1384+
if ( legend == mLegend )
1385+
return;
1386+
1387+
delete mLegend;
1388+
mLegend = legend;
1389+
1390+
if ( mLegend )
1391+
connect( mLegend, SIGNAL( itemsChanged() ), this, SIGNAL( legendChanged() ) );
1392+
1393+
emit legendChanged();
1394+
}
1395+
1396+
QgsMapLayerLegend*QgsMapLayer::legend() const
1397+
{
1398+
return mLegend;
1399+
}
1400+
13791401
void QgsMapLayer::clearCacheImage()
13801402
{
13811403
emit repaintRequested();

src/core/qgsmaplayer.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
class QgsRenderContext;
3636
class QgsCoordinateReferenceSystem;
37+
class QgsMapLayerLegend;
3738
class QgsMapLayerRenderer;
3839

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

386+
/**
387+
* Assign a legend controller to the map layer. The object will be responsible for providing legend items.
388+
* @param legend Takes ownership of the object. Can be null pointer
389+
* @note added in 2.6
390+
*/
391+
void setLegend( QgsMapLayerLegend* legend );
392+
/**
393+
* @note added in 2.6
394+
*/
395+
QgsMapLayerLegend* legend() const;
396+
385397
public slots:
386398

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

461+
/**
462+
* Signal emitted when legend of the layer has changed
463+
* @note added in 2.6
464+
*/
465+
void legendChanged();
466+
449467
protected:
450468
/** Set the extent */
451469
virtual void setExtent( const QgsRectangle &rect );
@@ -559,6 +577,9 @@ class CORE_EXPORT QgsMapLayer : public QObject
559577

560578
//! Layer's persistent storage of additional properties (may be used by plugins)
561579
QgsObjectCustomProperties mCustomProperties;
580+
581+
//! Controller of legend items of this layer
582+
QgsMapLayerLegend* mLegend;
562583
};
563584

564585
#endif

0 commit comments

Comments
 (0)