# HG changeset patch # User Sadrul Habib Chowdhury # Date 1180070960 0 # Node ID 969db2eac11b2d76e9083fb28db161d931cba2fa # Parent 19678776d406d1f795f30fd21eefa43bd73589aa# Parent 012aaa301a30c264c8bad83d87b06fdf3ed0875b merge of '68a7c85152f55e4b824422958bca00f79f48cd2f' and 'afa98b3ae88331e3d84749b17c5dd429182eaa02' diff -r 19678776d406 -r 969db2eac11b ChangeLog.API --- a/ChangeLog.API Fri May 25 04:03:19 2007 +0000 +++ b/ChangeLog.API Fri May 25 05:29:20 2007 +0000 @@ -1,5 +1,22 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.1.0 (?/?/?): + Added: + * purple_conversation_get_extended_menu + * purple_conversation_do_command + * pidgin_retrieve_user_info, shows immediate feedback when getting + information about a user. + + Changed: + * pidgin_separator returns the separator added to the menu. + * pidgin_append_menu_action returns the menuitem added to the menu. + + Signals - Added: (See the Doxygen docs for details on all signals.) + * "conversation-extended-menu" + + Finch - Added: + * finch_retrieve_user_info + version 2.0.0 (5/3/2007): Please note all functions, defines, and data structures have been re-namespaced to match the new names of Pidgin, Finch, and libpurple. diff -r 19678776d406 -r 969db2eac11b doc/conversation-signals.dox --- a/doc/conversation-signals.dox Fri May 25 04:03:19 2007 +0000 +++ b/doc/conversation-signals.dox Fri May 25 05:29:20 2007 +0000 @@ -29,6 +29,7 @@ @signal chat-joined @signal chat-left @signal chat-topic-changed + @signal conversation-extended-menu @endsignals @signaldef writing-im-msg @@ -417,5 +418,15 @@ @param topic The new topic. @endsignaldef + @signaldef conversation-extended-menu + @signalproto +void (*conversation_extended_menu)(PurpleConversation *conv, GList **list); + @endsignalproto + @signaldesc + Emitted when the UI requests a list of plugin actions for a + conversation. + @param conv The conversation. + @param list A pointer to the list of actions. + @endsignaldef */ // vim: syntax=c tw=75 et diff -r 19678776d406 -r 969db2eac11b finch/gntblist.c --- a/finch/gntblist.c Fri May 25 04:03:19 2007 +0000 +++ b/finch/gntblist.c Fri May 25 05:29:20 2007 +0000 @@ -824,17 +824,20 @@ PURPLE_CALLBACK(finch_add_group), group); } +void finch_retrieve_user_info(PurpleConnection *conn, const char *name) +{ + PurpleNotifyUserInfo *info = purple_notify_user_info_new(); + purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); + purple_notify_userinfo(conn, name, info, NULL, NULL); + purple_notify_user_info_destroy(info); + + serv_get_info(conn, name); +} + static void finch_blist_get_buddy_info_cb(PurpleBuddy *buddy, PurpleBlistNode *selected) { - /* Add a userinfo with a "Retrieving information", which will later be updated - * when the server finally returns the information. */ - PurpleNotifyUserInfo *info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); - purple_notify_userinfo(buddy->account->gc, purple_buddy_get_name(buddy), info, NULL, NULL); - purple_notify_user_info_destroy(info); - - serv_get_info(buddy->account->gc, purple_buddy_get_name(buddy)); + finch_retrieve_user_info(buddy->account->gc, purple_buddy_get_name(buddy)); } static void diff -r 19678776d406 -r 969db2eac11b finch/gntblist.h --- a/finch/gntblist.h Fri May 25 04:03:19 2007 +0000 +++ b/finch/gntblist.h Fri May 25 05:29:20 2007 +0000 @@ -90,6 +90,14 @@ */ void finch_blist_set_size(int width, int height); +/** + * Get information about a user. Show immediate feedback. + * + * @param conn The connection to get information fro + * @param name The user to get information about. + */ +void finch_retrieve_user_info(PurpleConnection *conn, const char *name); + /*@}*/ #endif diff -r 19678776d406 -r 969db2eac11b finch/gntconv.c --- a/finch/gntconv.c Fri May 25 04:03:19 2007 +0000 +++ b/finch/gntconv.c Fri May 25 05:29:20 2007 +0000 @@ -313,12 +313,7 @@ get_info_cb(GntMenuItem *item, gpointer ggconv) { FinchConv *ggc = ggconv; - PurpleNotifyUserInfo *info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); - purple_notify_userinfo(ggc->active_conv->account->gc, purple_conversation_get_name(ggc->active_conv), info, NULL, NULL); - purple_notify_user_info_destroy(info); - - serv_get_info(purple_conversation_get_gc(ggc->active_conv), + finch_retrieve_user_info(purple_conversation_get_gc(ggc->active_conv), purple_conversation_get_name(ggc->active_conv)); } diff -r 19678776d406 -r 969db2eac11b finch/gntnotify.c --- a/finch/gntnotify.c Fri May 25 04:03:19 2007 +0000 +++ b/finch/gntnotify.c Fri May 25 05:29:20 2007 +0000 @@ -168,7 +168,7 @@ gnt_label_new_with_format(_("You have mail!"), GNT_TEXT_FLAG_BOLD)); emaildialog.tree = tree = gnt_tree_new_with_columns(3); - gnt_tree_set_column_titles(GNT_TREE(tree), _("Account"), _("From"), _("Subject")); + gnt_tree_set_column_titles(GNT_TREE(tree), _("Account"), _("Sender"), _("Subject")); gnt_tree_set_show_title(GNT_TREE(tree), TRUE); gnt_tree_set_col_width(GNT_TREE(tree), 0, 15); gnt_tree_set_col_width(GNT_TREE(tree), 1, 25); diff -r 19678776d406 -r 969db2eac11b finch/libgnt/gntmain.c --- a/finch/libgnt/gntmain.c Fri May 25 04:03:19 2007 +0000 +++ b/finch/libgnt/gntmain.c Fri May 25 05:29:20 2007 +0000 @@ -359,8 +359,7 @@ switch (sig) { #ifdef SIGWINCH case SIGWINCH: - werase(stdscr); - wrefresh(stdscr); + erase(); g_idle_add(refresh_screen, NULL); org_winch_handler(sig); signal(SIGWINCH, sighandler); diff -r 19678776d406 -r 969db2eac11b finch/libgnt/gntwm.c --- a/finch/libgnt/gntwm.c Fri May 25 04:03:19 2007 +0000 +++ b/finch/libgnt/gntwm.c Fri May 25 05:29:20 2007 +0000 @@ -980,12 +980,11 @@ GntWM *wm = GNT_WM(bindable); endwin(); - refresh(); - curs_set(0); /* endwin resets the cursor to normal */ g_hash_table_foreach(wm->nodes, (GHFunc)refresh_node, NULL); update_screen(wm); draw_taskbar(wm, TRUE); + curs_set(0); /* endwin resets the cursor to normal */ return FALSE; } diff -r 19678776d406 -r 969db2eac11b libpurple/conversation.c --- a/libpurple/conversation.c Fri May 25 04:03:19 2007 +0000 +++ b/libpurple/conversation.c Fri May 25 05:29:20 2007 +0000 @@ -21,6 +21,7 @@ */ #include "internal.h" #include "blist.h" +#include "cmds.h" #include "conversation.h" #include "dbus-maybe.h" #include "debug.h" @@ -1989,6 +1990,29 @@ return cb->name; } +GList * +purple_conversation_get_extended_menu(PurpleConversation *conv) +{ + GList *menu = NULL; + + g_return_val_if_fail(conv != NULL, NULL); + + purple_signal_emit(purple_conversations_get_handle(), + "conversation-extended-menu", conv, &menu); + return menu; +} + +gboolean +purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline, + const gchar *markup, gchar **error) +{ + char *mark = (markup && *markup) ? NULL : g_markup_escape_text(cmdline, -1), *err = NULL; + PurpleCmdStatus status = purple_cmd_do_command(conv, cmdline, mark ? mark : markup, error ? error : &err); + g_free(mark); + g_free(err); + return (status == PURPLE_CMD_STATUS_OK); +} + void * purple_conversations_get_handle(void) { @@ -2252,6 +2276,12 @@ PURPLE_SUBTYPE_CONVERSATION), purple_value_new(PURPLE_TYPE_STRING), purple_value_new(PURPLE_TYPE_STRING)); + + purple_signal_register(handle, "conversation-extended-menu", + purple_marshal_VOID__POINTER_POINTER, NULL, 2, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_CONVERSATION), + purple_value_new(PURPLE_TYPE_BOXED, "GList **")); } void diff -r 19678776d406 -r 969db2eac11b libpurple/conversation.h --- a/libpurple/conversation.h Fri May 25 04:03:19 2007 +0000 +++ b/libpurple/conversation.h Fri May 25 05:29:20 2007 +0000 @@ -1190,6 +1190,30 @@ */ void purple_conv_chat_cb_destroy(PurpleConvChatBuddy *cb); +/** + * Retrieves the extended menu items for the conversation. + * + * @param conv The conversation. + * + * @return A list of PurpleMenuAction items, harvested by the + * chat-extended-menu signal. The list and the menuaction + * items should be freed by the caller. + */ +GList * purple_conversation_get_extended_menu(PurpleConversation *conv); + +/** + * Perform a command in a conversation. Similar to @see purple_cmd_do_command + * + * @param conv The conversation. + * @param cmdline The entire command including the arguments. + * @param markup @c NULL, or the formatted command line. + * @param error If the command failed errormsg is filled in with the appropriate error + * message, if not @c NULL. It must be freed by the caller with g_free(). + * + * @return @c TRUE if the command was executed successfully, @c FALSE otherwise. + */ +gboolean purple_conversation_do_command(PurpleConversation *conv, const gchar *cmdline, const gchar *markup, gchar **error); + /*@}*/ /**************************************************************************/ diff -r 19678776d406 -r 969db2eac11b libpurple/plugins/perl/common/Account.xs --- a/libpurple/plugins/perl/common/Account.xs Fri May 25 04:03:19 2007 +0000 +++ b/libpurple/plugins/perl/common/Account.xs Fri May 25 05:29:20 2007 +0000 @@ -215,6 +215,7 @@ t_GL = g_list_append(t_GL, SvPV(*av_fetch((AV *)SvRV(list), i, 0), t_sl)); } purple_account_add_buddies(account, t_GL); + g_list_free(t_GL); void purple_account_add_buddy(account, buddy) @@ -252,6 +253,8 @@ t_GL2 = g_list_append(t_GL2, SvPV(*av_fetch((AV *)SvRV(B), i, 0), t_sl)); } purple_account_remove_buddies(account, t_GL1, t_GL2); + g_list_free(t_GL1); + g_list_free(t_GL2); void purple_account_remove_buddy(account, buddy, group) diff -r 19678776d406 -r 969db2eac11b libpurple/plugins/perl/common/BuddyList.xs --- a/libpurple/plugins/perl/common/BuddyList.xs Fri May 25 04:03:19 2007 +0000 +++ b/libpurple/plugins/perl/common/BuddyList.xs Fri May 25 05:29:20 2007 +0000 @@ -263,7 +263,7 @@ PREINIT: GList *l; PPCODE: - for (l = purple_blist_node_get_extended_menu(node); l != NULL; l = l->next) { + for (l = purple_blist_node_get_extended_menu(node); l != NULL; l = g_list_delete_link(l, l)) { XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::Menu::Action"))); } diff -r 19678776d406 -r 969db2eac11b libpurple/plugins/perl/common/Conversation.xs --- a/libpurple/plugins/perl/common/Conversation.xs Fri May 25 04:03:19 2007 +0000 +++ b/libpurple/plugins/perl/common/Conversation.xs Fri May 25 05:29:20 2007 +0000 @@ -218,6 +218,21 @@ Purple::Conversation conv Purple::Account account +void +purple_conversation_write(conv, who, message, flags, mtime) + Purple::Conversation conv + const char *who + const char *message + Purple::MessageFlags flags + time_t mtime + +gboolean +purple_conversation_do_command(conv, cmdline, markup, error) + Purple::Conversation conv + const char *cmdline + const char *markup + char **error + MODULE = Purple::Conversation PACKAGE = Purple::Conversation::IM PREFIX = purple_conv_im_ PROTOTYPES: ENABLE diff -r 19678776d406 -r 969db2eac11b libpurple/plugins/perl/common/Prefs.xs --- a/libpurple/plugins/perl/common/Prefs.xs Fri May 25 04:03:19 2007 +0000 +++ b/libpurple/plugins/perl/common/Prefs.xs Fri May 25 05:29:20 2007 +0000 @@ -94,8 +94,9 @@ PREINIT: GList *l; PPCODE: - for (l = purple_prefs_get_string_list(name); l != NULL; l = l->next) { - XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::PrefValue"))); + for (l = purple_prefs_get_string_list(name); l != NULL; l = g_list_delete_link(l, l)) { + XPUSHs(sv_2mortal(newSVpv(l->data, 0))); + g_free(l->data); } Purple::PrefType diff -r 19678776d406 -r 969db2eac11b pidgin/gtkblist.c --- a/pidgin/gtkblist.c Fri May 25 04:03:19 2007 +0000 +++ b/pidgin/gtkblist.c Fri May 25 05:29:20 2007 +0000 @@ -274,12 +274,7 @@ static void gtk_blist_menu_info_cb(GtkWidget *w, PurpleBuddy *b) { - PurpleNotifyUserInfo *info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); - purple_notify_userinfo(b->account->gc, purple_buddy_get_name(b), info, NULL, NULL); - purple_notify_user_info_destroy(info); - - serv_get_info(b->account->gc, b->name); + pidgin_retrieve_user_info(b->account->gc, purple_buddy_get_name(b)); } static void gtk_blist_menu_im_cb(GtkWidget *w, PurpleBuddy *b) @@ -1147,7 +1142,8 @@ } static gboolean -gtk_blist_key_press_cb(GtkWidget *tv, GdkEventKey *event, gpointer data) { +gtk_blist_key_press_cb(GtkWidget *tv, GdkEventKey *event, gpointer data) +{ PurpleBlistNode *node; GValue val; GtkTreeIter iter; @@ -1174,7 +1170,7 @@ return FALSE; } if(buddy) - serv_get_info(buddy->account->gc, buddy->name); + pidgin_retrieve_user_info(buddy->account->gc, buddy->name); } else if (event->keyval == GDK_F2) { gtk_blist_menu_alias_cb(tv, node); } @@ -1428,7 +1424,7 @@ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); if (prpl && prpl_info->get_info) - serv_get_info(b->account->gc, b->name); + pidgin_retrieve_user_info(b->account->gc, b->name); handled = TRUE; } diff -r 19678776d406 -r 969db2eac11b pidgin/gtkconv.c --- a/pidgin/gtkconv.c Fri May 25 04:03:19 2007 +0000 +++ b/pidgin/gtkconv.c Fri May 25 05:29:20 2007 +0000 @@ -673,14 +673,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 */ @@ -2224,34 +2218,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; } @@ -2928,10 +2906,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. */ @@ -4206,10 +4239,10 @@ &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); @@ -4389,6 +4422,7 @@ 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); @@ -7964,6 +7998,7 @@ generate_send_to_items(win); regenerate_options_items(win); + regenerate_plugins_items(win); pidgin_conv_switch_active_conversation(conv); @@ -8034,6 +8069,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() { @@ -8108,6 +8149,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); @@ -8147,6 +8195,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); } diff -r 19678776d406 -r 969db2eac11b pidgin/gtkdialogs.c --- a/pidgin/gtkdialogs.c Fri May 25 04:03:19 2007 +0000 +++ b/pidgin/gtkdialogs.c Fri May 25 05:29:20 2007 +0000 @@ -823,7 +823,7 @@ found = pidgin_dialogs_ee(username); if (!found && username != NULL && *username != '\0' && account != NULL) - serv_get_info(purple_account_get_connection(account), username); + pidgin_retrieve_user_info(purple_account_get_connection(account), username); g_free(username); } diff -r 19678776d406 -r 969db2eac11b pidgin/gtkutils.c --- a/pidgin/gtkutils.c Fri May 25 04:03:19 2007 +0000 +++ b/pidgin/gtkutils.c Fri May 25 05:29:20 2007 +0000 @@ -237,13 +237,14 @@ gtk_widget_show(to_toggle); } -void pidgin_separator(GtkWidget *menu) +GtkWidget *pidgin_separator(GtkWidget *menu) { GtkWidget *menuitem; menuitem = gtk_separator_menu_item_new(); gtk_widget_show(menuitem); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + return menuitem; } GtkWidget *pidgin_new_item(GtkWidget *menu, const char *str) @@ -494,6 +495,39 @@ return item; } +static GdkPixbuf * +pidgin_create_prpl_icon_from_prpl(PurplePlugin *prpl, PidginPrplIconSize size, PurpleAccount *account) +{ + PurplePluginProtocolInfo *prpl_info; + const char *protoname = NULL; + char buf[MAXPATHLEN]; + char *filename = NULL; + GdkPixbuf *pixbuf; + + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + if (prpl_info->list_icon == NULL) + return NULL; + + protoname = prpl_info->list_icon(account, NULL); + if (protoname == NULL) + return NULL; + + /* + * Status icons will be themeable too, and then it will look up + * protoname from the theme + */ + g_snprintf(buf, sizeof(buf), "%s.png", protoname); + + filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", + size == PIDGIN_PRPL_ICON_SMALL ? "16" : + size == PIDGIN_PRPL_ICON_MEDIUM ? "22" : "48", + buf, NULL); + pixbuf = gdk_pixbuf_new_from_file(filename, NULL); + g_free(filename); + + return pixbuf; +} + GtkWidget * pidgin_protocol_option_menu_new(const char *id, GCallback cb, gpointer user_data) @@ -507,8 +541,6 @@ GList *p; GtkSizeGroup *sg; char *filename; - const char *proto_name; - char buf[256]; int i, selected_index = -1; const char *gtalk_name = NULL; @@ -555,13 +587,7 @@ } /* Load the image. */ - proto_name = prpl_info->list_icon(NULL, NULL); - g_snprintf(buf, sizeof(buf), "%s.png", proto_name); - - filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", - "16", buf, NULL); - pixbuf = gdk_pixbuf_new_from_file(filename, NULL); - g_free(filename); + pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL); if (pixbuf) image = gtk_image_new_from_pixbuf(pixbuf); @@ -637,10 +663,7 @@ GtkWidget *label; GdkPixbuf *pixbuf; GList *list; - GList *p; GtkSizeGroup *sg; - char *filename; - const char *proto_name; char buf[256]; int i, selected_index = -1; @@ -654,14 +677,12 @@ sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - for (p = list, i = 0; p != NULL; p = p->next, i++) { - PurplePluginProtocolInfo *prpl_info = NULL; - PurplePlugin *plugin; + for (i = 0; list != NULL; list = list->next, i++) { if (show_all) - account = (PurpleAccount *)p->data; + account = (PurpleAccount *)list->data; else { - PurpleConnection *gc = (PurpleConnection *)p->data; + PurpleConnection *gc = (PurpleConnection *)list->data; account = purple_connection_get_account(gc); } @@ -671,11 +692,6 @@ continue; } - plugin = purple_find_prpl(purple_account_get_protocol_id(account)); - - if (plugin != NULL) - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); - /* Create the item. */ item = gtk_menu_item_new(); @@ -684,27 +700,16 @@ gtk_container_add(GTK_CONTAINER(item), hbox); gtk_widget_show(hbox); - /* Load the image. */ - if (prpl_info != NULL) { - proto_name = prpl_info->list_icon(account, NULL); - g_snprintf(buf, sizeof(buf), "%s.png", proto_name); - - filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", - "16", buf, NULL); - pixbuf = gdk_pixbuf_new_from_file(filename, NULL); - g_free(filename); - - if (pixbuf != NULL) { - if (purple_account_is_disconnected(account) && show_all && - purple_connections_get_all()) - gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); - - image = gtk_image_new_from_pixbuf(pixbuf); - - g_object_unref(G_OBJECT(pixbuf)); - } - else - image = gtk_image_new(); + pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); + + if (pixbuf != NULL) { + if (purple_account_is_disconnected(account) && show_all && + purple_connections_get_all()) + gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); + + image = gtk_image_new_from_pixbuf(pixbuf); + + g_object_unref(G_OBJECT(pixbuf)); } else image = gtk_image_new(); @@ -946,6 +951,15 @@ g_free(filename); } +void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name) +{ + PurpleNotifyUserInfo *info = purple_notify_user_info_new(); + purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); + purple_notify_userinfo(conn, name, info, NULL, NULL); + purple_notify_user_info_destroy(info); + serv_get_info(conn, name); +} + gboolean pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts, PurpleAccount **ret_account, char **ret_protocol, @@ -1642,45 +1656,17 @@ } - GdkPixbuf * pidgin_create_prpl_icon(PurpleAccount *account, PidginPrplIconSize size) { PurplePlugin *prpl; - PurplePluginProtocolInfo *prpl_info; - const char *protoname = NULL; - char buf[256]; /* TODO: We should use a define for max file length */ - char *filename = NULL; - GdkPixbuf *pixbuf; - g_return_val_if_fail(account != NULL, NULL); prpl = purple_find_prpl(purple_account_get_protocol_id(account)); if (prpl == NULL) return NULL; - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); - if (prpl_info->list_icon == NULL) - return NULL; - - protoname = prpl_info->list_icon(account, NULL); - if (protoname == NULL) - return NULL; - - /* - * Status icons will be themeable too, and then it will look up - * protoname from the theme - */ - g_snprintf(buf, sizeof(buf), "%s.png", protoname); - - filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", - size == PIDGIN_PRPL_ICON_SMALL ? "16" : - size == PIDGIN_PRPL_ICON_MEDIUM ? "22" : "48", - buf, NULL); - pixbuf = gdk_pixbuf_new_from_file(filename, NULL); - g_free(filename); - - return pixbuf; + return pidgin_create_prpl_icon_from_prpl(prpl, size, account); } static void @@ -1696,62 +1682,61 @@ callback(object, data); } -void +GtkWidget * pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act, gpointer object) { - if (act == NULL) { - pidgin_separator(menu); - } else { - GtkWidget *menuitem; - - if (act->children == NULL) { - menuitem = gtk_menu_item_new_with_mnemonic(act->label); - - if (act->callback != NULL) { - g_object_set_data(G_OBJECT(menuitem), - "purplecallback", - act->callback); - g_object_set_data(G_OBJECT(menuitem), - "purplecallbackdata", - act->data); - g_signal_connect(G_OBJECT(menuitem), "activate", - G_CALLBACK(menu_action_cb), - object); - } else { - gtk_widget_set_sensitive(menuitem, FALSE); - } - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + GtkWidget *menuitem; + if (act == NULL) + return pidgin_separator(menu); + + if (act->children == NULL) { + menuitem = gtk_menu_item_new_with_mnemonic(act->label); + + if (act->callback != NULL) { + g_object_set_data(G_OBJECT(menuitem), + "purplecallback", + act->callback); + g_object_set_data(G_OBJECT(menuitem), + "purplecallbackdata", + act->data); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(menu_action_cb), + object); } else { - GList *l = NULL; - GtkWidget *submenu = NULL; - GtkAccelGroup *group; - - menuitem = gtk_menu_item_new_with_mnemonic(act->label); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - submenu = gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); - - group = gtk_menu_get_accel_group(GTK_MENU(menu)); - if (group) { - char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label); - gtk_menu_set_accel_path(GTK_MENU(submenu), path); - g_free(path); - gtk_menu_set_accel_group(GTK_MENU(submenu), group); - } - - for (l = act->children; l; l = l->next) { - PurpleMenuAction *act = (PurpleMenuAction *)l->data; - - pidgin_append_menu_action(submenu, act, object); - } - g_list_free(act->children); - act->children = NULL; + gtk_widget_set_sensitive(menuitem, FALSE); } - purple_menu_action_free(act); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + } else { + GList *l = NULL; + GtkWidget *submenu = NULL; + GtkAccelGroup *group; + + menuitem = gtk_menu_item_new_with_mnemonic(act->label); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + submenu = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); + + group = gtk_menu_get_accel_group(GTK_MENU(menu)); + if (group) { + char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label); + gtk_menu_set_accel_path(GTK_MENU(submenu), path); + g_free(path); + gtk_menu_set_accel_group(GTK_MENU(submenu), group); + } + + for (l = act->children; l; l = l->next) { + PurpleMenuAction *act = (PurpleMenuAction *)l->data; + + pidgin_append_menu_action(submenu, act, object); + } + g_list_free(act->children); + act->children = NULL; } + purple_menu_action_free(act); + return menuitem; } #if GTK_CHECK_VERSION(2,3,0) diff -r 19678776d406 -r 969db2eac11b pidgin/gtkutils.h --- a/pidgin/gtkutils.h Fri May 25 04:03:19 2007 +0000 +++ b/pidgin/gtkutils.h Fri May 25 05:29:20 2007 +0000 @@ -130,8 +130,10 @@ * Adds a separator to a menu. * * @param menu The menu to add a separator to. + * + * @return The separator. */ -void pidgin_separator(GtkWidget *menu); +GtkWidget *pidgin_separator(GtkWidget *menu); /** * Creates a menu item. @@ -307,6 +309,14 @@ void pidgin_load_accels(void); /** + * Get information about a user. Show immediate feedback. + * + * @param conn The connection to get information from. + * @param name The user to get information about. + */ +void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name); + +/** * Parses an application/x-im-contact MIME message and returns the * data inside. * @@ -404,8 +414,10 @@ * @param menu The menu to append to. * @param act The PurpleMenuAction to append. * @param gobject The object to be passed to the action callback. + * + * @return The menuitem added. */ -void pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act, +GtkWidget *pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act, gpointer gobject); /** diff -r 19678776d406 -r 969db2eac11b pidgin/plugins/cap/cap.c --- a/pidgin/plugins/cap/cap.c Fri May 25 04:03:19 2007 +0000 +++ b/pidgin/plugins/cap/cap.c Fri May 25 05:29:20 2007 +0000 @@ -918,7 +918,8 @@ static PidginPluginUiInfo ui_info = { get_config_frame, - 0 /* page_num (reserved) */ + 0 /* page_num (reserved) */, + NULL,NULL,NULL,NULL }; static PurplePluginInfo info = { @@ -944,7 +945,8 @@ &ui_info, /**< ui_info */ NULL, /**< extra_info */ NULL, /**< prefs_info */ - NULL + NULL, + NULL,NULL,NULL,NULL }; static GtkWidget * get_config_frame(PurplePlugin *plugin) {