@@ -5,6 +5,89 @@ typedef qint64 QgsFeatureId;
5
5
typedef QMap<int, QVariant> QgsAttributeMap;
6
6
7
7
typedef QVector<QVariant> QgsAttributes;
8
+ // QgsAttributes is implemented as a Python list of Python objects.
9
+ %MappedType QgsAttributes /DocType="list-of-attributes"/
10
+ {
11
+ %TypeHeaderCode
12
+ #include <qvector.h>
13
+ %End
14
+
15
+ %ConvertFromTypeCode
16
+ // Create the list.
17
+ PyObject *l;
18
+
19
+ if ((l = PyList_New(sipCpp->size())) == NULL)
20
+ return NULL;
21
+
22
+ // Set the list elements.
23
+ for (int i = 0; i < sipCpp->size(); ++i)
24
+ {
25
+ const QVariant& v = sipCpp->at(i);
26
+ PyObject *tobj;
27
+
28
+ if ( v.isNull() )
29
+ {
30
+ tobj = Py_None;
31
+ }
32
+ else if ((tobj = sipConvertFromType(&v, sipType_QVariant,Py_None)) == NULL)
33
+ {
34
+ return NULL;
35
+ }
36
+
37
+ PyList_SET_ITEM(l, i, tobj);
38
+ }
39
+
40
+ return l;
41
+ %End
42
+
43
+ %ConvertToTypeCode
44
+ // Check the type if that is all that is required.
45
+ if (sipIsErr == NULL)
46
+ {
47
+ if (!PyList_Check(sipPy))
48
+ return 0;
49
+
50
+ for (SIP_SSIZE_T i = 0; i < PyList_GET_SIZE(sipPy); ++i)
51
+ if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i), sipType_QVariant, SIP_NOT_NONE))
52
+ return 0;
53
+
54
+ return 1;
55
+ }
56
+
57
+ QVector<QVariant> *qv = new QVector<QVariant>;
58
+
59
+ for (SIP_SSIZE_T i = 0; i < PyList_GET_SIZE(sipPy); ++i)
60
+ {
61
+ int state;
62
+ PyObject* obj = PyList_GET_ITEM(sipPy, i);
63
+ QVariant *t;
64
+ if ( obj == Py_None )
65
+ {
66
+ t = new QVariant( QVariant::Int );
67
+ }
68
+ else
69
+ {
70
+ t = reinterpret_cast<QVariant *>(sipConvertToType(obj, sipType_QVariant, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr));
71
+
72
+ if (*sipIsErr)
73
+ {
74
+ sipReleaseType(t, sipType_QVariant, state);
75
+
76
+ delete qv;
77
+ return 0;
78
+ }
79
+ }
80
+
81
+ qv->append(*t);
82
+
83
+ sipReleaseType(t, sipType_QVariant, state);
84
+ }
85
+
86
+ *sipCppPtr = qv;
87
+
88
+ return sipGetState(sipTransferObj);
89
+ %End
90
+ };
8
91
9
92
// key = feature id, value = changed attributes
10
93
typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
@@ -38,13 +121,19 @@ class QgsFeature
38
121
39
122
if (fieldIdx >= 0)
40
123
{
41
- QVariant* v = new QVariant( sipCpp->attribute(fieldIdx) );
42
- sipRes = sipConvertFromInstance(v, sipClass_QVariant, Py_None);
124
+ const QVariant& v = sipCpp->attribute(fieldIdx);
125
+ if ( v.isNull() )
126
+ sipRes = Py_None;
127
+ else
128
+ sipRes = sipConvertFromInstance( &v, sipClass_QVariant, Py_None );
43
129
}
44
130
else if( altfieldIdx >= 0 )
45
131
{
46
- QVariant* v = new QVariant( sipCpp->attribute(altfieldIdx) );
47
- sipRes = sipConvertFromInstance(v, sipClass_QVariant, Py_None);
132
+ const QVariant& v = sipCpp->attribute(altfieldIdx);
133
+ if ( v.isNull() )
134
+ sipRes = Py_None;
135
+ else
136
+ sipRes = sipConvertFromInstance( &v, sipClass_QVariant, Py_None );
48
137
}
49
138
else
50
139
{
@@ -53,33 +142,50 @@ class QgsFeature
53
142
}
54
143
%End
55
144
56
- void __setattr__(const QString& key, QVariant value);
145
+ void __setattr__(const QString& key, QVariant value /GetWrapper/ );
57
146
%MethodCode
58
147
int fieldIdx = sipCpp->fieldNameIndex(*a0);
59
148
QString altname = QString(*a0).replace("_"," ");
60
149
int altfieldIdx = sipCpp->fieldNameIndex(altname);
61
150
62
151
if (fieldIdx >= 0)
63
152
{
153
+ if ( a1Wrapper == Py_None )
154
+ {
155
+ sipCpp->setAttribute(fieldIdx, QVariant( QVariant::Int ) );
156
+ }
157
+ else
158
+ {
64
159
sipCpp->setAttribute(fieldIdx, *a1);
160
+ }
65
161
}
66
162
else if( altfieldIdx >= 0 )
67
163
{
164
+ if ( a1Wrapper == Py_None )
165
+ {
166
+ sipCpp->setAttribute(altfieldIdx, QVariant( QVariant::Int ) );
167
+ }
168
+ else
169
+ {
68
170
sipCpp->setAttribute(altfieldIdx, *a1);
171
+ }
69
172
}
70
173
else
71
174
{
72
- PyObject* key = PyString_FromString(a0->toStdString().c_str());
73
- PyObject* value = sipConvertFromType( a1, sipType_QVariant, sipSelf);
74
- PyObject_GenericSetAttr(sipSelf, key, value);
175
+ PyObject* key = PyString_FromString(a0->toStdString().c_str());
176
+ PyObject* value = sipConvertFromType( a1, sipType_QVariant, sipSelf);
177
+ PyObject_GenericSetAttr(sipSelf, key, value);
75
178
}
76
179
%End
77
180
78
181
void __delattr__(const QString& key);
79
182
%MethodCode
80
183
int fieldIdx = sipCpp->fieldNameIndex(*a0);
81
184
if (fieldIdx == -1)
185
+ {
82
186
PyErr_SetString(PyExc_KeyError, a0->toAscii());
187
+ sipIsErr = 1;
188
+ }
83
189
else
84
190
sipCpp->deleteAttribute(fieldIdx);
85
191
%End
@@ -88,39 +194,76 @@ class QgsFeature
88
194
%MethodCode
89
195
const QgsAttributes& attrs = sipCpp->attributes();
90
196
if (a0 < 0 || a0 >= attrs.count())
197
+ {
91
198
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
199
+ sipIsErr = 1;
200
+ }
92
201
else
93
202
{
94
- QVariant* v = new QVariant(attrs[a0]);
95
- sipRes = sipConvertFromInstance(v, sipClass_QVariant, Py_None);
203
+ const QVariant& v = attrs[a0];
204
+ if ( v.isNull() )
205
+ sipRes = Py_None;
206
+ else
207
+ sipRes = sipConvertFromInstance( &v, sipClass_QVariant, Py_None );
96
208
}
97
209
%End
98
210
99
211
SIP_PYOBJECT __getitem__(const QString& name);
100
212
%MethodCode
101
213
int fieldIdx = sipCpp->fieldNameIndex(*a0);
102
214
if (fieldIdx == -1)
215
+ {
103
216
PyErr_SetString(PyExc_KeyError, a0->toAscii());
217
+ sipIsErr = 1;
218
+ }
104
219
else
105
220
{
106
- QVariant* v = new QVariant( sipCpp->attribute(fieldIdx) );
107
- sipRes = sipConvertFromInstance(v, sipClass_QVariant, Py_None);
221
+ const QVariant& v = sipCpp->attribute(fieldIdx);
222
+ if ( v.isNull() )
223
+ sipRes = Py_None;
224
+ else
225
+ sipRes = sipConvertFromInstance( &v, sipClass_QVariant, Py_None );
108
226
}
109
227
%End
110
228
111
- void __setitem__(int key, QVariant value);
229
+ void __setitem__(int key, QVariant value /GetWrapper/ );
112
230
%MethodCode
113
- sipCpp->setAttribute(a0, *a1);
231
+ bool rv;
232
+
233
+ if ( a1Wrapper == Py_None )
234
+ {
235
+ rv = sipCpp->setAttribute(a0, QVariant( QVariant::Int ) );
236
+ }
237
+ else
238
+ {
239
+ rv = sipCpp->setAttribute(a0, *a1);
240
+ }
241
+
242
+ if ( !rv )
243
+ {
244
+ PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
245
+ sipIsErr = 1;
246
+ }
114
247
%End
115
248
116
- void __setitem__(const QString& key, QVariant value);
249
+ void __setitem__(const QString& key, QVariant value /GetWrapper/ );
117
250
%MethodCode
118
251
int fieldIdx = sipCpp->fieldNameIndex(*a0);
119
252
if (fieldIdx == -1)
253
+ {
120
254
PyErr_SetString(PyExc_KeyError, a0->toAscii());
255
+ sipIsErr = 1;
256
+ }
121
257
else
122
258
{
123
- sipCpp->setAttribute(fieldIdx, *a1);
259
+ if ( a1Wrapper == Py_None )
260
+ {
261
+ sipCpp->setAttribute(a0, QVariant( QVariant::Int ) );
262
+ }
263
+ else
264
+ {
265
+ sipCpp->setAttribute(fieldIdx, *a1);
266
+ }
124
267
}
125
268
%End
126
269
@@ -129,14 +272,20 @@ class QgsFeature
129
272
if (a0 >= 0 && a0 < sipCpp->attributes().count())
130
273
sipCpp->deleteAttribute(a0);
131
274
else
275
+ {
132
276
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
277
+ sipIsErr = 1;
278
+ }
133
279
%End
134
280
135
281
void __delitem__(const QString& name);
136
282
%MethodCode
137
283
int fieldIdx = sipCpp->fieldNameIndex(*a0);
138
284
if (fieldIdx == -1)
285
+ {
139
286
PyErr_SetString(PyExc_KeyError, a0->toAscii());
287
+ sipIsErr = 1;
288
+ }
140
289
else
141
290
sipCpp->deleteAttribute(fieldIdx);
142
291
%End
@@ -167,12 +316,39 @@ class QgsFeature
167
316
const QgsAttributes& attributes() const;
168
317
//QgsAttributes& attributes();
169
318
void setAttributes(const QgsAttributes& attrs);
170
- bool setAttribute( int field, const QVariant& attr );
319
+ bool setAttribute( int field, const QVariant& attr /GetWrapper/);
320
+ %MethodCode
321
+ bool rv;
322
+
323
+ if ( a1Wrapper == Py_None )
324
+ {
325
+ rv = sipCpp->setAttribute(a0, QVariant( QVariant::Int ) );
326
+ }
327
+ else
328
+ {
329
+ rv = sipCpp->setAttribute(a0, *a1);
330
+ }
331
+
332
+ if ( !rv )
333
+ {
334
+ PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
335
+ sipIsErr = 1;
336
+ }
337
+ %End
338
+
171
339
void initAttributes( int fieldCount );
172
340
173
341
/**Deletes an attribute and its value*/
174
342
void deleteAttribute( int field );
175
-
343
+ %MethodCode
344
+ if ( a0 >= 0 && a0 < sipCpp->attributes().count() )
345
+ sipCpp->deleteAttribute(a0);
346
+ else
347
+ {
348
+ PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
349
+ sipIsErr = 1;
350
+ }
351
+ %End
176
352
/**
177
353
* Return the validity of this feature. This is normally set by
178
354
* the provider to indicate some problem that makes the feature
@@ -229,24 +405,71 @@ class QgsFeature
229
405
*/
230
406
const QgsFields* fields() const;
231
407
232
- /** Insert a value into attribute. Returns false if attribute name could not be converted to index.
408
+ /** Insert a value into attribute.
409
+ * Raises a KeyError exception if the attribute name is not found
233
410
* Field map must be associated to make this work.
234
411
* @note added in 2.0
235
412
*/
236
- bool setAttribute( const QString& name, QVariant value );
237
-
238
- /** Remove an attribute value. Returns false if attribute name could not be converted to index.
413
+ void setAttribute( const QString& name, QVariant value /GetWrapper/ );
414
+ %MethodCode
415
+ int fieldIdx = sipCpp->fieldNameIndex(*a0);
416
+ if (fieldIdx == -1)
417
+ {
418
+ PyErr_SetString(PyExc_KeyError, a0->toAscii());
419
+ sipIsErr = 1;
420
+ }
421
+ else
422
+ {
423
+ if ( a1Wrapper == Py_None )
424
+ {
425
+ sipCpp->setAttribute(a0, QVariant( QVariant::Int ) );
426
+ }
427
+ else
428
+ {
429
+ sipCpp->setAttribute(fieldIdx, *a1);
430
+ }
431
+ }
432
+ %End
433
+ /** Remove an attribute value.
434
+ * Raises a KeyError exception if the attribute name is not found
239
435
* Field map must be associated to make this work.
240
436
* @note added in 2.0
241
437
*/
242
- bool deleteAttribute( const QString& name );
243
-
244
- /** Lookup attribute value from attribute name. Returns invalid variant if attribute name could not be converted to index.
438
+ void deleteAttribute( const QString& name );
439
+ %MethodCode
440
+ int fieldIdx = sipCpp->fieldNameIndex(*a0);
441
+ if (fieldIdx == -1)
442
+ {
443
+ PyErr_SetString(PyExc_KeyError, a0->toAscii());
444
+ sipIsErr = 1;
445
+ }
446
+ else
447
+ {
448
+ sipCpp->deleteAttribute( fieldIdx );
449
+ }
450
+ %End
451
+ /** Lookup attribute value from attribute name.
452
+ * Raises a KeyError exception if the attribute is not found
245
453
* Field map must be associated to make this work.
246
454
* @note added in 2.0
247
455
*/
248
- QVariant attribute( const QString& name ) const;
249
-
456
+ SIP_PYOBJECT attribute( const QString& name ) const;
457
+ %MethodCode
458
+ int fieldIdx = sipCpp->fieldNameIndex(*a0);
459
+ if (fieldIdx == -1)
460
+ {
461
+ PyErr_SetString(PyExc_KeyError, a0->toAscii());
462
+ sipIsErr = 1;
463
+ }
464
+ else
465
+ {
466
+ const QVariant& v = sipCpp->attribute(fieldIdx);
467
+ if ( v.isNull() )
468
+ sipRes = Py_None;
469
+ else
470
+ sipRes = sipConvertFromInstance( &v, sipClass_QVariant, Py_None );
471
+ }
472
+ %End
250
473
/** Utility method to get attribute index from name. Returns -1 if field does not exist or field map is not associated.
251
474
* Field map must be associated to make this work.
252
475
* @note added in 2.0
0 commit comments