| 32 #include "gtkimhtml.h" |
32 #include "gtkimhtml.h" |
| 33 #include "gtkimhtmltoolbar.h" |
33 #include "gtkimhtmltoolbar.h" |
| 34 #include "gtkrequest.h" |
34 #include "gtkrequest.h" |
| 35 #include "gtkutils.h" |
35 #include "gtkutils.h" |
| 36 #include "pidginstock.h" |
36 #include "pidginstock.h" |
| |
37 #include "gtkblist.h" |
| 37 |
38 |
| 38 #include <gdk/gdkkeysyms.h> |
39 #include <gdk/gdkkeysyms.h> |
| 39 |
40 |
| 40 static GtkWidget * create_account_field(PurpleRequestField *field); |
41 static GtkWidget * create_account_field(PurpleRequestField *field); |
| 41 |
42 |
| 76 } file; |
77 } file; |
| 77 |
78 |
| 78 } u; |
79 } u; |
| 79 |
80 |
| 80 } PidginRequestData; |
81 } PidginRequestData; |
| |
82 |
| |
83 static GtkWindow * |
| |
84 find_toplevel(GList *ll_toplevels, const char *role) |
| |
85 { |
| |
86 const char *window_role = NULL; |
| |
87 GList *ll_itr = NULL; |
| |
88 |
| |
89 for (ll_itr = ll_toplevels ; ll_itr ; ll_itr = ll_itr->next) { |
| |
90 if ((window_role = gtk_window_get_role(GTK_WINDOW(ll_itr->data))) != NULL) { |
| |
91 if (!strcmp(window_role, role)) |
| |
92 return GTK_WINDOW(ll_itr->data); |
| |
93 } |
| |
94 } |
| |
95 |
| |
96 return NULL; |
| |
97 } |
| |
98 |
| |
99 static GtkWindow * |
| |
100 get_request_parent(const char *ui_hint, PidginConversation *convo) |
| |
101 { |
| |
102 GtkWindow *toplevel = NULL; |
| |
103 PidginBuddyList *blist = NULL; |
| |
104 |
| |
105 if (convo) |
| |
106 return GTK_WINDOW(convo->win->window); |
| |
107 |
| |
108 if (strcmp(ui_hint, "blist")) { |
| |
109 GList *ll_toplevels = NULL; |
| |
110 |
| |
111 ll_toplevels = gtk_window_list_toplevels(); |
| |
112 |
| |
113 if (!(toplevel = find_toplevel(ll_toplevels, ui_hint))) { |
| |
114 if (!strcmp(ui_hint, "register-account")) |
| |
115 toplevel = find_toplevel(ll_toplevels, "account"); |
| |
116 else |
| |
117 if (!strcmp(ui_hint, "xfer")) |
| |
118 toplevel = find_toplevel(ll_toplevels, "file transfer"); |
| |
119 } |
| |
120 |
| |
121 g_list_free(ll_toplevels); |
| |
122 } |
| |
123 |
| |
124 /* Takes care of "pidgin-statusbox" as well */ |
| |
125 if (!toplevel) |
| |
126 if ((blist = pidgin_blist_get_default_gtk_blist()) != NULL) |
| |
127 return GTK_WINDOW(blist->window); |
| |
128 |
| |
129 return toplevel; |
| |
130 } |
| 81 |
131 |
| 82 static void |
132 static void |
| 83 generic_response_start(PidginRequestData *data) |
133 generic_response_start(PidginRequestData *data) |
| 84 { |
134 { |
| 85 g_return_if_fail(data != NULL); |
135 g_return_if_fail(data != NULL); |
| 285 const char *secondary, const char *default_value, |
335 const char *secondary, const char *default_value, |
| 286 gboolean multiline, gboolean masked, gchar *hint, |
336 gboolean multiline, gboolean masked, gchar *hint, |
| 287 const char *ok_text, GCallback ok_cb, |
337 const char *ok_text, GCallback ok_cb, |
| 288 const char *cancel_text, GCallback cancel_cb, |
338 const char *cancel_text, GCallback cancel_cb, |
| 289 PurpleAccount *account, const char *who, PurpleConversation *conv, |
339 PurpleAccount *account, const char *who, PurpleConversation *conv, |
| 290 void *user_data) |
340 const char *ui_hint, void *user_data) |
| 291 { |
341 { |
| 292 PidginRequestData *data; |
342 PidginRequestData *data; |
| 293 GtkWidget *dialog; |
343 GtkWidget *dialog; |
| 294 GtkWidget *vbox; |
344 GtkWidget *vbox; |
| 295 GtkWidget *hbox; |
345 GtkWidget *hbox; |
| 310 data->cbs[0] = ok_cb; |
360 data->cbs[0] = ok_cb; |
| 311 data->cbs[1] = cancel_cb; |
361 data->cbs[1] = cancel_cb; |
| 312 |
362 |
| 313 /* Create the dialog. */ |
363 /* Create the dialog. */ |
| 314 dialog = gtk_dialog_new_with_buttons(title ? title : PIDGIN_ALERT_TITLE, |
364 dialog = gtk_dialog_new_with_buttons(title ? title : PIDGIN_ALERT_TITLE, |
| 315 NULL, 0, |
365 get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL), 0, |
| 316 text_to_stock(cancel_text), 1, |
366 text_to_stock(cancel_text), 1, |
| 317 text_to_stock(ok_text), 0, |
367 text_to_stock(ok_text), 0, |
| 318 NULL); |
368 NULL); |
| 319 data->dialog = dialog; |
369 data->dialog = dialog; |
| 320 |
370 |
| 448 pidgin_request_choice(const char *title, const char *primary, |
498 pidgin_request_choice(const char *title, const char *primary, |
| 449 const char *secondary, int default_value, |
499 const char *secondary, int default_value, |
| 450 const char *ok_text, GCallback ok_cb, |
500 const char *ok_text, GCallback ok_cb, |
| 451 const char *cancel_text, GCallback cancel_cb, |
501 const char *cancel_text, GCallback cancel_cb, |
| 452 PurpleAccount *account, const char *who, PurpleConversation *conv, |
502 PurpleAccount *account, const char *who, PurpleConversation *conv, |
| 453 void *user_data, va_list args) |
503 const char *ui_hint, void *user_data, va_list args) |
| 454 { |
504 { |
| 455 PidginRequestData *data; |
505 PidginRequestData *data; |
| 456 GtkWidget *dialog; |
506 GtkWidget *dialog; |
| 457 GtkWidget *vbox, *vbox2; |
507 GtkWidget *vbox, *vbox2; |
| 458 GtkWidget *hbox; |
508 GtkWidget *hbox; |
| 472 data->cbs[0] = cancel_cb; |
522 data->cbs[0] = cancel_cb; |
| 473 data->cbs[1] = ok_cb; |
523 data->cbs[1] = ok_cb; |
| 474 |
524 |
| 475 /* Create the dialog. */ |
525 /* Create the dialog. */ |
| 476 data->dialog = dialog = gtk_dialog_new(); |
526 data->dialog = dialog = gtk_dialog_new(); |
| |
527 gtk_window_set_transient_for(GTK_WINDOW(dialog), |
| |
528 get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL)); |
| 477 |
529 |
| 478 if (title != NULL) |
530 if (title != NULL) |
| 479 gtk_window_set_title(GTK_WINDOW(dialog), title); |
531 gtk_window_set_title(GTK_WINDOW(dialog), title); |
| 480 #ifdef _WIN32 |
532 #ifdef _WIN32 |
| 481 gtk_window_set_title(GTK_WINDOW(dialog), PIDGIN_ALERT_TITLE); |
533 gtk_window_set_title(GTK_WINDOW(dialog), PIDGIN_ALERT_TITLE); |
| 552 |
604 |
| 553 static void * |
605 static void * |
| 554 pidgin_request_action(const char *title, const char *primary, |
606 pidgin_request_action(const char *title, const char *primary, |
| 555 const char *secondary, int default_action, |
607 const char *secondary, int default_action, |
| 556 PurpleAccount *account, const char *who, PurpleConversation *conv, |
608 PurpleAccount *account, const char *who, PurpleConversation *conv, |
| 557 void *user_data, size_t action_count, va_list actions) |
609 const char *ui_hint, void *user_data, size_t action_count, va_list actions) |
| 558 { |
610 { |
| 559 PidginRequestData *data; |
611 PidginRequestData *data; |
| 560 GtkWidget *dialog; |
612 GtkWidget *dialog; |
| 561 GtkWidget *vbox; |
613 GtkWidget *vbox; |
| 562 GtkWidget *hbox; |
614 GtkWidget *hbox; |
| 582 buttons[(action_count * 2) - i - 1] = va_arg(actions, GCallback); |
634 buttons[(action_count * 2) - i - 1] = va_arg(actions, GCallback); |
| 583 } |
635 } |
| 584 |
636 |
| 585 /* Create the dialog. */ |
637 /* Create the dialog. */ |
| 586 data->dialog = dialog = gtk_dialog_new(); |
638 data->dialog = dialog = gtk_dialog_new(); |
| |
639 gtk_window_set_transient_for(GTK_WINDOW(dialog), |
| |
640 get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL)); |
| 587 |
641 |
| 588 #if GTK_CHECK_VERSION(2,10,0) |
642 #if GTK_CHECK_VERSION(2,10,0) |
| 589 gtk_window_set_deletable(GTK_WINDOW(data->dialog), FALSE); |
643 gtk_window_set_deletable(GTK_WINDOW(data->dialog), FALSE); |
| 590 #endif |
644 #endif |
| 591 |
645 |
| 1049 pidgin_request_fields(const char *title, const char *primary, |
1103 pidgin_request_fields(const char *title, const char *primary, |
| 1050 const char *secondary, PurpleRequestFields *fields, |
1104 const char *secondary, PurpleRequestFields *fields, |
| 1051 const char *ok_text, GCallback ok_cb, |
1105 const char *ok_text, GCallback ok_cb, |
| 1052 const char *cancel_text, GCallback cancel_cb, |
1106 const char *cancel_text, GCallback cancel_cb, |
| 1053 PurpleAccount *account, const char *who, PurpleConversation *conv, |
1107 PurpleAccount *account, const char *who, PurpleConversation *conv, |
| 1054 void *user_data) |
1108 const char *ui_hint, void *user_data) |
| 1055 { |
1109 { |
| 1056 PidginRequestData *data; |
1110 PidginRequestData *data; |
| 1057 GtkWidget *win; |
1111 GtkWidget *win; |
| 1058 GtkWidget *vbox; |
1112 GtkWidget *vbox; |
| 1059 GtkWidget *vbox2; |
1113 GtkWidget *vbox2; |
| 1090 #ifdef _WIN32 |
1144 #ifdef _WIN32 |
| 1091 data->dialog = win = pidgin_create_window(PIDGIN_ALERT_TITLE, PIDGIN_HIG_BORDER, "multifield", TRUE) ; |
1145 data->dialog = win = pidgin_create_window(PIDGIN_ALERT_TITLE, PIDGIN_HIG_BORDER, "multifield", TRUE) ; |
| 1092 #else /* !_WIN32 */ |
1146 #else /* !_WIN32 */ |
| 1093 data->dialog = win = pidgin_create_window(title, PIDGIN_HIG_BORDER, "multifield", TRUE) ; |
1147 data->dialog = win = pidgin_create_window(title, PIDGIN_HIG_BORDER, "multifield", TRUE) ; |
| 1094 #endif /* _WIN32 */ |
1148 #endif /* _WIN32 */ |
| |
1149 gtk_window_set_transient_for(GTK_WINDOW(win), |
| |
1150 get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL)); |
| 1095 |
1151 |
| 1096 g_signal_connect(G_OBJECT(win), "delete_event", |
1152 g_signal_connect(G_OBJECT(win), "delete_event", |
| 1097 G_CALLBACK(destroy_multifield_cb), data); |
1153 G_CALLBACK(destroy_multifield_cb), data); |
| 1098 |
1154 |
| 1099 /* Setup the main horizontal box */ |
1155 /* Setup the main horizontal box */ |
| 1505 if ((data->u.file.savedialog == TRUE) && |
1561 if ((data->u.file.savedialog == TRUE) && |
| 1506 (g_file_test(data->u.file.name, G_FILE_TEST_EXISTS))) { |
1562 (g_file_test(data->u.file.name, G_FILE_TEST_EXISTS))) { |
| 1507 purple_request_action(data, NULL, _("That file already exists"), |
1563 purple_request_action(data, NULL, _("That file already exists"), |
| 1508 _("Would you like to overwrite it?"), 0, |
1564 _("Would you like to overwrite it?"), 0, |
| 1509 NULL, NULL, NULL, |
1565 NULL, NULL, NULL, |
| 1510 data, 2, |
1566 "pidgin-request-file", data, 2, |
| 1511 _("Overwrite"), G_CALLBACK(file_yes_no_cb), |
1567 _("Overwrite"), G_CALLBACK(file_yes_no_cb), |
| 1512 _("Choose New Name"), G_CALLBACK(file_yes_no_cb)); |
1568 _("Choose New Name"), G_CALLBACK(file_yes_no_cb)); |
| 1513 } else |
1569 } else |
| 1514 file_yes_no_cb(data, 1); |
1570 file_yes_no_cb(data, 1); |
| 1515 } |
1571 } |
| 1530 static void * |
1586 static void * |
| 1531 pidgin_request_file(const char *title, const char *filename, |
1587 pidgin_request_file(const char *title, const char *filename, |
| 1532 gboolean savedialog, |
1588 gboolean savedialog, |
| 1533 GCallback ok_cb, GCallback cancel_cb, |
1589 GCallback ok_cb, GCallback cancel_cb, |
| 1534 PurpleAccount *account, const char *who, PurpleConversation *conv, |
1590 PurpleAccount *account, const char *who, PurpleConversation *conv, |
| 1535 void *user_data) |
1591 const char *ui_hint, void *user_data) |
| 1536 { |
1592 { |
| 1537 PidginRequestData *data; |
1593 PidginRequestData *data; |
| 1538 GtkWidget *filesel; |
1594 GtkWidget *filesel; |
| 1539 const gchar *current_folder; |
1595 const gchar *current_folder; |
| 1540 #if GTK_CHECK_VERSION(2,4,0) |
1596 #if GTK_CHECK_VERSION(2,4,0) |
| 1618 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button), |
1674 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button), |
| 1619 "clicked", G_CALLBACK(file_cancel_cb), data); |
1675 "clicked", G_CALLBACK(file_cancel_cb), data); |
| 1620 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked", |
1676 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked", |
| 1621 G_CALLBACK(file_ok_check_if_exists_cb), data); |
1677 G_CALLBACK(file_ok_check_if_exists_cb), data); |
| 1622 #endif /* FILECHOOSER */ |
1678 #endif /* FILECHOOSER */ |
| |
1679 gtk_window_set_role(GTK_WINDOW(filesel), "pidgin-request-file"); |
| |
1680 gtk_window_set_transient_for(GTK_WINDOW(filesel), |
| |
1681 get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL)); |
| 1623 |
1682 |
| 1624 data->dialog = filesel; |
1683 data->dialog = filesel; |
| 1625 gtk_widget_show(filesel); |
1684 gtk_widget_show(filesel); |
| 1626 |
1685 |
| 1627 return (void *)data; |
1686 return (void *)data; |
| 1629 |
1688 |
| 1630 static void * |
1689 static void * |
| 1631 pidgin_request_folder(const char *title, const char *dirname, |
1690 pidgin_request_folder(const char *title, const char *dirname, |
| 1632 GCallback ok_cb, GCallback cancel_cb, |
1691 GCallback ok_cb, GCallback cancel_cb, |
| 1633 PurpleAccount *account, const char *who, PurpleConversation *conv, |
1692 PurpleAccount *account, const char *who, PurpleConversation *conv, |
| 1634 void *user_data) |
1693 const char *ui_hint, void *user_data) |
| 1635 { |
1694 { |
| 1636 PidginRequestData *data; |
1695 PidginRequestData *data; |
| 1637 GtkWidget *dirsel; |
1696 GtkWidget *dirsel; |
| 1638 |
1697 |
| 1639 data = g_new0(PidginRequestData, 1); |
1698 data = g_new0(PidginRequestData, 1); |
| 1668 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(dirsel)->cancel_button), |
1727 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(dirsel)->cancel_button), |
| 1669 "clicked", G_CALLBACK(file_cancel_cb), data); |
1728 "clicked", G_CALLBACK(file_cancel_cb), data); |
| 1670 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dirsel)->ok_button), "clicked", |
1729 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dirsel)->ok_button), "clicked", |
| 1671 G_CALLBACK(file_ok_check_if_exists_cb), data); |
1730 G_CALLBACK(file_ok_check_if_exists_cb), data); |
| 1672 #endif |
1731 #endif |
| |
1732 gtk_window_set_role(GTK_WINDOW(dirsel), "pidgin-request-dir"); |
| |
1733 gtk_window_set_transient_for(GTK_WINDOW(dirsel), |
| |
1734 get_request_parent(ui_hint, conv ? PIDGIN_CONVERSATION(conv) : NULL)); |
| 1673 |
1735 |
| 1674 data->dialog = dirsel; |
1736 data->dialog = dirsel; |
| 1675 gtk_widget_show(dirsel); |
1737 gtk_widget_show(dirsel); |
| 1676 |
1738 |
| 1677 return (void *)data; |
1739 return (void *)data; |