QGIS API Documentation  3.20.0-Odense (decaadbb31)
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 
23 #include "qgsmaplayer.h"
24 #include "qgsdataprovider.h"
25 #include "qgsproject.h"
26 #include <utility>
27 
33 template<typename TYPE>
34 struct _LayerRef
35 {
36 
41  enum MatchType
42  {
43  Name = 1 << 2,
44  Provider = 1 << 3,
45  Source = 1 << 4,
46  All = Provider | Source
47  };
48 
49 
55  _LayerRef( TYPE *l = nullptr )
56  : layer( l )
57  , layerId( l ? l->id() : QString() )
58  , source( l ? l->publicSource() : QString() )
59  , name( l ? l->name() : QString() )
60  , provider( l && l->dataProvider() ? l->dataProvider()->name() : QString() )
61  {}
62 
67  _LayerRef( const QString &id, const QString &name = QString(), const QString &source = QString(), const QString &provider = QString() )
68  : layer()
69  , layerId( id )
70  , source( source )
71  , name( name )
72  , provider( provider )
73  {}
74 
78  void setLayer( TYPE *l )
79  {
80  layer = l;
81  layerId = l ? l->id() : QString();
82  source = l ? l->publicSource() : QString();
83  name = l ? l->name() : QString();
84  provider = l && l->dataProvider() ? l->dataProvider()->name() : QString();
85  }
86 
91  operator bool() const
92  {
93  return static_cast< bool >( layer.data() );
94  }
95 
99  TYPE *operator->() const
100  {
101  return layer.data();
102  }
103 
108  TYPE *get() const
109  {
110  return layer.data();
111  }
112 
114  QPointer<TYPE> layer;
115 
117  QString layerId;
118 
120  QString source;
122  QString name;
124  QString provider;
125 
132  {
133  if ( layer->publicSource() != source ||
134  layer->name() != name )
135  return false;
136 
137  if ( layer->providerType() != provider )
138  return false;
139 
140  return true;
141  }
142 
150  TYPE *resolve( const QgsProject *project )
151  {
152  if ( project && !layerId.isEmpty() )
153  {
154  if ( TYPE *l = qobject_cast<TYPE *>( project->mapLayer( layerId ) ) )
155  {
156  setLayer( l );
157  return l;
158  }
159  }
160  return nullptr;
161  }
162 
163  bool layerMatchesWeakly( QgsMapLayer *layer, MatchType matchType = MatchType::All )
164  {
165  // First match the name
166  if ( matchType & MatchType::Name && ( layer->name().isEmpty() || layer->name() != name ) )
167  {
168  return false;
169  }
170  else
171  {
172  // We have found a match by name, now check the other
173  // criteria
174  if ( matchType & MatchType::Provider && layer->providerType() != provider )
175  {
176  return false;
177  }
178  if ( matchType & MatchType::Source && layer->publicSource() != source )
179  {
180  return false;
181  }
182  // All tests passed
183  return true;
184  }
185  }
186 
211  TYPE *resolveWeakly( const QgsProject *project, MatchType matchType = MatchType::All )
212  {
213  // first try matching by layer ID
214  if ( resolve( project ) )
215  return layer;
216 
217  if ( project )
218  {
219  QList<QgsMapLayer *> layers;
220  // If matching by name ...
221  if ( matchType & MatchType::Name )
222  {
223  if ( name.isEmpty() )
224  {
225  return nullptr;
226  }
227  layers = project->mapLayersByName( name );
228  }
229  else // ... we need all layers
230  {
231  layers = project->mapLayers().values();
232  }
233  for ( auto it = layers.constBegin(); it != layers.constEnd(); ++it )
234  {
235  if ( TYPE *tl = qobject_cast< TYPE *>( *it ) )
236  {
237  if ( layerMatchesWeakly( tl, matchType ) )
238  {
239  setLayer( tl );
240  return tl;
241  }
242  }
243  }
244  }
245  return nullptr;
246  }
247 
270  TYPE *resolveByIdOrNameOnly( const QgsProject *project )
271  {
272  // first try by matching by layer ID, or weakly by source, name and provider
273  if ( resolveWeakly( project ) )
274  return layer;
275 
276  // fallback to checking by name only
277  if ( project && !name.isEmpty() )
278  {
279  const QList<QgsMapLayer *> layers = project->mapLayersByName( name );
280  for ( QgsMapLayer *l : layers )
281  {
282  if ( TYPE *tl = qobject_cast< TYPE *>( l ) )
283  {
284  setLayer( tl );
285  return tl;
286  }
287  }
288  }
289  return nullptr;
290  }
291 
292 
293 };
294 
296 
297 #endif // QGSMAPLAYERREF_H
Base class for all map layer types.
Definition: qgsmaplayer.h:70
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:99
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.
_LayerRef< QgsMapLayer > QgsMapLayerRef
Internal structure to keep weak pointer to QgsMapLayer or layerId if the layer is not available yet.
TYPE * resolveByIdOrNameOnly(const QgsProject *project)
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.
QString source
Weak reference to layer public source.
QString name
Weak reference to layer name.
TYPE * operator->() const
Forwards the to map layer.
TYPE * get() const
Returns a pointer to the layer, or nullptr if the reference has not yet been matched to a layer.
TYPE * resolve(const QgsProject *project)
Resolves the map layer by attempting to find a layer with matching ID within a project.
bool layerMatchesWeakly(QgsMapLayer *layer, MatchType matchType=MatchType::All)
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...
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.
void setLayer(TYPE *l)
Sets the reference to point to a specified layer.
QString layerId
Original layer ID.