QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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 "moc_qgslayertreelayer.cpp"
25
33
34QgsLayerTreeLayer::QgsLayerTreeLayer( const QString &layerId, const QString &name, const QString &source, const QString &provider )
36 , mRef( layerId, name, source, provider )
37 , mLayerName( name.isEmpty() ? QStringLiteral( "(?)" ) : name )
38{
39}
40
42 : QgsLayerTreeNode( other )
43 , mRef( other.mRef )
44 , mLayerName( other.mLayerName )
45 , mPatchShape( other.mPatchShape )
46 , mPatchSize( other.mPatchSize )
47 , mSplitBehavior( other.mSplitBehavior )
48{
50}
51
52void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool looseMatching )
53{
54 if ( mRef )
55 return; // already assigned
56
57 if ( !looseMatching )
58 {
59 mRef.resolve( project );
60 }
61 else
62 {
63 mRef.resolveWeakly( project );
64 }
65
66 if ( !mRef )
67 return;
68
70 emit layerLoaded();
71}
72
74{
75 if ( !mRef )
76 return;
77
78 connect( mRef.layer, &QgsMapLayer::nameChanged, this, &QgsLayerTreeLayer::layerNameChanged );
79 connect( mRef.layer, &QgsMapLayer::willBeDeleted, this, &QgsLayerTreeLayer::layerWillBeDeleted );
80}
81
82
84{
85 return ( mRef && mUseLayerName ) ? mRef->name() : mLayerName;
86}
87
88void QgsLayerTreeLayer::setName( const QString &n )
89{
90 if ( mRef && mUseLayerName )
91 {
92 if ( mRef->name() == n )
93 return;
94 mRef->setName( n );
95 // no need to emit signal: we will be notified from layer's nameChanged() signal
96 }
97 else
98 {
99 if ( mLayerName == n )
100 return;
101 mLayerName = n;
102 emit nameChanged( this, n );
103 }
104}
105
106QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsReadWriteContext &context ) // cppcheck-suppress duplInheritedMember
107{
108 if ( element.tagName() != QLatin1String( "layer-tree-layer" ) )
109 return nullptr;
110
111 const QString layerID = element.attribute( QStringLiteral( "id" ) );
112 const QString layerName = element.attribute( QStringLiteral( "name" ) );
113
114 const QString providerKey = element.attribute( QStringLiteral( "providerKey" ) );
115 const QString sourceRaw = element.attribute( QStringLiteral( "source" ) );
116 const QString source = providerKey.isEmpty() ? sourceRaw : QgsProviderRegistry::instance()->relativeToAbsoluteUri( providerKey, sourceRaw, context );
117
118 const Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( QStringLiteral( "checked" ) ) );
119 const bool isExpanded = ( element.attribute( QStringLiteral( "expanded" ), QStringLiteral( "1" ) ) == QLatin1String( "1" ) );
120 const QString labelExpression = element.attribute( QStringLiteral( "legend_exp" ) );
121
122 // needs to have the layer reference resolved later
123 QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layerID, layerName, source, providerKey );
124
125 nodeLayer->readCommonXml( element );
126
127 nodeLayer->setItemVisibilityChecked( checked != Qt::Unchecked );
128 nodeLayer->setExpanded( isExpanded );
130
131 const QDomElement patchElem = element.firstChildElement( QStringLiteral( "patch" ) );
132 if ( !patchElem.isNull() )
133 {
135 patch.readXml( patchElem, context );
136 nodeLayer->setPatchShape( patch );
137 }
138
139 nodeLayer->setPatchSize( QgsSymbolLayerUtils::decodeSize( element.attribute( QStringLiteral( "patch_size" ) ) ) );
140
141 nodeLayer->setLegendSplitBehavior( static_cast< LegendNodesSplitBehavior >( element.attribute( QStringLiteral( "legend_split_behavior" ), QStringLiteral( "0" ) ).toInt() ) );
142
143 return nodeLayer;
144}
145
146QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
147{
148 QgsLayerTreeLayer *node = readXml( element, context );
149 if ( node )
150 node->resolveReferences( project );
151 return node;
152}
153
154void QgsLayerTreeLayer::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
155{
156 QDomDocument doc = parentElement.ownerDocument();
157 QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-layer" ) );
158 elem.setAttribute( QStringLiteral( "id" ), layerId() );
159 elem.setAttribute( QStringLiteral( "name" ), name() );
160
161 if ( mRef )
162 {
163 const QString providerKey = mRef->dataProvider() ? mRef->dataProvider()->name() : QString();
164 const QString source = providerKey.isEmpty() ? mRef->publicSource() : QgsProviderRegistry::instance()->absoluteToRelativeUri( providerKey, mRef->publicSource(), context );
165 elem.setAttribute( QStringLiteral( "source" ), source );
166 elem.setAttribute( QStringLiteral( "providerKey" ), providerKey );
167 }
168
169 elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) );
170 elem.setAttribute( QStringLiteral( "expanded" ), mExpanded ? "1" : "0" );
171 elem.setAttribute( QStringLiteral( "legend_exp" ), mLabelExpression );
172
173 if ( !mPatchShape.isNull() )
174 {
175 QDomElement patchElem = doc.createElement( QStringLiteral( "patch" ) );
176 mPatchShape.writeXml( patchElem, doc, context );
177 elem.appendChild( patchElem );
178 }
179 elem.setAttribute( QStringLiteral( "patch_size" ), QgsSymbolLayerUtils::encodeSize( mPatchSize ) );
180
181 elem.setAttribute( QStringLiteral( "legend_split_behavior" ), mSplitBehavior );
182
183 writeCommonXml( elem );
184
185 parentElement.appendChild( elem );
186}
187
189{
190 return QStringLiteral( "LAYER: %1 checked=%2 expanded=%3 id=%4\n" ).arg( name() ).arg( mChecked ).arg( mExpanded ).arg( layerId() );
191}
192
194{
195 return new QgsLayerTreeLayer( *this );
196}
197
198void QgsLayerTreeLayer::layerWillBeDeleted()
199{
200 Q_ASSERT( mRef );
201
202 emit layerWillBeUnloaded();
203
204 mLayerName = mRef->name();
205 // in theory we do not even need to do this - the weak ref should clear itself
206 mRef.layer.clear();
207 // layerId stays in the reference
208
209}
210
212{
213 mUseLayerName = use;
214}
215
217{
218 return mUseLayerName;
219}
220
221void QgsLayerTreeLayer::layerNameChanged()
222{
223 Q_ASSERT( mRef );
224 emit nameChanged( this, mRef->name() );
225}
226
227void QgsLayerTreeLayer::setLabelExpression( const QString &expression )
228{
229 mLabelExpression = expression;
230}
231
233{
234 return mPatchShape;
235}
236
238{
239 mPatchShape = shape;
240}
241
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:80
QString name
Definition qgsmaplayer.h:84
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:109
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.