-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
qgsmaplayerref.h
193 lines (171 loc) · 5.38 KB
/
qgsmaplayerref.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/***************************************************************************
qgsmaplayerref.h
--------------------------------------
Date : January 2017
Copyright : (C) 2017 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSMAPLAYERREF_H
#define QGSMAPLAYERREF_H
#define SIP_NO_FILE
#include <QPointer>
#include "qgsmaplayer.h"
#include "qgsdataprovider.h"
#include "qgsproject.h"
/**
* Internal structure to keep weak pointer to QgsMapLayer or layerId
* if the layer is not available yet.
* \note not available in Python bindings
*/
template<typename TYPE>
struct _LayerRef
{
/**
* Constructor for a layer reference from an existing map layer.
* The layerId, source, name and provider members will automatically
* be populated from this layer.
*/
_LayerRef( TYPE *l = nullptr )
: layer( l )
, layerId( l ? l->id() : QString() )
, source( l ? l->publicSource() : QString() )
, name( l ? l->name() : QString() )
, provider( l && l->dataProvider() ? l->dataProvider()->name() : QString() )
{}
/**
* Constructor for a weak layer reference, using a combination of layer ID,
* \a name, public \a source and \a provider key.
*/
_LayerRef( const QString &id, const QString &name = QString(), const QString &source = QString(), const QString &provider = QString() )
: layer()
, layerId( id )
, source( source )
, name( name )
, provider( provider )
{}
/**
* Sets the reference to point to a specified layer.
*/
void setLayer( TYPE *l )
{
layer = l;
layerId = l ? l->id() : QString();
source = l ? l->publicSource() : QString();
name = l ? l->name() : QString();
provider = l && l->dataProvider() ? l->dataProvider()->name() : QString();
}
/**
* Returns true if the layer reference is resolved and contains a reference to an existing
* map layer.
*/
operator bool() const
{
return static_cast< bool >( layer.data() );
}
/**
* Forwards the to map layer.
*/
TYPE *operator->() const
{
return layer.data();
}
/**
* Returns a pointer to the layer, or nullptr if the reference has not yet been matched
* to a layer.
*/
TYPE *get() const
{
return layer.data();
}
//! Weak pointer to map layer
QPointer<TYPE> layer;
//! Original layer ID
QString layerId;
//! Weak reference to layer public source
QString source;
//! Weak reference to layer name
QString name;
//! Weak reference to layer provider
QString provider;
/**
* Returns true if a layer matches the weak references to layer public source,
* layer name and data provider contained in this layer reference.
* \see resolveWeakly()
*/
bool layerMatchesSource( QgsMapLayer *layer ) const
{
if ( layer->publicSource() != source ||
layer->name() != name )
return false;
if ( layer->dataProvider()->name() != provider )
return false;
return true;
}
/**
* Resolves the map layer by attempting to find a layer with matching ID
* within a \a project. If found, this reference will be updated to match
* the found layer and the layer will be returned. If no matching layer is
* found, a nullptr is returned.
* \see resolveWeakly()
*/
TYPE *resolve( const QgsProject *project )
{
if ( project && !layerId.isEmpty() )
{
if ( TYPE *l = qobject_cast<TYPE *>( project->mapLayer( layerId ) ) )
{
setLayer( l );
return l;
}
}
return nullptr;
}
/**
* Resolves the map layer by attempting to find a matching layer
* in a \a project using a weak match.
*
* First, the layer is attempted to match to project layers using the
* layer's ID (calling this method implicitly calls resolve()).
*
* Failing a match by layer ID, the layer will be matched by using
* the weak references to layer public source, layer name and data
* provider contained in this layer reference.
*
* If a matching layer is found, this reference will be updated to match
* the found layer and the layer will be returned. If no matching layer is
* found, a nullptr is returned.
* \see resolve()
* \see layerMatchesSource()
*/
TYPE *resolveWeakly( const QgsProject *project )
{
// first try matching by layer ID
if ( resolve( project ) )
return layer;
if ( project && !name.isEmpty() )
{
const QList<QgsMapLayer *> layers = project->mapLayersByName( name );
for ( QgsMapLayer *l : layers )
{
if ( TYPE *tl = qobject_cast< TYPE *>( l ) )
{
if ( layerMatchesSource( tl ) )
{
setLayer( tl );
return tl;
}
}
}
}
return nullptr;
}
};
typedef _LayerRef<QgsMapLayer> QgsMapLayerRef;
#endif // QGSMAPLAYERREF_H