Jid-multi almost works.
This commit is contained in:
parent
aed92d21b7
commit
db089f103d
|
@ -286,11 +286,11 @@
|
|||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="instructions_label">
|
||||
<widget class="GtkLabel" id="notes_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Fill in the form</b></property>
|
||||
<property name="label" translatable="yes">Please wait while the command is sending...</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
|
@ -651,26 +651,39 @@
|
|||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancel_button">
|
||||
<widget class="GtkHBox" id="hbox2958">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Thu, 22 Jun 2006 19:56:06 GMT"/>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancel_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:32 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">3</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="back_button">
|
||||
<property name="visible">True</property>
|
||||
|
@ -679,10 +692,10 @@
|
|||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_back_button_clicked" last_modification_time="Thu, 22 Jun 2006 19:56:13 GMT"/>
|
||||
<signal name="clicked" handler="on_back_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:50 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">3</property>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
|
@ -696,7 +709,7 @@
|
|||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_forward_button_clicked" last_modification_time="Thu, 22 Jun 2006 19:56:18 GMT"/>
|
||||
<signal name="clicked" handler="on_forward_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:47 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">3</property>
|
||||
|
@ -713,7 +726,23 @@
|
|||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_execute_button_clicked" last_modification_time="Thu, 22 Jun 2006 19:56:23 GMT"/>
|
||||
<signal name="clicked" handler="on_execute_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:42 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">3</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="close_button">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_close_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:38 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">3</property>
|
||||
|
|
|
@ -199,61 +199,214 @@
|
|||
<property name="focus_on_map">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="data_form_scrolledwindow">
|
||||
<widget class="GtkVBox" id="vbox111">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">10</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="container_vbox">
|
||||
<property name="border_width">5</property>
|
||||
<widget class="GtkScrolledWindow" id="data_form_scrolledwindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="form_instructions_label">
|
||||
<widget class="GtkViewport" id="viewport2">
|
||||
<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">True</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</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="padding">5</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHSeparator" id="hseparator16">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">5</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="container_vbox">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">5</property>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="form_instructions_label">
|
||||
<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">True</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</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="padding">5</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHSeparator" id="form_instructions_hseparator">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">5</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTable" id="item_list_table">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">1</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="row_spacing">0</property>
|
||||
<property name="column_spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow36">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="item_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">True</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox112">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="clear_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-clear</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="remove_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-remove</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="add_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-add</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="edit_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-edit</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options">fill</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
|
|
@ -61,11 +61,11 @@ class CommandWindow:
|
|||
self.xml = gtkgui_helpers.get_glade('adhoc_commands_window.glade')
|
||||
self.window = self.xml.get_widget('adhoc_commands_window')
|
||||
for name in ('cancel_button', 'back_button', 'forward_button',
|
||||
'execute_button','stages_notebook',
|
||||
'execute_button','close_button','stages_notebook',
|
||||
'retrieving_commands_stage_vbox',
|
||||
'command_list_stage_vbox','command_list_vbox',
|
||||
'sending_form_stage_vbox','sending_form_progressbar',
|
||||
'no_commands_stage_vbox','error_stage_vbox',
|
||||
'notes_label','no_commands_stage_vbox','error_stage_vbox',
|
||||
'error_description_label'):
|
||||
self.__dict__[name] = self.xml.get_widget(name)
|
||||
|
||||
|
@ -75,6 +75,7 @@ class CommandWindow:
|
|||
self.sending_form_stage_vbox.pack_start(self.data_form_widget)
|
||||
|
||||
# setting initial stage
|
||||
self.close_button.set_no_show_all(True)
|
||||
self.stage1()
|
||||
|
||||
# displaying the window
|
||||
|
@ -87,6 +88,7 @@ class CommandWindow:
|
|||
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_close_button_clicked(self, *anything): assert False
|
||||
def stage_adhoc_commands_window_delete_event(self, *anything): assert False
|
||||
def do_nothing(self, *anything): return False
|
||||
|
||||
|
@ -103,8 +105,11 @@ class CommandWindow:
|
|||
def on_execute_button_clicked(self, *anything):
|
||||
return self.stage_execute_button_clicked(*anything)
|
||||
|
||||
def on_close_button_clicked(self, *anything):
|
||||
return self.stage_close_button_clicked(*anything)
|
||||
|
||||
def on_adhoc_commands_window_destroy(self, *anything):
|
||||
# do all actions that are needed to remove this object from memory...
|
||||
# TODO: do all actions that are needed to remove this object from memory...
|
||||
self.remove_pulsing()
|
||||
|
||||
def on_adhoc_commands_window_delete_event(self, *anything):
|
||||
|
@ -215,6 +220,8 @@ class CommandWindow:
|
|||
|
||||
assert isinstance(self.commandnode, unicode)
|
||||
|
||||
self.form_status = None
|
||||
|
||||
self.stages_notebook.set_current_page(
|
||||
self.stages_notebook.page_num(
|
||||
self.sending_form_stage_vbox))
|
||||
|
@ -231,6 +238,7 @@ class CommandWindow:
|
|||
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_close_button_clicked = self.stage3_close_button_clicked
|
||||
self.stage_adhoc_commands_window_delete_event = self.stage3_cancel_button_clicked
|
||||
|
||||
def stage3_finish(self):
|
||||
|
@ -255,6 +263,14 @@ class CommandWindow:
|
|||
return False
|
||||
return True
|
||||
|
||||
def stage3_close_button_clicked(self, widget):
|
||||
# this works also as a handler for window_delete_event, so we have to return appropriate
|
||||
# values
|
||||
if widget==self.window:
|
||||
return False
|
||||
else:
|
||||
self.window.destroy()
|
||||
|
||||
def stage3_back_button_clicked(self, widget):
|
||||
self.stage3_submit_form('prev')
|
||||
|
||||
|
@ -287,23 +303,24 @@ class CommandWindow:
|
|||
if self.sessionid is None:
|
||||
self.sessionid = command.getAttr('sessionid')
|
||||
|
||||
self.dataform = dataforms.DataForm(node=command.getTag('x'))
|
||||
self.form_status = command.getAttr('status')
|
||||
|
||||
self.data_form_widget.set_sensitive(True)
|
||||
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()
|
||||
if command.getTag('x') is not None:
|
||||
self.dataform = dataforms.DataForm(node=command.getTag('x'))
|
||||
|
||||
self.data_form_widget.set_sensitive(True)
|
||||
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()
|
||||
else:
|
||||
self.data_form_widget.hide()
|
||||
|
||||
action = command.getTag('action')
|
||||
if action is None:
|
||||
# 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.cancel_button.set_sensitive(True)
|
||||
self.back_button.set_sensitive(False)
|
||||
self.forward_button.set_sensitive(False)
|
||||
self.execute_button.set_sensitive(True)
|
||||
|
@ -314,6 +331,25 @@ class CommandWindow:
|
|||
self.forward_button.set_sensitive(action.getTag('next') is not None)
|
||||
self.execute_button.set_sensitive(True)
|
||||
|
||||
if self.form_status == 'completed':
|
||||
self.cancel_button.set_sensitive(False)
|
||||
self.back_button.set_sensitive(False)
|
||||
self.forward_button.set_sensitive(False)
|
||||
self.execute_button.set_no_show_all(True)
|
||||
self.execute_button.hide()
|
||||
self.close_button.set_no_show_all(False)
|
||||
self.close_button.show()
|
||||
self.stage_adhoc_commands_window_delete_event = self.stage3_close_button_clicked
|
||||
|
||||
note = command.getTag('note')
|
||||
if note is not None:
|
||||
self.notes_label.set_text(note.getData().decode('utf-8'))
|
||||
self.notes_label.set_no_show_all(False)
|
||||
self.notes_label.show()
|
||||
else:
|
||||
self.notes_label.set_no_show_all(True)
|
||||
self.notes_label.hide()
|
||||
|
||||
# stage 4: no commands are exposed
|
||||
def stage4(self):
|
||||
'''Display the message. Wait for user to close the window'''
|
||||
|
|
|
@ -249,7 +249,7 @@ class DataForm(xmpp.Node, object):
|
|||
self.delChild('recorded')
|
||||
except ValueError:
|
||||
pass
|
||||
self.addChild('recorded', None, fields)
|
||||
self.addChild('recorded', {}, fields)
|
||||
|
||||
def del_fields(self):
|
||||
if self.mode is DATAFORM_SINGLE:
|
||||
|
@ -335,7 +335,10 @@ class DataField(xmpp.Node, object):
|
|||
self.setAttr('var', var)
|
||||
|
||||
def del_var(self):
|
||||
self.delAttr('var')
|
||||
try:
|
||||
self.delAttr('var')
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
var = property(get_var, set_var, del_var,
|
||||
""" Field name. """)
|
||||
|
@ -347,7 +350,10 @@ class DataField(xmpp.Node, object):
|
|||
self.setAttr('label', label)
|
||||
|
||||
def del_label(self):
|
||||
self.delAttr('label')
|
||||
try:
|
||||
self.delAttr('label')
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
label = property(get_label, set_label, del_label,
|
||||
""" Human-readable name for field. """)
|
||||
|
@ -384,6 +390,14 @@ class DataField(xmpp.Node, object):
|
|||
required = property(get_required, set_required, None,
|
||||
""" If this is set to True, the field is required for form to be valid. """)
|
||||
|
||||
def iter_values(self):
|
||||
assert self.type in ('list-single', 'list-multi', 'jid-multi')
|
||||
|
||||
for element in self.getChildren():
|
||||
if not isinstance(element, xmpp.Node): continue
|
||||
if not element.getName()=='value': continue
|
||||
yield element.getData().decode('utf-8')
|
||||
|
||||
def get_value(self):
|
||||
if self.type in ('boolean',):
|
||||
if self.getTagData('value') in (1, 'true'):
|
||||
|
@ -430,8 +444,10 @@ class DataField(xmpp.Node, object):
|
|||
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()
|
||||
try:
|
||||
yield element.getAttr('label'), element.getTag('value').getData()
|
||||
except TypeError:
|
||||
raise BadDataFormNode
|
||||
|
||||
def get_options(self):
|
||||
""" Returns a list of tuples: (label, value). """
|
||||
|
|
148
src/dataforms.py
148
src/dataforms.py
|
@ -17,6 +17,8 @@
|
|||
""" This module contains widget that can display data form (JEP-0004). """
|
||||
|
||||
import gtk
|
||||
import pango
|
||||
|
||||
import gtkgui_helpers
|
||||
|
||||
import common.xmpp as xmpp
|
||||
|
@ -27,12 +29,13 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
""" Data Form widget. Use like any other widget. """
|
||||
def __init__(self, dataformnode=None):
|
||||
""" Create a widget. """
|
||||
gtk.Alignment.__init__(self)
|
||||
gtk.Alignment.__init__(self, xscale=1.0, yscale=1.0)
|
||||
|
||||
self._data_form = None
|
||||
|
||||
self.xml=gtkgui_helpers.get_glade('data_form_window.glade', 'data_form_scrolledwindow')
|
||||
self.instructions = self.xml.get_widget('form_instructions_label')
|
||||
self.separator = self.xml.get_widget('form_instructions_hseparator')
|
||||
self.container = self.xml.get_widget('container_vbox')
|
||||
|
||||
self.add(self.xml.get_widget('data_form_scrolledwindow'))
|
||||
|
@ -54,6 +57,18 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
self.form.show()
|
||||
self.container.pack_end(self.form, expand=True, fill=True)
|
||||
|
||||
if dataform.instructions is None:
|
||||
self.instructions.set_no_show_all(True)
|
||||
self.instructions.hide()
|
||||
self.separator.set_no_show_all(True)
|
||||
self.separator.hide()
|
||||
else:
|
||||
self.instructions.set_text(dataform.instructions)
|
||||
self.instructions.set_no_show_all(False)
|
||||
self.instructions.show()
|
||||
self.separator.set_no_show_all(False)
|
||||
self.separator.show()
|
||||
|
||||
def get_data_form(self):
|
||||
""" Data form displayed in the widget or None if no form. """
|
||||
return self._data_form
|
||||
|
@ -81,39 +96,6 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
""" 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)
|
||||
#?
|
||||
#? 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,
|
||||
|
@ -129,6 +111,8 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
assert dataform.mode==dataforms.DATAFORM_SINGLE
|
||||
|
||||
gtk.Table.__init__(self)
|
||||
self.set_col_spacings(6)
|
||||
self.set_row_spacings(6)
|
||||
|
||||
self._data_form = dataform
|
||||
|
||||
|
@ -162,10 +146,8 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
commonwidget=False
|
||||
widget = gtk.Label(field.value)
|
||||
widget.set_line_wrap(True)
|
||||
self.attach(widget, leftattach, rightattach, linecounter, linecounter+1)
|
||||
|
||||
elif field.type in ('jid-multi'):
|
||||
widget = gtk.Label(field.type)
|
||||
self.attach(widget, leftattach, rightattach, linecounter, linecounter+1,
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
|
||||
elif field.type == 'list-single':
|
||||
# TODO: When more than few choices, make a list
|
||||
|
@ -204,6 +186,42 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
field.value = u''
|
||||
widget.set_text(field.value)
|
||||
|
||||
elif field.type == 'jid-multi':
|
||||
commonwidget = False
|
||||
|
||||
xml = gtkgui_helpers.get_glade('data_form_window.glade', 'item_list_table')
|
||||
widget = xml.get_widget('item_list_table')
|
||||
treeview = xml.get_widget('item_treeview')
|
||||
|
||||
listmodel = gtk.ListStore(str, bool)
|
||||
for value in field.iter_values():
|
||||
# nobody will create several megabytes long stanza
|
||||
listmodel.insert(999999, (value,False))
|
||||
|
||||
treeview.set_model(listmodel)
|
||||
|
||||
renderer = gtk.CellRendererText()
|
||||
renderer.set_property('ellipsize', pango.ELLIPSIZE_START)
|
||||
renderer.set_property('editable', True)
|
||||
renderer.connect('edited',
|
||||
self.on_jid_multi_cellrenderertext_edited, listmodel, field)
|
||||
|
||||
treeview.append_column(gtk.TreeViewColumn(None, renderer,
|
||||
text=0, editable=1))
|
||||
|
||||
xml.get_widget('add_button').connect('clicked',
|
||||
self.on_jid_multi_add_button_clicked, listmodel, field)
|
||||
xml.get_widget('edit_button').connect('clicked',
|
||||
self.on_jid_multi_edit_button_clicked, treeview)
|
||||
xml.get_widget('remove_button').connect('clicked',
|
||||
self.on_jid_multi_remove_button_clicked, treeview)
|
||||
xml.get_widget('clear_button').connect('clicked',
|
||||
self.on_jid_multi_clean_button_clicked, listmodel, field)
|
||||
|
||||
self.attach(widget, 1, 2, linecounter, linecounter+1)
|
||||
|
||||
del xml
|
||||
|
||||
elif field.type == 'text-private':
|
||||
widget = gtk.Entry()
|
||||
widget.connect('changed', self.on_text_single_entry_changed, field)
|
||||
|
@ -214,13 +232,20 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
|
||||
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,
|
||||
commonwidget = False
|
||||
|
||||
textwidget = gtk.TextView()
|
||||
textwidget.set_wrap_mode(gtk.WRAP_WORD)
|
||||
textwidget.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)
|
||||
textwidget.get_buffer().set_text(field.value)
|
||||
|
||||
widget = gtk.ScrolledWindow()
|
||||
widget.add(textwidget)
|
||||
|
||||
self.attach(widget, 1, 2, linecounter, linecounter+1)
|
||||
|
||||
else:# field.type == 'text-single' or field.type is nonstandard:
|
||||
# JEP says that if we don't understand some type, we
|
||||
|
@ -234,11 +259,13 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
if commonlabel and field.label is not None:
|
||||
label = gtk.Label(field.label)
|
||||
label.set_alignment(1.0, 0.5)
|
||||
self.attach(label, 0, 1, linecounter, linecounter+1)
|
||||
self.attach(label, 0, 1, linecounter, linecounter+1,
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
|
||||
if commonwidget:
|
||||
assert widget is not None
|
||||
self.attach(widget, 1, 2, linecounter, linecounter+1)
|
||||
self.attach(widget, 1, 2, linecounter, linecounter+1,
|
||||
yoptions=gtk.FILL)
|
||||
widget.show_all()
|
||||
|
||||
if commondesc and field.description is not None:
|
||||
|
@ -247,7 +274,8 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
gtkgui_helpers.escape_for_pango_markup(field.description)+\
|
||||
'</small>')
|
||||
label.set_line_wrap(True)
|
||||
self.attach(label, 2, 3, linecounter, linecounter+1)
|
||||
self.attach(label, 2, 3, linecounter, linecounter+1,
|
||||
xoptions=gtk.FILL|gtk.SHRINK, yoptions=gtk.FILL|gtk.SHRINK)
|
||||
|
||||
linecounter+=1
|
||||
if self.get_property('visible'):
|
||||
|
@ -264,10 +292,11 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
field.value = value
|
||||
|
||||
def on_list_multi_checkbutton_toggled(self, widget, field, value):
|
||||
# TODO: make some methods like add_value and remove_value
|
||||
if widget.get_active() and value not in field.value:
|
||||
field.value.append(value)
|
||||
field.value += [value]
|
||||
elif not widget.get_active() and value in field.value:
|
||||
field.value.remove(value)
|
||||
field.value = [v for v in field.value if v!=value]
|
||||
|
||||
def on_text_single_entry_changed(self, widget, field):
|
||||
field.value = widget.get_text()
|
||||
|
@ -277,6 +306,31 @@ class DataFormWidget(gtk.Alignment, object):
|
|||
widget.get_start_iter(),
|
||||
widget.get_end_iter())
|
||||
|
||||
def on_jid_multi_cellrenderertext_edited(self, cell, path, newtext, model, field):
|
||||
old=model[path][0]
|
||||
model[path][0]=newtext
|
||||
|
||||
values = field.values
|
||||
values[values.index(old)]=newtext
|
||||
field.values = values
|
||||
|
||||
def on_jid_multi_add_button_clicked(self, widget, model, field):
|
||||
iter = model.insert(999999, ("new@jid",))
|
||||
field.value += ["new@jid"]
|
||||
|
||||
def on_jid_multi_edit_button_clicked(self, widget, treeview):
|
||||
model, iter = treeview.get_selection().get_selected()
|
||||
assert iter is not None
|
||||
|
||||
model[iter][1]=True
|
||||
|
||||
def on_jid_multi_remove_button_clicked(self, widget, model, field):
|
||||
pass
|
||||
|
||||
def on_jid_multi_clean_button_clicked(self, widget, model, field):
|
||||
model.clear()
|
||||
del field.value
|
||||
|
||||
class MultipleForm(gtk.Alignment, object):
|
||||
def __init__(self, dataform):
|
||||
assert dataform.mode==dataforms.DATAFORM_MULTIPLE
|
||||
|
|
Loading…
Reference in New Issue