comparison pidgin/gtkconv.c @ 18068:0b3d6ea61760

propagate from branch 'im.pidgin.pidgin' (head 4b50880d8517570eaa67d4cd9d88c5934bb832f1) to branch 'im.pidgin.pidgin.2.1.0' (head fefd59692d4177b91d52f6d71b1565b76c88725d)
author Richard Laager <rlaager@wiktel.com>
date Thu, 07 Jun 2007 14:48:33 +0000
parents 68d034c6e65d 4ca97b26a8fb
children 40d51793f2d7 873ee0038752
comparison
equal deleted inserted replaced
17782:5eebb9b24e30 18068:0b3d6ea61760
269 269
270 static void 270 static void
271 default_formatize(PidginConversation *c) 271 default_formatize(PidginConversation *c)
272 { 272 {
273 PurpleConversation *conv = c->active_conv; 273 PurpleConversation *conv = c->active_conv;
274 274 gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), conv->features);
275 if (conv->features & PURPLE_CONNECTION_HTML)
276 {
277 char color[8];
278 GdkColor fg_color, bg_color;
279
280 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold") != GTK_IMHTML(c->entry)->edit.bold)
281 gtk_imhtml_toggle_bold(GTK_IMHTML(c->entry));
282
283 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic") != GTK_IMHTML(c->entry)->edit.italic)
284 gtk_imhtml_toggle_italic(GTK_IMHTML(c->entry));
285
286 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline") != GTK_IMHTML(c->entry)->edit.underline)
287 gtk_imhtml_toggle_underline(GTK_IMHTML(c->entry));
288
289 gtk_imhtml_toggle_fontface(GTK_IMHTML(c->entry),
290 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/font_face"));
291
292 if (!(conv->features & PURPLE_CONNECTION_NO_FONTSIZE))
293 {
294 int size = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/font_size");
295
296 /* 3 is the default. */
297 if (size != 3)
298 gtk_imhtml_font_set_size(GTK_IMHTML(c->entry), size);
299 }
300
301 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), "") != 0)
302 {
303 gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"),
304 &fg_color);
305 g_snprintf(color, sizeof(color), "#%02x%02x%02x",
306 fg_color.red / 256,
307 fg_color.green / 256,
308 fg_color.blue / 256);
309 } else
310 strcpy(color, "");
311
312 gtk_imhtml_toggle_forecolor(GTK_IMHTML(c->entry), color);
313
314 if(!(conv->features & PURPLE_CONNECTION_NO_BGCOLOR) &&
315 strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), "") != 0)
316 {
317 gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"),
318 &bg_color);
319 g_snprintf(color, sizeof(color), "#%02x%02x%02x",
320 bg_color.red / 256,
321 bg_color.green / 256,
322 bg_color.blue / 256);
323 } else
324 strcpy(color, "");
325
326 gtk_imhtml_toggle_background(GTK_IMHTML(c->entry), color);
327
328 if (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO)
329 gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(c->entry), TRUE);
330 else
331 gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(c->entry), FALSE);
332 }
333 } 275 }
334 276
335 static void 277 static void
336 clear_formatting_cb(GtkIMHtml *imhtml, PidginConversation *gtkconv) 278 clear_formatting_cb(GtkIMHtml *imhtml, PidginConversation *gtkconv)
337 { 279 {
475 { 417 {
476 PidginConversation *gtkconv; 418 PidginConversation *gtkconv;
477 char *cmd; 419 char *cmd;
478 const char *prefix; 420 const char *prefix;
479 GtkTextIter start; 421 GtkTextIter start;
422 gboolean retval = FALSE;
480 423
481 gtkconv = PIDGIN_CONVERSATION(conv); 424 gtkconv = PIDGIN_CONVERSATION(conv);
482 prefix = pidgin_get_cmd_prefix(); 425 prefix = pidgin_get_cmd_prefix();
483 426
484 cmd = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL); 427 cmd = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL);
498 441
499 gtk_text_iter_forward_chars(&start, g_utf8_strlen(prefix, -1)); 442 gtk_text_iter_forward_chars(&start, g_utf8_strlen(prefix, -1));
500 gtk_text_buffer_get_end_iter(GTK_IMHTML(gtkconv->entry)->text_buffer, &end); 443 gtk_text_buffer_get_end_iter(GTK_IMHTML(gtkconv->entry)->text_buffer, &end);
501 markup = gtk_imhtml_get_markup_range(GTK_IMHTML(gtkconv->entry), &start, &end); 444 markup = gtk_imhtml_get_markup_range(GTK_IMHTML(gtkconv->entry), &start, &end);
502 status = purple_cmd_do_command(conv, cmdline, markup, &error); 445 status = purple_cmd_do_command(conv, cmdline, markup, &error);
503 g_free(cmd);
504 g_free(markup); 446 g_free(markup);
505 447
506 switch (status) { 448 switch (status) {
507 case PURPLE_CMD_STATUS_OK: 449 case PURPLE_CMD_STATUS_OK:
508 return TRUE; 450 retval = TRUE;
451 break;
509 case PURPLE_CMD_STATUS_NOT_FOUND: 452 case PURPLE_CMD_STATUS_NOT_FOUND:
510 return FALSE; 453 {
454 PurplePluginProtocolInfo *prpl_info = NULL;
455 PurpleConnection *gc;
456
457 if ((gc = purple_conversation_get_gc(conv)))
458 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
459
460 if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) {
461 char *firstspace;
462 char *slash;
463
464 firstspace = strchr(cmdline, ' ');
465 if (firstspace != NULL) {
466 slash = strrchr(firstspace, '/');
467 } else {
468 slash = strchr(cmdline, '/');
469 }
470
471 if (slash == NULL) {
472 purple_conversation_write(conv, "", _("Unknown command."), PURPLE_MESSAGE_NO_LOG, time(NULL));
473 retval = TRUE;
474 }
475 }
476 break;
477 }
511 case PURPLE_CMD_STATUS_WRONG_ARGS: 478 case PURPLE_CMD_STATUS_WRONG_ARGS:
512 purple_conversation_write(conv, "", _("Syntax Error: You typed the wrong number of arguments " 479 purple_conversation_write(conv, "", _("Syntax Error: You typed the wrong number of arguments "
513 "to that command."), 480 "to that command."),
514 PURPLE_MESSAGE_NO_LOG, time(NULL)); 481 PURPLE_MESSAGE_NO_LOG, time(NULL));
515 return TRUE; 482 retval = TRUE;
483 break;
516 case PURPLE_CMD_STATUS_FAILED: 484 case PURPLE_CMD_STATUS_FAILED:
517 purple_conversation_write(conv, "", error ? error : _("Your command failed for an unknown reason."), 485 purple_conversation_write(conv, "", error ? error : _("Your command failed for an unknown reason."),
518 PURPLE_MESSAGE_NO_LOG, time(NULL)); 486 PURPLE_MESSAGE_NO_LOG, time(NULL));
519 g_free(error); 487 g_free(error);
520 return TRUE; 488 retval = TRUE;
489 break;
521 case PURPLE_CMD_STATUS_WRONG_TYPE: 490 case PURPLE_CMD_STATUS_WRONG_TYPE:
522 if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 491 if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
523 purple_conversation_write(conv, "", _("That command only works in chats, not IMs."), 492 purple_conversation_write(conv, "", _("That command only works in chats, not IMs."),
524 PURPLE_MESSAGE_NO_LOG, time(NULL)); 493 PURPLE_MESSAGE_NO_LOG, time(NULL));
525 else 494 else
526 purple_conversation_write(conv, "", _("That command only works in IMs, not chats."), 495 purple_conversation_write(conv, "", _("That command only works in IMs, not chats."),
527 PURPLE_MESSAGE_NO_LOG, time(NULL)); 496 PURPLE_MESSAGE_NO_LOG, time(NULL));
528 return TRUE; 497 retval = TRUE;
498 break;
529 case PURPLE_CMD_STATUS_WRONG_PRPL: 499 case PURPLE_CMD_STATUS_WRONG_PRPL:
530 purple_conversation_write(conv, "", _("That command doesn't work on this protocol."), 500 purple_conversation_write(conv, "", _("That command doesn't work on this protocol."),
531 PURPLE_MESSAGE_NO_LOG, time(NULL)); 501 PURPLE_MESSAGE_NO_LOG, time(NULL));
532 return TRUE; 502 retval = TRUE;
503 break;
533 } 504 }
534 } 505 }
535 506
536 g_free(cmd); 507 g_free(cmd);
537 return FALSE; 508 return retval;
538 } 509 }
539 510
540 static void 511 static void
541 send_cb(GtkWidget *widget, PidginConversation *gtkconv) 512 send_cb(GtkWidget *widget, PidginConversation *gtkconv)
542 { 513 {
664 { 635 {
665 prpl_info->get_cb_info(gc, 636 prpl_info->get_cb_info(gc,
666 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); 637 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
667 } 638 }
668 else 639 else
669 prpl_info->get_info(gc, who); 640 pidgin_retrieve_user_info(gc, who);
670 } 641 }
671 } 642 }
672 643
673 644
674 static void 645 static void
675 info_cb(GtkWidget *widget, PidginConversation *gtkconv) 646 info_cb(GtkWidget *widget, PidginConversation *gtkconv)
676 { 647 {
677 PurpleConversation *conv = gtkconv->active_conv; 648 PurpleConversation *conv = gtkconv->active_conv;
678 649
679 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 650 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
680 PurpleNotifyUserInfo *info = purple_notify_user_info_new(); 651 pidgin_retrieve_user_info(purple_conversation_get_gc(conv),
681 purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving..."));
682 purple_notify_userinfo(conv->account->gc, purple_conversation_get_name(conv), info, NULL, NULL);
683 purple_notify_user_info_destroy(info);
684
685 serv_get_info(purple_conversation_get_gc(conv),
686 purple_conversation_get_name(conv)); 652 purple_conversation_get_name(conv));
687
688 gtk_widget_grab_focus(gtkconv->entry); 653 gtk_widget_grab_focus(gtkconv->entry);
689 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 654 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
690 /* Get info of the person currently selected in the GtkTreeView */ 655 /* Get info of the person currently selected in the GtkTreeView */
691 PidginChatPane *gtkchat; 656 PidginChatPane *gtkchat;
692 GtkTreeIter iter; 657 GtkTreeIter iter;
2257 **************************************************************************/ 2222 **************************************************************************/
2258 2223
2259 static GList *get_prpl_icon_list(PurpleAccount *account) 2224 static GList *get_prpl_icon_list(PurpleAccount *account)
2260 { 2225 {
2261 GList *l = NULL; 2226 GList *l = NULL;
2262 GdkPixbuf *pixbuf; 2227 PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account));
2263 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account))); 2228 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
2264 const char *prpl = prpl_info->list_icon(account, NULL); 2229 const char *prplname = prpl_info->list_icon(account, NULL);
2265 char *filename, *path; 2230 l = g_hash_table_lookup(prpl_lists, prplname);
2266 l = g_hash_table_lookup(prpl_lists, prpl);
2267 if (l) 2231 if (l)
2268 return l; 2232 return l;
2269 filename = g_strdup_printf("%s.png", prpl); 2233
2270 2234 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_LARGE));
2271 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "16", filename, NULL); 2235 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM));
2272 pixbuf = gdk_pixbuf_new_from_file(path, NULL); 2236 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL));
2273 if (pixbuf) 2237
2274 l = g_list_append(l, pixbuf); 2238 g_hash_table_insert(prpl_lists, g_strdup(prplname), l);
2275 g_free(path);
2276
2277 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", filename, NULL);
2278 pixbuf = gdk_pixbuf_new_from_file(path, NULL);
2279 if (pixbuf)
2280 l = g_list_append(l, pixbuf);
2281 g_free(path);
2282
2283 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "48", filename, NULL);
2284 pixbuf = gdk_pixbuf_new_from_file(path, NULL);
2285 if (pixbuf)
2286 l = g_list_append(l, pixbuf);
2287 g_free(path);
2288
2289 g_hash_table_insert(prpl_lists, g_strdup(prpl), l);
2290 return l; 2239 return l;
2291 } 2240 }
2292 2241
2293 static GList * 2242 static GList *
2294 pidgin_conv_get_tab_icons(PurpleConversation *conv) 2243 pidgin_conv_get_tab_icons(PurpleConversation *conv)
2725 pidgin_conversations_find_unseen_list(PurpleConversationType type, 2674 pidgin_conversations_find_unseen_list(PurpleConversationType type,
2726 PidginUnseenState min_state, 2675 PidginUnseenState min_state,
2727 gboolean hidden_only, 2676 gboolean hidden_only,
2728 guint max_count) 2677 guint max_count)
2729 { 2678 {
2730 GList *l; 2679 const GList *l;
2731 GList *r = NULL; 2680 GList *r = NULL;
2732 guint c = 0; 2681 guint c = 0;
2733 2682
2734 if (type == PURPLE_CONV_TYPE_IM) { 2683 if (type == PURPLE_CONV_TYPE_IM) {
2735 l = purple_get_ims(); 2684 l = purple_get_ims();
2979 } 2928 }
2980 2929
2981 gtk_widget_show_all(menu); 2930 gtk_widget_show_all(menu);
2982 } 2931 }
2983 2932
2933 static void
2934 remove_from_list(GtkWidget *widget, PidginWindow *win)
2935 {
2936 GList *list = g_object_get_data(G_OBJECT(win->window), "plugin-actions");
2937 list = g_list_remove(list, widget);
2938 g_object_set_data(G_OBJECT(win->window), "plugin-actions", list);
2939 }
2940
2941 static void
2942 regenerate_plugins_items(PidginWindow *win)
2943 {
2944 GList *action_items;
2945 GtkWidget *menu;
2946 GList *list;
2947 PidginConversation *gtkconv;
2948 PurpleConversation *conv;
2949 GtkWidget *item;
2950
2951 if (win->window == NULL || win == hidden_convwin)
2952 return;
2953
2954 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
2955 if (gtkconv == NULL)
2956 return;
2957
2958 conv = gtkconv->active_conv;
2959 action_items = g_object_get_data(G_OBJECT(win->window), "plugin-actions");
2960
2961 /* Remove the old menuitems */
2962 while (action_items) {
2963 g_signal_handlers_disconnect_by_func(G_OBJECT(action_items->data),
2964 G_CALLBACK(remove_from_list), win);
2965 gtk_widget_destroy(action_items->data);
2966 action_items = g_list_delete_link(action_items, action_items);
2967 }
2968
2969 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options"));
2970
2971 list = purple_conversation_get_extended_menu(conv);
2972 if (list) {
2973 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu)));
2974 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win);
2975 }
2976
2977 for(; list; list = g_list_delete_link(list, list)) {
2978 PurpleMenuAction *act = (PurpleMenuAction *) list->data;
2979 item = pidgin_append_menu_action(menu, act, conv);
2980 action_items = g_list_prepend(action_items, item);
2981 gtk_widget_show_all(item);
2982 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win);
2983 }
2984 g_object_set_data(G_OBJECT(win->window), "plugin-actions", action_items);
2985 }
2986
2984 static void menubar_activated(GtkWidget *item, gpointer data) 2987 static void menubar_activated(GtkWidget *item, gpointer data)
2985 { 2988 {
2986 PidginWindow *win = data; 2989 PidginWindow *win = data;
2987 regenerate_options_items(win); 2990 regenerate_options_items(win);
2991 regenerate_plugins_items(win);
2988 2992
2989 /* The following are to make sure the 'More' submenu is not regenerated every time 2993 /* The following are to make sure the 'More' submenu is not regenerated every time
2990 * the focus shifts from 'Conversations' to some other menu and back. */ 2994 * the focus shifts from 'Conversations' to some other menu and back. */
2991 g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data); 2995 g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data);
2992 g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), data); 2996 g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), data);
3796 &matches, TRUE, l->data); 3800 &matches, TRUE, l->data);
3797 } 3801 }
3798 g_list_free(list); 3802 g_list_free(list);
3799 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 3803 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
3800 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); 3804 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
3801 GList *l = purple_conv_chat_get_users(chat); 3805 const GList *l = purple_conv_chat_get_users(chat);
3802 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list)); 3806 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list));
3803 GtkTreeIter iter; 3807 GtkTreeIter iter;
3804 int f; 3808 int f;
3805 3809
3806 /* Users */ 3810 /* Users */
4194 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height + PIDGIN_HIG_BOX_SPACE); 4198 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height + PIDGIN_HIG_BOX_SPACE);
4195 g_idle_add(reset_auto_resize_cb, gtkconv); 4199 g_idle_add(reset_auto_resize_cb, gtkconv);
4196 } 4200 }
4197 } 4201 }
4198 4202
4199 static GtkWidget * 4203 static void
4200 setup_chat_pane(PidginConversation *gtkconv) 4204 setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox)
4201 { 4205 {
4202 PurplePluginProtocolInfo *prpl_info;
4203 PurpleConversation *conv = gtkconv->active_conv; 4206 PurpleConversation *conv = gtkconv->active_conv;
4204 PidginChatPane *gtkchat; 4207 PurpleConnection *gc = purple_conversation_get_gc(conv);
4205 PurpleConnection *gc; 4208 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
4206 GtkWidget *vpaned, *hpaned;
4207 GtkWidget *vbox, *hbox, *frame;
4208 GtkWidget *imhtml_sw;
4209 GtkPolicyType imhtml_sw_hscroll;
4210 GtkWidget *lbox;
4211 GtkWidget *label;
4212 GtkWidget *list;
4213 GtkWidget *sw;
4214 GtkListStore *ls;
4215 GtkCellRenderer *rend;
4216 GtkTreeViewColumn *col;
4217 void *blist_handle = purple_blist_get_handle();
4218 GList *focus_chain = NULL;
4219 int ul_width;
4220
4221 gtkchat = gtkconv->u.chat;
4222 gc = purple_conversation_get_gc(conv);
4223 g_return_val_if_fail(gc != NULL, NULL);
4224 g_return_val_if_fail(gc->prpl != NULL, NULL);
4225 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
4226
4227 /* Setup the outer pane. */
4228 vpaned = gtk_vpaned_new();
4229 gtk_widget_show(vpaned);
4230
4231 /* Setup the top part of the pane. */
4232 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4233 gtk_paned_pack1(GTK_PANED(vpaned), vbox, TRUE, TRUE);
4234 gtk_widget_show(vbox);
4235
4236 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) 4209 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC)
4237 { 4210 {
4211 GtkWidget *hbox, *label;
4212 PidginChatPane *gtkchat = gtkconv->u.chat;
4213
4238 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 4214 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4239 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); 4215 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
4240 gtk_widget_show(hbox); 4216 gtk_widget_show(hbox);
4241 4217
4242 label = gtk_label_new(_("Topic:")); 4218 label = gtk_label_new(_("Topic:"));
4253 } 4229 }
4254 4230
4255 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); 4231 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0);
4256 gtk_widget_show(gtkchat->topic_text); 4232 gtk_widget_show(gtkchat->topic_text);
4257 } 4233 }
4258 4234 }
4259 /* Setup the horizontal pane. */ 4235
4260 hpaned = gtk_hpaned_new(); 4236 static void
4261 gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); 4237 setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned)
4262 gtk_widget_show(hpaned); 4238 {
4263 4239 PidginChatPane *gtkchat = gtkconv->u.chat;
4264 /* Setup gtkihmtml. */ 4240 GtkWidget *lbox, *sw, *list;
4265 frame = pidgin_create_imhtml(FALSE, &gtkconv->imhtml, NULL, &imhtml_sw); 4241 GtkListStore *ls;
4266 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); 4242 GtkCellRenderer *rend;
4267 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), TRUE); 4243 GtkTreeViewColumn *col;
4268 gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE); 4244 int ul_width;
4269 gtk_widget_show(frame); 4245 void *blist_handle = purple_blist_get_handle();
4270 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), 4246 PurpleConversation *conv = gtkconv->active_conv;
4271 &imhtml_sw_hscroll, NULL);
4272 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
4273 imhtml_sw_hscroll, GTK_POLICY_ALWAYS);
4274
4275 gtk_widget_set_size_request(gtkconv->imhtml,
4276 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width"),
4277 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height"));
4278 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
4279 G_CALLBACK(size_allocate_cb), gtkconv);
4280
4281 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
4282 G_CALLBACK(entry_stop_rclick_cb), NULL);
4283 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
4284 G_CALLBACK(refocus_entry_cb), gtkconv);
4285 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
4286 G_CALLBACK(refocus_entry_cb), gtkconv);
4287 4247
4288 /* Build the right pane. */ 4248 /* Build the right pane. */
4289 lbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 4249 lbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4290 gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE); 4250 gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE);
4291 gtk_widget_show(lbox); 4251 gtk_widget_show(lbox);
4329 G_CALLBACK(right_click_chat_cb), gtkconv); 4289 G_CALLBACK(right_click_chat_cb), gtkconv);
4330 g_signal_connect(G_OBJECT(list), "popup-menu", 4290 g_signal_connect(G_OBJECT(list), "popup-menu",
4331 G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv); 4291 G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv);
4332 g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv); 4292 g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv);
4333 4293
4334
4335 rend = gtk_cell_renderer_text_new(); 4294 rend = gtk_cell_renderer_text_new();
4336
4337 g_object_set(rend, 4295 g_object_set(rend,
4338 "foreground-set", TRUE, 4296 "foreground-set", TRUE,
4339 "weight-set", TRUE, 4297 "weight-set", TRUE,
4340 NULL); 4298 NULL);
4341 col = gtk_tree_view_column_new_with_attributes(NULL, rend, 4299 col = gtk_tree_view_column_new_with_attributes(NULL, rend,
4362 gtk_widget_show(list); 4320 gtk_widget_show(list);
4363 4321
4364 gtkchat->list = list; 4322 gtkchat->list = list;
4365 4323
4366 gtk_container_add(GTK_CONTAINER(sw), list); 4324 gtk_container_add(GTK_CONTAINER(sw), list);
4325 }
4326
4327 static GtkWidget *
4328 setup_common_pane(PidginConversation *gtkconv)
4329 {
4330 GtkWidget *paned, *vbox, *frame, *imhtml_sw;
4331 PurpleConversation *conv = gtkconv->active_conv;
4332 gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT);
4333 GtkPolicyType imhtml_sw_hscroll;
4334
4335 paned = gtk_vpaned_new();
4336 gtk_widget_show(paned);
4337
4338 /* Setup the top part of the pane */
4339 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4340 gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE);
4341 gtk_widget_show(vbox);
4342
4343 /* Setup the gtkimhtml widget */
4344 frame = pidgin_create_imhtml(FALSE, &gtkconv->imhtml, NULL, &imhtml_sw);
4345 if (chat) {
4346 GtkWidget *hpaned;
4347
4348 /* Add the topic */
4349 setup_chat_topic(gtkconv, vbox);
4350
4351 /* Add the gtkimhtml frame */
4352 hpaned = gtk_hpaned_new();
4353 gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0);
4354 gtk_widget_show(hpaned);
4355 gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE);
4356
4357 /* Now add the userlist */
4358 setup_chat_userlist(gtkconv, hpaned);
4359 } else {
4360 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
4361 }
4362 gtk_widget_show(frame);
4363
4364 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml");
4365 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE);
4366
4367 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
4368 &imhtml_sw_hscroll, NULL);
4369 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
4370 imhtml_sw_hscroll, GTK_POLICY_ALWAYS);
4371
4372 gtk_widget_set_size_request(gtkconv->imhtml,
4373 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width") :
4374 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"),
4375 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height") :
4376 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height"));
4377
4378 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
4379 G_CALLBACK(size_allocate_cb), gtkconv);
4380
4381 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
4382 G_CALLBACK(entry_stop_rclick_cb), NULL);
4383 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
4384 G_CALLBACK(refocus_entry_cb), gtkconv);
4385 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
4386 G_CALLBACK(refocus_entry_cb), gtkconv);
4367 4387
4368 /* Setup the bottom half of the conversation window */ 4388 /* Setup the bottom half of the conversation window */
4369 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 4389 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4370 gtk_paned_pack2(GTK_PANED(vpaned), vbox, FALSE, TRUE); 4390 gtk_paned_pack2(GTK_PANED(paned), vbox, FALSE, TRUE);
4371 gtk_widget_show(vbox); 4391 gtk_widget_show(vbox);
4372 4392
4373 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 4393 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4374 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->lower_hbox, TRUE, TRUE, 0); 4394 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->lower_hbox, TRUE, TRUE, 0);
4375 gtk_widget_show(gtkconv->lower_hbox); 4395 gtk_widget_show(gtkconv->lower_hbox);
4381 /* Setup the toolbar, entry widget and all signals */ 4401 /* Setup the toolbar, entry widget and all signals */
4382 frame = pidgin_create_imhtml(TRUE, &gtkconv->entry, &gtkconv->toolbar, NULL); 4402 frame = pidgin_create_imhtml(TRUE, &gtkconv->entry, &gtkconv->toolbar, NULL);
4383 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); 4403 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
4384 gtk_widget_show(frame); 4404 gtk_widget_show(frame);
4385 4405
4386 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup",
4387 G_CALLBACK(entry_popup_menu_cb), gtkconv);
4388
4389 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); 4406 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry");
4390 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), 4407 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
4391 purple_account_get_protocol_name(conv->account)); 4408 purple_account_get_protocol_name(conv->account));
4392 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, 4409 gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
4393 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height")); 4410 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height") :
4394 gtkconv->entry_buffer = 4411 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height"));
4395 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); 4412
4396 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); 4413 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup",
4397 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", 4414 G_CALLBACK(entry_popup_menu_cb), gtkconv);
4398 G_CALLBACK(resize_imhtml_cb), gtkconv);
4399
4400 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", 4415 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event",
4401 G_CALLBACK(entry_key_press_cb), gtkconv); 4416 G_CALLBACK(entry_key_press_cb), gtkconv);
4402 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", 4417 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send",
4403 G_CALLBACK(send_cb), gtkconv); 4418 G_CALLBACK(send_cb), gtkconv);
4404 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", 4419 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event",
4405 G_CALLBACK(entry_stop_rclick_cb), NULL); 4420 G_CALLBACK(entry_stop_rclick_cb), NULL);
4406 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", 4421 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate",
4407 G_CALLBACK(size_allocate_cb), gtkconv); 4422 G_CALLBACK(size_allocate_cb), gtkconv);
4408 4423
4409 default_formatize(gtkconv);
4410
4411 /*
4412 * Focus for chat windows should be as follows:
4413 * Tab title -> chat topic -> conversation scrollback -> user list ->
4414 * user list buttons -> entry -> buttons at bottom
4415 */
4416 focus_chain = g_list_prepend(focus_chain, gtkconv->entry);
4417 gtk_container_set_focus_chain(GTK_CONTAINER(vbox), focus_chain);
4418
4419 return vpaned;
4420 }
4421
4422 static GtkWidget *
4423 setup_im_pane(PidginConversation *gtkconv)
4424 {
4425 PurpleConversation *conv = gtkconv->active_conv;
4426 GtkWidget *frame;
4427 GtkWidget *imhtml_sw;
4428 GtkPolicyType imhtml_sw_hscroll;
4429 GtkWidget *paned;
4430 GtkWidget *vbox;
4431 GtkWidget *vbox2;
4432 GList *focus_chain = NULL;
4433
4434 /* Setup the outer pane */
4435 paned = gtk_vpaned_new();
4436 gtk_widget_show(paned);
4437
4438 /* Setup the top part of the pane */
4439 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4440 gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE);
4441 gtk_widget_show(vbox);
4442
4443 /* Setup the gtkimhtml widget */
4444 frame = pidgin_create_imhtml(FALSE, &gtkconv->imhtml, NULL, &imhtml_sw);
4445 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml");
4446 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE);
4447 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
4448 gtk_widget_show(frame);
4449 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
4450 &imhtml_sw_hscroll, NULL);
4451 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
4452 imhtml_sw_hscroll, GTK_POLICY_ALWAYS);
4453
4454 gtk_widget_set_size_request(gtkconv->imhtml,
4455 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"),
4456 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height"));
4457 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
4458 G_CALLBACK(size_allocate_cb), gtkconv);
4459
4460 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
4461 G_CALLBACK(entry_stop_rclick_cb), NULL);
4462 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
4463 G_CALLBACK(refocus_entry_cb), gtkconv);
4464 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
4465 G_CALLBACK(refocus_entry_cb), gtkconv);
4466
4467 /* Setup the bottom half of the conversation window */
4468 vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4469 gtk_paned_pack2(GTK_PANED(paned), vbox2, FALSE, TRUE);
4470 gtk_widget_show(vbox2);
4471
4472 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4473 gtk_box_pack_start(GTK_BOX(vbox2), gtkconv->lower_hbox, TRUE, TRUE, 0);
4474 gtk_widget_show(gtkconv->lower_hbox);
4475
4476 vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4477 gtk_box_pack_end(GTK_BOX(gtkconv->lower_hbox), vbox2, TRUE, TRUE, 0);
4478 gtk_widget_show(vbox2);
4479
4480 /* Setup the toolbar, entry widget and all signals */
4481 frame = pidgin_create_imhtml(TRUE, &gtkconv->entry, &gtkconv->toolbar, NULL);
4482 gtk_box_pack_start(GTK_BOX(vbox2), frame, TRUE, TRUE, 0);
4483 gtk_widget_show(frame);
4484
4485 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup",
4486 G_CALLBACK(entry_popup_menu_cb), gtkconv);
4487
4488 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry");
4489 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
4490 purple_account_get_protocol_name(conv->account));
4491 gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
4492 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height"));
4493 gtkconv->entry_buffer = 4424 gtkconv->entry_buffer =
4494 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); 4425 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry));
4495 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); 4426 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv);
4496 4427
4497 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", 4428 if (!chat) {
4498 G_CALLBACK(entry_key_press_cb), gtkconv); 4429 /* For sending typing notifications for IMs */
4499 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", 4430 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text",
4500 G_CALLBACK(send_cb), gtkconv); 4431 G_CALLBACK(insert_text_cb), gtkconv);
4501 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", 4432 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range",
4502 G_CALLBACK(entry_stop_rclick_cb), NULL); 4433 G_CALLBACK(delete_text_cb), gtkconv);
4503 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", 4434 gtkconv->u.im->typing_timer = 0;
4504 G_CALLBACK(size_allocate_cb), gtkconv); 4435 gtkconv->u.im->animate = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/animate_buddy_icons");
4505 4436 gtkconv->u.im->show_icon = TRUE;
4506 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", 4437 }
4507 G_CALLBACK(insert_text_cb), gtkconv); 4438
4508 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range",
4509 G_CALLBACK(delete_text_cb), gtkconv);
4510 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", 4439 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed",
4511 G_CALLBACK(resize_imhtml_cb), gtkconv); 4440 G_CALLBACK(resize_imhtml_cb), gtkconv);
4512 4441
4513 /* had to move this after the imtoolbar is attached so that the
4514 * signals get fired to toggle the buttons on the toolbar as well.
4515 */
4516 default_formatize(gtkconv); 4442 default_formatize(gtkconv);
4517
4518 g_signal_connect_after(G_OBJECT(gtkconv->entry), "format_function_clear", 4443 g_signal_connect_after(G_OBJECT(gtkconv->entry), "format_function_clear",
4519 G_CALLBACK(clear_formatting_cb), gtkconv); 4444 G_CALLBACK(clear_formatting_cb), gtkconv);
4520 4445
4521 gtkconv->u.im->animate = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/animate_buddy_icons");
4522 gtkconv->u.im->show_icon = TRUE;
4523
4524 /*
4525 * Focus for IM windows should be as follows:
4526 * Tab title -> conversation scrollback -> entry
4527 */
4528 focus_chain = g_list_prepend(focus_chain, gtkconv->entry);
4529 gtk_container_set_focus_chain(GTK_CONTAINER(vbox2), focus_chain);
4530
4531 gtkconv->u.im->typing_timer = 0;
4532 return paned; 4446 return paned;
4533 } 4447 }
4534 4448
4535 static void 4449 static void
4536 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, 4450 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
4722 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; 4636 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
4723 gtkconv->unseen_count = 0; 4637 gtkconv->unseen_count = 0;
4724 4638
4725 if (conv_type == PURPLE_CONV_TYPE_IM) { 4639 if (conv_type == PURPLE_CONV_TYPE_IM) {
4726 gtkconv->u.im = g_malloc0(sizeof(PidginImPane)); 4640 gtkconv->u.im = g_malloc0(sizeof(PidginImPane));
4727
4728 pane = setup_im_pane(gtkconv);
4729 } else if (conv_type == PURPLE_CONV_TYPE_CHAT) { 4641 } else if (conv_type == PURPLE_CONV_TYPE_CHAT) {
4730 gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane)); 4642 gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane));
4731 pane = setup_chat_pane(gtkconv); 4643 }
4732 } 4644 pane = setup_common_pane(gtkconv);
4733 4645
4734 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml), 4646 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml),
4735 gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE); 4647 gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE);
4736 4648
4737 if (pane == NULL) { 4649 if (pane == NULL) {
5125 g_return_if_fail(account != NULL); 5037 g_return_if_fail(account != NULL);
5126 gc = purple_account_get_connection(account); 5038 gc = purple_account_get_connection(account);
5127 g_return_if_fail(gc != NULL); 5039 g_return_if_fail(gc != NULL);
5128 5040
5129 /* Make sure URLs are clickable */ 5041 /* Make sure URLs are clickable */
5130 displaying = purple_markup_linkify(message); 5042 if(flags & PURPLE_MESSAGE_NO_LINKIFY)
5043 displaying = g_strdup(message);
5044 else
5045 displaying = purple_markup_linkify(message);
5046
5131 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( 5047 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
5132 pidgin_conversations_get_handle(), (type == PURPLE_CONV_TYPE_IM ? 5048 pidgin_conversations_get_handle(), (type == PURPLE_CONV_TYPE_IM ?
5133 "displaying-im-msg" : "displaying-chat-msg"), 5049 "displaying-im-msg" : "displaying-chat-msg"),
5134 account, name, &displaying, conv, flags)); 5050 account, name, &displaying, conv, flags));
5135 if (plugin_return) 5051 if (plugin_return)
5478 5394
5479 chat = PURPLE_CONV_CHAT(conv); 5395 chat = PURPLE_CONV_CHAT(conv);
5480 gtkconv = PIDGIN_CONVERSATION(conv); 5396 gtkconv = PIDGIN_CONVERSATION(conv);
5481 gtkchat = gtkconv->u.chat; 5397 gtkchat = gtkconv->u.chat;
5482 5398
5483 num_users = g_list_length(purple_conv_chat_get_users(chat)); 5399 num_users = g_list_length((GList *)purple_conv_chat_get_users(chat));
5484 5400
5485 g_snprintf(tmp, sizeof(tmp), 5401 g_snprintf(tmp, sizeof(tmp),
5486 ngettext("%d person in room", "%d people in room", 5402 ngettext("%d person in room", "%d people in room",
5487 num_users), 5403 num_users),
5488 num_users); 5404 num_users);
5572 5488
5573 chat = PURPLE_CONV_CHAT(conv); 5489 chat = PURPLE_CONV_CHAT(conv);
5574 gtkconv = PIDGIN_CONVERSATION(conv); 5490 gtkconv = PIDGIN_CONVERSATION(conv);
5575 gtkchat = gtkconv->u.chat; 5491 gtkchat = gtkconv->u.chat;
5576 5492
5577 num_users = g_list_length(purple_conv_chat_get_users(chat)); 5493 num_users = g_list_length((GList *)purple_conv_chat_get_users(chat));
5578 5494
5579 for (l = users; l != NULL; l = l->next) { 5495 for (l = users; l != NULL; l = l->next) {
5580 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); 5496 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
5581 5497
5582 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) 5498 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
6569 6485
6570 static void 6486 static void
6571 close_on_tabs_pref_cb(const char *name, PurplePrefType type, 6487 close_on_tabs_pref_cb(const char *name, PurplePrefType type,
6572 gconstpointer value, gpointer data) 6488 gconstpointer value, gpointer data)
6573 { 6489 {
6574 GList *l; 6490 const GList *l;
6575 PurpleConversation *conv; 6491 PurpleConversation *conv;
6576 PidginConversation *gtkconv; 6492 PidginConversation *gtkconv;
6577 6493
6578 for (l = purple_get_conversations(); l != NULL; l = l->next) { 6494 for (l = purple_get_conversations(); l != NULL; l = l->next) {
6579 conv = (PurpleConversation *)l->data; 6495 conv = (PurpleConversation *)l->data;
6593 static void 6509 static void
6594 spellcheck_pref_cb(const char *name, PurplePrefType type, 6510 spellcheck_pref_cb(const char *name, PurplePrefType type,
6595 gconstpointer value, gpointer data) 6511 gconstpointer value, gpointer data)
6596 { 6512 {
6597 #ifdef USE_GTKSPELL 6513 #ifdef USE_GTKSPELL
6598 GList *cl; 6514 const GList *cl;
6599 PurpleConversation *conv; 6515 PurpleConversation *conv;
6600 PidginConversation *gtkconv; 6516 PidginConversation *gtkconv;
6601 GtkSpell *spell; 6517 GtkSpell *spell;
6602 6518
6603 for (cl = purple_get_conversations(); cl != NULL; cl = cl->next) { 6519 for (cl = purple_get_conversations(); cl != NULL; cl = cl->next) {
6640 6556
6641 static void 6557 static void
6642 show_timestamps_pref_cb(const char *name, PurplePrefType type, 6558 show_timestamps_pref_cb(const char *name, PurplePrefType type,
6643 gconstpointer value, gpointer data) 6559 gconstpointer value, gpointer data)
6644 { 6560 {
6645 GList *l; 6561 const GList *l;
6646 PurpleConversation *conv; 6562 PurpleConversation *conv;
6647 PidginConversation *gtkconv; 6563 PidginConversation *gtkconv;
6648 PidginWindow *win; 6564 PidginWindow *win;
6649 6565
6650 for (l = purple_get_conversations(); l != NULL; l = l->next) 6566 for (l = purple_get_conversations(); l != NULL; l = l->next)
6668 6584
6669 static void 6585 static void
6670 show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type, 6586 show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type,
6671 gconstpointer value, gpointer data) 6587 gconstpointer value, gpointer data)
6672 { 6588 {
6673 GList *l; 6589 const GList *l;
6674 PurpleConversation *conv; 6590 PurpleConversation *conv;
6675 PidginConversation *gtkconv; 6591 PidginConversation *gtkconv;
6676 PidginWindow *win; 6592 PidginWindow *win;
6677 6593
6678 for (l = purple_get_conversations(); l != NULL; l = l->next) 6594 for (l = purple_get_conversations(); l != NULL; l = l->next)
6698 6614
6699 static void 6615 static void
6700 animate_buddy_icons_pref_cb(const char *name, PurplePrefType type, 6616 animate_buddy_icons_pref_cb(const char *name, PurplePrefType type,
6701 gconstpointer value, gpointer data) 6617 gconstpointer value, gpointer data)
6702 { 6618 {
6703 GList *l; 6619 const GList *l;
6704 PurpleConversation *conv; 6620 PurpleConversation *conv;
6705 PidginConversation *gtkconv; 6621 PidginConversation *gtkconv;
6706 PidginWindow *win; 6622 PidginWindow *win;
6707 6623
6708 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons")) 6624 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons"))
6725 6641
6726 static void 6642 static void
6727 show_buddy_icons_pref_cb(const char *name, PurplePrefType type, 6643 show_buddy_icons_pref_cb(const char *name, PurplePrefType type,
6728 gconstpointer value, gpointer data) 6644 gconstpointer value, gpointer data)
6729 { 6645 {
6730 GList *l; 6646 const GList *l;
6731 6647
6732 for (l = purple_get_conversations(); l != NULL; l = l->next) { 6648 for (l = purple_get_conversations(); l != NULL; l = l->next) {
6733 PurpleConversation *conv = l->data; 6649 PurpleConversation *conv = l->data;
6734 6650
6735 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 6651 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
6851 } 6767 }
6852 6768
6853 static void 6769 static void
6854 account_signed_off_cb(PurpleConnection *gc, gpointer event) 6770 account_signed_off_cb(PurpleConnection *gc, gpointer event)
6855 { 6771 {
6856 GList *iter; 6772 const GList *iter;
6857 6773
6858 for (iter = purple_get_conversations(); iter; iter = iter->next) 6774 for (iter = purple_get_conversations(); iter; iter = iter->next)
6859 { 6775 {
6860 PurpleConversation *conv = iter->data; 6776 PurpleConversation *conv = iter->data;
6861 6777
8040 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging), 7956 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging),
8041 purple_conversation_is_logging(conv)); 7957 purple_conversation_is_logging(conv));
8042 7958
8043 generate_send_to_items(win); 7959 generate_send_to_items(win);
8044 regenerate_options_items(win); 7960 regenerate_options_items(win);
7961 regenerate_plugins_items(win);
8045 7962
8046 pidgin_conv_switch_active_conversation(conv); 7963 pidgin_conv_switch_active_conversation(conv);
8047 7964
8048 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); 7965 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
8049 if (strcmp(sound_method, "none") != 0) 7966 if (strcmp(sound_method, "none") != 0)
8110 offline_list = make_status_icon_list(PIDGIN_STOCK_STATUS_OFFLINE, w); 8027 offline_list = make_status_icon_list(PIDGIN_STOCK_STATUS_OFFLINE, w);
8111 away_list = make_status_icon_list(PIDGIN_STOCK_STATUS_AWAY, w); 8028 away_list = make_status_icon_list(PIDGIN_STOCK_STATUS_AWAY, w);
8112 prpl_lists = g_hash_table_new(g_str_hash, g_str_equal); 8029 prpl_lists = g_hash_table_new(g_str_hash, g_str_equal);
8113 } 8030 }
8114 8031
8032 static void
8033 plugin_changed_cb(PurplePlugin *p, gpointer data)
8034 {
8035 regenerate_plugins_items(data);
8036 }
8037
8115 PidginWindow * 8038 PidginWindow *
8116 pidgin_conv_window_new() 8039 pidgin_conv_window_new()
8117 { 8040 {
8118 PidginWindow *win; 8041 PidginWindow *win;
8119 GtkPositionType pos; 8042 GtkPositionType pos;
8123 win = g_malloc0(sizeof(PidginWindow)); 8046 win = g_malloc0(sizeof(PidginWindow));
8124 8047
8125 window_list = g_list_append(window_list, win); 8048 window_list = g_list_append(window_list, win);
8126 8049
8127 /* Create the window. */ 8050 /* Create the window. */
8128 win->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 8051 win->window = pidgin_create_window(NULL, 0, "conversation", TRUE);
8129 gtk_window_set_role(GTK_WINDOW(win->window), "conversation");
8130 gtk_window_set_resizable(GTK_WINDOW(win->window), TRUE);
8131 gtk_container_set_border_width(GTK_CONTAINER(win->window), 0);
8132 GTK_WINDOW(win->window)->allow_shrink = TRUE; 8052 GTK_WINDOW(win->window)->allow_shrink = TRUE;
8133 8053
8134 if (available_list == NULL) { 8054 if (available_list == NULL) {
8135 create_icon_lists(win->window); 8055 create_icon_lists(win->window);
8136 } 8056 }
8183 gtk_box_pack_start(GTK_BOX(testidea), win->notebook, TRUE, TRUE, 0); 8103 gtk_box_pack_start(GTK_BOX(testidea), win->notebook, TRUE, TRUE, 0);
8184 8104
8185 gtk_container_add(GTK_CONTAINER(win->window), testidea); 8105 gtk_container_add(GTK_CONTAINER(win->window), testidea);
8186 8106
8187 gtk_widget_show(testidea); 8107 gtk_widget_show(testidea);
8108
8109 /* Update the plugin actions when plugins are (un)loaded */
8110 purple_signal_connect(purple_plugins_get_handle(), "plugin-load",
8111 win, PURPLE_CALLBACK(plugin_changed_cb), win);
8112 purple_signal_connect(purple_plugins_get_handle(), "plugin-unload",
8113 win, PURPLE_CALLBACK(plugin_changed_cb), win);
8114
8188 8115
8189 #ifdef _WIN32 8116 #ifdef _WIN32
8190 g_signal_connect(G_OBJECT(win->window), "show", 8117 g_signal_connect(G_OBJECT(win->window), "show",
8191 G_CALLBACK(winpidgin_ensure_onscreen), win->window); 8118 G_CALLBACK(winpidgin_ensure_onscreen), win->window);
8192 #endif 8119 #endif
8223 gtk_widget_destroy(win->window); 8150 gtk_widget_destroy(win->window);
8224 8151
8225 g_object_unref(G_OBJECT(win->menu.item_factory)); 8152 g_object_unref(G_OBJECT(win->menu.item_factory));
8226 8153
8227 purple_notify_close_with_handle(win); 8154 purple_notify_close_with_handle(win);
8155 purple_signals_disconnect_by_handle(win);
8228 8156
8229 g_free(win); 8157 g_free(win);
8230 } 8158 }
8231 8159
8232 void 8160 void