Author: liori Date: 2006-07-09 19:55:56 +0200 (Sun, 09 Jul 2006) New Revision: 6542
Modified: branches/ad_hoc/data/glade/adhoc_commands_window.glade branches/ad_hoc/src/adhoc_commands.py branches/ad_hoc/src/common/dataforms.py branches/ad_hoc/src/dataforms.py Log: Some fixes in common/dataforms, new field types... Now only jid-multi isn't handled.
Modified: branches/ad_hoc/data/glade/adhoc_commands_window.glade =================================================================== --- branches/ad_hoc/data/glade/adhoc_commands_window.glade 2006-07-08 11:51:42 UTC (rev 6541) +++ branches/ad_hoc/data/glade/adhoc_commands_window.glade 2006-07-09 17:55:56 UTC (rev 6542) @@ -28,6 +28,8 @@
<child> <widget class="GtkNotebook" id="stages_notebook"> + <property name="width_request">400</property> + <property name="height_request">400</property> <property name="visible">True</property> <property name="show_tabs">False</property> <property name="show_border">False</property> @@ -92,10 +94,56 @@ </child>
<child> + <widget class="GtkLabel" id="label264"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <placeholder/> </child>
<child> + <widget class="GtkLabel" id="label265"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <widget class="GtkVBox" id="command_list_stage_vbox"> <property name="visible">True</property> <property name="homogeneous">False</property> @@ -104,16 +152,16 @@ <child> <widget class="GtkLabel" id="label253"> <property name="visible">True</property> - <property name="label" translatable="yes">Choose command to execute:</property> + <property name="label" translatable="yes"><b>Choose command to execute:</b></property> <property name="use_underline">False</property> - <property name="use_markup">False</property> + <property name="use_markup">True</property> <property name="justify">GTK_JUSTIFY_LEFT</property> <property name="wrap">False</property> <property name="selectable">False</property> - <property name="xalign">0.5</property> + <property name="xalign">0.20000000298</property> <property name="yalign">0.5</property> <property name="xpad">0</property> - <property name="ypad">0</property> + <property name="ypad">6</property> <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> @@ -128,6 +176,7 @@
<child> <widget class="GtkVBox" id="command_list_vbox"> + <property name="border_width">12</property> <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">0</property> @@ -169,7 +218,7 @@ </widget> <packing> <property name="padding">0</property> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> </packing> </child> @@ -181,10 +230,56 @@ </child>
<child> + <widget class="GtkLabel" id="label266"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <placeholder/> </child>
<child> + <widget class="GtkLabel" id="label267"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <widget class="GtkVBox" id="sending_form_stage_vbox"> <property name="visible">True</property> <property name="homogeneous">False</property> @@ -193,9 +288,9 @@ <child> <widget class="GtkLabel" id="instructions_label"> <property name="visible">True</property> - <property name="label" translatable="yes">Fill in the form</property> + <property name="label" translatable="yes"><b>Fill in the form</b></property> <property name="use_underline">False</property> - <property name="use_markup">False</property> + <property name="use_markup">True</property> <property name="justify">GTK_JUSTIFY_LEFT</property> <property name="wrap">False</property> <property name="selectable">False</property> @@ -232,6 +327,7 @@ <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> + <property name="pack_type">GTK_PACK_END</property> </packing> </child> </widget> @@ -242,10 +338,56 @@ </child>
<child> + <widget class="GtkLabel" id="label268"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <placeholder/> </child>
<child> + <widget class="GtkLabel" id="label269"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <widget class="GtkVBox" id="no_commands_stage_vbox"> <property name="visible">True</property> <property name="homogeneous">False</property> @@ -310,8 +452,8 @@ </widget> <packing> <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> + <property name="expand">False</property> + <property name="fill">False</property> <property name="pack_type">GTK_PACK_END</property> </packing> </child> @@ -323,10 +465,56 @@ </child>
<child> + <widget class="GtkLabel" id="label270"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <placeholder/> </child>
<child> + <widget class="GtkLabel" id="label271"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <widget class="GtkVBox" id="error_stage_vbox"> <property name="visible">True</property> <property name="homogeneous">False</property> @@ -335,9 +523,9 @@ <child> <widget class="GtkLabel" id="label257"> <property name="visible">True</property> - <property name="label" translatable="yes">An error has occured:</property> + <property name="label" translatable="yes"><b>An error has occured:</b></property> <property name="use_underline">False</property> - <property name="use_markup">False</property> + <property name="use_markup">True</property> <property name="justify">GTK_JUSTIFY_LEFT</property> <property name="wrap">False</property> <property name="selectable">False</property> @@ -389,8 +577,54 @@ </child>
<child> + <widget class="GtkLabel" id="label272"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> <placeholder/> </child> + + <child> + <widget class="GtkLabel" id="label273"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> </widget> <packing> <property name="padding">0</property>
Modified: branches/ad_hoc/src/adhoc_commands.py =================================================================== --- branches/ad_hoc/src/adhoc_commands.py 2006-07-08 11:51:42 UTC (rev 6541) +++ branches/ad_hoc/src/adhoc_commands.py 2006-07-09 17:55:56 UTC (rev 6542) @@ -29,6 +29,7 @@ from common import xmpp, gajim, dataforms
import gtkgui_helpers +import dialogs import dataforms as dataformwidget
class CommandWindow: @@ -80,18 +81,12 @@ self.xml.signal_autoconnect(self) self.window.show_all()
- def on_adhoc_commands_window_destroy(self, window): - ''' The window dissappeared somehow... clean the environment, - Stop pulsing.''' - self.remove_pulsing() - # these functions are set up by appropriate stageX methods def stage_finish(self, *anything): pass def stage_cancel_button_clicked(self, *anything): assert False def stage_back_button_clicked(self, *anything): assert False def stage_forward_button_clicked(self, *anything): assert False def stage_execute_button_clicked(self, *anything): assert False - def stage_adhoc_commands_window_destroy(self, *anything): assert False def stage_adhoc_commands_window_delete_event(self, *anything): assert False def do_nothing(self, *anything): return False
@@ -109,11 +104,15 @@ return self.stage_execute_button_clicked(*anything)
def on_adhoc_commands_window_destroy(self, *anything): - return self.stage_adhoc_commands_window_destroy(*anything) + # do all actions that are needed to remove this object from memory... + self.remove_pulsing()
def on_adhoc_commands_window_delete_event(self, *anything): return self.stage_adhoc_commands_window_delete_event(self, *anything)
+ def __del__(self): + print "Object has been deleted." + # stage 1: waiting for command list def stage1(self): '''Prepare the first stage. Request command list, @@ -141,7 +140,6 @@ self.stage_finish = self.stage1_finish self.stage_cancel_button_clicked = self.stage1_cancel_button_clicked self.stage_adhoc_commands_window_delete_event = self.stage1_adhoc_commands_window_delete_event - self.stage_adhoc_commands_window_destroy = self.do_nothing
def stage1_finish(self): self.remove_pulsing() @@ -183,13 +181,12 @@ if first_radio is None: first_radio = radio self.commandnode = commandnode - self.command_list_vbox.pack_end(radio, expand=False) + self.command_list_vbox.pack_start(radio, expand=False) self.command_list_vbox.show_all()
self.stage_finish = self.stage2_finish self.stage_cancel_button_clicked = self.stage2_cancel_button_clicked self.stage_forward_button_clicked = self.stage2_forward_button_clicked - self.stage_adhoc_commands_window_destroy = self.do_nothing self.stage_adhoc_commands_window_delete_event = self.do_nothing
def stage2_finish(self): @@ -234,14 +231,29 @@ self.stage_back_button_clicked = self.stage3_back_button_clicked self.stage_forward_button_clicked = self.stage3_forward_button_clicked self.stage_execute_button_clicked = self.stage3_execute_button_clicked - self.stage_adhoc_commands_window_destroy = self.do_nothing - self.stage_adhoc_commands_window_delete_event = self.do_nothing + self.stage_adhoc_commands_window_delete_event = self.stage3_cancel_button_clicked
def stage3_finish(self): pass
- def stage3_cancel_button_clicked(self, widget): - pass + def stage3_cancel_button_clicked(self, widget, *anything): + ''' We are in the middle of executing command. Ask user if he really want to cancel + the process, then... cancel it. ''' + # this works also as a handler for window_delete_event, so we have to return appropriate + # values + # TODO: translate it + dialog = dialogs.HigDialog(self.window, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, + gtk.BUTTONS_YES_NO, 'Cancel confirmation', + 'You are in process of executing command. Do you really want to cancel it?') + dialog.popup() + if dialog.get_response()==gtk.RESPONSE_YES: + self.send_cancel() + if widget==self.window: + return False + else: + self.window.destroy() + return False + return True
def stage3_back_button_clicked(self, widget): self.stage3_submit_form('prev') @@ -256,6 +268,12 @@ self.data_form_widget.set_sensitive(False) if self.data_form_widget.get_data_form() is None: self.data_form_widget.hide() + + self.cancel_button.set_sensitive(True) + self.back_button.set_sensitive(False) + self.forward_button.set_sensitive(False) + self.execute_button.set_sensitive(False) + self.sending_form_progressbar.show() self.setup_pulsing(self.sending_form_progressbar) self.send_command(action) @@ -272,19 +290,26 @@ self.dataform = dataforms.DataForm(node=command.getTag('x'))
self.data_form_widget.set_sensitive(True) - self.data_form_widget.set_data_form(self.dataform) + try: + self.data_form_widget.data_form=self.dataform + except dataforms.BadDataFormNode: + # TODO: translate + self.stage5('Service sent malformed data', senderror=True) self.data_form_widget.show()
action = command.getTag('action') if action is None: - # no action tag? that's last stage... - self.cancel_button.set_sensitive(False) + # no action tag? check if that's last stage... + if command.getAttr('status')=='completed': + self.cancel_button.set_sensitive(False) + else: + self.cancel_button.set_sensitive(True) self.back_button.set_sensitive(False) self.forward_button.set_sensitive(False) self.execute_button.set_sensitive(True) else: # actions, actions, actions... - self.cancel_button.set_sensitive(False) + self.cancel_button.set_sensitive(True) self.back_button.set_sensitive(action.getTag('prev') is not None) self.forward_button.set_sensitive(action.getTag('next') is not None) self.execute_button.set_sensitive(True) @@ -306,7 +331,6 @@
self.stage_finish = self.do_nothing self.stage_cancel_button_clicked = self.stage4_cancel_button_clicked - self.stage_adhoc_commands_window_destroy = self.do_nothing self.stage_adhoc_commands_window_delete_event = self.do_nothing
def stage4_cancel_button_clicked(self, widget): @@ -316,12 +340,13 @@ self.stage1()
# stage 5: an error has occured - def stage5(self, error): + def stage5(self, error, senderror=False): '''Display the error message. Wait for user to close the window''' + # TODO: sending error to responder # close old stage self.stage_finish()
- assert isinstance(error, unicode) + assert isinstance(error, basestring)
self.stages_notebook.set_current_page( self.stages_notebook.page_num( @@ -336,7 +361,6 @@
self.stage_finish = self.do_nothing self.stage_cancel_button_clicked = self.stage5_cancel_button_clicked - self.stage_adhoc_commands_window_destroy = self.do_nothing self.stage_adhoc_commands_window_delete_event = self.do_nothing
def stage5_cancel_button_clicked(self, widget): @@ -419,3 +443,18 @@ print stanza
self.account.connection.SendAndCallForResponse(stanza, callback) + + def send_cancel(self): + '''Send the command with action='cancel'. ''' + assert self.commandnode is not None + assert self.sessionid is not None + + stanza = xmpp.Iq(typ='set', to=self.jid) + stanza.addChild('command', attrs={ + 'xmlns':xmpp.NS_COMMANDS, + 'node':self.commandnode, + 'sessionid':self.sessionid, + 'action':'cancel' + }) + + self.account.connection.send(stanza)
Modified: branches/ad_hoc/src/common/dataforms.py =================================================================== --- branches/ad_hoc/src/common/dataforms.py 2006-07-08 11:51:42 UTC (rev 6541) +++ branches/ad_hoc/src/common/dataforms.py 2006-07-09 17:55:56 UTC (rev 6542) @@ -78,9 +78,14 @@
if tofill is not None: self._mode = tofill.mode - self.fields = tofill.fields + self.fields = (field for field in tofill.fields if field.type!='fixed') self.records = tofill.records self.type = 'submit' + for field in self.iter_fields(): + field.required=False + del field.label + del field.options + del field.description elif node is not None: # if there is <reported/> element, the form contains multiple records if self.getTag('reported') is not None: @@ -138,7 +143,7 @@ return self.getTagData('title')
def set_title(self, title): - self.setTagData('title') + self.setTagData('title', title)
def del_title(self): try: @@ -283,11 +288,16 @@ raise KeyError, "This form does not contain %r field." % var
class DataField(xmpp.Node, object): - def __init__(self, typ='text-single', desc=None, required=None, value=None, options=None, node=None): + def __init__(self, typ=None,var=None, value=None, label=None, desc=None, + required=None, options=None, node=None): + assert typ in ('boolean', 'fixed', 'hidden', 'jid-multi', 'jid-single', 'list-multi', - 'list-single', 'text-multi', 'text-private', 'text-single', None) + 'list-single', 'text-multi', 'text-private', 'text-single',None) xmpp.Node.__init__(self, 'field', node=node) + if typ is not None: self.type = typ + if var is not None: self.var = var + if label is not None: self.label = label if desc is not None: self.description = desc if required is not None: self.required = required if value is not None: self.value = value @@ -309,7 +319,10 @@ if typ!='text-single': self.setAttr('type', typ) else: - self.delAttr('type') + try: + self.delAttr('type') + except KeyError: + pass
type = property(get_type, set_type, None, """ Field type. One of: 'boolean', 'fixed', 'hidden', 'jid-multi', 'jid-single', @@ -383,8 +396,8 @@
elif self.type in ('jid-multi', 'list-multi'): return [value.getData() for value in self.getTags('value')] - - elif self.type in ('hidden', 'jid-single', 'list-single', 'text-single', 'text-private'): + + elif self.type in ('hidden', 'jid-single', 'list-single', 'text-single', 'text-private') or True: return self.getTagData('value')
def set_value(self, value): @@ -399,8 +412,8 @@
elif self.type in ('jid-multi', 'list-multi'): del_multiple_tag_value(self, 'value') - for item in self.value: - self.addChild('value', None, (item,)) + for item in value: + self.addChild('value', {}, (item,))
elif self.type in ('hidden', 'jid-single', 'list-single', 'text-single', 'text-private'): self.setTagData('value', value) @@ -417,6 +430,7 @@ for element in self.getChildren(): if not isinstance(element, xmpp.Node): continue if not element.getName()=='option': continue + if element.getTag('value') is None: raise BadDataFormNode yield element.getAttr('label'), element.getTag('value').getData()
def get_options(self): @@ -432,10 +446,10 @@ assert option[0] is None or isinstance(option[0], unicode) assert isinstance(option[1], unicode) if option[0] is None: - attr=None + attr={} else: attr={'label': option[0].encode('utf-8')} - self.addChild('option', attr, (option[1].encode('utf-8'),)) + self.addChild('option', attr, (xmpp.Node('value', {}, (option[1].encode('utf-8'),)),))
def del_options(self): del_multiple_tag_value(self, 'option')
Modified: branches/ad_hoc/src/dataforms.py =================================================================== --- branches/ad_hoc/src/dataforms.py 2006-07-08 11:51:42 UTC (rev 6541) +++ branches/ad_hoc/src/dataforms.py 2006-07-09 17:55:56 UTC (rev 6542) @@ -52,7 +52,7 @@ else: self.form = self.__class__.MultipleForm(dataform) self.form.show() - self.container.pack_end(self.form) + self.container.pack_end(self.form, expand=True, fill=True)
def get_data_form(self): """ Data form displayed in the widget or None if no form. """ @@ -81,39 +81,39 @@ """ Treat 'us' as one widget. """ self.show_all()
- def filled_data_form(self): - """ Generates form that contains values filled by user. """ - assert isinstance(self._data_form, dataforms.DataForm) +#? def filled_data_form(self): +#? """ Generates form that contains values filled by user. """ +#? assert isinstance(self._data_form, dataforms.DataForm) +#? +#? form = xmpp.Node('x', {'xmlns':xmpp.NS_DATA, 'type':'submit'}) +#? +#? +#? for field in self._data_form.kids: +#? if not isinstance(field, xmpp.DataField): continue +#? +#? ftype = field.getType() +#? if ftype not in ('boolean', 'fixed', 'hidden', 'jid-multi', +#? 'jid-single', 'list-multi', 'list-single', +#? 'text-multi', 'text-private', 'text-single'): +#? ftype = 'text-single' +#? +#? if ftype in ('fixed',): +#? continue +#? +#? newfield = xmpp.Node('field', {'var': field.getVar()}) +#? +#? if ftype in ('jid-multi', 'list-multi', 'text-multi'): +#? for value in field.getValues(): +#? newvalue = xmpp.Node('value', {}, [value]) +#? newfield.addChild(node=newvalue) +#? else: +#? newvalue = xmpp.Node('value', {}, [field.getValue()]) +#? newfield.addChild(node=newvalue) +#? +#? form.addChild(node=newfield) +#? +#? return form
- form = xmpp.Node('x', {'xmlns':xmpp.NS_DATA, 'type':'submit'}) - - - for field in self._data_form.kids: - if not isinstance(field, xmpp.DataField): continue - - ftype = field.getType() - if ftype not in ('boolean', 'fixed', 'hidden', 'jid-multi', - 'jid-single', 'list-multi', 'list-single', - 'text-multi', 'text-private', 'text-single'): - ftype = 'text-single' - - if ftype in ('fixed',): - continue - - newfield = xmpp.Node('field', {'var': field.getVar()}) - - if ftype in ('jid-multi', 'list-multi', 'text-multi'): - for value in field.getValues(): - newvalue = xmpp.Node('value', {}, [value]) - newfield.addChild(node=newvalue) - else: - newvalue = xmpp.Node('value', {}, [field.getValue()]) - newfield.addChild(node=newvalue) - - form.addChild(node=newfield) - - return form - # "private" methods
# we have actually two different kinds of data forms: one is a simple form to fill, @@ -164,8 +164,7 @@ widget.set_line_wrap(True) self.attach(widget, leftattach, rightattach, linecounter, linecounter+1)
- elif field.type in ('jid-multi', 'jid-single', 'list-multi', 'text-multi', - 'text-private'): + elif field.type in ('jid-multi'): widget = gtk.Label(field.type)
elif field.type == 'list-single': @@ -176,7 +175,7 @@ # TODO: We cannot deactivate them all... widget = gtk.VBox() first_radio = None - for label, value in field.iter_options(): + for value, label in field.iter_options(): radio = gtk.RadioButton(first_radio, label=label) radio.connect('toggled', self.on_list_single_radiobutton_toggled, field, value) @@ -188,6 +187,41 @@ radio.set_active(True) widget.pack_start(radio, expand=False)
+ elif field.type == 'list-multi': + # TODO: When more than few choices, make a list + widget = gtk.VBox() + for value, label in field.iter_options(): + check = gtk.CheckButton(label, use_underline=False) + check.set_active(value in field.value) + check.connect('toggled', self.on_list_multi_checkbutton_toggled, + field, value) + widget.pack_start(check, expand=False) + + elif field.type == 'jid-single': + widget = gtk.Entry() + widget.connect('changed', self.on_text_single_entry_changed, field) + if field.value is None: + field.value = u'' + widget.set_text(field.value) + + elif field.type == 'text-private': + widget = gtk.Entry() + widget.connect('changed', self.on_text_single_entry_changed, field) + widget.set_visibility(False) + if field.value is None: + field.value = u'' + widget.set_text(field.value) + + elif field.type == 'text-multi': + # TODO: bigger text view + widget = gtk.TextView() + widget.set_wrap_mode(gtk.WRAP_WORD) + widget.get_buffer().connect('changed', self.on_text_multi_textbuffer_changed, + field) + if field.value is None: + field.value = u'' + widget.get_buffer().set_text(field.value) + else:# field.type == 'text-single' or field.type is nonstandard: # JEP says that if we don't understand some type, we # should handle it as text-single @@ -199,7 +233,7 @@
if commonlabel and field.label is not None: label = gtk.Label(field.label) - label.set_justify(gtk.JUSTIFY_RIGHT) + label.set_alignment(1.0, 0.5) self.attach(label, 0, 1, linecounter, linecounter+1)
if commonwidget: @@ -208,8 +242,10 @@ widget.show_all()
if commondesc and field.description is not None: - # TODO: with smaller font - label = gtk.Label(field.description) + label = gtk.Label() + label.set_markup('<small>'+\ + gtkgui_helpers.escape_for_pango_markup(field.description)+\ + '</small>') label.set_line_wrap(True) self.attach(label, 2, 3, linecounter, linecounter+1)
@@ -227,9 +263,20 @@ def on_list_single_radiobutton_toggled(self, widget, field, value): field.value = value
+ def on_list_multi_checkbutton_toggled(self, widget, field, value): + if widget.get_active() and value not in field.value: + field.value.append(value) + elif not widget.get_active() and value in field.value: + field.value.remove(value) + def on_text_single_entry_changed(self, widget, field): field.value = widget.get_text()
+ def on_text_multi_textbuffer_changed(self, widget, field): + field.value = widget.get_text( + widget.get_start_iter(), + widget.get_end_iter()) + class MultipleForm(gtk.Alignment, object): def __init__(self, dataform): assert dataform.mode==dataforms.DATAFORM_MULTIPLE