Mercurial > libervia-backend
comparison sat_frontends/jp/xmlui_manager.py @ 4037:524856bd7b19
massive refactoring to switch from camelCase to snake_case:
historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a
pre-PEP8 code, to use the same coding style as in Twisted.
However, snake_case is more readable and it's better to follow PEP8 best practices, so it
has been decided to move on full snake_case. Because Libervia has a huge codebase, this
ended with a ugly mix of camelCase and snake_case.
To fix that, this patch does a big refactoring by renaming every function and method
(including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case.
This is a massive change, and may result in some bugs.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 08 Apr 2023 13:54:42 +0200 |
parents | 53a8b50d69ca |
children | 2594e1951cf7 |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
72 | 72 |
73 must be overriden by subclasses | 73 must be overriden by subclasses |
74 """ | 74 """ |
75 raise NotImplementedError(self.__class__) | 75 raise NotImplementedError(self.__class__) |
76 | 76 |
77 def verboseName(self, elems=None, value=None): | 77 def verbose_name(self, elems=None, value=None): |
78 """add name in color to the elements | 78 """add name in color to the elements |
79 | 79 |
80 helper method to display name which can then be used to automate commands | 80 helper method to display name which can then be used to automate commands |
81 elems is only modified if verbosity is > 0 | 81 elems is only modified if verbosity is > 0 |
82 @param elems(list[unicode], None): elements to display | 82 @param elems(list[unicode], None): elements to display |
112 class InputWidget(ValueWidget): | 112 class InputWidget(ValueWidget): |
113 def __init__(self, xmlui_parent, value, read_only=False): | 113 def __init__(self, xmlui_parent, value, read_only=False): |
114 super(InputWidget, self).__init__(xmlui_parent, value) | 114 super(InputWidget, self).__init__(xmlui_parent, value) |
115 self.read_only = read_only | 115 self.read_only = read_only |
116 | 116 |
117 def _xmluiGetValue(self): | 117 def _xmlui_get_value(self): |
118 return self.value | 118 return self.value |
119 | 119 |
120 | 120 |
121 class OptionsWidget(Widget): | 121 class OptionsWidget(Widget): |
122 def __init__(self, xmlui_parent, options, selected, style): | 122 def __init__(self, xmlui_parent, options, selected, style): |
139 | 139 |
140 @value.setter | 140 @value.setter |
141 def value(self, value): | 141 def value(self, value): |
142 self.selected = [value] | 142 self.selected = [value] |
143 | 143 |
144 def _xmluiSelectValue(self, value): | 144 def _xmlui_select_value(self, value): |
145 self.value = value | 145 self.value = value |
146 | 146 |
147 def _xmluiSelectValues(self, values): | 147 def _xmlui_select_values(self, values): |
148 self.values = values | 148 self.values = values |
149 | 149 |
150 def _xmluiGetSelectedValues(self): | 150 def _xmlui_get_selected_values(self): |
151 return self.values | 151 return self.values |
152 | 152 |
153 @property | 153 @property |
154 def labels(self): | 154 def labels(self): |
155 """return only labels from self.items""" | 155 """return only labels from self.items""" |
217 async def show(self): | 217 async def show(self): |
218 if self.read_only or self.root.read_only: | 218 if self.read_only or self.root.read_only: |
219 self.disp(self.value) | 219 self.disp(self.value) |
220 else: | 220 else: |
221 elems = [] | 221 elems = [] |
222 self.verboseName(elems) | 222 self.verbose_name(elems) |
223 if self.value: | 223 if self.value: |
224 elems.append(_("(enter: {value})").format(value=self.value)) | 224 elems.append(_("(enter: {value})").format(value=self.value)) |
225 elems.extend([C.A_HEADER, "> "]) | 225 elems.extend([C.A_HEADER, "> "]) |
226 value = await self.host.ainput(A.color(*elems)) | 226 value = await self.host.ainput(A.color(*elems)) |
227 if value: | 227 if value: |
241 class TextBoxWidget(xmlui_base.TextWidget, StringWidget): | 241 class TextBoxWidget(xmlui_base.TextWidget, StringWidget): |
242 type = "textbox" | 242 type = "textbox" |
243 # TODO: use a more advanced input method | 243 # TODO: use a more advanced input method |
244 | 244 |
245 async def show(self): | 245 async def show(self): |
246 self.verboseName() | 246 self.verbose_name() |
247 if self.read_only or self.root.read_only: | 247 if self.read_only or self.root.read_only: |
248 self.disp(self.value) | 248 self.disp(self.value) |
249 else: | 249 else: |
250 if self.value: | 250 if self.value: |
251 self.disp( | 251 self.disp( |
273 | 273 |
274 async def show(self): | 274 async def show(self): |
275 # FIXME: we use bridge in a blocking way as permitted by python-dbus | 275 # FIXME: we use bridge in a blocking way as permitted by python-dbus |
276 # this only for now to make it simpler, it must be refactored | 276 # this only for now to make it simpler, it must be refactored |
277 # to use async when jp will be fully async (expected for 0.8) | 277 # to use async when jp will be fully async (expected for 0.8) |
278 self.value = await self.host.bridge.syntaxConvert( | 278 self.value = await self.host.bridge.syntax_convert( |
279 self.value, C.SYNTAX_XHTML, "markdown", False, self.host.profile | 279 self.value, C.SYNTAX_XHTML, "markdown", False, self.host.profile |
280 ) | 280 ) |
281 await super(XHTMLBoxWidget, self).show() | 281 await super(XHTMLBoxWidget, self).show() |
282 | 282 |
283 | 283 |
292 return | 292 return |
293 if not self.options: | 293 if not self.options: |
294 return | 294 return |
295 | 295 |
296 # list display | 296 # list display |
297 self.verboseName() | 297 self.verbose_name() |
298 | 298 |
299 for idx, (value, label) in enumerate(self.options): | 299 for idx, (value, label) in enumerate(self.options): |
300 elems = [] | 300 elems = [] |
301 if not self.root.read_only: | 301 if not self.root.read_only: |
302 elems.extend([C.A_SUBHEADER, str(idx), A.RESET, ": "]) | 302 elems.extend([C.A_SUBHEADER, str(idx), A.RESET, ": "]) |
303 elems.append(label) | 303 elems.append(label) |
304 self.verboseName(elems, value) | 304 self.verbose_name(elems, value) |
305 self.disp(A.color(*elems)) | 305 self.disp(A.color(*elems)) |
306 | 306 |
307 if self.root.read_only: | 307 if self.root.read_only: |
308 return | 308 return |
309 | 309 |
348 A.color(C.A_HEADER, "1: ", disp_true, A.RESET, " *" if self.value else "") | 348 A.color(C.A_HEADER, "1: ", disp_true, A.RESET, " *" if self.value else "") |
349 ) | 349 ) |
350 choice = None | 350 choice = None |
351 while choice not in ("0", "1"): | 351 while choice not in ("0", "1"): |
352 elems = [C.A_HEADER, _("your choice (0,1): ")] | 352 elems = [C.A_HEADER, _("your choice (0,1): ")] |
353 self.verboseName(elems) | 353 self.verbose_name(elems) |
354 choice = await self.host.ainput(A.color(*elems)) | 354 choice = await self.host.ainput(A.color(*elems)) |
355 self.value = bool(int(choice)) | 355 self.value = bool(int(choice)) |
356 self.disp("") | 356 self.disp("") |
357 | 357 |
358 def _xmluiGetValue(self): | 358 def _xmlui_get_value(self): |
359 return C.boolConst(self.value) | 359 return C.bool_const(self.value) |
360 | 360 |
361 ## Containers ## | 361 ## Containers ## |
362 | 362 |
363 | 363 |
364 class Container(Base): | 364 class Container(Base): |
369 self.children = [] | 369 self.children = [] |
370 | 370 |
371 def __iter__(self): | 371 def __iter__(self): |
372 return iter(self.children) | 372 return iter(self.children) |
373 | 373 |
374 def _xmluiAppend(self, widget): | 374 def _xmlui_append(self, widget): |
375 self.children.append(widget) | 375 self.children.append(widget) |
376 | 376 |
377 def _xmluiRemove(self, widget): | 377 def _xmlui_remove(self, widget): |
378 self.children.remove(widget) | 378 self.children.remove(widget) |
379 | 379 |
380 async def show(self): | 380 async def show(self): |
381 for child in self.children: | 381 for child in self.children: |
382 await child.show() | 382 await child.show() |
484 input_ = None | 484 input_ = None |
485 while input_ not in ("y", "n"): | 485 while input_ not in ("y", "n"): |
486 input_ = await self.host.ainput(f"{self.message} (y/n)? ") | 486 input_ = await self.host.ainput(f"{self.message} (y/n)? ") |
487 input_ = input_.lower() | 487 input_ = input_.lower() |
488 if input_ == "y": | 488 if input_ == "y": |
489 self._xmluiValidated() | 489 self._xmlui_validated() |
490 else: | 490 else: |
491 self._xmluiCancelled() | 491 self._xmlui_cancelled() |
492 | 492 |
493 ## Factory ## | 493 ## Factory ## |
494 | 494 |
495 | 495 |
496 class WidgetFactory(object): | 496 class WidgetFactory(object): |
500 return cls | 500 return cls |
501 | 501 |
502 | 502 |
503 class XMLUIPanel(xmlui_base.AIOXMLUIPanel): | 503 class XMLUIPanel(xmlui_base.AIOXMLUIPanel): |
504 widget_factory = WidgetFactory() | 504 widget_factory = WidgetFactory() |
505 _actions = 0 # use to keep track of bridge's launchAction calls | 505 _actions = 0 # use to keep track of bridge's action_launch calls |
506 read_only = False | 506 read_only = False |
507 values_only = False | 507 values_only = False |
508 workflow = None | 508 workflow = None |
509 _submit_cb = None | 509 _submit_cb = None |
510 | 510 |
555 if self.values_only: | 555 if self.values_only: |
556 self.read_only = True | 556 self.read_only = True |
557 if workflow: | 557 if workflow: |
558 XMLUIPanel.workflow = workflow | 558 XMLUIPanel.workflow = workflow |
559 if XMLUIPanel.workflow: | 559 if XMLUIPanel.workflow: |
560 await self.runWorkflow() | 560 await self.run_workflow() |
561 else: | 561 else: |
562 await self.main_cont.show() | 562 await self.main_cont.show() |
563 | 563 |
564 async def runWorkflow(self): | 564 async def run_workflow(self): |
565 """loop into workflow commands and execute commands | 565 """loop into workflow commands and execute commands |
566 | 566 |
567 SUBMIT will interrupt workflow (which will be continue on callback) | 567 SUBMIT will interrupt workflow (which will be continue on callback) |
568 @param workflow(list): same as [show] | 568 @param workflow(list): same as [show] |
569 """ | 569 """ |
572 try: | 572 try: |
573 cmd = workflow.pop(0) | 573 cmd = workflow.pop(0) |
574 except IndexError: | 574 except IndexError: |
575 break | 575 break |
576 if cmd == SUBMIT: | 576 if cmd == SUBMIT: |
577 await self.onFormSubmitted() | 577 await self.on_form_submitted() |
578 self.submit_id = None # avoid double submit | 578 self.submit_id = None # avoid double submit |
579 return | 579 return |
580 elif isinstance(cmd, list): | 580 elif isinstance(cmd, list): |
581 name, value = cmd | 581 name, value = cmd |
582 widget = self.widgets[name] | 582 widget = self.widgets[name] |
583 if widget.type == "bool": | 583 if widget.type == "bool": |
584 value = C.bool(value) | 584 value = C.bool(value) |
585 widget.value = value | 585 widget.value = value |
586 await self.show() | 586 await self.show() |
587 | 587 |
588 async def submitForm(self, callback=None): | 588 async def submit_form(self, callback=None): |
589 XMLUIPanel._submit_cb = callback | 589 XMLUIPanel._submit_cb = callback |
590 await self.onFormSubmitted() | 590 await self.on_form_submitted() |
591 | 591 |
592 async def onFormSubmitted(self, ignore=None): | 592 async def on_form_submitted(self, ignore=None): |
593 # self.submitted is a Q&D workaround to avoid | 593 # self.submitted is a Q&D workaround to avoid |
594 # double submit when a workflow is set | 594 # double submit when a workflow is set |
595 if self.submitted: | 595 if self.submitted: |
596 return | 596 return |
597 self.submitted = True | 597 self.submitted = True |
598 await super(XMLUIPanel, self).onFormSubmitted(ignore) | 598 await super(XMLUIPanel, self).on_form_submitted(ignore) |
599 | 599 |
600 def _xmluiClose(self): | 600 def _xmlui_close(self): |
601 pass | 601 pass |
602 | 602 |
603 async def _launchActionCb(self, data): | 603 async def _launch_action_cb(self, data): |
604 XMLUIPanel._actions -= 1 | 604 XMLUIPanel._actions -= 1 |
605 assert XMLUIPanel._actions >= 0 | 605 assert XMLUIPanel._actions >= 0 |
606 if "xmlui" in data: | 606 if "xmlui" in data: |
607 xmlui_raw = data["xmlui"] | 607 xmlui_raw = data["xmlui"] |
608 xmlui = create(self.host, xmlui_raw) | 608 xmlui = create(self.host, xmlui_raw) |
609 await xmlui.show() | 609 await xmlui.show() |
610 if xmlui.submit_id: | 610 if xmlui.submit_id: |
611 await xmlui.onFormSubmitted() | 611 await xmlui.on_form_submitted() |
612 # TODO: handle data other than XMLUI | 612 # TODO: handle data other than XMLUI |
613 if not XMLUIPanel._actions: | 613 if not XMLUIPanel._actions: |
614 if self._submit_cb is None: | 614 if self._submit_cb is None: |
615 self.host.quit() | 615 self.host.quit() |
616 else: | 616 else: |
617 self._submit_cb() | 617 self._submit_cb() |
618 | 618 |
619 async def _xmluiLaunchAction(self, action_id, data): | 619 async def _xmlui_launch_action(self, action_id, data): |
620 XMLUIPanel._actions += 1 | 620 XMLUIPanel._actions += 1 |
621 try: | 621 try: |
622 data = await self.host.bridge.launchAction( | 622 data = await self.host.bridge.action_launch( |
623 action_id, | 623 action_id, |
624 data, | 624 data, |
625 self.profile, | 625 self.profile, |
626 ) | 626 ) |
627 except Exception as e: | 627 except Exception as e: |
628 self.disp(f"can't launch XMLUI action: {e}", error=True) | 628 self.disp(f"can't launch XMLUI action: {e}", error=True) |
629 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 629 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
630 else: | 630 else: |
631 await self._launchActionCb(data) | 631 await self._launch_action_cb(data) |
632 | 632 |
633 | 633 |
634 class XMLUIDialog(xmlui_base.XMLUIDialog): | 634 class XMLUIDialog(xmlui_base.XMLUIDialog): |
635 type = "dialog" | 635 type = "dialog" |
636 dialog_factory = WidgetFactory() | 636 dialog_factory = WidgetFactory() |
637 read_only = False | 637 read_only = False |
638 | 638 |
639 async def show(self, __=None): | 639 async def show(self, __=None): |
640 await self.dlg.show() | 640 await self.dlg.show() |
641 | 641 |
642 def _xmluiClose(self): | 642 def _xmlui_close(self): |
643 pass | 643 pass |
644 | 644 |
645 | 645 |
646 create = partial( | 646 create = partial( |
647 xmlui_base.create, | 647 xmlui_base.create, |