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