Skip to content

Commit 73358c3

Browse files
committed
[layertree] Add python bindings - part one (core)
1 parent a50719b commit 73358c3

11 files changed

+342
-11
lines changed

python/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ INCLUDE_DIRECTORIES(
7979
../src/core/diagram
8080
../src/core/dxf
8181
../src/core/gps
82+
../src/core/layertree
8283
../src/core/raster
8384
../src/core/symbology-ng
8485

python/core/core.sip

+7
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@
153153
%Include gps/qgsnmeaconnection.sip
154154
%Include gps/qgsqtlocationconnection.sip
155155

156+
%Include layertree/qgslayertree.sip
157+
%Include layertree/qgslayertreegroup.sip
158+
%Include layertree/qgslayertreelayer.sip
159+
%Include layertree/qgslayertreenode.sip
160+
%Include layertree/qgslayertreeregistrybridge.sip
161+
%Include layertree/qgslayertreeutils.sip
162+
156163
%Include raster/qgsraster.sip
157164
%Include raster/qgscliptominmaxenhancement.sip
158165
%Include raster/qgscolorrampshader.sip
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
%ModuleHeaderCode
2+
#include <qgslayertree.h>
3+
%End
4+
5+
/**
6+
* Namespace with helper functions for layer tree operations.
7+
*
8+
* Only generally useful routines should be here. Miscellaneous utility functions for work
9+
* with the layer tree are in QgsLayerTreeUtils class.
10+
*
11+
* @note added in 2.4
12+
*/
13+
namespace QgsLayerTree
14+
{
15+
//! Check whether the node is a valid group node
16+
bool isGroup( QgsLayerTreeNode* node );
17+
18+
//! Check whether the node is a valid layer node
19+
bool isLayer( QgsLayerTreeNode* node );
20+
21+
//! Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is legal.
22+
// PYTHON: automatic cast
23+
//inline QgsLayerTreeGroup* toGroup( QgsLayerTreeNode* node );
24+
25+
//! Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
26+
// PYTHON: automatic cast
27+
//inline QgsLayerTreeLayer* toLayer( QgsLayerTreeNode* node );
28+
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Layer tree group node serves as a container for layers and further groups.
3+
*
4+
* @note added in 2.4
5+
*/
6+
class QgsLayerTreeGroup : QgsLayerTreeNode
7+
{
8+
%TypeHeaderCode
9+
#include <qgslayertreegroup.h>
10+
%End
11+
12+
public:
13+
QgsLayerTreeGroup( const QString& name = QString(), Qt::CheckState checked = Qt::Checked );
14+
15+
QString name() const;
16+
void setName( const QString& n );
17+
18+
QgsLayerTreeGroup* addGroup( const QString& name ) /Factory/;
19+
QgsLayerTreeLayer* insertLayer( int index, QgsMapLayer* layer ) /Factory/;
20+
QgsLayerTreeLayer* addLayer( QgsMapLayer* layer ) /Factory/;
21+
22+
void insertChildNodes( int index, QList<QgsLayerTreeNode*> nodes /Transfer/ );
23+
void insertChildNode( int index, QgsLayerTreeNode* node /Transfer/ );
24+
void addChildNode( QgsLayerTreeNode* node /Transfer/ );
25+
26+
void removeChildNode( QgsLayerTreeNode* node );
27+
28+
void removeLayer( QgsMapLayer* layer );
29+
30+
void removeChildren( int from, int count );
31+
32+
void removeAllChildren();
33+
34+
QgsLayerTreeLayer* findLayer( const QString& layerId );
35+
QList<QgsLayerTreeLayer*> findLayers() const;
36+
QStringList findLayerIds() const;
37+
QgsLayerTreeGroup* findGroup( const QString& name );
38+
39+
static QgsLayerTreeGroup* readXML( QDomElement& element ) /Factory/;
40+
virtual void writeXML( QDomElement& parentElement );
41+
42+
void readChildrenFromXML( QDomElement& element );
43+
44+
virtual QString dump() const;
45+
46+
virtual QgsLayerTreeNode* clone() const /Factory/;
47+
48+
Qt::CheckState isVisible() const;
49+
void setVisible( Qt::CheckState state );
50+
51+
private:
52+
QgsLayerTreeGroup( const QgsLayerTreeGroup& other );
53+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Layer tree node points to a map layer.
3+
*
4+
* When using with existing QgsMapLayer instance, it is expected that the layer
5+
* has been registered in QgsMapLayerRegistry earlier.
6+
*
7+
* The node can exist also without a valid instance of a layer (just ID). That
8+
* means the referenced layer does not need to be loaded in order to use it
9+
* in layer tree. In such case, the node will start listening to map layer
10+
* registry updates in expectation that the layer (identified by its ID) will
11+
* be loaded later.
12+
*
13+
* A map layer is supposed to be present in one layer tree just once. It is
14+
* however possible that temporarily a layer exists in one tree more than just
15+
* once, e.g. while reordering items with drag and drop.
16+
*
17+
* @note added in 2.4
18+
*/
19+
class QgsLayerTreeLayer : QgsLayerTreeNode
20+
{
21+
%TypeHeaderCode
22+
#include <qgslayertreelayer.h>
23+
%End
24+
25+
public:
26+
explicit QgsLayerTreeLayer( QgsMapLayer* layer );
27+
28+
explicit QgsLayerTreeLayer( QString layerId, QString name = QString() );
29+
30+
QString layerId() const;
31+
32+
QgsMapLayer* layer() const;
33+
34+
QString layerName() const;
35+
void setLayerName( const QString& n );
36+
37+
Qt::CheckState isVisible() const;
38+
void setVisible( Qt::CheckState visible );
39+
40+
static QgsLayerTreeLayer* readXML( QDomElement& element ) /Factory/;
41+
virtual void writeXML( QDomElement& parentElement );
42+
43+
virtual QString dump() const;
44+
45+
virtual QgsLayerTreeNode* clone() const /Factory/;
46+
47+
signals:
48+
//! emitted when a previously unavailable layer got loaded
49+
void layerLoaded();
50+
51+
private:
52+
QgsLayerTreeLayer( const QgsLayerTreeLayer& other );
53+
54+
};
+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
* This class is a base class for nodes in a layer tree.
3+
* Layer tree is a hierarchical structure consisting of group and layer nodes:
4+
* - group nodes are containers and may contain children (layer and group nodes)
5+
* - layer nodes point to map layers, they do not contain further children
6+
*
7+
* Layer trees may be used for organization of layers, typically a layer tree
8+
* is exposed to the user using QgsLayerTreeView widget which shows the tree
9+
* and allows manipulation with the tree.
10+
*
11+
* Ownership of nodes: every node is owned by its parent. Therefore once node
12+
* is added to a layer tree, it is the responsibility of the parent to delete it
13+
* when the node is not needed anymore. Deletion of root node of a tree will
14+
* delete all nodes of the tree.
15+
*
16+
* Signals: signals are propagated from children to parent. That means it is
17+
* sufficient to connect to root node in order to get signals about updates
18+
* in the whole layer tree. When adding or removing a node that contains further
19+
* children (i.e. a whole subtree), the addition/removal signals are emitted
20+
* only for the root node of the subtree that is being added or removed.
21+
*
22+
* Custom properties: Every node may have some custom properties assigned to it.
23+
* This mechanism allows third parties store additional data with the nodes.
24+
* The properties are used within QGIS code (whether to show layer in overview,
25+
* whether the node is embedded from another project etc), but may be also
26+
* used by third party plugins. Custom properties are stored also in the project
27+
* file. The storage is not efficient for large amount of data.
28+
*
29+
* Custom properties that have already been used within QGIS:
30+
* - "overview" - whether to show a layer in overview
31+
* - "showFeatureCount" - whether to show feature counts in layer tree (vector only)
32+
* - "embedded" - whether the node comes from an external project
33+
* - "embedded_project" - path to the external project (embedded root node only)
34+
*
35+
* @see also QgsLayerTree, QgsLayerTreeLayer, QgsLayerTreeGroup
36+
* @note added in 2.4
37+
*/
38+
class QgsLayerTreeNode : QObject
39+
{
40+
%TypeHeaderCode
41+
#include <qgslayertree.h>
42+
%End
43+
44+
%ConvertToSubClassCode
45+
if (sipCpp->inherits("QgsLayerTreeNode"))
46+
{
47+
sipType = sipType_QgsLayerTreeNode;
48+
QgsLayerTreeNode* node = qobject_cast<QgsLayerTreeNode*>(sipCpp);
49+
if (QgsLayerTree::isLayer(node))
50+
sipType = sipType_QgsLayerTreeLayer;
51+
else if (QgsLayerTree::isGroup(node))
52+
sipType = sipType_QgsLayerTreeGroup;
53+
}
54+
else
55+
sipType = 0;
56+
%End
57+
58+
public:
59+
60+
//! Enumeration of possible tree node types
61+
enum NodeType
62+
{
63+
NodeGroup, //!< container of other groups and layers
64+
NodeLayer //!< leaf node pointing to a layer
65+
};
66+
67+
~QgsLayerTreeNode();
68+
69+
//! Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree namespace for that
70+
NodeType nodeType();
71+
//! Get pointer to the parent. If parent is a null pointer, the node is a root node
72+
QgsLayerTreeNode* parent();
73+
//! Get list of children of the node. Children are owned by the parent
74+
QList<QgsLayerTreeNode*> children();
75+
76+
//! Read layer tree from XML. Returns new instance
77+
static QgsLayerTreeNode* readXML( QDomElement& element );
78+
//! Write layer tree to XML
79+
virtual void writeXML( QDomElement& parentElement ) = 0;
80+
81+
//! Return string with layer tree structure. For debug purposes only
82+
virtual QString dump() const = 0;
83+
84+
//! Create a copy of the node. Returns new instance
85+
virtual QgsLayerTreeNode* clone() const = 0 /Factory/;
86+
87+
//! Return whether the node should be shown as expanded or collapsed in GUI
88+
bool isExpanded() const;
89+
//! Set whether the node should be shown as expanded or collapsed in GUI
90+
void setExpanded( bool expanded );
91+
92+
/** Set a custom property for the node. Properties are stored in a map and saved in project file. */
93+
void setCustomProperty( const QString& key, const QVariant& value );
94+
/** Read a custom property from layer. Properties are stored in a map and saved in project file. */
95+
QVariant customProperty( const QString& key, const QVariant& defaultValue = QVariant() ) const;
96+
/** Remove a custom property from layer. Properties are stored in a map and saved in project file. */
97+
void removeCustomProperty( const QString& key );
98+
/** Return list of keys stored in custom properties */
99+
QStringList customProperties() const;
100+
101+
signals:
102+
103+
//! Emitted when one or more nodes will be added to a node within the tree
104+
void willAddChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo );
105+
//! Emitted when one or more nodes have been added to a node within the tree
106+
void addedChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo );
107+
//! Emitted when one or more nodes will be removed from a node within the tree
108+
void willRemoveChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo );
109+
//! Emitted when one or more nodes has been removed from a node within the tree
110+
void removedChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo );
111+
//! Emitted when check state of a node within the tree has been changed
112+
void visibilityChanged( QgsLayerTreeNode* node, Qt::CheckState state );
113+
//! Emitted when a custom property of a node within the tree has been changed or removed
114+
void customPropertyChanged( QgsLayerTreeNode* node, QString key );
115+
116+
protected:
117+
118+
QgsLayerTreeNode( NodeType t );
119+
120+
private:
121+
QgsLayerTreeNode( const QgsLayerTreeNode& other );
122+
123+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Listens to the updates in map layer registry and does changes in layer tree.
3+
*
4+
* When connected to a layer tree, any layers added to the map layer registry
5+
* will be also added to the layer tree. Similarly, map layers that are removed
6+
* from registry will be removed from the layer tree.
7+
*
8+
* If a layer is completely removed from the layer tree, it will be also removed
9+
* from the map layer registry.
10+
*
11+
* @note added in 2.4
12+
*/
13+
class QgsLayerTreeRegistryBridge : QObject
14+
{
15+
%TypeHeaderCode
16+
#include <qgslayertreeregistrybridge.h>
17+
%End
18+
19+
public:
20+
explicit QgsLayerTreeRegistryBridge( QgsLayerTreeGroup* root, QObject *parent /TransferThis/ = 0 );
21+
22+
void setEnabled( bool enabled );
23+
bool isEnabled() const;
24+
25+
//! Set where the new layers should be inserted - can be used to follow current selection.
26+
//! By default it is root group with zero index.
27+
void setLayerInsertionPoint( QgsLayerTreeGroup* parentGroup, int index );
28+
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Assorted functions for dealing with layer trees.
3+
*
4+
* @note added in 2.4
5+
*/
6+
class QgsLayerTreeUtils
7+
{
8+
%TypeHeaderCode
9+
#include <qgslayertreeutils.h>
10+
%End
11+
12+
public:
13+
14+
//! Try to load layer tree from <legend> tag from project files from QGIS 2.2 and below
15+
static bool readOldLegend( QgsLayerTreeGroup* root, const QDomElement& legendElem );
16+
//! Try to load custom layer order from <legend> tag from project files from QGIS 2.2 and below
17+
static bool readOldLegendLayerOrder( const QDomElement& legendElem, bool& hasCustomOrder, QStringList& order );
18+
//! Return <legend> tag used in QGIS 2.2 and below
19+
static QDomElement writeOldLegend( QDomDocument& doc, QgsLayerTreeGroup* root, bool hasCustomOrder, const QStringList& order );
20+
21+
//! Convert Qt::CheckState to QString
22+
static QString checkStateToXml( Qt::CheckState state );
23+
//! Convert QString to Qt::CheckState
24+
static Qt::CheckState checkStateFromXml( QString txt );
25+
26+
//! Return true if any of the layers is editable
27+
static bool layersEditable( const QList<QgsLayerTreeLayer*>& layerNodes );
28+
//! Return true if any of the layers is modified
29+
static bool layersModified( const QList<QgsLayerTreeLayer*>& layerNodes );
30+
31+
//! Remove layer nodes that refer to invalid layers
32+
static void removeInvalidLayers( QgsLayerTreeGroup* group );
33+
34+
//! Remove subtree of embedded groups. Useful when saving layer tree
35+
static void removeChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group );
36+
37+
};

python/core/qgspallabeling.sip

+4
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,10 @@ class QgsLabelComponent
606606
*/
607607
class QgsLabelingResults
608608
{
609+
%TypeHeaderCode
610+
#include <qgspallabeling.h>
611+
%End
612+
609613
public:
610614
QgsLabelingResults();
611615
~QgsLabelingResults();

0 commit comments

Comments
 (0)