Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dataforms.py « src - dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4d82a5885bafc6d995f204e7710a993dd18fd397 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
##	dataforms.py
##
## Copyright (C) 2003-2006 Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <nkour@jabber.org>
## Copyright (C) 2005 Dimitur Kirov <dkirov@gmail.com>
## Copyright (C) 2003-2005 Vincent Hanquez <tab@snarc.org>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
""" This module contains widget that can display data form (JEP-0004). """

import gtk
import gtkgui_helpers

import common.xmpp as xmpp
import common.dataforms as dataforms

class DataFormWidget(gtk.Alignment, object):
# "public" interface
	""" Data Form widget. Use like any other widget. """
	def __init__(self, dataformnode=None):
		""" Create a widget. """
		gtk.Alignment.__init__(self)

		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.container = self.xml.get_widget('container_vbox')

		self.add(self.xml.get_widget('data_form_scrolledwindow'))

		if dataformnode is not None:
			self.set_data_form(dataformnode)

	def set_data_form(self, dataform=None):
		""" Set the data form (xmpp.DataForm) displayed in widget.
		Set to None to erase the form. """
		assert isinstance(dataform, dataforms.DataForm)

		self.del_data_form()
		self._data_form = dataform
		if dataform.mode==dataforms.DATAFORM_SINGLE:
			self.form = self.__class__.SingleForm(dataform)
		else:
			self.form = self.__class__.MultipleForm(dataform)
		self.form.show()
		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. """
		return self._data_form

	def del_data_form(self):
		if self._data_form is not None:
			self.container.remove(self.form)
		self.form = None
		self._data_form = None

	data_form = property(get_data_form, set_data_form, del_data_form,
		"Data form presented in a widget")

	def get_title(self):
		""" Get the title of data form, as a unicode object. If no
		title or no form, returns u''. Useful for setting window title. """
		if self._data_form is not None:
			if self._data_form.has_key('title'):
				return self._data_form['title'].encode('utf-8')
		return u''

	title = property(get_title, None, None, "Data form title")

	def show(self):
		""" 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,
# second is a table with several records; we will treat second as read-only, but still
# we should have a way to show it

# we will place both types in two different private classes, so the code will be clean;
# both will have the same interface

	class SingleForm(gtk.Table, object):
		""" Widget that represent DATAFORM_SINGLE mode form. """
		def __init__(self, dataform):
			assert dataform.mode==dataforms.DATAFORM_SINGLE

			gtk.Table.__init__(self)

			self._data_form = dataform

			# building widget
			linecounter = 0

			# for each field...
			for field in self._data_form.iter_fields():
				if field.type=='hidden': continue

				commonlabel = True
				commondesc = True
				commonwidget = True
				widget = None

				if field.type=='boolean':
					widget = gtk.CheckButton()
					widget.connect('toggled', self.on_boolean_checkbutton_toggled, field)
					widget.set_active(field.value)

				elif field.type=='fixed':
					leftattach = 1
					rightattach = 2
					if field.label is None:
						commonlabel = False
						leftattach = 0
					if field.description is None:
						commondesc = False
						rightattach = 3
					
					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)

				elif field.type == 'list-single':
					# TODO: When more than few choices, make a list
					# TODO: Think of moving that to another function (it could be used
					# TODO: in stage2 of adhoc commands too).
					# TODO: What if we have radio buttons and non-required field?
					# TODO: We cannot deactivate them all...
					widget = gtk.VBox()
					first_radio = None
					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)
						if first_radio is None:
							first_radio = radio
							if field.value is None:
								field.value = value
						if value == field.value:
							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
					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)

				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)

				if commonwidget:
					assert widget is not None
					self.attach(widget, 1, 2, linecounter, linecounter+1)
				widget.show_all()

				if commondesc and field.description is not None:
					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)

				linecounter+=1
			if self.get_property('visible'):
				self.show_all()

		def show(self):
			# simulate that we are one widget
			self.show_all()

		def on_boolean_checkbutton_toggled(self, widget, field):
			field.value = widget.get_active()

		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