QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 "qgssymbollayerutils.h"
22 
23 
25  : QgsLayerTreeNode( NodeLayer, true )
26  , mRef( layer )
27  , mLayerName( layer->name() )
28 {
29  attachToLayer();
30 }
31 
32 QgsLayerTreeLayer::QgsLayerTreeLayer( const QString &layerId, const QString &name, const QString &source, const QString &provider )
33  : QgsLayerTreeNode( NodeLayer, true )
34  , mRef( layerId, name, source, provider )
35  , mLayerName( name.isEmpty() ? QStringLiteral( "(?)" ) : name )
36 {
37 }
38 
40  : QgsLayerTreeNode( other )
41  , mRef( other.mRef )
42  , mLayerName( other.mLayerName )
43  , mPatchShape( other.mPatchShape )
44  , mPatchSize( other.mPatchSize )
45  , mSplitBehavior( other.mSplitBehavior )
46 {
47  attachToLayer();
48 }
49 
50 void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool looseMatching )
51 {
52  if ( mRef )
53  return; // already assigned
54 
55  if ( !looseMatching )
56  {
57  mRef.resolve( project );
58  }
59  else
60  {
61  mRef.resolveWeakly( project );
62  }
63 
64  if ( !mRef )
65  return;
66 
67  attachToLayer();
68  emit layerLoaded();
69 }
70 
72 {
73  if ( !mRef )
74  return;
75 
76  connect( mRef.layer, &QgsMapLayer::nameChanged, this, &QgsLayerTreeLayer::layerNameChanged );
77  connect( mRef.layer, &QgsMapLayer::willBeDeleted, this, &QgsLayerTreeLayer::layerWillBeDeleted );
78 }
79 
80 
81 QString QgsLayerTreeLayer::name() const
82 {
83  return ( mRef && mUseLayerName ) ? mRef->name() : mLayerName;
84 }
85 
86 void QgsLayerTreeLayer::setName( const QString &n )
87 {
88  if ( mRef && mUseLayerName )
89  {
90  if ( mRef->name() == n )
91  return;
92  mRef->setName( n );
93  // no need to emit signal: we will be notified from layer's nameChanged() signal
94  }
95  else
96  {
97  if ( mLayerName == n )
98  return;
99  mLayerName = n;
100  emit nameChanged( this, n );
101  }
102 }
103 
104 QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsReadWriteContext &context )
105 {
106  if ( element.tagName() != QLatin1String( "layer-tree-layer" ) )
107  return nullptr;
108 
109  QString layerID = element.attribute( QStringLiteral( "id" ) );
110  QString layerName = element.attribute( QStringLiteral( "name" ) );
111 
112  QString providerKey = element.attribute( QStringLiteral( "providerKey" ) );
113  QString source = context.pathResolver().readPath( element.attribute( QStringLiteral( "source" ) ) );
114 
115  Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( QStringLiteral( "checked" ) ) );
116  bool isExpanded = ( element.attribute( QStringLiteral( "expanded" ), QStringLiteral( "1" ) ) == QLatin1String( "1" ) );
117  QString labelExpression = element.attribute( QStringLiteral( "legend_exp" ) );
118 
119  // needs to have the layer reference resolved later
120  QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layerID, layerName, source, providerKey );
121 
122  nodeLayer->readCommonXml( element );
123 
124  nodeLayer->setItemVisibilityChecked( checked != Qt::Unchecked );
125  nodeLayer->setExpanded( isExpanded );
126  nodeLayer->setLabelExpression( labelExpression );
127 
128  const QDomElement patchElem = element.firstChildElement( QStringLiteral( "patch" ) );
129  if ( !patchElem.isNull() )
130  {
131  QgsLegendPatchShape patch;
132  patch.readXml( patchElem, context );
133  nodeLayer->setPatchShape( patch );
134  }
135 
136  nodeLayer->setPatchSize( QgsSymbolLayerUtils::decodeSize( element.attribute( QStringLiteral( "patch_size" ) ) ) );
137 
138  nodeLayer->setLegendSplitBehavior( static_cast< LegendNodesSplitBehavior >( element.attribute( QStringLiteral( "legend_split_behavior" ), QStringLiteral( "0" ) ).toInt() ) );
139 
140  return nodeLayer;
141 }
142 
143 QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
144 {
145  QgsLayerTreeLayer *node = readXml( element, context );
146  if ( node )
147  node->resolveReferences( project );
148  return node;
149 }
150 
151 void QgsLayerTreeLayer::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
152 {
153  QDomDocument doc = parentElement.ownerDocument();
154  QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-layer" ) );
155  elem.setAttribute( QStringLiteral( "id" ), layerId() );
156  elem.setAttribute( QStringLiteral( "name" ), name() );
157 
158  if ( mRef )
159  {
160  elem.setAttribute( QStringLiteral( "source" ), context.pathResolver().writePath( mRef->publicSource() ) );
161  elem.setAttribute( QStringLiteral( "providerKey" ), mRef->dataProvider() ? mRef->dataProvider()->name() : QString() );
162  }
163 
164  elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) );
165  elem.setAttribute( QStringLiteral( "expanded" ), mExpanded ? "1" : "0" );
166  elem.setAttribute( QStringLiteral( "legend_exp" ), mLabelExpression );
167 
168  if ( !mPatchShape.isNull() )
169  {
170  QDomElement patchElem = doc.createElement( QStringLiteral( "patch" ) );
171  mPatchShape.writeXml( patchElem, doc, context );
172  elem.appendChild( patchElem );
173  }
174  elem.setAttribute( QStringLiteral( "patch_size" ), QgsSymbolLayerUtils::encodeSize( mPatchSize ) );
175 
176  elem.setAttribute( QStringLiteral( "legend_split_behavior" ), mSplitBehavior );
177 
178  writeCommonXml( elem );
179 
180  parentElement.appendChild( elem );
181 }
182 
183 QString QgsLayerTreeLayer::dump() const
184 {
185  return QStringLiteral( "LAYER: %1 checked=%2 expanded=%3 id=%4\n" ).arg( name() ).arg( mChecked ).arg( mExpanded ).arg( layerId() );
186 }
187 
189 {
190  return new QgsLayerTreeLayer( *this );
191 }
192 
193 void QgsLayerTreeLayer::layerWillBeDeleted()
194 {
195  Q_ASSERT( mRef );
196 
197  emit layerWillBeUnloaded();
198 
199  mLayerName = mRef->name();
200  // in theory we do not even need to do this - the weak ref should clear itself
201  mRef.layer.clear();
202  // layerId stays in the reference
203 
204 }
205 
207 {
208  mUseLayerName = use;
209 }
210 
212 {
213  return mUseLayerName;
214 }
215 
216 void QgsLayerTreeLayer::layerNameChanged()
217 {
218  Q_ASSERT( mRef );
219  emit nameChanged( this, mRef->name() );
220 }
221 
222 void QgsLayerTreeLayer::setLabelExpression( const QString &expression )
223 {
224  mLabelExpression = expression;
225 }
226 
228 {
229  return mPatchShape;
230 }
231 
233 {
234  mPatchShape = shape;
235 }
236 
QgsMapLayer::willBeDeleted
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
QgsLayerTreeLayer::labelExpression
QString labelExpression() const
Returns the expression member of the LayerTreeNode.
Definition: qgslayertreelayer.h:144
QgsLayerTreeLayer::QgsLayerTreeLayer
QgsLayerTreeLayer(QgsMapLayer *layer)
Definition: qgslayertreelayer.cpp:24
QgsLayerTreeNode
This class is a base class for nodes in a layer tree.
Definition: qgslayertreenode.h:75
QgsLayerTreeLayer::patchShape
QgsLegendPatchShape patchShape() const
Returns the symbol patch shape to use when rendering the legend node symbol.
Definition: qgslayertreelayer.cpp:227
QgsLayerTreeNode::setItemVisibilityChecked
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
Definition: qgslayertreenode.cpp:78
_LayerRef::resolveWeakly
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.
Definition: qgsmaplayerref.h:210
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
QgsLayerTreeLayer::layerLoaded
void layerLoaded()
Emitted when a previously unavailable layer got loaded.
QgsLayerTreeLayer::useLayerName
bool useLayerName() const
Returns whether the layer's name is used, or the name manually set.
Definition: qgslayertreelayer.cpp:211
QgsLayerTreeLayer::layerId
QString layerId() const
Returns the ID for the map layer associated with this node.
Definition: qgslayertreelayer.h:63
QgsLayerTreeNode::writeCommonXml
void writeCommonXml(QDomElement &element)
Write common XML elements.
Definition: qgslayertreenode.cpp:213
QgsLayerTreeNode::mChecked
bool mChecked
Definition: qgslayertreenode.h:279
QgsLayerTreeLayer::setUseLayerName
void setUseLayerName(bool use=true)
Uses the layer's name if use is true, or the name manually set if false.
Definition: qgslayertreelayer.cpp:206
qgssymbollayerutils.h
qgslayertreelayer.h
QgsLayerTreeNode::nameChanged
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
QgsLayerTreeLayer::name
QString name() const override
Returns the layer's name.
Definition: qgslayertreelayer.cpp:81
_LayerRef::layer
QPointer< TYPE > layer
Weak pointer to map layer.
Definition: qgsmaplayerref.h:113
QgsLayerTreeLayer::mUseLayerName
bool mUseLayerName
Definition: qgslayertreelayer.h:240
QgsLegendPatchShape
Represents a patch shape for use in map legends.
Definition: qgslegendpatchshape.h:31
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:95
QgsLayerTreeLayer::mLayerName
QString mLayerName
Layer name - only used if layer does not exist or if mUseLayerName is false.
Definition: qgslayertreelayer.h:235
QgsLayerTreeLayer::mRef
QgsMapLayerRef mRef
Weak reference to the layer (or just it's ID if the reference is not resolved yet)
Definition: qgslayertreelayer.h:233
QgsPathResolver::writePath
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
Definition: qgspathresolver.cpp:192
QgsLayerTreeLayer::writeXml
void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context) override
Write layer tree to XML.
Definition: qgslayertreelayer.cpp:151
QgsLayerTreeLayer::setPatchSize
void setPatchSize(QSizeF size)
Sets the user (overridden) size for the legend node.
Definition: qgslayertreelayer.h:182
QgsLayerTreeLayer::setName
void setName(const QString &n) override
Sets the layer's name.
Definition: qgslayertreelayer.cpp:86
QgsLayerTreeLayer
Layer tree node points to a map layer.
Definition: qgslayertreelayer.h:44
qgsmaplayer.h
QgsMapLayer::nameChanged
void nameChanged()
Emitted when the name has been changed.
QgsLayerTreeLayer::LegendNodesSplitBehavior
LegendNodesSplitBehavior
Legend node column split behavior.
Definition: qgslayertreelayer.h:190
QgsLayerTreeUtils::checkStateFromXml
static Qt::CheckState checkStateFromXml(const QString &txt)
Convert QString to Qt::CheckState.
Definition: qgslayertreeutils.cpp:197
QgsLayerTreeLayer::attachToLayer
void attachToLayer()
Definition: qgslayertreelayer.cpp:71
QgsLayerTreeNode::isExpanded
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:104
QgsSymbolLayerUtils::encodeSize
static QString encodeSize(QSizeF size)
Encodes a QSizeF to a string.
Definition: qgssymbollayerutils.cpp:494
QgsLayerTreeLayer::layerWillBeUnloaded
void layerWillBeUnloaded()
Emitted when a previously available layer got unloaded (from layer registry).
QgsMapLayer::publicSource
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
Definition: qgsmaplayer.cpp:184
QgsPathResolver::readPath
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Definition: qgspathresolver.cpp:35
QgsLayerTreeLayer::setLabelExpression
void setLabelExpression(const QString &expression)
set the expression to evaluate
Definition: qgslayertreelayer.cpp:222
QgsLayerTreeLayer::mLabelExpression
QString mLabelExpression
Expression to evaluate in the legend.
Definition: qgslayertreelayer.h:237
QgsMapLayer::setName
void setName(const QString &name)
Set the display name of the layer.
Definition: qgsmaplayer.cpp:153
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
QgsLayerTreeLayer::resolveReferences
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Resolves reference to layer from stored layer ID (if it has not been resolved already)
Definition: qgslayertreelayer.cpp:50
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:86
QgsLayerTreeLayer::clone
QgsLayerTreeLayer * clone() const override
Create a copy of the node. Returns new instance.
Definition: qgslayertreelayer.cpp:188
QgsLayerTreeNode::mExpanded
bool mExpanded
whether the node should be shown in GUI as expanded
Definition: qgslayertreenode.h:285
qgslayertreeutils.h
QgsLayerTreeLayer::setLegendSplitBehavior
void setLegendSplitBehavior(LegendNodesSplitBehavior behavior)
Sets the column split behavior for the node.
Definition: qgslayertreelayer.h:214
QgsDataProvider::name
virtual QString name() const =0
Returns a provider name.
QgsLayerTreeLayer::dump
QString dump() const override
Returns string with layer tree structure. For debug purposes only.
Definition: qgslayertreelayer.cpp:183
QgsLayerTreeNode::setExpanded
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
Definition: qgslayertreenode.cpp:170
QgsLegendPatchShape::writeXml
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
Definition: qgslegendpatchshape.cpp:200
QgsSymbolLayerUtils::decodeSize
static QSizeF decodeSize(const QString &string)
Decodes a QSizeF from a string.
Definition: qgssymbollayerutils.cpp:499
qgsproject.h
QgsLayerTreeLayer::setPatchShape
void setPatchShape(const QgsLegendPatchShape &shape)
Sets the symbol patch shape to use when rendering the legend node symbol.
Definition: qgslayertreelayer.cpp:232
QgsLayerTreeLayer::readXml
static QgsLayerTreeLayer * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer node from XML.
Definition: qgslayertreelayer.cpp:104
QgsLegendPatchShape::readXml
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
Definition: qgslegendpatchshape.cpp:193
QgsMapLayer::dataProvider
virtual QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
Definition: qgsmaplayer.cpp:169
_LayerRef::resolve
TYPE * resolve(const QgsProject *project)
Resolves the map layer by attempting to find a layer with matching ID within a project.
Definition: qgsmaplayerref.h:149
QgsReadWriteContext::pathResolver
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
Definition: qgsreadwritecontext.cpp:47
QgsLegendPatchShape::isNull
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
Definition: qgslegendpatchshape.cpp:32
QgsLayerTreeNode::readCommonXml
void readCommonXml(QDomElement &element)
Read common XML elements.
Definition: qgslayertreenode.cpp:208