Mercurial > pidgin.yaz
comparison pidgin/gtkconv.c @ 25512:ff69c2a9ccf2
propagate from branch 'im.pidgin.pidgin' (head 725fc6cb64d550dcc3a71741a974e5255f83a366)
to branch 'im.pidgin.pidgin.yaz' (head 51241dcb972c543304c03eb0b9edc39a64ba3c6f)
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Sun, 17 Jun 2007 05:28:54 +0000 |
parents | cf708cbcbc04 9b9e202eb449 |
children | 90d558470507 |
comparison
equal
deleted
inserted
replaced
25511:7a3c3c360624 | 25512:ff69c2a9ccf2 |
---|---|
47 #include "log.h" | 47 #include "log.h" |
48 #include "notify.h" | 48 #include "notify.h" |
49 #include "prpl.h" | 49 #include "prpl.h" |
50 #include "request.h" | 50 #include "request.h" |
51 #include "util.h" | 51 #include "util.h" |
52 #include "version.h" | |
52 | 53 |
53 #include "gtkdnd-hints.h" | 54 #include "gtkdnd-hints.h" |
54 #include "gtkblist.h" | 55 #include "gtkblist.h" |
55 #include "gtkconv.h" | 56 #include "gtkconv.h" |
56 #include "gtkconvwin.h" | 57 #include "gtkconvwin.h" |
273 | 274 |
274 static void | 275 static void |
275 default_formatize(PidginConversation *c) | 276 default_formatize(PidginConversation *c) |
276 { | 277 { |
277 PurpleConversation *conv = c->active_conv; | 278 PurpleConversation *conv = c->active_conv; |
278 | 279 gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), conv->features); |
279 if (conv->features & PURPLE_CONNECTION_HTML) | |
280 { | |
281 char color[8]; | |
282 GdkColor fg_color, bg_color; | |
283 | |
284 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold") != GTK_IMHTML(c->entry)->edit.bold) | |
285 gtk_imhtml_toggle_bold(GTK_IMHTML(c->entry)); | |
286 | |
287 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic") != GTK_IMHTML(c->entry)->edit.italic) | |
288 gtk_imhtml_toggle_italic(GTK_IMHTML(c->entry)); | |
289 | |
290 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline") != GTK_IMHTML(c->entry)->edit.underline) | |
291 gtk_imhtml_toggle_underline(GTK_IMHTML(c->entry)); | |
292 | |
293 gtk_imhtml_toggle_fontface(GTK_IMHTML(c->entry), | |
294 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/font_face")); | |
295 | |
296 if (!(conv->features & PURPLE_CONNECTION_NO_FONTSIZE)) | |
297 { | |
298 int size = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/font_size"); | |
299 | |
300 /* 3 is the default. */ | |
301 if (size != 3) | |
302 gtk_imhtml_font_set_size(GTK_IMHTML(c->entry), size); | |
303 } | |
304 | |
305 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), "") != 0) | |
306 { | |
307 gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), | |
308 &fg_color); | |
309 g_snprintf(color, sizeof(color), "#%02x%02x%02x", | |
310 fg_color.red / 256, | |
311 fg_color.green / 256, | |
312 fg_color.blue / 256); | |
313 } else | |
314 strcpy(color, ""); | |
315 | |
316 gtk_imhtml_toggle_forecolor(GTK_IMHTML(c->entry), color); | |
317 | |
318 if(!(conv->features & PURPLE_CONNECTION_NO_BGCOLOR) && | |
319 strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), "") != 0) | |
320 { | |
321 gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), | |
322 &bg_color); | |
323 g_snprintf(color, sizeof(color), "#%02x%02x%02x", | |
324 bg_color.red / 256, | |
325 bg_color.green / 256, | |
326 bg_color.blue / 256); | |
327 } else | |
328 strcpy(color, ""); | |
329 | |
330 gtk_imhtml_toggle_background(GTK_IMHTML(c->entry), color); | |
331 | |
332 if (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO) | |
333 gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(c->entry), TRUE); | |
334 else | |
335 gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(c->entry), FALSE); | |
336 } | |
337 } | 280 } |
338 | 281 |
339 static void | 282 static void |
340 clear_formatting_cb(GtkIMHtml *imhtml, PidginConversation *gtkconv) | 283 clear_formatting_cb(GtkIMHtml *imhtml, PidginConversation *gtkconv) |
341 { | 284 { |
479 { | 422 { |
480 PidginConversation *gtkconv; | 423 PidginConversation *gtkconv; |
481 char *cmd; | 424 char *cmd; |
482 const char *prefix; | 425 const char *prefix; |
483 GtkTextIter start; | 426 GtkTextIter start; |
427 gboolean retval = FALSE; | |
484 | 428 |
485 gtkconv = PIDGIN_CONVERSATION(conv); | 429 gtkconv = PIDGIN_CONVERSATION(conv); |
486 prefix = pidgin_get_cmd_prefix(); | 430 prefix = pidgin_get_cmd_prefix(); |
487 | 431 |
488 cmd = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL); | 432 cmd = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL); |
502 | 446 |
503 gtk_text_iter_forward_chars(&start, g_utf8_strlen(prefix, -1)); | 447 gtk_text_iter_forward_chars(&start, g_utf8_strlen(prefix, -1)); |
504 gtk_text_buffer_get_end_iter(GTK_IMHTML(gtkconv->entry)->text_buffer, &end); | 448 gtk_text_buffer_get_end_iter(GTK_IMHTML(gtkconv->entry)->text_buffer, &end); |
505 markup = gtk_imhtml_get_markup_range(GTK_IMHTML(gtkconv->entry), &start, &end); | 449 markup = gtk_imhtml_get_markup_range(GTK_IMHTML(gtkconv->entry), &start, &end); |
506 status = purple_cmd_do_command(conv, cmdline, markup, &error); | 450 status = purple_cmd_do_command(conv, cmdline, markup, &error); |
507 g_free(cmd); | |
508 g_free(markup); | 451 g_free(markup); |
509 | 452 |
510 switch (status) { | 453 switch (status) { |
511 case PURPLE_CMD_STATUS_OK: | 454 case PURPLE_CMD_STATUS_OK: |
512 return TRUE; | 455 retval = TRUE; |
456 break; | |
513 case PURPLE_CMD_STATUS_NOT_FOUND: | 457 case PURPLE_CMD_STATUS_NOT_FOUND: |
514 return FALSE; | 458 { |
459 PurplePluginProtocolInfo *prpl_info = NULL; | |
460 PurpleConnection *gc; | |
461 | |
462 if ((gc = purple_conversation_get_gc(conv))) | |
463 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
464 | |
465 if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) { | |
466 char *firstspace; | |
467 char *slash; | |
468 | |
469 firstspace = strchr(cmdline, ' '); | |
470 if (firstspace != NULL) { | |
471 slash = strrchr(firstspace, '/'); | |
472 } else { | |
473 slash = strchr(cmdline, '/'); | |
474 } | |
475 | |
476 if (slash == NULL) { | |
477 purple_conversation_write(conv, "", _("Unknown command."), PURPLE_MESSAGE_NO_LOG, time(NULL)); | |
478 retval = TRUE; | |
479 } | |
480 } | |
481 break; | |
482 } | |
515 case PURPLE_CMD_STATUS_WRONG_ARGS: | 483 case PURPLE_CMD_STATUS_WRONG_ARGS: |
516 purple_conversation_write(conv, "", _("Syntax Error: You typed the wrong number of arguments " | 484 purple_conversation_write(conv, "", _("Syntax Error: You typed the wrong number of arguments " |
517 "to that command."), | 485 "to that command."), |
518 PURPLE_MESSAGE_NO_LOG, time(NULL)); | 486 PURPLE_MESSAGE_NO_LOG, time(NULL)); |
519 return TRUE; | 487 retval = TRUE; |
488 break; | |
520 case PURPLE_CMD_STATUS_FAILED: | 489 case PURPLE_CMD_STATUS_FAILED: |
521 purple_conversation_write(conv, "", error ? error : _("Your command failed for an unknown reason."), | 490 purple_conversation_write(conv, "", error ? error : _("Your command failed for an unknown reason."), |
522 PURPLE_MESSAGE_NO_LOG, time(NULL)); | 491 PURPLE_MESSAGE_NO_LOG, time(NULL)); |
523 g_free(error); | 492 g_free(error); |
524 return TRUE; | 493 retval = TRUE; |
494 break; | |
525 case PURPLE_CMD_STATUS_WRONG_TYPE: | 495 case PURPLE_CMD_STATUS_WRONG_TYPE: |
526 if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) | 496 if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) |
527 purple_conversation_write(conv, "", _("That command only works in chats, not IMs."), | 497 purple_conversation_write(conv, "", _("That command only works in chats, not IMs."), |
528 PURPLE_MESSAGE_NO_LOG, time(NULL)); | 498 PURPLE_MESSAGE_NO_LOG, time(NULL)); |
529 else | 499 else |
530 purple_conversation_write(conv, "", _("That command only works in IMs, not chats."), | 500 purple_conversation_write(conv, "", _("That command only works in IMs, not chats."), |
531 PURPLE_MESSAGE_NO_LOG, time(NULL)); | 501 PURPLE_MESSAGE_NO_LOG, time(NULL)); |
532 return TRUE; | 502 retval = TRUE; |
503 break; | |
533 case PURPLE_CMD_STATUS_WRONG_PRPL: | 504 case PURPLE_CMD_STATUS_WRONG_PRPL: |
534 purple_conversation_write(conv, "", _("That command doesn't work on this protocol."), | 505 purple_conversation_write(conv, "", _("That command doesn't work on this protocol."), |
535 PURPLE_MESSAGE_NO_LOG, time(NULL)); | 506 PURPLE_MESSAGE_NO_LOG, time(NULL)); |
536 return TRUE; | 507 retval = TRUE; |
508 break; | |
537 } | 509 } |
538 } | 510 } |
539 | 511 |
540 g_free(cmd); | 512 g_free(cmd); |
541 return FALSE; | 513 return retval; |
542 } | 514 } |
543 | 515 |
544 static void | 516 static void |
545 send_cb(GtkWidget *widget, PidginConversation *gtkconv) | 517 send_cb(GtkWidget *widget, PidginConversation *gtkconv) |
546 { | 518 { |
668 { | 640 { |
669 prpl_info->get_cb_info(gc, | 641 prpl_info->get_cb_info(gc, |
670 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); | 642 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); |
671 } | 643 } |
672 else | 644 else |
673 prpl_info->get_info(gc, who); | 645 pidgin_retrieve_user_info(gc, who); |
674 } | 646 } |
675 } | 647 } |
676 | 648 |
677 | 649 |
678 static void | 650 static void |
679 info_cb(GtkWidget *widget, PidginConversation *gtkconv) | 651 info_cb(GtkWidget *widget, PidginConversation *gtkconv) |
680 { | 652 { |
681 PurpleConversation *conv = gtkconv->active_conv; | 653 PurpleConversation *conv = gtkconv->active_conv; |
682 | 654 |
683 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 655 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
684 PurpleNotifyUserInfo *info = purple_notify_user_info_new(); | 656 pidgin_retrieve_user_info(purple_conversation_get_gc(conv), |
685 purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); | |
686 purple_notify_userinfo(conv->account->gc, purple_conversation_get_name(conv), info, NULL, NULL); | |
687 purple_notify_user_info_destroy(info); | |
688 | |
689 serv_get_info(purple_conversation_get_gc(conv), | |
690 purple_conversation_get_name(conv)); | 657 purple_conversation_get_name(conv)); |
691 | |
692 gtk_widget_grab_focus(gtkconv->entry); | 658 gtk_widget_grab_focus(gtkconv->entry); |
693 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 659 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
694 /* Get info of the person currently selected in the GtkTreeView */ | 660 /* Get info of the person currently selected in the GtkTreeView */ |
695 PidginChatPane *gtkchat; | 661 PidginChatPane *gtkchat; |
696 GtkTreeIter iter; | 662 GtkTreeIter iter; |
2093 gtk_widget_event(gtkconv->entry, (GdkEvent *)event); | 2059 gtk_widget_event(gtkconv->entry, (GdkEvent *)event); |
2094 | 2060 |
2095 return TRUE; | 2061 return TRUE; |
2096 } | 2062 } |
2097 | 2063 |
2064 static void | |
2065 regenerate_options_items(PidginWindow *win); | |
2066 | |
2098 void | 2067 void |
2099 pidgin_conv_switch_active_conversation(PurpleConversation *conv) | 2068 pidgin_conv_switch_active_conversation(PurpleConversation *conv) |
2100 { | 2069 { |
2101 PidginConversation *gtkconv; | 2070 PidginConversation *gtkconv; |
2102 PurpleConversation *old_conv; | 2071 PurpleConversation *old_conv; |
2193 | 2162 |
2194 purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv); | 2163 purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv); |
2195 | 2164 |
2196 gray_stuff_out(gtkconv); | 2165 gray_stuff_out(gtkconv); |
2197 update_typing_icon(gtkconv); | 2166 update_typing_icon(gtkconv); |
2167 g_object_set_data(G_OBJECT(entry), "transient_buddy", NULL); | |
2168 regenerate_options_items(gtkconv->win); | |
2198 | 2169 |
2199 gtk_window_set_title(GTK_WINDOW(gtkconv->win->window), | 2170 gtk_window_set_title(GTK_WINDOW(gtkconv->win->window), |
2200 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); | 2171 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); |
2201 } | 2172 } |
2202 | 2173 |
2269 **************************************************************************/ | 2240 **************************************************************************/ |
2270 | 2241 |
2271 static GList *get_prpl_icon_list(PurpleAccount *account) | 2242 static GList *get_prpl_icon_list(PurpleAccount *account) |
2272 { | 2243 { |
2273 GList *l = NULL; | 2244 GList *l = NULL; |
2274 GdkPixbuf *pixbuf; | 2245 PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account)); |
2275 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account))); | 2246 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); |
2276 const char *prpl = prpl_info->list_icon(account, NULL); | 2247 const char *prplname = prpl_info->list_icon(account, NULL); |
2277 char *filename, *path; | 2248 l = g_hash_table_lookup(prpl_lists, prplname); |
2278 l = g_hash_table_lookup(prpl_lists, prpl); | |
2279 if (l) | 2249 if (l) |
2280 return l; | 2250 return l; |
2281 filename = g_strdup_printf("%s.png", prpl); | 2251 |
2282 | 2252 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_LARGE)); |
2283 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "16", filename, NULL); | 2253 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM)); |
2284 pixbuf = gdk_pixbuf_new_from_file(path, NULL); | 2254 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL)); |
2285 if (pixbuf) | 2255 |
2286 l = g_list_append(l, pixbuf); | 2256 g_hash_table_insert(prpl_lists, g_strdup(prplname), l); |
2287 g_free(path); | |
2288 | |
2289 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", filename, NULL); | |
2290 pixbuf = gdk_pixbuf_new_from_file(path, NULL); | |
2291 if (pixbuf) | |
2292 l = g_list_append(l, pixbuf); | |
2293 g_free(path); | |
2294 | |
2295 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "48", filename, NULL); | |
2296 pixbuf = gdk_pixbuf_new_from_file(path, NULL); | |
2297 if (pixbuf) | |
2298 l = g_list_append(l, pixbuf); | |
2299 g_free(path); | |
2300 | |
2301 g_hash_table_insert(prpl_lists, g_strdup(prpl), l); | |
2302 return l; | 2257 return l; |
2303 } | 2258 } |
2304 | 2259 |
2305 static GList * | 2260 static GList * |
2306 pidgin_conv_get_tab_icons(PurpleConversation *conv) | 2261 pidgin_conv_get_tab_icons(PurpleConversation *conv) |
2968 gtkconv = pidgin_conv_window_get_active_gtkconv(win); | 2923 gtkconv = pidgin_conv_window_get_active_gtkconv(win); |
2969 conv = gtkconv->active_conv; | 2924 conv = gtkconv->active_conv; |
2970 | 2925 |
2971 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More")); | 2926 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More")); |
2972 | 2927 |
2973 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) | 2928 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
2974 chat = purple_blist_find_chat(conv->account, conv->name); | 2929 chat = purple_blist_find_chat(conv->account, conv->name); |
2975 else | 2930 |
2931 if ((chat == NULL) && (gtkconv->imhtml != NULL)) { | |
2932 chat = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat"); | |
2933 } | |
2934 | |
2935 if ((chat == NULL) && (gtkconv->imhtml != NULL)) { | |
2936 GHashTable *components; | |
2937 components = g_hash_table_new_full(g_str_hash, g_str_equal, | |
2938 g_free, g_free); | |
2939 g_hash_table_replace(components, g_strdup("channel"), | |
2940 g_strdup(conv->name)); | |
2941 chat = purple_chat_new(conv->account, NULL, components); | |
2942 purple_blist_node_set_flags((PurpleBlistNode *)chat, | |
2943 PURPLE_BLIST_NODE_FLAG_NO_SAVE); | |
2944 g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_chat", | |
2945 chat, (GDestroyNotify)purple_blist_remove_chat); | |
2946 } | |
2947 } else { | |
2976 buddy = purple_find_buddy(conv->account, conv->name); | 2948 buddy = purple_find_buddy(conv->account, conv->name); |
2949 | |
2950 /* gotta remain bug-compatible :( libpurple < 2.0.2 didn't handle | |
2951 * removing "isolated" buddy nodes well */ | |
2952 if (purple_version_check(2, 0, 2) == NULL) { | |
2953 if ((buddy == NULL) && (gtkconv->imhtml != NULL)) { | |
2954 buddy = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy"); | |
2955 } | |
2956 | |
2957 if ((buddy == NULL) && (gtkconv->imhtml != NULL)) { | |
2958 buddy = purple_buddy_new(conv->account, conv->name, NULL); | |
2959 purple_blist_node_set_flags((PurpleBlistNode *)buddy, | |
2960 PURPLE_BLIST_NODE_FLAG_NO_SAVE); | |
2961 g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_buddy", | |
2962 buddy, (GDestroyNotify)purple_blist_remove_buddy); | |
2963 } | |
2964 } | |
2965 } | |
2977 | 2966 |
2978 if (chat) | 2967 if (chat) |
2979 node = (PurpleBlistNode *)chat; | 2968 node = (PurpleBlistNode *)chat; |
2980 else if (buddy) | 2969 else if (buddy) |
2981 node = (PurpleBlistNode *)buddy; | 2970 node = (PurpleBlistNode *)buddy; |
3004 } | 2993 } |
3005 | 2994 |
3006 gtk_widget_show_all(menu); | 2995 gtk_widget_show_all(menu); |
3007 } | 2996 } |
3008 | 2997 |
2998 static void | |
2999 remove_from_list(GtkWidget *widget, PidginWindow *win) | |
3000 { | |
3001 GList *list = g_object_get_data(G_OBJECT(win->window), "plugin-actions"); | |
3002 list = g_list_remove(list, widget); | |
3003 g_object_set_data(G_OBJECT(win->window), "plugin-actions", list); | |
3004 } | |
3005 | |
3006 static void | |
3007 regenerate_plugins_items(PidginWindow *win) | |
3008 { | |
3009 GList *action_items; | |
3010 GtkWidget *menu; | |
3011 GList *list; | |
3012 PidginConversation *gtkconv; | |
3013 PurpleConversation *conv; | |
3014 GtkWidget *item; | |
3015 | |
3016 if (win->window == NULL || win == hidden_convwin) | |
3017 return; | |
3018 | |
3019 gtkconv = pidgin_conv_window_get_active_gtkconv(win); | |
3020 if (gtkconv == NULL) | |
3021 return; | |
3022 | |
3023 conv = gtkconv->active_conv; | |
3024 action_items = g_object_get_data(G_OBJECT(win->window), "plugin-actions"); | |
3025 | |
3026 /* Remove the old menuitems */ | |
3027 while (action_items) { | |
3028 g_signal_handlers_disconnect_by_func(G_OBJECT(action_items->data), | |
3029 G_CALLBACK(remove_from_list), win); | |
3030 gtk_widget_destroy(action_items->data); | |
3031 action_items = g_list_delete_link(action_items, action_items); | |
3032 } | |
3033 | |
3034 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options")); | |
3035 | |
3036 list = purple_conversation_get_extended_menu(conv); | |
3037 if (list) { | |
3038 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu))); | |
3039 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); | |
3040 } | |
3041 | |
3042 for(; list; list = g_list_delete_link(list, list)) { | |
3043 PurpleMenuAction *act = (PurpleMenuAction *) list->data; | |
3044 item = pidgin_append_menu_action(menu, act, conv); | |
3045 action_items = g_list_prepend(action_items, item); | |
3046 gtk_widget_show_all(item); | |
3047 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); | |
3048 } | |
3049 g_object_set_data(G_OBJECT(win->window), "plugin-actions", action_items); | |
3050 } | |
3051 | |
3009 static void menubar_activated(GtkWidget *item, gpointer data) | 3052 static void menubar_activated(GtkWidget *item, gpointer data) |
3010 { | 3053 { |
3011 PidginWindow *win = data; | 3054 PidginWindow *win = data; |
3012 regenerate_options_items(win); | 3055 regenerate_options_items(win); |
3056 regenerate_plugins_items(win); | |
3013 | 3057 |
3014 /* The following are to make sure the 'More' submenu is not regenerated every time | 3058 /* The following are to make sure the 'More' submenu is not regenerated every time |
3015 * the focus shifts from 'Conversations' to some other menu and back. */ | 3059 * the focus shifts from 'Conversations' to some other menu and back. */ |
3016 g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data); | 3060 g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data); |
3017 g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), data); | 3061 g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), data); |
4231 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height + PIDGIN_HIG_BOX_SPACE); | 4275 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height + PIDGIN_HIG_BOX_SPACE); |
4232 g_idle_add(reset_auto_resize_cb, gtkconv); | 4276 g_idle_add(reset_auto_resize_cb, gtkconv); |
4233 } | 4277 } |
4234 } | 4278 } |
4235 | 4279 |
4236 static GtkWidget * | 4280 static void |
4237 setup_chat_pane(PidginConversation *gtkconv) | 4281 setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox) |
4238 { | 4282 { |
4239 PurplePluginProtocolInfo *prpl_info; | |
4240 PurpleConversation *conv = gtkconv->active_conv; | 4283 PurpleConversation *conv = gtkconv->active_conv; |
4241 PidginChatPane *gtkchat; | 4284 PurpleConnection *gc = purple_conversation_get_gc(conv); |
4242 PurpleConnection *gc; | 4285 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); |
4243 GtkWidget *vpaned, *hpaned; | |
4244 GtkWidget *vbox, *hbox, *frame; | |
4245 GtkWidget *imhtml_sw; | |
4246 GtkPolicyType imhtml_sw_hscroll; | |
4247 GtkWidget *lbox; | |
4248 GtkWidget *label; | |
4249 GtkWidget *list; | |
4250 GtkWidget *sw; | |
4251 GtkListStore *ls; | |
4252 GtkCellRenderer *rend; | |
4253 GtkTreeViewColumn *col; | |
4254 void *blist_handle = purple_blist_get_handle(); | |
4255 GList *focus_chain = NULL; | |
4256 int ul_width; | |
4257 | |
4258 gtkchat = gtkconv->u.chat; | |
4259 gc = purple_conversation_get_gc(conv); | |
4260 g_return_val_if_fail(gc != NULL, NULL); | |
4261 g_return_val_if_fail(gc->prpl != NULL, NULL); | |
4262 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
4263 | |
4264 /* Setup the outer pane. */ | |
4265 vpaned = gtk_vpaned_new(); | |
4266 gtk_widget_show(vpaned); | |
4267 | |
4268 /* Setup the top part of the pane. */ | |
4269 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | |
4270 gtk_paned_pack1(GTK_PANED(vpaned), vbox, TRUE, TRUE); | |
4271 gtk_widget_show(vbox); | |
4272 | |
4273 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) | 4286 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) |
4274 { | 4287 { |
4288 GtkWidget *hbox, *label; | |
4289 PidginChatPane *gtkchat = gtkconv->u.chat; | |
4290 | |
4275 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 4291 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4276 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | 4292 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
4277 gtk_widget_show(hbox); | 4293 gtk_widget_show(hbox); |
4278 | 4294 |
4279 label = gtk_label_new(_("Topic:")); | 4295 label = gtk_label_new(_("Topic:")); |
4292 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); | 4308 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); |
4293 gtk_widget_show(gtkchat->topic_text); | 4309 gtk_widget_show(gtkchat->topic_text); |
4294 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", | 4310 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", |
4295 G_CALLBACK(entry_key_press_cb), gtkconv); | 4311 G_CALLBACK(entry_key_press_cb), gtkconv); |
4296 } | 4312 } |
4297 | 4313 } |
4298 /* Setup the horizontal pane. */ | 4314 |
4299 hpaned = gtk_hpaned_new(); | 4315 static void |
4300 gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); | 4316 setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned) |
4301 gtk_widget_show(hpaned); | 4317 { |
4302 | 4318 PidginChatPane *gtkchat = gtkconv->u.chat; |
4303 /* Setup gtkihmtml. */ | 4319 GtkWidget *lbox, *sw, *list; |
4304 frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); | 4320 GtkListStore *ls; |
4305 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); | 4321 GtkCellRenderer *rend; |
4306 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), TRUE); | 4322 GtkTreeViewColumn *col; |
4307 gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE); | 4323 int ul_width; |
4308 gtk_widget_show(frame); | 4324 void *blist_handle = purple_blist_get_handle(); |
4309 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), | 4325 PurpleConversation *conv = gtkconv->active_conv; |
4310 &imhtml_sw_hscroll, NULL); | |
4311 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), | |
4312 imhtml_sw_hscroll, GTK_POLICY_ALWAYS); | |
4313 | |
4314 gtk_widget_set_size_request(gtkconv->imhtml, | |
4315 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width"), | |
4316 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height")); | |
4317 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", | |
4318 G_CALLBACK(size_allocate_cb), gtkconv); | |
4319 | |
4320 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", | |
4321 G_CALLBACK(entry_stop_rclick_cb), NULL); | |
4322 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", | |
4323 G_CALLBACK(refocus_entry_cb), gtkconv); | |
4324 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", | |
4325 G_CALLBACK(refocus_entry_cb), gtkconv); | |
4326 | 4326 |
4327 /* Build the right pane. */ | 4327 /* Build the right pane. */ |
4328 lbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 4328 lbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4329 gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE); | 4329 gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE); |
4330 gtk_widget_show(lbox); | 4330 gtk_widget_show(lbox); |
4368 G_CALLBACK(right_click_chat_cb), gtkconv); | 4368 G_CALLBACK(right_click_chat_cb), gtkconv); |
4369 g_signal_connect(G_OBJECT(list), "popup-menu", | 4369 g_signal_connect(G_OBJECT(list), "popup-menu", |
4370 G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv); | 4370 G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv); |
4371 g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv); | 4371 g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv); |
4372 | 4372 |
4373 | |
4374 rend = gtk_cell_renderer_text_new(); | 4373 rend = gtk_cell_renderer_text_new(); |
4375 | |
4376 g_object_set(rend, | 4374 g_object_set(rend, |
4377 "foreground-set", TRUE, | 4375 "foreground-set", TRUE, |
4378 "weight-set", TRUE, | 4376 "weight-set", TRUE, |
4379 NULL); | 4377 NULL); |
4380 col = gtk_tree_view_column_new_with_attributes(NULL, rend, | 4378 col = gtk_tree_view_column_new_with_attributes(NULL, rend, |
4401 gtk_widget_show(list); | 4399 gtk_widget_show(list); |
4402 | 4400 |
4403 gtkchat->list = list; | 4401 gtkchat->list = list; |
4404 | 4402 |
4405 gtk_container_add(GTK_CONTAINER(sw), list); | 4403 gtk_container_add(GTK_CONTAINER(sw), list); |
4404 } | |
4405 | |
4406 static GtkWidget * | |
4407 setup_common_pane(PidginConversation *gtkconv) | |
4408 { | |
4409 GtkWidget *paned, *vbox, *frame, *imhtml_sw; | |
4410 PurpleConversation *conv = gtkconv->active_conv; | |
4411 gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); | |
4412 GtkPolicyType imhtml_sw_hscroll; | |
4413 | |
4414 paned = gtk_vpaned_new(); | |
4415 gtk_widget_show(paned); | |
4416 | |
4417 /* Setup the top part of the pane */ | |
4418 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | |
4419 gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE); | |
4420 gtk_widget_show(vbox); | |
4421 | |
4422 /* Setup the gtkimhtml widget */ | |
4423 frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); | |
4424 if (chat) { | |
4425 GtkWidget *hpaned; | |
4426 | |
4427 /* Add the topic */ | |
4428 setup_chat_topic(gtkconv, vbox); | |
4429 | |
4430 /* Add the gtkimhtml frame */ | |
4431 hpaned = gtk_hpaned_new(); | |
4432 gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); | |
4433 gtk_widget_show(hpaned); | |
4434 gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE); | |
4435 | |
4436 /* Now add the userlist */ | |
4437 setup_chat_userlist(gtkconv, hpaned); | |
4438 } else { | |
4439 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | |
4440 } | |
4441 gtk_widget_show(frame); | |
4442 | |
4443 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); | |
4444 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); | |
4445 | |
4446 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), | |
4447 &imhtml_sw_hscroll, NULL); | |
4448 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), | |
4449 imhtml_sw_hscroll, GTK_POLICY_ALWAYS); | |
4450 | |
4451 gtk_widget_set_size_request(gtkconv->imhtml, | |
4452 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width") : | |
4453 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"), | |
4454 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height") : | |
4455 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height")); | |
4456 | |
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); | |
4406 | 4466 |
4407 /* Setup the bottom half of the conversation window */ | 4467 /* Setup the bottom half of the conversation window */ |
4408 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 4468 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4409 gtk_paned_pack2(GTK_PANED(vpaned), vbox, FALSE, TRUE); | 4469 gtk_paned_pack2(GTK_PANED(paned), vbox, FALSE, TRUE); |
4410 gtk_widget_show(vbox); | 4470 gtk_widget_show(vbox); |
4411 | 4471 |
4412 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 4472 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4413 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->lower_hbox, TRUE, TRUE, 0); | 4473 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->lower_hbox, TRUE, TRUE, 0); |
4414 gtk_widget_show(gtkconv->lower_hbox); | 4474 gtk_widget_show(gtkconv->lower_hbox); |
4420 /* Setup the toolbar, entry widget and all signals */ | 4480 /* Setup the toolbar, entry widget and all signals */ |
4421 frame = pidgin_create_imhtml(TRUE, >kconv->entry, >kconv->toolbar, NULL); | 4481 frame = pidgin_create_imhtml(TRUE, >kconv->entry, >kconv->toolbar, NULL); |
4422 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | 4482 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); |
4423 gtk_widget_show(frame); | 4483 gtk_widget_show(frame); |
4424 | 4484 |
4425 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", | |
4426 G_CALLBACK(entry_popup_menu_cb), gtkconv); | |
4427 | |
4428 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); | 4485 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); |
4429 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), | 4486 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), |
4430 purple_account_get_protocol_name(conv->account)); | 4487 purple_account_get_protocol_name(conv->account)); |
4431 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, | 4488 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, |
4432 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height")); | 4489 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height") : |
4433 gtkconv->entry_buffer = | 4490 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height")); |
4434 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); | 4491 |
4435 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); | 4492 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", |
4436 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", | 4493 G_CALLBACK(entry_popup_menu_cb), gtkconv); |
4437 G_CALLBACK(resize_imhtml_cb), gtkconv); | |
4438 | |
4439 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", | 4494 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", |
4440 G_CALLBACK(entry_key_press_cb), gtkconv); | 4495 G_CALLBACK(entry_key_press_cb), gtkconv); |
4441 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", | 4496 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", |
4442 G_CALLBACK(send_cb), gtkconv); | 4497 G_CALLBACK(send_cb), gtkconv); |
4443 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", | 4498 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", |
4444 G_CALLBACK(entry_stop_rclick_cb), NULL); | 4499 G_CALLBACK(entry_stop_rclick_cb), NULL); |
4445 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", | 4500 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", |
4446 G_CALLBACK(size_allocate_cb), gtkconv); | 4501 G_CALLBACK(size_allocate_cb), gtkconv); |
4447 | 4502 |
4448 default_formatize(gtkconv); | |
4449 | |
4450 /* | |
4451 * Focus for chat windows should be as follows: | |
4452 * Tab title -> chat topic -> conversation scrollback -> user list -> | |
4453 * user list buttons -> entry -> buttons at bottom | |
4454 */ | |
4455 focus_chain = g_list_prepend(focus_chain, gtkconv->entry); | |
4456 gtk_container_set_focus_chain(GTK_CONTAINER(vbox), focus_chain); | |
4457 | |
4458 return vpaned; | |
4459 } | |
4460 | |
4461 static GtkWidget * | |
4462 setup_im_pane(PidginConversation *gtkconv) | |
4463 { | |
4464 PurpleConversation *conv = gtkconv->active_conv; | |
4465 GtkWidget *frame; | |
4466 GtkWidget *imhtml_sw; | |
4467 GtkPolicyType imhtml_sw_hscroll; | |
4468 GtkWidget *paned; | |
4469 GtkWidget *vbox; | |
4470 GtkWidget *vbox2; | |
4471 GList *focus_chain = NULL; | |
4472 | |
4473 /* Setup the outer pane */ | |
4474 paned = gtk_vpaned_new(); | |
4475 gtk_widget_show(paned); | |
4476 | |
4477 /* Setup the top part of the pane */ | |
4478 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | |
4479 gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE); | |
4480 gtk_widget_show(vbox); | |
4481 | |
4482 /* Setup the gtkimhtml widget */ | |
4483 frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); | |
4484 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); | |
4485 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); | |
4486 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | |
4487 gtk_widget_show(frame); | |
4488 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), | |
4489 &imhtml_sw_hscroll, NULL); | |
4490 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), | |
4491 imhtml_sw_hscroll, GTK_POLICY_ALWAYS); | |
4492 | |
4493 gtk_widget_set_size_request(gtkconv->imhtml, | |
4494 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"), | |
4495 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height")); | |
4496 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", | |
4497 G_CALLBACK(size_allocate_cb), gtkconv); | |
4498 | |
4499 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", | |
4500 G_CALLBACK(entry_stop_rclick_cb), NULL); | |
4501 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", | |
4502 G_CALLBACK(refocus_entry_cb), gtkconv); | |
4503 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", | |
4504 G_CALLBACK(refocus_entry_cb), gtkconv); | |
4505 | |
4506 /* Setup the bottom half of the conversation window */ | |
4507 vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | |
4508 gtk_paned_pack2(GTK_PANED(paned), vbox2, FALSE, TRUE); | |
4509 gtk_widget_show(vbox2); | |
4510 | |
4511 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | |
4512 gtk_box_pack_start(GTK_BOX(vbox2), gtkconv->lower_hbox, TRUE, TRUE, 0); | |
4513 gtk_widget_show(gtkconv->lower_hbox); | |
4514 | |
4515 vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | |
4516 gtk_box_pack_end(GTK_BOX(gtkconv->lower_hbox), vbox2, TRUE, TRUE, 0); | |
4517 gtk_widget_show(vbox2); | |
4518 | |
4519 /* Setup the toolbar, entry widget and all signals */ | |
4520 frame = pidgin_create_imhtml(TRUE, >kconv->entry, >kconv->toolbar, NULL); | |
4521 gtk_box_pack_start(GTK_BOX(vbox2), frame, TRUE, TRUE, 0); | |
4522 gtk_widget_show(frame); | |
4523 | |
4524 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", | |
4525 G_CALLBACK(entry_popup_menu_cb), gtkconv); | |
4526 | |
4527 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); | |
4528 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), | |
4529 purple_account_get_protocol_name(conv->account)); | |
4530 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, | |
4531 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height")); | |
4532 gtkconv->entry_buffer = | 4503 gtkconv->entry_buffer = |
4533 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); | 4504 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); |
4534 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); | 4505 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); |
4535 | 4506 |
4536 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", | 4507 if (!chat) { |
4537 G_CALLBACK(entry_key_press_cb), gtkconv); | 4508 /* For sending typing notifications for IMs */ |
4538 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", | 4509 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", |
4539 G_CALLBACK(send_cb), gtkconv); | 4510 G_CALLBACK(insert_text_cb), gtkconv); |
4540 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", | 4511 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", |
4541 G_CALLBACK(entry_stop_rclick_cb), NULL); | 4512 G_CALLBACK(delete_text_cb), gtkconv); |
4542 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", | 4513 gtkconv->u.im->typing_timer = 0; |
4543 G_CALLBACK(size_allocate_cb), gtkconv); | 4514 gtkconv->u.im->animate = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/animate_buddy_icons"); |
4544 | 4515 gtkconv->u.im->show_icon = TRUE; |
4545 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", | 4516 } |
4546 G_CALLBACK(insert_text_cb), gtkconv); | 4517 |
4547 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", | |
4548 G_CALLBACK(delete_text_cb), gtkconv); | |
4549 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", | 4518 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", |
4550 G_CALLBACK(resize_imhtml_cb), gtkconv); | 4519 G_CALLBACK(resize_imhtml_cb), gtkconv); |
4551 | 4520 |
4552 /* had to move this after the imtoolbar is attached so that the | |
4553 * signals get fired to toggle the buttons on the toolbar as well. | |
4554 */ | |
4555 default_formatize(gtkconv); | 4521 default_formatize(gtkconv); |
4556 | |
4557 g_signal_connect_after(G_OBJECT(gtkconv->entry), "format_function_clear", | 4522 g_signal_connect_after(G_OBJECT(gtkconv->entry), "format_function_clear", |
4558 G_CALLBACK(clear_formatting_cb), gtkconv); | 4523 G_CALLBACK(clear_formatting_cb), gtkconv); |
4559 | 4524 |
4560 gtkconv->u.im->animate = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/animate_buddy_icons"); | |
4561 gtkconv->u.im->show_icon = TRUE; | |
4562 | |
4563 /* | |
4564 * Focus for IM windows should be as follows: | |
4565 * Tab title -> conversation scrollback -> entry | |
4566 */ | |
4567 focus_chain = g_list_prepend(focus_chain, gtkconv->entry); | |
4568 gtk_container_set_focus_chain(GTK_CONTAINER(vbox2), focus_chain); | |
4569 | |
4570 gtkconv->u.im->typing_timer = 0; | |
4571 return paned; | 4525 return paned; |
4572 } | 4526 } |
4573 | 4527 |
4574 static void | 4528 static void |
4575 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | 4529 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, |
4761 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; | 4715 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; |
4762 gtkconv->unseen_count = 0; | 4716 gtkconv->unseen_count = 0; |
4763 | 4717 |
4764 if (conv_type == PURPLE_CONV_TYPE_IM) { | 4718 if (conv_type == PURPLE_CONV_TYPE_IM) { |
4765 gtkconv->u.im = g_malloc0(sizeof(PidginImPane)); | 4719 gtkconv->u.im = g_malloc0(sizeof(PidginImPane)); |
4766 | |
4767 pane = setup_im_pane(gtkconv); | |
4768 } else if (conv_type == PURPLE_CONV_TYPE_CHAT) { | 4720 } else if (conv_type == PURPLE_CONV_TYPE_CHAT) { |
4769 gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane)); | 4721 gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane)); |
4770 pane = setup_chat_pane(gtkconv); | 4722 } |
4771 } | 4723 pane = setup_common_pane(gtkconv); |
4772 | 4724 |
4773 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml), | 4725 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml), |
4774 gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE); | 4726 gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE); |
4775 | 4727 |
4776 if (pane == NULL) { | 4728 if (pane == NULL) { |
5164 g_return_if_fail(account != NULL); | 5116 g_return_if_fail(account != NULL); |
5165 gc = purple_account_get_connection(account); | 5117 gc = purple_account_get_connection(account); |
5166 g_return_if_fail(gc != NULL); | 5118 g_return_if_fail(gc != NULL); |
5167 | 5119 |
5168 /* Make sure URLs are clickable */ | 5120 /* Make sure URLs are clickable */ |
5169 displaying = purple_markup_linkify(message); | 5121 if(flags & PURPLE_MESSAGE_NO_LINKIFY) |
5122 displaying = g_strdup(message); | |
5123 else | |
5124 displaying = purple_markup_linkify(message); | |
5125 | |
5170 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( | 5126 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( |
5171 pidgin_conversations_get_handle(), (type == PURPLE_CONV_TYPE_IM ? | 5127 pidgin_conversations_get_handle(), (type == PURPLE_CONV_TYPE_IM ? |
5172 "displaying-im-msg" : "displaying-chat-msg"), | 5128 "displaying-im-msg" : "displaying-chat-msg"), |
5173 account, name, &displaying, conv, flags)); | 5129 account, name, &displaying, conv, flags)); |
5174 if (plugin_return) | 5130 if (plugin_return) |
8114 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging), | 8070 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging), |
8115 purple_conversation_is_logging(conv)); | 8071 purple_conversation_is_logging(conv)); |
8116 | 8072 |
8117 generate_send_to_items(win); | 8073 generate_send_to_items(win); |
8118 regenerate_options_items(win); | 8074 regenerate_options_items(win); |
8075 regenerate_plugins_items(win); | |
8119 | 8076 |
8120 pidgin_conv_switch_active_conversation(conv); | 8077 pidgin_conv_switch_active_conversation(conv); |
8121 | 8078 |
8122 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); | 8079 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); |
8123 if (strcmp(sound_method, "none") != 0) | 8080 if (strcmp(sound_method, "none") != 0) |
8184 offline_list = make_status_icon_list(PIDGIN_STOCK_STATUS_OFFLINE, w); | 8141 offline_list = make_status_icon_list(PIDGIN_STOCK_STATUS_OFFLINE, w); |
8185 away_list = make_status_icon_list(PIDGIN_STOCK_STATUS_AWAY, w); | 8142 away_list = make_status_icon_list(PIDGIN_STOCK_STATUS_AWAY, w); |
8186 prpl_lists = g_hash_table_new(g_str_hash, g_str_equal); | 8143 prpl_lists = g_hash_table_new(g_str_hash, g_str_equal); |
8187 } | 8144 } |
8188 | 8145 |
8146 static void | |
8147 plugin_changed_cb(PurplePlugin *p, gpointer data) | |
8148 { | |
8149 regenerate_plugins_items(data); | |
8150 } | |
8151 | |
8189 PidginWindow * | 8152 PidginWindow * |
8190 pidgin_conv_window_new() | 8153 pidgin_conv_window_new() |
8191 { | 8154 { |
8192 PidginWindow *win; | 8155 PidginWindow *win; |
8193 GtkPositionType pos; | 8156 GtkPositionType pos; |
8197 win = g_malloc0(sizeof(PidginWindow)); | 8160 win = g_malloc0(sizeof(PidginWindow)); |
8198 | 8161 |
8199 window_list = g_list_append(window_list, win); | 8162 window_list = g_list_append(window_list, win); |
8200 | 8163 |
8201 /* Create the window. */ | 8164 /* Create the window. */ |
8202 win->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | 8165 win->window = pidgin_create_window(NULL, 0, "conversation", TRUE); |
8203 gtk_window_set_role(GTK_WINDOW(win->window), "conversation"); | |
8204 gtk_window_set_resizable(GTK_WINDOW(win->window), TRUE); | |
8205 gtk_container_set_border_width(GTK_CONTAINER(win->window), 0); | |
8206 GTK_WINDOW(win->window)->allow_shrink = TRUE; | 8166 GTK_WINDOW(win->window)->allow_shrink = TRUE; |
8207 | 8167 |
8208 if (available_list == NULL) { | 8168 if (available_list == NULL) { |
8209 create_icon_lists(win->window); | 8169 create_icon_lists(win->window); |
8210 } | 8170 } |
8257 gtk_box_pack_start(GTK_BOX(testidea), win->notebook, TRUE, TRUE, 0); | 8217 gtk_box_pack_start(GTK_BOX(testidea), win->notebook, TRUE, TRUE, 0); |
8258 | 8218 |
8259 gtk_container_add(GTK_CONTAINER(win->window), testidea); | 8219 gtk_container_add(GTK_CONTAINER(win->window), testidea); |
8260 | 8220 |
8261 gtk_widget_show(testidea); | 8221 gtk_widget_show(testidea); |
8222 | |
8223 /* Update the plugin actions when plugins are (un)loaded */ | |
8224 purple_signal_connect(purple_plugins_get_handle(), "plugin-load", | |
8225 win, PURPLE_CALLBACK(plugin_changed_cb), win); | |
8226 purple_signal_connect(purple_plugins_get_handle(), "plugin-unload", | |
8227 win, PURPLE_CALLBACK(plugin_changed_cb), win); | |
8228 | |
8262 | 8229 |
8263 #ifdef _WIN32 | 8230 #ifdef _WIN32 |
8264 g_signal_connect(G_OBJECT(win->window), "show", | 8231 g_signal_connect(G_OBJECT(win->window), "show", |
8265 G_CALLBACK(winpidgin_ensure_onscreen), win->window); | 8232 G_CALLBACK(winpidgin_ensure_onscreen), win->window); |
8266 #endif | 8233 #endif |
8297 gtk_widget_destroy(win->window); | 8264 gtk_widget_destroy(win->window); |
8298 | 8265 |
8299 g_object_unref(G_OBJECT(win->menu.item_factory)); | 8266 g_object_unref(G_OBJECT(win->menu.item_factory)); |
8300 | 8267 |
8301 purple_notify_close_with_handle(win); | 8268 purple_notify_close_with_handle(win); |
8269 purple_signals_disconnect_by_handle(win); | |
8302 | 8270 |
8303 g_free(win); | 8271 g_free(win); |
8304 } | 8272 } |
8305 | 8273 |
8306 void | 8274 void |