# HG changeset patch # User Goffi # Date 1387846830 -3600 # Node ID e4f586fc61016a5d332479e5bbf69c126b322b9a # Parent e99f578c71795785a024f1bb4e4e54cb127f0b1b server and browser side: updated callback system to follow core changes diff -r e99f578c7179 -r e4f586fc6101 browser_side/xmlui.py --- a/browser_side/xmlui.py Tue Dec 17 01:47:01 2013 +0100 +++ b/browser_side/xmlui.py Tue Dec 24 02:00:30 2013 +0100 @@ -101,26 +101,28 @@ elif node_type=="string": ctrl = TextBox() ctrl.setText(value) - self.ctrl_list[name] = ({'node_type':node_type, 'control':ctrl}) + self.ctrl_list[name] = {'node_type':node_type, 'control':ctrl} elif node_type=="password": ctrl = PasswordTextBox() ctrl.setText(value) - self.ctrl_list[name] = ({'node_type':node_type, 'control':ctrl}) + self.ctrl_list[name] = {'node_type':node_type, 'control':ctrl} elif node_type=="textbox": ctrl = TextArea() ctrl.setText(value) - self.ctrl_list[name] = ({'node_type':node_type, 'control':ctrl}) + self.ctrl_list[name] = {'node_type':node_type, 'control':ctrl} elif node_type=="bool": ctrl = CheckBox() ctrl.setChecked(value=="true") - self.ctrl_list[name] = ({'node_type':node_type, 'control':ctrl}) + self.ctrl_list[name] = {'node_type':node_type, 'control':ctrl} elif node_type=="list": + _options = [(option.getAttribute("label"), option.getAttribute("value")) for option in elem.getElementsByTagName("option")] + attr_map = {label: value for label, value in _options} ctrl = ListBox() ctrl.setMultipleSelect(elem.getAttribute("multi")=='yes') - for option in elem.getElementsByTagName("option"): - ctrl.addItem(option.getAttribute("value")) + for option in _options: + ctrl.addItem(option[0]) ctrl.selectItem(value) - self.ctrl_list[name] = ({'node_type':node_type, 'control':ctrl}) + self.ctrl_list[name] = {'node_type':node_type, 'control':ctrl, 'attr_map': attr_map} elif node_type=="button": callback_id = elem.getAttribute("callback_id") ctrl = Button(value, self.onButtonPress) @@ -190,6 +192,8 @@ top=cat_dom.documentElement self.node_type = top.getAttribute("type") self.title = top.getAttribute("title") or self.title + self.session_id = top.getAttribute("session_id") or None + self.submit_id = top.getAttribute("submit") or None if top.nodeName != "sat_xmlui" or not self.node_type in ['form', 'param', 'window']: raise InvalidXMLUI @@ -216,7 +220,6 @@ def onButtonPress(self, button): print "onButtonPress (%s)" % (button,) callback_id, fields = button.param_id - data = {"callback_id":callback_id} for field in fields: ctrl = self.ctrl_list[field] if isinstance(ctrl['control'],ListBox): @@ -226,8 +229,7 @@ else: data[field] = ctrl['control'].getText() - self.host.bridge.call('launchAction', None, "button", data) - self.host.current_action_ids.add(id) + self.host.launchAction(callback_id, None) def onParamChange(self, widget): """Called when type is param and a widget to save is modified""" @@ -241,17 +243,23 @@ print "FIXME FIXME FIXME: Form submitting not managed yet" data = [] for ctrl_name in self.ctrl_list: - ctrl = self.ctrl_list[ctrl_name] + escaped = u"%s%s" % (SAT_FORM_PREFIX, ctrl_name) + ctrl = self.ctrl_list[escaped] if isinstance(ctrl['control'], ListBox): - data.append((ctrl_name, '\t'.join(ctrl['control'].getSelectedItemText()))) + data.append((escaped, '\t'.join([ctrl['attr_map'][label] for label in ctrl['control'].getSelectedItemText()]))) elif isinstance(ctrl['control'], CheckBox): - data.append((ctrl_name, "true" if ctrl['control'].isChecked() else "false")) + data.append((escaped, "true" if ctrl['control'].isChecked() else "false")) else: - data.append((ctrl_name, ctrl['control'].getText())) + data.append((escaped, ctrl['control'].getText())) if 'action_back' in self.misc: #FIXME FIXME FIXME: WTF ! Must be cleaned raise NotImplementedError elif 'callback' in self.misc: self.misc['callback'](data) + elif self.submit_id is not None: + data = dict(selected_values) + if self.session_id is not None: + data["session_id"] = self.session_id + self.host.launchAction(self.submit_id, data) else: print ("WARNING: The form data is not sent back, the type is not managed properly") diff -r e99f578c7179 -r e4f586fc6101 libervia.py --- a/libervia.py Tue Dec 17 01:47:01 2013 +0100 +++ b/libervia.py Tue Dec 24 02:00:30 2013 +0100 @@ -173,7 +173,6 @@ self.room_list = [] # list of rooms self.mblog_cache = [] # used to keep our own blog entries in memory, to show them in new mblog panel self.avatars_cache = {} # keep track of jid's avatar hash (key=jid, value=file) - self.current_action_ids = set() #self.discuss_panel.addWidget(panels.EmptyPanel(self)) self.discuss_panel.addWidget(panels.MicroblogPanel(self, [])) #self.discuss_panel.addWidget(panels.EmptyPanel(self)) @@ -342,6 +341,36 @@ # this would eventually set the browser saved password Timer(5, lambda: self._register_box._form.login_pass_box.setFocus(True)) + + def _actionCb(data): + if not data: + # action was a one shot, nothing to do + pass + elif "xmlui" in data: + ui = XMLUI(self, xml_data = data['xmlui']) + _dialog = dialog.GenericDialog(ui.title, ui) + ui.setCloseCb(_dialog.close) + _dialog.setSize('80%', '80%') + _dialog.show() + else: + dialog.InfoDialog("Error", + "Unmanaged action result", Width="400px").center() + + def _actionEb(err_data): + err_code, err_obj = err_data + dialog.InfoDialog("Error", + str(err_obj), Width="400px").center() + + def launchAction(self, callback_id, data): + """ Launch a dynamic action + @param callback_id: id of the action to launch + @param data: data needed only for certain actions + + """ + if data is None: + data = {} + self.bridge.call('launchAction', (self._actionCb, self._actionEb), callback_id, data) + def _getContactsCB(self, contacts_data): for contact in contacts_data: jid, attributes, groups = contact diff -r e99f578c7179 -r e4f586fc6101 libervia.tac --- a/libervia.tac Tue Dec 17 01:47:01 2013 +0100 +++ b/libervia.tac Tue Dec 24 02:00:30 2013 +0100 @@ -486,9 +486,10 @@ warning("Trying to set parameter '%s' in category '%s' without authorization!!!" % (name, category)) - def jsonrpc_launchAction(self, action_type, data): + def jsonrpc_launchAction(self, callback_id, data): profile = ISATSession(self.session).profile - return self.sat_host.bridge.launchAction(action_type, data, profile) + d = self.asyncBridgeCall("launchAction", callback_id, data, profile) + return d def jsonrpc_chatStateComposing(self, to_jid_s): """Call the method to process a "composing" state.