QGIS API Documentation  3.6.0-Noosa (5873452)
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  , mRef( layer )
26  , mLayerName( layer->name() )
27 {
28  attachToLayer();
29 }
30 
31 QgsLayerTreeLayer::QgsLayerTreeLayer( const QString &layerId, const QString &name, const QString &source, const QString &provider )
32  : QgsLayerTreeNode( NodeLayer, true )
33  , mRef( layerId, name, source, provider )
34  , mLayerName( name.isEmpty() ? QStringLiteral( "(?)" ) : name )
35 {
36 }
37 
39  : QgsLayerTreeNode( other )
40  , mRef( other.mRef )
41  , mLayerName( other.mLayerName )
42 {
43  attachToLayer();
44 }
45 
46 void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool looseMatching )
47 {
48  if ( mRef )
49  return; // already assigned
50 
51  if ( !looseMatching )
52  {
53  mRef.resolve( project );
54  }
55  else
56  {
57  mRef.resolveWeakly( project );
58  }
59 
60  if ( !mRef )
61  return;
62 
63  attachToLayer();
64  emit layerLoaded();
65 }
66 
68 {
69  if ( !mRef )
70  return;
71 
72  connect( mRef.layer, &QgsMapLayer::nameChanged, this, &QgsLayerTreeLayer::layerNameChanged );
73  connect( mRef.layer, &QgsMapLayer::willBeDeleted, this, &QgsLayerTreeLayer::layerWillBeDeleted );
74 }
75 
76 
77 QString QgsLayerTreeLayer::name() const
78 {
79  return mRef ? mRef->name() : mLayerName;
80 }
81 
82 void QgsLayerTreeLayer::setName( const QString &n )
83 {
84  if ( mRef )
85  {
86  if ( mRef->name() == n )
87  return;
88  mRef->setName( n );
89  // no need to emit signal: we will be notified from layer's nameChanged() signal
90  }
91  else
92  {
93  if ( mLayerName == n )
94  return;
95  mLayerName = n;
96  emit nameChanged( this, n );
97  }
98 }
99 
100 QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsReadWriteContext &context )
101 {
102  if ( element.tagName() != QLatin1String( "layer-tree-layer" ) )
103  return nullptr;
104 
105  QString layerID = element.attribute( QStringLiteral( "id" ) );
106  QString layerName = element.attribute( QStringLiteral( "name" ) );
107 
108  QString providerKey = element.attribute( QStringLiteral( "providerKey" ) );
109  QString source = context.pathResolver().readPath( element.attribute( QStringLiteral( "source" ) ) );
110 
111  Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( QStringLiteral( "checked" ) ) );
112  bool isExpanded = ( element.attribute( QStringLiteral( "expanded" ), QStringLiteral( "1" ) ) == QLatin1String( "1" ) );
113 
114  // needs to have the layer reference resolved later
115  QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layerID, layerName, source, providerKey );
116 
117  nodeLayer->readCommonXml( element );
118 
119  nodeLayer->setItemVisibilityChecked( checked != Qt::Unchecked );
120  nodeLayer->setExpanded( isExpanded );
121  return nodeLayer;
122 }
123 
124 QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
125 {
126  QgsLayerTreeLayer *node = readXml( element, context );
127  if ( node )
128  node->resolveReferences( project );
129  return node;
130 }
131 
132 void QgsLayerTreeLayer::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
133 {
134  QDomDocument doc = parentElement.ownerDocument();
135  QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-layer" ) );
136  elem.setAttribute( QStringLiteral( "id" ), layerId() );
137  elem.setAttribute( QStringLiteral( "name" ), name() );
138 
139  if ( mRef )
140  {
141  elem.setAttribute( QStringLiteral( "source" ), context.pathResolver().writePath( mRef->publicSource() ) );
142  elem.setAttribute( QStringLiteral( "providerKey" ), mRef->dataProvider() ? mRef->dataProvider()->name() : QString() );
143  }
144 
145  elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) );
146  elem.setAttribute( QStringLiteral( "expanded" ), mExpanded ? "1" : "0" );
147 
148  writeCommonXml( elem );
149 
150  parentElement.appendChild( elem );
151 }
152 
153 QString QgsLayerTreeLayer::dump() const
154 {
155  return QStringLiteral( "LAYER: %1 checked=%2 expanded=%3 id=%4\n" ).arg( name() ).arg( mChecked ).arg( mExpanded ).arg( layerId() );
156 }
157 
159 {
160  return new QgsLayerTreeLayer( *this );
161 }
162 
163 void QgsLayerTreeLayer::layerWillBeDeleted()
164 {
165  Q_ASSERT( mRef );
166 
167  emit layerWillBeUnloaded();
168 
169  mLayerName = mRef->name();
170  // in theory we do not even need to do this - the weak ref should clear itself
171  mRef.layer.clear();
172  // layerId stays in the reference
173 
174 }
175 
176 
177 void QgsLayerTreeLayer::layerNameChanged()
178 {
179  Q_ASSERT( mRef );
180  emit nameChanged( this, mRef->name() );
181 }
The class is used as a container of context for various read/write operations on other objects...
Base class for all map layer types.
Definition: qgsmaplayer.h:64
virtual QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be null.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
bool mExpanded
whether the node should be shown in GUI as expanded
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
TYPE * resolveWeakly(const QgsProject *project)
Resolves the map layer by attempting to find a matching layer in a project using a weak match...
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
void layerLoaded()
Emitted when a previously unavailable layer got loaded.
QString layerId() const
Returns the ID for the map layer associated with this node.
virtual QString name() const =0
Returns a provider name.
QgsMapLayerRef mRef
Weak reference to the layer (or just it's ID if the reference is not resolved yet) ...
QString mLayerName
Layer name - only used if layer does not exist.
QString name() const override
Returns the layer's name.
void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context) override
Write layer tree to XML.
QPointer< TYPE > layer
Weak pointer to map layer.
void nameChanged()
Emitted when the name has been changed.
void writeCommonXml(QDomElement &element)
Write common XML elements.
This class is a base class for nodes in a layer tree.
static Qt::CheckState checkStateFromXml(const QString &txt)
Convert QString to Qt::CheckState.
Reads and writes project states.
Definition: qgsproject.h:89
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example...
void setName(const QString &name)
Set the display name of the layer.
void setName(const QString &n) override
Sets the layer&#39;s name.
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
Leaf node pointing to a layer.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
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 readCommonXml(QDomElement &element)
Read common XML elements.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
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
Definition: qgsmaplayer.h:68
QString dump() const override
Returns string with layer tree structure. For debug purposes only.
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
TYPE * resolve(const QgsProject *project)
Resolves the map layer by attempting to find a layer with matching ID within a project.
static QgsLayerTreeLayer * readXml(QDomElement &element, const QgsReadWriteContext &context)
Read layer node from XML.
QgsLayerTreeLayer * clone() const override
Create a copy of the node. Returns new instance.
Layer tree node points to a map layer.
QgsLayerTreeLayer(QgsMapLayer *layer)