3 * Finch is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 #include <gntbutton.h>
26 #include <gntcheckbox.h>
27 #include <gntcombobox.h>
29 #include <gntfilesel.h>
35 #include "gntrequest.h"
48 setup_request_window(const char *title
, const char *primary
,
49 const char *secondary
, PurpleRequestType type
)
53 window
= gnt_vbox_new(FALSE
);
54 gnt_box_set_toplevel(GNT_BOX(window
), TRUE
);
55 gnt_box_set_title(GNT_BOX(window
), title
);
56 gnt_box_set_alignment(GNT_BOX(window
), GNT_ALIGN_MID
);
59 gnt_box_add_widget(GNT_BOX(window
),
60 gnt_label_new_with_format(primary
, GNT_TEXT_FLAG_BOLD
));
62 gnt_box_add_widget(GNT_BOX(window
), gnt_label_new(secondary
));
64 g_signal_connect_swapped(G_OBJECT(window
), "destroy", G_CALLBACK(purple_request_close
),
65 GINT_TO_POINTER(type
));
71 * If the window is closed by the wm (ie, without triggering any of
72 * the buttons, then do some default callback.
75 setup_default_callback(GntWidget
*window
, gpointer default_cb
, gpointer data
)
77 if (default_cb
== NULL
)
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
);
84 action_performed(GntWidget
*button
, gpointer data
)
86 g_signal_handlers_disconnect_matched(data
, G_SIGNAL_MATCH_FUNC
,
88 g_object_get_data(data
, "default-callback"),
94 * @win: this is the window
95 * @userdata: the userdata to pass to the primary callbacks
97 * @data: data for the callback
98 * @...: (text, primary-callback) pairs, ended by a NULL
100 * The cancellation callback should be the last callback sent.
103 setup_button_box(GntWidget
*win
, gpointer userdata
, gpointer cb
, gpointer data
, ...)
106 GntWidget
*button
= NULL
;
111 box
= gnt_hbox_new(FALSE
);
113 va_start(list
, data
);
115 while ((text
= va_arg(list
, const char *)))
117 callback
= va_arg(list
, gpointer
);
118 button
= gnt_button_new(text
);
119 gnt_box_add_widget(GNT_BOX(box
), button
);
120 g_object_set_data(G_OBJECT(button
), "activate-callback", callback
);
121 g_object_set_data(G_OBJECT(button
), "activate-userdata", userdata
);
122 g_signal_connect(G_OBJECT(button
), "activate", G_CALLBACK(action_performed
), win
);
123 g_signal_connect(G_OBJECT(button
), "activate", G_CALLBACK(cb
), data
);
127 g_object_set_data(G_OBJECT(button
), "cancellation-function", GINT_TO_POINTER(TRUE
));
134 notify_input_cb(GntWidget
*button
, GntWidget
*entry
)
136 PurpleRequestInputCb callback
= g_object_get_data(G_OBJECT(button
), "activate-callback");
137 gpointer data
= g_object_get_data(G_OBJECT(button
), "activate-userdata");
138 const char *text
= gnt_entry_get_text(GNT_ENTRY(entry
));
142 callback(data
, text
);
144 window
= gnt_widget_get_toplevel(button
);
145 purple_request_close(PURPLE_REQUEST_INPUT
, window
);
149 finch_request_input(const char *title
, const char *primary
,
150 const char *secondary
, const char *default_value
,
151 gboolean multiline
, gboolean masked
, gchar
*hint
,
152 const char *ok_text
, GCallback ok_cb
,
153 const char *cancel_text
, GCallback cancel_cb
,
154 PurpleRequestCommonParameters
*cpar
,
157 GntWidget
*window
, *box
, *entry
;
159 window
= setup_request_window(title
, primary
, secondary
, PURPLE_REQUEST_INPUT
);
161 entry
= gnt_entry_new(default_value
);
163 gnt_entry_set_masked(GNT_ENTRY(entry
), TRUE
);
164 gnt_box_add_widget(GNT_BOX(window
), entry
);
166 box
= setup_button_box(window
, user_data
, notify_input_cb
, entry
,
167 ok_text
, ok_cb
, cancel_text
, cancel_cb
, NULL
);
168 gnt_box_add_widget(GNT_BOX(window
), box
);
170 setup_default_callback(window
, cancel_cb
, user_data
);
171 gnt_widget_show(window
);
177 finch_close_request(PurpleRequestType type
, gpointer ui_handle
)
179 GntWidget
*widget
= GNT_WIDGET(ui_handle
);
180 if (type
== PURPLE_REQUEST_FIELDS
) {
181 PurpleRequestFields
*fields
= g_object_get_data(G_OBJECT(widget
), "fields");
182 purple_request_fields_destroy(fields
);
185 widget
= gnt_widget_get_toplevel(widget
);
186 gnt_widget_destroy(widget
);
190 request_choice_cb(GntWidget
*button
, GntComboBox
*combo
)
192 PurpleRequestChoiceCb callback
= g_object_get_data(G_OBJECT(button
), "activate-callback");
193 gpointer data
= g_object_get_data(G_OBJECT(button
), "activate-userdata");
194 gpointer choice
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo
));
198 callback(data
, choice
);
200 window
= gnt_widget_get_toplevel(button
);
201 purple_request_close(PURPLE_REQUEST_INPUT
, window
);
205 finch_request_choice(const char *title
, const char *primary
,
206 const char *secondary
, gpointer default_value
,
207 const char *ok_text
, GCallback ok_cb
,
208 const char *cancel_text
, GCallback cancel_cb
,
209 PurpleRequestCommonParameters
*cpar
,
210 void *user_data
, va_list choices
)
212 GntWidget
*window
, *combo
, *box
;
216 window
= setup_request_window(title
, primary
, secondary
, PURPLE_REQUEST_CHOICE
);
218 combo
= gnt_combo_box_new();
219 gnt_box_add_widget(GNT_BOX(window
), combo
);
220 while ((text
= va_arg(choices
, const char *)))
222 val
= va_arg(choices
, int);
223 gnt_combo_box_add_data(GNT_COMBO_BOX(combo
), GINT_TO_POINTER(val
+ 1), text
);
225 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo
), default_value
);
227 box
= setup_button_box(window
, user_data
, request_choice_cb
, combo
,
228 ok_text
, ok_cb
, cancel_text
, cancel_cb
, NULL
);
229 gnt_box_add_widget(GNT_BOX(window
), box
);
231 setup_default_callback(window
, cancel_cb
, user_data
);
232 gnt_widget_show(window
);
238 request_action_cb(GntWidget
*button
, GntWidget
*window
)
240 PurpleRequestActionCb callback
= g_object_get_data(G_OBJECT(button
), "activate-callback");
241 gpointer data
= g_object_get_data(G_OBJECT(button
), "activate-userdata");
242 int id
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button
), "activate-id"));
247 purple_request_close(PURPLE_REQUEST_ACTION
, window
);
251 finch_request_action(const char *title
, const char *primary
,
252 const char *secondary
, int default_value
,
253 PurpleRequestCommonParameters
*cpar
,
254 void *user_data
, size_t actioncount
,
257 GntWidget
*window
, *box
, *button
, *focus
= NULL
;
260 window
= setup_request_window(title
, primary
, secondary
, PURPLE_REQUEST_ACTION
);
262 box
= gnt_hbox_new(FALSE
);
263 gnt_box_add_widget(GNT_BOX(window
), box
);
264 for (i
= 0; i
< actioncount
; i
++)
266 const char *text
= va_arg(actions
, const char *);
267 PurpleRequestActionCb callback
= va_arg(actions
, PurpleRequestActionCb
);
269 button
= gnt_button_new(text
);
270 gnt_box_add_widget(GNT_BOX(box
), button
);
272 g_object_set_data(G_OBJECT(button
), "activate-callback", callback
);
273 g_object_set_data(G_OBJECT(button
), "activate-userdata", user_data
);
274 g_object_set_data(G_OBJECT(button
), "activate-id", GINT_TO_POINTER(i
));
275 g_signal_connect(G_OBJECT(button
), "activate", G_CALLBACK(request_action_cb
), window
);
277 if (default_value
>= 0 && i
== (gsize
)default_value
)
281 gnt_widget_show(window
);
283 gnt_box_give_focus_to_child(GNT_BOX(window
), focus
);
289 request_fields_cb(GntWidget
*button
, PurpleRequestFields
*fields
)
291 PurpleRequestFieldsCb callback
= g_object_get_data(G_OBJECT(button
), "activate-callback");
292 gpointer data
= g_object_get_data(G_OBJECT(button
), "activate-userdata");
296 /* Update the data of the fields. Pidgin does this differently. Instead of
297 * updating the fields at the end like here, it updates the appropriate field
298 * instantly whenever a change is made. That allows it to make sure the
299 * 'required' fields are entered before the user can hit OK. It's not the case
300 * here, althought it can be done. */
301 for (list
= purple_request_fields_get_groups(fields
); list
; list
= list
->next
)
303 PurpleRequestFieldGroup
*group
= list
->data
;
304 GList
*fields
= purple_request_field_group_get_fields(group
);
306 for (; fields
; fields
= fields
->next
)
308 PurpleRequestField
*field
= fields
->data
;
309 PurpleRequestFieldType type
= purple_request_field_get_field_type(field
);
310 if (!purple_request_field_is_visible(field
))
312 if (type
== PURPLE_REQUEST_FIELD_BOOLEAN
)
314 GntWidget
*check
= purple_request_field_get_ui_data(field
);
315 gboolean value
= gnt_check_box_get_checked(GNT_CHECK_BOX(check
));
316 purple_request_field_bool_set_value(field
, value
);
318 else if (type
== PURPLE_REQUEST_FIELD_STRING
)
320 GntWidget
*entry
= purple_request_field_get_ui_data(field
);
321 const char *text
= gnt_entry_get_text(GNT_ENTRY(entry
));
322 purple_request_field_string_set_value(field
, (text
&& *text
) ? text
: NULL
);
324 else if (type
== PURPLE_REQUEST_FIELD_INTEGER
)
326 GntWidget
*entry
= purple_request_field_get_ui_data(field
);
327 const char *text
= gnt_entry_get_text(GNT_ENTRY(entry
));
328 int value
= (text
&& *text
) ? atoi(text
) : 0;
329 purple_request_field_int_set_value(field
, value
);
331 else if (type
== PURPLE_REQUEST_FIELD_CHOICE
)
333 GntWidget
*combo
= purple_request_field_get_ui_data(field
);
334 gpointer value
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo
));
335 purple_request_field_choice_set_value(field
, value
);
337 else if (type
== PURPLE_REQUEST_FIELD_LIST
)
339 GList
*list
= NULL
, *iter
;
340 if (purple_request_field_list_get_multi_select(field
))
342 GntWidget
*tree
= purple_request_field_get_ui_data(field
);
344 iter
= purple_request_field_list_get_items(field
);
345 for (; iter
; iter
= iter
->next
)
347 const char *text
= iter
->data
;
348 gpointer key
= purple_request_field_list_get_data(field
, text
);
349 if (gnt_tree_get_choice(GNT_TREE(tree
), key
))
350 list
= g_list_prepend(list
, (gpointer
)text
);
355 GntWidget
*combo
= purple_request_field_get_ui_data(field
);
356 gpointer data
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo
));
358 iter
= purple_request_field_list_get_items(field
);
359 for (; iter
; iter
= iter
->next
) {
360 const char *text
= iter
->data
;
361 gpointer key
= purple_request_field_list_get_data(field
, text
);
363 list
= g_list_prepend(list
, (gpointer
)text
);
369 purple_request_field_list_set_selected(field
, list
);
372 else if (type
== PURPLE_REQUEST_FIELD_ACCOUNT
)
374 GntWidget
*combo
= purple_request_field_get_ui_data(field
);
375 PurpleAccount
*acc
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo
));
376 purple_request_field_account_set_value(field
, acc
);
381 purple_notify_close_with_handle(button
);
383 if (!g_object_get_data(G_OBJECT(button
), "cancellation-function") &&
384 (!purple_request_fields_all_required_filled(fields
) ||
385 !purple_request_fields_all_valid(fields
))) {
386 purple_notify_error(button
, _("Error"),
387 _("You must properly fill all the required fields."),
388 _("The required fields are underlined."), NULL
);
393 callback(data
, fields
);
395 window
= gnt_widget_get_toplevel(button
);
396 purple_request_close(PURPLE_REQUEST_FIELDS
, window
);
400 update_selected_account(GntEntry
*username
, const char *start
, const char *end
,
401 GntComboBox
*accountlist
)
404 gnt_tree_get_rows(GNT_TREE(gnt_combo_box_get_dropdown(accountlist
)));
405 const char *name
= gnt_entry_get_text(username
);
407 if (purple_blist_find_buddy(accounts
->data
, name
)) {
408 gnt_combo_box_set_selected(accountlist
, accounts
->data
);
409 gnt_widget_draw(GNT_WIDGET(accountlist
));
412 accounts
= accounts
->next
;
417 create_boolean_field(PurpleRequestField
*field
)
419 const char *label
= purple_request_field_get_label(field
);
420 GntWidget
*check
= gnt_check_box_new(label
);
421 gnt_check_box_set_checked(GNT_CHECK_BOX(check
),
422 purple_request_field_bool_get_default_value(field
));
427 create_string_field(PurpleRequestField
*field
, GntWidget
**username
)
429 const char *hint
= purple_request_field_get_field_type_hint(field
);
430 GntWidget
*entry
= gnt_entry_new(
431 purple_request_field_string_get_default_value(field
));
432 gnt_entry_set_masked(GNT_ENTRY(entry
),
433 purple_request_field_string_is_masked(field
));
434 if (hint
&& purple_str_has_prefix(hint
, "screenname")) {
435 PurpleBlistNode
*node
= purple_blist_get_default_root();
436 gboolean offline
= purple_str_has_suffix(hint
, "all");
437 for (; node
; node
= purple_blist_node_next(node
, offline
)) {
438 if (!PURPLE_IS_BUDDY(node
))
440 gnt_entry_add_suggest(GNT_ENTRY(entry
), purple_buddy_get_name((PurpleBuddy
*)node
));
442 gnt_entry_set_always_suggest(GNT_ENTRY(entry
), TRUE
);
445 } else if (purple_strequal(hint
, "group")) {
446 PurpleBlistNode
*node
;
447 for (node
= purple_blist_get_default_root(); node
;
448 node
= purple_blist_node_get_sibling_next(node
)) {
449 if (PURPLE_IS_GROUP(node
))
450 gnt_entry_add_suggest(GNT_ENTRY(entry
), purple_group_get_name((PurpleGroup
*)node
));
457 create_integer_field(PurpleRequestField
*field
)
460 int val
= purple_request_field_int_get_default_value(field
);
463 snprintf(str
, sizeof(str
), "%d", val
);
464 entry
= gnt_entry_new(str
);
465 gnt_entry_set_flag(GNT_ENTRY(entry
), GNT_ENTRY_FLAG_INT
);
470 create_choice_field(PurpleRequestField
*field
)
473 GntWidget
*combo
= gnt_combo_box_new();
475 it
= purple_request_field_choice_get_elements(field
);
482 it
= g_list_next(it
);
483 g_assert(it
!= NULL
);
485 it
= g_list_next(it
);
487 gnt_combo_box_add_data(GNT_COMBO_BOX(combo
), value
, text
);
489 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo
),
490 purple_request_field_choice_get_default_value(field
));
495 create_list_field(PurpleRequestField
*field
)
497 GntWidget
*ret
= NULL
;
499 gboolean multi
= purple_request_field_list_get_multi_select(field
);
502 GntWidget
*tree
= gnt_tree_new();
504 list
= purple_request_field_list_get_items(field
);
505 for (; list
; list
= list
->next
)
507 const char *text
= list
->data
;
508 gpointer key
= purple_request_field_list_get_data(field
, text
);
509 gnt_tree_add_choice(GNT_TREE(tree
), key
,
510 gnt_tree_create_row(GNT_TREE(tree
), text
), NULL
, NULL
);
511 if (purple_request_field_list_is_selected(field
, text
))
512 gnt_tree_set_choice(GNT_TREE(tree
), key
, TRUE
);
518 GntWidget
*combo
= gnt_combo_box_new();
520 list
= purple_request_field_list_get_items(field
);
521 for (; list
; list
= list
->next
)
523 const char *text
= list
->data
;
524 gpointer key
= purple_request_field_list_get_data(field
, text
);
525 gnt_combo_box_add_data(GNT_COMBO_BOX(combo
), key
, text
);
526 if (purple_request_field_list_is_selected(field
, text
))
527 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo
), key
);
535 create_account_field(PurpleRequestField
*field
)
540 GntWidget
*combo
= gnt_combo_box_new();
542 all
= purple_request_field_account_get_show_all(field
);
543 def
= purple_request_field_account_get_value(field
);
545 def
= purple_request_field_account_get_default_value(field
);
548 list
= purple_accounts_get_all();
550 list
= purple_connections_get_all();
552 for (; list
; list
= list
->next
)
554 PurpleAccount
*account
;
558 account
= list
->data
;
560 account
= purple_connection_get_account(list
->data
);
562 text
= g_strdup_printf("%s (%s)",
563 purple_account_get_username(account
),
564 purple_account_get_protocol_name(account
));
565 gnt_combo_box_add_data(GNT_COMBO_BOX(combo
), account
, text
);
568 gnt_combo_box_set_selected(GNT_COMBO_BOX(combo
), account
);
570 gnt_widget_set_size(combo
, 20, 3); /* ew */
575 multifield_extra_cb(GntWidget
*button
, PurpleRequestFields
*allfields
)
577 PurpleRequestFieldsCb cb
;
581 handle
= g_object_get_data(G_OBJECT(button
), "ui-handle");
582 cb
= g_object_get_data(G_OBJECT(button
), "extra-cb");
583 cb_data
= g_object_get_data(G_OBJECT(button
), "extra-cb-data");
586 cb(cb_data
, allfields
);
588 action_performed(button
, handle
);
589 purple_request_close(PURPLE_REQUEST_FIELDS
, handle
);
593 finch_request_fields(const char *title
, const char *primary
,
594 const char *secondary
, PurpleRequestFields
*allfields
,
595 const char *ok
, GCallback ok_cb
,
596 const char *cancel
, GCallback cancel_cb
,
597 PurpleRequestCommonParameters
*cpar
,
600 GntWidget
*window
, *box
;
602 GntWidget
*username
= NULL
, *accountlist
= NULL
;
603 PurpleRequestHelpCb help_cb
;
605 GSList
*extra_actions
, *it
;
607 window
= setup_request_window(title
, primary
, secondary
, PURPLE_REQUEST_FIELDS
);
609 /* This is how it's going to work: the request-groups are going to be
610 * stacked vertically one after the other. A GntLine will be separating
612 box
= gnt_vbox_new(FALSE
);
613 gnt_box_set_pad(GNT_BOX(box
), 0);
614 gnt_box_set_fill(GNT_BOX(box
), TRUE
);
615 for (grlist
= purple_request_fields_get_groups(allfields
); grlist
; grlist
= grlist
->next
)
617 PurpleRequestFieldGroup
*group
= grlist
->data
;
618 GList
*fields
= purple_request_field_group_get_fields(group
);
620 const char *title
= purple_request_field_group_get_title(group
);
623 gnt_box_add_widget(GNT_BOX(box
),
624 gnt_label_new_with_format(title
, GNT_TEXT_FLAG_BOLD
));
626 for (; fields
; fields
= fields
->next
)
628 PurpleRequestField
*field
= fields
->data
;
629 PurpleRequestFieldType type
= purple_request_field_get_field_type(field
);
630 const char *label
= purple_request_field_get_label(field
);
632 if (!purple_request_field_is_visible(field
))
635 hbox
= gnt_hbox_new(TRUE
); /* hrm */
636 gnt_box_add_widget(GNT_BOX(box
), hbox
);
638 if (type
!= PURPLE_REQUEST_FIELD_BOOLEAN
&& label
)
641 if (purple_request_field_is_required(field
))
642 l
= gnt_label_new_with_format(label
, GNT_TEXT_FLAG_UNDERLINE
);
644 l
= gnt_label_new(label
);
645 gnt_widget_set_size(l
, 0, 1);
646 gnt_box_add_widget(GNT_BOX(hbox
), l
);
649 if (type
== PURPLE_REQUEST_FIELD_BOOLEAN
)
651 purple_request_field_set_ui_data(field
, create_boolean_field(field
));
653 else if (type
== PURPLE_REQUEST_FIELD_STRING
)
655 purple_request_field_set_ui_data(field
, create_string_field(field
, &username
));
657 else if (type
== PURPLE_REQUEST_FIELD_INTEGER
)
659 purple_request_field_set_ui_data(field
, create_integer_field(field
));
661 else if (type
== PURPLE_REQUEST_FIELD_CHOICE
)
663 purple_request_field_set_ui_data(field
, create_choice_field(field
));
665 else if (type
== PURPLE_REQUEST_FIELD_LIST
)
667 purple_request_field_set_ui_data(field
, create_list_field(field
));
669 else if (type
== PURPLE_REQUEST_FIELD_ACCOUNT
)
671 accountlist
= create_account_field(field
);
672 purple_request_field_set_ui_data(field
, accountlist
);
676 purple_request_field_set_ui_data(field
, gnt_label_new_with_format(_("Not implemented yet."),
677 GNT_TEXT_FLAG_BOLD
));
679 gnt_box_set_alignment(GNT_BOX(hbox
), GNT_ALIGN_MID
);
680 gnt_box_add_widget(GNT_BOX(hbox
), GNT_WIDGET(purple_request_field_get_ui_data(field
)));
683 gnt_box_add_widget(GNT_BOX(box
), gnt_hline_new());
685 gnt_box_add_widget(GNT_BOX(window
), box
);
687 box
= setup_button_box(window
, userdata
, request_fields_cb
, allfields
,
688 ok
, ok_cb
, cancel
, cancel_cb
, NULL
);
690 extra_actions
= purple_request_cpar_get_extra_actions(cpar
);
691 for (it
= extra_actions
; it
; it
= it
->next
->next
) {
692 const gchar
*label
= it
->data
;
693 PurpleRequestFieldsCb
*cb
= it
->next
->data
;
695 GntWidget
*button
= gnt_button_new(label
);
696 gnt_box_add_widget_in_front(GNT_BOX(box
), button
);
697 g_object_set_data(G_OBJECT(button
), "ui-handle", window
);
698 g_object_set_data(G_OBJECT(button
), "extra-cb", cb
);
699 g_object_set_data(G_OBJECT(button
), "extra-cb-data", userdata
);
700 g_signal_connect(G_OBJECT(button
), "activate",
701 G_CALLBACK(multifield_extra_cb
), allfields
);
704 help_cb
= purple_request_cpar_get_help_cb(cpar
, &help_data
);
706 GntWidget
*button
= gnt_button_new(_("Help"));
707 gnt_box_add_widget_in_front(GNT_BOX(box
), button
);
708 g_signal_connect_swapped(G_OBJECT(button
), "activate",
709 G_CALLBACK(help_cb
), help_data
);
712 gnt_box_add_widget(GNT_BOX(window
), box
);
714 setup_default_callback(window
, cancel_cb
, userdata
);
715 gnt_widget_show(window
);
717 if (username
&& accountlist
) {
718 g_signal_connect(username
, "completion", G_CALLBACK(update_selected_account
), accountlist
);
721 g_object_set_data(G_OBJECT(window
), "fields", allfields
);
727 file_cancel_cb(GntWidget
*wid
, gpointer fq
)
729 FinchFileRequest
*data
= fq
;
730 if (data
->dialog
== NULL
) {
731 /* We've already handled this request, and are in the destroy handler. */
735 if (data
->cbs
[1] != NULL
)
736 ((PurpleRequestFileCb
)data
->cbs
[1])(data
->user_data
, NULL
);
738 purple_request_close(PURPLE_REQUEST_FILE
, data
->dialog
);
743 file_ok_cb(GntWidget
*widget
, const char *path
, const char *file
, gpointer fq
)
745 FinchFileRequest
*data
= fq
;
746 char *dir
= g_path_get_dirname(path
);
747 if (data
->cbs
[0] != NULL
)
748 ((PurpleRequestFileCb
)data
->cbs
[0])(data
->user_data
, file
);
749 purple_prefs_set_path(data
->save
? "/finch/filelocations/last_save_folder" :
750 "/finch/filelocations/last_open_folder", dir
);
753 purple_request_close(PURPLE_REQUEST_FILE
, data
->dialog
);
758 file_request_destroy(FinchFileRequest
*data
)
764 static FinchFileRequest
*
765 finch_file_request_window(const char *title
, const char *path
,
766 GCallback ok_cb
, GCallback cancel_cb
,
769 GntWidget
*window
= gnt_file_sel_new();
770 GntFileSel
*sel
= GNT_FILE_SEL(window
);
771 FinchFileRequest
*data
= g_new0(FinchFileRequest
, 1);
773 data
->user_data
= user_data
;
774 data
->cbs
= g_new0(GCallback
, 2);
775 data
->cbs
[0] = ok_cb
;
776 data
->cbs
[1] = cancel_cb
;
777 data
->dialog
= window
;
778 gnt_box_set_title(GNT_BOX(window
), title
);
780 gnt_file_sel_set_current_location(sel
, (path
&& *path
) ? path
: purple_home_dir());
782 g_signal_connect(G_OBJECT(sel
), "destroy",
783 G_CALLBACK(file_cancel_cb
), data
);
784 g_signal_connect(G_OBJECT(sel
), "cancelled",
785 G_CALLBACK(file_cancel_cb
), data
);
786 g_signal_connect(G_OBJECT(sel
), "file_selected",
787 G_CALLBACK(file_ok_cb
), data
);
789 g_object_set_data_full(G_OBJECT(window
), "filerequestdata", data
,
790 (GDestroyNotify
)file_request_destroy
);
796 finch_request_file(const char *title
, const char *filename
, gboolean savedialog
,
797 GCallback ok_cb
, GCallback cancel_cb
,
798 PurpleRequestCommonParameters
*cpar
, void *user_data
)
800 FinchFileRequest
*data
;
803 path
= purple_prefs_get_path(savedialog
? "/finch/filelocations/last_save_folder" : "/finch/filelocations/last_open_folder");
804 data
= finch_file_request_window(title
? title
: (savedialog
? _("Save File...") : _("Open File...")), path
,
805 ok_cb
, cancel_cb
, user_data
);
806 data
->save
= savedialog
;
808 gnt_file_sel_set_suggested_filename(GNT_FILE_SEL(data
->dialog
), filename
);
810 gnt_widget_show(data
->dialog
);
815 finch_request_folder(const char *title
, const char *dirname
, GCallback ok_cb
,
816 GCallback cancel_cb
, PurpleRequestCommonParameters
*cpar
,
819 FinchFileRequest
*data
;
821 data
= finch_file_request_window(title
? title
: _("Choose Location..."), dirname
,
822 ok_cb
, cancel_cb
, user_data
);
824 gnt_file_sel_set_dirs_only(GNT_FILE_SEL(data
->dialog
), TRUE
);
826 gnt_widget_show(data
->dialog
);
830 static PurpleRequestUiOps uiops
=
834 finch_request_choice
,
835 finch_request_action
,
838 finch_request_fields
,
840 finch_request_folder
,
848 PurpleRequestUiOps
*finch_request_get_ui_ops()
853 void finch_request_init()
857 void finch_request_uninit()
861 void finch_request_save_in_prefs(gpointer null
, PurpleRequestFields
*allfields
)
864 for (list
= purple_request_fields_get_groups(allfields
); list
; list
= list
->next
) {
865 PurpleRequestFieldGroup
*group
= list
->data
;
866 GList
*fields
= purple_request_field_group_get_fields(group
);
868 for (; fields
; fields
= fields
->next
) {
869 PurpleRequestField
*field
= fields
->data
;
870 PurpleRequestFieldType type
= purple_request_field_get_field_type(field
);
873 const char *id
= purple_request_field_get_id(field
);
876 case PURPLE_REQUEST_FIELD_LIST
:
877 val
= purple_request_field_list_get_selected(field
)->data
;
878 val
= purple_request_field_list_get_data(field
, val
);
880 case PURPLE_REQUEST_FIELD_BOOLEAN
:
881 val
= GINT_TO_POINTER(purple_request_field_bool_get_value(field
));
883 case PURPLE_REQUEST_FIELD_INTEGER
:
884 val
= GINT_TO_POINTER(purple_request_field_int_get_value(field
));
886 case PURPLE_REQUEST_FIELD_STRING
:
887 val
= (gpointer
)purple_request_field_string_get_value(field
);
893 pt
= purple_prefs_get_pref_type(id
);
895 case PURPLE_PREF_INT
:
897 long int tmp
= GPOINTER_TO_INT(val
);
898 if (type
== PURPLE_REQUEST_FIELD_LIST
) {
899 /* Lists always return string */
900 if (sscanf(val
, "%ld", &tmp
) != 1)
903 purple_prefs_set_int(id
, (gint
)tmp
);
906 case PURPLE_PREF_BOOLEAN
:
907 purple_prefs_set_bool(id
, GPOINTER_TO_INT(val
));
909 case PURPLE_PREF_STRING
:
910 purple_prefs_set_string(id
, val
);
919 GntWidget
*finch_request_field_get_widget(PurpleRequestField
*field
)
921 GntWidget
*ret
= NULL
;
922 switch (purple_request_field_get_field_type(field
)) {
923 case PURPLE_REQUEST_FIELD_BOOLEAN
:
924 ret
= create_boolean_field(field
);
926 case PURPLE_REQUEST_FIELD_STRING
:
927 ret
= create_string_field(field
, NULL
);
929 case PURPLE_REQUEST_FIELD_INTEGER
:
930 ret
= create_integer_field(field
);
932 case PURPLE_REQUEST_FIELD_CHOICE
:
933 ret
= create_choice_field(field
);
935 case PURPLE_REQUEST_FIELD_LIST
:
936 ret
= create_list_field(field
);
938 case PURPLE_REQUEST_FIELD_ACCOUNT
:
939 ret
= create_account_field(field
);
942 purple_debug_error("GntRequest", "Unimplemented request-field %d\n",
943 purple_request_field_get_field_type(field
));