changeset 1489:039d96e131be

frontends: callback are now always used in QuickApp launchAction (before it was only used if validated is present): - actionManager is used by default (no callback provided) - in XMLUI, the dialog is closed before calling actionManager - if keys are not managed in resuling data, an exceptions is raised
author Goffi <goffi@goffi.org>
date Tue, 25 Aug 2015 14:41:42 +0200
parents 66d01f29f886
children 55cff13b1f10
files frontends/src/primitivus/profile_manager.py frontends/src/quick_frontend/quick_app.py frontends/src/quick_frontend/quick_profile_manager.py frontends/src/tools/xmlui.py
diffstat 4 files changed, 44 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/primitivus/profile_manager.py	Tue Aug 25 14:22:21 2015 +0200
+++ b/frontends/src/primitivus/profile_manager.py	Tue Aug 25 14:41:42 2015 +0200
@@ -167,11 +167,13 @@
         if not selected: # profile was just unselected
             return
         focused.setState(False, invisible=True) # we don't want the widget to be selected until we are sure we can access it
-        def authenticate_cb(callback_id, data, profile):
-            if C.bool(data['validated']):
+        def authenticate_cb(data, cb_id, profile):
+            if C.bool(data.pop('validated', C.BOOL_FALSE)):
                 self.current.profile = profile
                 focused.setState(True, invisible=True)
                 self.getConnectionParams(profile)
                 self.host.redraw()
+            self.host.actionManager(data, callback=authenticate_cb, profile=profile)
+
         self.host.launchAction(C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=focused.text)
 
--- a/frontends/src/quick_frontend/quick_app.py	Tue Aug 25 14:22:21 2015 +0200
+++ b/frontends/src/quick_frontend/quick_app.py	Tue Aug 25 14:41:42 2015 +0200
@@ -465,7 +465,7 @@
         self.setPresenceStatus(C.PRESENCE_UNAVAILABLE, '', profile=profile)
 
     def actionNewHandler(self, action_data, id_, profile):
-        self._actionManager(action_data, profile=profile)
+        self.actionManager(action_data, profile=profile)
 
     def newContactHandler(self, jid_s, attributes, groups, profile):
         entity = jid.JID(jid_s)
@@ -714,26 +714,28 @@
     def actionResultHandler(self, type, id, data, profile):
         raise NotImplementedError
 
-    def _actionManagerUnknownError(self):
-        raise NotImplementedError
-
-
-    def _actionManager(self, action_data, callback=None, profile=C.PROF_KEY_NONE):
-        if "xmlui" in action_data:
-            ui = self.xmlui.create(self, xml_data=action_data['xmlui'], callback=callback, profile=profile)
+    def actionManager(self, action_data, callback=None, profile=C.PROF_KEY_NONE):
+        try:
+            xmlui = action_data.pop('xmlui')
+        except KeyError:
+            pass
+        else:
+            ui = self.xmlui.create(self, xml_data=xmlui, callback=callback, profile=profile)
             ui.show()
-        else:
-            self._actionManagerUnknownError()
+        if action_data:
+            raise exceptions.DataError(u"Not all keys in action_data are managed ({keys})".format(keys=', '.join(action_data.keys())))
 
     def launchAction(self, callback_id, data=None, callback=None, profile=C.PROF_KEY_NONE):
         """ Launch a dynamic action
 
         @param callback_id: id of the action to launch
         @param data: data needed only for certain actions
-        @param callback: if not None and 'validated' key is present, it will be called with the following parameters:
-            - callback_id
-            - data
-            - profile
+        @param callback(callable, None): will be called with the resut
+            if None, self.actionManager will be called
+            else the callable will be called with the following kw parameters:
+                - data: action_data
+                - cb_id: callback id
+                - profile: %(doc_profile)s
         @param profile: %(doc_profile)s
 
         """
@@ -741,14 +743,10 @@
             data = dict()
 
         def action_cb(data):
-            if not data:
-                # action was a one shot, nothing to do
-                pass
-            elif 'validated' in data:
-                if callback:
-                    callback(callback_id, data, profile)
+            if callback is None:
+                self.actionManager(data, profile=profile)
             else:
-                self._actionManager(data, profile=profile)
+                callback(data=data, cb_id=callback_id, profile=profile)
 
         self.bridge.launchAction(callback_id, data, profile, callback=action_cb, errback=self.dialogFailure)
 
--- a/frontends/src/quick_frontend/quick_profile_manager.py	Tue Aug 25 14:22:21 2015 +0200
+++ b/frontends/src/quick_frontend/quick_profile_manager.py	Tue Aug 25 14:41:42 2015 +0200
@@ -96,9 +96,9 @@
         """
         assert self._autoconnect
 
-        def authenticate_cb(callback_id, data, profile):
+        def authenticate_cb(data, cb_id, profile):
 
-            if C.bool(data['validated']):
+            if C.bool(data.pop('validated', C.BOOL_FALSE)):
                 self._autoconnect_profiles.append(profile)
                 if len(self._autoconnect_profiles) == len(profile_keys):
                     # all the profiles have been validated
@@ -106,6 +106,7 @@
             else:
                 # a profile is not validated, we go to manual mode
                 self._autoconnect=False
+            self.host.actionManager(data, callback=authenticate_cb, profile=profile)
 
         for profile_key in profile_keys:
             profile = self.host.bridge.getProfileName(profile_key)
--- a/frontends/src/tools/xmlui.py	Tue Aug 25 14:22:21 2015 +0200
+++ b/frontends/src/tools/xmlui.py	Tue Aug 25 14:41:42 2015 +0200
@@ -237,7 +237,10 @@
         @param title: force the title, or use XMLUI one if None
         @param flags: list of string which can be:
             - NO_CANCEL: the UI can't be cancelled
-        @param callback: if present, will be used with launchAction
+        @param callback(callable, None): if not None, will be used with launchAction:
+            - if None is used, default behaviour will be used (closing the dialog and calling host.actionManager)
+            - if a callback is provided, it will be used instead, so you'll have to manage
+                dialog closing or new xmlui to display, or other action (you can call host.actionManager)
         """
         self.host = host
         top=parsed_dom.documentElement
@@ -247,9 +250,15 @@
         if flags is None:
             flags = []
         self.flags = flags
-        self.callback = callback
+        self.callback = callback or self._defaultCb
         self.profile = profile
 
+    def _defaultCb(self, data, cb_id, profile):
+        # TODO: when XMLUI updates will be managed, the _xmluiClose
+        #       must be called only if there is not update
+        self._xmluiClose()
+        self.host.actionManager(data, profile=profile)
+
     def _isAttrSet(self, name, node):
         """Returnw widget boolean attribute status
 
@@ -285,6 +294,13 @@
     def _xmluiLaunchAction(self, action_id, data):
         self.host.launchAction(action_id, data, callback=self.callback, profile=self.profile)
 
+    def _xmluiClose(self):
+        """Close the window/popup/... where the constructeur XMLUI is
+
+        this method must be overrided
+        """
+        raise NotImplementedError
+
 
 class XMLUIPanel(XMLUIBase):
     """XMLUI Panel
@@ -493,13 +509,6 @@
         if post_treat is not None:
             post_treat()
 
-    def _xmluiClose(self):
-        """Close the window/popup/... where the constructeur XMLUI is
-
-        this method must be overrided
-        """
-        raise NotImplementedError
-
     def _xmluiSetParam(self, name, value, category):
         self.host.bridge.setParam(name, value, category, profile_key=self.profile)