Quick Frontend (quick_widgets): added on_existing_widget in getOrCreateWidget (see docstring for more infos) + use of constants

This commit is contained in:
Goffi 2015-02-06 19:01:06 +01:00
commit 588d65132c
2 changed files with 61 additions and 12 deletions

View file

@ -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'

View file

@ -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