Skip to content
This repository was archived by the owner on Oct 24, 2023. It is now read-only.

Commit f1ffc1e

Browse files
committed
support QGIS 3 projects for edit config
1 parent ccfdd47 commit f1ffc1e

File tree

1 file changed

+100
-8
lines changed

1 file changed

+100
-8
lines changed

qgs_reader.py

Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class QGSReader:
77
"""QGSReader class
88
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.
1010
"""
1111

1212
def __init__(self, logger):
@@ -16,6 +16,7 @@ def __init__(self, logger):
1616
"""
1717
self.logger = logger
1818
self.root = None
19+
self.qgis_version = 0
1920

2021
# get path to QGIS projects from ENV
2122
self.qgs_resources_path = os.environ.get('QGIS_RESOURCES_PATH', 'qgs/')
@@ -39,6 +40,13 @@ def read(self, qgs_path):
3940
self.logger.warn("'%s' is not a QGS file" % qgs_path)
4041
return False
4142

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+
4250
except Exception as e:
4351
self.logger.error(e)
4452
return False
@@ -172,9 +180,8 @@ def attributes_metadata(self, maplayer):
172180
aliases = maplayer.find('aliases')
173181
for alias in aliases.findall('alias'):
174182
field = alias.get('field')
175-
edittype = maplayer.find("edittypes/edittype[@name='%s']" % field)
176183

177-
if edittype.get('widgetv2type') == 'Hidden':
184+
if self.field_hidden(maplayer, field):
178185
# skip hidden fields
179186
continue
180187

@@ -187,7 +194,7 @@ def attributes_metadata(self, maplayer):
187194
fields[field]['alias'] = name
188195

189196
# get any constraints from edit widgets
190-
constraints = self.edit_widget_constraints(edittype)
197+
constraints = self.edit_widget_constraints(maplayer, field)
191198
if constraints:
192199
fields[field]['constraints'] = constraints
193200

@@ -196,18 +203,32 @@ def attributes_metadata(self, maplayer):
196203
'fields': fields
197204
}
198205

199-
def edit_widget_constraints(self, edittype):
206+
def edit_widget_constraints(self, maplayer, field):
200207
"""Get any constraints from edit widget config.
201208
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
203222
"""
204223
constraints = {}
205224

225+
edittype = maplayer.find("edittypes/edittype[@name='%s']" % field)
206226
widget_config = edittype.find('widgetv2config')
207227
if widget_config.get('fieldEditable') == '0':
208228
constraints['readonly'] = True
209229

210-
if widget_config.get('notNull') == '1':
230+
if (not constraints.get('readonly', False) and
231+
widget_config.get('notNull') == '1'):
211232
constraints['required'] = True
212233

213234
constraint_desc = widget_config.get('constraintDescription', '')
@@ -218,7 +239,7 @@ def edit_widget_constraints(self, edittype):
218239
constraints.update({
219240
'min': widget_config.get('Min'),
220241
'max': widget_config.get('Max'),
221-
'step': widget_config.get('Step'),
242+
'step': widget_config.get('Step')
222243
})
223244
elif edittype.get('widgetv2type') == 'ValueMap':
224245
values = []
@@ -232,3 +253,74 @@ def edit_widget_constraints(self, edittype):
232253
constraints['values'] = values
233254

234255
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

Comments
 (0)