diff -r ed70e92f7c28 -r d461ccafa1fb pidgin/gtkconv.c --- a/pidgin/gtkconv.c Fri Jun 15 19:07:02 2007 +0000 +++ b/pidgin/gtkconv.c Fri Jun 15 19:34:24 2007 +0000 @@ -272,65 +272,7 @@ default_formatize(PidginConversation *c) { PurpleConversation *conv = c->active_conv; - - if (conv->features & PURPLE_CONNECTION_HTML) - { - char color[8]; - GdkColor fg_color, bg_color; - - if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold") != GTK_IMHTML(c->entry)->edit.bold) - gtk_imhtml_toggle_bold(GTK_IMHTML(c->entry)); - - if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic") != GTK_IMHTML(c->entry)->edit.italic) - gtk_imhtml_toggle_italic(GTK_IMHTML(c->entry)); - - if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline") != GTK_IMHTML(c->entry)->edit.underline) - gtk_imhtml_toggle_underline(GTK_IMHTML(c->entry)); - - gtk_imhtml_toggle_fontface(GTK_IMHTML(c->entry), - purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/font_face")); - - if (!(conv->features & PURPLE_CONNECTION_NO_FONTSIZE)) - { - int size = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/font_size"); - - /* 3 is the default. */ - if (size != 3) - gtk_imhtml_font_set_size(GTK_IMHTML(c->entry), size); - } - - if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), "") != 0) - { - gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), - &fg_color); - g_snprintf(color, sizeof(color), "#%02x%02x%02x", - fg_color.red / 256, - fg_color.green / 256, - fg_color.blue / 256); - } else - strcpy(color, ""); - - gtk_imhtml_toggle_forecolor(GTK_IMHTML(c->entry), color); - - if(!(conv->features & PURPLE_CONNECTION_NO_BGCOLOR) && - strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), "") != 0) - { - gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), - &bg_color); - g_snprintf(color, sizeof(color), "#%02x%02x%02x", - bg_color.red / 256, - bg_color.green / 256, - bg_color.blue / 256); - } else - strcpy(color, ""); - - gtk_imhtml_toggle_background(GTK_IMHTML(c->entry), color); - - if (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO) - gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(c->entry), TRUE); - else - gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(c->entry), FALSE); - } + gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), conv->features); } static void @@ -478,6 +420,7 @@ char *cmd; const char *prefix; GtkTextIter start; + gboolean retval = FALSE; gtkconv = PIDGIN_CONVERSATION(conv); prefix = pidgin_get_cmd_prefix(); @@ -501,24 +444,50 @@ gtk_text_buffer_get_end_iter(GTK_IMHTML(gtkconv->entry)->text_buffer, &end); markup = gtk_imhtml_get_markup_range(GTK_IMHTML(gtkconv->entry), &start, &end); status = purple_cmd_do_command(conv, cmdline, markup, &error); - g_free(cmd); g_free(markup); switch (status) { case PURPLE_CMD_STATUS_OK: - return TRUE; + retval = TRUE; + break; case PURPLE_CMD_STATUS_NOT_FOUND: - return FALSE; + { + PurplePluginProtocolInfo *prpl_info = NULL; + PurpleConnection *gc; + + if ((gc = purple_conversation_get_gc(conv))) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); + + if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) { + char *firstspace; + char *slash; + + firstspace = strchr(cmdline, ' '); + if (firstspace != NULL) { + slash = strrchr(firstspace, '/'); + } else { + slash = strchr(cmdline, '/'); + } + + if (slash == NULL) { + purple_conversation_write(conv, "", _("Unknown command."), PURPLE_MESSAGE_NO_LOG, time(NULL)); + retval = TRUE; + } + } + break; + } case PURPLE_CMD_STATUS_WRONG_ARGS: purple_conversation_write(conv, "", _("Syntax Error: You typed the wrong number of arguments " "to that command."), PURPLE_MESSAGE_NO_LOG, time(NULL)); - return TRUE; + retval = TRUE; + break; case PURPLE_CMD_STATUS_FAILED: purple_conversation_write(conv, "", error ? error : _("Your command failed for an unknown reason."), PURPLE_MESSAGE_NO_LOG, time(NULL)); g_free(error); - return TRUE; + retval = TRUE; + break; case PURPLE_CMD_STATUS_WRONG_TYPE: if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) purple_conversation_write(conv, "", _("That command only works in chats, not IMs."), @@ -526,16 +495,18 @@ else purple_conversation_write(conv, "", _("That command only works in IMs, not chats."), PURPLE_MESSAGE_NO_LOG, time(NULL)); - return TRUE; + retval = TRUE; + break; case PURPLE_CMD_STATUS_WRONG_PRPL: purple_conversation_write(conv, "", _("That command doesn't work on this protocol."), PURPLE_MESSAGE_NO_LOG, time(NULL)); - return TRUE; + retval = TRUE; + break; } } g_free(cmd); - return FALSE; + return retval; } static void @@ -667,7 +638,7 @@ purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); } else - prpl_info->get_info(gc, who); + pidgin_retrieve_user_info(gc, who); } } @@ -678,14 +649,8 @@ PurpleConversation *conv = gtkconv->active_conv; if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { - PurpleNotifyUserInfo *info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); - purple_notify_userinfo(conv->account->gc, purple_conversation_get_name(conv), info, NULL, NULL); - purple_notify_user_info_destroy(info); - - serv_get_info(purple_conversation_get_gc(conv), + pidgin_retrieve_user_info(purple_conversation_get_gc(conv), purple_conversation_get_name(conv)); - gtk_widget_grab_focus(gtkconv->entry); } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { /* Get info of the person currently selected in the GtkTreeView */ @@ -2273,34 +2238,18 @@ static GList *get_prpl_icon_list(PurpleAccount *account) { GList *l = NULL; - GdkPixbuf *pixbuf; - PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account))); - const char *prpl = prpl_info->list_icon(account, NULL); - char *filename, *path; - l = g_hash_table_lookup(prpl_lists, prpl); + PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account)); + PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + const char *prplname = prpl_info->list_icon(account, NULL); + l = g_hash_table_lookup(prpl_lists, prplname); if (l) return l; - filename = g_strdup_printf("%s.png", prpl); - - path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "16", filename, NULL); - pixbuf = gdk_pixbuf_new_from_file(path, NULL); - if (pixbuf) - l = g_list_append(l, pixbuf); - g_free(path); - - path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", filename, NULL); - pixbuf = gdk_pixbuf_new_from_file(path, NULL); - if (pixbuf) - l = g_list_append(l, pixbuf); - g_free(path); - - path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "48", filename, NULL); - pixbuf = gdk_pixbuf_new_from_file(path, NULL); - if (pixbuf) - l = g_list_append(l, pixbuf); - g_free(path); - - g_hash_table_insert(prpl_lists, g_strdup(prpl), l); + + l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_LARGE)); + l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM)); + l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL)); + + g_hash_table_insert(prpl_lists, g_strdup(prplname), l); return l; } @@ -2741,7 +2690,7 @@ gboolean hidden_only, guint max_count) { - GList *l; + const GList *l; GList *r = NULL; guint c = 0; @@ -3029,10 +2978,65 @@ gtk_widget_show_all(menu); } +static void +remove_from_list(GtkWidget *widget, PidginWindow *win) +{ + GList *list = g_object_get_data(G_OBJECT(win->window), "plugin-actions"); + list = g_list_remove(list, widget); + g_object_set_data(G_OBJECT(win->window), "plugin-actions", list); +} + +static void +regenerate_plugins_items(PidginWindow *win) +{ + GList *action_items; + GtkWidget *menu; + GList *list; + PidginConversation *gtkconv; + PurpleConversation *conv; + GtkWidget *item; + + if (win->window == NULL || win == hidden_convwin) + return; + + gtkconv = pidgin_conv_window_get_active_gtkconv(win); + if (gtkconv == NULL) + return; + + conv = gtkconv->active_conv; + action_items = g_object_get_data(G_OBJECT(win->window), "plugin-actions"); + + /* Remove the old menuitems */ + while (action_items) { + g_signal_handlers_disconnect_by_func(G_OBJECT(action_items->data), + G_CALLBACK(remove_from_list), win); + gtk_widget_destroy(action_items->data); + action_items = g_list_delete_link(action_items, action_items); + } + + menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options")); + + list = purple_conversation_get_extended_menu(conv); + if (list) { + action_items = g_list_prepend(NULL, (item = pidgin_separator(menu))); + g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); + } + + for(; list; list = g_list_delete_link(list, list)) { + PurpleMenuAction *act = (PurpleMenuAction *) list->data; + item = pidgin_append_menu_action(menu, act, conv); + action_items = g_list_prepend(action_items, item); + gtk_widget_show_all(item); + g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); + } + g_object_set_data(G_OBJECT(win->window), "plugin-actions", action_items); +} + static void menubar_activated(GtkWidget *item, gpointer data) { PidginWindow *win = data; regenerate_options_items(win); + regenerate_plugins_items(win); /* The following are to make sure the 'More' submenu is not regenerated every time * the focus shifts from 'Conversations' to some other menu and back. */ @@ -3846,7 +3850,7 @@ g_list_free(list); } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); - GList *l = purple_conv_chat_get_users(chat); + const GList *l = purple_conv_chat_get_users(chat); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list)); GtkTreeIter iter; int f; @@ -4244,45 +4248,17 @@ } } -static GtkWidget * -setup_chat_pane(PidginConversation *gtkconv) -{ - PurplePluginProtocolInfo *prpl_info; +static void +setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox) +{ PurpleConversation *conv = gtkconv->active_conv; - PidginChatPane *gtkchat; - PurpleConnection *gc; - GtkWidget *vpaned, *hpaned; - GtkWidget *vbox, *hbox, *frame; - GtkWidget *imhtml_sw; - GtkPolicyType imhtml_sw_hscroll; - GtkWidget *lbox; - GtkWidget *label; - GtkWidget *list; - GtkWidget *sw; - GtkListStore *ls; - GtkCellRenderer *rend; - GtkTreeViewColumn *col; - void *blist_handle = purple_blist_get_handle(); - GList *focus_chain = NULL; - int ul_width; - - gtkchat = gtkconv->u.chat; - gc = purple_conversation_get_gc(conv); - g_return_val_if_fail(gc != NULL, NULL); - g_return_val_if_fail(gc->prpl != NULL, NULL); - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); - - /* Setup the outer pane. */ - vpaned = gtk_vpaned_new(); - gtk_widget_show(vpaned); - - /* Setup the top part of the pane. */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_paned_pack1(GTK_PANED(vpaned), vbox, TRUE, TRUE); - gtk_widget_show(vbox); - + PurpleConnection *gc = purple_conversation_get_gc(conv); + PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) { + GtkWidget *hbox, *label; + PidginChatPane *gtkchat = gtkconv->u.chat; + hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); @@ -4305,35 +4281,19 @@ g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", G_CALLBACK(entry_key_press_cb), gtkconv); } - - /* Setup the horizontal pane. */ - hpaned = gtk_hpaned_new(); - gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); - gtk_widget_show(hpaned); - - /* Setup gtkihmtml. */ - frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); - gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); - gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), TRUE); - gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE); - gtk_widget_show(frame); - gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), - &imhtml_sw_hscroll, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), - imhtml_sw_hscroll, GTK_POLICY_ALWAYS); - - gtk_widget_set_size_request(gtkconv->imhtml, - purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width"), - purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height")); - g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", - G_CALLBACK(size_allocate_cb), gtkconv); - - g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", - G_CALLBACK(entry_stop_rclick_cb), NULL); - g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", - G_CALLBACK(refocus_entry_cb), gtkconv); - g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", - G_CALLBACK(refocus_entry_cb), gtkconv); +} + +static void +setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned) +{ + PidginChatPane *gtkchat = gtkconv->u.chat; + GtkWidget *lbox, *sw, *list; + GtkListStore *ls; + GtkCellRenderer *rend; + GtkTreeViewColumn *col; + int ul_width; + void *blist_handle = purple_blist_get_handle(); + PurpleConversation *conv = gtkconv->active_conv; /* Build the right pane. */ lbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); @@ -4381,9 +4341,7 @@ G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv); g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv); - rend = gtk_cell_renderer_text_new(); - g_object_set(rend, "foreground-set", TRUE, "weight-set", TRUE, @@ -4414,10 +4372,72 @@ gtkchat->list = list; gtk_container_add(GTK_CONTAINER(sw), list); +} + +static GtkWidget * +setup_common_pane(PidginConversation *gtkconv) +{ + GtkWidget *paned, *vbox, *frame, *imhtml_sw; + PurpleConversation *conv = gtkconv->active_conv; + gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); + GtkPolicyType imhtml_sw_hscroll; + + paned = gtk_vpaned_new(); + gtk_widget_show(paned); + + /* Setup the top part of the pane */ + vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); + gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE); + gtk_widget_show(vbox); + + /* Setup the gtkimhtml widget */ + frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); + if (chat) { + GtkWidget *hpaned; + + /* Add the topic */ + setup_chat_topic(gtkconv, vbox); + + /* Add the gtkimhtml frame */ + hpaned = gtk_hpaned_new(); + gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); + gtk_widget_show(hpaned); + gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE); + + /* Now add the userlist */ + setup_chat_userlist(gtkconv, hpaned); + } else { + gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); + } + gtk_widget_show(frame); + + gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); + gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); + + gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), + &imhtml_sw_hscroll, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), + imhtml_sw_hscroll, GTK_POLICY_ALWAYS); + + gtk_widget_set_size_request(gtkconv->imhtml, + chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width") : + purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"), + chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height") : + purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height")); + + g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", + G_CALLBACK(size_allocate_cb), gtkconv); + + g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", + G_CALLBACK(entry_stop_rclick_cb), NULL); + g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", + G_CALLBACK(refocus_entry_cb), gtkconv); + g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", + G_CALLBACK(refocus_entry_cb), gtkconv); /* Setup the bottom half of the conversation window */ vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_paned_pack2(GTK_PANED(vpaned), vbox, FALSE, TRUE); + gtk_paned_pack2(GTK_PANED(paned), vbox, FALSE, TRUE); gtk_widget_show(vbox); gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); @@ -4433,20 +4453,15 @@ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); - g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", - G_CALLBACK(entry_popup_menu_cb), gtkconv); - gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), - purple_account_get_protocol_name(conv->account)); + purple_account_get_protocol_name(conv->account)); gtk_widget_set_size_request(gtkconv->lower_hbox, -1, - purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height")); - gtkconv->entry_buffer = - gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); - g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); - g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", - G_CALLBACK(resize_imhtml_cb), gtkconv); - + chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height") : + purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height")); + + g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", + G_CALLBACK(entry_popup_menu_cb), gtkconv); g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", G_CALLBACK(entry_key_press_cb), gtkconv); g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", @@ -4456,129 +4471,28 @@ g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", G_CALLBACK(size_allocate_cb), gtkconv); - default_formatize(gtkconv); - - /* - * Focus for chat windows should be as follows: - * Tab title -> chat topic -> conversation scrollback -> user list -> - * user list buttons -> entry -> buttons at bottom - */ - focus_chain = g_list_prepend(focus_chain, gtkconv->entry); - gtk_container_set_focus_chain(GTK_CONTAINER(vbox), focus_chain); - - return vpaned; -} - -static GtkWidget * -setup_im_pane(PidginConversation *gtkconv) -{ - PurpleConversation *conv = gtkconv->active_conv; - GtkWidget *frame; - GtkWidget *imhtml_sw; - GtkPolicyType imhtml_sw_hscroll; - GtkWidget *paned; - GtkWidget *vbox; - GtkWidget *vbox2; - GList *focus_chain = NULL; - - /* Setup the outer pane */ - paned = gtk_vpaned_new(); - gtk_widget_show(paned); - - /* Setup the top part of the pane */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE); - gtk_widget_show(vbox); - - /* Setup the gtkimhtml widget */ - frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); - gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); - gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); - gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); - gtk_widget_show(frame); - gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), - &imhtml_sw_hscroll, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), - imhtml_sw_hscroll, GTK_POLICY_ALWAYS); - - gtk_widget_set_size_request(gtkconv->imhtml, - purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"), - purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height")); - g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", - G_CALLBACK(size_allocate_cb), gtkconv); - - g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", - G_CALLBACK(entry_stop_rclick_cb), NULL); - g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", - G_CALLBACK(refocus_entry_cb), gtkconv); - g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", - G_CALLBACK(refocus_entry_cb), gtkconv); - - /* Setup the bottom half of the conversation window */ - vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_paned_pack2(GTK_PANED(paned), vbox2, FALSE, TRUE); - gtk_widget_show(vbox2); - - gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_box_pack_start(GTK_BOX(vbox2), gtkconv->lower_hbox, TRUE, TRUE, 0); - gtk_widget_show(gtkconv->lower_hbox); - - vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_box_pack_end(GTK_BOX(gtkconv->lower_hbox), vbox2, TRUE, TRUE, 0); - gtk_widget_show(vbox2); - - /* Setup the toolbar, entry widget and all signals */ - frame = pidgin_create_imhtml(TRUE, >kconv->entry, >kconv->toolbar, NULL); - gtk_box_pack_start(GTK_BOX(vbox2), frame, TRUE, TRUE, 0); - gtk_widget_show(frame); - - g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", - G_CALLBACK(entry_popup_menu_cb), gtkconv); - - gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); - gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), - purple_account_get_protocol_name(conv->account)); - gtk_widget_set_size_request(gtkconv->lower_hbox, -1, - purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height")); gtkconv->entry_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); - g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", - G_CALLBACK(entry_key_press_cb), gtkconv); - g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", - G_CALLBACK(send_cb), gtkconv); - g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", - G_CALLBACK(entry_stop_rclick_cb), NULL); - g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", - G_CALLBACK(size_allocate_cb), gtkconv); - - g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", - G_CALLBACK(insert_text_cb), gtkconv); - g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", - G_CALLBACK(delete_text_cb), gtkconv); + if (!chat) { + /* For sending typing notifications for IMs */ + g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", + G_CALLBACK(insert_text_cb), gtkconv); + g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", + G_CALLBACK(delete_text_cb), gtkconv); + gtkconv->u.im->typing_timer = 0; + gtkconv->u.im->animate = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/animate_buddy_icons"); + gtkconv->u.im->show_icon = TRUE; + } + g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", G_CALLBACK(resize_imhtml_cb), gtkconv); - /* had to move this after the imtoolbar is attached so that the - * signals get fired to toggle the buttons on the toolbar as well. - */ default_formatize(gtkconv); - g_signal_connect_after(G_OBJECT(gtkconv->entry), "format_function_clear", - G_CALLBACK(clear_formatting_cb), gtkconv); - - gtkconv->u.im->animate = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/animate_buddy_icons"); - gtkconv->u.im->show_icon = TRUE; - - /* - * Focus for IM windows should be as follows: - * Tab title -> conversation scrollback -> entry - */ - focus_chain = g_list_prepend(focus_chain, gtkconv->entry); - gtk_container_set_focus_chain(GTK_CONTAINER(vbox2), focus_chain); - - gtkconv->u.im->typing_timer = 0; + G_CALLBACK(clear_formatting_cb), gtkconv); + return paned; } @@ -4774,12 +4688,10 @@ if (conv_type == PURPLE_CONV_TYPE_IM) { gtkconv->u.im = g_malloc0(sizeof(PidginImPane)); - - pane = setup_im_pane(gtkconv); } else if (conv_type == PURPLE_CONV_TYPE_CHAT) { gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane)); - pane = setup_chat_pane(gtkconv); - } + } + pane = setup_common_pane(gtkconv); gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml), gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE); @@ -5177,7 +5089,11 @@ g_return_if_fail(gc != NULL); /* Make sure URLs are clickable */ - displaying = purple_markup_linkify(message); + if(flags & PURPLE_MESSAGE_NO_LINKIFY) + displaying = g_strdup(message); + else + displaying = purple_markup_linkify(message); + plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( pidgin_conversations_get_handle(), (type == PURPLE_CONV_TYPE_IM ? "displaying-im-msg" : "displaying-chat-msg"), @@ -5530,7 +5446,7 @@ gtkconv = PIDGIN_CONVERSATION(conv); gtkchat = gtkconv->u.chat; - num_users = g_list_length(purple_conv_chat_get_users(chat)); + num_users = g_list_length((GList *)purple_conv_chat_get_users(chat)); g_snprintf(tmp, sizeof(tmp), ngettext("%d person in room", "%d people in room", @@ -5624,7 +5540,7 @@ gtkconv = PIDGIN_CONVERSATION(conv); gtkchat = gtkconv->u.chat; - num_users = g_list_length(purple_conv_chat_get_users(chat)); + num_users = g_list_length((GList *)purple_conv_chat_get_users(chat)); for (l = users; l != NULL; l = l->next) { model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); @@ -6621,7 +6537,7 @@ close_on_tabs_pref_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data) { - GList *l; + const GList *l; PurpleConversation *conv; PidginConversation *gtkconv; @@ -6645,7 +6561,7 @@ gconstpointer value, gpointer data) { #ifdef USE_GTKSPELL - GList *cl; + const GList *cl; PurpleConversation *conv; PidginConversation *gtkconv; GtkSpell *spell; @@ -6692,7 +6608,7 @@ show_timestamps_pref_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data) { - GList *l; + const GList *l; PurpleConversation *conv; PidginConversation *gtkconv; PidginWindow *win; @@ -6720,7 +6636,7 @@ show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data) { - GList *l; + const GList *l; PurpleConversation *conv; PidginConversation *gtkconv; PidginWindow *win; @@ -6750,7 +6666,7 @@ animate_buddy_icons_pref_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data) { - GList *l; + const GList *l; PurpleConversation *conv; PidginConversation *gtkconv; PidginWindow *win; @@ -6777,7 +6693,7 @@ show_buddy_icons_pref_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data) { - GList *l; + const GList *l; for (l = purple_get_conversations(); l != NULL; l = l->next) { PurpleConversation *conv = l->data; @@ -6903,7 +6819,7 @@ static void account_signed_off_cb(PurpleConnection *gc, gpointer event) { - GList *iter; + const GList *iter; for (iter = purple_get_conversations(); iter; iter = iter->next) { @@ -8092,6 +8008,7 @@ generate_send_to_items(win); regenerate_options_items(win); + regenerate_plugins_items(win); pidgin_conv_switch_active_conversation(conv); @@ -8162,6 +8079,12 @@ prpl_lists = g_hash_table_new(g_str_hash, g_str_equal); } +static void +plugin_changed_cb(PurplePlugin *p, gpointer data) +{ + regenerate_plugins_items(data); +} + PidginWindow * pidgin_conv_window_new() { @@ -8175,10 +8098,7 @@ window_list = g_list_append(window_list, win); /* Create the window. */ - win->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_role(GTK_WINDOW(win->window), "conversation"); - gtk_window_set_resizable(GTK_WINDOW(win->window), TRUE); - gtk_container_set_border_width(GTK_CONTAINER(win->window), 0); + win->window = pidgin_create_window(NULL, 0, "conversation", TRUE); GTK_WINDOW(win->window)->allow_shrink = TRUE; if (available_list == NULL) { @@ -8236,6 +8156,13 @@ gtk_widget_show(testidea); + /* Update the plugin actions when plugins are (un)loaded */ + purple_signal_connect(purple_plugins_get_handle(), "plugin-load", + win, PURPLE_CALLBACK(plugin_changed_cb), win); + purple_signal_connect(purple_plugins_get_handle(), "plugin-unload", + win, PURPLE_CALLBACK(plugin_changed_cb), win); + + #ifdef _WIN32 g_signal_connect(G_OBJECT(win->window), "show", G_CALLBACK(winpidgin_ensure_onscreen), win->window); @@ -8275,6 +8202,7 @@ g_object_unref(G_OBJECT(win->menu.item_factory)); purple_notify_close_with_handle(win); + purple_signals_disconnect_by_handle(win); g_free(win); }