6
6
class QGSReader :
7
7
"""QGSReader class
8
8
9
- Read QGIS 2.18 projects and extract data for QWC config.
9
+ Read QGIS 2.18 or 3.x projects and extract data for QWC config.
10
10
"""
11
11
12
12
def __init__ (self , logger ):
@@ -16,6 +16,7 @@ def __init__(self, logger):
16
16
"""
17
17
self .logger = logger
18
18
self .root = None
19
+ self .qgis_version = 0
19
20
20
21
# get path to QGIS projects from ENV
21
22
self .qgs_resources_path = os .environ .get ('QGIS_RESOURCES_PATH' , 'qgs/' )
@@ -39,6 +40,13 @@ def read(self, qgs_path):
39
40
self .logger .warn ("'%s' is not a QGS file" % qgs_path )
40
41
return False
41
42
43
+ # extract QGIS version
44
+ version = self .root .get ('version' )
45
+ major , minor , rev = [
46
+ int (v ) for v in version .split ('-' )[0 ].split ('.' )
47
+ ]
48
+ self .qgis_version = major * 10000 + minor * 100 + rev
49
+
42
50
except Exception as e :
43
51
self .logger .error (e )
44
52
return False
@@ -172,9 +180,8 @@ def attributes_metadata(self, maplayer):
172
180
aliases = maplayer .find ('aliases' )
173
181
for alias in aliases .findall ('alias' ):
174
182
field = alias .get ('field' )
175
- edittype = maplayer .find ("edittypes/edittype[@name='%s']" % field )
176
183
177
- if edittype . get ( 'widgetv2type' ) == 'Hidden' :
184
+ if self . field_hidden ( maplayer , field ) :
178
185
# skip hidden fields
179
186
continue
180
187
@@ -187,7 +194,7 @@ def attributes_metadata(self, maplayer):
187
194
fields [field ]['alias' ] = name
188
195
189
196
# get any constraints from edit widgets
190
- constraints = self .edit_widget_constraints (edittype )
197
+ constraints = self .edit_widget_constraints (maplayer , field )
191
198
if constraints :
192
199
fields [field ]['constraints' ] = constraints
193
200
@@ -196,18 +203,32 @@ def attributes_metadata(self, maplayer):
196
203
'fields' : fields
197
204
}
198
205
199
- def edit_widget_constraints (self , edittype ):
206
+ def edit_widget_constraints (self , maplayer , field ):
200
207
"""Get any constraints from edit widget config.
201
208
202
- :param Element edittype: QGS edittype node
209
+ :param Element maplayer: QGS maplayer node
210
+ :param str field: Field name
211
+ """
212
+ if self .qgis_version > 30000 :
213
+ return self .edit_widget_constraints_v3 (maplayer , field )
214
+ else :
215
+ return self .edit_widget_constraints_v2 (maplayer , field )
216
+
217
+ def edit_widget_constraints_v2 (self , maplayer , field ):
218
+ """Get any constraints from edit widget config (QGIS 2.18).
219
+
220
+ :param Element maplayer: QGS maplayer node
221
+ :param str field: Field name
203
222
"""
204
223
constraints = {}
205
224
225
+ edittype = maplayer .find ("edittypes/edittype[@name='%s']" % field )
206
226
widget_config = edittype .find ('widgetv2config' )
207
227
if widget_config .get ('fieldEditable' ) == '0' :
208
228
constraints ['readonly' ] = True
209
229
210
- if widget_config .get ('notNull' ) == '1' :
230
+ if (not constraints .get ('readonly' , False ) and
231
+ widget_config .get ('notNull' ) == '1' ):
211
232
constraints ['required' ] = True
212
233
213
234
constraint_desc = widget_config .get ('constraintDescription' , '' )
@@ -218,7 +239,7 @@ def edit_widget_constraints(self, edittype):
218
239
constraints .update ({
219
240
'min' : widget_config .get ('Min' ),
220
241
'max' : widget_config .get ('Max' ),
221
- 'step' : widget_config .get ('Step' ),
242
+ 'step' : widget_config .get ('Step' )
222
243
})
223
244
elif edittype .get ('widgetv2type' ) == 'ValueMap' :
224
245
values = []
@@ -232,3 +253,74 @@ def edit_widget_constraints(self, edittype):
232
253
constraints ['values' ] = values
233
254
234
255
return constraints
256
+
257
+ def edit_widget_constraints_v3 (self , maplayer , field ):
258
+ """Get any constraints from edit widget config (QGIS 3.x).
259
+
260
+ :param Element maplayer: QGS maplayer node
261
+ :param str field: Field name
262
+ """
263
+ constraints = {}
264
+
265
+ # NOTE: <editable /> is empty if Attributes Form is not configured
266
+ editable_field = maplayer .find ("editable/field[@name='%s']" % field )
267
+ if (editable_field is not None and
268
+ editable_field .get ('editable' ) == '0' ):
269
+ constraints ['readonly' ] = True
270
+
271
+ if not constraints .get ('readonly' , False ):
272
+ # ConstraintNotNull = 1
273
+ constraints ['required' ] = int (
274
+ maplayer .find ("constraints/constraint[@field='%s']" % field )
275
+ .get ('constraints' )
276
+ ) & 1 > 0
277
+
278
+ constraint_desc = maplayer .find (
279
+ "constraintExpressions/constraint[@field='%s']" % field
280
+ ).get ('desc' )
281
+ if len (constraint_desc ) > 0 :
282
+ constraints ['placeholder' ] = constraint_desc
283
+
284
+ edit_widget = maplayer .find (
285
+ "fieldConfiguration/field[@name='%s']/editWidget" % field
286
+ )
287
+
288
+ if edit_widget .get ('type' ) == 'Range' :
289
+ constraints .update ({
290
+ 'min' : edit_widget .find (
291
+ "config/Option/Option[@name='Min']" ).get ('value' ),
292
+ 'max' : edit_widget .find (
293
+ "config/Option/Option[@name='Max']" ).get ('value' ),
294
+ 'step' : edit_widget .find (
295
+ "config/Option/Option[@name='Step']" ).get ('value' )
296
+ })
297
+ elif edit_widget .get ('type' ) == 'ValueMap' :
298
+ values = []
299
+ for option_map in edit_widget .findall (
300
+ "config/Option/Option[@type='List']/Option"
301
+ ):
302
+ option = option_map .find ("Option" )
303
+ values .append ({
304
+ 'label' : option .get ('name' ),
305
+ 'value' : option .get ('value' )
306
+ })
307
+
308
+ if values :
309
+ constraints ['values' ] = values
310
+
311
+ return constraints
312
+
313
+ def field_hidden (self , maplayer , field ):
314
+ """Return whether field is hidden.
315
+
316
+ :param Element maplayer: QGS maplayer node
317
+ :param str field: Field name
318
+ """
319
+ if self .qgis_version > 30000 :
320
+ edit_widget = maplayer .find (
321
+ "fieldConfiguration/field[@name='%s']/editWidget" % field
322
+ )
323
+ return edit_widget .get ('type' ) == 'Hidden'
324
+ else :
325
+ edittype = maplayer .find ("edittypes/edittype[@name='%s']" % field )
326
+ return edittype .get ('widgetv2type' ) == 'Hidden'
0 commit comments