QGIS API Documentation 3.41.0-Master (af5edcb665c)
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#include "moc_qgslayertreelayer.cpp"
18
19#include "qgslayertreeutils.h"
20#include "qgsmaplayer.h"
21#include "qgsproject.h"
22#include "qgsproviderregistry.h"
23#include "qgssymbollayerutils.h"
24
26 : QgsLayerTreeNode( NodeLayer, true )
27 , mRef( layer )
28 , mLayerName( layer->name() )
29{
31}
32
33QgsLayerTreeLayer::QgsLayerTreeLayer( const QString &layerId, const QString &name, const QString &source, const QString &provider )
34 : QgsLayerTreeNode( NodeLayer, true )
35 , mRef( layerId, name, source, provider )
36 , mLayerName( name.isEmpty() ? QStringLiteral( "(?)" ) : name )
37{
38}
39
41 : QgsLayerTreeNode( other )
42 , mRef( other.mRef )
43 , mLayerName( other.mLayerName )
44 , mPatchShape( other.mPatchShape )
45 , mPatchSize( other.mPatchSize )
46 , mSplitBehavior( other.mSplitBehavior )
47{
49}
50
51void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool looseMatching )
52{
53 if ( mRef )
54 return; // already assigned
55
56 if ( !looseMatching )
57 {
58 mRef.resolve( project );
59 }
60 else
61 {
62 mRef.resolveWeakly( project );
63 }
64
65 if ( !mRef )
66 return;
67
69 emit layerLoaded();
70}
71
73{
74 if ( !mRef )
75 return;
76
77 connect( mRef.layer, &QgsMapLayer::nameChanged, this, &QgsLayerTreeLayer::layerNameChanged );
78 connect( mRef.layer, &QgsMapLayer::willBeDeleted, this, &QgsLayerTreeLayer::layerWillBeDeleted );
79}
80
81
83{
84 return ( mRef && mUseLayerName ) ? mRef->name() : mLayerName;
85}
86
87void QgsLayerTreeLayer::setName( const QString &n )
88{
89 if ( mRef && mUseLayerName )
90 {
91 if ( mRef->name() == n )
92 return;
93 mRef->setName( n );
94 // no need to emit signal: we will be notified from layer's nameChanged() signal
95 }
96 else
97 {
98 if ( mLayerName == n )
99 return;
100 mLayerName = n;
101 emit nameChanged( this, n );
102 }
103}
104
105QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsReadWriteContext &context ) // cppcheck-suppress duplInheritedMember
106{
107 if ( element.tagName() != QLatin1String( "layer-tree-layer" ) )
108 return nullptr;
109
110 const QString layerID = element.attribute( QStringLiteral( "id" ) );
111 const QString layerName = element.attribute( QStringLiteral( "name" ) );
112
113 const QString providerKey = element.attribute( QStringLiteral( "providerKey" ) );
114 const QString sourceRaw = element.attribute( QStringLiteral( "source" ) );
115 const QString source = providerKey.isEmpty() ? sourceRaw : QgsProviderRegistry::instance()->relativeToAbsoluteUri( providerKey, sourceRaw, context );
116
117 const Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( QStringLiteral( "checked" ) ) );
118 const bool isExpanded = ( element.attribute( QStringLiteral( "expanded" ), QStringLiteral( "1" ) ) == QLatin1String( "1" ) );
119 const QString labelExpression = element.attribute( QStringLiteral( "legend_exp" ) );
120
121 // needs to have the layer reference resolved later
122 QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layerID, layerName, source, providerKey );
123
124 nodeLayer->readCommonXml( element );
125
126 nodeLayer->setItemVisibilityChecked( checked != Qt::Unchecked );
127 nodeLayer->setExpanded( isExpanded );
129
130 const QDomElement patchElem = element.firstChildElement( QStringLiteral( "patch" ) );
131 if ( !patchElem.isNull() )
132 {
134 patch.readXml( patchElem, context );
135 nodeLayer->setPatchShape( patch );
136 }
137
138 nodeLayer->setPatchSize( QgsSymbolLayerUtils::decodeSize( element.attribute( QStringLiteral( "patch_size" ) ) ) );
139
140 nodeLayer->setLegendSplitBehavior( static_cast< LegendNodesSplitBehavior >( element.attribute( QStringLiteral( "legend_split_behavior" ), QStringLiteral( "0" ) ).toInt() ) );
141
142 return nodeLayer;
143}
144
145QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
146{
147 QgsLayerTreeLayer *node = readXml( element, context );
148 if ( node )
149 node->resolveReferences( project );
150 return node;
151}
152
153void QgsLayerTreeLayer::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
154{
155 QDomDocument doc = parentElement.ownerDocument();
156 QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-layer" ) );
157 elem.setAttribute( QStringLiteral( "id" ), layerId() );
158 elem.setAttribute( QStringLiteral( "name" ), name() );
159
160 if ( mRef )
161 {
162 const QString providerKey = mRef->dataProvider() ? mRef->dataProvider()->name() : QString();
163 const QString source = providerKey.isEmpty() ? mRef->publicSource() : QgsProviderRegistry::instance()->absoluteToRelativeUri( providerKey, mRef->publicSource(), context );
164 elem.setAttribute( QStringLiteral( "source" ), source );
165 elem.setAttribute( QStringLiteral( "providerKey" ), providerKey );
166 }
167
168 elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) );
169 elem.setAttribute( QStringLiteral( "expanded" ), mExpanded ? "1" : "0" );
170 elem.setAttribute( QStringLiteral( "legend_exp" ), mLabelExpression );
171
172 if ( !mPatchShape.isNull() )
173 {
174 QDomElement patchElem = doc.createElement( QStringLiteral( "patch" ) );
175 mPatchShape.writeXml( patchElem, doc, context );
176 elem.appendChild( patchElem );
177 }
178 elem.setAttribute( QStringLiteral( "patch_size" ), QgsSymbolLayerUtils::encodeSize( mPatchSize ) );
179
180 elem.setAttribute( QStringLiteral( "legend_split_behavior" ), mSplitBehavior );
181
182 writeCommonXml( elem );
183
184 parentElement.appendChild( elem );
185}
186
188{
189 return QStringLiteral( "LAYER: %1 checked=%2 expanded=%3 id=%4\n" ).arg( name() ).arg( mChecked ).arg( mExpanded ).arg( layerId() );
190}
191
193{
194 return new QgsLayerTreeLayer( *this );
195}
196
197void QgsLayerTreeLayer::layerWillBeDeleted()
198{
199 Q_ASSERT( mRef );
200
201 emit layerWillBeUnloaded();
202
203 mLayerName = mRef->name();
204 // in theory we do not even need to do this - the weak ref should clear itself
205 mRef.layer.clear();
206 // layerId stays in the reference
207
208}
209
211{
212 mUseLayerName = use;
213}
214
216{
217 return mUseLayerName;
218}
219
220void QgsLayerTreeLayer::layerNameChanged()
221{
222 Q_ASSERT( mRef );
223 emit nameChanged( this, mRef->name() );
224}
225
226void QgsLayerTreeLayer::setLabelExpression( const QString &expression )
227{
228 mLabelExpression = expression;
229}
230
232{
233 return mPatchShape;
234}
235
237{
238 mPatchShape = shape;
239}
240
virtual QString name() const =0
Returns a provider name.
Layer tree node points to a map layer.
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.
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.
This class is a base class for nodes in a layer tree.
void readCommonXml(QDomElement &element)
Read common XML elements.
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.
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)
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.
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
Base class for all map layer types.
Definition qgsmaplayer.h:76
QString name
Definition qgsmaplayer.h:80
QString publicSource(bool hidePassword=false) const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
void setName(const QString &name)
Set the display name of the layer.
void nameChanged()
Emitted when the name has been changed.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:107
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.
The class is used as a container of context for various read/write operations on other objects.
static QString encodeSize(QSizeF size)
Encodes a QSizeF to a string.
static QSizeF decodeSize(const QString &string)
Decodes a QSizeF from a string.
TYPE * resolveWeakly(const QgsProject *project, MatchType matchType=MatchType::All)
Resolves the map layer by attempting to find a matching layer in a project using a weak match.
QPointer< TYPE > layer
Weak pointer to map layer.
TYPE * resolve(const QgsProject *project)
Resolves the map layer by attempting to find a layer with matching ID within a project.