comparison frontends/src/quick_frontend/quick_app.py @ 1319:781ee3539252 frontends_multi_profiles

quick frontends(quick app): add a listeners (observer/observable) mechanism to call a callback when a event happen. Implemented an "avatar" event.
author Goffi <goffi@goffi.org>
date Mon, 09 Feb 2015 21:39:51 +0100
parents 6c7d89843f1b
children a599b6a70dc0 2ecc07a8f91b
comparison
equal deleted inserted replaced
1318:6c7d89843f1b 1319:781ee3539252
192 else: 192 else:
193 self.options = None 193 self.options = None
194 194
195 # widgets 195 # widgets
196 self.selected_widget = None # widget currently selected (must be filled by frontend) 196 self.selected_widget = None # widget currently selected (must be filled by frontend)
197
198 # listeners
199 self._listeners = {} # key: listerner type ("avatar", "selected", etc), value: list of callbacks
197 200
198 ## bridge ## 201 ## bridge ##
199 try: 202 try:
200 self.bridge = create_bridge() 203 self.bridge = create_bridge()
201 except exceptions.BridgeExceptionNoService: 204 except exceptions.BridgeExceptionNoService:
282 if profile is not None and not self.check_profile(profile): 285 if profile is not None and not self.check_profile(profile):
283 return # we ignore signal for profiles we don't manage 286 return # we ignore signal for profiles we don't manage
284 handler(*args, **kwargs) 287 handler(*args, **kwargs)
285 self.bridge.register(functionName, signalReceived, iface) 288 self.bridge.register(functionName, signalReceived, iface)
286 289
290 def addListerner(self, type_, callback):
291 """Add a listerner for an event
292
293 /!\ don't forget to remove listener when not used anymore (e.g. if you delete a widget)
294 @param type_: type of event, can be:
295 - avatar: called when avatar data is updated
296 args: (entity, avatar file, profile)
297 @param callback: method to call on event
298 """
299 assert type_ in C.LISTENERS
300 self._listeners.setdefault(type_, []).append(callback)
301
302 def removeListener(self, type_, callback):
303 """Remove a callback from listeners
304
305 @param type_: same as for [addListerner]
306 @param callback: callback to remove
307 """
308 assert type_ in C.LISTENERS
309 self._listeners[type_].remove(callback)
310
311 def callListeners(self, type_, *args):
312 """Call all methods which listen of type_ event
313
314 @param type_: same as for [addListerner]
315 @param *args: arguments sent to callback
316 """
317 assert type_ in C.LISTENERS
318 try:
319 listeners = self._listeners[type_]
320 except KeyError:
321 pass
322 else:
323 for listener in listeners:
324 listener(*args)
325
287 def check_profile(self, profile): 326 def check_profile(self, profile):
288 """Tell if the profile is currently followed by the application""" 327 """Tell if the profile is currently followed by the application"""
289 return profile in self.profiles 328 return profile in self.profiles
290 329
291 def postInit(self, profile_manager): 330 def postInit(self, profile_manager):
609 self.contact_lists[profile].setCache(entity, 'nick', value) 648 self.contact_lists[profile].setCache(entity, 'nick', value)
610 elif key == "avatar": 649 elif key == "avatar":
611 if entity in self.contact_lists[profile]: 650 if entity in self.contact_lists[profile]:
612 def gotFilename(filename): 651 def gotFilename(filename):
613 self.contact_lists[profile].setCache(entity, 'avatar', filename) 652 self.contact_lists[profile].setCache(entity, 'avatar', filename)
653 self.callListeners('avatar', entity, filename, profile)
614 self.bridge.getAvatarFile(value, callback=gotFilename) 654 self.bridge.getAvatarFile(value, callback=gotFilename)
615 655
616 def askConfirmationHandler(self, confirm_id, confirm_type, data, profile): 656 def askConfirmationHandler(self, confirm_id, confirm_type, data, profile):
617 raise NotImplementedError 657 raise NotImplementedError
618 658