| 32437:a1093fbc45d2 | 32438:dc8991868906 |
|---|---|
| 50 #include "imgstore.h" | 50 #include "imgstore.h" |
| 51 #include "log.h" | 51 #include "log.h" |
| 52 #include "notify.h" | 52 #include "notify.h" |
| 53 #include "prpl.h" | 53 #include "prpl.h" |
| 54 #include "request.h" | 54 #include "request.h" |
| 55 #include "theme-loader.h" | |
| 56 #include "theme-manager.h" | |
| 55 #include "util.h" | 57 #include "util.h" |
| 56 #include "version.h" | 58 #include "version.h" |
| 57 | 59 |
| 58 #include "gtkdnd-hints.h" | 60 #include "gtkdnd-hints.h" |
| 59 #include "gtkblist.h" | 61 #include "gtkblist.h" |
| 60 #include "gtkconv.h" | 62 #include "gtkconv.h" |
| 61 #include "gtkconvwin.h" | 63 #include "gtkconvwin.h" |
| 64 #include "gtkconv-theme.h" | |
| 65 #include "gtkconv-theme-loader.h" | |
| 62 #include "gtkdialogs.h" | 66 #include "gtkdialogs.h" |
| 63 #include "gtkimhtml.h" | 67 #include "gtkimhtml.h" |
| 64 #include "gtkimhtmltoolbar.h" | 68 #include "gtkimhtmltoolbar.h" |
| 65 #include "gtklog.h" | 69 #include "gtklog.h" |
| 66 #include "gtkmenutray.h" | 70 #include "gtkmenutray.h" |
| 67 #include "gtkpounce.h" | 71 #include "gtkpounce.h" |
| 68 #include "gtkprefs.h" | 72 #include "gtkprefs.h" |
| 69 #include "gtkprivacy.h" | 73 #include "gtkprivacy.h" |
| 70 #include "gtkthemes.h" | 74 #include "gtkthemes.h" |
| 71 #include "gtkutils.h" | 75 #include "gtkutils.h" |
| 76 #include "gtkwebview.h" | |
| 72 #include "pidginstock.h" | 77 #include "pidginstock.h" |
| 73 #include "pidgintooltip.h" | 78 #include "pidgintooltip.h" |
| 79 #include "smileyparser.h" | |
| 74 | 80 |
| 75 #include "gtknickcolors.h" | 81 #include "gtknickcolors.h" |
| 82 | |
| 83 #if !GTK_CHECK_VERSION(2,20,0) | |
| 84 #define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x) | |
| 85 | |
| 86 #if !GTK_CHECK_VERSION(2,18,0) | |
| 87 #define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x) | |
| 88 #define gtk_widget_is_drawable(x) GTK_WIDGET_DRAWABLE(x) | |
| 89 #endif | |
| 90 #endif | |
| 91 | |
| 92 /** | |
| 93 * A GTK+ Instant Message pane. | |
| 94 */ | |
| 95 struct _PidginImPane | |
| 96 { | |
| 97 GtkWidget *block; | |
| 98 GtkWidget *send_file; | |
| 99 GtkWidget *sep1; | |
| 100 GtkWidget *sep2; | |
| 101 GtkWidget *check; | |
| 102 GtkWidget *progress; | |
| 103 guint32 typing_timer; | |
| 104 | |
| 105 /* Buddy icon stuff */ | |
| 106 GtkWidget *icon_container; | |
| 107 GtkWidget *icon; | |
| 108 gboolean show_icon; | |
| 109 gboolean animate; | |
| 110 GdkPixbufAnimation *anim; | |
| 111 GdkPixbufAnimationIter *iter; | |
| 112 guint32 icon_timer; | |
| 113 }; | |
| 114 | |
| 115 /** | |
| 116 * GTK+ Chat panes. | |
| 117 */ | |
| 118 struct _PidginChatPane | |
| 119 { | |
| 120 GtkWidget *count; | |
| 121 GtkWidget *list; | |
| 122 GtkWidget *topic_text; | |
| 123 }; | |
| 76 | 124 |
| 77 #define CLOSE_CONV_TIMEOUT_SECS (10 * 60) | 125 #define CLOSE_CONV_TIMEOUT_SECS (10 * 60) |
| 78 | 126 |
| 79 #define AUTO_RESPONSE "<AUTO-REPLY> : " | 127 #define AUTO_RESPONSE "<AUTO-REPLY> : " |
| 80 | 128 |
| 173 static gboolean pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y); | 221 static gboolean pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y); |
| 174 | 222 |
| 175 static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) | 223 static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) |
| 176 { | 224 { |
| 177 static GdkColor col; | 225 static GdkColor col; |
| 178 GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml); | 226 GtkStyle *style = gtk_widget_get_style(gtkconv->webview); |
| 179 float scale; | 227 float scale; |
| 180 | 228 |
| 181 col = nick_colors[g_str_hash(name) % nbr_nick_colors]; | 229 col = nick_colors[g_str_hash(name) % nbr_nick_colors]; |
| 182 scale = ((1-(LUMINANCE(style->base[GTK_STATE_NORMAL]) / LUMINANCE(style->white))) * | 230 scale = ((1-(LUMINANCE(style->base[GTK_STATE_NORMAL]) / LUMINANCE(style->white))) * |
| 183 (LUMINANCE(style->white)/MAX(MAX(col.red, col.blue), col.green))); | 231 (LUMINANCE(style->white)/MAX(MAX(col.red, col.blue), col.green))); |
| 193 } | 241 } |
| 194 | 242 |
| 195 static PurpleBlistNode * | 243 static PurpleBlistNode * |
| 196 get_conversation_blist_node(PurpleConversation *conv) | 244 get_conversation_blist_node(PurpleConversation *conv) |
| 197 { | 245 { |
| 246 PurpleAccount *account = purple_conversation_get_account(conv); | |
| 198 PurpleBlistNode *node = NULL; | 247 PurpleBlistNode *node = NULL; |
| 199 | 248 |
| 200 switch (purple_conversation_get_type(conv)) { | 249 switch (purple_conversation_get_type(conv)) { |
| 201 case PURPLE_CONV_TYPE_IM: | 250 case PURPLE_CONV_TYPE_IM: |
| 202 node = PURPLE_BLIST_NODE(purple_find_buddy(conv->account, conv->name)); | 251 node = PURPLE_BLIST_NODE(purple_find_buddy(account, purple_conversation_get_name(conv))); |
| 203 node = node ? node->parent : NULL; | 252 node = node ? node->parent : NULL; |
| 204 break; | 253 break; |
| 205 case PURPLE_CONV_TYPE_CHAT: | 254 case PURPLE_CONV_TYPE_CHAT: |
| 206 node = PURPLE_BLIST_NODE(purple_blist_find_chat(conv->account, conv->name)); | 255 node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, purple_conversation_get_name(conv))); |
| 207 break; | 256 break; |
| 208 default: | 257 default: |
| 209 break; | 258 break; |
| 210 } | 259 } |
| 211 return node; | 260 return node; |
| 273 | 322 |
| 274 static void | 323 static void |
| 275 default_formatize(PidginConversation *c) | 324 default_formatize(PidginConversation *c) |
| 276 { | 325 { |
| 277 PurpleConversation *conv = c->active_conv; | 326 PurpleConversation *conv = c->active_conv; |
| 278 gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), conv->features); | 327 gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), purple_conversation_get_features(conv)); |
| 279 } | 328 } |
| 280 | 329 |
| 281 static void | 330 static void |
| 282 conversation_entry_clear(PidginConversation *gtkconv) | 331 conversation_entry_clear(PidginConversation *gtkconv) |
| 283 { | 332 { |
| 353 } else { | 402 } else { |
| 354 str = g_string_append(str, "(none)"); | 403 str = g_string_append(str, "(none)"); |
| 355 } | 404 } |
| 356 | 405 |
| 357 tmp = g_string_free(str, FALSE); | 406 tmp = g_string_free(str, FALSE); |
| 407 } else if (!g_ascii_strcasecmp(args[0], "unsafe")) { | |
| 408 if (purple_debug_is_unsafe()) { | |
| 409 purple_debug_set_unsafe(FALSE); | |
| 410 purple_conversation_write(conv, NULL, _("Unsafe debugging is now disabled."), | |
| 411 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); | |
| 412 } else { | |
| 413 purple_debug_set_unsafe(TRUE); | |
| 414 purple_conversation_write(conv, NULL, _("Unsafe debugging is now enabled."), | |
| 415 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); | |
| 416 } | |
| 417 | |
| 418 return PURPLE_CMD_RET_OK; | |
| 419 } else if (!g_ascii_strcasecmp(args[0], "verbose")) { | |
| 420 if (purple_debug_is_verbose()) { | |
| 421 purple_debug_set_verbose(FALSE); | |
| 422 purple_conversation_write(conv, NULL, _("Verbose debugging is now disabled."), | |
| 423 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); | |
| 424 } else { | |
| 425 purple_debug_set_verbose(TRUE); | |
| 426 purple_conversation_write(conv, NULL, _("Verbose debugging is now enabled."), | |
| 427 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); | |
| 428 } | |
| 429 | |
| 430 return PURPLE_CMD_RET_OK; | |
| 358 } else { | 431 } else { |
| 359 purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version"), | 432 purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version unsafe verbose"), |
| 360 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL)); | 433 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL)); |
| 361 return PURPLE_CMD_RET_OK; | 434 return PURPLE_CMD_RET_OK; |
| 362 } | 435 } |
| 363 | 436 |
| 364 markup = g_markup_escape_text(tmp, -1); | 437 markup = g_markup_escape_text(tmp, -1); |
| 376 void *data) | 449 void *data) |
| 377 { | 450 { |
| 378 PidginConversation *gtkconv = NULL; | 451 PidginConversation *gtkconv = NULL; |
| 379 | 452 |
| 380 gtkconv = PIDGIN_CONVERSATION(conv); | 453 gtkconv = PIDGIN_CONVERSATION(conv); |
| 381 if (gtkconv) | 454 |
| 382 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); | 455 if (PIDGIN_CONVERSATION(conv)) |
| 456 webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(gtkconv->webview), "", ""); | |
| 383 } | 457 } |
| 384 | 458 |
| 385 static PurpleCmdRet | 459 static PurpleCmdRet |
| 386 clear_command_cb(PurpleConversation *conv, | 460 clear_command_cb(PurpleConversation *conv, |
| 387 const char *cmd, char **args, char **error, void *data) | 461 const char *cmd, char **args, char **error, void *data) |
| 495 case PURPLE_CMD_STATUS_NOT_FOUND: | 569 case PURPLE_CMD_STATUS_NOT_FOUND: |
| 496 { | 570 { |
| 497 PurplePluginProtocolInfo *prpl_info = NULL; | 571 PurplePluginProtocolInfo *prpl_info = NULL; |
| 498 PurpleConnection *gc; | 572 PurpleConnection *gc; |
| 499 | 573 |
| 500 if ((gc = purple_conversation_get_gc(conv))) | 574 if ((gc = purple_conversation_get_connection(conv))) |
| 501 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 575 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 502 | 576 |
| 503 if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) { | 577 if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) { |
| 504 char *spaceslash; | 578 char *spaceslash; |
| 505 | 579 |
| 506 /* If the first word in the entered text has a '/' in it, then the user | 580 /* If the first word in the entered text has a '/' in it, then the user |
| 588 /* XXX: is there a better way to tell if the message has images? */ | 662 /* XXX: is there a better way to tell if the message has images? */ |
| 589 if (GTK_IMHTML(gtkconv->entry)->im_images != NULL) | 663 if (GTK_IMHTML(gtkconv->entry)->im_images != NULL) |
| 590 flags |= PURPLE_MESSAGE_IMAGES; | 664 flags |= PURPLE_MESSAGE_IMAGES; |
| 591 | 665 |
| 592 gc = purple_account_get_connection(account); | 666 gc = purple_account_get_connection(account); |
| 593 if (gc && (conv->features & PURPLE_CONNECTION_NO_NEWLINES)) { | 667 if (gc && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_NO_NEWLINES)) { |
| 594 char **bufs; | 668 char **bufs; |
| 595 int i; | 669 int i; |
| 596 | 670 |
| 597 bufs = gtk_imhtml_get_markup_lines(GTK_IMHTML(gtkconv->entry)); | 671 bufs = gtk_imhtml_get_markup_lines(GTK_IMHTML(gtkconv->entry)); |
| 598 for (i = 0; bufs[i]; i++) { | 672 for (i = 0; bufs[i]; i++) { |
| 654 static void chat_do_info(PidginConversation *gtkconv, const char *who) | 728 static void chat_do_info(PidginConversation *gtkconv, const char *who) |
| 655 { | 729 { |
| 656 PurpleConversation *conv = gtkconv->active_conv; | 730 PurpleConversation *conv = gtkconv->active_conv; |
| 657 PurpleConnection *gc; | 731 PurpleConnection *gc; |
| 658 | 732 |
| 659 if ((gc = purple_conversation_get_gc(conv))) { | 733 if ((gc = purple_conversation_get_connection(conv))) { |
| 660 pidgin_retrieve_user_info_in_chat(gc, who, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv))); | 734 pidgin_retrieve_user_info_in_chat(gc, who, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv))); |
| 661 } | 735 } |
| 662 } | 736 } |
| 663 | 737 |
| 664 | 738 |
| 666 info_cb(GtkWidget *widget, PidginConversation *gtkconv) | 740 info_cb(GtkWidget *widget, PidginConversation *gtkconv) |
| 667 { | 741 { |
| 668 PurpleConversation *conv = gtkconv->active_conv; | 742 PurpleConversation *conv = gtkconv->active_conv; |
| 669 | 743 |
| 670 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 744 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 671 pidgin_retrieve_user_info(purple_conversation_get_gc(conv), | 745 pidgin_retrieve_user_info(purple_conversation_get_connection(conv), |
| 672 purple_conversation_get_name(conv)); | 746 purple_conversation_get_name(conv)); |
| 673 gtk_widget_grab_focus(gtkconv->entry); | 747 gtk_widget_grab_focus(gtkconv->entry); |
| 674 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 748 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
| 675 /* Get info of the person currently selected in the GtkTreeView */ | 749 /* Get info of the person currently selected in the GtkTreeView */ |
| 676 PidginChatPane *gtkchat; | 750 PidginChatPane *gtkchat; |
| 754 message = gtk_entry_get_text(GTK_ENTRY(info->message)); | 828 message = gtk_entry_get_text(GTK_ENTRY(info->message)); |
| 755 | 829 |
| 756 if (!g_ascii_strcasecmp(buddy, "")) | 830 if (!g_ascii_strcasecmp(buddy, "")) |
| 757 return; | 831 return; |
| 758 | 832 |
| 759 serv_chat_invite(purple_conversation_get_gc(conv), | 833 serv_chat_invite(purple_conversation_get_connection(conv), |
| 760 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), | 834 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), |
| 761 message, buddy); | 835 message, buddy); |
| 762 } | 836 } |
| 763 | 837 |
| 764 gtk_widget_destroy(invite_dialog); | 838 gtk_widget_destroy(invite_dialog); |
| 772 GtkSelectionData *sd, guint inf, guint t, gpointer data) | 846 GtkSelectionData *sd, guint inf, guint t, gpointer data) |
| 773 { | 847 { |
| 774 InviteBuddyInfo *info = (InviteBuddyInfo *)data; | 848 InviteBuddyInfo *info = (InviteBuddyInfo *)data; |
| 775 const char *convprotocol; | 849 const char *convprotocol; |
| 776 gboolean success = TRUE; | 850 gboolean success = TRUE; |
| 777 GdkAtom target = gtk_selection_data_get_target(sd); | |
| 778 | 851 |
| 779 convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv)); | 852 convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv)); |
| 780 | 853 |
| 781 if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) | 854 if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) |
| 782 { | 855 { |
| 783 PurpleBlistNode *node = NULL; | 856 PurpleBlistNode *node = NULL; |
| 784 PurpleBuddy *buddy; | 857 PurpleBuddy *buddy; |
| 785 const guchar *data = gtk_selection_data_get_data(sd); | 858 |
| 786 | 859 memcpy(&node, sd->data, sizeof(node)); |
| 787 memcpy(&node, data, sizeof(node)); | |
| 788 | 860 |
| 789 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) | 861 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) |
| 790 buddy = purple_contact_get_priority_buddy((PurpleContact *)node); | 862 buddy = purple_contact_get_priority_buddy((PurpleContact *)node); |
| 791 else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) | 863 else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) |
| 792 buddy = (PurpleBuddy *)node; | 864 buddy = (PurpleBuddy *)node; |
| 793 else | 865 else |
| 794 return; | 866 return; |
| 795 | 867 |
| 796 if (strcmp(convprotocol, purple_account_get_protocol_id(buddy->account))) | 868 if (strcmp(convprotocol, purple_account_get_protocol_id(purple_buddy_get_account(buddy)))) |
| 797 { | 869 { |
| 798 purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL, | 870 purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL, |
| 799 _("That buddy is not on the same protocol as this " | 871 _("That buddy is not on the same protocol as this " |
| 800 "chat."), NULL); | 872 "chat."), NULL); |
| 801 success = FALSE; | 873 success = FALSE; |
| 802 } | 874 } |
| 803 else | 875 else |
| 804 gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy)); | 876 gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy)); |
| 805 | 877 |
| 806 gtk_drag_finish(dc, success, | 878 gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t); |
| 807 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t); | 879 } |
| 808 } | 880 else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE)) |
| 809 else if (target == gdk_atom_intern("application/x-im-contact", FALSE)) | |
| 810 { | 881 { |
| 811 char *protocol = NULL; | 882 char *protocol = NULL; |
| 812 char *username = NULL; | 883 char *username = NULL; |
| 813 PurpleAccount *account; | 884 PurpleAccount *account; |
| 814 | 885 |
| 815 if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account, | 886 if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, |
| 816 &protocol, &username, NULL)) | 887 &protocol, &username, NULL)) |
| 817 { | 888 { |
| 818 if (account == NULL) | 889 if (account == NULL) |
| 819 { | 890 { |
| 820 purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL, | 891 purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL, |
| 835 } | 906 } |
| 836 | 907 |
| 837 g_free(username); | 908 g_free(username); |
| 838 g_free(protocol); | 909 g_free(protocol); |
| 839 | 910 |
| 840 gtk_drag_finish(dc, success, | 911 gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t); |
| 841 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t); | |
| 842 } | 912 } |
| 843 } | 913 } |
| 844 | 914 |
| 845 static const GtkTargetEntry dnd_targets[] = | 915 static const GtkTargetEntry dnd_targets[] = |
| 846 { | 916 { |
| 878 | 948 |
| 879 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog), | 949 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog), |
| 880 GTK_RESPONSE_OK); | 950 GTK_RESPONSE_OK); |
| 881 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE); | 951 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE); |
| 882 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE); | 952 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE); |
| 883 /* TODO: set no separator using GTK+ 3.0 */ | 953 #if !GTK_CHECK_VERSION(2,22,0) |
| 884 #if 0 | |
| 885 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE); | 954 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE); |
| 886 #endif | 955 #endif |
| 887 | 956 |
| 888 info->window = GTK_WIDGET(invite_dialog); | 957 info->window = GTK_WIDGET(invite_dialog); |
| 889 | 958 |
| 890 /* Setup the outside spacing. */ | 959 /* Setup the outside spacing. */ |
| 891 vbox = gtk_dialog_get_content_area(GTK_DIALOG(invite_dialog)); | 960 vbox = GTK_DIALOG(invite_dialog)->vbox; |
| 892 | 961 |
| 893 gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER); | 962 gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER); |
| 894 gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE); | 963 gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE); |
| 895 | 964 |
| 896 /* Setup the inner hbox and put the dialog's icon in it. */ | 965 /* Setup the inner hbox and put the dialog's icon in it. */ |
| 984 { | 1053 { |
| 985 pidgin_dialogs_im(); | 1054 pidgin_dialogs_im(); |
| 986 } | 1055 } |
| 987 | 1056 |
| 988 static void | 1057 static void |
| 989 menu_join_chat_cb(gpointer data, guint action, GtkWidget *widget) | 1058 menu_join_chat_cb(GtkAction *action, gpointer data) |
| 990 { | 1059 { |
| 991 pidgin_blist_joinchat_show(); | 1060 pidgin_blist_joinchat_show(); |
| 992 } | 1061 } |
| 993 | 1062 |
| 994 static void | 1063 static void |
| 995 savelog_writefile_cb(void *user_data, const char *filename) | 1064 savelog_writefile_cb(void *user_data, const char *filename) |
| 996 { | 1065 { |
| 1066 /* TODO WEBKIT: I don't know how to support this using webkit yet. */ | |
| 1067 #if 0 | |
| 997 PurpleConversation *conv = (PurpleConversation *)user_data; | 1068 PurpleConversation *conv = (PurpleConversation *)user_data; |
| 998 FILE *fp; | 1069 FILE *fp; |
| 999 const char *name; | 1070 const char *name; |
| 1000 char **lines; | 1071 char **lines; |
| 1001 gchar *text; | 1072 gchar *text; |
| 1018 g_free(text); | 1089 g_free(text); |
| 1019 g_strfreev(lines); | 1090 g_strfreev(lines); |
| 1020 | 1091 |
| 1021 fprintf(fp, "\n</body>\n</html>\n"); | 1092 fprintf(fp, "\n</body>\n</html>\n"); |
| 1022 fclose(fp); | 1093 fclose(fp); |
| 1094 #endif /* if 0 */ | |
| 1023 } | 1095 } |
| 1024 | 1096 |
| 1025 /* | 1097 /* |
| 1026 * It would be kinda cool if this gave the option of saving a | 1098 * It would be kinda cool if this gave the option of saving a |
| 1027 * plaintext v. HTML file. | 1099 * plaintext v. HTML file. |
| 1029 static void | 1101 static void |
| 1030 menu_save_as_cb(GtkAction *action, gpointer data) | 1102 menu_save_as_cb(GtkAction *action, gpointer data) |
| 1031 { | 1103 { |
| 1032 PidginWindow *win = data; | 1104 PidginWindow *win = data; |
| 1033 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); | 1105 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); |
| 1034 PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name); | 1106 PurpleAccount *account = purple_conversation_get_account(conv); |
| 1107 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); | |
| 1035 const char *name; | 1108 const char *name; |
| 1036 gchar *buf; | 1109 gchar *buf; |
| 1037 gchar *c; | 1110 gchar *c; |
| 1038 | 1111 |
| 1039 if (buddy != NULL) | 1112 if (buddy != NULL) |
| 1040 name = purple_buddy_get_contact_alias(buddy); | 1113 name = purple_buddy_get_contact_alias(buddy); |
| 1041 else | 1114 else |
| 1042 name = purple_normalize(conv->account, conv->name); | 1115 name = purple_normalize(account, purple_conversation_get_name(conv)); |
| 1043 | 1116 |
| 1044 buf = g_strdup_printf("%s.html", name); | 1117 buf = g_strdup_printf("%s.html", name); |
| 1045 for (c = buf ; *c ; c++) | 1118 for (c = buf ; *c ; c++) |
| 1046 { | 1119 { |
| 1047 if (*c == '/' || *c == '\\') | 1120 if (*c == '/' || *c == '\\') |
| 1079 return; | 1152 return; |
| 1080 | 1153 |
| 1081 gtkblist = pidgin_blist_get_default_gtk_blist(); | 1154 gtkblist = pidgin_blist_get_default_gtk_blist(); |
| 1082 | 1155 |
| 1083 cursor = gdk_cursor_new(GDK_WATCH); | 1156 cursor = gdk_cursor_new(GDK_WATCH); |
| 1084 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), cursor); | 1157 gdk_window_set_cursor(gtkblist->window->window, cursor); |
| 1085 gdk_window_set_cursor(gtk_widget_get_window(win->window), cursor); | 1158 gdk_window_set_cursor(win->window->window, cursor); |
| 1086 gdk_cursor_unref(cursor); | 1159 gdk_cursor_unref(cursor); |
| 1087 #if GTK_CHECK_VERSION(2,4,0) && !GTK_CHECK_VERSION(2,6,0) //FIXME: What? | |
| 1088 gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window))); | |
| 1089 #endif | |
| 1090 | 1160 |
| 1091 name = purple_conversation_get_name(conv); | 1161 name = purple_conversation_get_name(conv); |
| 1092 account = purple_conversation_get_account(conv); | 1162 account = purple_conversation_get_account(conv); |
| 1093 | 1163 |
| 1094 buddies = purple_find_buddies(account, name); | 1164 buddies = purple_find_buddies(account, name); |
| 1097 PurpleBlistNode *node = cur->data; | 1167 PurpleBlistNode *node = cur->data; |
| 1098 if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL))) | 1168 if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL))) |
| 1099 { | 1169 { |
| 1100 pidgin_log_show_contact((PurpleContact *)node->parent); | 1170 pidgin_log_show_contact((PurpleContact *)node->parent); |
| 1101 g_slist_free(buddies); | 1171 g_slist_free(buddies); |
| 1102 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL); | 1172 gdk_window_set_cursor(gtkblist->window->window, NULL); |
| 1103 gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL); | 1173 gdk_window_set_cursor(win->window->window, NULL); |
| 1104 return; | 1174 return; |
| 1105 } | 1175 } |
| 1106 } | 1176 } |
| 1107 g_slist_free(buddies); | 1177 g_slist_free(buddies); |
| 1108 | 1178 |
| 1109 pidgin_log_show(type, name, account); | 1179 pidgin_log_show(type, name, account); |
| 1110 | 1180 |
| 1111 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL); | 1181 gdk_window_set_cursor(gtkblist->window->window, NULL); |
| 1112 gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL); | 1182 gdk_window_set_cursor(win->window->window, NULL); |
| 1113 } | 1183 } |
| 1114 | 1184 |
| 1115 static void | 1185 static void |
| 1116 menu_clear_cb(GtkAction *action, gpointer data) | 1186 menu_clear_cb(GtkAction *action, gpointer data) |
| 1117 { | 1187 { |
| 1153 { | 1223 { |
| 1154 PidginWindow *win = data; | 1224 PidginWindow *win = data; |
| 1155 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); | 1225 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); |
| 1156 | 1226 |
| 1157 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 1227 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 1158 serv_send_file(purple_conversation_get_gc(conv), purple_conversation_get_name(conv), NULL); | 1228 serv_send_file(purple_conversation_get_connection(conv), purple_conversation_get_name(conv), NULL); |
| 1159 } | 1229 } |
| 1160 | 1230 |
| 1161 } | 1231 } |
| 1162 | 1232 |
| 1163 static void | 1233 static void |
| 1164 menu_get_attention_cb(GtkAction *ation, gpointer data) | 1234 menu_get_attention_cb(GObject *obj, gpointer data) |
| 1165 { | 1235 { |
| 1166 PidginWindow *win = data; | 1236 PidginWindow *win = data; |
| 1167 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); | 1237 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); |
| 1168 | 1238 |
| 1169 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 1239 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 1170 purple_prpl_send_attention(purple_conversation_get_gc(conv), | 1240 int index; |
| 1171 purple_conversation_get_name(conv), 0); | 1241 if ((GtkAction *)obj == win->menu.get_attention) |
| 1242 index = 0; | |
| 1243 else | |
| 1244 index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(obj), "index")); | |
| 1245 purple_prpl_send_attention(purple_conversation_get_connection(conv), | |
| 1246 purple_conversation_get_name(conv), index); | |
| 1172 } | 1247 } |
| 1173 } | 1248 } |
| 1174 | 1249 |
| 1175 static void | 1250 static void |
| 1176 menu_add_pounce_cb(GtkAction *action, gpointer data) | 1251 menu_add_pounce_cb(GtkAction *action, gpointer data) |
| 1362 /* Enable logging first so the message below can be logged. */ | 1437 /* Enable logging first so the message below can be logged. */ |
| 1363 purple_conversation_set_logging(conv, TRUE); | 1438 purple_conversation_set_logging(conv, TRUE); |
| 1364 | 1439 |
| 1365 purple_conversation_write(conv, NULL, | 1440 purple_conversation_write(conv, NULL, |
| 1366 _("Logging started. Future messages in this conversation will be logged."), | 1441 _("Logging started. Future messages in this conversation will be logged."), |
| 1367 conv->logs ? (PURPLE_MESSAGE_SYSTEM) : | 1442 PURPLE_MESSAGE_SYSTEM, |
| 1368 (PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG), | |
| 1369 time(NULL)); | 1443 time(NULL)); |
| 1370 } | 1444 } |
| 1371 else | 1445 else |
| 1372 { | 1446 { |
| 1373 purple_conversation_write(conv, NULL, | 1447 purple_conversation_write(conv, NULL, |
| 1374 _("Logging stopped. Future messages in this conversation will not be logged."), | 1448 _("Logging stopped. Future messages in this conversation will not be logged."), |
| 1375 conv->logs ? (PURPLE_MESSAGE_SYSTEM) : | 1449 PURPLE_MESSAGE_SYSTEM, |
| 1376 (PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG), | |
| 1377 time(NULL)); | 1450 time(NULL)); |
| 1378 | 1451 |
| 1379 /* Disable the logging second, so that the above message can be logged. */ | 1452 /* Disable the logging second, so that the above message can be logged. */ |
| 1380 purple_conversation_set_logging(conv, FALSE); | 1453 purple_conversation_set_logging(conv, FALSE); |
| 1381 } | 1454 } |
| 1382 | 1455 |
| 1383 /* Save the setting IFF it's different than the pref. */ | 1456 /* Save the setting IFF it's different than the pref. */ |
| 1384 switch (conv->type) | 1457 switch (purple_conversation_get_type(conv)) |
| 1385 { | 1458 { |
| 1386 case PURPLE_CONV_TYPE_IM: | 1459 case PURPLE_CONV_TYPE_IM: |
| 1387 if (logging == purple_prefs_get_bool("/purple/logging/log_ims")) | 1460 if (logging == purple_prefs_get_bool("/purple/logging/log_ims")) |
| 1388 purple_blist_node_remove_setting(node, "enable-logging"); | 1461 purple_blist_node_remove_setting(node, "enable-logging"); |
| 1389 else | 1462 else |
| 1451 g_return_if_fail(account != NULL); | 1524 g_return_if_fail(account != NULL); |
| 1452 | 1525 |
| 1453 gc = purple_account_get_connection(account); | 1526 gc = purple_account_get_connection(account); |
| 1454 g_return_if_fail(gc != NULL); | 1527 g_return_if_fail(gc != NULL); |
| 1455 | 1528 |
| 1456 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 1529 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 1457 | 1530 |
| 1458 if (prpl_info && prpl_info->get_cb_real_name) | 1531 if (prpl_info && prpl_info->get_cb_real_name) |
| 1459 real_who = prpl_info->get_cb_real_name(gc, | 1532 real_who = prpl_info->get_cb_real_name(gc, |
| 1460 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); | 1533 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); |
| 1461 | 1534 |
| 1502 menu_chat_send_file_cb(GtkWidget *w, PidginConversation *gtkconv) | 1575 menu_chat_send_file_cb(GtkWidget *w, PidginConversation *gtkconv) |
| 1503 { | 1576 { |
| 1504 PurplePluginProtocolInfo *prpl_info; | 1577 PurplePluginProtocolInfo *prpl_info; |
| 1505 PurpleConversation *conv = gtkconv->active_conv; | 1578 PurpleConversation *conv = gtkconv->active_conv; |
| 1506 const char *who = g_object_get_data(G_OBJECT(w), "user_data"); | 1579 const char *who = g_object_get_data(G_OBJECT(w), "user_data"); |
| 1507 PurpleConnection *gc = purple_conversation_get_gc(conv); | 1580 PurpleConnection *gc = purple_conversation_get_connection(conv); |
| 1508 gchar *real_who = NULL; | 1581 gchar *real_who = NULL; |
| 1509 | 1582 |
| 1510 g_return_if_fail(gc != NULL); | 1583 g_return_if_fail(gc != NULL); |
| 1511 | 1584 |
| 1512 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 1585 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 1513 | 1586 |
| 1514 if (prpl_info && prpl_info->get_cb_real_name) | 1587 if (prpl_info && prpl_info->get_cb_real_name) |
| 1515 real_who = prpl_info->get_cb_real_name(gc, | 1588 real_who = prpl_info->get_cb_real_name(gc, |
| 1516 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); | 1589 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); |
| 1517 | 1590 |
| 1525 char *who; | 1598 char *who; |
| 1526 | 1599 |
| 1527 who = g_object_get_data(G_OBJECT(w), "user_data"); | 1600 who = g_object_get_data(G_OBJECT(w), "user_data"); |
| 1528 | 1601 |
| 1529 chat_do_info(gtkconv, who); | 1602 chat_do_info(gtkconv, who); |
| 1530 } | |
| 1531 | |
| 1532 static void | |
| 1533 menu_chat_get_away_cb(GtkWidget *w, PidginConversation *gtkconv) | |
| 1534 { | |
| 1535 PurpleConversation *conv = gtkconv->active_conv; | |
| 1536 PurplePluginProtocolInfo *prpl_info = NULL; | |
| 1537 PurpleConnection *gc; | |
| 1538 char *who; | |
| 1539 | |
| 1540 gc = purple_conversation_get_gc(conv); | |
| 1541 who = g_object_get_data(G_OBJECT(w), "user_data"); | |
| 1542 | |
| 1543 if (gc != NULL) { | |
| 1544 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
| 1545 | |
| 1546 /* | |
| 1547 * May want to expand this to work similarly to menu_info_cb? | |
| 1548 */ | |
| 1549 | |
| 1550 if (prpl_info->get_cb_away != NULL) | |
| 1551 { | |
| 1552 prpl_info->get_cb_away(gc, | |
| 1553 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); | |
| 1554 } | |
| 1555 } | |
| 1556 } | 1603 } |
| 1557 | 1604 |
| 1558 static void | 1605 static void |
| 1559 menu_chat_add_remove_cb(GtkWidget *w, PidginConversation *gtkconv) | 1606 menu_chat_add_remove_cb(GtkWidget *w, PidginConversation *gtkconv) |
| 1560 { | 1607 { |
| 1576 } | 1623 } |
| 1577 | 1624 |
| 1578 static GtkTextMark * | 1625 static GtkTextMark * |
| 1579 get_mark_for_user(PidginConversation *gtkconv, const char *who) | 1626 get_mark_for_user(PidginConversation *gtkconv, const char *who) |
| 1580 { | 1627 { |
| 1581 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)); | 1628 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->webview)); |
| 1582 char *tmp = g_strconcat("user:", who, NULL); | 1629 char *tmp = g_strconcat("user:", who, NULL); |
| 1583 GtkTextMark *mark = gtk_text_buffer_get_mark(buf, tmp); | 1630 GtkTextMark *mark = gtk_text_buffer_get_mark(buf, tmp); |
| 1584 | 1631 |
| 1585 g_free(tmp); | 1632 g_free(tmp); |
| 1586 return mark; | 1633 return mark; |
| 1587 } | 1634 } |
| 1588 | 1635 |
| 1589 static void | 1636 static void |
| 1590 menu_last_said_cb(GtkWidget *w, PidginConversation *gtkconv) | 1637 menu_last_said_cb(GtkWidget *w, PidginConversation *gtkconv) |
| 1591 { | 1638 { |
| 1639 /* TODO WEBKIT: This doesn't work yet, of course... */ | |
| 1640 #if 0 | |
| 1592 GtkTextMark *mark; | 1641 GtkTextMark *mark; |
| 1593 const char *who; | 1642 const char *who; |
| 1594 | 1643 |
| 1595 who = g_object_get_data(G_OBJECT(w), "user_data"); | 1644 who = g_object_get_data(G_OBJECT(w), "user_data"); |
| 1596 mark = get_mark_for_user(gtkconv, who); | 1645 mark = get_mark_for_user(gtkconv, who); |
| 1597 | 1646 |
| 1598 if (mark != NULL) | 1647 if (mark != NULL) |
| 1599 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); | 1648 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); |
| 1600 else | 1649 else |
| 1601 g_return_if_reached(); | 1650 g_return_if_reached(); |
| 1651 #endif /* if 0 */ | |
| 1602 } | 1652 } |
| 1603 | 1653 |
| 1604 static GtkWidget * | 1654 static GtkWidget * |
| 1605 create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc) | 1655 create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc) |
| 1606 { | 1656 { |
| 1607 static GtkWidget *menu = NULL; | 1657 static GtkWidget *menu = NULL; |
| 1608 PurplePluginProtocolInfo *prpl_info = NULL; | 1658 PurplePluginProtocolInfo *prpl_info = NULL; |
| 1609 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); | 1659 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); |
| 1660 PurpleAccount *account = purple_conversation_get_account(conv); | |
| 1610 gboolean is_me = FALSE; | 1661 gboolean is_me = FALSE; |
| 1611 GtkWidget *button; | 1662 GtkWidget *button; |
| 1612 PurpleBuddy *buddy = NULL; | 1663 PurpleBuddy *buddy = NULL; |
| 1613 | 1664 |
| 1614 if (gc != NULL) | 1665 if (gc != NULL) |
| 1615 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 1666 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 1616 | 1667 |
| 1617 /* | 1668 /* |
| 1618 * If a menu already exists, destroy it before creating a new one, | 1669 * If a menu already exists, destroy it before creating a new one, |
| 1619 * thus freeing-up the memory it occupied. | 1670 * thus freeing-up the memory it occupied. |
| 1620 */ | 1671 */ |
| 1621 if (menu) | 1672 if (menu) |
| 1622 gtk_widget_destroy(menu); | 1673 gtk_widget_destroy(menu); |
| 1623 | 1674 |
| 1624 if (!strcmp(chat->nick, purple_normalize(conv->account, who))) | 1675 if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, who))) |
| 1625 is_me = TRUE; | 1676 is_me = TRUE; |
| 1626 | 1677 |
| 1627 menu = gtk_menu_new(); | 1678 menu = gtk_menu_new(); |
| 1628 | 1679 |
| 1629 if (!is_me) { | 1680 if (!is_me) { |
| 1684 gtk_widget_set_sensitive(button, FALSE); | 1735 gtk_widget_set_sensitive(button, FALSE); |
| 1685 else | 1736 else |
| 1686 g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free); | 1737 g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free); |
| 1687 } | 1738 } |
| 1688 | 1739 |
| 1689 if (prpl_info && prpl_info->get_cb_away) { | |
| 1690 button = pidgin_new_item_from_stock(menu, _("Get Away Message"), PIDGIN_STOCK_AWAY, | |
| 1691 G_CALLBACK(menu_chat_get_away_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); | |
| 1692 | |
| 1693 if (gc == NULL) | |
| 1694 gtk_widget_set_sensitive(button, FALSE); | |
| 1695 else | |
| 1696 g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free); | |
| 1697 } | |
| 1698 | |
| 1699 if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { | 1740 if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { |
| 1700 if ((buddy = purple_find_buddy(conv->account, who)) != NULL) | 1741 if ((buddy = purple_find_buddy(account, who)) != NULL) |
| 1701 button = pidgin_new_item_from_stock(menu, _("Remove"), GTK_STOCK_REMOVE, | 1742 button = pidgin_new_item_from_stock(menu, _("Remove"), GTK_STOCK_REMOVE, |
| 1702 G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); | 1743 G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); |
| 1703 else | 1744 else |
| 1704 button = pidgin_new_item_from_stock(menu, _("Add"), GTK_STOCK_ADD, | 1745 button = pidgin_new_item_from_stock(menu, _("Add"), GTK_STOCK_ADD, |
| 1705 G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); | 1746 G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); |
| 1716 if (!get_mark_for_user(PIDGIN_CONVERSATION(conv), who)) | 1757 if (!get_mark_for_user(PIDGIN_CONVERSATION(conv), who)) |
| 1717 gtk_widget_set_sensitive(button, FALSE); | 1758 gtk_widget_set_sensitive(button, FALSE); |
| 1718 | 1759 |
| 1719 if (buddy != NULL) | 1760 if (buddy != NULL) |
| 1720 { | 1761 { |
| 1721 if (purple_account_is_connected(conv->account)) | 1762 if (purple_account_is_connected(account)) |
| 1722 pidgin_append_blist_node_proto_menu(menu, conv->account->gc, | 1763 pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(account), |
| 1723 (PurpleBlistNode *)buddy); | 1764 (PurpleBlistNode *)buddy); |
| 1724 pidgin_append_blist_node_extended_menu(menu, (PurpleBlistNode *)buddy); | 1765 pidgin_append_blist_node_extended_menu(menu, (PurpleBlistNode *)buddy); |
| 1725 gtk_widget_show_all(menu); | 1766 gtk_widget_show_all(menu); |
| 1726 } | 1767 } |
| 1727 | 1768 |
| 1743 gchar *who; | 1784 gchar *who; |
| 1744 | 1785 |
| 1745 gtkconv = PIDGIN_CONVERSATION(conv); | 1786 gtkconv = PIDGIN_CONVERSATION(conv); |
| 1746 gtkchat = gtkconv->u.chat; | 1787 gtkchat = gtkconv->u.chat; |
| 1747 account = purple_conversation_get_account(conv); | 1788 account = purple_conversation_get_account(conv); |
| 1748 gc = account->gc; | 1789 gc = purple_account_get_connection(account); |
| 1749 | 1790 |
| 1750 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | 1791 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); |
| 1751 | 1792 |
| 1752 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); | 1793 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); |
| 1753 if(!gtk_tree_selection_get_selected(sel, NULL, &iter)) | 1794 if(!gtk_tree_selection_get_selected(sel, NULL, &iter)) |
| 1779 gchar *who; | 1820 gchar *who; |
| 1780 int x, y; | 1821 int x, y; |
| 1781 | 1822 |
| 1782 gtkchat = gtkconv->u.chat; | 1823 gtkchat = gtkconv->u.chat; |
| 1783 account = purple_conversation_get_account(conv); | 1824 account = purple_conversation_get_account(conv); |
| 1784 gc = account->gc; | 1825 gc = purple_account_get_connection(account); |
| 1785 | 1826 |
| 1786 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | 1827 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); |
| 1787 | 1828 |
| 1788 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list), | 1829 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list), |
| 1789 event->x, event->y, &path, &column, &x, &y); | 1830 event->x, event->y, &path, &column, &x, &y); |
| 1811 | 1852 |
| 1812 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { | 1853 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { |
| 1813 chat_do_im(gtkconv, who); | 1854 chat_do_im(gtkconv, who); |
| 1814 } else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) { | 1855 } else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) { |
| 1815 /* Move to user's anchor */ | 1856 /* Move to user's anchor */ |
| 1857 /* TODO WEBKIT: This isn't implemented yet. */ | |
| 1858 #if 0 | |
| 1816 GtkTextMark *mark = get_mark_for_user(gtkconv, who); | 1859 GtkTextMark *mark = get_mark_for_user(gtkconv, who); |
| 1817 | 1860 |
| 1818 if(mark != NULL) | 1861 if(mark != NULL) |
| 1819 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); | 1862 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); |
| 1863 #endif /* if 0 */ | |
| 1820 } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { | 1864 } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { |
| 1821 GtkWidget *menu = create_chat_menu (conv, who, gc); | 1865 GtkWidget *menu = create_chat_menu (conv, who, gc); |
| 1822 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, | 1866 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, |
| 1823 event->button, event->time); | 1867 event->button, event->time); |
| 1824 } | 1868 } |
| 1891 GtkWidget *next = NULL; | 1935 GtkWidget *next = NULL; |
| 1892 struct { | 1936 struct { |
| 1893 GtkWidget *from; | 1937 GtkWidget *from; |
| 1894 GtkWidget *to; | 1938 GtkWidget *to; |
| 1895 } transitions[] = { | 1939 } transitions[] = { |
| 1896 {gtkconv->entry, gtkconv->imhtml}, | 1940 {gtkconv->entry, gtkconv->webview}, |
| 1897 {gtkconv->imhtml, chat ? gtkconv->u.chat->list : gtkconv->entry}, | 1941 {gtkconv->webview, chat ? gtkconv->u.chat->list : gtkconv->entry}, |
| 1898 {chat ? gtkconv->u.chat->list : NULL, gtkconv->entry}, | 1942 {chat ? gtkconv->u.chat->list : NULL, gtkconv->entry}, |
| 1899 {NULL, NULL} | 1943 {NULL, NULL} |
| 1900 }, *ptr; | 1944 }, *ptr; |
| 1901 | 1945 |
| 1902 for (ptr = transitions; !next && ptr->from; ptr++) { | 1946 for (ptr = transitions; !next && ptr->from; ptr++) { |
| 1930 pidgin_tooltip_destroy(); | 1974 pidgin_tooltip_destroy(); |
| 1931 | 1975 |
| 1932 /* If CTRL was held down... */ | 1976 /* If CTRL was held down... */ |
| 1933 if (event->state & GDK_CONTROL_MASK) { | 1977 if (event->state & GDK_CONTROL_MASK) { |
| 1934 switch (event->keyval) { | 1978 switch (event->keyval) { |
| 1935 case GDK_KEY_Page_Down: | 1979 case GDK_Page_Down: |
| 1936 case GDK_KEY_KP_Page_Down: | 1980 case GDK_KP_Page_Down: |
| 1937 case ']': | 1981 case ']': |
| 1938 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1)) | 1982 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1)) |
| 1939 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); | 1983 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); |
| 1940 else | 1984 else |
| 1941 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1); | 1985 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1); |
| 1942 return TRUE; | 1986 return TRUE; |
| 1943 break; | 1987 break; |
| 1944 | 1988 |
| 1945 case GDK_KEY_Page_Up: | 1989 case GDK_Page_Up: |
| 1946 case GDK_KEY_KP_Page_Up: | 1990 case GDK_KP_Page_Up: |
| 1947 case '[': | 1991 case '[': |
| 1948 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1)) | 1992 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1)) |
| 1949 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1); | 1993 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1); |
| 1950 else | 1994 else |
| 1951 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1); | 1995 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1); |
| 1952 return TRUE; | 1996 return TRUE; |
| 1953 break; | 1997 break; |
| 1954 | 1998 |
| 1955 case GDK_KEY_Tab: | 1999 case GDK_Tab: |
| 1956 case GDK_KEY_KP_Tab: | 2000 case GDK_KP_Tab: |
| 1957 case GDK_KEY_ISO_Left_Tab: | 2001 case GDK_ISO_Left_Tab: |
| 1958 if (event->state & GDK_SHIFT_MASK) { | 2002 if (event->state & GDK_SHIFT_MASK) { |
| 1959 move_to_next_unread_tab(gtkconv, FALSE); | 2003 move_to_next_unread_tab(gtkconv, FALSE); |
| 1960 } else { | 2004 } else { |
| 1961 move_to_next_unread_tab(gtkconv, TRUE); | 2005 move_to_next_unread_tab(gtkconv, TRUE); |
| 1962 } | 2006 } |
| 1963 | 2007 |
| 1964 return TRUE; | 2008 return TRUE; |
| 1965 break; | 2009 break; |
| 1966 | 2010 |
| 1967 case GDK_KEY_comma: | 2011 case GDK_comma: |
| 1968 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), | 2012 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), |
| 1969 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), | 2013 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), |
| 1970 curconv - 1); | 2014 curconv - 1); |
| 1971 return TRUE; | 2015 return TRUE; |
| 1972 break; | 2016 break; |
| 1973 | 2017 |
| 1974 case GDK_KEY_period: | 2018 case GDK_period: |
| 1975 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), | 2019 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), |
| 1976 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), | 2020 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), |
| 1977 (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook))); | 2021 (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook))); |
| 1978 return TRUE; | 2022 return TRUE; |
| 1979 break; | 2023 break; |
| 1980 case GDK_KEY_F6: | 2024 case GDK_F6: |
| 1981 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) | 2025 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) |
| 1982 return TRUE; | 2026 return TRUE; |
| 1983 break; | 2027 break; |
| 1984 } /* End of switch */ | 2028 } /* End of switch */ |
| 1985 } | 2029 } |
| 1999 | 2043 |
| 2000 /* If neither CTRL nor ALT were held down... */ | 2044 /* If neither CTRL nor ALT were held down... */ |
| 2001 else | 2045 else |
| 2002 { | 2046 { |
| 2003 switch (event->keyval) { | 2047 switch (event->keyval) { |
| 2004 case GDK_KEY_F2: | 2048 case GDK_F2: |
| 2005 if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) { | 2049 if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) { |
| 2006 infopane_entry_activate(gtkconv); | 2050 infopane_entry_activate(gtkconv); |
| 2007 return TRUE; | 2051 return TRUE; |
| 2008 } | 2052 } |
| 2009 break; | 2053 break; |
| 2010 case GDK_KEY_F6: | 2054 case GDK_F6: |
| 2011 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) | 2055 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) |
| 2012 return TRUE; | 2056 return TRUE; |
| 2013 break; | 2057 break; |
| 2014 } | 2058 } |
| 2015 } | 2059 } |
| 2029 return TRUE; | 2073 return TRUE; |
| 2030 | 2074 |
| 2031 /* If CTRL was held down... */ | 2075 /* If CTRL was held down... */ |
| 2032 if (event->state & GDK_CONTROL_MASK) { | 2076 if (event->state & GDK_CONTROL_MASK) { |
| 2033 switch (event->keyval) { | 2077 switch (event->keyval) { |
| 2034 case GDK_KEY_Up: | 2078 case GDK_Up: |
| 2035 if (!gtkconv->send_history) | 2079 if (!gtkconv->send_history) |
| 2036 break; | 2080 break; |
| 2037 | 2081 |
| 2038 if (gtkconv->entry != entry) | 2082 if (gtkconv->entry != entry) |
| 2039 break; | 2083 break; |
| 2080 } | 2124 } |
| 2081 | 2125 |
| 2082 return TRUE; | 2126 return TRUE; |
| 2083 break; | 2127 break; |
| 2084 | 2128 |
| 2085 case GDK_KEY_Down: | 2129 case GDK_Down: |
| 2086 if (!gtkconv->send_history) | 2130 if (!gtkconv->send_history) |
| 2087 break; | 2131 break; |
| 2088 | 2132 |
| 2089 if (gtkconv->entry != entry) | 2133 if (gtkconv->entry != entry) |
| 2090 break; | 2134 break; |
| 2133 } | 2177 } |
| 2134 | 2178 |
| 2135 /* If neither CTRL nor ALT were held down... */ | 2179 /* If neither CTRL nor ALT were held down... */ |
| 2136 else { | 2180 else { |
| 2137 switch (event->keyval) { | 2181 switch (event->keyval) { |
| 2138 case GDK_KEY_Tab: | 2182 case GDK_Tab: |
| 2139 case GDK_KEY_KP_Tab: | 2183 case GDK_KP_Tab: |
| 2140 case GDK_KEY_ISO_Left_Tab: | 2184 case GDK_ISO_Left_Tab: |
| 2141 if (gtkconv->entry != entry) | 2185 if (gtkconv->entry != entry) |
| 2142 break; | 2186 break; |
| 2143 { | 2187 { |
| 2144 gint plugin_return; | 2188 gint plugin_return; |
| 2145 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( | 2189 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( |
| 2147 conv, event->state & GDK_SHIFT_MASK)); | 2191 conv, event->state & GDK_SHIFT_MASK)); |
| 2148 return plugin_return ? TRUE : tab_complete(conv); | 2192 return plugin_return ? TRUE : tab_complete(conv); |
| 2149 } | 2193 } |
| 2150 break; | 2194 break; |
| 2151 | 2195 |
| 2152 case GDK_KEY_Page_Up: | 2196 case GDK_Page_Up: |
| 2153 case GDK_KEY_KP_Page_Up: | 2197 case GDK_KP_Page_Up: |
| 2198 /* TODO WEBKIT: Write this. */ | |
| 2199 #if 0 | |
| 2154 gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); | 2200 gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); |
| 2201 #endif /* if 0 */ | |
| 2155 return TRUE; | 2202 return TRUE; |
| 2156 break; | 2203 break; |
| 2157 | 2204 |
| 2158 case GDK_KEY_Page_Down: | 2205 case GDK_Page_Down: |
| 2159 case GDK_KEY_KP_Page_Down: | 2206 case GDK_KP_Page_Down: |
| 2207 /* TODO WEBKIT: Write this. */ | |
| 2208 #if 0 | |
| 2160 gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); | 2209 gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); |
| 2210 #endif /* if 0 */ | |
| 2161 return TRUE; | 2211 return TRUE; |
| 2162 break; | 2212 break; |
| 2163 | 2213 |
| 2164 } | 2214 } |
| 2165 } | 2215 } |
| 2198 { | 2248 { |
| 2199 PidginConversation *gtkconv = data; | 2249 PidginConversation *gtkconv = data; |
| 2200 | 2250 |
| 2201 /* If we have a valid key for the conversation display, then exit */ | 2251 /* If we have a valid key for the conversation display, then exit */ |
| 2202 if ((event->state & GDK_CONTROL_MASK) || | 2252 if ((event->state & GDK_CONTROL_MASK) || |
| 2203 (event->keyval == GDK_KEY_F6) || | 2253 (event->keyval == GDK_F6) || |
| 2204 (event->keyval == GDK_KEY_F10) || | 2254 (event->keyval == GDK_F10) || |
| 2205 (event->keyval == GDK_KEY_Shift_L) || | 2255 (event->keyval == GDK_Shift_L) || |
| 2206 (event->keyval == GDK_KEY_Shift_R) || | 2256 (event->keyval == GDK_Shift_R) || |
| 2207 (event->keyval == GDK_KEY_Control_L) || | 2257 (event->keyval == GDK_Control_L) || |
| 2208 (event->keyval == GDK_KEY_Control_R) || | 2258 (event->keyval == GDK_Control_R) || |
| 2209 (event->keyval == GDK_KEY_Escape) || | 2259 (event->keyval == GDK_Escape) || |
| 2210 (event->keyval == GDK_KEY_Up) || | 2260 (event->keyval == GDK_Up) || |
| 2211 (event->keyval == GDK_KEY_Down) || | 2261 (event->keyval == GDK_Down) || |
| 2212 (event->keyval == GDK_KEY_Left) || | 2262 (event->keyval == GDK_Left) || |
| 2213 (event->keyval == GDK_KEY_Right) || | 2263 (event->keyval == GDK_Right) || |
| 2214 (event->keyval == GDK_KEY_Page_Up) || | 2264 (event->keyval == GDK_Page_Up) || |
| 2215 (event->keyval == GDK_KEY_KP_Page_Up) || | 2265 (event->keyval == GDK_KP_Page_Up) || |
| 2216 (event->keyval == GDK_KEY_Page_Down) || | 2266 (event->keyval == GDK_Page_Down) || |
| 2217 (event->keyval == GDK_KEY_KP_Page_Down) || | 2267 (event->keyval == GDK_KP_Page_Down) || |
| 2218 (event->keyval == GDK_KEY_Home) || | 2268 (event->keyval == GDK_Home) || |
| 2219 (event->keyval == GDK_KEY_End) || | 2269 (event->keyval == GDK_End) || |
| 2220 (event->keyval == GDK_KEY_Tab) || | 2270 (event->keyval == GDK_Tab) || |
| 2221 (event->keyval == GDK_KEY_KP_Tab) || | 2271 (event->keyval == GDK_KP_Tab) || |
| 2222 (event->keyval == GDK_KEY_ISO_Left_Tab)) | 2272 (event->keyval == GDK_ISO_Left_Tab)) |
| 2223 { | 2273 { |
| 2224 if (event->type == GDK_KEY_PRESS) | 2274 if (event->type == GDK_KEY_PRESS) |
| 2225 return conv_keypress_common(gtkconv, event); | 2275 return conv_keypress_common(gtkconv, event); |
| 2226 return FALSE; | 2276 return FALSE; |
| 2227 } | 2277 } |
| 2242 { | 2292 { |
| 2243 PidginConversation *gtkconv; | 2293 PidginConversation *gtkconv; |
| 2244 PurpleConversation *old_conv; | 2294 PurpleConversation *old_conv; |
| 2245 GtkIMHtml *entry; | 2295 GtkIMHtml *entry; |
| 2246 const char *protocol_name; | 2296 const char *protocol_name; |
| 2297 PurpleConnectionFlags features; | |
| 2247 | 2298 |
| 2248 g_return_if_fail(conv != NULL); | 2299 g_return_if_fail(conv != NULL); |
| 2249 | 2300 |
| 2250 gtkconv = PIDGIN_CONVERSATION(conv); | 2301 gtkconv = PIDGIN_CONVERSATION(conv); |
| 2251 old_conv = gtkconv->active_conv; | 2302 old_conv = gtkconv->active_conv; |
| 2263 | 2314 |
| 2264 purple_conversation_set_logging(conv, | 2315 purple_conversation_set_logging(conv, |
| 2265 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging))); | 2316 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging))); |
| 2266 | 2317 |
| 2267 entry = GTK_IMHTML(gtkconv->entry); | 2318 entry = GTK_IMHTML(gtkconv->entry); |
| 2268 protocol_name = purple_account_get_protocol_name(conv->account); | 2319 protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv)); |
| 2269 gtk_imhtml_set_protocol_name(entry, protocol_name); | 2320 gtk_imhtml_set_protocol_name(entry, protocol_name); |
| 2270 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); | 2321 /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */ |
| 2271 | 2322 |
| 2272 if (!(conv->features & PURPLE_CONNECTION_HTML)) | 2323 features = purple_conversation_get_features(conv); |
| 2324 if (!(features & PURPLE_CONNECTION_HTML)) | |
| 2273 gtk_imhtml_clear_formatting(GTK_IMHTML(gtkconv->entry)); | 2325 gtk_imhtml_clear_formatting(GTK_IMHTML(gtkconv->entry)); |
| 2274 else if (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO && | 2326 else if (features & PURPLE_CONNECTION_FORMATTING_WBFO && |
| 2275 !(old_conv->features & PURPLE_CONNECTION_FORMATTING_WBFO)) | 2327 !(purple_conversation_get_features(old_conv) & PURPLE_CONNECTION_FORMATTING_WBFO)) |
| 2276 { | 2328 { |
| 2277 /* The old conversation allowed formatting on parts of the | 2329 /* The old conversation allowed formatting on parts of the |
| 2278 * buffer, but the new one only allows it on the whole | 2330 * buffer, but the new one only allows it on the whole |
| 2279 * buffer. This code saves the formatting from the current | 2331 * buffer. This code saves the formatting from the current |
| 2280 * position of the cursor, clears the formatting, then | 2332 * position of the cursor, clears the formatting, then |
| 2310 if (underline != underline2) | 2362 if (underline != underline2) |
| 2311 gtk_imhtml_toggle_underline(entry); | 2363 gtk_imhtml_toggle_underline(entry); |
| 2312 | 2364 |
| 2313 gtk_imhtml_toggle_fontface(entry, fontface); | 2365 gtk_imhtml_toggle_fontface(entry, fontface); |
| 2314 | 2366 |
| 2315 if (!(conv->features & PURPLE_CONNECTION_NO_FONTSIZE)) | 2367 if (!(features & PURPLE_CONNECTION_NO_FONTSIZE)) |
| 2316 gtk_imhtml_font_set_size(entry, fontsize); | 2368 gtk_imhtml_font_set_size(entry, fontsize); |
| 2317 | 2369 |
| 2318 gtk_imhtml_toggle_forecolor(entry, forecolor); | 2370 gtk_imhtml_toggle_forecolor(entry, forecolor); |
| 2319 | 2371 |
| 2320 if (!(conv->features & PURPLE_CONNECTION_NO_BGCOLOR)) | 2372 if (!(features & PURPLE_CONNECTION_NO_BGCOLOR)) |
| 2321 { | 2373 { |
| 2322 gtk_imhtml_toggle_backcolor(entry, backcolor); | 2374 gtk_imhtml_toggle_backcolor(entry, backcolor); |
| 2323 gtk_imhtml_toggle_background(entry, background); | 2375 gtk_imhtml_toggle_background(entry, background); |
| 2324 } | 2376 } |
| 2325 | 2377 |
| 2333 /* This is done in default_formatize, which is called from clear_formatting_cb, | 2385 /* This is done in default_formatize, which is called from clear_formatting_cb, |
| 2334 * which is (obviously) a clear_formatting signal handler. However, if we're | 2386 * which is (obviously) a clear_formatting signal handler. However, if we're |
| 2335 * here, we didn't call gtk_imhtml_clear_formatting() (because we want to | 2387 * here, we didn't call gtk_imhtml_clear_formatting() (because we want to |
| 2336 * preserve the formatting exactly as it is), so we have to do this now. */ | 2388 * preserve the formatting exactly as it is), so we have to do this now. */ |
| 2337 gtk_imhtml_set_whole_buffer_formatting_only(entry, | 2389 gtk_imhtml_set_whole_buffer_formatting_only(entry, |
| 2338 (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO)); | 2390 (features & PURPLE_CONNECTION_FORMATTING_WBFO)); |
| 2339 } | 2391 } |
| 2340 | 2392 |
| 2341 purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv); | 2393 purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv); |
| 2342 | 2394 |
| 2343 gray_stuff_out(gtkconv); | 2395 gray_stuff_out(gtkconv); |
| 2398 if (gtk_text_iter_is_start(start_pos) && gtk_text_iter_is_end(end_pos)) { | 2450 if (gtk_text_iter_is_start(start_pos) && gtk_text_iter_is_end(end_pos)) { |
| 2399 | 2451 |
| 2400 /* We deleted all the text, so turn off typing. */ | 2452 /* We deleted all the text, so turn off typing. */ |
| 2401 purple_conv_im_stop_send_typed_timeout(im); | 2453 purple_conv_im_stop_send_typed_timeout(im); |
| 2402 | 2454 |
| 2403 serv_send_typing(purple_conversation_get_gc(conv), | 2455 serv_send_typing(purple_conversation_get_connection(conv), |
| 2404 purple_conversation_get_name(conv), | 2456 purple_conversation_get_name(conv), |
| 2405 PURPLE_NOT_TYPING); | 2457 PURPLE_NOT_TYPING); |
| 2406 } | 2458 } |
| 2407 else { | 2459 else { |
| 2408 /* We're deleting, but not all of it, so it counts as typing. */ | 2460 /* We're deleting, but not all of it, so it counts as typing. */ |
| 2448 | 2500 |
| 2449 /* Use the buddy icon, if possible */ | 2501 /* Use the buddy icon, if possible */ |
| 2450 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 2502 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 2451 PurpleBuddy *b = purple_find_buddy(account, name); | 2503 PurpleBuddy *b = purple_find_buddy(account, name); |
| 2452 if (b != NULL) { | 2504 if (b != NULL) { |
| 2453 PurplePresence *p = purple_buddy_get_presence(b); | 2505 PurplePresence *p; |
| 2506 p = purple_buddy_get_presence(b); | |
| 2454 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY)) | 2507 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY)) |
| 2455 return away_list; | 2508 return away_list; |
| 2456 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE)) | 2509 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE)) |
| 2457 return busy_list; | 2510 return busy_list; |
| 2458 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY)) | 2511 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY)) |
| 2562 return; | 2615 return; |
| 2563 | 2616 |
| 2564 status = infopane_status = pidgin_conv_get_icon_stock(conv); | 2617 status = infopane_status = pidgin_conv_get_icon_stock(conv); |
| 2565 | 2618 |
| 2566 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 2619 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 2567 PurpleBuddy *b = purple_find_buddy(conv->account, conv->name); | 2620 PurpleBuddy *b = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); |
| 2568 if (b) | 2621 if (b) |
| 2569 emblem = pidgin_blist_get_emblem((PurpleBlistNode*)b); | 2622 emblem = pidgin_blist_get_emblem((PurpleBlistNode*)b); |
| 2570 } | 2623 } |
| 2571 | 2624 |
| 2572 g_return_if_fail(status != NULL); | 2625 g_return_if_fail(status != NULL); |
| 2583 CONV_EMBLEM_COLUMN, emblem, -1); | 2636 CONV_EMBLEM_COLUMN, emblem, -1); |
| 2584 if (emblem) | 2637 if (emblem) |
| 2585 g_object_unref(emblem); | 2638 g_object_unref(emblem); |
| 2586 | 2639 |
| 2587 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) { | 2640 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) { |
| 2588 emblem = pidgin_create_prpl_icon(gtkconv->active_conv->account, PIDGIN_PRPL_ICON_SMALL); | 2641 emblem = pidgin_create_prpl_icon(purple_conversation_get_account(gtkconv->active_conv), PIDGIN_PRPL_ICON_SMALL); |
| 2589 } else { | 2642 } else { |
| 2590 emblem = NULL; | 2643 emblem = NULL; |
| 2591 } | 2644 } |
| 2592 | 2645 |
| 2593 gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), | 2646 gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), |
| 2639 int size; | 2692 int size; |
| 2640 | 2693 |
| 2641 gtkconv = PIDGIN_CONVERSATION(conv); | 2694 gtkconv = PIDGIN_CONVERSATION(conv); |
| 2642 account = purple_conversation_get_account(conv); | 2695 account = purple_conversation_get_account(conv); |
| 2643 | 2696 |
| 2644 if (!(account && account->gc)) { | 2697 if (!(account && purple_account_get_connection(account))) { |
| 2645 gtkconv->u.im->icon_timer = 0; | 2698 gtkconv->u.im->icon_timer = 0; |
| 2646 return FALSE; | 2699 return FALSE; |
| 2647 } | 2700 } |
| 2648 | 2701 |
| 2649 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); | 2702 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); |
| 2684 | 2737 |
| 2685 return FALSE; | 2738 return FALSE; |
| 2686 } | 2739 } |
| 2687 | 2740 |
| 2688 static void | 2741 static void |
| 2689 start_anim(GtkWidget *widget, PidginConversation *gtkconv) | 2742 start_anim(GtkObject *obj, PidginConversation *gtkconv) |
| 2690 { | 2743 { |
| 2691 int delay; | 2744 int delay; |
| 2692 | 2745 |
| 2693 if (gtkconv->u.im->anim == NULL) | 2746 if (gtkconv->u.im->anim == NULL) |
| 2694 return; | 2747 return; |
| 2846 | 2899 |
| 2847 g_return_if_fail(conv != NULL); | 2900 g_return_if_fail(conv != NULL); |
| 2848 | 2901 |
| 2849 ext = purple_buddy_icon_get_extension(purple_conv_im_get_icon(PURPLE_CONV_IM(conv))); | 2902 ext = purple_buddy_icon_get_extension(purple_conv_im_get_icon(PURPLE_CONV_IM(conv))); |
| 2850 | 2903 |
| 2851 buf = g_strdup_printf("%s.%s", purple_normalize(conv->account, conv->name), ext); | 2904 buf = g_strdup_printf("%s.%s", purple_normalize(purple_conversation_get_account(conv), purple_conversation_get_name(conv)), ext); |
| 2852 | 2905 |
| 2853 purple_request_file(gtkconv, _("Save Icon"), buf, TRUE, | 2906 purple_request_file(gtkconv, _("Save Icon"), buf, TRUE, |
| 2854 G_CALLBACK(saveicon_writefile_cb), NULL, | 2907 G_CALLBACK(saveicon_writefile_cb), NULL, |
| 2855 conv->account, NULL, conv, | 2908 purple_conversation_get_account(conv), NULL, conv, |
| 2856 gtkconv); | 2909 gtkconv); |
| 2857 | 2910 |
| 2858 g_free(buf); | 2911 g_free(buf); |
| 2859 } | 2912 } |
| 2860 | 2913 |
| 2861 static void | 2914 static void |
| 2862 stop_anim(GtkWidget *widget, PidginConversation *gtkconv) | 2915 stop_anim(GtkObject *obj, PidginConversation *gtkconv) |
| 2863 { | 2916 { |
| 2864 if (gtkconv->u.im->icon_timer != 0) | 2917 if (gtkconv->u.im->icon_timer != 0) |
| 2865 g_source_remove(gtkconv->u.im->icon_timer); | 2918 g_source_remove(gtkconv->u.im->icon_timer); |
| 2866 | 2919 |
| 2867 gtkconv->u.im->icon_timer = 0; | 2920 gtkconv->u.im->icon_timer = 0; |
| 2879 else | 2932 else |
| 2880 stop_anim(NULL, gtkconv); | 2933 stop_anim(NULL, gtkconv); |
| 2881 } | 2934 } |
| 2882 | 2935 |
| 2883 static gboolean | 2936 static gboolean |
| 2884 icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) | 2937 icon_menu(GtkObject *obj, GdkEventButton *e, PidginConversation *gtkconv) |
| 2885 { | 2938 { |
| 2886 static GtkWidget *menu = NULL; | 2939 static GtkWidget *menu = NULL; |
| 2887 PurpleConversation *conv; | 2940 PurpleConversation *conv; |
| 2888 PurpleBuddy *buddy; | 2941 PurpleBuddy *buddy; |
| 2889 | 2942 |
| 3073 { | 3126 { |
| 3074 g_return_val_if_fail(gtkconv != NULL, NULL); | 3127 g_return_val_if_fail(gtkconv != NULL, NULL); |
| 3075 return gtkconv->win; | 3128 return gtkconv->win; |
| 3076 } | 3129 } |
| 3077 | 3130 |
| 3078 #if 1 | |
| 3079 | |
| 3080 static GtkActionEntry menu_entries[] = | 3131 static GtkActionEntry menu_entries[] = |
| 3081 /* TODO: fill out tooltips... */ | 3132 /* TODO: fill out tooltips... */ |
| 3082 { | 3133 { |
| 3083 /* Conversation menu */ | 3134 /* Conversation menu */ |
| 3084 { "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL }, | 3135 { "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL }, |
| 3085 { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) }, | 3136 { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) }, |
| 3137 { "JoinAChat", PIDGIN_STOCK_CHAT, N_("Join a _Chat..."), NULL, NULL, G_CALLBACK(menu_join_chat_cb) }, | |
| 3086 { "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) }, | 3138 { "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) }, |
| 3087 { "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) }, | 3139 { "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) }, |
| 3088 { "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) }, | 3140 { "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) }, |
| 3089 { "ClearScrollback", GTK_STOCK_CLEAR, N_("Clea_r Scrollback"), "<control>L", NULL, G_CALLBACK(menu_clear_cb) }, | 3141 { "ClearScrollback", GTK_STOCK_CLEAR, N_("Clea_r Scrollback"), "<control>L", NULL, G_CALLBACK(menu_clear_cb) }, |
| 3090 | 3142 |
| 3125 static const char *conversation_menu = | 3177 static const char *conversation_menu = |
| 3126 "<ui>" | 3178 "<ui>" |
| 3127 "<menubar name='Conversation'>" | 3179 "<menubar name='Conversation'>" |
| 3128 "<menu action='ConversationMenu'>" | 3180 "<menu action='ConversationMenu'>" |
| 3129 "<menuitem action='NewInstantMessage'/>" | 3181 "<menuitem action='NewInstantMessage'/>" |
| 3182 "<menuitem action='JoinAChat'/>" | |
| 3130 "<separator/>" | 3183 "<separator/>" |
| 3131 "<menuitem action='Find'/>" | 3184 "<menuitem action='Find'/>" |
| 3132 "<menuitem action='ViewLog'/>" | 3185 "<menuitem action='ViewLog'/>" |
| 3133 "<menuitem action='SaveAs'/>" | 3186 "<menuitem action='SaveAs'/>" |
| 3134 "<menuitem action='ClearScrollback'/>" | 3187 "<menuitem action='ClearScrollback'/>" |
| 3166 "<menuitem action='ShowTimestamps'/>" | 3219 "<menuitem action='ShowTimestamps'/>" |
| 3167 "</menu>" | 3220 "</menu>" |
| 3168 "</menubar>" | 3221 "</menubar>" |
| 3169 "</ui>"; | 3222 "</ui>"; |
| 3170 | 3223 |
| 3171 #else | |
| 3172 | |
| 3173 static GtkItemFactoryEntry menu_items[] = | |
| 3174 { | |
| 3175 /* Conversation menu */ | |
| 3176 { N_("/_Conversation"), NULL, NULL, 0, "<Branch>", NULL }, | |
| 3177 | |
| 3178 { N_("/Conversation/New Instant _Message..."), "<CTL>M", menu_new_conv_cb, | |
| 3179 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW }, | |
| 3180 { N_("/Conversation/Join a _Chat..."), NULL, menu_join_chat_cb, | |
| 3181 0, "<StockItem>", PIDGIN_STOCK_CHAT }, | |
| 3182 | |
| 3183 { "/Conversation/sep0", NULL, NULL, 0, "<Separator>", NULL }, | |
| 3184 | |
| 3185 { N_("/Conversation/_Find..."), NULL, menu_find_cb, 0, | |
| 3186 "<StockItem>", GTK_STOCK_FIND }, | |
| 3187 { N_("/Conversation/View _Log"), NULL, menu_view_log_cb, 0, "<Item>", NULL }, | |
| 3188 { N_("/Conversation/_Save As..."), NULL, menu_save_as_cb, 0, | |
| 3189 "<StockItem>", GTK_STOCK_SAVE_AS }, | |
| 3190 { N_("/Conversation/Clea_r Scrollback"), "<CTL>L", menu_clear_cb, 0, "<StockItem>", GTK_STOCK_CLEAR }, | |
| 3191 | |
| 3192 { "/Conversation/sep1", NULL, NULL, 0, "<Separator>", NULL }, | |
| 3193 | |
| 3194 #ifdef USE_VV | |
| 3195 { N_("/Conversation/M_edia"), NULL, NULL, 0, "<Branch>", NULL }, | |
| 3196 | |
| 3197 { N_("/Conversation/Media/_Audio Call"), NULL, menu_initiate_media_call_cb, 0, | |
| 3198 "<StockItem>", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL }, | |
| 3199 { N_("/Conversation/Media/_Video Call"), NULL, menu_initiate_media_call_cb, 1, | |
| 3200 "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL }, | |
| 3201 { N_("/Conversation/Media/Audio\\/Video _Call"), NULL, menu_initiate_media_call_cb, 2, | |
| 3202 "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL }, | |
| 3203 #endif | |
| 3204 | |
| 3205 { N_("/Conversation/Se_nd File..."), NULL, menu_send_file_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_FILE }, | |
| 3206 { N_("/Conversation/Get _Attention"), NULL, menu_get_attention_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION }, | |
| 3207 { N_("/Conversation/Add Buddy _Pounce..."), NULL, menu_add_pounce_cb, | |
| 3208 0, "<Item>", NULL }, | |
| 3209 { N_("/Conversation/_Get Info"), "<CTL>O", menu_get_info_cb, 0, | |
| 3210 "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO }, | |
| 3211 { N_("/Conversation/In_vite..."), NULL, menu_invite_cb, 0, | |
| 3212 "<Item>", NULL }, | |
| 3213 { N_("/Conversation/M_ore"), NULL, NULL, 0, "<Branch>", NULL }, | |
| 3214 | |
| 3215 { "/Conversation/sep2", NULL, NULL, 0, "<Separator>", NULL }, | |
| 3216 | |
| 3217 { N_("/Conversation/Al_ias..."), NULL, menu_alias_cb, 0, | |
| 3218 "<Item>", NULL }, | |
| 3219 { N_("/Conversation/_Block..."), NULL, menu_block_cb, 0, | |
| 3220 "<StockItem>", PIDGIN_STOCK_TOOLBAR_BLOCK }, | |
| 3221 { N_("/Conversation/_Unblock..."), NULL, menu_unblock_cb, 0, | |
| 3222 "<StockItem>", PIDGIN_STOCK_TOOLBAR_UNBLOCK }, | |
| 3223 { N_("/Conversation/_Add..."), NULL, menu_add_remove_cb, 0, | |
| 3224 "<StockItem>", GTK_STOCK_ADD }, | |
| 3225 { N_("/Conversation/_Remove..."), NULL, menu_add_remove_cb, 0, | |
| 3226 "<StockItem>", GTK_STOCK_REMOVE }, | |
| 3227 | |
| 3228 { "/Conversation/sep3", NULL, NULL, 0, "<Separator>", NULL }, | |
| 3229 | |
| 3230 { N_("/Conversation/Insert Lin_k..."), NULL, menu_insert_link_cb, 0, | |
| 3231 "<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_LINK }, | |
| 3232 { N_("/Conversation/Insert Imag_e..."), NULL, menu_insert_image_cb, 0, | |
| 3233 "<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE }, | |
| 3234 | |
| 3235 { "/Conversation/sep4", NULL, NULL, 0, "<Separator>", NULL }, | |
| 3236 | |
| 3237 | |
| 3238 { N_("/Conversation/_Close"), NULL, menu_close_conv_cb, 0, | |
| 3239 "<StockItem>", GTK_STOCK_CLOSE }, | |
| 3240 | |
| 3241 /* Options */ | |
| 3242 { N_("/_Options"), NULL, NULL, 0, "<Branch>", NULL }, | |
| 3243 { N_("/Options/Enable _Logging"), NULL, menu_logging_cb, 0, "<CheckItem>", NULL }, | |
| 3244 { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL }, | |
| 3245 { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL }, | |
| 3246 { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL }, | |
| 3247 { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL }, | |
| 3248 }; | |
| 3249 #endif | |
| 3250 | |
| 3251 static void | 3224 static void |
| 3252 sound_method_pref_changed_cb(const char *name, PurplePrefType type, | 3225 sound_method_pref_changed_cb(const char *name, PurplePrefType type, |
| 3253 gconstpointer value, gpointer data) | 3226 gconstpointer value, gpointer data) |
| 3254 { | 3227 { |
| 3255 PidginWindow *win = data; | 3228 PidginWindow *win = data; |
| 3276 static gboolean | 3249 static gboolean |
| 3277 populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolean all) | 3250 populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolean all) |
| 3278 { | 3251 { |
| 3279 GList *list; | 3252 GList *list; |
| 3280 PurpleConversation *conv; | 3253 PurpleConversation *conv; |
| 3254 PurpleAccount *account; | |
| 3281 PurpleBlistNode *node = NULL; | 3255 PurpleBlistNode *node = NULL; |
| 3282 PurpleChat *chat = NULL; | 3256 PurpleChat *chat = NULL; |
| 3283 PurpleBuddy *buddy = NULL; | 3257 PurpleBuddy *buddy = NULL; |
| 3284 gboolean ret; | 3258 gboolean ret; |
| 3285 | 3259 |
| 3286 conv = gtkconv->active_conv; | 3260 conv = gtkconv->active_conv; |
| 3261 account = purple_conversation_get_account(conv); | |
| 3287 | 3262 |
| 3288 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 3263 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
| 3289 chat = purple_blist_find_chat(conv->account, conv->name); | 3264 chat = purple_blist_find_chat(account, purple_conversation_get_name(conv)); |
| 3290 | 3265 |
| 3291 if ((chat == NULL) && (gtkconv->imhtml != NULL)) { | 3266 if ((chat == NULL) && (gtkconv->webview != NULL)) { |
| 3292 chat = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat"); | 3267 chat = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_chat"); |
| 3293 } | 3268 } |
| 3294 | 3269 |
| 3295 if ((chat == NULL) && (gtkconv->imhtml != NULL)) { | 3270 if ((chat == NULL) && (gtkconv->webview != NULL)) { |
| 3296 GHashTable *components; | 3271 GHashTable *components; |
| 3297 PurpleAccount *account = purple_conversation_get_account(conv); | 3272 PurpleAccount *account = purple_conversation_get_account(conv); |
| 3298 PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account)); | 3273 PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account)); |
| 3299 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); | 3274 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); |
| 3300 if (purple_account_get_connection(account) != NULL && | 3275 if (purple_account_get_connection(account) != NULL && |
| 3305 components = g_hash_table_new_full(g_str_hash, g_str_equal, | 3280 components = g_hash_table_new_full(g_str_hash, g_str_equal, |
| 3306 g_free, g_free); | 3281 g_free, g_free); |
| 3307 g_hash_table_replace(components, g_strdup("channel"), | 3282 g_hash_table_replace(components, g_strdup("channel"), |
| 3308 g_strdup(purple_conversation_get_name(conv))); | 3283 g_strdup(purple_conversation_get_name(conv))); |
| 3309 } | 3284 } |
| 3310 chat = purple_chat_new(conv->account, NULL, components); | 3285 chat = purple_chat_new(account, NULL, components); |
| 3311 purple_blist_node_set_flags((PurpleBlistNode *)chat, | 3286 purple_blist_node_set_flags((PurpleBlistNode *)chat, |
| 3312 PURPLE_BLIST_NODE_FLAG_NO_SAVE); | 3287 PURPLE_BLIST_NODE_FLAG_NO_SAVE); |
| 3313 g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_chat", | 3288 g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_chat", |
| 3314 chat, (GDestroyNotify)purple_blist_remove_chat); | 3289 chat, (GDestroyNotify)purple_blist_remove_chat); |
| 3315 } | 3290 } |
| 3316 } else { | 3291 } else { |
| 3317 if (!purple_account_is_connected(conv->account)) | 3292 if (!purple_account_is_connected(account)) |
| 3318 return FALSE; | 3293 return FALSE; |
| 3319 | 3294 |
| 3320 buddy = purple_find_buddy(conv->account, conv->name); | 3295 buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); |
| 3321 | 3296 |
| 3322 /* gotta remain bug-compatible :( libpurple < 2.0.2 didn't handle | 3297 /* gotta remain bug-compatible :( libpurple < 2.0.2 didn't handle |
| 3323 * removing "isolated" buddy nodes well */ | 3298 * removing "isolated" buddy nodes well */ |
| 3324 if (purple_version_check(2, 0, 2) == NULL) { | 3299 if (purple_version_check(2, 0, 2) == NULL) { |
| 3325 if ((buddy == NULL) && (gtkconv->imhtml != NULL)) { | 3300 if ((buddy == NULL) && (gtkconv->webview != NULL)) { |
| 3326 buddy = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy"); | 3301 buddy = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy"); |
| 3327 } | 3302 } |
| 3328 | 3303 |
| 3329 if ((buddy == NULL) && (gtkconv->imhtml != NULL)) { | 3304 if ((buddy == NULL) && (gtkconv->webview != NULL)) { |
| 3330 buddy = purple_buddy_new(conv->account, conv->name, NULL); | 3305 buddy = purple_buddy_new(account, purple_conversation_get_name(conv), NULL); |
| 3331 purple_blist_node_set_flags((PurpleBlistNode *)buddy, | 3306 purple_blist_node_set_flags((PurpleBlistNode *)buddy, |
| 3332 PURPLE_BLIST_NODE_FLAG_NO_SAVE); | 3307 PURPLE_BLIST_NODE_FLAG_NO_SAVE); |
| 3333 g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_buddy", | 3308 g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_buddy", |
| 3334 buddy, (GDestroyNotify)purple_buddy_destroy); | 3309 buddy, (GDestroyNotify)purple_buddy_destroy); |
| 3335 } | 3310 } |
| 3336 } | 3311 } |
| 3337 } | 3312 } |
| 3338 | 3313 |
| 3347 pidgin_blist_make_buddy_menu(menu, buddy, TRUE); | 3322 pidgin_blist_make_buddy_menu(menu, buddy, TRUE); |
| 3348 else if (chat) { | 3323 else if (chat) { |
| 3349 /* XXX: */ | 3324 /* XXX: */ |
| 3350 } | 3325 } |
| 3351 } else if (node) { | 3326 } else if (node) { |
| 3352 if (purple_account_is_connected(conv->account)) | 3327 if (purple_account_is_connected(account)) |
| 3353 pidgin_append_blist_node_proto_menu(menu, conv->account->gc, node); | 3328 pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(account), node); |
| 3354 pidgin_append_blist_node_extended_menu(menu, node); | 3329 pidgin_append_blist_node_extended_menu(menu, node); |
| 3355 } | 3330 } |
| 3356 | 3331 |
| 3357 if ((list = gtk_container_get_children(GTK_CONTAINER(menu))) == NULL) { | 3332 if ((list = gtk_container_get_children(GTK_CONTAINER(menu))) == NULL) { |
| 3358 ret = FALSE; | 3333 ret = FALSE; |
| 3400 caps & PURPLE_MEDIA_CAPS_AUDIO | 3375 caps & PURPLE_MEDIA_CAPS_AUDIO |
| 3401 ? TRUE : FALSE); | 3376 ? TRUE : FALSE); |
| 3402 gtk_action_set_sensitive(win->video_call, | 3377 gtk_action_set_sensitive(win->video_call, |
| 3403 caps & PURPLE_MEDIA_CAPS_VIDEO | 3378 caps & PURPLE_MEDIA_CAPS_VIDEO |
| 3404 ? TRUE : FALSE); | 3379 ? TRUE : FALSE); |
| 3405 gtk_action_set_sensitive(win->audio_video_call, | 3380 gtk_action_set_sensitive(win->audio_video_call, |
| 3406 caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO | 3381 caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO |
| 3407 ? TRUE : FALSE); | 3382 ? TRUE : FALSE); |
| 3408 } else if (purple_conversation_get_type(conv) | 3383 } else if (purple_conversation_get_type(conv) |
| 3409 == PURPLE_CONV_TYPE_CHAT) { | 3384 == PURPLE_CONV_TYPE_CHAT) { |
| 3410 /* for now, don't care about chats... */ | 3385 /* for now, don't care about chats... */ |
| 3418 } | 3393 } |
| 3419 #endif | 3394 #endif |
| 3420 } | 3395 } |
| 3421 | 3396 |
| 3422 static void | 3397 static void |
| 3398 regenerate_attention_items(PidginWindow *win) | |
| 3399 { | |
| 3400 GtkWidget *menu; | |
| 3401 PurpleConversation *conv; | |
| 3402 PurpleConnection *pc; | |
| 3403 PurplePlugin *prpl = NULL; | |
| 3404 PurplePluginProtocolInfo *prpl_info = NULL; | |
| 3405 GList *list; | |
| 3406 | |
| 3407 conv = pidgin_conv_window_get_active_conversation(win); | |
| 3408 if (!conv) | |
| 3409 return; | |
| 3410 | |
| 3411 /* Remove the previous entries */ | |
| 3412 gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu.get_attention), NULL); | |
| 3413 | |
| 3414 pc = purple_conversation_get_connection(conv); | |
| 3415 if (pc != NULL) | |
| 3416 prpl = purple_connection_get_prpl(pc); | |
| 3417 if (prpl != NULL) | |
| 3418 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); | |
| 3419 | |
| 3420 if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_attention_types)) { | |
| 3421 list = prpl_info->get_attention_types(purple_connection_get_account(pc)); | |
| 3422 | |
| 3423 /* Multiple attention types */ | |
| 3424 if (list && list->next) { | |
| 3425 int index = 0; | |
| 3426 | |
| 3427 menu = gtk_menu_new(); | |
| 3428 while (list) { | |
| 3429 PurpleAttentionType *type; | |
| 3430 GtkWidget *menuitem; | |
| 3431 | |
| 3432 type = list->data; | |
| 3433 | |
| 3434 menuitem = gtk_menu_item_new_with_label(purple_attention_type_get_name(type)); | |
| 3435 g_object_set_data(G_OBJECT(menuitem), "index", GINT_TO_POINTER(index)); | |
| 3436 g_signal_connect(G_OBJECT(menuitem), "activate", | |
| 3437 G_CALLBACK(menu_get_attention_cb), | |
| 3438 win); | |
| 3439 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
| 3440 | |
| 3441 index++; | |
| 3442 list = g_list_delete_link(list, list); | |
| 3443 } | |
| 3444 | |
| 3445 gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu.get_attention), menu); | |
| 3446 gtk_widget_show_all(menu); | |
| 3447 } | |
| 3448 } | |
| 3449 } | |
| 3450 | |
| 3451 static void | |
| 3423 regenerate_options_items(PidginWindow *win) | 3452 regenerate_options_items(PidginWindow *win) |
| 3424 { | 3453 { |
| 3425 GtkWidget *menu; | 3454 GtkWidget *menu; |
| 3426 PidginConversation *gtkconv; | 3455 PidginConversation *gtkconv; |
| 3427 GList *list; | 3456 GList *list; |
| 3428 #if GTK_CHECK_VERSION(2,6,0) | |
| 3429 GtkWidget *more_menu; | 3457 GtkWidget *more_menu; |
| 3430 | 3458 |
| 3431 gtkconv = pidgin_conv_window_get_active_gtkconv(win); | 3459 gtkconv = pidgin_conv_window_get_active_gtkconv(win); |
| 3432 more_menu = gtk_ui_manager_get_widget(win->menu.ui, | 3460 more_menu = gtk_ui_manager_get_widget(win->menu.ui, |
| 3433 "/Conversation/ConversationMenu/MoreMenu"); | 3461 "/Conversation/ConversationMenu/MoreMenu"); |
| 3434 gtk_widget_show(more_menu); | 3462 gtk_widget_show(more_menu); |
| 3435 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(more_menu)); | 3463 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(more_menu)); |
| 3436 #else | |
| 3437 gtkconv = pidgin_conv_window_get_active_gtkconv(win); | |
| 3438 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More")); | |
| 3439 #endif | |
| 3440 | 3464 |
| 3441 /* Remove the previous entries */ | 3465 /* Remove the previous entries */ |
| 3442 for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; ) | 3466 for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; ) |
| 3443 { | 3467 { |
| 3444 GtkWidget *w = list->data; | 3468 GtkWidget *w = list->data; |
| 3490 G_CALLBACK(remove_from_list), win); | 3514 G_CALLBACK(remove_from_list), win); |
| 3491 gtk_widget_destroy(action_items->data); | 3515 gtk_widget_destroy(action_items->data); |
| 3492 action_items = g_list_delete_link(action_items, action_items); | 3516 action_items = g_list_delete_link(action_items, action_items); |
| 3493 } | 3517 } |
| 3494 | 3518 |
| 3495 #if GTK_CHECK_VERSION(2,6,0) | |
| 3496 item = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/OptionsMenu"); | 3519 item = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/OptionsMenu"); |
| 3497 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(item)); | 3520 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(item)); |
| 3498 #else | |
| 3499 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options")); | |
| 3500 #endif | |
| 3501 | 3521 |
| 3502 list = purple_conversation_get_extended_menu(conv); | 3522 list = purple_conversation_get_extended_menu(conv); |
| 3503 if (list) { | 3523 if (list) { |
| 3504 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu))); | 3524 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu))); |
| 3505 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); | 3525 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); |
| 3519 { | 3539 { |
| 3520 PidginWindow *win = data; | 3540 PidginWindow *win = data; |
| 3521 regenerate_media_items(win); | 3541 regenerate_media_items(win); |
| 3522 regenerate_options_items(win); | 3542 regenerate_options_items(win); |
| 3523 regenerate_plugins_items(win); | 3543 regenerate_plugins_items(win); |
| 3544 regenerate_attention_items(win); | |
| 3524 | 3545 |
| 3525 /* The following are to make sure the 'More' submenu is not regenerated every time | 3546 /* The following are to make sure the 'More' submenu is not regenerated every time |
| 3526 * the focus shifts from 'Conversations' to some other menu and back. */ | 3547 * the focus shifts from 'Conversations' to some other menu and back. */ |
| 3527 g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data); | 3548 g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data); |
| 3528 g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), data); | 3549 g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), data); |
| 3604 | 3625 |
| 3605 win->menu.send_file = | 3626 win->menu.send_file = |
| 3606 gtk_ui_manager_get_action(win->menu.ui, | 3627 gtk_ui_manager_get_action(win->menu.ui, |
| 3607 "/Conversation/ConversationMenu/SendFile"); | 3628 "/Conversation/ConversationMenu/SendFile"); |
| 3608 | 3629 |
| 3609 g_object_set_data(G_OBJECT(win->window), "get_attention", | 3630 win->menu.get_attention = |
| 3610 gtk_ui_manager_get_action(win->menu.ui, | 3631 gtk_ui_manager_get_action(win->menu.ui, |
| 3611 "/Conversation/ConversationMenu/GetAttention")); | 3632 "/Conversation/ConversationMenu/GetAttention"); |
| 3612 | 3633 |
| 3613 win->menu.add_pounce = | 3634 win->menu.add_pounce = |
| 3614 gtk_ui_manager_get_action(win->menu.ui, | 3635 gtk_ui_manager_get_action(win->menu.ui, |
| 3615 "/Conversation/ConversationMenu/AddBuddyPounce"); | 3636 "/Conversation/ConversationMenu/AddBuddyPounce"); |
| 3616 | 3637 |
| 3716 /* Check if we need to send another PURPLE_TYPING message */ | 3737 /* Check if we need to send another PURPLE_TYPING message */ |
| 3717 if (first || (purple_conv_im_get_type_again(im) != 0 && | 3738 if (first || (purple_conv_im_get_type_again(im) != 0 && |
| 3718 time(NULL) > purple_conv_im_get_type_again(im))) | 3739 time(NULL) > purple_conv_im_get_type_again(im))) |
| 3719 { | 3740 { |
| 3720 unsigned int timeout; | 3741 unsigned int timeout; |
| 3721 timeout = serv_send_typing(purple_conversation_get_gc(conv), | 3742 timeout = serv_send_typing(purple_conversation_get_connection(conv), |
| 3722 purple_conversation_get_name(conv), | 3743 purple_conversation_get_name(conv), |
| 3723 PURPLE_TYPING); | 3744 PURPLE_TYPING); |
| 3724 purple_conv_im_set_type_again(im, timeout); | 3745 purple_conv_im_set_type_again(im, timeout); |
| 3725 } | 3746 } |
| 3726 } | 3747 } |
| 3752 case 4: | 3773 case 4: |
| 3753 stock_id = PIDGIN_STOCK_ANIMATION_TYPING4; | 3774 stock_id = PIDGIN_STOCK_ANIMATION_TYPING4; |
| 3754 break; | 3775 break; |
| 3755 } | 3776 } |
| 3756 if (gtkwin->menu.typing_icon == NULL) { | 3777 if (gtkwin->menu.typing_icon == NULL) { |
| 3757 gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU); | 3778 gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU); |
| 3758 pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray), | 3779 pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray), |
| 3759 gtkwin->menu.typing_icon, | 3780 gtkwin->menu.typing_icon, |
| 3760 _("User is typing...")); | 3781 _("User is typing...")); |
| 3761 } else { | 3782 } else { |
| 3762 gtk_image_set_from_stock(GTK_IMAGE(gtkwin->menu.typing_icon), stock_id, GTK_ICON_SIZE_MENU); | 3783 gtk_image_set_from_stock(GTK_IMAGE(gtkwin->menu.typing_icon), stock_id, GTK_ICON_SIZE_MENU); |
| 3763 } | 3784 } |
| 3764 gtk_widget_show(gtkwin->menu.typing_icon); | 3785 gtk_widget_show(gtkwin->menu.typing_icon); |
| 3765 return TRUE; | 3786 return TRUE; |
| 3767 #endif | 3788 #endif |
| 3768 | 3789 |
| 3769 static void | 3790 static void |
| 3770 update_typing_message(PidginConversation *gtkconv, const char *message) | 3791 update_typing_message(PidginConversation *gtkconv, const char *message) |
| 3771 { | 3792 { |
| 3793 /* TODO WEBKIT: this is not handled at all */ | |
| 3794 #if 0 | |
| 3772 GtkTextBuffer *buffer; | 3795 GtkTextBuffer *buffer; |
| 3773 GtkTextMark *stmark, *enmark; | 3796 GtkTextMark *stmark, *enmark; |
| 3774 | 3797 |
| 3775 if (g_object_get_data(G_OBJECT(gtkconv->imhtml), "disable-typing-notification")) | 3798 if (g_object_get_data(G_OBJECT(gtkconv->imhtml), "disable-typing-notification")) |
| 3776 return; | 3799 return; |
| 3799 gtk_text_buffer_create_mark(buffer, "typing-notification-start", &iter, TRUE); | 3822 gtk_text_buffer_create_mark(buffer, "typing-notification-start", &iter, TRUE); |
| 3800 gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, message, -1, "TYPING-NOTIFICATION", NULL); | 3823 gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, message, -1, "TYPING-NOTIFICATION", NULL); |
| 3801 gtk_text_buffer_get_end_iter(buffer, &iter); | 3824 gtk_text_buffer_get_end_iter(buffer, &iter); |
| 3802 gtk_text_buffer_create_mark(buffer, "typing-notification-end", &iter, TRUE); | 3825 gtk_text_buffer_create_mark(buffer, "typing-notification-end", &iter, TRUE); |
| 3803 } | 3826 } |
| 3827 #endif /* if 0 */ | |
| 3804 } | 3828 } |
| 3805 | 3829 |
| 3806 static void | 3830 static void |
| 3807 update_typing_icon(PidginConversation *gtkconv) | 3831 update_typing_icon(PidginConversation *gtkconv) |
| 3808 { | 3832 { |
| 3855 return FALSE; | 3879 return FALSE; |
| 3856 | 3880 |
| 3857 if (win->menu.send_to == NULL) | 3881 if (win->menu.send_to == NULL) |
| 3858 return FALSE; | 3882 return FALSE; |
| 3859 | 3883 |
| 3860 if (!(b = purple_find_buddy(account, conv->name))) | 3884 if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv)))) |
| 3861 return FALSE; | 3885 return FALSE; |
| 3862 | 3886 |
| 3863 #if 0 /* TODO */ | |
| 3864 gtk_widget_show(win->menu.send_to); | 3887 gtk_widget_show(win->menu.send_to); |
| 3865 | 3888 |
| 3866 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to)); | 3889 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to)); |
| 3867 | 3890 |
| 3868 for (child = gtk_container_get_children(GTK_CONTAINER(menu)); | 3891 for (child = gtk_container_get_children(GTK_CONTAINER(menu)); |
| 3880 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); | 3903 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); |
| 3881 g_list_free(child); | 3904 g_list_free(child); |
| 3882 break; | 3905 break; |
| 3883 } | 3906 } |
| 3884 } | 3907 } |
| 3885 #endif | |
| 3886 | 3908 |
| 3887 return FALSE; | 3909 return FALSE; |
| 3888 } | 3910 } |
| 3889 | 3911 |
| 3890 static gboolean | 3912 static gboolean |
| 3990 } | 4012 } |
| 3991 | 4013 |
| 3992 static void | 4014 static void |
| 3993 generate_send_to_items(PidginWindow *win) | 4015 generate_send_to_items(PidginWindow *win) |
| 3994 { | 4016 { |
| 3995 #if 0 /* TODO */ | |
| 3996 GtkWidget *menu; | 4017 GtkWidget *menu; |
| 3997 GSList *group = NULL; | 4018 GSList *group = NULL; |
| 3998 GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | 4019 GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
| 3999 PidginConversation *gtkconv; | 4020 PidginConversation *gtkconv; |
| 4000 GSList *l, *buds; | 4021 GSList *l, *buds; |
| 4017 win->menu.send_to, 2); | 4038 win->menu.send_to, 2); |
| 4018 gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu.send_to), menu); | 4039 gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu.send_to), menu); |
| 4019 | 4040 |
| 4020 gtk_widget_show(menu); | 4041 gtk_widget_show(menu); |
| 4021 | 4042 |
| 4022 if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM) { | 4043 if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM) { |
| 4023 buds = purple_find_buddies(gtkconv->active_conv->account, gtkconv->active_conv->name); | 4044 buds = purple_find_buddies(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv)); |
| 4024 | 4045 |
| 4025 if (buds == NULL) | 4046 if (buds == NULL) |
| 4026 { | 4047 { |
| 4027 /* The user isn't on the buddy list. So we don't create any sendto menu. */ | 4048 /* The user isn't on the buddy list. So we don't create any sendto menu. */ |
| 4028 } | 4049 } |
| 4042 | 4063 |
| 4043 if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) | 4064 if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) |
| 4044 continue; | 4065 continue; |
| 4045 | 4066 |
| 4046 account = purple_buddy_get_account(buddy); | 4067 account = purple_buddy_get_account(buddy); |
| 4047 if (purple_account_is_connected(account) || account == gtkconv->active_conv->account) | 4068 /* TODO WEBKIT: (I'm not actually sure if this is webkit-related --Mark Doliner) */ |
| 4069 if (purple_account_is_connected(account) /*|| account == purple_conversation_get_account(gtkconv->active_conv)*/) | |
| 4048 { | 4070 { |
| 4049 /* Use the PurplePresence to get unique buddies. */ | 4071 /* Use the PurplePresence to get unique buddies. */ |
| 4050 PurplePresence *presence = purple_buddy_get_presence(buddy); | 4072 PurplePresence *presence = purple_buddy_get_presence(buddy); |
| 4051 if (!g_list_find_custom(list, presence, (GCompareFunc)compare_buddy_presence)) | 4073 if (!g_list_find_custom(list, presence, (GCompareFunc)compare_buddy_presence)) |
| 4052 list = g_list_prepend(list, presence); | 4074 list = g_list_prepend(list, presence); |
| 4075 gtk_widget_show(win->menu.send_to); | 4097 gtk_widget_show(win->menu.send_to); |
| 4076 /* TODO: This should never be insensitive. Possibly hidden or not. */ | 4098 /* TODO: This should never be insensitive. Possibly hidden or not. */ |
| 4077 if (!group) | 4099 if (!group) |
| 4078 gtk_widget_set_sensitive(win->menu.send_to, FALSE); | 4100 gtk_widget_set_sensitive(win->menu.send_to, FALSE); |
| 4079 update_send_to_selection(win); | 4101 update_send_to_selection(win); |
| 4080 #endif | |
| 4081 } | 4102 } |
| 4082 | 4103 |
| 4083 static const char * | 4104 static const char * |
| 4084 get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvChatBuddyFlags flags) | 4105 get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvChatBuddyFlags flags) |
| 4085 { | 4106 { |
| 4102 } | 4123 } |
| 4103 | 4124 |
| 4104 static void | 4125 static void |
| 4105 deleting_chat_buddy_cb(PurpleConvChatBuddy *cb) | 4126 deleting_chat_buddy_cb(PurpleConvChatBuddy *cb) |
| 4106 { | 4127 { |
| 4107 if (cb->ui_data) { | 4128 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); |
| 4108 GtkTreeRowReference *ref = cb->ui_data; | 4129 |
| 4130 if (ref) { | |
| 4109 gtk_tree_row_reference_free(ref); | 4131 gtk_tree_row_reference_free(ref); |
| 4110 cb->ui_data = NULL; | 4132 purple_conv_chat_cb_set_ui_data(cb, NULL); |
| 4111 } | 4133 } |
| 4112 } | 4134 } |
| 4113 | 4135 |
| 4114 static void | 4136 static void |
| 4115 add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name) | 4137 add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name) |
| 4124 GtkTreePath *newpath; | 4146 GtkTreePath *newpath; |
| 4125 const char *stock; | 4147 const char *stock; |
| 4126 GtkTreeIter iter; | 4148 GtkTreeIter iter; |
| 4127 gboolean is_me = FALSE; | 4149 gboolean is_me = FALSE; |
| 4128 gboolean is_buddy; | 4150 gboolean is_buddy; |
| 4129 gchar *tmp, *alias_key, *name, *alias; | 4151 const gchar *name, *alias; |
| 4152 gchar *tmp, *alias_key; | |
| 4130 PurpleConvChatBuddyFlags flags; | 4153 PurpleConvChatBuddyFlags flags; |
| 4131 GdkColor *color = NULL; | 4154 GdkColor *color = NULL; |
| 4132 | 4155 |
| 4133 alias = cb->alias; | 4156 alias = purple_conv_chat_cb_get_alias(cb); |
| 4134 name = cb->name; | 4157 name = purple_conv_chat_cb_get_name(cb); |
| 4135 flags = cb->flags; | 4158 flags = purple_conv_chat_cb_get_flags(cb); |
| 4136 | 4159 |
| 4137 chat = PURPLE_CONV_CHAT(conv); | 4160 chat = PURPLE_CONV_CHAT(conv); |
| 4138 gtkconv = PIDGIN_CONVERSATION(conv); | 4161 gtkconv = PIDGIN_CONVERSATION(conv); |
| 4139 gtkchat = gtkconv->u.chat; | 4162 gtkchat = gtkconv->u.chat; |
| 4140 gc = purple_conversation_get_gc(conv); | 4163 gc = purple_conversation_get_connection(conv); |
| 4141 | 4164 |
| 4142 if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl))) | 4165 if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)))) |
| 4143 return; | 4166 return; |
| 4144 | 4167 |
| 4145 tm = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | 4168 tm = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); |
| 4146 ls = GTK_LIST_STORE(tm); | 4169 ls = GTK_LIST_STORE(tm); |
| 4147 | 4170 |
| 4148 stock = get_chat_buddy_status_icon(chat, name, flags); | 4171 stock = get_chat_buddy_status_icon(chat, name, flags); |
| 4149 | 4172 |
| 4150 if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name))) | 4173 if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(purple_conversation_get_account(conv), old_name != NULL ? old_name : name))) |
| 4151 is_me = TRUE; | 4174 is_me = TRUE; |
| 4152 | 4175 |
| 4153 is_buddy = cb->buddy; | 4176 is_buddy = purple_conv_chat_cb_is_buddy(cb); |
| 4154 | 4177 |
| 4155 tmp = g_utf8_casefold(alias, -1); | 4178 tmp = g_utf8_casefold(alias, -1); |
| 4156 alias_key = g_utf8_collate_key(tmp, -1); | 4179 alias_key = g_utf8_collate_key(tmp, -1); |
| 4157 g_free(tmp); | 4180 g_free(tmp); |
| 4158 | 4181 |
| 4159 if (is_me) { | 4182 if (is_me) { |
| 4183 #if 0 | |
| 4184 /* TODO WEBKIT: No tags in webkit stuff, yet. */ | |
| 4160 GtkTextTag *tag = gtk_text_tag_table_lookup( | 4185 GtkTextTag *tag = gtk_text_tag_table_lookup( |
| 4161 gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->imhtml)->text_buffer), | 4186 gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->webview)->text_buffer), |
| 4162 "send-name"); | 4187 "send-name"); |
| 4163 g_object_get(tag, "foreground-gdk", &color, NULL); | 4188 g_object_get(tag, "foreground-gdk", &color, NULL); |
| 4189 #endif /* if 0 */ | |
| 4164 } else { | 4190 } else { |
| 4165 GtkTextTag *tag; | 4191 GtkTextTag *tag; |
| 4166 if ((tag = get_buddy_tag(conv, name, 0, FALSE))) | 4192 if ((tag = get_buddy_tag(conv, name, 0, FALSE))) |
| 4167 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL); | 4193 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL); |
| 4168 if ((tag = get_buddy_tag(conv, name, PURPLE_MESSAGE_NICK, FALSE))) | 4194 if ((tag = get_buddy_tag(conv, name, PURPLE_MESSAGE_NICK, FALSE))) |
| 4186 CHAT_USERS_FLAGS_COLUMN, flags, | 4212 CHAT_USERS_FLAGS_COLUMN, flags, |
| 4187 CHAT_USERS_COLOR_COLUMN, color, | 4213 CHAT_USERS_COLOR_COLUMN, color, |
| 4188 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, | 4214 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, |
| 4189 -1); | 4215 -1); |
| 4190 | 4216 |
| 4191 if (cb->ui_data) { | 4217 if (purple_conv_chat_cb_get_ui_data(cb)) { |
| 4192 GtkTreeRowReference *ref = cb->ui_data; | 4218 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); |
| 4193 gtk_tree_row_reference_free(ref); | 4219 gtk_tree_row_reference_free(ref); |
| 4194 } | 4220 } |
| 4195 | 4221 |
| 4196 newpath = gtk_tree_model_get_path(tm, &iter); | 4222 newpath = gtk_tree_model_get_path(tm, &iter); |
| 4197 cb->ui_data = gtk_tree_row_reference_new(tm, newpath); | 4223 purple_conv_chat_cb_set_ui_data(cb, gtk_tree_row_reference_new(tm, newpath)); |
| 4198 gtk_tree_path_free(newpath); | 4224 gtk_tree_path_free(newpath); |
| 4199 | 4225 |
| 4200 if (is_me && color) | 4226 if (is_me && color) |
| 4201 gdk_color_free(color); | 4227 gdk_color_free(color); |
| 4202 g_free(alias_key); | 4228 g_free(alias_key); |
| 4222 * @param name The buddy name or alias or slash command name that we're | 4248 * @param name The buddy name or alias or slash command name that we're |
| 4223 * checking for a match. | 4249 * checking for a match. |
| 4224 */ | 4250 */ |
| 4225 static void | 4251 static void |
| 4226 tab_complete_process_item(int *most_matched, const char *entered, gsize entered_bytes, char **partial, char *nick_partial, | 4252 tab_complete_process_item(int *most_matched, const char *entered, gsize entered_bytes, char **partial, char *nick_partial, |
| 4227 GList **matches, char *name) | 4253 GList **matches, const char *name) |
| 4228 { | 4254 { |
| 4229 memcpy(nick_partial, name, entered_bytes); | 4255 memcpy(nick_partial, name, entered_bytes); |
| 4230 if (purple_utf8_strcasecmp(nick_partial, entered)) | 4256 if (purple_utf8_strcasecmp(nick_partial, entered)) |
| 4231 return; | 4257 return; |
| 4232 | 4258 |
| 4344 int f; | 4370 int f; |
| 4345 | 4371 |
| 4346 /* Users */ | 4372 /* Users */ |
| 4347 for (; l != NULL; l = l->next) { | 4373 for (; l != NULL; l = l->next) { |
| 4348 tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial, | 4374 tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial, |
| 4349 &matches, ((PurpleConvChatBuddy *)l->data)->name); | 4375 &matches, purple_conv_chat_cb_get_name((PurpleConvChatBuddy *)l->data)); |
| 4350 } | 4376 } |
| 4351 | 4377 |
| 4352 | 4378 |
| 4353 /* Aliases */ | 4379 /* Aliases */ |
| 4354 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 4380 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
| 4442 PurpleConversation *conv = gtkconv->active_conv; | 4468 PurpleConversation *conv = gtkconv->active_conv; |
| 4443 PidginChatPane *gtkchat; | 4469 PidginChatPane *gtkchat; |
| 4444 char *new_topic; | 4470 char *new_topic; |
| 4445 const char *current_topic; | 4471 const char *current_topic; |
| 4446 | 4472 |
| 4447 gc = purple_conversation_get_gc(conv); | 4473 gc = purple_conversation_get_connection(conv); |
| 4448 | 4474 |
| 4449 if(!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl))) | 4475 if(!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)))) |
| 4450 return; | 4476 return; |
| 4451 | 4477 |
| 4452 if(prpl_info->set_chat_topic == NULL) | 4478 if(prpl_info->set_chat_topic == NULL) |
| 4453 return; | 4479 return; |
| 4454 | 4480 |
| 4519 static void | 4545 static void |
| 4520 update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection *gc, PurplePluginProtocolInfo *prpl_info) | 4546 update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection *gc, PurplePluginProtocolInfo *prpl_info) |
| 4521 { | 4547 { |
| 4522 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); | 4548 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
| 4523 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); | 4549 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); |
| 4550 PurpleAccount *account = purple_conversation_get_account(conv); | |
| 4524 GtkTreeModel *model; | 4551 GtkTreeModel *model; |
| 4525 char *normalized_name; | 4552 char *normalized_name; |
| 4526 GtkTreeIter iter; | 4553 GtkTreeIter iter; |
| 4527 int f; | 4554 int f; |
| 4528 | 4555 |
| 4533 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->u.chat->list)); | 4560 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->u.chat->list)); |
| 4534 | 4561 |
| 4535 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 4562 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
| 4536 return; | 4563 return; |
| 4537 | 4564 |
| 4538 normalized_name = g_strdup(purple_normalize(conv->account, buddy->name)); | 4565 normalized_name = g_strdup(purple_normalize(account, purple_buddy_get_name(buddy))); |
| 4539 | 4566 |
| 4540 do { | 4567 do { |
| 4541 char *name; | 4568 char *name; |
| 4542 | 4569 |
| 4543 gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1); | 4570 gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1); |
| 4544 | 4571 |
| 4545 if (!strcmp(normalized_name, purple_normalize(conv->account, name))) { | 4572 if (!strcmp(normalized_name, purple_normalize(account, name))) { |
| 4546 const char *alias = name; | 4573 const char *alias = name; |
| 4547 char *tmp; | 4574 char *tmp; |
| 4548 char *alias_key = NULL; | 4575 char *alias_key = NULL; |
| 4549 PurpleBuddy *buddy2; | 4576 PurpleBuddy *buddy2; |
| 4550 | 4577 |
| 4551 if (strcmp(chat->nick, purple_normalize(conv->account, name))) { | 4578 if (strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, name))) { |
| 4552 /* This user is not me, so look into updating the alias. */ | 4579 /* This user is not me, so look into updating the alias. */ |
| 4553 | 4580 |
| 4554 if ((buddy2 = purple_find_buddy(conv->account, name)) != NULL) { | 4581 if ((buddy2 = purple_find_buddy(account, name)) != NULL) { |
| 4555 alias = purple_buddy_get_contact_alias(buddy2); | 4582 alias = purple_buddy_get_contact_alias(buddy2); |
| 4556 } | 4583 } |
| 4557 | 4584 |
| 4558 tmp = g_utf8_casefold(alias, -1); | 4585 tmp = g_utf8_casefold(alias, -1); |
| 4559 alias_key = g_utf8_collate_key(tmp, -1); | 4586 alias_key = g_utf8_collate_key(tmp, -1); |
| 4584 PurplePluginProtocolInfo *prpl_info; | 4611 PurplePluginProtocolInfo *prpl_info; |
| 4585 | 4612 |
| 4586 g_return_if_fail(node != NULL); | 4613 g_return_if_fail(node != NULL); |
| 4587 g_return_if_fail(conv != NULL); | 4614 g_return_if_fail(conv != NULL); |
| 4588 | 4615 |
| 4589 gc = purple_conversation_get_gc(conv); | 4616 gc = purple_conversation_get_connection(conv); |
| 4590 g_return_if_fail(gc != NULL); | 4617 g_return_if_fail(gc != NULL); |
| 4591 g_return_if_fail(gc->prpl != NULL); | 4618 g_return_if_fail(purple_connection_get_prpl(gc) != NULL); |
| 4592 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 4619 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 4593 | 4620 |
| 4594 if (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME) | 4621 if (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME) |
| 4595 return; | 4622 return; |
| 4596 | 4623 |
| 4597 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) | 4624 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) |
| 4607 } | 4634 } |
| 4608 } | 4635 } |
| 4609 else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) | 4636 else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) |
| 4610 update_chat_alias((PurpleBuddy *)node, conv, gc, prpl_info); | 4637 update_chat_alias((PurpleBuddy *)node, conv, gc, prpl_info); |
| 4611 else if (PURPLE_BLIST_NODE_IS_CHAT(node) && | 4638 else if (PURPLE_BLIST_NODE_IS_CHAT(node) && |
| 4612 purple_conversation_get_account(conv) == ((PurpleChat*)node)->account) | 4639 purple_conversation_get_account(conv) == purple_chat_get_account((PurpleChat*)node)) |
| 4613 { | 4640 { |
| 4614 if (old_alias == NULL || g_utf8_collate(old_alias, purple_conversation_get_title(conv)) == 0) | 4641 if (old_alias == NULL || g_utf8_collate(old_alias, purple_conversation_get_title(conv)) == 0) |
| 4615 pidgin_conv_update_fields(conv, PIDGIN_CONV_SET_TITLE); | 4642 pidgin_conv_update_fields(conv, PIDGIN_CONV_SET_TITLE); |
| 4616 } | 4643 } |
| 4617 } | 4644 } |
| 4636 model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list)); | 4663 model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list)); |
| 4637 | 4664 |
| 4638 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 4665 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
| 4639 return; | 4666 return; |
| 4640 | 4667 |
| 4641 normalized_name = g_strdup(purple_normalize(conv->account, buddy->name)); | 4668 normalized_name = g_strdup(purple_normalize(purple_conversation_get_account(conv), purple_buddy_get_name(buddy))); |
| 4642 | 4669 |
| 4643 do { | 4670 do { |
| 4644 char *name; | 4671 char *name; |
| 4645 | 4672 |
| 4646 gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1); | 4673 gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1); |
| 4647 | 4674 |
| 4648 if (!strcmp(normalized_name, purple_normalize(conv->account, name))) { | 4675 if (!strcmp(normalized_name, purple_normalize(purple_conversation_get_account(conv), name))) { |
| 4649 gtk_list_store_set(GTK_LIST_STORE(model), &iter, | 4676 gtk_list_store_set(GTK_LIST_STORE(model), &iter, |
| 4650 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1); | 4677 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1); |
| 4651 g_free(name); | 4678 g_free(name); |
| 4652 break; | 4679 break; |
| 4653 } | 4680 } |
| 4722 GtkTextIter iter; | 4749 GtkTextIter iter; |
| 4723 int lines; | 4750 int lines; |
| 4724 GdkRectangle oneline; | 4751 GdkRectangle oneline; |
| 4725 int height, diff; | 4752 int height, diff; |
| 4726 int pad_top, pad_inside, pad_bottom; | 4753 int pad_top, pad_inside, pad_bottom; |
| 4727 int total_height; | 4754 int total_height = (gtkconv->webview->allocation.height + gtkconv->entry->allocation.height); |
| 4728 int max_height; | 4755 int max_height = total_height / 2; |
| 4729 int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines"); | 4756 int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines"); |
| 4730 int min_height; | 4757 int min_height; |
| 4731 gboolean interior_focus; | 4758 gboolean interior_focus; |
| 4732 int focus_width; | 4759 int focus_width; |
| 4733 GtkAllocation imhtml_allocation; | |
| 4734 GtkAllocation entry_allocation; | |
| 4735 GtkAllocation lower_hbox_allocation; | |
| 4736 | |
| 4737 gtk_widget_get_allocation(gtkconv->imhtml, &imhtml_allocation); | |
| 4738 gtk_widget_get_allocation(gtkconv->entry, &entry_allocation); | |
| 4739 gtk_widget_get_allocation(gtkconv->lower_hbox, &lower_hbox_allocation); | |
| 4740 total_height = imhtml_allocation.height + entry_allocation.height; | |
| 4741 max_height = total_height / 2; | |
| 4742 | 4760 |
| 4743 pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry)); | 4761 pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry)); |
| 4744 pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry)); | 4762 pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry)); |
| 4745 pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry)); | 4763 pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry)); |
| 4746 | 4764 |
| 4770 "focus-line-width", &focus_width, | 4788 "focus-line-width", &focus_width, |
| 4771 NULL); | 4789 NULL); |
| 4772 if (!interior_focus) | 4790 if (!interior_focus) |
| 4773 height += 2 * focus_width; | 4791 height += 2 * focus_width; |
| 4774 | 4792 |
| 4775 diff = height - entry_allocation.height; | 4793 diff = height - gtkconv->entry->allocation.height; |
| 4776 if (ABS(diff) < oneline.height / 2) | 4794 if (ABS(diff) < oneline.height / 2) |
| 4777 return FALSE; | 4795 return FALSE; |
| 4778 | 4796 |
| 4779 purple_debug_info("pidgin", "resizing to %d, %d lines, diff %d\n", | |
| 4780 diff + lower_hbox_allocation.height, min_lines, diff); | |
| 4781 | |
| 4782 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, | 4797 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, |
| 4783 diff + lower_hbox_allocation.height); | 4798 diff + gtkconv->lower_hbox->allocation.height); |
| 4784 | 4799 |
| 4785 return FALSE; | 4800 return FALSE; |
| 4786 } | 4801 } |
| 4787 | 4802 |
| 4788 static void | 4803 static void |
| 4806 | 4821 |
| 4807 static void | 4822 static void |
| 4808 setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox) | 4823 setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox) |
| 4809 { | 4824 { |
| 4810 PurpleConversation *conv = gtkconv->active_conv; | 4825 PurpleConversation *conv = gtkconv->active_conv; |
| 4811 PurpleConnection *gc = purple_conversation_get_gc(conv); | 4826 PurpleConnection *gc = purple_conversation_get_connection(conv); |
| 4812 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 4827 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 4813 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) | 4828 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) |
| 4814 { | 4829 { |
| 4815 GtkWidget *hbox, *label; | 4830 GtkWidget *hbox, *label; |
| 4816 PidginChatPane *gtkchat = gtkconv->u.chat; | 4831 PidginChatPane *gtkchat = gtkconv->u.chat; |
| 4817 | 4832 |
| 4825 gtk_widget_set_size_request(gtkchat->topic_text, -1, BUDDYICON_SIZE_MIN); | 4840 gtk_widget_set_size_request(gtkchat->topic_text, -1, BUDDYICON_SIZE_MIN); |
| 4826 | 4841 |
| 4827 if(prpl_info->set_chat_topic == NULL) { | 4842 if(prpl_info->set_chat_topic == NULL) { |
| 4828 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE); | 4843 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE); |
| 4829 } else { | 4844 } else { |
| 4830 g_signal_connect(GTK_WIDGET(gtkchat->topic_text), "activate", | 4845 g_signal_connect(GTK_OBJECT(gtkchat->topic_text), "activate", |
| 4831 G_CALLBACK(topic_callback), gtkconv); | 4846 G_CALLBACK(topic_callback), gtkconv); |
| 4832 } | 4847 } |
| 4833 | 4848 |
| 4834 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); | 4849 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); |
| 4835 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", | 4850 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", |
| 4848 PurpleBlistNode *node; | 4863 PurpleBlistNode *node; |
| 4849 PurplePluginProtocolInfo *prpl_info; | 4864 PurplePluginProtocolInfo *prpl_info; |
| 4850 PurpleAccount *account = purple_conversation_get_account(conv); | 4865 PurpleAccount *account = purple_conversation_get_account(conv); |
| 4851 char *who = NULL; | 4866 char *who = NULL; |
| 4852 | 4867 |
| 4853 if (account->gc == NULL) | 4868 if (purple_account_get_connection(account) == NULL) |
| 4854 return FALSE; | 4869 return FALSE; |
| 4855 | 4870 |
| 4856 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path)) | 4871 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path)) |
| 4857 return FALSE; | 4872 return FALSE; |
| 4858 | 4873 |
| 4859 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); | 4874 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); |
| 4860 | 4875 |
| 4861 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl); | 4876 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(purple_account_get_connection(account))); |
| 4862 node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who)); | 4877 node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), who)); |
| 4863 if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) | 4878 if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) |
| 4864 pidgin_blist_draw_tooltip(node, gtkconv->infopane); | 4879 pidgin_blist_draw_tooltip(node, gtkconv->infopane); |
| 4865 | 4880 |
| 4866 g_free(who); | 4881 g_free(who); |
| 4867 return FALSE; | 4882 return FALSE; |
| 4958 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); | 4973 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); |
| 4959 gtk_widget_show(list); | 4974 gtk_widget_show(list); |
| 4960 | 4975 |
| 4961 gtkchat->list = list; | 4976 gtkchat->list = list; |
| 4962 | 4977 |
| 4963 gtk_box_pack_start(GTK_BOX(lbox), | 4978 gtk_box_pack_start(GTK_BOX(lbox), |
| 4964 pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1), | 4979 pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1), |
| 4965 TRUE, TRUE, 0); | 4980 TRUE, TRUE, 0); |
| 4966 } | 4981 } |
| 4967 | 4982 |
| 4968 static gboolean | 4983 static gboolean |
| 4972 PurpleConversation *conv; | 4987 PurpleConversation *conv; |
| 4973 PidginConversation *gtkconv = userdata; | 4988 PidginConversation *gtkconv = userdata; |
| 4974 | 4989 |
| 4975 conv = gtkconv->active_conv; | 4990 conv = gtkconv->active_conv; |
| 4976 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 4991 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
| 4977 node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name)); | 4992 node = (PurpleBlistNode*)(purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv))); |
| 4978 if (!node) | 4993 if (!node) |
| 4979 node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat"); | 4994 node = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_chat"); |
| 4980 } else { | 4995 } else { |
| 4981 node = (PurpleBlistNode*)(purple_find_buddy(conv->account, conv->name)); | 4996 node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv))); |
| 4982 #if 0 | 4997 #if 0 |
| 4983 /* Using the transient blist nodes to show the tooltip doesn't quite work yet. */ | 4998 /* Using the transient blist nodes to show the tooltip doesn't quite work yet. */ |
| 4984 if (!node) | 4999 if (!node) |
| 4985 node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy"); | 5000 node = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy"); |
| 4986 #endif | 5001 #endif |
| 4987 } | 5002 } |
| 4988 | 5003 |
| 4989 if (node) | 5004 if (node) |
| 4990 pidgin_blist_draw_tooltip(node, gtkconv->infopane); | 5005 pidgin_blist_draw_tooltip(node, gtkconv->infopane); |
| 4995 static gboolean | 5010 static gboolean |
| 4996 pidgin_conv_end_quickfind(PidginConversation *gtkconv) | 5011 pidgin_conv_end_quickfind(PidginConversation *gtkconv) |
| 4997 { | 5012 { |
| 4998 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); | 5013 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); |
| 4999 | 5014 |
| 5000 gtk_imhtml_search_clear(GTK_IMHTML(gtkconv->imhtml)); | 5015 webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview)); |
| 5001 gtk_widget_hide(gtkconv->quickfind.container); | 5016 gtk_widget_hide_all(gtkconv->quickfind.container); |
| 5002 | 5017 |
| 5003 gtk_widget_grab_focus(gtkconv->entry); | 5018 gtk_widget_grab_focus(gtkconv->entry); |
| 5004 return TRUE; | 5019 return TRUE; |
| 5005 } | 5020 } |
| 5006 | 5021 |
| 5007 static gboolean | 5022 static gboolean |
| 5008 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv) | 5023 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv) |
| 5009 { | 5024 { |
| 5010 switch (event->keyval) { | 5025 switch (event->keyval) { |
| 5011 case GDK_KEY_Return: | 5026 case GDK_Return: |
| 5012 case GDK_KEY_KP_Enter: | 5027 case GDK_KP_Enter: |
| 5013 if (gtk_imhtml_search_find(GTK_IMHTML(gtkconv->imhtml), gtk_entry_get_text(GTK_ENTRY(entry)))) { | 5028 if (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) { |
| 5014 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); | 5029 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); |
| 5015 } else { | 5030 } else { |
| 5016 GdkColor col; | 5031 GdkColor col; |
| 5017 col.red = 0xffff; | 5032 col.red = 0xffff; |
| 5018 col.green = 0xafff; | 5033 col.green = 0xafff; |
| 5019 col.blue = 0xafff; | 5034 col.blue = 0xafff; |
| 5020 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col); | 5035 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col); |
| 5021 } | 5036 } |
| 5022 break; | 5037 break; |
| 5023 case GDK_KEY_Escape: | 5038 case GDK_Escape: |
| 5024 pidgin_conv_end_quickfind(gtkconv); | 5039 pidgin_conv_end_quickfind(gtkconv); |
| 5025 break; | 5040 break; |
| 5026 default: | 5041 default: |
| 5027 return FALSE; | 5042 return FALSE; |
| 5028 } | 5043 } |
| 5062 G_CALLBACK(pidgin_conv_end_quickfind), gtkconv); | 5077 G_CALLBACK(pidgin_conv_end_quickfind), gtkconv); |
| 5063 } | 5078 } |
| 5064 | 5079 |
| 5065 /* }}} */ | 5080 /* }}} */ |
| 5066 | 5081 |
| 5082 static char * | |
| 5083 replace_header_tokens(PurpleConversation *conv, const char *text) | |
| 5084 { | |
| 5085 PurpleAccount *account = purple_conversation_get_account(conv); | |
| 5086 GString *str; | |
| 5087 const char *cur = text; | |
| 5088 const char *prev = cur; | |
| 5089 | |
| 5090 if (text == NULL || *text == '\0') | |
| 5091 return NULL; | |
| 5092 | |
| 5093 str = g_string_new(NULL); | |
| 5094 while ((cur = strchr(cur, '%'))) { | |
| 5095 const char *replace = NULL; | |
| 5096 const char *fin = NULL; | |
| 5097 | |
| 5098 if (g_str_has_prefix(cur, "%chatName%")) { | |
| 5099 replace = purple_conversation_get_name(conv); | |
| 5100 | |
| 5101 } else if (g_str_has_prefix(cur, "%sourceName%")) { | |
| 5102 replace = purple_account_get_alias(account); | |
| 5103 if (replace == NULL) | |
| 5104 replace = purple_account_get_username(account); | |
| 5105 | |
| 5106 } else if (g_str_has_prefix(cur, "%destinationName%")) { | |
| 5107 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); | |
| 5108 if (buddy) { | |
| 5109 replace = purple_buddy_get_alias(buddy); | |
| 5110 } else { | |
| 5111 replace = purple_conversation_get_name(conv); | |
| 5112 } | |
| 5113 | |
| 5114 } else if (g_str_has_prefix(cur, "%incomingIconPath%")) { | |
| 5115 PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); | |
| 5116 if (icon) | |
| 5117 replace = purple_buddy_icon_get_full_path(icon); | |
| 5118 | |
| 5119 } else if (g_str_has_prefix(cur, "%outgoingIconPath%")) { | |
| 5120 replace = purple_account_get_buddy_icon_path(account); | |
| 5121 | |
| 5122 } else if (g_str_has_prefix(cur, "%timeOpened")) { | |
| 5123 const char *tmp = cur + strlen("%timeOpened"); | |
| 5124 char *format = NULL; | |
| 5125 if (*tmp == '{') { | |
| 5126 const char *end; | |
| 5127 tmp++; | |
| 5128 end = strstr(tmp, "}%"); | |
| 5129 if (!end) /* Invalid string */ | |
| 5130 continue; | |
| 5131 format = g_strndup(tmp, end - tmp); | |
| 5132 fin = end + 1; | |
| 5133 } | |
| 5134 replace = purple_utf8_strftime(format ? format : "%X", NULL); | |
| 5135 g_free(format); | |
| 5136 | |
| 5137 } else if (g_str_has_prefix(cur, "%dateOpened%")) { | |
| 5138 replace = purple_date_format_short(NULL); | |
| 5139 | |
| 5140 } else { | |
| 5141 cur++; | |
| 5142 continue; | |
| 5143 } | |
| 5144 | |
| 5145 /* Here we have a replacement to make */ | |
| 5146 g_string_append_len(str, prev, cur - prev); | |
| 5147 if (replace) | |
| 5148 g_string_append(str, replace); | |
| 5149 | |
| 5150 /* And update the pointers */ | |
| 5151 if (fin) { | |
| 5152 prev = cur = fin + 1; | |
| 5153 } else { | |
| 5154 prev = cur = strchr(cur + 1, '%') + 1; | |
| 5155 } | |
| 5156 } | |
| 5157 | |
| 5158 /* And wrap it up */ | |
| 5159 g_string_append(str, prev); | |
| 5160 return g_string_free(str, FALSE); | |
| 5161 } | |
| 5162 | |
| 5163 static char * | |
| 5164 replace_template_tokens(PidginConvTheme *theme, const char *header, const char *footer) | |
| 5165 { | |
| 5166 GString *str; | |
| 5167 const char *text; | |
| 5168 char **ms; | |
| 5169 char *path; | |
| 5170 | |
| 5171 text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN); | |
| 5172 if (text == NULL) | |
| 5173 return NULL; | |
| 5174 | |
| 5175 ms = g_strsplit(text, "%@", 6); | |
| 5176 if (ms[0] == NULL || ms[1] == NULL || ms[2] == NULL || ms[3] == NULL || ms[4] == NULL || ms[5] == NULL) { | |
| 5177 g_strfreev(ms); | |
| 5178 return NULL; | |
| 5179 } | |
| 5180 | |
| 5181 str = g_string_new(NULL); | |
| 5182 | |
| 5183 g_string_append(str, ms[0]); | |
| 5184 g_string_append(str, "file://"); | |
| 5185 path = pidgin_conversation_theme_get_template_path(theme); | |
| 5186 g_string_append(str, path); | |
| 5187 g_free(path); | |
| 5188 | |
| 5189 g_string_append(str, ms[1]); | |
| 5190 | |
| 5191 text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_BASESTYLE_CSS); | |
| 5192 g_string_append(str, text); | |
| 5193 | |
| 5194 g_string_append(str, ms[2]); | |
| 5195 | |
| 5196 g_string_append(str, "file://"); | |
| 5197 path = pidgin_conversation_theme_get_css_path(theme); | |
| 5198 g_string_append(str, path); | |
| 5199 g_free(path); | |
| 5200 | |
| 5201 g_string_append(str, ms[3]); | |
| 5202 if (header) | |
| 5203 g_string_append(str, header); | |
| 5204 g_string_append(str, ms[4]); | |
| 5205 if (footer) | |
| 5206 g_string_append(str, footer); | |
| 5207 g_string_append(str, ms[5]); | |
| 5208 | |
| 5209 g_strfreev(ms); | |
| 5210 | |
| 5211 return g_string_free(str, FALSE); | |
| 5212 } | |
| 5213 | |
| 5214 static void | |
| 5215 set_theme_webkit_settings(WebKitWebView *webview, PidginConvTheme *theme) | |
| 5216 { | |
| 5217 WebKitWebSettings *settings; | |
| 5218 const GValue *val; | |
| 5219 | |
| 5220 g_object_get(G_OBJECT(webview), "settings", &settings, NULL); | |
| 5221 | |
| 5222 val = pidgin_conversation_theme_lookup(theme, "DefaultFontFamily", TRUE); | |
| 5223 if (val && G_VALUE_HOLDS_STRING(val)) | |
| 5224 g_object_set(G_OBJECT(settings), "default-font-family", g_value_get_string(val), NULL); | |
| 5225 | |
| 5226 val = pidgin_conversation_theme_lookup(theme, "DefaultFontSize", TRUE); | |
| 5227 if (val && G_VALUE_HOLDS_INT(val)) | |
| 5228 g_object_set(G_OBJECT(settings), "default-font-size", GINT_TO_POINTER(g_value_get_int(val)), NULL); | |
| 5229 | |
| 5230 val = pidgin_conversation_theme_lookup(theme, "DefaultBackgroundIsTransparent", TRUE); | |
| 5231 if (val && G_VALUE_HOLDS_BOOLEAN(val)) | |
| 5232 /* this does not work :( */ | |
| 5233 webkit_web_view_set_transparent(webview, g_value_get_boolean(val)); | |
| 5234 } | |
| 5235 | |
| 5236 static void | |
| 5237 conv_variant_changed_cb(GObject *gobject, GParamSpec *pspec, gpointer user_data) | |
| 5238 { | |
| 5239 PidginConversation *gtkconv = user_data; | |
| 5240 const char *path; | |
| 5241 char *js; | |
| 5242 | |
| 5243 path = pidgin_conversation_theme_get_css_path(PIDGIN_CONV_THEME(gobject)); | |
| 5244 js = g_strdup_printf("setStylesheet(\"mainStyle\", \"file://%s\");", path); | |
| 5245 gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), js); | |
| 5246 g_free(js); | |
| 5247 } | |
| 5248 | |
| 5067 static GtkWidget * | 5249 static GtkWidget * |
| 5068 setup_common_pane(PidginConversation *gtkconv) | 5250 setup_common_pane(PidginConversation *gtkconv) |
| 5069 { | 5251 { |
| 5070 GtkWidget *vbox, *frame, *imhtml_sw, *event_box; | 5252 GtkWidget *vbox, *frame, *webview_sw, *event_box; |
| 5071 GtkCellRenderer *rend; | 5253 GtkCellRenderer *rend; |
| 5072 GtkTreePath *path; | 5254 GtkTreePath *path; |
| 5073 PurpleConversation *conv = gtkconv->active_conv; | 5255 PurpleConversation *conv = gtkconv->active_conv; |
| 5074 PurpleBuddy *buddy; | 5256 PurpleBuddy *buddy; |
| 5075 gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); | 5257 gboolean chat = (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT); |
| 5076 int buddyicon_size = 0; | 5258 int buddyicon_size = 0; |
| 5259 char *header, *footer; | |
| 5260 char *template; | |
| 5077 | 5261 |
| 5078 /* Setup the top part of the pane */ | 5262 /* Setup the top part of the pane */ |
| 5079 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 5263 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| 5080 gtk_widget_show(vbox); | 5264 gtk_widget_show(vbox); |
| 5081 | 5265 |
| 5161 rend = gtk_cell_renderer_pixbuf_new(); | 5345 rend = gtk_cell_renderer_pixbuf_new(); |
| 5162 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE); | 5346 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE); |
| 5163 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_EMBLEM_COLUMN, NULL); | 5347 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_EMBLEM_COLUMN, NULL); |
| 5164 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); | 5348 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); |
| 5165 | 5349 |
| 5166 /* Setup the gtkimhtml widget */ | 5350 /* Setup the webkit widget */ |
| 5167 frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); | 5351 frame = pidgin_create_webview(FALSE, >kconv->webview, NULL, &webview_sw); |
| 5168 gtk_widget_set_size_request(gtkconv->imhtml, -1, 0); | 5352 gtk_widget_set_size_request(gtkconv->webview, -1, 0); |
| 5353 | |
| 5354 header = replace_header_tokens(conv, | |
| 5355 pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_HEADER)); | |
| 5356 footer = replace_header_tokens(conv, | |
| 5357 pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_FOOTER)); | |
| 5358 template = replace_template_tokens(gtkconv->theme, header, footer); | |
| 5359 g_free(header); | |
| 5360 g_free(footer); | |
| 5361 | |
| 5362 if (template != NULL) { | |
| 5363 char *basedir; | |
| 5364 char *baseuri; | |
| 5365 | |
| 5366 purple_debug_info("webkit", "template: %s\n", template); | |
| 5367 | |
| 5368 set_theme_webkit_settings(WEBKIT_WEB_VIEW(gtkconv->webview), gtkconv->theme); | |
| 5369 | |
| 5370 basedir = pidgin_conversation_theme_get_template_path(gtkconv->theme); | |
| 5371 baseuri = g_strdup_printf("file://%s", basedir); | |
| 5372 webkit_web_view_load_string(WEBKIT_WEB_VIEW(gtkconv->webview), template, "text/html", "UTF-8", baseuri); | |
| 5373 | |
| 5374 if (chat) | |
| 5375 gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), "document.getElementById('Chat').className = 'groupchat'"); | |
| 5376 | |
| 5377 g_signal_connect(G_OBJECT(gtkconv->theme), "notify::variant", | |
| 5378 G_CALLBACK(conv_variant_changed_cb), gtkconv); | |
| 5379 | |
| 5380 g_free(basedir); | |
| 5381 g_free(baseuri); | |
| 5382 g_free(template); | |
| 5383 } | |
| 5384 | |
| 5169 if (chat) { | 5385 if (chat) { |
| 5170 GtkWidget *hpaned; | 5386 GtkWidget *hpaned; |
| 5171 | 5387 |
| 5172 /* Add the topic */ | 5388 /* Add the topic */ |
| 5173 setup_chat_topic(gtkconv, vbox); | 5389 setup_chat_topic(gtkconv, vbox); |
| 5181 /* Now add the userlist */ | 5397 /* Now add the userlist */ |
| 5182 setup_chat_userlist(gtkconv, hpaned); | 5398 setup_chat_userlist(gtkconv, hpaned); |
| 5183 } else { | 5399 } else { |
| 5184 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | 5400 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); |
| 5185 } | 5401 } |
| 5186 gtk_widget_show(frame); | 5402 gtk_widget_show_all(frame); |
| 5187 | 5403 |
| 5188 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); | 5404 gtk_widget_set_name(gtkconv->webview, "pidgin_conv_webview"); |
| 5189 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); | 5405 g_object_set_data(G_OBJECT(gtkconv->webview), "gtkconv", gtkconv); |
| 5190 g_object_set_data(G_OBJECT(gtkconv->imhtml), "gtkconv", gtkconv); | 5406 |
| 5191 | 5407 g_signal_connect_after(G_OBJECT(gtkconv->webview), "button_press_event", |
| 5192 g_object_set(G_OBJECT(imhtml_sw), "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL); | |
| 5193 | |
| 5194 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", | |
| 5195 G_CALLBACK(entry_stop_rclick_cb), NULL); | 5408 G_CALLBACK(entry_stop_rclick_cb), NULL); |
| 5196 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", | 5409 g_signal_connect(G_OBJECT(gtkconv->webview), "key_press_event", |
| 5197 G_CALLBACK(refocus_entry_cb), gtkconv); | 5410 G_CALLBACK(refocus_entry_cb), gtkconv); |
| 5198 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", | 5411 g_signal_connect(G_OBJECT(gtkconv->webview), "key_release_event", |
| 5199 G_CALLBACK(refocus_entry_cb), gtkconv); | 5412 G_CALLBACK(refocus_entry_cb), gtkconv); |
| 5200 | 5413 |
| 5201 pidgin_conv_setup_quickfind(gtkconv, vbox); | 5414 pidgin_conv_setup_quickfind(gtkconv, vbox); |
| 5202 | 5415 |
| 5203 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 5416 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| 5209 gtk_box_pack_start(GTK_BOX(gtkconv->lower_hbox), frame, TRUE, TRUE, 0); | 5422 gtk_box_pack_start(GTK_BOX(gtkconv->lower_hbox), frame, TRUE, TRUE, 0); |
| 5210 gtk_widget_show(frame); | 5423 gtk_widget_show(frame); |
| 5211 | 5424 |
| 5212 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); | 5425 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); |
| 5213 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), | 5426 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), |
| 5214 purple_account_get_protocol_name(conv->account)); | 5427 purple_account_get_protocol_name(purple_conversation_get_account(conv))); |
| 5215 | 5428 |
| 5216 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", | 5429 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", |
| 5217 G_CALLBACK(entry_popup_menu_cb), gtkconv); | 5430 G_CALLBACK(entry_popup_menu_cb), gtkconv); |
| 5218 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", | 5431 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", |
| 5219 G_CALLBACK(entry_key_press_cb), gtkconv); | 5432 G_CALLBACK(entry_key_press_cb), gtkconv); |
| 5256 PurpleConversation *conv = gtkconv->active_conv; | 5469 PurpleConversation *conv = gtkconv->active_conv; |
| 5257 PidginWindow *win = gtkconv->win; | 5470 PidginWindow *win = gtkconv->win; |
| 5258 PurpleConversation *c; | 5471 PurpleConversation *c; |
| 5259 PurpleAccount *convaccount = purple_conversation_get_account(conv); | 5472 PurpleAccount *convaccount = purple_conversation_get_account(conv); |
| 5260 PurpleConnection *gc = purple_account_get_connection(convaccount); | 5473 PurpleConnection *gc = purple_account_get_connection(convaccount); |
| 5261 PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL; | 5474 PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL; |
| 5262 GdkAtom target = gtk_selection_data_get_target(sd); | 5475 |
| 5263 const guchar *data = gtk_selection_data_get_data(sd); | 5476 if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) |
| 5264 | |
| 5265 if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) | |
| 5266 { | 5477 { |
| 5267 PurpleBlistNode *n = NULL; | 5478 PurpleBlistNode *n = NULL; |
| 5268 PurpleBuddy *b; | 5479 PurpleBuddy *b; |
| 5269 PidginConversation *gtkconv = NULL; | 5480 PidginConversation *gtkconv = NULL; |
| 5270 PurpleAccount *buddyaccount; | 5481 PurpleAccount *buddyaccount; |
| 5271 const char *buddyname; | 5482 const char *buddyname; |
| 5272 | 5483 |
| 5273 n = *(PurpleBlistNode **) data; | 5484 n = *(PurpleBlistNode **)sd->data; |
| 5274 | 5485 |
| 5275 if (PURPLE_BLIST_NODE_IS_CONTACT(n)) | 5486 if (PURPLE_BLIST_NODE_IS_CONTACT(n)) |
| 5276 b = purple_contact_get_priority_buddy((PurpleContact*)n); | 5487 b = purple_contact_get_priority_buddy((PurpleContact*)n); |
| 5277 else if (PURPLE_BLIST_NODE_IS_BUDDY(n)) | 5488 else if (PURPLE_BLIST_NODE_IS_BUDDY(n)) |
| 5278 b = (PurpleBuddy*)n; | 5489 b = (PurpleBuddy*)n; |
| 5316 | 5527 |
| 5317 /* Make this conversation the active conversation */ | 5528 /* Make this conversation the active conversation */ |
| 5318 pidgin_conv_window_switch_gtkconv(win, gtkconv); | 5529 pidgin_conv_window_switch_gtkconv(win, gtkconv); |
| 5319 } | 5530 } |
| 5320 | 5531 |
| 5321 gtk_drag_finish(dc, TRUE, | 5532 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); |
| 5322 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t); | 5533 } |
| 5323 } | 5534 else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE)) |
| 5324 else if (target == gdk_atom_intern("application/x-im-contact", FALSE)) | |
| 5325 { | 5535 { |
| 5326 char *protocol = NULL; | 5536 char *protocol = NULL; |
| 5327 char *username = NULL; | 5537 char *username = NULL; |
| 5328 PurpleAccount *account; | 5538 PurpleAccount *account; |
| 5329 PidginConversation *gtkconv; | 5539 PidginConversation *gtkconv; |
| 5330 | 5540 |
| 5331 if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account, | 5541 if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, |
| 5332 &protocol, &username, NULL)) | 5542 &protocol, &username, NULL)) |
| 5333 { | 5543 { |
| 5334 if (account == NULL) | 5544 if (account == NULL) |
| 5335 { | 5545 { |
| 5336 purple_notify_error(win, NULL, | 5546 purple_notify_error(win, NULL, |
| 5357 } | 5567 } |
| 5358 | 5568 |
| 5359 g_free(username); | 5569 g_free(username); |
| 5360 g_free(protocol); | 5570 g_free(protocol); |
| 5361 | 5571 |
| 5362 gtk_drag_finish(dc, TRUE, | 5572 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); |
| 5363 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t); | 5573 } |
| 5364 } | 5574 else if (sd->target == gdk_atom_intern("text/uri-list", FALSE)) { |
| 5365 else if (target == gdk_atom_intern("text/uri-list", FALSE)) { | |
| 5366 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) | 5575 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) |
| 5367 pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv)); | 5576 pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv)); |
| 5368 gtk_drag_finish(dc, TRUE, | 5577 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); |
| 5369 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t); | |
| 5370 } | 5578 } |
| 5371 else | 5579 else |
| 5372 gtk_drag_finish(dc, FALSE, FALSE, t); | 5580 gtk_drag_finish(dc, FALSE, FALSE, t); |
| 5373 } | 5581 } |
| 5374 | 5582 |
| 5381 }; | 5589 }; |
| 5382 | 5590 |
| 5383 static PidginConversation * | 5591 static PidginConversation * |
| 5384 pidgin_conv_find_gtkconv(PurpleConversation * conv) | 5592 pidgin_conv_find_gtkconv(PurpleConversation * conv) |
| 5385 { | 5593 { |
| 5386 PurpleBuddy *bud = purple_find_buddy(conv->account, conv->name); | 5594 PurpleBuddy *bud = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); |
| 5387 PurpleContact *c; | 5595 PurpleContact *c; |
| 5388 PurpleBlistNode *cn, *bn; | 5596 PurpleBlistNode *cn, *bn; |
| 5389 | 5597 |
| 5390 if (!bud) | 5598 if (!bud) |
| 5391 return NULL; | 5599 return NULL; |
| 5395 | 5603 |
| 5396 cn = PURPLE_BLIST_NODE(c); | 5604 cn = PURPLE_BLIST_NODE(c); |
| 5397 for (bn = purple_blist_node_get_first_child(cn); bn; bn = purple_blist_node_get_sibling_next(bn)) { | 5605 for (bn = purple_blist_node_get_first_child(cn); bn; bn = purple_blist_node_get_sibling_next(bn)) { |
| 5398 PurpleBuddy *b = PURPLE_BUDDY(bn); | 5606 PurpleBuddy *b = PURPLE_BUDDY(bn); |
| 5399 PurpleConversation *conv; | 5607 PurpleConversation *conv; |
| 5400 if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account))) { | 5608 if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(b), purple_buddy_get_account(b)))) { |
| 5401 if (conv->ui_data) | 5609 if (PIDGIN_CONVERSATION(conv)) |
| 5402 return conv->ui_data; | 5610 return PIDGIN_CONVERSATION(conv); |
| 5403 } | 5611 } |
| 5404 } | 5612 } |
| 5405 | 5613 |
| 5406 return NULL; | 5614 return NULL; |
| 5407 } | 5615 } |
| 5439 return FALSE; | 5647 return FALSE; |
| 5440 } | 5648 } |
| 5441 | 5649 |
| 5442 static void set_typing_font(GtkWidget *widget, GtkStyle *style, PidginConversation *gtkconv) | 5650 static void set_typing_font(GtkWidget *widget, GtkStyle *style, PidginConversation *gtkconv) |
| 5443 { | 5651 { |
| 5652 /* TODO WEBKIT */ | |
| 5653 #if 0 | |
| 5444 static PangoFontDescription *font_desc = NULL; | 5654 static PangoFontDescription *font_desc = NULL; |
| 5445 static GdkColor *color = NULL; | 5655 static GdkColor *color = NULL; |
| 5446 static gboolean enable = TRUE; | 5656 static gboolean enable = TRUE; |
| 5447 | 5657 |
| 5448 if (font_desc == NULL) { | 5658 if (font_desc == NULL) { |
| 5469 g_object_set_data(G_OBJECT(widget), "disable-typing-notification", GINT_TO_POINTER(TRUE)); | 5679 g_object_set_data(G_OBJECT(widget), "disable-typing-notification", GINT_TO_POINTER(TRUE)); |
| 5470 /* or may be 'gtkconv->disable_typing = TRUE;' instead? */ | 5680 /* or may be 'gtkconv->disable_typing = TRUE;' instead? */ |
| 5471 } | 5681 } |
| 5472 | 5682 |
| 5473 g_signal_handlers_disconnect_by_func(G_OBJECT(widget), set_typing_font, gtkconv); | 5683 g_signal_handlers_disconnect_by_func(G_OBJECT(widget), set_typing_font, gtkconv); |
| 5684 #endif /* if 0 */ | |
| 5474 } | 5685 } |
| 5475 | 5686 |
| 5476 /************************************************************************** | 5687 /************************************************************************** |
| 5477 * Conversation UI operations | 5688 * Conversation UI operations |
| 5478 **************************************************************************/ | 5689 **************************************************************************/ |
| 5479 static void | 5690 static void |
| 5480 private_gtkconv_new(PurpleConversation *conv, gboolean hidden) | 5691 private_gtkconv_new(PurpleConversation *conv, gboolean hidden) |
| 5481 { | 5692 { |
| 5482 PidginConversation *gtkconv; | 5693 PidginConversation *gtkconv; |
| 5694 PurpleTheme *theme; | |
| 5483 PurpleConversationType conv_type = purple_conversation_get_type(conv); | 5695 PurpleConversationType conv_type = purple_conversation_get_type(conv); |
| 5484 GtkWidget *pane = NULL; | 5696 GtkWidget *pane = NULL; |
| 5485 GtkWidget *tab_cont; | 5697 GtkWidget *tab_cont; |
| 5486 PurpleBlistNode *convnode; | 5698 PurpleBlistNode *convnode; |
| 5487 PurpleValue *value; | |
| 5488 | 5699 |
| 5489 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) { | 5700 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) { |
| 5490 conv->ui_data = gtkconv; | 5701 purple_conversation_set_ui_data(conv, gtkconv); |
| 5491 if (!g_list_find(gtkconv->convs, conv)) | 5702 if (!g_list_find(gtkconv->convs, conv)) |
| 5492 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); | 5703 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); |
| 5493 pidgin_conv_switch_active_conversation(conv); | 5704 pidgin_conv_switch_active_conversation(conv); |
| 5494 return; | 5705 return; |
| 5495 } | 5706 } |
| 5496 | 5707 |
| 5497 gtkconv = g_new0(PidginConversation, 1); | 5708 gtkconv = g_new0(PidginConversation, 1); |
| 5498 conv->ui_data = gtkconv; | 5709 purple_conversation_set_ui_data(conv, gtkconv); |
| 5499 gtkconv->active_conv = conv; | 5710 gtkconv->active_conv = conv; |
| 5500 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); | 5711 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); |
| 5501 gtkconv->send_history = g_list_append(NULL, NULL); | 5712 gtkconv->send_history = g_list_append(NULL, NULL); |
| 5502 | 5713 |
| 5503 /* Setup some initial variables. */ | 5714 /* Setup some initial variables. */ |
| 5504 #if !GTK_CHECK_VERSION(2,12,0) | 5715 #if !GTK_CHECK_VERSION(2,12,0) |
| 5505 gtkconv->tooltips = gtk_tooltips_new(); | 5716 gtkconv->tooltips = gtk_tooltips_new(); |
| 5506 #endif | 5717 #endif |
| 5507 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; | 5718 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; |
| 5508 gtkconv->unseen_count = 0; | 5719 gtkconv->unseen_count = 0; |
| 5720 theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation"); | |
| 5721 if (!theme) | |
| 5722 theme = purple_theme_manager_find_theme("Default", "conversation"); | |
| 5723 gtkconv->theme = PIDGIN_CONV_THEME(g_object_ref(theme)); | |
| 5724 gtkconv->last_flags = 0; | |
| 5509 | 5725 |
| 5510 if (conv_type == PURPLE_CONV_TYPE_IM) { | 5726 if (conv_type == PURPLE_CONV_TYPE_IM) { |
| 5511 gtkconv->u.im = g_malloc0(sizeof(PidginImPane)); | 5727 gtkconv->u.im = g_malloc0(sizeof(PidginImPane)); |
| 5512 } else if (conv_type == PURPLE_CONV_TYPE_CHAT) { | 5728 } else if (conv_type == PURPLE_CONV_TYPE_CHAT) { |
| 5513 gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane)); | 5729 gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane)); |
| 5514 } | 5730 } |
| 5515 pane = setup_common_pane(gtkconv); | 5731 pane = setup_common_pane(gtkconv); |
| 5516 | |
| 5517 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml), | |
| 5518 gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE); | |
| 5519 | 5732 |
| 5520 if (pane == NULL) { | 5733 if (pane == NULL) { |
| 5521 if (conv_type == PURPLE_CONV_TYPE_CHAT) | 5734 if (conv_type == PURPLE_CONV_TYPE_CHAT) |
| 5522 g_free(gtkconv->u.chat); | 5735 g_free(gtkconv->u.chat); |
| 5523 else if (conv_type == PURPLE_CONV_TYPE_IM) | 5736 else if (conv_type == PURPLE_CONV_TYPE_IM) |
| 5524 g_free(gtkconv->u.im); | 5737 g_free(gtkconv->u.im); |
| 5525 | 5738 |
| 5526 g_free(gtkconv); | 5739 g_free(gtkconv); |
| 5527 conv->ui_data = NULL; | 5740 purple_conversation_set_ui_data(conv, NULL); |
| 5528 return; | 5741 return; |
| 5529 } | 5742 } |
| 5530 | 5743 |
| 5531 /* Setup drag-and-drop */ | 5744 /* Setup drag-and-drop */ |
| 5532 gtk_drag_dest_set(pane, | 5745 gtk_drag_dest_set(pane, |
| 5537 gtk_drag_dest_set(pane, | 5750 gtk_drag_dest_set(pane, |
| 5538 GTK_DEST_DEFAULT_MOTION | | 5751 GTK_DEST_DEFAULT_MOTION | |
| 5539 GTK_DEST_DEFAULT_DROP, | 5752 GTK_DEST_DEFAULT_DROP, |
| 5540 te, sizeof(te) / sizeof(GtkTargetEntry), | 5753 te, sizeof(te) / sizeof(GtkTargetEntry), |
| 5541 GDK_ACTION_COPY); | 5754 GDK_ACTION_COPY); |
| 5542 gtk_drag_dest_set(gtkconv->imhtml, 0, | 5755 gtk_drag_dest_set(gtkconv->webview, 0, |
| 5543 te, sizeof(te) / sizeof(GtkTargetEntry), | 5756 te, sizeof(te) / sizeof(GtkTargetEntry), |
| 5544 GDK_ACTION_COPY); | 5757 GDK_ACTION_COPY); |
| 5545 | 5758 |
| 5546 gtk_drag_dest_set(gtkconv->entry, 0, | 5759 gtk_drag_dest_set(gtkconv->entry, 0, |
| 5547 te, sizeof(te) / sizeof(GtkTargetEntry), | 5760 te, sizeof(te) / sizeof(GtkTargetEntry), |
| 5549 | 5762 |
| 5550 g_signal_connect(G_OBJECT(pane), "button_press_event", | 5763 g_signal_connect(G_OBJECT(pane), "button_press_event", |
| 5551 G_CALLBACK(ignore_middle_click), NULL); | 5764 G_CALLBACK(ignore_middle_click), NULL); |
| 5552 g_signal_connect(G_OBJECT(pane), "drag_data_received", | 5765 g_signal_connect(G_OBJECT(pane), "drag_data_received", |
| 5553 G_CALLBACK(conv_dnd_recv), gtkconv); | 5766 G_CALLBACK(conv_dnd_recv), gtkconv); |
| 5554 g_signal_connect(G_OBJECT(gtkconv->imhtml), "drag_data_received", | 5767 g_signal_connect(G_OBJECT(gtkconv->webview), "drag_data_received", |
| 5555 G_CALLBACK(conv_dnd_recv), gtkconv); | 5768 G_CALLBACK(conv_dnd_recv), gtkconv); |
| 5556 g_signal_connect(G_OBJECT(gtkconv->entry), "drag_data_received", | 5769 g_signal_connect(G_OBJECT(gtkconv->entry), "drag_data_received", |
| 5557 G_CALLBACK(conv_dnd_recv), gtkconv); | 5770 G_CALLBACK(conv_dnd_recv), gtkconv); |
| 5558 | 5771 |
| 5559 g_signal_connect(gtkconv->imhtml, "style-set", G_CALLBACK(set_typing_font), gtkconv); | 5772 g_signal_connect(gtkconv->webview, "style-set", G_CALLBACK(set_typing_font), gtkconv); |
| 5560 | 5773 |
| 5561 /* Setup the container for the tab. */ | 5774 /* Setup the container for the tab. */ |
| 5562 gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 5775 gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| 5563 g_object_set_data(G_OBJECT(tab_cont), "PidginConversation", gtkconv); | 5776 g_object_set_data(G_OBJECT(tab_cont), "PidginConversation", gtkconv); |
| 5564 gtk_container_set_border_width(GTK_CONTAINER(tab_cont), PIDGIN_HIG_BOX_SPACE); | 5777 gtk_container_set_border_width(GTK_CONTAINER(tab_cont), PIDGIN_HIG_BOX_SPACE); |
| 5567 | 5780 |
| 5568 convnode = get_conversation_blist_node(conv); | 5781 convnode = get_conversation_blist_node(conv); |
| 5569 if (convnode == NULL || !purple_blist_node_get_bool(convnode, "gtk-mute-sound")) | 5782 if (convnode == NULL || !purple_blist_node_get_bool(convnode, "gtk-mute-sound")) |
| 5570 gtkconv->make_sound = TRUE; | 5783 gtkconv->make_sound = TRUE; |
| 5571 | 5784 |
| 5572 if (convnode != NULL && | 5785 if (convnode != NULL) { |
| 5573 (value = g_hash_table_lookup(convnode->settings, "enable-logging")) && | 5786 gboolean logging = purple_blist_node_get_bool(convnode, "enable-logging"); |
| 5574 purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN) | 5787 purple_conversation_set_logging(conv, logging); |
| 5575 { | |
| 5576 purple_conversation_set_logging(conv, purple_value_get_boolean(value)); | |
| 5577 } | 5788 } |
| 5578 | 5789 |
| 5579 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")) | 5790 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")) |
| 5580 gtk_widget_show(gtkconv->toolbar); | 5791 gtk_widget_show(gtkconv->toolbar); |
| 5581 else | 5792 else |
| 5584 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons")) | 5795 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons")) |
| 5585 gtk_widget_show(gtkconv->infopane_hbox); | 5796 gtk_widget_show(gtkconv->infopane_hbox); |
| 5586 else | 5797 else |
| 5587 gtk_widget_hide(gtkconv->infopane_hbox); | 5798 gtk_widget_hide(gtkconv->infopane_hbox); |
| 5588 | 5799 |
| 5589 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), | |
| 5590 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps")); | |
| 5591 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), | |
| 5592 purple_account_get_protocol_name(conv->account)); | |
| 5593 | 5800 |
| 5594 g_signal_connect_swapped(G_OBJECT(pane), "focus", | 5801 g_signal_connect_swapped(G_OBJECT(pane), "focus", |
| 5595 G_CALLBACK(gtk_widget_grab_focus), | 5802 G_CALLBACK(gtk_widget_grab_focus), |
| 5596 gtkconv->entry); | 5803 gtkconv->entry); |
| 5597 | 5804 |
| 5600 else | 5807 else |
| 5601 pidgin_conv_placement_place(gtkconv); | 5808 pidgin_conv_placement_place(gtkconv); |
| 5602 | 5809 |
| 5603 if (nick_colors == NULL) { | 5810 if (nick_colors == NULL) { |
| 5604 nbr_nick_colors = NUM_NICK_COLORS; | 5811 nbr_nick_colors = NUM_NICK_COLORS; |
| 5605 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); | 5812 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->webview)->base[GTK_STATE_NORMAL]); |
| 5606 } | 5813 } |
| 5607 | 5814 |
| 5608 if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) | 5815 if (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) |
| 5609 pidgin_themes_smiley_themeize_custom(gtkconv->entry); | 5816 pidgin_themes_smiley_themeize_custom(gtkconv->entry); |
| 5610 } | 5817 } |
| 5611 | 5818 |
| 5612 static void | 5819 static void |
| 5613 pidgin_conv_new_hidden(PurpleConversation *conv) | 5820 pidgin_conv_new_hidden(PurpleConversation *conv) |
| 5715 g_list_free(gtkconv->send_history); | 5922 g_list_free(gtkconv->send_history); |
| 5716 | 5923 |
| 5717 if (gtkconv->attach.timer) { | 5924 if (gtkconv->attach.timer) { |
| 5718 g_source_remove(gtkconv->attach.timer); | 5925 g_source_remove(gtkconv->attach.timer); |
| 5719 } | 5926 } |
| 5927 | |
| 5928 g_object_disconnect(G_OBJECT(gtkconv->theme), "any_signal::notify", | |
| 5929 conv_variant_changed_cb, gtkconv, NULL); | |
| 5930 g_object_unref(gtkconv->theme); | |
| 5720 | 5931 |
| 5721 g_free(gtkconv); | 5932 g_free(gtkconv); |
| 5722 } | 5933 } |
| 5723 | 5934 |
| 5724 | 5935 |
| 5743 } | 5954 } |
| 5744 | 5955 |
| 5745 purple_conversation_write(conv, who, message, flags, mtime); | 5956 purple_conversation_write(conv, who, message, flags, mtime); |
| 5746 } | 5957 } |
| 5747 | 5958 |
| 5959 #if 0 | |
| 5748 static const char * | 5960 static const char * |
| 5749 get_text_tag_color(GtkTextTag *tag) | 5961 get_text_tag_color(GtkTextTag *tag) |
| 5750 { | 5962 { |
| 5751 GdkColor *color = NULL; | 5963 GdkColor *color = NULL; |
| 5752 gboolean set = FALSE; | 5964 gboolean set = FALSE; |
| 5770 if (event->type == GDK_BUTTON_PRESS | 5982 if (event->type == GDK_BUTTON_PRESS |
| 5771 || event->type == GDK_2BUTTON_PRESS) { | 5983 || event->type == GDK_2BUTTON_PRESS) { |
| 5772 GdkEventButton *btn_event = (GdkEventButton*) event; | 5984 GdkEventButton *btn_event = (GdkEventButton*) event; |
| 5773 PurpleConversation *conv = data; | 5985 PurpleConversation *conv = data; |
| 5774 char *buddyname; | 5986 char *buddyname; |
| 5775 gchar *name; | |
| 5776 | |
| 5777 g_object_get(G_OBJECT(tag), "name", &name, NULL); | |
| 5778 | 5987 |
| 5779 /* strlen("BUDDY " or "HILIT ") == 6 */ | 5988 /* strlen("BUDDY " or "HILIT ") == 6 */ |
| 5780 g_return_val_if_fail((name != NULL) && (strlen(name) > 6), FALSE); | 5989 g_return_val_if_fail((tag->name != NULL) |
| 5781 | 5990 && (strlen(tag->name) > 6), FALSE); |
| 5782 buddyname = name + 6; | 5991 |
| 5992 buddyname = (tag->name) + 6; | |
| 5783 | 5993 |
| 5784 /* emit chat-nick-clicked signal */ | 5994 /* emit chat-nick-clicked signal */ |
| 5785 if (event->type == GDK_BUTTON_PRESS) { | 5995 if (event->type == GDK_BUTTON_PRESS) { |
| 5786 gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( | 5996 gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( |
| 5787 pidgin_conversations_get_handle(), "chat-nick-clicked", | 5997 pidgin_conversations_get_handle(), "chat-nick-clicked", |
| 5788 data, buddyname, btn_event->button)); | 5998 data, buddyname, btn_event->button)); |
| 5789 if (plugin_return) { | 5999 if (plugin_return) |
| 5790 g_free(name); | |
| 5791 return TRUE; | 6000 return TRUE; |
| 5792 } | 6001 } |
| 5793 } | 6002 |
| 5794 | 6003 if (btn_event->button == 1 && |
| 5795 if (btn_event->button == 1 && event->type == GDK_2BUTTON_PRESS) { | 6004 event->type == GDK_2BUTTON_PRESS) { |
| 5796 chat_do_im(PIDGIN_CONVERSATION(conv), buddyname); | 6005 chat_do_im(PIDGIN_CONVERSATION(conv), buddyname); |
| 5797 g_free(name); | |
| 5798 | |
| 5799 return TRUE; | 6006 return TRUE; |
| 5800 } else if (btn_event->button == 2 && event->type == GDK_2BUTTON_PRESS) { | 6007 } else if (btn_event->button == 2 |
| 6008 && event->type == GDK_2BUTTON_PRESS) { | |
| 5801 chat_do_info(PIDGIN_CONVERSATION(conv), buddyname); | 6009 chat_do_info(PIDGIN_CONVERSATION(conv), buddyname); |
| 5802 g_free(name); | |
| 5803 | 6010 |
| 5804 return TRUE; | 6011 return TRUE; |
| 5805 } else if (btn_event->button == 3 && event->type == GDK_BUTTON_PRESS) { | 6012 } else if (btn_event->button == 3 |
| 6013 && event->type == GDK_BUTTON_PRESS) { | |
| 5806 GtkTextIter start, end; | 6014 GtkTextIter start, end; |
| 5807 | 6015 |
| 5808 /* we shouldn't display the popup | 6016 /* we shouldn't display the popup |
| 5809 * if the user has selected something: */ | 6017 * if the user has selected something: */ |
| 5810 if (!gtk_text_buffer_get_selection_bounds( | 6018 if (!gtk_text_buffer_get_selection_bounds( |
| 5811 gtk_text_iter_get_buffer(arg2), | 6019 gtk_text_iter_get_buffer(arg2), |
| 5812 &start, &end)) { | 6020 &start, &end)) { |
| 5813 GtkWidget *menu = NULL; | 6021 GtkWidget *menu = NULL; |
| 5814 PurpleConnection *gc = | 6022 PurpleConnection *gc = |
| 5815 purple_conversation_get_gc(conv); | 6023 purple_conversation_get_connection(conv); |
| 5816 | 6024 |
| 5817 | 6025 |
| 5818 menu = create_chat_menu(conv, buddyname, gc); | 6026 menu = create_chat_menu(conv, buddyname, gc); |
| 5819 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, | 6027 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, |
| 5820 NULL, GTK_WIDGET(imhtml), | 6028 NULL, GTK_WIDGET(imhtml), |
| 5821 btn_event->button, | 6029 btn_event->button, |
| 5822 btn_event->time); | 6030 btn_event->time); |
| 5823 | 6031 |
| 5824 g_free(name); | |
| 5825 | |
| 5826 /* Don't propagate the event any further */ | 6032 /* Don't propagate the event any further */ |
| 5827 return TRUE; | 6033 return TRUE; |
| 5828 } | 6034 } |
| 5829 } | 6035 } |
| 5830 | |
| 5831 g_free(name); | |
| 5832 } | 6036 } |
| 5833 | 6037 |
| 5834 return FALSE; | 6038 return FALSE; |
| 5835 } | 6039 } |
| 6040 #endif | |
| 5836 | 6041 |
| 5837 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, | 6042 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, |
| 5838 gboolean create) | 6043 gboolean create) |
| 5839 { | 6044 { |
| 6045 /* TODO WEBKIT */ | |
| 6046 #if 0 | |
| 5840 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); | 6047 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
| 5841 GtkTextTag *buddytag; | 6048 GtkTextTag *buddytag; |
| 5842 gchar *str; | 6049 gchar *str; |
| 5843 gboolean highlight = (flag & PURPLE_MESSAGE_NICK); | 6050 gboolean highlight = (flag & PURPLE_MESSAGE_NICK); |
| 5844 GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer; | 6051 GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer; |
| 5868 } | 6075 } |
| 5869 | 6076 |
| 5870 g_free(str); | 6077 g_free(str); |
| 5871 | 6078 |
| 5872 return buddytag; | 6079 return buddytag; |
| 5873 } | 6080 #endif /* if 0 */ |
| 5874 | 6081 return NULL; |
| 6082 } | |
| 6083 | |
| 6084 #if 0 | |
| 5875 static void pidgin_conv_calculate_newday(PidginConversation *gtkconv, time_t mtime) | 6085 static void pidgin_conv_calculate_newday(PidginConversation *gtkconv, time_t mtime) |
| 5876 { | 6086 { |
| 5877 struct tm *tm = localtime(&mtime); | 6087 struct tm *tm = localtime(&mtime); |
| 5878 | 6088 |
| 5879 tm->tm_hour = tm->tm_min = tm->tm_sec = 0; | 6089 tm->tm_hour = tm->tm_min = tm->tm_sec = 0; |
| 5915 | 6125 |
| 5916 g_free(*str); | 6126 g_free(*str); |
| 5917 *str = ret; | 6127 *str = ret; |
| 5918 #endif | 6128 #endif |
| 5919 } | 6129 } |
| 6130 #endif | |
| 6131 | |
| 6132 static char * | |
| 6133 replace_message_tokens( | |
| 6134 const char *text, | |
| 6135 PurpleConversation *conv, | |
| 6136 const char *name, | |
| 6137 const char *alias, | |
| 6138 const char *message, | |
| 6139 PurpleMessageFlags flags, | |
| 6140 time_t mtime) | |
| 6141 { | |
| 6142 GString *str; | |
| 6143 const char *cur = text; | |
| 6144 const char *prev = cur; | |
| 6145 | |
| 6146 if (text == NULL) | |
| 6147 return g_strdup(""); | |
| 6148 | |
| 6149 str = g_string_new(NULL); | |
| 6150 while ((cur = strchr(cur, '%'))) { | |
| 6151 const char *replace = NULL; | |
| 6152 const char *fin = NULL; | |
| 6153 | |
| 6154 if (g_str_has_prefix(cur, "%message%")) { | |
| 6155 replace = message; | |
| 6156 | |
| 6157 } else if (g_str_has_prefix(cur, "%messageClasses%")) { | |
| 6158 replace = flags & PURPLE_MESSAGE_SEND ? "outgoing" : | |
| 6159 flags & PURPLE_MESSAGE_RECV ? "incoming" : "event"; | |
| 6160 | |
| 6161 } else if (g_str_has_prefix(cur, "%time")) { | |
| 6162 const char *tmp = cur + strlen("%time"); | |
| 6163 char *format = NULL; | |
| 6164 if (*tmp == '{') { | |
| 6165 char *end; | |
| 6166 tmp++; | |
| 6167 end = strstr(tmp, "}%"); | |
| 6168 if (!end) /* Invalid string */ | |
| 6169 continue; | |
| 6170 format = g_strndup(tmp, end - tmp); | |
| 6171 fin = end + 1; | |
| 6172 } | |
| 6173 replace = purple_utf8_strftime(format ? format : "%X", NULL); | |
| 6174 g_free(format); | |
| 6175 | |
| 6176 } else if (g_str_has_prefix(cur, "%shortTime%")) { | |
| 6177 replace = purple_utf8_strftime("%H:%M", NULL); | |
| 6178 | |
| 6179 } else if (g_str_has_prefix(cur, "%userIconPath%")) { | |
| 6180 if (flags & PURPLE_MESSAGE_SEND) { | |
| 6181 if (purple_account_get_bool(purple_conversation_get_account(conv), "use-global-buddyicon", TRUE)) { | |
| 6182 replace = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon"); | |
| 6183 } else { | |
| 6184 PurpleStoredImage *img = purple_buddy_icons_find_account_icon(purple_conversation_get_account(conv)); | |
| 6185 replace = purple_imgstore_get_filename(img); | |
| 6186 } | |
| 6187 if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) { | |
| 6188 replace = g_build_filename("Outgoing", "buddy_icon.png", NULL); | |
| 6189 } | |
| 6190 } else if (flags & PURPLE_MESSAGE_RECV) { | |
| 6191 PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); | |
| 6192 if (icon) | |
| 6193 replace = purple_buddy_icon_get_full_path(icon); | |
| 6194 if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) { | |
| 6195 replace = g_build_filename("Incoming", "buddy_icon.png", NULL); | |
| 6196 } | |
| 6197 } | |
| 6198 | |
| 6199 } else if (g_str_has_prefix(cur, "%senderScreenName%")) { | |
| 6200 replace = name; | |
| 6201 | |
| 6202 } else if (g_str_has_prefix(cur, "%sender%")) { | |
| 6203 replace = alias; | |
| 6204 | |
| 6205 } else if (g_str_has_prefix(cur, "%service%")) { | |
| 6206 replace = purple_account_get_protocol_name(purple_conversation_get_account(conv)); | |
| 6207 | |
| 6208 } else if (g_str_has_prefix(cur, "%messageDirection%")) { | |
| 6209 replace = purple_markup_is_rtl(message) ? "rtl" : "ltr"; | |
| 6210 | |
| 6211 } else { | |
| 6212 cur++; | |
| 6213 continue; | |
| 6214 } | |
| 6215 | |
| 6216 /* Here we have a replacement to make */ | |
| 6217 g_string_append_len(str, prev, cur - prev); | |
| 6218 if (replace) | |
| 6219 g_string_append(str, replace); | |
| 6220 | |
| 6221 /* And update the pointers */ | |
| 6222 if (fin) { | |
| 6223 prev = cur = fin + 1; | |
| 6224 } else { | |
| 6225 prev = cur = strchr(cur + 1, '%') + 1; | |
| 6226 } | |
| 6227 | |
| 6228 } | |
| 6229 | |
| 6230 /* And wrap it up */ | |
| 6231 g_string_append(str, prev); | |
| 6232 | |
| 6233 return g_string_free(str, FALSE); | |
| 6234 } | |
| 5920 | 6235 |
| 5921 static void | 6236 static void |
| 5922 pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias, | 6237 pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias, |
| 5923 const char *message, PurpleMessageFlags flags, | 6238 const char *message, PurpleMessageFlags flags, |
| 5924 time_t mtime) | 6239 time_t mtime) |
| 5925 { | 6240 { |
| 5926 PidginConversation *gtkconv; | 6241 PidginConversation *gtkconv; |
| 5927 PurpleConnection *gc; | 6242 PurpleConnection *gc; |
| 5928 PurpleAccount *account; | 6243 PurpleAccount *account; |
| 6244 #if 0 | |
| 5929 int gtk_font_options = 0; | 6245 int gtk_font_options = 0; |
| 5930 int gtk_font_options_all = 0; | 6246 int gtk_font_options_all = 0; |
| 5931 int max_scrollback_lines; | |
| 5932 int line_count; | |
| 5933 char buf2[BUF_LONG]; | 6247 char buf2[BUF_LONG]; |
| 5934 gboolean show_date; | 6248 gboolean show_date; |
| 5935 char *mdate; | 6249 char *mdate; |
| 5936 char *str; | 6250 char *str; |
| 5937 char *with_font_tag; | 6251 char *with_font_tag; |
| 5938 char *sml_attrib = NULL; | 6252 char *sml_attrib = NULL; |
| 6253 #endif | |
| 5939 size_t length; | 6254 size_t length; |
| 5940 PurpleConversationType type; | 6255 PurpleConversationType type; |
| 5941 char *displaying; | 6256 char *displaying; |
| 5942 gboolean plugin_return; | 6257 gboolean plugin_return; |
| 5943 char *bracket; | 6258 #if 0 |
| 5944 int tag_count = 0; | |
| 5945 gboolean is_rtl_message = FALSE; | 6259 gboolean is_rtl_message = FALSE; |
| 6260 #endif | |
| 6261 | |
| 6262 const char *message_html; | |
| 6263 char *msg; | |
| 6264 char *escape; | |
| 6265 char *script; | |
| 6266 char *smileyed; | |
| 6267 PurpleMessageFlags old_flags; | |
| 6268 const char *func = "appendMessage"; | |
| 5946 | 6269 |
| 5947 g_return_if_fail(conv != NULL); | 6270 g_return_if_fail(conv != NULL); |
| 5948 gtkconv = PIDGIN_CONVERSATION(conv); | 6271 gtkconv = PIDGIN_CONVERSATION(conv); |
| 5949 g_return_if_fail(gtkconv != NULL); | 6272 g_return_if_fail(gtkconv != NULL); |
| 5950 | 6273 |
| 5997 g_free(displaying); | 6320 g_free(displaying); |
| 5998 return; | 6321 return; |
| 5999 } | 6322 } |
| 6000 length = strlen(displaying) + 1; | 6323 length = strlen(displaying) + 1; |
| 6001 | 6324 |
| 6002 /* Awful hack to work around GtkIMHtml's inefficient rendering of messages with lots of formatting changes. | 6325 old_flags = gtkconv->last_flags; |
| 6003 * If a message has over 100 '<' characters, strip formatting before appending it. Hopefully nobody actually | 6326 if ((flags & PURPLE_MESSAGE_SEND) && (old_flags & PURPLE_MESSAGE_SEND)) { |
| 6004 * needs that much formatting, anyway. | 6327 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTENT); |
| 6005 */ | 6328 func = "appendNextMessage"; |
| 6006 for (bracket = strchr(displaying, '<'); bracket && *(bracket + 1); bracket = strchr(bracket + 1, '<')) | 6329 } else if (flags & PURPLE_MESSAGE_SEND) { |
| 6007 tag_count++; | 6330 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT); |
| 6008 | 6331 } else if ((flags & PURPLE_MESSAGE_RECV) && (old_flags & PURPLE_MESSAGE_RECV)) { |
| 6009 if (tag_count > 100) { | 6332 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTENT); |
| 6010 char *tmp = displaying; | 6333 func = "appendNextMessage"; |
| 6011 displaying = purple_markup_strip_html(tmp); | 6334 } else if (flags & PURPLE_MESSAGE_RECV) { |
| 6012 g_free(tmp); | 6335 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT); |
| 6013 } | 6336 } else { |
| 6014 | 6337 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_STATUS); |
| 6015 line_count = gtk_text_buffer_get_line_count( | 6338 } |
| 6016 gtk_text_view_get_buffer(GTK_TEXT_VIEW( | 6339 gtkconv->last_flags = flags; |
| 6017 gtkconv->imhtml))); | 6340 |
| 6018 | 6341 smileyed = smiley_parse_markup(message, purple_account_get_protocol_id(account)); |
| 6019 max_scrollback_lines = purple_prefs_get_int( | 6342 msg = replace_message_tokens(message_html, conv, name, alias, smileyed, flags, mtime); |
| 6020 PIDGIN_PREFS_ROOT "/conversations/scrollback_lines"); | 6343 escape = gtk_webview_quote_js_string(msg); |
| 6021 /* If we're sitting at more than 100 lines more than the | 6344 script = g_strdup_printf("%s(%s)", func, escape); |
| 6022 max scrollback, trim down to max scrollback */ | 6345 |
| 6023 if (max_scrollback_lines > 0 | 6346 purple_debug_info("webkit", "JS: %s\n", script); |
| 6024 && line_count > (max_scrollback_lines + 100)) { | 6347 gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), script); |
| 6025 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer( | 6348 |
| 6026 GTK_TEXT_VIEW(gtkconv->imhtml)); | 6349 g_free(script); |
| 6027 GtkTextIter start, end; | 6350 g_free(smileyed); |
| 6028 | 6351 g_free(msg); |
| 6029 gtk_text_buffer_get_start_iter(text_buffer, &start); | 6352 g_free(escape); |
| 6030 gtk_text_buffer_get_iter_at_line(text_buffer, &end, | 6353 |
| 6031 (line_count - max_scrollback_lines)); | 6354 #if 0 |
| 6032 gtk_imhtml_delete(GTK_IMHTML(gtkconv->imhtml), &start, &end); | 6355 /* if the buffer is not empty add a <br> */ |
| 6033 } | 6356 if (!gtk_webview_is_empty(GTK_WEBVIEW(gtkconv->webview))) |
| 6034 | 6357 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<br />"); |
| 6035 if (type == PURPLE_CONV_TYPE_CHAT) | |
| 6036 { | |
| 6037 /* Create anchor for user */ | |
| 6038 GtkTextIter iter; | |
| 6039 char *tmp = g_strconcat("user:", name, NULL); | |
| 6040 | |
| 6041 gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)), &iter); | |
| 6042 gtk_text_buffer_create_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)), | |
| 6043 tmp, &iter, TRUE); | |
| 6044 g_free(tmp); | |
| 6045 } | |
| 6046 | |
| 6047 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling")) | |
| 6048 gtk_font_options_all |= GTK_IMHTML_USE_SMOOTHSCROLLING; | |
| 6049 | |
| 6050 if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)))) | |
| 6051 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", gtk_font_options_all | GTK_IMHTML_NO_SCROLL); | |
| 6052 | 6358 |
| 6053 /* First message in a conversation. */ | 6359 /* First message in a conversation. */ |
| 6054 if (gtkconv->newday == 0) | 6360 if (gtkconv->newday == 0) |
| 6055 pidgin_conv_calculate_newday(gtkconv, mtime); | 6361 pidgin_conv_calculate_newday(gtkconv, mtime); |
| 6056 | 6362 |
| 6089 if ((flags & PURPLE_MESSAGE_RECV) && | 6395 if ((flags & PURPLE_MESSAGE_RECV) && |
| 6090 !purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting")) | 6396 !purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting")) |
| 6091 gtk_font_options |= GTK_IMHTML_NO_COLOURS | GTK_IMHTML_NO_FONTS | GTK_IMHTML_NO_SIZES | GTK_IMHTML_NO_FORMATTING; | 6397 gtk_font_options |= GTK_IMHTML_NO_COLOURS | GTK_IMHTML_NO_FONTS | GTK_IMHTML_NO_SIZES | GTK_IMHTML_NO_FORMATTING; |
| 6092 | 6398 |
| 6093 /* this is gonna crash one day, I can feel it. */ | 6399 /* this is gonna crash one day, I can feel it. */ |
| 6094 if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(conv->account)))->options & | 6400 if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(purple_conversation_get_account(conv))))->options & |
| 6095 OPT_PROTO_USE_POINTSIZE) { | 6401 OPT_PROTO_USE_POINTSIZE) { |
| 6096 gtk_font_options |= GTK_IMHTML_USE_POINTSIZE; | 6402 gtk_font_options |= GTK_IMHTML_USE_POINTSIZE; |
| 6097 } | 6403 } |
| 6098 | 6404 |
| 6099 if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) | 6405 if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) |
| 6100 { | 6406 { |
| 6101 /* We want to see our own smileys. Need to revert it after send*/ | 6407 /* We want to see our own smileys. Need to revert it after send*/ |
| 6102 pidgin_themes_smiley_themeize_custom(gtkconv->imhtml); | 6408 pidgin_themes_smiley_themeize_custom(gtkconv->webview); |
| 6103 } | 6409 } |
| 6104 | 6410 |
| 6105 /* TODO: These colors should not be hardcoded so log.c can use them */ | 6411 /* TODO: These colors should not be hardcoded so log.c can use them */ |
| 6106 if (flags & PURPLE_MESSAGE_RAW) { | 6412 if (flags & PURPLE_MESSAGE_RAW) { |
| 6107 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all); | 6413 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), message); |
| 6108 } else if (flags & PURPLE_MESSAGE_SYSTEM) { | 6414 } else if (flags & PURPLE_MESSAGE_SYSTEM) { |
| 6109 g_snprintf(buf2, sizeof(buf2), | 6415 g_snprintf(buf2, sizeof(buf2), |
| 6110 "<FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT>", | 6416 "<font %s><font size=\"2\"><span class='timestamp'>%s</span></font><b>%s</b></font>", |
| 6111 sml_attrib ? sml_attrib : "", mdate, displaying); | 6417 sml_attrib ? sml_attrib : "", mdate, displaying); |
| 6112 | 6418 |
| 6113 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all); | 6419 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); |
| 6114 | 6420 |
| 6115 } else if (flags & PURPLE_MESSAGE_ERROR) { | 6421 } else if (flags & PURPLE_MESSAGE_ERROR) { |
| 6116 g_snprintf(buf2, sizeof(buf2), | 6422 g_snprintf(buf2, sizeof(buf2), |
| 6117 "<FONT COLOR=\"#ff0000\"><FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT></FONT>", | 6423 "<font color=\"#ff0000\"><font %s><font size=\"2\"><span class='timestamp'>%s</span> </font><b>%s</b></font></font>", |
| 6118 sml_attrib ? sml_attrib : "", mdate, displaying); | 6424 sml_attrib ? sml_attrib : "", mdate, displaying); |
| 6119 | 6425 |
| 6120 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all); | 6426 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); |
| 6121 | 6427 |
| 6122 } else if (flags & PURPLE_MESSAGE_NO_LOG) { | 6428 } else if (flags & PURPLE_MESSAGE_NO_LOG) { |
| 6123 g_snprintf(buf2, BUF_LONG, | 6429 g_snprintf(buf2, BUF_LONG, |
| 6124 "<B><FONT %s COLOR=\"#777777\">%s</FONT></B>", | 6430 "<b><font %s color=\"#777777\">%s</font></b>", |
| 6125 sml_attrib ? sml_attrib : "", displaying); | 6431 sml_attrib ? sml_attrib : "", displaying); |
| 6126 | 6432 |
| 6127 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all); | 6433 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); |
| 6128 } else { | 6434 } else { |
| 6129 char *new_message = g_memdup(displaying, length); | 6435 char *new_message = g_memdup(displaying, length); |
| 6130 char *alias_escaped = (alias ? g_markup_escape_text(alias, strlen(alias)) : g_strdup("")); | 6436 char *alias_escaped = (alias ? g_markup_escape_text(alias, strlen(alias)) : g_strdup("")); |
| 6131 /* The initial offset is to deal with | 6437 /* The initial offset is to deal with |
| 6132 * escaped entities making the string longer */ | 6438 * escaped entities making the string longer */ |
| 6133 int tag_start_offset = 0; | 6439 int tag_start_offset = 0; |
| 6134 int tag_end_offset = 0; | 6440 int tag_end_offset = 0; |
| 6135 const char *tagname = NULL; | 6441 const char *tagname = NULL; |
| 6136 | |
| 6137 GtkTextIter start, end; | |
| 6138 GtkTextMark *mark; | |
| 6139 GtkTextTag *tag; | |
| 6140 GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer; | |
| 6141 | 6442 |
| 6142 /* Enforce direction on alias */ | 6443 /* Enforce direction on alias */ |
| 6143 if (is_rtl_message) | 6444 if (is_rtl_message) |
| 6144 str_embed_direction_chars(&alias_escaped); | 6445 str_embed_direction_chars(&alias_escaped); |
| 6145 | 6446 |
| 6197 } | 6498 } |
| 6198 } | 6499 } |
| 6199 | 6500 |
| 6200 g_free(alias_escaped); | 6501 g_free(alias_escaped); |
| 6201 | 6502 |
| 6503 /* TODO WEBKIT */ | |
| 6504 #if 0 | |
| 6202 if (tagname) | 6505 if (tagname) |
| 6203 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname); | 6506 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname); |
| 6204 else | 6507 else |
| 6205 tag = get_buddy_tag(conv, name, flags, TRUE); | 6508 tag = get_buddy_tag(conv, name, flags, TRUE); |
| 6206 | 6509 |
| 6207 if (GTK_IMHTML(gtkconv->imhtml)->show_comments) { | 6510 if (GTK_IMHTML(gtkconv->imhtml)->show_comments) { |
| 6511 { | |
| 6208 /* The color for the timestamp has to be set in the font-tags, unfortunately. | 6512 /* The color for the timestamp has to be set in the font-tags, unfortunately. |
| 6209 * Applying the nick-tag to timestamps would work, but that can make it | 6513 * Applying the nick-tag to timestamps would work, but that can make it |
| 6210 * bold. I thought applying the "comment" tag again, which has "weight" set | 6514 * bold. I thought applying the "comment" tag again, which has "weight" set |
| 6211 * to PANGO_WEIGHT_NORMAL, would remove the boldness. But it doesn't. So | 6515 * to PANGO_WEIGHT_NORMAL, would remove the boldness. But it doesn't. So |
| 6212 * this will have to do. I don't terribly like it. -- sadrul */ | 6516 * this will have to do. I don't terribly like it. -- sadrul */ |
| 6213 const char *color = get_text_tag_color(tag); | 6517 /* const char *color = get_text_tag_color(tag); */ |
| 6214 g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>", | 6518 g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>", |
| 6215 color ? "COLOR=\"" : "", color ? color : "", color ? "\"" : "", mdate); | 6519 color ? "COLOR=\"" : "", color ? color : "", color ? "\"" : "", mdate); |
| 6216 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL); | 6520 gtk_webview_append_html (GTK_WEBVIEW(gtkconv->webview), buf2); |
| 6217 } | 6521 } |
| 6218 | 6522 #endif /* if 0 */ |
| 6219 gtk_text_buffer_get_end_iter(buffer, &end); | 6523 g_snprintf(buf2, BUF_LONG, "<font %s>%s</font> ", sml_attrib ? sml_attrib : "", str); |
| 6220 mark = gtk_text_buffer_create_mark(buffer, NULL, &end, TRUE); | 6524 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); |
| 6221 | |
| 6222 g_snprintf(buf2, BUF_LONG, "<FONT %s>%s</FONT> ", sml_attrib ? sml_attrib : "", str); | |
| 6223 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL); | |
| 6224 | |
| 6225 gtk_text_buffer_get_end_iter(buffer, &end); | |
| 6226 gtk_text_buffer_get_iter_at_mark(buffer, &start, mark); | |
| 6227 gtk_text_buffer_apply_tag(buffer, tag, &start, &end); | |
| 6228 gtk_text_buffer_delete_mark(buffer, mark); | |
| 6229 | 6525 |
| 6230 g_free(str); | 6526 g_free(str); |
| 6231 | 6527 |
| 6232 if(gc){ | 6528 if (gc) { |
| 6233 char *pre = g_strdup_printf("<font %s>", sml_attrib ? sml_attrib : ""); | 6529 char *pre = g_strdup_printf("<font %s>", sml_attrib ? sml_attrib : ""); |
| 6234 char *post = "</font>"; | 6530 char *post = "</font>"; |
| 6235 int pre_len = strlen(pre); | 6531 with_font_tag = g_strdup_printf("%s%s%s", pre, new_message, post); |
| 6236 int post_len = strlen(post); | |
| 6237 | |
| 6238 with_font_tag = g_malloc(length + pre_len + post_len + 1); | |
| 6239 | |
| 6240 strcpy(with_font_tag, pre); | |
| 6241 memcpy(with_font_tag + pre_len, new_message, length); | |
| 6242 strcpy(with_font_tag + pre_len + length, post); | |
| 6243 | |
| 6244 length += pre_len + post_len; | |
| 6245 g_free(pre); | 6532 g_free(pre); |
| 6246 } else | 6533 } else |
| 6247 with_font_tag = g_memdup(new_message, length); | 6534 with_font_tag = g_memdup(new_message, length); |
| 6248 | 6535 |
| 6249 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), | 6536 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), |
| 6250 with_font_tag, gtk_font_options | gtk_font_options_all); | 6537 with_font_tag); |
| 6251 | 6538 |
| 6252 g_free(with_font_tag); | 6539 g_free(with_font_tag); |
| 6253 g_free(new_message); | 6540 g_free(new_message); |
| 6254 } | 6541 } |
| 6255 | 6542 |
| 6256 g_free(mdate); | 6543 g_free(mdate); |
| 6257 g_free(sml_attrib); | 6544 g_free(sml_attrib); |
| 6545 | |
| 6546 #endif | |
| 6258 | 6547 |
| 6259 /* Tab highlighting stuff */ | 6548 /* Tab highlighting stuff */ |
| 6260 if (!(flags & PURPLE_MESSAGE_SEND) && !pidgin_conv_has_focus(conv)) | 6549 if (!(flags & PURPLE_MESSAGE_SEND) && !pidgin_conv_has_focus(conv)) |
| 6261 { | 6550 { |
| 6262 PidginUnseenState unseen = PIDGIN_UNSEEN_NONE; | 6551 PidginUnseenState unseen = PIDGIN_UNSEEN_NONE; |
| 6272 unseen = PIDGIN_UNSEEN_TEXT; | 6561 unseen = PIDGIN_UNSEEN_TEXT; |
| 6273 | 6562 |
| 6274 gtkconv_set_unseen(gtkconv, unseen); | 6563 gtkconv_set_unseen(gtkconv, unseen); |
| 6275 } | 6564 } |
| 6276 | 6565 |
| 6277 if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) | 6566 #if 0 |
| 6567 if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) | |
| 6278 { | 6568 { |
| 6279 /* Restore the smiley-data */ | 6569 /* Restore the smiley-data */ |
| 6280 pidgin_themes_smiley_themeize(gtkconv->imhtml); | 6570 pidgin_themes_smiley_themeize(gtkconv->webview); |
| 6281 } | 6571 } |
| 6572 #endif | |
| 6282 | 6573 |
| 6283 purple_signal_emit(pidgin_conversations_get_handle(), | 6574 purple_signal_emit(pidgin_conversations_get_handle(), |
| 6284 (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"), | 6575 (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"), |
| 6285 account, name, displaying, conv, flags); | 6576 account, name, displaying, conv, flags); |
| 6286 g_free(displaying); | 6577 g_free(displaying); |
| 6287 update_typing_message(gtkconv, NULL); | 6578 update_typing_message(gtkconv, NULL); |
| 6288 } | 6579 } |
| 6289 | 6580 |
| 6290 static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *iter) | 6581 static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *iter) |
| 6291 { | 6582 { |
| 6292 GtkTreeRowReference *ref = cb->ui_data; | 6583 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); |
| 6293 GtkTreePath *path; | 6584 GtkTreePath *path; |
| 6294 GtkTreeModel *model; | 6585 GtkTreeModel *model; |
| 6295 | 6586 |
| 6296 if (!ref) | 6587 if (!ref) |
| 6297 return FALSE; | 6588 return FALSE; |
| 6371 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | 6662 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); |
| 6372 | 6663 |
| 6373 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 6664 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
| 6374 return; | 6665 return; |
| 6375 | 6666 |
| 6376 old_cbuddy = purple_conv_chat_cb_find(chat, old_name); | |
| 6377 if (get_iter_from_chatbuddy(old_cbuddy, &iter)) { | |
| 6378 GtkTreeRowReference *ref = old_cbuddy->ui_data; | |
| 6379 | |
| 6380 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); | |
| 6381 gtk_tree_row_reference_free(ref); | |
| 6382 old_cbuddy->ui_data = NULL; | |
| 6383 } | |
| 6384 | |
| 6385 if ((tag = get_buddy_tag(conv, old_name, 0, FALSE))) | 6667 if ((tag = get_buddy_tag(conv, old_name, 0, FALSE))) |
| 6386 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL); | 6668 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL); |
| 6387 if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE))) | 6669 if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE))) |
| 6388 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL); | 6670 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL); |
| 6389 | 6671 |
| 6672 old_cbuddy = purple_conv_chat_cb_find(chat, old_name); | |
| 6390 if (!old_cbuddy) | 6673 if (!old_cbuddy) |
| 6391 return; | 6674 return; |
| 6675 | |
| 6676 if (get_iter_from_chatbuddy(old_cbuddy, &iter)) { | |
| 6677 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(old_cbuddy); | |
| 6678 | |
| 6679 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); | |
| 6680 gtk_tree_row_reference_free(ref); | |
| 6681 purple_conv_chat_cb_set_ui_data(old_cbuddy, NULL); | |
| 6682 } | |
| 6392 | 6683 |
| 6393 g_return_if_fail(new_alias != NULL); | 6684 g_return_if_fail(new_alias != NULL); |
| 6394 | 6685 |
| 6395 new_cbuddy = purple_conv_chat_cb_find(chat, new_name); | 6686 new_cbuddy = purple_conv_chat_cb_find(chat, new_name); |
| 6396 | 6687 |
| 6471 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 6762 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
| 6472 return; | 6763 return; |
| 6473 | 6764 |
| 6474 cbuddy = purple_conv_chat_cb_find(chat, user); | 6765 cbuddy = purple_conv_chat_cb_find(chat, user); |
| 6475 if (get_iter_from_chatbuddy(cbuddy, &iter)) { | 6766 if (get_iter_from_chatbuddy(cbuddy, &iter)) { |
| 6476 GtkTreeRowReference *ref = cbuddy->ui_data; | 6767 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cbuddy); |
| 6477 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); | 6768 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); |
| 6478 gtk_tree_row_reference_free(ref); | 6769 gtk_tree_row_reference_free(ref); |
| 6479 cbuddy->ui_data = NULL; | 6770 purple_conv_chat_cb_set_ui_data(cbuddy, NULL); |
| 6480 } | 6771 } |
| 6481 | 6772 |
| 6482 if (cbuddy) | 6773 if (cbuddy) |
| 6483 add_chat_buddy_common(conv, cbuddy, NULL); | 6774 add_chat_buddy_common(conv, cbuddy, NULL); |
| 6484 } | 6775 } |
| 6521 | 6812 |
| 6522 return TRUE; | 6813 return TRUE; |
| 6523 } | 6814 } |
| 6524 | 6815 |
| 6525 static gboolean | 6816 static gboolean |
| 6817 add_custom_smiley_for_webview(GtkWebView *webview, const char *sml, const char *smile) | |
| 6818 { | |
| 6819 /* TODO WEBKIT: Smileys need to be added to webkit stuff */ | |
| 6820 return TRUE; | |
| 6821 } | |
| 6822 | |
| 6823 static gboolean | |
| 6526 pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gboolean remote) | 6824 pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gboolean remote) |
| 6527 { | 6825 { |
| 6528 PidginConversation *gtkconv; | 6826 PidginConversation *gtkconv; |
| 6529 struct smiley_list *list; | 6827 struct smiley_list *list; |
| 6530 const char *sml = NULL, *conv_sml; | 6828 const char *sml = NULL, *conv_sml; |
| 6537 if (pidgin_themes_smileys_disabled()) | 6835 if (pidgin_themes_smileys_disabled()) |
| 6538 return FALSE; | 6836 return FALSE; |
| 6539 | 6837 |
| 6540 /* If possible add this smiley to the current theme. | 6838 /* If possible add this smiley to the current theme. |
| 6541 * The addition is only temporary: custom smilies aren't saved to disk. */ | 6839 * The addition is only temporary: custom smilies aren't saved to disk. */ |
| 6542 conv_sml = purple_account_get_protocol_name(conv->account); | 6840 conv_sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); |
| 6543 gtkconv = PIDGIN_CONVERSATION(conv); | 6841 gtkconv = PIDGIN_CONVERSATION(conv); |
| 6544 | 6842 |
| 6545 for (list = (struct smiley_list *)current_smiley_theme->list; list; list = list->next) { | 6843 for (list = (struct smiley_list *)current_smiley_theme->list; list; list = list->next) { |
| 6546 if (!strcmp(list->sml, conv_sml)) { | 6844 if (!strcmp(list->sml, conv_sml)) { |
| 6547 sml = list->sml; | 6845 sml = list->sml; |
| 6548 break; | 6846 break; |
| 6549 } | 6847 } |
| 6550 } | 6848 } |
| 6551 | 6849 |
| 6552 if (!add_custom_smiley_for_imhtml(GTK_IMHTML(gtkconv->imhtml), sml, smile)) | 6850 if (!add_custom_smiley_for_webview(GTK_WEBVIEW(gtkconv->webview), sml, smile)) |
| 6553 return FALSE; | 6851 return FALSE; |
| 6554 | 6852 |
| 6555 if (!remote) /* If it's a local custom smiley, then add it for the entry */ | 6853 if (!remote) /* If it's a local custom smiley, then add it for the entry */ |
| 6556 if (!add_custom_smiley_for_imhtml(GTK_IMHTML(gtkconv->entry), sml, smile)) | 6854 if (!add_custom_smiley_for_imhtml(GTK_IMHTML(gtkconv->entry), sml, smile)) |
| 6557 return FALSE; | 6855 return FALSE; |
| 6561 | 6859 |
| 6562 static void | 6860 static void |
| 6563 pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile, | 6861 pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile, |
| 6564 const guchar *data, gsize size) | 6862 const guchar *data, gsize size) |
| 6565 { | 6863 { |
| 6864 /* TODO WEBKIT */ | |
| 6865 #if 0 | |
| 6566 PidginConversation *gtkconv; | 6866 PidginConversation *gtkconv; |
| 6567 GtkIMHtmlSmiley *smiley; | 6867 GtkIMHtmlSmiley *smiley; |
| 6568 const char *sml; | 6868 const char *sml; |
| 6569 GError *error = NULL; | 6869 GError *error = NULL; |
| 6570 | 6870 |
| 6571 sml = purple_account_get_protocol_name(conv->account); | 6871 sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); |
| 6572 gtkconv = PIDGIN_CONVERSATION(conv); | 6872 gtkconv = PIDGIN_CONVERSATION(conv); |
| 6573 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); | 6873 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); |
| 6574 | 6874 |
| 6575 if (!smiley) | 6875 if (!smiley) |
| 6576 return; | 6876 return; |
| 6582 if (!smiley->loader) | 6882 if (!smiley->loader) |
| 6583 return; | 6883 return; |
| 6584 | 6884 |
| 6585 if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) { | 6885 if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) { |
| 6586 purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() " | 6886 purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() " |
| 6587 "failed with size=%zu: %s\n", size, | 6887 "failed with size=%" G_GSIZE_FORMAT ": %s\n", size, |
| 6588 error ? error->message : "(no error message)"); | 6888 error ? error->message : "(no error message)"); |
| 6589 if (error) | 6889 if (error) |
| 6590 g_error_free(error); | 6890 g_error_free(error); |
| 6591 /* We must stop using the GdkPixbufLoader because trying to load | 6891 /* We must stop using the GdkPixbufLoader because trying to load |
| 6592 certain invalid GIFs with at least gdk-pixbuf 2.23.3 can return | 6892 certain invalid GIFs with at least gdk-pixbuf 2.23.3 can return |
| 6595 But we also don't want to set smiley->loader to NULL because our | 6895 But we also don't want to set smiley->loader to NULL because our |
| 6596 code might expect it to be set. So create a new loader. */ | 6896 code might expect it to be set. So create a new loader. */ |
| 6597 g_object_unref(G_OBJECT(smiley->loader)); | 6897 g_object_unref(G_OBJECT(smiley->loader)); |
| 6598 smiley->loader = gdk_pixbuf_loader_new(); | 6898 smiley->loader = gdk_pixbuf_loader_new(); |
| 6599 } | 6899 } |
| 6900 #endif /* if 0 */ | |
| 6600 } | 6901 } |
| 6601 | 6902 |
| 6602 static void | 6903 static void |
| 6603 pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile) | 6904 pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile) |
| 6604 { | 6905 { |
| 6906 /* TODO WEBKIT */ | |
| 6907 #if 0 | |
| 6605 PidginConversation *gtkconv; | 6908 PidginConversation *gtkconv; |
| 6606 GtkIMHtmlSmiley *smiley; | 6909 GtkIMHtmlSmiley *smiley; |
| 6607 const char *sml; | 6910 const char *sml; |
| 6608 GError *error = NULL; | 6911 GError *error = NULL; |
| 6609 | 6912 |
| 6610 g_return_if_fail(conv != NULL); | 6913 g_return_if_fail(conv != NULL); |
| 6611 g_return_if_fail(smile != NULL); | 6914 g_return_if_fail(smile != NULL); |
| 6612 | 6915 |
| 6613 sml = purple_account_get_protocol_name(conv->account); | 6916 sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); |
| 6614 gtkconv = PIDGIN_CONVERSATION(conv); | 6917 gtkconv = PIDGIN_CONVERSATION(conv); |
| 6615 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); | 6918 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); |
| 6616 | 6919 |
| 6617 if (!smiley) | 6920 if (!smiley) |
| 6618 return; | 6921 return; |
| 6636 to set smiley->loader to NULL because our code might expect it | 6939 to set smiley->loader to NULL because our code might expect it |
| 6637 to be set. So create a new loader. */ | 6940 to be set. So create a new loader. */ |
| 6638 g_object_unref(G_OBJECT(smiley->loader)); | 6941 g_object_unref(G_OBJECT(smiley->loader)); |
| 6639 smiley->loader = gdk_pixbuf_loader_new(); | 6942 smiley->loader = gdk_pixbuf_loader_new(); |
| 6640 } | 6943 } |
| 6944 #endif /* if 0 */ | |
| 6641 } | 6945 } |
| 6642 | 6946 |
| 6643 static void | 6947 static void |
| 6644 pidgin_conv_send_confirm(PurpleConversation *conv, const char *message) | 6948 pidgin_conv_send_confirm(PurpleConversation *conv, const char *message) |
| 6645 { | 6949 { |
| 6663 GdkPixbuf *window_icon = NULL; | 6967 GdkPixbuf *window_icon = NULL; |
| 6664 GtkIMHtmlButtons buttons; | 6968 GtkIMHtmlButtons buttons; |
| 6665 PurpleAccount *account; | 6969 PurpleAccount *account; |
| 6666 | 6970 |
| 6667 win = pidgin_conv_get_window(gtkconv); | 6971 win = pidgin_conv_get_window(gtkconv); |
| 6668 gc = purple_conversation_get_gc(conv); | 6972 gc = purple_conversation_get_connection(conv); |
| 6669 account = purple_conversation_get_account(conv); | 6973 account = purple_conversation_get_account(conv); |
| 6670 | 6974 |
| 6671 if (gc != NULL) | 6975 if (gc != NULL) |
| 6672 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 6976 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 6673 | 6977 |
| 6674 if (win->menu.send_to != NULL) | 6978 if (win->menu.send_to != NULL) |
| 6675 update_send_to_selection(win); | 6979 update_send_to_selection(win); |
| 6676 | 6980 |
| 6677 /* | 6981 /* |
| 6686 /* Show stuff that applies to IMs, hide stuff that applies to chats */ | 6990 /* Show stuff that applies to IMs, hide stuff that applies to chats */ |
| 6687 | 6991 |
| 6688 /* Deal with menu items */ | 6992 /* Deal with menu items */ |
| 6689 gtk_action_set_visible(win->menu.view_log, TRUE); | 6993 gtk_action_set_visible(win->menu.view_log, TRUE); |
| 6690 gtk_action_set_visible(win->menu.send_file, TRUE); | 6994 gtk_action_set_visible(win->menu.send_file, TRUE); |
| 6691 gtk_action_set_visible(GTK_ACTION(g_object_get_data(G_OBJECT(win->window), "get_attention")), TRUE); | 6995 gtk_action_set_visible(win->menu.get_attention, TRUE); |
| 6692 gtk_action_set_visible(win->menu.add_pounce, TRUE); | 6996 gtk_action_set_visible(win->menu.add_pounce, TRUE); |
| 6693 gtk_action_set_visible(win->menu.get_info, TRUE); | 6997 gtk_action_set_visible(win->menu.get_info, TRUE); |
| 6694 gtk_action_set_visible(win->menu.invite, FALSE); | 6998 gtk_action_set_visible(win->menu.invite, FALSE); |
| 6695 gtk_action_set_visible(win->menu.alias, TRUE); | 6999 gtk_action_set_visible(win->menu.alias, TRUE); |
| 6696 if (purple_privacy_check(account, purple_conversation_get_name(conv))) { | 7000 if (purple_privacy_check(account, purple_conversation_get_name(conv))) { |
| 6715 /* Show stuff that applies to Chats, hide stuff that applies to IMs */ | 7019 /* Show stuff that applies to Chats, hide stuff that applies to IMs */ |
| 6716 | 7020 |
| 6717 /* Deal with menu items */ | 7021 /* Deal with menu items */ |
| 6718 gtk_action_set_visible(win->menu.view_log, TRUE); | 7022 gtk_action_set_visible(win->menu.view_log, TRUE); |
| 6719 gtk_action_set_visible(win->menu.send_file, FALSE); | 7023 gtk_action_set_visible(win->menu.send_file, FALSE); |
| 6720 gtk_action_set_visible(g_object_get_data(G_OBJECT(win->window), "get_attention"), FALSE); | 7024 gtk_action_set_visible(win->menu.get_attention, FALSE); |
| 6721 gtk_action_set_visible(win->menu.add_pounce, FALSE); | 7025 gtk_action_set_visible(win->menu.add_pounce, FALSE); |
| 6722 gtk_action_set_visible(win->menu.get_info, FALSE); | 7026 gtk_action_set_visible(win->menu.get_info, FALSE); |
| 6723 gtk_action_set_visible(win->menu.invite, TRUE); | 7027 gtk_action_set_visible(win->menu.invite, TRUE); |
| 6724 gtk_action_set_visible(win->menu.alias, TRUE); | 7028 gtk_action_set_visible(win->menu.alias, TRUE); |
| 6725 gtk_action_set_visible(win->menu.block, FALSE); | 7029 gtk_action_set_visible(win->menu.block, FALSE); |
| 6745 */ | 7049 */ |
| 6746 if ((gc != NULL) && | 7050 if ((gc != NULL) && |
| 6747 ((purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT) || | 7051 ((purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT) || |
| 6748 !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) )) | 7052 !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) )) |
| 6749 { | 7053 { |
| 7054 PurpleConnectionFlags features = purple_conversation_get_features(conv); | |
| 6750 /* Account is online */ | 7055 /* Account is online */ |
| 6751 /* Deal with the toolbar */ | 7056 /* Deal with the toolbar */ |
| 6752 if (conv->features & PURPLE_CONNECTION_HTML) | 7057 if (features & PURPLE_CONNECTION_HTML) |
| 6753 { | 7058 { |
| 6754 buttons = GTK_IMHTML_ALL; /* Everything on */ | 7059 buttons = GTK_IMHTML_ALL; /* Everything on */ |
| 6755 if (conv->features & PURPLE_CONNECTION_NO_BGCOLOR) | 7060 if (features & PURPLE_CONNECTION_NO_BGCOLOR) |
| 6756 buttons &= ~GTK_IMHTML_BACKCOLOR; | 7061 buttons &= ~GTK_IMHTML_BACKCOLOR; |
| 6757 if (conv->features & PURPLE_CONNECTION_NO_FONTSIZE) | 7062 if (features & PURPLE_CONNECTION_NO_FONTSIZE) |
| 6758 { | 7063 { |
| 6759 buttons &= ~GTK_IMHTML_GROW; | 7064 buttons &= ~GTK_IMHTML_GROW; |
| 6760 buttons &= ~GTK_IMHTML_SHRINK; | 7065 buttons &= ~GTK_IMHTML_SHRINK; |
| 6761 } | 7066 } |
| 6762 if (conv->features & PURPLE_CONNECTION_NO_URLDESC) | 7067 if (features & PURPLE_CONNECTION_NO_URLDESC) |
| 6763 buttons &= ~GTK_IMHTML_LINKDESC; | 7068 buttons &= ~GTK_IMHTML_LINKDESC; |
| 6764 } else { | 7069 } else { |
| 6765 buttons = GTK_IMHTML_SMILEY | GTK_IMHTML_IMAGE; | 7070 buttons = GTK_IMHTML_SMILEY | GTK_IMHTML_IMAGE; |
| 6766 } | 7071 } |
| 6767 | 7072 |
| 6768 if (!(prpl_info->options & OPT_PROTO_IM_IMAGE)) | 7073 if (!(prpl_info->options & OPT_PROTO_IM_IMAGE) |
| 6769 conv->features |= PURPLE_CONNECTION_NO_IMAGES; | 7074 && !(features & PURPLE_CONNECTION_NO_IMAGES)) { |
| 6770 | 7075 features |= PURPLE_CONNECTION_NO_IMAGES; |
| 6771 if(conv->features & PURPLE_CONNECTION_NO_IMAGES) | 7076 purple_conversation_set_features(conv, features); |
| 7077 } | |
| 7078 | |
| 7079 if (features & PURPLE_CONNECTION_NO_IMAGES) | |
| 6772 buttons &= ~GTK_IMHTML_IMAGE; | 7080 buttons &= ~GTK_IMHTML_IMAGE; |
| 6773 | 7081 |
| 6774 if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) | 7082 if (features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) |
| 6775 buttons |= GTK_IMHTML_CUSTOM_SMILEY; | 7083 buttons |= GTK_IMHTML_CUSTOM_SMILEY; |
| 6776 else | 7084 else |
| 6777 buttons &= ~GTK_IMHTML_CUSTOM_SMILEY; | 7085 buttons &= ~GTK_IMHTML_CUSTOM_SMILEY; |
| 6778 | 7086 |
| 6779 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons); | 7087 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons); |
| 6783 /* Deal with menu items */ | 7091 /* Deal with menu items */ |
| 6784 gtk_action_set_sensitive(win->menu.view_log, TRUE); | 7092 gtk_action_set_sensitive(win->menu.view_log, TRUE); |
| 6785 gtk_action_set_sensitive(win->menu.add_pounce, TRUE); | 7093 gtk_action_set_sensitive(win->menu.add_pounce, TRUE); |
| 6786 gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL)); | 7094 gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL)); |
| 6787 gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL)); | 7095 gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL)); |
| 6788 gtk_action_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML)); | 7096 gtk_action_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML)); |
| 6789 gtk_action_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES)); | 7097 gtk_action_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES)); |
| 6790 | 7098 |
| 6791 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) | 7099 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) |
| 6792 { | 7100 { |
| 6793 gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL) || (prpl_info->add_buddy_with_invite != NULL)); | 7101 gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL)); |
| 6794 gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL)); | 7102 gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL)); |
| 6795 gtk_action_set_sensitive(win->menu.send_file, | 7103 gtk_action_set_sensitive(win->menu.send_file, |
| 6796 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || | 7104 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || |
| 6797 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); | 7105 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); |
| 6798 gtk_action_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL)); | 7106 gtk_action_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL)); |
| 6799 gtk_action_set_sensitive(win->menu.alias, | 7107 gtk_action_set_sensitive(win->menu.alias, |
| 6800 (account != NULL) && | 7108 (account != NULL) && |
| 6801 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL)); | 7109 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL)); |
| 6802 } | 7110 } |
| 6803 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) | 7111 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) |
| 6814 /* Or it's a chat that we've left. */ | 7122 /* Or it's a chat that we've left. */ |
| 6815 | 7123 |
| 6816 /* Then deal with menu items */ | 7124 /* Then deal with menu items */ |
| 6817 gtk_action_set_sensitive(win->menu.view_log, TRUE); | 7125 gtk_action_set_sensitive(win->menu.view_log, TRUE); |
| 6818 gtk_action_set_sensitive(win->menu.send_file, FALSE); | 7126 gtk_action_set_sensitive(win->menu.send_file, FALSE); |
| 6819 gtk_action_set_sensitive(g_object_get_data(G_OBJECT(win->window), | 7127 gtk_action_set_sensitive(win->menu.get_attention, FALSE); |
| 6820 "get_attention"), FALSE); | |
| 6821 gtk_action_set_sensitive(win->menu.add_pounce, TRUE); | 7128 gtk_action_set_sensitive(win->menu.add_pounce, TRUE); |
| 6822 gtk_action_set_sensitive(win->menu.get_info, FALSE); | 7129 gtk_action_set_sensitive(win->menu.get_info, FALSE); |
| 6823 gtk_action_set_sensitive(win->menu.invite, FALSE); | 7130 gtk_action_set_sensitive(win->menu.invite, FALSE); |
| 6824 gtk_action_set_sensitive(win->menu.alias, FALSE); | 7131 gtk_action_set_sensitive(win->menu.alias, FALSE); |
| 6825 gtk_action_set_sensitive(win->menu.add, FALSE); | 7132 gtk_action_set_sensitive(win->menu.add, FALSE); |
| 6835 { | 7142 { |
| 6836 GList *l = NULL; | 7143 GList *l = NULL; |
| 6837 if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) && | 7144 if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) && |
| 6838 (gtkconv->u.im->anim)) | 7145 (gtkconv->u.im->anim)) |
| 6839 { | 7146 { |
| 6840 PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name); | 7147 PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); |
| 6841 window_icon = | 7148 window_icon = |
| 6842 gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); | 7149 gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); |
| 6843 | 7150 |
| 6844 if (buddy && !PURPLE_BUDDY_IS_ONLINE(buddy)) | 7151 if (buddy && !PURPLE_BUDDY_IS_ONLINE(buddy)) |
| 6845 gdk_pixbuf_saturate_and_pixelate(window_icon, window_icon, 0.0, FALSE); | 7152 gdk_pixbuf_saturate_and_pixelate(window_icon, window_icon, 0.0, FALSE); |
| 6883 | 7190 |
| 6884 if (fields & PIDGIN_CONV_MENU) | 7191 if (fields & PIDGIN_CONV_MENU) |
| 6885 { | 7192 { |
| 6886 gray_stuff_out(PIDGIN_CONVERSATION(conv)); | 7193 gray_stuff_out(PIDGIN_CONVERSATION(conv)); |
| 6887 generate_send_to_items(win); | 7194 generate_send_to_items(win); |
| 7195 regenerate_plugins_items(win); | |
| 6888 } | 7196 } |
| 6889 | 7197 |
| 6890 if (fields & PIDGIN_CONV_TAB_ICON) | 7198 if (fields & PIDGIN_CONV_TAB_ICON) |
| 6891 { | 7199 { |
| 6892 update_tab_icon(conv); | 7200 update_tab_icon(conv); |
| 6913 topic ? topic : "", NULL); | 7221 topic ? topic : "", NULL); |
| 6914 #endif | 7222 #endif |
| 6915 } | 7223 } |
| 6916 } | 7224 } |
| 6917 | 7225 |
| 7226 #if 0 | |
| 6918 if (fields & PIDGIN_CONV_SMILEY_THEME) | 7227 if (fields & PIDGIN_CONV_SMILEY_THEME) |
| 6919 pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->imhtml); | 7228 pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview); |
| 7229 #endif | |
| 6920 | 7230 |
| 6921 if ((fields & PIDGIN_CONV_COLORIZE_TITLE) || | 7231 if ((fields & PIDGIN_CONV_COLORIZE_TITLE) || |
| 6922 (fields & PIDGIN_CONV_SET_TITLE) || | 7232 (fields & PIDGIN_CONV_SET_TITLE) || |
| 6923 (fields & PIDGIN_CONV_TOPIC)) | 7233 (fields & PIDGIN_CONV_TOPIC)) |
| 6924 { | 7234 { |
| 6925 char *title; | 7235 char *title; |
| 6926 PurpleConvIm *im = NULL; | 7236 PurpleConvIm *im = NULL; |
| 6927 PurpleAccount *account = purple_conversation_get_account(conv); | 7237 PurpleAccount *account = purple_conversation_get_account(conv); |
| 6928 PurpleBuddy *buddy = NULL; | 7238 PurpleBuddy *buddy = NULL; |
| 6941 title = g_strdup_printf("(%s)", purple_conversation_get_title(conv)); | 7251 title = g_strdup_printf("(%s)", purple_conversation_get_title(conv)); |
| 6942 else | 7252 else |
| 6943 title = g_strdup(purple_conversation_get_title(conv)); | 7253 title = g_strdup(purple_conversation_get_title(conv)); |
| 6944 | 7254 |
| 6945 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 7255 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 6946 buddy = purple_find_buddy(account, conv->name); | 7256 buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); |
| 6947 if (buddy) { | 7257 if (buddy) { |
| 6948 markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE); | 7258 markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE); |
| 6949 } else { | 7259 } else { |
| 6950 markup = title; | 7260 markup = title; |
| 6951 } | 7261 } |
| 6986 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) { | 7296 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) { |
| 6987 atk_object_set_description(accessibility_obj, _("Nick Said")); | 7297 atk_object_set_description(accessibility_obj, _("Nick Said")); |
| 6988 style = "tab-label-attention"; | 7298 style = "tab-label-attention"; |
| 6989 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) { | 7299 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) { |
| 6990 atk_object_set_description(accessibility_obj, _("Unread Messages")); | 7300 atk_object_set_description(accessibility_obj, _("Unread Messages")); |
| 6991 if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_CHAT) | 7301 if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_CHAT) |
| 6992 style = "tab-label-unreadchat"; | 7302 style = "tab-label-unreadchat"; |
| 6993 else | 7303 else |
| 6994 style = "tab-label-attention"; | 7304 style = "tab-label-attention"; |
| 6995 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) { | 7305 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) { |
| 6996 atk_object_set_description(accessibility_obj, _("New Event")); | 7306 atk_object_set_description(accessibility_obj, _("New Event")); |
| 7198 gtkconv->u.im->iter = NULL; | 7508 gtkconv->u.im->iter = NULL; |
| 7199 | 7509 |
| 7200 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons")) | 7510 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons")) |
| 7201 return; | 7511 return; |
| 7202 | 7512 |
| 7203 if (purple_conversation_get_gc(conv) == NULL) | 7513 if (purple_conversation_get_connection(conv) == NULL) |
| 7204 return; | 7514 return; |
| 7205 | 7515 |
| 7206 buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); | 7516 buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); |
| 7207 if (buddy) | 7517 if (buddy) |
| 7208 { | 7518 { |
| 7284 | 7594 |
| 7285 event = gtk_event_box_new(); | 7595 event = gtk_event_box_new(); |
| 7286 gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event); | 7596 gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event); |
| 7287 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), FALSE); | 7597 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), FALSE); |
| 7288 gtk_widget_add_events(event, | 7598 gtk_widget_add_events(event, |
| 7289 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); | 7599 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); |
| 7290 g_signal_connect(G_OBJECT(event), "button-press-event", | 7600 g_signal_connect(G_OBJECT(event), "button-press-event", |
| 7291 G_CALLBACK(icon_menu), gtkconv); | 7601 G_CALLBACK(icon_menu), gtkconv); |
| 7292 | 7602 |
| 7293 pidgin_tooltip_setup_for_widget(event, gtkconv, pidgin_conv_create_tooltip, NULL); | 7603 pidgin_tooltip_setup_for_widget(event, gtkconv, pidgin_conv_create_tooltip, NULL); |
| 7294 gtk_widget_show(event); | 7604 gtk_widget_show(event); |
| 7326 static gboolean | 7636 static gboolean |
| 7327 pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y) | 7637 pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y) |
| 7328 { | 7638 { |
| 7329 gint pane_x, pane_y, x_rel; | 7639 gint pane_x, pane_y, x_rel; |
| 7330 PidginConversation *gtkconv; | 7640 PidginConversation *gtkconv; |
| 7331 GtkAllocation allocation; | 7641 |
| 7332 | 7642 gdk_window_get_origin(win->notebook->window, &pane_x, &pane_y); |
| 7333 gdk_window_get_origin(gtk_widget_get_window(win->notebook), | |
| 7334 &pane_x, &pane_y); | |
| 7335 x_rel = x - pane_x; | 7643 x_rel = x - pane_x; |
| 7336 gtkconv = pidgin_conv_window_get_active_gtkconv(win); | 7644 gtkconv = pidgin_conv_window_get_active_gtkconv(win); |
| 7337 gtk_widget_get_allocation(gtkconv->infopane, &allocation); | 7645 return (x_rel > gtkconv->infopane->allocation.x + gtkconv->infopane->allocation.width / 2); |
| 7338 return (x_rel > allocation.x + allocation.width / 2); | |
| 7339 } | 7646 } |
| 7340 | 7647 |
| 7341 int | 7648 int |
| 7342 pidgin_conv_get_tab_at_xy(PidginWindow *win, int x, int y, gboolean *to_right) | 7649 pidgin_conv_get_tab_at_xy(PidginWindow *win, int x, int y, gboolean *to_right) |
| 7343 { | 7650 { |
| 7351 if (to_right) | 7658 if (to_right) |
| 7352 *to_right = FALSE; | 7659 *to_right = FALSE; |
| 7353 | 7660 |
| 7354 notebook = GTK_NOTEBOOK(win->notebook); | 7661 notebook = GTK_NOTEBOOK(win->notebook); |
| 7355 | 7662 |
| 7356 gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y); | 7663 gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y); |
| 7357 x_rel = x - nb_x; | 7664 x_rel = x - nb_x; |
| 7358 y_rel = y - nb_y; | 7665 y_rel = y - nb_y; |
| 7359 | 7666 |
| 7360 horiz = (gtk_notebook_get_tab_pos(notebook) == GTK_POS_TOP || | 7667 horiz = (gtk_notebook_get_tab_pos(notebook) == GTK_POS_TOP || |
| 7361 gtk_notebook_get_tab_pos(notebook) == GTK_POS_BOTTOM); | 7668 gtk_notebook_get_tab_pos(notebook) == GTK_POS_BOTTOM); |
| 7362 | 7669 |
| 7363 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook)); | 7670 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook)); |
| 7364 | 7671 |
| 7365 for (i = 0; i < count; i++) { | 7672 for (i = 0; i < count; i++) { |
| 7366 GtkAllocation allocation; | |
| 7367 | 7673 |
| 7368 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i); | 7674 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i); |
| 7369 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page); | 7675 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page); |
| 7370 gtk_widget_get_allocation(tab, &allocation); | |
| 7371 | 7676 |
| 7372 /* Make sure the tab is not hidden beyond an arrow */ | 7677 /* Make sure the tab is not hidden beyond an arrow */ |
| 7373 if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook)) | 7678 if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook)) |
| 7374 continue; | 7679 continue; |
| 7375 | 7680 |
| 7376 if (horiz) { | 7681 if (horiz) { |
| 7377 if (x_rel >= allocation.x - PIDGIN_HIG_BOX_SPACE && | 7682 if (x_rel >= tab->allocation.x - PIDGIN_HIG_BOX_SPACE && |
| 7378 x_rel <= allocation.x + allocation.width + PIDGIN_HIG_BOX_SPACE) { | 7683 x_rel <= tab->allocation.x + tab->allocation.width + PIDGIN_HIG_BOX_SPACE) { |
| 7379 page_num = i; | 7684 page_num = i; |
| 7380 | 7685 |
| 7381 if (to_right && x_rel >= allocation.x + allocation.width/2) | 7686 if (to_right && x_rel >= tab->allocation.x + tab->allocation.width/2) |
| 7382 *to_right = TRUE; | 7687 *to_right = TRUE; |
| 7383 | 7688 |
| 7384 break; | 7689 break; |
| 7385 } | 7690 } |
| 7386 } else { | 7691 } else { |
| 7387 if (y_rel >= allocation.y - PIDGIN_HIG_BOX_SPACE && | 7692 if (y_rel >= tab->allocation.y - PIDGIN_HIG_BOX_SPACE && |
| 7388 y_rel <= allocation.y + allocation.height + PIDGIN_HIG_BOX_SPACE) { | 7693 y_rel <= tab->allocation.y + tab->allocation.height + PIDGIN_HIG_BOX_SPACE) { |
| 7389 page_num = i; | 7694 page_num = i; |
| 7390 | 7695 |
| 7391 if (to_right && y_rel >= allocation.y + allocation.height/2) | 7696 if (to_right && y_rel >= tab->allocation.y + tab->allocation.height/2) |
| 7392 *to_right = TRUE; | 7697 *to_right = TRUE; |
| 7393 | 7698 |
| 7394 break; | 7699 break; |
| 7395 } | 7700 } |
| 7396 } | 7701 } |
| 7497 | 7802 |
| 7498 gtk_toggle_action_set_active( | 7803 gtk_toggle_action_set_active( |
| 7499 GTK_TOGGLE_ACTION(win->menu.show_timestamps), | 7804 GTK_TOGGLE_ACTION(win->menu.show_timestamps), |
| 7500 (gboolean)GPOINTER_TO_INT(value)); | 7805 (gboolean)GPOINTER_TO_INT(value)); |
| 7501 | 7806 |
| 7807 /* TODO WEBKIT: Use WebKit version of this. */ | |
| 7808 #if 0 | |
| 7502 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), | 7809 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), |
| 7503 (gboolean)GPOINTER_TO_INT(value)); | 7810 (gboolean)GPOINTER_TO_INT(value)); |
| 7811 #endif /* if 0 */ | |
| 7504 } | 7812 } |
| 7505 } | 7813 } |
| 7506 | 7814 |
| 7507 static void | 7815 static void |
| 7508 show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type, | 7816 show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type, |
| 7666 gtkconv = l->data; | 7974 gtkconv = l->data; |
| 7667 l = l->next; | 7975 l = l->next; |
| 7668 | 7976 |
| 7669 conv = gtkconv->active_conv; | 7977 conv = gtkconv->active_conv; |
| 7670 | 7978 |
| 7671 if (conv->type == PURPLE_CONV_TYPE_CHAT || | 7979 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT || |
| 7672 gtkconv->unseen_count == 0 || | 7980 gtkconv->unseen_count == 0 || |
| 7673 (when_away && !purple_status_is_available( | 7981 (when_away && !purple_status_is_available( |
| 7674 purple_account_get_active_status( | 7982 purple_account_get_active_status( |
| 7675 purple_conversation_get_account(conv))))) | 7983 purple_conversation_get_account(conv))))) |
| 7676 continue; | 7984 continue; |
| 7706 | 8014 |
| 7707 for (; node; node = node->next) | 8015 for (; node; node = node->next) |
| 7708 { | 8016 { |
| 7709 PurpleBuddy *buddy = (PurpleBuddy*)node; | 8017 PurpleBuddy *buddy = (PurpleBuddy*)node; |
| 7710 PurpleConversation *conv; | 8018 PurpleConversation *conv; |
| 7711 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account); | 8019 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); |
| 7712 if (conv) | 8020 if (conv) |
| 7713 return PIDGIN_CONVERSATION(conv); | 8021 return PIDGIN_CONVERSATION(conv); |
| 7714 } | 8022 } |
| 7715 return NULL; | 8023 return NULL; |
| 7716 } | 8024 } |
| 7731 /* if (purple_conversation_get_account(conv) == account) */ | 8039 /* if (purple_conversation_get_account(conv) == account) */ |
| 7732 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | | 8040 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | |
| 7733 PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE); | 8041 PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE); |
| 7734 | 8042 |
| 7735 if (PURPLE_CONNECTION_IS_CONNECTED(gc) && | 8043 if (PURPLE_CONNECTION_IS_CONNECTED(gc) && |
| 7736 conv->type == PURPLE_CONV_TYPE_CHAT && | 8044 purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT && |
| 7737 conv->account == gc->account && | 8045 purple_conversation_get_account(conv) == purple_connection_get_account(gc) && |
| 7738 purple_conversation_get_data(conv, "want-to-rejoin")) { | 8046 purple_conversation_get_data(conv, "want-to-rejoin")) { |
| 7739 GHashTable *comps = NULL; | 8047 GHashTable *comps = NULL; |
| 7740 PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name); | 8048 PurpleChat *chat = purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); |
| 7741 if (chat == NULL) { | 8049 if (chat == NULL) { |
| 7742 if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) | 8050 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 7743 comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, conv->name); | 8051 |
| 8052 if (prpl_info->chat_info_defaults != NULL) | |
| 8053 comps = prpl_info->chat_info_defaults(gc, purple_conversation_get_name(conv)); | |
| 7744 } else { | 8054 } else { |
| 7745 comps = chat->components; | 8055 comps = purple_chat_get_components(chat); |
| 7746 } | 8056 } |
| 7747 serv_join_chat(gc, comps); | 8057 serv_join_chat(gc, comps); |
| 7748 if (chat == NULL && comps != NULL) | 8058 if (chat == NULL && comps != NULL) |
| 7749 g_hash_table_destroy(comps); | 8059 g_hash_table_destroy(comps); |
| 7750 } | 8060 } |
| 7807 static void | 8117 static void |
| 7808 update_buddy_idle_changed(PurpleBuddy *buddy, gboolean old, gboolean newidle) | 8118 update_buddy_idle_changed(PurpleBuddy *buddy, gboolean old, gboolean newidle) |
| 7809 { | 8119 { |
| 7810 PurpleConversation *conv; | 8120 PurpleConversation *conv; |
| 7811 | 8121 |
| 7812 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account); | 8122 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); |
| 7813 if (conv) | 8123 if (conv) |
| 7814 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON); | 8124 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON); |
| 7815 } | 8125 } |
| 7816 | 8126 |
| 7817 static void | 8127 static void |
| 7818 update_buddy_icon(PurpleBuddy *buddy) | 8128 update_buddy_icon(PurpleBuddy *buddy) |
| 7819 { | 8129 { |
| 7820 PurpleConversation *conv; | 8130 PurpleConversation *conv; |
| 7821 | 8131 |
| 7822 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account); | 8132 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); |
| 7823 if (conv) | 8133 if (conv) |
| 7824 pidgin_conv_update_fields(conv, PIDGIN_CONV_BUDDY_ICON); | 8134 pidgin_conv_update_fields(conv, PIDGIN_CONV_BUDDY_ICON); |
| 7825 } | 8135 } |
| 7826 | 8136 |
| 7827 static void | 8137 static void |
| 7882 /* Compare two PurpleConvMessage's, according to time in ascending order. */ | 8192 /* Compare two PurpleConvMessage's, according to time in ascending order. */ |
| 7883 static int | 8193 static int |
| 7884 message_compare(gconstpointer p1, gconstpointer p2) | 8194 message_compare(gconstpointer p1, gconstpointer p2) |
| 7885 { | 8195 { |
| 7886 const PurpleConvMessage *m1 = p1, *m2 = p2; | 8196 const PurpleConvMessage *m1 = p1, *m2 = p2; |
| 7887 return (m1->when > m2->when); | 8197 return (purple_conversation_message_get_timestamp(m1) > purple_conversation_message_get_timestamp(m2)); |
| 7888 } | 8198 } |
| 7889 | 8199 |
| 7890 /* Adds some message history to the gtkconv. This happens in a idle-callback. */ | 8200 /* Adds some message history to the gtkconv. This happens in a idle-callback. */ |
| 7891 static gboolean | 8201 static gboolean |
| 7892 add_message_history_to_gtkconv(gpointer data) | 8202 add_message_history_to_gtkconv(gpointer data) |
| 7893 { | 8203 { |
| 7894 PidginConversation *gtkconv = data; | 8204 PidginConversation *gtkconv = data; |
| 7895 int count = 0; | 8205 int count = 0; |
| 7896 int timer = gtkconv->attach.timer; | 8206 int timer = gtkconv->attach.timer; |
| 7897 time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time")); | 8207 time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time")); |
| 7898 gboolean im = (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM); | 8208 gboolean im = (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM); |
| 7899 | 8209 |
| 7900 gtkconv->attach.timer = 0; | 8210 gtkconv->attach.timer = 0; |
| 7901 while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ | 8211 while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ |
| 7902 PurpleConvMessage *msg = gtkconv->attach.current->data; | 8212 PurpleConvMessage *msg = gtkconv->attach.current->data; |
| 7903 if (!im && when && when < msg->when) { | 8213 if (!im && when && when < purple_conversation_message_get_timestamp(msg)) { |
| 7904 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0); | 8214 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<BR><HR>"); |
| 7905 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); | 8215 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
| 7906 } | 8216 } |
| 7907 pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when); | 8217 pidgin_conv_write_conv( |
| 8218 purple_conversation_message_get_conv(msg), | |
| 8219 purple_conversation_message_get_sender(msg), | |
| 8220 purple_conversation_message_get_alias(msg), | |
| 8221 purple_conversation_message_get_message(msg), | |
| 8222 purple_conversation_message_get_flags(msg), | |
| 8223 purple_conversation_message_get_timestamp(msg)); | |
| 7908 if (im) { | 8224 if (im) { |
| 7909 gtkconv->attach.current = g_list_delete_link(gtkconv->attach.current, gtkconv->attach.current); | 8225 gtkconv->attach.current = g_list_delete_link(gtkconv->attach.current, gtkconv->attach.current); |
| 7910 } else { | 8226 } else { |
| 7911 gtkconv->attach.current = gtkconv->attach.current->prev; | 8227 gtkconv->attach.current = gtkconv->attach.current->prev; |
| 7912 } | 8228 } |
| 7925 for (; iter; iter = iter->next) { | 8241 for (; iter; iter = iter->next) { |
| 7926 PurpleConversation *conv = iter->data; | 8242 PurpleConversation *conv = iter->data; |
| 7927 GList *history = purple_conversation_get_message_history(conv); | 8243 GList *history = purple_conversation_get_message_history(conv); |
| 7928 for (; history; history = history->next) { | 8244 for (; history; history = history->next) { |
| 7929 PurpleConvMessage *msg = history->data; | 8245 PurpleConvMessage *msg = history->data; |
| 7930 if (msg->when > when) | 8246 if (purple_conversation_message_get_timestamp(msg) > when) |
| 7931 msgs = g_list_prepend(msgs, msg); | 8247 msgs = g_list_prepend(msgs, msg); |
| 7932 } | 8248 } |
| 7933 } | 8249 } |
| 7934 msgs = g_list_sort(msgs, message_compare); | 8250 msgs = g_list_sort(msgs, message_compare); |
| 7935 for (; msgs; msgs = g_list_delete_link(msgs, msgs)) { | 8251 for (; msgs; msgs = g_list_delete_link(msgs, msgs)) { |
| 7936 PurpleConvMessage *msg = msgs->data; | 8252 PurpleConvMessage *msg = msgs->data; |
| 7937 pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when); | 8253 pidgin_conv_write_conv( |
| 7938 } | 8254 purple_conversation_message_get_conv(msg), |
| 7939 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0); | 8255 purple_conversation_message_get_sender(msg), |
| 8256 purple_conversation_message_get_alias(msg), | |
| 8257 purple_conversation_message_get_message(msg), | |
| 8258 purple_conversation_message_get_flags(msg), | |
| 8259 purple_conversation_message_get_timestamp(msg)); | |
| 8260 } | |
| 8261 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<BR><HR>"); | |
| 7940 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); | 8262 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
| 7941 } | 8263 } |
| 7942 | 8264 |
| 7943 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); | 8265 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
| 7944 purple_signal_emit(pidgin_conversations_get_handle(), | 8266 purple_signal_emit(pidgin_conversations_get_handle(), |
| 8010 break; | 8332 break; |
| 8011 default: | 8333 default: |
| 8012 g_return_val_if_reached(TRUE); | 8334 g_return_val_if_reached(TRUE); |
| 8013 } | 8335 } |
| 8014 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", | 8336 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", |
| 8015 GINT_TO_POINTER(((PurpleConvMessage*)(list->data))->when)); | 8337 GINT_TO_POINTER(purple_conversation_message_get_timestamp((PurpleConvMessage*)(list->data)))); |
| 8016 gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv); | 8338 gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv); |
| 8017 } else { | 8339 } else { |
| 8018 purple_signal_emit(pidgin_conversations_get_handle(), | 8340 purple_signal_emit(pidgin_conversations_get_handle(), |
| 8019 "conversation-displayed", gtkconv); | 8341 "conversation-displayed", gtkconv); |
| 8020 } | 8342 } |
| 8021 | 8343 |
| 8022 if (conv->type == PURPLE_CONV_TYPE_CHAT) { | 8344 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
| 8023 pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC); | 8345 pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC); |
| 8024 pidgin_conv_chat_add_users(conv, PURPLE_CONV_CHAT(conv)->in_room, TRUE); | 8346 pidgin_conv_chat_add_users(conv, purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv)), TRUE); |
| 8025 } | 8347 } |
| 8026 | 8348 |
| 8027 return TRUE; | 8349 return TRUE; |
| 8028 } | 8350 } |
| 8029 | 8351 |
| 8041 void *handle = pidgin_conversations_get_handle(); | 8363 void *handle = pidgin_conversations_get_handle(); |
| 8042 void *blist_handle = purple_blist_get_handle(); | 8364 void *blist_handle = purple_blist_get_handle(); |
| 8043 | 8365 |
| 8044 /* Conversations */ | 8366 /* Conversations */ |
| 8045 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations"); | 8367 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations"); |
| 8368 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations/themes"); | |
| 8046 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE); | 8369 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE); |
| 8047 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE); | 8370 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE); |
| 8048 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", FALSE); | 8371 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", FALSE); |
| 8049 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic", FALSE); | 8372 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic", FALSE); |
| 8050 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline", FALSE); | 8373 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline", FALSE); |
| 8128 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons", | 8451 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons", |
| 8129 show_buddy_icons_pref_cb, NULL); | 8452 show_buddy_icons_pref_cb, NULL); |
| 8130 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons", | 8453 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons", |
| 8131 show_protocol_icons_pref_cb, NULL); | 8454 show_protocol_icons_pref_cb, NULL); |
| 8132 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new", | 8455 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new", |
| 8133 hide_new_pref_cb, NULL); | 8456 hide_new_pref_cb, NULL); |
| 8134 | 8457 |
| 8135 | 8458 |
| 8136 | 8459 |
| 8137 /********************************************************************** | 8460 /********************************************************************** |
| 8138 * Register signals | 8461 * Register signals |
| 8285 | 8608 |
| 8286 hidden_convwin = pidgin_conv_window_new(); | 8609 hidden_convwin = pidgin_conv_window_new(); |
| 8287 window_list = g_list_remove(window_list, hidden_convwin); | 8610 window_list = g_list_remove(window_list, hidden_convwin); |
| 8288 | 8611 |
| 8289 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", | 8612 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", |
| 8290 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); | 8613 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); |
| 8291 | 8614 |
| 8292 /* Callbacks to update a conversation */ | 8615 /* Callbacks to update a conversation */ |
| 8293 purple_signal_connect(blist_handle, "blist-node-added", handle, | 8616 purple_signal_connect(blist_handle, "blist-node-added", handle, |
| 8294 G_CALLBACK(buddy_update_cb), NULL); | 8617 G_CALLBACK(buddy_update_cb), NULL); |
| 8295 purple_signal_connect(blist_handle, "blist-node-removed", handle, | 8618 purple_signal_connect(blist_handle, "blist-node-removed", handle, |
| 8324 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle, | 8647 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle, |
| 8325 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); | 8648 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
| 8326 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, | 8649 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, |
| 8327 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); | 8650 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
| 8328 | 8651 |
| 8652 purple_theme_manager_register_type(g_object_new(PIDGIN_TYPE_CONV_THEME_LOADER, "type", "conversation", NULL)); | |
| 8653 | |
| 8329 { | 8654 { |
| 8330 /* Set default tab colors */ | 8655 /* Set default tab colors */ |
| 8331 GString *str = g_string_new(NULL); | 8656 GString *str = g_string_new(NULL); |
| 8332 GtkSettings *settings = gtk_settings_get_default(); | 8657 GtkSettings *settings = gtk_settings_get_default(); |
| 8333 GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now; | 8658 GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now; |
| 8469 GTK_RESPONSE_OK); | 8794 GTK_RESPONSE_OK); |
| 8470 | 8795 |
| 8471 gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog), | 8796 gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog), |
| 8472 6); | 8797 6); |
| 8473 gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE); | 8798 gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE); |
| 8474 | 8799 #if !GTK_CHECK_VERSION(2,22,0) |
| 8475 /* TODO: figure out how to set no separator in GTK+ 3.0 */ | 8800 gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), FALSE); |
| 8476 #if 0 | |
| 8477 gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), | |
| 8478 FALSE); | |
| 8479 #endif | 8801 #endif |
| 8480 | 8802 |
| 8481 /* Setup the outside spacing. */ | 8803 /* Setup the outside spacing. */ |
| 8482 vbox = gtk_dialog_get_content_area(GTK_DIALOG(warn_close_dialog)); | 8804 vbox = GTK_DIALOG(warn_close_dialog)->vbox; |
| 8483 | 8805 |
| 8484 gtk_box_set_spacing(GTK_BOX(vbox), 12); | 8806 gtk_box_set_spacing(GTK_BOX(vbox), 12); |
| 8485 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); | 8807 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); |
| 8486 | 8808 |
| 8487 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_WARNING, | 8809 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_WARNING, |
| 8631 #ifndef _WIN32 | 8953 #ifndef _WIN32 |
| 8632 /* Currently for win32 GTK+ (as of 2.2.1), gdk_pointer_is_grabbed will | 8954 /* Currently for win32 GTK+ (as of 2.2.1), gdk_pointer_is_grabbed will |
| 8633 always be true after a button press. */ | 8955 always be true after a button press. */ |
| 8634 if (!gdk_pointer_is_grabbed()) | 8956 if (!gdk_pointer_is_grabbed()) |
| 8635 #endif | 8957 #endif |
| 8636 gdk_pointer_grab(gtk_widget_get_window(gtkwin->notebook), FALSE, | 8958 gdk_pointer_grab(gtkwin->notebook->window, FALSE, |
| 8637 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, | 8959 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, |
| 8638 NULL, cursor, GDK_CURRENT_TIME); | 8960 NULL, cursor, GDK_CURRENT_TIME); |
| 8639 } | 8961 } |
| 8640 | 8962 |
| 8641 static gboolean | 8963 static gboolean |
| 8751 if (e->type != GDK_BUTTON_PRESS) | 9073 if (e->type != GDK_BUTTON_PRESS) |
| 8752 return FALSE; | 9074 return FALSE; |
| 8753 | 9075 |
| 8754 if (e->button == 1) { | 9076 if (e->button == 1) { |
| 8755 int nb_x, nb_y; | 9077 int nb_x, nb_y; |
| 8756 GtkAllocation allocation; | |
| 8757 | |
| 8758 gtk_widget_get_allocation(gtkconv->infopane_hbox, &allocation); | |
| 8759 | 9078 |
| 8760 if (gtkconv->win->in_drag) | 9079 if (gtkconv->win->in_drag) |
| 8761 return TRUE; | 9080 return TRUE; |
| 8762 | 9081 |
| 8763 gtkconv->win->in_predrag = TRUE; | 9082 gtkconv->win->in_predrag = TRUE; |
| 8764 gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont); | 9083 gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont); |
| 8765 | 9084 |
| 8766 gdk_window_get_origin(gtk_widget_get_window(gtkconv->infopane_hbox), &nb_x, &nb_y); | 9085 gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y); |
| 8767 | 9086 |
| 8768 gtkconv->win->drag_min_x = allocation.x + nb_x; | 9087 gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x; |
| 8769 gtkconv->win->drag_min_y = allocation.y + nb_y; | 9088 gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y; |
| 8770 gtkconv->win->drag_max_x = allocation.width + gtkconv->win->drag_min_x; | 9089 gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x; |
| 8771 gtkconv->win->drag_max_y = allocation.height + gtkconv->win->drag_min_y; | 9090 gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y; |
| 8772 | 9091 |
| 8773 gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event", | 9092 gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event", |
| 8774 G_CALLBACK(notebook_motion_cb), gtkconv->win); | 9093 G_CALLBACK(notebook_motion_cb), gtkconv->win); |
| 8775 gtkconv->win->drag_leave_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event", | 9094 gtkconv->win->drag_leave_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event", |
| 8776 G_CALLBACK(notebook_leave_cb), gtkconv->win); | 9095 G_CALLBACK(notebook_leave_cb), gtkconv->win); |
| 8779 | 9098 |
| 8780 if (e->button == 3) { | 9099 if (e->button == 3) { |
| 8781 /* Right click was pressed. Popup the context menu. */ | 9100 /* Right click was pressed. Popup the context menu. */ |
| 8782 GtkWidget *menu = gtk_menu_new(), *sub; | 9101 GtkWidget *menu = gtk_menu_new(), *sub; |
| 8783 gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE); | 9102 gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE); |
| 8784 #if 0 /* TODO */ | 9103 |
| 8785 sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to)); | 9104 sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to)); |
| 8786 | 9105 if (sub && gtk_widget_is_sensitive(gtkconv->win->menu.send_to)) { |
| 8787 if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) { | |
| 8788 GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To")); | 9106 GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To")); |
| 8789 if (populated) | 9107 if (populated) |
| 8790 pidgin_separator(menu); | 9108 pidgin_separator(menu); |
| 8791 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | 9109 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
| 8792 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), sub); | 9110 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), sub); |
| 8794 gtk_widget_show_all(sub); | 9112 gtk_widget_show_all(sub); |
| 8795 } else if (!populated) { | 9113 } else if (!populated) { |
| 8796 gtk_widget_destroy(menu); | 9114 gtk_widget_destroy(menu); |
| 8797 return FALSE; | 9115 return FALSE; |
| 8798 } | 9116 } |
| 8799 #endif | 9117 |
| 8800 gtk_widget_show_all(menu); | 9118 gtk_widget_show_all(menu); |
| 8801 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time); | 9119 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time); |
| 8802 return TRUE; | 9120 return TRUE; |
| 8803 } | 9121 } |
| 8804 return FALSE; | 9122 return FALSE; |
| 8809 { | 9127 { |
| 8810 gint nb_x, nb_y; | 9128 gint nb_x, nb_y; |
| 8811 int tab_clicked; | 9129 int tab_clicked; |
| 8812 GtkWidget *page; | 9130 GtkWidget *page; |
| 8813 GtkWidget *tab; | 9131 GtkWidget *tab; |
| 8814 GtkAllocation allocation; | |
| 8815 | 9132 |
| 8816 if (e->button == 2 && e->type == GDK_BUTTON_PRESS) { | 9133 if (e->button == 2 && e->type == GDK_BUTTON_PRESS) { |
| 8817 PidginConversation *gtkconv; | 9134 PidginConversation *gtkconv; |
| 8818 tab_clicked = pidgin_conv_get_tab_at_xy(win, e->x_root, e->y_root, NULL); | 9135 tab_clicked = pidgin_conv_get_tab_at_xy(win, e->x_root, e->y_root, NULL); |
| 8819 | 9136 |
| 8847 | 9164 |
| 8848 /* | 9165 /* |
| 8849 * Get the relative position of the press event, with regards to | 9166 * Get the relative position of the press event, with regards to |
| 8850 * the position of the notebook. | 9167 * the position of the notebook. |
| 8851 */ | 9168 */ |
| 8852 gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y); | 9169 gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y); |
| 8853 | 9170 |
| 8854 /* Reset the min/max x/y */ | 9171 /* Reset the min/max x/y */ |
| 8855 win->drag_min_x = 0; | 9172 win->drag_min_x = 0; |
| 8856 win->drag_min_y = 0; | 9173 win->drag_min_y = 0; |
| 8857 win->drag_max_x = 0; | 9174 win->drag_max_x = 0; |
| 8859 | 9176 |
| 8860 /* Find out which tab was dragged. */ | 9177 /* Find out which tab was dragged. */ |
| 8861 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked); | 9178 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked); |
| 8862 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page); | 9179 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page); |
| 8863 | 9180 |
| 8864 gtk_widget_get_allocation(tab, &allocation); | 9181 win->drag_min_x = tab->allocation.x + nb_x; |
| 8865 | 9182 win->drag_min_y = tab->allocation.y + nb_y; |
| 8866 win->drag_min_x = allocation.x + nb_x; | 9183 win->drag_max_x = tab->allocation.width + win->drag_min_x; |
| 8867 win->drag_min_y = allocation.y + nb_y; | 9184 win->drag_max_y = tab->allocation.height + win->drag_min_y; |
| 8868 win->drag_max_x = allocation.width + win->drag_min_x; | |
| 8869 win->drag_max_y = allocation.height + win->drag_min_y; | |
| 8870 | 9185 |
| 8871 /* Make sure the click occurred in the tab. */ | 9186 /* Make sure the click occurred in the tab. */ |
| 8872 if (e->x_root < win->drag_min_x || | 9187 if (e->x_root < win->drag_min_x || |
| 8873 e->x_root >= win->drag_max_x || | 9188 e->x_root >= win->drag_max_x || |
| 8874 e->y_root < win->drag_min_y || | 9189 e->y_root < win->drag_min_y || |
| 8875 e->y_root >= win->drag_max_y) { | 9190 e->y_root >= win->drag_max_y) { |
| 8876 | 9191 |
| 8877 return FALSE; | 9192 return FALSE; |
| 8878 } | 9193 } |
| 8879 | 9194 |
| 8880 win->in_predrag = TRUE; | 9195 win->in_predrag = TRUE; |
| 8881 win->drag_tab = tab_clicked; | 9196 win->drag_tab = tab_clicked; |
| 8882 | 9197 |
| 8883 /* Connect the new motion signals. */ | 9198 /* Connect the new motion signals. */ |
| 9101 | 9416 |
| 9102 if (gtkconv) | 9417 if (gtkconv) |
| 9103 close_conv_cb(NULL, gtkconv); | 9418 close_conv_cb(NULL, gtkconv); |
| 9104 } | 9419 } |
| 9105 | 9420 |
| 9106 /* TODO: I don't know if this doable in GTK+ 3.0 */ | |
| 9107 #if 0 | |
| 9108 static gboolean | 9421 static gboolean |
| 9109 right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win) | 9422 right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win) |
| 9110 { | 9423 { |
| 9111 GtkWidget *item; | 9424 GtkWidget *item, *menu; |
| 9112 PidginConversation *gtkconv; | 9425 PidginConversation *gtkconv; |
| 9113 GtkWidget *menu = gtk_notebook_get_menu | |
| 9114 | 9426 |
| 9115 if (event->type != GDK_BUTTON_PRESS || event->button != 3) | 9427 if (event->type != GDK_BUTTON_PRESS || event->button != 3) |
| 9116 return FALSE; | 9428 return FALSE; |
| 9117 | 9429 |
| 9118 gtkconv = pidgin_conv_window_get_gtkconv_at_index(win, | 9430 gtkconv = pidgin_conv_window_get_gtkconv_at_index(win, |
| 9155 g_signal_connect(G_OBJECT(item), "activate", | 9467 g_signal_connect(G_OBJECT(item), "activate", |
| 9156 G_CALLBACK(close_tab_cb), menu); | 9468 G_CALLBACK(close_tab_cb), menu); |
| 9157 | 9469 |
| 9158 return FALSE; | 9470 return FALSE; |
| 9159 } | 9471 } |
| 9160 #endif | |
| 9161 | 9472 |
| 9162 static void | 9473 static void |
| 9163 remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry) | 9474 remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry) |
| 9164 { | 9475 { |
| 9165 g_signal_handlers_disconnect_matched(G_OBJECT(entry), G_SIGNAL_MATCH_DATA, | 9476 g_signal_handlers_disconnect_matched(G_OBJECT(entry), G_SIGNAL_MATCH_DATA, |
| 9177 } | 9488 } |
| 9178 | 9489 |
| 9179 static gboolean | 9490 static gboolean |
| 9180 alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data) | 9491 alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data) |
| 9181 { | 9492 { |
| 9182 if (event->keyval == GDK_KEY_Escape) { | 9493 if (event->keyval == GDK_Escape) { |
| 9183 remove_edit_entry(user_data, widget); | 9494 remove_edit_entry(user_data, widget); |
| 9184 return TRUE; | 9495 return TRUE; |
| 9185 } | 9496 } |
| 9186 return FALSE; | 9497 return FALSE; |
| 9187 } | 9498 } |
| 9204 | 9515 |
| 9205 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 9516 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 9206 PurpleBuddy *buddy; | 9517 PurpleBuddy *buddy; |
| 9207 buddy = purple_find_buddy(account, name); | 9518 buddy = purple_find_buddy(account, name); |
| 9208 if (buddy != NULL) { | 9519 if (buddy != NULL) { |
| 9209 purple_blist_alias_buddy(buddy, gtk_entry_get_text(entry)); | 9520 purple_blist_alias_buddy(buddy, |
| 9521 gtk_entry_get_text(entry)); | |
| 9210 } | 9522 } |
| 9211 serv_alias_buddy(buddy); | 9523 serv_alias_buddy(buddy); |
| 9212 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 9524 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
| 9213 gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry)); | 9525 gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry)); |
| 9214 topic_callback(NULL, gtkconv); | 9526 topic_callback(NULL, gtkconv); |
| 9226 if (!gtk_widget_get_visible(gtkconv->infopane)) { | 9538 if (!gtk_widget_get_visible(gtkconv->infopane)) { |
| 9227 /* There's already an entry for alias. Let's not create another one. */ | 9539 /* There's already an entry for alias. Let's not create another one. */ |
| 9228 return FALSE; | 9540 return FALSE; |
| 9229 } | 9541 } |
| 9230 | 9542 |
| 9231 if (!purple_account_is_connected(gtkconv->active_conv->account)) { | 9543 if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) { |
| 9232 /* Do not allow aliasing someone on a disconnected account. */ | 9544 /* Do not allow aliasing someone on a disconnected account. */ |
| 9233 return FALSE; | 9545 return FALSE; |
| 9234 } | 9546 } |
| 9235 | 9547 |
| 9236 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 9548 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 9237 PurpleBuddy *buddy = purple_find_buddy(gtkconv->active_conv->account, gtkconv->active_conv->name); | 9549 PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv)); |
| 9238 if (!buddy) | 9550 if (!buddy) |
| 9239 /* This buddy isn't in your buddy list, so we can't alias him */ | 9551 /* This buddy isn't in your buddy list, so we can't alias him */ |
| 9240 return FALSE; | 9552 return FALSE; |
| 9241 | 9553 |
| 9242 text = purple_buddy_get_contact_alias(buddy); | 9554 text = purple_buddy_get_contact_alias(buddy); |
| 9243 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 9555 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
| 9244 PurpleConnection *gc; | 9556 PurpleConnection *gc; |
| 9245 PurplePluginProtocolInfo *prpl_info = NULL; | 9557 PurplePluginProtocolInfo *prpl_info = NULL; |
| 9246 | 9558 |
| 9247 gc = purple_conversation_get_gc(conv); | 9559 gc = purple_conversation_get_connection(conv); |
| 9248 if (gc != NULL) | 9560 if (gc != NULL) |
| 9249 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 9561 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
| 9250 if (prpl_info && prpl_info->set_chat_topic == NULL) | 9562 if (prpl_info && prpl_info->set_chat_topic == NULL) |
| 9251 /* This protocol doesn't support setting the chat room topic */ | 9563 /* This protocol doesn't support setting the chat room topic */ |
| 9252 return FALSE; | 9564 return FALSE; |
| 9253 | 9565 |
| 9254 text = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv)); | 9566 text = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv)); |
| 9350 | 9662 |
| 9351 static GList* | 9663 static GList* |
| 9352 make_status_icon_list(const char *stock, GtkWidget *w) | 9664 make_status_icon_list(const char *stock, GtkWidget *w) |
| 9353 { | 9665 { |
| 9354 GList *l = NULL; | 9666 GList *l = NULL; |
| 9355 l = g_list_append(l, | 9667 l = g_list_append(l, gtk_widget_render_icon (w, stock, |
| 9356 gtk_widget_render_icon(w, stock, | 9668 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow")); |
| 9357 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow")); | 9669 l = g_list_append(l, gtk_widget_render_icon (w, stock, |
| 9358 l = g_list_append(l, | 9670 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow")); |
| 9359 gtk_widget_render_icon(w, stock, | 9671 l = g_list_append(l, gtk_widget_render_icon (w, stock, |
| 9360 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow")); | 9672 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow")); |
| 9361 l = g_list_append(l, | 9673 l = g_list_append(l, gtk_widget_render_icon (w, stock, |
| 9362 gtk_widget_render_icon(w, stock, | 9674 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow")); |
| 9363 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow")); | |
| 9364 l = g_list_append(l, | |
| 9365 gtk_widget_render_icon(w, stock, | |
| 9366 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow")); | |
| 9367 return l; | 9675 return l; |
| 9368 } | 9676 } |
| 9369 | 9677 |
| 9370 static void | 9678 static void |
| 9371 create_icon_lists(GtkWidget *w) | 9679 create_icon_lists(GtkWidget *w) |
| 9392 else | 9700 else |
| 9393 return FALSE; /* carry on normally */ | 9701 return FALSE; /* carry on normally */ |
| 9394 | 9702 |
| 9395 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired | 9703 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired |
| 9396 * when the window is being maximized */ | 9704 * when the window is being maximized */ |
| 9397 if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED) | 9705 if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) |
| 9398 return FALSE; | 9706 return FALSE; |
| 9399 | 9707 |
| 9400 /* don't save off-screen positioning */ | 9708 /* don't save off-screen positioning */ |
| 9401 if (x + event->width < 0 || | 9709 if (x + event->width < 0 || |
| 9402 y + event->height < 0 || | 9710 y + event->height < 0 || |
| 9417 | 9725 |
| 9418 static void | 9726 static void |
| 9419 pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y, | 9727 pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y, |
| 9420 int conv_width, int conv_height) | 9728 int conv_width, int conv_height) |
| 9421 { | 9729 { |
| 9422 /* if the window exists, is hidden, we're saving positions, and the | 9730 /* if the window exists, is hidden, we're saving positions, and the |
| 9423 * position is sane... */ | 9731 * position is sane... */ |
| 9424 if (win && win->window && | 9732 if (win && win->window && |
| 9425 !gtk_widget_get_visible(win->window) && conv_width != 0) { | 9733 !gtk_widget_get_visible(win->window) && conv_width != 0) { |
| 9426 | 9734 |
| 9427 #ifdef _WIN32 /* only override window manager placement on Windows */ | 9735 #ifdef _WIN32 /* only override window manager placement on Windows */ |
| 9428 /* ...check position is on screen... */ | 9736 /* ...check position is on screen... */ |
| 9505 gtk_notebook_set_scrollable(GTK_NOTEBOOK(win->notebook), TRUE); | 9813 gtk_notebook_set_scrollable(GTK_NOTEBOOK(win->notebook), TRUE); |
| 9506 gtk_notebook_popup_enable(GTK_NOTEBOOK(win->notebook)); | 9814 gtk_notebook_popup_enable(GTK_NOTEBOOK(win->notebook)); |
| 9507 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE); | 9815 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE); |
| 9508 gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE); | 9816 gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE); |
| 9509 | 9817 |
| 9510 /* TODO: figure out how to add custom stuff to the right-click menu in | |
| 9511 GtkNotebook in GTK+ 3.0 */ | |
| 9512 #if 0 | |
| 9513 g_signal_connect(G_OBJECT(win->notebook), "button-press-event", | 9818 g_signal_connect(G_OBJECT(win->notebook), "button-press-event", |
| 9514 G_CALLBACK(right_click_menu_cb), win); | 9819 G_CALLBACK(right_click_menu_cb), win); |
| 9515 #endif | |
| 9516 | 9820 |
| 9517 gtk_widget_show(win->notebook); | 9821 gtk_widget_show(win->notebook); |
| 9518 | 9822 |
| 9519 g_signal_connect(G_OBJECT(win->notebook), "switch_page", | 9823 g_signal_connect(G_OBJECT(win->notebook), "switch_page", |
| 9520 G_CALLBACK(before_switch_conv_cb), win); | 9824 G_CALLBACK(before_switch_conv_cb), win); |
| 9602 } | 9906 } |
| 9603 | 9907 |
| 9604 void | 9908 void |
| 9605 pidgin_conv_window_raise(PidginWindow *win) | 9909 pidgin_conv_window_raise(PidginWindow *win) |
| 9606 { | 9910 { |
| 9607 gdk_window_raise(GDK_WINDOW(gtk_widget_get_window(win->window))); | 9911 gdk_window_raise(GDK_WINDOW(win->window->window)); |
| 9608 } | 9912 } |
| 9609 | 9913 |
| 9610 void | 9914 void |
| 9611 pidgin_conv_window_switch_gtkconv(PidginWindow *win, PidginConversation *gtkconv) | 9915 pidgin_conv_window_switch_gtkconv(PidginWindow *win, PidginConversation *gtkconv) |
| 9612 { | 9916 { |
| 9777 gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE); | 10081 gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE); |
| 9778 gtk_container_add(GTK_CONTAINER(ebox), gtkconv->tabby); | 10082 gtk_container_add(GTK_CONTAINER(ebox), gtkconv->tabby); |
| 9779 g_signal_connect(G_OBJECT(ebox), "enter-notify-event", | 10083 g_signal_connect(G_OBJECT(ebox), "enter-notify-event", |
| 9780 G_CALLBACK(gtkconv_tab_set_tip), gtkconv); | 10084 G_CALLBACK(gtkconv_tab_set_tip), gtkconv); |
| 9781 | 10085 |
| 9782 if (gtk_widget_get_parent(gtkconv->tab_label) == NULL) { | 10086 if (gtkconv->tab_label->parent == NULL) { |
| 9783 /* Pack if it's a new widget */ | 10087 /* Pack if it's a new widget */ |
| 9784 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0); | 10088 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0); |
| 9785 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE, TRUE, 0); | 10089 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE, TRUE, 0); |
| 9786 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), third, FALSE, FALSE, 0); | 10090 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), third, FALSE, FALSE, 0); |
| 9787 | 10091 |
| 9798 | 10102 |
| 9799 /* Reset the tabs label to the new version */ | 10103 /* Reset the tabs label to the new version */ |
| 9800 gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox); | 10104 gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox); |
| 9801 } | 10105 } |
| 9802 | 10106 |
| 9803 g_object_set(G_OBJECT(win->notebook), "expand", !tabs_side && !angle, NULL); | 10107 gtk_container_child_set(GTK_CONTAINER(win->notebook), gtkconv->tab_cont, |
| 10108 "tab-expand", !tabs_side && !angle, | |
| 10109 "tab-fill", TRUE, NULL); | |
| 9804 | 10110 |
| 9805 if (pidgin_conv_window_get_gtkconv_count(win) == 1) | 10111 if (pidgin_conv_window_get_gtkconv_count(win) == 1) |
| 9806 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), | 10112 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), |
| 9807 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") && | 10113 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") && |
| 9808 (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") || | 10114 (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") || |
| 9822 { | 10128 { |
| 9823 unsigned int index; | 10129 unsigned int index; |
| 9824 | 10130 |
| 9825 index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont); | 10131 index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont); |
| 9826 | 10132 |
| 9827 #if GTK_CHECK_VERSION(2,10,0) | |
| 9828 g_object_ref_sink(G_OBJECT(gtkconv->tab_cont)); | 10133 g_object_ref_sink(G_OBJECT(gtkconv->tab_cont)); |
| 9829 #else | |
| 9830 g_object_ref(gtkconv->tab_cont); | |
| 9831 gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont)); | |
| 9832 #endif | |
| 9833 | 10134 |
| 9834 gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index); | 10135 gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index); |
| 9835 | 10136 |
| 9836 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv); | 10137 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv); |
| 9837 | 10138 |
| 9910 gdkwin = gdk_window_get_toplevel(gdkwin); | 10211 gdkwin = gdk_window_get_toplevel(gdkwin); |
| 9911 | 10212 |
| 9912 for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) { | 10213 for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) { |
| 9913 win = l->data; | 10214 win = l->data; |
| 9914 | 10215 |
| 9915 if (gdkwin == gtk_widget_get_window(win->window)) | 10216 if (gdkwin == win->window->window) |
| 9916 return win; | 10217 return win; |
| 9917 } | 10218 } |
| 9918 | 10219 |
| 9919 return NULL; | 10220 return NULL; |
| 9920 } | 10221 } |
| 10039 else | 10340 else |
| 10040 return FALSE; /* carry on normally */ | 10341 return FALSE; /* carry on normally */ |
| 10041 | 10342 |
| 10042 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired | 10343 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired |
| 10043 * when the window is being maximized */ | 10344 * when the window is being maximized */ |
| 10044 if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED) | 10345 if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) |
| 10045 return FALSE; | 10346 return FALSE; |
| 10046 | 10347 |
| 10047 /* don't save off-screen positioning */ | 10348 /* don't save off-screen positioning */ |
| 10048 if (x + event->width < 0 || | 10349 if (x + event->width < 0 || |
| 10049 y + event->height < 0 || | 10350 y + event->height < 0 || |