Mercurial > libervia-backend
comparison frontends/src/quick_frontend/quick_widgets.py @ 1290:faa1129559b8 frontends_multi_profiles
core, frontends: refactoring to base Libervia on QuickFrontend (big mixed commit):
/!\ not finished, everything is still instable !
- bridge: DBus bridge has been modified to allow blocking call to be called in the same way as asynchronous calls
- bridge: calls with a callback and no errback are now possible, default errback log the error
- constants: removed hack to manage presence without OrderedDict, as an OrderedDict like class has been implemented in Libervia
- core: getLastResource has been removed and replaced by getMainResource (there is a global better management of resources)
- various style improvments: use of constants when possible, fixed variable overlaps, import of module instead of direct class import
- frontends: printInfo and printMessage methods in (Quick)Chat are more generic (use of extra instead of timestamp)
- frontends: bridge creation and option parsing (command line arguments) are now specified by the frontend in QuickApp __init__
- frontends: ProfileManager manage a more complete plug sequence (some stuff formerly manage in contact_list have moved to ProfileManager)
- quick_frontend (quick_widgets): QuickWidgetsManager is now iterable (all widgets are then returned), or can return an iterator on a specific class (return all widgets of this class) with getWidgets
- frontends: tools.jid can now be used in Pyjamas, with some care
- frontends (XMLUI): profile is now managed
- core (memory): big improvment on entities cache management (and specially resource management)
- core (params/exceptions): added PermissionError
- various fixes and improvments, check diff for more details
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 24 Jan 2015 01:00:29 +0100 |
parents | e3a9ea76de35 |
children | afc57b34c0a3 |
comparison
equal
deleted
inserted
replaced
1289:653f2e2eea31 | 1290:faa1129559b8 |
---|---|
21 log = getLogger(__name__) | 21 log = getLogger(__name__) |
22 from sat.core import exceptions | 22 from sat.core import exceptions |
23 | 23 |
24 | 24 |
25 classes_map = {} | 25 classes_map = {} |
26 | |
27 | |
28 try: | |
29 # FIXME: to be removed when an acceptable solution is here | |
30 unicode('') # XXX: unicode doesn't exist in pyjamas | |
31 except (TypeError, AttributeError): # Error raised is not the same depending on pyjsbuild options | |
32 unicode = str | |
26 | 33 |
27 | 34 |
28 def register(base_cls, child_cls=None): | 35 def register(base_cls, child_cls=None): |
29 """Register a child class to use by default when a base class is needed | 36 """Register a child class to use by default when a base class is needed |
30 | 37 |
40 A widget can be a window, a graphical thing, or someting else depending of the frontend""" | 47 A widget can be a window, a graphical thing, or someting else depending of the frontend""" |
41 | 48 |
42 def __init__(self, host): | 49 def __init__(self, host): |
43 self.host = host | 50 self.host = host |
44 self._widgets = {} | 51 self._widgets = {} |
52 | |
53 def __iter__(self): | |
54 """Iterate throught all widgets""" | |
55 for widget_map in self._widgets.itervalues(): | |
56 for widget in widget_map.itervalues(): | |
57 yield widget | |
58 | |
59 def getRealClass(self, class_): | |
60 """Return class registered for given class_ | |
61 | |
62 @param class_: subclass of QuickWidget | |
63 @return: class actually used to create widget | |
64 """ | |
65 try: | |
66 cls = classes_map[class_] | |
67 except KeyError: | |
68 cls = class_ | |
69 if cls is None: | |
70 raise exceptions.InternalError("There is not class registered for {}".format(class_)) | |
71 return cls | |
72 | |
73 def getWidgets(self, class_): | |
74 """Get all subclassed widgets | |
75 | |
76 @param class_: subclass of QuickWidget, same parameter as used in [getOrCreateWidget] | |
77 @return: iterator on widgets | |
78 """ | |
79 class_ = self.getRealClass(class_) | |
80 try: | |
81 widgets_map = self._widgets[class_] | |
82 except KeyError: | |
83 return iter([]) | |
84 else: | |
85 return widgets_map.itervalues() | |
45 | 86 |
46 def getOrCreateWidget(self, class_, target, *args, **kwargs): | 87 def getOrCreateWidget(self, class_, target, *args, **kwargs): |
47 """Get an existing widget or create a new one when necessary | 88 """Get an existing widget or create a new one when necessary |
48 | 89 |
49 If the widget is new, self.host.newWidget will be called with it. | 90 If the widget is new, self.host.newWidget will be called with it. |
58 [callable]: this method will be called instead of self.host.newWidget | 99 [callable]: this method will be called instead of self.host.newWidget |
59 None: do nothing | 100 None: do nothing |
60 if 'force_hash' is present, the hash given in value will be used instead of the one returned by class_.getWidgetHash | 101 if 'force_hash' is present, the hash given in value will be used instead of the one returned by class_.getWidgetHash |
61 @return: a class_ instance, either new or already existing | 102 @return: a class_ instance, either new or already existing |
62 """ | 103 """ |
63 # class management | 104 cls = self.getRealClass(class_) |
64 try: | |
65 cls = classes_map[class_] | |
66 except KeyError: | |
67 cls = class_ | |
68 if cls is None: | |
69 raise exceptions.InternalError("There is not class registered for {}".format(class_)) | |
70 | 105 |
71 # arguments management | 106 # arguments management |
72 _args = [self.host, target] + list(args) or [] # FIXME: check if it's really necessary to use optional args | 107 _args = [self.host, target] + list(args) or [] # FIXME: check if it's really necessary to use optional args |
73 _kwargs = kwargs or {} | 108 _kwargs = kwargs or {} |
74 if 'profiles' in _kwargs and 'profile' in _kwargs: | 109 if 'profiles' in _kwargs and 'profile' in _kwargs: |
84 hash_ = _kwargs.pop('force_hash') | 119 hash_ = _kwargs.pop('force_hash') |
85 except KeyError: | 120 except KeyError: |
86 hash_ = cls.getWidgetHash(target, _kwargs['profiles']) | 121 hash_ = cls.getWidgetHash(target, _kwargs['profiles']) |
87 | 122 |
88 # widget creation or retrieval | 123 # widget creation or retrieval |
89 widgets_list = self._widgets.setdefault(cls, {}) # we sorts widgets by classes | 124 widgets_map = self._widgets.setdefault(cls, {}) # we sorts widgets by classes |
90 if not cls.SINGLE: | 125 if not cls.SINGLE: |
91 widget = None # if the class is not SINGLE, we always create a new widget | 126 widget = None # if the class is not SINGLE, we always create a new widget |
92 else: | 127 else: |
93 try: | 128 try: |
94 widget = widgets_list[hash_] | 129 widget = widgets_map[hash_] |
95 widget.addTarget(target) | 130 widget.addTarget(target) |
96 except KeyError: | 131 except KeyError: |
97 widget = None | 132 widget = None |
98 | 133 |
99 if widget is None: | 134 if widget is None: |
104 except KeyError: | 139 except KeyError: |
105 on_new_widget = 'NEW_WIDGET' | 140 on_new_widget = 'NEW_WIDGET' |
106 | 141 |
107 log.debug(u"Creating new widget for target {} {}".format(target, cls)) | 142 log.debug(u"Creating new widget for target {} {}".format(target, cls)) |
108 widget = cls(*_args, **_kwargs) | 143 widget = cls(*_args, **_kwargs) |
109 widgets_list[hash_] = widget | 144 widgets_map[hash_] = widget |
110 | 145 |
111 if on_new_widget == 'NEW_WIDGET': | 146 if on_new_widget == 'NEW_WIDGET': |
112 self.host.newWidget(widget) | 147 self.host.newWidget(widget) |
113 elif callable(on_new_widget): | 148 elif callable(on_new_widget): |
114 on_new_widget(widget) | 149 on_new_widget(widget) |