4 * Finch is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
27 #include <gntbutton.h>
28 #include <gntcheckbox.h>
29 #include <gntcombobox.h>
31 #include <gntfilesel.h>
37 #include "gntrequest.h"
50 setup_request_window(const char *title
, const char *primary
,
51 const char *secondary
, PurpleRequestType type
)
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
);
61 gnt_box_add_widget(GNT_BOX(window
),
62 gnt_label_new_with_format(primary
, GNT_TEXT_FLAG_BOLD
));
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
));
73 * If the window is closed by the wm (ie, without triggering any of
74 * the buttons, then do some default callback.
77 setup_default_callback(GntWidget
*window
, gpointer default_cb
, gpointer data
)
79 if (default_cb
== NULL
)
81 g_object_set_data(G_OBJECT(window
), "default-callback", default_cb
);
82 g_signal_connect_swapped(G_OBJECT(window
), "destroy", G_CALLBACK(default_cb
), data
);
86 action_performed(GntWidget
*button
, gpointer data
)
88 g_signal_handlers_disconnect_matched(data
, G_SIGNAL_MATCH_FUNC
,
90 g_object_get_data(data
, "default-callback"),
96 * @win: this is the window
97 * @userdata: the userdata to pass to the primary callbacks
99 * @data: data for the callback
100 * @...: (text, primary-callback) pairs, ended by a NULL
102 * The cancellation callback should be the last callback sent.
105 setup_button_box(GntWidget
*win
, gpointer userdata
, gpointer cb
, gpointer data
, ...)
108 GntWidget
*button
= NULL
;
113 box
= gnt_hbox_new(FALSE
);
115 va_start(list
, data
);
117 while ((text
= va_arg(list
, const char *)))
119 callback
= va_arg(list
, gpointer
);
120 button
= gnt_button_new(text
);
121 gnt_box_add_widget(GNT_BOX(box
), button
);
122 g_object_set_data(G_OBJECT(button
), "activate-callback", callback
);
123 g_object_set_data(G_OBJECT(button
), "activate-userdata", userdata
);
124 g_signal_connect(G_OBJECT(button
), "activate", G_CALLBACK(action_performed
), win
);
125 g_signal_connect(G_OBJECT(button
), "activate", G_CALLBACK(cb
), data
);
129 g_object_set_data(G_OBJECT(button
), "cancellation-function", GINT_TO_POINTER(TRUE
));
136 notify_input_cb(GntWidget
*button
, GntWidget
*entry
)
138 PurpleRequestInputCb callback
= g_object_get_data(G_OBJECT(button
), "activate-callback");
139 gpointer data
= g_object_get_data(G_OBJECT(button
), "activate-userdata");
140 const char *text
= gnt_entry_get_text(GNT_ENTRY(entry
));
144 callback(data
, text
);
146 window
= gnt_widget_get_toplevel(button
);
147 purple_request_close(PURPLE_REQUEST_INPUT
, window
);
151 finch_request_input(const char *title
, const char *primary
,
152 const char *secondary
, const char *default_value
,
153 gboolean multiline
, gboolean masked
, gchar
*hint
,
154 const char *ok_text
, GCallback ok_cb
,
155 const char *cancel_text
, GCallback cancel_cb
,
156 PurpleRequestCommonParameters
*cpar
,
159 GntWidget
*window
, *box
, *entry
;
161 window
= setup_request_window(title
, primary
, secondary
, PURPLE_REQUEST_INPUT
);
163 entry
= gnt_entry_new(default_value
);
165 gnt_entry_set_masked(GNT_ENTRY(entry
), TRUE
);
166 gnt_box_add_widget(GNT_BOX(window
), entry
);
168 box
= setup_button_box(window
, user_data
, notify_input_cb
, entry
,
169 ok_text
, ok_cb
, cancel_text
, cancel_cb
, NULL
);
170 gnt_box_add_widget(GNT_BOX(window
), box
);
172 setup_default_callback(window
, cancel_cb
, user_data
);
173 gnt_widget_show(window
);
179 finch_close_request(PurpleRequestType type
, gpointer ui_handle
)
181 GntWidget
*widget
= GNT_WIDGET(ui_handle
);
182 if (type
== PURPLE_REQUEST_FIELDS
) {
183 PurpleRequestFields
*fields
= g_object_get_data(G_OBJECT(widget
), "fields");
184 purple_request_fields_destroy(fields
);
187 widget
= gnt_widget_get_toplevel(widget
);
188 gnt_widget_destroy(widget
);
192 request_choice_cb(GntWidget
*button
, GntComboBox
*combo
)
194 PurpleRequestChoiceCb callback
= g_object_get_data(G_OBJECT(button
), "activate-callback");
195 gpointer data
= g_object_get_data(G_OBJECT(button
), "activate-userdata");
196 gpointer choice
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo
));
200 callback(data
, choice
);
202 window
= gnt_widget_get_toplevel(button
);
203 purple_request_close(PURPLE_REQUEST_INPUT
, window
);
207 finch_request_choice(const char *title
, const char *primary
,
208 const char *secondary
, gpointer default_value
,
209 const char *ok_text
, GCallback ok_cb
,
210 const char *cancel_text
, GCallback cancel_cb
,
211 PurpleRequestCommonParameters
*cpar
,
212 void *user_data
, va_list choices
)
214 GntWidget
*window
, *combo
, *box
;
218 window
= setup_request_window(title
, primary
, secondary
, PURPLE_REQUEST_CHOICE
);
220 combo
= gnt_combo_box_new();
221 gnt_box_add_widget(GNT_BOX(window
), combo
);
222 while ((text
= va_arg(choices
, const char *)))
224 val
= va_arg(choices
, int);
225 gnt_combo_box_add_data(GNT_COMBO_BOX(combo
), GINT_TO_POINTER(val
+ 1), text
);
227 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo
), default_value
);
229 box
= setup_button_box(window
, user_data
, request_choice_cb
, combo
,
230 ok_text
, ok_cb
, cancel_text
, cancel_cb
, NULL
);
231 gnt_box_add_widget(GNT_BOX(window
), box
);
233 setup_default_callback(window
, cancel_cb
, user_data
);
234 gnt_widget_show(window
);
240 request_action_cb(GntWidget
*button
, GntWidget
*window
)
242 PurpleRequestActionCb callback
= g_object_get_data(G_OBJECT(button
), "activate-callback");
243 gpointer data
= g_object_get_data(G_OBJECT(button
), "activate-userdata");
244 int id
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button
), "activate-id"));
249 purple_request_close(PURPLE_REQUEST_ACTION
, window
);
253 finch_request_action(const char *title
, const char *primary
,
254 const char *secondary
, int default_value
,
255 PurpleRequestCommonParameters
*cpar
,
256 void *user_data
, size_t actioncount
,
259 GntWidget
*window
, *box
, *button
, *focus
= NULL
;
262 window
= setup_request_window(title
, primary
, secondary
, PURPLE_REQUEST_ACTION
);
264 box
= gnt_hbox_new(FALSE
);
265 gnt_box_add_widget(GNT_BOX(window
), box
);
266 for (i
= 0; i
< actioncount
; i
++)
268 const char *text
= va_arg(actions
, const char *);
269 PurpleRequestActionCb callback
= va_arg(actions
, PurpleRequestActionCb
);
271 button
= gnt_button_new(text
);
272 gnt_box_add_widget(GNT_BOX(box
), button
);
274 g_object_set_data(G_OBJECT(button
), "activate-callback", callback
);
275 g_object_set_data(G_OBJECT(button
), "activate-userdata", user_data
);
276 g_object_set_data(G_OBJECT(button
), "activate-id", GINT_TO_POINTER(i
));
277 g_signal_connect(G_OBJECT(button
), "activate", G_CALLBACK(request_action_cb
), window
);
279 if (default_value
>= 0 && i
== (gsize
)default_value
)
283 gnt_widget_show(window
);
285 gnt_box_give_focus_to_child(GNT_BOX(window
), focus
);
291 request_fields_cb(GntWidget
*button
, PurpleRequestFields
*fields
)
293 PurpleRequestFieldsCb callback
= g_object_get_data(G_OBJECT(button
), "activate-callback");
294 gpointer data
= g_object_get_data(G_OBJECT(button
), "activate-userdata");
298 /* Update the data of the fields. Pidgin does this differently. Instead of
299 * updating the fields at the end like here, it updates the appropriate field
300 * instantly whenever a change is made. That allows it to make sure the
301 * 'required' fields are entered before the user can hit OK. It's not the case
302 * here, althought it can be done. */
303 for (list
= purple_request_fields_get_groups(fields
); list
; list
= list
->next
)
305 PurpleRequestFieldGroup
*group
= list
->data
;
306 GList
*fields
= purple_request_field_group_get_fields(group
);
308 for (; fields
; fields
= fields
->next
)
310 PurpleRequestField
*field
= fields
->data
;
311 PurpleRequestFieldType type
= purple_request_field_get_field_type(field
);
312 if (!purple_request_field_is_visible(field
))
314 if (type
== PURPLE_REQUEST_FIELD_BOOLEAN
)
316 GntWidget
*check
= purple_request_field_get_ui_data(field
);
317 gboolean value
= gnt_check_box_get_checked(GNT_CHECK_BOX(check
));
318 purple_request_field_bool_set_value(field
, value
);
320 else if (type
== PURPLE_REQUEST_FIELD_STRING
)
322 GntWidget
*entry
= purple_request_field_get_ui_data(field
);
323 const char *text
= gnt_entry_get_text(GNT_ENTRY(entry
));
324 purple_request_field_string_set_value(field
, (text
&& *text
) ? text
: NULL
);
326 else if (type
== PURPLE_REQUEST_FIELD_INTEGER
)
328 GntWidget
*entry
= purple_request_field_get_ui_data(field
);
329 const char *text
= gnt_entry_get_text(GNT_ENTRY(entry
));
330 int value
= (text
&& *text
) ? atoi(text
) : 0;
331 purple_request_field_int_set_value(field
, value
);
333 else if (type
== PURPLE_REQUEST_FIELD_CHOICE
)
335 GntWidget
*combo
= purple_request_field_get_ui_data(field
);
336 gpointer value
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo
));
337 purple_request_field_choice_set_value(field
, value
);
339 else if (type
== PURPLE_REQUEST_FIELD_LIST
)
341 GList
*list
= NULL
, *iter
;
342 if (purple_request_field_list_get_multi_select(field
))
344 GntWidget
*tree
= purple_request_field_get_ui_data(field
);
346 iter
= purple_request_field_list_get_items(field
);
347 for (; iter
; iter
= iter
->next
)
349 const char *text
= iter
->data
;
350 gpointer key
= purple_request_field_list_get_data(field
, text
);
351 if (gnt_tree_get_choice(GNT_TREE(tree
), key
))
352 list
= g_list_prepend(list
, (gpointer
)text
);
357 GntWidget
*combo
= purple_request_field_get_ui_data(field
);
358 gpointer data
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo
));
360 iter
= purple_request_field_list_get_items(field
);
361 for (; iter
; iter
= iter
->next
) {
362 const char *text
= iter
->data
;
363 gpointer key
= purple_request_field_list_get_data(field
, text
);
365 list
= g_list_prepend(list
, (gpointer
)text
);
371 purple_request_field_list_set_selected(field
, list
);
374 else if (type
== PURPLE_REQUEST_FIELD_ACCOUNT
)
376 GntWidget
*combo
= purple_request_field_get_ui_data(field
);
377 PurpleAccount
*acc
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo
));
378 purple_request_field_account_set_value(field
, acc
);
383 purple_notify_close_with_handle(button
);
385 if (!g_object_get_data(G_OBJECT(button
), "cancellation-function") &&
386 (!purple_request_fields_all_required_filled(fields
) ||
387 !purple_request_fields_all_valid(fields
))) {
388 purple_notify_error(button
, _("Error"),
389 _("You must properly fill all the required fields."),
390 _("The required fields are underlined."), NULL
);
395 callback(data
, fields
);
397 window
= gnt_widget_get_toplevel(button
);
398 purple_request_close(PURPLE_REQUEST_FIELDS
, window
);
402 update_selected_account(GntEntry
*username
, const char *start
, const char *end
,
403 GntComboBox
*accountlist
)
406 gnt_tree_get_rows(GNT_TREE(gnt_combo_box_get_dropdown(accountlist
)));
407 const char *name
= gnt_entry_get_text(username
);
409 if (purple_blist_find_buddy(accounts
->data
, name
)) {
410 gnt_combo_box_set_selected(accountlist
, accounts
->data
);
411 gnt_widget_draw(GNT_WIDGET(accountlist
));
414 accounts
= accounts
->next
;
419 create_boolean_field(PurpleRequestField
*field
)
421 const char *label
= purple_request_field_get_label(field
);
422 GntWidget
*check
= gnt_check_box_new(label
);
423 gnt_check_box_set_checked(GNT_CHECK_BOX(check
),
424 purple_request_field_bool_get_default_value(field
));
429 create_string_field(PurpleRequestField
*field
, GntWidget
**username
)
431 const char *hint
= purple_request_field_get_field_type_hint(field
);
432 GntWidget
*entry
= gnt_entry_new(
433 purple_request_field_string_get_default_value(field
));
434 gnt_entry_set_masked(GNT_ENTRY(entry
),
435 purple_request_field_string_is_masked(field
));
436 if (hint
&& purple_str_has_prefix(hint
, "screenname")) {
437 PurpleBlistNode
*node
= purple_blist_get_default_root();
438 gboolean offline
= purple_str_has_suffix(hint
, "all");
439 for (; node
; node
= purple_blist_node_next(node
, offline
)) {
440 if (!PURPLE_IS_BUDDY(node
))
442 gnt_entry_add_suggest(GNT_ENTRY(entry
), purple_buddy_get_name((PurpleBuddy
*)node
));
444 gnt_entry_set_always_suggest(GNT_ENTRY(entry
), TRUE
);
447 } else if (purple_strequal(hint
, "group")) {
448 PurpleBlistNode
*node
;
449 for (node
= purple_blist_get_default_root(); node
;
450 node
= purple_blist_node_get_sibling_next(node
)) {
451 if (PURPLE_IS_GROUP(node
))
452 gnt_entry_add_suggest(GNT_ENTRY(entry
), purple_group_get_name((PurpleGroup
*)node
));
459 create_integer_field(PurpleRequestField
*field
)
462 int val
= purple_request_field_int_get_default_value(field
);
465 snprintf(str
, sizeof(str
), "%d", val
);
466 entry
= gnt_entry_new(str
);
467 gnt_entry_set_flag(GNT_ENTRY(entry
), GNT_ENTRY_FLAG_INT
);
472 create_choice_field(PurpleRequestField
*field
)
475 GntWidget
*combo
= gnt_combo_box_new();
477 it
= purple_request_field_choice_get_elements(field
);
484 it
= g_list_next(it
);
485 g_assert(it
!= NULL
);
487 it
= g_list_next(it
);
489 gnt_combo_box_add_data(GNT_COMBO_BOX(combo
), value
, text
);
491 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo
),
492 purple_request_field_choice_get_default_value(field
));
497 create_list_field(PurpleRequestField
*field
)
499 GntWidget
*ret
= NULL
;
501 gboolean multi
= purple_request_field_list_get_multi_select(field
);
504 GntWidget
*tree
= gnt_tree_new();
506 list
= purple_request_field_list_get_items(field
);
507 for (; list
; list
= list
->next
)
509 const char *text
= list
->data
;
510 gpointer key
= purple_request_field_list_get_data(field
, text
);
511 gnt_tree_add_choice(GNT_TREE(tree
), key
,
512 gnt_tree_create_row(GNT_TREE(tree
), text
), NULL
, NULL
);
513 if (purple_request_field_list_is_selected(field
, text
))
514 gnt_tree_set_choice(GNT_TREE(tree
), key
, TRUE
);
520 GntWidget
*combo
= gnt_combo_box_new();
522 list
= purple_request_field_list_get_items(field
);
523 for (; list
; list
= list
->next
)
525 const char *text
= list
->data
;
526 gpointer key
= purple_request_field_list_get_data(field
, text
);
527 gnt_combo_box_add_data(GNT_COMBO_BOX(combo
), key
, text
);
528 if (purple_request_field_list_is_selected(field
, text
))
529 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo
), key
);
537 create_account_field(PurpleRequestField
*field
)
542 GntWidget
*combo
= gnt_combo_box_new();
544 all
= purple_request_field_account_get_show_all(field
);
545 def
= purple_request_field_account_get_value(field
);
547 def
= purple_request_field_account_get_default_value(field
);
550 list
= purple_accounts_get_all();
552 list
= purple_connections_get_all();
554 for (; list
; list
= list
->next
)
556 PurpleAccount
*account
;
560 account
= list
->data
;
562 account
= purple_connection_get_account(list
->data
);
564 text
= g_strdup_printf("%s (%s)",
565 purple_account_get_username(account
),
566 purple_account_get_protocol_name(account
));
567 gnt_combo_box_add_data(GNT_COMBO_BOX(combo
), account
, text
);
570 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo
), account
);
572 gnt_widget_set_size(combo
, 20, 3); /* ew */
577 multifield_extra_cb(GntWidget
*button
, PurpleRequestFields
*allfields
)
579 PurpleRequestFieldsCb cb
;
583 handle
= g_object_get_data(G_OBJECT(button
), "ui-handle");
584 cb
= g_object_get_data(G_OBJECT(button
), "extra-cb");
585 cb_data
= g_object_get_data(G_OBJECT(button
), "extra-cb-data");
588 cb(cb_data
, allfields
);
590 action_performed(button
, handle
);
591 purple_request_close(PURPLE_REQUEST_FIELDS
, handle
);
595 finch_request_fields(const char *title
, const char *primary
,
596 const char *secondary
, PurpleRequestFields
*allfields
,
597 const char *ok
, GCallback ok_cb
,
598 const char *cancel
, GCallback cancel_cb
,
599 PurpleRequestCommonParameters
*cpar
,
602 GntWidget
*window
, *box
;
604 GntWidget
*username
= NULL
, *accountlist
= NULL
;
605 PurpleRequestHelpCb help_cb
;
607 GSList
*extra_actions
, *it
;
609 window
= setup_request_window(title
, primary
, secondary
, PURPLE_REQUEST_FIELDS
);
611 /* This is how it's going to work: the request-groups are going to be
612 * stacked vertically one after the other. A GntLine will be separating
614 box
= gnt_vbox_new(FALSE
);
615 gnt_box_set_pad(GNT_BOX(box
), 0);
616 gnt_box_set_fill(GNT_BOX(box
), TRUE
);
617 for (grlist
= purple_request_fields_get_groups(allfields
); grlist
; grlist
= grlist
->next
)
619 PurpleRequestFieldGroup
*group
= grlist
->data
;
620 GList
*fields
= purple_request_field_group_get_fields(group
);
622 const char *title
= purple_request_field_group_get_title(group
);
625 gnt_box_add_widget(GNT_BOX(box
),
626 gnt_label_new_with_format(title
, GNT_TEXT_FLAG_BOLD
));
628 for (; fields
; fields
= fields
->next
)
630 PurpleRequestField
*field
= fields
->data
;
631 PurpleRequestFieldType type
= purple_request_field_get_field_type(field
);
632 const char *label
= purple_request_field_get_label(field
);
634 if (!purple_request_field_is_visible(field
))
637 hbox
= gnt_hbox_new(TRUE
); /* hrm */
638 gnt_box_add_widget(GNT_BOX(box
), hbox
);
640 if (type
!= PURPLE_REQUEST_FIELD_BOOLEAN
&& label
)
643 if (purple_request_field_is_required(field
))
644 l
= gnt_label_new_with_format(label
, GNT_TEXT_FLAG_UNDERLINE
);
646 l
= gnt_label_new(label
);
647 gnt_widget_set_size(l
, 0, 1);
648 gnt_box_add_widget(GNT_BOX(hbox
), l
);
651 if (type
== PURPLE_REQUEST_FIELD_BOOLEAN
)
653 purple_request_field_set_ui_data(field
, create_boolean_field(field
));
655 else if (type
== PURPLE_REQUEST_FIELD_STRING
)
657 purple_request_field_set_ui_data(field
, create_string_field(field
, &username
));
659 else if (type
== PURPLE_REQUEST_FIELD_INTEGER
)
661 purple_request_field_set_ui_data(field
, create_integer_field(field
));
663 else if (type
== PURPLE_REQUEST_FIELD_CHOICE
)
665 purple_request_field_set_ui_data(field
, create_choice_field(field
));
667 else if (type
== PURPLE_REQUEST_FIELD_LIST
)
669 purple_request_field_set_ui_data(field
, create_list_field(field
));
671 else if (type
== PURPLE_REQUEST_FIELD_ACCOUNT
)
673 accountlist
= create_account_field(field
);
674 purple_request_field_set_ui_data(field
, accountlist
);
678 purple_request_field_set_ui_data(field
, gnt_label_new_with_format(_("Not implemented yet."),
679 GNT_TEXT_FLAG_BOLD
));
681 gnt_box_set_alignment(GNT_BOX(hbox
), GNT_ALIGN_MID
);
682 gnt_box_add_widget(GNT_BOX(hbox
), GNT_WIDGET(purple_request_field_get_ui_data(field
)));
685 gnt_box_add_widget(GNT_BOX(box
), gnt_hline_new());
687 gnt_box_add_widget(GNT_BOX(window
), box
);
689 box
= setup_button_box(window
, userdata
, request_fields_cb
, allfields
,
690 ok
, ok_cb
, cancel
, cancel_cb
, NULL
);
692 extra_actions
= purple_request_cpar_get_extra_actions(cpar
);
693 for (it
= extra_actions
; it
; it
= it
->next
->next
) {
694 const gchar
*label
= it
->data
;
695 PurpleRequestFieldsCb
*cb
= it
->next
->data
;
697 GntWidget
*button
= gnt_button_new(label
);
698 gnt_box_add_widget_in_front(GNT_BOX(box
), button
);
699 g_object_set_data(G_OBJECT(button
), "ui-handle", window
);
700 g_object_set_data(G_OBJECT(button
), "extra-cb", cb
);
701 g_object_set_data(G_OBJECT(button
), "extra-cb-data", userdata
);
702 g_signal_connect(G_OBJECT(button
), "activate",
703 G_CALLBACK(multifield_extra_cb
), allfields
);
706 help_cb
= purple_request_cpar_get_help_cb(cpar
, &help_data
);
708 GntWidget
*button
= gnt_button_new(_("Help"));
709 gnt_box_add_widget_in_front(GNT_BOX(box
), button
);
710 g_signal_connect_swapped(G_OBJECT(button
), "activate",
711 G_CALLBACK(help_cb
), help_data
);
714 gnt_box_add_widget(GNT_BOX(window
), box
);
716 setup_default_callback(window
, cancel_cb
, userdata
);
717 gnt_widget_show(window
);
719 if (username
&& accountlist
) {
720 g_signal_connect(username
, "completion", G_CALLBACK(update_selected_account
), accountlist
);
723 g_object_set_data(G_OBJECT(window
), "fields", allfields
);
729 file_cancel_cb(GntWidget
*wid
, gpointer fq
)
731 FinchFileRequest
*data
= fq
;
732 if (data
->dialog
== NULL
) {
733 /* We've already handled this request, and are in the destroy handler. */
737 if (data
->cbs
[1] != NULL
)
738 ((PurpleRequestFileCb
)data
->cbs
[1])(data
->user_data
, NULL
);
740 purple_request_close(PURPLE_REQUEST_FILE
, data
->dialog
);
745 file_ok_cb(GntWidget
*widget
, const char *path
, const char *file
, gpointer fq
)
747 FinchFileRequest
*data
= fq
;
748 char *dir
= g_path_get_dirname(path
);
749 if (data
->cbs
[0] != NULL
)
750 ((PurpleRequestFileCb
)data
->cbs
[0])(data
->user_data
, file
);
751 purple_prefs_set_path(data
->save
? "/finch/filelocations/last_save_folder" :
752 "/finch/filelocations/last_open_folder", dir
);
755 purple_request_close(PURPLE_REQUEST_FILE
, data
->dialog
);
760 file_request_destroy(FinchFileRequest
*data
)
766 static FinchFileRequest
*
767 finch_file_request_window(const char *title
, const char *path
,
768 GCallback ok_cb
, GCallback cancel_cb
,
771 GntWidget
*window
= gnt_file_sel_new();
772 GntFileSel
*sel
= GNT_FILE_SEL(window
);
773 FinchFileRequest
*data
= g_new0(FinchFileRequest
, 1);
775 data
->user_data
= user_data
;
776 data
->cbs
= g_new0(GCallback
, 2);
777 data
->cbs
[0] = ok_cb
;
778 data
->cbs
[1] = cancel_cb
;
779 data
->dialog
= window
;
780 gnt_box_set_title(GNT_BOX(window
), title
);
782 gnt_file_sel_set_current_location(sel
, (path
&& *path
) ? path
: purple_home_dir());
784 g_signal_connect(G_OBJECT(sel
), "destroy",
785 G_CALLBACK(file_cancel_cb
), data
);
786 g_signal_connect(G_OBJECT(sel
), "cancelled",
787 G_CALLBACK(file_cancel_cb
), data
);
788 g_signal_connect(G_OBJECT(sel
), "file_selected",
789 G_CALLBACK(file_ok_cb
), data
);
791 g_object_set_data_full(G_OBJECT(window
), "filerequestdata", data
,
792 (GDestroyNotify
)file_request_destroy
);
798 finch_request_file(const char *title
, const char *filename
, gboolean savedialog
,
799 GCallback ok_cb
, GCallback cancel_cb
,
800 PurpleRequestCommonParameters
*cpar
, void *user_data
)
802 FinchFileRequest
*data
;
805 path
= purple_prefs_get_path(savedialog
? "/finch/filelocations/last_save_folder" : "/finch/filelocations/last_open_folder");
806 data
= finch_file_request_window(title
? title
: (savedialog
? _("Save File...") : _("Open File...")), path
,
807 ok_cb
, cancel_cb
, user_data
);
808 data
->save
= savedialog
;
810 gnt_file_sel_set_suggested_filename(GNT_FILE_SEL(data
->dialog
), filename
);
812 gnt_widget_show(data
->dialog
);
817 finch_request_folder(const char *title
, const char *dirname
, GCallback ok_cb
,
818 GCallback cancel_cb
, PurpleRequestCommonParameters
*cpar
,
821 FinchFileRequest
*data
;
823 data
= finch_file_request_window(title
? title
: _("Choose Location..."), dirname
,
824 ok_cb
, cancel_cb
, user_data
);
826 gnt_file_sel_set_dirs_only(GNT_FILE_SEL(data
->dialog
), TRUE
);
828 gnt_widget_show(data
->dialog
);
832 static PurpleRequestUiOps uiops
=
836 finch_request_choice
,
837 finch_request_action
,
840 finch_request_fields
,
842 finch_request_folder
,
850 PurpleRequestUiOps
*finch_request_get_ui_ops()
855 void finch_request_init()
859 void finch_request_uninit()
863 void finch_request_save_in_prefs(gpointer data
, PurpleRequestFields
*allfields
)
866 for (list
= purple_request_fields_get_groups(allfields
); list
; list
= list
->next
) {
867 PurpleRequestFieldGroup
*group
= list
->data
;
868 GList
*fields
= purple_request_field_group_get_fields(group
);
870 for (; fields
; fields
= fields
->next
) {
871 PurpleRequestField
*field
= fields
->data
;
872 PurpleRequestFieldType type
= purple_request_field_get_field_type(field
);
875 const char *id
= purple_request_field_get_id(field
);
878 case PURPLE_REQUEST_FIELD_LIST
:
879 val
= purple_request_field_list_get_selected(field
)->data
;
880 val
= purple_request_field_list_get_data(field
, val
);
882 case PURPLE_REQUEST_FIELD_BOOLEAN
:
883 val
= GINT_TO_POINTER(purple_request_field_bool_get_value(field
));
885 case PURPLE_REQUEST_FIELD_INTEGER
:
886 val
= GINT_TO_POINTER(purple_request_field_int_get_value(field
));
888 case PURPLE_REQUEST_FIELD_STRING
:
889 val
= (gpointer
)purple_request_field_string_get_value(field
);
895 pt
= purple_prefs_get_pref_type(id
);
897 case PURPLE_PREF_INT
:
899 long int tmp
= GPOINTER_TO_INT(val
);
900 if (type
== PURPLE_REQUEST_FIELD_LIST
) {
901 /* Lists always return string */
902 if (sscanf(val
, "%ld", &tmp
) != 1)
905 purple_prefs_set_int(id
, (gint
)tmp
);
908 case PURPLE_PREF_BOOLEAN
:
909 purple_prefs_set_bool(id
, GPOINTER_TO_INT(val
));
911 case PURPLE_PREF_STRING
:
912 purple_prefs_set_string(id
, val
);
921 GntWidget
*finch_request_field_get_widget(PurpleRequestField
*field
)
923 GntWidget
*ret
= NULL
;
924 switch (purple_request_field_get_field_type(field
)) {
925 case PURPLE_REQUEST_FIELD_BOOLEAN
:
926 ret
= create_boolean_field(field
);
928 case PURPLE_REQUEST_FIELD_STRING
:
929 ret
= create_string_field(field
, NULL
);
931 case PURPLE_REQUEST_FIELD_INTEGER
:
932 ret
= create_integer_field(field
);
934 case PURPLE_REQUEST_FIELD_CHOICE
:
935 ret
= create_choice_field(field
);
937 case PURPLE_REQUEST_FIELD_LIST
:
938 ret
= create_list_field(field
);
940 case PURPLE_REQUEST_FIELD_ACCOUNT
:
941 ret
= create_account_field(field
);
944 purple_debug_error("GntRequest", "Unimplemented request-field %d\n",
945 purple_request_field_get_field_type(field
));