Mercurial > libervia-backend
comparison src/tools/xml_tools.py @ 2398:3ff9d7a7fe71
core (XMLUI): filters can now be used when converting data form to XMLUI:
they can be used to modify created widgets, this is specially useful to customise well known field.
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 27 Oct 2017 18:06:58 +0200 |
parents | 7fff98d64ab5 |
children | f4b6176eb65f |
comparison
equal
deleted
inserted
replaced
2397:7fff98d64ab5 | 2398:3ff9d7a7fe71 |
---|---|
100 widget_kwargs["name"] = field.var | 100 widget_kwargs["name"] = field.var |
101 | 101 |
102 return widget_type, widget_args, widget_kwargs | 102 return widget_type, widget_args, widget_kwargs |
103 | 103 |
104 | 104 |
105 def dataForm2Widgets(form_ui, form, read_only=False, prepend=None): | 105 def dataForm2Widgets(form_ui, form, read_only=False, prepend=None, filters=None): |
106 """Complete an existing XMLUI with widget converted from XEP-0004 data forms. | 106 """Complete an existing XMLUI with widget converted from XEP-0004 data forms. |
107 | 107 |
108 @param form_ui (XMLUI): XMLUI instance | 108 @param form_ui (XMLUI): XMLUI instance |
109 @param form (data_form.Form): Wokkel's implementation of data form | 109 @param form (data_form.Form): Wokkel's implementation of data form |
110 @param read_only (bool): if True and it makes sense, create a read only input widget | 110 @param read_only (bool): if True and it makes sense, create a read only input widget |
111 @param prepend(iterable, None): widgets to prepend to main LabelContainer | 111 @param prepend(iterable, None): widgets to prepend to main LabelContainer |
112 if not None, must be an iterable of *args for addWidget. Those widgets will | 112 if not None, must be an iterable of *args for addWidget. Those widgets will |
113 be added first to the container. | 113 be added first to the container. |
114 @param filters(dict, None): if not None, a dictionary of callable: | |
115 key is the name of the widget to filter | |
116 the value is a callable, it will get widget's type, args and kwargs | |
117 and must return the same variable, which it can modify | |
118 This is especially useful to modify well known fields | |
114 @return: the completed XMLUI instance | 119 @return: the completed XMLUI instance |
115 """ | 120 """ |
116 if form.instructions: | 121 if form.instructions: |
117 form_ui.addText('\n'.join(form.instructions), 'instructions') | 122 form_ui.addText('\n'.join(form.instructions), 'instructions') |
118 | 123 |
122 for widget_args in prepend: | 127 for widget_args in prepend: |
123 form_ui.addWidget(*widget_args) | 128 form_ui.addWidget(*widget_args) |
124 | 129 |
125 for field in form.fieldList: | 130 for field in form.fieldList: |
126 widget_type, widget_args, widget_kwargs = _dataFormField2XMLUIData(field, read_only) | 131 widget_type, widget_args, widget_kwargs = _dataFormField2XMLUIData(field, read_only) |
132 try: | |
133 widget_filter = filters[widget_kwargs['name']] | |
134 except KeyError: | |
135 pass | |
136 else: | |
137 widget_type, widget_args, widget_kwargs = widget_filter(widget_type, widget_args, widget_kwargs) | |
127 label = field.label or field.var | 138 label = field.label or field.var |
128 if label: | 139 if label: |
129 form_ui.addLabel(label) | 140 form_ui.addLabel(label) |
130 else: | 141 else: |
131 form_ui.addEmpty() | 142 form_ui.addEmpty() |
233 except exceptions.DataError: | 244 except exceptions.DataError: |
234 parsed_form = data_form.Form.fromElement(form_elt) | 245 parsed_form = data_form.Form.fromElement(form_elt) |
235 dataForm2Widgets(xml_ui, parsed_form, read_only=True) | 246 dataForm2Widgets(xml_ui, parsed_form, read_only=True) |
236 return xml_ui | 247 return xml_ui |
237 | 248 |
238 def dataFormResult2XMLUI(result_form, base_form, session_id=None, prepend=None): | 249 def dataFormResult2XMLUI(result_form, base_form, session_id=None, prepend=None, filters=None): |
239 """Convert data form result to SàT XMLUI. | 250 """Convert data form result to SàT XMLUI. |
240 | 251 |
241 @param result_form (data_form.Form): result form to convert | 252 @param result_form (data_form.Form): result form to convert |
242 @param base_form (data_form.Form): initial form (i.e. of form type "form") | 253 @param base_form (data_form.Form): initial form (i.e. of form type "form") |
243 this one is necessary to reconstruct options when needed (e.g. list elements) | 254 this one is necessary to reconstruct options when needed (e.g. list elements) |
244 @param session_id (unicode): session id to return with the data | 255 @param session_id (unicode): session id to return with the data |
245 @param prepend: same as for [dataForm2Widgets] | 256 @param prepend: same as for [dataForm2Widgets] |
257 @param filters: same as for [dataForm2Widgets] | |
246 @return: XMLUI instance | 258 @return: XMLUI instance |
247 """ | 259 """ |
248 form = deepcopy(result_form) | 260 form = deepcopy(result_form) |
249 for name, field in form.fields.iteritems(): | 261 for name, field in form.fields.iteritems(): |
250 try: | 262 try: |
251 base_field = base_form.fields[name] | 263 base_field = base_form.fields[name] |
252 except KeyError: | 264 except KeyError: |
253 continue | 265 continue |
254 field.options = base_field.options[:] | 266 field.options = base_field.options[:] |
255 xml_ui = XMLUI("window", "vertical", session_id=session_id) | 267 xml_ui = XMLUI("window", "vertical", session_id=session_id) |
256 dataForm2Widgets(xml_ui, form, read_only=True, prepend=prepend) | 268 dataForm2Widgets(xml_ui, form, read_only=True, prepend=prepend, filters=filters) |
257 return xml_ui | 269 return xml_ui |
258 | 270 |
259 | 271 |
260 def _cleanValue(value): | 272 def _cleanValue(value): |
261 """Workaround method to avoid DBus types with D-Bus bridge. | 273 """Workaround method to avoid DBus types with D-Bus bridge. |
758 """ | 770 """ |
759 self.elem = xmlui.doc.createElement('widget') | 771 self.elem = xmlui.doc.createElement('widget') |
760 super(Widget, self).__init__(xmlui, parent) | 772 super(Widget, self).__init__(xmlui, parent) |
761 if name: | 773 if name: |
762 self.elem.setAttribute('name', name) | 774 self.elem.setAttribute('name', name) |
775 if name in xmlui.named_widgets: | |
776 raise exceptions.ConflictError(_(u'A widget with the name "{name}" already exists.').format(name=name)) | |
777 xmlui.named_widgets[name] = self | |
763 self.elem.setAttribute('type', self.type) | 778 self.elem.setAttribute('type', self.type) |
764 | 779 |
765 def setInternalCallback(self, callback, fields, data_elts=None): | 780 def setInternalCallback(self, callback, fields, data_elts=None): |
766 """Set an internal UI callback when the widget value is changed. | 781 """Set an internal UI callback when the widget value is changed. |
767 | 782 |
1126 - C.XMLUI_DATA_FILETYPE_DEFAULT: same as C.XMLUI_DATA_FILETYPE_FILE | 1141 - C.XMLUI_DATA_FILETYPE_DEFAULT: same as C.XMLUI_DATA_FILETYPE_FILE |
1127 | 1142 |
1128 @param title: title or default if None | 1143 @param title: title or default if None |
1129 @param submit_id: callback id to call for panel_type we can submit (form, param, dialog) | 1144 @param submit_id: callback id to call for panel_type we can submit (form, param, dialog) |
1130 @param session_id: use to keep a session attached to the dialog, must be returned by frontends | 1145 @param session_id: use to keep a session attached to the dialog, must be returned by frontends |
1146 @attribute named_widgets(dict): map from name to widget | |
1131 """ | 1147 """ |
1132 self._introspect() # FIXME: why doing that on each XMLUI ? should be done once | 1148 self._introspect() # FIXME: why doing that on each XMLUI ? should be done once |
1133 if panel_type not in [C.XMLUI_WINDOW, C.XMLUI_FORM, C.XMLUI_PARAM, C.XMLUI_POPUP, C.XMLUI_DIALOG]: | 1149 if panel_type not in [C.XMLUI_WINDOW, C.XMLUI_FORM, C.XMLUI_PARAM, C.XMLUI_POPUP, C.XMLUI_DIALOG]: |
1134 raise exceptions.DataError(_("Unknown panel type [%s]") % panel_type) | 1150 raise exceptions.DataError(_("Unknown panel type [%s]") % panel_type) |
1135 if panel_type == C.XMLUI_FORM and submit_id is None: | 1151 if panel_type == C.XMLUI_FORM and submit_id is None: |
1153 dialog_opt = {} | 1169 dialog_opt = {} |
1154 self._createDialog(dialog_opt) | 1170 self._createDialog(dialog_opt) |
1155 return | 1171 return |
1156 self.main_container = self._createContainer(container, TopElement(self)) | 1172 self.main_container = self._createContainer(container, TopElement(self)) |
1157 self.current_container = self.main_container | 1173 self.current_container = self.main_container |
1174 self.named_widgets = {} | |
1158 | 1175 |
1159 def _introspect(self): | 1176 def _introspect(self): |
1160 """ Introspect module to find Widgets and Containers """ | 1177 """ Introspect module to find Widgets and Containers """ |
1161 self._containers = {} | 1178 self._containers = {} |
1162 self._widgets = {} | 1179 self._widgets = {} |