Minor changelog updates
[pidgin-git.git] / finch / gntrequest.c
bloba1157684bc00c76a2e6c01c0231a6854dfa51e4c
1 /**
2 * @file gntrequest.c GNT Request API
3 * @ingroup finch
4 */
6 /* finch
8 * Finch is the legal property of its developers, whose names are too numerous
9 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * source distribution.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 #include <gnt.h>
27 #include <gntbox.h>
28 #include <gntbutton.h>
29 #include <gntcheckbox.h>
30 #include <gntcombobox.h>
31 #include <gntentry.h>
32 #include <gntfilesel.h>
33 #include <gntlabel.h>
34 #include <gntline.h>
35 #include <gnttree.h>
37 #include "finch.h"
38 #include "gntrequest.h"
39 #include "util.h"
41 typedef struct
43 void *user_data;
44 GntWidget *dialog;
45 GCallback *cbs;
46 gboolean save;
47 } PurpleGntFileRequest;
49 static GntWidget *
50 setup_request_window(const char *title, const char *primary,
51 const char *secondary, PurpleRequestType type)
53 GntWidget *window;
55 window = gnt_vbox_new(FALSE);
56 gnt_box_set_toplevel(GNT_BOX(window), TRUE);
57 gnt_box_set_title(GNT_BOX(window), title);
58 gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
60 if (primary)
61 gnt_box_add_widget(GNT_BOX(window),
62 gnt_label_new_with_format(primary, GNT_TEXT_FLAG_BOLD));
63 if (secondary)
64 gnt_box_add_widget(GNT_BOX(window), gnt_label_new(secondary));
66 g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(purple_request_close),
67 GINT_TO_POINTER(type));
69 return window;
72 /**
73 * If the window is closed by the wm (ie, without triggering any of
74 * the buttons, then do some default callback.
76 static void
77 setup_default_callback(GntWidget *window, gpointer default_cb, gpointer data)
79 g_object_set_data(G_OBJECT(window), "default-callback", default_cb);
80 g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(default_cb), data);
83 static void
84 action_performed(GntWidget *button, gpointer data)
86 g_signal_handlers_disconnect_matched(data, G_SIGNAL_MATCH_FUNC,
87 0, 0, NULL,
88 g_object_get_data(data, "default-callback"),
89 NULL);
92 /**
93 * window: this is the window
94 * userdata: the userdata to pass to the primary callbacks
95 * cb: the callback
96 * data: data for the callback
97 * (text, primary-callback) pairs, ended by a NULL
99 static GntWidget *
100 setup_button_box(GntWidget *win, gpointer userdata, gpointer cb, gpointer data, ...)
102 GntWidget *box, *button;
103 va_list list;
104 const char *text;
105 gpointer callback;
107 box = gnt_hbox_new(FALSE);
109 va_start(list, data);
111 while ((text = va_arg(list, const char *)))
113 callback = va_arg(list, gpointer);
114 button = gnt_button_new(text);
115 gnt_box_add_widget(GNT_BOX(box), button);
116 g_object_set_data(G_OBJECT(button), "activate-callback", callback);
117 g_object_set_data(G_OBJECT(button), "activate-userdata", userdata);
118 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(action_performed), win);
119 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(cb), data);
122 va_end(list);
123 return box;
126 static void
127 notify_input_cb(GntWidget *button, GntWidget *entry)
129 PurpleRequestInputCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
130 gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
131 const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
133 if (callback)
134 callback(data, text);
136 while (button->parent)
137 button = button->parent;
139 purple_request_close(PURPLE_REQUEST_INPUT, button);
142 static void *
143 finch_request_input(const char *title, const char *primary,
144 const char *secondary, const char *default_value,
145 gboolean multiline, gboolean masked, gchar *hint,
146 const char *ok_text, GCallback ok_cb,
147 const char *cancel_text, GCallback cancel_cb,
148 PurpleAccount *account, const char *who, PurpleConversation *conv,
149 void *user_data)
151 GntWidget *window, *box, *entry;
153 window = setup_request_window(title, primary, secondary, PURPLE_REQUEST_INPUT);
155 entry = gnt_entry_new(default_value);
156 if (masked)
157 gnt_entry_set_masked(GNT_ENTRY(entry), TRUE);
158 gnt_box_add_widget(GNT_BOX(window), entry);
160 box = setup_button_box(window, user_data, notify_input_cb, entry,
161 ok_text, ok_cb, cancel_text, cancel_cb, NULL);
162 gnt_box_add_widget(GNT_BOX(window), box);
164 setup_default_callback(window, cancel_cb, user_data);
165 gnt_widget_show(window);
167 return window;
170 static void
171 finch_close_request(PurpleRequestType type, gpointer ui_handle)
173 GntWidget *widget = GNT_WIDGET(ui_handle);
174 if (type == PURPLE_REQUEST_FIELDS) {
175 PurpleRequestFields *fields = g_object_get_data(G_OBJECT(widget), "fields");
176 purple_request_fields_destroy(fields);
179 while (widget->parent)
180 widget = widget->parent;
181 gnt_widget_destroy(widget);
184 static void
185 request_choice_cb(GntWidget *button, GntComboBox *combo)
187 PurpleRequestChoiceCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
188 gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
189 int choice = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo))) - 1;
191 if (callback)
192 callback(data, choice);
194 while (button->parent)
195 button = button->parent;
197 purple_request_close(PURPLE_REQUEST_INPUT, button);
200 static void *
201 finch_request_choice(const char *title, const char *primary,
202 const char *secondary, int default_value,
203 const char *ok_text, GCallback ok_cb,
204 const char *cancel_text, GCallback cancel_cb,
205 PurpleAccount *account, const char *who, PurpleConversation *conv,
206 void *user_data, va_list choices)
208 GntWidget *window, *combo, *box;
209 const char *text;
210 int val;
212 window = setup_request_window(title, primary, secondary, PURPLE_REQUEST_CHOICE);
214 combo = gnt_combo_box_new();
215 gnt_box_add_widget(GNT_BOX(window), combo);
216 while ((text = va_arg(choices, const char *)))
218 val = va_arg(choices, int);
219 gnt_combo_box_add_data(GNT_COMBO_BOX(combo), GINT_TO_POINTER(val + 1), text);
221 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), GINT_TO_POINTER(default_value + 1));
223 box = setup_button_box(window, user_data, request_choice_cb, combo,
224 ok_text, ok_cb, cancel_text, cancel_cb, NULL);
225 gnt_box_add_widget(GNT_BOX(window), box);
227 setup_default_callback(window, cancel_cb, user_data);
228 gnt_widget_show(window);
230 return window;
233 static void
234 request_action_cb(GntWidget *button, GntWidget *window)
236 PurpleRequestActionCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
237 gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
238 int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "activate-id"));
240 if (callback)
241 callback(data, id);
243 purple_request_close(PURPLE_REQUEST_ACTION, window);
246 static void*
247 finch_request_action(const char *title, const char *primary,
248 const char *secondary, int default_value,
249 PurpleAccount *account, const char *who, PurpleConversation *conv,
250 void *user_data, size_t actioncount,
251 va_list actions)
253 GntWidget *window, *box, *button;
254 int i;
256 window = setup_request_window(title, primary, secondary, PURPLE_REQUEST_ACTION);
258 box = gnt_hbox_new(FALSE);
259 gnt_box_add_widget(GNT_BOX(window), box);
260 for (i = 0; i < actioncount; i++)
262 const char *text = va_arg(actions, const char *);
263 PurpleRequestActionCb callback = va_arg(actions, PurpleRequestActionCb);
265 button = gnt_button_new(text);
266 gnt_box_add_widget(GNT_BOX(box), button);
268 g_object_set_data(G_OBJECT(button), "activate-callback", callback);
269 g_object_set_data(G_OBJECT(button), "activate-userdata", user_data);
270 g_object_set_data(G_OBJECT(button), "activate-id", GINT_TO_POINTER(i));
271 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(request_action_cb), window);
274 gnt_widget_show(window);
276 return window;
279 static void
280 request_fields_cb(GntWidget *button, PurpleRequestFields *fields)
282 PurpleRequestFieldsCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
283 gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
284 GList *list;
286 /* Update the data of the fields. Pidgin does this differently. Instead of
287 * updating the fields at the end like here, it updates the appropriate field
288 * instantly whenever a change is made. That allows it to make sure the
289 * 'required' fields are entered before the user can hit OK. It's not the case
290 * here, althought it can be done. I am not honouring the 'required' fields
291 * for the moment. */
292 for (list = purple_request_fields_get_groups(fields); list; list = list->next)
294 PurpleRequestFieldGroup *group = list->data;
295 GList *fields = purple_request_field_group_get_fields(group);
297 for (; fields ; fields = fields->next)
299 PurpleRequestField *field = fields->data;
300 PurpleRequestFieldType type = purple_request_field_get_type(field);
301 if (type == PURPLE_REQUEST_FIELD_BOOLEAN)
303 GntWidget *check = field->ui_data;
304 gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(check));
305 purple_request_field_bool_set_value(field, value);
307 else if (type == PURPLE_REQUEST_FIELD_STRING)
309 GntWidget *entry = field->ui_data;
310 const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
311 purple_request_field_string_set_value(field, (text && *text) ? text : NULL);
313 else if (type == PURPLE_REQUEST_FIELD_INTEGER)
315 GntWidget *entry = field->ui_data;
316 const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
317 int value = (text && *text) ? atoi(text) : 0;
318 purple_request_field_int_set_value(field, value);
320 else if (type == PURPLE_REQUEST_FIELD_CHOICE)
322 GntWidget *combo = field->ui_data;
323 int id;
324 id = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)));
325 purple_request_field_choice_set_value(field, id);
327 else if (type == PURPLE_REQUEST_FIELD_LIST)
329 GList *list = NULL;
330 if (purple_request_field_list_get_multi_select(field))
332 GList *iter;
333 GntWidget *tree = field->ui_data;
335 iter = purple_request_field_list_get_items(field);
336 for (; iter; iter = iter->next)
338 const char *text = iter->data;
339 gpointer key = purple_request_field_list_get_data(field, text);
340 if (gnt_tree_get_choice(GNT_TREE(tree), key))
341 list = g_list_prepend(list, key);
344 else
346 GntWidget *combo = field->ui_data;
347 gpointer data = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
348 list = g_list_append(list, data);
351 purple_request_field_list_set_selected(field, list);
352 g_list_free(list);
354 else if (type == PURPLE_REQUEST_FIELD_ACCOUNT)
356 GntWidget *combo = field->ui_data;
357 PurpleAccount *acc = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
358 purple_request_field_account_set_value(field, acc);
363 if (callback)
364 callback(data, fields);
366 while (button->parent)
367 button = button->parent;
369 purple_request_close(PURPLE_REQUEST_FIELDS, button);
372 static void
373 update_selected_account(GntEntry *screenname, const char *start, const char *end,
374 GntComboBox *accountlist)
376 GList *accounts = gnt_tree_get_rows(GNT_TREE(accountlist->dropdown));
377 const char *name = gnt_entry_get_text(screenname);
378 while (accounts) {
379 if (purple_find_buddy(accounts->data, name)) {
380 gnt_combo_box_set_selected(accountlist, accounts->data);
381 gnt_widget_draw(GNT_WIDGET(accountlist));
382 break;
384 accounts = accounts->next;
388 static void *
389 finch_request_fields(const char *title, const char *primary,
390 const char *secondary, PurpleRequestFields *allfields,
391 const char *ok, GCallback ok_cb,
392 const char *cancel, GCallback cancel_cb,
393 PurpleAccount *account, const char *who, PurpleConversation *conv,
394 void *userdata)
396 GntWidget *window, *box;
397 GList *grlist;
398 GntWidget *screenname = NULL, *accountlist = NULL;
400 window = setup_request_window(title, primary, secondary, PURPLE_REQUEST_FIELDS);
402 /* This is how it's going to work: the request-groups are going to be
403 * stacked vertically one after the other. A GntLine will be separating
404 * the groups. */
405 box = gnt_vbox_new(FALSE);
406 gnt_box_set_pad(GNT_BOX(box), 0);
407 gnt_box_set_fill(GNT_BOX(box), TRUE);
408 for (grlist = purple_request_fields_get_groups(allfields); grlist; grlist = grlist->next)
410 PurpleRequestFieldGroup *group = grlist->data;
411 GList *fields = purple_request_field_group_get_fields(group);
412 GntWidget *hbox;
413 const char *title = purple_request_field_group_get_title(group);
415 if (title)
416 gnt_box_add_widget(GNT_BOX(box),
417 gnt_label_new_with_format(title, GNT_TEXT_FLAG_BOLD));
419 for (; fields ; fields = fields->next)
421 /* XXX: Break each of the fields into a separate function? */
422 PurpleRequestField *field = fields->data;
423 PurpleRequestFieldType type = purple_request_field_get_type(field);
424 const char *label = purple_request_field_get_label(field);
426 hbox = gnt_hbox_new(TRUE); /* hrm */
427 gnt_box_add_widget(GNT_BOX(box), hbox);
429 if (type != PURPLE_REQUEST_FIELD_BOOLEAN && label)
431 GntWidget *l = gnt_label_new(label);
432 gnt_widget_set_size(l, 0, 1);
433 gnt_box_add_widget(GNT_BOX(hbox), l);
436 if (type == PURPLE_REQUEST_FIELD_BOOLEAN)
438 GntWidget *check = gnt_check_box_new(label);
439 gnt_check_box_set_checked(GNT_CHECK_BOX(check),
440 purple_request_field_bool_get_default_value(field));
441 gnt_box_add_widget(GNT_BOX(hbox), check);
442 field->ui_data = check;
444 else if (type == PURPLE_REQUEST_FIELD_STRING)
446 const char *hint = purple_request_field_get_type_hint(field);
447 GntWidget *entry = gnt_entry_new(
448 purple_request_field_string_get_default_value(field));
449 gnt_entry_set_masked(GNT_ENTRY(entry),
450 purple_request_field_string_is_masked(field));
451 if (hint && purple_str_has_prefix(hint, "screenname")) {
452 PurpleBlistNode *node = purple_blist_get_root();
453 gboolean offline = purple_str_has_suffix(hint, "all");
454 for (; node; node = purple_blist_node_next(node, offline)) {
455 if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
456 continue;
457 gnt_entry_add_suggest(GNT_ENTRY(entry), purple_buddy_get_name((PurpleBuddy*)node));
459 gnt_entry_set_always_suggest(GNT_ENTRY(entry), TRUE);
460 screenname = entry;
461 } else if (hint && !strcmp(hint, "group")) {
462 PurpleBlistNode *node;
463 for (node = purple_blist_get_root(); node; node = node->next) {
464 if (PURPLE_BLIST_NODE_IS_GROUP(node))
465 gnt_entry_add_suggest(GNT_ENTRY(entry), ((PurpleGroup *)node)->name);
468 gnt_box_add_widget(GNT_BOX(hbox), entry);
469 field->ui_data = entry;
471 else if (type == PURPLE_REQUEST_FIELD_INTEGER)
473 char str[256];
474 int val = purple_request_field_int_get_default_value(field);
475 GntWidget *entry;
477 snprintf(str, sizeof(str), "%d", val);
478 entry = gnt_entry_new(str);
479 gnt_entry_set_flag(GNT_ENTRY(entry), GNT_ENTRY_FLAG_INT);
480 gnt_box_add_widget(GNT_BOX(hbox), entry);
481 field->ui_data = entry;
483 else if (type == PURPLE_REQUEST_FIELD_CHOICE)
485 int id;
486 GList *list;
487 GntWidget *combo = gnt_combo_box_new();
488 gnt_box_add_widget(GNT_BOX(hbox), combo);
489 field->ui_data = combo;
491 list = purple_request_field_choice_get_labels(field);
492 for (id = 1; list; list = list->next, id++)
494 gnt_combo_box_add_data(GNT_COMBO_BOX(combo),
495 GINT_TO_POINTER(id), list->data);
497 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo),
498 GINT_TO_POINTER(purple_request_field_choice_get_default_value(field)));
500 else if (type == PURPLE_REQUEST_FIELD_LIST)
502 GList *list;
503 gboolean multi = purple_request_field_list_get_multi_select(field);
504 if (multi)
506 GntWidget *tree = gnt_tree_new();
507 gnt_box_add_widget(GNT_BOX(hbox), tree);
508 field->ui_data = tree;
510 list = purple_request_field_list_get_items(field);
511 for (; list; list = list->next)
513 const char *text = list->data;
514 gpointer key = purple_request_field_list_get_data(field, text);
515 gnt_tree_add_choice(GNT_TREE(tree), key,
516 gnt_tree_create_row(GNT_TREE(tree), text), NULL, NULL);
517 if (purple_request_field_list_is_selected(field, text))
518 gnt_tree_set_choice(GNT_TREE(tree), key, TRUE);
521 else
523 GntWidget *combo = gnt_combo_box_new();
524 gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
525 gnt_box_add_widget(GNT_BOX(hbox), combo);
526 field->ui_data = combo;
528 list = purple_request_field_list_get_items(field);
529 for (; list; list = list->next)
531 const char *text = list->data;
532 gpointer key = purple_request_field_list_get_data(field, text);
533 gnt_combo_box_add_data(GNT_COMBO_BOX(combo), key, text);
534 if (purple_request_field_list_is_selected(field, text))
535 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), key);
539 else if (type == PURPLE_REQUEST_FIELD_ACCOUNT)
541 gboolean all;
542 PurpleAccount *def;
543 GList *list;
544 GntWidget *combo = gnt_combo_box_new();
545 gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
546 gnt_box_add_widget(GNT_BOX(hbox), combo);
547 field->ui_data = combo;
549 all = purple_request_field_account_get_show_all(field);
550 def = purple_request_field_account_get_value(field);
551 if (!def)
552 def = purple_request_field_account_get_default_value(field);
554 if (all)
555 list = purple_accounts_get_all();
556 else
557 list = purple_connections_get_all();
559 for (; list; list = list->next)
561 PurpleAccount *account;
562 char *text;
564 if (all)
565 account = list->data;
566 else
567 account = purple_connection_get_account(list->data);
569 text = g_strdup_printf("%s (%s)",
570 purple_account_get_username(account),
571 purple_account_get_protocol_name(account));
572 gnt_combo_box_add_data(GNT_COMBO_BOX(combo), account, text);
573 g_free(text);
574 if (account == def)
575 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), account);
577 gnt_widget_set_size(combo, 20, 3); /* ew */
578 accountlist = combo;
580 else
582 gnt_box_add_widget(GNT_BOX(hbox),
583 gnt_label_new_with_format(_("Not implemented yet."),
584 GNT_TEXT_FLAG_BOLD));
587 if (grlist->next)
588 gnt_box_add_widget(GNT_BOX(box), gnt_hline_new());
590 gnt_box_add_widget(GNT_BOX(window), box);
592 box = setup_button_box(window, userdata, request_fields_cb, allfields,
593 ok, ok_cb, cancel, cancel_cb, NULL);
594 gnt_box_add_widget(GNT_BOX(window), box);
596 setup_default_callback(window, cancel_cb, userdata);
597 gnt_widget_show(window);
599 if (screenname && accountlist) {
600 g_signal_connect(screenname, "completion", G_CALLBACK(update_selected_account), accountlist);
603 g_object_set_data(G_OBJECT(window), "fields", allfields);
605 return window;
608 static void
609 file_cancel_cb(gpointer fq, GntWidget *wid)
611 PurpleGntFileRequest *data = fq;
612 if (data->cbs[1] != NULL)
613 ((PurpleRequestFileCb)data->cbs[1])(data->user_data, NULL);
615 purple_request_close(PURPLE_REQUEST_FILE, data->dialog);
618 static void
619 file_ok_cb(gpointer fq, GntWidget *widget)
621 PurpleGntFileRequest *data = fq;
622 char *file = gnt_file_sel_get_selected_file(GNT_FILE_SEL(data->dialog));
623 char *dir = g_path_get_dirname(file);
624 if (data->cbs[0] != NULL)
625 ((PurpleRequestFileCb)data->cbs[0])(data->user_data, file);
626 g_free(file);
627 purple_prefs_set_path(data->save ? "/finch/filelocations/last_save_folder" :
628 "/finch/filelocations/last_open_folder", dir);
629 g_free(dir);
631 purple_request_close(PURPLE_REQUEST_FILE, data->dialog);
634 static void
635 file_request_destroy(PurpleGntFileRequest *data)
637 g_free(data->cbs);
638 g_free(data);
641 static void *
642 finch_request_file(const char *title, const char *filename,
643 gboolean savedialog,
644 GCallback ok_cb, GCallback cancel_cb,
645 PurpleAccount *account, const char *who, PurpleConversation *conv,
646 void *user_data)
648 GntWidget *window = gnt_file_sel_new();
649 GntFileSel *sel = GNT_FILE_SEL(window);
650 PurpleGntFileRequest *data = g_new0(PurpleGntFileRequest, 1);
651 const char *path;
653 data->user_data = user_data;
654 data->cbs = g_new0(GCallback, 2);
655 data->cbs[0] = ok_cb;
656 data->cbs[1] = cancel_cb;
657 data->dialog = window;
658 data->save = savedialog;
659 gnt_box_set_title(GNT_BOX(window), title ? title : (savedialog ? _("Save File...") : _("Open File...")));
661 path = purple_prefs_get_path(savedialog ? "/finch/filelocations/last_save_folder" : "/finch/filelocations/last_open_folder");
662 gnt_file_sel_set_current_location(sel, (path && *path) ? path : purple_home_dir());
664 if (savedialog)
665 gnt_file_sel_set_suggested_filename(sel, filename);
667 g_signal_connect(G_OBJECT(sel->cancel), "activate",
668 G_CALLBACK(action_performed), window);
669 g_signal_connect(G_OBJECT(sel->select), "activate",
670 G_CALLBACK(action_performed), window);
671 g_signal_connect_swapped(G_OBJECT(sel->cancel), "activate",
672 G_CALLBACK(file_cancel_cb), data);
673 g_signal_connect_swapped(G_OBJECT(sel->select), "activate",
674 G_CALLBACK(file_ok_cb), data);
676 setup_default_callback(window, file_cancel_cb, data);
677 g_object_set_data_full(G_OBJECT(window), "filerequestdata", data,
678 (GDestroyNotify)file_request_destroy);
679 gnt_widget_show(window);
681 return window;
684 static PurpleRequestUiOps uiops =
686 finch_request_input,
687 finch_request_choice,
688 finch_request_action,
689 finch_request_fields,
690 finch_request_file,
691 finch_close_request,
692 NULL, /* No plans for request_folder */
693 NULL,
694 NULL,
695 NULL,
696 NULL
699 PurpleRequestUiOps *finch_request_get_ui_ops()
701 return &uiops;
704 void finch_request_init()
708 void finch_request_uninit()
712 void finch_request_save_in_prefs(gpointer null, PurpleRequestFields *allfields)
714 GList *list;
715 for (list = purple_request_fields_get_groups(allfields); list; list = list->next) {
716 PurpleRequestFieldGroup *group = list->data;
717 GList *fields = purple_request_field_group_get_fields(group);
719 for (; fields ; fields = fields->next) {
720 PurpleRequestField *field = fields->data;
721 PurpleRequestFieldType type = purple_request_field_get_type(field);
722 PurplePrefType pt;
723 gpointer val = NULL;
724 const char *id = purple_request_field_get_id(field);
726 switch (type) {
727 case PURPLE_REQUEST_FIELD_LIST:
728 val = purple_request_field_list_get_selected(field)->data;
729 break;
730 case PURPLE_REQUEST_FIELD_BOOLEAN:
731 val = GINT_TO_POINTER(purple_request_field_bool_get_value(field));
732 break;
733 case PURPLE_REQUEST_FIELD_INTEGER:
734 val = GINT_TO_POINTER(purple_request_field_int_get_value(field));
735 break;
736 case PURPLE_REQUEST_FIELD_STRING:
737 val = (gpointer)purple_request_field_string_get_value(field);
738 break;
739 default:
740 break;
743 pt = purple_prefs_get_type(id);
744 switch (pt) {
745 case PURPLE_PREF_INT:
747 long int tmp = GPOINTER_TO_INT(val);
748 if (type == PURPLE_REQUEST_FIELD_LIST) /* Lists always return string */
749 sscanf(val, "%ld", &tmp);
750 purple_prefs_set_int(id, (gint)tmp);
751 break;
753 case PURPLE_PREF_BOOLEAN:
754 purple_prefs_set_bool(id, GPOINTER_TO_INT(val));
755 break;
756 case PURPLE_PREF_STRING:
757 purple_prefs_set_string(id, val);
758 break;
759 default:
760 break;