Mercurial > libervia-backend
annotate sat/tools/common/template_xmlui.py @ 4036:c4464d7ae97b
dpc (cli/info): update "disco" documentation to include new "external services":
fix 418
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 07 Apr 2023 15:18:39 +0200 |
parents | 185601bc0cd3 |
children | 524856bd7b19 |
rev | line source |
---|---|
3028 | 1 #!/usr/bin/env python3 |
3137 | 2 |
2362 | 3 |
4 # SAT: a jabber client | |
3479 | 5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
2362 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 """ template XMLUI parsing | |
21 | |
22 XMLUI classes from this modules can then be iterated to create the template | |
23 """ | |
24 | |
3271
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
25 from functools import partial |
2362 | 26 from sat.core.log import getLogger |
27 from sat_frontends.tools import xmlui | |
3271
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
28 from sat_frontends.tools import jid |
2783
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
29 try: |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
30 from jinja2 import Markup as safe |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
31 except ImportError: |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
32 # Safe marks XHTML values as usable as it. |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
33 # If jinja2 is not there, we can use a simple lamba |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
34 safe = lambda x: x |
2362 | 35 |
36 | |
3271
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
37 log = getLogger(__name__) |
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
38 |
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
39 |
2362 | 40 ## Widgets ## |
41 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
42 |
2362 | 43 class Widget(object): |
3028 | 44 category = "widget" |
2362 | 45 type = None |
46 enabled = True | |
47 read_only = True | |
48 | |
49 def __init__(self, xmlui_parent): | |
50 self.xmlui_parent = xmlui_parent | |
51 | |
52 @property | |
53 def name(self): | |
54 return self._xmlui_name | |
55 | |
56 | |
57 class ValueWidget(Widget): | |
58 def __init__(self, xmlui_parent, value): | |
59 super(ValueWidget, self).__init__(xmlui_parent) | |
60 self.value = value | |
61 | |
2367
9878635586f3
template (xmlui): added values property to be able to use always values even when there is only one value
Goffi <goffi@goffi.org>
parents:
2362
diff
changeset
|
62 @property |
9878635586f3
template (xmlui): added values property to be able to use always values even when there is only one value
Goffi <goffi@goffi.org>
parents:
2362
diff
changeset
|
63 def values(self): |
9878635586f3
template (xmlui): added values property to be able to use always values even when there is only one value
Goffi <goffi@goffi.org>
parents:
2362
diff
changeset
|
64 return [self.value] |
9878635586f3
template (xmlui): added values property to be able to use always values even when there is only one value
Goffi <goffi@goffi.org>
parents:
2362
diff
changeset
|
65 |
2455
7b02372f8734
template (xmlui): added labels property in ValueWidget (actually return values) and values property in OptionsWidget
Goffi <goffi@goffi.org>
parents:
2435
diff
changeset
|
66 @property |
7b02372f8734
template (xmlui): added labels property in ValueWidget (actually return values) and values property in OptionsWidget
Goffi <goffi@goffi.org>
parents:
2435
diff
changeset
|
67 def labels(self): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
68 # helper property, there is not label for ValueWidget |
2455
7b02372f8734
template (xmlui): added labels property in ValueWidget (actually return values) and values property in OptionsWidget
Goffi <goffi@goffi.org>
parents:
2435
diff
changeset
|
69 # but using labels make rendering more easy (one single method to call) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
70 # values are actually returned |
2455
7b02372f8734
template (xmlui): added labels property in ValueWidget (actually return values) and values property in OptionsWidget
Goffi <goffi@goffi.org>
parents:
2435
diff
changeset
|
71 return [self.value] |
7b02372f8734
template (xmlui): added labels property in ValueWidget (actually return values) and values property in OptionsWidget
Goffi <goffi@goffi.org>
parents:
2435
diff
changeset
|
72 |
2362 | 73 |
74 class InputWidget(ValueWidget): | |
75 def __init__(self, xmlui_parent, value, read_only=False): | |
76 super(InputWidget, self).__init__(xmlui_parent, value) | |
77 self.read_only = read_only | |
78 | |
79 | |
80 class OptionsWidget(Widget): | |
81 def __init__(self, xmlui_parent, options, selected, style): | |
82 super(OptionsWidget, self).__init__(xmlui_parent) | |
83 self.options = options | |
84 self.selected = selected | |
85 self.style = style | |
86 | |
2379
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
87 @property |
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
88 def values(self): |
2455
7b02372f8734
template (xmlui): added labels property in ValueWidget (actually return values) and values property in OptionsWidget
Goffi <goffi@goffi.org>
parents:
2435
diff
changeset
|
89 for value, label in self.items: |
7b02372f8734
template (xmlui): added labels property in ValueWidget (actually return values) and values property in OptionsWidget
Goffi <goffi@goffi.org>
parents:
2435
diff
changeset
|
90 yield value |
2379
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
91 |
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
92 @property |
3546
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
93 def value(self): |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
94 if self.multi or self.no_select or len(self.selected) != 1: |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
95 raise ValueError( |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
96 "Can't get value for list with multiple selections or nothing selected" |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
97 ) |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
98 return self.selected[0] |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
99 |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
100 @property |
2379
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
101 def labels(self): |
2400
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
102 """return only labels from self.items""" |
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
103 for value, label in self.items: |
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
104 yield label |
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
105 |
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
106 @property |
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
107 def items(self): |
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
108 """return suitable items, according to style""" |
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
109 no_select = self.no_select |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
110 for value, label in self.options: |
2400
8253ea069781
template(XMLUI): added items property to ListWidget:
Goffi <goffi@goffi.org>
parents:
2397
diff
changeset
|
111 if no_select or value in self.selected: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
112 yield value, label |
2379
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
113 |
2397
7fff98d64ab5
core (XMLUI), template(XMLUI): added flags to ListWidget:
Goffi <goffi@goffi.org>
parents:
2379
diff
changeset
|
114 @property |
7fff98d64ab5
core (XMLUI), template(XMLUI): added flags to ListWidget:
Goffi <goffi@goffi.org>
parents:
2379
diff
changeset
|
115 def inline(self): |
3028 | 116 return "inline" in self.style |
2397
7fff98d64ab5
core (XMLUI), template(XMLUI): added flags to ListWidget:
Goffi <goffi@goffi.org>
parents:
2379
diff
changeset
|
117 |
7fff98d64ab5
core (XMLUI), template(XMLUI): added flags to ListWidget:
Goffi <goffi@goffi.org>
parents:
2379
diff
changeset
|
118 @property |
7fff98d64ab5
core (XMLUI), template(XMLUI): added flags to ListWidget:
Goffi <goffi@goffi.org>
parents:
2379
diff
changeset
|
119 def no_select(self): |
3028 | 120 return "noselect" in self.style |
2397
7fff98d64ab5
core (XMLUI), template(XMLUI): added flags to ListWidget:
Goffi <goffi@goffi.org>
parents:
2379
diff
changeset
|
121 |
3546
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
122 @property |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
123 def multi(self): |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
124 return "multi" in self.style |
185601bc0cd3
tools (common/template_xmlui: add `multi` and `value` propertied to OptionsWidget
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
125 |
2362 | 126 |
127 class EmptyWidget(xmlui.EmptyWidget, Widget): | |
128 def __init__(self, _xmlui_parent): | |
129 Widget.__init__(self) | |
130 | |
131 | |
132 class TextWidget(xmlui.TextWidget, ValueWidget): | |
3028 | 133 type = "text" |
2362 | 134 |
135 | |
3271
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
136 class JidWidget(xmlui.JidWidget, ValueWidget): |
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
137 type = "jid" |
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
138 |
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
139 def __init__(self, xmlui_parent, value): |
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
140 self.value = jid.JID(value) |
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
141 |
abca25af06d7
plugin pubsub schema, tools (common/template xmlui): use a JID for publisher:
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
142 |
2362 | 143 class LabelWidget(xmlui.LabelWidget, ValueWidget): |
3028 | 144 type = "label" |
2362 | 145 |
2379
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
146 @property |
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
147 def for_name(self): |
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
148 try: |
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
149 return self._xmlui_for_name |
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
150 except AttributeError: |
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
151 return None |
2362 | 152 |
2379
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
153 |
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
154 class StringWidget(xmlui.StringWidget, InputWidget): |
3028 | 155 type = "string" |
2362 | 156 |
157 | |
2435
49884c579266
template (XMLUI): added JidInputWidget
Goffi <goffi@goffi.org>
parents:
2419
diff
changeset
|
158 class JidInputWidget(xmlui.JidInputWidget, StringWidget): |
3028 | 159 type = "jid" |
2435
49884c579266
template (XMLUI): added JidInputWidget
Goffi <goffi@goffi.org>
parents:
2419
diff
changeset
|
160 |
2379
42a54cbc1872
template (xmlui): new properties + inheritance fix:
Goffi <goffi@goffi.org>
parents:
2367
diff
changeset
|
161 class TextBoxWidget(xmlui.TextWidget, InputWidget): |
3028 | 162 type = "textbox" |
2362 | 163 |
164 | |
2783
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
165 class XHTMLBoxWidget(xmlui.XHTMLBoxWidget, InputWidget): |
3028 | 166 type = "xhtmlbox" |
2783
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
167 |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
168 def __init__(self, xmlui_parent, value, read_only=False): |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
169 # XXX: XHTMLBoxWidget value must be cleaned (harmful XHTML must be removed) |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
170 # This is normally done in the backend, the frontends should not need to |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
171 # worry about it. |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
172 super(XHTMLBoxWidget, self).__init__( |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
173 xmlui_parent=xmlui_parent, value=safe(value), read_only=read_only) |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
174 |
442ab697f831
frontends, jp, templates: added XHTMLBox widget:
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
175 |
2362 | 176 class ListWidget(xmlui.ListWidget, OptionsWidget): |
3028 | 177 type = "list" |
2362 | 178 |
179 | |
180 ## Containers ## | |
181 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
182 |
2362 | 183 class Container(object): |
3028 | 184 category = "container" |
2362 | 185 type = None |
186 | |
187 def __init__(self, xmlui_parent): | |
188 self.xmlui_parent = xmlui_parent | |
189 self.children = [] | |
190 | |
191 def __iter__(self): | |
192 return iter(self.children) | |
193 | |
194 def _xmluiAppend(self, widget): | |
195 self.children.append(widget) | |
196 | |
2419
c38c54c47e16
frontends (xmlui): added an attribute to ignore some widgets (and their label) in create
Goffi <goffi@goffi.org>
parents:
2414
diff
changeset
|
197 def _xmluiRemove(self, widget): |
c38c54c47e16
frontends (xmlui): added an attribute to ignore some widgets (and their label) in create
Goffi <goffi@goffi.org>
parents:
2414
diff
changeset
|
198 self.children.remove(widget) |
c38c54c47e16
frontends (xmlui): added an attribute to ignore some widgets (and their label) in create
Goffi <goffi@goffi.org>
parents:
2414
diff
changeset
|
199 |
2362 | 200 |
201 class VerticalContainer(xmlui.VerticalContainer, Container): | |
3028 | 202 type = "vertical" |
2362 | 203 |
204 | |
205 class PairsContainer(xmlui.PairsContainer, Container): | |
3028 | 206 type = "pairs" |
2362 | 207 |
208 | |
209 class LabelContainer(xmlui.PairsContainer, Container): | |
3028 | 210 type = "label" |
2362 | 211 |
212 | |
213 ## Factory ## | |
214 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
215 |
2362 | 216 class WidgetFactory(object): |
2669
bdb8276fd2da
frontends (xmlui): class_map is now an arg of create function:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
217 |
2362 | 218 def __getattr__(self, attr): |
219 if attr.startswith("create"): | |
220 cls = globals()[attr[6:]] | |
221 return cls | |
222 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
223 |
2362 | 224 ## Core ## |
225 | |
226 | |
227 class XMLUIPanel(xmlui.XMLUIPanel): | |
228 widget_factory = WidgetFactory() | |
229 | |
230 def show(self, *args, **kwargs): | |
231 raise NotImplementedError | |
232 | |
233 | |
234 class XMLUIDialog(xmlui.XMLUIDialog): | |
235 dialog_factory = WidgetFactory() | |
236 | |
237 def __init__(*args, **kwargs): | |
238 raise NotImplementedError | |
239 | |
240 | |
2669
bdb8276fd2da
frontends (xmlui): class_map is now an arg of create function:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
241 create = partial(xmlui.create, class_map={ |
bdb8276fd2da
frontends (xmlui): class_map is now an arg of create function:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
242 xmlui.CLASS_PANEL: XMLUIPanel, |
bdb8276fd2da
frontends (xmlui): class_map is now an arg of create function:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
243 xmlui.CLASS_DIALOG: XMLUIDialog}) |