Mercurial > pidgin.yaz
comparison pidgin/gtkrequest.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 | 9c0cf4db1f4d |
comparison
equal
deleted
inserted
replaced
15373:f79e0f4df793 | 15374:5fe8042783c1 |
---|---|
1 /** | |
2 * @file gtkrequest.c GTK+ Request API | |
3 * @ingroup gtkui | |
4 * | |
5 * gaim | |
6 * | |
7 * Gaim is the legal property of its developers, whose names are too numerous | |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
25 #include "internal.h" | |
26 #include "gtkgaim.h" | |
27 | |
28 #include "prefs.h" | |
29 #include "util.h" | |
30 | |
31 #include "gtkimhtml.h" | |
32 #include "gtkimhtmltoolbar.h" | |
33 #include "gtkrequest.h" | |
34 #include "gtkutils.h" | |
35 #include "gaimstock.h" | |
36 | |
37 #include <gdk/gdkkeysyms.h> | |
38 | |
39 static GtkWidget * create_account_field(GaimRequestField *field); | |
40 | |
41 typedef struct | |
42 { | |
43 GaimRequestType type; | |
44 | |
45 void *user_data; | |
46 GtkWidget *dialog; | |
47 | |
48 GtkWidget *ok_button; | |
49 | |
50 size_t cb_count; | |
51 GCallback *cbs; | |
52 | |
53 union | |
54 { | |
55 struct | |
56 { | |
57 GtkWidget *entry; | |
58 | |
59 gboolean multiline; | |
60 gchar *hint; | |
61 | |
62 } input; | |
63 | |
64 struct | |
65 { | |
66 GaimRequestFields *fields; | |
67 | |
68 } multifield; | |
69 | |
70 struct | |
71 { | |
72 gboolean savedialog; | |
73 gchar *name; | |
74 | |
75 } file; | |
76 | |
77 } u; | |
78 | |
79 } GaimGtkRequestData; | |
80 | |
81 static void | |
82 generic_response_start(GaimGtkRequestData *data) | |
83 { | |
84 g_return_if_fail(data != NULL); | |
85 | |
86 /* Tell the user we're doing something. */ | |
87 gaim_gtk_set_cursor(GTK_WIDGET(data->dialog), GDK_WATCH); | |
88 } | |
89 | |
90 static void | |
91 input_response_cb(GtkDialog *dialog, gint id, GaimGtkRequestData *data) | |
92 { | |
93 const char *value; | |
94 char *multiline_value = NULL; | |
95 | |
96 generic_response_start(data); | |
97 | |
98 if (data->u.input.multiline) { | |
99 GtkTextIter start_iter, end_iter; | |
100 GtkTextBuffer *buffer = | |
101 gtk_text_view_get_buffer(GTK_TEXT_VIEW(data->u.input.entry)); | |
102 | |
103 gtk_text_buffer_get_start_iter(buffer, &start_iter); | |
104 gtk_text_buffer_get_end_iter(buffer, &end_iter); | |
105 | |
106 if ((data->u.input.hint != NULL) && (!strcmp(data->u.input.hint, "html"))) | |
107 multiline_value = gtk_imhtml_get_markup(GTK_IMHTML(data->u.input.entry)); | |
108 else | |
109 multiline_value = gtk_text_buffer_get_text(buffer, &start_iter, &end_iter, | |
110 FALSE); | |
111 | |
112 value = multiline_value; | |
113 } | |
114 else | |
115 value = gtk_entry_get_text(GTK_ENTRY(data->u.input.entry)); | |
116 | |
117 if (id < data->cb_count && data->cbs[id] != NULL) | |
118 ((GaimRequestInputCb)data->cbs[id])(data->user_data, value); | |
119 else if (data->cbs[1] != NULL) | |
120 ((GaimRequestInputCb)data->cbs[1])(data->user_data, value); | |
121 | |
122 if (data->u.input.multiline) | |
123 g_free(multiline_value); | |
124 | |
125 gaim_request_close(GAIM_REQUEST_INPUT, data); | |
126 } | |
127 | |
128 static void | |
129 action_response_cb(GtkDialog *dialog, gint id, GaimGtkRequestData *data) | |
130 { | |
131 generic_response_start(data); | |
132 | |
133 if (id < data->cb_count && data->cbs[id] != NULL) | |
134 ((GaimRequestActionCb)data->cbs[id])(data->user_data, id); | |
135 | |
136 gaim_request_close(GAIM_REQUEST_INPUT, data); | |
137 } | |
138 | |
139 | |
140 static void | |
141 choice_response_cb(GtkDialog *dialog, gint id, GaimGtkRequestData *data) | |
142 { | |
143 GtkWidget *radio = g_object_get_data(G_OBJECT(dialog), "radio"); | |
144 GSList *group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); | |
145 | |
146 generic_response_start(data); | |
147 | |
148 if (id < data->cb_count && data->cbs[id] != NULL) | |
149 while (group) { | |
150 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(group->data))) { | |
151 ((GaimRequestChoiceCb)data->cbs[id])(data->user_data, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(group->data), "choice_id"))); | |
152 break; | |
153 } | |
154 group = group->next; | |
155 } | |
156 gaim_request_close(GAIM_REQUEST_INPUT, data); | |
157 } | |
158 | |
159 static gboolean | |
160 field_string_focus_out_cb(GtkWidget *entry, GdkEventFocus *event, | |
161 GaimRequestField *field) | |
162 { | |
163 const char *value; | |
164 | |
165 if (gaim_request_field_string_is_multiline(field)) | |
166 { | |
167 GtkTextBuffer *buffer; | |
168 GtkTextIter start_iter, end_iter; | |
169 | |
170 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry)); | |
171 | |
172 gtk_text_buffer_get_start_iter(buffer, &start_iter); | |
173 gtk_text_buffer_get_end_iter(buffer, &end_iter); | |
174 | |
175 value = gtk_text_buffer_get_text(buffer, &start_iter, &end_iter, FALSE); | |
176 } | |
177 else | |
178 value = gtk_entry_get_text(GTK_ENTRY(entry)); | |
179 | |
180 gaim_request_field_string_set_value(field, | |
181 (*value == '\0' ? NULL : value)); | |
182 | |
183 return FALSE; | |
184 } | |
185 | |
186 static gboolean | |
187 field_int_focus_out_cb(GtkEntry *entry, GdkEventFocus *event, | |
188 GaimRequestField *field) | |
189 { | |
190 gaim_request_field_int_set_value(field, | |
191 atoi(gtk_entry_get_text(entry))); | |
192 | |
193 return FALSE; | |
194 } | |
195 | |
196 static void | |
197 field_bool_cb(GtkToggleButton *button, GaimRequestField *field) | |
198 { | |
199 gaim_request_field_bool_set_value(field, | |
200 gtk_toggle_button_get_active(button)); | |
201 } | |
202 | |
203 static void | |
204 field_choice_menu_cb(GtkOptionMenu *menu, GaimRequestField *field) | |
205 { | |
206 gaim_request_field_choice_set_value(field, | |
207 gtk_option_menu_get_history(menu)); | |
208 } | |
209 | |
210 static void | |
211 field_choice_option_cb(GtkRadioButton *button, GaimRequestField *field) | |
212 { | |
213 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) | |
214 gaim_request_field_choice_set_value(field, | |
215 (g_slist_length(gtk_radio_button_get_group(button)) - | |
216 g_slist_index(gtk_radio_button_get_group(button), button)) - 1); | |
217 } | |
218 | |
219 static void | |
220 field_account_cb(GObject *w, GaimAccount *account, GaimRequestField *field) | |
221 { | |
222 gaim_request_field_account_set_value(field, account); | |
223 } | |
224 | |
225 static void | |
226 multifield_ok_cb(GtkWidget *button, GaimGtkRequestData *data) | |
227 { | |
228 generic_response_start(data); | |
229 | |
230 if (!GTK_WIDGET_HAS_FOCUS(button)) | |
231 gtk_widget_grab_focus(button); | |
232 | |
233 if (data->cbs[0] != NULL) | |
234 ((GaimRequestFieldsCb)data->cbs[0])(data->user_data, | |
235 data->u.multifield.fields); | |
236 | |
237 gaim_request_close(GAIM_REQUEST_FIELDS, data); | |
238 } | |
239 | |
240 static void | |
241 multifield_cancel_cb(GtkWidget *button, GaimGtkRequestData *data) | |
242 { | |
243 generic_response_start(data); | |
244 | |
245 if (data->cbs[1] != NULL) | |
246 ((GaimRequestFieldsCb)data->cbs[1])(data->user_data, | |
247 data->u.multifield.fields); | |
248 | |
249 gaim_request_close(GAIM_REQUEST_FIELDS, data); | |
250 } | |
251 | |
252 static void | |
253 destroy_multifield_cb(GtkWidget *dialog, GdkEvent *event, | |
254 GaimGtkRequestData *data) | |
255 { | |
256 multifield_cancel_cb(NULL, data); | |
257 } | |
258 | |
259 | |
260 #define STOCK_ITEMIZE(r, l) \ | |
261 if (!strcmp((r), text)) \ | |
262 return (l); | |
263 | |
264 static const char * | |
265 text_to_stock(const char *text) | |
266 { | |
267 STOCK_ITEMIZE(_("Yes"), GTK_STOCK_YES); | |
268 STOCK_ITEMIZE(_("No"), GTK_STOCK_NO); | |
269 STOCK_ITEMIZE(_("OK"), GTK_STOCK_OK); | |
270 STOCK_ITEMIZE(_("Cancel"), GTK_STOCK_CANCEL); | |
271 STOCK_ITEMIZE(_("Apply"), GTK_STOCK_APPLY); | |
272 STOCK_ITEMIZE(_("Close"), GTK_STOCK_CLOSE); | |
273 STOCK_ITEMIZE(_("Delete"), GTK_STOCK_DELETE); | |
274 STOCK_ITEMIZE(_("Add"), GTK_STOCK_ADD); | |
275 STOCK_ITEMIZE(_("Remove"), GTK_STOCK_REMOVE); | |
276 STOCK_ITEMIZE(_("Save"), GTK_STOCK_SAVE); | |
277 STOCK_ITEMIZE(_("Alias"), GAIM_STOCK_ALIAS); | |
278 | |
279 return text; | |
280 } | |
281 | |
282 static void * | |
283 gaim_gtk_request_input(const char *title, const char *primary, | |
284 const char *secondary, const char *default_value, | |
285 gboolean multiline, gboolean masked, gchar *hint, | |
286 const char *ok_text, GCallback ok_cb, | |
287 const char *cancel_text, GCallback cancel_cb, | |
288 void *user_data) | |
289 { | |
290 GaimGtkRequestData *data; | |
291 GtkWidget *dialog; | |
292 GtkWidget *vbox; | |
293 GtkWidget *hbox; | |
294 GtkWidget *label; | |
295 GtkWidget *entry; | |
296 GtkWidget *img; | |
297 GtkWidget *toolbar; | |
298 char *label_text; | |
299 char *primary_esc, *secondary_esc; | |
300 | |
301 data = g_new0(GaimGtkRequestData, 1); | |
302 data->type = GAIM_REQUEST_INPUT; | |
303 data->user_data = user_data; | |
304 | |
305 data->cb_count = 2; | |
306 data->cbs = g_new0(GCallback, 2); | |
307 | |
308 data->cbs[0] = ok_cb; | |
309 data->cbs[1] = cancel_cb; | |
310 | |
311 /* Create the dialog. */ | |
312 dialog = gtk_dialog_new_with_buttons(title ? title : GAIM_ALERT_TITLE, | |
313 NULL, 0, | |
314 text_to_stock(cancel_text), 1, | |
315 text_to_stock(ok_text), 0, | |
316 NULL); | |
317 data->dialog = dialog; | |
318 | |
319 g_signal_connect(G_OBJECT(dialog), "response", | |
320 G_CALLBACK(input_response_cb), data); | |
321 | |
322 /* Setup the dialog */ | |
323 gtk_container_set_border_width(GTK_CONTAINER(dialog), GAIM_HIG_BORDER/2); | |
324 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), GAIM_HIG_BORDER/2); | |
325 gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); | |
326 gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); | |
327 gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0); | |
328 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), GAIM_HIG_BORDER); | |
329 | |
330 /* Setup the main horizontal box */ | |
331 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); | |
332 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox); | |
333 | |
334 /* Dialog icon. */ | |
335 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
336 GTK_ICON_SIZE_DIALOG); | |
337 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
338 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
339 | |
340 /* Vertical box */ | |
341 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
342 | |
343 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); | |
344 | |
345 /* Descriptive label */ | |
346 primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL; | |
347 secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL; | |
348 label_text = g_strdup_printf((primary ? "<span weight=\"bold\" size=\"larger\">" | |
349 "%s</span>%s%s" : "%s%s%s"), | |
350 (primary ? primary_esc : ""), | |
351 ((primary && secondary) ? "\n\n" : ""), | |
352 (secondary ? secondary_esc : "")); | |
353 g_free(primary_esc); | |
354 g_free(secondary_esc); | |
355 | |
356 label = gtk_label_new(NULL); | |
357 | |
358 gtk_label_set_markup(GTK_LABEL(label), label_text); | |
359 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
360 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
361 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); | |
362 | |
363 g_free(label_text); | |
364 | |
365 /* Entry field. */ | |
366 data->u.input.multiline = multiline; | |
367 data->u.input.hint = g_strdup(hint); | |
368 | |
369 if ((data->u.input.hint != NULL) && (!strcmp(data->u.input.hint, "html"))) { | |
370 GtkWidget *frame; | |
371 | |
372 /* imhtml */ | |
373 frame = gaim_gtk_create_imhtml(TRUE, &entry, &toolbar, NULL); | |
374 gtk_widget_set_size_request(entry, 320, 130); | |
375 gtk_widget_set_name(entry, "gaim_gtkrequest_imhtml"); | |
376 if (default_value != NULL) | |
377 gtk_imhtml_append_text(GTK_IMHTML(entry), default_value, GTK_IMHTML_NO_SCROLL); | |
378 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | |
379 gtk_widget_show(frame); | |
380 } | |
381 else { | |
382 if (multiline) { | |
383 GtkWidget *sw; | |
384 | |
385 sw = gtk_scrolled_window_new(NULL, NULL); | |
386 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
387 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); | |
388 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
389 GTK_SHADOW_IN); | |
390 | |
391 gtk_widget_set_size_request(sw, 320, 130); | |
392 | |
393 /* GtkTextView */ | |
394 entry = gtk_text_view_new(); | |
395 gtk_text_view_set_editable(GTK_TEXT_VIEW(entry), TRUE); | |
396 | |
397 if (default_value != NULL) { | |
398 GtkTextBuffer *buffer; | |
399 | |
400 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry)); | |
401 gtk_text_buffer_set_text(buffer, default_value, -1); | |
402 } | |
403 | |
404 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(entry), GTK_WRAP_WORD_CHAR); | |
405 | |
406 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); | |
407 | |
408 if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck")) | |
409 gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(entry)); | |
410 | |
411 gtk_container_add(GTK_CONTAINER(sw), entry); | |
412 } | |
413 else { | |
414 entry = gtk_entry_new(); | |
415 | |
416 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); | |
417 | |
418 gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0); | |
419 | |
420 if (default_value != NULL) | |
421 gtk_entry_set_text(GTK_ENTRY(entry), default_value); | |
422 | |
423 if (masked) | |
424 { | |
425 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | |
426 if (gtk_entry_get_invisible_char(GTK_ENTRY(entry)) == '*') | |
427 gtk_entry_set_invisible_char(GTK_ENTRY(entry), GAIM_INVISIBLE_CHAR); | |
428 } | |
429 } | |
430 } | |
431 | |
432 gaim_set_accessible_label (entry, label); | |
433 data->u.input.entry = entry; | |
434 | |
435 /* Show everything. */ | |
436 gtk_widget_show_all(dialog); | |
437 | |
438 return data; | |
439 } | |
440 | |
441 static void * | |
442 gaim_gtk_request_choice(const char *title, const char *primary, | |
443 const char *secondary, unsigned int default_value, | |
444 const char *ok_text, GCallback ok_cb, | |
445 const char *cancel_text, GCallback cancel_cb, | |
446 void *user_data, va_list args) | |
447 { | |
448 GaimGtkRequestData *data; | |
449 GtkWidget *dialog; | |
450 GtkWidget *vbox, *vbox2; | |
451 GtkWidget *hbox; | |
452 GtkWidget *label; | |
453 GtkWidget *img; | |
454 GtkWidget *radio = NULL; | |
455 char *label_text; | |
456 char *radio_text; | |
457 char *primary_esc, *secondary_esc; | |
458 | |
459 data = g_new0(GaimGtkRequestData, 1); | |
460 data->type = GAIM_REQUEST_ACTION; | |
461 data->user_data = user_data; | |
462 | |
463 data->cb_count = 2; | |
464 data->cbs = g_new0(GCallback, 2); | |
465 data->cbs[0] = cancel_cb; | |
466 data->cbs[1] = ok_cb; | |
467 | |
468 /* Create the dialog. */ | |
469 data->dialog = dialog = gtk_dialog_new(); | |
470 | |
471 if (title != NULL) | |
472 gtk_window_set_title(GTK_WINDOW(dialog), title); | |
473 | |
474 | |
475 gtk_dialog_add_button(GTK_DIALOG(dialog), | |
476 text_to_stock(cancel_text), 0); | |
477 | |
478 gtk_dialog_add_button(GTK_DIALOG(dialog), | |
479 text_to_stock(ok_text), 1); | |
480 | |
481 g_signal_connect(G_OBJECT(dialog), "response", | |
482 G_CALLBACK(choice_response_cb), data); | |
483 | |
484 /* Setup the dialog */ | |
485 gtk_container_set_border_width(GTK_CONTAINER(dialog), GAIM_HIG_BORDER/2); | |
486 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), GAIM_HIG_BORDER/2); | |
487 gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); | |
488 gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); | |
489 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), GAIM_HIG_BORDER); | |
490 | |
491 /* Setup the main horizontal box */ | |
492 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); | |
493 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox); | |
494 | |
495 /* Dialog icon. */ | |
496 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
497 GTK_ICON_SIZE_DIALOG); | |
498 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
499 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
500 | |
501 /* Vertical box */ | |
502 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
503 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); | |
504 | |
505 /* Descriptive label */ | |
506 primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL; | |
507 secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL; | |
508 label_text = g_strdup_printf((primary ? "<span weight=\"bold\" size=\"larger\">" | |
509 "%s</span>%s%s" : "%s%s%s"), | |
510 (primary ? primary_esc : ""), | |
511 ((primary && secondary) ? "\n\n" : ""), | |
512 (secondary ? secondary_esc : "")); | |
513 g_free(primary_esc); | |
514 g_free(secondary_esc); | |
515 | |
516 label = gtk_label_new(NULL); | |
517 | |
518 gtk_label_set_markup(GTK_LABEL(label), label_text); | |
519 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
520 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
521 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); | |
522 | |
523 g_free(label_text); | |
524 | |
525 vbox2 = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
526 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, FALSE, 0); | |
527 while ((radio_text = va_arg(args, char*))) { | |
528 int resp = va_arg(args, int); | |
529 radio = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio), radio_text); | |
530 gtk_box_pack_start(GTK_BOX(vbox2), radio, FALSE, FALSE, 0); | |
531 g_object_set_data(G_OBJECT(radio), "choice_id", GINT_TO_POINTER(resp)); | |
532 if (resp == default_value) | |
533 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); | |
534 } | |
535 | |
536 g_object_set_data(G_OBJECT(dialog), "radio", radio); | |
537 | |
538 /* Show everything. */ | |
539 gtk_widget_show_all(dialog); | |
540 | |
541 return data; | |
542 } | |
543 | |
544 static void * | |
545 gaim_gtk_request_action(const char *title, const char *primary, | |
546 const char *secondary, unsigned int default_action, | |
547 void *user_data, size_t action_count, va_list actions) | |
548 { | |
549 GaimGtkRequestData *data; | |
550 GtkWidget *dialog; | |
551 GtkWidget *vbox; | |
552 GtkWidget *hbox; | |
553 GtkWidget *label; | |
554 GtkWidget *img; | |
555 void **buttons; | |
556 char *label_text; | |
557 char *primary_esc, *secondary_esc; | |
558 int i; | |
559 | |
560 data = g_new0(GaimGtkRequestData, 1); | |
561 data->type = GAIM_REQUEST_ACTION; | |
562 data->user_data = user_data; | |
563 | |
564 data->cb_count = action_count; | |
565 data->cbs = g_new0(GCallback, action_count); | |
566 | |
567 /* Reverse the buttons */ | |
568 buttons = g_new0(void *, action_count * 2); | |
569 | |
570 for (i = 0; i < action_count * 2; i += 2) { | |
571 buttons[(action_count * 2) - i - 2] = va_arg(actions, char *); | |
572 buttons[(action_count * 2) - i - 1] = va_arg(actions, GCallback); | |
573 } | |
574 | |
575 /* Create the dialog. */ | |
576 data->dialog = dialog = gtk_dialog_new(); | |
577 | |
578 if (title != NULL) | |
579 gtk_window_set_title(GTK_WINDOW(dialog), title); | |
580 | |
581 for (i = 0; i < action_count; i++) { | |
582 gtk_dialog_add_button(GTK_DIALOG(dialog), | |
583 text_to_stock(buttons[2 * i]), i); | |
584 | |
585 data->cbs[i] = buttons[2 * i + 1]; | |
586 } | |
587 | |
588 g_free(buttons); | |
589 | |
590 g_signal_connect(G_OBJECT(dialog), "response", | |
591 G_CALLBACK(action_response_cb), data); | |
592 | |
593 /* Setup the dialog */ | |
594 gtk_container_set_border_width(GTK_CONTAINER(dialog), GAIM_HIG_BORDER/2); | |
595 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), GAIM_HIG_BORDER/2); | |
596 gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); | |
597 gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); | |
598 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), GAIM_HIG_BORDER); | |
599 | |
600 /* Setup the main horizontal box */ | |
601 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); | |
602 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox); | |
603 | |
604 /* Dialog icon. */ | |
605 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
606 GTK_ICON_SIZE_DIALOG); | |
607 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
608 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
609 | |
610 /* Vertical box */ | |
611 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
612 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); | |
613 | |
614 /* Descriptive label */ | |
615 primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL; | |
616 secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL; | |
617 label_text = g_strdup_printf((primary ? "<span weight=\"bold\" size=\"larger\">" | |
618 "%s</span>%s%s" : "%s%s%s"), | |
619 (primary ? primary_esc : ""), | |
620 ((primary && secondary) ? "\n\n" : ""), | |
621 (secondary ? secondary_esc : "")); | |
622 g_free(primary_esc); | |
623 g_free(secondary_esc); | |
624 | |
625 label = gtk_label_new(NULL); | |
626 | |
627 gtk_label_set_markup(GTK_LABEL(label), label_text); | |
628 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
629 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
630 gtk_label_set_selectable(GTK_LABEL(label), TRUE); | |
631 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); | |
632 | |
633 g_free(label_text); | |
634 | |
635 | |
636 if (default_action == GAIM_DEFAULT_ACTION_NONE) { | |
637 GTK_WIDGET_SET_FLAGS(img, GTK_CAN_DEFAULT); | |
638 GTK_WIDGET_SET_FLAGS(img, GTK_CAN_FOCUS); | |
639 gtk_widget_grab_focus(img); | |
640 gtk_widget_grab_default(img); | |
641 } else | |
642 gtk_dialog_set_default_response(GTK_DIALOG(dialog), default_action); | |
643 | |
644 /* Show everything. */ | |
645 gtk_widget_show_all(dialog); | |
646 | |
647 return data; | |
648 } | |
649 | |
650 static void | |
651 req_entry_field_changed_cb(GtkWidget *entry, GaimRequestField *field) | |
652 { | |
653 GaimGtkRequestData *req_data; | |
654 const char *text = gtk_entry_get_text(GTK_ENTRY(entry)); | |
655 | |
656 gaim_request_field_string_set_value(field, (*text == '\0' ? NULL : text)); | |
657 | |
658 req_data = (GaimGtkRequestData *)field->group->fields_list->ui_data; | |
659 | |
660 gtk_widget_set_sensitive(req_data->ok_button, | |
661 gaim_request_fields_all_required_filled(field->group->fields_list)); | |
662 } | |
663 | |
664 static void | |
665 setup_entry_field(GtkWidget *entry, GaimRequestField *field) | |
666 { | |
667 const char *type_hint; | |
668 | |
669 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); | |
670 | |
671 if (gaim_request_field_is_required(field)) | |
672 { | |
673 g_signal_connect(G_OBJECT(entry), "changed", | |
674 G_CALLBACK(req_entry_field_changed_cb), field); | |
675 } | |
676 | |
677 if ((type_hint = gaim_request_field_get_type_hint(field)) != NULL) | |
678 { | |
679 if (gaim_str_has_prefix(type_hint, "screenname")) | |
680 { | |
681 GtkWidget *optmenu = NULL; | |
682 GList *fields = field->group->fields; | |
683 while (fields) | |
684 { | |
685 GaimRequestField *fld = fields->data; | |
686 fields = fields->next; | |
687 | |
688 if (gaim_request_field_get_type(fld) == GAIM_REQUEST_FIELD_ACCOUNT) | |
689 { | |
690 const char *type_hint = gaim_request_field_get_type_hint(fld); | |
691 if (type_hint != NULL && strcmp(type_hint, "account") == 0) | |
692 { | |
693 if (fld->ui_data == NULL) | |
694 fld->ui_data = create_account_field(fld); | |
695 optmenu = GTK_WIDGET(fld->ui_data); | |
696 break; | |
697 } | |
698 } | |
699 } | |
700 gaim_gtk_setup_screenname_autocomplete(entry, optmenu, !strcmp(type_hint, "screenname-all")); | |
701 } | |
702 } | |
703 } | |
704 | |
705 static GtkWidget * | |
706 create_string_field(GaimRequestField *field) | |
707 { | |
708 const char *value; | |
709 GtkWidget *widget; | |
710 | |
711 value = gaim_request_field_string_get_default_value(field); | |
712 | |
713 if (gaim_request_field_string_is_multiline(field)) | |
714 { | |
715 GtkWidget *textview; | |
716 | |
717 widget = gtk_scrolled_window_new(NULL, NULL); | |
718 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(widget), | |
719 GTK_SHADOW_IN); | |
720 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget), | |
721 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); | |
722 | |
723 textview = gtk_text_view_new(); | |
724 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), | |
725 TRUE); | |
726 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), | |
727 GTK_WRAP_WORD_CHAR); | |
728 | |
729 if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck")) | |
730 gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(textview)); | |
731 | |
732 gtk_container_add(GTK_CONTAINER(widget), textview); | |
733 gtk_widget_show(textview); | |
734 | |
735 gtk_widget_set_size_request(widget, -1, 75); | |
736 | |
737 if (value != NULL) | |
738 { | |
739 GtkTextBuffer *buffer; | |
740 | |
741 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); | |
742 | |
743 gtk_text_buffer_set_text(buffer, value, -1); | |
744 } | |
745 | |
746 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), | |
747 gaim_request_field_string_is_editable(field)); | |
748 | |
749 g_signal_connect(G_OBJECT(textview), "focus-out-event", | |
750 G_CALLBACK(field_string_focus_out_cb), field); | |
751 } | |
752 else | |
753 { | |
754 widget = gtk_entry_new(); | |
755 | |
756 setup_entry_field(widget, field); | |
757 | |
758 if (value != NULL) | |
759 gtk_entry_set_text(GTK_ENTRY(widget), value); | |
760 | |
761 if (gaim_request_field_string_is_masked(field)) | |
762 { | |
763 gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE); | |
764 if (gtk_entry_get_invisible_char(GTK_ENTRY(widget)) == '*') | |
765 gtk_entry_set_invisible_char(GTK_ENTRY(widget), GAIM_INVISIBLE_CHAR); | |
766 } | |
767 | |
768 gtk_editable_set_editable(GTK_EDITABLE(widget), | |
769 gaim_request_field_string_is_editable(field)); | |
770 | |
771 g_signal_connect(G_OBJECT(widget), "focus-out-event", | |
772 G_CALLBACK(field_string_focus_out_cb), field); | |
773 } | |
774 | |
775 return widget; | |
776 } | |
777 | |
778 static GtkWidget * | |
779 create_int_field(GaimRequestField *field) | |
780 { | |
781 int value; | |
782 GtkWidget *widget; | |
783 | |
784 widget = gtk_entry_new(); | |
785 | |
786 setup_entry_field(widget, field); | |
787 | |
788 value = gaim_request_field_int_get_default_value(field); | |
789 | |
790 if (value != 0) | |
791 { | |
792 char buf[32]; | |
793 | |
794 g_snprintf(buf, sizeof(buf), "%d", value); | |
795 | |
796 gtk_entry_set_text(GTK_ENTRY(widget), buf); | |
797 } | |
798 | |
799 g_signal_connect(G_OBJECT(widget), "focus-out-event", | |
800 G_CALLBACK(field_int_focus_out_cb), field); | |
801 | |
802 return widget; | |
803 } | |
804 | |
805 static GtkWidget * | |
806 create_bool_field(GaimRequestField *field) | |
807 { | |
808 GtkWidget *widget; | |
809 | |
810 widget = gtk_check_button_new_with_label( | |
811 gaim_request_field_get_label(field)); | |
812 | |
813 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), | |
814 gaim_request_field_bool_get_default_value(field)); | |
815 | |
816 g_signal_connect(G_OBJECT(widget), "toggled", | |
817 G_CALLBACK(field_bool_cb), field); | |
818 | |
819 return widget; | |
820 } | |
821 | |
822 static GtkWidget * | |
823 create_choice_field(GaimRequestField *field) | |
824 { | |
825 GtkWidget *widget; | |
826 GList *labels; | |
827 GList *l; | |
828 | |
829 labels = gaim_request_field_choice_get_labels(field); | |
830 | |
831 if (g_list_length(labels) > 5) | |
832 { | |
833 GtkWidget *menu; | |
834 GtkWidget *item; | |
835 | |
836 widget = gtk_option_menu_new(); | |
837 | |
838 menu = gtk_menu_new(); | |
839 | |
840 for (l = labels; l != NULL; l = l->next) | |
841 { | |
842 const char *text = l->data; | |
843 | |
844 item = gtk_menu_item_new_with_label(text); | |
845 gtk_widget_show(item); | |
846 | |
847 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
848 } | |
849 | |
850 gtk_widget_show(menu); | |
851 gtk_option_menu_set_menu(GTK_OPTION_MENU(widget), menu); | |
852 gtk_option_menu_set_history(GTK_OPTION_MENU(widget), | |
853 gaim_request_field_choice_get_default_value(field)); | |
854 | |
855 g_signal_connect(G_OBJECT(widget), "changed", | |
856 G_CALLBACK(field_choice_menu_cb), field); | |
857 } | |
858 else | |
859 { | |
860 GtkWidget *box; | |
861 GtkWidget *first_radio = NULL; | |
862 GtkWidget *radio; | |
863 gint i; | |
864 | |
865 if (g_list_length(labels) == 2) | |
866 box = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
867 else | |
868 box = gtk_vbox_new(FALSE, 0); | |
869 | |
870 widget = box; | |
871 | |
872 for (l = labels, i = 0; l != NULL; l = l->next, i++) | |
873 { | |
874 const char *text = l->data; | |
875 | |
876 radio = gtk_radio_button_new_with_label_from_widget( | |
877 GTK_RADIO_BUTTON(first_radio), text); | |
878 | |
879 if (first_radio == NULL) | |
880 first_radio = radio; | |
881 | |
882 if (i == gaim_request_field_choice_get_default_value(field)) | |
883 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); | |
884 | |
885 gtk_box_pack_start(GTK_BOX(box), radio, TRUE, TRUE, 0); | |
886 gtk_widget_show(radio); | |
887 | |
888 g_signal_connect(G_OBJECT(radio), "toggled", | |
889 G_CALLBACK(field_choice_option_cb), field); | |
890 } | |
891 } | |
892 | |
893 return widget; | |
894 } | |
895 | |
896 static GtkWidget * | |
897 create_image_field(GaimRequestField *field) | |
898 { | |
899 GtkWidget *widget; | |
900 GdkPixbuf *buf, *scale; | |
901 GdkPixbufLoader *loader; | |
902 | |
903 loader = gdk_pixbuf_loader_new(); | |
904 gdk_pixbuf_loader_write(loader, | |
905 (const guchar *)gaim_request_field_image_get_buffer(field), | |
906 gaim_request_field_image_get_size(field), | |
907 NULL); | |
908 gdk_pixbuf_loader_close(loader, NULL); | |
909 buf = gdk_pixbuf_loader_get_pixbuf(loader); | |
910 | |
911 scale = gdk_pixbuf_scale_simple(buf, | |
912 gaim_request_field_image_get_scale_x(field) * gdk_pixbuf_get_width(buf), | |
913 gaim_request_field_image_get_scale_y(field) * gdk_pixbuf_get_height(buf), | |
914 GDK_INTERP_BILINEAR); | |
915 widget = gtk_image_new_from_pixbuf(scale); | |
916 g_object_unref(G_OBJECT(buf)); | |
917 g_object_unref(G_OBJECT(scale)); | |
918 | |
919 return widget; | |
920 } | |
921 | |
922 static GtkWidget * | |
923 create_account_field(GaimRequestField *field) | |
924 { | |
925 GtkWidget *widget; | |
926 | |
927 widget = gaim_gtk_account_option_menu_new( | |
928 gaim_request_field_account_get_default_value(field), | |
929 gaim_request_field_account_get_show_all(field), | |
930 G_CALLBACK(field_account_cb), | |
931 gaim_request_field_account_get_filter(field), | |
932 field); | |
933 | |
934 return widget; | |
935 } | |
936 | |
937 static void | |
938 select_field_list_item(GtkTreeModel *model, GtkTreePath *path, | |
939 GtkTreeIter *iter, gpointer data) | |
940 { | |
941 GaimRequestField *field = (GaimRequestField *)data; | |
942 char *text; | |
943 | |
944 gtk_tree_model_get(model, iter, 1, &text, -1); | |
945 | |
946 gaim_request_field_list_add_selected(field, text); | |
947 g_free(text); | |
948 } | |
949 | |
950 static void | |
951 list_field_select_changed_cb(GtkTreeSelection *sel, GaimRequestField *field) | |
952 { | |
953 gaim_request_field_list_clear_selected(field); | |
954 | |
955 gtk_tree_selection_selected_foreach(sel, select_field_list_item, field); | |
956 } | |
957 | |
958 static GtkWidget * | |
959 create_list_field(GaimRequestField *field) | |
960 { | |
961 GtkWidget *sw; | |
962 GtkWidget *treeview; | |
963 GtkListStore *store; | |
964 GtkCellRenderer *renderer; | |
965 GtkTreeSelection *sel; | |
966 GtkTreeViewColumn *column; | |
967 GtkTreeIter iter; | |
968 const GList *l; | |
969 | |
970 /* Create the scrolled window */ | |
971 sw = gtk_scrolled_window_new(NULL, NULL); | |
972 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
973 GTK_POLICY_AUTOMATIC, | |
974 GTK_POLICY_AUTOMATIC); | |
975 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
976 GTK_SHADOW_IN); | |
977 gtk_widget_show(sw); | |
978 | |
979 /* Create the list store */ | |
980 store = gtk_list_store_new(2, G_TYPE_POINTER, G_TYPE_STRING); | |
981 | |
982 /* Create the tree view */ | |
983 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); | |
984 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
985 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); | |
986 | |
987 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); | |
988 | |
989 if (gaim_request_field_list_get_multi_select(field)) | |
990 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
991 | |
992 g_signal_connect(G_OBJECT(sel), "changed", | |
993 G_CALLBACK(list_field_select_changed_cb), field); | |
994 | |
995 column = gtk_tree_view_column_new(); | |
996 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeview), column, -1); | |
997 | |
998 renderer = gtk_cell_renderer_text_new(); | |
999 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1000 gtk_tree_view_column_add_attribute(column, renderer, "text", 1); | |
1001 | |
1002 for (l = gaim_request_field_list_get_items(field); l != NULL; l = l->next) | |
1003 { | |
1004 const char *text = (const char *)l->data; | |
1005 | |
1006 gtk_list_store_append(store, &iter); | |
1007 | |
1008 gtk_list_store_set(store, &iter, | |
1009 0, gaim_request_field_list_get_data(field, text), | |
1010 1, text, | |
1011 -1); | |
1012 | |
1013 if (gaim_request_field_list_is_selected(field, text)) | |
1014 gtk_tree_selection_select_iter(sel, &iter); | |
1015 } | |
1016 | |
1017 gtk_container_add(GTK_CONTAINER(sw), treeview); | |
1018 gtk_widget_show(treeview); | |
1019 | |
1020 return sw; | |
1021 } | |
1022 | |
1023 static void * | |
1024 gaim_gtk_request_fields(const char *title, const char *primary, | |
1025 const char *secondary, GaimRequestFields *fields, | |
1026 const char *ok_text, GCallback ok_cb, | |
1027 const char *cancel_text, GCallback cancel_cb, | |
1028 void *user_data) | |
1029 { | |
1030 GaimGtkRequestData *data; | |
1031 GtkWidget *win; | |
1032 GtkWidget *vbox; | |
1033 GtkWidget *vbox2; | |
1034 GtkWidget *hbox; | |
1035 GtkWidget *bbox; | |
1036 GtkWidget *frame; | |
1037 GtkWidget *label; | |
1038 GtkWidget *table; | |
1039 GtkWidget *button; | |
1040 GtkWidget *img; | |
1041 GtkWidget *sw; | |
1042 GtkSizeGroup *sg; | |
1043 GList *gl, *fl; | |
1044 GaimRequestFieldGroup *group; | |
1045 GaimRequestField *field; | |
1046 char *label_text; | |
1047 char *primary_esc, *secondary_esc; | |
1048 int total_fields = 0; | |
1049 | |
1050 data = g_new0(GaimGtkRequestData, 1); | |
1051 data->type = GAIM_REQUEST_FIELDS; | |
1052 data->user_data = user_data; | |
1053 data->u.multifield.fields = fields; | |
1054 | |
1055 fields->ui_data = data; | |
1056 | |
1057 data->cb_count = 2; | |
1058 data->cbs = g_new0(GCallback, 2); | |
1059 | |
1060 data->cbs[0] = ok_cb; | |
1061 data->cbs[1] = cancel_cb; | |
1062 | |
1063 data->dialog = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
1064 | |
1065 if (title != NULL) | |
1066 gtk_window_set_title(GTK_WINDOW(win), title); | |
1067 | |
1068 gtk_window_set_role(GTK_WINDOW(win), "multifield"); | |
1069 gtk_container_set_border_width(GTK_CONTAINER(win), GAIM_HIG_BORDER); | |
1070 | |
1071 g_signal_connect(G_OBJECT(win), "delete_event", | |
1072 G_CALLBACK(destroy_multifield_cb), data); | |
1073 | |
1074 /* Setup the main horizontal box */ | |
1075 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); | |
1076 gtk_container_add(GTK_CONTAINER(win), hbox); | |
1077 gtk_widget_show(hbox); | |
1078 | |
1079 /* Dialog icon. */ | |
1080 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
1081 GTK_ICON_SIZE_DIALOG); | |
1082 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
1083 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
1084 gtk_widget_show(img); | |
1085 | |
1086 /* Setup the vbox */ | |
1087 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
1088 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); | |
1089 gtk_widget_show(vbox); | |
1090 | |
1091 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
1092 | |
1093 if(primary) { | |
1094 primary_esc = g_markup_escape_text(primary, -1); | |
1095 label_text = g_strdup_printf( | |
1096 "<span weight=\"bold\" size=\"larger\">%s</span>", primary_esc); | |
1097 g_free(primary_esc); | |
1098 label = gtk_label_new(NULL); | |
1099 | |
1100 gtk_label_set_markup(GTK_LABEL(label), label_text); | |
1101 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
1102 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
1103 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
1104 gtk_widget_show(label); | |
1105 g_free(label_text); | |
1106 } | |
1107 | |
1108 for (gl = gaim_request_fields_get_groups(fields); gl != NULL; | |
1109 gl = gl->next) | |
1110 total_fields += g_list_length(gaim_request_field_group_get_fields(gl->data)); | |
1111 | |
1112 if(total_fields > 9) { | |
1113 sw = gtk_scrolled_window_new(NULL, NULL); | |
1114 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
1115 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); | |
1116 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
1117 GTK_SHADOW_NONE); | |
1118 gtk_widget_set_size_request(sw, -1, 200); | |
1119 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); | |
1120 gtk_widget_show(sw); | |
1121 | |
1122 vbox2 = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
1123 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), vbox2); | |
1124 gtk_widget_show(vbox2); | |
1125 } else { | |
1126 vbox2 = vbox; | |
1127 } | |
1128 | |
1129 if (secondary) { | |
1130 secondary_esc = g_markup_escape_text(secondary, -1); | |
1131 label = gtk_label_new(NULL); | |
1132 | |
1133 gtk_label_set_markup(GTK_LABEL(label), secondary_esc); | |
1134 g_free(secondary_esc); | |
1135 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
1136 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
1137 gtk_box_pack_start(GTK_BOX(vbox2), label, TRUE, TRUE, 0); | |
1138 gtk_widget_show(label); | |
1139 } | |
1140 | |
1141 for (gl = gaim_request_fields_get_groups(fields); | |
1142 gl != NULL; | |
1143 gl = gl->next) | |
1144 { | |
1145 GList *field_list; | |
1146 size_t field_count = 0; | |
1147 size_t cols = 1; | |
1148 size_t rows; | |
1149 size_t col_num; | |
1150 size_t row_num = 0; | |
1151 | |
1152 group = gl->data; | |
1153 field_list = gaim_request_field_group_get_fields(group); | |
1154 | |
1155 if (gaim_request_field_group_get_title(group) != NULL) | |
1156 { | |
1157 frame = gaim_gtk_make_frame(vbox2, | |
1158 gaim_request_field_group_get_title(group)); | |
1159 } | |
1160 else | |
1161 frame = vbox2; | |
1162 | |
1163 field_count = g_list_length(field_list); | |
1164 /* | |
1165 if (field_count > 9) | |
1166 { | |
1167 rows = field_count / 2; | |
1168 cols++; | |
1169 } | |
1170 else | |
1171 */ | |
1172 rows = field_count; | |
1173 | |
1174 col_num = 0; | |
1175 | |
1176 for (fl = field_list; fl != NULL; fl = fl->next) | |
1177 { | |
1178 GaimRequestFieldType type; | |
1179 | |
1180 field = (GaimRequestField *)fl->data; | |
1181 | |
1182 type = gaim_request_field_get_type(field); | |
1183 | |
1184 if (type == GAIM_REQUEST_FIELD_LABEL) | |
1185 { | |
1186 if (col_num > 0) | |
1187 rows++; | |
1188 | |
1189 rows++; | |
1190 } | |
1191 else if ((type == GAIM_REQUEST_FIELD_LIST) || | |
1192 (type == GAIM_REQUEST_FIELD_STRING && | |
1193 gaim_request_field_string_is_multiline(field))) | |
1194 { | |
1195 if (col_num > 0) | |
1196 rows++; | |
1197 | |
1198 rows += 2; | |
1199 } | |
1200 | |
1201 col_num++; | |
1202 | |
1203 if (col_num >= cols) | |
1204 col_num = 0; | |
1205 } | |
1206 | |
1207 table = gtk_table_new(rows, 2 * cols, FALSE); | |
1208 gtk_table_set_row_spacings(GTK_TABLE(table), GAIM_HIG_BOX_SPACE); | |
1209 gtk_table_set_col_spacings(GTK_TABLE(table), GAIM_HIG_BOX_SPACE); | |
1210 | |
1211 gtk_container_add(GTK_CONTAINER(frame), table); | |
1212 gtk_widget_show(table); | |
1213 | |
1214 for (row_num = 0, fl = field_list; | |
1215 row_num < rows && fl != NULL; | |
1216 row_num++) | |
1217 { | |
1218 for (col_num = 0; | |
1219 col_num < cols && fl != NULL; | |
1220 col_num++, fl = fl->next) | |
1221 { | |
1222 size_t col_offset = col_num * 2; | |
1223 GaimRequestFieldType type; | |
1224 GtkWidget *widget = NULL; | |
1225 | |
1226 label = NULL; | |
1227 field = fl->data; | |
1228 | |
1229 if (!gaim_request_field_is_visible(field)) { | |
1230 col_num--; | |
1231 continue; | |
1232 } | |
1233 | |
1234 type = gaim_request_field_get_type(field); | |
1235 | |
1236 if (type != GAIM_REQUEST_FIELD_BOOLEAN && | |
1237 gaim_request_field_get_label(field)) | |
1238 { | |
1239 char *text; | |
1240 | |
1241 text = g_strdup_printf("%s:", | |
1242 gaim_request_field_get_label(field)); | |
1243 | |
1244 label = gtk_label_new(NULL); | |
1245 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), text); | |
1246 g_free(text); | |
1247 | |
1248 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
1249 | |
1250 gtk_size_group_add_widget(sg, label); | |
1251 | |
1252 if (type == GAIM_REQUEST_FIELD_LABEL || | |
1253 type == GAIM_REQUEST_FIELD_LIST || | |
1254 (type == GAIM_REQUEST_FIELD_STRING && | |
1255 gaim_request_field_string_is_multiline(field))) | |
1256 { | |
1257 if(col_num > 0) | |
1258 row_num++; | |
1259 | |
1260 gtk_table_attach_defaults(GTK_TABLE(table), label, | |
1261 0, 2 * cols, | |
1262 row_num, row_num + 1); | |
1263 | |
1264 row_num++; | |
1265 col_num=cols; | |
1266 } | |
1267 else | |
1268 { | |
1269 gtk_table_attach_defaults(GTK_TABLE(table), label, | |
1270 col_offset, col_offset + 1, | |
1271 row_num, row_num + 1); | |
1272 } | |
1273 | |
1274 gtk_widget_show(label); | |
1275 } | |
1276 | |
1277 if (field->ui_data != NULL) | |
1278 widget = GTK_WIDGET(field->ui_data); | |
1279 else if (type == GAIM_REQUEST_FIELD_STRING) | |
1280 widget = create_string_field(field); | |
1281 else if (type == GAIM_REQUEST_FIELD_INTEGER) | |
1282 widget = create_int_field(field); | |
1283 else if (type == GAIM_REQUEST_FIELD_BOOLEAN) | |
1284 widget = create_bool_field(field); | |
1285 else if (type == GAIM_REQUEST_FIELD_CHOICE) | |
1286 widget = create_choice_field(field); | |
1287 else if (type == GAIM_REQUEST_FIELD_LIST) | |
1288 widget = create_list_field(field); | |
1289 else if (type == GAIM_REQUEST_FIELD_IMAGE) | |
1290 widget = create_image_field(field); | |
1291 else if (type == GAIM_REQUEST_FIELD_ACCOUNT) | |
1292 widget = create_account_field(field); | |
1293 else | |
1294 continue; | |
1295 | |
1296 if (label) | |
1297 gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget); | |
1298 | |
1299 if (type == GAIM_REQUEST_FIELD_STRING && | |
1300 gaim_request_field_string_is_multiline(field)) | |
1301 { | |
1302 gtk_table_attach(GTK_TABLE(table), widget, | |
1303 0, 2 * cols, | |
1304 row_num, row_num + 1, | |
1305 GTK_FILL | GTK_EXPAND, | |
1306 GTK_FILL | GTK_EXPAND, | |
1307 5, 0); | |
1308 } | |
1309 else if (type == GAIM_REQUEST_FIELD_LIST) | |
1310 { | |
1311 gtk_table_attach(GTK_TABLE(table), widget, | |
1312 0, 2 * cols, | |
1313 row_num, row_num + 1, | |
1314 GTK_FILL | GTK_EXPAND, | |
1315 GTK_FILL | GTK_EXPAND, | |
1316 5, 0); | |
1317 } | |
1318 else if (type == GAIM_REQUEST_FIELD_BOOLEAN) | |
1319 { | |
1320 gtk_table_attach(GTK_TABLE(table), widget, | |
1321 col_offset, col_offset + 1, | |
1322 row_num, row_num + 1, | |
1323 GTK_FILL | GTK_EXPAND, | |
1324 GTK_FILL | GTK_EXPAND, | |
1325 5, 0); | |
1326 } | |
1327 else | |
1328 { | |
1329 gtk_table_attach(GTK_TABLE(table), widget, | |
1330 1, 2 * cols, | |
1331 row_num, row_num + 1, | |
1332 GTK_FILL | GTK_EXPAND, | |
1333 GTK_FILL | GTK_EXPAND, | |
1334 5, 0); | |
1335 } | |
1336 | |
1337 gtk_widget_show(widget); | |
1338 | |
1339 field->ui_data = widget; | |
1340 } | |
1341 } | |
1342 } | |
1343 | |
1344 g_object_unref(sg); | |
1345 | |
1346 /* Button box. */ | |
1347 bbox = gtk_hbutton_box_new(); | |
1348 gtk_box_set_spacing(GTK_BOX(bbox), GAIM_HIG_BOX_SPACE); | |
1349 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
1350 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
1351 gtk_widget_show(bbox); | |
1352 | |
1353 /* Cancel button */ | |
1354 button = gtk_button_new_from_stock(text_to_stock(cancel_text)); | |
1355 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1356 gtk_widget_show(button); | |
1357 | |
1358 g_signal_connect(G_OBJECT(button), "clicked", | |
1359 G_CALLBACK(multifield_cancel_cb), data); | |
1360 | |
1361 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
1362 | |
1363 /* OK button */ | |
1364 button = gtk_button_new_from_stock(text_to_stock(ok_text)); | |
1365 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1366 gtk_widget_show(button); | |
1367 | |
1368 data->ok_button = button; | |
1369 | |
1370 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
1371 gtk_window_set_default(GTK_WINDOW(win), button); | |
1372 | |
1373 g_signal_connect(G_OBJECT(button), "clicked", | |
1374 G_CALLBACK(multifield_ok_cb), data); | |
1375 | |
1376 if (!gaim_request_fields_all_required_filled(fields)) | |
1377 gtk_widget_set_sensitive(button, FALSE); | |
1378 | |
1379 gtk_widget_show(win); | |
1380 | |
1381 return data; | |
1382 } | |
1383 | |
1384 static void | |
1385 file_yes_no_cb(GaimGtkRequestData *data, gint id) | |
1386 { | |
1387 /* Only call the callback if yes was selected, otherwise the request | |
1388 * (eg. file transfer) will be cancelled, then when a new filename is chosen | |
1389 * things go BOOM */ | |
1390 if (id == 1) { | |
1391 if (data->cbs[1] != NULL) | |
1392 ((GaimRequestFileCb)data->cbs[1])(data->user_data, data->u.file.name); | |
1393 gaim_request_close(data->type, data); | |
1394 } else { | |
1395 gaim_gtk_clear_cursor(GTK_WIDGET(data->dialog)); | |
1396 } | |
1397 } | |
1398 | |
1399 #if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ | |
1400 static void | |
1401 file_ok_check_if_exists_cb(GtkWidget *widget, gint response, GaimGtkRequestData *data) | |
1402 { | |
1403 gchar *current_folder; | |
1404 | |
1405 generic_response_start(data); | |
1406 | |
1407 if (response != GTK_RESPONSE_ACCEPT) { | |
1408 if (data->cbs[0] != NULL) | |
1409 ((GaimRequestFileCb)data->cbs[0])(data->user_data, NULL); | |
1410 gaim_request_close(data->type, data); | |
1411 return; | |
1412 } | |
1413 | |
1414 data->u.file.name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(data->dialog)); | |
1415 current_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(data->dialog)); | |
1416 if (current_folder != NULL) { | |
1417 if (data->u.file.savedialog) { | |
1418 gaim_prefs_set_path("/gaim/gtk/filelocations/last_save_folder", current_folder); | |
1419 } else { | |
1420 gaim_prefs_set_path("/gaim/gtk/filelocations/last_open_folder", current_folder); | |
1421 } | |
1422 g_free(current_folder); | |
1423 } | |
1424 | |
1425 #else /* FILECHOOSER */ | |
1426 | |
1427 static void | |
1428 file_ok_check_if_exists_cb(GtkWidget *button, GaimGtkRequestData *data) | |
1429 { | |
1430 const gchar *name; | |
1431 gchar *current_folder; | |
1432 | |
1433 generic_response_start(data); | |
1434 | |
1435 name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(data->dialog)); | |
1436 | |
1437 /* If name is a directory then change directories */ | |
1438 if (data->type == GAIM_REQUEST_FILE) { | |
1439 if (gaim_gtk_check_if_dir(name, GTK_FILE_SELECTION(data->dialog))) | |
1440 return; | |
1441 } | |
1442 | |
1443 current_folder = g_path_get_dirname(name); | |
1444 | |
1445 g_free(data->u.file.name); | |
1446 if (data->type == GAIM_REQUEST_FILE) | |
1447 data->u.file.name = g_strdup(name); | |
1448 else | |
1449 { | |
1450 if (g_file_test(name, G_FILE_TEST_IS_DIR)) | |
1451 data->u.file.name = g_strdup(name); | |
1452 else | |
1453 data->u.file.name = g_strdup(current_folder); | |
1454 } | |
1455 | |
1456 if (current_folder != NULL) { | |
1457 if (data->u.file.savedialog) { | |
1458 gaim_prefs_set_path("/gaim/gtk/filelocations/last_save_folder", current_folder); | |
1459 } else { | |
1460 gaim_prefs_set_path("/gaim/gtk/filelocations/last_open_folder", current_folder); | |
1461 } | |
1462 g_free(current_folder); | |
1463 } | |
1464 | |
1465 #endif /* FILECHOOSER */ | |
1466 | |
1467 if ((data->u.file.savedialog == TRUE) && | |
1468 (g_file_test(data->u.file.name, G_FILE_TEST_EXISTS))) { | |
1469 gaim_request_action(data, NULL, _("That file already exists"), | |
1470 _("Would you like to overwrite it?"), 0, data, 2, | |
1471 _("Overwrite"), G_CALLBACK(file_yes_no_cb), | |
1472 _("Choose New Name"), G_CALLBACK(file_yes_no_cb)); | |
1473 } else | |
1474 file_yes_no_cb(data, 1); | |
1475 } | |
1476 | |
1477 #if !GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ | |
1478 static void | |
1479 file_cancel_cb(GaimGtkRequestData *data) | |
1480 { | |
1481 generic_response_start(data); | |
1482 | |
1483 if (data->cbs[0] != NULL) | |
1484 ((GaimRequestFileCb)data->cbs[0])(data->user_data, NULL); | |
1485 | |
1486 gaim_request_close(data->type, data); | |
1487 } | |
1488 #endif /* FILECHOOSER */ | |
1489 | |
1490 static void * | |
1491 gaim_gtk_request_file(const char *title, const char *filename, | |
1492 gboolean savedialog, | |
1493 GCallback ok_cb, GCallback cancel_cb, | |
1494 void *user_data) | |
1495 { | |
1496 GaimGtkRequestData *data; | |
1497 GtkWidget *filesel; | |
1498 const gchar *current_folder; | |
1499 #if GTK_CHECK_VERSION(2,4,0) | |
1500 gboolean folder_set = FALSE; | |
1501 #endif | |
1502 | |
1503 data = g_new0(GaimGtkRequestData, 1); | |
1504 data->type = GAIM_REQUEST_FILE; | |
1505 data->user_data = user_data; | |
1506 data->cb_count = 2; | |
1507 data->cbs = g_new0(GCallback, 2); | |
1508 data->cbs[0] = cancel_cb; | |
1509 data->cbs[1] = ok_cb; | |
1510 data->u.file.savedialog = savedialog; | |
1511 | |
1512 #if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ | |
1513 filesel = gtk_file_chooser_dialog_new( | |
1514 title ? title : (savedialog ? _("Save File...") | |
1515 : _("Open File...")), | |
1516 NULL, | |
1517 savedialog ? GTK_FILE_CHOOSER_ACTION_SAVE | |
1518 : GTK_FILE_CHOOSER_ACTION_OPEN, | |
1519 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
1520 savedialog ? GTK_STOCK_SAVE | |
1521 : GTK_STOCK_OPEN, | |
1522 GTK_RESPONSE_ACCEPT, | |
1523 NULL); | |
1524 gtk_dialog_set_default_response(GTK_DIALOG(filesel), GTK_RESPONSE_ACCEPT); | |
1525 | |
1526 if (savedialog) { | |
1527 current_folder = gaim_prefs_get_path("/gaim/gtk/filelocations/last_save_folder"); | |
1528 } else { | |
1529 current_folder = gaim_prefs_get_path("/gaim/gtk/filelocations/last_open_folder"); | |
1530 } | |
1531 | |
1532 if ((filename != NULL) && (*filename != '\0')) { | |
1533 if (savedialog) | |
1534 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(filesel), filename); | |
1535 else | |
1536 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(filesel), filename); | |
1537 } | |
1538 if ((current_folder != NULL) && (*current_folder != '\0')) { | |
1539 folder_set = gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filesel), current_folder); | |
1540 } | |
1541 | |
1542 #ifdef _WIN32 | |
1543 if (!folder_set) { | |
1544 char *my_documents = wgaim_get_special_folder(CSIDL_PERSONAL); | |
1545 | |
1546 if (my_documents != NULL) { | |
1547 gtk_file_chooser_set_current_folder( | |
1548 GTK_FILE_CHOOSER(filesel), my_documents); | |
1549 | |
1550 g_free(my_documents); | |
1551 } | |
1552 } | |
1553 | |
1554 #endif | |
1555 g_signal_connect(G_OBJECT(GTK_FILE_CHOOSER(filesel)), "response", | |
1556 G_CALLBACK(file_ok_check_if_exists_cb), data); | |
1557 #else /* FILECHOOSER */ | |
1558 filesel = gtk_file_selection_new( | |
1559 title ? title : (savedialog ? _("Save File...") | |
1560 : _("Open File..."))); | |
1561 if (savedialog) { | |
1562 current_folder = gaim_prefs_get_path("/gaim/gtk/filelocations/last_save_folder"); | |
1563 } else { | |
1564 current_folder = gaim_prefs_get_path("/gaim/gtk/filelocations/last_open_folder"); | |
1565 } | |
1566 if (current_folder != NULL) { | |
1567 gchar *path = g_strdup_printf("%s%s", current_folder, G_DIR_SEPARATOR_S); | |
1568 gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel), path); | |
1569 g_free(path); | |
1570 } | |
1571 if (filename != NULL) | |
1572 gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel), filename); | |
1573 | |
1574 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(filesel)), "delete_event", | |
1575 G_CALLBACK(file_cancel_cb), data); | |
1576 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button), | |
1577 "clicked", G_CALLBACK(file_cancel_cb), data); | |
1578 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked", | |
1579 G_CALLBACK(file_ok_check_if_exists_cb), data); | |
1580 #endif /* FILECHOOSER */ | |
1581 | |
1582 data->dialog = filesel; | |
1583 gtk_widget_show(filesel); | |
1584 | |
1585 return (void *)data; | |
1586 } | |
1587 | |
1588 static void * | |
1589 gaim_gtk_request_folder(const char *title, const char *dirname, | |
1590 GCallback ok_cb, GCallback cancel_cb, | |
1591 void *user_data) | |
1592 { | |
1593 GaimGtkRequestData *data; | |
1594 GtkWidget *dirsel; | |
1595 | |
1596 data = g_new0(GaimGtkRequestData, 1); | |
1597 data->type = GAIM_REQUEST_FOLDER; | |
1598 data->user_data = user_data; | |
1599 data->cb_count = 2; | |
1600 data->cbs = g_new0(GCallback, 2); | |
1601 data->cbs[0] = cancel_cb; | |
1602 data->cbs[1] = ok_cb; | |
1603 data->u.file.savedialog = FALSE; | |
1604 | |
1605 #if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ | |
1606 dirsel = gtk_file_chooser_dialog_new( | |
1607 title ? title : _("Select Folder..."), | |
1608 NULL, | |
1609 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, | |
1610 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
1611 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, | |
1612 NULL); | |
1613 gtk_dialog_set_default_response(GTK_DIALOG(dirsel), GTK_RESPONSE_ACCEPT); | |
1614 | |
1615 if ((dirname != NULL) && (*dirname != '\0')) | |
1616 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dirsel), dirname); | |
1617 | |
1618 g_signal_connect(G_OBJECT(GTK_FILE_CHOOSER(dirsel)), "response", | |
1619 G_CALLBACK(file_ok_check_if_exists_cb), data); | |
1620 #else | |
1621 dirsel = gtk_file_selection_new(title ? title : _("Select Folder...")); | |
1622 | |
1623 g_signal_connect_swapped(G_OBJECT(dirsel), "delete_event", | |
1624 G_CALLBACK(file_cancel_cb), data); | |
1625 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(dirsel)->cancel_button), | |
1626 "clicked", G_CALLBACK(file_cancel_cb), data); | |
1627 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dirsel)->ok_button), "clicked", | |
1628 G_CALLBACK(file_ok_check_if_exists_cb), data); | |
1629 #endif | |
1630 | |
1631 data->dialog = dirsel; | |
1632 gtk_widget_show(dirsel); | |
1633 | |
1634 return (void *)data; | |
1635 } | |
1636 | |
1637 static void | |
1638 gaim_gtk_close_request(GaimRequestType type, void *ui_handle) | |
1639 { | |
1640 GaimGtkRequestData *data = (GaimGtkRequestData *)ui_handle; | |
1641 | |
1642 g_free(data->cbs); | |
1643 | |
1644 gtk_widget_destroy(data->dialog); | |
1645 | |
1646 if (type == GAIM_REQUEST_FIELDS) | |
1647 gaim_request_fields_destroy(data->u.multifield.fields); | |
1648 else if (type == GAIM_REQUEST_FILE) | |
1649 g_free(data->u.file.name); | |
1650 | |
1651 g_free(data); | |
1652 } | |
1653 | |
1654 static GaimRequestUiOps ops = | |
1655 { | |
1656 gaim_gtk_request_input, | |
1657 gaim_gtk_request_choice, | |
1658 gaim_gtk_request_action, | |
1659 gaim_gtk_request_fields, | |
1660 gaim_gtk_request_file, | |
1661 gaim_gtk_close_request, | |
1662 gaim_gtk_request_folder | |
1663 }; | |
1664 | |
1665 GaimRequestUiOps * | |
1666 gaim_gtk_request_get_ui_ops(void) | |
1667 { | |
1668 return &ops; | |
1669 } |