diff 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
line wrap: on
line diff
--- a/frontends/src/quick_frontend/quick_app.py	Mon Feb 09 21:39:51 2015 +0100
+++ b/frontends/src/quick_frontend/quick_app.py	Mon Feb 09 21:39:51 2015 +0100
@@ -195,6 +195,9 @@
         # widgets
         self.selected_widget = None # widget currently selected (must be filled by frontend)
 
+        # listeners
+        self._listeners = {} # key: listerner type ("avatar", "selected", etc), value: list of callbacks
+
         ## bridge ##
         try:
             self.bridge = create_bridge()
@@ -284,6 +287,42 @@
             handler(*args, **kwargs)
         self.bridge.register(functionName, signalReceived, iface)
 
+    def addListerner(self, type_, callback):
+        """Add a listerner for an event
+
+        /!\ don't forget to remove listener when not used anymore (e.g. if you delete a widget)
+        @param type_: type of event, can be:
+            - avatar: called when avatar data is updated
+                      args: (entity, avatar file, profile)
+        @param callback: method to call on event
+        """
+        assert type_ in C.LISTENERS
+        self._listeners.setdefault(type_, []).append(callback)
+
+    def removeListener(self, type_, callback):
+        """Remove a callback from listeners
+
+        @param type_: same as for [addListerner]
+        @param callback: callback to remove
+        """
+        assert type_ in C.LISTENERS
+        self._listeners[type_].remove(callback)
+
+    def callListeners(self, type_, *args):
+        """Call all methods which listen of type_ event
+
+        @param type_: same as for [addListerner]
+        @param *args: arguments sent to callback
+        """
+        assert type_ in C.LISTENERS
+        try:
+            listeners = self._listeners[type_]
+        except KeyError:
+            pass
+        else:
+            for listener in listeners:
+                listener(*args)
+
     def check_profile(self, profile):
         """Tell if the profile is currently followed by the application"""
         return profile in self.profiles
@@ -611,6 +650,7 @@
             if entity in self.contact_lists[profile]:
                 def gotFilename(filename):
                     self.contact_lists[profile].setCache(entity, 'avatar', filename)
+                    self.callListeners('avatar', entity, filename, profile)
                 self.bridge.getAvatarFile(value, callback=gotFilename)
 
     def askConfirmationHandler(self, confirm_id, confirm_type, data, profile):