QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsmaplayerref.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaplayerref.h
3 --------------------------------------
4 Date : January 2017
5 Copyright : (C) 2017 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#ifndef QGSMAPLAYERREF_H
17#define QGSMAPLAYERREF_H
18
19#define SIP_NO_FILE
20
21#include <QPointer>
22#include <QDomElement>
23
24#include "qgsmaplayer.h"
25#include "qgsdataprovider.h"
26#include "qgsproject.h"
27#include <utility>
28
34template<typename TYPE>
36{
37
43 {
44 Name = 1 << 2,
45 Provider = 1 << 3,
46 Source = 1 << 4,
48 };
49
50
56 _LayerRef( TYPE *l = nullptr )
57 : layer( l )
58 , layerId( l ? l->id() : QString() )
59 , source( l ? l->publicSource() : QString() )
60 , name( l ? l->name() : QString() )
61 , provider( l && l->dataProvider() ? l->dataProvider()->name() : QString() )
62 {}
63
68 _LayerRef( const QString &id, const QString &name = QString(), const QString &source = QString(), const QString &provider = QString() )
69 : layer()
70 , layerId( id )
71 , source( source )
72 , name( name )
74 {}
75
79 void setLayer( TYPE *l )
80 {
81 layer = l;
82 layerId = l ? l->id() : QString();
83 source = l ? l->publicSource() : QString();
84 name = l ? l->name() : QString();
85 provider = l && l->dataProvider() ? l->dataProvider()->name() : QString();
86 }
87
92 operator bool() const
93 {
94 return static_cast< bool >( layer.data() );
95 }
96
100 TYPE *operator->() const
101 {
102 return layer.data();
103 }
104
109 TYPE *get() const
110 {
111 return layer.data();
112 }
113
115 QPointer<TYPE> layer;
116
118 QString layerId;
119
121 QString source;
123 QString name;
125 QString provider;
126
133 {
134 if ( layer->publicSource() != source ||
135 layer->name() != name )
136 return false;
137
138 if ( layer->providerType() != provider )
139 return false;
140
141 return true;
142 }
143
151 TYPE *resolve( const QgsProject *project )
152 {
153 if ( project && !layerId.isEmpty() )
154 {
155 if ( TYPE *l = qobject_cast<TYPE *>( project->mapLayer( layerId ) ) )
156 {
157 setLayer( l );
158 return l;
159 }
160 }
161 return nullptr;
162 }
163
164 bool layerMatchesWeakly( QgsMapLayer *layer, MatchType matchType = MatchType::All ) const
165 {
166 // First match the name
167 if ( matchType & MatchType::Name && ( layer->name().isEmpty() || layer->name() != name ) )
168 {
169 return false;
170 }
171 else
172 {
173 // We have found a match by name, now check the other
174 // criteria
175 if ( matchType & MatchType::Provider && layer->providerType() != provider )
176 {
177 return false;
178 }
179 if ( matchType & MatchType::Source && layer->publicSource() != source )
180 {
181 return false;
182 }
183 // All tests passed
184 return true;
185 }
186 }
187
212 TYPE *resolveWeakly( const QgsProject *project, MatchType matchType = MatchType::All )
213 {
214 // first try matching by layer ID
215 if ( resolve( project ) )
216 return layer;
217
218 if ( project )
219 {
220 QList<QgsMapLayer *> layers;
221 // If matching by name ...
222 if ( matchType & MatchType::Name )
223 {
224 if ( name.isEmpty() )
225 {
226 return nullptr;
227 }
228 layers = project->mapLayersByName( name );
229 }
230 else // ... we need all layers
231 {
232 layers = project->mapLayers().values();
233 }
234 for ( auto it = layers.constBegin(); it != layers.constEnd(); ++it )
235 {
236 if ( TYPE *tl = qobject_cast< TYPE *>( *it ) )
237 {
238 if ( layerMatchesWeakly( tl, matchType ) )
239 {
240 setLayer( tl );
241 return tl;
242 }
243 }
244 }
245 }
246 return nullptr;
247 }
248
271 TYPE *resolveByIdOrNameOnly( const QgsProject *project )
272 {
273 // first try by matching by layer ID, or weakly by source, name and provider
274 if ( resolveWeakly( project ) )
275 return layer;
276
277 // fallback to checking by name only
278 if ( project && !name.isEmpty() )
279 {
280 const QList<QgsMapLayer *> layers = project->mapLayersByName( name );
281 for ( QgsMapLayer *l : layers )
282 {
283 if ( TYPE *tl = qobject_cast< TYPE *>( l ) )
284 {
285 setLayer( tl );
286 return tl;
287 }
288 }
289 }
290 return nullptr;
291 }
292
299 bool readXml( const QDomElement &element, const QgsReadWriteContext &context )
300 {
301 Q_UNUSED( context )
302
303 layerId = element.attribute( QStringLiteral( "id" ) );
304 name = element.attribute( QStringLiteral( "name" ) );
305 source = element.attribute( QStringLiteral( "source" ) );
306 provider = element.attribute( QStringLiteral( "provider" ) );
307 return true;
308 }
309
316 void writeXml( QDomElement &element, const QgsReadWriteContext &context ) const
317 {
318 Q_UNUSED( context )
319
320 element.setAttribute( QStringLiteral( "id" ), layerId );
321 element.setAttribute( QStringLiteral( "name" ), name );
322 element.setAttribute( QStringLiteral( "source" ), source );
323 element.setAttribute( QStringLiteral( "provider" ), provider );
324 }
325
326};
327
329
330#endif // QGSMAPLAYERREF_H
Base class for all map layer types.
Definition: qgsmaplayer.h:75
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:107
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
The class is used as a container of context for various read/write operations on other objects.
_LayerRef< QgsMapLayer > QgsMapLayerRef
Internal structure to keep weak pointer to QgsMapLayer or layerId if the layer is not available yet.
TYPE * operator->() const
Forwards the to map layer.
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.
_LayerRef(const QString &id, const QString &name=QString(), const QString &source=QString(), const QString &provider=QString())
Constructor for a weak layer reference, using a combination of layer ID, name, public source and prov...
_LayerRef(TYPE *l=nullptr)
Constructor for a layer reference from an existing map layer.
MatchType
Flag for match type in weak resolution.
@ All
Match layer source.
@ Provider
Match layer name.
@ Source
Match layer provider name.
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes the layer's properties to a XML element.
QString source
Weak reference to layer public source.
QString name
Weak reference to layer name.
bool layerMatchesWeakly(QgsMapLayer *layer, MatchType matchType=MatchType::All) const
TYPE * resolveByIdOrNameOnly(const QgsProject *project)
Resolves the map layer by attempting to find a matching layer in a project using a weak match.
TYPE * get() const
Returns a pointer to the layer, or nullptr if the reference has not yet been matched to a layer.
QString provider
Weak reference to layer provider.
bool layerMatchesSource(QgsMapLayer *layer) const
Returns true if a layer matches the weak references to layer public source, layer name and data provi...
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.
void setLayer(TYPE *l)
Sets the reference to point to a specified layer.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the layer's properties from an XML element.
QString layerId
Original layer ID.