Quick Frontend (quick_widgets): added on_existing_widget in getOrCreateWidget (see docstring for more infos) + use of constants
This commit is contained in:
parent
b4937bef76
commit
588d65132c
2 changed files with 61 additions and 12 deletions
|
|
@ -62,6 +62,14 @@ class Const(constants.Const):
|
|||
# Roster
|
||||
GROUP_NOT_IN_ROSTER = D_('Not in roster')
|
||||
|
||||
#Chats
|
||||
# Chats
|
||||
CHAT_ONE2ONE = 'one2one'
|
||||
CHAT_GROUP = 'group'
|
||||
|
||||
# Widgets management
|
||||
# FIXME: should be in quick_frontend.constant, but Libervia doesn't inherit from it
|
||||
WIDGET_NEW = 'NEW'
|
||||
WIDGET_KEEP = 'KEEP'
|
||||
WIDGET_RAISE = 'RAISE'
|
||||
WIDGET_RECREATE = 'RECREATE'
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from sat.core.log import getLogger
|
|||
log = getLogger(__name__)
|
||||
from sat.core import exceptions
|
||||
|
||||
from sat_frontends.quick_frontend.constants import Const as C
|
||||
|
||||
classes_map = {}
|
||||
|
||||
|
|
@ -40,6 +41,8 @@ def register(base_cls, child_cls=None):
|
|||
Can be None if it's the base_cls itself which register
|
||||
"""
|
||||
classes_map[base_cls] = child_cls
|
||||
class WidgetAlreadyExistsError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class QuickWidgetsManager(object):
|
||||
|
|
@ -95,15 +98,19 @@ class QuickWidgetsManager(object):
|
|||
if 'profile' key is present, it will be popped and put in 'profiles'
|
||||
if there is neither 'profile' nor 'profiles', None will be used for 'profiles'
|
||||
if 'on_new_widget' is present it can have the following values:
|
||||
'NEW_WIDGET' [default]: self.host.newWidget will be called on widget creation
|
||||
C.WIDGET_NEW [default]: self.host.newWidget will be called on widget creation
|
||||
[callable]: this method will be called instead of self.host.newWidget
|
||||
None: do nothing
|
||||
if 'on_existing_widget' is present it can have the following values:
|
||||
C.WIDGET_KEEP [default]: return the existing widget
|
||||
C.WIDGET_RAISE: raise WidgetAlreadyExistsError
|
||||
C.WIDGET_RECREATE: create a new widget *WITH A NEW HASH*
|
||||
if 'force_hash' is present, the hash given in value will be used instead of the one returned by class_.getWidgetHash
|
||||
@return: a class_ instance, either new or already existing
|
||||
"""
|
||||
cls = self.getRealClass(class_)
|
||||
|
||||
# arguments management
|
||||
## arguments management ##
|
||||
_args = [self.host, target] + list(args) or [] # FIXME: check if it's really necessary to use optional args
|
||||
_kwargs = kwargs or {}
|
||||
if 'profiles' in _kwargs and 'profile' in _kwargs:
|
||||
|
|
@ -114,7 +121,19 @@ class QuickWidgetsManager(object):
|
|||
if not 'profiles' in _kwargs:
|
||||
_kwargs['profiles'] = None
|
||||
|
||||
# we get the hash
|
||||
#on_new_widget tell what to do for the new widget creation
|
||||
try:
|
||||
on_new_widget = _kwargs.pop('on_new_widget')
|
||||
except KeyError:
|
||||
on_new_widget = C.WIDGET_NEW
|
||||
|
||||
#on_existing_widget tell what to do when the widget already exists
|
||||
try:
|
||||
on_existing_widget = _kwargs.pop('on_existing_widget')
|
||||
except KeyError:
|
||||
on_existing_widget = C.WIDGET_KEEP
|
||||
|
||||
## we get the hash ##
|
||||
try:
|
||||
hash_ = _kwargs.pop('force_hash')
|
||||
except KeyError:
|
||||
|
|
@ -133,23 +152,45 @@ class QuickWidgetsManager(object):
|
|||
|
||||
if widget is None:
|
||||
# we need to create a new widget
|
||||
try:
|
||||
#on_new_widget tell what to do for the new widget creation
|
||||
on_new_widget = _kwargs.pop('on_new_widget')
|
||||
except KeyError:
|
||||
on_new_widget = 'NEW_WIDGET'
|
||||
|
||||
log.debug(u"Creating new widget for target {} {}".format(target, cls))
|
||||
widget = cls(*_args, **_kwargs)
|
||||
widgets_map[hash_] = widget
|
||||
|
||||
if on_new_widget == 'NEW_WIDGET':
|
||||
if on_new_widget == C.WIDGET_NEW:
|
||||
self.host.newWidget(widget)
|
||||
elif callable(on_new_widget):
|
||||
on_new_widget(widget)
|
||||
else:
|
||||
assert on_new_widget is None
|
||||
else:
|
||||
# the widget already exists
|
||||
if on_existing_widget == C.WIDGET_RAISE:
|
||||
raise WidgetAlreadyExistsError(hash_)
|
||||
elif on_existing_widget == C.WIDGET_RECREATE:
|
||||
# we use getOrCreateWidget to recreate the new widget
|
||||
# /!\ we use args and kwargs and not _args and _kwargs because we need the original args
|
||||
# we need to get rid of kwargs special options
|
||||
new_kwargs = kwargs.copy()
|
||||
try:
|
||||
new_kwargs.pop('force_hash') # FIXME: we use pop instead of del here because pyjamas doesn't raise error on del
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
raise ValueError("force_hash option can't be used with on_existing_widget=RECREATE")
|
||||
|
||||
# XXX: keep up-to-date if new special kwargs are added (i.e.: delete these keys here)
|
||||
new_kwargs['on_new_widget'] = None
|
||||
new_kwargs['on_existing_widget'] = C.WIDGET_RAISE
|
||||
hash_idx = 1
|
||||
while True:
|
||||
new_kwargs['force_hash'] = hash_ + "_new_instance_{}".format(hash_idx)
|
||||
try:
|
||||
widget = self.getOrCreateWidget(class_, target, *args, **new_kwargs)
|
||||
except WidgetAlreadyExistsError:
|
||||
hash_idx += 1
|
||||
else:
|
||||
log.debug(u"Widget already exists, a new one has been recreated with hash {}".format(new_kwargs['force_hash']))
|
||||
break
|
||||
return widget
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue