QGIS API Documentation  2.99.0-Master (0a63d1f)
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 
22 
24  : QgsLayerTreeNode( NodeLayer, true )
25  , mLayerId( layer->id() )
26  , mLayer( nullptr )
27 {
28  Q_ASSERT( QgsProject::instance()->mapLayer( mLayerId ) == layer );
29  attachToLayer();
30 }
31 
32 QgsLayerTreeLayer::QgsLayerTreeLayer( const QString& layerId, const QString& name )
33  : QgsLayerTreeNode( NodeLayer, true )
34  , mLayerId( layerId )
35  , mLayerName( name )
36  , mLayer( nullptr )
37 {
38  attachToLayer();
39 }
40 
42  : QgsLayerTreeNode( other )
43  , mLayerId( other.mLayerId )
44  , mLayerName( other.mLayerName )
45  , mLayer( nullptr )
46 {
47  attachToLayer();
48 }
49 
51 {
52  // layer is not necessarily already loaded
54  if ( l )
55  {
56  mLayer = l;
57  mLayerName = l->name();
58  connect( l, SIGNAL( nameChanged() ), this, SLOT( layerNameChanged() ) );
59  // make sure we are notified if the layer is removed
60  connect( QgsProject::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( registryLayersWillBeRemoved( QStringList ) ) );
61  }
62  else
63  {
64  if ( mLayerName.isEmpty() )
65  mLayerName = QStringLiteral( "(?)" );
66  // wait for the layer to be eventually loaded
67  connect( QgsProject::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( registryLayersAdded( QList<QgsMapLayer*> ) ) );
68  }
69 }
70 
71 QString QgsLayerTreeLayer::name() const
72 {
73  return mLayer ? mLayer->name() : mLayerName;
74 }
75 
76 void QgsLayerTreeLayer::setName( const QString& n )
77 {
78  if ( mLayer )
79  {
80  if ( mLayer->name() == n )
81  return;
82  mLayer->setName( n );
83  // no need to emit signal: we will be notified from layer's nameChanged() signal
84  }
85  else
86  {
87  if ( mLayerName == n )
88  return;
89  mLayerName = n;
90  emit nameChanged( this, n );
91  }
92 }
93 
95 {
96  if ( element.tagName() != QLatin1String( "layer-tree-layer" ) )
97  return nullptr;
98 
99  QString layerID = element.attribute( QStringLiteral( "id" ) );
100  QString layerName = element.attribute( QStringLiteral( "name" ) );
101  Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( QStringLiteral( "checked" ) ) );
102  bool isExpanded = ( element.attribute( QStringLiteral( "expanded" ), QStringLiteral( "1" ) ) == QLatin1String( "1" ) );
103 
104  QgsLayerTreeLayer* nodeLayer = nullptr;
105 
107 
108  if ( layer )
109  nodeLayer = new QgsLayerTreeLayer( layer );
110  else
111  nodeLayer = new QgsLayerTreeLayer( layerID, layerName );
112 
113  nodeLayer->readCommonXml( element );
114 
115  nodeLayer->setItemVisibilityChecked( checked != Qt::Unchecked );
116  nodeLayer->setExpanded( isExpanded );
117  return nodeLayer;
118 }
119 
120 void QgsLayerTreeLayer::writeXml( QDomElement& parentElement )
121 {
122  QDomDocument doc = parentElement.ownerDocument();
123  QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-layer" ) );
124  elem.setAttribute( QStringLiteral( "id" ), mLayerId );
125  elem.setAttribute( QStringLiteral( "name" ), name() );
126  elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) );
127  elem.setAttribute( QStringLiteral( "expanded" ), mExpanded ? "1" : "0" );
128 
129  writeCommonXml( elem );
130 
131  parentElement.appendChild( elem );
132 }
133 
134 QString QgsLayerTreeLayer::dump() const
135 {
136  return QStringLiteral( "LAYER: %1 checked=%2 expanded=%3 id=%4\n" ).arg( name() ).arg( mChecked ).arg( mExpanded ).arg( layerId() );
137 }
138 
140 {
141  return new QgsLayerTreeLayer( *this );
142 }
143 
144 void QgsLayerTreeLayer::registryLayersAdded( const QList<QgsMapLayer*>& layers )
145 {
146  Q_FOREACH ( QgsMapLayer* l, layers )
147  {
148  if ( l->id() == mLayerId )
149  {
150  disconnect( QgsProject::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( registryLayersAdded( QList<QgsMapLayer*> ) ) );
151  attachToLayer();
152  emit layerLoaded();
153  break;
154  }
155  }
156 }
157 
158 void QgsLayerTreeLayer::registryLayersWillBeRemoved( const QStringList& layerIds )
159 {
160  if ( layerIds.contains( mLayerId ) )
161  {
162  emit layerWillBeUnloaded();
163 
164  // stop listening to removal signals and start hoping that the layer may be added again
165  disconnect( QgsProject::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( registryLayersWillBeRemoved( QStringList ) ) );
166  connect( QgsProject::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( registryLayersAdded( QList<QgsMapLayer*> ) ) );
167 
168  mLayer = nullptr;
169  }
170 }
171 
173 {
174  Q_ASSERT( mLayer );
175  emit nameChanged( this, mLayer->name() );
176 }
Base class for all map layer types.
Definition: qgsmaplayer.h:50
QgsMapLayer * mapLayer(const QString &theLayerId) const
Retrieve a pointer to a registered layer by layer ID.
bool mExpanded
whether the node should be shown in GUI as expanded
bool isExpanded() const
Return whether the node should be shown as expanded or collapsed in GUI.
void layerLoaded()
emitted when a previously unavailable layer got loaded
void registryLayersWillBeRemoved(const QStringList &layerIds)
QString layerId() const
QgsMapLayer * mLayer
void layerNameChanged()
Emits a nameChanged() signal if layer&#39;s name has changed.
QString name() const override
Get layer&#39;s name.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
void writeCommonXml(QDomElement &element)
Write common XML elements.
static QgsLayerTreeLayer * readXml(QDomElement &element)
This class is a base class for nodes in a layer tree.
static Qt::CheckState checkStateFromXml(const QString &txt)
Convert QString to Qt::CheckState.
void setName(const QString &name)
Set the display name of the layer.
void setName(const QString &n) override
Set layer&#39;s name.
void setExpanded(bool expanded)
Set whether the node should be shown as expanded or collapsed in GUI.
QgsMapLayer * layer() const
Leaf node pointing to a layer.
void readCommonXml(QDomElement &element)
Read common XML elements.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:350
void layerWillBeUnloaded()
emitted when a previously available layer got unloaded (from layer registry)
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
QString name
Read property of QString layerName.
Definition: qgsmaplayer.h:54
virtual QString dump() const override
Return string with layer tree structure. For debug purposes only.
void registryLayersAdded(const QList< QgsMapLayer *> &layers)
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
virtual void writeXml(QDomElement &parentElement) override
Write layer tree to XML.
virtual QgsLayerTreeLayer * clone() const override
Create a copy of the node. Returns new instance.
Layer tree node points to a map layer.
QgsLayerTreeLayer(QgsMapLayer *layer)