QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
qgslayertreelayer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayertreelayer.cpp
3 --------------------------------------
4 Date : May 2014
5 Copyright : (C) 2014 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgslayertreelayer.h"
17
18#include "qgslayertreeutils.h"
19#include "qgsmaplayer.h"
20#include "qgsproject.h"
21#include "qgsproviderregistry.h"
22#include "qgssymbollayerutils.h"
23
24#include <QString>
25
26#include "moc_qgslayertreelayer.cpp"
27
28using namespace Qt::StringLiterals;
29
37
38QgsLayerTreeLayer::QgsLayerTreeLayer( const QString &layerId, const QString &name, const QString &source, const QString &provider )
40 , mRef( layerId, name, source, provider )
41 , mLayerName( name.isEmpty() ? u"(?)"_s : name )
42{}
43
45 : QgsLayerTreeNode( other )
46 , mRef( other.mRef )
47 , mLayerName( other.mLayerName )
48 , mPatchShape( other.mPatchShape )
49 , mPatchSize( other.mPatchSize )
50 , mSplitBehavior( other.mSplitBehavior )
51{
53}
54
55void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool looseMatching )
56{
57 if ( mRef )
58 return; // already assigned
59
60 if ( !looseMatching )
61 {
62 mRef.resolve( project );
63 }
64 else
65 {
66 mRef.resolveWeakly( project );
67 }
68
69 if ( !mRef )
70 return;
71
73 emit layerLoaded();
74}
75
77{
78 if ( !mRef )
79 return;
80
81 connect( mRef.layer, &QgsMapLayer::nameChanged, this, &QgsLayerTreeLayer::layerNameChanged );
82 connect( mRef.layer, &QgsMapLayer::willBeDeleted, this, &QgsLayerTreeLayer::layerWillBeDeleted );
83}
84
85
87{
88 return ( mRef && mUseLayerName ) ? mRef->name() : mLayerName;
89}
90
91void QgsLayerTreeLayer::setName( const QString &n )
92{
93 if ( mRef && mUseLayerName )
94 {
95 if ( mRef->name() == n )
96 return;
97 mRef->setName( n );
98 // no need to emit signal: we will be notified from layer's nameChanged() signal
99 }
100 else
101 {
102 if ( mLayerName == n )
103 return;
104 mLayerName = n;
105 emit nameChanged( this, n );
106 }
107}
108
109QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsReadWriteContext &context ) // cppcheck-suppress duplInheritedMember
110{
111 if ( element.tagName() != "layer-tree-layer"_L1 )
112 return nullptr;
113
114 const QString layerID = element.attribute( u"id"_s );
115 const QString layerName = element.attribute( u"name"_s );
116
117 const QString providerKey = element.attribute( u"providerKey"_s );
118 const QString sourceRaw = element.attribute( u"source"_s );
119 const QString source = providerKey.isEmpty() ? sourceRaw : QgsProviderRegistry::instance()->relativeToAbsoluteUri( providerKey, sourceRaw, context );
120
121 const Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( u"checked"_s ) );
122 const bool isExpanded = ( element.attribute( u"expanded"_s, u"1"_s ) == "1"_L1 );
123 const QString labelExpression = element.attribute( u"legend_exp"_s );
124
125 // needs to have the layer reference resolved later
126 QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layerID, layerName, source, providerKey );
127
128 nodeLayer->readCommonXml( element );
129
130 nodeLayer->setItemVisibilityChecked( checked != Qt::Unchecked );
131 nodeLayer->setExpanded( isExpanded );
133
134 const QDomElement patchElem = element.firstChildElement( u"patch"_s );
135 if ( !patchElem.isNull() )
136 {
138 patch.readXml( patchElem, context );
139 nodeLayer->setPatchShape( patch );
140 }
141
142 nodeLayer->setPatchSize( QgsSymbolLayerUtils::decodeSize( element.attribute( u"patch_size"_s ) ) );
143
144 nodeLayer->setLegendSplitBehavior( static_cast< LegendNodesSplitBehavior >( element.attribute( u"legend_split_behavior"_s, u"0"_s ).toInt() ) );
145
146 return nodeLayer;
147}
148
149QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
150{
151 QgsLayerTreeLayer *node = readXml( element, context );
152 if ( node )
153 node->resolveReferences( project );
154 return node;
155}
156
157void QgsLayerTreeLayer::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
158{
159 QDomDocument doc = parentElement.ownerDocument();
160 QDomElement elem = doc.createElement( u"layer-tree-layer"_s );
161 elem.setAttribute( u"id"_s, layerId() );
162 elem.setAttribute( u"name"_s, name() );
163
164 if ( mRef )
165 {
166 const QString providerKey = mRef->dataProvider() ? mRef->dataProvider()->name() : QString();
167 const QString source = providerKey.isEmpty() ? mRef->publicSource() : QgsProviderRegistry::instance()->absoluteToRelativeUri( providerKey, mRef->publicSource(), context );
168 elem.setAttribute( u"source"_s, source );
169 elem.setAttribute( u"providerKey"_s, providerKey );
170 }
171
172 elem.setAttribute( u"checked"_s, mChecked ? u"Qt::Checked"_s : u"Qt::Unchecked"_s );
173 elem.setAttribute( u"expanded"_s, mExpanded ? "1" : "0" );
174 elem.setAttribute( u"legend_exp"_s, mLabelExpression );
175
176 if ( !mPatchShape.isNull() )
177 {
178 QDomElement patchElem = doc.createElement( u"patch"_s );
179 mPatchShape.writeXml( patchElem, doc, context );
180 elem.appendChild( patchElem );
181 }
182 elem.setAttribute( u"patch_size"_s, QgsSymbolLayerUtils::encodeSize( mPatchSize ) );
183
184 elem.setAttribute( u"legend_split_behavior"_s, mSplitBehavior );
185
186 writeCommonXml( elem );
187
188 parentElement.appendChild( elem );
189}
190
192{
193 return u"LAYER: %1 checked=%2 expanded=%3 id=%4\n"_s.arg( name() ).arg( mChecked ).arg( mExpanded ).arg( layerId() );
194}
195
197{
198 return new QgsLayerTreeLayer( *this );
199}
200
201void QgsLayerTreeLayer::layerWillBeDeleted()
202{
203 Q_ASSERT( mRef );
204
205 emit layerWillBeUnloaded();
206
207 mLayerName = mRef->name();
208 // in theory we do not even need to do this - the weak ref should clear itself
209 mRef.layer.clear();
210 // layerId stays in the reference
211}
212
214{
215 mUseLayerName = use;
216}
217
219{
220 return mUseLayerName;
221}
222
223void QgsLayerTreeLayer::layerNameChanged()
224{
225 Q_ASSERT( mRef );
226 emit nameChanged( this, mRef->name() );
227}
228
229void QgsLayerTreeLayer::setLabelExpression( const QString &expression )
230{
231 mLabelExpression = expression;
232}
233
235{
236 return mPatchShape;
237}
238
240{
241 mPatchShape = shape;
242}
QString dump() const override
Returns string with layer tree structure. For debug purposes only.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Resolves reference to layer from stored layer ID (if it has not been resolved already).
void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context) override
Write layer tree to XML.
QString layerId() const
Returns the ID for the map layer associated with this node.
QString mLabelExpression
Expression to evaluate in the legend.
void setPatchSize(QSizeF size)
Sets the user (overridden) size for the legend node.
QgsMapLayerRef mRef
Weak reference to the layer (or just it's ID if the reference is not resolved yet).
void layerWillBeUnloaded()
Emitted when a previously available layer got unloaded (from layer registry).
void setName(const QString &n) override
Sets the layer's name.
QString labelExpression() const
Returns the expression member of the LayerTreeNode.
LegendNodesSplitBehavior
Legend node column split behavior.
void setUseLayerName(bool use=true)
Uses the layer's name if use is true, or the name manually set if false.
QgsLegendPatchShape patchShape() const
Returns the symbol patch shape to use when rendering the legend node symbol.
void setLabelExpression(const QString &expression)
set the expression to evaluate
QgsLayerTreeLayer(QgsMapLayer *layer)
bool useLayerName() const
Returns whether the layer's name is used, or the name manually set.
void setPatchShape(const QgsLegendPatchShape &shape)
Sets the symbol patch shape to use when rendering the legend node symbol.
QString name() const override
Returns the layer's name.
void layerLoaded()
Emitted when a previously unavailable layer got loaded.
static QgsLayerTreeLayer * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer node from XML.
void setLegendSplitBehavior(LegendNodesSplitBehavior behavior)
Sets the column split behavior for the node.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
QString mLayerName
Layer name - only used if layer does not exist or if mUseLayerName is false.
QgsLayerTreeLayer * clone() const override
Create a copy of the node. Returns new instance.
@ NodeLayer
Leaf node pointing to a layer.
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
QgsLayerTreeNode(NodeType t, bool checked=true)
Constructor.
void writeCommonXml(QDomElement &element)
Write common XML elements.
bool mExpanded
whether the node should be shown in GUI as expanded
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children).
void readCommonXml(const QDomElement &element)
Read common XML elements.
static Qt::CheckState checkStateFromXml(const QString &txt)
Convert QString to Qt::CheckState.
Represents a patch shape for use in map legends.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
Base class for all map layer types.
Definition qgsmaplayer.h:83
QString name
Definition qgsmaplayer.h:87
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
void nameChanged()
Emitted when the name has been changed.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:113
QString absoluteToRelativeUri(const QString &providerKey, const QString &uri, const QgsReadWriteContext &context) const
Converts absolute path(s) to relative path(s) in the given provider-specific URI.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString relativeToAbsoluteUri(const QString &providerKey, const QString &uri, const QgsReadWriteContext &context) const
Converts relative path(s) to absolute path(s) in the given provider-specific URI.
A container for the context for various read/write operations on objects.
static QString encodeSize(QSizeF size)
Encodes a QSizeF to a string.
static QSizeF decodeSize(const QString &string)
Decodes a QSizeF from a string.
QPointer< TYPE > layer
Weak pointer to map layer.