Skip to content

Commit 33b6c41

Browse files
authoredApr 18, 2017
Merge pull request #4357 from nyalldawson/composer_layer_ref
Use weak layer references and loose matching for composer legend customisation
2 parents 302e9dd + 3535ee2 commit 33b6c41

33 files changed

+709
-316
lines changed
 

‎python/auto_sip.blacklist

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,6 @@ core/fieldformatter/qgsrelationreferencefieldformatter.sip
217217
core/fieldformatter/qgsvaluemapfieldformatter.sip
218218
core/fieldformatter/qgsvaluerelationfieldformatter.sip
219219
core/layertree/qgslayertree.sip
220-
core/layertree/qgslayertreegroup.sip
221-
core/layertree/qgslayertreelayer.sip
222220
core/layertree/qgslayertreemodel.sip
223221
core/layertree/qgslayertreemodellegendnode.sip
224222
core/layertree/qgslayertreenode.sip

‎python/core/annotations/qgshtmlannotation.sip

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class QgsHtmlAnnotation: QgsAnnotation
3131

3232
~QgsHtmlAnnotation();
3333

34-
QSizeF minimumFrameSize() const;
34+
virtual QSizeF minimumFrameSize() const;
3535

3636
void setSourceFile( const QString &htmlFile );
3737
%Docstring
@@ -49,7 +49,7 @@ class QgsHtmlAnnotation: QgsAnnotation
4949
virtual void writeXml( QDomElement &elem, QDomDocument &doc ) const;
5050
virtual void readXml( const QDomElement &itemElem, const QDomDocument &doc );
5151

52-
void setAssociatedFeature( const QgsFeature &feature );
52+
virtual void setAssociatedFeature( const QgsFeature &feature );
5353

5454
static QgsHtmlAnnotation *create() /Factory/;
5555
%Docstring
@@ -59,7 +59,7 @@ class QgsHtmlAnnotation: QgsAnnotation
5959

6060
protected:
6161

62-
void renderAnnotation( QgsRenderContext &context, QSizeF size ) const;
62+
virtual void renderAnnotation( QgsRenderContext &context, QSizeF size ) const;
6363

6464
};
6565

‎python/core/annotations/qgssvgannotation.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class QgsSvgAnnotation: QgsAnnotation
5050

5151
protected:
5252

53-
void renderAnnotation( QgsRenderContext &context, QSizeF size ) const;
53+
virtual void renderAnnotation( QgsRenderContext &context, QSizeF size ) const;
5454

5555
};
5656

‎python/core/annotations/qgstextannotation.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class QgsTextAnnotation: QgsAnnotation
5252

5353
protected:
5454

55-
void renderAnnotation( QgsRenderContext &context, QSizeF size ) const;
55+
virtual void renderAnnotation( QgsRenderContext &context, QSizeF size ) const;
5656

5757
};
5858

Lines changed: 207 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,232 @@
1-
/**
2-
* Layer tree group node serves as a container for layers and further groups.
3-
*
4-
* Group names do not need to be unique within one tree nor within one parent.
5-
*
6-
* @note added in 2.4
7-
*/
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/layertree/qgslayertreegroup.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
812
class QgsLayerTreeGroup : QgsLayerTreeNode
913
{
10-
%TypeHeaderCode
11-
#include <qgslayertreegroup.h>
14+
%Docstring
15+
Layer tree group node serves as a container for layers and further groups.
16+
17+
Group names do not need to be unique within one tree nor within one parent.
18+
19+
.. versionadded:: 2.4
1220
%End
1321

22+
%TypeHeaderCode
23+
#include "qgslayertreegroup.h"
24+
%End
1425
public:
15-
QgsLayerTreeGroup( const QString& name = QString(), Qt::CheckState checked = Qt::Checked );
16-
17-
//! Get group's name
18-
QString name() const;
19-
//! Set group's name
20-
void setName( const QString& n );
21-
22-
//! Insert a new group node with given name at specified position. Newly created node is owned by this group.
23-
QgsLayerTreeGroup* insertGroup( int index, const QString& name );
24-
//! Append a new group node with given name. Newly created node is owned by this group.
25-
QgsLayerTreeGroup* addGroup( const QString& name );
26-
//! Insert a new layer node for given map layer at specified position. Newly created node is owned by this group.
27-
QgsLayerTreeLayer* insertLayer( int index, QgsMapLayer* layer );
28-
//! Append a new layer node for given map layer. Newly created node is owned by this group.
29-
QgsLayerTreeLayer* addLayer( QgsMapLayer* layer );
30-
31-
//! Insert existing nodes at specified position. The nodes must not have a parent yet. The nodes will be owned by this group.
32-
void insertChildNodes( int index, const QList<QgsLayerTreeNode*>& nodes /Transfer/ );
33-
//! Insert existing node at specified position. The node must not have a parent yet. The node will be owned by this group.
34-
void insertChildNode( int index, QgsLayerTreeNode* node /Transfer/ );
35-
//! Append an existing node. The node must not have a parent yet. The node will be owned by this group.
36-
void addChildNode( QgsLayerTreeNode* node /Transfer/ );
37-
38-
//! Remove a child node from this group. The node will be deleted.
39-
void removeChildNode( QgsLayerTreeNode* node );
40-
//! Remove map layer's node from this group. The node will be deleted.
41-
void removeLayer( QgsMapLayer* layer );
42-
//! Remove child nodes from index "from". The nodes will be deleted.
26+
27+
QgsLayerTreeGroup( const QString &name = QString(), bool checked = true );
28+
%Docstring
29+
Constructor
30+
%End
31+
32+
33+
virtual QString name() const;
34+
%Docstring
35+
Returns the group's name.
36+
:rtype: str
37+
%End
38+
39+
virtual void setName( const QString &n );
40+
%Docstring
41+
Sets the group's name.
42+
%End
43+
44+
QgsLayerTreeGroup *insertGroup( int index, const QString &name );
45+
%Docstring
46+
Insert a new group node with given name at specified position. The newly created node is owned by this group.
47+
:rtype: QgsLayerTreeGroup
48+
%End
49+
50+
QgsLayerTreeGroup *addGroup( const QString &name );
51+
%Docstring
52+
Append a new group node with given name. Newly created node is owned by this group.
53+
:rtype: QgsLayerTreeGroup
54+
%End
55+
56+
QgsLayerTreeLayer *insertLayer( int index, QgsMapLayer *layer );
57+
%Docstring
58+
Insert a new layer node for given map layer at specified position. The newly created node is owned by this group.
59+
:rtype: QgsLayerTreeLayer
60+
%End
61+
62+
QgsLayerTreeLayer *addLayer( QgsMapLayer *layer );
63+
%Docstring
64+
Append a new layer node for given map layer. The newly created node is owned by this group.
65+
:rtype: QgsLayerTreeLayer
66+
%End
67+
68+
void insertChildNodes( int index, const QList<QgsLayerTreeNode *> &nodes /Transfer/ );
69+
%Docstring
70+
Insert existing nodes at specified position. The nodes must not have a parent yet. The nodes will be owned by this group.
71+
%End
72+
73+
void insertChildNode( int index, QgsLayerTreeNode *node /Transfer/ );
74+
%Docstring
75+
Insert existing node at specified position. The node must not have a parent yet. The node will be owned by this group.
76+
%End
77+
78+
void addChildNode( QgsLayerTreeNode *node /Transfer/ );
79+
%Docstring
80+
Append an existing node. The node must not have a parent yet. The node will be owned by this group.
81+
%End
82+
83+
void removeChildNode( QgsLayerTreeNode *node );
84+
%Docstring
85+
Remove a child node from this group. The node will be deleted.
86+
%End
87+
88+
void removeLayer( QgsMapLayer *layer );
89+
%Docstring
90+
Remove map layer's node from this group. The node will be deleted.
91+
%End
92+
4393
void removeChildren( int from, int count );
44-
//! Remove all child group nodes without layers. The groupnodes will be deleted.
94+
%Docstring
95+
Remove child nodes from index "from". The nodes will be deleted.
96+
%End
97+
4598
void removeChildrenGroupWithoutLayers();
46-
//! Remove all child nodes. The nodes will be deleted.
99+
%Docstring
100+
Remove all child group nodes without layers. The groupnodes will be deleted.
101+
%End
102+
47103
void removeAllChildren();
104+
%Docstring
105+
Remove all child nodes. The nodes will be deleted.
106+
%End
107+
108+
QgsLayerTreeLayer *findLayer( QgsMapLayer *layer ) const;
109+
%Docstring
110+
Find layer node representing the map layer. Searches recursively the whole sub-tree.
111+
.. versionadded:: 3.0
112+
:rtype: QgsLayerTreeLayer
113+
%End
114+
115+
QgsLayerTreeLayer *findLayer( const QString &layerId ) const;
116+
%Docstring
117+
Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tree.
118+
:rtype: QgsLayerTreeLayer
119+
%End
120+
121+
QList<QgsLayerTreeLayer *> findLayers() const;
122+
%Docstring
123+
Find all layer nodes. Searches recursively the whole sub-tree.
124+
:rtype: list of QgsLayerTreeLayer
125+
%End
48126

49-
//! Find layer node representing the map layer. Searches recursively the whole sub-tree.
50-
//! @note added in 3.0
51-
QgsLayerTreeLayer* findLayer( QgsMapLayer* layer ) const;
52-
//! Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tree.
53-
QgsLayerTreeLayer* findLayer( const QString& layerId );
54-
//! Find all layer nodes. Searches recursively the whole sub-tree.
55-
QList<QgsLayerTreeLayer*> findLayers() const;
56-
//! Find layer IDs used in all layer nodes. Searches recursively the whole sub-tree.
57127
QStringList findLayerIds() const;
58-
//! Find group node with specified name. Searches recursively the whole sub-tree.
59-
QgsLayerTreeGroup* findGroup( const QString& name );
60-
61-
//! Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on error).
62-
//! Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
63-
static QgsLayerTreeGroup* readXml( QDomElement& element ) /Factory/;
64-
//! Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on error).
65-
//! Also resolves textual references to layers from the project (calls resolveReferences() internally).
66-
//! @note added in 3.0
67-
static QgsLayerTreeGroup* readXml( QDomElement& element, const QgsProject* project ) /Factory/;
68-
69-
//! Write group (tree) as XML element <layer-tree-group> and add it to the given parent element
70-
virtual void writeXml( QDomElement& parentElement );
71-
//! Read children from XML and append them to the group.
72-
//! Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
73-
void readChildrenFromXml( QDomElement& element );
74-
75-
//! Return text representation of the tree. For debugging purposes only.
128+
%Docstring
129+
Find layer IDs used in all layer nodes. Searches recursively the whole sub-tree.
130+
:rtype: list of str
131+
%End
132+
133+
QgsLayerTreeGroup *findGroup( const QString &name );
134+
%Docstring
135+
Find group node with specified name. Searches recursively the whole sub-tree.
136+
:rtype: QgsLayerTreeGroup
137+
%End
138+
139+
static QgsLayerTreeGroup *readXml( QDomElement &element ) /Factory/;
140+
%Docstring
141+
Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on error).
142+
Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
143+
:rtype: QgsLayerTreeGroup
144+
%End
145+
146+
static QgsLayerTreeGroup *readXml( QDomElement &element, const QgsProject *project ) /Factory/;
147+
%Docstring
148+
Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on error).
149+
Also resolves textual references to layers from the project (calls resolveReferences() internally).
150+
.. versionadded:: 3.0
151+
:rtype: QgsLayerTreeGroup
152+
%End
153+
154+
virtual void writeXml( QDomElement &parentElement );
155+
%Docstring
156+
Write group (tree) as XML element <layer-tree-group> and add it to the given parent element
157+
%End
158+
159+
void readChildrenFromXml( QDomElement &element );
160+
%Docstring
161+
Read children from XML and append them to the group.
162+
Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
163+
%End
164+
76165
virtual QString dump() const;
166+
%Docstring
167+
Return text representation of the tree. For debugging purposes only.
168+
:rtype: str
169+
%End
77170

78-
//! Return a clone of the group. The children are cloned too.
79-
virtual QgsLayerTreeGroup* clone() const /Factory/;
171+
virtual QgsLayerTreeGroup *clone() const /Factory/;
172+
%Docstring
173+
Return a clone of the group. The children are cloned too.
174+
:rtype: QgsLayerTreeGroup
175+
%End
80176

81-
//! Calls resolveReferences() on child tree nodes
82-
//! @note added in 3.0
83-
virtual void resolveReferences( const QgsProject* project );
177+
virtual void resolveReferences( const QgsProject *project, bool looseMatching = false );
178+
%Docstring
179+
Calls resolveReferences() on child tree nodes
180+
.. versionadded:: 3.0
181+
%End
182+
183+
virtual void setItemVisibilityCheckedRecursive( bool checked );
184+
%Docstring
185+
Check or uncheck a node and all its children (taking into account exclusion rules)
186+
%End
84187

85-
//! Return whether the group is mutually exclusive (only one child can be checked at a time)
86-
//! @note added in 2.12
87188
bool isMutuallyExclusive() const;
88-
//! Set whether the group is mutually exclusive (only one child can be checked at a time).
89-
//! The initial child index determines which child should be initially checked. The default value
90-
//! of -1 will determine automatically (either first one currently checked or none)
91-
//! @note added in 2.12
189+
%Docstring
190+
Return whether the group is mutually exclusive (only one child can be checked at a time)
191+
.. versionadded:: 2.12
192+
:rtype: bool
193+
%End
194+
92195
void setIsMutuallyExclusive( bool enabled, int initialChildIndex = -1 );
196+
%Docstring
197+
Set whether the group is mutually exclusive (only one child can be checked at a time).
198+
The initial child index determines which child should be initially checked. The default value
199+
of -1 will determine automatically (either first one currently checked or none)
200+
.. versionadded:: 2.12
201+
%End
93202

94203
protected slots:
95-
void nodeVisibilityChanged( QgsLayerTreeNode* node );
204+
void nodeVisibilityChanged( QgsLayerTreeNode *node );
96205

97206
protected:
98207

99-
//! Set check state of children - if mutually exclusive
100208
void updateChildVisibilityMutuallyExclusive();
209+
%Docstring
210+
Set check state of children - if mutually exclusive
211+
%End
212+
213+
214+
215+
101216

102217
private:
103-
QgsLayerTreeGroup( const QgsLayerTreeGroup& other );
218+
219+
QgsLayerTreeGroup( const QgsLayerTreeGroup &other );
220+
%Docstring
221+
Copies are not allowed
222+
%End
104223
};
224+
225+
226+
/************************************************************************
227+
* This file has been generated automatically from *
228+
* *
229+
* src/core/layertree/qgslayertreegroup.h *
230+
* *
231+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
232+
************************************************************************/
Lines changed: 97 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,124 @@
1-
/**
2-
* Layer tree node points to a map layer.
3-
*
4-
* The node can exist also without a valid instance of a layer (just ID). That
5-
* means the referenced layer does not need to be loaded in order to use it
6-
* in layer tree. In such case, resolveReferences() method can be called
7-
* once the layer is loaded.
8-
*
9-
* A map layer is supposed to be present in one layer tree just once. It is
10-
* however possible that temporarily a layer exists in one tree more than just
11-
* once, e.g. while reordering items with drag and drop.
12-
*
13-
* @note added in 2.4
14-
*/
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/layertree/qgslayertreelayer.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
1512
class QgsLayerTreeLayer : QgsLayerTreeNode
1613
{
17-
%TypeHeaderCode
18-
#include <qgslayertreelayer.h>
14+
%Docstring
15+
Layer tree node points to a map layer.
16+
17+
The node can exist also without a valid instance of a layer (just ID). That
18+
means the referenced layer does not need to be loaded in order to use it
19+
in layer tree. In such case, resolveReferences() method can be called
20+
once the layer is loaded.
21+
22+
A map layer is supposed to be present in one layer tree just once. It is
23+
however possible that temporarily a layer exists in one tree more than just
24+
once, e.g. while reordering items with drag and drop.
25+
26+
.. versionadded:: 2.4
1927
%End
2028

29+
%TypeHeaderCode
30+
#include "qgslayertreelayer.h"
31+
%End
2132
public:
22-
explicit QgsLayerTreeLayer( QgsMapLayer* layer );
33+
explicit QgsLayerTreeLayer( QgsMapLayer *layer );
2334

24-
explicit QgsLayerTreeLayer( const QString& layerId, const QString& name = QString() );
35+
36+
explicit QgsLayerTreeLayer( const QString &layerId, const QString &name = QString(), const QString &source = QString(), const QString &provider = QString() );
37+
%Docstring
38+
Constructor for QgsLayerTreeLayer using weak references to layer ID, ``name``, public ``source``, and ``provider`` key.
39+
%End
2540

2641
QString layerId() const;
42+
%Docstring
43+
:rtype: str
44+
%End
45+
46+
QgsMapLayer *layer() const;
47+
%Docstring
48+
:rtype: QgsMapLayer
49+
%End
2750

28-
QgsMapLayer* layer() const;
51+
virtual QString name() const;
52+
%Docstring
53+
Returns the layer's name.
54+
.. versionadded:: 3.0
55+
:rtype: str
56+
%End
57+
58+
virtual void setName( const QString &n );
59+
%Docstring
60+
Sets the layer's name.
61+
.. versionadded:: 3.0
62+
%End
2963

30-
//! Get layer's name
31-
//! @note added in 3.0
32-
QString name() const;
33-
//! Set layer's name
34-
//! @note added in 3.0
35-
void setName( const QString& n );
64+
static QgsLayerTreeLayer *readXml( QDomElement &element ) /Factory/;
65+
%Docstring
66+
Read layer node from XML. Returns new instance.
67+
Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
68+
:rtype: QgsLayerTreeLayer
69+
%End
3670

37-
//! Read layer node from XML. Returns new instance.
38-
//! Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
39-
static QgsLayerTreeLayer* readXml( QDomElement& element ) /Factory/;
40-
//! Read layer node from XML. Returns new instance.
41-
//! Also resolves textual references to layers from the project (calls resolveReferences() internally).
42-
//! @note added in 3.0
43-
static QgsLayerTreeLayer* readXml( QDomElement& element, const QgsProject* project ) /Factory/;
71+
static QgsLayerTreeLayer *readXml( QDomElement &element, const QgsProject *project ) /Factory/;
72+
%Docstring
73+
Read layer node from XML. Returns new instance.
74+
Also resolves textual references to layers from the project (calls resolveReferences() internally).
75+
.. versionadded:: 3.0
76+
:rtype: QgsLayerTreeLayer
77+
%End
4478

45-
virtual void writeXml( QDomElement& parentElement );
79+
virtual void writeXml( QDomElement &parentElement );
4680

4781
virtual QString dump() const;
4882

49-
virtual QgsLayerTreeLayer* clone() const /Factory/;
83+
virtual QgsLayerTreeLayer *clone() const /Factory/;
5084

51-
//! Resolves reference to layer from stored layer ID (if it has not been resolved already)
52-
//! @note added in 3.0
53-
virtual void resolveReferences( const QgsProject* project );
85+
virtual void resolveReferences( const QgsProject *project, bool looseMatching = false );
86+
%Docstring
87+
Resolves reference to layer from stored layer ID (if it has not been resolved already)
88+
.. versionadded:: 3.0
89+
%End
5490

5591
signals:
56-
//! emitted when a previously unavailable layer got loaded
92+
5793
void layerLoaded();
58-
//! emitted when a previously available layer got unloaded (from layer registry)
59-
//! @note added in 2.6
94+
%Docstring
95+
Emitted when a previously unavailable layer got loaded.
96+
%End
97+
6098
void layerWillBeUnloaded();
99+
%Docstring
100+
Emitted when a previously available layer got unloaded (from layer registry).
101+
.. versionadded:: 2.6
102+
%End
61103

62104
protected:
63105
void attachToLayer();
64106

107+
65108
private:
66-
QgsLayerTreeLayer( const QgsLayerTreeLayer& other );
67109

110+
QgsLayerTreeLayer( const QgsLayerTreeLayer &other );
111+
%Docstring
112+
Copies are not allowed
113+
%End
68114
};
115+
116+
117+
118+
/************************************************************************
119+
* This file has been generated automatically from *
120+
* *
121+
* src/core/layertree/qgslayertreelayer.h *
122+
* *
123+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
124+
************************************************************************/

‎python/core/layertree/qgslayertreenode.sip

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,16 @@ class QgsLayerTreeNode : QObject
102102
//! Create a copy of the node. Returns new instance
103103
virtual QgsLayerTreeNode *clone() const = 0 /Factory/;
104104

105-
//! Turn textual references to layers into map layer object from project.
106-
//! This method should be called after readXml()
107-
//! @note added in 3.0
108-
virtual void resolveReferences( const QgsProject* project ) = 0;
105+
/**
106+
* Turn textual references to layers into map layer object from project.
107+
* This method should be called after readXml()
108+
* If \a looseMatching is true then a looser match will be used, where a layer
109+
* will match if the name, public source, and data provider match. This can be
110+
* used to match legend customisation from different projects where layers
111+
* will have different layer IDs.
112+
* \since QGIS 3.0
113+
*/
114+
virtual void resolveReferences( const QgsProject *project, bool looseMatching = false ) = 0;
109115

110116
//! Returns whether a node is really visible (ie checked and all its ancestors checked as well)
111117
//! @note added in 3.0

‎python/core/qgscolorramp.sip

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ class QgsLimitedRandomColorRamp : QgsColorRamp
302302
virtual QString type() const;
303303
virtual QgsLimitedRandomColorRamp *clone() const /Factory/;
304304
virtual QgsStringMap properties() const;
305-
int count() const;
305+
virtual int count() const;
306306

307307
static QList<QColor> randomColors( int count,
308308
int hueMax = DEFAULT_RANDOM_HUE_MAX, int hueMin = DEFAULT_RANDOM_HUE_MIN,
@@ -420,11 +420,11 @@ class QgsRandomColorRamp: QgsColorRamp
420420
public:
421421
QgsRandomColorRamp();
422422

423-
int count() const;
423+
virtual int count() const;
424424

425-
double value( int index ) const;
425+
virtual double value( int index ) const;
426426

427-
QColor color( double value ) const;
427+
virtual QColor color( double value ) const;
428428

429429
virtual void setTotalColorCount( const int colorCount );
430430
%Docstring
@@ -435,7 +435,7 @@ class QgsRandomColorRamp: QgsColorRamp
435435
.. versionadded:: 2.5
436436
%End
437437

438-
QString type() const;
438+
virtual QString type() const;
439439

440440
virtual QgsRandomColorRamp *clone() const /Factory/;
441441

@@ -483,7 +483,7 @@ class QgsPresetSchemeColorRamp : QgsColorRamp, QgsColorScheme
483483
:rtype: QgsColorRamp
484484
%End
485485

486-
bool setColors( const QgsNamedColorList &colors, const QString & = QString(), const QColor & = QColor() );
486+
virtual bool setColors( const QgsNamedColorList &colors, const QString & = QString(), const QColor & = QColor() );
487487
%Docstring
488488
Sets the list of colors used by the ramp.
489489
\param colors list of colors
@@ -499,25 +499,16 @@ class QgsPresetSchemeColorRamp : QgsColorRamp, QgsColorScheme
499499
%End
500500

501501
virtual double value( int index ) const;
502-
%Docstring
503-
QgsColorRamp interface
504-
:rtype: float
505-
%End
506502
virtual QColor color( double value ) const;
507503
virtual QString type() const;
508504
virtual void invert();
509505
virtual QgsPresetSchemeColorRamp *clone() const /Factory/;
510506
virtual QgsStringMap properties() const;
511-
int count() const;
507+
virtual int count() const;
512508

513-
QString schemeName() const;
514-
%Docstring
515-
QgsColorScheme interface
516-
:rtype: str
517-
%End
518-
QgsNamedColorList fetchColors( const QString &context = QString(),
519-
const QColor &baseColor = QColor() );
520-
bool isEditable() const;
509+
virtual QString schemeName() const;
510+
virtual QgsNamedColorList fetchColors( const QString &context = QString(), const QColor &baseColor = QColor() );
511+
virtual bool isEditable() const;
521512

522513
};
523514

‎python/core/qgsmaplayer.sip

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ Returns the layer's unique ID, which is used to access this layer from QgsProjec
9595
:rtype: str
9696
%End
9797

98+
virtual QgsDataProvider *dataProvider();
99+
%Docstring
100+
Returns the layer's data provider.
101+
:rtype: QgsDataProvider
102+
%End
103+
104+
98105
QString originalName() const;
99106
%Docstring
100107
Returns the original name of the layer.

‎python/core/qgsvectorlayer.sip

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -383,12 +383,7 @@ Returns a comment for the data in the layer
383383
:rtype: str
384384
%End
385385

386-
QgsVectorDataProvider *dataProvider();
387-
%Docstring
388-
Returns the data provider
389-
:rtype: QgsVectorDataProvider
390-
%End
391-
386+
virtual QgsVectorDataProvider *dataProvider();
392387

393388
void setProviderEncoding( const QString &encoding );
394389
%Docstring
@@ -772,7 +767,7 @@ Return the provider type for this layer
772767
:rtype: str
773768
%End
774769

775-
bool readSymbology( const QDomNode &layerNode, QString &errorMessage );
770+
virtual bool readSymbology( const QDomNode &layerNode, QString &errorMessage );
776771
%Docstring
777772
Read the symbology for the current layer from the Dom node supplied.
778773
\param layerNode node that will contain the symbology definition for this layer.
@@ -781,7 +776,7 @@ Return the provider type for this layer
781776
:rtype: bool
782777
%End
783778

784-
bool readStyle( const QDomNode &node, QString &errorMessage );
779+
virtual bool readStyle( const QDomNode &node, QString &errorMessage );
785780
%Docstring
786781
Read the style for the current layer from the Dom node supplied.
787782
\param node node that will contain the style definition for this layer.
@@ -790,7 +785,7 @@ Return the provider type for this layer
790785
:rtype: bool
791786
%End
792787

793-
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage ) const;
788+
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage ) const;
794789
%Docstring
795790
Write the symbology for the layer into the docment provided.
796791
\param node the node that will have the style element added to it.
@@ -800,7 +795,7 @@ Return the provider type for this layer
800795
:rtype: bool
801796
%End
802797

803-
bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage ) const;
798+
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage ) const;
804799
%Docstring
805800
Write just the style information for the layer into the document
806801
\param node the node that will have the style element added to it.
@@ -821,7 +816,7 @@ Return the provider type for this layer
821816
:rtype: bool
822817
%End
823818

824-
bool readSld( const QDomNode &node, QString &errorMessage );
819+
virtual bool readSld( const QDomNode &node, QString &errorMessage );
825820

826821
long featureCount( const QString &legendKey ) const;
827822
%Docstring
@@ -1099,7 +1094,7 @@ Synchronises with changes in the datasource
10991094
:rtype: QgsMapLayerRenderer
11001095
%End
11011096

1102-
QgsRectangle extent() const;
1097+
virtual QgsRectangle extent() const;
11031098
%Docstring
11041099
Return the extent of the layer
11051100
:rtype: QgsRectangle
@@ -1627,7 +1622,7 @@ Returns the current transparency for the vector layer
16271622
:rtype: int
16281623
%End
16291624

1630-
QString htmlMetadata() const;
1625+
virtual QString htmlMetadata() const;
16311626

16321627

16331628
void setSimplifyMethod( const QgsVectorSimplifyMethod &simplifyMethod );
@@ -1695,7 +1690,7 @@ Returns the current transparency for the vector layer
16951690
.. versionadded:: 3.0
16961691
%End
16971692

1698-
QgsExpressionContext createExpressionContext() const;
1693+
virtual QgsExpressionContext createExpressionContext() const;
16991694

17001695
QgsEditFormConfig editFormConfig() const;
17011696
%Docstring
@@ -2041,7 +2036,7 @@ Signal emitted when setLayerTransparency() is called
20412036

20422037

20432038
protected:
2044-
void setExtent( const QgsRectangle &rect );
2039+
virtual void setExtent( const QgsRectangle &rect );
20452040
%Docstring
20462041
Set the extent
20472042
%End

‎python/core/raster/qgsrasterlayer.sip

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,12 @@ class QgsRasterLayer : QgsMapLayer
103103
QString bandName( int bandNoInt ) const;
104104

105105
/** Returns the data provider */
106-
QgsRasterDataProvider* dataProvider();
106+
virtual QgsRasterDataProvider* dataProvider();
107107

108108
/** Returns the data provider in a const-correct manner
109109
@note available in python bindings as constDataProvider()
110110
*/
111-
const QgsRasterDataProvider* dataProvider() const /PyName=constDataProvider/;
111+
virtual const QgsRasterDataProvider* dataProvider() const /PyName=constDataProvider/;
112112

113113
/** Synchronises with changes in the datasource */
114114
virtual void reload();

‎python/gui/qgscolorbutton.sip

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -346,48 +346,48 @@ class QgsColorButton : QToolButton
346346

347347
protected:
348348

349-
bool event( QEvent *e );
350-
void changeEvent( QEvent *e );
351-
void showEvent( QShowEvent *e );
352-
void resizeEvent( QResizeEvent *event );
349+
virtual bool event( QEvent *e );
350+
virtual void changeEvent( QEvent *e );
351+
virtual void showEvent( QShowEvent *e );
352+
virtual void resizeEvent( QResizeEvent *event );
353353

354354
static const QPixmap &transparentBackground();
355355
%Docstring
356356
Returns a checkboard pattern pixmap for use as a background to transparent colors
357357
:rtype: QPixmap
358358
%End
359359

360-
void mousePressEvent( QMouseEvent *e );
360+
virtual void mousePressEvent( QMouseEvent *e );
361361
%Docstring
362362
Reimplemented to detect right mouse button clicks on the color button and allow dragging colors
363363
%End
364364

365-
void mouseMoveEvent( QMouseEvent *e );
365+
virtual void mouseMoveEvent( QMouseEvent *e );
366366
%Docstring
367367
Reimplemented to allow dragging colors from button
368368
%End
369369

370-
void mouseReleaseEvent( QMouseEvent *e );
370+
virtual void mouseReleaseEvent( QMouseEvent *e );
371371
%Docstring
372372
Reimplemented to allow color picking
373373
%End
374374

375-
void keyPressEvent( QKeyEvent *e );
375+
virtual void keyPressEvent( QKeyEvent *e );
376376
%Docstring
377377
Reimplemented to allow canceling color pick via keypress, and sample via space bar press
378378
%End
379379

380-
void dragEnterEvent( QDragEnterEvent *e );
380+
virtual void dragEnterEvent( QDragEnterEvent *e );
381381
%Docstring
382382
Reimplemented to accept dragged colors
383383
%End
384384

385-
void dragLeaveEvent( QDragLeaveEvent *e );
385+
virtual void dragLeaveEvent( QDragLeaveEvent *e );
386386
%Docstring
387387
Reimplemented to reset button appearance after drag leave
388388
%End
389389

390-
void dropEvent( QDropEvent *e );
390+
virtual void dropEvent( QDropEvent *e );
391391
%Docstring
392392
Reimplemented to accept dropped colors
393393
%End

‎python/gui/qgscolorrampbutton.sip

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,12 @@ class QgsColorRampButton : QToolButton
257257

258258
protected:
259259

260-
bool event( QEvent *e );
261-
void changeEvent( QEvent *e );
262-
void showEvent( QShowEvent *e );
263-
void resizeEvent( QResizeEvent *event );
260+
virtual bool event( QEvent *e );
261+
virtual void changeEvent( QEvent *e );
262+
virtual void showEvent( QShowEvent *e );
263+
virtual void resizeEvent( QResizeEvent *event );
264264

265-
void mousePressEvent( QMouseEvent *e );
265+
virtual void mousePressEvent( QMouseEvent *e );
266266
%Docstring
267267
Reimplemented to detect right mouse button clicks on the color ramp button
268268
%End

‎python/gui/qgsmessagelogviewer.sip

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class QgsMessageLogViewer: QDialog
3535
%End
3636

3737
protected:
38-
void closeEvent( QCloseEvent *e );
39-
void reject();
38+
virtual void closeEvent( QCloseEvent *e );
39+
virtual void reject();
4040

4141
};
4242

‎python/gui/symbology-ng/characterwidget.sip

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class CharacterWidget : QWidget
2727
Constructor for CharacterWidget.
2828
%End
2929

30-
QSize sizeHint() const;
30+
virtual QSize sizeHint() const;
3131

3232
int columns() const;
3333
%Docstring
@@ -101,9 +101,9 @@ class CharacterWidget : QWidget
101101
%End
102102

103103
protected:
104-
void mouseMoveEvent( QMouseEvent *event );
105-
void mousePressEvent( QMouseEvent *event );
106-
void paintEvent( QPaintEvent *event );
104+
virtual void mouseMoveEvent( QMouseEvent *event );
105+
virtual void mousePressEvent( QMouseEvent *event );
106+
virtual void paintEvent( QPaintEvent *event );
107107

108108
};
109109

‎scripts/sipify.pl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,12 @@ sub processDoxygenLine
318318
# remove keywords
319319
if ( $line =~ m/\boverride\b/){
320320
$is_override = 1;
321+
if ( $line !~ m/^(\s*)virtual\b(.*)$/ ){
322+
#sip often requires the virtual keyword to be present, or it chokes on covariant return types
323+
#in overridden methods
324+
$line =~ m/^(\s*?)\b(.*)$/;
325+
$line = "$1virtual $2\n";
326+
}
321327
}
322328
$line =~ s/\s*\boverride\b//;
323329
$line =~ s/^(\s*)?(const )?(virtual |static )?inline /$1$2$3/;

‎src/core/composer/qgscomposerlegend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ bool QgsComposerLegend::readXml( const QDomElement &itemElem, const QDomDocument
489489
{
490490
std::unique_ptr< QgsLayerTree > tree( QgsLayerTree::readXml( layerTreeElem ) );
491491
if ( mComposition )
492-
tree->resolveReferences( mComposition->project() );
492+
tree->resolveReferences( mComposition->project(), true );
493493
setCustomLayerTree( tree.release() );
494494
}
495495
else

‎src/core/layertree/qgslayertreegroup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,10 +336,10 @@ QgsLayerTreeGroup *QgsLayerTreeGroup::clone() const
336336
return new QgsLayerTreeGroup( *this );
337337
}
338338

339-
void QgsLayerTreeGroup::resolveReferences( const QgsProject *project )
339+
void QgsLayerTreeGroup::resolveReferences( const QgsProject *project, bool looseMatching )
340340
{
341341
Q_FOREACH ( QgsLayerTreeNode *node, mChildren )
342-
node->resolveReferences( project );
342+
node->resolveReferences( project, looseMatching );
343343
}
344344

345345
static bool _nodeIsChecked( QgsLayerTreeNode *node )

‎src/core/layertree/qgslayertreegroup.h

Lines changed: 149 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define QGSLAYERTREEGROUP_H
1818

1919
#include "qgis_core.h"
20+
#include "qgis.h"
2021
#include "qgslayertreenode.h"
2122

2223
class QgsMapLayer;
@@ -33,108 +34,204 @@ class CORE_EXPORT QgsLayerTreeGroup : public QgsLayerTreeNode
3334
{
3435
Q_OBJECT
3536
public:
36-
//! Constructor
37+
38+
/**
39+
* Constructor
40+
*/
3741
QgsLayerTreeGroup( const QString &name = QString(), bool checked = true );
42+
43+
#ifndef SIP_RUN
3844
QgsLayerTreeGroup( const QgsLayerTreeGroup &other );
45+
#endif
3946

40-
//! Get group's name
47+
/**
48+
* Returns the group's name.
49+
*/
4150
QString name() const override;
42-
//! Set group's name
51+
52+
/**
53+
* Sets the group's name.
54+
*/
4355
void setName( const QString &n ) override;
4456

45-
//! Insert a new group node with given name at specified position. Newly created node is owned by this group.
57+
/**
58+
* Insert a new group node with given name at specified position. The newly created node is owned by this group.
59+
*/
4660
QgsLayerTreeGroup *insertGroup( int index, const QString &name );
47-
//! Append a new group node with given name. Newly created node is owned by this group.
61+
62+
/**
63+
* Append a new group node with given name. Newly created node is owned by this group.
64+
*/
4865
QgsLayerTreeGroup *addGroup( const QString &name );
49-
//! Insert a new layer node for given map layer at specified position. Newly created node is owned by this group.
66+
67+
/**
68+
* Insert a new layer node for given map layer at specified position. The newly created node is owned by this group.
69+
*/
5070
QgsLayerTreeLayer *insertLayer( int index, QgsMapLayer *layer );
51-
//! Append a new layer node for given map layer. Newly created node is owned by this group.
71+
72+
/**
73+
* Append a new layer node for given map layer. The newly created node is owned by this group.
74+
*/
5275
QgsLayerTreeLayer *addLayer( QgsMapLayer *layer );
5376

54-
//! Insert existing nodes at specified position. The nodes must not have a parent yet. The nodes will be owned by this group.
55-
void insertChildNodes( int index, const QList<QgsLayerTreeNode *> &nodes );
56-
//! Insert existing node at specified position. The node must not have a parent yet. The node will be owned by this group.
57-
void insertChildNode( int index, QgsLayerTreeNode *node );
58-
//! Append an existing node. The node must not have a parent yet. The node will be owned by this group.
59-
void addChildNode( QgsLayerTreeNode *node );
77+
/**
78+
* Insert existing nodes at specified position. The nodes must not have a parent yet. The nodes will be owned by this group.
79+
*/
80+
void insertChildNodes( int index, const QList<QgsLayerTreeNode *> &nodes SIP_TRANSFER );
81+
82+
/**
83+
* Insert existing node at specified position. The node must not have a parent yet. The node will be owned by this group.
84+
*/
85+
void insertChildNode( int index, QgsLayerTreeNode *node SIP_TRANSFER );
6086

61-
//! Remove a child node from this group. The node will be deleted.
87+
/**
88+
* Append an existing node. The node must not have a parent yet. The node will be owned by this group.
89+
*/
90+
void addChildNode( QgsLayerTreeNode *node SIP_TRANSFER );
91+
92+
/**
93+
* Remove a child node from this group. The node will be deleted.
94+
*/
6295
void removeChildNode( QgsLayerTreeNode *node );
63-
//! Remove map layer's node from this group. The node will be deleted.
96+
97+
/**
98+
* Remove map layer's node from this group. The node will be deleted.
99+
*/
64100
void removeLayer( QgsMapLayer *layer );
65-
//! Remove child nodes from index "from". The nodes will be deleted.
101+
102+
/**
103+
* Remove child nodes from index "from". The nodes will be deleted.
104+
*/
66105
void removeChildren( int from, int count );
67-
//! Remove all child group nodes without layers. The groupnodes will be deleted.
106+
107+
/**
108+
* Remove all child group nodes without layers. The groupnodes will be deleted.
109+
*/
68110
void removeChildrenGroupWithoutLayers();
69-
//! Remove all child nodes. The nodes will be deleted.
111+
112+
/**
113+
* Remove all child nodes. The nodes will be deleted.
114+
*/
70115
void removeAllChildren();
71116

72-
//! Find layer node representing the map layer. Searches recursively the whole sub-tree.
73-
//! \since QGIS 3.0
117+
/**
118+
* Find layer node representing the map layer. Searches recursively the whole sub-tree.
119+
* \since QGIS 3.0
120+
*/
74121
QgsLayerTreeLayer *findLayer( QgsMapLayer *layer ) const;
75-
//! Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tree.
122+
123+
/**
124+
* Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tree.
125+
*/
76126
QgsLayerTreeLayer *findLayer( const QString &layerId ) const;
77-
//! Find all layer nodes. Searches recursively the whole sub-tree.
127+
128+
/**
129+
* Find all layer nodes. Searches recursively the whole sub-tree.
130+
*/
78131
QList<QgsLayerTreeLayer *> findLayers() const;
79-
//! Find layer IDs used in all layer nodes. Searches recursively the whole sub-tree.
132+
133+
/**
134+
* Find layer IDs used in all layer nodes. Searches recursively the whole sub-tree.
135+
*/
80136
QStringList findLayerIds() const;
81-
//! Find group node with specified name. Searches recursively the whole sub-tree.
82-
QgsLayerTreeGroup *findGroup( const QString &name );
83137

84-
//! Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on error).
85-
//! Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
86-
static QgsLayerTreeGroup *readXml( QDomElement &element );
87-
//! Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on error).
88-
//! Also resolves textual references to layers from the project (calls resolveReferences() internally).
89-
//! \since QGIS 3.0
90-
static QgsLayerTreeGroup *readXml( QDomElement &element, const QgsProject *project );
138+
/**
139+
* Find group node with specified name. Searches recursively the whole sub-tree.
140+
*/
141+
QgsLayerTreeGroup *findGroup( const QString &name );
91142

92-
//! Write group (tree) as XML element <layer-tree-group> and add it to the given parent element
143+
/**
144+
* Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on error).
145+
* Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
146+
*/
147+
static QgsLayerTreeGroup *readXml( QDomElement &element ) SIP_FACTORY;
148+
149+
/**
150+
* Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on error).
151+
* Also resolves textual references to layers from the project (calls resolveReferences() internally).
152+
* \since QGIS 3.0
153+
*/
154+
static QgsLayerTreeGroup *readXml( QDomElement &element, const QgsProject *project ) SIP_FACTORY;
155+
156+
/**
157+
* Write group (tree) as XML element <layer-tree-group> and add it to the given parent element
158+
*/
93159
virtual void writeXml( QDomElement &parentElement ) override;
94-
//! Read children from XML and append them to the group.
95-
//! Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
160+
161+
/**
162+
* Read children from XML and append them to the group.
163+
* Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
164+
*/
96165
void readChildrenFromXml( QDomElement &element );
97166

98-
//! Return text representation of the tree. For debugging purposes only.
167+
/**
168+
* Return text representation of the tree. For debugging purposes only.
169+
*/
99170
virtual QString dump() const override;
100171

101-
//! Return a clone of the group. The children are cloned too.
102-
virtual QgsLayerTreeGroup *clone() const override;
172+
/**
173+
* Return a clone of the group. The children are cloned too.
174+
*/
175+
virtual QgsLayerTreeGroup *clone() const override SIP_FACTORY;
103176

104-
//! Calls resolveReferences() on child tree nodes
105-
//! \since QGIS 3.0
106-
virtual void resolveReferences( const QgsProject *project ) override;
177+
/**
178+
* Calls resolveReferences() on child tree nodes
179+
* \since QGIS 3.0
180+
*/
181+
virtual void resolveReferences( const QgsProject *project, bool looseMatching = false ) override;
107182

108-
//! Check or uncheck a node and all its children (taking into account exclusion rules)
183+
/**
184+
* Check or uncheck a node and all its children (taking into account exclusion rules)
185+
*/
109186
virtual void setItemVisibilityCheckedRecursive( bool checked ) override;
110187

111-
//! Return whether the group is mutually exclusive (only one child can be checked at a time)
112-
//! \since QGIS 2.12
188+
/**
189+
* Return whether the group is mutually exclusive (only one child can be checked at a time)
190+
* \since QGIS 2.12
191+
*/
113192
bool isMutuallyExclusive() const;
114-
//! Set whether the group is mutually exclusive (only one child can be checked at a time).
115-
//! The initial child index determines which child should be initially checked. The default value
116-
//! of -1 will determine automatically (either first one currently checked or none)
117-
//! \since QGIS 2.12
193+
194+
/**
195+
* Set whether the group is mutually exclusive (only one child can be checked at a time).
196+
* The initial child index determines which child should be initially checked. The default value
197+
* of -1 will determine automatically (either first one currently checked or none)
198+
* \since QGIS 2.12
199+
*/
118200
void setIsMutuallyExclusive( bool enabled, int initialChildIndex = -1 );
119201

120202
protected slots:
121203
void nodeVisibilityChanged( QgsLayerTreeNode *node );
122204

123205
protected:
124206

125-
//! Set check state of children - if mutually exclusive
207+
/**
208+
* Set check state of children - if mutually exclusive
209+
*/
126210
void updateChildVisibilityMutuallyExclusive();
127211

128-
protected:
129212
QString mName;
130213

131214
bool mChangingChildVisibility;
132215

133216
//! Whether the group is mutually exclusive (i.e. only one child can be checked at a time)
134217
bool mMutuallyExclusive;
135-
//! Keeps track which child has been most recently selected
136-
//! (so if the whole group is unchecked and checked again, we know which child to check)
218+
219+
/**
220+
* Keeps track which child has been most recently selected
221+
* (so if the whole group is unchecked and checked again, we know which child to check)
222+
*/
137223
int mMutuallyExclusiveChildIndex;
224+
225+
private:
226+
227+
#ifdef SIP_RUN
228+
229+
/**
230+
* Copies are not allowed
231+
*/
232+
QgsLayerTreeGroup( const QgsLayerTreeGroup &other );
233+
#endif
234+
138235
};
139236

140237

‎src/core/layertree/qgslayertreelayer.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ QgsLayerTreeLayer::QgsLayerTreeLayer( QgsMapLayer *layer )
2828
attachToLayer();
2929
}
3030

31-
QgsLayerTreeLayer::QgsLayerTreeLayer( const QString &layerId, const QString &name )
31+
QgsLayerTreeLayer::QgsLayerTreeLayer( const QString &layerId, const QString &name, const QString &source, const QString &provider )
3232
: QgsLayerTreeNode( NodeLayer, true )
33-
, mRef( layerId )
33+
, mRef( layerId, name, source, provider )
3434
, mLayerName( name.isEmpty() ? QStringLiteral( "(?)" ) : name )
3535
{
3636
}
@@ -43,12 +43,25 @@ QgsLayerTreeLayer::QgsLayerTreeLayer( const QgsLayerTreeLayer &other )
4343
attachToLayer();
4444
}
4545

46-
void QgsLayerTreeLayer::resolveReferences( const QgsProject *project )
46+
void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool looseMatching )
4747
{
4848
if ( mRef.layer )
4949
return; // already assigned
5050

5151
QgsMapLayer *layer = project->mapLayer( mRef.layerId );
52+
53+
if ( !layer && looseMatching && !mRef.name.isEmpty() )
54+
{
55+
Q_FOREACH ( QgsMapLayer *l, project->mapLayersByName( mRef.name ) )
56+
{
57+
if ( mRef.layerMatchesSource( l ) )
58+
{
59+
layer = l;
60+
break;
61+
}
62+
}
63+
}
64+
5265
if ( !layer )
5366
return;
5467

@@ -98,11 +111,15 @@ QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element )
98111

99112
QString layerID = element.attribute( QStringLiteral( "id" ) );
100113
QString layerName = element.attribute( QStringLiteral( "name" ) );
114+
115+
QString providerKey = element.attribute( "providerKey" );
116+
QString source = element.attribute( "source" );
117+
101118
Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( QStringLiteral( "checked" ) ) );
102119
bool isExpanded = ( element.attribute( QStringLiteral( "expanded" ), QStringLiteral( "1" ) ) == QLatin1String( "1" ) );
103120

104121
// needs to have the layer reference resolved later
105-
QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layerID, layerName );
122+
QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layerID, layerName, source, providerKey );
106123

107124
nodeLayer->readCommonXml( element );
108125

@@ -125,6 +142,13 @@ void QgsLayerTreeLayer::writeXml( QDomElement &parentElement )
125142
QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-layer" ) );
126143
elem.setAttribute( QStringLiteral( "id" ), layerId() );
127144
elem.setAttribute( QStringLiteral( "name" ), name() );
145+
146+
if ( mRef.layer )
147+
{
148+
elem.setAttribute( "source", mRef.layer->publicSource() );
149+
elem.setAttribute( "providerKey", mRef.layer->dataProvider() ? mRef.layer->dataProvider()->name() : QString() );
150+
}
151+
128152
elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) );
129153
elem.setAttribute( QStringLiteral( "expanded" ), mExpanded ? "1" : "0" );
130154

‎src/core/layertree/qgslayertreelayer.h

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define QGSLAYERTREELAYER_H
1818

1919
#include "qgis_core.h"
20+
#include "qgis.h"
2021
#include "qgslayertreenode.h"
2122
#include "qgsmaplayerref.h"
2223

@@ -41,52 +42,68 @@ class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode
4142
Q_OBJECT
4243
public:
4344
explicit QgsLayerTreeLayer( QgsMapLayer *layer );
45+
46+
#ifndef SIP_RUN
4447
QgsLayerTreeLayer( const QgsLayerTreeLayer &other );
48+
#endif
4549

46-
explicit QgsLayerTreeLayer( const QString &layerId, const QString &name = QString() );
50+
/**
51+
* Constructor for QgsLayerTreeLayer using weak references to layer ID, \a name, public \a source, and \a provider key.
52+
*/
53+
explicit QgsLayerTreeLayer( const QString &layerId, const QString &name = QString(), const QString &source = QString(), const QString &provider = QString() );
4754

4855
QString layerId() const { return mRef.layerId; }
4956

5057
QgsMapLayer *layer() const { return mRef.layer.data(); }
5158

52-
//! Get layer's name
53-
//! \since QGIS 3.0
59+
/**
60+
* Returns the layer's name.
61+
* \since QGIS 3.0
62+
*/
5463
QString name() const override;
55-
//! Set layer's name
56-
//! \since QGIS 3.0
64+
65+
/**
66+
* Sets the layer's name.
67+
* \since QGIS 3.0
68+
*/
5769
void setName( const QString &n ) override;
5870

59-
//! Read layer node from XML. Returns new instance.
60-
//! Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
61-
static QgsLayerTreeLayer *readXml( QDomElement &element );
62-
//! Read layer node from XML. Returns new instance.
63-
//! Also resolves textual references to layers from the project (calls resolveReferences() internally).
64-
//! \since QGIS 3.0
65-
static QgsLayerTreeLayer *readXml( QDomElement &element, const QgsProject *project );
71+
/**
72+
* Read layer node from XML. Returns new instance.
73+
* Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
74+
*/
75+
static QgsLayerTreeLayer *readXml( QDomElement &element ) SIP_FACTORY;
76+
77+
/**
78+
* Read layer node from XML. Returns new instance.
79+
* Also resolves textual references to layers from the project (calls resolveReferences() internally).
80+
* \since QGIS 3.0
81+
*/
82+
static QgsLayerTreeLayer *readXml( QDomElement &element, const QgsProject *project ) SIP_FACTORY;
6683

6784
virtual void writeXml( QDomElement &parentElement ) override;
6885

6986
virtual QString dump() const override;
7087

71-
virtual QgsLayerTreeLayer *clone() const override;
88+
virtual QgsLayerTreeLayer *clone() const override SIP_FACTORY;
7289

73-
//! Resolves reference to layer from stored layer ID (if it has not been resolved already)
74-
//! \since QGIS 3.0
75-
virtual void resolveReferences( const QgsProject *project ) override;
76-
77-
private slots:
78-
//! Emits a nameChanged() signal if layer's name has changed
79-
//! \since QGIS 3.0
80-
void layerNameChanged();
81-
//! Handles the event of deletion of the referenced layer
82-
//! \since QGIS 3.0
83-
void layerWillBeDeleted();
90+
/**
91+
* Resolves reference to layer from stored layer ID (if it has not been resolved already)
92+
* \since QGIS 3.0
93+
*/
94+
virtual void resolveReferences( const QgsProject *project, bool looseMatching = false ) override;
8495

8596
signals:
86-
//! emitted when a previously unavailable layer got loaded
97+
98+
/**
99+
* Emitted when a previously unavailable layer got loaded.
100+
*/
87101
void layerLoaded();
88-
//! emitted when a previously available layer got unloaded (from layer registry)
89-
//! \since QGIS 2.6
102+
103+
/**
104+
* Emitted when a previously available layer got unloaded (from layer registry).
105+
* \since QGIS 2.6
106+
*/
90107
void layerWillBeUnloaded();
91108

92109
protected:
@@ -96,6 +113,30 @@ class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode
96113
QgsMapLayerRef mRef;
97114
//! Layer name - only used if layer does not exist
98115
QString mLayerName;
116+
117+
private slots:
118+
119+
/**
120+
* Emits a nameChanged() signal if layer's name has changed
121+
* \since QGIS 3.0
122+
*/
123+
void layerNameChanged();
124+
125+
/**
126+
* Handles the event of deletion of the referenced layer
127+
* \since QGIS 3.0
128+
*/
129+
void layerWillBeDeleted();
130+
131+
private:
132+
133+
#ifdef SIP_RUN
134+
135+
/**
136+
* Copies are not allowed
137+
*/
138+
QgsLayerTreeLayer( const QgsLayerTreeLayer &other );
139+
#endif
99140
};
100141

101142

‎src/core/layertree/qgslayertreenode.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,16 @@ class CORE_EXPORT QgsLayerTreeNode : public QObject
113113
//! Create a copy of the node. Returns new instance
114114
virtual QgsLayerTreeNode *clone() const = 0;
115115

116-
//! Turn textual references to layers into map layer object from project.
117-
//! This method should be called after readXml()
118-
//! \since QGIS 3.0
119-
virtual void resolveReferences( const QgsProject *project ) = 0;
116+
/**
117+
* Turn textual references to layers into map layer object from project.
118+
* This method should be called after readXml()
119+
* If \a looseMatching is true then a looser match will be used, where a layer
120+
* will match if the name, public source, and data provider match. This can be
121+
* used to match legend customisation from different projects where layers
122+
* will have different layer IDs.
123+
* \since QGIS 3.0
124+
*/
125+
virtual void resolveReferences( const QgsProject *project, bool looseMatching = false ) = 0;
120126

121127
//! Returns whether a node is really visible (ie checked and all its ancestors checked as well)
122128
//! \since QGIS 3.0

‎src/core/qgscolorramp.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ class CORE_EXPORT QgsPresetSchemeColorRamp : public QgsColorRamp, public QgsColo
450450
*/
451451
QList< QColor > colors() const;
452452

453-
// QgsColorRamp interface
454453
virtual double value( int index ) const override;
455454
virtual QColor color( double value ) const override;
456455
virtual QString type() const override { return QStringLiteral( "preset" ); }
@@ -459,10 +458,8 @@ class CORE_EXPORT QgsPresetSchemeColorRamp : public QgsColorRamp, public QgsColo
459458
virtual QgsStringMap properties() const override;
460459
int count() const override;
461460

462-
// QgsColorScheme interface
463461
QString schemeName() const override { return QStringLiteral( "preset" ); }
464-
QgsNamedColorList fetchColors( const QString &context = QString(),
465-
const QColor &baseColor = QColor() ) override;
462+
QgsNamedColorList fetchColors( const QString &context = QString(), const QColor &baseColor = QColor() ) override;
466463
bool isEditable() const override { return true; }
467464

468465
private:

‎src/core/qgsmaplayer.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "qgsrendercontext.h"
3636
#include "qgsmaplayerdependency.h"
3737

38+
class QgsDataProvider;
3839
class QgsMapLayerLegend;
3940
class QgsMapLayerRenderer;
4041
class QgsMapLayerStyleManager;
@@ -128,6 +129,17 @@ class CORE_EXPORT QgsMapLayer : public QObject
128129
*/
129130
QString name() const;
130131

132+
/**
133+
* Returns the layer's data provider.
134+
*/
135+
virtual QgsDataProvider *dataProvider() { return nullptr; }
136+
137+
/**
138+
* Returns the layer's data provider in a const-correct manner
139+
* \note not available in Python bindings
140+
*/
141+
virtual const QgsDataProvider *dataProvider() const SIP_SKIP { return nullptr; }
142+
131143
/** Returns the original name of the layer.
132144
* \returns the original layer name
133145
*/

‎src/core/qgsmaplayerproxymodel.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,7 @@ bool QgsMapLayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex
9898
if ( mExceptList.contains( layer ) )
9999
return false;
100100

101-
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
102-
if ( vl && mExcludedProviders.contains( vl->dataProvider()->name() ) )
103-
return false;
104-
QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
105-
if ( rl && mExcludedProviders.contains( rl->dataProvider()->name() ) )
101+
if ( mExcludedProviders.contains( layer->dataProvider()->name() ) )
106102
return false;
107103

108104
if ( mFilters.testFlag( WritableLayer ) && layer->readOnly() )
@@ -122,7 +118,7 @@ bool QgsMapLayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex
122118
mFilters.testFlag( HasGeometry );
123119
if ( detectGeometry && layer->type() == QgsMapLayer::VectorLayer )
124120
{
125-
if ( vl )
121+
if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer *>( layer ) )
126122
{
127123
if ( mFilters.testFlag( HasGeometry ) && vl->hasGeometryType() )
128124
return true;

‎src/core/qgsmaplayerref.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include <QPointer>
2020

2121
#include "qgsmaplayer.h"
22+
#include "qgsvectorlayer.h"
23+
#include "qgsvectordataprovider.h"
24+
#include "raster/qgsrasterlayer.h"
25+
#include "raster/qgsrasterdataprovider.h"
2226

2327
/** Internal structure to keep weak pointer to QgsMapLayer or layerId
2428
* if the layer is not available yet.
@@ -28,10 +32,44 @@ template<typename TYPE>
2832
struct _LayerRef
2933
{
3034
_LayerRef( TYPE *l = nullptr ): layer( l ), layerId( l ? l->id() : QString() ) {}
31-
_LayerRef( const QString &id ): layer(), layerId( id ) {}
35+
36+
/**
37+
* Constructor for a weak layer reference, using a combination of layer ID,
38+
* \a name, public \a source and \a provider key.
39+
*/
40+
_LayerRef( const QString &id, const QString &name = QString(), const QString &source = QString(), const QString &provider = QString() )
41+
: layer()
42+
, layerId( id )
43+
, source( source )
44+
, name( name )
45+
, provider( provider )
46+
{}
3247

3348
QPointer<TYPE> layer;
3449
QString layerId;
50+
51+
//! Weak reference to layer public source
52+
QString source;
53+
//! Weak reference to layer name
54+
QString name;
55+
//! Weak reference to layer provider
56+
QString provider;
57+
58+
/**
59+
* Returns true if a layer matches the weak references to layer public source,
60+
* layer name and data provider contained in this layer reference.
61+
*/
62+
bool layerMatchesSource( QgsMapLayer *layer ) const
63+
{
64+
if ( layer->publicSource() != source ||
65+
layer->name() != name )
66+
return false;
67+
68+
if ( layer->dataProvider()->name() != provider )
69+
return false;
70+
71+
return true;
72+
}
3573
};
3674

3775
typedef _LayerRef<QgsMapLayer> QgsMapLayerRef;

‎src/core/qgsmimedatautils.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,23 +108,21 @@ static void _addLayerTreeNodeToUriList( QgsLayerTreeNode *node, QgsMimeDataUtils
108108
else if ( QgsLayerTree::isLayer( node ) )
109109
{
110110
QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
111-
if ( !nodeLayer->layer() )
111+
QgsMapLayer *layer = nodeLayer->layer();
112+
if ( !layer )
112113
return;
113114

114115
QgsMimeDataUtils::Uri uri;
115-
if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( nodeLayer->layer() ) )
116+
uri.name = layer->name();
117+
uri.uri = layer->dataProvider()->dataSourceUri();
118+
uri.providerKey = layer->dataProvider()->name();
119+
if ( layer->type() == QgsMapLayer::VectorLayer )
116120
{
117121
uri.layerType = QStringLiteral( "vector" );
118-
uri.name = vlayer->name();
119-
uri.providerKey = vlayer->dataProvider()->name();
120-
uri.uri = vlayer->dataProvider()->dataSourceUri();
121122
}
122-
else if ( QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( nodeLayer->layer() ) )
123+
else if ( layer->type() == QgsMapLayer::RasterLayer )
123124
{
124125
uri.layerType = QStringLiteral( "raster" );
125-
uri.name = rlayer->name();
126-
uri.providerKey = rlayer->dataProvider()->name();
127-
uri.uri = rlayer->dataProvider()->dataSourceUri();
128126
}
129127
else
130128
{

‎src/core/qgsvectordataprovider.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,22 +525,22 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
525525
* Get metadata, dependent on the provider type, that will be display in the metadata tab of the layer properties.
526526
* \returns The provider metadata
527527
*/
528-
virtual QVariantMap metadata() const { return QVariantMap(); };
528+
virtual QVariantMap metadata() const { return QVariantMap(); }
529529

530530
/**
531531
* Get the translated metadata key.
532532
* \param mdKey The metadata key
533533
* \returns The translated metadata value
534534
*/
535-
virtual QString translateMetadataKey( const QString &mdKey ) const { return mdKey; };
535+
virtual QString translateMetadataKey( const QString &mdKey ) const { return mdKey; }
536536

537537
/**
538538
* Get the translated metadata value.
539539
* \param mdKey The metadata key
540540
* \param value The metadata value
541541
* \returns The translated metadata value
542542
*/
543-
virtual QString translateMetadataValue( const QString &mdKey, const QVariant &value ) const { Q_UNUSED( mdKey ); return value.toString(); };
543+
virtual QString translateMetadataValue( const QString &mdKey, const QVariant &value ) const { Q_UNUSED( mdKey ); return value.toString(); }
544544

545545
signals:
546546

‎src/core/qgsvectorlayer.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "qgsfeaturerequest.h"
3434
#include "qgsfields.h"
3535
#include "qgssnapper.h"
36+
#include "qgsvectordataprovider.h"
3637
#include "qgsvectorsimplifymethod.h"
3738
#include "qgseditformconfig.h"
3839
#include "qgsattributetableconfig.h"
@@ -63,7 +64,6 @@ class QgsRelation;
6364
class QgsRelationManager;
6465
class QgsSingleSymbolRenderer;
6566
class QgsSymbol;
66-
class QgsVectorDataProvider;
6767
class QgsVectorLayerJoinInfo;
6868
class QgsVectorLayerEditBuffer;
6969
class QgsVectorLayerJoinBuffer;
@@ -437,13 +437,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
437437
*/
438438
QString displayExpression() const;
439439

440-
//! Returns the data provider
441-
QgsVectorDataProvider *dataProvider();
442-
443-
/** Returns the data provider in a const-correct manner
444-
* \note not available in Python bindings
445-
*/
446-
const QgsVectorDataProvider *dataProvider() const SIP_SKIP;
440+
QgsVectorDataProvider *dataProvider() override;
441+
const QgsVectorDataProvider *dataProvider() const override SIP_SKIP;
447442

448443
//! Sets the textencoding of the data provider
449444
void setProviderEncoding( const QString &encoding );

‎src/core/raster/qgsrasterlayer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "qgis.h"
3333
#include "qgsmaplayer.h"
3434
#include "qgsraster.h"
35+
#include "qgsrasterdataprovider.h"
3536
#include "qgsrasterpipe.h"
3637
#include "qgsrasterviewport.h"
3738
#include "qgsrasterminmaxorigin.h"
@@ -247,13 +248,12 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
247248
//! \brief Get the name of a band given its number
248249
QString bandName( int bandNoInt ) const;
249250

250-
//! Returns the data provider
251-
QgsRasterDataProvider *dataProvider();
251+
QgsRasterDataProvider *dataProvider() override;
252252

253253
/** Returns the data provider in a const-correct manner
254254
\note available in Python bindings as constDataProvider()
255255
*/
256-
const QgsRasterDataProvider *dataProvider() const;
256+
const QgsRasterDataProvider *dataProvider() const override;
257257

258258
//! Synchronises with changes in the datasource
259259
virtual void reload() override;

‎tests/scripts/sipifyheader.expected.sip

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Factory annotation
129129
:rtype: SomeObject
130130
%End
131131

132-
SomeObject *createAnother2() /Factory/;
132+
virtual SomeObject *createAnother2() /Factory/;
133133

134134
void LongDocStringMethod();
135135
%Docstring
@@ -202,6 +202,8 @@ Removing function body with virtual const reference
202202

203203

204204
virtual int overriddenProperty();
205+
virtual int overrideWithoutVirtual();
206+
205207
QString returnTypeString() const;
206208
%Docstring
207209
:rtype: str

‎tests/scripts/sipifyheader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ class CORE_EXPORT QgsSipifyHeader : public QtClass<QVariant>, private Ui::QgsBas
216216

217217
virtual int overriddenProperty() override { return 42; } // if in doubt, comment it out
218218

219+
int overrideWithoutVirtual() override;
220+
219221
QString returnTypeString() const;
220222

221223
double returnTypeDouble() const;

‎tests/src/core/testqgscomposition.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,6 @@ void TestQgsComposition::legendRestoredFromTemplate()
720720
QCOMPARE( layerNode2->layer(), layer );
721721
QCOMPARE( model2->data( model->node2index( layerNode2 ), Qt::DisplayRole ).toString(), QString( "new title!" ) );
722722

723-
#if 0 //expected failure (#2738)
724723
QString oldId = layer->id();
725724
// new test
726725
// remove existing layer
@@ -749,7 +748,6 @@ void TestQgsComposition::legendRestoredFromTemplate()
749748
QVERIFY( layerNode3 );
750749
QCOMPARE( layerNode3->layer(), layer2 );
751750
QCOMPARE( model3->data( model->node2index( layerNode3 ), Qt::DisplayRole ).toString(), QString( "new title!" ) );
752-
#endif
753751
}
754752

755753
void TestQgsComposition::legendRestoredFromTemplateAutoUpdate()

0 commit comments

Comments
 (0)
Please sign in to comment.