From 5d6321ec9f6398bcb892ec5fa20bf5bac3f3064b Mon Sep 17 00:00:00 2001 From: Goffi Date: Fri, 31 Aug 2018 16:03:12 +0200 Subject: [PATCH] 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. --- sat/tools/common/template_xmlui.py | 8 ++-- sat_frontends/jp/xmlui_manager.py | 57 ++++++++++------------- sat_frontends/quick_frontend/quick_app.py | 10 +--- sat_frontends/tools/xmlui.py | 30 ++++++------ 4 files changed, 47 insertions(+), 58 deletions(-) diff --git a/sat/tools/common/template_xmlui.py b/sat/tools/common/template_xmlui.py index 8ccefe6a..086ab537 100644 --- a/sat/tools/common/template_xmlui.py +++ b/sat/tools/common/template_xmlui.py @@ -26,6 +26,7 @@ from sat.core.log import getLogger log = getLogger(__name__) from sat_frontends.tools import xmlui +from functools import partial ## Widgets ## @@ -176,6 +177,7 @@ class LabelContainer(xmlui.PairsContainer, Container): class WidgetFactory(object): + def __getattr__(self, attr): if attr.startswith("create"): cls = globals()[attr[6:]] @@ -199,6 +201,6 @@ class XMLUIDialog(xmlui.XMLUIDialog): raise NotImplementedError -xmlui.registerClass(xmlui.CLASS_PANEL, XMLUIPanel) -xmlui.registerClass(xmlui.CLASS_DIALOG, XMLUIDialog) -create = xmlui.create +create = partial(xmlui.create, class_map={ + xmlui.CLASS_PANEL: XMLUIPanel, + xmlui.CLASS_DIALOG: XMLUIDialog}) diff --git a/sat_frontends/jp/xmlui_manager.py b/sat_frontends/jp/xmlui_manager.py index 3fe0ab4c..80c7a95f 100644 --- a/sat_frontends/jp/xmlui_manager.py +++ b/sat_frontends/jp/xmlui_manager.py @@ -20,7 +20,7 @@ from sat.core.log import getLogger log = getLogger(__name__) -from sat_frontends.tools import xmlui as xmlui_manager +from sat_frontends.tools import xmlui as xmlui_base from sat_frontends.jp.constants import Const as C from sat.tools.common.ansi import ANSI as A from sat.core.i18n import _ @@ -50,7 +50,7 @@ class Base(object): if self._root is not None: return self._root root = self - while not isinstance(root, xmlui_manager.XMLUIBase): + while not isinstance(root, xmlui_base.XMLUIBase): root = root.xmlui_parent self._root = root return root @@ -173,19 +173,19 @@ class OptionsWidget(Widget): return u"noselect" in self.style -class EmptyWidget(xmlui_manager.EmptyWidget, Widget): +class EmptyWidget(xmlui_base.EmptyWidget, Widget): def __init__(self, _xmlui_parent): Widget.__init__(self) -class TextWidget(xmlui_manager.TextWidget, ValueWidget): +class TextWidget(xmlui_base.TextWidget, ValueWidget): type = u"text" def show(self): self.host.disp(self.value) -class LabelWidget(xmlui_manager.LabelWidget, ValueWidget): +class LabelWidget(xmlui_base.LabelWidget, ValueWidget): type = u"label" @property @@ -204,7 +204,7 @@ class LabelWidget(xmlui_manager.LabelWidget, ValueWidget): self.disp(A.color(ansi, self.value), no_lf=no_lf) -class StringWidget(xmlui_manager.StringWidget, InputWidget): +class StringWidget(xmlui_base.StringWidget, InputWidget): type = u"string" def show(self): @@ -223,15 +223,15 @@ class StringWidget(xmlui_manager.StringWidget, InputWidget): self.value = value -class JidInputWidget(xmlui_manager.JidInputWidget, StringWidget): +class JidInputWidget(xmlui_base.JidInputWidget, StringWidget): type = u"jid_input" -class TextBoxWidget(xmlui_manager.TextWidget, StringWidget): +class TextBoxWidget(xmlui_base.TextWidget, StringWidget): type = u"textbox" -class ListWidget(xmlui_manager.ListWidget, OptionsWidget): +class ListWidget(xmlui_base.ListWidget, OptionsWidget): type = u"list" # TODO: handle flags, notably multi @@ -277,7 +277,7 @@ class ListWidget(xmlui_manager.ListWidget, OptionsWidget): self.disp("") -class BoolWidget(xmlui_manager.BoolWidget, InputWidget): +class BoolWidget(xmlui_base.BoolWidget, InputWidget): type = u"bool" def show(self): @@ -324,15 +324,15 @@ class Container(Base): child.show() -class VerticalContainer(xmlui_manager.VerticalContainer, Container): +class VerticalContainer(xmlui_base.VerticalContainer, Container): type = u"vertical" -class PairsContainer(xmlui_manager.PairsContainer, Container): +class PairsContainer(xmlui_base.PairsContainer, Container): type = u"pairs" -class LabelContainer(xmlui_manager.PairsContainer, Container): +class LabelContainer(xmlui_base.PairsContainer, Container): type = u"label" def show(self): @@ -377,14 +377,14 @@ class Dialog(object): raise NotImplementedError(self.__class__) -class NoteDialog(xmlui_manager.NoteDialog, Dialog): +class NoteDialog(xmlui_base.NoteDialog, Dialog): def show(self): # TODO: handle title and level self.disp(self.message) def __init__(self, _xmlui_parent, title, message, level): Dialog.__init__(self, _xmlui_parent) - xmlui_manager.NoteDialog.__init__(self, _xmlui_parent) + xmlui_base.NoteDialog.__init__(self, _xmlui_parent) self.title, self.message, self.level = title, message, level @@ -398,7 +398,7 @@ class WidgetFactory(object): return cls -class XMLUIPanel(xmlui_manager.XMLUIPanel): +class XMLUIPanel(xmlui_base.XMLUIPanel): widget_factory = WidgetFactory() _actions = 0 # use to keep track of bridge's launchAction calls read_only = False @@ -406,18 +406,9 @@ class XMLUIPanel(xmlui_manager.XMLUIPanel): workflow = None _submit_cb = None - def __init__( - self, - host, - parsed_dom, - title=None, - flags=None, - callback=None, - ignore=None, - whitelist=None, - profile=None, - ): - xmlui_manager.XMLUIPanel.__init__( + def __init__(self, host, parsed_dom, title=None, flags=None, callback=None, + ignore=None, whitelist=None, profile=None): + xmlui_base.XMLUIPanel.__init__( self, host, parsed_dom, @@ -500,7 +491,7 @@ class XMLUIPanel(xmlui_manager.XMLUIPanel): assert XMLUIPanel._actions >= 0 if u"xmlui" in data: xmlui_raw = data["xmlui"] - xmlui = xmlui_manager.create(self.host, xmlui_raw) + xmlui = create(self.host, xmlui_raw) xmlui.show() if xmlui.submit_id: xmlui.onFormSubmitted() @@ -526,7 +517,7 @@ class XMLUIPanel(xmlui_manager.XMLUIPanel): ) -class XMLUIDialog(xmlui_manager.XMLUIDialog): +class XMLUIDialog(xmlui_base.XMLUIDialog): type = "dialog" dialog_factory = WidgetFactory() read_only = False @@ -538,6 +529,6 @@ class XMLUIDialog(xmlui_manager.XMLUIDialog): pass -xmlui_manager.registerClass(xmlui_manager.CLASS_PANEL, XMLUIPanel) -xmlui_manager.registerClass(xmlui_manager.CLASS_DIALOG, XMLUIDialog) -create = xmlui_manager.create +create = partial(xmlui_base.create, class_map={ + xmlui_base.CLASS_PANEL: XMLUIPanel, + xmlui_base.CLASS_DIALOG: XMLUIDialog}) diff --git a/sat_frontends/quick_frontend/quick_app.py b/sat_frontends/quick_frontend/quick_app.py index 93c9b143..876c3b74 100644 --- a/sat_frontends/quick_frontend/quick_app.py +++ b/sat_frontends/quick_frontend/quick_app.py @@ -1121,14 +1121,8 @@ class QuickApp(object): if value and entity in self.contact_lists[profile]: self.getAvatar(entity, ignore_cache=True, profile=profile) - def actionManager( - self, - action_data, - callback=None, - ui_show_cb=None, - user_action=True, - profile=C.PROF_KEY_NONE, - ): + def actionManager(self, action_data, callback=None, ui_show_cb=None, user_action=True, + profile=C.PROF_KEY_NONE): """Handle backend action @param action_data(dict): action dict as sent by launchAction or returned by an diff --git a/sat_frontends/tools/xmlui.py b/sat_frontends/tools/xmlui.py index 224c3851..eebb74ff 100644 --- a/sat_frontends/tools/xmlui.py +++ b/sat_frontends/tools/xmlui.py @@ -25,7 +25,7 @@ from sat_frontends.quick_frontend.constants import Const as C from sat.core import exceptions -class_map = {} +_class_map = {} CLASS_PANEL = "panel" CLASS_DIALOG = "dialog" CURRENT_LABEL = "current_label" @@ -986,22 +986,22 @@ def registerClass(type_, class_): CLASS_DIALOG: XMLUI dialog @param class_: the class to use to instanciate given type """ + # TODO: remove this method, as there are seme use cases where different XMLUI + # classes can be used in the same frontend, so a global value is not good assert type_ in (CLASS_PANEL, CLASS_DIALOG) - class_map[type_] = class_ + log.warning(u"registerClass for XMLUI is deprecated, please use partial with " + u"xmlui.create and class_map instead") + if type_ in _class_map: + log.debug(_(u"XMLUI class already registered for {type_}, ignoring").format( + type_=type_)) + return + + _class_map[type_] = class_ -def create( - host, - xml_data, - title=None, - flags=None, - dom_parse=None, - dom_free=None, - callback=None, - ignore=None, - whitelist=None, - profile=C.PROF_KEY_NONE, -): +def create(host, xml_data, title=None, flags=None, dom_parse=None, dom_free=None, + callback=None, ignore=None, whitelist=None, class_map=None, + profile=C.PROF_KEY_NONE): """ @param dom_parse: methode equivalent to minidom.parseString (but which must manage unicode), or None to use default one @param dom_free: method used to free the parsed DOM @@ -1011,6 +1011,8 @@ def create( when not None, only widgets in this list and their label will be kept mutually exclusive with ignore """ + if class_map is None: + class_map = _class_map if dom_parse is None: from xml.dom import minidom