comparison sat_frontends/jp/xmlui_manager.py @ 2669:bdb8276fd2da

frontends (xmlui): class_map is now an arg of create function: class_map was so far used as a global value, but in some cases, several XMLUI managers may be used (it's the case in Cagou's remote controllers plugins, template_xmlui is used to manage remotes). This patch set class_map as a create argument, this way it can be set with partial, and several XMLUI managers can be instanced at the same time.
author Goffi <goffi@goffi.org>
date Fri, 31 Aug 2018 16:03:12 +0200
parents 56f94936df1e
children e8dc00f612fb
comparison
equal deleted inserted replaced
2668:c274201cea94 2669:bdb8276fd2da
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from sat.core.log import getLogger 20 from sat.core.log import getLogger
21 21
22 log = getLogger(__name__) 22 log = getLogger(__name__)
23 from sat_frontends.tools import xmlui as xmlui_manager 23 from sat_frontends.tools import xmlui as xmlui_base
24 from sat_frontends.jp.constants import Const as C 24 from sat_frontends.jp.constants import Const as C
25 from sat.tools.common.ansi import ANSI as A 25 from sat.tools.common.ansi import ANSI as A
26 from sat.core.i18n import _ 26 from sat.core.i18n import _
27 from functools import partial 27 from functools import partial
28 28
48 def root(self): 48 def root(self):
49 """retrieve main XMLUI parent class""" 49 """retrieve main XMLUI parent class"""
50 if self._root is not None: 50 if self._root is not None:
51 return self._root 51 return self._root
52 root = self 52 root = self
53 while not isinstance(root, xmlui_manager.XMLUIBase): 53 while not isinstance(root, xmlui_base.XMLUIBase):
54 root = root.xmlui_parent 54 root = root.xmlui_parent
55 self._root = root 55 self._root = root
56 return root 56 return root
57 57
58 def disp(self, *args, **kwargs): 58 def disp(self, *args, **kwargs):
171 @property 171 @property
172 def no_select(self): 172 def no_select(self):
173 return u"noselect" in self.style 173 return u"noselect" in self.style
174 174
175 175
176 class EmptyWidget(xmlui_manager.EmptyWidget, Widget): 176 class EmptyWidget(xmlui_base.EmptyWidget, Widget):
177 def __init__(self, _xmlui_parent): 177 def __init__(self, _xmlui_parent):
178 Widget.__init__(self) 178 Widget.__init__(self)
179 179
180 180
181 class TextWidget(xmlui_manager.TextWidget, ValueWidget): 181 class TextWidget(xmlui_base.TextWidget, ValueWidget):
182 type = u"text" 182 type = u"text"
183 183
184 def show(self): 184 def show(self):
185 self.host.disp(self.value) 185 self.host.disp(self.value)
186 186
187 187
188 class LabelWidget(xmlui_manager.LabelWidget, ValueWidget): 188 class LabelWidget(xmlui_base.LabelWidget, ValueWidget):
189 type = u"label" 189 type = u"label"
190 190
191 @property 191 @property
192 def for_name(self): 192 def for_name(self):
193 try: 193 try:
202 @param ansi(unicode): ansi escape code to print before label 202 @param ansi(unicode): ansi escape code to print before label
203 """ 203 """
204 self.disp(A.color(ansi, self.value), no_lf=no_lf) 204 self.disp(A.color(ansi, self.value), no_lf=no_lf)
205 205
206 206
207 class StringWidget(xmlui_manager.StringWidget, InputWidget): 207 class StringWidget(xmlui_base.StringWidget, InputWidget):
208 type = u"string" 208 type = u"string"
209 209
210 def show(self): 210 def show(self):
211 if self.read_only: 211 if self.read_only:
212 self.disp(self.value) 212 self.disp(self.value)
221 #  TODO: empty value should be possible 221 #  TODO: empty value should be possible
222 # an escape key should be used for default instead of enter with empty value 222 # an escape key should be used for default instead of enter with empty value
223 self.value = value 223 self.value = value
224 224
225 225
226 class JidInputWidget(xmlui_manager.JidInputWidget, StringWidget): 226 class JidInputWidget(xmlui_base.JidInputWidget, StringWidget):
227 type = u"jid_input" 227 type = u"jid_input"
228 228
229 229
230 class TextBoxWidget(xmlui_manager.TextWidget, StringWidget): 230 class TextBoxWidget(xmlui_base.TextWidget, StringWidget):
231 type = u"textbox" 231 type = u"textbox"
232 232
233 233
234 class ListWidget(xmlui_manager.ListWidget, OptionsWidget): 234 class ListWidget(xmlui_base.ListWidget, OptionsWidget):
235 type = u"list" 235 type = u"list"
236 # TODO: handle flags, notably multi 236 # TODO: handle flags, notably multi
237 237
238 def show(self): 238 def show(self):
239 if self.root.values_only: 239 if self.root.values_only:
275 choice = None 275 choice = None
276 self.value = self.options[choice][0] 276 self.value = self.options[choice][0]
277 self.disp("") 277 self.disp("")
278 278
279 279
280 class BoolWidget(xmlui_manager.BoolWidget, InputWidget): 280 class BoolWidget(xmlui_base.BoolWidget, InputWidget):
281 type = u"bool" 281 type = u"bool"
282 282
283 def show(self): 283 def show(self):
284 disp_true = A.color(A.FG_GREEN, u"TRUE") 284 disp_true = A.color(A.FG_GREEN, u"TRUE")
285 disp_false = A.color(A.FG_RED, u"FALSE") 285 disp_false = A.color(A.FG_RED, u"FALSE")
322 def show(self): 322 def show(self):
323 for child in self.children: 323 for child in self.children:
324 child.show() 324 child.show()
325 325
326 326
327 class VerticalContainer(xmlui_manager.VerticalContainer, Container): 327 class VerticalContainer(xmlui_base.VerticalContainer, Container):
328 type = u"vertical" 328 type = u"vertical"
329 329
330 330
331 class PairsContainer(xmlui_manager.PairsContainer, Container): 331 class PairsContainer(xmlui_base.PairsContainer, Container):
332 type = u"pairs" 332 type = u"pairs"
333 333
334 334
335 class LabelContainer(xmlui_manager.PairsContainer, Container): 335 class LabelContainer(xmlui_base.PairsContainer, Container):
336 type = u"label" 336 type = u"label"
337 337
338 def show(self): 338 def show(self):
339 for child in self.children: 339 for child in self.children:
340 no_lf = False 340 no_lf = False
375 must be overriden by subclasses 375 must be overriden by subclasses
376 """ 376 """
377 raise NotImplementedError(self.__class__) 377 raise NotImplementedError(self.__class__)
378 378
379 379
380 class NoteDialog(xmlui_manager.NoteDialog, Dialog): 380 class NoteDialog(xmlui_base.NoteDialog, Dialog):
381 def show(self): 381 def show(self):
382 # TODO: handle title and level 382 # TODO: handle title and level
383 self.disp(self.message) 383 self.disp(self.message)
384 384
385 def __init__(self, _xmlui_parent, title, message, level): 385 def __init__(self, _xmlui_parent, title, message, level):
386 Dialog.__init__(self, _xmlui_parent) 386 Dialog.__init__(self, _xmlui_parent)
387 xmlui_manager.NoteDialog.__init__(self, _xmlui_parent) 387 xmlui_base.NoteDialog.__init__(self, _xmlui_parent)
388 self.title, self.message, self.level = title, message, level 388 self.title, self.message, self.level = title, message, level
389 389
390 390
391 ## Factory ## 391 ## Factory ##
392 392
396 if attr.startswith("create"): 396 if attr.startswith("create"):
397 cls = globals()[attr[6:]] 397 cls = globals()[attr[6:]]
398 return cls 398 return cls
399 399
400 400
401 class XMLUIPanel(xmlui_manager.XMLUIPanel): 401 class XMLUIPanel(xmlui_base.XMLUIPanel):
402 widget_factory = WidgetFactory() 402 widget_factory = WidgetFactory()
403 _actions = 0 # use to keep track of bridge's launchAction calls 403 _actions = 0 # use to keep track of bridge's launchAction calls
404 read_only = False 404 read_only = False
405 values_only = False 405 values_only = False
406 workflow = None 406 workflow = None
407 _submit_cb = None 407 _submit_cb = None
408 408
409 def __init__( 409 def __init__(self, host, parsed_dom, title=None, flags=None, callback=None,
410 self, 410 ignore=None, whitelist=None, profile=None):
411 host, 411 xmlui_base.XMLUIPanel.__init__(
412 parsed_dom,
413 title=None,
414 flags=None,
415 callback=None,
416 ignore=None,
417 whitelist=None,
418 profile=None,
419 ):
420 xmlui_manager.XMLUIPanel.__init__(
421 self, 412 self,
422 host, 413 host,
423 parsed_dom, 414 parsed_dom,
424 title=title, 415 title=title,
425 flags=flags, 416 flags=flags,
498 def _launchActionCb(self, data): 489 def _launchActionCb(self, data):
499 XMLUIPanel._actions -= 1 490 XMLUIPanel._actions -= 1
500 assert XMLUIPanel._actions >= 0 491 assert XMLUIPanel._actions >= 0
501 if u"xmlui" in data: 492 if u"xmlui" in data:
502 xmlui_raw = data["xmlui"] 493 xmlui_raw = data["xmlui"]
503 xmlui = xmlui_manager.create(self.host, xmlui_raw) 494 xmlui = create(self.host, xmlui_raw)
504 xmlui.show() 495 xmlui.show()
505 if xmlui.submit_id: 496 if xmlui.submit_id:
506 xmlui.onFormSubmitted() 497 xmlui.onFormSubmitted()
507 # TODO: handle data other than XMLUI 498 # TODO: handle data other than XMLUI
508 if not XMLUIPanel._actions: 499 if not XMLUIPanel._actions:
524 exit_code=C.EXIT_BRIDGE_ERRBACK, 515 exit_code=C.EXIT_BRIDGE_ERRBACK,
525 ), 516 ),
526 ) 517 )
527 518
528 519
529 class XMLUIDialog(xmlui_manager.XMLUIDialog): 520 class XMLUIDialog(xmlui_base.XMLUIDialog):
530 type = "dialog" 521 type = "dialog"
531 dialog_factory = WidgetFactory() 522 dialog_factory = WidgetFactory()
532 read_only = False 523 read_only = False
533 524
534 def show(self, dummy=None): 525 def show(self, dummy=None):
536 527
537 def _xmluiClose(self): 528 def _xmluiClose(self):
538 pass 529 pass
539 530
540 531
541 xmlui_manager.registerClass(xmlui_manager.CLASS_PANEL, XMLUIPanel) 532 create = partial(xmlui_base.create, class_map={
542 xmlui_manager.registerClass(xmlui_manager.CLASS_DIALOG, XMLUIDialog) 533 xmlui_base.CLASS_PANEL: XMLUIPanel,
543 create = xmlui_manager.create 534 xmlui_base.CLASS_DIALOG: XMLUIDialog})