Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/xdata.c @ 15374:5fe8042783c1
Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sat, 20 Jan 2007 02:32:10 +0000 |
parents | |
children | 32c366eeeb99 |
comparison
equal
deleted
inserted
replaced
15373:f79e0f4df793 | 15374:5fe8042783c1 |
---|---|
1 /* | |
2 * gaim - Jabber Protocol Plugin | |
3 * | |
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 #include "internal.h" | |
22 #include "request.h" | |
23 #include "server.h" | |
24 | |
25 #include "xdata.h" | |
26 | |
27 typedef enum { | |
28 JABBER_X_DATA_IGNORE = 0, | |
29 JABBER_X_DATA_TEXT_SINGLE, | |
30 JABBER_X_DATA_TEXT_MULTI, | |
31 JABBER_X_DATA_LIST_SINGLE, | |
32 JABBER_X_DATA_LIST_MULTI, | |
33 JABBER_X_DATA_BOOLEAN, | |
34 JABBER_X_DATA_JID_SINGLE | |
35 } jabber_x_data_field_type; | |
36 | |
37 struct jabber_x_data_data { | |
38 GHashTable *fields; | |
39 GSList *values; | |
40 jabber_x_data_cb cb; | |
41 gpointer user_data; | |
42 JabberStream *js; | |
43 }; | |
44 | |
45 static void jabber_x_data_ok_cb(struct jabber_x_data_data *data, GaimRequestFields *fields) { | |
46 xmlnode *result = xmlnode_new("x"); | |
47 jabber_x_data_cb cb = data->cb; | |
48 gpointer user_data = data->user_data; | |
49 JabberStream *js = data->js; | |
50 GList *groups, *flds; | |
51 | |
52 xmlnode_set_namespace(result, "jabber:x:data"); | |
53 xmlnode_set_attrib(result, "type", "submit"); | |
54 | |
55 for(groups = gaim_request_fields_get_groups(fields); groups; groups = groups->next) { | |
56 for(flds = gaim_request_field_group_get_fields(groups->data); flds; flds = flds->next) { | |
57 xmlnode *fieldnode, *valuenode; | |
58 GaimRequestField *field = flds->data; | |
59 const char *id = gaim_request_field_get_id(field); | |
60 jabber_x_data_field_type type = GPOINTER_TO_INT(g_hash_table_lookup(data->fields, id)); | |
61 | |
62 switch(type) { | |
63 case JABBER_X_DATA_TEXT_SINGLE: | |
64 case JABBER_X_DATA_JID_SINGLE: | |
65 { | |
66 const char *value = gaim_request_field_string_get_value(field); | |
67 fieldnode = xmlnode_new_child(result, "field"); | |
68 xmlnode_set_attrib(fieldnode, "var", id); | |
69 valuenode = xmlnode_new_child(fieldnode, "value"); | |
70 if(value) | |
71 xmlnode_insert_data(valuenode, value, -1); | |
72 break; | |
73 } | |
74 case JABBER_X_DATA_TEXT_MULTI: | |
75 { | |
76 char **pieces, **p; | |
77 const char *value = gaim_request_field_string_get_value(field); | |
78 fieldnode = xmlnode_new_child(result, "field"); | |
79 xmlnode_set_attrib(fieldnode, "var", id); | |
80 | |
81 pieces = g_strsplit(value, "\n", -1); | |
82 for(p = pieces; *p != NULL; p++) { | |
83 valuenode = xmlnode_new_child(fieldnode, "value"); | |
84 xmlnode_insert_data(valuenode, *p, -1); | |
85 } | |
86 g_strfreev(pieces); | |
87 } | |
88 break; | |
89 case JABBER_X_DATA_LIST_SINGLE: | |
90 case JABBER_X_DATA_LIST_MULTI: | |
91 { | |
92 const GList *selected = gaim_request_field_list_get_selected(field); | |
93 char *value; | |
94 fieldnode = xmlnode_new_child(result, "field"); | |
95 xmlnode_set_attrib(fieldnode, "var", id); | |
96 | |
97 while(selected) { | |
98 value = gaim_request_field_list_get_data(field, selected->data); | |
99 valuenode = xmlnode_new_child(fieldnode, "value"); | |
100 if(value) | |
101 xmlnode_insert_data(valuenode, value, -1); | |
102 selected = selected->next; | |
103 } | |
104 } | |
105 break; | |
106 case JABBER_X_DATA_BOOLEAN: | |
107 fieldnode = xmlnode_new_child(result, "field"); | |
108 xmlnode_set_attrib(fieldnode, "var", id); | |
109 valuenode = xmlnode_new_child(fieldnode, "value"); | |
110 if(gaim_request_field_bool_get_value(field)) | |
111 xmlnode_insert_data(valuenode, "1", -1); | |
112 else | |
113 xmlnode_insert_data(valuenode, "0", -1); | |
114 break; | |
115 case JABBER_X_DATA_IGNORE: | |
116 break; | |
117 } | |
118 } | |
119 } | |
120 | |
121 g_hash_table_destroy(data->fields); | |
122 while(data->values) { | |
123 g_free(data->values->data); | |
124 data->values = g_slist_delete_link(data->values, data->values); | |
125 } | |
126 g_free(data); | |
127 | |
128 cb(js, result, user_data); | |
129 } | |
130 | |
131 static void jabber_x_data_cancel_cb(struct jabber_x_data_data *data, GaimRequestFields *fields) { | |
132 xmlnode *result = xmlnode_new("x"); | |
133 jabber_x_data_cb cb = data->cb; | |
134 gpointer user_data = data->user_data; | |
135 JabberStream *js = data->js; | |
136 g_hash_table_destroy(data->fields); | |
137 while(data->values) { | |
138 g_free(data->values->data); | |
139 data->values = g_slist_delete_link(data->values, data->values); | |
140 } | |
141 g_free(data); | |
142 | |
143 xmlnode_set_namespace(result, "jabber:x:data"); | |
144 xmlnode_set_attrib(result, "type", "cancel"); | |
145 | |
146 cb(js, result, user_data); | |
147 } | |
148 | |
149 void *jabber_x_data_request(JabberStream *js, xmlnode *packet, jabber_x_data_cb cb, gpointer user_data) | |
150 { | |
151 void *handle; | |
152 xmlnode *fn, *x; | |
153 GaimRequestFields *fields; | |
154 GaimRequestFieldGroup *group; | |
155 GaimRequestField *field; | |
156 | |
157 char *title = NULL; | |
158 char *instructions = NULL; | |
159 | |
160 struct jabber_x_data_data *data = g_new0(struct jabber_x_data_data, 1); | |
161 | |
162 data->fields = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); | |
163 data->user_data = user_data; | |
164 data->cb = cb; | |
165 data->js = js; | |
166 | |
167 fields = gaim_request_fields_new(); | |
168 group = gaim_request_field_group_new(NULL); | |
169 gaim_request_fields_add_group(fields, group); | |
170 | |
171 for(fn = xmlnode_get_child(packet, "field"); fn; fn = xmlnode_get_next_twin(fn)) { | |
172 xmlnode *valuenode; | |
173 const char *type = xmlnode_get_attrib(fn, "type"); | |
174 const char *label = xmlnode_get_attrib(fn, "label"); | |
175 const char *var = xmlnode_get_attrib(fn, "var"); | |
176 char *value = NULL; | |
177 | |
178 if(!type) | |
179 continue; | |
180 | |
181 if(!var && strcmp(type, "fixed")) | |
182 continue; | |
183 if(!label) | |
184 label = var; | |
185 | |
186 if((valuenode = xmlnode_get_child(fn, "value"))) | |
187 value = xmlnode_get_data(valuenode); | |
188 | |
189 | |
190 /* XXX: handle <required/> */ | |
191 | |
192 if(!strcmp(type, "text-private")) { | |
193 if((valuenode = xmlnode_get_child(fn, "value"))) | |
194 value = xmlnode_get_data(valuenode); | |
195 | |
196 field = gaim_request_field_string_new(var, label, | |
197 value ? value : "", FALSE); | |
198 gaim_request_field_string_set_masked(field, TRUE); | |
199 gaim_request_field_group_add_field(group, field); | |
200 | |
201 g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_SINGLE)); | |
202 | |
203 if(value) | |
204 g_free(value); | |
205 } else if(!strcmp(type, "text-multi") || !strcmp(type, "jid-multi")) { | |
206 GString *str = g_string_new(""); | |
207 | |
208 for(valuenode = xmlnode_get_child(fn, "value"); valuenode; | |
209 valuenode = xmlnode_get_next_twin(valuenode)) { | |
210 | |
211 if(!(value = xmlnode_get_data(valuenode))) | |
212 continue; | |
213 | |
214 g_string_append_printf(str, "%s\n", value); | |
215 g_free(value); | |
216 } | |
217 | |
218 field = gaim_request_field_string_new(var, label, | |
219 str->str, TRUE); | |
220 gaim_request_field_group_add_field(group, field); | |
221 | |
222 g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_MULTI)); | |
223 | |
224 g_string_free(str, TRUE); | |
225 } else if(!strcmp(type, "list-single") || !strcmp(type, "list-multi")) { | |
226 xmlnode *optnode; | |
227 GList *selected = NULL; | |
228 | |
229 field = gaim_request_field_list_new(var, label); | |
230 | |
231 if(!strcmp(type, "list-multi")) { | |
232 gaim_request_field_list_set_multi_select(field, TRUE); | |
233 g_hash_table_replace(data->fields, g_strdup(var), | |
234 GINT_TO_POINTER(JABBER_X_DATA_LIST_MULTI)); | |
235 } else { | |
236 g_hash_table_replace(data->fields, g_strdup(var), | |
237 GINT_TO_POINTER(JABBER_X_DATA_LIST_SINGLE)); | |
238 } | |
239 | |
240 for(valuenode = xmlnode_get_child(fn, "value"); valuenode; | |
241 valuenode = xmlnode_get_next_twin(valuenode)) { | |
242 selected = g_list_prepend(selected, xmlnode_get_data(valuenode)); | |
243 } | |
244 | |
245 for(optnode = xmlnode_get_child(fn, "option"); optnode; | |
246 optnode = xmlnode_get_next_twin(optnode)) { | |
247 const char *lbl; | |
248 | |
249 if(!(valuenode = xmlnode_get_child(optnode, "value"))) | |
250 continue; | |
251 | |
252 if(!(value = xmlnode_get_data(valuenode))) | |
253 continue; | |
254 | |
255 if(!(lbl = xmlnode_get_attrib(optnode, "label"))) | |
256 label = value; | |
257 | |
258 data->values = g_slist_prepend(data->values, value); | |
259 | |
260 gaim_request_field_list_add(field, lbl, value); | |
261 if(g_list_find_custom(selected, value, (GCompareFunc)strcmp)) | |
262 gaim_request_field_list_add_selected(field, lbl); | |
263 } | |
264 gaim_request_field_group_add_field(group, field); | |
265 | |
266 while(selected) { | |
267 g_free(selected->data); | |
268 selected = g_list_delete_link(selected, selected); | |
269 } | |
270 | |
271 } else if(!strcmp(type, "boolean")) { | |
272 gboolean def = FALSE; | |
273 | |
274 if((valuenode = xmlnode_get_child(fn, "value"))) | |
275 value = xmlnode_get_data(valuenode); | |
276 | |
277 if(value && (!g_ascii_strcasecmp(value, "yes") || | |
278 !g_ascii_strcasecmp(value, "true") || !g_ascii_strcasecmp(value, "1"))) | |
279 def = TRUE; | |
280 | |
281 field = gaim_request_field_bool_new(var, label, def); | |
282 gaim_request_field_group_add_field(group, field); | |
283 | |
284 g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_BOOLEAN)); | |
285 | |
286 if(value) | |
287 g_free(value); | |
288 } else if(!strcmp(type, "fixed") && value) { | |
289 if((valuenode = xmlnode_get_child(fn, "value"))) | |
290 value = xmlnode_get_data(valuenode); | |
291 | |
292 field = gaim_request_field_label_new("", value); | |
293 gaim_request_field_group_add_field(group, field); | |
294 | |
295 if(value) | |
296 g_free(value); | |
297 } else if(!strcmp(type, "hidden")) { | |
298 if((valuenode = xmlnode_get_child(fn, "value"))) | |
299 value = xmlnode_get_data(valuenode); | |
300 | |
301 field = gaim_request_field_string_new(var, "", value ? value : "", | |
302 FALSE); | |
303 gaim_request_field_set_visible(field, FALSE); | |
304 gaim_request_field_group_add_field(group, field); | |
305 | |
306 g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_SINGLE)); | |
307 | |
308 if(value) | |
309 g_free(value); | |
310 } else { /* text-single, jid-single, and the default */ | |
311 if((valuenode = xmlnode_get_child(fn, "value"))) | |
312 value = xmlnode_get_data(valuenode); | |
313 | |
314 field = gaim_request_field_string_new(var, label, | |
315 value ? value : "", FALSE); | |
316 gaim_request_field_group_add_field(group, field); | |
317 | |
318 if(!strcmp(type, "jid-single")) { | |
319 gaim_request_field_set_type_hint(field, "screenname"); | |
320 g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_JID_SINGLE)); | |
321 } else { | |
322 g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_SINGLE)); | |
323 } | |
324 | |
325 if(value) | |
326 g_free(value); | |
327 } | |
328 } | |
329 | |
330 if((x = xmlnode_get_child(packet, "title"))) | |
331 title = xmlnode_get_data(x); | |
332 | |
333 if((x = xmlnode_get_child(packet, "instructions"))) | |
334 instructions = xmlnode_get_data(x); | |
335 | |
336 handle = gaim_request_fields(js->gc, title, title, instructions, fields, | |
337 _("OK"), G_CALLBACK(jabber_x_data_ok_cb), | |
338 _("Cancel"), G_CALLBACK(jabber_x_data_cancel_cb), data); | |
339 | |
340 if(title) | |
341 g_free(title); | |
342 if(instructions) | |
343 g_free(instructions); | |
344 | |
345 return handle; | |
346 } | |
347 | |
348 |